OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ | 5 #ifndef V8_ARM64_ASSEMBLER_ARM64_H_ |
6 #define V8_ARM64_ASSEMBLER_ARM64_H_ | 6 #define V8_ARM64_ASSEMBLER_ARM64_H_ |
7 | 7 |
8 #include <list> | 8 #include <list> |
9 #include <map> | 9 #include <map> |
10 | 10 |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 | 592 |
593 // AAPCS64 callee-saved registers. | 593 // AAPCS64 callee-saved registers. |
594 #define kCalleeSaved CPURegList::GetCalleeSaved() | 594 #define kCalleeSaved CPURegList::GetCalleeSaved() |
595 #define kCalleeSavedFP CPURegList::GetCalleeSavedFP() | 595 #define kCalleeSavedFP CPURegList::GetCalleeSavedFP() |
596 | 596 |
597 | 597 |
598 // AAPCS64 caller-saved registers. Note that this includes lr. | 598 // AAPCS64 caller-saved registers. Note that this includes lr. |
599 #define kCallerSaved CPURegList::GetCallerSaved() | 599 #define kCallerSaved CPURegList::GetCallerSaved() |
600 #define kCallerSavedFP CPURegList::GetCallerSavedFP() | 600 #define kCallerSavedFP CPURegList::GetCallerSavedFP() |
601 | 601 |
| 602 // ----------------------------------------------------------------------------- |
| 603 // Immediates. |
| 604 class Immediate { |
| 605 public: |
| 606 template<typename T> |
| 607 inline explicit Immediate(Handle<T> handle); |
| 608 |
| 609 // This is allowed to be an implicit constructor because Immediate is |
| 610 // a wrapper class that doesn't normally perform any type conversion. |
| 611 template<typename T> |
| 612 inline Immediate(T value); // NOLINT(runtime/explicit) |
| 613 |
| 614 template<typename T> |
| 615 inline Immediate(T value, RelocInfo::Mode rmode); |
| 616 |
| 617 int64_t value() const { return value_; } |
| 618 RelocInfo::Mode rmode() const { return rmode_; } |
| 619 |
| 620 private: |
| 621 void InitializeHandle(Handle<Object> value); |
| 622 |
| 623 int64_t value_; |
| 624 RelocInfo::Mode rmode_; |
| 625 }; |
| 626 |
602 | 627 |
603 // ----------------------------------------------------------------------------- | 628 // ----------------------------------------------------------------------------- |
604 // Operands. | 629 // Operands. |
605 const int kSmiShift = kSmiTagSize + kSmiShiftSize; | 630 const int kSmiShift = kSmiTagSize + kSmiShiftSize; |
606 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; | 631 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; |
607 | 632 |
608 // Represents an operand in a machine instruction. | 633 // Represents an operand in a machine instruction. |
609 class Operand { | 634 class Operand { |
610 // TODO(all): If necessary, study more in details which methods | 635 // TODO(all): If necessary, study more in details which methods |
611 // TODO(all): should be inlined or not. | 636 // TODO(all): should be inlined or not. |
(...skipping 15 matching lines...) Expand all Loading... |
627 unsigned shift_amount = 0); | 652 unsigned shift_amount = 0); |
628 | 653 |
629 template<typename T> | 654 template<typename T> |
630 inline explicit Operand(Handle<T> handle); | 655 inline explicit Operand(Handle<T> handle); |
631 | 656 |
632 // Implicit constructor for all int types, ExternalReference, and Smi. | 657 // Implicit constructor for all int types, ExternalReference, and Smi. |
633 template<typename T> | 658 template<typename T> |
634 inline Operand(T t); // NOLINT(runtime/explicit) | 659 inline Operand(T t); // NOLINT(runtime/explicit) |
635 | 660 |
636 // Implicit constructor for int types. | 661 // Implicit constructor for int types. |
637 template<typename int_t> | 662 template<typename T> |
638 inline Operand(int_t t, RelocInfo::Mode rmode); | 663 inline Operand(T t, RelocInfo::Mode rmode); |
639 | 664 |
640 inline bool IsImmediate() const; | 665 inline bool IsImmediate() const; |
641 inline bool IsShiftedRegister() const; | 666 inline bool IsShiftedRegister() const; |
642 inline bool IsExtendedRegister() const; | 667 inline bool IsExtendedRegister() const; |
643 inline bool IsZero() const; | 668 inline bool IsZero() const; |
644 | 669 |
645 // This returns an LSL shift (<= 4) operand as an equivalent extend operand, | 670 // This returns an LSL shift (<= 4) operand as an equivalent extend operand, |
646 // which helps in the encoding of instructions that use the stack pointer. | 671 // which helps in the encoding of instructions that use the stack pointer. |
647 inline Operand ToExtendedRegister() const; | 672 inline Operand ToExtendedRegister() const; |
648 | 673 |
649 inline int64_t immediate() const; | 674 inline Immediate immediate() const; |
| 675 inline int64_t ImmediateValue() const; |
650 inline Register reg() const; | 676 inline Register reg() const; |
651 inline Shift shift() const; | 677 inline Shift shift() const; |
652 inline Extend extend() const; | 678 inline Extend extend() const; |
653 inline unsigned shift_amount() const; | 679 inline unsigned shift_amount() const; |
654 | 680 |
655 // Relocation information. | 681 // Relocation information. |
656 RelocInfo::Mode rmode() const { return rmode_; } | |
657 void set_rmode(RelocInfo::Mode rmode) { rmode_ = rmode; } | |
658 bool NeedsRelocation(const Assembler* assembler) const; | 682 bool NeedsRelocation(const Assembler* assembler) const; |
659 | 683 |
660 // Helpers | 684 // Helpers |
661 inline static Operand UntagSmi(Register smi); | 685 inline static Operand UntagSmi(Register smi); |
662 inline static Operand UntagSmiAndScale(Register smi, int scale); | 686 inline static Operand UntagSmiAndScale(Register smi, int scale); |
663 | 687 |
664 private: | 688 private: |
665 void initialize_handle(Handle<Object> value); | 689 Immediate immediate_; |
666 int64_t immediate_; | |
667 Register reg_; | 690 Register reg_; |
668 Shift shift_; | 691 Shift shift_; |
669 Extend extend_; | 692 Extend extend_; |
670 unsigned shift_amount_; | 693 unsigned shift_amount_; |
671 RelocInfo::Mode rmode_; | |
672 }; | 694 }; |
673 | 695 |
674 | 696 |
675 // MemOperand represents a memory operand in a load or store instruction. | 697 // MemOperand represents a memory operand in a load or store instruction. |
676 class MemOperand { | 698 class MemOperand { |
677 public: | 699 public: |
678 inline explicit MemOperand(); | 700 inline explicit MemOperand(); |
679 inline explicit MemOperand(Register base, | 701 inline explicit MemOperand(Register base, |
680 ptrdiff_t offset = 0, | 702 ptrdiff_t offset = 0, |
681 AddrMode addrmode = Offset); | 703 AddrMode addrmode = Offset); |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1362 // Bit count, bit reverse and endian reverse. | 1384 // Bit count, bit reverse and endian reverse. |
1363 void rbit(const Register& rd, const Register& rn); | 1385 void rbit(const Register& rd, const Register& rn); |
1364 void rev16(const Register& rd, const Register& rn); | 1386 void rev16(const Register& rd, const Register& rn); |
1365 void rev32(const Register& rd, const Register& rn); | 1387 void rev32(const Register& rd, const Register& rn); |
1366 void rev(const Register& rd, const Register& rn); | 1388 void rev(const Register& rd, const Register& rn); |
1367 void clz(const Register& rd, const Register& rn); | 1389 void clz(const Register& rd, const Register& rn); |
1368 void cls(const Register& rd, const Register& rn); | 1390 void cls(const Register& rd, const Register& rn); |
1369 | 1391 |
1370 // Memory instructions. | 1392 // Memory instructions. |
1371 | 1393 |
1372 // Load literal from pc + offset_from_pc. | |
1373 void LoadLiteral(const CPURegister& rt, int offset_from_pc); | |
1374 | |
1375 // Load integer or FP register. | 1394 // Load integer or FP register. |
1376 void ldr(const CPURegister& rt, const MemOperand& src); | 1395 void ldr(const CPURegister& rt, const MemOperand& src); |
1377 | 1396 |
1378 // Store integer or FP register. | 1397 // Store integer or FP register. |
1379 void str(const CPURegister& rt, const MemOperand& dst); | 1398 void str(const CPURegister& rt, const MemOperand& dst); |
1380 | 1399 |
1381 // Load word with sign extension. | 1400 // Load word with sign extension. |
1382 void ldrsw(const Register& rt, const MemOperand& src); | 1401 void ldrsw(const Register& rt, const MemOperand& src); |
1383 | 1402 |
1384 // Load byte. | 1403 // Load byte. |
(...skipping 26 matching lines...) Expand all Loading... |
1411 void ldpsw(const Register& rt, const Register& rt2, const MemOperand& src); | 1430 void ldpsw(const Register& rt, const Register& rt2, const MemOperand& src); |
1412 | 1431 |
1413 // Load integer or FP register pair, non-temporal. | 1432 // Load integer or FP register pair, non-temporal. |
1414 void ldnp(const CPURegister& rt, const CPURegister& rt2, | 1433 void ldnp(const CPURegister& rt, const CPURegister& rt2, |
1415 const MemOperand& src); | 1434 const MemOperand& src); |
1416 | 1435 |
1417 // Store integer or FP register pair, non-temporal. | 1436 // Store integer or FP register pair, non-temporal. |
1418 void stnp(const CPURegister& rt, const CPURegister& rt2, | 1437 void stnp(const CPURegister& rt, const CPURegister& rt2, |
1419 const MemOperand& dst); | 1438 const MemOperand& dst); |
1420 | 1439 |
| 1440 // Load literal to register from a pc relative address. |
| 1441 void ldr_pcrel(const CPURegister& rt, int imm19); |
| 1442 |
1421 // Load literal to register. | 1443 // Load literal to register. |
1422 void ldr(const Register& rt, uint64_t imm); | 1444 void ldr(const CPURegister& rt, const Immediate& imm); |
1423 | |
1424 // Load literal to FP register. | |
1425 void ldr(const FPRegister& ft, double imm); | |
1426 void ldr(const FPRegister& ft, float imm); | |
1427 | 1445 |
1428 // Move instructions. The default shift of -1 indicates that the move | 1446 // Move instructions. The default shift of -1 indicates that the move |
1429 // instruction will calculate an appropriate 16-bit immediate and left shift | 1447 // instruction will calculate an appropriate 16-bit immediate and left shift |
1430 // that is equal to the 64-bit immediate argument. If an explicit left shift | 1448 // that is equal to the 64-bit immediate argument. If an explicit left shift |
1431 // is specified (0, 16, 32 or 48), the immediate must be a 16-bit value. | 1449 // is specified (0, 16, 32 or 48), the immediate must be a 16-bit value. |
1432 // | 1450 // |
1433 // For movk, an explicit shift can be used to indicate which half word should | 1451 // For movk, an explicit shift can be used to indicate which half word should |
1434 // be overwritten, eg. movk(x0, 0, 0) will overwrite the least-significant | 1452 // be overwritten, eg. movk(x0, 0, 0) will overwrite the least-significant |
1435 // half word with zero, whereas movk(x0, 0, 48) will overwrite the | 1453 // half word with zero, whereas movk(x0, 0, 48) will overwrite the |
1436 // most-significant. | 1454 // most-significant. |
(...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1834 // If need_protection is true, the veneers are protected by a branch jumping | 1852 // If need_protection is true, the veneers are protected by a branch jumping |
1835 // over the code. | 1853 // over the code. |
1836 void EmitVeneers(bool force_emit, bool need_protection, | 1854 void EmitVeneers(bool force_emit, bool need_protection, |
1837 int margin = kVeneerDistanceMargin); | 1855 int margin = kVeneerDistanceMargin); |
1838 void EmitVeneersGuard() { EmitPoolGuard(); } | 1856 void EmitVeneersGuard() { EmitPoolGuard(); } |
1839 // Checks whether veneers need to be emitted at this point. | 1857 // Checks whether veneers need to be emitted at this point. |
1840 // If force_emit is set, a veneer is generated for *all* unresolved branches. | 1858 // If force_emit is set, a veneer is generated for *all* unresolved branches. |
1841 void CheckVeneerPool(bool force_emit, bool require_jump, | 1859 void CheckVeneerPool(bool force_emit, bool require_jump, |
1842 int margin = kVeneerDistanceMargin); | 1860 int margin = kVeneerDistanceMargin); |
1843 | 1861 |
1844 | |
1845 class BlockPoolsScope { | 1862 class BlockPoolsScope { |
1846 public: | 1863 public: |
1847 explicit BlockPoolsScope(Assembler* assem) : assem_(assem) { | 1864 explicit BlockPoolsScope(Assembler* assem) : assem_(assem) { |
1848 assem_->StartBlockPools(); | 1865 assem_->StartBlockPools(); |
1849 } | 1866 } |
1850 ~BlockPoolsScope() { | 1867 ~BlockPoolsScope() { |
1851 assem_->EndBlockPools(); | 1868 assem_->EndBlockPools(); |
1852 } | 1869 } |
1853 | 1870 |
1854 private: | 1871 private: |
1855 Assembler* assem_; | 1872 Assembler* assem_; |
1856 | 1873 |
1857 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope); | 1874 DISALLOW_IMPLICIT_CONSTRUCTORS(BlockPoolsScope); |
1858 }; | 1875 }; |
1859 | 1876 |
1860 // Available for constrained code generation scopes. Prefer | |
1861 // MacroAssembler::Mov() when possible. | |
1862 inline void LoadRelocated(const CPURegister& rt, const Operand& operand); | |
1863 | |
1864 protected: | 1877 protected: |
1865 inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const; | 1878 inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const; |
1866 | 1879 |
1867 void LoadStore(const CPURegister& rt, | 1880 void LoadStore(const CPURegister& rt, |
1868 const MemOperand& addr, | 1881 const MemOperand& addr, |
1869 LoadStoreOp op); | 1882 LoadStoreOp op); |
1870 static bool IsImmLSUnscaled(ptrdiff_t offset); | 1883 static bool IsImmLSUnscaled(ptrdiff_t offset); |
1871 static bool IsImmLSScaled(ptrdiff_t offset, LSDataSize size); | 1884 static bool IsImmLSScaled(ptrdiff_t offset, LSDataSize size); |
1872 | 1885 |
1873 void Logical(const Register& rd, | 1886 void Logical(const Register& rd, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1920 static inline LoadStoreOp LoadOpFor(const CPURegister& rt); | 1933 static inline LoadStoreOp LoadOpFor(const CPURegister& rt); |
1921 static inline LoadStorePairOp LoadPairOpFor(const CPURegister& rt, | 1934 static inline LoadStorePairOp LoadPairOpFor(const CPURegister& rt, |
1922 const CPURegister& rt2); | 1935 const CPURegister& rt2); |
1923 static inline LoadStoreOp StoreOpFor(const CPURegister& rt); | 1936 static inline LoadStoreOp StoreOpFor(const CPURegister& rt); |
1924 static inline LoadStorePairOp StorePairOpFor(const CPURegister& rt, | 1937 static inline LoadStorePairOp StorePairOpFor(const CPURegister& rt, |
1925 const CPURegister& rt2); | 1938 const CPURegister& rt2); |
1926 static inline LoadStorePairNonTemporalOp LoadPairNonTemporalOpFor( | 1939 static inline LoadStorePairNonTemporalOp LoadPairNonTemporalOpFor( |
1927 const CPURegister& rt, const CPURegister& rt2); | 1940 const CPURegister& rt, const CPURegister& rt2); |
1928 static inline LoadStorePairNonTemporalOp StorePairNonTemporalOpFor( | 1941 static inline LoadStorePairNonTemporalOp StorePairNonTemporalOpFor( |
1929 const CPURegister& rt, const CPURegister& rt2); | 1942 const CPURegister& rt, const CPURegister& rt2); |
| 1943 static inline LoadLiteralOp LoadLiteralOpFor(const CPURegister& rt); |
1930 | 1944 |
1931 // Remove the specified branch from the unbound label link chain. | 1945 // Remove the specified branch from the unbound label link chain. |
1932 // If available, a veneer for this label can be used for other branches in the | 1946 // If available, a veneer for this label can be used for other branches in the |
1933 // chain if the link chain cannot be fixed up without this branch. | 1947 // chain if the link chain cannot be fixed up without this branch. |
1934 void RemoveBranchFromLabelLinkChain(Instruction* branch, | 1948 void RemoveBranchFromLabelLinkChain(Instruction* branch, |
1935 Label* label, | 1949 Label* label, |
1936 Instruction* label_veneer = NULL); | 1950 Instruction* label_veneer = NULL); |
1937 | 1951 |
1938 private: | 1952 private: |
1939 // Instruction helpers. | 1953 // Instruction helpers. |
(...skipping 12 matching lines...) Expand all Loading... |
1952 FlagsUpdate S, | 1966 FlagsUpdate S, |
1953 Instr op); | 1967 Instr op); |
1954 void LoadStorePair(const CPURegister& rt, | 1968 void LoadStorePair(const CPURegister& rt, |
1955 const CPURegister& rt2, | 1969 const CPURegister& rt2, |
1956 const MemOperand& addr, | 1970 const MemOperand& addr, |
1957 LoadStorePairOp op); | 1971 LoadStorePairOp op); |
1958 void LoadStorePairNonTemporal(const CPURegister& rt, | 1972 void LoadStorePairNonTemporal(const CPURegister& rt, |
1959 const CPURegister& rt2, | 1973 const CPURegister& rt2, |
1960 const MemOperand& addr, | 1974 const MemOperand& addr, |
1961 LoadStorePairNonTemporalOp op); | 1975 LoadStorePairNonTemporalOp op); |
1962 // Register the relocation information for the operand and load its value | |
1963 // into rt. | |
1964 void LoadRelocatedValue(const CPURegister& rt, | |
1965 const Operand& operand, | |
1966 LoadLiteralOp op); | |
1967 void ConditionalSelect(const Register& rd, | 1976 void ConditionalSelect(const Register& rd, |
1968 const Register& rn, | 1977 const Register& rn, |
1969 const Register& rm, | 1978 const Register& rm, |
1970 Condition cond, | 1979 Condition cond, |
1971 ConditionalSelectOp op); | 1980 ConditionalSelectOp op); |
1972 void DataProcessing1Source(const Register& rd, | 1981 void DataProcessing1Source(const Register& rd, |
1973 const Register& rn, | 1982 const Register& rn, |
1974 DataProcessing1SourceOp op); | 1983 DataProcessing1SourceOp op); |
1975 void DataProcessing3Source(const Register& rd, | 1984 void DataProcessing3Source(const Register& rd, |
1976 const Register& rn, | 1985 const Register& rn, |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2238 class EnsureSpace BASE_EMBEDDED { | 2247 class EnsureSpace BASE_EMBEDDED { |
2239 public: | 2248 public: |
2240 explicit EnsureSpace(Assembler* assembler) { | 2249 explicit EnsureSpace(Assembler* assembler) { |
2241 assembler->CheckBufferSpace(); | 2250 assembler->CheckBufferSpace(); |
2242 } | 2251 } |
2243 }; | 2252 }; |
2244 | 2253 |
2245 } } // namespace v8::internal | 2254 } } // namespace v8::internal |
2246 | 2255 |
2247 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ | 2256 #endif // V8_ARM64_ASSEMBLER_ARM64_H_ |
OLD | NEW |