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

Side by Side Diff: src/compiler/x64/instruction-selector-x64.cc

Issue 747283005: [turbofan]: Port lea changes to ia32 (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: For Dan Created 6 years 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/instruction-selector-impl.h" 5 #include "src/compiler/instruction-selector-impl.h"
6 #include "src/compiler/node-matchers.h" 6 #include "src/compiler/node-matchers.h"
7 7
8 namespace v8 { 8 namespace v8 {
9 namespace internal { 9 namespace internal {
10 namespace compiler { 10 namespace compiler {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 inputs[(*input_count)++] = UseImmediate(displacement); 60 inputs[(*input_count)++] = UseImmediate(displacement);
61 mode = kMode_MRI; 61 mode = kMode_MRI;
62 } 62 }
63 } 63 }
64 } else { 64 } else {
65 DCHECK(index != NULL); 65 DCHECK(index != NULL);
66 DCHECK(scale_exponent >= 0 && scale_exponent <= 3); 66 DCHECK(scale_exponent >= 0 && scale_exponent <= 3);
67 inputs[(*input_count)++] = UseRegister(index); 67 inputs[(*input_count)++] = UseRegister(index);
68 if (displacement != NULL) { 68 if (displacement != NULL) {
69 inputs[(*input_count)++] = UseImmediate(displacement); 69 inputs[(*input_count)++] = UseImmediate(displacement);
70 static const AddressingMode kMnI_modes[] = {kMode_M1I, kMode_M2I, 70 static const AddressingMode kMnI_modes[] = {kMode_MRI, kMode_M2I,
71 kMode_M4I, kMode_M8I}; 71 kMode_M4I, kMode_M8I};
72 mode = kMnI_modes[scale_exponent]; 72 mode = kMnI_modes[scale_exponent];
73 } else { 73 } else {
74 static const AddressingMode kMn_modes[] = {kMode_M1, kMode_MR1, 74 static const AddressingMode kMn_modes[] = {kMode_MR, kMode_MR1,
75 kMode_M4, kMode_M8}; 75 kMode_M4, kMode_M8};
76 mode = kMn_modes[scale_exponent]; 76 mode = kMn_modes[scale_exponent];
77 if (mode == kMode_MR1) { 77 if (mode == kMode_MR1) {
78 // [%r1 + %r1*1] has a smaller encoding than [%r1*2+0] 78 // [%r1 + %r1*1] has a smaller encoding than [%r1*2+0]
79 inputs[(*input_count)++] = UseRegister(index); 79 inputs[(*input_count)++] = UseRegister(index);
80 } 80 }
81 } 81 }
82 } 82 }
83 return mode; 83 return mode;
84 } 84 }
85 85
86 AddressingMode GetEffectiveAddressMemoryOperand(Node* operand,
87 InstructionOperand* inputs[],
88 size_t* input_count) {
89 BaseWithIndexAndDisplacement64Matcher m(operand, true);
90 DCHECK(m.matches());
91 if ((m.displacement() == NULL || CanBeImmediate(m.displacement()))) {
92 return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(),
93 m.displacement(), inputs, input_count);
94 } else {
95 inputs[(*input_count)++] = UseRegister(operand->InputAt(0));
96 inputs[(*input_count)++] = UseRegister(operand->InputAt(1));
97 return kMode_MR1;
98 }
99 }
100
86 bool CanBeBetterLeftOperand(Node* node) const { 101 bool CanBeBetterLeftOperand(Node* node) const {
87 return !selector()->IsLive(node); 102 return !selector()->IsLive(node);
88 } 103 }
89 }; 104 };
90 105
91 106
92 void InstructionSelector::VisitLoad(Node* node) { 107 void InstructionSelector::VisitLoad(Node* node) {
93 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); 108 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
94 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); 109 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
95 X64OperandGenerator g(this); 110 X64OperandGenerator g(this);
96 Node* const base = node->InputAt(0);
97 Node* const index = node->InputAt(1);
98 111
99 ArchOpcode opcode; 112 ArchOpcode opcode;
100 switch (rep) { 113 switch (rep) {
101 case kRepFloat32: 114 case kRepFloat32:
102 opcode = kX64Movss; 115 opcode = kX64Movss;
103 break; 116 break;
104 case kRepFloat64: 117 case kRepFloat64:
105 opcode = kX64Movsd; 118 opcode = kX64Movsd;
106 break; 119 break;
107 case kRepBit: // Fall through. 120 case kRepBit: // Fall through.
108 case kRepWord8: 121 case kRepWord8:
109 opcode = typ == kTypeInt32 ? kX64Movsxbl : kX64Movzxbl; 122 opcode = typ == kTypeInt32 ? kX64Movsxbl : kX64Movzxbl;
110 break; 123 break;
111 case kRepWord16: 124 case kRepWord16:
112 opcode = typ == kTypeInt32 ? kX64Movsxwl : kX64Movzxwl; 125 opcode = typ == kTypeInt32 ? kX64Movsxwl : kX64Movzxwl;
113 break; 126 break;
114 case kRepWord32: 127 case kRepWord32:
115 opcode = kX64Movl; 128 opcode = kX64Movl;
116 break; 129 break;
117 case kRepTagged: // Fall through. 130 case kRepTagged: // Fall through.
118 case kRepWord64: 131 case kRepWord64:
119 opcode = kX64Movq; 132 opcode = kX64Movq;
120 break; 133 break;
121 default: 134 default:
122 UNREACHABLE(); 135 UNREACHABLE();
123 return; 136 return;
124 } 137 }
125 if (g.CanBeImmediate(index)) { 138
126 // load [%base + #index] 139 InstructionOperand* outputs[1];
127 Emit(opcode | AddressingModeField::encode(kMode_MRI), 140 outputs[0] = g.DefineAsRegister(node);
128 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); 141 InstructionOperand* inputs[3];
129 } else if (g.CanBeImmediate(base)) { 142 size_t input_count = 0;
130 // load [#base + %index] 143 AddressingMode mode =
131 Emit(opcode | AddressingModeField::encode(kMode_MRI), 144 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
132 g.DefineAsRegister(node), g.UseRegister(index), g.UseImmediate(base)); 145 InstructionCode code = opcode | AddressingModeField::encode(mode);
133 } else { 146 Emit(code, 1, outputs, input_count, inputs);
134 // load [%base + %index*1]
135 Emit(opcode | AddressingModeField::encode(kMode_MR1),
136 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index));
137 }
138 } 147 }
139 148
140 149
141 void InstructionSelector::VisitStore(Node* node) { 150 void InstructionSelector::VisitStore(Node* node) {
142 X64OperandGenerator g(this); 151 X64OperandGenerator g(this);
143 Node* base = node->InputAt(0); 152 Node* base = node->InputAt(0);
144 Node* index = node->InputAt(1); 153 Node* index = node->InputAt(1);
145 Node* value = node->InputAt(2); 154 Node* value = node->InputAt(2);
146 155
147 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); 156 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
(...skipping 29 matching lines...) Expand all
177 opcode = kX64Movl; 186 opcode = kX64Movl;
178 break; 187 break;
179 case kRepTagged: // Fall through. 188 case kRepTagged: // Fall through.
180 case kRepWord64: 189 case kRepWord64:
181 opcode = kX64Movq; 190 opcode = kX64Movq;
182 break; 191 break;
183 default: 192 default:
184 UNREACHABLE(); 193 UNREACHABLE();
185 return; 194 return;
186 } 195 }
196 InstructionOperand* inputs[4];
197 size_t input_count = 0;
198 AddressingMode mode =
199 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
200 InstructionCode code = opcode | AddressingModeField::encode(mode);
187 InstructionOperand* value_operand = 201 InstructionOperand* value_operand =
188 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); 202 g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
189 if (g.CanBeImmediate(index)) { 203 inputs[input_count++] = value_operand;
190 // store [%base + #index], %|#value 204 Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs);
191 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr,
192 g.UseRegister(base), g.UseImmediate(index), value_operand);
193 } else if (g.CanBeImmediate(base)) {
194 // store [#base + %index], %|#value
195 Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr,
196 g.UseRegister(index), g.UseImmediate(base), value_operand);
197 } else {
198 // store [%base + %index*1], %|#value
199 Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr,
200 g.UseRegister(base), g.UseRegister(index), value_operand);
201 }
202 } 205 }
203 206
204 207
205 void InstructionSelector::VisitCheckedLoad(Node* node) { 208 void InstructionSelector::VisitCheckedLoad(Node* node) {
206 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); 209 MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
207 MachineType typ = TypeOf(OpParameter<MachineType>(node)); 210 MachineType typ = TypeOf(OpParameter<MachineType>(node));
208 X64OperandGenerator g(this); 211 X64OperandGenerator g(this);
209 Node* const buffer = node->InputAt(0); 212 Node* const buffer = node->InputAt(0);
210 Node* const offset = node->InputAt(1); 213 Node* const offset = node->InputAt(1);
211 Node* const length = node->InputAt(2); 214 Node* const length = node->InputAt(2);
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 MachineOperatorBuilder::kFloat64Ceil | 1317 MachineOperatorBuilder::kFloat64Ceil |
1315 MachineOperatorBuilder::kFloat64RoundTruncate | 1318 MachineOperatorBuilder::kFloat64RoundTruncate |
1316 MachineOperatorBuilder::kWord32ShiftIsSafe; 1319 MachineOperatorBuilder::kWord32ShiftIsSafe;
1317 } 1320 }
1318 return MachineOperatorBuilder::kNoFlags; 1321 return MachineOperatorBuilder::kNoFlags;
1319 } 1322 }
1320 1323
1321 } // namespace compiler 1324 } // namespace compiler
1322 } // namespace internal 1325 } // namespace internal
1323 } // namespace v8 1326 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/node-matchers.h ('k') | test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698