@@ -1221,11 +1221,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
12211221#if V8_TARGET_ARCH_PPC64
12221222 if (check_conversion) {
12231223 // Set 2nd output to zero if conversion fails.
1224- CRBit crbit = static_cast <CRBit>(VXCVI % CRWIDTH);
1225- __ mcrfs (cr7, VXCVI); // extract FPSCR field containing VXCVI into cr7
1226- __ li (i.OutputRegister (1 ), Operand (1 ));
1227- __ isel (i.OutputRegister (1 ), r0, i.OutputRegister (1 ),
1228- v8::internal::Assembler::encode_crbit (cr7, crbit));
1224+ CRegister cr = cr7;
1225+ int crbit = v8::internal::Assembler::encode_crbit (
1226+ cr, static_cast <CRBit>(VXCVI % CRWIDTH));
1227+ __ mcrfs (cr, VXCVI); // extract FPSCR field containing VXCVI into cr7
1228+ if (CpuFeatures::IsSupported (ISELECT)) {
1229+ __ li (i.OutputRegister (1 ), Operand (1 ));
1230+ __ isel (i.OutputRegister (1 ), r0, i.OutputRegister (1 ), crbit);
1231+ } else {
1232+ __ li (i.OutputRegister (1 ), Operand::Zero ());
1233+ __ bc (v8::internal::Assembler::kInstrSize * 2 , BT, crbit);
1234+ __ li (i.OutputRegister (1 ), Operand (1 ));
1235+ }
12291236 }
12301237#endif
12311238 DCHECK_EQ (LeaveRC, i.OutputRCBit ());
@@ -1241,11 +1248,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
12411248 i.OutputRegister (0 ), kScratchDoubleReg );
12421249 if (check_conversion) {
12431250 // Set 2nd output to zero if conversion fails.
1244- CRBit crbit = static_cast <CRBit>(VXCVI % CRWIDTH);
1245- __ mcrfs (cr7, VXCVI); // extract FPSCR field containing VXCVI into cr7
1246- __ li (i.OutputRegister (1 ), Operand (1 ));
1247- __ isel (i.OutputRegister (1 ), r0, i.OutputRegister (1 ),
1248- v8::internal::Assembler::encode_crbit (cr7, crbit));
1251+ CRegister cr = cr7;
1252+ int crbit = v8::internal::Assembler::encode_crbit (
1253+ cr, static_cast <CRBit>(VXCVI % CRWIDTH));
1254+ __ mcrfs (cr, VXCVI); // extract FPSCR field containing VXCVI into cr7
1255+ if (CpuFeatures::IsSupported (ISELECT)) {
1256+ __ li (i.OutputRegister (1 ), Operand (1 ));
1257+ __ isel (i.OutputRegister (1 ), r0, i.OutputRegister (1 ), crbit);
1258+ } else {
1259+ __ li (i.OutputRegister (1 ), Operand::Zero ());
1260+ __ bc (v8::internal::Assembler::kInstrSize * 2 , BT, crbit);
1261+ __ li (i.OutputRegister (1 ), Operand (1 ));
1262+ }
12491263 }
12501264 DCHECK_EQ (LeaveRC, i.OutputRCBit ());
12511265 break ;
@@ -1440,53 +1454,53 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
14401454 PPCOperandConverter i (this , instr);
14411455 Label done;
14421456 ArchOpcode op = instr->arch_opcode ();
1443- bool check_unordered = (op == kPPC_CmpDouble );
14441457 CRegister cr = cr0;
1458+ int reg_value = -1 ;
14451459
14461460 // Materialize a full 32-bit 1 or 0 value. The result register is always the
14471461 // last output of the instruction.
14481462 DCHECK_NE (0u , instr->OutputCount ());
14491463 Register reg = i.OutputRegister (instr->OutputCount () - 1 );
14501464
14511465 Condition cond = FlagsConditionToCondition (condition, op);
1452- switch (cond) {
1453- case eq:
1454- case lt:
1466+ if (op == kPPC_CmpDouble ) {
1467+ // check for unordered if necessary
1468+ if (cond == le) {
1469+ reg_value = 0 ;
14551470 __ li (reg, Operand::Zero ());
1456- __ li (kScratchReg , Operand (1 ));
1457- __ isel (cond, reg, kScratchReg , reg, cr);
1458- break ;
1459- case ne:
1460- case ge:
1471+ __ bunordered (&done, cr);
1472+ } else if (cond == gt) {
1473+ reg_value = 1 ;
14611474 __ li (reg, Operand (1 ));
1462- __ isel (NegateCondition (cond), reg, r0, reg, cr);
1463- break ;
1464- case gt:
1465- if (check_unordered) {
1466- __ li (reg, Operand (1 ));
1475+ __ bunordered (&done, cr);
1476+ }
1477+ // Unnecessary for eq/lt & ne/ge since only FU bit will be set.
1478+ }
1479+
1480+ if (CpuFeatures::IsSupported (ISELECT)) {
1481+ switch (cond) {
1482+ case eq:
1483+ case lt:
1484+ case gt:
1485+ if (reg_value != 1 ) __ li (reg, Operand (1 ));
14671486 __ li (kScratchReg , Operand::Zero ());
1468- __ bunordered (&done, cr);
14691487 __ isel (cond, reg, reg, kScratchReg , cr);
1470- } else {
1471- __ li (reg, Operand::Zero ());
1472- __ li (kScratchReg , Operand (1 ));
1473- __ isel (cond, reg, kScratchReg , reg, cr);
1474- }
1475- break ;
1476- case le:
1477- if (check_unordered) {
1478- __ li (reg, Operand::Zero ());
1479- __ li (kScratchReg , Operand (1 ));
1480- __ bunordered (&done, cr);
1481- __ isel (NegateCondition (cond), reg, r0, kScratchReg , cr);
1482- } else {
1483- __ li (reg, Operand (1 ));
1488+ break ;
1489+ case ne:
1490+ case ge:
1491+ case le:
1492+ if (reg_value != 1 ) __ li (reg, Operand (1 ));
1493+ // r0 implies logical zero in this form
14841494 __ isel (NegateCondition (cond), reg, r0, reg, cr);
1485- }
1486- break ;
1495+ break ;
14871496 default :
14881497 UNREACHABLE ();
14891498 break ;
1499+ }
1500+ } else {
1501+ if (reg_value != 0 ) __ li (reg, Operand::Zero ());
1502+ __ b (NegateCondition (cond), &done, cr);
1503+ __ li (reg, Operand (1 ));
14901504 }
14911505 __ bind (&done);
14921506}
0 commit comments