Chromium Code Reviews| Index: src/compiler/arm/instruction-selector-arm.cc |
| diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc |
| index 29af6ba0b200b6e82ad46ab2069213035030ed2a..d79fe46295a17132db414abbc7eb37e67d0b2208 100644 |
| --- a/src/compiler/arm/instruction-selector-arm.cc |
| +++ b/src/compiler/arm/instruction-selector-arm.cc |
| @@ -1093,6 +1093,33 @@ void InstructionSelector::VisitInt32Sub(Node* node) { |
| VisitBinop(this, node, kArmSub, kArmRsb); |
| } |
| +void VisitInt32MulWithOverflowImpl(InstructionSelector* selector, Node* node, |
|
Benedikt Meurer
2016/07/12 04:09:28
Put this into an anonymous namespace and remove th
mvstanton
2016/07/12 08:52:49
Done.
|
| + FlagsContinuation* cont) { |
| + ArmOperandGenerator g(selector); |
| + Int32BinopMatcher m(node); |
| + InstructionOperand result_operand = g.DefineAsRegister(node); |
| + InstructionOperand temp_operand = g.TempRegister(); |
| + InstructionOperand outputs[] = {result_operand, temp_operand}; |
| + InstructionOperand inputs[] = {g.UseRegister(m.left().node()), |
| + g.UseRegister(m.right().node())}; |
| + selector->Emit(kArmSmull, 2, outputs, 2, inputs); |
| + |
| + // result operand needs shift operator. |
| + InstructionOperand shift_31 = g.UseImmediate(31); |
| + InstructionCode opcode = cont->Encode(kArmCmp) | |
| + AddressingModeField::encode(kMode_Operand2_R_ASR_I); |
| + if (cont->IsBranch()) { |
| + selector->Emit(opcode, g.NoOutput(), temp_operand, result_operand, shift_31, |
| + g.Label(cont->true_block()), g.Label(cont->false_block())); |
| + } else if (cont->IsDeoptimize()) { |
| + InstructionOperand in[] = {temp_operand, result_operand, shift_31}; |
| + selector->EmitDeoptimize(opcode, 0, nullptr, 3, in, cont->frame_state()); |
| + } else { |
| + DCHECK(cont->IsSet()); |
| + selector->Emit(opcode, g.DefineAsRegister(cont->result()), temp_operand, |
| + result_operand, shift_31); |
| + } |
| +} |
| void InstructionSelector::VisitInt32Mul(Node* node) { |
| ArmOperandGenerator g(this); |
| @@ -1681,6 +1708,13 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, |
| case IrOpcode::kInt32SubWithOverflow: |
| cont->OverwriteAndNegateIfEqual(kOverflow); |
| return VisitBinop(selector, node, kArmSub, kArmRsb, cont); |
| + case IrOpcode::kInt32MulWithOverflow: |
| + // ARM doesn't set the overflow flag for multiplication, so we |
|
Benedikt Meurer
2016/07/12 04:09:28
Nice, thanks.
mvstanton
2016/07/12 08:52:49
Acknowledged.
|
| + // need to test on kNotEqual. Here is the code sequence used: |
| + // smull resultlow, resulthigh, left, right |
| + // cmp resulthigh, Operand(resultlow, ASR, 31) |
| + cont->OverwriteAndNegateIfEqual(kNotEqual); |
| + return VisitInt32MulWithOverflowImpl(selector, node, cont); |
| default: |
| break; |
| } |
| @@ -1822,7 +1856,6 @@ void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { |
| VisitBinop(this, node, kArmAdd, kArmAdd, &cont); |
| } |
| - |
| void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
| if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf); |
| @@ -1832,6 +1865,18 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { |
| VisitBinop(this, node, kArmSub, kArmRsb, &cont); |
| } |
| +void InstructionSelector::VisitInt32MulWithOverflow(Node* node) { |
| + if (Node* ovf = NodeProperties::FindProjection(node, 1)) { |
| + // ARM doesn't set the overflow flag for multiplication, so we need to test |
| + // on kNotEqual. Here is the code sequence used: |
| + // smull resultlow, resulthigh, left, right |
| + // cmp resulthigh, Operand(resultlow, ASR, 31) |
| + FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, ovf); |
| + return VisitInt32MulWithOverflowImpl(this, node, &cont); |
| + } |
| + FlagsContinuation cont; |
| + VisitInt32MulWithOverflowImpl(this, node, &cont); |
| +} |
| void InstructionSelector::VisitFloat32Equal(Node* node) { |
| FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node); |