diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_asm_arm.h | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h index 8574a2b3..618bc5b7 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h | |||
| @@ -339,18 +339,27 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
| 339 | { | 339 | { |
| 340 | uint32_t n, nargs = CCI_NARGS(ci); | 340 | uint32_t n, nargs = CCI_NARGS(ci); |
| 341 | int32_t ofs = 0; | 341 | int32_t ofs = 0; |
| 342 | #if LJ_SOFTFP | ||
| 342 | Reg gpr = REGARG_FIRSTGPR; | 343 | Reg gpr = REGARG_FIRSTGPR; |
| 343 | #if !LJ_SOFTFP | 344 | #else |
| 344 | Reg fpr = REGARG_FIRSTFPR, fprodd = 0; | 345 | Reg gpr, fpr = REGARG_FIRSTFPR, fprodd = 0; |
| 345 | #endif | 346 | #endif |
| 346 | if ((void *)ci->func) | 347 | if ((void *)ci->func) |
| 347 | emit_call(as, (void *)ci->func); | 348 | emit_call(as, (void *)ci->func); |
| 349 | #if !LJ_SOFTFP | ||
| 350 | for (gpr = REGARG_FIRSTGPR; gpr <= REGARG_LASTGPR; gpr++) | ||
| 351 | as->cost[gpr] = REGCOST(~0u, 0u); | ||
| 352 | gpr = REGARG_FIRSTGPR; | ||
| 353 | #endif | ||
| 348 | for (n = 0; n < nargs; n++) { /* Setup args. */ | 354 | for (n = 0; n < nargs; n++) { /* Setup args. */ |
| 349 | IRRef ref = args[n]; | 355 | IRRef ref = args[n]; |
| 350 | IRIns *ir = IR(ref); | 356 | IRIns *ir = IR(ref); |
| 351 | #if !LJ_SOFTFP | 357 | #if !LJ_SOFTFP |
| 352 | if (irt_isfp(ir->t)) { | 358 | if (irt_isfp(ir->t)) { |
| 359 | RegSet of = as->freeset; | ||
| 353 | Reg src; | 360 | Reg src; |
| 361 | /* Workaround to protect argument GPRs from being used for remat. */ | ||
| 362 | as->freeset &= ~RSET_RANGE(REGARG_FIRSTGPR, REGARG_LASTGPR+1); | ||
| 354 | if (!LJ_ABI_SOFTFP && !(ci->flags & CCI_VARARG)) { | 363 | if (!LJ_ABI_SOFTFP && !(ci->flags & CCI_VARARG)) { |
| 355 | if (irt_isnum(ir->t)) { | 364 | if (irt_isnum(ir->t)) { |
| 356 | if (fpr <= REGARG_LASTFPR) { | 365 | if (fpr <= REGARG_LASTFPR) { |
| @@ -368,15 +377,17 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
| 368 | fprodd = fpr++; | 377 | fprodd = fpr++; |
| 369 | continue; | 378 | continue; |
| 370 | } | 379 | } |
| 371 | src = ra_alloc1(as, ref, RSET_FPR); | 380 | src = ra_alloc1(as, ref, RSET_FPR); /* May alloc GPR to remat FPR. */ |
| 372 | fprodd = 0; | 381 | fprodd = 0; |
| 373 | goto stackfp; | 382 | goto stackfp; |
| 374 | } | 383 | } |
| 375 | src = ra_alloc1(as, ref, RSET_FPR); | 384 | src = ra_alloc1(as, ref, RSET_FPR); /* May alloc GPR to remat FPR. */ |
| 385 | as->freeset |= (of & RSET_RANGE(REGARG_FIRSTGPR, REGARG_LASTGPR+1)); | ||
| 376 | if (irt_isnum(ir->t)) gpr = (gpr+1) & ~1u; | 386 | if (irt_isnum(ir->t)) gpr = (gpr+1) & ~1u; |
| 377 | if (gpr <= REGARG_LASTGPR) { | 387 | if (gpr <= REGARG_LASTGPR) { |
| 378 | lua_assert(rset_test(as->freeset, gpr)); /* Must have been evicted. */ | 388 | lua_assert(rset_test(as->freeset, gpr)); /* Must have been evicted. */ |
| 379 | if (irt_isnum(ir->t)) { | 389 | if (irt_isnum(ir->t)) { |
| 390 | lua_assert(rset_test(as->freeset, gpr+1)); /* Ditto. */ | ||
| 380 | emit_dnm(as, ARMI_VMOV_RR_D, gpr, gpr+1, (src & 15)); | 391 | emit_dnm(as, ARMI_VMOV_RR_D, gpr, gpr+1, (src & 15)); |
| 381 | gpr += 2; | 392 | gpr += 2; |
| 382 | } else { | 393 | } else { |
