diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_asm_ppc.h | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h index 88869d9d..caef8fd7 100644 --- a/src/lj_asm_ppc.h +++ b/src/lj_asm_ppc.h | |||
@@ -156,6 +156,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow) | |||
156 | return ra_allock(as, ofs-(int16_t)ofs, allow); | 156 | return ra_allock(as, ofs-(int16_t)ofs, allow); |
157 | } | 157 | } |
158 | } | 158 | } |
159 | } else if (ir->o == IR_TMPREF) { | ||
160 | *ofsp = (int32_t)(offsetof(global_State, tmptv)-32768); | ||
161 | return RID_JGL; | ||
159 | } | 162 | } |
160 | } | 163 | } |
161 | *ofsp = 0; | 164 | *ofsp = 0; |
@@ -567,28 +570,54 @@ static void asm_strto(ASMState *as, IRIns *ir) | |||
567 | /* -- Memory references --------------------------------------------------- */ | 570 | /* -- Memory references --------------------------------------------------- */ |
568 | 571 | ||
569 | /* Get pointer to TValue. */ | 572 | /* Get pointer to TValue. */ |
570 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) | 573 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode) |
571 | { | 574 | { |
572 | IRIns *ir = IR(ref); | 575 | int32_t tmpofs = (int32_t)(offsetof(global_State, tmptv)-32768); |
573 | if (irt_isnum(ir->t)) { | 576 | if ((mode & IRTMPREF_IN1)) { |
574 | if (irref_isk(ref)) /* Use the number constant itself as a TValue. */ | 577 | IRIns *ir = IR(ref); |
575 | ra_allockreg(as, i32ptr(ir_knum(ir)), dest); | 578 | if (irt_isnum(ir->t)) { |
576 | else /* Otherwise force a spill and use the spill slot. */ | 579 | if ((mode & IRTMPREF_OUT1)) { |
577 | emit_tai(as, PPCI_ADDI, dest, RID_SP, ra_spill(as, ir)); | 580 | #if LJ_SOFTFP |
578 | } else { | 581 | lj_assertA(irref_isk(ref), "unsplit FP op"); |
579 | /* Otherwise use g->tmptv to hold the TValue. */ | 582 | emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs); |
580 | RegSet allow = rset_exclude(RSET_GPR, dest); | 583 | emit_setgl(as, |
581 | Reg type; | 584 | ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, RSET_GPR), |
582 | emit_tai(as, PPCI_ADDI, dest, RID_JGL, (int32_t)offsetof(global_State, tmptv)-32768); | 585 | tmptv.u32.lo); |
583 | if (!irt_ispri(ir->t)) { | 586 | emit_setgl(as, |
584 | Reg src = ra_alloc1(as, ref, allow); | 587 | ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, RSET_GPR), |
585 | emit_setgl(as, src, tmptv.gcr); | 588 | tmptv.u32.hi); |
589 | #else | ||
590 | Reg src = ra_alloc1(as, ref, RSET_FPR); | ||
591 | emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs); | ||
592 | emit_fai(as, PPCI_STFD, src, RID_JGL, tmpofs); | ||
593 | #endif | ||
594 | } else if (irref_isk(ref)) { | ||
595 | /* Use the number constant itself as a TValue. */ | ||
596 | ra_allockreg(as, i32ptr(ir_knum(ir)), dest); | ||
597 | } else { | ||
598 | #if LJ_SOFTFP | ||
599 | lj_assertA(0, "unsplit FP op"); | ||
600 | #else | ||
601 | /* Otherwise force a spill and use the spill slot. */ | ||
602 | emit_tai(as, PPCI_ADDI, dest, RID_SP, ra_spill(as, ir)); | ||
603 | #endif | ||
604 | } | ||
605 | } else { | ||
606 | /* Otherwise use g->tmptv to hold the TValue. */ | ||
607 | Reg type; | ||
608 | emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs); | ||
609 | if (!irt_ispri(ir->t)) { | ||
610 | Reg src = ra_alloc1(as, ref, RSET_GPR); | ||
611 | emit_setgl(as, src, tmptv.gcr); | ||
612 | } | ||
613 | if (LJ_SOFTFP && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)) | ||
614 | type = ra_alloc1(as, ref+1, RSET_GPR); | ||
615 | else | ||
616 | type = ra_allock(as, irt_toitype(ir->t), RSET_GPR); | ||
617 | emit_setgl(as, type, tmptv.it); | ||
586 | } | 618 | } |
587 | if (LJ_SOFTFP && (ir+1)->o == IR_HIOP) | 619 | } else { |
588 | type = ra_alloc1(as, ref+1, allow); | 620 | emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs); |
589 | else | ||
590 | type = ra_allock(as, irt_toitype(ir->t), allow); | ||
591 | emit_setgl(as, type, tmptv.it); | ||
592 | } | 621 | } |
593 | } | 622 | } |
594 | 623 | ||
@@ -1958,7 +1987,7 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
1958 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ | 1987 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ |
1959 | break; | 1988 | break; |
1960 | #if LJ_SOFTFP | 1989 | #if LJ_SOFTFP |
1961 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: | 1990 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: case IR_TMPREF: |
1962 | #endif | 1991 | #endif |
1963 | case IR_CNEWI: | 1992 | case IR_CNEWI: |
1964 | /* Nothing to do here. Handled by lo op itself. */ | 1993 | /* Nothing to do here. Handled by lo op itself. */ |