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

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

Issue 1972103002: [turbofan] ARM64: Support shifted indexes in loads and stores (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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
Index: src/compiler/arm64/instruction-selector-arm64.cc
diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc
index 6106c514f14468f0a86c57a7abebbcc321578ea2..fc57dcdf1473d0959de80ec733b8ef5cf56872ba 100644
--- a/src/compiler/arm64/instruction-selector-arm64.cc
+++ b/src/compiler/arm64/instruction-selector-arm64.cc
@@ -121,6 +121,13 @@ class Arm64OperandGenerator final : public OperandGenerator {
return false;
}
+ bool CanBeLoadStoreShiftImmediate(Node* node, MachineRepresentation rep) {
+ // TODO(arm64): Load and Store on 128 bit Q registers is not supported yet.
+ DCHECK_NE(MachineRepresentation::kSimd128, rep);
+ return IsIntegerConstant(node) &&
+ (GetIntegerConstantValue(node) == ElementSizeLog2Of(rep));
+ }
+
private:
bool IsLoadStoreImmediate(int64_t value, LSDataSize size) {
return Assembler::IsImmLSScaled(value, size) ||
@@ -226,6 +233,28 @@ bool TryMatchAnyExtend(Arm64OperandGenerator* g, InstructionSelector* selector,
return false;
}
+bool TryMatchLoadStoreShift(Arm64OperandGenerator* g,
+ InstructionSelector* selector,
+ MachineRepresentation rep, Node* node, Node* index,
+ InstructionOperand* index_op,
+ InstructionOperand* shift_immediate_op) {
+ if (!selector->CanCover(node, index)) return false;
+ if (index->InputCount() != 2) return false;
+ Node* left = index->InputAt(0);
+ Node* right = index->InputAt(1);
+ switch (index->opcode()) {
+ case IrOpcode::kWord32Shl:
+ case IrOpcode::kWord64Shl:
+ if (!g->CanBeLoadStoreShiftImmediate(right, rep)) {
+ return false;
+ }
+ *index_op = g->UseRegister(left);
+ *shift_immediate_op = g->UseImmediate(right);
+ return true;
+ default:
+ return false;
+ }
+}
// Shared routine for multiple binary operations.
template <typename Matcher>
@@ -359,12 +388,16 @@ int32_t LeftShiftForReducedMultiply(Matcher* m) {
void InstructionSelector::VisitLoad(Node* node) {
LoadRepresentation load_rep = LoadRepresentationOf(node->op());
+ MachineRepresentation rep = load_rep.representation();
Arm64OperandGenerator g(this);
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
- ArchOpcode opcode = kArchNop;
+ InstructionCode opcode = kArchNop;
ImmediateMode immediate_mode = kNoImmediate;
- switch (load_rep.representation()) {
+ InstructionOperand inputs[3];
+ size_t input_count = 0;
+ InstructionOperand outputs[1];
+ switch (rep) {
case MachineRepresentation::kFloat32:
opcode = kArm64LdrS;
immediate_mode = kLoadStoreImm32;
@@ -396,13 +429,25 @@ void InstructionSelector::VisitLoad(Node* node) {
UNREACHABLE();
return;
}
+
+ outputs[0] = g.DefineAsRegister(node);
+ inputs[0] = g.UseRegister(base);
+
if (g.CanBeImmediate(index, immediate_mode)) {
- Emit(opcode | AddressingModeField::encode(kMode_MRI),
- g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
+ input_count = 2;
+ inputs[1] = g.UseImmediate(index);
+ opcode |= AddressingModeField::encode(kMode_MRI);
+ } else if (TryMatchLoadStoreShift(&g, this, rep, node, index, &inputs[1],
+ &inputs[2])) {
+ input_count = 3;
+ opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
} else {
- Emit(opcode | AddressingModeField::encode(kMode_MRR),
- g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index));
+ input_count = 2;
+ inputs[1] = g.UseRegister(index);
+ opcode |= AddressingModeField::encode(kMode_MRR);
}
+
+ Emit(opcode, arraysize(outputs), outputs, input_count, inputs);
}
@@ -456,7 +501,9 @@ void InstructionSelector::VisitStore(Node* node) {
code |= MiscField::encode(static_cast<int>(record_write_mode));
Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
} else {
- ArchOpcode opcode = kArchNop;
+ InstructionOperand inputs[4];
+ size_t input_count = 0;
+ InstructionCode opcode = kArchNop;
ImmediateMode immediate_mode = kNoImmediate;
switch (rep) {
case MachineRepresentation::kFloat32:
@@ -490,15 +537,25 @@ void InstructionSelector::VisitStore(Node* node) {
UNREACHABLE();
return;
}
+
+ inputs[0] = g.UseRegisterOrImmediateZero(value);
+ inputs[1] = g.UseRegister(base);
+
if (g.CanBeImmediate(index, immediate_mode)) {
- Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
- g.UseRegister(base), g.UseImmediate(index),
- g.UseRegisterOrImmediateZero(value));
+ input_count = 3;
+ inputs[2] = g.UseImmediate(index);
+ opcode |= AddressingModeField::encode(kMode_MRI);
+ } else if (TryMatchLoadStoreShift(&g, this, rep, node, index, &inputs[2],
+ &inputs[3])) {
+ input_count = 4;
+ opcode |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
} else {
- Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(),
- g.UseRegister(base), g.UseRegister(index),
- g.UseRegisterOrImmediateZero(value));
+ input_count = 3;
+ inputs[2] = g.UseRegister(index);
+ opcode |= AddressingModeField::encode(kMode_MRR);
}
+
+ Emit(opcode, 0, nullptr, input_count, inputs);
}
}
« no previous file with comments | « src/compiler/arm64/code-generator-arm64.cc ('k') | test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698