| 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 |