| 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 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 InstructionOperand mul_operand = g.TempRegister(); | 296 InstructionOperand mul_operand = g.TempRegister(); |
| 297 selector->Emit(kArmMul, mul_operand, div_operand, right_operand); | 297 selector->Emit(kArmMul, mul_operand, div_operand, right_operand); |
| 298 selector->Emit(kArmSub, result_operand, left_operand, mul_operand); | 298 selector->Emit(kArmSub, result_operand, left_operand, mul_operand); |
| 299 } | 299 } |
| 300 } | 300 } |
| 301 | 301 |
| 302 } // namespace | 302 } // namespace |
| 303 | 303 |
| 304 | 304 |
| 305 void InstructionSelector::VisitLoad(Node* node) { | 305 void InstructionSelector::VisitLoad(Node* node) { |
| 306 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 306 LoadRepresentation load_rep = LoadRepresentationOf(node->op()); |
| 307 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | |
| 308 ArmOperandGenerator g(this); | 307 ArmOperandGenerator g(this); |
| 309 Node* base = node->InputAt(0); | 308 Node* base = node->InputAt(0); |
| 310 Node* index = node->InputAt(1); | 309 Node* index = node->InputAt(1); |
| 311 | 310 |
| 312 ArchOpcode opcode; | 311 ArchOpcode opcode; |
| 313 switch (rep) { | 312 switch (load_rep.representation()) { |
| 314 case kRepFloat32: | 313 case MachineRepresentation::kFloat32: |
| 315 opcode = kArmVldrF32; | 314 opcode = kArmVldrF32; |
| 316 break; | 315 break; |
| 317 case kRepFloat64: | 316 case MachineRepresentation::kFloat64: |
| 318 opcode = kArmVldrF64; | 317 opcode = kArmVldrF64; |
| 319 break; | 318 break; |
| 320 case kRepBit: // Fall through. | 319 case MachineRepresentation::kBit: // Fall through. |
| 321 case kRepWord8: | 320 case MachineRepresentation::kWord8: |
| 322 opcode = typ == kTypeUint32 ? kArmLdrb : kArmLdrsb; | 321 opcode = load_rep.IsUnsigned() ? kArmLdrb : kArmLdrsb; |
| 323 break; | 322 break; |
| 324 case kRepWord16: | 323 case MachineRepresentation::kWord16: |
| 325 opcode = typ == kTypeUint32 ? kArmLdrh : kArmLdrsh; | 324 opcode = load_rep.IsUnsigned() ? kArmLdrh : kArmLdrsh; |
| 326 break; | 325 break; |
| 327 case kRepTagged: // Fall through. | 326 case MachineRepresentation::kTagged: // Fall through. |
| 328 case kRepWord32: | 327 case MachineRepresentation::kWord32: |
| 329 opcode = kArmLdr; | 328 opcode = kArmLdr; |
| 330 break; | 329 break; |
| 331 default: | 330 default: |
| 332 UNREACHABLE(); | 331 UNREACHABLE(); |
| 333 return; | 332 return; |
| 334 } | 333 } |
| 335 | 334 |
| 336 if (g.CanBeImmediate(index, opcode)) { | 335 if (g.CanBeImmediate(index, opcode)) { |
| 337 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), | 336 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), |
| 338 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); | 337 g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); |
| 339 } else { | 338 } else { |
| 340 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), | 339 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), |
| 341 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); | 340 g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); |
| 342 } | 341 } |
| 343 } | 342 } |
| 344 | 343 |
| 345 | 344 |
| 346 void InstructionSelector::VisitStore(Node* node) { | 345 void InstructionSelector::VisitStore(Node* node) { |
| 347 ArmOperandGenerator g(this); | 346 ArmOperandGenerator g(this); |
| 348 Node* base = node->InputAt(0); | 347 Node* base = node->InputAt(0); |
| 349 Node* index = node->InputAt(1); | 348 Node* index = node->InputAt(1); |
| 350 Node* value = node->InputAt(2); | 349 Node* value = node->InputAt(2); |
| 351 | 350 |
| 352 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); | 351 StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node); |
| 353 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); | 352 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind(); |
| 354 MachineType rep = RepresentationOf(store_rep.machine_type()); | 353 MachineRepresentation rep = store_rep.machine_type().representation(); |
| 355 | 354 |
| 356 if (write_barrier_kind != kNoWriteBarrier) { | 355 if (write_barrier_kind != kNoWriteBarrier) { |
| 357 DCHECK_EQ(kRepTagged, rep); | 356 DCHECK_EQ(MachineRepresentation::kTagged, rep); |
| 358 InstructionOperand inputs[3]; | 357 InstructionOperand inputs[3]; |
| 359 size_t input_count = 0; | 358 size_t input_count = 0; |
| 360 inputs[input_count++] = g.UseUniqueRegister(base); | 359 inputs[input_count++] = g.UseUniqueRegister(base); |
| 361 inputs[input_count++] = g.UseUniqueRegister(index); | 360 inputs[input_count++] = g.UseUniqueRegister(index); |
| 362 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) | 361 inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
| 363 ? g.UseRegister(value) | 362 ? g.UseRegister(value) |
| 364 : g.UseUniqueRegister(value); | 363 : g.UseUniqueRegister(value); |
| 365 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; | 364 RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny; |
| 366 switch (write_barrier_kind) { | 365 switch (write_barrier_kind) { |
| 367 case kNoWriteBarrier: | 366 case kNoWriteBarrier: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 378 break; | 377 break; |
| 379 } | 378 } |
| 380 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; | 379 InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()}; |
| 381 size_t const temp_count = arraysize(temps); | 380 size_t const temp_count = arraysize(temps); |
| 382 InstructionCode code = kArchStoreWithWriteBarrier; | 381 InstructionCode code = kArchStoreWithWriteBarrier; |
| 383 code |= MiscField::encode(static_cast<int>(record_write_mode)); | 382 code |= MiscField::encode(static_cast<int>(record_write_mode)); |
| 384 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); | 383 Emit(code, 0, nullptr, input_count, inputs, temp_count, temps); |
| 385 } else { | 384 } else { |
| 386 ArchOpcode opcode; | 385 ArchOpcode opcode; |
| 387 switch (rep) { | 386 switch (rep) { |
| 388 case kRepFloat32: | 387 case MachineRepresentation::kFloat32: |
| 389 opcode = kArmVstrF32; | 388 opcode = kArmVstrF32; |
| 390 break; | 389 break; |
| 391 case kRepFloat64: | 390 case MachineRepresentation::kFloat64: |
| 392 opcode = kArmVstrF64; | 391 opcode = kArmVstrF64; |
| 393 break; | 392 break; |
| 394 case kRepBit: // Fall through. | 393 case MachineRepresentation::kBit: // Fall through. |
| 395 case kRepWord8: | 394 case MachineRepresentation::kWord8: |
| 396 opcode = kArmStrb; | 395 opcode = kArmStrb; |
| 397 break; | 396 break; |
| 398 case kRepWord16: | 397 case MachineRepresentation::kWord16: |
| 399 opcode = kArmStrh; | 398 opcode = kArmStrh; |
| 400 break; | 399 break; |
| 401 case kRepTagged: // Fall through. | 400 case MachineRepresentation::kTagged: // Fall through. |
| 402 case kRepWord32: | 401 case MachineRepresentation::kWord32: |
| 403 opcode = kArmStr; | 402 opcode = kArmStr; |
| 404 break; | 403 break; |
| 405 default: | 404 default: |
| 406 UNREACHABLE(); | 405 UNREACHABLE(); |
| 407 return; | 406 return; |
| 408 } | 407 } |
| 409 | 408 |
| 410 if (g.CanBeImmediate(index, opcode)) { | 409 if (g.CanBeImmediate(index, opcode)) { |
| 411 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(), | 410 Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(), |
| 412 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); | 411 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); |
| 413 } else { | 412 } else { |
| 414 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), | 413 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), |
| 415 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); | 414 g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); |
| 416 } | 415 } |
| 417 } | 416 } |
| 418 } | 417 } |
| 419 | 418 |
| 420 | 419 |
| 421 void InstructionSelector::VisitCheckedLoad(Node* node) { | 420 void InstructionSelector::VisitCheckedLoad(Node* node) { |
| 422 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 421 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); |
| 423 MachineType typ = TypeOf(OpParameter<MachineType>(node)); | |
| 424 ArmOperandGenerator g(this); | 422 ArmOperandGenerator g(this); |
| 425 Node* const buffer = node->InputAt(0); | 423 Node* const buffer = node->InputAt(0); |
| 426 Node* const offset = node->InputAt(1); | 424 Node* const offset = node->InputAt(1); |
| 427 Node* const length = node->InputAt(2); | 425 Node* const length = node->InputAt(2); |
| 428 ArchOpcode opcode; | 426 ArchOpcode opcode; |
| 429 switch (rep) { | 427 switch (load_rep.representation()) { |
| 430 case kRepWord8: | 428 case MachineRepresentation::kWord8: |
| 431 opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8; | 429 opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8; |
| 432 break; | 430 break; |
| 433 case kRepWord16: | 431 case MachineRepresentation::kWord16: |
| 434 opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16; | 432 opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16; |
| 435 break; | 433 break; |
| 436 case kRepWord32: | 434 case MachineRepresentation::kWord32: |
| 437 opcode = kCheckedLoadWord32; | 435 opcode = kCheckedLoadWord32; |
| 438 break; | 436 break; |
| 439 case kRepFloat32: | 437 case MachineRepresentation::kFloat32: |
| 440 opcode = kCheckedLoadFloat32; | 438 opcode = kCheckedLoadFloat32; |
| 441 break; | 439 break; |
| 442 case kRepFloat64: | 440 case MachineRepresentation::kFloat64: |
| 443 opcode = kCheckedLoadFloat64; | 441 opcode = kCheckedLoadFloat64; |
| 444 break; | 442 break; |
| 445 default: | 443 default: |
| 446 UNREACHABLE(); | 444 UNREACHABLE(); |
| 447 return; | 445 return; |
| 448 } | 446 } |
| 449 InstructionOperand offset_operand = g.UseRegister(offset); | 447 InstructionOperand offset_operand = g.UseRegister(offset); |
| 450 InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) | 448 InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) |
| 451 ? g.UseImmediate(length) | 449 ? g.UseImmediate(length) |
| 452 : g.UseRegister(length); | 450 : g.UseRegister(length); |
| 453 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), | 451 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), |
| 454 g.DefineAsRegister(node), offset_operand, length_operand, | 452 g.DefineAsRegister(node), offset_operand, length_operand, |
| 455 g.UseRegister(buffer), offset_operand); | 453 g.UseRegister(buffer), offset_operand); |
| 456 } | 454 } |
| 457 | 455 |
| 458 | 456 |
| 459 void InstructionSelector::VisitCheckedStore(Node* node) { | 457 void InstructionSelector::VisitCheckedStore(Node* node) { |
| 460 MachineType rep = RepresentationOf(OpParameter<MachineType>(node)); | 458 MachineRepresentation rep = |
| 459 CheckedStoreRepresentationOf(node->op()).representation(); |
| 461 ArmOperandGenerator g(this); | 460 ArmOperandGenerator g(this); |
| 462 Node* const buffer = node->InputAt(0); | 461 Node* const buffer = node->InputAt(0); |
| 463 Node* const offset = node->InputAt(1); | 462 Node* const offset = node->InputAt(1); |
| 464 Node* const length = node->InputAt(2); | 463 Node* const length = node->InputAt(2); |
| 465 Node* const value = node->InputAt(3); | 464 Node* const value = node->InputAt(3); |
| 466 ArchOpcode opcode; | 465 ArchOpcode opcode; |
| 467 switch (rep) { | 466 switch (rep) { |
| 468 case kRepWord8: | 467 case MachineRepresentation::kWord8: |
| 469 opcode = kCheckedStoreWord8; | 468 opcode = kCheckedStoreWord8; |
| 470 break; | 469 break; |
| 471 case kRepWord16: | 470 case MachineRepresentation::kWord16: |
| 472 opcode = kCheckedStoreWord16; | 471 opcode = kCheckedStoreWord16; |
| 473 break; | 472 break; |
| 474 case kRepWord32: | 473 case MachineRepresentation::kWord32: |
| 475 opcode = kCheckedStoreWord32; | 474 opcode = kCheckedStoreWord32; |
| 476 break; | 475 break; |
| 477 case kRepFloat32: | 476 case MachineRepresentation::kFloat32: |
| 478 opcode = kCheckedStoreFloat32; | 477 opcode = kCheckedStoreFloat32; |
| 479 break; | 478 break; |
| 480 case kRepFloat64: | 479 case MachineRepresentation::kFloat64: |
| 481 opcode = kCheckedStoreFloat64; | 480 opcode = kCheckedStoreFloat64; |
| 482 break; | 481 break; |
| 483 default: | 482 default: |
| 484 UNREACHABLE(); | 483 UNREACHABLE(); |
| 485 return; | 484 return; |
| 486 } | 485 } |
| 487 InstructionOperand offset_operand = g.UseRegister(offset); | 486 InstructionOperand offset_operand = g.UseRegister(offset); |
| 488 InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) | 487 InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) |
| 489 ? g.UseImmediate(length) | 488 ? g.UseImmediate(length) |
| 490 : g.UseRegister(length); | 489 : g.UseRegister(length); |
| (...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1594 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1593 MachineOperatorBuilder::kFloat64RoundTiesAway | |
| 1595 MachineOperatorBuilder::kFloat32RoundTiesEven | | 1594 MachineOperatorBuilder::kFloat32RoundTiesEven | |
| 1596 MachineOperatorBuilder::kFloat64RoundTiesEven; | 1595 MachineOperatorBuilder::kFloat64RoundTiesEven; |
| 1597 } | 1596 } |
| 1598 return flags; | 1597 return flags; |
| 1599 } | 1598 } |
| 1600 | 1599 |
| 1601 } // namespace compiler | 1600 } // namespace compiler |
| 1602 } // namespace internal | 1601 } // namespace internal |
| 1603 } // namespace v8 | 1602 } // namespace v8 |
| OLD | NEW |