-2004-03-31 Richard Henderson <rth@redhat.com>
+2006-03-31 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/lib1funcs.asm: Rename abi_entry/abi_return macros
+ to leaf_entry/leaf_return. Change leaf_entry to add 16 bytes to
+ the frame size. Update to use the new macros.
+ * config/xtensa/ieee754-sf.S: Use new leaf_entry/leaf_return macros.
+ * config/xtensa/ieee754-df.S: Likewise.
+
+2006-03-31 Richard Henderson <rth@redhat.com>
* tree-cfg.c (make_ctrl_stmt_edges, make_exit_edges): Merge into...
(make_edges): ... here. Control fallthru creation with a local
.global __negdf2
.type __negdf2, @function
__negdf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a4, 0x80000000
xor xh, xh, a4
- abi_return
+ leaf_return
#endif /* L_negdf2 */
slli a7, xh, 12
or a7, a7, xl
beqz a7, .Ladd_ynan_or_inf
-1: abi_return
+1: leaf_return
.Ladd_ynan_or_inf:
/* Return y. */
mov xh, yh
mov xl, yl
- abi_return
+ leaf_return
.Ladd_opposite_signs:
/* Operand signs differ. Do a subtraction. */
.global __adddf3
.type __adddf3, @function
__adddf3:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7ff00000
/* Check if the two operands have the same sign. */
add xh, xh, yh
bgeu xl, yl, 1f
addi xh, xh, 1
-1: abi_return
+1: leaf_return
.Ladd_bigshifty:
/* Exponent difference > 64 -- just return the bigger value. */
/* Check if the leftover fraction is exactly 1/2. */
slli a9, a9, 1
beqz a9, .Ladd_exactlyhalf
-1: abi_return
+1: leaf_return
.Ladd_bigshiftx:
/* Mostly the same thing as "bigshifty".... */
.Ladd_returny:
mov xh, yh
mov xl, yl
- abi_return
+ leaf_return
.Ladd_carry:
/* The addition has overflowed into the exponent field, so the
addi xl, xl, 1
beqz xl, .Ladd_roundcarry
beqz a9, .Ladd_exactlyhalf
-1: abi_return
+1: leaf_return
.Ladd_infinity:
/* Clear the mantissa. */
/* The sign bit may have been lost in a carry-out. Put it back. */
slli a8, a8, 1
or xh, xh, a8
- abi_return
+ leaf_return
.Ladd_exactlyhalf:
/* Round down to the nearest even value. */
srli xl, xl, 1
slli xl, xl, 1
- abi_return
+ leaf_return
.Ladd_roundcarry:
/* xl is always zero when the rounding increment overflows, so
there's no need to round it to an even value. */
addi xh, xh, 1
/* Overflow to the exponent is OK. */
- abi_return
+ leaf_return
/* Subtraction */
/* Both x and y are either NaN or Inf, so the result is NaN. */
movi a4, 0x80000 /* make it a quiet NaN */
or xh, xh, a4
-1: abi_return
+1: leaf_return
.Lsub_ynan_or_inf:
/* Negate y and return it. */
slli a7, a6, 11
xor xh, yh, a7
mov xl, yl
- abi_return
+ leaf_return
.Lsub_opposite_signs:
/* Operand signs differ. Do an addition. */
.global __subdf3
.type __subdf3, @function
__subdf3:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7ff00000
/* Check if the two operands have the same sign. */
/* The operands are equal. Return 0.0. */
movi xh, 0
movi xl, 0
-1: abi_return
+1: leaf_return
.Lsub_yexpzero:
/* y is a subnormal value. Replace its sign/exponent with zero,
/* Check if the leftover fraction is exactly 1/2. */
slli a9, a9, 1
beqz a9, .Lsub_exactlyhalf
-1: abi_return
+1: leaf_return
.Lsub_xexpzero:
/* Same as "yexpzero". */
slli a7, a6, 11
xor xh, yh, a7
mov xl, yl
- abi_return
+ leaf_return
.Lsub_borrow:
/* The subtraction has underflowed into the exponent field, so the
/* Round down to the nearest even value. */
srli xl, xl, 1
slli xl, xl, 1
- abi_return
+ leaf_return
.Lsub_roundcarry:
/* xl is always zero when the rounding increment overflows, so
there's no need to round it to an even value. */
addi xh, xh, 1
/* Overflow to the exponent is OK. */
- abi_return
+ leaf_return
.Lsub_xhzero:
/* When normalizing the result, all the mantissa bits in the high
.global __muldf3
.type __muldf3, @function
__muldf3:
- abi_entry sp, 48
+ leaf_entry sp, 32
#if __XTENSA_CALL0_ABI__
addi sp, sp, -32
s32i a12, sp, 16
l32i a15, sp, 28
addi sp, sp, 32
#endif
- abi_return
+ leaf_return
.Lmul_exactlyhalf:
/* Round down to the nearest even value. */
movi a4, 0x80000 /* make it a quiet NaN */
or xh, xh, a4
1: movi xl, 0
- abi_return
+ leaf_return
.Ldiv_xexpzero:
/* Clear the sign bit of x. */
srli xh, a7, 31
slli xh, xh, 31
movi xl, 0
- abi_return
+ leaf_return
.Ldiv_xnan_or_inf:
/* Set the sign bit of the result. */
bnall yh, a6, 1f
movi a4, 0x80000 /* make it a quiet NaN */
or xh, xh, a4
-1: abi_return
+1: leaf_return
.Ldiv_ynan_or_inf:
/* If y is Infinity, return zero. */
/* y is NaN; return it. */
mov xh, yh
mov xl, yl
- abi_return
+ leaf_return
.Ldiv_highequal1:
bltu xl, yl, 2f
.global __divdf3
.type __divdf3, @function
__divdf3:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7ff00000
/* Get the sign of the result. */
srli a7, a7, 31
slli a7, a7, 31
or xh, xh, a7
- abi_return
+ leaf_return
.Ldiv_highequal2:
bgeu xl, yl, 2b
srli xh, a7, 31
slli xh, xh, 31
movi xl, 0
- abi_return
+ leaf_return
#endif /* L_divdf3 */
.set __nedf2, __eqdf2
.type __eqdf2, @function
__eqdf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
bne xl, yl, 2f
bne xh, yh, 4f
/* Equal. */
movi a2, 0
- abi_return
+ leaf_return
/* Not equal. */
2: movi a2, 1
- abi_return
+ leaf_return
/* Check if the mantissas are nonzero. */
3: slli a7, xh, 12
5: movi a2, 0
movi a3, 1
movnez a2, a3, a7
- abi_return
+ leaf_return
/* Greater Than */
.global __gtdf2
.type __gtdf2, @function
__gtdf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7ff00000
ball xh, a6, 2f
1: bnall yh, a6, .Lle_cmp
or a7, a7, yl
beqz a7, .Lle_cmp
movi a2, 0
- abi_return
+ leaf_return
/* Check if x is a NaN. */
2: slli a7, xh, 12
or a7, a7, xl
beqz a7, 1b
movi a2, 0
- abi_return
+ leaf_return
/* Less Than or Equal */
.global __ledf2
.type __ledf2, @function
__ledf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7ff00000
ball xh, a6, 2f
1: bnall yh, a6, .Lle_cmp
or a7, a7, yl
beqz a7, .Lle_cmp
movi a2, 1
- abi_return
+ leaf_return
/* Check if x is a NaN. */
2: slli a7, xh, 12
or a7, a7, xl
beqz a7, 1b
movi a2, 1
- abi_return
+ leaf_return
.Lle_cmp:
/* Check if x and y have different signs. */
bne xh, yh, 5f
bltu yl, xl, 5f
4: movi a2, 0
- abi_return
+ leaf_return
.Lle_xneg:
/* Check if y <= x. */
bne yh, xh, 5f
bgeu xl, yl, 4b
5: movi a2, 1
- abi_return
+ leaf_return
.Lle_diff_signs:
bltz xh, 4b
movi a2, 1
movi a3, 0
moveqz a2, a3, a7
- abi_return
+ leaf_return
/* Greater Than or Equal */
.global __gedf2
.type __gedf2, @function
__gedf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7ff00000
ball xh, a6, 2f
1: bnall yh, a6, .Llt_cmp
or a7, a7, yl
beqz a7, .Llt_cmp
movi a2, -1
- abi_return
+ leaf_return
/* Check if x is a NaN. */
2: slli a7, xh, 12
or a7, a7, xl
beqz a7, 1b
movi a2, -1
- abi_return
+ leaf_return
/* Less Than */
.global __ltdf2
.type __ltdf2, @function
__ltdf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7ff00000
ball xh, a6, 2f
1: bnall yh, a6, .Llt_cmp
or a7, a7, yl
beqz a7, .Llt_cmp
movi a2, 0
- abi_return
+ leaf_return
/* Check if x is a NaN. */
2: slli a7, xh, 12
or a7, a7, xl
beqz a7, 1b
movi a2, 0
- abi_return
+ leaf_return
.Llt_cmp:
/* Check if x and y have different signs. */
bne xh, yh, 5f
bgeu xl, yl, 5f
4: movi a2, -1
- abi_return
+ leaf_return
.Llt_xneg:
/* Check if y < x. */
bne yh, xh, 5f
bltu yl, xl, 4b
5: movi a2, 0
- abi_return
+ leaf_return
.Llt_diff_signs:
bgez xh, 5b
movi a2, 0
movi a3, -1
movnez a2, a3, a7
- abi_return
+ leaf_return
/* Unordered */
.global __unorddf2
.type __unorddf2, @function
__unorddf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7ff00000
ball xh, a6, 3f
1: ball yh, a6, 4f
2: movi a2, 0
- abi_return
+ leaf_return
3: slli a7, xh, 12
or a7, a7, xl
beqz a7, 1b
movi a2, 1
- abi_return
+ leaf_return
4: slli a7, yh, 12
or a7, a7, yl
beqz a7, 2b
movi a2, 1
- abi_return
+ leaf_return
#endif /* L_cmpdf2 */
.global __fixdfsi
.type __fixdfsi, @function
__fixdfsi:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for NaN and Infinity. */
movi a6, 0x7ff00000
/* Negate the result if sign != 0. */
neg a2, a5
movgez a2, a5, a7
- abi_return
+ leaf_return
.Lfixdfsi_nan_or_inf:
/* Handle Infinity and NaN. */
addi a5, a4, -1 /* 0x7fffffff */
movgez a4, a5, xh
mov a2, a4
- abi_return
+ leaf_return
.Lfixdfsi_zero:
movi a2, 0
- abi_return
+ leaf_return
#endif /* L_fixdfsi */
.global __fixdfdi
.type __fixdfdi, @function
__fixdfdi:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for NaN and Infinity. */
movi a6, 0x7ff00000
neg xh, xh
beqz xl, 1f
addi xh, xh, -1
-1: abi_return
+1: leaf_return
.Lfixdfdi_smallshift:
src xl, xh, xl
bgez xh, 1f
mov xh, a7
movi xl, 0
- abi_return
+ leaf_return
1: addi xh, a7, -1 /* 0x7fffffff */
movi xl, -1
- abi_return
+ leaf_return
.Lfixdfdi_zero:
movi xh, 0
movi xl, 0
- abi_return
+ leaf_return
#endif /* L_fixdfdi */
.global __fixunsdfsi
.type __fixunsdfsi, @function
__fixunsdfsi:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for NaN and Infinity. */
movi a6, 0x7ff00000
/* Negate the result if sign != 0. */
neg a2, a5
movgez a2, a5, a7
- abi_return
+ leaf_return
.Lfixunsdfsi_nan_or_inf:
/* Handle Infinity and NaN. */
/* Translate NaN to 0xffffffff. */
movi a2, -1
- abi_return
+ leaf_return
.Lfixunsdfsi_maxint:
slli a4, a6, 11 /* 0x80000000 */
movi a5, -1 /* 0xffffffff */
movgez a4, a5, xh
mov a2, a4
- abi_return
+ leaf_return
.Lfixunsdfsi_zero:
movi a2, 0
- abi_return
+ leaf_return
.Lfixunsdfsi_bigexp:
/* Handle unsigned maximum exponent case. */
bltz xh, 1f
mov a2, a5 /* no shift needed */
- abi_return
+ leaf_return
/* Return 0x80000000 if negative. */
1: slli a2, a6, 11
- abi_return
+ leaf_return
#endif /* L_fixunsdfsi */
.global __fixunsdfdi
.type __fixunsdfdi, @function
__fixunsdfdi:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for NaN and Infinity. */
movi a6, 0x7ff00000
neg xh, xh
beqz xl, 1f
addi xh, xh, -1
-1: abi_return
+1: leaf_return
.Lfixunsdfdi_smallshift:
src xl, xh, xl
/* Translate NaN to 0xffffffff.... */
1: movi xh, -1
movi xl, -1
- abi_return
+ leaf_return
.Lfixunsdfdi_maxint:
bgez xh, 1b
2: slli xh, a6, 11 /* 0x80000000 */
movi xl, 0
- abi_return
+ leaf_return
.Lfixunsdfdi_zero:
movi xh, 0
movi xl, 0
- abi_return
+ leaf_return
.Lfixunsdfdi_bigexp:
/* Handle unsigned maximum exponent case. */
bltz a7, 2b
- abi_return /* no shift needed */
+ leaf_return /* no shift needed */
#endif /* L_fixunsdfdi */
.global __floatunsidf
.type __floatunsidf, @function
__floatunsidf:
- abi_entry sp, 32
+ leaf_entry sp, 16
beqz a2, .Lfloatsidf_return_zero
/* Set the sign to zero and jump to the floatsidf code. */
.global __floatsidf
.type __floatsidf, @function
__floatsidf:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for zero. */
beqz a2, .Lfloatsidf_return_zero
/* Add the sign and return. */
slli a7, a7, 31
or xh, xh, a7
- abi_return
+ leaf_return
.Lfloatsidf_return_zero:
movi a3, 0
- abi_return
+ leaf_return
#endif /* L_floatsidf */
.global __floatundidf
.type __floatundidf, @function
__floatundidf:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for zero. */
or a4, xh, xl
.global __floatdidf
.type __floatdidf, @function
__floatdidf:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for zero. */
or a4, xh, xl
/* Check if the leftover fraction is exactly 1/2. */
slli a6, a6, 1
beqz a6, .Lfloatdidf_exactlyhalf
-2: abi_return
+2: leaf_return
.Lfloatdidf_bigshift:
/* xh is zero. Normalize with first 1 bit of xl in the msb of xh. */
/* Round down to the nearest even value. */
srli xl, xl, 1
slli xl, xl, 1
- abi_return
+ leaf_return
.Lfloatdidf_roundcarry:
/* xl is always zero when the rounding increment overflows, so
there's no need to round it to an even value. */
addi xh, xh, 1
/* Overflow to the exponent is OK. */
- abi_return
+ leaf_return
#endif /* L_floatdidf */
.global __truncdfsf2
.type __truncdfsf2, @function
__truncdfsf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Adjust the exponent bias. */
movi a4, (0x3ff - 0x7f) << 20
/* Check if the leftover fraction is exactly 1/2. */
slli a4, a4, 1
beqz a4, .Ltrunc_exactlyhalf
-1: abi_return
+1: leaf_return
.Ltrunc_exactlyhalf:
/* Round down to the nearest even value. */
srli a2, a2, 1
slli a2, a2, 1
- abi_return
+ leaf_return
.Ltrunc_overflow:
/* Check if exponent == 0x7ff. */
extui a6, xh, 31, 1
ssai 1
src a2, a6, a4
- abi_return
+ leaf_return
.Ltrunc_underflow:
/* Find shift count for a subnormal. Flush to zero if >= 32. */
/* Return +/- zero. */
1: extui a2, xh, 31, 1
slli a2, a2, 31
- abi_return
+ leaf_return
#endif /* L_truncdfsf2 */
.global __extendsfdf2
.type __extendsfdf2, @function
__extendsfdf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Save the sign bit and then shift it off. */
extui a5, a2, 31, 1
/* Add the sign bit. */
or xh, a4, a5
- abi_return
+ leaf_return
.Lextend_nan_or_inf:
movi a4, 0x7ff00000
/* Add the sign and return. */
1: or xh, a4, a5
movi xl, 0
- abi_return
+ leaf_return
.Lextend_expzero:
beqz a4, 1b
/* Add the sign and return. */
or xh, a4, a5
- abi_return
+ leaf_return
#endif /* L_extendsfdf2 */
.global __negsf2
.type __negsf2, @function
__negsf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a4, 0x80000000
xor a2, a2, a4
- abi_return
+ leaf_return
#endif /* L_negsf2 */
/* If x is a NaN, return it. Otherwise, return y. */
slli a7, a2, 9
beqz a7, .Ladd_ynan_or_inf
-1: abi_return
+1: leaf_return
.Ladd_ynan_or_inf:
/* Return y. */
mov a2, a3
- abi_return
+ leaf_return
.Ladd_opposite_signs:
/* Operand signs differ. Do a subtraction. */
.global __addsf3
.type __addsf3, @function
__addsf3:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7f800000
/* Check if the two operands have the same sign. */
a carry into the exponent field will not work because it
assumes there is an implicit "1.0" that needs to be added. */
add a2, a2, a3
-1: abi_return
+1: leaf_return
.Ladd_xexpzero:
/* Same as "yexpzero" except skip handling the case when both
/* Check if the leftover fraction is exactly 1/2. */
slli a9, a9, 1
beqz a9, .Ladd_exactlyhalf
-1: abi_return
+1: leaf_return
.Ladd_returny:
mov a2, a3
- abi_return
+ leaf_return
.Ladd_carry:
/* The addition has overflowed into the exponent field, so the
bbci.l a10, 0, 1f
addi a2, a2, 1
beqz a9, .Ladd_exactlyhalf
-1: abi_return
+1: leaf_return
.Ladd_infinity:
/* Clear the mantissa. */
/* The sign bit may have been lost in a carry-out. Put it back. */
slli a8, a8, 1
or a2, a2, a8
- abi_return
+ leaf_return
.Ladd_exactlyhalf:
/* Round down to the nearest even value. */
srli a2, a2, 1
slli a2, a2, 1
- abi_return
+ leaf_return
/* Subtraction */
/* Both x and y are either NaN or Inf, so the result is NaN. */
movi a4, 0x400000 /* make it a quiet NaN */
or a2, a2, a4
-1: abi_return
+1: leaf_return
.Lsub_ynan_or_inf:
/* Negate y and return it. */
slli a7, a6, 8
xor a2, a3, a7
- abi_return
+ leaf_return
.Lsub_opposite_signs:
/* Operand signs differ. Do an addition. */
.global __subsf3
.type __subsf3, @function
__subsf3:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7f800000
/* Check if the two operands have the same sign. */
/* Negate and return y. */
slli a7, a6, 8
xor a2, a3, a7
-1: abi_return
+1: leaf_return
.Lsub_xsmaller:
/* Same thing as the "ysmaller" code, but with x and y swapped and
/* Check if the leftover fraction is exactly 1/2. */
slli a9, a9, 1
beqz a9, .Lsub_exactlyhalf
-1: abi_return
+1: leaf_return
.Lsub_xexpzero:
/* Same as "yexpzero". */
.Lsub_return_zero:
movi a2, 0
- abi_return
+ leaf_return
.Lsub_borrow:
/* The subtraction has underflowed into the exponent field, so the
/* Round down to the nearest even value. */
srli a2, a2, 1
slli a2, a2, 1
- abi_return
+ leaf_return
.Lsub_xzero:
/* If there was a borrow from the exponent, and the mantissa and
.global __mulsf3
.type __mulsf3, @function
__mulsf3:
- abi_entry sp, 48
+ leaf_entry sp, 32
#if __XTENSA_CALL0_ABI__
addi sp, sp, -32
s32i a12, sp, 16
l32i a15, sp, 28
addi sp, sp, 32
#endif
- abi_return
+ leaf_return
.Lmul_exactlyhalf:
/* Round down to the nearest even value. */
bnez a4, 1f
movi a4, 0x400000 /* make it a quiet NaN */
or a2, a2, a4
-1: abi_return
+1: leaf_return
.Ldiv_xexpzero:
/* Clear the sign bit of x. */
/* Return zero with the appropriate sign bit. */
srli a2, a7, 31
slli a2, a2, 31
- abi_return
+ leaf_return
.Ldiv_xnan_or_inf:
/* Set the sign bit of the result. */
bnall a3, a6, 1f
movi a4, 0x400000 /* make it a quiet NaN */
or a2, a2, a4
-1: abi_return
+1: leaf_return
.Ldiv_ynan_or_inf:
/* If y is Infinity, return zero. */
beqz a8, .Ldiv_return_zero
/* y is NaN; return it. */
mov a2, a3
- abi_return
+ leaf_return
.align 4
.global __divsf3
.type __divsf3, @function
__divsf3:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7f800000
/* Get the sign of the result. */
srli a7, a7, 31
slli a7, a7, 31
or a2, a2, a7
- abi_return
+ leaf_return
.Ldiv_overflow:
bltz a8, .Ldiv_underflow
/* Return zero with the appropriate sign bit. */
srli a2, a7, 31
slli a2, a2, 31
- abi_return
+ leaf_return
#endif /* L_divsf3 */
.set __nesf2, __eqsf2
.type __eqsf2, @function
__eqsf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
bne a2, a3, 4f
/* The values are equal but NaN != NaN. Check the exponent. */
/* Equal. */
movi a2, 0
- abi_return
+ leaf_return
/* Not equal. */
2: movi a2, 1
- abi_return
+ leaf_return
/* Check if the mantissas are nonzero. */
3: slli a7, a2, 9
5: movi a2, 0
movi a3, 1
movnez a2, a3, a7
- abi_return
+ leaf_return
/* Greater Than */
.global __gtsf2
.type __gtsf2, @function
__gtsf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7f800000
ball a2, a6, 2f
1: bnall a3, a6, .Lle_cmp
slli a7, a3, 9
beqz a7, .Lle_cmp
movi a2, 0
- abi_return
+ leaf_return
/* Check if x is a NaN. */
2: slli a7, a2, 9
beqz a7, 1b
movi a2, 0
- abi_return
+ leaf_return
/* Less Than or Equal */
.global __lesf2
.type __lesf2, @function
__lesf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7f800000
ball a2, a6, 2f
1: bnall a3, a6, .Lle_cmp
slli a7, a3, 9
beqz a7, .Lle_cmp
movi a2, 1
- abi_return
+ leaf_return
/* Check if x is a NaN. */
2: slli a7, a2, 9
beqz a7, 1b
movi a2, 1
- abi_return
+ leaf_return
.Lle_cmp:
/* Check if x and y have different signs. */
/* Check if x <= y. */
bltu a3, a2, 5f
4: movi a2, 0
- abi_return
+ leaf_return
.Lle_xneg:
/* Check if y <= x. */
bgeu a2, a3, 4b
5: movi a2, 1
- abi_return
+ leaf_return
.Lle_diff_signs:
bltz a2, 4b
movi a2, 1
movi a3, 0
moveqz a2, a3, a7
- abi_return
+ leaf_return
/* Greater Than or Equal */
.global __gesf2
.type __gesf2, @function
__gesf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7f800000
ball a2, a6, 2f
1: bnall a3, a6, .Llt_cmp
slli a7, a3, 9
beqz a7, .Llt_cmp
movi a2, -1
- abi_return
+ leaf_return
/* Check if x is a NaN. */
2: slli a7, a2, 9
beqz a7, 1b
movi a2, -1
- abi_return
+ leaf_return
/* Less Than */
.global __ltsf2
.type __ltsf2, @function
__ltsf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7f800000
ball a2, a6, 2f
1: bnall a3, a6, .Llt_cmp
slli a7, a3, 9
beqz a7, .Llt_cmp
movi a2, 0
- abi_return
+ leaf_return
/* Check if x is a NaN. */
2: slli a7, a2, 9
beqz a7, 1b
movi a2, 0
- abi_return
+ leaf_return
.Llt_cmp:
/* Check if x and y have different signs. */
/* Check if x < y. */
bgeu a2, a3, 5f
4: movi a2, -1
- abi_return
+ leaf_return
.Llt_xneg:
/* Check if y < x. */
bltu a3, a2, 4b
5: movi a2, 0
- abi_return
+ leaf_return
.Llt_diff_signs:
bgez a2, 5b
movi a2, 0
movi a3, -1
movnez a2, a3, a7
- abi_return
+ leaf_return
/* Unordered */
.global __unordsf2
.type __unordsf2, @function
__unordsf2:
- abi_entry sp, 32
+ leaf_entry sp, 16
movi a6, 0x7f800000
ball a2, a6, 3f
1: ball a3, a6, 4f
2: movi a2, 0
- abi_return
+ leaf_return
3: slli a7, a2, 9
beqz a7, 1b
movi a2, 1
- abi_return
+ leaf_return
4: slli a7, a3, 9
beqz a7, 2b
movi a2, 1
- abi_return
+ leaf_return
#endif /* L_cmpsf2 */
.global __fixsfsi
.type __fixsfsi, @function
__fixsfsi:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for NaN and Infinity. */
movi a6, 0x7f800000
/* Negate the result if sign != 0. */
neg a2, a5
movgez a2, a5, a7
- abi_return
+ leaf_return
.Lfixsfsi_nan_or_inf:
/* Handle Infinity and NaN. */
addi a5, a4, -1 /* 0x7fffffff */
movgez a4, a5, a2
mov a2, a4
- abi_return
+ leaf_return
.Lfixsfsi_zero:
movi a2, 0
- abi_return
+ leaf_return
#endif /* L_fixsfsi */
.global __fixsfdi
.type __fixsfdi, @function
__fixsfdi:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for NaN and Infinity. */
movi a6, 0x7f800000
neg xh, xh
beqz xl, 1f
addi xh, xh, -1
-1: abi_return
+1: leaf_return
.Lfixsfdi_smallshift:
movi xl, 0
bgez a2, 1f
mov xh, a7
movi xl, 0
- abi_return
+ leaf_return
1: addi xh, a7, -1 /* 0x7fffffff */
movi xl, -1
- abi_return
+ leaf_return
.Lfixsfdi_zero:
movi xh, 0
movi xl, 0
- abi_return
+ leaf_return
#endif /* L_fixsfdi */
.global __fixunssfsi
.type __fixunssfsi, @function
__fixunssfsi:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for NaN and Infinity. */
movi a6, 0x7f800000
/* Negate the result if sign != 0. */
neg a2, a5
movgez a2, a5, a7
- abi_return
+ leaf_return
.Lfixunssfsi_nan_or_inf:
/* Handle Infinity and NaN. */
/* Translate NaN to 0xffffffff. */
movi a2, -1
- abi_return
+ leaf_return
.Lfixunssfsi_maxint:
slli a4, a6, 8 /* 0x80000000 */
movi a5, -1 /* 0xffffffff */
movgez a4, a5, a2
mov a2, a4
- abi_return
+ leaf_return
.Lfixunssfsi_zero:
movi a2, 0
- abi_return
+ leaf_return
.Lfixunssfsi_bigexp:
/* Handle unsigned maximum exponent case. */
bltz a2, 1f
mov a2, a5 /* no shift needed */
- abi_return
+ leaf_return
/* Return 0x80000000 if negative. */
1: slli a2, a6, 8
- abi_return
+ leaf_return
#endif /* L_fixunssfsi */
.global __fixunssfdi
.type __fixunssfdi, @function
__fixunssfdi:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for NaN and Infinity. */
movi a6, 0x7f800000
neg xh, xh
beqz xl, 1f
addi xh, xh, -1
-1: abi_return
+1: leaf_return
.Lfixunssfdi_smallshift:
movi xl, 0
/* Translate NaN to 0xffffffff.... */
1: movi xh, -1
movi xl, -1
- abi_return
+ leaf_return
.Lfixunssfdi_maxint:
bgez a2, 1b
2: slli xh, a6, 8 /* 0x80000000 */
movi xl, 0
- abi_return
+ leaf_return
.Lfixunssfdi_zero:
movi xh, 0
movi xl, 0
- abi_return
+ leaf_return
.Lfixunssfdi_bigexp:
/* Handle unsigned maximum exponent case. */
bltz a7, 2b
movi xl, 0
- abi_return /* no shift needed */
+ leaf_return /* no shift needed */
#endif /* L_fixunssfdi */
.global __floatunsisf
.type __floatunsisf, @function
__floatunsisf:
- abi_entry sp, 32
+ leaf_entry sp, 16
beqz a2, .Lfloatsisf_return
/* Set the sign to zero and jump to the floatsisf code. */
.global __floatsisf
.type __floatsisf, @function
__floatsisf:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for zero. */
beqz a2, .Lfloatsisf_return
beqz a6, .Lfloatsisf_exactlyhalf
.Lfloatsisf_return:
- abi_return
+ leaf_return
.Lfloatsisf_exactlyhalf:
/* Round down to the nearest even value. */
srli a2, a2, 1
slli a2, a2, 1
- abi_return
+ leaf_return
#endif /* L_floatsisf */
.global __floatundisf
.type __floatundisf, @function
__floatundisf:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for zero. */
or a4, xh, xl
.global __floatdisf
.type __floatdisf, @function
__floatdisf:
- abi_entry sp, 32
+ leaf_entry sp, 16
/* Check for zero. */
or a4, xh, xl
/* Check if the leftover fraction is exactly 1/2. */
slli a6, a6, 1
beqz a6, .Lfloatdisf_exactlyhalf
-2: abi_return
+2: leaf_return
.Lfloatdisf_bigshift:
/* xh is zero. Normalize with first 1 bit of xl in the msb of xh. */
/* Round down to the nearest even value. */
srli a2, a2, 1
slli a2, a2, 1
- abi_return
+ leaf_return
#endif /* L_floatdisf */
#include "xtensa-config.h"
-# Note: These functions use a minimum stack frame size of 32. This is
-# necessary for Xtensa configurations that only support a fixed register
-# window size of 8, where even leaf functions (such as these) need to
-# allocate space for a 4-word "extra save area".
+# Force each stack frame to contain an "Extra Save Area" (ESA) of at least
+# 16 bytes. This is necessary for non-standard Xtensa configurations that
+# only support a fixed register window size of 8, where even leaf functions
+# (such as these) need the ESA for interrupt handlers.
+#define MIN_ESA 16
# Define macros for the ABS and ADDX* instructions to handle cases
# where they are not included in the Xtensa processor configuration.
#endif
.endm
-# Define macros for function entry and return, supporting either the
+# Define macros for leaf function entry and return, supporting either the
# standard register windowed ABI or the non-windowed call0 ABI. These
# macros do not allocate any extra stack space, so they only work for
# leaf functions that do not need to spill anything to the stack.
- .macro abi_entry reg, size
+ .macro leaf_entry reg, size
#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__
- entry \reg, \size
+ entry \reg, \size + MIN_ESA
#else
/* do nothing */
#endif
.endm
- .macro abi_return
+ .macro leaf_return
#if XCHAL_HAVE_WINDOWED && !__XTENSA_CALL0_ABI__
retw
#else
.global __mulsi3
.type __mulsi3,@function
__mulsi3:
- abi_entry sp, 32
+ leaf_entry sp, 16
#if XCHAL_HAVE_MUL16
or a4, a2, a3
srai a4, a4, 16
bnez a4, .LMUL16
mul16u a2, a2, a3
- abi_return
+ leaf_return
.LMUL16:
srai a4, a2, 16
srai a5, a3, 16
bgeui a3, 16, .Lmult_main_loop
neg a3, a2
movltz a2, a3, a5
- abi_return
+ leaf_return
.align 4
.Lmult_main_loop:
#endif /* !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MAC16 */
- abi_return
+ leaf_return
.size __mulsi3,.-__mulsi3
#endif /* L_mulsi3 */
.global __udivsi3
.type __udivsi3,@function
__udivsi3:
- abi_entry sp, 32
+ leaf_entry sp, 16
bltui a3, 2, .Lle_one # check if the divisor <= 1
mov a6, a2 # keep dividend in a6
bltu a6, a3, .Lreturn
addi a2, a2, 1 # increment quotient if dividend >= divisor
.Lreturn:
- abi_return
+ leaf_return
.Lle_one:
beqz a3, .Lerror # if divisor == 1, return the dividend
- abi_return
+ leaf_return
.Lspecial:
# return dividend >= divisor
bltu a6, a3, .Lreturn0
movi a2, 1
- abi_return
+ leaf_return
.Lerror:
# just return 0; could throw an exception
.Lreturn0:
movi a2, 0
- abi_return
+ leaf_return
.size __udivsi3,.-__udivsi3
#endif /* L_udivsi3 */
.global __divsi3
.type __divsi3,@function
__divsi3:
- abi_entry sp, 32
+ leaf_entry sp, 16
xor a7, a2, a3 # sign = dividend ^ divisor
do_abs a6, a2, a4 # udividend = abs(dividend)
do_abs a3, a3, a4 # udivisor = abs(divisor)
.Lreturn:
neg a5, a2
movltz a2, a5, a7 # return (sign < 0) ? -quotient : quotient
- abi_return
+ leaf_return
.Lle_one:
beqz a3, .Lerror
neg a2, a6 # if udivisor == 1, then return...
movgez a2, a6, a7 # (sign < 0) ? -udividend : udividend
- abi_return
+ leaf_return
.Lspecial:
bltu a6, a3, .Lreturn0 # if dividend < divisor, return 0
movi a2, 1
movi a4, -1
movltz a2, a4, a7 # else return (sign < 0) ? -1 : 1
- abi_return
+ leaf_return
.Lerror:
# just return 0; could throw an exception
.Lreturn0:
movi a2, 0
- abi_return
+ leaf_return
.size __divsi3,.-__divsi3
#endif /* L_divsi3 */
.global __umodsi3
.type __umodsi3,@function
__umodsi3:
- abi_entry sp, 32
+ leaf_entry sp, 16
bltui a3, 2, .Lle_one # check if the divisor is <= 1
do_nsau a5, a2, a6, a7 # dividend_shift = nsau(dividend)
bltu a2, a3, .Lreturn
sub a2, a2, a3 # subtract once more if dividend >= divisor
.Lreturn:
- abi_return
+ leaf_return
.Lle_one:
# the divisor is either 0 or 1, so just return 0.
# someday we may want to throw an exception if the divisor is 0.
movi a2, 0
- abi_return
+ leaf_return
.size __umodsi3,.-__umodsi3
#endif /* L_umodsi3 */
.global __modsi3
.type __modsi3,@function
__modsi3:
- abi_entry sp, 32
+ leaf_entry sp, 16
mov a7, a2 # save original (signed) dividend
do_abs a2, a2, a4 # udividend = abs(dividend)
do_abs a3, a3, a4 # udivisor = abs(divisor)
bgez a7, .Lpositive
neg a2, a2 # if (dividend < 0), return -udividend
.Lpositive:
- abi_return
+ leaf_return
.Lle_one:
# udivisor is either 0 or 1, so just return 0.
# someday we may want to throw an exception if udivisor is 0.
movi a2, 0
- abi_return
+ leaf_return
.size __modsi3,.-__modsi3
#endif /* L_modsi3 */