|
@@ -979,7 +979,7 @@ static ARMIns asm_fxloadins(IRIns *ir)
|
|
|
case IRT_I16: return ARMI_LDRSH;
|
|
|
case IRT_U16: return ARMI_LDRH;
|
|
|
case IRT_NUM: lua_assert(!LJ_SOFTFP); return ARMI_VLDR_D;
|
|
|
- case IRT_FLOAT: if (!LJ_SOFTFP) return ARMI_VLDR_S;
|
|
|
+ case IRT_FLOAT: if (!LJ_SOFTFP) return ARMI_VLDR_S; /* fallthrough */
|
|
|
default: return ARMI_LDR;
|
|
|
}
|
|
|
}
|
|
@@ -990,7 +990,7 @@ static ARMIns asm_fxstoreins(IRIns *ir)
|
|
|
case IRT_I8: case IRT_U8: return ARMI_STRB;
|
|
|
case IRT_I16: case IRT_U16: return ARMI_STRH;
|
|
|
case IRT_NUM: lua_assert(!LJ_SOFTFP); return ARMI_VSTR_D;
|
|
|
- case IRT_FLOAT: if (!LJ_SOFTFP) return ARMI_VSTR_S;
|
|
|
+ case IRT_FLOAT: if (!LJ_SOFTFP) return ARMI_VSTR_S; /* fallthrough */
|
|
|
default: return ARMI_STR;
|
|
|
}
|
|
|
}
|
|
@@ -1412,14 +1412,29 @@ static void asm_intop(ASMState *as, IRIns *ir, ARMIns ai)
|
|
|
emit_dn(as, ai^m, dest, left);
|
|
|
}
|
|
|
|
|
|
-static void asm_intop_s(ASMState *as, IRIns *ir, ARMIns ai)
|
|
|
+/* Try to drop cmp r, #0. */
|
|
|
+static ARMIns asm_drop_cmp0(ASMState *as, ARMIns ai)
|
|
|
{
|
|
|
- if (as->flagmcp == as->mcp) { /* Drop cmp r, #0. */
|
|
|
+ if (as->flagmcp == as->mcp) {
|
|
|
+ uint32_t cc = (as->mcp[1] >> 28);
|
|
|
as->flagmcp = NULL;
|
|
|
- as->mcp++;
|
|
|
- ai |= ARMI_S;
|
|
|
+ if (cc <= CC_NE) {
|
|
|
+ as->mcp++;
|
|
|
+ ai |= ARMI_S;
|
|
|
+ } else if (cc == CC_GE) {
|
|
|
+ *++as->mcp ^= ((CC_GE^CC_PL) << 28);
|
|
|
+ ai |= ARMI_S;
|
|
|
+ } else if (cc == CC_LT) {
|
|
|
+ *++as->mcp ^= ((CC_LT^CC_MI) << 28);
|
|
|
+ ai |= ARMI_S;
|
|
|
+ } /* else: other conds don't work in general. */
|
|
|
}
|
|
|
- asm_intop(as, ir, ai);
|
|
|
+ return ai;
|
|
|
+}
|
|
|
+
|
|
|
+static void asm_intop_s(ASMState *as, IRIns *ir, ARMIns ai)
|
|
|
+{
|
|
|
+ asm_intop(as, ir, asm_drop_cmp0(as, ai));
|
|
|
}
|
|
|
|
|
|
static void asm_intneg(ASMState *as, IRIns *ir, ARMIns ai)
|
|
@@ -1514,20 +1529,7 @@ static void asm_neg(ASMState *as, IRIns *ir)
|
|
|
|
|
|
static void asm_bitop(ASMState *as, IRIns *ir, ARMIns ai)
|
|
|
{
|
|
|
- if (as->flagmcp == as->mcp) { /* Try to drop cmp r, #0. */
|
|
|
- uint32_t cc = (as->mcp[1] >> 28);
|
|
|
- as->flagmcp = NULL;
|
|
|
- if (cc <= CC_NE) {
|
|
|
- as->mcp++;
|
|
|
- ai |= ARMI_S;
|
|
|
- } else if (cc == CC_GE) {
|
|
|
- *++as->mcp ^= ((CC_GE^CC_PL) << 28);
|
|
|
- ai |= ARMI_S;
|
|
|
- } else if (cc == CC_LT) {
|
|
|
- *++as->mcp ^= ((CC_LT^CC_MI) << 28);
|
|
|
- ai |= ARMI_S;
|
|
|
- } /* else: other conds don't work with bit ops. */
|
|
|
- }
|
|
|
+ ai = asm_drop_cmp0(as, ai);
|
|
|
if (ir->op2 == 0) {
|
|
|
Reg dest = ra_dest(as, ir, RSET_GPR);
|
|
|
uint32_t m = asm_fuseopm(as, ai, ir->op1, RSET_GPR);
|