1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-12 08:40:20 +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
disassembler function.

View file

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

View file

@ -18,6 +18,8 @@
*/
#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_D 0x11 /* float64 */
# 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)
static void _movi_f(jit_state_t*,jit_int32_t,jit_float32_t*);
# 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_d_w(r0, r1) DMFC1(r0, r1)
# define movi_d_w(r0, i0) _movi_d_w(_jit,r0,i0)
@ -759,17 +767,51 @@ dopi(mul)
dopi(div)
#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
_movi_d_w(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
{
jit_word_t w;
union {
jit_word_t w;
jit_int64_t l;
jit_float64_t d;
} data;
if (_jitc->no_data) {
data.d = *i0;
movi(r0, data.w);
movi64(r0, data.l);
}
else {
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)
{
assert(r1 == r2 - 1);
MTC1(r1, r0);
MTC1(r2, r0 + 1);
MTC1(r1, r0 + BE_P);
MTC1(r2, r0 + LE_P);
}
static void
_movr_d_ww(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
assert(r0 == r1 - 1);
MFC1(r0, r2);
MFC1(r1, r2 + 1);
MFC1(r0, r2 + BE_P);
MFC1(r1, r2 + LE_P);
}
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
LDC1(r0, 0, r1);
# else
LWC1(r0, 0, r1);
LWC1(r0 + 1, 4, r1);
LWC1(r0 + BE_P, 0, r1);
LWC1(r0 + LE_P, 4, r1);
# endif
}
@ -877,14 +919,14 @@ _ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
}
# else
if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) {
LWC1(r0, i0, _ZERO_REGNO);
LWC1(r0 + 1, i0 + 4, _ZERO_REGNO);
LWC1(r0 + BE_P, i0, _ZERO_REGNO);
LWC1(r0 + LE_P, i0 + 4, _ZERO_REGNO);
}
else {
reg = jit_get_reg(jit_class_gpr);
movi(rn(reg), i0);
LWC1(r0, 0, rn(reg));
LWC1(r0 + 1, 4, rn(reg));
LWC1(r0 + BE_P, 0, rn(reg));
LWC1(r0 + LE_P, 4, rn(reg));
jit_unget_reg(reg);
}
# 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);
# else
if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) {
LWC1(r0, i0, r1);
LWC1(r0 + 1, i0 + 4, r1);
LWC1(r0 + BE_P, i0, r1);
LWC1(r0 + LE_P, i0 + 4, r1);
}
# endif
else {
@ -927,8 +969,8 @@ _str_d(jit_state_t *_jit,jit_int32_t r0, jit_int32_t r1)
# if __WORDSIZE == 64 || NEW_ABI
SDC1(r1, 0, r0);
# else
SWC1(r1, 0, r0);
SWC1(r1 + 1, 4, r0);
SWC1(r1 + BE_P, 0, r0);
SWC1(r1 + LE_P, 4, r0);
# endif
}
@ -941,8 +983,8 @@ _sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
SDC1(r0, i0, _ZERO_REGNO);
# else
if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) {
SWC1(r0, i0, _ZERO_REGNO);
SWC1(r0 + 1, i0 + 4, _ZERO_REGNO);
SWC1(r0 + BE_P, i0, _ZERO_REGNO);
SWC1(r0 + LE_P, i0 + 4, _ZERO_REGNO);
}
# endif
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);
# else
if (can_sign_extend_short_p(i0) && can_sign_extend_short_p(i0 + 4)) {
SWC1(r1, i0, r0);
SWC1(r1 + 1, i0 + 4, r0);
SWC1(r1 + BE_P, i0, r0);
SWC1(r1 + LE_P, i0 + 4, r0);
}
# endif
else {
@ -1006,23 +1048,8 @@ _movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
if (data.l) {
if (_jitc->no_data) {
reg = jit_get_reg(jit_class_gpr);
# if __WORDSIZE == 64
movi(rn(reg), data.l);
movi64(rn(reg), data.l);
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);
}
else
@ -1036,23 +1063,23 @@ _movi_d(jit_state_t *_jit, jit_int32_t r0, jit_float64_t *i0)
if (data.i[0]) {
if (_jitc->no_data) {
movi(rn(reg), data.i[0]);
MTC1(rn(reg), r0);
MTC1(rn(reg), r0 + BE_P);
}
else
ldi_f(r0, (jit_word_t)i0);
ldi_f(r0 + BE_P, (jit_word_t)i0);
}
else
MTC1(_ZERO_REGNO, r0);
MTC1(_ZERO_REGNO, r0 + BE_P);
if (data.i[1]) {
if (_jitc->no_data) {
movi(rn(reg), data.i[1]);
MTC1(rn(reg), r0 + 1);
MTC1(rn(reg), r0 + LE_P);
}
else
ldi_f(r0 + 1, ((jit_word_t)i0) + 4);
ldi_f(r0 + LE_P, ((jit_word_t)i0) + 4);
}
else
MTC1(_ZERO_REGNO, r0 + 1);
MTC1(_ZERO_REGNO, r0 + LE_P);
if (_jitc->no_data)
jit_unget_reg(reg);
# endif

View file

@ -21,10 +21,6 @@
# include <sys/cachectl.h>
#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
# define NUM_WORD_ARGS 8
# define STACK_SLOT 8
@ -34,7 +30,7 @@
# define STACK_SLOT 4
# define STACK_SHIFT 2
#endif
#if __BYTE_ORDER == __BIG_ENDIAN && __WORDSIZE == 32
#if NEW_ABI && __BYTE_ORDER == __BIG_ENDIAN && __WORDSIZE == 32
# define WORD_ADJUST 4
#else
# 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))
jit_movr(_A0 - v->u.w, u);
else
jit_stxi(v->u.w, _FP, u);
jit_stxi(v->u.w + WORD_ADJUST, _FP, u);
jit_dec_synth();
}
@ -629,7 +625,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
else {
regno = jit_get_reg(jit_class_gpr);
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_dec_synth();