Index: src/compiler/ppc/instruction-selector-ppc.cc |
diff --git a/src/compiler/ppc/instruction-selector-ppc.cc b/src/compiler/ppc/instruction-selector-ppc.cc |
index dd81d8510b7a0c53520be9c42a508cbbd35c8d56..5abb5f14762b89615444513f1438f539a64cebbc 100644 |
--- a/src/compiler/ppc/instruction-selector-ppc.cc |
+++ b/src/compiler/ppc/instruction-selector-ppc.cc |
@@ -863,6 +863,30 @@ void InstructionSelector::VisitWord32PairSar(Node* node) { |
#if V8_TARGET_ARCH_PPC64 |
void InstructionSelector::VisitWord64Sar(Node* node) { |
+ PPCOperandGenerator 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.index() == nullptr) { |
+ int64_t offset = 0; |
+ Node* displacement = mleft.displacement(); |
+ if (displacement != nullptr) { |
+ Int64Matcher mdisplacement(displacement); |
+ DCHECK(mdisplacement.HasValue()); |
+ offset = mdisplacement.Value(); |
+ } |
+ offset = SmiWordOffset(offset); |
+ if (g.CanBeImmediate(offset, kInt16Imm_4ByteAligned)) { |
+ Emit(kPPC_LoadWordS32 | AddressingModeField::encode(kMode_MRI), |
+ g.DefineAsRegister(node), g.UseRegister(mleft.base()), |
+ g.TempImmediate(offset)); |
+ return; |
+ } |
+ } |
+ } |
VisitRRO(this, kPPC_ShiftRightAlg64, node, kShift64Imm); |
} |
#endif |