aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_asm_arm.h6
-rw-r--r--src/lj_asm_arm64.h6
-rw-r--r--src/lj_asm_mips.h6
-rw-r--r--src/lj_asm_ppc.h5
-rw-r--r--src/lj_opt_fold.c53
-rw-r--r--src/lj_vmmath.c4
-rw-r--r--src/vm_arm.dasc4
-rw-r--r--src/vm_arm64.dasc4
-rw-r--r--src/vm_mips.dasc69
-rw-r--r--src/vm_mips64.dasc68
-rw-r--r--src/vm_ppc.dasc14
-rw-r--r--src/vm_x64.dasc2
-rw-r--r--src/vm_x86.dasc2
13 files changed, 151 insertions, 92 deletions
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h
index 9d055c81..d2579349 100644
--- a/src/lj_asm_arm.h
+++ b/src/lj_asm_arm.h
@@ -1659,8 +1659,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, int cc, int fcc)
1659 asm_intmin_max(as, ir, cc); 1659 asm_intmin_max(as, ir, cc);
1660} 1660}
1661 1661
1662#define asm_min(as, ir) asm_min_max(as, ir, CC_GT, CC_HI) 1662#define asm_min(as, ir) asm_min_max(as, ir, CC_GT, CC_PL)
1663#define asm_max(as, ir) asm_min_max(as, ir, CC_LT, CC_LO) 1663#define asm_max(as, ir) asm_min_max(as, ir, CC_LT, CC_LE)
1664 1664
1665/* -- Comparisons --------------------------------------------------------- */ 1665/* -- Comparisons --------------------------------------------------------- */
1666 1666
@@ -1852,7 +1852,7 @@ static void asm_hiop(ASMState *as, IRIns *ir)
1852 } else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) { 1852 } else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
1853 as->curins--; /* Always skip the loword min/max. */ 1853 as->curins--; /* Always skip the loword min/max. */
1854 if (uselo || usehi) 1854 if (uselo || usehi)
1855 asm_sfpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_HI : CC_LO); 1855 asm_sfpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_PL : CC_LE);
1856 return; 1856 return;
1857#elif LJ_HASFFI 1857#elif LJ_HASFFI
1858 } else if ((ir-1)->o == IR_CONV) { 1858 } else if ((ir-1)->o == IR_CONV) {
diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h
index 624cc2da..f640b91b 100644
--- a/src/lj_asm_arm64.h
+++ b/src/lj_asm_arm64.h
@@ -1598,7 +1598,7 @@ static void asm_fpmin_max(ASMState *as, IRIns *ir, A64CC fcc)
1598 Reg dest = (ra_dest(as, ir, RSET_FPR) & 31); 1598 Reg dest = (ra_dest(as, ir, RSET_FPR) & 31);
1599 Reg right, left = ra_alloc2(as, ir, RSET_FPR); 1599 Reg right, left = ra_alloc2(as, ir, RSET_FPR);
1600 right = ((left >> 8) & 31); left &= 31; 1600 right = ((left >> 8) & 31); left &= 31;
1601 emit_dnm(as, A64I_FCSELd | A64F_CC(fcc), dest, left, right); 1601 emit_dnm(as, A64I_FCSELd | A64F_CC(fcc), dest, right, left);
1602 emit_nm(as, A64I_FCMPd, left, right); 1602 emit_nm(as, A64I_FCMPd, left, right);
1603} 1603}
1604 1604
@@ -1610,8 +1610,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, A64CC cc, A64CC fcc)
1610 asm_intmin_max(as, ir, cc); 1610 asm_intmin_max(as, ir, cc);
1611} 1611}
1612 1612
1613#define asm_max(as, ir) asm_min_max(as, ir, CC_GT, CC_HI) 1613#define asm_min(as, ir) asm_min_max(as, ir, CC_LT, CC_PL)
1614#define asm_min(as, ir) asm_min_max(as, ir, CC_LT, CC_LO) 1614#define asm_max(as, ir) asm_min_max(as, ir, CC_GT, CC_LE)
1615 1615
1616/* -- Comparisons --------------------------------------------------------- */ 1616/* -- Comparisons --------------------------------------------------------- */
1617 1617
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h
index 9309b781..a242904e 100644
--- a/src/lj_asm_mips.h
+++ b/src/lj_asm_mips.h
@@ -2121,12 +2121,12 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
2121 right = (left >> 8); left &= 255; 2121 right = (left >> 8); left &= 255;
2122#if !LJ_TARGET_MIPSR6 2122#if !LJ_TARGET_MIPSR6
2123 if (dest == left) { 2123 if (dest == left) {
2124 emit_fg(as, MIPSI_MOVT_D, dest, right); 2124 emit_fg(as, MIPSI_MOVF_D, dest, right);
2125 } else { 2125 } else {
2126 emit_fg(as, MIPSI_MOVF_D, dest, left); 2126 emit_fg(as, MIPSI_MOVT_D, dest, left);
2127 if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right); 2127 if (dest != right) emit_fg(as, MIPSI_MOV_D, dest, right);
2128 } 2128 }
2129 emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? left : right, ismax ? right : left); 2129 emit_fgh(as, MIPSI_C_OLT_D, 0, ismax ? right : left, ismax ? left : right);
2130#else 2130#else
2131 emit_fgh(as, ismax ? MIPSI_MAX_D : MIPSI_MIN_D, dest, left, right); 2131 emit_fgh(as, ismax ? MIPSI_MAX_D : MIPSI_MIN_D, dest, left, right);
2132#endif 2132#endif
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h
index 8fa8c8ef..afcd6b7a 100644
--- a/src/lj_asm_ppc.h
+++ b/src/lj_asm_ppc.h
@@ -1724,9 +1724,8 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
1724 if (tmp == left || tmp == right) 1724 if (tmp == left || tmp == right)
1725 tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_FPR, 1725 tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_FPR,
1726 dest), left), right)); 1726 dest), left), right));
1727 emit_facb(as, PPCI_FSEL, dest, tmp, 1727 emit_facb(as, PPCI_FSEL, dest, tmp, left, right);
1728 ismax ? left : right, ismax ? right : left); 1728 emit_fab(as, PPCI_FSUB, tmp, ismax ? left : right, ismax ? right : left);
1729 emit_fab(as, PPCI_FSUB, tmp, left, right);
1730 } else { 1729 } else {
1731 Reg dest = ra_dest(as, ir, RSET_GPR); 1730 Reg dest = ra_dest(as, ir, RSET_GPR);
1732 Reg tmp1 = RID_TMP, tmp2 = dest; 1731 Reg tmp1 = RID_TMP, tmp2 = dest;
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index b4d05a26..cefd69c8 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -1774,8 +1774,6 @@ LJFOLDF(reassoc_intarith_k64)
1774#endif 1774#endif
1775} 1775}
1776 1776
1777LJFOLD(MIN MIN any)
1778LJFOLD(MAX MAX any)
1779LJFOLD(BAND BAND any) 1777LJFOLD(BAND BAND any)
1780LJFOLD(BOR BOR any) 1778LJFOLD(BOR BOR any)
1781LJFOLDF(reassoc_dup) 1779LJFOLDF(reassoc_dup)
@@ -1785,6 +1783,15 @@ LJFOLDF(reassoc_dup)
1785 return NEXTFOLD; 1783 return NEXTFOLD;
1786} 1784}
1787 1785
1786LJFOLD(MIN MIN any)
1787LJFOLD(MAX MAX any)
1788LJFOLDF(reassoc_dup_minmax)
1789{
1790 if (fins->op2 == fleft->op2)
1791 return LEFTFOLD; /* (a o b) o b ==> a o b */
1792 return NEXTFOLD;
1793}
1794
1788LJFOLD(BXOR BXOR any) 1795LJFOLD(BXOR BXOR any)
1789LJFOLDF(reassoc_bxor) 1796LJFOLDF(reassoc_bxor)
1790{ 1797{
@@ -1823,23 +1830,12 @@ LJFOLDF(reassoc_shift)
1823 return NEXTFOLD; 1830 return NEXTFOLD;
1824} 1831}
1825 1832
1826LJFOLD(MIN MIN KNUM)
1827LJFOLD(MAX MAX KNUM)
1828LJFOLD(MIN MIN KINT) 1833LJFOLD(MIN MIN KINT)
1829LJFOLD(MAX MAX KINT) 1834LJFOLD(MAX MAX KINT)
1830LJFOLDF(reassoc_minmax_k) 1835LJFOLDF(reassoc_minmax_k)
1831{ 1836{
1832 IRIns *irk = IR(fleft->op2); 1837 IRIns *irk = IR(fleft->op2);
1833 if (irk->o == IR_KNUM) { 1838 if (irk->o == IR_KINT) {
1834 lua_Number a = ir_knum(irk)->n;
1835 lua_Number y = lj_vm_foldarith(a, knumright, fins->o - IR_ADD);
1836 if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
1837 return LEFTFOLD;
1838 PHIBARRIER(fleft);
1839 fins->op1 = fleft->op1;
1840 fins->op2 = (IRRef1)lj_ir_knum(J, y);
1841 return RETRYFOLD; /* (x o k1) o k2 ==> x o (k1 o k2) */
1842 } else if (irk->o == IR_KINT) {
1843 int32_t a = irk->i; 1839 int32_t a = irk->i;
1844 int32_t y = kfold_intop(a, fright->i, fins->o); 1840 int32_t y = kfold_intop(a, fright->i, fins->o);
1845 if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */ 1841 if (a == y) /* (x o k1) o k2 ==> x o k1, if (k1 o k2) == k1. */
@@ -1852,24 +1848,6 @@ LJFOLDF(reassoc_minmax_k)
1852 return NEXTFOLD; 1848 return NEXTFOLD;
1853} 1849}
1854 1850
1855LJFOLD(MIN MAX any)
1856LJFOLD(MAX MIN any)
1857LJFOLDF(reassoc_minmax_left)
1858{
1859 if (fins->op2 == fleft->op1 || fins->op2 == fleft->op2)
1860 return RIGHTFOLD; /* (b o1 a) o2 b ==> b; (a o1 b) o2 b ==> b */
1861 return NEXTFOLD;
1862}
1863
1864LJFOLD(MIN any MAX)
1865LJFOLD(MAX any MIN)
1866LJFOLDF(reassoc_minmax_right)
1867{
1868 if (fins->op1 == fright->op1 || fins->op1 == fright->op2)
1869 return LEFTFOLD; /* a o2 (a o1 b) ==> a; a o2 (b o1 a) ==> a */
1870 return NEXTFOLD;
1871}
1872
1873/* -- Array bounds check elimination -------------------------------------- */ 1851/* -- Array bounds check elimination -------------------------------------- */
1874 1852
1875/* Eliminate ABC across PHIs to handle t[i-1] forwarding case. 1853/* Eliminate ABC across PHIs to handle t[i-1] forwarding case.
@@ -1995,8 +1973,6 @@ LJFOLDF(comm_comp)
1995 1973
1996LJFOLD(BAND any any) 1974LJFOLD(BAND any any)
1997LJFOLD(BOR any any) 1975LJFOLD(BOR any any)
1998LJFOLD(MIN any any)
1999LJFOLD(MAX any any)
2000LJFOLDF(comm_dup) 1976LJFOLDF(comm_dup)
2001{ 1977{
2002 if (fins->op1 == fins->op2) /* x o x ==> x */ 1978 if (fins->op1 == fins->op2) /* x o x ==> x */
@@ -2004,6 +1980,15 @@ LJFOLDF(comm_dup)
2004 return fold_comm_swap(J); 1980 return fold_comm_swap(J);
2005} 1981}
2006 1982
1983LJFOLD(MIN any any)
1984LJFOLD(MAX any any)
1985LJFOLDF(comm_dup_minmax)
1986{
1987 if (fins->op1 == fins->op2) /* x o x ==> x */
1988 return LEFTFOLD;
1989 return NEXTFOLD;
1990}
1991
2007LJFOLD(BXOR any any) 1992LJFOLD(BXOR any any)
2008LJFOLDF(comm_bxor) 1993LJFOLDF(comm_bxor)
2009{ 1994{
diff --git a/src/lj_vmmath.c b/src/lj_vmmath.c
index 2a41bcaa..e89405d7 100644
--- a/src/lj_vmmath.c
+++ b/src/lj_vmmath.c
@@ -50,8 +50,8 @@ double lj_vm_foldarith(double x, double y, int op)
50#if LJ_HASJIT 50#if LJ_HASJIT
51 case IR_ATAN2 - IR_ADD: return atan2(x, y); break; 51 case IR_ATAN2 - IR_ADD: return atan2(x, y); break;
52 case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break; 52 case IR_LDEXP - IR_ADD: return ldexp(x, (int)y); break;
53 case IR_MIN - IR_ADD: return x > y ? y : x; break; 53 case IR_MIN - IR_ADD: return x < y ? x : y; break;
54 case IR_MAX - IR_ADD: return x < y ? y : x; break; 54 case IR_MAX - IR_ADD: return x > y ? x : y; break;
55#endif 55#endif
56 default: return x; 56 default: return x;
57 } 57 }
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc
index 5bbdbbff..013688fb 100644
--- a/src/vm_arm.dasc
+++ b/src/vm_arm.dasc
@@ -1716,8 +1716,8 @@ static void build_subroutines(BuildCtx *ctx)
1716 |.endif 1716 |.endif
1717 |.endmacro 1717 |.endmacro
1718 | 1718 |
1719 | math_minmax math_min, gt, hi 1719 | math_minmax math_min, gt, pl
1720 | math_minmax math_max, lt, lo 1720 | math_minmax math_max, lt, le
1721 | 1721 |
1722 |//-- String library ----------------------------------------------------- 1722 |//-- String library -----------------------------------------------------
1723 | 1723 |
diff --git a/src/vm_arm64.dasc b/src/vm_arm64.dasc
index 62946373..c157696c 100644
--- a/src/vm_arm64.dasc
+++ b/src/vm_arm64.dasc
@@ -1489,8 +1489,8 @@ static void build_subroutines(BuildCtx *ctx)
1489 | b <6 1489 | b <6
1490 |.endmacro 1490 |.endmacro
1491 | 1491 |
1492 | math_minmax math_min, gt, hi 1492 | math_minmax math_min, gt, pl
1493 | math_minmax math_max, lt, lo 1493 | math_minmax math_max, lt, le
1494 | 1494 |
1495 |//-- String library ----------------------------------------------------- 1495 |//-- String library -----------------------------------------------------
1496 | 1496 |
diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc
index 37506139..0c84c13b 100644
--- a/src/vm_mips.dasc
+++ b/src/vm_mips.dasc
@@ -1768,7 +1768,7 @@ static void build_subroutines(BuildCtx *ctx)
1768 | b ->fff_res 1768 | b ->fff_res
1769 |. li RD, (2+1)*8 1769 |. li RD, (2+1)*8
1770 | 1770 |
1771 |.macro math_minmax, name, intins, fpins 1771 |.macro math_minmax, name, intins, ismax
1772 | .ffunc_1 name 1772 | .ffunc_1 name
1773 | addu TMP3, BASE, NARGS8:RC 1773 | addu TMP3, BASE, NARGS8:RC
1774 | bne SFARG1HI, TISNUM, >5 1774 | bne SFARG1HI, TISNUM, >5
@@ -1822,13 +1822,21 @@ static void build_subroutines(BuildCtx *ctx)
1822 |.endif 1822 |.endif
1823 |7: 1823 |7:
1824 |.if FPU 1824 |.if FPU
1825 |.if ismax
1826 | c.olt.d FARG1, FRET1
1827 |.else
1825 | c.olt.d FRET1, FARG1 1828 | c.olt.d FRET1, FARG1
1826 | fpins FRET1, FARG1 1829 |.endif
1830 | movf.d FRET1, FARG1
1831 |.else
1832 |.if ismax
1833 | bal ->vm_sfcmpogt
1827 |.else 1834 |.else
1828 | bal ->vm_sfcmpolt 1835 | bal ->vm_sfcmpolt
1836 |.endif
1829 |. nop 1837 |. nop
1830 | intins SFARG1LO, SFARG2LO, CRET1 1838 | movz SFARG1LO, SFARG2LO, CRET1
1831 | intins SFARG1HI, SFARG2HI, CRET1 1839 | movz SFARG1HI, SFARG2HI, CRET1
1832 |.endif 1840 |.endif
1833 | b <6 1841 | b <6
1834 |. addiu TMP2, TMP2, 8 1842 |. addiu TMP2, TMP2, 8
@@ -1849,8 +1857,8 @@ static void build_subroutines(BuildCtx *ctx)
1849 | 1857 |
1850 |.endmacro 1858 |.endmacro
1851 | 1859 |
1852 | math_minmax math_min, movz, movf.d 1860 | math_minmax math_min, movz, 0
1853 | math_minmax math_max, movn, movt.d 1861 | math_minmax math_max, movn, 1
1854 | 1862 |
1855 |//-- String library ----------------------------------------------------- 1863 |//-- String library -----------------------------------------------------
1856 | 1864 |
@@ -2692,6 +2700,43 @@ static void build_subroutines(BuildCtx *ctx)
2692 |. move CRET1, CRET2 2700 |. move CRET1, CRET2
2693 |.endif 2701 |.endif
2694 | 2702 |
2703 |->vm_sfcmpogt:
2704 |.if not FPU
2705 | sll AT, SFARG2HI, 1
2706 | sll TMP0, SFARG1HI, 1
2707 | or CRET1, SFARG2LO, SFARG1LO
2708 | or TMP1, AT, TMP0
2709 | or TMP1, TMP1, CRET1
2710 | beqz TMP1, >8 // Both args +-0: return 0.
2711 |. sltu CRET1, r0, SFARG2LO
2712 | lui TMP1, 0xffe0
2713 | addu AT, AT, CRET1
2714 | sltu CRET1, r0, SFARG1LO
2715 | sltu AT, TMP1, AT
2716 | addu TMP0, TMP0, CRET1
2717 | sltu TMP0, TMP1, TMP0
2718 | or TMP1, AT, TMP0
2719 | bnez TMP1, >9 // Either arg is NaN: return 0 or 1;
2720 |. and AT, SFARG2HI, SFARG1HI
2721 | bltz AT, >5 // Both args negative?
2722 |. nop
2723 | beq SFARG2HI, SFARG1HI, >8
2724 |. sltu CRET1, SFARG2LO, SFARG1LO
2725 | jr ra
2726 |. slt CRET1, SFARG2HI, SFARG1HI
2727 |5: // Swap conditions if both operands are negative.
2728 | beq SFARG2HI, SFARG1HI, >8
2729 |. sltu CRET1, SFARG1LO, SFARG2LO
2730 | jr ra
2731 |. slt CRET1, SFARG1HI, SFARG2HI
2732 |8:
2733 | jr ra
2734 |. nop
2735 |9:
2736 | jr ra
2737 |. li CRET1, 0
2738 |.endif
2739 |
2695 |// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a. 2740 |// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a.
2696 |// Input: SFARG*, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1. 2741 |// Input: SFARG*, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1.
2697 |->vm_sfcmpolex: 2742 |->vm_sfcmpolex:
@@ -2734,24 +2779,24 @@ static void build_subroutines(BuildCtx *ctx)
2734 |. li CRET1, 0 2779 |. li CRET1, 0
2735 |.endif 2780 |.endif
2736 | 2781 |
2737 |.macro sfmin_max, name, intins 2782 |.macro sfmin_max, name, fpcall
2738 |->vm_sf .. name: 2783 |->vm_sf .. name:
2739 |.if JIT and not FPU 2784 |.if JIT and not FPU
2740 | move TMP2, ra 2785 | move TMP2, ra
2741 | bal ->vm_sfcmpolt 2786 | bal ->fpcall
2742 |. nop 2787 |. nop
2743 | move TMP0, CRET1 2788 | move TMP0, CRET1
2744 | move SFRETHI, SFARG1HI 2789 | move SFRETHI, SFARG1HI
2745 | move SFRETLO, SFARG1LO 2790 | move SFRETLO, SFARG1LO
2746 | move ra, TMP2 2791 | move ra, TMP2
2747 | intins SFRETHI, SFARG2HI, TMP0 2792 | movz SFRETHI, SFARG2HI, TMP0
2748 | jr ra 2793 | jr ra
2749 |. intins SFRETLO, SFARG2LO, TMP0 2794 |. movz SFRETLO, SFARG2LO, TMP0
2750 |.endif 2795 |.endif
2751 |.endmacro 2796 |.endmacro
2752 | 2797 |
2753 | sfmin_max min, movz 2798 | sfmin_max min, vm_sfcmpolt
2754 | sfmin_max max, movn 2799 | sfmin_max max, vm_sfcmpogt
2755 | 2800 |
2756 |//----------------------------------------------------------------------- 2801 |//-----------------------------------------------------------------------
2757 |//-- Miscellaneous functions -------------------------------------------- 2802 |//-- Miscellaneous functions --------------------------------------------
diff --git a/src/vm_mips64.dasc b/src/vm_mips64.dasc
index 4ae19b7d..dac143a4 100644
--- a/src/vm_mips64.dasc
+++ b/src/vm_mips64.dasc
@@ -1852,18 +1852,26 @@ static void build_subroutines(BuildCtx *ctx)
1852 |.if MIPSR6 1852 |.if MIPSR6
1853 | fpins FRET1, FRET1, FARG1 1853 | fpins FRET1, FRET1, FARG1
1854 |.else 1854 |.else
1855 |.if fpins // ismax
1856 | c.olt.d FARG1, FRET1
1857 |.else
1855 | c.olt.d FRET1, FARG1 1858 | c.olt.d FRET1, FARG1
1856 | fpins FRET1, FARG1
1857 |.endif 1859 |.endif
1860 | movf.d FRET1, FARG1
1861 |.endif
1862 |.else
1863 |.if fpins // ismax
1864 | bal ->vm_sfcmpogt
1858 |.else 1865 |.else
1859 | bal ->vm_sfcmpolt 1866 | bal ->vm_sfcmpolt
1867 |.endif
1860 |. nop 1868 |. nop
1861 |.if MIPSR6 1869 |.if MIPSR6
1862 | intins AT, CARG2, CRET1 1870 | seleqz AT, CARG2, CRET1
1863 | intinsc CARG1, CARG1, CRET1 1871 | selnez CARG1, CARG1, CRET1
1864 | or CARG1, CARG1, AT 1872 | or CARG1, CARG1, AT
1865 |.else 1873 |.else
1866 | intins CARG1, CARG2, CRET1 1874 | movz CARG1, CARG2, CRET1
1867 |.endif 1875 |.endif
1868 |.endif 1876 |.endif
1869 | b <6 1877 | b <6
@@ -1889,8 +1897,8 @@ static void build_subroutines(BuildCtx *ctx)
1889 | math_minmax math_min, seleqz, selnez, min.d 1897 | math_minmax math_min, seleqz, selnez, min.d
1890 | math_minmax math_max, selnez, seleqz, max.d 1898 | math_minmax math_max, selnez, seleqz, max.d
1891 |.else 1899 |.else
1892 | math_minmax math_min, movz, _, movf.d 1900 | math_minmax math_min, movz, _, 0
1893 | math_minmax math_max, movn, _, movt.d 1901 | math_minmax math_max, movn, _, 1
1894 |.endif 1902 |.endif
1895 | 1903 |
1896 |//-- String library ----------------------------------------------------- 1904 |//-- String library -----------------------------------------------------
@@ -2108,7 +2116,6 @@ static void build_subroutines(BuildCtx *ctx)
2108 | dsllv CRET2, CRET2, TMP0 // Integer check. 2116 | dsllv CRET2, CRET2, TMP0 // Integer check.
2109 | sextw AT, CRET1 2117 | sextw AT, CRET1
2110 | xor AT, CRET1, AT // Range check. 2118 | xor AT, CRET1, AT // Range check.
2111 | jr ra
2112 |.if MIPSR6 2119 |.if MIPSR6
2113 | seleqz AT, AT, CRET2 2120 | seleqz AT, AT, CRET2
2114 | selnez CRET2, CRET2, CRET2 2121 | selnez CRET2, CRET2, CRET2
@@ -2809,6 +2816,34 @@ static void build_subroutines(BuildCtx *ctx)
2809 |. move CRET1, CRET2 2816 |. move CRET1, CRET2
2810 |.endif 2817 |.endif
2811 | 2818 |
2819 |->vm_sfcmpogt:
2820 |.if not FPU
2821 | dsll AT, CARG2, 1
2822 | dsll TMP0, CARG1, 1
2823 | or TMP1, AT, TMP0
2824 | beqz TMP1, >8 // Both args +-0: return 0.
2825 |. lui TMP1, 0xffe0
2826 | dsll TMP1, TMP1, 32
2827 | sltu AT, TMP1, AT
2828 | sltu TMP0, TMP1, TMP0
2829 | or TMP1, AT, TMP0
2830 | bnez TMP1, >9 // Either arg is NaN: return 0 or 1;
2831 |. and AT, CARG2, CARG1
2832 | bltz AT, >5 // Both args negative?
2833 |. nop
2834 | jr ra
2835 |. slt CRET1, CARG2, CARG1
2836 |5: // Swap conditions if both operands are negative.
2837 | jr ra
2838 |. slt CRET1, CARG1, CARG2
2839 |8:
2840 | jr ra
2841 |. li CRET1, 0
2842 |9:
2843 | jr ra
2844 |. li CRET1, 0
2845 |.endif
2846 |
2812 |// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a. 2847 |// Soft-float comparison. Equivalent to c.ole.d a, b or c.ole.d b, a.
2813 |// Input: CARG1, CARG2, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1. 2848 |// Input: CARG1, CARG2, TMP3. Output: CRET1. Temporaries: AT, TMP0, TMP1.
2814 |->vm_sfcmpolex: 2849 |->vm_sfcmpolex:
@@ -2840,34 +2875,29 @@ static void build_subroutines(BuildCtx *ctx)
2840 |. li CRET1, 0 2875 |. li CRET1, 0
2841 |.endif 2876 |.endif
2842 | 2877 |
2843 |.macro sfmin_max, name, intins, intinsc 2878 |.macro sfmin_max, name, fpcall
2844 |->vm_sf .. name: 2879 |->vm_sf .. name:
2845 |.if JIT and not FPU 2880 |.if JIT and not FPU
2846 | move TMP2, ra 2881 | move TMP2, ra
2847 | bal ->vm_sfcmpolt 2882 | bal ->fpcall
2848 |. nop 2883 |. nop
2849 | move ra, TMP2 2884 | move ra, TMP2
2850 | move TMP0, CRET1 2885 | move TMP0, CRET1
2851 | move CRET1, CARG1 2886 | move CRET1, CARG1
2852 |.if MIPSR6 2887 |.if MIPSR6
2853 | intins CRET1, CRET1, TMP0 2888 | selnez CRET1, CRET1, TMP0
2854 | intinsc TMP0, CARG2, TMP0 2889 | seleqz TMP0, CARG2, TMP0
2855 | jr ra 2890 | jr ra
2856 |. or CRET1, CRET1, TMP0 2891 |. or CRET1, CRET1, TMP0
2857 |.else 2892 |.else
2858 | jr ra 2893 | jr ra
2859 |. intins CRET1, CARG2, TMP0 2894 |. movz CRET1, CARG2, TMP0
2860 |.endif 2895 |.endif
2861 |.endif 2896 |.endif
2862 |.endmacro 2897 |.endmacro
2863 | 2898 |
2864 |.if MIPSR6 2899 | sfmin_max min, vm_sfcmpolt
2865 | sfmin_max min, selnez, seleqz 2900 | sfmin_max max, vm_sfcmpogt
2866 | sfmin_max max, seleqz, selnez
2867 |.else
2868 | sfmin_max min, movz, _
2869 | sfmin_max max, movn, _
2870 |.endif
2871 | 2901 |
2872 |//----------------------------------------------------------------------- 2902 |//-----------------------------------------------------------------------
2873 |//-- Miscellaneous functions -------------------------------------------- 2903 |//-- Miscellaneous functions --------------------------------------------
diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc
index a66e30b5..7a2d321e 100644
--- a/src/vm_ppc.dasc
+++ b/src/vm_ppc.dasc
@@ -2309,12 +2309,12 @@ static void build_subroutines(BuildCtx *ctx)
2309 |6: 2309 |6:
2310 | addi SAVE0, SAVE0, 8 2310 | addi SAVE0, SAVE0, 8
2311 |.if FPU 2311 |.if FPU
2312 | fsub f0, FARG1, FARG2
2313 |.if ismax 2312 |.if ismax
2314 | fsel FARG1, f0, FARG1, FARG2 2313 | fsub f0, FARG1, FARG2
2315 |.else 2314 |.else
2316 | fsel FARG1, f0, FARG2, FARG1 2315 | fsub f0, FARG2, FARG1
2317 |.endif 2316 |.endif
2317 | fsel FARG1, f0, FARG1, FARG2
2318 |.else 2318 |.else
2319 | stw CARG1, SFSAVE_1 2319 | stw CARG1, SFSAVE_1
2320 | stw CARG2, SFSAVE_2 2320 | stw CARG2, SFSAVE_2
@@ -2354,13 +2354,13 @@ static void build_subroutines(BuildCtx *ctx)
2354 | checknum CARG2 2354 | checknum CARG2
2355 | bge cr1, ->fff_resn 2355 | bge cr1, ->fff_resn
2356 | bge ->fff_fallback 2356 | bge ->fff_fallback
2357 | fsub f0, FARG1, FARG2
2358 | addi TMP1, TMP1, 8
2359 |.if ismax 2357 |.if ismax
2360 | fsel FARG1, f0, FARG1, FARG2 2358 | fsub f0, FARG1, FARG2
2361 |.else 2359 |.else
2362 | fsel FARG1, f0, FARG2, FARG1 2360 | fsub f0, FARG2, FARG1
2363 |.endif 2361 |.endif
2362 | addi TMP1, TMP1, 8
2363 | fsel FARG1, f0, FARG1, FARG2
2364 | b <1 2364 | b <1
2365 |.endif 2365 |.endif
2366 |.endmacro 2366 |.endmacro
diff --git a/src/vm_x64.dasc b/src/vm_x64.dasc
index a5749b17..c714f4c7 100644
--- a/src/vm_x64.dasc
+++ b/src/vm_x64.dasc
@@ -1840,7 +1840,7 @@ static void build_subroutines(BuildCtx *ctx)
1840 | jmp ->fff_res 1840 | jmp ->fff_res
1841 | 1841 |
1842 |.macro math_minmax, name, cmovop, sseop 1842 |.macro math_minmax, name, cmovop, sseop
1843 | .ffunc name 1843 | .ffunc_1 name
1844 | mov RAd, 2 1844 | mov RAd, 2
1845 |.if DUALNUM 1845 |.if DUALNUM
1846 | mov RB, [BASE] 1846 | mov RB, [BASE]
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc
index 1965b06b..c3999e7c 100644
--- a/src/vm_x86.dasc
+++ b/src/vm_x86.dasc
@@ -2233,7 +2233,7 @@ static void build_subroutines(BuildCtx *ctx)
2233 | xorps xmm4, xmm4; jmp <1 // Return +-Inf and +-0. 2233 | xorps xmm4, xmm4; jmp <1 // Return +-Inf and +-0.
2234 | 2234 |
2235 |.macro math_minmax, name, cmovop, sseop 2235 |.macro math_minmax, name, cmovop, sseop
2236 | .ffunc name 2236 | .ffunc_1 name
2237 | mov RA, 2 2237 | mov RA, 2
2238 | cmp dword [BASE+4], LJ_TISNUM 2238 | cmp dword [BASE+4], LJ_TISNUM
2239 |.if DUALNUM 2239 |.if DUALNUM