[BACK]Return to l0asm.txt CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / pari-2.2 / src / kernel / ix86

Annotation of OpenXM_contrib/pari-2.2/src/kernel/ix86/l0asm.txt, Revision 1.1.1.1

1.1       noro        1: // Assembly language support for i386 CPU.
                      2: // Bruno Haible 21.6.1997
                      3:
                      4: // An assembly language file for the i386/i486/i586/i686 CPUs:
                      5: // On Unix, it is preprocessed and then assembled. NB: This file requires
                      6: // an ANSI C or C++ preprocessor which understands C++ comments.
                      7: // On Windows, with MSVC, it is preprocessed and then compiled with
                      8: // optimization. (The MSVC development environment does not have a separate
                      9: // assembler, we must use the C compiler's inline asm extension. Compiling
                     10: // without optimization pushes the registers %ebx,%esi,%edi onto the stack
                     11: // at function entry and pops them at function exit, which is not what we
                     12: // want because it affects the %esp offsets of the function arguments.)
                     13:
                     14: // The assembly language file should
                     15: // 1. include a configuration file which defines ASM_UNDERSCORE if appropriate.
                     16: //    #ifndef _MSC_VER
                     17: //    #include "config.h"
                     18: //    #endif
                     19: // 2. include this file.
                     20: //    #include "level0asm.h"
                     21: // 3. define all assembly language code.
                     22:
                     23: // The three different assembler syntaxes for this CPU are a MAJOR annoyance.
                     24: // In order not to have to maintain several copies of the assembly language
                     25: // code, we use lots of macros which expand into the correct syntax.
                     26: // These macros are:
                     27: //   C(name)
                     28: //           This expands to the name of the C variable or function `name'.
                     29: //           On Unix BSD systems, this prepends an underscore.
                     30: //   L(label)
                     31: //           This expands to the name of a local label, having the name `label'.
                     32: //           On Unix ELF systems, where there is no underscore, names beginning
                     33: //           with an alphabetic character are automatically exported, so this
                     34: //           prepends a dot. Note that when defining a label, the `:' must
                     35: //           be inside the parentheses, not outside, because otherwise some
                     36: //           ANSI C preprocessor inserts a space between the label and the `:',
                     37: //           and some assemblers don't like this.
                     38: //   R(reg)
                     39: //           This expands to a reference to register `reg'. On Unix, this
                     40: //           prepends a % charater.
                     41: //   NUM(value)
                     42: //           This expands to an immediate value. On Unix, this prepends a $
                     43: //           character.
                     44: //   ADDR(variable)
                     45: //           This expands to an immediate value, the address of some variable
                     46: //           or function. On Unix, this prepends a $ character. With MSVC,
                     47: //           this prepends the keyword "OFFSET".
                     48: //   About operand sizes: On Unix, a suffix to the instruction specifies the
                     49: //           size of the operands (for example "movb", "movw", "movl"). With
                     50: //           MSVC, there is no such suffix. Instead, the assembler infers the
                     51: //           operand size from the names of the registers ("al" vs. "ax" vs.
                     52: //           "eax"). This works well in most cases, but in instructions like
                     53: //           "mul [esi]" the assembler guesses the operand size: "byte" by
                     54: //           default. So it is better to explicitly specify the operand size
                     55: //           of memory operands (prefix X1, X2, X4, X8).
                     56: //           (Side note about Unix assemblers: Some Unix assemblers allow you
                     57: //           to write "testb %eax,%eax" but silently treat this as
                     58: //           "testb %al,%al".)
                     59: //   X1
                     60: //           This prefixes a memory reference of 1 byte.
                     61: //   X2
                     62: //           This prefixes a memory reference of 2 bytes.
                     63: //   X4
                     64: //           This prefixes a memory reference of 4 bytes.
                     65: //   X8
                     66: //           This prefixes a memory reference of 8 bytes.
                     67: //   MEM(base)
                     68: //           This expands to a memory reference at address `base'.
                     69: //   MEM_DISP(base,displacement)
                     70: //           This expands to a memory reference at address `base+displacement'.
                     71: //   MEM_INDEX(base,index)
                     72: //           This expands to a memory reference at address `base+index'.
                     73: //   MEM_SHINDEX(base,index,size)
                     74: //           This expands to a memory reference at address
                     75: //           `base+index*size', where `size' is 1, 2, 4, or 8.
                     76: //   MEM_DISP_SHINDEX0(displacement,index,size)
                     77: //           This expands to a memory reference at address
                     78: //           `displacement+index*size', where `size' is 1, 2, 4, or 8.
                     79: //   MEM_DISP_SHINDEX(base,displacement,index,size)
                     80: //           This expands to a memory reference at address
                     81: //           `base+displacement+index*size', where `size' is 1, 2, 4, or 8.
                     82: //   INDIR(value)
                     83: //           This expands to an implicit indirection. On Unix, this prepends
                     84: //           a * character.
                     85: //   INSN1(mnemonic,size_suffix,dst)
                     86: //           This expands to an instruction with one operand.
                     87: //   INSN2(mnemonic,size_suffix,src,dst)
                     88: //           This expands to an instruction with two operands. In our notation,
                     89: //           `src' comes first and `dst' second, but they are reversed when
                     90: //           expanding to Intel syntax.
                     91: //   INSN2MOVX(mnemonic,size_suffix,src,dst)
                     92: //           This expands to an instruction with two operands, of type
                     93: //           movsbl/movzbl, which in some syntaxes requires a second suffix.
                     94: //   INSN2SHCL(mnemonic,size_suffix,src,dst)
                     95: //           This expands to an instruction with two operands, of type
                     96: //           shrd/shld, which in some syntaxes requires an additional operand
                     97: //           %cl.
                     98: //   REP, REPZ
                     99: //           This expands to a prefix for string instructions.
                    100: //   _
                    101: //           For instructions which don't have a size suffix, like jump
                    102: //           instructions. Expands to nothing. Needed for MSVC, which has
                    103: //           problems with empty macro arguments.
                    104: //   TEXT()
                    105: //           Switch to the code section.
                    106: //   ALIGN(log)
                    107: //           Align to 2^log bytes.
                    108: //   GLOBL(name)
                    109: //           Declare `name' to be a global symbol.
                    110: //   FUNBEGIN(name)
                    111: //           Start the assembly language code for the C function `name'.
                    112: //   FUNEND()
                    113: //           End the assembly language code for a function.
                    114:
                    115: // Define the C(name) and L(label) macros.
                    116: #ifdef _MSC_VER
                    117: #  define C(entrypoint) entrypoint
                    118: #  define L(label) L##label
                    119: #else
                    120: #  ifdef ASM_UNDERSCORE
                    121: #    if defined(__STDC__) || defined(__cplusplus)
                    122: #      define C(entrypoint) _##entrypoint
                    123: #      define L(label) L##label
                    124: #    else
                    125: #      define C(entrypoint) _/**/entrypoint
                    126: #      define L(label) L/**/label
                    127: #    endif
                    128: #  else
                    129: #    define C(entrypoint) entrypoint
                    130: #    if defined(__STDC__) || defined(__cplusplus)
                    131: #      define L(label) .L##label
                    132: #    else
                    133: #      define L(label) .L/**/label
                    134: #    endif
                    135: #  endif
                    136: #endif
                    137:
                    138: // Define one of these.
                    139: // BSD_SYNTAX for GNU assembler version 2.
                    140: // ELF_SYNTAX for SVR4 and Solaris assemblers.
                    141: // INTEL_SYNTAX for MS assembler.
                    142: #ifdef _MSC_VER
                    143: #  define INTEL_SYNTAX
                    144: #else
                    145: // On Unix, it happens that the ELF systems (ASM_UNDERSCORE not defined) use
                    146: // the ELF syntax, while the BSD systems (ASM_UNDERSCORE defined) use the
                    147: // BSD syntax. Neat to know, this saves us from enumerating all the systems.
                    148: #  ifdef ASM_UNDERSCORE
                    149: #    define BSD_SYNTAX
                    150: #  else
                    151: #    define ELF_SYNTAX
                    152: #  endif
                    153: #endif
                    154:
                    155: #if defined (BSD_SYNTAX) || defined (ELF_SYNTAX)
                    156: #  define R(r) %r
                    157: #  define NUM(n) $##n
                    158: #  define ADDR(a) $##a
                    159: #  define X1
                    160: #  define X2
                    161: #  define X4
                    162: #  define X8
                    163: #  define MEM(base)(R(base))
                    164: #  define MEM_DISP(base,displacement)displacement(R(base))
                    165: #  define MEM_INDEX(base,index)(R(base),R(index))
                    166: #  define MEM_SHINDEX(base,index,size)(R(base),R(index),size)
                    167: #  define MEM_DISP_SHINDEX0(displacement,index,size)displacement(,R(index),size)
                    168: #  define MEM_DISP_SHINDEX(base,displacement,index,size)displacement(R(base),R(index),size)
                    169: #  define INDIR(value)*value
                    170: #  define INSNCONC(mnemonic,size_suffix)mnemonic##size_suffix
                    171: #  define INSN1(mnemonic,size_suffix,dst)INSNCONC(mnemonic,size_suffix) dst
                    172: #  define INSN2(mnemonic,size_suffix,src,dst)INSNCONC(mnemonic,size_suffix) src,dst
                    173: #  define INSN2MOVX(mnemonic,size_suffix,src,dst)INSNCONC(INSNCONC(mnemonic,size_suffix),l) src,dst
                    174: #  if defined(BSD_SYNTAX) || defined(COHERENT)
                    175: #    define INSN2SHCL(mnemonic,size_suffix,src,dst)INSNCONC(mnemonic,size_suffix) R(cl),src,dst
                    176: #    define REPZ repe ;
                    177: #  else
                    178: #    define INSN2SHCL(mnemonic,size_suffix,src,dst)INSNCONC(mnemonic,size_suffix) src,dst
                    179: #    define REPZ repz ;
                    180: #  endif
                    181: #  define REP rep ;
                    182: #  if defined(BSD_SYNTAX) && !(defined(__CYGWIN32__) || defined(__MINGW32__))
                    183: #    define ALIGN(log) .align log,0x90
                    184: #  endif
                    185: #  if defined(ELF_SYNTAX) || defined(__CYGWIN32__) || defined(__MINGW32__)
                    186: #    define ALIGN(log) .align 1<<(log)
                    187: #  endif
                    188: #endif
                    189: #ifdef INTEL_SYNTAX
                    190: #  define R(r) r
                    191: #  define NUM(n) n
                    192: #  define ADDR(a) OFFSET a
                    193: #  define X1 BYTE PTR
                    194: #  define X2 WORD PTR
                    195: #  define X4 DWORD PTR
                    196: #  define X8 QWORD PTR
                    197: #  define MEM(base) [base]
                    198: #  define MEM_DISP(base,displacement) [base+(displacement)]
                    199: #  define MEM_INDEX(base,index) [base+index]
                    200: #  define MEM_SHINDEX(base,index,size) [base+index*size]
                    201: #  define MEM_DISP_SHINDEX0(displacement,index,size) [(displacement)+index*size]
                    202: #  define MEM_DISP_SHINDEX(base,displacement,index,size) [base+(displacement)+index*size]
                    203: #  define INDIR(value)value
                    204: #  define INSNCONC(mnemonic,suffix)mnemonic##suffix
                    205: #  define INSN1(mnemonic,size_suffix,dst)mnemonic dst
                    206: #  define INSN2(mnemonic,size_suffix,src,dst)mnemonic dst,src
                    207: #  define INSN2MOVX(mnemonic,size_suffix,src,dst)INSNCONC(mnemonic,x) dst,src
                    208: #  define INSN2SHCL(mnemonic,size_suffix,src,dst)mnemonic dst,src,R(cl)
                    209: #  define REPZ repz
                    210: #  define REP rep
                    211: #  define movsl  movs R(eax)
                    212: #  define stosl  stos R(eax)
                    213: #  define scasl  scas R(eax)
                    214: #  define cmpsl  cmpsd
                    215: #  ifdef _MSC_VER
                    216: // No pseudo-ops available in MS inline assembler.
                    217: #    define ALIGN(log)
                    218: #  else
                    219: #    define ALIGN(log) .align log
                    220: #  endif
                    221: #endif
                    222:
                    223: #ifdef _MSC_VER
                    224: // No pseudo-ops available in MS inline assembler.
                    225: #  define TEXT()
                    226: #else
                    227: #  define TEXT() .text
                    228: #endif
                    229:
                    230: #ifdef _MSC_VER
                    231: #  define GLOBL(name)
                    232: #else
                    233: #  define GLOBL(name) .globl name
                    234: #endif
                    235:
                    236: // Define the FUNBEGIN(name) and FUNEND() macros.
                    237: #ifdef _MSC_VER
                    238: // The "naked" attribute avoids the compiler generated prologue and epilogue
                    239: // (which saves the registers %ebx,%esi,%edi if no optimization is enabled,
                    240: // and those registers among %ebx,%esi,%edi which occur in the asm code
                    241: // if optimization is enabled).
                    242: #  define FUNBEGIN(name) __declspec(naked) void name () { __asm {
                    243: #  define FUNEND()                                      }       }
                    244: #else
                    245: #  define FUNBEGIN(name) C(name##:)
                    246: #  define FUNEND()
                    247: #endif
                    248:
                    249: #define _
                    250:
                    251: // Here we go!
                    252:
                    253: TEXT()
                    254:
                    255: // Rules about registers:
                    256: // Registers %eax,%edx,%ecx may be freely used.
                    257: // Registers %ebx,%esi,%edi must be saved before being used.
                    258: // Don't fiddle with register %ebp - some platforms don't like this.

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>