@@ -1270,11 +1270,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
12701270#if V8_TARGET_ARCH_PPC64
12711271 if (check_conversion) {
12721272 // Set 2nd output to zero if conversion fails.
1273- CRBit crbit = static_cast <CRBit>(VXCVI % CRWIDTH);
1274- __ mcrfs (cr7, VXCVI); // extract FPSCR field containing VXCVI into cr7
1275- __ li (i.OutputRegister (1 ), Operand (1 ));
1276- __ isel (i.OutputRegister (1 ), r0, i.OutputRegister (1 ),
1277- v8::internal::Assembler::encode_crbit (cr7, crbit));
1273+ CRegister cr = cr7;
1274+ int crbit = v8::internal::Assembler::encode_crbit (
1275+ cr, static_cast <CRBit>(VXCVI % CRWIDTH));
1276+ __ mcrfs (cr, VXCVI); // extract FPSCR field containing VXCVI into cr7
1277+ if (CpuFeatures::IsSupported (ISELECT)) {
1278+ __ li (i.OutputRegister (1 ), Operand (1 ));
1279+ __ isel (i.OutputRegister (1 ), r0, i.OutputRegister (1 ), crbit);
1280+ } else {
1281+ __ li (i.OutputRegister (1 ), Operand::Zero ());
1282+ __ bc (v8::internal::Assembler::kInstrSize * 2 , BT, crbit);
1283+ __ li (i.OutputRegister (1 ), Operand (1 ));
1284+ }
12781285 }
12791286#endif
12801287 DCHECK_EQ (LeaveRC, i.OutputRCBit ());
@@ -1290,11 +1297,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
12901297 i.OutputRegister (0 ), kScratchDoubleReg );
12911298 if (check_conversion) {
12921299 // Set 2nd output to zero if conversion fails.
1293- CRBit crbit = static_cast <CRBit>(VXCVI % CRWIDTH);
1294- __ mcrfs (cr7, VXCVI); // extract FPSCR field containing VXCVI into cr7
1295- __ li (i.OutputRegister (1 ), Operand (1 ));
1296- __ isel (i.OutputRegister (1 ), r0, i.OutputRegister (1 ),
1297- v8::internal::Assembler::encode_crbit (cr7, crbit));
1300+ CRegister cr = cr7;
1301+ int crbit = v8::internal::Assembler::encode_crbit (
1302+ cr, static_cast <CRBit>(VXCVI % CRWIDTH));
1303+ __ mcrfs (cr, VXCVI); // extract FPSCR field containing VXCVI into cr7
1304+ if (CpuFeatures::IsSupported (ISELECT)) {
1305+ __ li (i.OutputRegister (1 ), Operand (1 ));
1306+ __ isel (i.OutputRegister (1 ), r0, i.OutputRegister (1 ), crbit);
1307+ } else {
1308+ __ li (i.OutputRegister (1 ), Operand::Zero ());
1309+ __ bc (v8::internal::Assembler::kInstrSize * 2 , BT, crbit);
1310+ __ li (i.OutputRegister (1 ), Operand (1 ));
1311+ }
12981312 }
12991313 DCHECK_EQ (LeaveRC, i.OutputRCBit ());
13001314 break ;
@@ -1489,53 +1503,53 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
14891503 PPCOperandConverter i (this , instr);
14901504 Label done;
14911505 ArchOpcode op = instr->arch_opcode ();
1492- bool check_unordered = (op == kPPC_CmpDouble );
14931506 CRegister cr = cr0;
1507+ int reg_value = -1 ;
14941508
14951509 // Materialize a full 32-bit 1 or 0 value. The result register is always the
14961510 // last output of the instruction.
14971511 DCHECK_NE (0u , instr->OutputCount ());
14981512 Register reg = i.OutputRegister (instr->OutputCount () - 1 );
14991513
15001514 Condition cond = FlagsConditionToCondition (condition, op);
1501- switch (cond) {
1502- case eq:
1503- case lt:
1515+ if (op == kPPC_CmpDouble ) {
1516+ // check for unordered if necessary
1517+ if (cond == le) {
1518+ reg_value = 0 ;
15041519 __ li (reg, Operand::Zero ());
1505- __ li (kScratchReg , Operand (1 ));
1506- __ isel (cond, reg, kScratchReg , reg, cr);
1507- break ;
1508- case ne:
1509- case ge:
1520+ __ bunordered (&done, cr);
1521+ } else if (cond == gt) {
1522+ reg_value = 1 ;
15101523 __ li (reg, Operand (1 ));
1511- __ isel (NegateCondition (cond), reg, r0, reg, cr);
1512- break ;
1513- case gt:
1514- if (check_unordered) {
1515- __ li (reg, Operand (1 ));
1524+ __ bunordered (&done, cr);
1525+ }
1526+ // Unnecessary for eq/lt & ne/ge since only FU bit will be set.
1527+ }
1528+
1529+ if (CpuFeatures::IsSupported (ISELECT)) {
1530+ switch (cond) {
1531+ case eq:
1532+ case lt:
1533+ case gt:
1534+ if (reg_value != 1 ) __ li (reg, Operand (1 ));
15161535 __ li (kScratchReg , Operand::Zero ());
1517- __ bunordered (&done, cr);
15181536 __ isel (cond, reg, reg, kScratchReg , cr);
1519- } else {
1520- __ li (reg, Operand::Zero ());
1521- __ li (kScratchReg , Operand (1 ));
1522- __ isel (cond, reg, kScratchReg , reg, cr);
1523- }
1524- break ;
1525- case le:
1526- if (check_unordered) {
1527- __ li (reg, Operand::Zero ());
1528- __ li (kScratchReg , Operand (1 ));
1529- __ bunordered (&done, cr);
1530- __ isel (NegateCondition (cond), reg, r0, kScratchReg , cr);
1531- } else {
1532- __ li (reg, Operand (1 ));
1537+ break ;
1538+ case ne:
1539+ case ge:
1540+ case le:
1541+ if (reg_value != 1 ) __ li (reg, Operand (1 ));
1542+ // r0 implies logical zero in this form
15331543 __ isel (NegateCondition (cond), reg, r0, reg, cr);
1534- }
1535- break ;
1544+ break ;
15361545 default :
15371546 UNREACHABLE ();
15381547 break ;
1548+ }
1549+ } else {
1550+ if (reg_value != 0 ) __ li (reg, Operand::Zero ());
1551+ __ b (NegateCondition (cond), &done, cr);
1552+ __ li (reg, Operand (1 ));
15391553 }
15401554 __ bind (&done);
15411555}
0 commit comments