Annotation of OpenXM_contrib/pari/src/kernel/ix86/l0asm.c, Revision 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>