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