diff options
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r-- | src/lj_asm.c | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 441700d4..27c9ac31 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -3988,7 +3988,23 @@ static void asm_ir(ASMState *as, IRIns *ir) | |||
3988 | else | 3988 | else |
3989 | asm_intarith(as, ir, XOg_X_IMUL); | 3989 | asm_intarith(as, ir, XOg_X_IMUL); |
3990 | break; | 3990 | break; |
3991 | case IR_DIV: asm_fparith(as, ir, XO_DIVSD); break; | 3991 | case IR_DIV: |
3992 | #if LJ_64 && LJ_HASFFI | ||
3993 | if (!irt_isnum(ir->t)) | ||
3994 | asm_arith64(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_divi64 : | ||
3995 | IRCALL_lj_carith_divu64); | ||
3996 | else | ||
3997 | #endif | ||
3998 | asm_fparith(as, ir, XO_DIVSD); | ||
3999 | break; | ||
4000 | case IR_MOD: | ||
4001 | #if LJ_64 && LJ_HASFFI | ||
4002 | asm_arith64(as, ir, irt_isi64(ir->t) ? IRCALL_lj_carith_modi64 : | ||
4003 | IRCALL_lj_carith_modu64); | ||
4004 | #else | ||
4005 | lua_assert(0); | ||
4006 | #endif | ||
4007 | break; | ||
3992 | 4008 | ||
3993 | case IR_NEG: | 4009 | case IR_NEG: |
3994 | if (irt_isnum(ir->t)) | 4010 | if (irt_isnum(ir->t)) |
@@ -4168,6 +4184,14 @@ static void asm_setup_regsp(ASMState *as, GCtrace *T) | |||
4168 | as->modset = RSET_SCRATCH; | 4184 | as->modset = RSET_SCRATCH; |
4169 | break; | 4185 | break; |
4170 | case IR_POWI: | 4186 | case IR_POWI: |
4187 | if (irt_isnum(ir->t)) { | ||
4188 | ir->prev = REGSP_HINT(RID_XMM0); | ||
4189 | if (inloop) | ||
4190 | as->modset |= RSET_RANGE(RID_XMM0, RID_XMM1+1)|RID2RSET(RID_EAX); | ||
4191 | continue; | ||
4192 | } | ||
4193 | /* fallthrough */ | ||
4194 | case IR_DIV: case IR_MOD: | ||
4171 | #if LJ_64 && LJ_HASFFI | 4195 | #if LJ_64 && LJ_HASFFI |
4172 | if (!irt_isnum(ir->t)) { | 4196 | if (!irt_isnum(ir->t)) { |
4173 | ir->prev = REGSP_HINT(RID_RET); | 4197 | ir->prev = REGSP_HINT(RID_RET); |
@@ -4176,10 +4200,7 @@ static void asm_setup_regsp(ASMState *as, GCtrace *T) | |||
4176 | continue; | 4200 | continue; |
4177 | } | 4201 | } |
4178 | #endif | 4202 | #endif |
4179 | ir->prev = REGSP_HINT(RID_XMM0); | 4203 | break; |
4180 | if (inloop) | ||
4181 | as->modset |= RSET_RANGE(RID_XMM0, RID_XMM1+1)|RID2RSET(RID_EAX); | ||
4182 | continue; | ||
4183 | case IR_FPMATH: | 4204 | case IR_FPMATH: |
4184 | if (ir->op2 == IRFPM_EXP2) { /* May be joined to lj_vm_pow_sse. */ | 4205 | if (ir->op2 == IRFPM_EXP2) { /* May be joined to lj_vm_pow_sse. */ |
4185 | ir->prev = REGSP_HINT(RID_XMM0); | 4206 | ir->prev = REGSP_HINT(RID_XMM0); |