Commit a9f69934 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [turbofan] Add Int64(Add|Sub)WithOverflow support.

Port bafb568b

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

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

Cr-Commit-Position: refs/heads/master@{#33063}
parent 49e25ff4
......@@ -201,7 +201,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
};
Condition FlagsConditionToCondition(FlagsCondition condition) {
Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
switch (condition) {
case kEqual:
return eq;
......@@ -220,17 +220,42 @@ Condition FlagsConditionToCondition(FlagsCondition condition) {
case kUnsignedGreaterThan:
return gt;
case kOverflow:
// Overflow checked for add/sub only.
switch (op) {
#if V8_TARGET_ARCH_PPC64
return ne;
case kPPC_Add:
case kPPC_Sub:
return lt;
#endif
case kPPC_AddWithOverflow32:
case kPPC_SubWithOverflow32:
#if V8_TARGET_ARCH_PPC64
return ne;
#else
return lt;
return lt;
#endif
default:
break;
}
break;
case kNotOverflow:
switch (op) {
#if V8_TARGET_ARCH_PPC64
return eq;
case kPPC_Add:
case kPPC_Sub:
return ge;
#endif
case kPPC_AddWithOverflow32:
case kPPC_SubWithOverflow32:
#if V8_TARGET_ARCH_PPC64
return eq;
#else
return ge;
return ge;
#endif
default:
break;
}
break;
default:
break;
}
......@@ -290,13 +315,6 @@ Condition FlagsConditionToCondition(FlagsCondition condition) {
} while (0)
#if V8_TARGET_ARCH_PPC64
#define ASSEMBLE_ADD_WITH_OVERFLOW() \
do { \
ASSEMBLE_BINOP(add, addi); \
__ TestIfInt32(i.OutputRegister(), r0, cr0); \
} while (0)
#else
#define ASSEMBLE_ADD_WITH_OVERFLOW() \
do { \
if (HasRegisterInput(instr, 1)) { \
......@@ -307,16 +325,8 @@ Condition FlagsConditionToCondition(FlagsCondition condition) {
i.InputInt32(1), kScratchReg, r0); \
} \
} while (0)
#endif
#if V8_TARGET_ARCH_PPC64
#define ASSEMBLE_SUB_WITH_OVERFLOW() \
do { \
ASSEMBLE_BINOP(sub, subi); \
__ TestIfInt32(i.OutputRegister(), r0, cr0); \
} while (0)
#else
#define ASSEMBLE_SUB_WITH_OVERFLOW() \
do { \
if (HasRegisterInput(instr, 1)) { \
......@@ -327,6 +337,24 @@ Condition FlagsConditionToCondition(FlagsCondition condition) {
-i.InputInt32(1), kScratchReg, r0); \
} \
} while (0)
#if V8_TARGET_ARCH_PPC64
#define ASSEMBLE_ADD_WITH_OVERFLOW32() \
do { \
ASSEMBLE_BINOP(add, addi); \
__ TestIfInt32(i.OutputRegister(), r0, cr0); \
} while (0)
#define ASSEMBLE_SUB_WITH_OVERFLOW32() \
do { \
ASSEMBLE_BINOP(sub, subi); \
__ TestIfInt32(i.OutputRegister(), r0, cr0); \
} while (0)
#else
#define ASSEMBLE_ADD_WITH_OVERFLOW32 ASSEMBLE_ADD_WITH_OVERFLOW
#define ASSEMBLE_SUB_WITH_OVERFLOW32 ASSEMBLE_SUB_WITH_OVERFLOW
#endif
......@@ -903,31 +931,47 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
#endif
case kPPC_Add:
if (HasRegisterInput(instr, 1)) {
__ add(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
LeaveOE, i.OutputRCBit());
#if V8_TARGET_ARCH_PPC64
if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
ASSEMBLE_ADD_WITH_OVERFLOW();
} else {
__ addi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
#endif
if (HasRegisterInput(instr, 1)) {
__ add(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
LeaveOE, i.OutputRCBit());
} else {
__ addi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
}
#if V8_TARGET_ARCH_PPC64
}
#endif
break;
case kPPC_AddWithOverflow32:
ASSEMBLE_ADD_WITH_OVERFLOW();
ASSEMBLE_ADD_WITH_OVERFLOW32();
break;
case kPPC_AddDouble:
ASSEMBLE_FLOAT_BINOP_RC(fadd);
break;
case kPPC_Sub:
if (HasRegisterInput(instr, 1)) {
__ sub(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
LeaveOE, i.OutputRCBit());
#if V8_TARGET_ARCH_PPC64
if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
ASSEMBLE_SUB_WITH_OVERFLOW();
} else {
__ subi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
#endif
if (HasRegisterInput(instr, 1)) {
__ sub(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
LeaveOE, i.OutputRCBit());
} else {
__ subi(i.OutputRegister(), i.InputRegister(0), i.InputImmediate(1));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
}
#if V8_TARGET_ARCH_PPC64
}
#endif
break;
case kPPC_SubWithOverflow32:
ASSEMBLE_SUB_WITH_OVERFLOW();
ASSEMBLE_SUB_WITH_OVERFLOW32();
break;
case kPPC_SubDouble:
ASSEMBLE_FLOAT_BINOP_RC(fsub);
......@@ -1128,8 +1172,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kPPC_Int64ToInt32:
// TODO(mbrandy): sign extend?
__ Move(i.OutputRegister(), i.InputRegister(0));
__ extsw(i.OutputRegister(), i.InputRegister(0));
DCHECK_EQ(LeaveRC, i.OutputRCBit());
break;
case kPPC_Int64ToFloat32:
......@@ -1370,11 +1413,7 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
FlagsCondition condition = branch->condition;
CRegister cr = cr0;
// Overflow checked for add/sub only.
DCHECK((condition != kOverflow && condition != kNotOverflow) ||
(op == kPPC_AddWithOverflow32 || op == kPPC_SubWithOverflow32));
Condition cond = FlagsConditionToCondition(condition);
Condition cond = FlagsConditionToCondition(condition, op);
if (op == kPPC_CmpDouble) {
// check for unordered if necessary
if (cond == le) {
......@@ -1404,16 +1443,12 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
bool check_unordered = (op == kPPC_CmpDouble);
CRegister cr = cr0;
// Overflow checked for add/sub only.
DCHECK((condition != kOverflow && condition != kNotOverflow) ||
(op == kPPC_AddWithOverflow32 || op == kPPC_SubWithOverflow32));
// Materialize a full 32-bit 1 or 0 value. The result register is always the
// last output of the instruction.
DCHECK_NE(0u, instr->OutputCount());
Register reg = i.OutputRegister(instr->OutputCount() - 1);
Condition cond = FlagsConditionToCondition(condition);
Condition cond = FlagsConditionToCondition(condition, op);
switch (cond) {
case eq:
case lt:
......
......@@ -1241,6 +1241,30 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
}
#if V8_TARGET_ARCH_PPC64
void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont(kOverflow, ovf);
return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add, kInt16Imm,
&cont);
}
FlagsContinuation cont;
VisitBinop<Int64BinopMatcher>(this, node, kPPC_Add, kInt16Imm, &cont);
}
void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont(kOverflow, ovf);
return VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate,
&cont);
}
FlagsContinuation cont;
VisitBinop<Int64BinopMatcher>(this, node, kPPC_Sub, kInt16Imm_Negate, &cont);
}
#endif
static bool CompareLogical(FlagsContinuation* cont) {
switch (cont->condition()) {
case kUnsignedLessThan:
......@@ -1423,6 +1447,16 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
return VisitBinop<Int32BinopMatcher>(selector, node,
kPPC_SubWithOverflow32,
kInt16Imm_Negate, cont);
#if V8_TARGET_ARCH_PPC64
case IrOpcode::kInt64AddWithOverflow:
cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitBinop<Int64BinopMatcher>(selector, node, kPPC_Add,
kInt16Imm, cont);
case IrOpcode::kInt64SubWithOverflow:
cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitBinop<Int64BinopMatcher>(selector, node, kPPC_Sub,
kInt16Imm_Negate, cont);
#endif
default:
break;
}
......
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