[BACK]Return to l0asm.c 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.c, Revision 1.1.1.1

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

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