OLD | NEW |
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/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/compiler/instruction-selector-impl.h" | 6 #include "src/compiler/instruction-selector-impl.h" |
7 #include "src/compiler/node-matchers.h" | 7 #include "src/compiler/node-matchers.h" |
8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 } | 123 } |
124 } | 124 } |
125 | 125 |
126 bool CanBeBetterLeftOperand(Node* node) const { | 126 bool CanBeBetterLeftOperand(Node* node) const { |
127 return !selector()->IsLive(node); | 127 return !selector()->IsLive(node); |
128 } | 128 } |
129 }; | 129 }; |
130 | 130 |
131 | 131 |
132 void InstructionSelector::VisitLoad(Node* node) { | 132 void InstructionSelector::VisitLoad(Node* node) { |
133 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 133 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
134 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
135 | 134 |
136 ArchOpcode opcode; | 135 ArchOpcode opcode; |
137 switch (rep) { | 136 switch (load_rep.representation()) { |
138 case kRepFloat32: | 137 case MachineRepresentation::kFloat32: |
139 opcode = kX87Movss; | 138 opcode = kX87Movss; |
140 break; | 139 break; |
141 case kRepFloat64: | 140 case MachineRepresentation::kFloat64: |
142 opcode = kX87Movsd; | 141 opcode = kX87Movsd; |
143 break; | 142 break; |
144 case kRepBit: // Fall through. | 143 case MachineRepresentation::kBit: // Fall through. |
145 case kRepWord8: | 144 case MachineRepresentation::kWord8: |
146 opcode = typ == kTypeInt32 ? kX87Movsxbl : kX87Movzxbl; | 145 opcode = load_rep.IsSigned() ? kX87Movsxbl : kX87Movzxbl; |
147 break; | 146 break; |
148 case kRepWord16: | 147 case MachineRepresentation::kWord16: |
149 opcode = typ == kTypeInt32 ? kX87Movsxwl : kX87Movzxwl; | 148 opcode = load_rep.IsSigned() ? kX87Movsxwl : kX87Movzxwl; |
150 break; | 149 break; |
151 case kRepTagged: // Fall through. | 150 case MachineRepresentation::kTagged: // Fall through. |
152 case kRepWord32: | 151 case MachineRepresentation::kWord32: |
153 opcode = kX87Movl; | 152 opcode = kX87Movl; |
154 break; | 153 break; |
155 default: | 154 default: |
156 UNREACHABLE(); | 155 UNREACHABLE(); |
157 return; | 156 return; |
158 } | 157 } |
159 | 158 |
160 X87OperandGenerator g(this); | 159 X87OperandGenerator g(this); |
161 InstructionOperand outputs[1]; | 160 InstructionOperand outputs[1]; |
162 outputs[0] = g.DefineAsRegister(node); | 161 outputs[0] = g.DefineAsRegister(node); |
163 InstructionOperand inputs[3]; | 162 InstructionOperand inputs[3]; |
164 size_t input_count = 0; | 163 size_t input_count = 0; |
165 AddressingMode mode = | 164 AddressingMode mode = |
166 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 165 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
167 InstructionCode code = opcode | AddressingModeField::encode(mode); | 166 InstructionCode code = opcode | AddressingModeField::encode(mode); |
168 Emit(code, 1, outputs, input_count, inputs); | 167 Emit(code, 1, outputs, input_count, inputs); |
169 } | 168 } |
170 | 169 |
171 | 170 |
172 void InstructionSelector::VisitStore(Node* node) { | 171 void InstructionSelector::VisitStore(Node* node) { |
173 X87OperandGenerator g(this); | 172 X87OperandGenerator g(this); |
174 Node* base = node->InputAt(0); | 173 Node* base = node->InputAt(0); |
175 Node* index = node->InputAt(1); | 174 Node* index = node->InputAt(1); |
176 Node* value = node->InputAt(2); | 175 Node* value = node->InputAt(2); |
177 | 176 |
178 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 177 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
179 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 178 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
180 MachineType rep = RepresentationOf(store_rep.machine_type()); | 179 MachineRepresentation rep = store_rep.machine_type().representation(); |
181 | 180 |
182 if (write_barrier_kind != kNoWriteBarrier) { | 181 if (write_barrier_kind != kNoWriteBarrier) { |
183 DCHECK_EQ(kRepTagged, rep); | 182 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
184 AddressingMode addressing_mode; | 183 AddressingMode addressing_mode; |
185 InstructionOperand inputs[3]; | 184 InstructionOperand inputs[3]; |
186 size_t input_count = 0; | 185 size_t input_count = 0; |
187 inputs[input_count++] = g.UseUniqueRegister(base); | 186 inputs[input_count++] = g.UseUniqueRegister(base); |
188 if (g.CanBeImmediate(index)) { | 187 if (g.CanBeImmediate(index)) { |
189 inputs[input_count++] = g.UseImmediate(index); | 188 inputs[input_count++] = g.UseImmediate(index); |
190 addressing_mode = kMode_MRI; | 189 addressing_mode = kMode_MRI; |
191 } else { | 190 } else { |
192 inputs[input_count++] = g.UseUniqueRegister(index); | 191 inputs[input_count++] = g.UseUniqueRegister(index); |
193 addressing_mode = kMode_MR1; | 192 addressing_mode = kMode_MR1; |
(...skipping 18 matching lines...) Expand all Loading... |
212 } | 211 } |
213 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 212 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
214 size_t const temp_count = arraysize(temps); | 213 size_t const temp_count = arraysize(temps); |
215 InstructionCode code = kArchStoreWithWriteBarrier; | 214 InstructionCode code = kArchStoreWithWriteBarrier; |
216 code |= AddressingModeField::encode(addressing_mode); | 215 code |= AddressingModeField::encode(addressing_mode); |
217 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 216 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
218 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 217 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
219 } else { | 218 } else { |
220 ArchOpcode opcode; | 219 ArchOpcode opcode; |
221 switch (rep) { | 220 switch (rep) { |
222 case kRepFloat32: | 221 case MachineRepresentation::kFloat32: |
223 opcode = kX87Movss; | 222 opcode = kX87Movss; |
224 break; | 223 break; |
225 case kRepFloat64: | 224 case MachineRepresentation::kFloat64: |
226 opcode = kX87Movsd; | 225 opcode = kX87Movsd; |
227 break; | 226 break; |
228 case kRepBit: // Fall through. | 227 case MachineRepresentation::kBit: // Fall through. |
229 case kRepWord8: | 228 case MachineRepresentation::kWord8: |
230 opcode = kX87Movb; | 229 opcode = kX87Movb; |
231 break; | 230 break; |
232 case kRepWord16: | 231 case MachineRepresentation::kWord16: |
233 opcode = kX87Movw; | 232 opcode = kX87Movw; |
234 break; | 233 break; |
235 case kRepTagged: // Fall through. | 234 case MachineRepresentation::kTagged: // Fall through. |
236 case kRepWord32: | 235 case MachineRepresentation::kWord32: |
237 opcode = kX87Movl; | 236 opcode = kX87Movl; |
238 break; | 237 break; |
239 default: | 238 default: |
240 UNREACHABLE(); | 239 UNREACHABLE(); |
241 return; | 240 return; |
242 } | 241 } |
243 | 242 |
244 InstructionOperand val; | 243 InstructionOperand val; |
245 if (g.CanBeImmediate(value)) { | 244 if (g.CanBeImmediate(value)) { |
246 val = g.UseImmediate(value); | 245 val = g.UseImmediate(value); |
247 } else if (rep == kRepWord8 || rep == kRepBit) { | 246 } else if (rep == MachineRepresentation::kWord8 || |
| 247 rep == MachineRepresentation::kBit) { |
248 val = g.UseByteRegister(value); | 248 val = g.UseByteRegister(value); |
249 } else { | 249 } else { |
250 val = g.UseRegister(value); | 250 val = g.UseRegister(value); |
251 } | 251 } |
252 | 252 |
253 InstructionOperand inputs[4]; | 253 InstructionOperand inputs[4]; |
254 size_t input_count = 0; | 254 size_t input_count = 0; |
255 AddressingMode addressing_mode = | 255 AddressingMode addressing_mode = |
256 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); | 256 g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
257 InstructionCode code = | 257 InstructionCode code = |
258 opcode | AddressingModeField::encode(addressing_mode); | 258 opcode | AddressingModeField::encode(addressing_mode); |
259 inputs[input_count++] = val; | 259 inputs[input_count++] = val; |
260 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); | 260 Emit(code, 0, static_cast<InstructionOperand*>(NULL), input_count, inputs); |
261 } | 261 } |
262 } | 262 } |
263 | 263 |
264 | 264 |
265 void InstructionSelector::VisitCheckedLoad(Node* node) { | 265 void InstructionSelector::VisitCheckedLoad(Node* node) { |
266 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 266 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
267 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
268 X87OperandGenerator g(this); | 267 X87OperandGenerator g(this); |
269 Node* const buffer = node->InputAt(0); | 268 Node* const buffer = node->InputAt(0); |
270 Node* const offset = node->InputAt(1); | 269 Node* const offset = node->InputAt(1); |
271 Node* const length = node->InputAt(2); | 270 Node* const length = node->InputAt(2); |
272 ArchOpcode opcode; | 271 ArchOpcode opcode; |
273 switch (rep) { | 272 switch (load_rep.representation()) { |
274 case kRepWord8: | 273 case MachineRepresentation::kWord8: |
275 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 274 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
276 break; | 275 break; |
277 case kRepWord16: | 276 case MachineRepresentation::kWord16: |
278 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 277 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
279 break; | 278 break; |
280 case kRepWord32: | 279 case MachineRepresentation::kWord32: |
281 opcode = kCheckedLoadWord32; | 280 opcode = kCheckedLoadWord32; |
282 break; | 281 break; |
283 case kRepFloat32: | 282 case MachineRepresentation::kFloat32: |
284 opcode = kCheckedLoadFloat32; | 283 opcode = kCheckedLoadFloat32; |
285 break; | 284 break; |
286 case kRepFloat64: | 285 case MachineRepresentation::kFloat64: |
287 opcode = kCheckedLoadFloat64; | 286 opcode = kCheckedLoadFloat64; |
288 break; | 287 break; |
289 default: | 288 default: |
290 UNREACHABLE(); | 289 UNREACHABLE(); |
291 return; | 290 return; |
292 } | 291 } |
293 InstructionOperand offset_operand = g.UseRegister(offset); | 292 InstructionOperand offset_operand = g.UseRegister(offset); |
294 InstructionOperand length_operand = | 293 InstructionOperand length_operand = |
295 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); | 294 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
296 if (g.CanBeImmediate(buffer)) { | 295 if (g.CanBeImmediate(buffer)) { |
297 Emit(opcode | AddressingModeField::encode(kMode_MRI), | 296 Emit(opcode | AddressingModeField::encode(kMode_MRI), |
298 g.DefineAsRegister(node), offset_operand, length_operand, | 297 g.DefineAsRegister(node), offset_operand, length_operand, |
299 offset_operand, g.UseImmediate(buffer)); | 298 offset_operand, g.UseImmediate(buffer)); |
300 } else { | 299 } else { |
301 Emit(opcode | AddressingModeField::encode(kMode_MR1), | 300 Emit(opcode | AddressingModeField::encode(kMode_MR1), |
302 g.DefineAsRegister(node), offset_operand, length_operand, | 301 g.DefineAsRegister(node), offset_operand, length_operand, |
303 g.UseRegister(buffer), offset_operand); | 302 g.UseRegister(buffer), offset_operand); |
304 } | 303 } |
305 } | 304 } |
306 | 305 |
307 | 306 |
308 void InstructionSelector::VisitCheckedStore(Node* node) { | 307 void InstructionSelector::VisitCheckedStore(Node* node) { |
309 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 308 MachineRepresentation rep = |
| 309 CheckedStoreRepresentationOf(node->op()).representation(); |
310 X87OperandGenerator g(this); | 310 X87OperandGenerator g(this); |
311 Node* const buffer = node->InputAt(0); | 311 Node* const buffer = node->InputAt(0); |
312 Node* const offset = node->InputAt(1); | 312 Node* const offset = node->InputAt(1); |
313 Node* const length = node->InputAt(2); | 313 Node* const length = node->InputAt(2); |
314 Node* const value = node->InputAt(3); | 314 Node* const value = node->InputAt(3); |
315 ArchOpcode opcode; | 315 ArchOpcode opcode; |
316 switch (rep) { | 316 switch (rep) { |
317 case kRepWord8: | 317 case MachineRepresentation::kWord8: |
318 opcode = kCheckedStoreWord8; | 318 opcode = kCheckedStoreWord8; |
319 break; | 319 break; |
320 case kRepWord16: | 320 case MachineRepresentation::kWord16: |
321 opcode = kCheckedStoreWord16; | 321 opcode = kCheckedStoreWord16; |
322 break; | 322 break; |
323 case kRepWord32: | 323 case MachineRepresentation::kWord32: |
324 opcode = kCheckedStoreWord32; | 324 opcode = kCheckedStoreWord32; |
325 break; | 325 break; |
326 case kRepFloat32: | 326 case MachineRepresentation::kFloat32: |
327 opcode = kCheckedStoreFloat32; | 327 opcode = kCheckedStoreFloat32; |
328 break; | 328 break; |
329 case kRepFloat64: | 329 case MachineRepresentation::kFloat64: |
330 opcode = kCheckedStoreFloat64; | 330 opcode = kCheckedStoreFloat64; |
331 break; | 331 break; |
332 default: | 332 default: |
333 UNREACHABLE(); | 333 UNREACHABLE(); |
334 return; | 334 return; |
335 } | 335 } |
336 InstructionOperand value_operand = | 336 InstructionOperand value_operand = |
337 g.CanBeImmediate(value) | 337 g.CanBeImmediate(value) ? g.UseImmediate(value) |
338 ? g.UseImmediate(value) | 338 : ((rep == MachineRepresentation::kWord8 || |
339 : ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value) | 339 rep == MachineRepresentation::kBit) |
340 : g.UseRegister(value)); | 340 ? g.UseByteRegister(value) |
| 341 : g.UseRegister(value)); |
341 InstructionOperand offset_operand = g.UseRegister(offset); | 342 InstructionOperand offset_operand = g.UseRegister(offset); |
342 InstructionOperand length_operand = | 343 InstructionOperand length_operand = |
343 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); | 344 g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); |
344 if (g.CanBeImmediate(buffer)) { | 345 if (g.CanBeImmediate(buffer)) { |
345 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), | 346 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), |
346 offset_operand, length_operand, value_operand, offset_operand, | 347 offset_operand, length_operand, value_operand, offset_operand, |
347 g.UseImmediate(buffer)); | 348 g.UseImmediate(buffer)); |
348 } else { | 349 } else { |
349 Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), | 350 Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), |
350 offset_operand, length_operand, value_operand, g.UseRegister(buffer), | 351 offset_operand, length_operand, value_operand, g.UseRegister(buffer), |
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1326 MachineOperatorBuilder::kFloat32RoundTruncate | | 1327 MachineOperatorBuilder::kFloat32RoundTruncate | |
1327 MachineOperatorBuilder::kFloat64RoundTruncate | | 1328 MachineOperatorBuilder::kFloat64RoundTruncate | |
1328 MachineOperatorBuilder::kFloat32RoundTiesEven | | 1329 MachineOperatorBuilder::kFloat32RoundTiesEven | |
1329 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1330 MachineOperatorBuilder::kFloat64RoundTiesEven; |
1330 return flags; | 1331 return flags; |
1331 } | 1332 } |
1332 | 1333 |
1333 } // namespace compiler | 1334 } // namespace compiler |
1334 } // namespace internal | 1335 } // namespace internal |
1335 } // namespace v8 | 1336 } // namespace v8 |
OLD | NEW |