aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lj_arch.h1
-rw-r--r--src/lj_asm_ppc.h321
2 files changed, 278 insertions, 44 deletions
diff --git a/src/lj_arch.h b/src/lj_arch.h
index 0145a7c0..5962f3af 100644
--- a/src/lj_arch.h
+++ b/src/lj_arch.h
@@ -273,7 +273,6 @@
273#endif 273#endif
274 274
275#if LJ_ABI_SOFTFP 275#if LJ_ABI_SOFTFP
276#define LJ_ARCH_NOJIT 1 /* NYI */
277#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL 276#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL
278#else 277#else
279#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE 278#define LJ_ARCH_NUMMODE LJ_NUMMODE_DUAL_SINGLE
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h
index 6daa861b..1955429f 100644
--- a/src/lj_asm_ppc.h
+++ b/src/lj_asm_ppc.h
@@ -226,6 +226,7 @@ static void asm_fusexrefx(ASMState *as, PPCIns pi, Reg rt, IRRef ref,
226 emit_tab(as, pi, rt, left, right); 226 emit_tab(as, pi, rt, left, right);
227} 227}
228 228
229#if !LJ_SOFTFP
229/* Fuse to multiply-add/sub instruction. */ 230/* Fuse to multiply-add/sub instruction. */
230static int asm_fusemadd(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pir) 231static int asm_fusemadd(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pir)
231{ 232{
@@ -245,6 +246,7 @@ static int asm_fusemadd(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pir)
245 } 246 }
246 return 0; 247 return 0;
247} 248}
249#endif
248 250
249/* -- Calls --------------------------------------------------------------- */ 251/* -- Calls --------------------------------------------------------------- */
250 252
@@ -253,13 +255,17 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
253{ 255{
254 uint32_t n, nargs = CCI_XNARGS(ci); 256 uint32_t n, nargs = CCI_XNARGS(ci);
255 int32_t ofs = 8; 257 int32_t ofs = 8;
256 Reg gpr = REGARG_FIRSTGPR, fpr = REGARG_FIRSTFPR; 258 Reg gpr = REGARG_FIRSTGPR;
259#if !LJ_SOFTFP
260 Reg fpr = REGARG_FIRSTFPR;
261#endif
257 if ((void *)ci->func) 262 if ((void *)ci->func)
258 emit_call(as, (void *)ci->func); 263 emit_call(as, (void *)ci->func);
259 for (n = 0; n < nargs; n++) { /* Setup args. */ 264 for (n = 0; n < nargs; n++) { /* Setup args. */
260 IRRef ref = args[n]; 265 IRRef ref = args[n];
261 if (ref) { 266 if (ref) {
262 IRIns *ir = IR(ref); 267 IRIns *ir = IR(ref);
268#if !LJ_SOFTFP
263 if (irt_isfp(ir->t)) { 269 if (irt_isfp(ir->t)) {
264 if (fpr <= REGARG_LASTFPR) { 270 if (fpr <= REGARG_LASTFPR) {
265 lua_assert(rset_test(as->freeset, fpr)); /* Already evicted. */ 271 lua_assert(rset_test(as->freeset, fpr)); /* Already evicted. */
@@ -271,7 +277,9 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
271 emit_spstore(as, ir, r, ofs); 277 emit_spstore(as, ir, r, ofs);
272 ofs += irt_isnum(ir->t) ? 8 : 4; 278 ofs += irt_isnum(ir->t) ? 8 : 4;
273 } 279 }
274 } else { 280 } else
281#endif
282 {
275 if (gpr <= REGARG_LASTGPR) { 283 if (gpr <= REGARG_LASTGPR) {
276 lua_assert(rset_test(as->freeset, gpr)); /* Already evicted. */ 284 lua_assert(rset_test(as->freeset, gpr)); /* Already evicted. */
277 ra_leftov(as, gpr, ref); 285 ra_leftov(as, gpr, ref);
@@ -290,8 +298,10 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
290 } 298 }
291 checkmclim(as); 299 checkmclim(as);
292 } 300 }
301#if !LJ_SOFTFP
293 if ((ci->flags & CCI_VARARG)) /* Vararg calls need to know about FPR use. */ 302 if ((ci->flags & CCI_VARARG)) /* Vararg calls need to know about FPR use. */
294 emit_tab(as, fpr == REGARG_FIRSTFPR ? PPCI_CRXOR : PPCI_CREQV, 6, 6, 6); 303 emit_tab(as, fpr == REGARG_FIRSTFPR ? PPCI_CRXOR : PPCI_CREQV, 6, 6, 6);
304#endif
295} 305}
296 306
297/* Setup result reg/sp for call. Evict scratch regs. */ 307/* Setup result reg/sp for call. Evict scratch regs. */
@@ -299,8 +309,10 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
299{ 309{
300 RegSet drop = RSET_SCRATCH; 310 RegSet drop = RSET_SCRATCH;
301 int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)); 311 int hiop = ((ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t));
312#if !LJ_SOFTFP
302 if ((ci->flags & CCI_NOFPRCLOBBER)) 313 if ((ci->flags & CCI_NOFPRCLOBBER))
303 drop &= ~RSET_FPR; 314 drop &= ~RSET_FPR;
315#endif
304 if (ra_hasreg(ir->r)) 316 if (ra_hasreg(ir->r))
305 rset_clear(drop, ir->r); /* Dest reg handled below. */ 317 rset_clear(drop, ir->r); /* Dest reg handled below. */
306 if (hiop && ra_hasreg((ir+1)->r)) 318 if (hiop && ra_hasreg((ir+1)->r))
@@ -308,7 +320,7 @@ static void asm_setupresult(ASMState *as, IRIns *ir, const CCallInfo *ci)
308 ra_evictset(as, drop); /* Evictions must be performed first. */ 320 ra_evictset(as, drop); /* Evictions must be performed first. */
309 if (ra_used(ir)) { 321 if (ra_used(ir)) {
310 lua_assert(!irt_ispri(ir->t)); 322 lua_assert(!irt_ispri(ir->t));
311 if (irt_isfp(ir->t)) { 323 if (!LJ_SOFTFP && irt_isfp(ir->t)) {
312 if ((ci->flags & CCI_CASTU64)) { 324 if ((ci->flags & CCI_CASTU64)) {
313 /* Use spill slot or temp slots. */ 325 /* Use spill slot or temp slots. */
314 int32_t ofs = ir->s ? sps_scale(ir->s) : SPOFS_TMP; 326 int32_t ofs = ir->s ? sps_scale(ir->s) : SPOFS_TMP;
@@ -377,6 +389,7 @@ static void asm_retf(ASMState *as, IRIns *ir)
377 389
378/* -- Type conversions ---------------------------------------------------- */ 390/* -- Type conversions ---------------------------------------------------- */
379 391
392#if !LJ_SOFTFP
380static void asm_tointg(ASMState *as, IRIns *ir, Reg left) 393static void asm_tointg(ASMState *as, IRIns *ir, Reg left)
381{ 394{
382 RegSet allow = RSET_FPR; 395 RegSet allow = RSET_FPR;
@@ -409,15 +422,23 @@ static void asm_tobit(ASMState *as, IRIns *ir)
409 emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP); 422 emit_fai(as, PPCI_STFD, tmp, RID_SP, SPOFS_TMP);
410 emit_fab(as, PPCI_FADD, tmp, left, right); 423 emit_fab(as, PPCI_FADD, tmp, left, right);
411} 424}
425#endif
412 426
413static void asm_conv(ASMState *as, IRIns *ir) 427static void asm_conv(ASMState *as, IRIns *ir)
414{ 428{
415 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); 429 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
430#if !LJ_SOFTFP
416 int stfp = (st == IRT_NUM || st == IRT_FLOAT); 431 int stfp = (st == IRT_NUM || st == IRT_FLOAT);
432#endif
417 IRRef lref = ir->op1; 433 IRRef lref = ir->op1;
418 lua_assert(irt_type(ir->t) != st);
419 lua_assert(!(irt_isint64(ir->t) || 434 lua_assert(!(irt_isint64(ir->t) ||
420 (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */ 435 (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */
436#if LJ_SOFTFP
437 /* FP conversions are handled by SPLIT. */
438 lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT));
439 /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */
440#else
441 lua_assert(irt_type(ir->t) != st);
421 if (irt_isfp(ir->t)) { 442 if (irt_isfp(ir->t)) {
422 Reg dest = ra_dest(as, ir, RSET_FPR); 443 Reg dest = ra_dest(as, ir, RSET_FPR);
423 if (stfp) { /* FP to FP conversion. */ 444 if (stfp) { /* FP to FP conversion. */
@@ -476,7 +497,9 @@ static void asm_conv(ASMState *as, IRIns *ir)
476 emit_fb(as, PPCI_FCTIWZ, tmp, left); 497 emit_fb(as, PPCI_FCTIWZ, tmp, left);
477 } 498 }
478 } 499 }
479 } else { 500 } else
501#endif
502 {
480 Reg dest = ra_dest(as, ir, RSET_GPR); 503 Reg dest = ra_dest(as, ir, RSET_GPR);
481 if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */ 504 if (st >= IRT_I8 && st <= IRT_U16) { /* Extend to 32 bit integer. */
482 Reg left = ra_alloc1(as, ir->op1, RSET_GPR); 505 Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
@@ -496,17 +519,41 @@ static void asm_strto(ASMState *as, IRIns *ir)
496{ 519{
497 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_strscan_num]; 520 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_strscan_num];
498 IRRef args[2]; 521 IRRef args[2];
499 int32_t ofs; 522 int32_t ofs = SPOFS_TMP;
523#if LJ_SOFTFP
524 ra_evictset(as, RSET_SCRATCH);
525 if (ra_used(ir)) {
526 if (ra_hasspill(ir->s) && ra_hasspill((ir+1)->s) &&
527 (ir->s & 1) == LJ_BE && (ir->s ^ 1) == (ir+1)->s) {
528 int i;
529 for (i = 0; i < 2; i++) {
530 Reg r = (ir+i)->r;
531 if (ra_hasreg(r)) {
532 ra_free(as, r);
533 ra_modified(as, r);
534 emit_spload(as, ir+i, r, sps_scale((ir+i)->s));
535 }
536 }
537 ofs = sps_scale(ir->s & ~1);
538 } else {
539 Reg rhi = ra_dest(as, ir+1, RSET_GPR);
540 Reg rlo = ra_dest(as, ir, rset_exclude(RSET_GPR, rhi));
541 emit_tai(as, PPCI_LWZ, rhi, RID_SP, ofs);
542 emit_tai(as, PPCI_LWZ, rlo, RID_SP, ofs+4);
543 }
544 }
545#else
500 RegSet drop = RSET_SCRATCH; 546 RegSet drop = RSET_SCRATCH;
501 if (ra_hasreg(ir->r)) rset_set(drop, ir->r); /* Spill dest reg (if any). */ 547 if (ra_hasreg(ir->r)) rset_set(drop, ir->r); /* Spill dest reg (if any). */
502 ra_evictset(as, drop); 548 ra_evictset(as, drop);
549 if (ir->s) ofs = sps_scale(ir->s);
550#endif
503 asm_guardcc(as, CC_EQ); 551 asm_guardcc(as, CC_EQ);
504 emit_ai(as, PPCI_CMPWI, RID_RET, 0); /* Test return status. */ 552 emit_ai(as, PPCI_CMPWI, RID_RET, 0); /* Test return status. */
505 args[0] = ir->op1; /* GCstr *str */ 553 args[0] = ir->op1; /* GCstr *str */
506 args[1] = ASMREF_TMP1; /* TValue *n */ 554 args[1] = ASMREF_TMP1; /* TValue *n */
507 asm_gencall(as, ci, args); 555 asm_gencall(as, ci, args);
508 /* Store the result to the spill slot or temp slots. */ 556 /* Store the result to the spill slot or temp slots. */
509 ofs = ir->s ? sps_scale(ir->s) : SPOFS_TMP;
510 emit_tai(as, PPCI_ADDI, ra_releasetmp(as, ASMREF_TMP1), RID_SP, ofs); 557 emit_tai(as, PPCI_ADDI, ra_releasetmp(as, ASMREF_TMP1), RID_SP, ofs);
511} 558}
512 559
@@ -530,7 +577,10 @@ static void asm_tvptr(ASMState *as, Reg dest, IRRef ref)
530 Reg src = ra_alloc1(as, ref, allow); 577 Reg src = ra_alloc1(as, ref, allow);
531 emit_setgl(as, src, tmptv.gcr); 578 emit_setgl(as, src, tmptv.gcr);
532 } 579 }
533 type = ra_allock(as, irt_toitype(ir->t), allow); 580 if (LJ_SOFTFP && (ir+1)->o == IR_HIOP)
581 type = ra_alloc1(as, ref+1, allow);
582 else
583 type = ra_allock(as, irt_toitype(ir->t), allow);
534 emit_setgl(as, type, tmptv.it); 584 emit_setgl(as, type, tmptv.it);
535 } 585 }
536} 586}
@@ -574,11 +624,27 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
574 Reg tisnum = RID_NONE, tmpnum = RID_NONE; 624 Reg tisnum = RID_NONE, tmpnum = RID_NONE;
575 IRRef refkey = ir->op2; 625 IRRef refkey = ir->op2;
576 IRIns *irkey = IR(refkey); 626 IRIns *irkey = IR(refkey);
627 int isk = irref_isk(refkey);
577 IRType1 kt = irkey->t; 628 IRType1 kt = irkey->t;
578 uint32_t khash; 629 uint32_t khash;
579 MCLabel l_end, l_loop, l_next; 630 MCLabel l_end, l_loop, l_next;
580 631
581 rset_clear(allow, tab); 632 rset_clear(allow, tab);
633#if LJ_SOFTFP
634 if (!isk) {
635 key = ra_alloc1(as, refkey, allow);
636 rset_clear(allow, key);
637 if (irkey[1].o == IR_HIOP) {
638 if (ra_hasreg((irkey+1)->r)) {
639 tmpnum = (irkey+1)->r;
640 ra_noweak(as, tmpnum);
641 } else {
642 tmpnum = ra_allocref(as, refkey+1, allow);
643 }
644 rset_clear(allow, tmpnum);
645 }
646 }
647#else
582 if (irt_isnum(kt)) { 648 if (irt_isnum(kt)) {
583 key = ra_alloc1(as, refkey, RSET_FPR); 649 key = ra_alloc1(as, refkey, RSET_FPR);
584 tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key)); 650 tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key));
@@ -588,6 +654,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
588 key = ra_alloc1(as, refkey, allow); 654 key = ra_alloc1(as, refkey, allow);
589 rset_clear(allow, key); 655 rset_clear(allow, key);
590 } 656 }
657#endif
591 tmp2 = ra_scratch(as, allow); 658 tmp2 = ra_scratch(as, allow);
592 rset_clear(allow, tmp2); 659 rset_clear(allow, tmp2);
593 660
@@ -610,7 +677,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
610 asm_guardcc(as, CC_EQ); 677 asm_guardcc(as, CC_EQ);
611 else 678 else
612 emit_condbranch(as, PPCI_BC|PPCF_Y, CC_EQ, l_end); 679 emit_condbranch(as, PPCI_BC|PPCF_Y, CC_EQ, l_end);
613 if (irt_isnum(kt)) { 680 if (!LJ_SOFTFP && irt_isnum(kt)) {
614 emit_fab(as, PPCI_FCMPU, 0, tmpnum, key); 681 emit_fab(as, PPCI_FCMPU, 0, tmpnum, key);
615 emit_condbranch(as, PPCI_BC, CC_GE, l_next); 682 emit_condbranch(as, PPCI_BC, CC_GE, l_next);
616 emit_ab(as, PPCI_CMPLW, tmp1, tisnum); 683 emit_ab(as, PPCI_CMPLW, tmp1, tisnum);
@@ -620,7 +687,10 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
620 emit_ab(as, PPCI_CMPW, tmp2, key); 687 emit_ab(as, PPCI_CMPW, tmp2, key);
621 emit_condbranch(as, PPCI_BC, CC_NE, l_next); 688 emit_condbranch(as, PPCI_BC, CC_NE, l_next);
622 } 689 }
623 emit_ai(as, PPCI_CMPWI, tmp1, irt_toitype(irkey->t)); 690 if (LJ_SOFTFP && ra_hasreg(tmpnum))
691 emit_ab(as, PPCI_CMPW, tmp1, tmpnum);
692 else
693 emit_ai(as, PPCI_CMPWI, tmp1, irt_toitype(irkey->t));
624 if (!irt_ispri(kt)) 694 if (!irt_ispri(kt))
625 emit_tai(as, PPCI_LWZ, tmp2, dest, (int32_t)offsetof(Node, key.gcr)); 695 emit_tai(as, PPCI_LWZ, tmp2, dest, (int32_t)offsetof(Node, key.gcr));
626 } 696 }
@@ -629,19 +699,19 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
629 (((char *)as->mcp-(char *)l_loop) & 0xffffu); 699 (((char *)as->mcp-(char *)l_loop) & 0xffffu);
630 700
631 /* Load main position relative to tab->node into dest. */ 701 /* Load main position relative to tab->node into dest. */
632 khash = irref_isk(refkey) ? ir_khash(irkey) : 1; 702 khash = isk ? ir_khash(irkey) : 1;
633 if (khash == 0) { 703 if (khash == 0) {
634 emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node)); 704 emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node));
635 } else { 705 } else {
636 Reg tmphash = tmp1; 706 Reg tmphash = tmp1;
637 if (irref_isk(refkey)) 707 if (isk)
638 tmphash = ra_allock(as, khash, allow); 708 tmphash = ra_allock(as, khash, allow);
639 emit_tab(as, PPCI_ADD, dest, dest, tmp1); 709 emit_tab(as, PPCI_ADD, dest, dest, tmp1);
640 emit_tai(as, PPCI_MULLI, tmp1, tmp1, sizeof(Node)); 710 emit_tai(as, PPCI_MULLI, tmp1, tmp1, sizeof(Node));
641 emit_asb(as, PPCI_AND, tmp1, tmp2, tmphash); 711 emit_asb(as, PPCI_AND, tmp1, tmp2, tmphash);
642 emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node)); 712 emit_tai(as, PPCI_LWZ, dest, tab, (int32_t)offsetof(GCtab, node));
643 emit_tai(as, PPCI_LWZ, tmp2, tab, (int32_t)offsetof(GCtab, hmask)); 713 emit_tai(as, PPCI_LWZ, tmp2, tab, (int32_t)offsetof(GCtab, hmask));
644 if (irref_isk(refkey)) { 714 if (isk) {
645 /* Nothing to do. */ 715 /* Nothing to do. */
646 } else if (irt_isstr(kt)) { 716 } else if (irt_isstr(kt)) {
647 emit_tai(as, PPCI_LWZ, tmp1, key, (int32_t)offsetof(GCstr, hash)); 717 emit_tai(as, PPCI_LWZ, tmp1, key, (int32_t)offsetof(GCstr, hash));
@@ -651,13 +721,19 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge)
651 emit_asb(as, PPCI_XOR, tmp1, tmp1, tmp2); 721 emit_asb(as, PPCI_XOR, tmp1, tmp1, tmp2);
652 emit_rotlwi(as, tmp1, tmp1, (HASH_ROT2+HASH_ROT1)&31); 722 emit_rotlwi(as, tmp1, tmp1, (HASH_ROT2+HASH_ROT1)&31);
653 emit_tab(as, PPCI_SUBF, tmp2, dest, tmp2); 723 emit_tab(as, PPCI_SUBF, tmp2, dest, tmp2);
654 if (irt_isnum(kt)) { 724 if (LJ_SOFTFP ? (irkey[1].o == IR_HIOP) : irt_isnum(kt)) {
725#if LJ_SOFTFP
726 emit_asb(as, PPCI_XOR, tmp2, key, tmp1);
727 emit_rotlwi(as, dest, tmp1, HASH_ROT1);
728 emit_tab(as, PPCI_ADD, tmp1, tmpnum, tmpnum);
729#else
655 int32_t ofs = ra_spill(as, irkey); 730 int32_t ofs = ra_spill(as, irkey);
656 emit_asb(as, PPCI_XOR, tmp2, tmp2, tmp1); 731 emit_asb(as, PPCI_XOR, tmp2, tmp2, tmp1);
657 emit_rotlwi(as, dest, tmp1, HASH_ROT1); 732 emit_rotlwi(as, dest, tmp1, HASH_ROT1);
658 emit_tab(as, PPCI_ADD, tmp1, tmp1, tmp1); 733 emit_tab(as, PPCI_ADD, tmp1, tmp1, tmp1);
659 emit_tai(as, PPCI_LWZ, tmp2, RID_SP, ofs+4); 734 emit_tai(as, PPCI_LWZ, tmp2, RID_SP, ofs+4);
660 emit_tai(as, PPCI_LWZ, tmp1, RID_SP, ofs); 735 emit_tai(as, PPCI_LWZ, tmp1, RID_SP, ofs);
736#endif
661 } else { 737 } else {
662 emit_asb(as, PPCI_XOR, tmp2, key, tmp1); 738 emit_asb(as, PPCI_XOR, tmp2, key, tmp1);
663 emit_rotlwi(as, dest, tmp1, HASH_ROT1); 739 emit_rotlwi(as, dest, tmp1, HASH_ROT1);
@@ -784,8 +860,8 @@ static PPCIns asm_fxloadins(IRIns *ir)
784 case IRT_U8: return PPCI_LBZ; 860 case IRT_U8: return PPCI_LBZ;
785 case IRT_I16: return PPCI_LHA; 861 case IRT_I16: return PPCI_LHA;
786 case IRT_U16: return PPCI_LHZ; 862 case IRT_U16: return PPCI_LHZ;
787 case IRT_NUM: return PPCI_LFD; 863 case IRT_NUM: lua_assert(!LJ_SOFTFP); return PPCI_LFD;
788 case IRT_FLOAT: return PPCI_LFS; 864 case IRT_FLOAT: if (!LJ_SOFTFP) return PPCI_LFS;
789 default: return PPCI_LWZ; 865 default: return PPCI_LWZ;
790 } 866 }
791} 867}
@@ -795,8 +871,8 @@ static PPCIns asm_fxstoreins(IRIns *ir)
795 switch (irt_type(ir->t)) { 871 switch (irt_type(ir->t)) {
796 case IRT_I8: case IRT_U8: return PPCI_STB; 872 case IRT_I8: case IRT_U8: return PPCI_STB;
797 case IRT_I16: case IRT_U16: return PPCI_STH; 873 case IRT_I16: case IRT_U16: return PPCI_STH;
798 case IRT_NUM: return PPCI_STFD; 874 case IRT_NUM: lua_assert(!LJ_SOFTFP); return PPCI_STFD;
799 case IRT_FLOAT: return PPCI_STFS; 875 case IRT_FLOAT: if (!LJ_SOFTFP) return PPCI_STFS;
800 default: return PPCI_STW; 876 default: return PPCI_STW;
801 } 877 }
802} 878}
@@ -839,7 +915,8 @@ static void asm_fstore(ASMState *as, IRIns *ir)
839 915
840static void asm_xload(ASMState *as, IRIns *ir) 916static void asm_xload(ASMState *as, IRIns *ir)
841{ 917{
842 Reg dest = ra_dest(as, ir, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); 918 Reg dest = ra_dest(as, ir,
919 (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
843 lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED)); 920 lua_assert(!(ir->op2 & IRXLOAD_UNALIGNED));
844 if (irt_isi8(ir->t)) 921 if (irt_isi8(ir->t))
845 emit_as(as, PPCI_EXTSB, dest, dest); 922 emit_as(as, PPCI_EXTSB, dest, dest);
@@ -857,7 +934,8 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
857 Reg src = ra_alloc1(as, irb->op1, RSET_GPR); 934 Reg src = ra_alloc1(as, irb->op1, RSET_GPR);
858 asm_fusexrefx(as, PPCI_STWBRX, src, ir->op1, rset_exclude(RSET_GPR, src)); 935 asm_fusexrefx(as, PPCI_STWBRX, src, ir->op1, rset_exclude(RSET_GPR, src));
859 } else { 936 } else {
860 Reg src = ra_alloc1(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); 937 Reg src = ra_alloc1(as, ir->op2,
938 (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR);
861 asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1, 939 asm_fusexref(as, asm_fxstoreins(ir), src, ir->op1,
862 rset_exclude(RSET_GPR, src), ofs); 940 rset_exclude(RSET_GPR, src), ofs);
863 } 941 }
@@ -871,10 +949,19 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
871 Reg dest = RID_NONE, type = RID_TMP, tmp = RID_TMP, idx; 949 Reg dest = RID_NONE, type = RID_TMP, tmp = RID_TMP, idx;
872 RegSet allow = RSET_GPR; 950 RegSet allow = RSET_GPR;
873 int32_t ofs = AHUREF_LSX; 951 int32_t ofs = AHUREF_LSX;
952 if (LJ_SOFTFP && (ir+1)->o == IR_HIOP) {
953 t.irt = IRT_NUM;
954 if (ra_used(ir+1)) {
955 type = ra_dest(as, ir+1, allow);
956 rset_clear(allow, type);
957 }
958 ofs = 0;
959 }
874 if (ra_used(ir)) { 960 if (ra_used(ir)) {
875 lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t)); 961 lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) ||
876 if (!irt_isnum(t)) ofs = 0; 962 irt_isint(ir->t) || irt_isaddr(ir->t));
877 dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : RSET_GPR); 963 if (LJ_SOFTFP || !irt_isnum(t)) ofs = 0;
964 dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
878 rset_clear(allow, dest); 965 rset_clear(allow, dest);
879 } 966 }
880 idx = asm_fuseahuref(as, ir->op1, &ofs, allow); 967 idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
@@ -883,12 +970,13 @@ static void asm_ahuvload(ASMState *as, IRIns *ir)
883 asm_guardcc(as, CC_GE); 970 asm_guardcc(as, CC_GE);
884 emit_ab(as, PPCI_CMPLW, type, tisnum); 971 emit_ab(as, PPCI_CMPLW, type, tisnum);
885 if (ra_hasreg(dest)) { 972 if (ra_hasreg(dest)) {
886 if (ofs == AHUREF_LSX) { 973 if (!LJ_SOFTFP && ofs == AHUREF_LSX) {
887 tmp = ra_scratch(as, rset_exclude(rset_exclude(RSET_GPR, 974 tmp = ra_scratch(as, rset_exclude(rset_exclude(RSET_GPR,
888 (idx&255)), (idx>>8))); 975 (idx&255)), (idx>>8)));
889 emit_fab(as, PPCI_LFDX, dest, (idx&255), tmp); 976 emit_fab(as, PPCI_LFDX, dest, (idx&255), tmp);
890 } else { 977 } else {
891 emit_fai(as, PPCI_LFD, dest, idx, ofs); 978 emit_fai(as, LJ_SOFTFP ? PPCI_LWZ : PPCI_LFD, dest, idx,
979 ofs+4*LJ_SOFTFP);
892 } 980 }
893 } 981 }
894 } else { 982 } else {
@@ -911,7 +999,7 @@ static void asm_ahustore(ASMState *as, IRIns *ir)
911 int32_t ofs = AHUREF_LSX; 999 int32_t ofs = AHUREF_LSX;
912 if (ir->r == RID_SINK) 1000 if (ir->r == RID_SINK)
913 return; 1001 return;
914 if (irt_isnum(ir->t)) { 1002 if (!LJ_SOFTFP && irt_isnum(ir->t)) {
915 src = ra_alloc1(as, ir->op2, RSET_FPR); 1003 src = ra_alloc1(as, ir->op2, RSET_FPR);
916 } else { 1004 } else {
917 if (!irt_ispri(ir->t)) { 1005 if (!irt_ispri(ir->t)) {
@@ -919,11 +1007,14 @@ static void asm_ahustore(ASMState *as, IRIns *ir)
919 rset_clear(allow, src); 1007 rset_clear(allow, src);
920 ofs = 0; 1008 ofs = 0;
921 } 1009 }
922 type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow); 1010 if (LJ_SOFTFP && (ir+1)->o == IR_HIOP)
1011 type = ra_alloc1(as, (ir+1)->op2, allow);
1012 else
1013 type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
923 rset_clear(allow, type); 1014 rset_clear(allow, type);
924 } 1015 }
925 idx = asm_fuseahuref(as, ir->op1, &ofs, allow); 1016 idx = asm_fuseahuref(as, ir->op1, &ofs, allow);
926 if (irt_isnum(ir->t)) { 1017 if (!LJ_SOFTFP && irt_isnum(ir->t)) {
927 if (ofs == AHUREF_LSX) { 1018 if (ofs == AHUREF_LSX) {
928 emit_fab(as, PPCI_STFDX, src, (idx&255), RID_TMP); 1019 emit_fab(as, PPCI_STFDX, src, (idx&255), RID_TMP);
929 emit_slwi(as, RID_TMP, (idx>>8), 3); 1020 emit_slwi(as, RID_TMP, (idx>>8), 3);
@@ -948,21 +1039,33 @@ static void asm_sload(ASMState *as, IRIns *ir)
948 IRType1 t = ir->t; 1039 IRType1 t = ir->t;
949 Reg dest = RID_NONE, type = RID_NONE, base; 1040 Reg dest = RID_NONE, type = RID_NONE, base;
950 RegSet allow = RSET_GPR; 1041 RegSet allow = RSET_GPR;
1042 int hiop = (LJ_SOFTFP && (ir+1)->o == IR_HIOP);
1043 if (hiop)
1044 t.irt = IRT_NUM;
951 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */ 1045 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
952 lua_assert(irt_isguard(t) || !(ir->op2 & IRSLOAD_TYPECHECK)); 1046 lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK));
953 lua_assert(LJ_DUALNUM || 1047 lua_assert(LJ_DUALNUM ||
954 !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME))); 1048 !irt_isint(t) || (ir->op2 & (IRSLOAD_CONVERT|IRSLOAD_FRAME)));
1049#if LJ_SOFTFP
1050 lua_assert(!(ir->op2 & IRSLOAD_CONVERT)); /* Handled by LJ_SOFTFP SPLIT. */
1051 if (hiop && ra_used(ir+1)) {
1052 type = ra_dest(as, ir+1, allow);
1053 rset_clear(allow, type);
1054 }
1055#else
955 if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) { 1056 if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) {
956 dest = ra_scratch(as, RSET_FPR); 1057 dest = ra_scratch(as, RSET_FPR);
957 asm_tointg(as, ir, dest); 1058 asm_tointg(as, ir, dest);
958 t.irt = IRT_NUM; /* Continue with a regular number type check. */ 1059 t.irt = IRT_NUM; /* Continue with a regular number type check. */
959 } else if (ra_used(ir)) { 1060 } else
1061#endif
1062 if (ra_used(ir)) {
960 lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t)); 1063 lua_assert(irt_isnum(t) || irt_isint(t) || irt_isaddr(t));
961 dest = ra_dest(as, ir, irt_isnum(t) ? RSET_FPR : RSET_GPR); 1064 dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow);
962 rset_clear(allow, dest); 1065 rset_clear(allow, dest);
963 base = ra_alloc1(as, REF_BASE, allow); 1066 base = ra_alloc1(as, REF_BASE, allow);
964 rset_clear(allow, base); 1067 rset_clear(allow, base);
965 if ((ir->op2 & IRSLOAD_CONVERT)) { 1068 if (!LJ_SOFTFP && (ir->op2 & IRSLOAD_CONVERT)) {
966 if (irt_isint(t)) { 1069 if (irt_isint(t)) {
967 emit_tai(as, PPCI_LWZ, dest, RID_SP, SPOFS_TMPLO); 1070 emit_tai(as, PPCI_LWZ, dest, RID_SP, SPOFS_TMPLO);
968 dest = ra_scratch(as, RSET_FPR); 1071 dest = ra_scratch(as, RSET_FPR);
@@ -994,10 +1097,13 @@ dotypecheck:
994 if ((ir->op2 & IRSLOAD_TYPECHECK)) { 1097 if ((ir->op2 & IRSLOAD_TYPECHECK)) {
995 Reg tisnum = ra_allock(as, (int32_t)LJ_TISNUM, allow); 1098 Reg tisnum = ra_allock(as, (int32_t)LJ_TISNUM, allow);
996 asm_guardcc(as, CC_GE); 1099 asm_guardcc(as, CC_GE);
997 emit_ab(as, PPCI_CMPLW, RID_TMP, tisnum); 1100#if !LJ_SOFTFP
998 type = RID_TMP; 1101 type = RID_TMP;
1102#endif
1103 emit_ab(as, PPCI_CMPLW, type, tisnum);
999 } 1104 }
1000 if (ra_hasreg(dest)) emit_fai(as, PPCI_LFD, dest, base, ofs-4); 1105 if (ra_hasreg(dest)) emit_fai(as, LJ_SOFTFP ? PPCI_LWZ : PPCI_LFD, dest,
1106 base, ofs-(LJ_SOFTFP?0:4));
1001 } else { 1107 } else {
1002 if ((ir->op2 & IRSLOAD_TYPECHECK)) { 1108 if ((ir->op2 & IRSLOAD_TYPECHECK)) {
1003 asm_guardcc(as, CC_NE); 1109 asm_guardcc(as, CC_NE);
@@ -1119,6 +1225,7 @@ static void asm_obar(ASMState *as, IRIns *ir)
1119 1225
1120/* -- Arithmetic and logic operations ------------------------------------- */ 1226/* -- Arithmetic and logic operations ------------------------------------- */
1121 1227
1228#if !LJ_SOFTFP
1122static void asm_fparith(ASMState *as, IRIns *ir, PPCIns pi) 1229static void asm_fparith(ASMState *as, IRIns *ir, PPCIns pi)
1123{ 1230{
1124 Reg dest = ra_dest(as, ir, RSET_FPR); 1231 Reg dest = ra_dest(as, ir, RSET_FPR);
@@ -1146,13 +1253,17 @@ static void asm_fpmath(ASMState *as, IRIns *ir)
1146 else 1253 else
1147 asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2); 1254 asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);
1148} 1255}
1256#endif
1149 1257
1150static void asm_add(ASMState *as, IRIns *ir) 1258static void asm_add(ASMState *as, IRIns *ir)
1151{ 1259{
1260#if !LJ_SOFTFP
1152 if (irt_isnum(ir->t)) { 1261 if (irt_isnum(ir->t)) {
1153 if (!asm_fusemadd(as, ir, PPCI_FMADD, PPCI_FMADD)) 1262 if (!asm_fusemadd(as, ir, PPCI_FMADD, PPCI_FMADD))
1154 asm_fparith(as, ir, PPCI_FADD); 1263 asm_fparith(as, ir, PPCI_FADD);
1155 } else { 1264 } else
1265#endif
1266 {
1156 Reg dest = ra_dest(as, ir, RSET_GPR); 1267 Reg dest = ra_dest(as, ir, RSET_GPR);
1157 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR); 1268 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1158 PPCIns pi; 1269 PPCIns pi;
@@ -1191,10 +1302,13 @@ static void asm_add(ASMState *as, IRIns *ir)
1191 1302
1192static void asm_sub(ASMState *as, IRIns *ir) 1303static void asm_sub(ASMState *as, IRIns *ir)
1193{ 1304{
1305#if !LJ_SOFTFP
1194 if (irt_isnum(ir->t)) { 1306 if (irt_isnum(ir->t)) {
1195 if (!asm_fusemadd(as, ir, PPCI_FMSUB, PPCI_FNMSUB)) 1307 if (!asm_fusemadd(as, ir, PPCI_FMSUB, PPCI_FNMSUB))
1196 asm_fparith(as, ir, PPCI_FSUB); 1308 asm_fparith(as, ir, PPCI_FSUB);
1197 } else { 1309 } else
1310#endif
1311 {
1198 PPCIns pi = PPCI_SUBF; 1312 PPCIns pi = PPCI_SUBF;
1199 Reg dest = ra_dest(as, ir, RSET_GPR); 1313 Reg dest = ra_dest(as, ir, RSET_GPR);
1200 Reg left, right; 1314 Reg left, right;
@@ -1220,9 +1334,12 @@ static void asm_sub(ASMState *as, IRIns *ir)
1220 1334
1221static void asm_mul(ASMState *as, IRIns *ir) 1335static void asm_mul(ASMState *as, IRIns *ir)
1222{ 1336{
1337#if !LJ_SOFTFP
1223 if (irt_isnum(ir->t)) { 1338 if (irt_isnum(ir->t)) {
1224 asm_fparith(as, ir, PPCI_FMUL); 1339 asm_fparith(as, ir, PPCI_FMUL);
1225 } else { 1340 } else
1341#endif
1342 {
1226 PPCIns pi = PPCI_MULLW; 1343 PPCIns pi = PPCI_MULLW;
1227 Reg dest = ra_dest(as, ir, RSET_GPR); 1344 Reg dest = ra_dest(as, ir, RSET_GPR);
1228 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR); 1345 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
@@ -1250,9 +1367,12 @@ static void asm_mul(ASMState *as, IRIns *ir)
1250 1367
1251static void asm_neg(ASMState *as, IRIns *ir) 1368static void asm_neg(ASMState *as, IRIns *ir)
1252{ 1369{
1370#if !LJ_SOFTFP
1253 if (irt_isnum(ir->t)) { 1371 if (irt_isnum(ir->t)) {
1254 asm_fpunary(as, ir, PPCI_FNEG); 1372 asm_fpunary(as, ir, PPCI_FNEG);
1255 } else { 1373 } else
1374#endif
1375 {
1256 Reg dest, left; 1376 Reg dest, left;
1257 PPCIns pi = PPCI_NEG; 1377 PPCIns pi = PPCI_NEG;
1258 if (as->flagmcp == as->mcp) { 1378 if (as->flagmcp == as->mcp) {
@@ -1563,9 +1683,40 @@ static void asm_bitshift(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik)
1563 PPCI_RLWINM|PPCF_MB(0)|PPCF_ME(31)) 1683 PPCI_RLWINM|PPCF_MB(0)|PPCF_ME(31))
1564#define asm_bror(as, ir) lua_assert(0) 1684#define asm_bror(as, ir) lua_assert(0)
1565 1685
1686#if LJ_SOFTFP
1687static void asm_sfpmin_max(ASMState *as, IRIns *ir)
1688{
1689 CCallInfo ci = lj_ir_callinfo[IRCALL_softfp_cmp];
1690 IRRef args[4];
1691 MCLabel l_right, l_end;
1692 Reg desthi = ra_dest(as, ir, RSET_GPR), destlo = ra_dest(as, ir+1, RSET_GPR);
1693 Reg righthi, lefthi = ra_alloc2(as, ir, RSET_GPR);
1694 Reg rightlo, leftlo = ra_alloc2(as, ir+1, RSET_GPR);
1695 PPCCC cond = (IROp)ir->o == IR_MIN ? CC_EQ : CC_NE;
1696 righthi = (lefthi >> 8); lefthi &= 255;
1697 rightlo = (leftlo >> 8); leftlo &= 255;
1698 args[0^LJ_BE] = ir->op1; args[1^LJ_BE] = (ir+1)->op1;
1699 args[2^LJ_BE] = ir->op2; args[3^LJ_BE] = (ir+1)->op2;
1700 l_end = emit_label(as);
1701 if (desthi != righthi) emit_mr(as, desthi, righthi);
1702 if (destlo != rightlo) emit_mr(as, destlo, rightlo);
1703 l_right = emit_label(as);
1704 if (l_end != l_right) emit_jmp(as, l_end);
1705 if (desthi != lefthi) emit_mr(as, desthi, lefthi);
1706 if (destlo != leftlo) emit_mr(as, destlo, leftlo);
1707 if (l_right == as->mcp+1) {
1708 cond ^= 4; l_right = l_end; ++as->mcp;
1709 }
1710 emit_condbranch(as, PPCI_BC, cond, l_right);
1711 ra_evictset(as, RSET_SCRATCH);
1712 emit_cmpi(as, RID_RET, 1);
1713 asm_gencall(as, &ci, args);
1714}
1715#endif
1716
1566static void asm_min_max(ASMState *as, IRIns *ir, int ismax) 1717static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
1567{ 1718{
1568 if (irt_isnum(ir->t)) { 1719 if (!LJ_SOFTFP && irt_isnum(ir->t)) {
1569 Reg dest = ra_dest(as, ir, RSET_FPR); 1720 Reg dest = ra_dest(as, ir, RSET_FPR);
1570 Reg tmp = dest; 1721 Reg tmp = dest;
1571 Reg right, left = ra_alloc2(as, ir, RSET_FPR); 1722 Reg right, left = ra_alloc2(as, ir, RSET_FPR);
@@ -1653,7 +1804,7 @@ static void asm_intcomp_(ASMState *as, IRRef lref, IRRef rref, Reg cr, PPCCC cc)
1653static void asm_comp(ASMState *as, IRIns *ir) 1804static void asm_comp(ASMState *as, IRIns *ir)
1654{ 1805{
1655 PPCCC cc = asm_compmap[ir->o]; 1806 PPCCC cc = asm_compmap[ir->o];
1656 if (irt_isnum(ir->t)) { 1807 if (!LJ_SOFTFP && irt_isnum(ir->t)) {
1657 Reg right, left = ra_alloc2(as, ir, RSET_FPR); 1808 Reg right, left = ra_alloc2(as, ir, RSET_FPR);
1658 right = (left >> 8); left &= 255; 1809 right = (left >> 8); left &= 255;
1659 asm_guardcc(as, (cc >> 4)); 1810 asm_guardcc(as, (cc >> 4));
@@ -1674,6 +1825,44 @@ static void asm_comp(ASMState *as, IRIns *ir)
1674 1825
1675#define asm_equal(as, ir) asm_comp(as, ir) 1826#define asm_equal(as, ir) asm_comp(as, ir)
1676 1827
1828#if LJ_SOFTFP
1829/* SFP comparisons. */
1830static void asm_sfpcomp(ASMState *as, IRIns *ir)
1831{
1832 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_softfp_cmp];
1833 RegSet drop = RSET_SCRATCH;
1834 Reg r;
1835 IRRef args[4];
1836 args[0^LJ_BE] = ir->op1; args[1^LJ_BE] = (ir+1)->op1;
1837 args[2^LJ_BE] = ir->op2; args[3^LJ_BE] = (ir+1)->op2;
1838
1839 for (r = REGARG_FIRSTGPR; r <= REGARG_FIRSTGPR+3; r++) {
1840 if (!rset_test(as->freeset, r) &&
1841 regcost_ref(as->cost[r]) == args[r-REGARG_FIRSTGPR])
1842 rset_clear(drop, r);
1843 }
1844 ra_evictset(as, drop);
1845 asm_setupresult(as, ir, ci);
1846 switch ((IROp)ir->o) {
1847 case IR_ULT:
1848 asm_guardcc(as, CC_EQ);
1849 emit_ai(as, PPCI_CMPWI, RID_RET, 0);
1850 case IR_ULE:
1851 asm_guardcc(as, CC_EQ);
1852 emit_ai(as, PPCI_CMPWI, RID_RET, 1);
1853 break;
1854 case IR_GE: case IR_GT:
1855 asm_guardcc(as, CC_EQ);
1856 emit_ai(as, PPCI_CMPWI, RID_RET, 2);
1857 default:
1858 asm_guardcc(as, (asm_compmap[ir->o] & 0xf));
1859 emit_ai(as, PPCI_CMPWI, RID_RET, 0);
1860 break;
1861 }
1862 asm_gencall(as, ci, args);
1863}
1864#endif
1865
1677#if LJ_HASFFI 1866#if LJ_HASFFI
1678/* 64 bit integer comparisons. */ 1867/* 64 bit integer comparisons. */
1679static void asm_comp64(ASMState *as, IRIns *ir) 1868static void asm_comp64(ASMState *as, IRIns *ir)
@@ -1703,19 +1892,36 @@ static void asm_comp64(ASMState *as, IRIns *ir)
1703/* Hiword op of a split 64 bit op. Previous op must be the loword op. */ 1892/* Hiword op of a split 64 bit op. Previous op must be the loword op. */
1704static void asm_hiop(ASMState *as, IRIns *ir) 1893static void asm_hiop(ASMState *as, IRIns *ir)
1705{ 1894{
1706#if LJ_HASFFI 1895#if LJ_HASFFI || LJ_SOFTFP
1707 /* HIOP is marked as a store because it needs its own DCE logic. */ 1896 /* HIOP is marked as a store because it needs its own DCE logic. */
1708 int uselo = ra_used(ir-1), usehi = ra_used(ir); /* Loword/hiword used? */ 1897 int uselo = ra_used(ir-1), usehi = ra_used(ir); /* Loword/hiword used? */
1709 if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1; 1898 if (LJ_UNLIKELY(!(as->flags & JIT_F_OPT_DCE))) uselo = usehi = 1;
1710 if ((ir-1)->o == IR_CONV) { /* Conversions to/from 64 bit. */ 1899 if ((ir-1)->o == IR_CONV) { /* Conversions to/from 64 bit. */
1711 as->curins--; /* Always skip the CONV. */ 1900 as->curins--; /* Always skip the CONV. */
1901#if LJ_HASFFI && !LJ_SOFTFP
1712 if (usehi || uselo) 1902 if (usehi || uselo)
1713 asm_conv64(as, ir); 1903 asm_conv64(as, ir);
1714 return; 1904 return;
1905#endif
1715 } else if ((ir-1)->o <= IR_NE) { /* 64 bit integer comparisons. ORDER IR. */ 1906 } else if ((ir-1)->o <= IR_NE) { /* 64 bit integer comparisons. ORDER IR. */
1716 as->curins--; /* Always skip the loword comparison. */ 1907 as->curins--; /* Always skip the loword comparison. */
1908#if LJ_SOFTFP
1909 if (!irt_isint(ir->t)) {
1910 asm_sfpcomp(as, ir-1);
1911 return;
1912 }
1913#endif
1914#if LJ_HASFFI
1717 asm_comp64(as, ir); 1915 asm_comp64(as, ir);
1916#endif
1917 return;
1918#if LJ_SOFTFP
1919 } else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
1920 as->curins--; /* Always skip the loword min/max. */
1921 if (uselo || usehi)
1922 asm_sfpmin_max(as, ir-1);
1718 return; 1923 return;
1924#endif
1719 } else if ((ir-1)->o == IR_XSTORE) { 1925 } else if ((ir-1)->o == IR_XSTORE) {
1720 as->curins--; /* Handle both stores here. */ 1926 as->curins--; /* Handle both stores here. */
1721 if ((ir-1)->r != RID_SINK) { 1927 if ((ir-1)->r != RID_SINK) {
@@ -1726,14 +1932,27 @@ static void asm_hiop(ASMState *as, IRIns *ir)
1726 } 1932 }
1727 if (!usehi) return; /* Skip unused hiword op for all remaining ops. */ 1933 if (!usehi) return; /* Skip unused hiword op for all remaining ops. */
1728 switch ((ir-1)->o) { 1934 switch ((ir-1)->o) {
1935#if LJ_HASFFI
1729 case IR_ADD: as->curins--; asm_add64(as, ir); break; 1936 case IR_ADD: as->curins--; asm_add64(as, ir); break;
1730 case IR_SUB: as->curins--; asm_sub64(as, ir); break; 1937 case IR_SUB: as->curins--; asm_sub64(as, ir); break;
1731 case IR_NEG: as->curins--; asm_neg64(as, ir); break; 1938 case IR_NEG: as->curins--; asm_neg64(as, ir); break;
1939#endif
1940#if LJ_SOFTFP
1941 case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
1942 case IR_STRTO:
1943 if (!uselo)
1944 ra_allocref(as, ir->op1, RSET_GPR); /* Mark lo op as used. */
1945 break;
1946#endif
1732 case IR_CALLN: 1947 case IR_CALLN:
1948 case IR_CALLS:
1733 case IR_CALLXS: 1949 case IR_CALLXS:
1734 if (!uselo) 1950 if (!uselo)
1735 ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ 1951 ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */
1736 break; 1952 break;
1953#if LJ_SOFTFP
1954 case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR:
1955#endif
1737 case IR_CNEWI: 1956 case IR_CNEWI:
1738 /* Nothing to do here. Handled by lo op itself. */ 1957 /* Nothing to do here. Handled by lo op itself. */
1739 break; 1958 break;
@@ -1797,8 +2016,19 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
1797 if ((sn & SNAP_NORESTORE)) 2016 if ((sn & SNAP_NORESTORE))
1798 continue; 2017 continue;
1799 if (irt_isnum(ir->t)) { 2018 if (irt_isnum(ir->t)) {
2019#if LJ_SOFTFP
2020 Reg tmp;
2021 RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
2022 lua_assert(irref_isk(ref)); /* LJ_SOFTFP: must be a number constant. */
2023 tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, allow);
2024 emit_tai(as, PPCI_STW, tmp, RID_BASE, ofs+(LJ_BE?4:0));
2025 if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1);
2026 tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, allow);
2027 emit_tai(as, PPCI_STW, tmp, RID_BASE, ofs+(LJ_BE?0:4));
2028#else
1800 Reg src = ra_alloc1(as, ref, RSET_FPR); 2029 Reg src = ra_alloc1(as, ref, RSET_FPR);
1801 emit_fai(as, PPCI_STFD, src, RID_BASE, ofs); 2030 emit_fai(as, PPCI_STFD, src, RID_BASE, ofs);
2031#endif
1802 } else { 2032 } else {
1803 Reg type; 2033 Reg type;
1804 RegSet allow = rset_exclude(RSET_GPR, RID_BASE); 2034 RegSet allow = rset_exclude(RSET_GPR, RID_BASE);
@@ -1811,6 +2041,10 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
1811 if ((sn & (SNAP_CONT|SNAP_FRAME))) { 2041 if ((sn & (SNAP_CONT|SNAP_FRAME))) {
1812 if (s == 0) continue; /* Do not overwrite link to previous frame. */ 2042 if (s == 0) continue; /* Do not overwrite link to previous frame. */
1813 type = ra_allock(as, (int32_t)(*flinks--), allow); 2043 type = ra_allock(as, (int32_t)(*flinks--), allow);
2044#if LJ_SOFTFP
2045 } else if ((sn & SNAP_SOFTFPNUM)) {
2046 type = ra_alloc1(as, ref+1, rset_exclude(RSET_GPR, RID_BASE));
2047#endif
1814 } else { 2048 } else {
1815 type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow); 2049 type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow);
1816 } 2050 }
@@ -1947,14 +2181,15 @@ static Reg asm_setup_call_slots(ASMState *as, IRIns *ir, const CCallInfo *ci)
1947 int nslots = 2, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR; 2181 int nslots = 2, ngpr = REGARG_NUMGPR, nfpr = REGARG_NUMFPR;
1948 asm_collectargs(as, ir, ci, args); 2182 asm_collectargs(as, ir, ci, args);
1949 for (i = 0; i < nargs; i++) 2183 for (i = 0; i < nargs; i++)
1950 if (args[i] && irt_isfp(IR(args[i])->t)) { 2184 if (!LJ_SOFTFP && args[i] && irt_isfp(IR(args[i])->t)) {
1951 if (nfpr > 0) nfpr--; else nslots = (nslots+3) & ~1; 2185 if (nfpr > 0) nfpr--; else nslots = (nslots+3) & ~1;
1952 } else { 2186 } else {
1953 if (ngpr > 0) ngpr--; else nslots++; 2187 if (ngpr > 0) ngpr--; else nslots++;
1954 } 2188 }
1955 if (nslots > as->evenspill) /* Leave room for args in stack slots. */ 2189 if (nslots > as->evenspill) /* Leave room for args in stack slots. */
1956 as->evenspill = nslots; 2190 as->evenspill = nslots;
1957 return irt_isfp(ir->t) ? REGSP_HINT(RID_FPRET) : REGSP_HINT(RID_RET); 2191 return (!LJ_SOFTFP && irt_isfp(ir->t)) ? REGSP_HINT(RID_FPRET) :
2192 REGSP_HINT(RID_RET);
1958} 2193}
1959 2194
1960static void asm_setup_target(ASMState *as) 2195static void asm_setup_target(ASMState *as)