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

File: [local] / OpenXM_contrib / pari / src / kernel / ix86 / Attic / l0asm.c (download)

Revision 1.1.1.1 (vendor branch), Sun Jan 9 17:35:32 2000 UTC (24 years, 5 months ago) by maekawa
Branch: PARI_GP
CVS Tags: maekawa-ipv6, VERSION_2_0_17_BETA, RELEASE_20000124, RELEASE_1_2_3, RELEASE_1_2_2_KNOPPIX_b, RELEASE_1_2_2_KNOPPIX, RELEASE_1_2_2, RELEASE_1_2_1, RELEASE_1_1_3, RELEASE_1_1_2
Changes since 1.1: +0 -0 lines

Import PARI/GP 2.0.17 beta.

/***********************************************************************/
/**								      **/
/**		       Low level arithmetic for PARI		      **/
/**                   written by Bruno Haible 14.11.1992              **/
/**                        macroified 21.1.1998                       **/
/**								      **/
/***********************************************************************/
/* $Id: l0asm.c,v 1.1.1.1 1999/09/16 13:47:45 karim Exp $

/* processor: Intel ix86 in native mode
 * assembler syntax: GNU or SUN, moves go from left to right
 * compiler: GNU gcc or SUN cc
 * parameter passing convention: on the stack 4(%esp),8(%esp),...
 * registers: %eax,%edx,%ecx may be modified,
 *            everything else must be saved and restored
 * result: passed in %eax
 * word length: 32 bits
 */

/* If the C compiler is GNU C, better stuff is contained in asmix86inline.h,
   but we compile and link this file nevertheless because it defines the
   global variable `hiremainder'. */

/* This should ideally be determined at configure time. */
#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__)
#  define ASM_UNDERSCORE
#endif

#include "l0asm.h"

#if defined(__EMX__) && defined(__NO_AOUT) /* No underscores, rest as is */
#   undef C
#   define C(entrypoint) /**/entrypoint
#endif


#undef ALIGN
#ifdef _MSC_VER
  #define ALIGN
#else
#if defined(ASM_UNDERSCORE) && !(defined(__CYGWIN32__) || defined(__MINGW32__))
  /* BSD syntax assembler */
  #define ALIGN  .align 3
#else
  /* ELF syntax assembler */
  #define ALIGN  .align 8
#endif
#endif

        GLOBL(C(addll))
        GLOBL(C(subll))
        GLOBL(C(addllx))
        GLOBL(C(subllx))
        GLOBL(C(shiftl))
        GLOBL(C(shiftlr))
        GLOBL(C(bfffo))
        GLOBL(C(mulll))
        GLOBL(C(addmul))
        GLOBL(C(divll))
        GLOBL(C(overflow))
        GLOBL(C(hiremainder))

#ifdef _MSC_VER
unsigned long overflow;
unsigned long hiremainder;
#else
#ifdef BSD_SYNTAX
#  if defined(__EMX__) && defined(__NO_AOUT) /* Otherwise IBM linker will
					        ignore this module */
.data
.align 2
C(overflow):
    .long 0
C(hiremainder):
    .long 0
.text
#  else
.comm C(overflow),4
.comm C(hiremainder),4
#  endif
#endif
#ifdef ELF_SYNTAX
.comm C(overflow),4,4
.comm C(hiremainder),4,4
#endif
#endif

TEXT()

	ALIGN
FUNBEGIN(addll)
        INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx    */
        INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x         */
        INSN2(add,l     ,X4 MEM_DISP(esp,8),R(eax)) /* add y         */
        INSN2(adc,l     ,R(edx),R(edx))             /* %edx := carry */
        INSN2(mov,l     ,R(edx),C(overflow))        /* set overflow  */
	ret                                         /* return %eax   */
FUNEND()

	ALIGN
FUNBEGIN(addllx)
        INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx      */
        INSN2(xor,l     ,R(eax),R(eax))             /* clear %eax      */
        INSN2(sub,l     ,C(overflow),R(eax))        /* set carry       */
        INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x           */
        INSN2(adc,l     ,X4 MEM_DISP(esp,8),R(eax)) /* add y and carry */
        INSN2(adc,l     ,R(edx),R(edx))             /* %edx := carry   */
        INSN2(mov,l     ,R(edx),C(overflow))        /* set overflow    */
	ret                                         /* return %eax     */
