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