mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-11 16:20:19 +02:00
ARM: Correct several inconsistencies with ldrd and strd
* lib/jit_disasm.c: Change thumb or arm disassemble based on jit code before disassembly. * lib/jit_arm-cpu.c: Correct reversed arguments to LDRD and STRD instructions, and correct checking for support of those. * lib/jit_arm-swf.c: Correct wrong use of LDRD and STRD and only use those if the register is even. * check/check.arm.swf.sh, check/check.arm4.swf.sh: New files to test LDRD and STRD, as well as the alternate code path when those are not available, in the .arm4. test case. * check/Makefile.am: Update for the new test cases.
This commit is contained in:
parent
7b449aa063
commit
3f397228f5
7 changed files with 131 additions and 30 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
2014-11-20 Paulo Andrade <pcpa@gnu.org>
|
||||
|
||||
* lib/jit_disasm.c: Change thumb or arm disassemble based on
|
||||
jit code before disassembly.
|
||||
|
||||
* lib/jit_arm-cpu.c: Correct reversed arguments to LDRD and
|
||||
STRD instructions, and correct checking for support of those.
|
||||
|
||||
* lib/jit_arm-swf.c: Correct wrong use of LDRD and STRD and
|
||||
only use those if the register is even.
|
||||
|
||||
* check/check.arm.swf.sh, check/check.arm4.swf.sh: New files
|
||||
to test LDRD and STRD, as well as the alternate code path
|
||||
when those are not available, in the .arm4. test case.
|
||||
|
||||
* check/Makefile.am: Update for the new test cases.
|
||||
|
||||
2014-11-08 Paulo Andrade <pcpa@gnu.org>
|
||||
|
||||
* include/lightning/jit_private.h, lib/jit_aarch64.c,
|
||||
|
|
|
@ -92,6 +92,8 @@ EXTRA_DIST = \
|
|||
check.sh \
|
||||
check.x87.sh \
|
||||
check.arm.sh check.swf.sh \
|
||||
check.arm.swf.sh \
|
||||
check.arm4.swf.sh \
|
||||
check.nodata.sh \
|
||||
check.x87.nodata.sh \
|
||||
run-test all.tst
|
||||
|
@ -213,6 +215,53 @@ swf_TESTS = \
|
|||
$(swf_TESTS): check.swf.sh
|
||||
$(LN_S) $(srcdir)/check.swf.sh $@
|
||||
TESTS += $(swf_TESTS)
|
||||
if test_arm_arm
|
||||
#arm_swf_TESTS = $(addsuffix .arm.swf, $(base_TESTS))
|
||||
arm_swf_TESTS = \
|
||||
3to2.arm.swf add.arm.swf allocai.arm.swf \
|
||||
bp.arm.swf divi.arm.swf fib.arm.swf rpn.arm.swf \
|
||||
ldstr.arm.swf ldsti.arm.swf \
|
||||
ldstxr.arm.swf ldstxi.arm.swf \
|
||||
ldstr-c.arm.swf ldstxr-c.arm.swf ldstxi-c.arm.swf \
|
||||
cvt.arm.swf branch.arm.swf \
|
||||
alu_add.arm.swf alux_add.arm.swf \
|
||||
alu_sub.arm.swf alux_sub.arm.swf alu_rsb.arm.swf \
|
||||
alu_mul.arm.swf alu_div.arm.swf alu_rem.arm.swf \
|
||||
alu_and.arm.swf alu_or.arm.swf alu_xor.arm.swf \
|
||||
alu_lsh.arm.swf alu_rsh.arm.swf \
|
||||
alu_com.arm.swf alu_neg.arm.swf \
|
||||
fop_abs.arm.swf fop_sqrt.arm.swf \
|
||||
varargs.arm.swf stack.arm.swf \
|
||||
clobber.arm.swf carry.arm.swf call.arm.swf \
|
||||
float.arm.swf jmpr.arm.swf tramp.arm.swf range.arm.swf
|
||||
$(arm_swf_TESTS): check.arm.swf.sh
|
||||
$(LN_S) $(srcdir)/check.arm.swf.sh $@
|
||||
TESTS += $(arm_swf_TESTS)
|
||||
endif
|
||||
if test_arm_arm
|
||||
#arm4_swf_TESTS = $(addsuffix .arm4.swf, $(base_TESTS))
|
||||
arm4_swf_TESTS = \
|
||||
3to2.arm4.swf add.arm4.swf allocai.arm4.swf \
|
||||
bp.arm4.swf divi.arm4.swf fib.arm4.swf rpn.arm4.swf \
|
||||
ldstr.arm4.swf ldsti.arm4.swf \
|
||||
ldstxr.arm4.swf ldstxi.arm4.swf \
|
||||
ldstr-c.arm4.swf ldstxr-c.arm4.swf ldstxi-c.arm4.swf \
|
||||
cvt.arm4.swf branch.arm4.swf \
|
||||
alu_add.arm4.swf alux_add.arm4.swf \
|
||||
alu_sub.arm4.swf alux_sub.arm4.swf alu_rsb.arm4.swf \
|
||||
alu_mul.arm4.swf alu_div.arm4.swf alu_rem.arm4.swf \
|
||||
alu_and.arm4.swf alu_or.arm4.swf alu_xor.arm4.swf \
|
||||
alu_lsh.arm4.swf alu_rsh.arm4.swf \
|
||||
alu_com.arm4.swf alu_neg.arm4.swf \
|
||||
fop_abs.arm4.swf fop_sqrt.arm4.swf \
|
||||
varargs.arm4.swf stack.arm4.swf \
|
||||
clobber.arm4.swf carry.arm4.swf call.arm4.swf \
|
||||
float.arm4.swf jmpr.arm4.swf tramp.arm4.swf \
|
||||
range.arm4.swf
|
||||
$(arm4_swf_TESTS): check.arm4.swf.sh
|
||||
$(LN_S) $(srcdir)/check.arm4.swf.sh $@
|
||||
TESTS += $(arm4_swf_TESTS)
|
||||
endif
|
||||
endif
|
||||
|
||||
if test_nodata
|
||||
|
|
15
check/check.arm.swf.sh
Executable file
15
check/check.arm.swf.sh
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
test=`basename $0 | sed -e 's|\.arm\.swf$||'`
|
||||
./lightning -mthumb=0 -mvfp=0 $srcdir/$test.tst | tr -d \\r > $test.out
|
||||
if test $? != 0; then
|
||||
exit $?
|
||||
fi
|
||||
|
||||
cmp -s $srcdir/$test.ok $test.out
|
||||
result=$?
|
||||
if test $result != 0; then
|
||||
diff $srcdir/$test.ok $test.out
|
||||
rm $test.out
|
||||
exit 1
|
||||
fi
|
||||
rm $test.out
|
15
check/check.arm4.swf.sh
Executable file
15
check/check.arm4.swf.sh
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/bin/sh
|
||||
test=`basename $0 | sed -e 's|\.arm4\.swf$||'`
|
||||
./lightning -mcpu=4 -mthumb=0 -mvfp=0 $srcdir/$test.tst | tr -d \\r > $test.out
|
||||
if test $? != 0; then
|
||||
exit $?
|
||||
fi
|
||||
|
||||
cmp -s $srcdir/$test.ok $test.out
|
||||
result=$?
|
||||
if test $result != 0; then
|
||||
diff $srcdir/$test.ok $test.out
|
||||
rm $test.out
|
||||
exit 1
|
||||
fi
|
||||
rm $test.out
|
|
@ -31,7 +31,7 @@
|
|||
# define jit_thumb_p() jit_cpu.thumb
|
||||
# define jit_no_set_flags() _jitc->no_set_flags
|
||||
# define jit_armv5_p() (jit_cpu.version >= 5)
|
||||
# define jit_armv5e_p() (jit_cpu.version >= 5 && jit_cpu.extend)
|
||||
# define jit_armv5e_p() (jit_cpu.version > 5 || (jit_cpu.version == 5 && jit_cpu.extend))
|
||||
# define jit_armv6_p() (jit_cpu.version >= 6)
|
||||
# define jit_armv7r_p() 0
|
||||
# define stack_framesize 48
|
||||
|
@ -709,9 +709,9 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
|
|||
# define LDRD(rt,rn,rm) CC_LDRD(ARM_CC_AL,rt,rn,rm)
|
||||
# define T2_LDRDI(rt,rt2,rn,im) torrri8(THUMB2_LDRDI|ARM_P,rn,rt,rt2,im)
|
||||
# define CC_LDRDN(cc,rt,rn,rm) corrr(cc,ARM_LDRD,rn,rt,rm)
|
||||
# define LDRDN(rd,rn,rm) CC_LDRDN(ARM_CC_AL,rn,rt,rm)
|
||||
# define LDRDN(rd,rn,rm) CC_LDRDN(ARM_CC_AL,rt,rn,rm)
|
||||
# define CC_LDRDI(cc,rt,rn,im) corri8(cc,ARM_LDRDI|ARM_P,rn,rt,im)
|
||||
# define LDRDI(rt,rn,im) CC_LDRDI(ARM_CC_AL,rn,rt,im)
|
||||
# define LDRDI(rt,rn,im) CC_LDRDI(ARM_CC_AL,rt,rn,im)
|
||||
# define CC_LDRDIN(cc,rt,rn,im) corri8(cc,ARM_LDRDI,rn,rt,im)
|
||||
# define LDRDIN(rt,rn,im) CC_LDRDIN(ARM_CC_AL,rt,rn,im)
|
||||
# define T2_LDRDIN(rt,rt2,rn,im) torrri8(THUMB2_LDRDI,rn,rt,rt2,im)
|
||||
|
@ -758,7 +758,7 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
|
|||
# define CC_STRIN(cc,rt,rn,im) corri(cc,ARM_STRI,rn,rt,im)
|
||||
# define STRIN(rt,rn,im) CC_STRIN(ARM_CC_AL,rt,rn,im)
|
||||
# define T2_STRIN(rt,rn,im) torri8(THUMB2_STRI,rn,rt,im)
|
||||
# define CC_STRD(cc,rt,rn,rm) corrr(cc,ARM_STRD|ARM_P,rt,rn,rm)
|
||||
# define CC_STRD(cc,rt,rn,rm) corrr(cc,ARM_STRD|ARM_P,rn,rt,rm)
|
||||
# define STRD(rt,rn,rm) CC_STRD(ARM_CC_AL,rt,rn,rm)
|
||||
# define CC_STRDN(cc,rt,rn,rm) corrr(cc,ARM_STRD,rn,rt,rm)
|
||||
# define STRDN(rt,rn,rm) CC_STRDN(ARM_CC_AL,rt,rn,rm)
|
||||
|
|
|
@ -1870,7 +1870,7 @@ _swf_movr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|||
}
|
||||
}
|
||||
else if (jit_fpr_p(r0)) {
|
||||
if (!jit_thumb_p() && jit_armv5e_p())
|
||||
if (!jit_thumb_p() && jit_armv5e_p() && !(r1 & 1))
|
||||
STRDIN(r1, _FP_REGNO, swf_off(r0) + 8);
|
||||
else {
|
||||
swf_strin(r1, _FP_REGNO, swf_off(r0) + 8);
|
||||
|
@ -1967,9 +1967,9 @@ _swf_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|||
if (jit_fpr_p(r1)) {
|
||||
if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() &&
|
||||
r0 != r1 && (reg = jit_get_reg_pair()) != JIT_NOREG) {
|
||||
LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 4);
|
||||
swf_bici(rn(reg), rn(reg), 0x80000000);
|
||||
STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 4);
|
||||
LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 8);
|
||||
swf_bici(rn(reg) + 1, rn(reg) + 1, 0x80000000);
|
||||
STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 8);
|
||||
jit_unget_reg_pair(reg);
|
||||
}
|
||||
else {
|
||||
|
@ -2039,9 +2039,9 @@ _swf_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|||
if (jit_fpr_p(r1)) {
|
||||
if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() &&
|
||||
r0 != r1 && (reg = jit_get_reg_pair()) != JIT_NOREG) {
|
||||
LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 4);
|
||||
EORI(rn(reg), rn(reg), encode_arm_immediate(0x80000000));
|
||||
STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 4);
|
||||
LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 8);
|
||||
EORI(rn(reg) + 1, rn(reg) + 1, encode_arm_immediate(0x80000000));
|
||||
STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 8);
|
||||
jit_unget_reg_pair(reg);
|
||||
}
|
||||
else {
|
||||
|
@ -2197,7 +2197,7 @@ _swf_ldr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|||
jit_unget_reg(reg);
|
||||
}
|
||||
}
|
||||
else if (!jit_thumb_p() && jit_armv5e_p())
|
||||
else if (!jit_thumb_p() && jit_armv5e_p() && !(r0 & 1))
|
||||
LDRDI(r0, r1, 0);
|
||||
else {
|
||||
ldxi_i(r0, r1, 0);
|
||||
|
@ -2241,7 +2241,7 @@ _swf_ldi_d(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
|
|||
swf_strin(rn(rg0), _FP_REGNO, swf_off(r0) + 4);
|
||||
jit_unget_reg(rg0);
|
||||
}
|
||||
else if (!jit_thumb_p() && jit_armv5e_p())
|
||||
else if (!jit_thumb_p() && jit_armv5e_p() && !(r0 & 1))
|
||||
LDRDI(r0, rn(rg1), 0);
|
||||
else {
|
||||
ldxi_i(r0, rn(rg1), 0);
|
||||
|
@ -2289,7 +2289,7 @@ _swf_ldxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (!jit_thumb_p() && jit_armv5e_p())
|
||||
if (!jit_thumb_p() && jit_armv5e_p() && !(r0 & 1))
|
||||
LDRD(r0, r1, r2);
|
||||
else {
|
||||
rg1 = jit_get_reg(jit_class_gpr);
|
||||
|
@ -2360,9 +2360,11 @@ _swf_ldxi_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (!jit_thumb_p() && jit_armv5e_p() && i0 >= 0 && i0 <= 255)
|
||||
if (!jit_thumb_p() && jit_armv5e_p() &&
|
||||
i0 >= 0 && i0 <= 255 && !(r0 & 1))
|
||||
LDRDI(r0, r1, i0);
|
||||
else if (!jit_thumb_p() && jit_armv5e_p() && i0 < 0 && i0 >= -255)
|
||||
else if (!jit_thumb_p() && jit_armv5e_p() &&
|
||||
i0 < 0 && i0 >= -255 && !(r0 & 1))
|
||||
LDRDIN(r0, r1, -i0);
|
||||
else if (i0 >= 0 && i0 + 4 <= 4095) {
|
||||
ldxi_i(r0, r1, i0);
|
||||
|
@ -2417,7 +2419,7 @@ _swf_str_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (!jit_thumb_p() && jit_armv5e_p())
|
||||
if (!jit_thumb_p() && jit_armv5e_p() && !(r1 & 1))
|
||||
STRDI(r1, r0, 0);
|
||||
else {
|
||||
stxi_i(0, r0, r1);
|
||||
|
@ -2469,7 +2471,7 @@ _swf_sti_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0)
|
|||
else {
|
||||
rg1 = jit_get_reg(jit_class_gpr);
|
||||
movi(rn(rg1), i0);
|
||||
if (!jit_thumb_p() && jit_armv5e_p())
|
||||
if (!jit_thumb_p() && jit_armv5e_p() && !(r0 & 1))
|
||||
STRDI(r0, rn(rg1), 0);
|
||||
else {
|
||||
stxi_i(0, rn(rg1), r0);
|
||||
|
@ -2517,7 +2519,7 @@ _swf_stxr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (!jit_thumb_p() && jit_armv5e_p())
|
||||
if (!jit_thumb_p() && jit_armv5e_p() && !(r2 & 1))
|
||||
STRD(r0, r1, r2);
|
||||
else {
|
||||
rg1 = jit_get_reg(jit_class_gpr);
|
||||
|
@ -2556,6 +2558,7 @@ _swf_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|||
STRDI(rn(rg0), r0, i0);
|
||||
else
|
||||
STRDIN(rn(rg0), r0, -i0);
|
||||
jit_unget_reg_pair(rg0);
|
||||
}
|
||||
else if (i0 >= 0 && i0 + 4 <= 4095) {
|
||||
rg0 = jit_get_reg(jit_class_gpr);
|
||||
|
@ -2587,9 +2590,11 @@ _swf_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (!jit_thumb_p() && jit_armv5e_p() && i0 >= 0 && i0 <= 255)
|
||||
if (!jit_thumb_p() && jit_armv5e_p() &&
|
||||
i0 >= 0 && i0 <= 255 && !(r1 & 1))
|
||||
STRDI(r1, r0, i0);
|
||||
else if (!jit_thumb_p() && jit_armv5e_p() && i0 < 0 && i0 >= -255)
|
||||
else if (!jit_thumb_p() && jit_armv5e_p() &&
|
||||
i0 < 0 && i0 >= -255 && !(r1 & 1))
|
||||
STRDIN(r1, r0, -i0);
|
||||
else if (i0 >= 0 && i0 + 4 <= 4095) {
|
||||
stxi_i(i0, r0, r1);
|
||||
|
|
|
@ -84,12 +84,6 @@ jit_init_debug(const char *progname)
|
|||
disasm_info.mach = bfd_mach_i386_i386;
|
||||
# endif
|
||||
# endif
|
||||
# if defined(__arm__)
|
||||
/* FIXME add mapping for prolog switching to arm and possible jump
|
||||
* before first prolog also in arm mode */
|
||||
if (jit_cpu.thumb)
|
||||
disasm_info.disassembler_options = "force-thumb";
|
||||
# endif
|
||||
# if defined(__powerpc__)
|
||||
disasm_info.arch = bfd_arch_powerpc;
|
||||
disasm_info.mach = bfd_mach_ppc64;
|
||||
|
@ -204,8 +198,15 @@ void
|
|||
_jit_disassemble(jit_state_t *_jit)
|
||||
{
|
||||
#if DISASSEMBLER
|
||||
if (disasm_bfd)
|
||||
if (disasm_bfd) {
|
||||
# if defined(__arm__)
|
||||
/* FIXME add mapping for prolog switching to arm and possible jump
|
||||
* before first prolog also in arm mode */
|
||||
disasm_info.disassembler_options = jit_cpu.thumb ? "force-thumb" : "";
|
||||
# endif
|
||||
|
||||
disassemble(_jit->code.ptr, _jit->pc.uc - _jit->code.ptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -326,8 +327,7 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length)
|
|||
again:
|
||||
if (data_info) {
|
||||
while (_jitc->data_info.ptr[data_offset].code < pc) {
|
||||
data_offset += 2;
|
||||
if (data_offset >= _jitc->data_info.length) {
|
||||
if (++data_offset >= _jitc->data_info.length) {
|
||||
data_info = 0;
|
||||
goto again;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue