diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_asm_mips.h | 217 |
1 files changed, 179 insertions, 38 deletions
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index 05af3d09..1406a873 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
@@ -290,7 +290,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
290 | { | 290 | { |
291 | ra_leftov(as, gpr, ref); | 291 | ra_leftov(as, gpr, ref); |
292 | gpr++; | 292 | gpr++; |
293 | #if LJ_64 | 293 | #if LJ_64 && !LJ_SOFTFP |
294 | fpr++; | 294 | fpr++; |
295 | #endif | 295 | #endif |
296 | } | 296 | } |
@@ -301,7 +301,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
301 | emit_spstore(as, ir, r, ofs); | 301 | emit_spstore(as, ir, r, ofs); |
302 | ofs += irt_isnum(ir->t) ? 8 : 4; | 302 | ofs += irt_isnum(ir->t) ? 8 : 4; |
303 | #else | 303 | #else |
304 | emit_spstore(as, ir, r, ofs + ((LJ_BE && (LJ_SOFTFP || r < RID_MAX_GPR) && !irt_is64(ir->t)) ? 4 : 0)); | 304 | emit_spstore(as, ir, r, ofs + ((LJ_BE && !irt_isfp(ir->t) && !irt_is64(ir->t)) ? 4 : 0)); |
305 | ofs += 8; | 305 | ofs += 8; |
306 | #endif | 306 | #endif |
307 | } | 307 | } |
@@ -312,7 +312,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
312 | #endif | 312 | #endif |
313 | if (gpr <= REGARG_LASTGPR) { | 313 | if (gpr <= REGARG_LASTGPR) { |
314 | gpr++; | 314 | gpr++; |
315 | #if LJ_64 | 315 | #if LJ_64 && !LJ_SOFTFP |
316 | fpr++; | 316 | fpr++; |
317 | #endif | 317 | #endif |
318 | } else { | 318 | } else { |
@@ -461,12 +461,36 @@ static void asm_tobit(ASMState *as, IRIns *ir) | |||
461 | emit_tg(as, MIPSI_MFC1, dest, tmp); | 461 | emit_tg(as, MIPSI_MFC1, dest, tmp); |
462 | emit_fgh(as, MIPSI_ADD_D, tmp, left, right); | 462 | emit_fgh(as, MIPSI_ADD_D, tmp, left, right); |
463 | } | 463 | } |
464 | #elif LJ_64 /* && LJ_SOFTFP */ | ||
465 | static void asm_tointg(ASMState *as, IRIns *ir, Reg r) | ||
466 | { | ||
467 | /* The modified regs must match with the *.dasc implementation. */ | ||
468 | RegSet drop = RID2RSET(REGARG_FIRSTGPR)|RID2RSET(RID_RET)|RID2RSET(RID_RET+1)| | ||
469 | RID2RSET(RID_R1)|RID2RSET(RID_R12); | ||
470 | if (ra_hasreg(ir->r)) rset_clear(drop, ir->r); | ||
471 | ra_evictset(as, drop); | ||
472 | /* Return values are in RID_RET (converted value) and RID_RET+1 (status). */ | ||
473 | ra_destreg(as, ir, RID_RET); | ||
474 | asm_guard(as, MIPSI_BNE, RID_RET+1, RID_ZERO); | ||
475 | emit_call(as, (void *)lj_ir_callinfo[IRCALL_lj_vm_tointg].func, 0); | ||
476 | if (r == RID_NONE) | ||
477 | ra_leftov(as, REGARG_FIRSTGPR, ir->op1); | ||
478 | else if (r != REGARG_FIRSTGPR) | ||
479 | emit_move(as, REGARG_FIRSTGPR, r); | ||
480 | } | ||
481 | |||
482 | static void asm_tobit(ASMState *as, IRIns *ir) | ||
483 | { | ||
484 | Reg dest = ra_dest(as, ir, RSET_GPR); | ||
485 | emit_dta(as, MIPSI_SLL, dest, dest, 0); | ||
486 | asm_callid(as, ir, IRCALL_lj_vm_tobit); | ||
487 | } | ||
464 | #endif | 488 | #endif |
465 | 489 | ||
466 | static void asm_conv(ASMState *as, IRIns *ir) | 490 | static void asm_conv(ASMState *as, IRIns *ir) |
467 | { | 491 | { |
468 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); | 492 | IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); |
469 | #if !LJ_SOFTFP | 493 | #if !LJ_SOFTFP32 |
470 | int stfp = (st == IRT_NUM || st == IRT_FLOAT); | 494 | int stfp = (st == IRT_NUM || st == IRT_FLOAT); |
471 | #endif | 495 | #endif |
472 | #if LJ_64 | 496 | #if LJ_64 |
@@ -477,12 +501,13 @@ static void asm_conv(ASMState *as, IRIns *ir) | |||
477 | lua_assert(!(irt_isint64(ir->t) || | 501 | lua_assert(!(irt_isint64(ir->t) || |
478 | (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */ | 502 | (st == IRT_I64 || st == IRT_U64))); /* Handled by SPLIT. */ |
479 | #endif | 503 | #endif |
480 | #if LJ_32 && LJ_SOFTFP | 504 | #if LJ_SOFTFP32 |
481 | /* FP conversions are handled by SPLIT. */ | 505 | /* FP conversions are handled by SPLIT. */ |
482 | lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT)); | 506 | lua_assert(!irt_isfp(ir->t) && !(st == IRT_NUM || st == IRT_FLOAT)); |
483 | /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */ | 507 | /* Can't check for same types: SPLIT uses CONV int.int + BXOR for sfp NEG. */ |
484 | #else | 508 | #else |
485 | lua_assert(irt_type(ir->t) != st); | 509 | lua_assert(irt_type(ir->t) != st); |
510 | #if !LJ_SOFTFP | ||
486 | if (irt_isfp(ir->t)) { | 511 | if (irt_isfp(ir->t)) { |
487 | Reg dest = ra_dest(as, ir, RSET_FPR); | 512 | Reg dest = ra_dest(as, ir, RSET_FPR); |
488 | if (stfp) { /* FP to FP conversion. */ | 513 | if (stfp) { /* FP to FP conversion. */ |
@@ -608,6 +633,42 @@ static void asm_conv(ASMState *as, IRIns *ir) | |||
608 | } | 633 | } |
609 | } | 634 | } |
610 | } else | 635 | } else |
636 | #else | ||
637 | if (irt_isfp(ir->t)) { | ||
638 | #if LJ_64 && LJ_HASFFI | ||
639 | if (stfp) { /* FP to FP conversion. */ | ||
640 | asm_callid(as, ir, irt_isnum(ir->t) ? IRCALL_softfp_f2d : | ||
641 | IRCALL_softfp_d2f); | ||
642 | } else { /* Integer to FP conversion. */ | ||
643 | IRCallID cid = ((IRT_IS64 >> st) & 1) ? | ||
644 | (irt_isnum(ir->t) ? | ||
645 | (st == IRT_I64 ? IRCALL_fp64_l2d : IRCALL_fp64_ul2d) : | ||
646 | (st == IRT_I64 ? IRCALL_fp64_l2f : IRCALL_fp64_ul2f)) : | ||
647 | (irt_isnum(ir->t) ? | ||
648 | (st == IRT_INT ? IRCALL_softfp_i2d : IRCALL_softfp_ui2d) : | ||
649 | (st == IRT_INT ? IRCALL_softfp_i2f : IRCALL_softfp_ui2f)); | ||
650 | asm_callid(as, ir, cid); | ||
651 | } | ||
652 | #else | ||
653 | asm_callid(as, ir, IRCALL_softfp_i2d); | ||
654 | #endif | ||
655 | } else if (stfp) { /* FP to integer conversion. */ | ||
656 | if (irt_isguard(ir->t)) { | ||
657 | /* Checked conversions are only supported from number to int. */ | ||
658 | lua_assert(irt_isint(ir->t) && st == IRT_NUM); | ||
659 | asm_tointg(as, ir, RID_NONE); | ||
660 | } else { | ||
661 | IRCallID cid = irt_is64(ir->t) ? | ||
662 | ((st == IRT_NUM) ? | ||
663 | (irt_isi64(ir->t) ? IRCALL_fp64_d2l : IRCALL_fp64_d2ul) : | ||
664 | (irt_isi64(ir->t) ? IRCALL_fp64_f2l : IRCALL_fp64_f2ul)) : | ||
665 | ((st == IRT_NUM) ? | ||
666 | (irt_isint(ir->t) ? IRCALL_softfp_d2i : IRCALL_softfp_d2ui) : | ||
667 | (irt_isint(ir->t) ? IRCALL_softfp_f2i : IRCALL_softfp_f2ui)); | ||
668 | asm_callid(as, ir, cid); | ||
669 | } | ||
670 | } else | ||
671 | #endif | ||
611 | #endif | 672 | #endif |
612 | { | 673 | { |
613 | Reg dest = ra_dest(as, ir, RSET_GPR); | 674 | Reg dest = ra_dest(as, ir, RSET_GPR); |
@@ -665,7 +726,7 @@ static void asm_strto(ASMState *as, IRIns *ir) | |||
665 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_strscan_num]; | 726 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_strscan_num]; |
666 | IRRef args[2]; | 727 | IRRef args[2]; |
667 | int32_t ofs = 0; | 728 | int32_t ofs = 0; |
668 | #if LJ_SOFTFP | 729 | #if LJ_SOFTFP32 |
669 | ra_evictset(as, RSET_SCRATCH); | 730 | ra_evictset(as, RSET_SCRATCH); |
670 | if (ra_used(ir)) { | 731 | if (ra_used(ir)) { |
671 | if (ra_hasspill(ir->s) && ra_hasspill((ir+1)->s) && | 732 | if (ra_hasspill(ir->s) && ra_hasspill((ir+1)->s) && |
@@ -806,7 +867,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) | |||
806 | MCLabel l_end, l_loop, l_next; | 867 | MCLabel l_end, l_loop, l_next; |
807 | 868 | ||
808 | rset_clear(allow, tab); | 869 | rset_clear(allow, tab); |
809 | #if LJ_32 && LJ_SOFTFP | 870 | #if LJ_SOFTFP32 |
810 | if (!isk) { | 871 | if (!isk) { |
811 | key = ra_alloc1(as, refkey, allow); | 872 | key = ra_alloc1(as, refkey, allow); |
812 | rset_clear(allow, key); | 873 | rset_clear(allow, key); |
@@ -826,7 +887,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) | |||
826 | } | 887 | } |
827 | } | 888 | } |
828 | #else | 889 | #else |
829 | if (irt_isnum(kt)) { | 890 | if (!LJ_SOFTFP && irt_isnum(kt)) { |
830 | key = ra_alloc1(as, refkey, RSET_FPR); | 891 | key = ra_alloc1(as, refkey, RSET_FPR); |
831 | tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key)); | 892 | tmpnum = ra_scratch(as, rset_exclude(RSET_FPR, key)); |
832 | } else if (!irt_ispri(kt)) { | 893 | } else if (!irt_ispri(kt)) { |
@@ -882,6 +943,9 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) | |||
882 | emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15); | 943 | emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 15); |
883 | emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum); | 944 | emit_tg(as, MIPSI_DMTC1, tmp1, tmpnum); |
884 | emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64)); | 945 | emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64)); |
946 | } else if (LJ_SOFTFP && irt_isnum(kt)) { | ||
947 | emit_branch(as, MIPSI_BEQ, tmp1, key, l_end); | ||
948 | emit_tsi(as, MIPSI_LD, tmp1, dest, (int32_t)offsetof(Node, key.u64)); | ||
885 | } else if (irt_isaddr(kt)) { | 949 | } else if (irt_isaddr(kt)) { |
886 | Reg refk = tmp2; | 950 | Reg refk = tmp2; |
887 | if (isk) { | 951 | if (isk) { |
@@ -960,7 +1024,7 @@ static void asm_href(ASMState *as, IRIns *ir, IROp merge) | |||
960 | emit_dta(as, MIPSI_ROTR, dest, tmp1, (-HASH_ROT1)&31); | 1024 | emit_dta(as, MIPSI_ROTR, dest, tmp1, (-HASH_ROT1)&31); |
961 | if (irt_isnum(kt)) { | 1025 | if (irt_isnum(kt)) { |
962 | emit_dst(as, MIPSI_ADDU, tmp1, tmp1, tmp1); | 1026 | emit_dst(as, MIPSI_ADDU, tmp1, tmp1, tmp1); |
963 | emit_dta(as, MIPSI_DSRA32, tmp1, tmp1, 0); | 1027 | emit_dta(as, MIPSI_DSRA32, tmp1, LJ_SOFTFP ? key : tmp1, 0); |
964 | emit_dta(as, MIPSI_SLL, tmp2, LJ_SOFTFP ? key : tmp1, 0); | 1028 | emit_dta(as, MIPSI_SLL, tmp2, LJ_SOFTFP ? key : tmp1, 0); |
965 | #if !LJ_SOFTFP | 1029 | #if !LJ_SOFTFP |
966 | emit_tg(as, MIPSI_DMFC1, tmp1, key); | 1030 | emit_tg(as, MIPSI_DMFC1, tmp1, key); |
@@ -1123,7 +1187,7 @@ static MIPSIns asm_fxloadins(IRIns *ir) | |||
1123 | case IRT_U8: return MIPSI_LBU; | 1187 | case IRT_U8: return MIPSI_LBU; |
1124 | case IRT_I16: return MIPSI_LH; | 1188 | case IRT_I16: return MIPSI_LH; |
1125 | case IRT_U16: return MIPSI_LHU; | 1189 | case IRT_U16: return MIPSI_LHU; |
1126 | case IRT_NUM: lua_assert(!LJ_SOFTFP); return MIPSI_LDC1; | 1190 | case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_LDC1; |
1127 | case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_LWC1; | 1191 | case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_LWC1; |
1128 | default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_LD : MIPSI_LW; | 1192 | default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_LD : MIPSI_LW; |
1129 | } | 1193 | } |
@@ -1134,7 +1198,7 @@ static MIPSIns asm_fxstoreins(IRIns *ir) | |||
1134 | switch (irt_type(ir->t)) { | 1198 | switch (irt_type(ir->t)) { |
1135 | case IRT_I8: case IRT_U8: return MIPSI_SB; | 1199 | case IRT_I8: case IRT_U8: return MIPSI_SB; |
1136 | case IRT_I16: case IRT_U16: return MIPSI_SH; | 1200 | case IRT_I16: case IRT_U16: return MIPSI_SH; |
1137 | case IRT_NUM: lua_assert(!LJ_SOFTFP); return MIPSI_SDC1; | 1201 | case IRT_NUM: lua_assert(!LJ_SOFTFP32); if (!LJ_SOFTFP) return MIPSI_SDC1; |
1138 | case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_SWC1; | 1202 | case IRT_FLOAT: if (!LJ_SOFTFP) return MIPSI_SWC1; |
1139 | default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_SD : MIPSI_SW; | 1203 | default: return (LJ_64 && irt_is64(ir->t)) ? MIPSI_SD : MIPSI_SW; |
1140 | } | 1204 | } |
@@ -1199,7 +1263,7 @@ static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs) | |||
1199 | 1263 | ||
1200 | static void asm_ahuvload(ASMState *as, IRIns *ir) | 1264 | static void asm_ahuvload(ASMState *as, IRIns *ir) |
1201 | { | 1265 | { |
1202 | int hiop = (LJ_32 && LJ_SOFTFP && (ir+1)->o == IR_HIOP); | 1266 | int hiop = (LJ_SOFTFP32 && (ir+1)->o == IR_HIOP); |
1203 | Reg dest = RID_NONE, type = RID_TMP, idx; | 1267 | Reg dest = RID_NONE, type = RID_TMP, idx; |
1204 | RegSet allow = RSET_GPR; | 1268 | RegSet allow = RSET_GPR; |
1205 | int32_t ofs = 0; | 1269 | int32_t ofs = 0; |
@@ -1212,7 +1276,7 @@ static void asm_ahuvload(ASMState *as, IRIns *ir) | |||
1212 | } | 1276 | } |
1213 | } | 1277 | } |
1214 | if (ra_used(ir)) { | 1278 | if (ra_used(ir)) { |
1215 | lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) || | 1279 | lua_assert((LJ_SOFTFP32 ? 0 : irt_isnum(ir->t)) || |
1216 | irt_isint(ir->t) || irt_isaddr(ir->t)); | 1280 | irt_isint(ir->t) || irt_isaddr(ir->t)); |
1217 | dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow); | 1281 | dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow); |
1218 | rset_clear(allow, dest); | 1282 | rset_clear(allow, dest); |
@@ -1261,10 +1325,10 @@ static void asm_ahustore(ASMState *as, IRIns *ir) | |||
1261 | int32_t ofs = 0; | 1325 | int32_t ofs = 0; |
1262 | if (ir->r == RID_SINK) | 1326 | if (ir->r == RID_SINK) |
1263 | return; | 1327 | return; |
1264 | if (!LJ_SOFTFP && irt_isnum(ir->t)) { | 1328 | if (!LJ_SOFTFP32 && irt_isnum(ir->t)) { |
1265 | src = ra_alloc1(as, ir->op2, RSET_FPR); | 1329 | src = ra_alloc1(as, ir->op2, LJ_SOFTFP ? RSET_GPR : RSET_FPR); |
1266 | idx = asm_fuseahuref(as, ir->op1, &ofs, allow); | 1330 | idx = asm_fuseahuref(as, ir->op1, &ofs, allow); |
1267 | emit_hsi(as, MIPSI_SDC1, src, idx, ofs); | 1331 | emit_hsi(as, LJ_SOFTFP ? MIPSI_SD : MIPSI_SDC1, src, idx, ofs); |
1268 | } else { | 1332 | } else { |
1269 | #if LJ_32 | 1333 | #if LJ_32 |
1270 | if (!irt_ispri(ir->t)) { | 1334 | if (!irt_ispri(ir->t)) { |
@@ -1312,7 +1376,7 @@ static void asm_sload(ASMState *as, IRIns *ir) | |||
1312 | IRType1 t = ir->t; | 1376 | IRType1 t = ir->t; |
1313 | #if LJ_32 | 1377 | #if LJ_32 |
1314 | int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0); | 1378 | int32_t ofs = 8*((int32_t)ir->op1-1) + ((ir->op2 & IRSLOAD_FRAME) ? 4 : 0); |
1315 | int hiop = (LJ_32 && LJ_SOFTFP && (ir+1)->o == IR_HIOP); | 1379 | int hiop = (LJ_SOFTFP32 && (ir+1)->o == IR_HIOP); |
1316 | if (hiop) | 1380 | if (hiop) |
1317 | t.irt = IRT_NUM; | 1381 | t.irt = IRT_NUM; |
1318 | #else | 1382 | #else |
@@ -1320,7 +1384,7 @@ static void asm_sload(ASMState *as, IRIns *ir) | |||
1320 | #endif | 1384 | #endif |
1321 | lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */ | 1385 | lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */ |
1322 | lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK)); | 1386 | lua_assert(irt_isguard(ir->t) || !(ir->op2 & IRSLOAD_TYPECHECK)); |
1323 | #if LJ_32 && LJ_SOFTFP | 1387 | #if LJ_SOFTFP32 |
1324 | lua_assert(!(ir->op2 & IRSLOAD_CONVERT)); /* Handled by LJ_SOFTFP SPLIT. */ | 1388 | lua_assert(!(ir->op2 & IRSLOAD_CONVERT)); /* Handled by LJ_SOFTFP SPLIT. */ |
1325 | if (hiop && ra_used(ir+1)) { | 1389 | if (hiop && ra_used(ir+1)) { |
1326 | type = ra_dest(as, ir+1, allow); | 1390 | type = ra_dest(as, ir+1, allow); |
@@ -1328,29 +1392,44 @@ static void asm_sload(ASMState *as, IRIns *ir) | |||
1328 | } | 1392 | } |
1329 | #else | 1393 | #else |
1330 | if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) { | 1394 | if ((ir->op2 & IRSLOAD_CONVERT) && irt_isguard(t) && irt_isint(t)) { |
1331 | dest = ra_scratch(as, RSET_FPR); | 1395 | dest = ra_scratch(as, LJ_SOFTFP ? allow : RSET_FPR); |
1332 | asm_tointg(as, ir, dest); | 1396 | asm_tointg(as, ir, dest); |
1333 | t.irt = IRT_NUM; /* Continue with a regular number type check. */ | 1397 | t.irt = IRT_NUM; /* Continue with a regular number type check. */ |
1334 | } else | 1398 | } else |
1335 | #endif | 1399 | #endif |
1336 | if (ra_used(ir)) { | 1400 | if (ra_used(ir)) { |
1337 | lua_assert((LJ_SOFTFP ? 0 : irt_isnum(ir->t)) || | 1401 | lua_assert((LJ_SOFTFP32 ? 0 : irt_isnum(ir->t)) || |
1338 | irt_isint(ir->t) || irt_isaddr(ir->t)); | 1402 | irt_isint(ir->t) || irt_isaddr(ir->t)); |
1339 | dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow); | 1403 | dest = ra_dest(as, ir, (!LJ_SOFTFP && irt_isnum(t)) ? RSET_FPR : allow); |
1340 | rset_clear(allow, dest); | 1404 | rset_clear(allow, dest); |
1341 | base = ra_alloc1(as, REF_BASE, allow); | 1405 | base = ra_alloc1(as, REF_BASE, allow); |
1342 | rset_clear(allow, base); | 1406 | rset_clear(allow, base); |
1343 | if (!LJ_SOFTFP && (ir->op2 & IRSLOAD_CONVERT)) { | 1407 | if (!LJ_SOFTFP32 && (ir->op2 & IRSLOAD_CONVERT)) { |
1344 | if (irt_isint(t)) { | 1408 | if (irt_isint(t)) { |
1345 | Reg tmp = ra_scratch(as, RSET_FPR); | 1409 | Reg tmp = ra_scratch(as, LJ_SOFTFP ? RSET_GPR : RSET_FPR); |
1410 | #if LJ_SOFTFP | ||
1411 | ra_evictset(as, rset_exclude(RSET_SCRATCH, dest)); | ||
1412 | ra_destreg(as, ir, RID_RET); | ||
1413 | emit_call(as, (void *)lj_ir_callinfo[IRCALL_softfp_d2i].func, 0); | ||
1414 | if (tmp != REGARG_FIRSTGPR) | ||
1415 | emit_move(as, REGARG_FIRSTGPR, tmp); | ||
1416 | #else | ||
1346 | emit_tg(as, MIPSI_MFC1, dest, tmp); | 1417 | emit_tg(as, MIPSI_MFC1, dest, tmp); |
1347 | emit_fg(as, MIPSI_TRUNC_W_D, tmp, tmp); | 1418 | emit_fg(as, MIPSI_TRUNC_W_D, tmp, tmp); |
1419 | #endif | ||
1348 | dest = tmp; | 1420 | dest = tmp; |
1349 | t.irt = IRT_NUM; /* Check for original type. */ | 1421 | t.irt = IRT_NUM; /* Check for original type. */ |
1350 | } else { | 1422 | } else { |
1351 | Reg tmp = ra_scratch(as, RSET_GPR); | 1423 | Reg tmp = ra_scratch(as, RSET_GPR); |
1424 | #if LJ_SOFTFP | ||
1425 | ra_evictset(as, rset_exclude(RSET_SCRATCH, dest)); | ||
1426 | ra_destreg(as, ir, RID_RET); | ||
1427 | emit_call(as, (void *)lj_ir_callinfo[IRCALL_softfp_i2d].func, 0); | ||
1428 | emit_dta(as, MIPSI_SLL, REGARG_FIRSTGPR, tmp, 0); | ||
1429 | #else | ||
1352 | emit_fg(as, MIPSI_CVT_D_W, dest, dest); | 1430 | emit_fg(as, MIPSI_CVT_D_W, dest, dest); |
1353 | emit_tg(as, MIPSI_MTC1, tmp, dest); | 1431 | emit_tg(as, MIPSI_MTC1, tmp, dest); |
1432 | #endif | ||
1354 | dest = tmp; | 1433 | dest = tmp; |
1355 | t.irt = IRT_INT; /* Check for original type. */ | 1434 | t.irt = IRT_INT; /* Check for original type. */ |
1356 | } | 1435 | } |
@@ -1399,7 +1478,7 @@ dotypecheck: | |||
1399 | if (irt_isnum(t)) { | 1478 | if (irt_isnum(t)) { |
1400 | asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO); | 1479 | asm_guard(as, MIPSI_BEQ, RID_TMP, RID_ZERO); |
1401 | emit_tsi(as, MIPSI_SLTIU, RID_TMP, RID_TMP, (int32_t)LJ_TISNUM); | 1480 | emit_tsi(as, MIPSI_SLTIU, RID_TMP, RID_TMP, (int32_t)LJ_TISNUM); |
1402 | if (ra_hasreg(dest)) | 1481 | if (!LJ_SOFTFP && ra_hasreg(dest)) |
1403 | emit_hsi(as, MIPSI_LDC1, dest, base, ofs); | 1482 | emit_hsi(as, MIPSI_LDC1, dest, base, ofs); |
1404 | } else { | 1483 | } else { |
1405 | asm_guard(as, MIPSI_BNE, RID_TMP, | 1484 | asm_guard(as, MIPSI_BNE, RID_TMP, |
@@ -1409,7 +1488,7 @@ dotypecheck: | |||
1409 | } | 1488 | } |
1410 | emit_tsi(as, MIPSI_LD, type, base, ofs); | 1489 | emit_tsi(as, MIPSI_LD, type, base, ofs); |
1411 | } else if (ra_hasreg(dest)) { | 1490 | } else if (ra_hasreg(dest)) { |
1412 | if (irt_isnum(t)) | 1491 | if (!LJ_SOFTFP && irt_isnum(t)) |
1413 | emit_hsi(as, MIPSI_LDC1, dest, base, ofs); | 1492 | emit_hsi(as, MIPSI_LDC1, dest, base, ofs); |
1414 | else | 1493 | else |
1415 | emit_tsi(as, irt_isint(t) ? MIPSI_LW : MIPSI_LD, dest, base, | 1494 | emit_tsi(as, irt_isint(t) ? MIPSI_LW : MIPSI_LD, dest, base, |
@@ -1548,26 +1627,40 @@ static void asm_fpunary(ASMState *as, IRIns *ir, MIPSIns mi) | |||
1548 | Reg left = ra_hintalloc(as, ir->op1, dest, RSET_FPR); | 1627 | Reg left = ra_hintalloc(as, ir->op1, dest, RSET_FPR); |
1549 | emit_fg(as, mi, dest, left); | 1628 | emit_fg(as, mi, dest, left); |
1550 | } | 1629 | } |
1630 | #endif | ||
1551 | 1631 | ||
1632 | #if !LJ_SOFTFP32 | ||
1552 | static void asm_fpmath(ASMState *as, IRIns *ir) | 1633 | static void asm_fpmath(ASMState *as, IRIns *ir) |
1553 | { | 1634 | { |
1554 | if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir)) | 1635 | if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir)) |
1555 | return; | 1636 | return; |
1637 | #if !LJ_SOFTFP | ||
1556 | if (ir->op2 <= IRFPM_TRUNC) | 1638 | if (ir->op2 <= IRFPM_TRUNC) |
1557 | asm_callround(as, ir, IRCALL_lj_vm_floor + ir->op2); | 1639 | asm_callround(as, ir, IRCALL_lj_vm_floor + ir->op2); |
1558 | else if (ir->op2 == IRFPM_SQRT) | 1640 | else if (ir->op2 == IRFPM_SQRT) |
1559 | asm_fpunary(as, ir, MIPSI_SQRT_D); | 1641 | asm_fpunary(as, ir, MIPSI_SQRT_D); |
1560 | else | 1642 | else |
1643 | #endif | ||
1561 | asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2); | 1644 | asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2); |
1562 | } | 1645 | } |
1563 | #endif | 1646 | #endif |
1564 | 1647 | ||
1648 | #if !LJ_SOFTFP | ||
1649 | #define asm_fpadd(as, ir) asm_fparith(as, ir, MIPSI_ADD_D) | ||
1650 | #define asm_fpsub(as, ir) asm_fparith(as, ir, MIPSI_SUB_D) | ||
1651 | #define asm_fpmul(as, ir) asm_fparith(as, ir, MIPSI_MUL_D) | ||
1652 | #elif LJ_64 /* && LJ_SOFTFP */ | ||
1653 | #define asm_fpadd(as, ir) asm_callid(as, ir, IRCALL_softfp_add) | ||
1654 | #define asm_fpsub(as, ir) asm_callid(as, ir, IRCALL_softfp_sub) | ||
1655 | #define asm_fpmul(as, ir) asm_callid(as, ir, IRCALL_softfp_mul) | ||
1656 | #endif | ||
1657 | |||
1565 | static void asm_add(ASMState *as, IRIns *ir) | 1658 | static void asm_add(ASMState *as, IRIns *ir) |
1566 | { | 1659 | { |
1567 | IRType1 t = ir->t; | 1660 | IRType1 t = ir->t; |
1568 | #if !LJ_SOFTFP | 1661 | #if !LJ_SOFTFP32 |
1569 | if (irt_isnum(t)) { | 1662 | if (irt_isnum(t)) { |
1570 | asm_fparith(as, ir, MIPSI_ADD_D); | 1663 | asm_fpadd(as, ir); |
1571 | } else | 1664 | } else |
1572 | #endif | 1665 | #endif |
1573 | { | 1666 | { |
@@ -1589,9 +1682,9 @@ static void asm_add(ASMState *as, IRIns *ir) | |||
1589 | 1682 | ||
1590 | static void asm_sub(ASMState *as, IRIns *ir) | 1683 | static void asm_sub(ASMState *as, IRIns *ir) |
1591 | { | 1684 | { |
1592 | #if !LJ_SOFTFP | 1685 | #if !LJ_SOFTFP32 |
1593 | if (irt_isnum(ir->t)) { | 1686 | if (irt_isnum(ir->t)) { |
1594 | asm_fparith(as, ir, MIPSI_SUB_D); | 1687 | asm_fpsub(as, ir); |
1595 | } else | 1688 | } else |
1596 | #endif | 1689 | #endif |
1597 | { | 1690 | { |
@@ -1605,9 +1698,9 @@ static void asm_sub(ASMState *as, IRIns *ir) | |||
1605 | 1698 | ||
1606 | static void asm_mul(ASMState *as, IRIns *ir) | 1699 | static void asm_mul(ASMState *as, IRIns *ir) |
1607 | { | 1700 | { |
1608 | #if !LJ_SOFTFP | 1701 | #if !LJ_SOFTFP32 |
1609 | if (irt_isnum(ir->t)) { | 1702 | if (irt_isnum(ir->t)) { |
1610 | asm_fparith(as, ir, MIPSI_MUL_D); | 1703 | asm_fpmul(as, ir); |
1611 | } else | 1704 | } else |
1612 | #endif | 1705 | #endif |
1613 | { | 1706 | { |
@@ -1634,7 +1727,7 @@ static void asm_mod(ASMState *as, IRIns *ir) | |||
1634 | asm_callid(as, ir, IRCALL_lj_vm_modi); | 1727 | asm_callid(as, ir, IRCALL_lj_vm_modi); |
1635 | } | 1728 | } |
1636 | 1729 | ||
1637 | #if !LJ_SOFTFP | 1730 | #if !LJ_SOFTFP32 |
1638 | static void asm_pow(ASMState *as, IRIns *ir) | 1731 | static void asm_pow(ASMState *as, IRIns *ir) |
1639 | { | 1732 | { |
1640 | #if LJ_64 && LJ_HASFFI | 1733 | #if LJ_64 && LJ_HASFFI |
@@ -1654,7 +1747,11 @@ static void asm_div(ASMState *as, IRIns *ir) | |||
1654 | IRCALL_lj_carith_divu64); | 1747 | IRCALL_lj_carith_divu64); |
1655 | else | 1748 | else |
1656 | #endif | 1749 | #endif |
1750 | #if !LJ_SOFTFP | ||
1657 | asm_fparith(as, ir, MIPSI_DIV_D); | 1751 | asm_fparith(as, ir, MIPSI_DIV_D); |
1752 | #else | ||
1753 | asm_callid(as, ir, IRCALL_softfp_div); | ||
1754 | #endif | ||
1658 | } | 1755 | } |
1659 | #endif | 1756 | #endif |
1660 | 1757 | ||
@@ -1664,6 +1761,13 @@ static void asm_neg(ASMState *as, IRIns *ir) | |||
1664 | if (irt_isnum(ir->t)) { | 1761 | if (irt_isnum(ir->t)) { |
1665 | asm_fpunary(as, ir, MIPSI_NEG_D); | 1762 | asm_fpunary(as, ir, MIPSI_NEG_D); |
1666 | } else | 1763 | } else |
1764 | #elif LJ_64 /* && LJ_SOFTFP */ | ||
1765 | if (irt_isnum(ir->t)) { | ||
1766 | Reg dest = ra_dest(as, ir, RSET_GPR); | ||
1767 | Reg left = ra_hintalloc(as, ir->op1, dest, RSET_GPR); | ||
1768 | emit_dst(as, MIPSI_XOR, dest, left, | ||
1769 | ra_allock(as, 0x8000000000000000ll, rset_exclude(RSET_GPR, dest))); | ||
1770 | } else | ||
1667 | #endif | 1771 | #endif |
1668 | { | 1772 | { |
1669 | Reg dest = ra_dest(as, ir, RSET_GPR); | 1773 | Reg dest = ra_dest(as, ir, RSET_GPR); |
@@ -1673,7 +1777,17 @@ static void asm_neg(ASMState *as, IRIns *ir) | |||
1673 | } | 1777 | } |
1674 | } | 1778 | } |
1675 | 1779 | ||
1780 | #if !LJ_SOFTFP | ||
1676 | #define asm_abs(as, ir) asm_fpunary(as, ir, MIPSI_ABS_D) | 1781 | #define asm_abs(as, ir) asm_fpunary(as, ir, MIPSI_ABS_D) |
1782 | #elif LJ_64 /* && LJ_SOFTFP */ | ||
1783 | static void asm_abs(ASMState *as, IRIns *ir) | ||
1784 | { | ||
1785 | Reg dest = ra_dest(as, ir, RSET_GPR); | ||
1786 | Reg left = ra_alloc1(as, ir->op1, RSET_GPR); | ||
1787 | emit_tsml(as, MIPSI_DEXTM, dest, left, 30, 0); | ||
1788 | } | ||
1789 | #endif | ||
1790 | |||
1677 | #define asm_atan2(as, ir) asm_callid(as, ir, IRCALL_atan2) | 1791 | #define asm_atan2(as, ir) asm_callid(as, ir, IRCALL_atan2) |
1678 | #define asm_ldexp(as, ir) asm_callid(as, ir, IRCALL_ldexp) | 1792 | #define asm_ldexp(as, ir) asm_callid(as, ir, IRCALL_ldexp) |
1679 | 1793 | ||
@@ -1918,15 +2032,21 @@ static void asm_bror(ASMState *as, IRIns *ir) | |||
1918 | } | 2032 | } |
1919 | } | 2033 | } |
1920 | 2034 | ||
1921 | #if LJ_32 && LJ_SOFTFP | 2035 | #if LJ_SOFTFP |
1922 | static void asm_sfpmin_max(ASMState *as, IRIns *ir) | 2036 | static void asm_sfpmin_max(ASMState *as, IRIns *ir) |
1923 | { | 2037 | { |
1924 | CCallInfo ci = lj_ir_callinfo[(IROp)ir->o == IR_MIN ? IRCALL_lj_vm_sfmin : IRCALL_lj_vm_sfmax]; | 2038 | CCallInfo ci = lj_ir_callinfo[(IROp)ir->o == IR_MIN ? IRCALL_lj_vm_sfmin : IRCALL_lj_vm_sfmax]; |
2039 | #if LJ_64 | ||
2040 | IRRef args[2]; | ||
2041 | args[0] = ir->op1; | ||
2042 | args[1] = ir->op2; | ||
2043 | #else | ||
1925 | IRRef args[4]; | 2044 | IRRef args[4]; |
1926 | args[0^LJ_BE] = ir->op1; | 2045 | args[0^LJ_BE] = ir->op1; |
1927 | args[1^LJ_BE] = (ir+1)->op1; | 2046 | args[1^LJ_BE] = (ir+1)->op1; |
1928 | args[2^LJ_BE] = ir->op2; | 2047 | args[2^LJ_BE] = ir->op2; |
1929 | args[3^LJ_BE] = (ir+1)->op2; | 2048 | args[3^LJ_BE] = (ir+1)->op2; |
2049 | #endif | ||
1930 | asm_setupresult(as, ir, &ci); | 2050 | asm_setupresult(as, ir, &ci); |
1931 | emit_call(as, (void *)ci.func, 0); | 2051 | emit_call(as, (void *)ci.func, 0); |
1932 | ci.func = NULL; | 2052 | ci.func = NULL; |
@@ -1936,7 +2056,10 @@ static void asm_sfpmin_max(ASMState *as, IRIns *ir) | |||
1936 | 2056 | ||
1937 | static void asm_min_max(ASMState *as, IRIns *ir, int ismax) | 2057 | static void asm_min_max(ASMState *as, IRIns *ir, int ismax) |
1938 | { | 2058 | { |
1939 | if (!LJ_SOFTFP && irt_isnum(ir->t)) { | 2059 | if (!LJ_SOFTFP32 && irt_isnum(ir->t)) { |
2060 | #if LJ_SOFTFP | ||
2061 | asm_sfpmin_max(as, ir); | ||
2062 | #else | ||
1940 | Reg dest = ra_dest(as, ir, RSET_FPR); | 2063 | Reg dest = ra_dest(as, ir, RSET_FPR); |
1941 | Reg right, left = ra_alloc2(as, ir, RSET_FPR); | 2064 | Reg right, left = ra_alloc2(as, ir, RSET_FPR); |
1942 | right = (left >> 8); left &= 255; | 2065 | right = (left >> 8); left &= 255; |
@@ -1947,6 +2070,7 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax) | |||
1947 | if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right); | 2070 | if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right); |
1948 | } | 2071 | } |
1949 | emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? left : right, ismax ? right : left); | 2072 | emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? left : right, ismax ? right : left); |
2073 | #endif | ||
1950 | } else { | 2074 | } else { |
1951 | Reg dest = ra_dest(as, ir, RSET_GPR); | 2075 | Reg dest = ra_dest(as, ir, RSET_GPR); |
1952 | Reg right, left = ra_alloc2(as, ir, RSET_GPR); | 2076 | Reg right, left = ra_alloc2(as, ir, RSET_GPR); |
@@ -1967,18 +2091,24 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax) | |||
1967 | 2091 | ||
1968 | /* -- Comparisons --------------------------------------------------------- */ | 2092 | /* -- Comparisons --------------------------------------------------------- */ |
1969 | 2093 | ||
1970 | #if LJ_32 && LJ_SOFTFP | 2094 | #if LJ_SOFTFP |
1971 | /* SFP comparisons. */ | 2095 | /* SFP comparisons. */ |
1972 | static void asm_sfpcomp(ASMState *as, IRIns *ir) | 2096 | static void asm_sfpcomp(ASMState *as, IRIns *ir) |
1973 | { | 2097 | { |
1974 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_softfp_cmp]; | 2098 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_softfp_cmp]; |
1975 | RegSet drop = RSET_SCRATCH; | 2099 | RegSet drop = RSET_SCRATCH; |
1976 | Reg r; | 2100 | Reg r; |
2101 | #if LJ_64 | ||
2102 | IRRef args[2]; | ||
2103 | args[0] = ir->op1; | ||
2104 | args[1] = ir->op2; | ||
2105 | #else | ||
1977 | IRRef args[4]; | 2106 | IRRef args[4]; |
1978 | args[LJ_LE ? 0 : 1] = ir->op1; args[LJ_LE ? 1 : 0] = (ir+1)->op1; | 2107 | args[LJ_LE ? 0 : 1] = ir->op1; args[LJ_LE ? 1 : 0] = (ir+1)->op1; |
1979 | args[LJ_LE ? 2 : 3] = ir->op2; args[LJ_LE ? 3 : 2] = (ir+1)->op2; | 2108 | args[LJ_LE ? 2 : 3] = ir->op2; args[LJ_LE ? 3 : 2] = (ir+1)->op2; |
2109 | #endif | ||
1980 | 2110 | ||
1981 | for (r = REGARG_FIRSTGPR; r <= REGARG_FIRSTGPR+3; r++) { | 2111 | for (r = REGARG_FIRSTGPR; r <= REGARG_FIRSTGPR+(LJ_64?1:3); r++) { |
1982 | if (!rset_test(as->freeset, r) && | 2112 | if (!rset_test(as->freeset, r) && |
1983 | regcost_ref(as->cost[r]) == args[r-REGARG_FIRSTGPR]) | 2113 | regcost_ref(as->cost[r]) == args[r-REGARG_FIRSTGPR]) |
1984 | rset_clear(drop, r); | 2114 | rset_clear(drop, r); |
@@ -2032,11 +2162,15 @@ static void asm_comp(ASMState *as, IRIns *ir) | |||
2032 | { | 2162 | { |
2033 | /* ORDER IR: LT GE LE GT ULT UGE ULE UGT. */ | 2163 | /* ORDER IR: LT GE LE GT ULT UGE ULE UGT. */ |
2034 | IROp op = ir->o; | 2164 | IROp op = ir->o; |
2035 | if (!LJ_SOFTFP && irt_isnum(ir->t)) { | 2165 | if (!LJ_SOFTFP32 && irt_isnum(ir->t)) { |
2166 | #if LJ_SOFTFP | ||
2167 | asm_sfpcomp(as, ir); | ||
2168 | #else | ||
2036 | Reg right, left = ra_alloc2(as, ir, RSET_FPR); | 2169 | Reg right, left = ra_alloc2(as, ir, RSET_FPR); |
2037 | right = (left >> 8); left &= 255; | 2170 | right = (left >> 8); left &= 255; |
2038 | asm_guard(as, (op&1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0); | 2171 | asm_guard(as, (op&1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0); |
2039 | emit_fgh(as, MIPSI_C_OLT_D + ((op&3) ^ ((op>>2)&1)), 0, left, right); | 2172 | emit_fgh(as, MIPSI_C_OLT_D + ((op&3) ^ ((op>>2)&1)), 0, left, right); |
2173 | #endif | ||
2040 | } else { | 2174 | } else { |
2041 | Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR); | 2175 | Reg right, left = ra_alloc1(as, ir->op1, RSET_GPR); |
2042 | if (op == IR_ABC) op = IR_UGT; | 2176 | if (op == IR_ABC) op = IR_UGT; |
@@ -2068,9 +2202,13 @@ static void asm_equal(ASMState *as, IRIns *ir) | |||
2068 | Reg right, left = ra_alloc2(as, ir, (!LJ_SOFTFP && irt_isnum(ir->t)) ? | 2202 | Reg right, left = ra_alloc2(as, ir, (!LJ_SOFTFP && irt_isnum(ir->t)) ? |
2069 | RSET_FPR : RSET_GPR); | 2203 | RSET_FPR : RSET_GPR); |
2070 | right = (left >> 8); left &= 255; | 2204 | right = (left >> 8); left &= 255; |
2071 | if (!LJ_SOFTFP && irt_isnum(ir->t)) { | 2205 | if (!LJ_SOFTFP32 && irt_isnum(ir->t)) { |
2206 | #if LJ_SOFTFP | ||
2207 | asm_sfpcomp(as, ir); | ||
2208 | #else | ||
2072 | asm_guard(as, (ir->o & 1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0); | 2209 | asm_guard(as, (ir->o & 1) ? MIPSI_BC1T : MIPSI_BC1F, 0, 0); |
2073 | emit_fgh(as, MIPSI_C_EQ_D, 0, left, right); | 2210 | emit_fgh(as, MIPSI_C_EQ_D, 0, left, right); |
2211 | #endif | ||
2074 | } else { | 2212 | } else { |
2075 | asm_guard(as, (ir->o & 1) ? MIPSI_BEQ : MIPSI_BNE, left, right); | 2213 | asm_guard(as, (ir->o & 1) ? MIPSI_BEQ : MIPSI_BNE, left, right); |
2076 | } | 2214 | } |
@@ -2263,7 +2401,7 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap) | |||
2263 | if ((sn & SNAP_NORESTORE)) | 2401 | if ((sn & SNAP_NORESTORE)) |
2264 | continue; | 2402 | continue; |
2265 | if (irt_isnum(ir->t)) { | 2403 | if (irt_isnum(ir->t)) { |
2266 | #if LJ_SOFTFP | 2404 | #if LJ_SOFTFP32 |
2267 | Reg tmp; | 2405 | Reg tmp; |
2268 | RegSet allow = rset_exclude(RSET_GPR, RID_BASE); | 2406 | RegSet allow = rset_exclude(RSET_GPR, RID_BASE); |
2269 | lua_assert(irref_isk(ref)); /* LJ_SOFTFP: must be a number constant. */ | 2407 | lua_assert(irref_isk(ref)); /* LJ_SOFTFP: must be a number constant. */ |
@@ -2272,6 +2410,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap) | |||
2272 | if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1); | 2410 | if (rset_test(as->freeset, tmp+1)) allow = RID2RSET(tmp+1); |
2273 | tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, allow); | 2411 | tmp = ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, allow); |
2274 | emit_tsi(as, MIPSI_SW, tmp, RID_BASE, ofs+(LJ_BE?0:4)); | 2412 | emit_tsi(as, MIPSI_SW, tmp, RID_BASE, ofs+(LJ_BE?0:4)); |
2413 | #elif LJ_SOFTFP /* && LJ_64 */ | ||
2414 | Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, RID_BASE)); | ||
2415 | emit_tsi(as, MIPSI_SD, src, RID_BASE, ofs); | ||
2275 | #else | 2416 | #else |
2276 | Reg src = ra_alloc1(as, ref, RSET_FPR); | 2417 | Reg src = ra_alloc1(as, ref, RSET_FPR); |
2277 | emit_hsi(as, MIPSI_SDC1, src, RID_BASE, ofs); | 2418 | emit_hsi(as, MIPSI_SDC1, src, RID_BASE, ofs); |