Commit 789ad2f4 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [turbofan] Support for CPU models lacking isel.

R=joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1710453002

Cr-Commit-Position: refs/heads/master@{#34090}
parent 6b6b005f
...@@ -1270,11 +1270,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -1270,11 +1270,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
#if V8_TARGET_ARCH_PPC64 #if V8_TARGET_ARCH_PPC64
if (check_conversion) { if (check_conversion) {
// Set 2nd output to zero if conversion fails. // Set 2nd output to zero if conversion fails.
CRBit crbit = static_cast<CRBit>(VXCVI % CRWIDTH); CRegister cr = cr7;
__ mcrfs(cr7, VXCVI); // extract FPSCR field containing VXCVI into cr7 int crbit = v8::internal::Assembler::encode_crbit(
__ li(i.OutputRegister(1), Operand(1)); cr, static_cast<CRBit>(VXCVI % CRWIDTH));
__ isel(i.OutputRegister(1), r0, i.OutputRegister(1), __ mcrfs(cr, VXCVI); // extract FPSCR field containing VXCVI into cr7
v8::internal::Assembler::encode_crbit(cr7, crbit)); 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 #endif
DCHECK_EQ(LeaveRC, i.OutputRCBit()); DCHECK_EQ(LeaveRC, i.OutputRCBit());
...@@ -1290,11 +1297,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { ...@@ -1290,11 +1297,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
i.OutputRegister(0), kScratchDoubleReg); i.OutputRegister(0), kScratchDoubleReg);
if (check_conversion) { if (check_conversion) {
// Set 2nd output to zero if conversion fails. // Set 2nd output to zero if conversion fails.
CRBit crbit = static_cast<CRBit>(VXCVI % CRWIDTH); CRegister cr = cr7;
__ mcrfs(cr7, VXCVI); // extract FPSCR field containing VXCVI into cr7 int crbit = v8::internal::Assembler::encode_crbit(
__ li(i.OutputRegister(1), Operand(1)); cr, static_cast<CRBit>(VXCVI % CRWIDTH));
__ isel(i.OutputRegister(1), r0, i.OutputRegister(1), __ mcrfs(cr, VXCVI); // extract FPSCR field containing VXCVI into cr7
v8::internal::Assembler::encode_crbit(cr7, crbit)); 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()); DCHECK_EQ(LeaveRC, i.OutputRCBit());
break; break;
...@@ -1489,8 +1503,8 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, ...@@ -1489,8 +1503,8 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
PPCOperandConverter i(this, instr); PPCOperandConverter i(this, instr);
Label done; Label done;
ArchOpcode op = instr->arch_opcode(); ArchOpcode op = instr->arch_opcode();
bool check_unordered = (op == kPPC_CmpDouble);
CRegister cr = cr0; CRegister cr = cr0;
int reg_value = -1;
// Materialize a full 32-bit 1 or 0 value. The result register is always the // Materialize a full 32-bit 1 or 0 value. The result register is always the
// last output of the instruction. // last output of the instruction.
...@@ -1498,44 +1512,44 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, ...@@ -1498,44 +1512,44 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
Register reg = i.OutputRegister(instr->OutputCount() - 1); Register reg = i.OutputRegister(instr->OutputCount() - 1);
Condition cond = FlagsConditionToCondition(condition, op); Condition cond = FlagsConditionToCondition(condition, op);
switch (cond) { if (op == kPPC_CmpDouble) {
case eq: // check for unordered if necessary
case lt: if (cond == le) {
reg_value = 0;
__ li(reg, Operand::Zero()); __ li(reg, Operand::Zero());
__ li(kScratchReg, Operand(1)); __ bunordered(&done, cr);
__ isel(cond, reg, kScratchReg, reg, cr); } else if (cond == gt) {
break; reg_value = 1;
case ne:
case ge:
__ li(reg, Operand(1)); __ li(reg, Operand(1));
__ isel(NegateCondition(cond), reg, r0, reg, cr); __ bunordered(&done, cr);
break; }
case gt: // Unnecessary for eq/lt & ne/ge since only FU bit will be set.
if (check_unordered) { }
__ li(reg, Operand(1));
if (CpuFeatures::IsSupported(ISELECT)) {
switch (cond) {
case eq:
case lt:
case gt:
if (reg_value != 1) __ li(reg, Operand(1));
__ li(kScratchReg, Operand::Zero()); __ li(kScratchReg, Operand::Zero());
__ bunordered(&done, cr);
__ isel(cond, reg, reg, kScratchReg, cr); __ isel(cond, reg, reg, kScratchReg, cr);
} else { break;
__ li(reg, Operand::Zero()); case ne:
__ li(kScratchReg, Operand(1)); case ge:
__ isel(cond, reg, kScratchReg, reg, cr); case le:
} if (reg_value != 1) __ li(reg, Operand(1));
break; // r0 implies logical zero in this form
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));
__ isel(NegateCondition(cond), reg, r0, reg, cr); __ isel(NegateCondition(cond), reg, r0, reg, cr);
} break;
break;
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
}
} else {
if (reg_value != 0) __ li(reg, Operand::Zero());
__ b(NegateCondition(cond), &done, cr);
__ li(reg, Operand(1));
} }
__ bind(&done); __ bind(&done);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment