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:
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月27日 19:33:33 +0000

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