@@ -1268,12 +1268,19 @@ void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Regist
1268
1268
}
1269
1269
1270
1270
// ----------- cmove, compare float -----------
1271
+ //
1272
+ // For CmpF/D + CMoveI/L, ordered ones are quite straight and simple,
1273
+ // so, just list behaviour of unordered ones as follow.
1274
+ //
1275
+ // Set dst (CMoveI (Binary cop (CmpF/D op1 op2)) (Binary dst src))
1276
+ // (If one or both inputs to the compare are NaN, then)
1277
+ // 1. (op1 lt op2) => true => CMove: dst = src
1278
+ // 2. (op1 le op2) => true => CMove: dst = src
1279
+ // 3. (op1 gt op2) => false => CMove: dst = dst
1280
+ // 4. (op1 ge op2) => false => CMove: dst = dst
1281
+ // 5. (op1 eq op2) => false => CMove: dst = dst
1282
+ // 6. (op1 ne op2) => true => CMove: dst = src
1271
1283
1272
- // Move src to dst only if cmp1 == cmp2,
1273
- // otherwise leave dst unchanged, including the case where one of them is NaN.
1274
- // Clarification:
1275
- // java code : cmp1 != cmp2 ? dst : src
1276
- // transformed to : CMove dst, (cmp1 eq cmp2), dst, src
1277
1284
void MacroAssembler::cmov_cmp_fp_eq (FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
1278
1285
if (UseZicond) {
1279
1286
if (is_single) {
@@ -1289,7 +1296,7 @@ void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Regi
1289
1296
Label no_set;
1290
1297
if (is_single) {
1291
1298
// jump if cmp1 != cmp2, including the case of NaN
1292
- // not jump (i.e. move src to dst) if cmp1 == cmp2
1299
+ // fallthrough (i.e. move src to dst) if cmp1 == cmp2
1293
1300
float_bne (cmp1, cmp2, no_set);
1294
1301
} else {
1295
1302
double_bne (cmp1, cmp2, no_set);
@@ -1298,11 +1305,6 @@ void MacroAssembler::cmov_cmp_fp_eq(FloatRegister cmp1, FloatRegister cmp2, Regi
1298
1305
bind (no_set);
1299
1306
}
1300
1307
1301
- // Keep dst unchanged only if cmp1 == cmp2,
1302
- // otherwise move src to dst, including the case where one of them is NaN.
1303
- // Clarification:
1304
- // java code : cmp1 == cmp2 ? dst : src
1305
- // transformed to : CMove dst, (cmp1 ne cmp2), dst, src
1306
1308
void MacroAssembler::cmov_cmp_fp_ne (FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
1307
1309
if (UseZicond) {
1308
1310
if (is_single) {
@@ -1318,7 +1320,7 @@ void MacroAssembler::cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Regi
1318
1320
Label no_set;
1319
1321
if (is_single) {
1320
1322
// jump if cmp1 == cmp2
1321
- // not jump (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN
1323
+ // fallthrough (i.e. move src to dst) if cmp1 != cmp2, including the case of NaN
1322
1324
float_beq (cmp1, cmp2, no_set);
1323
1325
} else {
1324
1326
double_beq (cmp1, cmp2, no_set);
@@ -1327,14 +1329,6 @@ void MacroAssembler::cmov_cmp_fp_ne(FloatRegister cmp1, FloatRegister cmp2, Regi
1327
1329
bind (no_set);
1328
1330
}
1329
1331
1330
- // When cmp1 <= cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
1331
- // Clarification
1332
- // scenario 1:
1333
- // java code : cmp2 < cmp1 ? dst : src
1334
- // transformed to : CMove dst, (cmp1 le cmp2), dst, src
1335
- // scenario 2:
1336
- // java code : cmp1 > cmp2 ? dst : src
1337
- // transformed to : CMove dst, (cmp1 le cmp2), dst, src
1338
1332
void MacroAssembler::cmov_cmp_fp_le (FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
1339
1333
if (UseZicond) {
1340
1334
if (is_single) {
@@ -1350,7 +1344,7 @@ void MacroAssembler::cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Regi
1350
1344
Label no_set;
1351
1345
if (is_single) {
1352
1346
// jump if cmp1 > cmp2
1353
- // not jump (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN
1347
+ // fallthrough (i.e. move src to dst) if cmp1 <= cmp2 or either is NaN
1354
1348
float_bgt (cmp1, cmp2, no_set);
1355
1349
} else {
1356
1350
double_bgt (cmp1, cmp2, no_set);
@@ -1359,14 +1353,30 @@ void MacroAssembler::cmov_cmp_fp_le(FloatRegister cmp1, FloatRegister cmp2, Regi
1359
1353
bind (no_set);
1360
1354
}
1361
1355
1362
- // When cmp1 < cmp2 or any of them is NaN then dst = src, otherwise, dst = dst
1363
- // Clarification
1364
- // scenario 1:
1365
- // java code : cmp2 <= cmp1 ? dst : src
1366
- // transformed to : CMove dst, (cmp1 lt cmp2), dst, src
1367
- // scenario 2:
1368
- // java code : cmp1 >= cmp2 ? dst : src
1369
- // transformed to : CMove dst, (cmp1 lt cmp2), dst, src
1356
+ void MacroAssembler::cmov_cmp_fp_ge (FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
1357
+ if (UseZicond) {
1358
+ if (is_single) {
1359
+ fle_s (t0, cmp2, cmp1);
1360
+ } else {
1361
+ fle_d (t0, cmp2, cmp1);
1362
+ }
1363
+ czero_nez (dst, dst, t0);
1364
+ czero_eqz (t0 , src, t0);
1365
+ orr (dst, dst, t0);
1366
+ return ;
1367
+ }
1368
+ Label no_set;
1369
+ if (is_single) {
1370
+ // jump if cmp1 < cmp2 or either is NaN
1371
+ // fallthrough (i.e. move src to dst) if cmp1 >= cmp2
1372
+ float_blt (cmp1, cmp2, no_set, false , true );
1373
+ } else {
1374
+ double_blt (cmp1, cmp2, no_set, false , true );
1375
+ }
1376
+ mv (dst, src);
1377
+ bind (no_set);
1378
+ }
1379
+
1370
1380
void MacroAssembler::cmov_cmp_fp_lt (FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
1371
1381
if (UseZicond) {
1372
1382
if (is_single) {
@@ -1382,7 +1392,7 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi
1382
1392
Label no_set;
1383
1393
if (is_single) {
1384
1394
// jump if cmp1 >= cmp2
1385
- // not jump (i.e. move src to dst) if cmp1 < cmp2 or either is NaN
1395
+ // fallthrough (i.e. move src to dst) if cmp1 < cmp2 or either is NaN
1386
1396
float_bge (cmp1, cmp2, no_set);
1387
1397
} else {
1388
1398
double_bge (cmp1, cmp2, no_set);
@@ -1391,6 +1401,30 @@ void MacroAssembler::cmov_cmp_fp_lt(FloatRegister cmp1, FloatRegister cmp2, Regi
1391
1401
bind (no_set);
1392
1402
}
1393
1403
1404
+ void MacroAssembler::cmov_cmp_fp_gt (FloatRegister cmp1, FloatRegister cmp2, Register dst, Register src, bool is_single) {
1405
+ if (UseZicond) {
1406
+ if (is_single) {
1407
+ flt_s (t0, cmp2, cmp1);
1408
+ } else {
1409
+ flt_d (t0, cmp2, cmp1);
1410
+ }
1411
+ czero_nez (dst, dst, t0);
1412
+ czero_eqz (t0 , src, t0);
1413
+ orr (dst, dst, t0);
1414
+ return ;
1415
+ }
1416
+ Label no_set;
1417
+ if (is_single) {
1418
+ // jump if cmp1 <= cmp2 or either is NaN
1419
+ // fallthrough (i.e. move src to dst) if cmp1 > cmp2
1420
+ float_ble (cmp1, cmp2, no_set, false , true );
1421
+ } else {
1422
+ double_ble (cmp1, cmp2, no_set, false , true );
1423
+ }
1424
+ mv (dst, src);
1425
+ bind (no_set);
1426
+ }
1427
+
1394
1428
// Float compare branch instructions
1395
1429
1396
1430
#define INSN (NAME, FLOATCMP, BRANCH ) \
0 commit comments