| 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);
|
| }
|
|
|