[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     ! 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>