FUNEND()

	ALIGN
FUNBEGIN(subll)
        INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx    */
        INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x         */
        INSN2(sub,l     ,X4 MEM_DISP(esp,8),R(eax)) /* subtract y    */
        INSN2(adc,l     ,R(edx),R(edx))             /* %edx := carry */
        INSN2(mov,l     ,R(edx),C(overflow))        /* set overflow  */
	ret                                         /* return %eax   */
FUNEND()

	ALIGN
FUNBEGIN(subllx)
        INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx           */
        INSN2(xor,l     ,R(eax),R(eax))             /* clear %eax           */
        INSN2(sub,l     ,C(overflow),R(eax))        /* set carry            */
        INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                */
        INSN2(sbb,l     ,X4 MEM_DISP(esp,8),R(eax)) /* subtract y and carry */
        INSN2(adc,l     ,R(edx),R(edx))             /* %edx := carry        */
        INSN2(mov,l     ,R(edx),C(overflow))        /* set overflow         */
	ret                                         /* return %eax          */
FUNEND()

	ALIGN
FUNBEGIN(shiftl)
        INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                          */
        INSN2(mov,b     ,X1 MEM_DISP(esp,8),R(cl))  /* get shift count i              */
        INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx                     */
        INSN2SHCL(shld,l,R(eax),R(edx))             /* shift %edx left by i bits,
                                                       feeding in %eax from the right */
        INSN2(shl,l     ,R(cl),R(eax))              /* shift %eax left by i bits      */
        INSN2(mov,l     ,R(edx),C(hiremainder))     /* set hiremainder                */
	ret                                         /* return %eax                    */
FUNEND()

	ALIGN
FUNBEGIN(shiftlr)
        INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                         */
        INSN2(mov,b     ,X1 MEM_DISP(esp,8),R(cl))  /* get shift count i             */
        INSN2(xor,l     ,R(edx),R(edx))             /* clear %edx                    */
        INSN2SHCL(shrd,l,R(eax),R(edx))             /* shift %edx right by i bits,
                                                       feeding in %eax from the left */
        INSN2(shr,l     ,R(cl),R(eax))              /* shift %eax right by i bits    */
        INSN2(mov,l     ,R(edx),C(hiremainder))     /* set hiremainder               */
	ret                                         /* return %eax                   */
FUNEND()

	ALIGN
FUNBEGIN(bfffo)
        INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                         */
        INSN2(bsr,l     ,R(eax),R(edx))             /* %edx := number of leading bit */
        INSN2(mov,l     ,NUM(31),R(eax))
        INSN2(sub,l     ,R(edx),R(eax))             /* result is 31 - %edx           */
        ret                                         /* return %eax                   */
FUNEND()

	ALIGN
FUNBEGIN(mulll)
        INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                */
        INSN1(mul,l     ,X4 MEM_DISP(esp,8))        /* %edx|%eax := x * y   */
        INSN2(mov,l     ,R(edx),C(hiremainder))     /* store high word      */
        ret                                         /* return low word %eax */
FUNEND()

	ALIGN
FUNBEGIN(addmul)
        INSN2(xor,l     ,R(ecx),R(ecx))             /* clear %ecx           */
        INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get x                */
        INSN1(mul,l     ,X4 MEM_DISP(esp,8))        /* %edx|%eax := x * y   */
        INSN2(add,l     ,C(hiremainder),R(eax))     /* add 0|hiremainder    */
        INSN2(adc,l     ,R(ecx),R(edx))
        INSN2(mov,l     ,R(edx),C(hiremainder))     /* store high word      */
        ret                                         /* return low word %eax */
FUNEND()

        ALIGN
FUNBEGIN(divll)
        INSN2(mov,l     ,X4 MEM_DISP(esp,4),R(eax)) /* get low word x        */
        INSN2(mov,l     ,C(hiremainder),R(edx))     /* get high word         */
        INSN1(div,l     ,X4 MEM_DISP(esp,8))        /* divide %edx|%eax by y */
        INSN2(mov,l     ,R(edx), C(hiremainder))    /* store remainder       */
        ret                                         /* return quotient %eax  */
FUNEND()

	ALIGN