/* WARNING: compile this in 32 bit int mode even for short library */ #include #include #ifndef _COMPILER_H #include #endif #ifdef __DEF_ALL__ /* this def'ed when making on the ST */ #define L_adddi3 #define L_subdi3 #define L_muldi3 #define L_divdi3 #define L_moddi3 #define L_udivdi3 #define L_umoddi3 #define L_negdi2 #define L_anddi3 #define L_iordi3 #define L_xordi3 #define L_lshrdi3 #define L_lshldi3 #define L_ashldi3 #define L_ashrdi3 #define L_one_cmpldi2 #define L_bdiv #define L_cmpdi2 #define L_ucmpdi2 #define L_fixunsdfdi #define L_fixdfdi #define L_floatdidf /* gcc-2.0 stuff */ #if 0 /* NOTE: these are now covered, and should not be generated here */ #define L_lshrsi3 #define L_lshlsi3 #define L_ashrsi3 #define L_ashlsi3 #define L_eqdf2 #define L_nedf2 #define L_gtdf2 #define L_gedf2 #define L_ltdf2 #define L_ledf2 #define L_fixsfsi #define L_floatsisf #define L_eqsf2 #define L_nesf2 #define L_gtsf2 #define L_gesf2 #define L_ltsf2 #define L_lesf2 #endif #define L_fxussfsi #endif /* __DEF_ALL__ */ /* More subroutines needed by GCC output code on some machines. */ /* Compile this one with gcc. */ #if 0 #include "config.h" /* dont drag this in, just define relevant stuff from xm/tm-atari.h & xm/tm-m68k.h here */ #else /* #defines that need visibility everywhere. */ #define FALSE 0 #define TRUE 1 /* This describes the machine the compiler is hosted on. */ #define HOST_BITS_PER_CHAR 8 #define HOST_BITS_PER_SHORT 16 #define HOST_BITS_PER_INT 32 #define HOST_BITS_PER_LONG 32 /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. This is true for 68020 insns such as bfins and bfexts. We make it true always by avoiding using the single-bit insns except in special cases with constant bit numbers. */ #define BITS_BIG_ENDIAN /* Define this if most significant byte of a word is the lowest numbered. */ /* That is true on the 68000. */ #define BYTES_BIG_ENDIAN /* Define this if most significant word of a multiword number is numbered. */ /* For 68000 we can decide arbitrarily since there are no machine instructions for them. */ /* #define WORDS_BIG_ENDIAN */ /* number of bits in an addressible storage unit */ #define BITS_PER_UNIT 8 /* Width in bits of a "word", which is the contents of a machine register. Note that this is not necessarily the width of data type `int'; if using 16-bit ints on a 68000, this would still be 32. But on a machine with 16-bit registers, this would be 16. */ #define BITS_PER_WORD 32 /* Width of a word, in units (bytes). */ #define UNITS_PER_WORD 4 /* Width in bits of a pointer. See also the macro `Pmode' defined below. */ #define POINTER_SIZE 32 /* Allocation boundary (in *bits*) for storing pointers in memory. */ #define POINTER_BOUNDARY 16 /* Allocation boundary (in *bits*) for storing arguments in argument list. */ #define PARM_BOUNDARY (TARGET_SHORT ? 16 : 32) /* Boundary (in *bits*) on which stack pointer should be aligned. */ #define STACK_BOUNDARY 16 /* Allocation boundary (in *bits*) for the code of a function. */ #define FUNCTION_BOUNDARY 16 /* Alignment of field after `int : 0' in a structure. */ #define EMPTY_FIELD_BOUNDARY 16 /* No data type wants to be aligned rounder than this. */ #define BIGGEST_ALIGNMENT 16 /* Define this if move instructions will actually fail to work when given unaligned data. */ #define STRICT_ALIGNMENT /* Define number of bits in most basic integer type. (If undefined, default is BITS_PER_WORD). */ #ifdef __MSHORT__ #define INT_TYPE_SIZE 16 #else #define INT_TYPE_SIZE 32 #endif #endif #ifndef minix #include #else typedef unsigned long size_t; #include "lib.h" #endif #ifndef SItype #define SItype long int #endif /* long long ints are pairs of long ints in the order determined by WORDS_BIG_ENDIAN. */ #ifdef WORDS_BIG_ENDIAN struct longlong {long high, low;}; #else struct longlong {long low, high;}; #endif /* We need this union to unpack/pack longlongs, since we don't have any arithmetic yet. Incoming long long parameters are stored into the `ll' field, and the unpacked result is read from the struct longlong. */ typedef union { struct longlong s; long long ll; SItype i[2]; unsigned SItype ui[2]; } long_long; /* Internally, long long ints are strings of unsigned shorts in the order determined by BYTES_BIG_ENDIAN. */ #define B 0x10000 #define low16 (B - 1) #ifdef BYTES_BIG_ENDIAN /* Note that HIGH and LOW do not describe the order of words in a long long. They describe the order of words in vectors ordered according to the byte order. */ #define HIGH 0 #define LOW 1 #define big_end(n) 0 #define little_end(n) ((n) - 1) #define next_msd(i) ((i) - 1) #define next_lsd(i) ((i) + 1) #define is_not_msd(i,n) ((i) >= 0) #define is_not_lsd(i,n) ((i) < (n)) #else #define LOW 0 #define HIGH 1 #define big_end(n) ((n) - 1) #define little_end(n) 0 #define next_msd(i) ((i) + 1) #define next_lsd(i) ((i) - 1) #define is_not_msd(i,n) ((i) < (n)) #define is_not_lsd(i,n) ((i) >= 0) #endif /* These algorithms are all straight out of Knuth, vol. 2, sec. 4.3.1. */ __EXTERN long long __adddi3 __PROTO((long long u, long long v)); __EXTERN long long __anddi3 __PROTO((long long u, long long v)); __EXTERN long long __iordi3 __PROTO((long long u, long long v)); __EXTERN long long __xordi3 __PROTO((long long u, long long v)); __EXTERN long long __one_cmpldi2 __PROTO((long long u)); __EXTERN long long __lshldi3 __PROTO((long long u, long int b1)); __EXTERN long long __lshrdi3 __PROTO((long long u, long int b1)); __EXTERN long long __ashldi3 __PROTO((long long u, long int b1)); __EXTERN long long __ashrdi3 __PROTO((long long u, long int b1)); __EXTERN long long __subdi3 __PROTO((long long u, long long v)); __EXTERN long long __muldi3 __PROTO((long long u, long long v)); __EXTERN long long __divdi3 __PROTO((long long u, long long v)); __EXTERN long long __moddi3 __PROTO((long long u, long long v)); __EXTERN long long __udivdi3 __PROTO((long long u, long long v)); __EXTERN long long __umoddi3 __PROTO((long long u, long long v)); __EXTERN long long __negdi2 __PROTO((long long u)); __EXTERN void __bdiv __PROTO((unsigned short *a, unsigned short *b, unsigned short *q, unsigned short *r, size_t m, size_t n)); __EXTERN SItype __cmpdi2 __PROTO((long long a, long long b)); __EXTERN SItype __ucmpdi2 __PROTO((long long a, long long b)); __EXTERN long long __fixunsdfdi __PROTO((double a)); __EXTERN long long __fixdfdi __PROTO((double a)); __EXTERN double __floatdidf __PROTO((long long u)); __EXTERN int __builtin_saveregs __PROTO((void)); __EXTERN unsigned SItype __fixunssfsi __PROTO((float a)); #ifdef L_adddi3 static int badd __PROTO((unsigned short *a, unsigned short *b, unsigned short *c, size_t n)); long long __adddi3 (u, v) long long u, v; { long a[2], b[2], c[2]; long_long w; long_long uu, vv; uu.ll = u; vv.ll = v; a[HIGH] = uu.s.high; a[LOW] = uu.s.low; b[HIGH] = vv.s.high; b[LOW] = vv.s.low; badd ((unsigned short *)a, (unsigned short *)b, (unsigned short *)c, sizeof c); w.s.high = c[HIGH]; w.s.low = c[LOW]; return w.ll; } static int badd (a, b, c, n) unsigned short *a, *b, *c; size_t n; { unsigned long acc; int i; n /= sizeof *c; acc = 0; for (i = little_end (n); is_not_msd (i, n); i = next_msd (i)) { /* Widen before adding to avoid loss of high bits. */ acc += (unsigned long) a[i] + b[i]; c[i] = acc & low16; acc = acc >> 16; } return acc; } #endif #ifdef L_anddi3 long long __anddi3 (u, v) long long u, v; { long_long w; long_long uu, vv; uu.ll = u; vv.ll = v; w.s.high = uu.s.high & vv.s.high; w.s.low = uu.s.low & vv.s.low; return w.ll; } #endif #ifdef L_iordi3 long long __iordi3 (u, v) long long u, v; { long_long w; long_long uu, vv; uu.ll = u; vv.ll = v; w.s.high = uu.s.high | vv.s.high; w.s.low = uu.s.low | vv.s.low; return w.ll; } #endif #ifdef L_xordi3 long long __xordi3 (u, v) long long u, v; { long_long w; long_long uu, vv; uu.ll = u; vv.ll = v; w.s.high = uu.s.high ^ vv.s.high; w.s.low = uu.s.low ^ vv.s.low; return w.ll; } #endif #ifdef L_one_cmpldi2 long long __one_cmpldi2 (u) long long u; { long_long w; long_long uu; uu.ll = u; w.s.high = ~uu.s.high; w.s.low = ~uu.s.low; return w.ll; } #endif #ifdef L_lshldi3 long long __lshldi3 (u, b1) long long u; long int b1; { long_long w; unsigned long carries; int bm; long_long uu; int b = b1; if (b == 0) return u; uu.ll = u; bm = (sizeof (int) * BITS_PER_UNIT) - b; if (bm <= 0) { w.s.low = 0; w.s.high = (unsigned long)uu.s.low << -bm; } else { carries = (unsigned long)uu.s.low >> bm; w.s.low = (unsigned long)uu.s.low << b; w.s.high = ((unsigned long)uu.s.high << b) | carries; } return w.ll; } #endif #ifdef L_lshrdi3 long long __lshrdi3 (u, b1) long long u; long int b1; { long_long w; unsigned long carries; int bm; long_long uu; int b = b1; if (b == 0) return u; uu.ll = u; bm = (sizeof (int) * BITS_PER_UNIT) - b; if (bm <= 0) { w.s.high = 0; w.s.low = (unsigned long)uu.s.high >> -bm; } else { carries = (unsigned long)uu.s.high << bm; w.s.high = (unsigned long)uu.s.high >> b; w.s.low = ((unsigned long)uu.s.low >> b) | carries; } return w.ll; } #endif #ifdef L_ashldi3 long long __ashldi3 (u, b1) long long u; long int b1; { long_long w; unsigned long carries; int bm; long_long uu; int b = b1; if (b == 0) return u; uu.ll = u; bm = (sizeof (int) * BITS_PER_UNIT) - b; if (bm <= 0) { w.s.low = 0; w.s.high = (unsigned long)uu.s.low << -bm; } else { carries = (unsigned long)uu.s.low >> bm; w.s.low = (unsigned long)uu.s.low << b; w.s.high = ((unsigned long)uu.s.high << b) | carries; } return w.ll; } #endif #ifdef L_ashrdi3 long long __ashrdi3 (u, b1) long long u; long int b1; { long_long w; unsigned long carries; int bm; long_long uu; int b = b1; if (b == 0) return u; uu.ll = u; bm = (sizeof (int) * BITS_PER_UNIT) - b; if (bm <= 0) { w.s.high = uu.s.high >> 31; /* just to make w.s.high 1..1 or 0..0 */ w.s.low = uu.s.high >> -bm; } else { carries = (unsigned long)uu.s.high << bm; w.s.high = uu.s.high >> b; w.s.low = ((unsigned long)uu.s.low >> b) | carries; } return w.ll; } #endif #ifdef L_subdi3 static int bsub __PROTO((unsigned short *a, unsigned short *b, unsigned short *c, size_t n)); long long __subdi3 (u, v) long long u, v; { long a[2], b[2], c[2]; long_long w; long_long uu, vv; uu.ll = u; vv.ll = v; a[HIGH] = uu.s.high; a[LOW] = uu.s.low; b[HIGH] = vv.s.high; b[LOW] = vv.s.low; bsub ((unsigned short *)a, (unsigned short *)b, (unsigned short *)c, sizeof c); w.s.high = c[HIGH]; w.s.low = c[LOW]; return w.ll; } static int bsub (a, b, c, n) unsigned short *a, *b, *c; size_t n; { signed long acc; int i; n /= sizeof *c; acc = 0; for (i = little_end (n); is_not_msd (i, n); i = next_msd (i)) { /* Widen before subtracting to avoid loss of high bits. */ acc += (long) a[i] - b[i]; c[i] = acc & low16; acc = acc >> 16; } return acc; } #endif #ifdef L_muldi3 static void bmul __PROTO((unsigned short *a, unsigned short *b, unsigned short *c, size_t m, size_t n)); long long __muldi3 (u, v) long long u, v; { long a[2], b[2], c[2][2]; long_long w; long_long uu, vv; uu.ll = u; vv.ll = v; a[HIGH] = uu.s.high; a[LOW] = uu.s.low; b[HIGH] = vv.s.high; b[LOW] = vv.s.low; bmul ((unsigned short *)a, (unsigned short *)b, (unsigned short *)c, sizeof a, sizeof b); w.s.high = c[LOW][HIGH]; w.s.low = c[LOW][LOW]; return w.ll; } static void bmul (a, b, c, m, n) unsigned short *a, *b, *c; size_t m, n; { int i, j; unsigned long acc; (void)bzero (c, m + n); m /= sizeof *a; n /= sizeof *b; for (j = little_end (n); is_not_msd (j, n); j = next_msd (j)) { unsigned short *c1 = c + j + little_end (2); acc = 0; for (i = little_end (m); is_not_msd (i, m); i = next_msd (i)) { /* Widen before arithmetic to avoid loss of high bits. */ acc += (unsigned long) a[i] * b[j] + c1[i]; c1[i] = acc & low16; acc = acc >> 16; } c1[i] = acc; } } #endif #ifdef L_divdi3 long long __divdi3 (u, v) long long u, v; { if (u < 0) if (v < 0) return (unsigned long long) -u / (unsigned long long) -v; else return - ((unsigned long long) -u / (unsigned long long) v); else if (v < 0) return - ((unsigned long long) u / (unsigned long long) -v); else return (unsigned long long) u / (unsigned long long) v; } #endif #ifdef L_moddi3 long long __moddi3 (u, v) long long u, v; { if (u < 0) if (v < 0) return - ((unsigned long long) -u % (unsigned long long) -v); else return - ((unsigned long long) -u % (unsigned long long) v); else if (v < 0) return (unsigned long long) u % (unsigned long long) -v; else return (unsigned long long) u % (unsigned long long) v; } #endif #ifdef L_udivdi3 long long __udivdi3 (u, v) long long u, v; { unsigned long a[2][2], b[2], q[2], r[2]; long_long w; long_long uu, vv; uu.ll = u; vv.ll = v; a[HIGH][HIGH] = 0; a[HIGH][LOW] = 0; a[LOW][HIGH] = uu.s.high; a[LOW][LOW] = uu.s.low; b[HIGH] = vv.s.high; b[LOW] = vv.s.low; __bdiv ((unsigned short *)a, (unsigned short *)b, (unsigned short *)q, (unsigned short *)r, sizeof a, sizeof b); w.s.high = q[HIGH]; w.s.low = q[LOW]; return w.ll; } #endif #ifdef L_umoddi3 long long __umoddi3 (u, v) long long u, v; { unsigned long a[2][2], b[2], q[2], r[2]; long_long w; long_long uu, vv; uu.ll = u; vv.ll = v; a[HIGH][HIGH] = 0; a[HIGH][LOW] = 0; a[LOW][HIGH] = uu.s.high; a[LOW][LOW] = uu.s.low; b[HIGH] = vv.s.high; b[LOW] = vv.s.low; __bdiv ((unsigned short *)a, (unsigned short *)b, (unsigned short *)q, (unsigned short *)r, sizeof a, sizeof b); w.s.high = r[HIGH]; w.s.low = r[LOW]; return w.ll; } #endif #ifdef L_negdi2 static int bneg __PROTO((unsigned short *a, unsigned short *b, size_t n)); long long __negdi2 (u) long long u; { unsigned long a[2], b[2]; long_long w; long_long uu; uu.ll = u; a[HIGH] = uu.s.high; a[LOW] = uu.s.low; bneg ((unsigned short *)a, (unsigned short *)b, sizeof b); w.s.high = b[HIGH]; w.s.low = b[LOW]; return w.ll; } static int bneg (a, b, n) unsigned short *a, *b; size_t n; { signed long acc; int i; n /= sizeof (short); acc = 0; for (i = little_end (n); is_not_msd (i, n); i = next_msd (i)) { acc -= a[i]; b[i] = acc & low16; acc = acc >> 16; } return acc; } #endif /* Divide a by b, producing quotient q and remainder r. sizeof a is m sizeof b is n sizeof q is m - n sizeof r is n The quotient must fit in m - n bytes, i.e., the most significant n digits of a must be less than b, and m must be greater than n. */ /* The name of this used to be __div_internal, but that is too long for SYSV. */ #ifdef L_bdiv static int bshift __PROTO((unsigned short *u, int k, unsigned short *w, unsigned int carry_in, int n)); void __bdiv (a, b, q, r, m, n) unsigned short *a, *b, *q, *r; size_t m, n; { void abort(void); unsigned long qhat, rhat; unsigned long acc; unsigned short *u = (unsigned short *) alloca (m); unsigned short *v = (unsigned short *) alloca (n); unsigned short *u0, *u1, *u2; unsigned short *v0; int d, qn; int i, j; m /= sizeof *a; n /= sizeof *b; qn = m - n; /* Remove leading zero digits from divisor, and the same number of digits (which must be zero) from dividend. */ while (b[big_end (n)] == 0) { r[big_end (n)] = 0; a += little_end (2); b += little_end (2); r += little_end (2); m--; n--; /* Check for zero divisor. */ if (n == 0) abort (); } /* If divisor is a single digit, do short division. */ if (n == 1) { acc = a[big_end (m)]; a += little_end (2); for (j = big_end (qn); is_not_lsd (j, qn); j = next_lsd (j)) { acc = (acc << 16) | a[j]; q[j] = acc / *b; acc = acc % *b; } *r = acc; return; } /* No such luck, must do long division. Shift divisor and dividend left until the high bit of the divisor is 1. */ for (d = 0; d < 16; d++) if (b[big_end (n)] & (1 << (16 - 1 - d))) break; bshift (a, d, u, 0, m); bshift (b, d, v, 0, n); /* Get pointers to the high dividend and divisor digits. */ u0 = u + big_end (m) - big_end (qn); u1 = next_lsd (u0); u2 = next_lsd (u1); u += little_end (2); v0 = v + big_end (n); /* Main loop: find a quotient digit, multiply it by the divisor, and subtract that from the dividend, shifted over the right amount. */ for (j = big_end (qn); is_not_lsd (j, qn); j = next_lsd (j)) { /* Quotient digit initial guess: high 2 dividend digits over high divisor digit. */ if (u0[j] == *v0) { qhat = B - 1; rhat = (unsigned long) *v0 + u1[j]; } else { unsigned long numerator = ((unsigned long) u0[j] << 16) | u1[j]; qhat = numerator / *v0; rhat = numerator % *v0; } /* Now get the quotient right for high 3 dividend digits over high 2 divisor digits. */ while (rhat < B && qhat * *next_lsd (v0) > ((rhat << 16) | u2[j])) { qhat -= 1; rhat += *v0; } /* Multiply quotient by divisor, subtract from dividend. */ acc = 0; for (i = little_end (n); is_not_msd (i, n); i = next_msd (i)) { acc += (unsigned long) (u + j)[i] - v[i] * qhat; (u + j)[i] = acc & low16; if (acc < B) acc = 0; else acc = (acc >> 16) | -B; } q[j] = qhat; /* Quotient may have been too high by 1. If dividend went negative, decrement the quotient by 1 and add the divisor back. */ if ((signed long) (acc + u0[j]) < 0) { q[j] -= 1; acc = 0; for (i = little_end (n); is_not_msd (i, n); i = next_msd (i)) { acc += (unsigned long) (u + j)[i] + v[i]; (u + j)[i] = acc & low16; acc = acc >> 16; } } } /* Now the remainder is what's left of the dividend, shifted right by the amount of the normalizing left shift at the top. */ r[big_end (n)] = bshift (u + 1 + little_end (j - 1), 16 - d, r + little_end (2), u[little_end (m - 1)] >> d, n - 1); } /* Left shift U by K giving W; fill the introduced low-order bits with CARRY_IN. Length of U and W is N. Return carry out. K must be in 0 .. 16. */ static int bshift (u, k, w, carry_in, n) unsigned short *u, *w; unsigned int carry_in; int k, n; { unsigned long acc; int i; if (k == 0) { bcopy (u, w, n * sizeof *u); return 0; } acc = carry_in; for (i = little_end (n); is_not_msd (i, n); i = next_msd (i)) { acc |= (unsigned long) u[i] << k; w[i] = acc & low16; acc = acc >> 16; } return acc; } #endif #ifdef L_cmpdi2 SItype __cmpdi2 (a, b) long long a, b; { long_long au, bu; au.ll = a, bu.ll = b; if (au.s.high < bu.s.high) return 0; else if (au.s.high > bu.s.high) return 2; if ((unsigned) au.s.low < (unsigned) bu.s.low) return 0; else if ((unsigned) au.s.low > (unsigned) bu.s.low) return 2; return 1; } #endif #ifdef L_ucmpdi2 SItype __ucmpdi2 (a, b) long long a, b; { long_long au, bu; au.ll = a, bu.ll = b; if ((unsigned) au.s.high < (unsigned) bu.s.high) return 0; else if ((unsigned) au.s.high > (unsigned) bu.s.high) return 2; if ((unsigned) au.s.low < (unsigned) bu.s.low) return 0; else if ((unsigned) au.s.low > (unsigned) bu.s.low) return 2; return 1; } #endif #ifdef L_fixunsdfdi #define HIGH_WORD_COEFF (((long long) 1) << BITS_PER_WORD) long long __fixunsdfdi (a) double a; { double b; unsigned long long v; if (a < 0) return 0; /* Compute high word of result, as a flonum. */ b = (a / HIGH_WORD_COEFF); /* Convert that to fixed (but not to long long!), and shift it into the high word. */ v = (unsigned long int) b; v <<= BITS_PER_WORD; /* Remove high part from the double, leaving the low part as flonum. */ a -= (double)v; /* Convert that to fixed (but not to long long!) and add it in. Sometimes A comes out negative. This is significant, since A has more bits than a long int does. */ if (a < 0) v -= (unsigned long int) (- a); else v += (unsigned long int) a; return v; } #endif #ifdef L_fixdfdi long long __fixdfdi (a) double a; { long long __fixunsdfdi (double a); if (a < 0) return - __fixunsdfdi (-a); return __fixunsdfdi (a); } #endif #ifdef L_floatdidf #define HIGH_HALFWORD_COEFF (((long long) 1) << (BITS_PER_WORD / 2)) #define HIGH_WORD_COEFF (((long long) 1) << BITS_PER_WORD) double __floatdidf (u) long long u; { double d; int negate = 0; if (u < 0) /* was : if (d < 0) */ u = -u, negate = 1; d = (unsigned int) (u >> BITS_PER_WORD); d *= HIGH_HALFWORD_COEFF; d *= HIGH_HALFWORD_COEFF; d += (unsigned int) (u & (HIGH_WORD_COEFF - 1)); return (negate ? -d : d); } #endif #ifdef L_varargs #ifdef sparc asm (".global ___builtin_saveregs"); asm ("___builtin_saveregs:"); asm ("st %i0,[%fp+68]"); asm ("st %i1,[%fp+72]"); asm ("st %i2,[%fp+76]"); asm ("st %i3,[%fp+80]"); asm ("st %i4,[%fp+84]"); asm ("retl"); asm ("st %i5,[%fp+88]"); #else /* not sparc */ #if defined(MIPSEL) | defined(R3000) | defined(R2000) | defined(mips) asm (" .ent __builtin_saveregs"); asm (" .globl __builtin_saveregs"); asm ("__builtin_saveregs:"); asm (" sw $4,0($30)"); asm (" sw $5,4($30)"); asm (" sw $6,8($30)"); asm (" sw $7,12($30)"); asm (" j $31"); asm (" .end __builtin_saveregs"); #else /* not mips */ __builtin_saveregs () { abort (); } #endif /* not mips */ #endif /* not sparc */ #endif /* stuff for gcc-2.0, note that you cannot compile the corresponding C code from libgcc1.c for these functions with gcc-2.0! This stuff should eventually be hand optimized as we have done with the other stuff, */ #if 0 /* these were the decls used to compile the asm below */ #ifndef SItype #define SItype long int #endif #ifndef FLOAT_VALUE_TYPE #define FLOAT_VALUE_TYPE long int #endif #ifndef INTIFY #define INTIFY(FLOATVAL) (intify.f = (FLOATVAL), intify.i) #endif #ifndef FLOATIFY #define FLOATIFY(INTVAL) ((INTVAL).f) #endif #ifndef FLOAT_ARG_TYPE #define FLOAT_ARG_TYPE union flt_or_int #endif union flt_or_value { FLOAT_VALUE_TYPE i; float f; }; union flt_or_int { long int i; float f; }; #endif #if 0 /* NOTE: all these come from elsewhere now */ #ifdef L_lshrsi3 #if 0 SItype __lshrsi3 (a, b) unsigned SItype a, b; { return a >> b; } #endif asm(" .text .even .globl ___lshrsi3 ___lshrsi3: movel sp@(4),d0 movel sp@(8),d1 lsrl d1,d0 rts "); #endif #ifdef L_lshlsi3 #if 0 SItype __lshlsi3 (a, b) unsigned SItype a, b; { return a << b; } #endif asm(" .text .even .globl ___lshlsi3 ___lshlsi3: movel sp@(4),d0 movel sp@(8),d1 lsll d1,d0 rts "); #endif #ifdef L_ashrsi3 #if 0 SItype __ashrsi3 (a, b) SItype a, b; { return a >> b; } #endif asm(" .text .even .globl ___ashrsi3 ___ashrsi3: movel sp@(4),d0 movel sp@(8),d1 asrl d1,d0 rts "); #endif #ifdef L_ashlsi3 #if 0 SItype __ashlsi3 (a, b) SItype a, b; { return a << b; } #endif asm(" .text .even .globl ___ashlsi3 ___ashlsi3: movel sp@(4),d0 movel sp@(8),d1 asll d1,d0 rts "); #endif #ifdef L_eqdf2 #if 0 SItype __eqdf2 (a, b) double a, b; { /* Value == 0 iff a == b. */ return !(a == b); } #endif asm(" .text .even .globl ___eqdf2 ___eqdf2: moveml #0x3000,sp@- movel sp@(12),d1 movel sp@(16),d2 movel sp@(24),sp@- movel sp@(24),sp@- movel d2,sp@- movel d1,sp@- jbsr ___cmpdf2 addw #16,sp tstl d0 sne d0 moveq #1,d3 andl d3,d0 moveml sp@+,#0xc rts "); #endif #ifdef L_nedf2 #if 0 SItype __nedf2 (a, b) double a, b; { /* Value != 0 iff a != b. */ return a != b; } #endif asm(" .text .even .globl ___nedf2 ___nedf2: moveml #0x3000,sp@- movel sp@(12),d1 movel sp@(16),d2 movel sp@(24),sp@- movel sp@(24),sp@- movel d2,sp@- movel d1,sp@- jbsr ___cmpdf2 addw #16,sp tstl d0 sne d0 moveq #1,d3 andl d3,d0 moveml sp@+,#0xc rts "); #endif #ifdef L_gtdf2 #if 0 SItype __gtdf2 (a, b) double a, b; { /* Value > 0 iff a > b. */ return a > b; } #endif asm(" .text .even .globl ___gtdf2 ___gtdf2: moveml #0x3000,sp@- movel sp@(12),d1 movel sp@(16),d2 movel sp@(24),sp@- movel sp@(24),sp@- movel d2,sp@- movel d1,sp@- jbsr ___cmpdf2 addw #16,sp tstl d0 sgt d0 moveq #1,d3 andl d3,d0 moveml sp@+,#0xc rts "); #endif #ifdef L_gedf2 #if 0 SItype __gedf2 (a, b) double a, b; { /* Value >= 0 iff a >= b. */ return (a >= b) - 1; } #endif asm(" .text .even .globl ___gedf2 ___gedf2: moveml #0x3000,sp@- movel sp@(12),d1 movel sp@(16),d2 movel sp@(24),sp@- movel sp@(24),sp@- movel d2,sp@- movel d1,sp@- jbsr ___cmpdf2 addw #16,sp tstl d0 sge d0 moveq #1,d3 andl d3,d0 subql #1,d0 moveml sp@+,#0xc rts "); #endif #ifdef L_ltdf2 #if 0 SItype __ltdf2 (a, b) double a, b; { /* Value < 0 iff a < b. */ return -(a < b); } #endif asm(" .text .even .globl ___ltdf2 ___ltdf2: moveml #0x3000,sp@- movel sp@(12),d1 movel sp@(16),d2 movel sp@(24),sp@- movel sp@(24),sp@- movel d2,sp@- movel d1,sp@- jbsr ___cmpdf2 addw #16,sp tstl d0 slt d0 moveq #1,d3 andl d3,d0 negl d0 moveml sp@+,#0xc rts "); #endif #ifdef L_ledf2 #if 0 SItype __ledf2 (a, b) double a, b; { /* Value <= 0 iff a <= b. */ return 1 - (a <= b); } #endif asm(" .text .even .globl ___ledf2 ___ledf2: movel d2,sp@- movel sp@(8),d0 movel sp@(12),d1 moveq #1,d2 movel sp@(20),sp@- movel sp@(20),sp@- movel d1,sp@- movel d0,sp@- jbsr ___cmpdf2 addw #16,sp tstl d0 jgt L11 moveq #0,d2 L11: movel d2,d0 movel sp@+,d2 rts "); #endif #ifdef L_fixsfsi #if 0 SItype __fixsfsi (a) FLOAT_ARG_TYPE a; { union flt_or_value intify; #define perform_fixsfsi(a) return (SItype) a perform_fixsfsi (FLOATIFY (a)); } #endif asm(" .text .even .globl ___fixsfsi ___fixsfsi: movel sp@(4),sp@- jbsr ___extendsfdf2 addqw #4,sp movel d1,sp@- movel d0,sp@- jbsr ___fixdfsi addqw #8,sp rts "); #endif #ifdef L_floatsisf #if 0 FLOAT_VALUE_TYPE __floatsisf (a) SItype a; { union flt_or_value intify; #define perform_floatsisf(a) return INTIFY ((float) a) perform_floatsisf (a); } #endif asm(" .text .even .globl ___floatsisf ___floatsisf: movel sp@(4),sp@- jbsr ___floatsidf addqw #4,sp movel d1,sp@- movel d0,sp@- jbsr ___truncdfsf2 addqw #8,sp rts "); #endif #ifdef L_eqsf2 #if 0 SItype __eqsf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value == 0 iff a == b. */ #define perform_eqsf2(a, b) return !(a == b) perform_eqsf2 (FLOATIFY (a), FLOATIFY (b)); } #endif asm(" .text .even .globl ___eqsf2 ___eqsf2: movel d2,sp@- movel sp@(8),d1 movel sp@(12),sp@- movel d1,sp@- jbsr ___cmpsf2 addqw #8,sp tstl d0 sne d0 moveq #1,d2 andl d2,d0 movel sp@+,d2 rts "); #endif #ifdef L_nesf2 #if 0 SItype __nesf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value != 0 iff a != b. */ #define perform_nesf2(a, b) return a != b perform_nesf2 (FLOATIFY (a), FLOATIFY (b)); } #endif asm(" .text .even .globl ___nesf2 ___nesf2: movel d2,sp@- movel sp@(8),d1 movel sp@(12),sp@- movel d1,sp@- jbsr ___cmpsf2 addqw #8,sp tstl d0 sne d0 moveq #1,d2 andl d2,d0 movel sp@+,d2 rts "); #endif #ifdef L_gtsf2 #if 0 SItype __gtsf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value > 0 iff a > b. */ #define perform_gtsf2(a, b) return a > b perform_gtsf2 (FLOATIFY (a), FLOATIFY (b)); } #endif asm(" .text .even .globl ___gtsf2 ___gtsf2: movel d2,sp@- movel sp@(8),d1 movel sp@(12),sp@- movel d1,sp@- jbsr ___cmpsf2 addqw #8,sp tstl d0 sgt d0 moveq #1,d2 andl d2,d0 movel sp@+,d2 rts "); #endif #ifdef L_gesf2 #if 0 SItype __gesf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value >= 0 iff a >= b. */ #define perform_gesf2(a, b) return (a >= b) - 1 perform_gesf2 (FLOATIFY (a), FLOATIFY (b)); } #endif asm(" .text .even .globl ___gesf2 ___gesf2: movel d2,sp@- movel sp@(8),d1 movel sp@(12),sp@- movel d1,sp@- jbsr ___cmpsf2 addqw #8,sp tstl d0 sge d0 moveq #1,d2 andl d2,d0 subql #1,d0 movel sp@+,d2 rts "); #endif #ifdef L_ltsf2 #if 0 SItype __ltsf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value < 0 iff a < b. */ #define perform_ltsf2(a, b) return -(a < b) perform_ltsf2 (FLOATIFY (a), FLOATIFY (b)); } #endif asm(" .text .even .globl ___ltsf2 ___ltsf2: movel d2,sp@- movel sp@(8),d1 movel sp@(12),sp@- movel d1,sp@- jbsr ___cmpsf2 addqw #8,sp tstl d0 slt d0 moveq #1,d2 andl d2,d0 negl d0 movel sp@+,d2 rts "); #endif #ifdef L_lesf2 #if 0 SItype __lesf2 (a, b) FLOAT_ARG_TYPE a, b; { union flt_or_int intify; /* Value <= 0 iff a <= b. */ #define perform_lesf2(a, b) return 1 - (a <= b); /* note bug fix from libgcc1.c */ perform_lesf2 (FLOATIFY (a), FLOATIFY (b)); } #endif asm(" .text .even .globl ___lesf2 ___lesf2: movel d2,sp@- movel sp@(8),d0 moveq #1,d2 movel sp@(12),sp@- movel d0,sp@- jbsr ___cmpsf2 addqw #8,sp tstl d0 jgt L20 moveq #0,d2 L20: movel d2,d0 movel sp@+,d2 rts "); #endif #endif /* # if 0 to ensure that the above functions are not compiled */ #ifdef L_fxussfsi #include unsigned SItype __fixunssfsi (float a) { if (a >= ((float) LONG_MAX)+1) return (SItype) (a + LONG_MIN) - LONG_MIN; return (SItype) a; } #endif