Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(103)

Unified Diff: src/compiler/s390/instruction-selector-s390.cc

Issue 2244373002: s390: Allow larger Operands/Displacements/Offsets in s390 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/s390/instruction-codes-s390.h ('k') | src/s390/assembler-s390.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2fd3f78f593ea373e8018e06cbf3eb95ff822f99..90a3d3e2f382b9ae910d41e397de178f2d02f364 100644
--- a/src/compiler/s390/instruction-selector-s390.cc
+++ b/src/compiler/s390/instruction-selector-s390.cc
@@ -13,12 +13,12 @@ namespace internal {
namespace compiler {
enum ImmediateMode {
- kInt16Imm,
- kInt16Imm_Unsigned,
- kInt16Imm_Negate,
- kInt16Imm_4ByteAligned,
kShift32Imm,
kShift64Imm,
+ kInt32Imm,
+ kInt32Imm_Negate,
+ kUint32Imm,
+ kInt20Imm,
kNoImmediate
};
@@ -48,23 +48,90 @@ class S390OperandGenerator final : public OperandGenerator {
bool CanBeImmediate(int64_t value, ImmediateMode mode) {
switch (mode) {
- case kInt16Imm:
- return is_int16(value);
- case kInt16Imm_Unsigned:
- return is_uint16(value);
- case kInt16Imm_Negate:
- return is_int16(-value);
- case kInt16Imm_4ByteAligned:
- return is_int16(value) && !(value & 3);
case kShift32Imm:
return 0 <= value && value < 32;
case kShift64Imm:
return 0 <= value && value < 64;
+ case kInt32Imm:
+ return is_int32(value);
+ case kInt32Imm_Negate:
+ return is_int32(-value);
+ case kUint32Imm:
+ return is_uint32(value);
+ case kInt20Imm:
+ return is_int20(value);
case kNoImmediate:
return false;
}
return false;
}
+
+ AddressingMode GenerateMemoryOperandInputs(Node* index, Node* base,
+ Node* displacement,
+ DisplacementMode displacement_mode,
+ InstructionOperand inputs[],
+ size_t* input_count) {
+ AddressingMode mode = kMode_MRI;
+ if (base != nullptr) {
+ inputs[(*input_count)++] = UseRegister(base);
+ if (index != nullptr) {
+ inputs[(*input_count)++] = UseRegister(index);
+ if (displacement != nullptr) {
+ inputs[(*input_count)++] = displacement_mode
+ ? UseNegatedImmediate(displacement)
+ : UseImmediate(displacement);
+ mode = kMode_MRRI;
+ } else {
+ mode = kMode_MRR;
+ }
+ } else {
+ if (displacement == nullptr) {
+ mode = kMode_MR;
+ } else {
+ inputs[(*input_count)++] = displacement_mode == kNegativeDisplacement
+ ? UseNegatedImmediate(displacement)
+ : UseImmediate(displacement);
+ mode = kMode_MRI;
+ }
+ }
+ } else {
+ DCHECK_NOT_NULL(index);
+ inputs[(*input_count)++] = UseRegister(index);
+ if (displacement != nullptr) {
+ inputs[(*input_count)++] = displacement_mode == kNegativeDisplacement
+ ? UseNegatedImmediate(displacement)
+ : UseImmediate(displacement);
+ mode = kMode_MRI;
+ } else {
+ mode = kMode_MR;
+ }
+ }
+ return mode;
+ }
+
+ AddressingMode GetEffectiveAddressMemoryOperand(Node* operand,
+ InstructionOperand inputs[],
+ size_t* input_count) {
+#if V8_TARGET_ARCH_S390X
+ BaseWithIndexAndDisplacement64Matcher m(operand,
+ AddressOption::kAllowInputSwap);
+#else
+ BaseWithIndexAndDisplacement32Matcher m(operand,
+ AddressOption::kAllowInputSwap);
+#endif
+ DCHECK(m.matches());
+ if ((m.displacement() == nullptr ||
+ CanBeImmediate(m.displacement(), kInt20Imm))) {
+ DCHECK(m.scale() == 0);
+ return GenerateMemoryOperandInputs(m.index(), m.base(), m.displacement(),
+ m.displacement_mode(), inputs,
+ input_count);
+ } else {
+ inputs[(*input_count)++] = UseRegister(operand->InputAt(0));
+ inputs[(*input_count)++] = UseRegister(operand->InputAt(1));
+ return kMode_MRR;
+ }
+ }
};
namespace {
@@ -167,10 +234,7 @@ void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode,
void InstructionSelector::VisitLoad(Node* node) {
LoadRepresentation load_rep = LoadRepresentationOf(node->op());
S390OperandGenerator g(this);
- Node* base = node->InputAt(0);
- Node* offset = node->InputAt(1);
ArchOpcode opcode = kArchNop;
- ImmediateMode mode = kInt16Imm;
switch (load_rep.representation()) {
case MachineRepresentation::kFloat32:
opcode = kS390_LoadFloat32;
@@ -195,7 +259,6 @@ void InstructionSelector::VisitLoad(Node* node) {
case MachineRepresentation::kTagged: // Fall through.
case MachineRepresentation::kWord64:
opcode = kS390_LoadWord64;
- mode = kInt16Imm_4ByteAligned;
break;
#else
case MachineRepresentation::kWord64: // Fall through.
@@ -205,16 +268,14 @@ void InstructionSelector::VisitLoad(Node* node) {
UNREACHABLE();
return;
}
- if (g.CanBeImmediate(offset, mode)) {
- Emit(opcode | AddressingModeField::encode(kMode_MRI),
- g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(offset));
- } else if (g.CanBeImmediate(base, mode)) {
- Emit(opcode | AddressingModeField::encode(kMode_MRI),
- g.DefineAsRegister(node), g.UseRegister(offset), g.UseImmediate(base));
- } else {
- Emit(opcode | AddressingModeField::encode(kMode_MRR),
- g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset));
- }
+ InstructionOperand outputs[1];
+ outputs[0] = g.DefineAsRegister(node);
+ InstructionOperand inputs[3];
+ size_t input_count = 0;
+ AddressingMode mode =
+ g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
+ InstructionCode code = opcode | AddressingModeField::encode(mode);
+ Emit(code, 1, outputs, input_count, inputs);
}
void InstructionSelector::VisitStore(Node* node) {
@@ -235,11 +296,7 @@ void InstructionSelector::VisitStore(Node* node) {
inputs[input_count++] = g.UseUniqueRegister(base);
// OutOfLineRecordWrite uses the offset in an 'AddP' instruction as well as
// for the store itself, so we must check compatibility with both.
- if (g.CanBeImmediate(offset, kInt16Imm)
-#if V8_TARGET_ARCH_S390X
- && g.CanBeImmediate(offset, kInt16Imm_4ByteAligned)
-#endif
- ) {
+ if (g.CanBeImmediate(offset, kInt20Imm)) {
inputs[input_count++] = g.UseImmediate(offset);
addressing_mode = kMode_MRI;
} else {
@@ -270,7 +327,6 @@ void InstructionSelector::VisitStore(Node* node) {
Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
} else {
ArchOpcode opcode = kArchNop;
- ImmediateMode mode = kInt16Imm;
NodeMatcher m(value);
switch (rep) {
case MachineRepresentation::kFloat32:
@@ -300,7 +356,6 @@ void InstructionSelector::VisitStore(Node* node) {
case MachineRepresentation::kTagged: // Fall through.
case MachineRepresentation::kWord64:
opcode = kS390_StoreWord64;
- mode = kInt16Imm_4ByteAligned;
if (m.IsWord64ReverseBytes()) {
opcode = kS390_StoreReverse64;
value = value->InputAt(0);
@@ -314,16 +369,16 @@ void InstructionSelector::VisitStore(Node* node) {
UNREACHABLE();
return;
}
- if (g.CanBeImmediate(offset, mode)) {
- Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
- g.UseRegister(base), g.UseImmediate(offset), g.UseRegister(value));
- } else if (g.CanBeImmediate(base, mode)) {
- Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
- g.UseRegister(offset), g.UseImmediate(base), g.UseRegister(value));
- } else {
- Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(),
- g.UseRegister(base), g.UseRegister(offset), g.UseRegister(value));
- }
+ InstructionOperand inputs[4];
+ size_t input_count = 0;
+ AddressingMode addressing_mode =
+ g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
+ InstructionCode code =
+ opcode | AddressingModeField::encode(addressing_mode);
+ InstructionOperand value_operand = g.UseRegister(value);
+ inputs[input_count++] = value_operand;
+ Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count,
+ inputs);
}
}
@@ -374,7 +429,7 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
AddressingMode addressingMode = kMode_MRR;
Emit(opcode | AddressingModeField::encode(addressingMode),
g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(offset),
- g.UseOperand(length, kInt16Imm_Unsigned));
+ g.UseOperand(length, kUint32Imm));
}
void InstructionSelector::VisitCheckedStore(Node* node) {
@@ -419,7 +474,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
AddressingMode addressingMode = kMode_MRR;
Emit(opcode | AddressingModeField::encode(addressingMode), g.NoOutput(),
g.UseRegister(base), g.UseRegister(offset),
- g.UseOperand(length, kInt16Imm_Unsigned), g.UseRegister(value));
+ g.UseOperand(length, kUint32Imm), g.UseRegister(value));
}
static inline bool IsContiguousMask32(uint32_t value, int* mb, int* me) {
@@ -477,7 +532,7 @@ void InstructionSelector::VisitWord32And(Node* node) {
return;
}
}
- VisitBinop<Int32BinopMatcher>(this, node, kS390_And32, kInt16Imm_Unsigned);
+ VisitBinop<Int32BinopMatcher>(this, node, kS390_And32, kUint32Imm);
}
#if V8_TARGET_ARCH_S390X
@@ -529,19 +584,19 @@ void InstructionSelector::VisitWord64And(Node* node) {
}
}
}
- VisitBinop<Int64BinopMatcher>(this, node, kS390_And64, kInt16Imm_Unsigned);
+ VisitBinop<Int64BinopMatcher>(this, node, kS390_And64, kUint32Imm);
}
#endif
void InstructionSelector::VisitWord32Or(Node* node) {
Int32BinopMatcher m(node);
- VisitBinop<Int32BinopMatcher>(this, node, kS390_Or32, kInt16Imm_Unsigned);
+ VisitBinop<Int32BinopMatcher>(this, node, kS390_Or32, kUint32Imm);
}
#if V8_TARGET_ARCH_S390X
void InstructionSelector::VisitWord64Or(Node* node) {
Int64BinopMatcher m(node);
- VisitBinop<Int64BinopMatcher>(this, node, kS390_Or64, kInt16Imm_Unsigned);
+ VisitBinop<Int64BinopMatcher>(this, node, kS390_Or64, kUint32Imm);
}
#endif
@@ -551,7 +606,7 @@ void InstructionSelector::VisitWord32Xor(Node* node) {
if (m.right().Is(-1)) {
Emit(kS390_Not32, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
} else {
- VisitBinop<Int32BinopMatcher>(this, node, kS390_Xor32, kInt16Imm_Unsigned);
+ VisitBinop<Int32BinopMatcher>(this, node, kS390_Xor32, kUint32Imm);
}
}
@@ -562,7 +617,7 @@ void InstructionSelector::VisitWord64Xor(Node* node) {
if (m.right().Is(-1)) {
Emit(kS390_Not64, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
} else {
- VisitBinop<Int64BinopMatcher>(this, node, kS390_Xor64, kInt16Imm_Unsigned);
+ VisitBinop<Int64BinopMatcher>(this, node, kS390_Xor64, kUint32Imm);
}
}
#endif
@@ -874,12 +929,12 @@ void InstructionSelector::VisitWord32ReverseBytes(Node* node) {
}
void InstructionSelector::VisitInt32Add(Node* node) {
- VisitBinop<Int32BinopMatcher>(this, node, kS390_Add32, kInt16Imm);
+ VisitBinop<Int32BinopMatcher>(this, node, kS390_Add32, kInt32Imm);
}
#if V8_TARGET_ARCH_S390X
void InstructionSelector::VisitInt64Add(Node* node) {
- VisitBinop<Int64BinopMatcher>(this, node, kS390_Add64, kInt16Imm);
+ VisitBinop<Int64BinopMatcher>(this, node, kS390_Add64, kInt32Imm);
}
#endif
@@ -890,7 +945,7 @@ void InstructionSelector::VisitInt32Sub(Node* node) {
Emit(kS390_Neg32, g.DefineAsRegister(node),
g.UseRegister(m.right().node()));
} else {
- VisitBinop<Int32BinopMatcher>(this, node, kS390_Sub32, kInt16Imm_Negate);
+ VisitBinop<Int32BinopMatcher>(this, node, kS390_Sub32, kInt32Imm_Negate);
}
}
@@ -902,7 +957,7 @@ void InstructionSelector::VisitInt64Sub(Node* node) {
Emit(kS390_Neg64, g.DefineAsRegister(node),
g.UseRegister(m.right().node()));
} else {
- VisitBinop<Int64BinopMatcher>(this, node, kS390_Sub64, kInt16Imm_Negate);
+ VisitBinop<Int64BinopMatcher>(this, node, kS390_Sub64, kInt32Imm_Negate);
}
}
#endif
@@ -1254,21 +1309,21 @@ void InstructionSelector::VisitFloat64Neg(Node* node) {
void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
- return VisitBinop<Int32BinopMatcher>(this, node, kS390_Add32, kInt16Imm,
+ return VisitBinop<Int32BinopMatcher>(this, node, kS390_Add32, kInt32Imm,
&cont);
}
FlagsContinuation cont;
- VisitBinop<Int32BinopMatcher>(this, node, kS390_Add32, kInt16Imm, &cont);
+ VisitBinop<Int32BinopMatcher>(this, node, kS390_Add32, kInt32Imm, &cont);
}
void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int32BinopMatcher>(this, node, kS390_Sub32,
- kInt16Imm_Negate, &cont);
+ kInt32Imm_Negate, &cont);
}
FlagsContinuation cont;
- VisitBinop<Int32BinopMatcher>(this, node, kS390_Sub32, kInt16Imm_Negate,
+ VisitBinop<Int32BinopMatcher>(this, node, kS390_Sub32, kInt32Imm_Negate,
&cont);
}
@@ -1276,21 +1331,21 @@ void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
- return VisitBinop<Int64BinopMatcher>(this, node, kS390_Add64, kInt16Imm,
+ return VisitBinop<Int64BinopMatcher>(this, node, kS390_Add64, kInt32Imm,
&cont);
}
FlagsContinuation cont;
- VisitBinop<Int64BinopMatcher>(this, node, kS390_Add64, kInt16Imm, &cont);
+ VisitBinop<Int64BinopMatcher>(this, node, kS390_Add64, kInt32Imm, &cont);
}
void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
return VisitBinop<Int64BinopMatcher>(this, node, kS390_Sub64,
- kInt16Imm_Negate, &cont);
+ kInt32Imm_Negate, &cont);
}
FlagsContinuation cont;
- VisitBinop<Int64BinopMatcher>(this, node, kS390_Sub64, kInt16Imm_Negate,
+ VisitBinop<Int64BinopMatcher>(this, node, kS390_Sub64, kInt32Imm_Negate,
&cont);
}
#endif
@@ -1353,14 +1408,14 @@ void VisitWordCompare(InstructionSelector* selector, Node* node,
void VisitWord32Compare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
- ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm);
+ ImmediateMode mode = (CompareLogical(cont) ? kUint32Imm : kInt32Imm);
VisitWordCompare(selector, node, kS390_Cmp32, cont, false, mode);
}
#if V8_TARGET_ARCH_S390X
void VisitWord64Compare(InstructionSelector* selector, Node* node,
FlagsContinuation* cont) {
- ImmediateMode mode = (CompareLogical(cont) ? kInt16Imm_Unsigned : kInt16Imm);
+ ImmediateMode mode = (CompareLogical(cont) ? kUint32Imm : kUint32Imm);
VisitWordCompare(selector, node, kS390_Cmp64, cont, false, mode);
}
#endif
@@ -1467,11 +1522,11 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
case IrOpcode::kInt32AddWithOverflow:
cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitBinop<Int32BinopMatcher>(
- selector, node, kS390_Add32, kInt16Imm, cont);
+ selector, node, kS390_Add32, kInt32Imm, cont);
case IrOpcode::kInt32SubWithOverflow:
cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitBinop<Int32BinopMatcher>(
- selector, node, kS390_Sub32, kInt16Imm_Negate, cont);
+ selector, node, kS390_Sub32, kInt32Imm_Negate, cont);
case IrOpcode::kInt32MulWithOverflow:
cont->OverwriteAndNegateIfEqual(kNotEqual);
return EmitInt32MulWithOverflow(selector, node, cont);
@@ -1479,11 +1534,11 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
case IrOpcode::kInt64AddWithOverflow:
cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitBinop<Int64BinopMatcher>(
- selector, node, kS390_Add64, kInt16Imm, cont);
+ selector, node, kS390_Add64, kInt32Imm, cont);
case IrOpcode::kInt64SubWithOverflow:
cont->OverwriteAndNegateIfEqual(kOverflow);
return VisitBinop<Int64BinopMatcher>(
- selector, node, kS390_Sub64, kInt16Imm_Negate, cont);
+ selector, node, kS390_Sub64, kInt32Imm_Negate, cont);
#endif
default:
break;
@@ -1495,7 +1550,7 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
return VisitWord32Compare(selector, value, cont);
case IrOpcode::kWord32And:
return VisitWordCompare(selector, value, kS390_Tst32, cont, true,
- kInt16Imm_Unsigned);
+ kUint32Imm);
// TODO(mbrandy): Handle?
// case IrOpcode::kInt32Add:
// case IrOpcode::kWord32Or:
@@ -1509,7 +1564,7 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user,
return VisitWord64Compare(selector, value, cont);
case IrOpcode::kWord64And:
return VisitWordCompare(selector, value, kS390_Tst64, cont, true,
- kInt16Imm_Unsigned);
+ kUint32Imm);
// TODO(mbrandy): Handle?
// case IrOpcode::kInt64Add:
// case IrOpcode::kWord64Or:
« no previous file with comments | « src/compiler/s390/instruction-codes-s390.h ('k') | src/s390/assembler-s390.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698