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

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

Issue 613643002: [turbofan] add new ia32 addressing modes (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 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/ia32/instruction-codes-ia32.h ('k') | src/compiler/ia32/instruction-selector-ia32-unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/ia32/instruction-selector-ia32.cc
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc
index d72f0dc1e36c4cbeed63b421108e354d4a6c903a..70bee35a2f4d3a7e4d3d34176403b500128fc644 100644
--- a/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/src/compiler/ia32/instruction-selector-ia32.cc
@@ -44,10 +44,108 @@ class IA32OperandGenerator FINAL : public OperandGenerator {
};
+class AddressingModeMatcher {
+ public:
+ AddressingModeMatcher(IA32OperandGenerator* g, Node* base, Node* index)
+ : base_operand_(NULL),
+ index_operand_(NULL),
+ displacement_operand_(NULL),
+ mode_(kMode_None) {
+ Int32Matcher index_imm(index);
+ if (index_imm.HasValue()) {
+ int32_t displacement = index_imm.Value();
+ // Compute base operand and fold base immediate into displacement.
+ Int32Matcher base_imm(base);
+ if (!base_imm.HasValue()) {
+ base_operand_ = g->UseRegister(base);
+ } else {
+ displacement += base_imm.Value();
+ }
+ if (displacement != 0 || base_operand_ == NULL) {
+ displacement_operand_ = g->TempImmediate(displacement);
+ }
+ if (base_operand_ == NULL) {
+ mode_ = kMode_MI;
+ } else {
+ if (displacement == 0) {
+ mode_ = kMode_MR;
+ } else {
+ mode_ = kMode_MRI;
+ }
+ }
+ } else {
+ // Compute index and displacement.
+ IndexAndDisplacementMatcher matcher(index);
+ index_operand_ = g->UseRegister(matcher.index_node());
+ int32_t displacement = matcher.displacement();
+ // Compute base operand and fold base immediate into displacement.
+ Int32Matcher base_imm(base);
+ if (!base_imm.HasValue()) {
+ base_operand_ = g->UseRegister(base);
+ } else {
+ displacement += base_imm.Value();
+ }
+ // Compute displacement operand.
+ if (displacement != 0) {
+ displacement_operand_ = g->TempImmediate(displacement);
+ }
+ // Compute mode with scale factor one.
+ if (base_operand_ == NULL) {
+ if (displacement_operand_ == NULL) {
+ mode_ = kMode_M1;
+ } else {
+ mode_ = kMode_M1I;
+ }
+ } else {
+ if (displacement_operand_ == NULL) {
+ mode_ = kMode_MR1;
+ } else {
+ mode_ = kMode_MR1I;
+ }
+ }
+ // Adjust mode to actual scale factor.
+ mode_ = GetMode(mode_, matcher.power());
+ // Don't emit instructions with scale factor 1 if there's no base.
+ if (mode_ == kMode_M1) {
+ mode_ = kMode_MR;
+ } else if (mode_ == kMode_M1I) {
+ mode_ = kMode_MRI;
+ }
+ }
+ DCHECK_NE(kMode_None, mode_);
+ }
+
+ AddressingMode GetMode(AddressingMode one, int power) {
+ return static_cast<AddressingMode>(static_cast<int>(one) + power);
+ }
+
+ size_t SetInputs(InstructionOperand** inputs) {
+ size_t input_count = 0;
+ // Compute inputs_ and input_count.
+ if (base_operand_ != NULL) {
+ inputs[input_count++] = base_operand_;
+ }
+ if (index_operand_ != NULL) {
+ inputs[input_count++] = index_operand_;
+ }
+ if (displacement_operand_ != NULL) {
+ inputs[input_count++] = displacement_operand_;
+ }
+ DCHECK_NE(input_count, 0);
+ return input_count;
+ }
+
+ static const int kMaxInputCount = 3;
+ InstructionOperand* base_operand_;
+ InstructionOperand* index_operand_;
+ InstructionOperand* displacement_operand_;
+ AddressingMode mode_;
+};
+
+
void InstructionSelector::VisitLoad(Node* node) {
MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
- IA32OperandGenerator g(this);
Node* base = node->InputAt(0);
Node* index = node->InputAt(1);
@@ -75,23 +173,14 @@ void InstructionSelector::VisitLoad(Node* node) {
UNREACHABLE();
return;
}
- if (g.CanBeImmediate(base)) {
- if (Int32Matcher(index).Is(0)) { // load [#base + #0]
- Emit(opcode | AddressingModeField::encode(kMode_MI),
- g.DefineAsRegister(node), g.UseImmediate(base));
- } else { // load [#base + %index]
- Emit(opcode | AddressingModeField::encode(kMode_MRI),
- g.DefineAsRegister(node), g.UseRegister(index),
- g.UseImmediate(base));
- }
- } else if (g.CanBeImmediate(index)) { // load [%base + #index]
- Emit(opcode | AddressingModeField::encode(kMode_MRI),
- g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
- } else { // load [%base + %index + K]
- Emit(opcode | AddressingModeField::encode(kMode_MR1I),
- g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index));
- }
- // TODO(turbofan): addressing modes [r+r*{2,4,8}+K]
+
+ IA32OperandGenerator g(this);
+ AddressingModeMatcher matcher(&g, base, index);
+ InstructionCode code = opcode | AddressingModeField::encode(matcher.mode_);
+ InstructionOperand* outputs[] = {g.DefineAsRegister(node)};
+ InstructionOperand* inputs[AddressingModeMatcher::kMaxInputCount];
+ size_t input_count = matcher.SetInputs(inputs);
+ Emit(code, 1, outputs, input_count, inputs);
}
@@ -115,14 +204,7 @@ void InstructionSelector::VisitStore(Node* node) {
return;
}
DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
- InstructionOperand* val;
- if (g.CanBeImmediate(value)) {
- val = g.UseImmediate(value);
- } else if (rep == kRepWord8 || rep == kRepBit) {
- val = g.UseByteRegister(value);
- } else {
- val = g.UseRegister(value);
- }
+
ArchOpcode opcode;
switch (rep) {
case kRepFloat32:
@@ -146,22 +228,22 @@ void InstructionSelector::VisitStore(Node* node) {
UNREACHABLE();
return;
}
- if (g.CanBeImmediate(base)) {
- if (Int32Matcher(index).Is(0)) { // store [#base], %|#value
- Emit(opcode | AddressingModeField::encode(kMode_MI), NULL,
- g.UseImmediate(base), val);
- } else { // store [#base + %index], %|#value
- Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
- g.UseRegister(index), g.UseImmediate(base), val);
- }
- } else if (g.CanBeImmediate(index)) { // store [%base + #index], %|#value
- Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
- g.UseRegister(base), g.UseImmediate(index), val);
- } else { // store [%base + %index], %|#value
- Emit(opcode | AddressingModeField::encode(kMode_MR1I), NULL,
- g.UseRegister(base), g.UseRegister(index), val);
+
+ InstructionOperand* val;
+ if (g.CanBeImmediate(value)) {
+ val = g.UseImmediate(value);
+ } else if (rep == kRepWord8 || rep == kRepBit) {
+ val = g.UseByteRegister(value);
+ } else {
+ val = g.UseRegister(value);
}
- // TODO(turbofan): addressing modes [r+r*{2,4,8}+K]
+
+ AddressingModeMatcher matcher(&g, base, index);
+ InstructionCode code = opcode | AddressingModeField::encode(matcher.mode_);
+ InstructionOperand* inputs[AddressingModeMatcher::kMaxInputCount + 1];
+ size_t input_count = matcher.SetInputs(inputs);
+ inputs[input_count++] = val;
+ Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs);
}
« no previous file with comments | « src/compiler/ia32/instruction-codes-ia32.h ('k') | src/compiler/ia32/instruction-selector-ia32-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698