aboutsummaryrefslogtreecommitdiff
path: root/gcc-1.40/gnulib2.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-1.40/gnulib2.c')
-rw-r--r--gcc-1.40/gnulib2.c922
1 files changed, 922 insertions, 0 deletions
diff --git a/gcc-1.40/gnulib2.c b/gcc-1.40/gnulib2.c
new file mode 100644
index 0000000..b31b8f6
--- /dev/null
+++ b/gcc-1.40/gnulib2.c
@@ -0,0 +1,922 @@
+/* More subroutines needed by GCC output code on some machines. */
+/* Compile this one with gcc. */
+
+#include "config.h"
+#include <stddef.h>
+
+#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. */
+
+static int badd ();
+static int bsub ();
+static void bmul ();
+static int bneg ();
+static int bshift ();
+
+#ifdef L_adddi3
+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 (a, b, 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 long 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 long 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 long 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 long 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
+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 (a, b, 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
+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 (a, b, 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;
+
+ 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 (a, b, q, 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 (a, b, q, r, sizeof a, sizeof b);
+
+ w.s.high = r[HIGH];
+ w.s.low = r[LOW];
+ return w.ll;
+}
+#endif
+
+#ifdef L_negdi2
+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 (a, 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
+void
+__bdiv (a, b, q, r, m, n)
+ unsigned short *a, *b, *q, *r;
+ size_t m, n;
+{
+ 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, 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)
+ 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 i860
+ asm (" .text");
+ asm (" .align 4");
+
+ asm ("___builtin_saveregs::");
+ asm (" mov sp,r30");
+ asm (" andnot 0x0f,sp,sp");
+ asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */
+
+ asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */
+ asm (" st.l r17, 4(sp)"); /* int fixed[12] */
+ asm (" st.l r18, 8(sp)");
+ asm (" st.l r19,12(sp)");
+ asm (" st.l r20,16(sp)");
+ asm (" st.l r21,20(sp)");
+ asm (" st.l r22,24(sp)");
+ asm (" st.l r23,28(sp)");
+ asm (" st.l r24,32(sp)");
+ asm (" st.l r25,36(sp)");
+ asm (" st.l r26,40(sp)");
+ asm (" st.l r27,44(sp)");
+
+ asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */
+ asm (" fst.q f12,64(sp)"); /* int floating[8] */
+
+ asm (" st.l r28,80(sp)"); /* pointer to more args */
+ asm (" st.l r0, 84(sp)"); /* nfixed */
+ asm (" st.l r0, 88(sp)"); /* nfloating */
+ asm (" st.l r0, 92(sp)"); /* pad */
+
+ asm (" mov sp,r16");
+ asm (" bri r1");
+ asm (" mov r30,sp");
+ /* recover stack and pass address to start
+ of data. */
+#endif
+#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 (" .text");
+ 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