OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2); | 511 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize < kDoubleSizeLog2); |
512 return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize); | 512 return Operand(key, LSL, kDoubleSizeLog2 - kSmiTagSize); |
513 } | 513 } |
514 | 514 |
515 // rm <shift_op> rs | 515 // rm <shift_op> rs |
516 explicit Operand(Register rm, ShiftOp shift_op, Register rs); | 516 explicit Operand(Register rm, ShiftOp shift_op, Register rs); |
517 | 517 |
518 // Return true if this is a register operand. | 518 // Return true if this is a register operand. |
519 INLINE(bool is_reg() const); | 519 INLINE(bool is_reg() const); |
520 | 520 |
521 // Return true if this operand fits in one instruction so that no | 521 // Return the number of actual instructions required to implement the given |
522 // 2-instruction solution with a load into the ip register is necessary. If | 522 // instruction for this particular operand. This can be a single instruction, |
| 523 // if no load into the ip register is necessary, or anything between 2 and 4 |
| 524 // instructions when we need to load from the constant pool (depending upon |
| 525 // whether the constant pool entry is in the small or extended section). If |
523 // the instruction this operand is used for is a MOV or MVN instruction the | 526 // the instruction this operand is used for is a MOV or MVN instruction the |
524 // actual instruction to use is required for this calculation. For other | 527 // actual instruction to use is required for this calculation. For other |
525 // instructions instr is ignored. | 528 // instructions instr is ignored. |
526 bool is_single_instruction(const Assembler* assembler, | 529 int instructions_required(const Assembler* assembler, Instr instr = 0) const; |
527 Instr instr = 0) const; | |
528 bool must_output_reloc_info(const Assembler* assembler) const; | 530 bool must_output_reloc_info(const Assembler* assembler) const; |
529 | 531 |
530 inline int32_t immediate() const { | 532 inline int32_t immediate() const { |
531 ASSERT(!rm_.is_valid()); | 533 ASSERT(!rm_.is_valid()); |
532 return imm32_; | 534 return imm32_; |
533 } | 535 } |
534 | 536 |
535 Register rm() const { return rm_; } | 537 Register rm() const { return rm_; } |
536 Register rs() const { return rs_; } | 538 Register rs() const { return rs_; } |
537 ShiftOp shift_op() const { return shift_op_; } | 539 ShiftOp shift_op() const { return shift_op_; } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 private: | 640 private: |
639 DoubleRegister base_; | 641 DoubleRegister base_; |
640 NeonListType type_; | 642 NeonListType type_; |
641 }; | 643 }; |
642 | 644 |
643 | 645 |
644 // Class used to build a constant pool. | 646 // Class used to build a constant pool. |
645 class ConstantPoolBuilder BASE_EMBEDDED { | 647 class ConstantPoolBuilder BASE_EMBEDDED { |
646 public: | 648 public: |
647 explicit ConstantPoolBuilder(); | 649 explicit ConstantPoolBuilder(); |
648 void AddEntry(Assembler* assm, const RelocInfo& rinfo); | 650 ConstantPoolArray::LayoutSection AddEntry(Assembler* assm, |
| 651 const RelocInfo& rinfo); |
649 void Relocate(int pc_delta); | 652 void Relocate(int pc_delta); |
650 bool IsEmpty(); | 653 bool IsEmpty(); |
651 Handle<ConstantPoolArray> New(Isolate* isolate); | 654 Handle<ConstantPoolArray> New(Isolate* isolate); |
652 void Populate(Assembler* assm, ConstantPoolArray* constant_pool); | 655 void Populate(Assembler* assm, ConstantPoolArray* constant_pool); |
653 | 656 |
654 inline int count_of_64bit() const { return count_of_64bit_; } | 657 inline ConstantPoolArray::LayoutSection current_section() const { |
655 inline int count_of_code_ptr() const { return count_of_code_ptr_; } | 658 return current_section_; |
656 inline int count_of_heap_ptr() const { return count_of_heap_ptr_; } | 659 } |
657 inline int count_of_32bit() const { return count_of_32bit_; } | 660 |
| 661 inline ConstantPoolArray::NumberOfEntries* number_of_entries( |
| 662 ConstantPoolArray::LayoutSection section) { |
| 663 return &number_of_entries_[section]; |
| 664 } |
| 665 |
| 666 inline ConstantPoolArray::NumberOfEntries* small_entries() { |
| 667 return number_of_entries(ConstantPoolArray::SMALL_SECTION); |
| 668 } |
| 669 |
| 670 inline ConstantPoolArray::NumberOfEntries* extended_entries() { |
| 671 return number_of_entries(ConstantPoolArray::EXTENDED_SECTION); |
| 672 } |
658 | 673 |
659 private: | 674 private: |
660 bool Is64BitEntry(RelocInfo::Mode rmode); | 675 struct ConstantPoolEntry { |
661 bool Is32BitEntry(RelocInfo::Mode rmode); | 676 ConstantPoolEntry(RelocInfo rinfo, ConstantPoolArray::LayoutSection section, |
662 bool IsCodePtrEntry(RelocInfo::Mode rmode); | 677 int merged_index) |
663 bool IsHeapPtrEntry(RelocInfo::Mode rmode); | 678 : rinfo_(rinfo), section_(section), merged_index_(merged_index) { } |
664 | 679 |
665 // TODO(rmcilroy): This should ideally be a ZoneList, however that would mean | 680 RelocInfo rinfo_; |
666 // RelocInfo would need to subclass ZoneObject which it currently doesn't. | 681 ConstantPoolArray::LayoutSection section_; |
667 std::vector<RelocInfo> entries_; | 682 int merged_index_; |
668 std::vector<int> merged_indexes_; | 683 }; |
669 int count_of_64bit_; | 684 |
670 int count_of_code_ptr_; | 685 ConstantPoolArray::Type GetConstantPoolType(RelocInfo::Mode rmode); |
671 int count_of_heap_ptr_; | 686 |
672 int count_of_32bit_; | 687 std::vector<ConstantPoolEntry> entries_; |
| 688 ConstantPoolArray::LayoutSection current_section_; |
| 689 ConstantPoolArray::NumberOfEntries number_of_entries_[2]; |
673 }; | 690 }; |
674 | 691 |
675 struct VmovIndex { | 692 struct VmovIndex { |
676 unsigned char index; | 693 unsigned char index; |
677 }; | 694 }; |
678 const VmovIndex VmovIndexLo = { 0 }; | 695 const VmovIndex VmovIndexLo = { 0 }; |
679 const VmovIndex VmovIndexHi = { 1 }; | 696 const VmovIndex VmovIndexHi = { 1 }; |
680 | 697 |
681 class Assembler : public AssemblerBase { | 698 class Assembler : public AssemblerBase { |
682 public: | 699 public: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
716 // Note: The same Label can be used for forward and backward branches | 733 // Note: The same Label can be used for forward and backward branches |
717 // but it may be bound only once. | 734 // but it may be bound only once. |
718 | 735 |
719 void bind(Label* L); // binds an unbound label L to the current code position | 736 void bind(Label* L); // binds an unbound label L to the current code position |
720 | 737 |
721 // Returns the branch offset to the given label from the current code position | 738 // Returns the branch offset to the given label from the current code position |
722 // Links the label to the current position if it is still unbound | 739 // Links the label to the current position if it is still unbound |
723 // Manages the jump elimination optimization if the second parameter is true. | 740 // Manages the jump elimination optimization if the second parameter is true. |
724 int branch_offset(Label* L, bool jump_elimination_allowed); | 741 int branch_offset(Label* L, bool jump_elimination_allowed); |
725 | 742 |
| 743 // Returns true if the given pc address is the start of a constant pool load |
| 744 // instruction sequence. |
| 745 INLINE(static bool is_constant_pool_load(Address pc)); |
| 746 |
726 // Return the address in the constant pool of the code target address used by | 747 // Return the address in the constant pool of the code target address used by |
727 // the branch/call instruction at pc, or the object in a mov. | 748 // the branch/call instruction at pc, or the object in a mov. |
728 INLINE(static Address constant_pool_entry_address( | 749 INLINE(static Address constant_pool_entry_address( |
729 Address pc, ConstantPoolArray* constant_pool)); | 750 Address pc, ConstantPoolArray* constant_pool)); |
730 | 751 |
731 // Read/Modify the code target address in the branch/call instruction at pc. | 752 // Read/Modify the code target address in the branch/call instruction at pc. |
732 INLINE(static Address target_address_at(Address pc, | 753 INLINE(static Address target_address_at(Address pc, |
733 ConstantPoolArray* constant_pool)); | 754 ConstantPoolArray* constant_pool)); |
734 INLINE(static void set_target_address_at(Address pc, | 755 INLINE(static void set_target_address_at(Address pc, |
735 ConstantPoolArray* constant_pool, | 756 ConstantPoolArray* constant_pool, |
(...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } | 1373 static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); } |
1353 static void instr_at_put(byte* pc, Instr instr) { | 1374 static void instr_at_put(byte* pc, Instr instr) { |
1354 *reinterpret_cast<Instr*>(pc) = instr; | 1375 *reinterpret_cast<Instr*>(pc) = instr; |
1355 } | 1376 } |
1356 static Condition GetCondition(Instr instr); | 1377 static Condition GetCondition(Instr instr); |
1357 static bool IsBranch(Instr instr); | 1378 static bool IsBranch(Instr instr); |
1358 static int GetBranchOffset(Instr instr); | 1379 static int GetBranchOffset(Instr instr); |
1359 static bool IsLdrRegisterImmediate(Instr instr); | 1380 static bool IsLdrRegisterImmediate(Instr instr); |
1360 static bool IsVldrDRegisterImmediate(Instr instr); | 1381 static bool IsVldrDRegisterImmediate(Instr instr); |
1361 static Instr GetConsantPoolLoadPattern(); | 1382 static Instr GetConsantPoolLoadPattern(); |
| 1383 static Instr GetConsantPoolLoadMask(); |
| 1384 static bool IsLdrPpRegOffset(Instr instr); |
| 1385 static Instr GetLdrPpRegOffsetPattern(); |
1362 static bool IsLdrPpImmediateOffset(Instr instr); | 1386 static bool IsLdrPpImmediateOffset(Instr instr); |
1363 static bool IsVldrDPpImmediateOffset(Instr instr); | 1387 static bool IsVldrDPpImmediateOffset(Instr instr); |
1364 static int GetLdrRegisterImmediateOffset(Instr instr); | 1388 static int GetLdrRegisterImmediateOffset(Instr instr); |
1365 static int GetVldrDRegisterImmediateOffset(Instr instr); | 1389 static int GetVldrDRegisterImmediateOffset(Instr instr); |
1366 static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset); | 1390 static Instr SetLdrRegisterImmediateOffset(Instr instr, int offset); |
1367 static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset); | 1391 static Instr SetVldrDRegisterImmediateOffset(Instr instr, int offset); |
1368 static bool IsStrRegisterImmediate(Instr instr); | 1392 static bool IsStrRegisterImmediate(Instr instr); |
1369 static Instr SetStrRegisterImmediateOffset(Instr instr, int offset); | 1393 static Instr SetStrRegisterImmediateOffset(Instr instr, int offset); |
1370 static bool IsAddRegisterImmediate(Instr instr); | 1394 static bool IsAddRegisterImmediate(Instr instr); |
1371 static Instr SetAddRegisterImmediateOffset(Instr instr, int offset); | 1395 static Instr SetAddRegisterImmediateOffset(Instr instr, int offset); |
(...skipping 10 matching lines...) Expand all Loading... |
1382 static bool IsVldrDPcImmediateOffset(Instr instr); | 1406 static bool IsVldrDPcImmediateOffset(Instr instr); |
1383 static bool IsBlxReg(Instr instr); | 1407 static bool IsBlxReg(Instr instr); |
1384 static bool IsBlxIp(Instr instr); | 1408 static bool IsBlxIp(Instr instr); |
1385 static bool IsTstImmediate(Instr instr); | 1409 static bool IsTstImmediate(Instr instr); |
1386 static bool IsCmpRegister(Instr instr); | 1410 static bool IsCmpRegister(Instr instr); |
1387 static bool IsCmpImmediate(Instr instr); | 1411 static bool IsCmpImmediate(Instr instr); |
1388 static Register GetCmpImmediateRegister(Instr instr); | 1412 static Register GetCmpImmediateRegister(Instr instr); |
1389 static int GetCmpImmediateRawImmediate(Instr instr); | 1413 static int GetCmpImmediateRawImmediate(Instr instr); |
1390 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); | 1414 static bool IsNop(Instr instr, int type = NON_MARKING_NOP); |
1391 static bool IsMovT(Instr instr); | 1415 static bool IsMovT(Instr instr); |
| 1416 static Instr GetMovTPattern(); |
1392 static bool IsMovW(Instr instr); | 1417 static bool IsMovW(Instr instr); |
| 1418 static Instr GetMovWPattern(); |
| 1419 static Instr EncodeMovwImmediate(uint32_t immediate); |
| 1420 static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate); |
1393 | 1421 |
1394 // Constants in pools are accessed via pc relative addressing, which can | 1422 // Constants in pools are accessed via pc relative addressing, which can |
1395 // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point | 1423 // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point |
1396 // PC-relative loads, thereby defining a maximum distance between the | 1424 // PC-relative loads, thereby defining a maximum distance between the |
1397 // instruction and the accessed constant. | 1425 // instruction and the accessed constant. |
1398 static const int kMaxDistToIntPool = 4*KB; | 1426 static const int kMaxDistToIntPool = 4*KB; |
1399 static const int kMaxDistToFPPool = 1*KB; | 1427 static const int kMaxDistToFPPool = 1*KB; |
1400 // All relocations could be integer, it therefore acts as the limit. | 1428 // All relocations could be integer, it therefore acts as the limit. |
1401 static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize; | 1429 static const int kMaxNumPending32RelocInfo = kMaxDistToIntPool/kInstrSize; |
1402 static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize; | 1430 static const int kMaxNumPending64RelocInfo = kMaxDistToFPPool/kInstrSize; |
1403 | 1431 |
1404 // Postpone the generation of the constant pool for the specified number of | 1432 // Postpone the generation of the constant pool for the specified number of |
1405 // instructions. | 1433 // instructions. |
1406 void BlockConstPoolFor(int instructions); | 1434 void BlockConstPoolFor(int instructions); |
1407 | 1435 |
1408 // Check if is time to emit a constant pool. | 1436 // Check if is time to emit a constant pool. |
1409 void CheckConstPool(bool force_emit, bool require_jump); | 1437 void CheckConstPool(bool force_emit, bool require_jump); |
1410 | 1438 |
1411 // Allocate a constant pool of the correct size for the generated code. | 1439 // Allocate a constant pool of the correct size for the generated code. |
1412 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); | 1440 Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate); |
1413 | 1441 |
1414 // Generate the constant pool for the generated code. | 1442 // Generate the constant pool for the generated code. |
1415 void PopulateConstantPool(ConstantPoolArray* constant_pool); | 1443 void PopulateConstantPool(ConstantPoolArray* constant_pool); |
1416 | 1444 |
1417 bool can_use_constant_pool() const { | 1445 bool is_constant_pool_available() const { |
1418 return is_constant_pool_available() && !constant_pool_full_; | 1446 return constant_pool_available_; |
1419 } | 1447 } |
1420 | 1448 |
1421 void set_constant_pool_full() { | 1449 bool use_extended_constant_pool() const { |
1422 constant_pool_full_ = true; | 1450 return constant_pool_builder_.current_section() == |
| 1451 ConstantPoolArray::EXTENDED_SECTION; |
1423 } | 1452 } |
1424 | 1453 |
| 1454 |
1425 protected: | 1455 protected: |
1426 // Relocation for a type-recording IC has the AST id added to it. This | 1456 // Relocation for a type-recording IC has the AST id added to it. This |
1427 // member variable is a way to pass the information from the call site to | 1457 // member variable is a way to pass the information from the call site to |
1428 // the relocation info. | 1458 // the relocation info. |
1429 TypeFeedbackId recorded_ast_id_; | 1459 TypeFeedbackId recorded_ast_id_; |
1430 | 1460 |
1431 int buffer_space() const { return reloc_info_writer.pos() - pc_; } | 1461 int buffer_space() const { return reloc_info_writer.pos() - pc_; } |
1432 | 1462 |
1433 // Decode branch instruction at pos and return branch target pos | 1463 // Decode branch instruction at pos and return branch target pos |
1434 int target_at(int pos); | 1464 int target_at(int pos); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1468 // trigger a check. | 1498 // trigger a check. |
1469 next_buffer_check_ = no_const_pool_before_; | 1499 next_buffer_check_ = no_const_pool_before_; |
1470 } | 1500 } |
1471 } | 1501 } |
1472 | 1502 |
1473 bool is_const_pool_blocked() const { | 1503 bool is_const_pool_blocked() const { |
1474 return (const_pool_blocked_nesting_ > 0) || | 1504 return (const_pool_blocked_nesting_ > 0) || |
1475 (pc_offset() < no_const_pool_before_); | 1505 (pc_offset() < no_const_pool_before_); |
1476 } | 1506 } |
1477 | 1507 |
1478 bool is_constant_pool_available() const { | |
1479 return constant_pool_available_; | |
1480 } | |
1481 | |
1482 void set_constant_pool_available(bool available) { | 1508 void set_constant_pool_available(bool available) { |
1483 constant_pool_available_ = available; | 1509 constant_pool_available_ = available; |
1484 } | 1510 } |
1485 | 1511 |
1486 private: | 1512 private: |
1487 int next_buffer_check_; // pc offset of next buffer check | 1513 int next_buffer_check_; // pc offset of next buffer check |
1488 | 1514 |
1489 // Code generation | 1515 // Code generation |
1490 // The relocation writer's position is at least kGap bytes below the end of | 1516 // The relocation writer's position is at least kGap bytes below the end of |
1491 // the generated instructions. This is so that multi-instruction sequences do | 1517 // the generated instructions. This is so that multi-instruction sequences do |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1541 int num_pending_64_bit_reloc_info_; | 1567 int num_pending_64_bit_reloc_info_; |
1542 | 1568 |
1543 ConstantPoolBuilder constant_pool_builder_; | 1569 ConstantPoolBuilder constant_pool_builder_; |
1544 | 1570 |
1545 // The bound position, before this we cannot do instruction elimination. | 1571 // The bound position, before this we cannot do instruction elimination. |
1546 int last_bound_pos_; | 1572 int last_bound_pos_; |
1547 | 1573 |
1548 // Indicates whether the constant pool can be accessed, which is only possible | 1574 // Indicates whether the constant pool can be accessed, which is only possible |
1549 // if the pp register points to the current code object's constant pool. | 1575 // if the pp register points to the current code object's constant pool. |
1550 bool constant_pool_available_; | 1576 bool constant_pool_available_; |
1551 // Indicates whether the constant pool is too full to accept new entries due | |
1552 // to the ldr instruction's limitted immediate offset range. | |
1553 bool constant_pool_full_; | |
1554 | 1577 |
1555 // Code emission | 1578 // Code emission |
1556 inline void CheckBuffer(); | 1579 inline void CheckBuffer(); |
1557 void GrowBuffer(); | 1580 void GrowBuffer(); |
1558 inline void emit(Instr x); | 1581 inline void emit(Instr x); |
1559 | 1582 |
1560 // 32-bit immediate values | 1583 // 32-bit immediate values |
1561 void move_32_bit_immediate(Register rd, | 1584 void move_32_bit_immediate(Register rd, |
1562 const Operand& x, | 1585 const Operand& x, |
1563 Condition cond = al); | 1586 Condition cond = al); |
(...skipping 11 matching lines...) Expand all Loading... |
1575 void next(Label* L); | 1598 void next(Label* L); |
1576 | 1599 |
1577 enum UseConstantPoolMode { | 1600 enum UseConstantPoolMode { |
1578 USE_CONSTANT_POOL, | 1601 USE_CONSTANT_POOL, |
1579 DONT_USE_CONSTANT_POOL | 1602 DONT_USE_CONSTANT_POOL |
1580 }; | 1603 }; |
1581 | 1604 |
1582 // Record reloc info for current pc_ | 1605 // Record reloc info for current pc_ |
1583 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); | 1606 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
1584 void RecordRelocInfo(const RelocInfo& rinfo); | 1607 void RecordRelocInfo(const RelocInfo& rinfo); |
1585 void ConstantPoolAddEntry(const RelocInfo& rinfo); | 1608 ConstantPoolArray::LayoutSection ConstantPoolAddEntry(const RelocInfo& rinfo); |
1586 | 1609 |
1587 friend class RelocInfo; | 1610 friend class RelocInfo; |
1588 friend class CodePatcher; | 1611 friend class CodePatcher; |
1589 friend class BlockConstPoolScope; | 1612 friend class BlockConstPoolScope; |
1590 friend class FrameAndConstantPoolScope; | 1613 friend class FrameAndConstantPoolScope; |
1591 friend class ConstantPoolUnavailableScope; | 1614 friend class ConstantPoolUnavailableScope; |
1592 | 1615 |
1593 PositionsRecorder positions_recorder_; | 1616 PositionsRecorder positions_recorder_; |
1594 friend class PositionsRecorder; | 1617 friend class PositionsRecorder; |
1595 friend class EnsureSpace; | 1618 friend class EnsureSpace; |
1596 }; | 1619 }; |
1597 | 1620 |
1598 | 1621 |
1599 class EnsureSpace BASE_EMBEDDED { | 1622 class EnsureSpace BASE_EMBEDDED { |
1600 public: | 1623 public: |
1601 explicit EnsureSpace(Assembler* assembler) { | 1624 explicit EnsureSpace(Assembler* assembler) { |
1602 assembler->CheckBuffer(); | 1625 assembler->CheckBuffer(); |
1603 } | 1626 } |
1604 }; | 1627 }; |
1605 | 1628 |
1606 | 1629 |
1607 } } // namespace v8::internal | 1630 } } // namespace v8::internal |
1608 | 1631 |
1609 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1632 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
OLD | NEW |