1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-12 16:50:22 +02:00

Correct issues with 32 bit big endian mips abis

* lib/jit_mips-cpu.c: Correct frame size and varargs
	initialization for the n32 abi.
	* lib/jit_mips.c, lib/jit_mips-fpu.c: Correct 32 bit abis
	in big-endian.
This commit is contained in:
pcpa 2018-01-31 08:52:27 -05:00
parent df57fa95eb
commit 68dc475474
4 changed files with 89 additions and 54 deletions

View file

@ -1,4 +1,11 @@
2017-13-09 Paulo Andrade <pcpa@gnu.org> 2018-01-31 Paulo Andrade <pcpa@gnu.org>
* lib/jit_mips-cpu.c: Correct frame size and varargs
initialization for the n32 abi.
* lib/jit_mips.c, lib/jit_mips-fpu.c: Correct 32 bit abis
in big-endian.
2017-09-13 Paulo Andrade <pcpa@gnu.org>
* configure.ac: Add check for binutils 2.29 prototype to the * configure.ac: Add check for binutils 2.29 prototype to the
disassembler function. disassembler function.

View file

@ -88,7 +88,7 @@ typedef union {
# define _F30_REGNO 30 # define _F30_REGNO 30
# if __WORDSIZE == 32 # if __WORDSIZE == 32
# if NEW_ABI # if NEW_ABI
# define stack_framesize 96 # define stack_framesize 144
# else # else
# define stack_framesize 112 # define stack_framesize 112
# endif # endif
@ -2968,8 +2968,13 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
index = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT; index = (_jitc->function->self.size - stack_framesize) >> STACK_SHIFT;
#endif #endif
offset = stack_framesize + index * STACK_SLOT; offset = stack_framesize + index * STACK_SLOT;
for (; jit_arg_reg_p(index); ++index, offset += STACK_SLOT) for (; jit_arg_reg_p(index); ++index, offset += STACK_SLOT) {
#if NEW_ABI
SD(rn(_A0 - index), offset, _BP_REGNO);
#else
stxi(offset + WORD_ADJUST, _BP_REGNO, rn(_A0 - index)); stxi(offset + WORD_ADJUST, _BP_REGNO, rn(_A0 - index));
#endif
}
} }
} }
@ -3014,7 +3019,7 @@ _vastart(jit_state_t *_jit, jit_int32_t r0)
#if NEW_ABI #if NEW_ABI
if (jit_arg_reg_p(_jitc->function->vagp)) if (jit_arg_reg_p(_jitc->function->vagp))
addi(r0, _BP_REGNO, stack_framesize + _jitc->function->vagp * addi(r0, _BP_REGNO, stack_framesize + _jitc->function->vagp *
sizeof(jit_word_t)); sizeof(jit_int64_t));
else else
#endif #endif
addi(r0, _BP_REGNO, _jitc->function->self.size); addi(r0, _BP_REGNO, _jitc->function->self.size);

View file

