diff options
-rw-r--r-- | src/lj_asm.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 2f00749b..e028ab4f 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -448,7 +448,7 @@ static void ra_evictset(ASMState *as, RegSet drop) | |||
448 | as->modset |= drop; | 448 | as->modset |= drop; |
449 | drop &= ~as->freeset; | 449 | drop &= ~as->freeset; |
450 | while (drop) { | 450 | while (drop) { |
451 | Reg r = rset_picktop(drop); | 451 | Reg r = rset_pickbot(drop); |
452 | ra_restore(as, regcost_ref(as->cost[r])); | 452 | ra_restore(as, regcost_ref(as->cost[r])); |
453 | rset_clear(drop, r); | 453 | rset_clear(drop, r); |
454 | checkmclim(as); | 454 | checkmclim(as); |
@@ -604,7 +604,14 @@ static Reg ra_dest(ASMState *as, IRIns *ir, RegSet allow) | |||
604 | ra_free(as, dest); | 604 | ra_free(as, dest); |
605 | ra_modified(as, dest); | 605 | ra_modified(as, dest); |
606 | } else { | 606 | } else { |
607 | dest = ra_scratch(as, allow); | 607 | if (ra_hashint(dest) && rset_test(as->freeset, ra_gethint(dest))) { |
608 | dest = ra_gethint(dest); | ||
609 | ra_modified(as, dest); | ||
610 | RA_DBGX((as, "dest $r", dest)); | ||
611 | } else { | ||
612 | dest = ra_scratch(as, allow); | ||
613 | } | ||
614 | ir->r = dest; | ||
608 | } | 615 | } |
609 | if (LJ_UNLIKELY(ra_hasspill(ir->s))) ra_save(as, ir, dest); | 616 | if (LJ_UNLIKELY(ra_hasspill(ir->s))) ra_save(as, ir, dest); |
610 | return dest; | 617 | return dest; |
@@ -932,7 +939,7 @@ static void asm_phi_shuffle(ASMState *as) | |||
932 | RegSet blockedby = RSET_EMPTY; | 939 | RegSet blockedby = RSET_EMPTY; |
933 | RegSet phiset = as->phiset; | 940 | RegSet phiset = as->phiset; |
934 | while (phiset) { /* Check all left PHI operand registers. */ | 941 | while (phiset) { /* Check all left PHI operand registers. */ |
935 | Reg r = rset_picktop(phiset); | 942 | Reg r = rset_pickbot(phiset); |
936 | IRIns *irl = IR(as->phireg[r]); | 943 | IRIns *irl = IR(as->phireg[r]); |
937 | Reg left = irl->r; | 944 | Reg left = irl->r; |
938 | if (r != left) { /* Mismatch? */ | 945 | if (r != left) { /* Mismatch? */ |
@@ -966,7 +973,7 @@ static void asm_phi_shuffle(ASMState *as) | |||
966 | /* Restore/remat invariants whose registers are modified inside the loop. */ | 973 | /* Restore/remat invariants whose registers are modified inside the loop. */ |
967 | work = as->modset & ~(as->freeset | as->phiset); | 974 | work = as->modset & ~(as->freeset | as->phiset); |
968 | while (work) { | 975 | while (work) { |
969 | Reg r = rset_picktop(work); | 976 | Reg r = rset_pickbot(work); |
970 | ra_restore(as, regcost_ref(as->cost[r])); | 977 | ra_restore(as, regcost_ref(as->cost[r])); |
971 | rset_clear(work, r); | 978 | rset_clear(work, r); |
972 | checkmclim(as); | 979 | checkmclim(as); |
@@ -1311,6 +1318,9 @@ static void asm_setup_regsp(ASMState *as) | |||
1311 | GCtrace *T = as->T; | 1318 | GCtrace *T = as->T; |
1312 | IRRef i, nins; | 1319 | IRRef i, nins; |
1313 | int inloop; | 1320 | int inloop; |
1321 | #if LJ_TARGET_ARM | ||
1322 | uint32_t rload = 0xa6402a64; | ||
1323 | #endif | ||
1314 | 1324 | ||
1315 | ra_setup(as); | 1325 | ra_setup(as); |
1316 | 1326 | ||
@@ -1353,7 +1363,20 @@ static void asm_setup_regsp(ASMState *as) | |||
1353 | continue; | 1363 | continue; |
1354 | } | 1364 | } |
1355 | } | 1365 | } |
1366 | #if LJ_TARGET_ARM | ||
1367 | if ((ir->op2 & IRSLOAD_TYPECHECK) || (ir+1)->o == IR_HIOP) { | ||
1368 | ir->prev = (uint16_t)REGSP_HINT((rload & 15)); | ||
1369 | rload = lj_ror(rload, 4); | ||
1370 | continue; | ||
1371 | } | ||
1372 | #endif | ||
1356 | break; | 1373 | break; |
1374 | #if LJ_TARGET_ARM | ||
1375 | case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD: | ||
1376 | ir->prev = (uint16_t)REGSP_HINT((rload & 15)); | ||
1377 | rload = lj_ror(rload, 4); | ||
1378 | continue; | ||
1379 | #endif | ||
1357 | case IR_CALLXS: { | 1380 | case IR_CALLXS: { |
1358 | CCallInfo ci; | 1381 | CCallInfo ci; |
1359 | ci.flags = asm_callx_flags(as, ir); | 1382 | ci.flags = asm_callx_flags(as, ir); |
@@ -1384,6 +1407,14 @@ static void asm_setup_regsp(ASMState *as) | |||
1384 | continue; | 1407 | continue; |
1385 | } | 1408 | } |
1386 | } | 1409 | } |
1410 | #if LJ_TARGET_ARM | ||
1411 | /* fallthrough */ | ||
1412 | case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD: | ||
1413 | if (ra_hashint((ir-1)->r)) { | ||
1414 | ir->prev = (ir-1)->prev + 1; | ||
1415 | continue; | ||
1416 | } | ||
1417 | #endif | ||
1387 | break; | 1418 | break; |
1388 | #endif | 1419 | #endif |
1389 | case IR_CALLN: case IR_CALLXS: | 1420 | case IR_CALLN: case IR_CALLXS: |