Chromium Code Reviews| Index: src/compiler/x64/instruction-selector-x64.cc |
| diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc |
| index edcf62a5ecbcd19db8a68d1a0c2abf08ecd508c9..282049e8130d3593894b001a160e7bb9b5fae300 100644 |
| --- a/src/compiler/x64/instruction-selector-x64.cc |
| +++ b/src/compiler/x64/instruction-selector-x64.cc |
| @@ -63,6 +63,17 @@ class X64OperandGenerator final : public OperandGenerator { |
| return false; |
| } |
| + AddressingMode EnsureHasDisplacement( |
| + const BaseWithIndexAndDisplacement64Matcher& matcher, |
| + AddressingMode mode) { |
| + if (matcher.displacement() != nullptr) { |
| + return mode; |
| + } |
| + DCHECK(mode == kMode_MR || (kMode_MR1 <= mode && mode <= kMode_MR8) || |
|
Benedikt Meurer
2016/04/01 08:33:00
As discussed offline, please do a switch here. And
epertoso
2016/04/01 09:16:44
Done.
|
| + (kMode_M4 == mode || kMode_M8 == mode)); |
| + return mode == kMode_MR ? kMode_MRI : static_cast<AddressingMode>(mode + 4); |
| + } |
| + |
| AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent, |
| Node* base, Node* displacement, |
| InstructionOperand inputs[], |
| @@ -618,6 +629,33 @@ void InstructionSelector::VisitWord32Sar(Node* node) { |
| void InstructionSelector::VisitWord64Sar(Node* node) { |
| + X64OperandGenerator g(this); |
| + Int64BinopMatcher m(node); |
| + if (CanCover(m.node(), m.left().node()) && m.left().IsLoad() && |
| + m.right().Is(32)) { |
| + // Just load and sign-extend the interesting 4 bytes instead. This happens, |
| + // for example, when we're loading and untagging SMIs. |
| + BaseWithIndexAndDisplacement64Matcher mleft(m.left().node(), true); |
| + if (mleft.matches() && (mleft.displacement() == nullptr || |
| + g.CanBeImmediate(mleft.displacement()))) { |
| + size_t input_count = 0; |
| + InstructionOperand inputs[3]; |
| + AddressingMode mode = g.GetEffectiveAddressMemoryOperand( |
| + m.left().node(), inputs, &input_count); |
| + mode = g.EnsureHasDisplacement(mleft, mode); |
| + if (mleft.displacement() == nullptr) { |
| + inputs[input_count++] = ImmediateOperand(ImmediateOperand::INLINE, 4); |
| + } else { |
| + ImmediateOperand* op = ImmediateOperand::cast(&inputs[input_count - 1]); |
| + int32_t displacement = sequence()->GetImmediate(op).ToInt32(); |
| + *op = ImmediateOperand(ImmediateOperand::INLINE, displacement + 4); |
| + } |
| + InstructionOperand outputs[] = {g.DefineAsRegister(node)}; |
| + InstructionCode code = kX64Movsxlq | AddressingModeField::encode(mode); |
| + Emit(code, 1, outputs, input_count, inputs); |
| + return; |
| + } |
| + } |
| VisitWord64Shift(this, node, kX64Sar); |
| } |