Index: src/compiler/ppc/code-generator-ppc.cc |
diff --git a/src/compiler/ppc/code-generator-ppc.cc b/src/compiler/ppc/code-generator-ppc.cc |
index e639a9247fa3f54856ddcd1fae81d7f5b579383a..6d33abefcd68f7fe0f0bc3a65f82c315d6136ee0 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<CRBit>(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<CRBit>(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<CRBit>(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<CRBit>(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); |
} |