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

Annotation of OpenXM_contrib/pari/src/kernel/ix86/l0asm.c, Revision 1.1.1.1

1.1       maekawa     1: /***********************************************************************/
                      2: /**                                                                  **/
                      3: /**                   Low level arithmetic for PARI                  **/
                      4: /**                   written by Bruno Haible 14.11.1992              **/
                      5: /**                        macroified 21.1.1998                       **/
                      6: /**                                                                  **/
                      7: /***********************************************************************/
                      8: /* $Id: l0asm.c,v 1.1.1.1 1999/09/16 13:47:45 karim Exp $
                      9:
                     10: /* processor: Intel ix86 in native mode
                     11:  * assembler syntax: GNU or SUN, moves go from left to right
                     12:  * compiler: GNU gcc or SUN cc
                     13:  * parameter passing convention: on the stack 4(%esp),8(%esp),...
                     14:  * registers: %eax,%edx,%ecx may be modified,
                     15:  *            everything else must be saved and restored
                     16:  * result: passed in %eax
                     17:  * word length: 32 bits
                     18:  */
                     19:
                     20: /* If the C compiler is GNU C, better stuff is contained in asmix86inline.h,
                     21:    but we compile and link this file nevertheless because it defines the
                     22:    global variable `hiremainder'. */
                     23:
                     24: /* This should ideally be determined at configure time. */
                     25: #if defined(__EMX__) || defined(__DJGCC__) || defined(__GO32__) || (defined(linux) && !defined(__ELF__)) || defined(__386BSD__) || defined(__NetBSD__) || (defined(__FreeBSD__) && !defined(__ELF__)) || defined(NeXT) || defined(__CYGWIN32__) || defined(__MINGW32__)
                     26: #  define ASM_UNDERSCORE
                     27: #endif
                     28:
                     29: #include "l0asm.h"
                     30:
                     31: #if defined(__EMX__) && defined(__NO_AOUT) /* No underscores, rest as is */
                     32: #   undef C
                     33: #   define C(entrypoint) /**/entrypoint
                     34: #endif
                     35:
                     36:
                     37: #undef ALIGN
                     38: #ifdef _MSC_VER
                     39:   #define ALIGN
                     40: #else
                     41: #if defined(ASM_UNDERSCORE) && !(defined(__CYGWIN32__) || defined(__MINGW32__))
                     42:   /* BSD syntax assembler */
                     43:   #define ALIGN  .align 3
                     44: #else
                     45:   /* ELF syntax assembler */
                     46:   #define ALIGN  .align 8
                     47: #endif
                     48: #endif
                     49:
                     50:         GLOBL(C(addll))
                     51:         GLOBL(C(subll))
                     52:         GLOBL(C(addllx))
                     53:         GLOBL(C(subllx))
                     54:         GLOBL(C(shiftl))
                     55:         GLOBL(C(shiftlr))
                     56:         GLOBL(C(bfffo))
                     57:         GLOBL(C(mulll))
                     58:         GLOBL(C(addmul))
                     59:         GLOBL(C(divll))
                     60:         GLOBL(C(overflow))
                     61:         GLOBL(C(hiremainder))
                     62:
                     63: #ifdef _MSC_VER
                     64: unsigned long overflow;
                     65: unsigned long hiremainder;
                     66: #else
                     67: #ifdef BSD_SYNTAX
                     68: #  if defined(__EMX__) && defined(__NO_AOUT) /* Otherwise IBM linker will
                     69:                                                ignore this module */
                     70: .data
                     71: .align 2
                     72: C(overflow):
                     73:     .long 0
                     74: C(hiremainder):
                     75:     .long 0
                     76: .text
                     77: #  else
                     78: .comm C(overflow),4
                     79: .comm C(hiremainder),4
                     80: #  endif
                     81: #endif
                     82: #ifdef ELF_SYNTAX
                     83: .comm C(overflow),4,4
                     84: .comm C(hiremainder),4,4
                     85: #endif
                     86: #endif
                     87:
                     88: TEXT()
                     89:
                     90:        ALIGN
                     91: FUNBEGIN(addll)
                     92:         INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx    */
                     93:         INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x         */
                     94:         INSN2(add,l     ,X4 MEM_DISP(esp,8),R(eax)) /* add y         */
                     95:         INSN2(adc,l     ,R(edx),R(edx))             /* %edx := carry */
                     96:         INSN2(mov,l     ,R(edx),C(overflow))        /* set overflow  */
                     97:        ret                                         /* return %eax   */
                     98: FUNEND()
                     99:
                    100:        ALIGN
                    101: FUNBEGIN(addllx)
                    102:         INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx      */
                    103:         INSN2(xor,l     ,R(eax),R(eax))             /* clear %eax      */
                    104:         INSN2(sub,l     ,C(overflow),R(eax))        /* set carry       */
                    105:         INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x           */
                    106:         INSN2(adc,l     ,X4 MEM_DISP(esp,8),R(eax)) /* add y and carry */
                    107:         INSN2(adc,l     ,R(edx),R(edx))             /* %edx := carry   */
                    108:         INSN2(mov,l     ,R(edx),C(overflow))        /* set overflow    */
                    109:        ret                                         /* return %eax     */
                    110: FUNEND()
                    111:
                    112:        ALIGN
                    113: FUNBEGIN(subll)
                    114:         INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx    */
                    115:         INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x         */
                    116:         INSN2(sub,l     ,X4 MEM_DISP(esp,8),R(eax)) /* subtract y    */
                    117:         INSN2(adc,l     ,R(edx),R(edx))             /* %edx := carry */
                    118:         INSN2(mov,l     ,R(edx),C(overflow))        /* set overflow  */
                    119:        ret                                         /* return %eax   */
                    120: FUNEND()
                    121:
                    122:        ALIGN
                    123: FUNBEGIN(subllx)
                    124:         INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx           */
                    125:         INSN2(xor,l     ,R(eax),R(eax))             /* clear %eax           */
                    126:         INSN2(sub,l     ,C(overflow),R(eax))        /* set carry            */
                    127:         INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                */
                    128:         INSN2(sbb,l     ,X4 MEM_DISP(esp,8),R(eax)) /* subtract y and carry */
                    129:         INSN2(adc,l     ,R(edx),R(edx))             /* %edx := carry        */
                    130:         INSN2(mov,l     ,R(edx),C(overflow))        /* set overflow         */
                    131:        ret                                         /* return %eax          */
                    132: FUNEND()
                    133:
                    134:        ALIGN
                    135: FUNBEGIN(shiftl)
                    136:         INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                          */
                    137:         INSN2(mov,b     ,X1 MEM_DISP(esp,8),R(cl))  /* get shift count i              */
                    138:         INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx                     */
                    139:         INSN2SHCL(shld,l,R(eax),R(edx))             /* shift %edx left by i bits,
                    140:                                                        feeding in %eax from the right */
                    141:         INSN2(shl,l     ,R(cl),R(eax))              /* shift %eax left by i bits      */
                    142:         INSN2(mov,l     ,R(edx),C(hiremainder))     /* set hiremainder                */
                    143:        ret                                         /* return %eax                    */
                    144: FUNEND()
                    145:
                    146:        ALIGN
                    147: FUNBEGIN(shiftlr)
                    148:         INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                         */
                    149:         INSN2(mov,b     ,X1 MEM_DISP(esp,8),R(cl))  /* get shift count i             */
                    150:         INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx                    */
                    151:         INSN2SHCL(shrd,l,R(eax),R(edx))             /* shift %edx right by i bits,
                    152:                                                        feeding in %eax from the left */
                    153:         INSN2(shr,l     ,R(cl),R(eax))              /* shift %eax right by i bits    */
                    154:         INSN2(mov,l     ,R(edx),C(hiremainder))     /* set hiremainder               */
                    155:        ret                                         /* return %eax                   */
                    156: FUNEND()
                    157:
                    158:        ALIGN
                    159: FUNBEGIN(bfffo)
                    160:         INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                         */
                    161:         INSN2(bsr,l     ,R(eax),R(edx))             /* %edx := number of leading bit */
                    162:         INSN2(mov,l     ,NUM(31),R(eax))
                    163:         INSN2(sub,l     ,R(edx),R(eax))             /* result is 31 - %edx           */
                    164:         ret                                         /* return %eax                   */
                    165: FUNEND()
                    166:
                    167:        ALIGN
                    168: FUNBEGIN(mulll)
                    169:         INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                */
                    170:         INSN1(mul,l     ,X4 MEM_DISP(esp,8))        /* %edx|%eax := x * y   */
                    171:         INSN2(mov,l     ,R(edx),C(hiremainder))     /* store high word      */
                    172:         ret                                         /* return low word %eax */
                    173: FUNEND()
                    174:
                    175:        ALIGN
                    176: FUNBEGIN(addmul)
                    177:         INSN2(xor,l     ,R(ecx),R(ecx))             /* clear %ecx           */
                    178:         INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                */
                    179:         INSN1(mul,l     ,X4 MEM_DISP(esp,8))        /* %edx|%eax := x * y   */
                    180:         INSN2(add,l     ,C(hiremainder),R(eax))     /* add 0|hiremainder    */
                    181:         INSN2(adc,l     ,R(ecx),R(edx))
                    182:         INSN2(mov,l     ,R(edx),C(hiremainder))     /* store high word      */
                    183:         ret                                         /* return low word %eax */
                    184: FUNEND()
                    185:
                    186:         ALIGN
                    187: FUNBEGIN(divll)
                    188:         INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get low word x        */
                    189:         INSN2(mov,l     ,C(hiremainder),R(edx))     /* get high word         */
                    190:         INSN1(div,l     ,X4 MEM_DISP(esp,8))        /* divide %edx|%eax by y */
                    191:         INSN2(mov,l     ,R(edx), C(hiremainder))    /* store remainder       */
                    192:         ret                                         /* return quotient %eax  */
                    193: FUNEND()
                    194:
                    195:        ALIGN

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