Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Side by Side Diff: src/a64/macro-assembler-a64.h

Issue 164793003: A64: Use a scope utility to allocate scratch registers. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/a64/lithium-codegen-a64.cc ('k') | src/a64/macro-assembler-a64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 // must be aligned to 16 bytes on entry and the total size of the specified 513 // must be aligned to 16 bytes on entry and the total size of the specified
514 // registers must also be a multiple of 16 bytes. 514 // registers must also be a multiple of 16 bytes.
515 // 515 //
516 // Even if the current stack pointer is not the system stack pointer (csp), 516 // Even if the current stack pointer is not the system stack pointer (csp),
517 // Push (and derived methods) will still modify the system stack pointer in 517 // Push (and derived methods) will still modify the system stack pointer in
518 // order to comply with ABI rules about accessing memory below the system 518 // order to comply with ABI rules about accessing memory below the system
519 // stack pointer. 519 // stack pointer.
520 // 520 //
521 // Other than the registers passed into Pop, the stack pointer and (possibly) 521 // Other than the registers passed into Pop, the stack pointer and (possibly)
522 // the system stack pointer, these methods do not modify any other registers. 522 // the system stack pointer, these methods do not modify any other registers.
523 // Scratch registers such as Tmp0() and Tmp1() are preserved.
524 void Push(const CPURegister& src0, const CPURegister& src1 = NoReg, 523 void Push(const CPURegister& src0, const CPURegister& src1 = NoReg,
525 const CPURegister& src2 = NoReg, const CPURegister& src3 = NoReg); 524 const CPURegister& src2 = NoReg, const CPURegister& src3 = NoReg);
526 void Pop(const CPURegister& dst0, const CPURegister& dst1 = NoReg, 525 void Pop(const CPURegister& dst0, const CPURegister& dst1 = NoReg,
527 const CPURegister& dst2 = NoReg, const CPURegister& dst3 = NoReg); 526 const CPURegister& dst2 = NoReg, const CPURegister& dst3 = NoReg);
528 527
529 // Alternative forms of Push and Pop, taking a RegList or CPURegList that 528 // Alternative forms of Push and Pop, taking a RegList or CPURegList that
530 // specifies the registers that are to be pushed or popped. Higher-numbered 529 // specifies the registers that are to be pushed or popped. Higher-numbered
531 // registers are associated with higher memory addresses (as in the A32 push 530 // registers are associated with higher memory addresses (as in the A32 push
532 // and pop instructions). 531 // and pop instructions).
533 // 532 //
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 // Floating-point registers are popped after general-purpose registers, and 738 // Floating-point registers are popped after general-purpose registers, and
740 // thus come from higher addresses. 739 // thus come from higher addresses.
741 // 740 //
742 // This method must not be called unless the current stack pointer (as set by 741 // This method must not be called unless the current stack pointer (as set by
743 // SetStackPointer) is the system stack pointer (csp), and is aligned to 742 // SetStackPointer) is the system stack pointer (csp), and is aligned to
744 // ActivationFrameAlignment(). 743 // ActivationFrameAlignment().
745 void PopCalleeSavedRegisters(); 744 void PopCalleeSavedRegisters();
746 745
747 // Set the current stack pointer, but don't generate any code. 746 // Set the current stack pointer, but don't generate any code.
748 inline void SetStackPointer(const Register& stack_pointer) { 747 inline void SetStackPointer(const Register& stack_pointer) {
749 ASSERT(!AreAliased(stack_pointer, Tmp0(), Tmp1())); 748 ASSERT(!TmpList()->IncludesAliasOf(stack_pointer));
750 sp_ = stack_pointer; 749 sp_ = stack_pointer;
751 } 750 }
752 751
753 // Return the current stack pointer, as set by SetStackPointer. 752 // Return the current stack pointer, as set by SetStackPointer.
754 inline const Register& StackPointer() const { 753 inline const Register& StackPointer() const {
755 return sp_; 754 return sp_;
756 } 755 }
757 756
758 // Align csp for a frame, as per ActivationFrameAlignment, and make it the 757 // Align csp for a frame, as per ActivationFrameAlignment, and make it the
759 // current stack pointer. 758 // current stack pointer.
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 Label* on_failed_conversion = NULL) { 932 Label* on_failed_conversion = NULL) {
934 ASSERT(as_int.Is64Bits()); 933 ASSERT(as_int.Is64Bits());
935 TryConvertDoubleToInt(as_int, value, scratch_d, on_successful_conversion, 934 TryConvertDoubleToInt(as_int, value, scratch_d, on_successful_conversion,
936 on_failed_conversion); 935 on_failed_conversion);
937 } 936 }
938 937
939 // ---- Object Utilities ---- 938 // ---- Object Utilities ----
940 939
941 // Copy fields from 'src' to 'dst', where both are tagged objects. 940 // Copy fields from 'src' to 'dst', where both are tagged objects.
942 // The 'temps' list is a list of X registers which can be used for scratch 941 // The 'temps' list is a list of X registers which can be used for scratch
943 // values. The temps list must include at least one register, and it must not 942 // values. The temps list must include at least one register.
944 // contain Tmp0() or Tmp1().
945 // 943 //
946 // Currently, CopyFields cannot make use of more than three registers from 944 // Currently, CopyFields cannot make use of more than three registers from
947 // the 'temps' list. 945 // the 'temps' list.
948 // 946 //
949 // As with several MacroAssembler methods, Tmp0() and Tmp1() will be used. 947 // CopyFields expects to be able to take at least two registers from
948 // MacroAssembler::TmpList().
950 void CopyFields(Register dst, Register src, CPURegList temps, unsigned count); 949 void CopyFields(Register dst, Register src, CPURegList temps, unsigned count);
951 950
952 // Copies a number of bytes from src to dst. All passed registers are 951 // Copies a number of bytes from src to dst. All passed registers are
953 // clobbered. On exit src and dst will point to the place just after where the 952 // clobbered. On exit src and dst will point to the place just after where the
954 // last byte was read or written and length will be zero. Hint may be used to 953 // last byte was read or written and length will be zero. Hint may be used to
955 // determine which is the most efficient algorithm to use for copying. 954 // determine which is the most efficient algorithm to use for copying.
956 void CopyBytes(Register dst, 955 void CopyBytes(Register dst,
957 Register src, 956 Register src,
958 Register length, 957 Register length,
959 Register scratch, 958 Register scratch,
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 1441
1443 // Test the bitfield of the heap object map with mask and set the condition 1442 // Test the bitfield of the heap object map with mask and set the condition
1444 // flags. The object register is preserved. 1443 // flags. The object register is preserved.
1445 void TestMapBitfield(Register object, uint64_t mask); 1444 void TestMapBitfield(Register object, uint64_t mask);
1446 1445
1447 // Load the elements kind field of an object, and return it in the result 1446 // Load the elements kind field of an object, and return it in the result
1448 // register. 1447 // register.
1449 void LoadElementsKind(Register result, Register object); 1448 void LoadElementsKind(Register result, Register object);
1450 1449
1451 // Compare the object in a register to a value from the root list. 1450 // Compare the object in a register to a value from the root list.
1452 // Uses the Tmp0() register as scratch.
1453 void CompareRoot(const Register& obj, Heap::RootListIndex index); 1451 void CompareRoot(const Register& obj, Heap::RootListIndex index);
1454 1452
1455 // Compare the object in a register to a value and jump if they are equal. 1453 // Compare the object in a register to a value and jump if they are equal.
1456 void JumpIfRoot(const Register& obj, 1454 void JumpIfRoot(const Register& obj,
1457 Heap::RootListIndex index, 1455 Heap::RootListIndex index,
1458 Label* if_equal); 1456 Label* if_equal);
1459 1457
1460 // Compare the object in a register to a value and jump if they are not equal. 1458 // Compare the object in a register to a value and jump if they are not equal.
1461 void JumpIfNotRoot(const Register& obj, 1459 void JumpIfNotRoot(const Register& obj,
1462 Heap::RootListIndex index, 1460 Heap::RootListIndex index,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 void EmitSeqStringSetCharCheck(Register string, 1547 void EmitSeqStringSetCharCheck(Register string,
1550 Register index, 1548 Register index,
1551 SeqStringSetCharCheckIndexType index_type, 1549 SeqStringSetCharCheckIndexType index_type,
1552 Register scratch, 1550 Register scratch,
1553 uint32_t encoding_mask); 1551 uint32_t encoding_mask);
1554 1552
1555 // Generate code for checking access rights - used for security checks 1553 // Generate code for checking access rights - used for security checks
1556 // on access to global objects across environments. The holder register 1554 // on access to global objects across environments. The holder register
1557 // is left untouched, whereas both scratch registers are clobbered. 1555 // is left untouched, whereas both scratch registers are clobbered.
1558 void CheckAccessGlobalProxy(Register holder_reg, 1556 void CheckAccessGlobalProxy(Register holder_reg,
1559 Register scratch, 1557 Register scratch1,
1558 Register scratch2,
1560 Label* miss); 1559 Label* miss);
1561 1560
1562 // Hash the interger value in 'key' register. 1561 // Hash the interger value in 'key' register.
1563 // It uses the same algorithm as ComputeIntegerHash in utils.h. 1562 // It uses the same algorithm as ComputeIntegerHash in utils.h.
1564 void GetNumberHash(Register key, Register scratch); 1563 void GetNumberHash(Register key, Register scratch);
1565 1564
1566 // Load value from the dictionary. 1565 // Load value from the dictionary.
1567 // 1566 //
1568 // elements - holds the slow-case elements of the receiver on entry. 1567 // elements - holds the slow-case elements of the receiver on entry.
1569 // Unchanged unless 'result' is the same register. 1568 // Unchanged unless 'result' is the same register.
(...skipping 11 matching lines...) Expand all
1581 Register result, 1580 Register result,
1582 Register scratch0, 1581 Register scratch0,
1583 Register scratch1, 1582 Register scratch1,
1584 Register scratch2, 1583 Register scratch2,
1585 Register scratch3); 1584 Register scratch3);
1586 1585
1587 // --------------------------------------------------------------------------- 1586 // ---------------------------------------------------------------------------
1588 // Frames. 1587 // Frames.
1589 1588
1590 // Activation support. 1589 // Activation support.
1591 // Note that Tmp0() and Tmp1() are used as a scratch registers. This is safe
1592 // because these methods are not used in Crankshaft.
1593 void EnterFrame(StackFrame::Type type); 1590 void EnterFrame(StackFrame::Type type);
1594 void LeaveFrame(StackFrame::Type type); 1591 void LeaveFrame(StackFrame::Type type);
1595 1592
1596 // Returns map with validated enum cache in object register. 1593 // Returns map with validated enum cache in object register.
1597 void CheckEnumCache(Register object, 1594 void CheckEnumCache(Register object,
1598 Register null_value, 1595 Register null_value,
1599 Register scratch0, 1596 Register scratch0,
1600 Register scratch1, 1597 Register scratch1,
1601 Register scratch2, 1598 Register scratch2,
1602 Register scratch3, 1599 Register scratch3,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 // * The stack pointer is reset to jssp. 1668 // * The stack pointer is reset to jssp.
1672 // 1669 //
1673 // The stack pointer must be csp on entry. 1670 // The stack pointer must be csp on entry.
1674 void LeaveExitFrame(bool save_doubles, 1671 void LeaveExitFrame(bool save_doubles,
1675 const Register& scratch, 1672 const Register& scratch,
1676 bool restore_context); 1673 bool restore_context);
1677 1674
1678 void LoadContext(Register dst, int context_chain_length); 1675 void LoadContext(Register dst, int context_chain_length);
1679 1676
1680 // Emit code for a flooring division by a constant. The dividend register is 1677 // Emit code for a flooring division by a constant. The dividend register is
1681 // unchanged and Tmp0() gets clobbered. Dividend and result must be different. 1678 // unchanged. Dividend and result must be different.
1682 void FlooringDiv(Register result, Register dividend, int32_t divisor); 1679 void FlooringDiv(Register result, Register dividend, int32_t divisor);
1683 1680
1684 // --------------------------------------------------------------------------- 1681 // ---------------------------------------------------------------------------
1685 // StatsCounter support 1682 // StatsCounter support
1686 1683
1687 void SetCounter(StatsCounter* counter, int value, Register scratch1, 1684 void SetCounter(StatsCounter* counter, int value, Register scratch1,
1688 Register scratch2); 1685 Register scratch2);
1689 void IncrementCounter(StatsCounter* counter, int value, Register scratch1, 1686 void IncrementCounter(StatsCounter* counter, int value, Register scratch1,
1690 Register scratch2); 1687 Register scratch2);
1691 void DecrementCounter(StatsCounter* counter, int value, Register scratch1, 1688 void DecrementCounter(StatsCounter* counter, int value, Register scratch1,
1692 Register scratch2); 1689 Register scratch2);
1693 1690
1694 // --------------------------------------------------------------------------- 1691 // ---------------------------------------------------------------------------
1695 // Garbage collector support (GC). 1692 // Garbage collector support (GC).
1696 1693
1697 enum RememberedSetFinalAction { 1694 enum RememberedSetFinalAction {
1698 kReturnAtEnd, 1695 kReturnAtEnd,
1699 kFallThroughAtEnd 1696 kFallThroughAtEnd
1700 }; 1697 };
1701 1698
1702 // Record in the remembered set the fact that we have a pointer to new space 1699 // Record in the remembered set the fact that we have a pointer to new space
1703 // at the address pointed to by the addr register. Only works if addr is not 1700 // at the address pointed to by the addr register. Only works if addr is not
1704 // in new space. 1701 // in new space.
1705 void RememberedSetHelper(Register object, // Used for debug code. 1702 void RememberedSetHelper(Register object, // Used for debug code.
1706 Register addr, 1703 Register addr,
1707 Register scratch, 1704 Register scratch1,
1708 SaveFPRegsMode save_fp, 1705 SaveFPRegsMode save_fp,
1709 RememberedSetFinalAction and_then); 1706 RememberedSetFinalAction and_then);
1710 1707
1711 // Push and pop the registers that can hold pointers, as defined by the 1708 // Push and pop the registers that can hold pointers, as defined by the
1712 // RegList constant kSafepointSavedRegisters. 1709 // RegList constant kSafepointSavedRegisters.
1713 void PushSafepointRegisters(); 1710 void PushSafepointRegisters();
1714 void PopSafepointRegisters(); 1711 void PopSafepointRegisters();
1715 1712
1716 void PushSafepointFPRegisters(); 1713 void PushSafepointFPRegisters();
1717 void PopSafepointFPRegisters(); 1714 void PopSafepointFPRegisters();
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1882 void Abort(BailoutReason reason); 1879 void Abort(BailoutReason reason);
1883 1880
1884 // Conditionally load the cached Array transitioned map of type 1881 // Conditionally load the cached Array transitioned map of type
1885 // transitioned_kind from the native context if the map in register 1882 // transitioned_kind from the native context if the map in register
1886 // map_in_out is the cached Array map in the native context of 1883 // map_in_out is the cached Array map in the native context of
1887 // expected_kind. 1884 // expected_kind.
1888 void LoadTransitionedArrayMapConditional( 1885 void LoadTransitionedArrayMapConditional(
1889 ElementsKind expected_kind, 1886 ElementsKind expected_kind,
1890 ElementsKind transitioned_kind, 1887 ElementsKind transitioned_kind,
1891 Register map_in_out, 1888 Register map_in_out,
1892 Register scratch, 1889 Register scratch1,
1890 Register scratch2,
1893 Label* no_map_match); 1891 Label* no_map_match);
1894 1892
1895 void LoadGlobalFunction(int index, Register function); 1893 void LoadGlobalFunction(int index, Register function);
1896 1894
1897 // Load the initial map from the global function. The registers function and 1895 // Load the initial map from the global function. The registers function and
1898 // map can be the same, function is then overwritten. 1896 // map can be the same, function is then overwritten.
1899 void LoadGlobalFunctionInitialMap(Register function, 1897 void LoadGlobalFunctionInitialMap(Register function,
1900 Register map, 1898 Register map,
1901 Register scratch); 1899 Register scratch);
1902 1900
1903 // -------------------------------------------------------------------------- 1901 CPURegList* TmpList() { return &tmp_list_; }
1904 // Set the registers used internally by the MacroAssembler as scratch 1902 CPURegList* FPTmpList() { return &fptmp_list_; }
1905 // registers. These registers are used to implement behaviours which are not
1906 // directly supported by A64, and where an intermediate result is required.
1907 //
1908 // Both tmp0 and tmp1 may be set to any X register except for xzr, sp,
1909 // and StackPointer(). Also, they must not be the same register (though they
1910 // may both be NoReg).
1911 //
1912 // It is valid to set either or both of these registers to NoReg if you don't
1913 // want the MacroAssembler to use any scratch registers. In a debug build, the
1914 // Assembler will assert that any registers it uses are valid. Be aware that
1915 // this check is not present in release builds. If this is a problem, use the
1916 // Assembler directly.
1917 void SetScratchRegisters(const Register& tmp0, const Register& tmp1) {
1918 // V8 assumes the macro assembler uses ip0 and ip1 as temp registers.
1919 ASSERT(tmp0.IsNone() || tmp0.Is(ip0));
1920 ASSERT(tmp1.IsNone() || tmp1.Is(ip1));
1921
1922 ASSERT(!AreAliased(xzr, csp, tmp0, tmp1));
1923 ASSERT(!AreAliased(StackPointer(), tmp0, tmp1));
1924 tmp0_ = tmp0;
1925 tmp1_ = tmp1;
1926 }
1927
1928 const Register& Tmp0() const {
1929 return tmp0_;
1930 }
1931
1932 const Register& Tmp1() const {
1933 return tmp1_;
1934 }
1935
1936 const Register WTmp0() const {
1937 return Register::Create(tmp0_.code(), kWRegSize);
1938 }
1939
1940 const Register WTmp1() const {
1941 return Register::Create(tmp1_.code(), kWRegSize);
1942 }
1943
1944 void SetFPScratchRegister(const FPRegister& fptmp0) {
1945 fptmp0_ = fptmp0;
1946 }
1947
1948 const FPRegister& FPTmp0() const {
1949 return fptmp0_;
1950 }
1951
1952 const Register AppropriateTempFor(
1953 const Register& target,
1954 const CPURegister& forbidden = NoCPUReg) const {
1955 Register candidate = forbidden.Is(Tmp0()) ? Tmp1() : Tmp0();
1956 ASSERT(!candidate.Is(target));
1957 return Register::Create(candidate.code(), target.SizeInBits());
1958 }
1959
1960 const FPRegister AppropriateTempFor(
1961 const FPRegister& target,
1962 const CPURegister& forbidden = NoCPUReg) const {
1963 USE(forbidden);
1964 FPRegister candidate = FPTmp0();
1965 ASSERT(!candidate.Is(forbidden));
1966 ASSERT(!candidate.Is(target));
1967 return FPRegister::Create(candidate.code(), target.SizeInBits());
1968 }
1969 1903
1970 // Like printf, but print at run-time from generated code. 1904 // Like printf, but print at run-time from generated code.
1971 // 1905 //
1972 // The caller must ensure that arguments for floating-point placeholders 1906 // The caller must ensure that arguments for floating-point placeholders
1973 // (such as %e, %f or %g) are FPRegisters, and that arguments for integer 1907 // (such as %e, %f or %g) are FPRegisters, and that arguments for integer
1974 // placeholders are Registers. 1908 // placeholders are Registers.
1975 // 1909 //
1976 // A maximum of four arguments may be given to any single Printf call. The 1910 // A maximum of four arguments may be given to any single Printf call. The
1977 // arguments must be of the same type, but they do not need to have the same 1911 // arguments must be of the same type, but they do not need to have the same
1978 // size. 1912 // size.
1979 // 1913 //
1980 // The following registers cannot be printed: 1914 // The following registers cannot be printed:
1981 // Tmp0(), Tmp1(), StackPointer(), csp. 1915 // StackPointer(), csp.
1982 // 1916 //
1983 // This function automatically preserves caller-saved registers so that 1917 // This function automatically preserves caller-saved registers so that
1984 // calling code can use Printf at any point without having to worry about 1918 // calling code can use Printf at any point without having to worry about
1985 // corruption. The preservation mechanism generates a lot of code. If this is 1919 // corruption. The preservation mechanism generates a lot of code. If this is
1986 // a problem, preserve the important registers manually and then call 1920 // a problem, preserve the important registers manually and then call
1987 // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are 1921 // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are
1988 // implicitly preserved. 1922 // implicitly preserved.
1989 // 1923 //
1990 // Unlike many MacroAssembler functions, x8 and x9 are guaranteed to be 1924 // Unlike many MacroAssembler functions, x8 and x9 are guaranteed to be
1991 // preserved, and can be printed. This allows Printf to be used during debug 1925 // preserved, and can be printed. This allows Printf to be used during debug
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2056 1990
2057 // Jumps to found label if a prototype map has dictionary elements. 1991 // Jumps to found label if a prototype map has dictionary elements.
2058 void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0, 1992 void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
2059 Register scratch1, Label* found); 1993 Register scratch1, Label* found);
2060 1994
2061 private: 1995 private:
2062 // Helpers for CopyFields. 1996 // Helpers for CopyFields.
2063 // These each implement CopyFields in a different way. 1997 // These each implement CopyFields in a different way.
2064 void CopyFieldsLoopPairsHelper(Register dst, Register src, unsigned count, 1998 void CopyFieldsLoopPairsHelper(Register dst, Register src, unsigned count,
2065 Register scratch1, Register scratch2, 1999 Register scratch1, Register scratch2,
2066 Register scratch3); 2000 Register scratch3, Register scratch4,
2001 Register scratch5);
2067 void CopyFieldsUnrolledPairsHelper(Register dst, Register src, unsigned count, 2002 void CopyFieldsUnrolledPairsHelper(Register dst, Register src, unsigned count,
2068 Register scratch1, Register scratch2); 2003 Register scratch1, Register scratch2,
2004 Register scratch3, Register scratch4);
2069 void CopyFieldsUnrolledHelper(Register dst, Register src, unsigned count, 2005 void CopyFieldsUnrolledHelper(Register dst, Register src, unsigned count,
2070 Register scratch1); 2006 Register scratch1, Register scratch2,
2007 Register scratch3);
2071 2008
2072 // The actual Push and Pop implementations. These don't generate any code 2009 // The actual Push and Pop implementations. These don't generate any code
2073 // other than that required for the push or pop. This allows 2010 // other than that required for the push or pop. This allows
2074 // (Push|Pop)CPURegList to bundle together run-time assertions for a large 2011 // (Push|Pop)CPURegList to bundle together run-time assertions for a large
2075 // block of registers. 2012 // block of registers.
2076 // 2013 //
2077 // Note that size is per register, and is specified in bytes. 2014 // Note that size is per register, and is specified in bytes.
2078 void PushHelper(int count, int size, 2015 void PushHelper(int count, int size,
2079 const CPURegister& src0, const CPURegister& src1, 2016 const CPURegister& src0, const CPURegister& src1,
2080 const CPURegister& src2, const CPURegister& src3); 2017 const CPURegister& src2, const CPURegister& src3);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 // The purpose of this is to allow Aborts to be compiled whilst CEntryStub is 2078 // The purpose of this is to allow Aborts to be compiled whilst CEntryStub is
2142 // being generated. 2079 // being generated.
2143 bool use_real_aborts_; 2080 bool use_real_aborts_;
2144 2081
2145 // This handle will be patched with the code object on installation. 2082 // This handle will be patched with the code object on installation.
2146 Handle<Object> code_object_; 2083 Handle<Object> code_object_;
2147 2084
2148 // The register to use as a stack pointer for stack operations. 2085 // The register to use as a stack pointer for stack operations.
2149 Register sp_; 2086 Register sp_;
2150 2087
2151 // Scratch registers used internally by the MacroAssembler. 2088 // Scratch registers available for use by the MacroAssembler.
2152 Register tmp0_; 2089 CPURegList tmp_list_;
2153 Register tmp1_; 2090 CPURegList fptmp_list_;
2154 FPRegister fptmp0_;
2155 2091
2156 void InitializeNewString(Register string, 2092 void InitializeNewString(Register string,
2157 Register length, 2093 Register length,
2158 Heap::RootListIndex map_index, 2094 Heap::RootListIndex map_index,
2159 Register scratch1, 2095 Register scratch1,
2160 Register scratch2); 2096 Register scratch2);
2161 2097
2162 public: 2098 public:
2163 // Far branches resolving. 2099 // Far branches resolving.
2164 // 2100 //
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 private: 2161 private:
2226 MacroAssembler* masm_; 2162 MacroAssembler* masm_;
2227 #ifdef DEBUG 2163 #ifdef DEBUG
2228 size_t size_; 2164 size_t size_;
2229 Label start_; 2165 Label start_;
2230 bool previous_allow_macro_instructions_; 2166 bool previous_allow_macro_instructions_;
2231 #endif 2167 #endif
2232 }; 2168 };
2233 2169
2234 2170
2171 // This scope utility allows scratch registers to be managed safely. The
2172 // MacroAssembler's TmpList() (and FPTmpList()) is used as a pool of scratch
2173 // registers. These registers can be allocated on demand, and will be returned
2174 // at the end of the scope.
2175 //
2176 // When the scope ends, the MacroAssembler's lists will be restored to their
2177 // original state, even if the lists were modified by some other means.
2178 class UseScratchRegisterScope {
2179 public:
2180 explicit UseScratchRegisterScope(MacroAssembler* masm)
2181 : available_(masm->TmpList()),
2182 availablefp_(masm->FPTmpList()),
2183 old_available_(available_->list()),
2184 old_availablefp_(availablefp_->list()) {
2185 ASSERT(available_->type() == CPURegister::kRegister);
2186 ASSERT(availablefp_->type() == CPURegister::kFPRegister);
2187 }
2188
2189 ~UseScratchRegisterScope();
2190
2191 // Take a register from the appropriate temps list. It will be returned
2192 // automatically when the scope ends.
2193 Register AcquireW() { return AcquireNextAvailable(available_).W(); }
2194 Register AcquireX() { return AcquireNextAvailable(available_).X(); }
2195 FPRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); }
2196 FPRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); }
2197
2198 Register AcquireSameSizeAs(const Register& reg);
2199 FPRegister AcquireSameSizeAs(const FPRegister& reg);
2200
2201 private:
2202 static CPURegister AcquireNextAvailable(CPURegList* available);
2203
2204 // Available scratch registers.
2205 CPURegList* available_; // kRegister
2206 CPURegList* availablefp_; // kFPRegister
2207
2208 // The state of the available lists at the start of this scope.
2209 RegList old_available_; // kRegister
2210 RegList old_availablefp_; // kFPRegister
2211 };
2212
2213
2235 inline MemOperand ContextMemOperand(Register context, int index) { 2214 inline MemOperand ContextMemOperand(Register context, int index) {
2236 return MemOperand(context, Context::SlotOffset(index)); 2215 return MemOperand(context, Context::SlotOffset(index));
2237 } 2216 }
2238 2217
2239 inline MemOperand GlobalObjectMemOperand() { 2218 inline MemOperand GlobalObjectMemOperand() {
2240 return ContextMemOperand(cp, Context::GLOBAL_OBJECT_INDEX); 2219 return ContextMemOperand(cp, Context::GLOBAL_OBJECT_INDEX);
2241 } 2220 }
2242 2221
2243 2222
2244 // Encode and decode information about patchable inline SMI checks. 2223 // Encode and decode information about patchable inline SMI checks.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2295 #error "Unsupported option" 2274 #error "Unsupported option"
2296 #define CODE_COVERAGE_STRINGIFY(x) #x 2275 #define CODE_COVERAGE_STRINGIFY(x) #x
2297 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 2276 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
2298 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 2277 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
2299 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm-> 2278 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
2300 #else 2279 #else
2301 #define ACCESS_MASM(masm) masm-> 2280 #define ACCESS_MASM(masm) masm->
2302 #endif 2281 #endif
2303 2282
2304 #endif // V8_A64_MACRO_ASSEMBLER_A64_H_ 2283 #endif // V8_A64_MACRO_ASSEMBLER_A64_H_
OLDNEW
« no previous file with comments | « src/a64/lithium-codegen-a64.cc ('k') | src/a64/macro-assembler-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698