Index: src/compiler/s390/instruction-selector-s390.cc |
diff --git a/src/compiler/s390/instruction-selector-s390.cc b/src/compiler/s390/instruction-selector-s390.cc |
index 8176419e15ab1e6dc86f67f2f33c6b6263575210..72772e9f0ea77fde4fb4e7e66e52786ab7fb6ac5 100644 |
--- a/src/compiler/s390/instruction-selector-s390.cc |
+++ b/src/compiler/s390/instruction-selector-s390.cc |
@@ -264,6 +264,7 @@ void InstructionSelector::VisitStore(Node* node) { |
} else { |
ArchOpcode opcode = kArchNop; |
ImmediateMode mode = kInt16Imm; |
+ NodeMatcher m(value); |
switch (rep) { |
case MachineRepresentation::kFloat32: |
opcode = kS390_StoreFloat32; |
@@ -277,18 +278,30 @@ void InstructionSelector::VisitStore(Node* node) { |
break; |
case MachineRepresentation::kWord16: |
opcode = kS390_StoreWord16; |
+ if (m.IsWord16ReverseBytes()) { |
+ opcode = kS390_StoreReverse16; |
+ value = value->InputAt(0); |
+ } |
break; |
#if !V8_TARGET_ARCH_S390X |
case MachineRepresentation::kTagged: // Fall through. |
#endif |
case MachineRepresentation::kWord32: |
opcode = kS390_StoreWord32; |
+ if (m.IsWord32ReverseBytes()) { |
+ opcode = kS390_StoreReverse32; |
+ value = value->InputAt(0); |
+ } |
break; |
#if V8_TARGET_ARCH_S390X |
case MachineRepresentation::kTagged: // Fall through. |
case MachineRepresentation::kWord64: |
opcode = kS390_StoreWord64; |
mode = kInt16Imm_4ByteAligned; |
+ if (m.IsWord64ReverseBytes()) { |
+ opcode = kS390_StoreReverse64; |
+ value = value->InputAt(0); |
+ } |
break; |
#else |
case MachineRepresentation::kWord64: // Fall through. |
@@ -880,6 +893,51 @@ void InstructionSelector::VisitWord32ReverseBits(Node* node) { UNREACHABLE(); } |
void InstructionSelector::VisitWord64ReverseBits(Node* node) { UNREACHABLE(); } |
#endif |
+void InstructionSelector::VisitWord64ReverseBytes(Node* node) { |
+ UNREACHABLE(); |
+ S390OperandGenerator g(this); |
+ Emit(kS390_LoadReverse64RR, g.DefineAsRegister(node), |
+ g.UseRegister(node->InputAt(0))); |
+} |
+ |
+void InstructionSelector::VisitWord32ReverseBytes(Node* node) { |
+ S390OperandGenerator g(this); |
+ NodeMatcher input(node->InputAt(0)); |
+ if (CanCover(node, input.node()) && input.IsLoad()) { |
+ LoadRepresentation load_rep = LoadRepresentationOf(input.node()->op()); |
+ if (load_rep.representation() == MachineRepresentation::kWord32) { |
+ Node* base = input.node()->InputAt(0); |
+ Node* offset = input.node()->InputAt(1); |
+ Emit(kS390_LoadReverse32 | AddressingModeField::encode(kMode_MRR), |
+ // TODO(john.yan): one of the base and offset can be imm. |
+ g.DefineAsRegister(node), g.UseRegister(base), |
+ g.UseRegister(offset)); |
+ return; |
+ } |
+ } |
+ Emit(kS390_LoadReverse32RR, g.DefineAsRegister(node), |
+ g.UseRegister(node->InputAt(0))); |
+} |
+ |
+void InstructionSelector::VisitWord16ReverseBytes(Node* node) { |
+ S390OperandGenerator g(this); |
+ NodeMatcher input(node->InputAt(0)); |
+ if (CanCover(node, input.node()) && input.IsLoad()) { |
+ LoadRepresentation load_rep = LoadRepresentationOf(input.node()->op()); |
+ if (load_rep.representation() == MachineRepresentation::kWord16) { |
+ Node* base = input.node()->InputAt(0); |
+ Node* offset = input.node()->InputAt(1); |
+ Emit(kS390_LoadReverse16 | AddressingModeField::encode(kMode_MRR), |
+ // TODO(john.yan): one of the base and offset can be imm. |
+ g.DefineAsRegister(node), g.UseRegister(base), |
+ g.UseRegister(offset)); |
+ return; |
+ } |
+ } |
+ Emit(kS390_LoadReverse16RR, g.DefineAsRegister(node), |
+ g.UseRegister(node->InputAt(0))); |
+} |
+ |
void InstructionSelector::VisitInt32Add(Node* node) { |
VisitBinop<Int32BinopMatcher>(this, node, kS390_Add, kInt16Imm); |
} |
@@ -1830,6 +1888,9 @@ InstructionSelector::SupportedMachineOperatorFlags() { |
MachineOperatorBuilder::kFloat64RoundTruncate | |
MachineOperatorBuilder::kFloat64RoundTiesAway | |
MachineOperatorBuilder::kWord32Popcnt | |
+ MachineOperatorBuilder::kWord16ReverseBytes | |
+ MachineOperatorBuilder::kWord32ReverseBytes | |
+ MachineOperatorBuilder::kWord64ReverseBytes | |
MachineOperatorBuilder::kWord64Popcnt; |
} |