| 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..22062abc7410428c3a767ad04be3f3ec249fe0da 100644
|
| --- a/src/compiler/x64/instruction-selector-x64.cc
|
| +++ b/src/compiler/x64/instruction-selector-x64.cc
|
| @@ -618,6 +618,75 @@ 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);
|
| + if (mleft.displacement() == nullptr) {
|
| + // Make sure that the addressing mode indicates the presence of an
|
| + // immediate displacement. It seems that we never use M1 and M2, but we
|
| + // handle them here anyways.
|
| + switch (mode) {
|
| + case kMode_MR:
|
| + mode = kMode_MRI;
|
| + break;
|
| + case kMode_MR1:
|
| + mode = kMode_MR1I;
|
| + break;
|
| + case kMode_MR2:
|
| + mode = kMode_MR2I;
|
| + break;
|
| + case kMode_MR4:
|
| + mode = kMode_MR4I;
|
| + break;
|
| + case kMode_MR8:
|
| + mode = kMode_MR8I;
|
| + break;
|
| + case kMode_M1:
|
| + mode = kMode_M1I;
|
| + break;
|
| + case kMode_M2:
|
| + mode = kMode_M2I;
|
| + break;
|
| + case kMode_M4:
|
| + mode = kMode_M4I;
|
| + break;
|
| + case kMode_M8:
|
| + mode = kMode_M8I;
|
| + break;
|
| + case kMode_None:
|
| + case kMode_MRI:
|
| + case kMode_MR1I:
|
| + case kMode_MR2I:
|
| + case kMode_MR4I:
|
| + case kMode_MR8I:
|
| + case kMode_M1I:
|
| + case kMode_M2I:
|
| + case kMode_M4I:
|
| + case kMode_M8I:
|
| + UNREACHABLE();
|
| + }
|
| + 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);
|
| }
|
|
|
|
|