@@ -1233,7 +1233,119 @@ void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Regist
12331233 bind (no_set);
12341234}
12351235
1236- // ----------- cmove, compare float -----------
1236+ // ----------- cmove float/double -----------
1237+
1238+ void MacroAssembler::cmov_fp_eq (Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
1239+ Label no_set;
1240+ bne (cmp1, cmp2, no_set);
1241+ if (is_single) {
1242+ fmv_s (dst, src);
1243+ } else {
1244+ fmv_d (dst, src);
1245+ }
1246+ bind (no_set);
1247+ }
1248+
1249+ void MacroAssembler::cmov_fp_ne (Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
1250+ Label no_set;
1251+ beq (cmp1, cmp2, no_set);
1252+ if (is_single) {
1253+ fmv_s (dst, src);
1254+ } else {
1255+ fmv_d (dst, src);
1256+ }
1257+ bind (no_set);
1258+ }
1259+
1260+ void MacroAssembler::cmov_fp_le (Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
1261+ Label no_set;
1262+ bgt (cmp1, cmp2, no_set);
1263+ if (is_single) {
1264+ fmv_s (dst, src);
1265+ } else {
1266+ fmv_d (dst, src);
1267+ }
1268+ bind (no_set);
1269+ }
1270+
1271+ void MacroAssembler::cmov_fp_leu (Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
1272+ Label no_set;
1273+ bgtu (cmp1, cmp2, no_set);
1274+ if (is_single) {
1275+ fmv_s (dst, src);
1276+ } else {
1277+ fmv_d (dst, src);
1278+ }
1279+ bind (no_set);
1280+ }
1281+
1282+ void MacroAssembler::cmov_fp_ge (Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
1283+ Label no_set;
1284+ blt (cmp1, cmp2, no_set);
1285+ if (is_single) {
1286+ fmv_s (dst, src);
1287+ } else {
1288+ fmv_d (dst, src);
1289+ }
1290+ bind (no_set);
1291+ }
1292+
1293+ void MacroAssembler::cmov_fp_geu (Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
1294+ Label no_set;
1295+ bltu (cmp1, cmp2, no_set);
1296+ if (is_single) {
1297+ fmv_s (dst, src);
1298+ } else {
1299+ fmv_d (dst, src);
1300+ }
1301+ bind (no_set);
1302+ }
1303+
1304+ void MacroAssembler::cmov_fp_lt (Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
1305+ Label no_set;
1306+ bge (cmp1, cmp2, no_set);
1307+ if (is_single) {
1308+ fmv_s (dst, src);
1309+ } else {
1310+ fmv_d (dst, src);
1311+ }
1312+ bind (no_set);
1313+ }
1314+
1315+ void MacroAssembler::cmov_fp_ltu (Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
1316+ Label no_set;
1317+ bgeu (cmp1, cmp2, no_set);
1318+ if (is_single) {
1319+ fmv_s (dst, src);
1320+ } else {
1321+ fmv_d (dst, src);
1322+ }
1323+ bind (no_set);
1324+ }
1325+
1326+ void MacroAssembler::cmov_fp_gt (Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
1327+ Label no_set;
1328+ ble (cmp1, cmp2, no_set);
1329+ if (is_single) {
1330+ fmv_s (dst, src);
1331+ } else {
1332+ fmv_d (dst, src);
1333+ }
1334+ bind (no_set);
1335+ }
1336+
1337+ void MacroAssembler::cmov_fp_gtu (Register cmp1, Register cmp2, FloatRegister dst, FloatRegister src, bool is_single) {
1338+ Label no_set;
1339+ bleu (cmp1, cmp2, no_set);
1340+ if (is_single) {
1341+ fmv_s (dst, src);
1342+ } else {
1343+ fmv_d (dst, src);
1344+ }
1345+ bind (no_set);
1346+ }
1347+
1348+ // ----------- cmove, compare float/double -----------
12371349//
12381350// For CmpF/D + CMoveI/L, ordered ones are quite straight and simple,
12391351// so, just list behaviour of unordered ones as follow.
@@ -1391,6 +1503,148 @@ void MacroAssembler::cmov_cmp_fp_gt(FloatRegister cmp1, FloatRegister cmp2, Regi
13911503 bind (no_set);
13921504}
13931505
1506+ // ----------- cmove float/double, compare float/double -----------
1507+
1508+ // Move src to dst only if cmp1 == cmp2,
1509+ // otherwise leave dst unchanged, including the case where one of them is NaN.
1510+ // Clarification:
1511+ // java code : cmp1 != cmp2 ? dst : src
1512+ // transformed to : CMove dst, (cmp1 eq cmp2), dst, src
1513+ void MacroAssembler::cmov_fp_cmp_fp_eq (FloatRegister cmp1, FloatRegister cmp2,
1514+ FloatRegister dst, FloatRegister src,
1515+ bool cmp_single, bool cmov_single) {
1516+ Label no_set;
1517+ if (cmp_single) {
1518+ // jump if cmp1 != cmp2, including the case of NaN
1519+ // not jump (i.e. move src to dst) if cmp1 == cmp2
1520+ float_bne (cmp1, cmp2, no_set);
1521+ } else {
1522+ double_bne (cmp1, cmp2, no_set);
1523+ }
1524+ if (cmov_single) {
1525+ fmv_s (dst, src);
1526+ } else {
1527+ fmv_d (dst, src);
1528+ }
1529+ bind (no_set);
1530+ }
1531+
1532+ // Keep dst unchanged only if cmp1 == cmp2,
1533+ // otherwise move src to dst, including the case where one of them is NaN.
1534+ // Clarification:
1535+ // java code : cmp1 == cmp2 ? dst : src
1536+ // transformed to : CMove dst, (cmp1 ne cmp2), dst, src
1537+ void MacroAssembler::cmov_fp_cmp_fp_ne (FloatRegister cmp1, FloatRegister cmp2,
1538+ FloatRegister dst, FloatRegister src,
1539+ bool cmp_single, bool cmov_single) {
1540+ Label no_set;
1541+ if (cmp_single) {
1542+ // jump if cmp1 == cmp2
1543+ // not jump (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN
1544+ float_beq (cmp1, cmp2, no_set);
1545+ } else {
1546+ double_beq (cmp1, cmp2, no_set);
1547+ }
1548+ if (cmov_single) {
1549+ fmv_s (dst, src);
1550+ } else {
1551+ fmv_d (dst, src);
1552+ }
1553+ bind (no_set);
1554+ }
1555+
1556+ // When cmp1 <= cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
1557+ // Clarification
1558+ // scenario 1:
1559+ // java code : cmp2 < cmp1 ? dst : src
1560+ // transformed to : CMove dst, (cmp1 le cmp2), dst, src
1561+ // scenario 2:
1562+ // java code : cmp1 > cmp2 ? dst : src
1563+ // transformed to : CMove dst, (cmp1 le cmp2), dst, src
1564+ void MacroAssembler::cmov_fp_cmp_fp_le (FloatRegister cmp1, FloatRegister cmp2,
1565+ FloatRegister dst, FloatRegister src,
1566+ bool cmp_single, bool cmov_single) {
1567+ Label no_set;
1568+ if (cmp_single) {
1569+ // jump if cmp1 > cmp2
1570+ // not jump (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN
1571+ float_bgt (cmp1, cmp2, no_set);
1572+ } else {
1573+ double_bgt (cmp1, cmp2, no_set);
1574+ }
1575+ if (cmov_single) {
1576+ fmv_s (dst, src);
1577+ } else {
1578+ fmv_d (dst, src);
1579+ }
1580+ bind (no_set);
1581+ }
1582+
1583+ void MacroAssembler::cmov_fp_cmp_fp_ge (FloatRegister cmp1, FloatRegister cmp2,
1584+ FloatRegister dst, FloatRegister src,
1585+ bool cmp_single, bool cmov_single) {
1586+ Label no_set;
1587+ if (cmp_single) {
1588+ // jump if cmp1 < cmp2 or either is NaN
1589+ // not jump (i.e. move src to dst) if cmp1 >= cmp2
1590+ float_blt (cmp1, cmp2, no_set, false , true );
1591+ } else {
1592+ double_blt (cmp1, cmp2, no_set, false , true );
1593+ }
1594+ if (cmov_single) {
1595+ fmv_s (dst, src);
1596+ } else {
1597+ fmv_d (dst, src);
1598+ }
1599+ bind (no_set);
1600+ }
1601+
1602+ // When cmp1 < cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
1603+ // Clarification
1604+ // scenario 1:
1605+ // java code : cmp2 <= cmp1 ? dst : src
1606+ // transformed to : CMove dst, (cmp1 lt cmp2), dst, src
1607+ // scenario 2:
1608+ // java code : cmp1 >= cmp2 ? dst : src
1609+ // transformed to : CMove dst, (cmp1 lt cmp2), dst, src
1610+ void MacroAssembler::cmov_fp_cmp_fp_lt (FloatRegister cmp1, FloatRegister cmp2,
1611+ FloatRegister dst, FloatRegister src,
1612+ bool cmp_single, bool cmov_single) {
1613+ Label no_set;
1614+ if (cmp_single) {
1615+ // jump if cmp1 >= cmp2
1616+ // not jump (i.e. move src to dst) if cmp1 < cmp2 or either is NaN
1617+ float_bge (cmp1, cmp2, no_set);
1618+ } else {
1619+ double_bge (cmp1, cmp2, no_set);
1620+ }
1621+ if (cmov_single) {
1622+ fmv_s (dst, src);
1623+ } else {
1624+ fmv_d (dst, src);
1625+ }
1626+ bind (no_set);
1627+ }
1628+
1629+ void MacroAssembler::cmov_fp_cmp_fp_gt (FloatRegister cmp1, FloatRegister cmp2,
1630+ FloatRegister dst, FloatRegister src,
1631+ bool cmp_single, bool cmov_single) {
1632+ Label no_set;
1633+ if (cmp_single) {
1634+ // jump if cmp1 <= cmp2 or either is NaN
1635+ // not jump (i.e. move src to dst) if cmp1 > cmp2
1636+ float_ble (cmp1, cmp2, no_set, false , true );
1637+ } else {
1638+ double_ble (cmp1, cmp2, no_set, false , true );
1639+ }
1640+ if (cmov_single) {
1641+ fmv_s (dst, src);
1642+ } else {
1643+ fmv_d (dst, src);
1644+ }
1645+ bind (no_set);
1646+ }
1647+
13941648// Float compare branch instructions
13951649
13961650#define INSN (NAME, FLOATCMP, BRANCH ) \
0 commit comments