author | pcpa <paulo.cesar.pereira.de.andrade@gmail.com> | 2012年12月09日 19:13:33 -0200 |
---|---|---|
committer | pcpa <paulo.cesar.pereira.de.andrade@gmail.com> | 2012年12月09日 19:13:33 -0200 |
commit | e255b7606842c02be793e0d447aaac2f9a40bc65 (patch) | |
tree | 7212ff1d58e72a2d00449d52144322b5027a2b84 /lib | |
parent | d1c0bc8e983620693bb71c58b7bfd64bd3690d94 (diff) | |
download | lightning-e255b7606842c02be793e0d447aaac2f9a40bc65.tar.gz |
-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 |
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); |