Add several arithmetic and branch tests cases. - lightning.git - Portable just-in-time compiler library

index : lightning.git
Portable just-in-time compiler library
summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorpcpa <paulo.cesar.pereira.de.andrade@gmail.com>2012年12月09日 19:13:33 -0200
committerpcpa <paulo.cesar.pereira.de.andrade@gmail.com>2012年12月09日 19:13:33 -0200
commite255b7606842c02be793e0d447aaac2f9a40bc65 (patch)
tree7212ff1d58e72a2d00449d52144322b5027a2b84 /lib
parentd1c0bc8e983620693bb71c58b7bfd64bd3690d94 (diff)
downloadlightning-e255b7606842c02be793e0d447aaac2f9a40bc65.tar.gz
Add several arithmetic and branch tests cases.
* check/alu.inc, check/alu_add.ok, check/alu_add.tst, check/alu_and.ok, check/alu_and.tst, check/alu_com.ok, check/alu_com.tst, check/alu_div.ok, check/alu_div.tst, check/alu_lsh.ok, check/alu_lsh.tst, check/alu_mul.ok, check/alu_mul.tst, check/alu_neg.ok, check/alu_neg.tst, check/alu_or.ok, check/alu_or.tst, check/alu_rem.ok, check/alu_rem.tst, check/alu_rsh.ok, check/alu_rsh.tst, check/alu_sub.ok, check/alu_sub.tst, check/alu_xor.ok, check/alu_xor.tst, check/alux_add.ok, check/alux_add.tst, check/alux_sub.ok, check/alux_sub.tst, check/branch.ok, check/branch.tst: New test cases for arithmetic and branch tests. * check/Makefile.am: Update for new test cases. * include/lightning/jit_private.h: Make the jit_reg_free_p macro shared by all backends. Previously was added for the arm backend, but is useful in the x86_64 backend when checking state of "special purpose register". Also add the new jit_class_named register class, that must be or'ed with the register value if calling jit_get_reg expecting an specific value, because the specific register value may be zero, that previously was treated as no register requested. * lib/jit_arm-cpu.c: Correct argument order for T2_MVN. * lib/jit_arm-swf.c: Call the proper function for double divide. The "software float" implementation just calls libgcc functions. * lib/jit_arm.c: Return float/double values in the float register if using the hard float ABI. * lib/jit_x86-cpu.c: Change the can_sign_extend_int_p macro to not include -0x80000000L, because there is code that "abuses" it and thinks it can negate the immediate value after calling that macro. Correct implementation of jit_subi that had a wrong code patch logic doing subtraction with reversed arguments. Correct REX prefix calculation in the jit_muli implementation. Correct logic to get/unget %*ax and %*dx registers in divremr and divremi. Correct divremi that was using the symbolic, unique %*ax value in on place (not using the _REGNO name suffix). Correct cut&paste error causing it to use "xor" instead of "or" in one code path of the jit_ori implementation. Correct several flaws when clobbering registers and/or when one of the arguments was %*cx in the rotshr wrapper function implementing most shift operations. * lib/lightning.c: No longer expect that the backend be smart enough to know what to do when asking for a named register if that register is already an argument or is live. It fails if it is an argument, or if register is live, fails if cannot spill. No longer incorrectly assume that eqr_{f,d} and ltgr_{f,d} are safe to inverse value tests in jump thread optimization.
Diffstat (limited to 'lib')
-rw-r--r--lib/jit_arm-cpu.c 10
-rw-r--r--lib/jit_arm-swf.c 4
-rw-r--r--lib/jit_arm.c 12
-rw-r--r--lib/jit_x86-cpu.c 111
-rw-r--r--lib/lightning.c 23
5 files changed, 102 insertions, 58 deletions
diff --git a/lib/jit_arm-cpu.c b/lib/jit_arm-cpu.c
index 948f260..1922a6c 100644
--- a/lib/jit_arm-cpu.c
+++ b/lib/jit_arm-cpu.c
@@ -409,7 +409,7 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define CC_MVN(cc,rd,rm) corrr(cc,ARM_MVN,0,rd,rm)
# define MVN(rd,rm) CC_MVN(ARM_CC_AL,rd,rm)
# define T1_MVN(rd,rm) is(THUMB_MVN|(_u3(rm)<<3)|_u3(rd))
-# define T2_MVN(rd,rm) torrr(THUMB2_MVN,rd,_R15_REGNO,rm)
+# define T2_MVN(rd,rm) torrr(THUMB2_MVN,_R15_REGNO,rd,rm)
# define CC_MVNI(cc,rd,im) corri(cc,ARM_MVN|ARM_I,0,rd,im)
# define MVNI(rd,im) CC_MVNI(ARM_CC_AL,rd,im)
# define T2_MVNI(rd,im) torri(THUMB2_MVNI,_R15_REGNO,rd,im)
@@ -816,10 +816,10 @@ static void _torl(jit_state_t*,int,int,int) maybe_unused;
# define T2_POP(im) tpp(THUMB2_POP,im)
# define jit_get_reg_args() \
do { \
- (void)jit_get_reg(_R0|jit_class_gpr); \
- (void)jit_get_reg(_R1|jit_class_gpr); \
- (void)jit_get_reg(_R2|jit_class_gpr); \
- (void)jit_get_reg(_R3|jit_class_gpr); \
+ (void)jit_get_reg(_R0|jit_class_named|jit_class_gpr); \
+ (void)jit_get_reg(_R1|jit_class_named|jit_class_gpr); \
+ (void)jit_get_reg(_R2|jit_class_named|jit_class_gpr); \
+ (void)jit_get_reg(_R3|jit_class_named|jit_class_gpr); \
} while (0)
# define jit_unget_reg_args() \
do { \
diff --git a/lib/jit_arm-swf.c b/lib/jit_arm-swf.c
index cc311df..ad0d12d 100644
--- a/lib/jit_arm-swf.c
+++ b/lib/jit_arm-swf.c
@@ -156,8 +156,8 @@ static void _swf_negr_d(jit_state_t*,jit_int32_t,jit_int32_t);
# define swf_muli_d(r0,r1,i0) swf_ddd_(__aeabi_dmul,r0,r1,i0)
# define swf_divr_f(r0,r1,r2) swf_fff(__aeabi_fdiv,r0,r1,r2)
# define swf_divi_f(r0,r1,i0) swf_fff_(__aeabi_fdiv,r0,r1,i0)
-# define swf_divr_d(r0,r1,r2) swf_ddd(__aeabi_dsub,r0,r1,r2)
-# define swf_divi_d(r0,r1,i0) swf_ddd_(__aeabi_dsub,r0,r1,i0)
+# define swf_divr_d(r0,r1,r2) swf_ddd(__aeabi_ddiv,r0,r1,r2)
+# define swf_divi_d(r0,r1,i0) swf_ddd_(__aeabi_ddiv,r0,r1,i0)
# define swf_ltr_f(r0,r1,r2) swf_iff(__aeabi_fcmplt,r0,r1,r2)
# define swf_lti_f(r0,r1,i0) swf_iff_(__aeabi_fcmplt,r0,r1,i0)
# define swf_ltr_d(r0,r1,r2) swf_idd(__aeabi_dcmplt,r0,r1,r2)
diff --git a/lib/jit_arm.c b/lib/jit_arm.c
index 319703e..b706440 100644
--- a/lib/jit_arm.c
+++ b/lib/jit_arm.c
@@ -37,10 +37,6 @@
#define jit_exchange_p() 1
/* FIXME is it really required to not touch _R10? */
-#define jit_reg_free_p(regno) \
- (!jit_regset_tstbit(_jit->reglive, regno) && \
- !jit_regset_tstbit(_jit->regarg, regno) && \
- !jit_regset_tstbit(_jit->regsav, regno))
/*
* Types
@@ -290,28 +286,28 @@ _jit_reti(jit_state_t *_jit, jit_word_t u)
void
_jit_retr_f(jit_state_t *_jit, jit_int32_t u)
{
- jit_movr_f(JIT_RET, u);
+ jit_movr_f(JIT_FRET, u);
jit_ret();
}
void
_jit_reti_f(jit_state_t *_jit, jit_float32_t u)
{
- jit_movi_f(JIT_RET, u);
+ jit_movi_f(JIT_FRET, u);
jit_ret();
}
void
_jit_retr_d(jit_state_t *_jit, jit_int32_t u)
{
- jit_movr_d(JIT_RET, u);
+ jit_movr_d(JIT_FRET, u);
jit_ret();
}
void
_jit_reti_d(jit_state_t *_jit, jit_float64_t u)
{
- jit_movi_d(JIT_RET, u);
+ jit_movi_d(JIT_FRET, u);
jit_ret();
}
diff --git a/lib/jit_x86-cpu.c b/lib/jit_x86-cpu.c
index bef8d4c..ed02008 100644
--- a/lib/jit_x86-cpu.c
+++ b/lib/jit_x86-cpu.c
@@ -40,7 +40,7 @@
# define stxi(u, v, w) stxi_l(u, v, w)
# define can_sign_extend_int_p(im) \
(((im) >= 0 && (long)(im) <= 0x7fffffffL) || \
- ((im) < 0 && (long)(im) >= -0x80000000L))
+ ((im) < 0 && (long)(im) > -0x80000000L))
# define can_zero_extend_int_p(im) \
((im) >= 0 && (im) < 0x80000000L)
# define fits_uint32_p(im) ((im & 0xffffffff00000000L) == 0)
@@ -975,8 +975,8 @@ _subi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
lea(-i0, r1, _NOREG, _SCL1, r0);
}
else if (r0 != r1) {
- movi(r0, i0);
- isubr(r0, r1);
+ movi(r0, -i0);
+ iaddr(r0, r1);
}
else {
reg = jit_get_reg(jit_class_gpr);
@@ -1064,7 +1064,7 @@ _imuli(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
{
jit_int32_t reg;
if (can_sign_extend_int_p(i0)) {
- rex(0, 1, r1, _NOREG, r0);
+ rex(0, 1, r0, _NOREG, r1);
if ((jit_int8_t)i0 == i0) {
ic(0x6b);
mrm(0x03, r7(r0), r7(r1));
@@ -1147,16 +1147,25 @@ _divremr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2,
{
jit_int32_t div;
jit_int32_t reg;
-
- if (r0 != _RDX_REGNO)
- (void)jit_get_reg(_RDX|jit_class_gpr);
- if (r0 != _RAX_REGNO)
- (void)jit_get_reg(_RAX|jit_class_gpr);
+ jit_int32_t set;
+ jit_int32_t use;
+
+ set = use = 0;
+ if (r0 != _RDX_REGNO && r1 != _RDX_REGNO && r2 != _RDX_REGNO)
+ set |= 1 << _RDX_REGNO;
+ if (r0 != _RAX_REGNO && r1 != _RAX_REGNO && r2 != _RAX_REGNO)
+ set |= 1 << _RAX_REGNO;
+ if (set & (1 <<_RDX_REGNO))
+ (void)jit_get_reg(_RDX|jit_class_gpr|jit_class_named);
+ if (set & (1 << _RAX_REGNO))
+ (void)jit_get_reg(_RAX|jit_class_gpr|jit_class_named);
if (r2 == _RAX_REGNO) {
if (r0 == _RAX_REGNO || r0 == _RDX_REGNO) {
if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG)
- reg = jit_get_reg(r1 == _RCX_REGNO ? _RBX : _RCX);
+ reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) |
+ jit_class_gpr|jit_class_named);
+ use = 1;
div = rn(reg);
movr(div, _RAX_REGNO);
if (r1 != _RAX_REGNO)
@@ -1172,13 +1181,14 @@ _divremr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2,
movr(_RAX_REGNO, r1);
}
div = r0;
- reg = 0;
}
}
else if (r2 == _RDX_REGNO) {
if (r0 == _RAX_REGNO || r0 == _RDX_REGNO) {
if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG)
- reg = jit_get_reg(r1 == _RCX_REGNO ? _RBX : _RCX);
+ reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) |
+ jit_class_gpr|jit_class_named);
+ use = 1;
div = rn(reg);
movr(div, _RDX_REGNO);
if (r1 != _RAX_REGNO)
@@ -1189,14 +1199,12 @@ _divremr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2,
movr(_RAX_REGNO, r1);
movr(r0, _RDX_REGNO);
div = r0;
- reg = 0;
}
}
else {
if (r1 != _RAX_REGNO)
movr(_RAX_REGNO, r1);
div = r2;
- reg = 0;
}
if (sign) {
@@ -1208,19 +1216,21 @@ _divremr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2,
idivr_u(div);
}
- if (reg)
+ if (use)
jit_unget_reg(reg);
if (r0 != _RAX_REGNO) {
if (divide)
movr(r0, _RAX_REGNO);
- jit_unget_reg(_RAX);
}
if (r0 != _RDX_REGNO) {
if (!divide)
movr(r0, _RDX_REGNO);
- jit_unget_reg(_RDX);
}
+ if (set & (1 <<_RDX_REGNO))
+ jit_unget_reg(_RDX);
+ if (set & (1 << _RAX_REGNO))
+ jit_unget_reg(_RAX);
}
static void
@@ -1229,6 +1239,8 @@ _divremi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0,
{
jit_int32_t reg;
jit_int32_t div;
+ jit_int32_t set;
+ jit_int32_t use;
if (divide) {
switch (i0) {
@@ -1275,23 +1287,28 @@ _divremi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0,
return;
}
- if (r0 != _RDX_REGNO)
- (void)jit_get_reg(_RDX|jit_class_gpr);
- if (r0 != _RAX_REGNO)
- (void)jit_get_reg(_RAX|jit_class_gpr);
+ set = use = 0;
+ if (r0 != _RDX_REGNO && r1 != _RDX_REGNO)
+ set |= 1 << _RDX_REGNO;
+ if (r0 != _RAX_REGNO && r1 != _RAX_REGNO)
+ set |= 1 << _RAX_REGNO;
+ if (set & (1 <<_RDX_REGNO))
+ (void)jit_get_reg(_RDX|jit_class_gpr|jit_class_named);
+ if (set & (1 << _RAX_REGNO))
+ (void)jit_get_reg(_RAX|jit_class_gpr|jit_class_named);
- if (r0 == _RAX_REGNO || r0 == _RDX_REGNO) {
+ if (r0 == _RAX_REGNO || r0 == _RDX_REGNO || r0 == r1) {
if ((reg = jit_get_reg(jit_class_gpr|jit_class_chk)) == JIT_NOREG)
- reg = jit_get_reg(_RCX);
+ reg = jit_get_reg((r1 == _RCX_REGNO ? _RBX : _RCX) |
+ jit_class_gpr|jit_class_named);
+ use = 1;
div = rn(reg);
}
- else {
- reg = 0;
+ else
div = r0;
- }
movi(div, i0);
- movr(_RAX, r1);
+ movr(_RAX_REGNO, r1);
if (sign) {
sign_extend_rdx_rax();
@@ -1302,19 +1319,21 @@ _divremi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0,
idivr_u(div);
}
- if (reg)
+ if (use)
jit_unget_reg(reg);
if (r0 != _RAX_REGNO) {
if (divide)
movr(r0, _RAX_REGNO);
- jit_unget_reg(_RAX);
}
if (r0 != _RDX_REGNO) {
if (!divide)
movr(r0, _RDX_REGNO);
- jit_unget_reg(_RDX);
}
+ if (set & (1 <<_RDX_REGNO))
+ jit_unget_reg(_RDX);
+ if (set & (1 << _RAX_REGNO))
+ jit_unget_reg(_RAX);
}
static void
@@ -1386,7 +1405,7 @@ _ori(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
}
else if (r0 != r1) {
movi(r0, i0);
- ixorr(r0, r1);
+ iorr(r0, r1);
}
else {
reg = jit_get_reg(jit_class_gpr);
@@ -1448,6 +1467,7 @@ _rotshr(jit_state_t *_jit, jit_int32_t code,
jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
{
jit_int32_t reg;
+ jit_int32_t use;
if (r0 == _RCX_REGNO) {
reg = jit_get_reg(jit_class_gpr);
@@ -1459,13 +1479,30 @@ _rotshr(jit_state_t *_jit, jit_int32_t code,
jit_unget_reg(reg);
}
else if (r2 != _RCX_REGNO) {
- reg = jit_get_reg(jit_class_gpr);
- movr(rn(reg), _RCX_REGNO);
- movr(_RCX_REGNO, r2);
- movr(r0, r1);
+ use = !jit_reg_free_p(_RCX);
+ if (use) {
+ reg = jit_get_reg(jit_class_gpr);
+ movr(rn(reg), _RCX_REGNO);
+ }
+ else
+ reg = 0;
+ if (r1 == _RCX_REGNO) {
+ if (r0 == r2)
+ xchgr(r0, _RCX_REGNO);
+ else {
+ movr(r0, r1);
+ movr(_RCX_REGNO, r2);
+ }
+ }
+ else {
+ movr(_RCX_REGNO, r2);
+ movr(r0, r1);
+ }
irotshr(code, r0);
- movr(_RCX_REGNO, rn(reg));
- jit_unget_reg(reg);
+ if (use) {
+ movr(_RCX_REGNO, rn(reg));
+ jit_unget_reg(reg);
+ }
}
else {
movr(r0, r1);
diff --git a/lib/lightning.c b/lib/lightning.c
index ac06ffe..69abeeb 100644
--- a/lib/lightning.c
+++ b/lib/lightning.c
@@ -148,17 +148,18 @@ _jit_get_reg(jit_state_t *_jit, jit_int32_t regspec)
jit_int32_t spec;
jit_int32_t regno;
- /* if asking for an explicit register value, assume it will
- * properly handle the case of the register also being an
- * argument for the instruction, or the register value
- * being live */
spec = regspec & ~(jit_class_chk|jit_class_nospill);
- if ((regno = jit_regno(spec))) {
+ if (spec & jit_class_named) {
+ regno = jit_regno(spec);
if (jit_regset_tstbit(_jit->regsav, regno))
/* fail if register is spilled */
goto fail;
- if (jit_regset_tstbit(_jit->regarg, regno)) {
+ if (jit_regset_tstbit(_jit->regarg, regno))
+ /* fail if register is an argument to current instruction */
+ goto fail;
+ if (jit_regset_tstbit(_jit->reglive, regno)) {
if (regspec & jit_class_nospill)
+ /* fail if register is live and should not spill/reload */
goto fail;
goto spill;
}
@@ -1453,6 +1454,12 @@ _thread_jumps(jit_state_t *_jit)
case jit_code_callr: case jit_code_calli:
/* non optimizable jump like code */
break;
+ case jit_code_beqr_f: case jit_code_beqi_f:
+ case jit_code_beqr_d: case jit_code_beqi_d:
+ case jit_code_bltgtr_f: case jit_code_bltgti_f:
+ case jit_code_bltgtr_d: case jit_code_bltgti_d:
+ /* non optimizable jump code */
+ break;
default:
mask = jit_classify(node->code);
if (mask & jit_cc_a0_jmp) {
@@ -1633,8 +1640,10 @@ reverse_jump_code(jit_code_t code)
case jit_code_blti_f: return (jit_code_bungei_f);
case jit_code_bler_f: return (jit_code_bungtr_f);
case jit_code_blei_f: return (jit_code_bungti_f);
+#if 0
case jit_code_beqr_f: return (jit_code_bltgtr_f);
case jit_code_beqi_f: return (jit_code_bltgti_f);
+#endif
case jit_code_bger_f: return (jit_code_bunltr_f);
case jit_code_bgei_f: return (jit_code_bunlti_f);
case jit_code_bgtr_f: return (jit_code_bunler_f);
@@ -1651,8 +1660,10 @@ reverse_jump_code(jit_code_t code)
case jit_code_bungei_f: return (jit_code_blti_f);
case jit_code_bungtr_f: return (jit_code_bler_f);
case jit_code_bungti_f: return (jit_code_blei_f);
+#if 0
case jit_code_bltgtr_f: return (jit_code_beqr_f);
case jit_code_bltgti_f: return (jit_code_beqi_f);
+#endif
case jit_code_bordr_f: return (jit_code_bunordr_f);
case jit_code_bordi_f: return (jit_code_bunordi_f);
case jit_code_bunordr_f:return (jit_code_bordr_f);
generated by cgit v1.2.3 (git 2.39.1) at 2025年09月26日 14:10:39 +0000

AltStyle によって変換されたページ (->オリジナル) /