@ -18,6 +18,8 @@
*/ */
#if PROTO #if PROTO
# define BE_P (__BYTE_ORDER == __BIG_ENDIAN)
# define LE_P (__BYTE_ORDER == __LITTLE_ENDIAN)
# define MIPS_fmt_S 0x10 /* float32 */ # define MIPS_fmt_S 0x10 /* float32 */
# define MIPS_fmt_D 0x11 /* float64 */ # define MIPS_fmt_D 0x11 /* float64 */
# define MIPS_fmt_W 0x14 /* int32 */ # define MIPS_fmt_W 0x14 /* int32 */
@ -249,6 +251,12 @@ static void _movr_f(jit_state_t*,jit_int32_t,jit_int32_t);
# define movi_f(r0, i0) _movi_f(_jit, r0, i0) # define movi_f(r0, i0) _movi_f(_jit, r0, i0)
static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*); static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*);
# if NEW_ABI # if NEW_ABI
# if __WORDSIZE == 32
# define movi64(r0, i0) _movi64(_jit, r0, i0)
static void _movi64(jit_state_t*,jit_int32_t,jit_int64_t);
# else
# define movi64(r0, i0) movi(r0, i0)
# endif
# define movr_w_d(r0, r1) DMTC1(r1, r0) # define movr_w_d(r0, r1) DMTC1(r1, r0)
# define movr_d_w(r0, r1) DMFC1(r0, r1) # define movr_d_w(r0, r1) DMFC1(r0, r1)
# define movi_d_w(r0, i0) _movi_d_w(_jit,r0,i0) # define movi_d_w(r0, i0) _movi_d_w(_jit,r0,i0)
@ -759,17 +767,51 @@ dopi(mul)
dopi(div) dopi(div)
#if NEW_ABI #if NEW_ABI
/* n32 abi requires 64 bit cpu */
static void
_movi64(jit_state_t *_jit, jit_int32_t r0, jit_int64_t i0)
{
if (i0 == 0)
OR(r0, _ZERO_REGNO, _ZERO_REGNO);
else if (i0 >= -32678 && i0 <= 32767)
DADDIU(r0, _ZERO_REGNO, i0);
else if (i0 >= 0 && i0 <= 65535)
ORI(r0, _ZERO_REGNO, i0);
else {
if (i0 >= 0 && i0 <= 0x7fffffffLL)
LUI(r0, i0 >> 16);
else if (i0 >= 0 && i0 <= 0xffffffffLL) {
if (i0 & 0xffff0000LL) {
ORI(r0, _ZERO_REGNO, (jit_word_t)(i0 >> 16));
DSLL(r0, r0, 16);
}
}
else {
movi(r0, (jit_word_t)(i0 >> 32));
if (i0 & 0xffff0000LL) {
DSLL(r0, r0, 16);
ORI(r0, r0, (jit_word_t)(i0 >> 16));
DSLL(r0, r0, 16);
}
else
DSLL32(r0, r0, 0);
}
if ((jit_word_t)i0 & 0xffff)
ORI(r0, r0, (jit_word_t)i0 & 0xffff);
}
}
static void static void
_movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0) _movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
{ {
jit_word_t w; jit_word_t w;
union { union {
jit_word_t w; jit_int64_t l;
jit_float64_t d; jit_float64_t d;
} data; } data;
if (_jitc->no_data) { if (_jitc->no_data) {
data.d = *i0; data.d = *i0;
movi(r0, data.w); movi64(r0, data.l);
} }
else { else {
w = (jit_word_t)i0; w = (jit_word_t)i0;
@ -787,16 +829,16 @@ static void
_movr_ww_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) _movr_ww_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{ {
assert(r1 == r2 - 1); assert(r1 == r2 - 1);
MTC1(r1, r0); MTC1(r1, r0 + BE_P);
MTC1(r2, r0 + 1); MTC1(r2, r0 + LE_P);
} }
static void static void
_movr_d_ww(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2) _movr_d_ww(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{ {
assert(r0 == r1 - 1); assert(r0 == r1 - 1);
MFC1(r0, r2); MFC1(r0, r2 + BE_P);
MFC1(r1, r2 + 1); MFC1(r1, r2 + LE_P);
} }
static void static void
@ -857,8 +899,8 @@ _ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
# if __WORDSIZE == 64 || NEW_ABI # if __WORDSIZE == 64 || NEW_ABI
LDC1(r0, 0, r1); LDC1(r0, 0, r1);
# else # else
LWC1(r0, 0, r1); LWC1(r0 + BE_P, 0, r1);
LWC1(r0 + 1, 4, r1); LWC1(r0 + LE_P, 4, r1);
# endif # endif
} }
@ -877,14 +919,14 @@ _ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
} }
# else # else
if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) { if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) {
LWC1(r0, i0, _ZERO_REGNO); LWC1(r0 + BE_P, i0, _ZERO_REGNO);
LWC1(r0 + 1, i0 + 4, _ZERO_REGNO); LWC1(r0 + LE_P, i0 + 4, _ZERO_REGNO);
} }
else { else {
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0); movi(rn(reg), i0);
LWC1(r0, 0, rn(reg)); LWC1(r0 + BE_P, 0, rn(reg));
LWC1(r0 + 1, 4, rn(reg)); LWC1(r0 + LE_P, 4, rn(reg));
jit_unget_reg(reg); jit_unget_reg(reg);
} }
# endif # endif
@ -909,8 +951,8 @@ _ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
LDC1(r0, i0, r1); LDC1(r0, i0, r1);
# else # else
if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) { if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) {
LWC1(r0, i0, r1); LWC1(r0 + BE_P, i0, r1);
LWC1(r0 + 1, i0 + 4, r1); LWC1(r0 + LE_P, i0 + 4, r1);
} }
# endif # endif
else { else {
@ -927,8 +969,8 @@ _str_d(jit_state_t *_jit,jit_int32_t r0, jit_int32_t r1)
# if __WORDSIZE == 64 || NEW_ABI # if __WORDSIZE == 64 || NEW_ABI
SDC1(r1, 0, r0); SDC1(r1, 0, r0);
# else # else
SWC1(r1, 0, r0); SWC1(r1 + BE_P, 0, r0);
SWC1(r1 + 1, 4, r0); SWC1(r1 + LE_P, 4, r0);
# endif # endif
} }
@ -941,8 +983,8 @@ _sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
SDC1(r0, i0, _ZERO_REGNO); SDC1(r0, i0, _ZERO_REGNO);
# else # else
if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) { if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) {
SWC1(r0, i0, _ZERO_REGNO); SWC1(r0 + BE_P, i0, _ZERO_REGNO);
SWC1(r0 + 1, i0 + 4, _ZERO_REGNO); SWC1(r0 + LE_P, i0 + 4, _ZERO_REGNO);
} }
# endif # endif
else { else {
@ -972,8 +1014,8 @@ _stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
SDC1(r1, i0, r0); SDC1(r1, i0, r0);
# else # else
if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) { if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) {
SWC1(r1, i0, r0); SWC1(r1 + BE_P, i0, r0);
SWC1(r1 + 1, i0 + 4, r0); SWC1(r1 + LE_P, i0 + 4, r0);
} }
# endif # endif
else { else {
@ -1006,23 +1048,8 @@ _movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
if (data.l) { if (data.l) {
if (_jitc->no_data) { if (_jitc->no_data) {
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
# if __WORDSIZE == 64 movi64(rn(reg), data.l);
movi(rn(reg), data.l);
DMTC1(rn(reg), r0); DMTC1(rn(reg), r0);
# else
if (data.i[0]) {
movi(rn(reg), data.i[0]);
MTC1(rn(reg), r0);
}
else
MTC1(_ZERO_REGNO, r0);
if (data.i[1]) {
movi(rn(reg), data.i[1]);
MTC1(rn(reg), r0 + 1);
}
else
MTC1(_ZERO_REGNO, r0 + 1);
# endif
jit_unget_reg(reg); jit_unget_reg(reg);
} }
else else
@ -1036,23 +1063,23 @@ _movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
if (data.i[0]) { if (data.i[0]) {
if (_jitc->no_data) { if (_jitc->no_data) {
movi(rn(reg), data.i[0]); movi(rn(reg), data.i[0]);
MTC1(rn(reg), r0); MTC1(rn(reg), r0 + BE_P);
} }
else else
ldi_f(r0, (jit_word_t)i0); ldi_f(r0 + BE_P, (jit_word_t)i0);
} }
else else
MTC1(_ZERO_REGNO, r0); MTC1(_ZERO_REGNO, r0 + BE_P);
if (data.i[1]) { if (data.i[1]) {
if (_jitc->no_data) { if (_jitc->no_data) {
movi(rn(reg), data.i[1]); movi(rn(reg), data.i[1]);
MTC1(rn(reg), r0 + 1); MTC1(rn(reg), r0 + LE_P);
} }
else else
ldi_f(r0 + 1, ((jit_word_t)i0) + 4); ldi_f(r0 + LE_P, ((jit_word_t)i0) + 4);
} }
else else
MTC1(_ZERO_REGNO, r0 + 1); MTC1(_ZERO_REGNO, r0 + LE_P);
if (_jitc->no_data) if (_jitc->no_data)
jit_unget_reg(reg); jit_unget_reg(reg);
# endif # endif

View file

@ -21,10 +21,6 @@
# include <sys/cachectl.h> # include <sys/cachectl.h>
#endif #endif
/* FIXME Need to detect (from /proc on Linux?) if a Loongson or Godson,
* because n32 and n64 mandate that float registers are 64 bit, and
* on the later, registers are 32 bit.
*/
#if NEW_ABI #if NEW_ABI
# define NUM_WORD_ARGS 8 # define NUM_WORD_ARGS 8
# define STACK_SLOT 8 # define STACK_SLOT 8
@ -34,7 +30,7 @@
# define STACK_SLOT 4 # define STACK_SLOT 4
# define STACK_SHIFT 2 # define STACK_SHIFT 2
#endif #endif
#if __BYTE_ORDER == __BIG_ENDIAN && __WORDSIZE == 32 #if NEW_ABI && __BYTE_ORDER == __BIG_ENDIAN && __WORDSIZE == 32
# define WORD_ADJUST 4 # define WORD_ADJUST 4
#else #else
# define WORD_ADJUST 0 # define WORD_ADJUST 0
@ -614,7 +610,7 @@ _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
if (jit_arg_reg_p(v->u.w)) if (jit_arg_reg_p(v->u.w))
jit_movr(_A0 - v->u.w, u); jit_movr(_A0 - v->u.w, u);
else else
jit_stxi(v->u.w, _FP, u); jit_stxi(v->u.w + WORD_ADJUST, _FP, u);
jit_dec_synth(); jit_dec_synth();
} }
@ -629,7 +625,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
else { else {
regno = jit_get_reg(jit_class_gpr); regno = jit_get_reg(jit_class_gpr);
jit_movi(regno, u); jit_movi(regno, u);
jit_stxi(v->u.w, _FP, regno); jit_stxi(v->u.w + WORD_ADJUST, _FP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
jit_dec_synth(); jit_dec_synth();