diff --git a/src/compiler/ppc/code-generator-ppc.cc b/src/compiler/ppc/code-generator-ppc.cc index e639a9247fa..6d33abefcd6 100644 --- a/src/compiler/ppc/code-generator-ppc.cc +++ b/src/compiler/ppc/code-generator-ppc.cc @@ -1270,11 +1270,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { #if V8_TARGET_ARCH_PPC64 if (check_conversion) { // Set 2nd output to zero if conversion fails. - CRBit crbit = static_cast(VXCVI % CRWIDTH); - __ mcrfs(cr7, VXCVI); // extract FPSCR field containing VXCVI into cr7 - __ li(i.OutputRegister(1), Operand(1)); - __ isel(i.OutputRegister(1), r0, i.OutputRegister(1), - v8::internal::Assembler::encode_crbit(cr7, crbit)); + CRegister cr = cr7; + int crbit = v8::internal::Assembler::encode_crbit( + cr, static_cast(VXCVI % CRWIDTH)); + __ mcrfs(cr, VXCVI); // extract FPSCR field containing VXCVI into cr7 + if (CpuFeatures::IsSupported(ISELECT)) { + __ li(i.OutputRegister(1), Operand(1)); + __ isel(i.OutputRegister(1), r0, i.OutputRegister(1), crbit); + } else { + __ li(i.OutputRegister(1), Operand::Zero()); + __ bc(v8::internal::Assembler::kInstrSize * 2, BT, crbit); + __ li(i.OutputRegister(1), Operand(1)); + } } #endif DCHECK_EQ(LeaveRC, i.OutputRCBit()); @@ -1290,11 +1297,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { i.OutputRegister(0), kScratchDoubleReg); if (check_conversion) { // Set 2nd output to zero if conversion fails. - CRBit crbit = static_cast(VXCVI % CRWIDTH); - __ mcrfs(cr7, VXCVI); // extract FPSCR field containing VXCVI into cr7 - __ li(i.OutputRegister(1), Operand(1)); - __ isel(i.OutputRegister(1), r0, i.OutputRegister(1), - v8::internal::Assembler::encode_crbit(cr7, crbit)); + CRegister cr = cr7; + int crbit = v8::internal::Assembler::encode_crbit( + cr, static_cast(VXCVI % CRWIDTH)); + __ mcrfs(cr, VXCVI); // extract FPSCR field containing VXCVI into cr7 + if (CpuFeatures::IsSupported(ISELECT)) { + __ li(i.OutputRegister(1), Operand(1)); + __ isel(i.OutputRegister(1), r0, i.OutputRegister(1), crbit); + } else { + __ li(i.OutputRegister(1), Operand::Zero()); + __ bc(v8::internal::Assembler::kInstrSize * 2, BT, crbit); + __ li(i.OutputRegister(1), Operand(1)); + } } DCHECK_EQ(LeaveRC, i.OutputRCBit()); break; @@ -1489,8 +1503,8 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, PPCOperandConverter i(this, instr); Label done; ArchOpcode op = instr->arch_opcode(); - bool check_unordered = (op == kPPC_CmpDouble); CRegister cr = cr0; + int reg_value = -1; // Materialize a full 32-bit 1 or 0 value. The result register is always the // last output of the instruction. @@ -1498,44 +1512,44 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, Register reg = i.OutputRegister(instr->OutputCount() - 1); Condition cond = FlagsConditionToCondition(condition, op); - switch (cond) { - case eq: - case lt: + if (op == kPPC_CmpDouble) { + // check for unordered if necessary + if (cond == le) { + reg_value = 0; __ li(reg, Operand::Zero()); - __ li(kScratchReg, Operand(1)); - __ isel(cond, reg, kScratchReg, reg, cr); - break; - case ne: - case ge: + __ bunordered(&done, cr); + } else if (cond == gt) { + reg_value = 1; __ li(reg, Operand(1)); - __ isel(NegateCondition(cond), reg, r0, reg, cr); - break; - case gt: - if (check_unordered) { - __ li(reg, Operand(1)); + __ bunordered(&done, cr); + } + // Unnecessary for eq/lt & ne/ge since only FU bit will be set. + } + + if (CpuFeatures::IsSupported(ISELECT)) { + switch (cond) { + case eq: + case lt: + case gt: + if (reg_value != 1) __ li(reg, Operand(1)); __ li(kScratchReg, Operand::Zero()); - __ bunordered(&done, cr); __ isel(cond, reg, reg, kScratchReg, cr); - } else { - __ li(reg, Operand::Zero()); - __ li(kScratchReg, Operand(1)); - __ isel(cond, reg, kScratchReg, reg, cr); - } - break; - case le: - if (check_unordered) { - __ li(reg, Operand::Zero()); - __ li(kScratchReg, Operand(1)); - __ bunordered(&done, cr); - __ isel(NegateCondition(cond), reg, r0, kScratchReg, cr); - } else { - __ li(reg, Operand(1)); + break; + case ne: + case ge: + case le: + if (reg_value != 1) __ li(reg, Operand(1)); + // r0 implies logical zero in this form __ isel(NegateCondition(cond), reg, r0, reg, cr); - } - break; + break; default: UNREACHABLE(); break; + } + } else { + if (reg_value != 0) __ li(reg, Operand::Zero()); + __ b(NegateCondition(cond), &done, cr); + __ li(reg, Operand(1)); } __ bind(&done); }