mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-04-20 05:53:26 +00:00
Fix math.min()/math.max() inconsistencies.
This commit is contained in:
parent
1e6e8aaa20
commit
03208c8162
@ -1659,8 +1659,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, int cc, int fcc)
|
|||||||
asm_intmin_max(as, ir, cc);
|
asm_intmin_max(as, ir, cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define asm_min(as, ir) asm_min_max(as, ir, CC_GT, CC_HI)
|
#define asm_min(as, ir) asm_min_max(as, ir, CC_GT, CC_PL)
|
||||||
#define asm_max(as, ir) asm_min_max(as, ir, CC_LT, CC_LO)
|
#define asm_max(as, ir) asm_min_max(as, ir, CC_LT, CC_LE)
|
||||||
|
|
||||||
/* -- Comparisons --------------------------------------------------------- */
|
/* -- Comparisons --------------------------------------------------------- */
|
||||||
|
|
||||||
@ -1852,7 +1852,7 @@ static void asm_hiop(ASMState *as, IRIns *ir)
|
|||||||
} else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
|
} else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
|
||||||
as->curins--; /* Always skip the loword min/max. */
|
as->curins--; /* Always skip the loword min/max. */
|
||||||
if (uselo || usehi)
|
if (uselo || usehi)
|
||||||
asm_sfpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_HI : CC_LO);
|
asm_sfpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_PL : CC_LE);
|
||||||
return;
|
return;
|
||||||
#elif LJ_HASFFI
|
#elif LJ_HASFFI
|
||||||
} else if ((ir-1)->o == IR_CONV) {
|
} else if ((ir-1)->o == IR_CONV) {
|
||||||
|
@ -1598,7 +1598,7 @@ static void asm_fpmin_max(ASMState *as, IRIns *ir, A64CC fcc)
|
|||||||
Reg dest = (ra_dest(as, ir, RSET_FPR) & 31);
|
Reg dest = (ra_dest(as, ir, RSET_FPR) & 31);
|
||||||
Reg right, left = ra_alloc2(as, ir, RSET_FPR);
|
Reg right, left = ra_alloc2(as, ir, RSET_FPR);
|
||||||
right = ((left >> 8) & 31); left &= 31;
|
right = ((left >> 8) & 31); left &= 31;
|
||||||
emit_dnm(as, A64I_FCSELd | A64F_CC(fcc), dest, left, right);
|
emit_dnm(as, A64I_FCSELd | A64F_CC(fcc), dest, right, left);
|
||||||
emit_nm(as, A64I_FCMPd, left, right);
|
emit_nm(as, A64I_FCMPd, left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1610,8 +1610,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, A64CC cc, A64CC fcc)
|
|||||||
asm_intmin_max(as, ir, cc);
|
asm_intmin_max(as, ir, cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define asm_max(as, ir) asm_min_max(as, ir, CC_GT, CC_HI)
|
#define asm_min(as, ir) asm_min_max(as, ir, CC_LT, CC_PL)
|
||||||
#define asm_min(as, ir) asm_min_max(as, ir, CC_LT, CC_LO)
|
#define asm_max(as, ir) asm_min_max(as, ir, CC_GT, CC_LE)
|
||||||
|
|
||||||
/* -- Comparisons --------------------------------------------------------- */
|
/* -- Comparisons --------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -2121,12 +2121,12 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
|
|||||||
right = (left >> 8); left &= 255;
|
right = (left >> 8); left &= 255;
|
||||||
#if !LJ_TARGET_MIPSR6
|
#if !LJ_TARGET_MIPSR6
|
||||||
if (dest == left) {
|
if (dest == left) {
|
||||||
emit_fg(as, MIPSI_MOVT_D, dest, right);
|
emit_fg(as, MIPSI_MOVF_D, dest, right);
|
||||||
} else {
|
} else {
|
||||||
emit_fg(as, MIPSI_MOVF_D, dest, left);
|
emit_fg(as, MIPSI_MOVT_D, dest, left);
|
||||||
if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right);
|
if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right);
|
||||||
}
|
}
|
||||||
emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? left : right, ismax ? right : left);
|
emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? right : left, ismax ? left : right);
|
||||||
#else
|
#else
|
||||||
emit_fgh(as, ismax ? MIPSI_MAX_D : MIPSI_MIN_D, dest, left, right);
|
emit_fgh(as, ismax ? MIPSI_MAX_D : MIPSI_MIN_D, dest, left, right);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1724,9 +1724,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
|
|||||||
if (tmp == left || tmp == right)
|
if (tmp == left || tmp == right)
|
||||||
tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_FPR,
|
tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_FPR,
|
||||||
dest), left), right));
|
dest), left), right));
|
||||||
emit_facb(as, PPCI_FSEL, dest, tmp,
|
emit_facb(as, PPCI_FSEL, dest, tmp, left, right);
|
||||||
ismax ? left : right, ismax ? right : left);
|
emit_fab(as, PPCI_FSUB, tmp, ismax ? left : right, ismax ? right : left);
|
||||||
emit_fab(as, PPCI_FSUB, tmp, left, right);
|
|
||||||
} else {
|
} else {
|
||||||
Reg dest = ra_dest(as, ir, RSET_GPR);
|
Reg dest = ra_dest(as, ir, RSET_GPR);
|
||||||
Reg tmp1 = RID_TMP, tmp2 = dest;
|
Reg tmp1 = RID_TMP, tmp2 = dest;
|
||||||
|
@ -1774,8 +1774,6 @@ LJFOLDF(reassoc_intarith_k64)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
LJFOLD(MIN MIN any)
|
|
||||||
LJFOLD(MAX MAX any)
|
|
||||||
LJFOLD(BAND BAND any)
|
LJFOLD(BAND BAND any)
|
||||||
LJFOLD(BOR BOR any)
|
LJFOLD(BOR BOR any)
|
||||||
LJFOLDF(reassoc_dup)
|
LJFOLDF(reassoc_dup)
|
||||||
@ -1785,6 +1783,15 @@ LJFOLDF(reassoc_dup)
|
|||||||
return NEXTFOLD;
|
return NEXTFOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LJFOLD(MIN MIN any)
|
||||||
|
LJFOLD(MAX MAX any)
|
||||||
|
LJFOLDF(reassoc_dup_minmax)
|
||||||
|
{
|
||||||
|
if (fins->op2 == fleft->op2)
|
||||||
|
return LEFTFOLD; /* (a o b) o b ==> a o b */
|
||||||
|
return NEXTFOLD;
|
||||||
|
}
|
||||||
|
|
||||||
LJFOLD(BXOR BXOR any)
|
LJFOLD(BXOR BXOR any)
|
||||||
LJFOLDF(reassoc_bxor)
|
LJFOLDF(reassoc_bxor)
|
||||||
{
|
{
|
||||||
@ -1823,23 +1830,12 @@ LJFOLDF(reassoc_shift)
|
|||||||
return NEXTFOLD;
|
return NEXTFOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
LJFOLD(MIN MIN KNUM)
|
|
||||||
LJFOLD(MAX MAX KNUM)
|
|
||||||
LJFOLD(MIN MIN KINT)
|
LJFOLD(MIN MIN KINT)
|
||||||
LJFOLD(MAX MAX KINT)
|
LJFOLD(MAX MAX KINT)
|
||||||
LJFOLDF(reassoc_minmax_k)
|
LJFOLDF(reassoc_minmax_k)
|
||||||
{
|
{
|
||||||
IRIns *irk = IR(fleft->op2);
|
IRIns *irk = IR(fleft->op2);
|
||||||
if (irk->o == IR_KNUM) {
|
if (irk->o == IR_KINT) {
|
||||||
lua_Number a = ir_knum(irk)->n;
|
|
||||||
lua_Number y = lj_vm_foldarith(a, knumright, fins->o - IR_ADD);
|
|
||||||
if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
|
|
||||||
return LEFTFOLD;
|
|
||||||
PHIBARRIER(fleft);
|
|
||||||
fins->op1 = fleft->op1;
|
|
||||||
fins->op2 = (IRRef1)lj_ir_knum(J, y);
|
|
||||||
return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */
|
|
||||||
} else if (irk->o == IR_KINT) {
|
|
||||||
int32_t a = irk->i;
|
int32_t a = irk->i;
|
||||||
int32_t y = kfold_intop(a, fright->i, fins->o);
|
int32_t y = kfold_intop(a, fright->i, fins->o);
|
||||||
if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
|
if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
|
||||||
@ -1852,24 +1848,6 @@ LJFOLDF(reassoc_minmax_k)
|
|||||||
return NEXTFOLD;
|
return NEXTFOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
LJFOLD(MIN MAX any)
|
|
||||||
LJFOLD(MAX MIN any)
|
|
||||||
LJFOLDF(reassoc_minmax_left)
|
|
||||||
{
|
|
||||||
if (fins->op2 == fleft->op1 || fins->op2 == fleft->op2)
|
|
||||||
return RIGHTFOLD; /* (b o1 a) o2 b ==> b; (a o1 b) o2 b ==> b */
|
|
||||||
return NEXTFOLD;
|
|
||||||
}
|
|
||||||
|
|
||||||
LJFOLD(MIN any MAX)
|
|
||||||
LJFOLD(MAX any MIN)
|
|
||||||
LJFOLDF(reassoc_minmax_right)
|
|
||||||
{
|
|
||||||
if (fins->op1 == fright->op1 || fins->op1 == fright->op2)
|
|
||||||
return LEFTFOLD; /* a o2 (a o1 b) ==> a; a o2 (b o1 a) ==> a */
|
|
||||||
return NEXTFOLD;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Array bounds check elimination -------------------------------------- */
|
/* -- Array bounds check elimination -------------------------------------- */
|
||||||
|
|
||||||
/* Eliminate ABC across PHIs to handle t[i-1] forwarding case.
|
/* Eliminate ABC across PHIs to handle t[i-1] forwarding case.
|
||||||
@ -1995,8 +1973,6 @@ LJFOLDF(comm_comp)
|
|||||||
|
|
||||||
LJFOLD(BAND any any)
|
LJFOLD(BAND any any)
|
||||||
LJFOLD(BOR any any)
|
LJFOLD(BOR any any)
|
||||||
LJFOLD(MIN any any)
|
|
||||||
LJFOLD(MAX any any)
|
|
||||||
LJFOLDF(comm_dup)
|
LJFOLDF(comm_dup)
|
||||||
{
|
{
|
||||||
if (fins->op1 == fins->op2) /* x o x ==> x */
|
if (fins->op1 == fins->op2) /* x o x ==> x */
|
||||||
@ -2004,6 +1980,15 @@ LJFOLDF(comm_dup)
|
|||||||
return fold_comm_swap(J);
|
return fold_comm_swap(J);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LJFOLD(MIN any any)
|
||||||
|
LJFOLD(MAX any any)
|
||||||
|
LJFOLDF(comm_dup_minmax)
|
||||||
|
{
|
||||||
|
if (fins->op1 == fins->op2) /* x o x ==> x */
|
||||||
|
return LEFTFOLD;
|
||||||
|
return NEXTFOLD;
|
||||||
|
}
|
||||||
|
|
||||||
LJFOLD(BXOR any any)
|
LJFOLD(BXOR any any)
|
||||||
LJFOLDF(comm_bxor)
|
LJFOLDF(comm_bxor)
|
||||||
{
|
{
|
||||||
|
@ -50,8 +50,8 @@ double lj_vm_foldarith(double x, double y, int op)
|
|||||||
#if LJ_HASJIT
|
#if LJ_HASJIT
|
||||||
case IR_ATAN2 - IR_ADD: return atan2(x, y); break;
|
case IR_ATAN2 - IR_ADD: return atan2(x, y); break;
|
||||||
case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break;
|
case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break;
|
||||||
case IR_MIN - IR_ADD: return x > y ? y : x; break;
|
case IR_MIN - IR_ADD: return x < y ? x : y; break;
|
||||||
case IR_MAX - IR_ADD: return x < y ? y : x; break;
|
case IR_MAX - IR_ADD: return x > y ? x : y; break;
|
||||||
#endif
|
#endif
|
||||||
default: return x;
|
default: return x;
|
||||||
}
|
}
|
||||||
|
@ -1716,8 +1716,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|.endif
|
|.endif
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
| math_minmax math_min, gt, hi
|
| math_minmax math_min, gt, pl
|
||||||
| math_minmax math_max, lt, lo
|
| math_minmax math_max, lt, le
|
||||||
|
|
|
|
||||||
|//-- String library -----------------------------------------------------
|
|//-- String library -----------------------------------------------------
|
||||||
|
|
|
|
||||||
|
@ -1489,8 +1489,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| b <6
|
| b <6
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
| math_minmax math_min, gt, hi
|
| math_minmax math_min, gt, pl
|
||||||
| math_minmax math_max, lt, lo
|
| math_minmax math_max, lt, le
|
||||||
|
|
|
|
||||||
|//-- String library -----------------------------------------------------
|
|//-- String library -----------------------------------------------------
|
||||||
|
|
|
|
||||||
|
@ -1768,7 +1768,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| b ->fff_res
|
| b ->fff_res
|
||||||
|. li RD, (2+1)*8
|
|. li RD, (2+1)*8
|
||||||
|
|
|
|
||||||
|.macro math_minmax, name, intins, fpins
|
|.macro math_minmax, name, intins, ismax
|
||||||
| .ffunc_1 name
|
| .ffunc_1 name
|
||||||
| addu TMP3, BASE, NARGS8:RC
|
| addu TMP3, BASE, NARGS8:RC
|
||||||
| bne SFARG1HI, TISNUM, >5
|
| bne SFARG1HI, TISNUM, >5
|
||||||
@ -1822,13 +1822,21 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|.endif
|
|.endif
|
||||||
|7:
|
|7:
|
||||||
|.if FPU
|
|.if FPU
|
||||||
|
|.if ismax
|
||||||
|
| c.olt.d FARG1, FRET1
|
||||||
|
|.else
|
||||||
| c.olt.d FRET1, FARG1
|
| c.olt.d FRET1, FARG1
|
||||||
| fpins FRET1, FARG1
|
|.endif
|
||||||
|
| movf.d FRET1, FARG1
|
||||||
|
|.else
|
||||||
|
|.if ismax
|
||||||
|
| bal ->vm_sfcmpogt
|
||||||
|.else
|
|.else
|
||||||
| bal ->vm_sfcmpolt
|
| bal ->vm_sfcmpolt
|
||||||
|
|.endif
|
||||||
|. nop
|
|. nop
|
||||||
| intins SFARG1LO, SFARG2LO, CRET1
|
| movz SFARG1LO, SFARG2LO, CRET1
|
||||||
| intins SFARG1HI, SFARG2HI, CRET1
|
| movz SFARG1HI, SFARG2HI, CRET1
|
||||||
|.endif
|
|.endif
|
||||||
| b <6
|
| b <6
|
||||||
|. addiu TMP2, TMP2, 8
|
|. addiu TMP2, TMP2, 8
|
||||||
@ -1849,8 +1857,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|
|
|
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
| math_minmax math_min, movz, movf.d
|
| math_minmax math_min, movz, 0
|
||||||
| math_minmax math_max, movn, movt.d
|
| math_minmax math_max, movn, 1
|
||||||
|
|
|
|
||||||
|//-- String library -----------------------------------------------------
|
|//-- String library -----------------------------------------------------
|
||||||
|
|
|
|
||||||
@ -2692,6 +2700,43 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|. move CRET1, CRET2
|
|. move CRET1, CRET2
|
||||||
|.endif
|
|.endif
|
||||||
|
|
|
|
||||||
|
|->vm_sfcmpogt:
|
||||||
|
|.if not FPU
|
||||||
|
| sll AT, SFARG2HI, 1
|
||||||
|
| sll TMP0, SFARG1HI, 1
|
||||||
|
| or CRET1, SFARG2LO, SFARG1LO
|
||||||
|
| or TMP1, AT, TMP0
|
||||||
|
| or TMP1, TMP1, CRET1
|
||||||
|
| beqz TMP1, >8 // Both args +-0: return 0.
|
||||||
|
|. sltu CRET1, r0, SFARG2LO
|
||||||
|
| lui TMP1, 0xffe0
|
||||||
|
| addu AT, AT, CRET1
|
||||||
|
| sltu CRET1, r0, SFARG1LO
|
||||||
|
| sltu AT, TMP1, AT
|
||||||
|
| addu TMP0, TMP0, CRET1
|
||||||
|
| sltu TMP0, TMP1, TMP0
|
||||||
|
| or TMP1, AT, TMP0
|
||||||
|
| bnez TMP1, >9 // Either arg is NaN: return 0 or 1;
|
||||||
|
|. and AT, SFARG2HI, SFARG1HI
|
||||||
|
| bltz AT, >5 // Both args negative?
|
||||||
|
|. nop
|
||||||
|
| beq SFARG2HI, SFARG1HI, >8
|
||||||
|
|. sltu CRET1, SFARG2LO, SFARG1LO
|
||||||
|
| jr ra
|
||||||
|
|. slt CRET1, SFARG2HI, SFARG1HI
|
||||||
|
|5: // Swap conditions if both operands are negative.
|
||||||
|
| beq SFARG2HI, SFARG1HI, >8
|
||||||
|
|. sltu CRET1, SFARG1LO, SFARG2LO
|
||||||
|
| jr ra
|
||||||
|
|. slt CRET1, SFARG1HI, SFARG2HI
|
||||||
|
|8:
|
||||||
|
| jr ra
|
||||||
|
|. nop
|
||||||
|
|9:
|
||||||
|
| jr ra
|
||||||
|
|. li CRET1, 0
|
||||||
|
|.endif
|
||||||
|
|
|
||||||
|// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a.
|
|// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a.
|
||||||
|// Input: SFARG*, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1.
|
|// Input: SFARG*, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1.
|
||||||
|->vm_sfcmpolex:
|
|->vm_sfcmpolex:
|
||||||
@ -2734,24 +2779,24 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|. li CRET1, 0
|
|. li CRET1, 0
|
||||||
|.endif
|
|.endif
|
||||||
|
|
|
|
||||||
|.macro sfmin_max, name, intins
|
|.macro sfmin_max, name, fpcall
|
||||||
|->vm_sf .. name:
|
|->vm_sf .. name:
|
||||||
|.if JIT and not FPU
|
|.if JIT and not FPU
|
||||||
| move TMP2, ra
|
| move TMP2, ra
|
||||||
| bal ->vm_sfcmpolt
|
| bal ->fpcall
|
||||||
|. nop
|
|. nop
|
||||||
| move TMP0, CRET1
|
| move TMP0, CRET1
|
||||||
| move SFRETHI, SFARG1HI
|
| move SFRETHI, SFARG1HI
|
||||||
| move SFRETLO, SFARG1LO
|
| move SFRETLO, SFARG1LO
|
||||||
| move ra, TMP2
|
| move ra, TMP2
|
||||||
| intins SFRETHI, SFARG2HI, TMP0
|
| movz SFRETHI, SFARG2HI, TMP0
|
||||||
| jr ra
|
| jr ra
|
||||||
|. intins SFRETLO, SFARG2LO, TMP0
|
|. movz SFRETLO, SFARG2LO, TMP0
|
||||||
|.endif
|
|.endif
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
| sfmin_max min, movz
|
| sfmin_max min, vm_sfcmpolt
|
||||||
| sfmin_max max, movn
|
| sfmin_max max, vm_sfcmpogt
|
||||||
|
|
|
|
||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
|//-- Miscellaneous functions --------------------------------------------
|
|//-- Miscellaneous functions --------------------------------------------
|
||||||
|
@ -1852,18 +1852,26 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|.if MIPSR6
|
|.if MIPSR6
|
||||||
| fpins FRET1, FRET1, FARG1
|
| fpins FRET1, FRET1, FARG1
|
||||||
|.else
|
|.else
|
||||||
|
|.if fpins // ismax
|
||||||
|
| c.olt.d FARG1, FRET1
|
||||||
|
|.else
|
||||||
| c.olt.d FRET1, FARG1
|
| c.olt.d FRET1, FARG1
|
||||||
| fpins FRET1, FARG1
|
|.endif
|
||||||
|
| movf.d FRET1, FARG1
|
||||||
|.endif
|
|.endif
|
||||||
|.else
|
|.else
|
||||||
|
|.if fpins // ismax
|
||||||
|
| bal ->vm_sfcmpogt
|
||||||
|
|.else
|
||||||
| bal ->vm_sfcmpolt
|
| bal ->vm_sfcmpolt
|
||||||
|
|.endif
|
||||||
|. nop
|
|. nop
|
||||||
|.if MIPSR6
|
|.if MIPSR6
|
||||||
| intins AT, CARG2, CRET1
|
| seleqz AT, CARG2, CRET1
|
||||||
| intinsc CARG1, CARG1, CRET1
|
| selnez CARG1, CARG1, CRET1
|
||||||
| or CARG1, CARG1, AT
|
| or CARG1, CARG1, AT
|
||||||
|.else
|
|.else
|
||||||
| intins CARG1, CARG2, CRET1
|
| movz CARG1, CARG2, CRET1
|
||||||
|.endif
|
|.endif
|
||||||
|.endif
|
|.endif
|
||||||
| b <6
|
| b <6
|
||||||
@ -1889,8 +1897,8 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| math_minmax math_min, seleqz, selnez, min.d
|
| math_minmax math_min, seleqz, selnez, min.d
|
||||||
| math_minmax math_max, selnez, seleqz, max.d
|
| math_minmax math_max, selnez, seleqz, max.d
|
||||||
|.else
|
|.else
|
||||||
| math_minmax math_min, movz, _, movf.d
|
| math_minmax math_min, movz, _, 0
|
||||||
| math_minmax math_max, movn, _, movt.d
|
| math_minmax math_max, movn, _, 1
|
||||||
|.endif
|
|.endif
|
||||||
|
|
|
|
||||||
|//-- String library -----------------------------------------------------
|
|//-- String library -----------------------------------------------------
|
||||||
@ -2108,7 +2116,6 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| dsllv CRET2, CRET2, TMP0 // Integer check.
|
| dsllv CRET2, CRET2, TMP0 // Integer check.
|
||||||
| sextw AT, CRET1
|
| sextw AT, CRET1
|
||||||
| xor AT, CRET1, AT // Range check.
|
| xor AT, CRET1, AT // Range check.
|
||||||
| jr ra
|
|
||||||
|.if MIPSR6
|
|.if MIPSR6
|
||||||
| seleqz AT, AT, CRET2
|
| seleqz AT, AT, CRET2
|
||||||
| selnez CRET2, CRET2, CRET2
|
| selnez CRET2, CRET2, CRET2
|
||||||
@ -2809,6 +2816,34 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|. move CRET1, CRET2
|
|. move CRET1, CRET2
|
||||||
|.endif
|
|.endif
|
||||||
|
|
|
|
||||||
|
|->vm_sfcmpogt:
|
||||||
|
|.if not FPU
|
||||||
|
| dsll AT, CARG2, 1
|
||||||
|
| dsll TMP0, CARG1, 1
|
||||||
|
| or TMP1, AT, TMP0
|
||||||
|
| beqz TMP1, >8 // Both args +-0: return 0.
|
||||||
|
|. lui TMP1, 0xffe0
|
||||||
|
| dsll TMP1, TMP1, 32
|
||||||
|
| sltu AT, TMP1, AT
|
||||||
|
| sltu TMP0, TMP1, TMP0
|
||||||
|
| or TMP1, AT, TMP0
|
||||||
|
| bnez TMP1, >9 // Either arg is NaN: return 0 or 1;
|
||||||
|
|. and AT, CARG2, CARG1
|
||||||
|
| bltz AT, >5 // Both args negative?
|
||||||
|
|. nop
|
||||||
|
| jr ra
|
||||||
|
|. slt CRET1, CARG2, CARG1
|
||||||
|
|5: // Swap conditions if both operands are negative.
|
||||||
|
| jr ra
|
||||||
|
|. slt CRET1, CARG1, CARG2
|
||||||
|
|8:
|
||||||
|
| jr ra
|
||||||
|
|. li CRET1, 0
|
||||||
|
|9:
|
||||||
|
| jr ra
|
||||||
|
|. li CRET1, 0
|
||||||
|
|.endif
|
||||||
|
|
|
||||||
|// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a.
|
|// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a.
|
||||||
|// Input: CARG1, CARG2, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1.
|
|// Input: CARG1, CARG2, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1.
|
||||||
|->vm_sfcmpolex:
|
|->vm_sfcmpolex:
|
||||||
@ -2840,34 +2875,29 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|. li CRET1, 0
|
|. li CRET1, 0
|
||||||
|.endif
|
|.endif
|
||||||
|
|
|
|
||||||
|.macro sfmin_max, name, intins, intinsc
|
|.macro sfmin_max, name, fpcall
|
||||||
|->vm_sf .. name:
|
|->vm_sf .. name:
|
||||||
|.if JIT and not FPU
|
|.if JIT and not FPU
|
||||||
| move TMP2, ra
|
| move TMP2, ra
|
||||||
| bal ->vm_sfcmpolt
|
| bal ->fpcall
|
||||||
|. nop
|
|. nop
|
||||||
| move ra, TMP2
|
| move ra, TMP2
|
||||||
| move TMP0, CRET1
|
| move TMP0, CRET1
|
||||||
| move CRET1, CARG1
|
| move CRET1, CARG1
|
||||||
|.if MIPSR6
|
|.if MIPSR6
|
||||||
| intins CRET1, CRET1, TMP0
|
| selnez CRET1, CRET1, TMP0
|
||||||
| intinsc TMP0, CARG2, TMP0
|
| seleqz TMP0, CARG2, TMP0
|
||||||
| jr ra
|
| jr ra
|
||||||
|. or CRET1, CRET1, TMP0
|
|. or CRET1, CRET1, TMP0
|
||||||
|.else
|
|.else
|
||||||
| jr ra
|
| jr ra
|
||||||
|. intins CRET1, CARG2, TMP0
|
|. movz CRET1, CARG2, TMP0
|
||||||
|.endif
|
|.endif
|
||||||
|.endif
|
|.endif
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
|.if MIPSR6
|
| sfmin_max min, vm_sfcmpolt
|
||||||
| sfmin_max min, selnez, seleqz
|
| sfmin_max max, vm_sfcmpogt
|
||||||
| sfmin_max max, seleqz, selnez
|
|
||||||
|.else
|
|
||||||
| sfmin_max min, movz, _
|
|
||||||
| sfmin_max max, movn, _
|
|
||||||
|.endif
|
|
||||||
|
|
|
|
||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
|//-- Miscellaneous functions --------------------------------------------
|
|//-- Miscellaneous functions --------------------------------------------
|
||||||
|
@ -2309,12 +2309,12 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|6:
|
|6:
|
||||||
| addi SAVE0, SAVE0, 8
|
| addi SAVE0, SAVE0, 8
|
||||||
|.if FPU
|
|.if FPU
|
||||||
| fsub f0, FARG1, FARG2
|
|
||||||
|.if ismax
|
|.if ismax
|
||||||
| fsel FARG1, f0, FARG1, FARG2
|
| fsub f0, FARG1, FARG2
|
||||||
|.else
|
|.else
|
||||||
| fsel FARG1, f0, FARG2, FARG1
|
| fsub f0, FARG2, FARG1
|
||||||
|.endif
|
|.endif
|
||||||
|
| fsel FARG1, f0, FARG1, FARG2
|
||||||
|.else
|
|.else
|
||||||
| stw CARG1, SFSAVE_1
|
| stw CARG1, SFSAVE_1
|
||||||
| stw CARG2, SFSAVE_2
|
| stw CARG2, SFSAVE_2
|
||||||
@ -2354,13 +2354,13 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| checknum CARG2
|
| checknum CARG2
|
||||||
| bge cr1, ->fff_resn
|
| bge cr1, ->fff_resn
|
||||||
| bge ->fff_fallback
|
| bge ->fff_fallback
|
||||||
| fsub f0, FARG1, FARG2
|
|
||||||
| addi TMP1, TMP1, 8
|
|
||||||
|.if ismax
|
|.if ismax
|
||||||
| fsel FARG1, f0, FARG1, FARG2
|
| fsub f0, FARG1, FARG2
|
||||||
|.else
|
|.else
|
||||||
| fsel FARG1, f0, FARG2, FARG1
|
| fsub f0, FARG2, FARG1
|
||||||
|.endif
|
|.endif
|
||||||
|
| addi TMP1, TMP1, 8
|
||||||
|
| fsel FARG1, f0, FARG1, FARG2
|
||||||
| b <1
|
| b <1
|
||||||
|.endif
|
|.endif
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
@ -1840,7 +1840,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| jmp ->fff_res
|
| jmp ->fff_res
|
||||||
|
|
|
|
||||||
|.macro math_minmax, name, cmovop, sseop
|
|.macro math_minmax, name, cmovop, sseop
|
||||||
| .ffunc name
|
| .ffunc_1 name
|
||||||
| mov RAd, 2
|
| mov RAd, 2
|
||||||
|.if DUALNUM
|
|.if DUALNUM
|
||||||
| mov RB, [BASE]
|
| mov RB, [BASE]
|
||||||
|
@ -2233,7 +2233,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| xorps xmm4, xmm4; jmp <1 // Return +-Inf and +-0.
|
| xorps xmm4, xmm4; jmp <1 // Return +-Inf and +-0.
|
||||||
|
|
|
|
||||||
|.macro math_minmax, name, cmovop, sseop
|
|.macro math_minmax, name, cmovop, sseop
|
||||||
| .ffunc name
|
| .ffunc_1 name
|
||||||
| mov RA, 2
|
| mov RA, 2
|
||||||
| cmp dword [BASE+4], LJ_TISNUM
|
| cmp dword [BASE+4], LJ_TISNUM
|
||||||
|.if DUALNUM
|
|.if DUALNUM
|
||||||
|
Loading…
Reference in New Issue
Block a user