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/base/bits.h" | 6 #include "src/base/bits.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 | 10 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 *shift_return = g.UseImmediate(m.right().node()); | 108 *shift_return = g.UseImmediate(m.right().node()); |
109 } else { | 109 } else { |
110 *opcode_return |= AddressingModeField::encode(kRegMode); | 110 *opcode_return |= AddressingModeField::encode(kRegMode); |
111 *shift_return = g.UseRegister(m.right().node()); | 111 *shift_return = g.UseRegister(m.right().node()); |
112 } | 112 } |
113 return true; | 113 return true; |
114 } | 114 } |
115 return false; | 115 return false; |
116 } | 116 } |
117 | 117 |
| 118 template <IrOpcode::Value kOpcode, int kImmMin, int kImmMax, |
| 119 AddressingMode kImmMode> |
| 120 bool TryMatchShiftImmediate(InstructionSelector* selector, |
| 121 InstructionCode* opcode_return, Node* node, |
| 122 InstructionOperand* value_return, |
| 123 InstructionOperand* shift_return) { |
| 124 ArmOperandGenerator g(selector); |
| 125 if (node->opcode() == kOpcode) { |
| 126 Int32BinopMatcher m(node); |
| 127 if (m.right().IsInRange(kImmMin, kImmMax)) { |
| 128 *opcode_return |= AddressingModeField::encode(kImmMode); |
| 129 *value_return = g.UseRegister(m.left().node()); |
| 130 *shift_return = g.UseImmediate(m.right().node()); |
| 131 return true; |
| 132 } |
| 133 } |
| 134 return false; |
| 135 } |
118 | 136 |
119 bool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_return, | 137 bool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_return, |
120 Node* node, InstructionOperand* value_return, | 138 Node* node, InstructionOperand* value_return, |
121 InstructionOperand* shift_return) { | 139 InstructionOperand* shift_return) { |
122 return TryMatchShift<IrOpcode::kWord32Ror, 1, 31, kMode_Operand2_R_ROR_I, | 140 return TryMatchShift<IrOpcode::kWord32Ror, 1, 31, kMode_Operand2_R_ROR_I, |
123 kMode_Operand2_R_ROR_R>(selector, opcode_return, node, | 141 kMode_Operand2_R_ROR_R>(selector, opcode_return, node, |
124 value_return, shift_return); | 142 value_return, shift_return); |
125 } | 143 } |
126 | 144 |
127 | 145 |
128 bool TryMatchASR(InstructionSelector* selector, InstructionCode* opcode_return, | 146 bool TryMatchASR(InstructionSelector* selector, InstructionCode* opcode_return, |
129 Node* node, InstructionOperand* value_return, | 147 Node* node, InstructionOperand* value_return, |
130 InstructionOperand* shift_return) { | 148 InstructionOperand* shift_return) { |
131 return TryMatchShift<IrOpcode::kWord32Sar, 1, 32, kMode_Operand2_R_ASR_I, | 149 return TryMatchShift<IrOpcode::kWord32Sar, 1, 32, kMode_Operand2_R_ASR_I, |
132 kMode_Operand2_R_ASR_R>(selector, opcode_return, node, | 150 kMode_Operand2_R_ASR_R>(selector, opcode_return, node, |
133 value_return, shift_return); | 151 value_return, shift_return); |
134 } | 152 } |
135 | 153 |
136 | 154 |
137 bool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_return, | 155 bool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_return, |
138 Node* node, InstructionOperand* value_return, | 156 Node* node, InstructionOperand* value_return, |
139 InstructionOperand* shift_return) { | 157 InstructionOperand* shift_return) { |
140 return TryMatchShift<IrOpcode::kWord32Shl, 0, 31, kMode_Operand2_R_LSL_I, | 158 return TryMatchShift<IrOpcode::kWord32Shl, 0, 31, kMode_Operand2_R_LSL_I, |
141 kMode_Operand2_R_LSL_R>(selector, opcode_return, node, | 159 kMode_Operand2_R_LSL_R>(selector, opcode_return, node, |
142 value_return, shift_return); | 160 value_return, shift_return); |
143 } | 161 } |
144 | 162 |
| 163 bool TryMatchLSLImmediate(InstructionSelector* selector, |
| 164 InstructionCode* opcode_return, Node* node, |
| 165 InstructionOperand* value_return, |
| 166 InstructionOperand* shift_return) { |
| 167 return TryMatchShiftImmediate<IrOpcode::kWord32Shl, 0, 31, |
| 168 kMode_Operand2_R_LSL_I>( |
| 169 selector, opcode_return, node, value_return, shift_return); |
| 170 } |
145 | 171 |
146 bool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_return, | 172 bool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_return, |
147 Node* node, InstructionOperand* value_return, | 173 Node* node, InstructionOperand* value_return, |
148 InstructionOperand* shift_return) { | 174 InstructionOperand* shift_return) { |
149 return TryMatchShift<IrOpcode::kWord32Shr, 1, 32, kMode_Operand2_R_LSR_I, | 175 return TryMatchShift<IrOpcode::kWord32Shr, 1, 32, kMode_Operand2_R_LSR_I, |
150 kMode_Operand2_R_LSR_R>(selector, opcode_return, node, | 176 kMode_Operand2_R_LSR_R>(selector, opcode_return, node, |
151 value_return, shift_return); | 177 value_return, shift_return); |
152 } | 178 } |
153 | 179 |
154 | 180 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 } | 331 } |
306 | 332 |
307 } // namespace | 333 } // namespace |
308 | 334 |
309 | 335 |
310 void InstructionSelector::VisitLoad(Node* node) { | 336 void InstructionSelector::VisitLoad(Node* node) { |
311 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); | 337 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
312 ArmOperandGenerator g(this); | 338 ArmOperandGenerator g(this); |
313 Node* base = node->InputAt(0); | 339 Node* base = node->InputAt(0); |
314 Node* index = node->InputAt(1); | 340 Node* index = node->InputAt(1); |
| 341 InstructionOperand inputs[3]; |
| 342 size_t input_count = 0; |
| 343 InstructionOperand outputs[1]; |
315 | 344 |
316 ArchOpcode opcode = kArchNop; | 345 InstructionCode opcode = kArchNop; |
317 switch (load_rep.representation()) { | 346 switch (load_rep.representation()) { |
318 case MachineRepresentation::kFloat32: | 347 case MachineRepresentation::kFloat32: |
319 opcode = kArmVldrF32; | 348 opcode = kArmVldrF32; |
320 break; | 349 break; |
321 case MachineRepresentation::kFloat64: | 350 case MachineRepresentation::kFloat64: |
322 opcode = kArmVldrF64; | 351 opcode = kArmVldrF64; |
323 break; | 352 break; |
324 case MachineRepresentation::kBit: // Fall through. | 353 case MachineRepresentation::kBit: // Fall through. |
325 case MachineRepresentation::kWord8: | 354 case MachineRepresentation::kWord8: |
326 opcode = load_rep.IsUnsigned() ? kArmLdrb : kArmLdrsb; | 355 opcode = load_rep.IsUnsigned() ? kArmLdrb : kArmLdrsb; |
327 break; | 356 break; |
328 case MachineRepresentation::kWord16: | 357 case MachineRepresentation::kWord16: |
329 opcode = load_rep.IsUnsigned() ? kArmLdrh : kArmLdrsh; | 358 opcode = load_rep.IsUnsigned() ? kArmLdrh : kArmLdrsh; |
330 break; | 359 break; |
331 case MachineRepresentation::kTagged: // Fall through. | 360 case MachineRepresentation::kTagged: // Fall through. |
332 case MachineRepresentation::kWord32: | 361 case MachineRepresentation::kWord32: |
333 opcode = kArmLdr; | 362 opcode = kArmLdr; |
334 break; | 363 break; |
335 case MachineRepresentation::kWord64: // Fall through. | 364 case MachineRepresentation::kWord64: // Fall through. |
336 case MachineRepresentation::kSimd128: // Fall through. | 365 case MachineRepresentation::kSimd128: // Fall through. |
337 case MachineRepresentation::kNone: | 366 case MachineRepresentation::kNone: |
338 UNREACHABLE(); | 367 UNREACHABLE(); |
339 return; | 368 return; |
340 } | 369 } |
341 | 370 |
| 371 outputs[0] = g.DefineAsRegister(node); |
| 372 inputs[0] = g.UseRegister(base); |
| 373 |
342 if (g.CanBeImmediate(index, opcode)) { | 374 if (g.CanBeImmediate(index, opcode)) { |
343 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), | 375 input_count = 2; |
344 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); | 376 inputs[1] = g.UseImmediate(index); |
| 377 opcode |= AddressingModeField::encode(kMode_Offset_RI); |
| 378 } else if ((opcode == kArmLdr) && |
| 379 TryMatchLSLImmediate(this, &opcode, index, &inputs[1], |
| 380 &inputs[2])) { |
| 381 input_count = 3; |
345 } else { | 382 } else { |
346 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), | 383 input_count = 2; |
347 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); | 384 inputs[1] = g.UseRegister(index); |
| 385 opcode |= AddressingModeField::encode(kMode_Offset_RR); |
348 } | 386 } |
| 387 |
| 388 Emit(opcode, arraysize(outputs), outputs, input_count, inputs); |
349 } | 389 } |
350 | 390 |
351 | 391 |
352 void InstructionSelector::VisitStore(Node* node) { | 392 void InstructionSelector::VisitStore(Node* node) { |
353 ArmOperandGenerator g(this); | 393 ArmOperandGenerator g(this); |
354 Node* base = node->InputAt(0); | 394 Node* base = node->InputAt(0); |
355 Node* index = node->InputAt(1); | 395 Node* index = node->InputAt(1); |
356 Node* value = node->InputAt(2); | 396 Node* value = node->InputAt(2); |
357 | 397 |
358 StoreRepresentation store_rep = StoreRepresentationOf(node->op()); | 398 StoreRepresentation store_rep = StoreRepresentationOf(node->op()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 record_write_mode = RecordWriteMode::kValueIsAny; | 430 record_write_mode = RecordWriteMode::kValueIsAny; |
391 break; | 431 break; |
392 } | 432 } |
393 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 433 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
394 size_t const temp_count = arraysize(temps); | 434 size_t const temp_count = arraysize(temps); |
395 InstructionCode code = kArchStoreWithWriteBarrier; | 435 InstructionCode code = kArchStoreWithWriteBarrier; |
396 code |= AddressingModeField::encode(addressing_mode); | 436 code |= AddressingModeField::encode(addressing_mode); |
397 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 437 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
398 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 438 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
399 } else { | 439 } else { |
400 ArchOpcode opcode = kArchNop; | 440 InstructionOperand inputs[4]; |
| 441 size_t input_count = 0; |
| 442 |
| 443 InstructionCode opcode = kArchNop; |
401 switch (rep) { | 444 switch (rep) { |
402 case MachineRepresentation::kFloat32: | 445 case MachineRepresentation::kFloat32: |
403 opcode = kArmVstrF32; | 446 opcode = kArmVstrF32; |
404 break; | 447 break; |
405 case MachineRepresentation::kFloat64: | 448 case MachineRepresentation::kFloat64: |
406 opcode = kArmVstrF64; | 449 opcode = kArmVstrF64; |
407 break; | 450 break; |
408 case MachineRepresentation::kBit: // Fall through. | 451 case MachineRepresentation::kBit: // Fall through. |
409 case MachineRepresentation::kWord8: | 452 case MachineRepresentation::kWord8: |
410 opcode = kArmStrb; | 453 opcode = kArmStrb; |
411 break; | 454 break; |
412 case MachineRepresentation::kWord16: | 455 case MachineRepresentation::kWord16: |
413 opcode = kArmStrh; | 456 opcode = kArmStrh; |
414 break; | 457 break; |
415 case MachineRepresentation::kTagged: // Fall through. | 458 case MachineRepresentation::kTagged: // Fall through. |
416 case MachineRepresentation::kWord32: | 459 case MachineRepresentation::kWord32: |
417 opcode = kArmStr; | 460 opcode = kArmStr; |
418 break; | 461 break; |
419 case MachineRepresentation::kWord64: // Fall through. | 462 case MachineRepresentation::kWord64: // Fall through. |
420 case MachineRepresentation::kSimd128: // Fall through. | 463 case MachineRepresentation::kSimd128: // Fall through. |
421 case MachineRepresentation::kNone: | 464 case MachineRepresentation::kNone: |
422 UNREACHABLE(); | 465 UNREACHABLE(); |
423 return; | 466 return; |
424 } | 467 } |
425 | 468 |
| 469 inputs[0] = g.UseRegister(value); |
| 470 inputs[1] = g.UseRegister(base); |
| 471 |
426 if (g.CanBeImmediate(index, opcode)) { | 472 if (g.CanBeImmediate(index, opcode)) { |
427 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(), | 473 input_count = 3; |
428 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 474 inputs[2] = g.UseImmediate(index); |
| 475 opcode |= AddressingModeField::encode(kMode_Offset_RI); |
| 476 } else if ((opcode == kArmStr) && |
| 477 TryMatchLSLImmediate(this, &opcode, index, &inputs[2], |
| 478 &inputs[3])) { |
| 479 input_count = 4; |
429 } else { | 480 } else { |
430 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), | 481 input_count = 3; |
431 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); | 482 inputs[2] = g.UseRegister(index); |
| 483 opcode |= AddressingModeField::encode(kMode_Offset_RR); |
432 } | 484 } |
| 485 Emit(opcode, 0, nullptr, input_count, inputs); |
433 } | 486 } |
434 } | 487 } |
435 | 488 |
436 | 489 |
437 void InstructionSelector::VisitCheckedLoad(Node* node) { | 490 void InstructionSelector::VisitCheckedLoad(Node* node) { |
438 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); | 491 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
439 ArmOperandGenerator g(this); | 492 ArmOperandGenerator g(this); |
440 Node* const buffer = node->InputAt(0); | 493 Node* const buffer = node->InputAt(0); |
441 Node* const offset = node->InputAt(1); | 494 Node* const offset = node->InputAt(1); |
442 Node* const length = node->InputAt(2); | 495 Node* const length = node->InputAt(2); |
(...skipping 1468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1911 MachineOperatorBuilder::kFloat32Max | | 1964 MachineOperatorBuilder::kFloat32Max | |
1912 MachineOperatorBuilder::kFloat64Min | | 1965 MachineOperatorBuilder::kFloat64Min | |
1913 MachineOperatorBuilder::kFloat64Max; | 1966 MachineOperatorBuilder::kFloat64Max; |
1914 } | 1967 } |
1915 return flags; | 1968 return flags; |
1916 } | 1969 } |
1917 | 1970 |
1918 } // namespace compiler | 1971 } // namespace compiler |
1919 } // namespace internal | 1972 } // namespace internal |
1920 } // namespace v8 | 1973 } // namespace v8 |
OLD | NEW |