aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_mips.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_asm_mips.h217
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 */
465static 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
482static 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
466static void asm_conv(ASMState *as, IRIns *ir) 490static 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
1200static void asm_ahuvload(ASMState *as, IRIns *ir) 1264static 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
1552static void asm_fpmath(ASMState *as, IRIns *ir) 1633static 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
1565static void asm_add(ASMState *as, IRIns *ir) 1658static 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
1590static void asm_sub(ASMState *as, IRIns *ir) 1683static 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
1606static void asm_mul(ASMState *as, IRIns *ir) 1699static 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
1638static void asm_pow(ASMState *as, IRIns *ir) 1731static 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 */
1783static 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
1922static void asm_sfpmin_max(ASMState *as, IRIns *ir) 2036static 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
1937static void asm_min_max(ASMState *as, IRIns *ir, int ismax) 2057static 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. */
1972static void asm_sfpcomp(ASMState *as, IRIns *ir) 2096static 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);