FFI: Cleanup/fix 64 bit arithmetic in assembler backend.

This commit is contained in:
Mike Pall 2011-10-22 02:02:51 +02:00
parent 2e5c0870bc
commit fee957b22d
2 changed files with 31 additions and 33 deletions

View File

@ -932,12 +932,18 @@ static void asm_cnew(ASMState *as, IRIns *ir)
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
IRRef args[2];
RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
RegSet drop = RSET_SCRATCH;
lua_assert(sz != CTSIZE_INVALID);
args[0] = ASMREF_L; /* lua_State *L */
args[1] = ASMREF_TMP1; /* MSize size */
as->gcsteps++;
asm_setupresult(as, ir, ci); /* GCcdata * */
if (ra_hasreg(ir->r))
rset_clear(drop, ir->r); /* Dest reg handled below. */
ra_evictset(as, drop);
if (ra_used(ir))
ra_destreg(as, ir, RID_RET); /* GCcdata * */
/* Initialize immutable cdata object. */
if (ir->o == IR_CNEWI) {
@ -1360,42 +1366,28 @@ static void asm_hiop(ASMState *as, IRIns *ir)
asm_fpcomp(as, ir-1);
return;
} else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
if (uselo || usehi || !(as->flags & JIT_F_OPT_DCE)) {
as->curins--; /* Always skip the loword min/max. */
as->curins--; /* Always skip the loword min/max. */
if (uselo || usehi)
asm_fpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_HI : CC_LO);
}
return;
}
if (!usehi && (as->flags & JIT_F_OPT_DCE))
return; /* Skip unused hiword op for all remaining ops. */
if (!usehi) return; /* Skip unused hiword op for all remaining ops. */
switch ((ir-1)->o) {
#if LJ_HASFFI
case IR_ADD:
if (uselo) {
as->curins--;
asm_intop(as, ir, ARMI_ADC);
asm_intop(as, ir-1, ARMI_ADD|ARMI_S);
} else {
asm_intop(as, ir, ARMI_ADD);
}
as->curins--;
asm_intop(as, ir, ARMI_ADC);
asm_intop(as, ir-1, ARMI_ADD|ARMI_S);
break;
case IR_SUB:
if (uselo) {
as->curins--;
asm_intop(as, ir, ARMI_SBC);
asm_intop(as, ir-1, ARMI_SUB|ARMI_S);
} else {
asm_intop(as, ir, ARMI_SUB);
}
as->curins--;
asm_intop(as, ir, ARMI_SBC);
asm_intop(as, ir-1, ARMI_SUB|ARMI_S);
break;
case IR_NEG:
if (uselo) {
as->curins--;
asm_intneg(as, ir, ARMI_RSC);
asm_intneg(as, ir-1, ARMI_RSB|ARMI_S);
} else {
asm_intneg(as, ir, ARMI_RSB);
}
as->curins--;
asm_intneg(as, ir, ARMI_RSC);
asm_intneg(as, ir-1, ARMI_RSB|ARMI_S);
break;
#endif
case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:

View File

@ -2160,19 +2160,25 @@ static void asm_hiop(ASMState *as, IRIns *ir)
if (!usehi) return; /* Skip unused hiword op for all remaining ops. */
switch ((ir-1)->o) {
case IR_ADD:
asm_intarith(as, ir, uselo ? XOg_ADC : XOg_ADD);
as->flagmcp = NULL;
as->curins--;
asm_intarith(as, ir, XOg_ADC);
asm_intarith(as, ir-1, XOg_ADD);
break;
case IR_SUB:
asm_intarith(as, ir, uselo ? XOg_SBB : XOg_SUB);
as->flagmcp = NULL;
as->curins--;
asm_intarith(as, ir, XOg_SBB);
asm_intarith(as, ir-1, XOg_SUB);
break;
case IR_NEG: {
Reg dest = ra_dest(as, ir, RSET_GPR);
emit_rr(as, XO_GROUP3, XOg_NEG, dest);
if (uselo) {
emit_i8(as, 0);
emit_rr(as, XO_ARITHi8, XOg_ADC, dest);
}
emit_i8(as, 0);
emit_rr(as, XO_ARITHi8, XOg_ADC, dest);
ra_left(as, dest, ir->op1);
as->curins--;
asm_neg_not(as, ir-1, XOg_NEG);
break;
}
case IR_CALLN: