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

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: Address _all_ of the latest review comments. 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
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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 enum RememberedSetFinalAction { 1690 enum RememberedSetFinalAction {
1694 kReturnAtEnd, 1691 kReturnAtEnd,
1695 kFallThroughAtEnd 1692 kFallThroughAtEnd
1696 }; 1693 };
1697 1694
1698 // Record in the remembered set the fact that we have a pointer to new space 1695 // Record in the remembered set the fact that we have a pointer to new space
1699 // at the address pointed to by the addr register. Only works if addr is not 1696 // at the address pointed to by the addr register. Only works if addr is not
1700 // in new space. 1697 // in new space.
1701 void RememberedSetHelper(Register object, // Used for debug code. 1698 void RememberedSetHelper(Register object, // Used for debug code.
1702 Register addr, 1699 Register addr,
1703 Register scratch, 1700 Register scratch1,
1704 SaveFPRegsMode save_fp, 1701 SaveFPRegsMode save_fp,
1705 RememberedSetFinalAction and_then); 1702 RememberedSetFinalAction and_then);
1706 1703
1707 // Push and pop the registers that can hold pointers, as defined by the 1704 // Push and pop the registers that can hold pointers, as defined by the
1708 // RegList constant kSafepointSavedRegisters. 1705 // RegList constant kSafepointSavedRegisters.
1709 void PushSafepointRegisters(); 1706 void PushSafepointRegisters();
1710 void PopSafepointRegisters(); 1707 void PopSafepointRegisters();
1711 1708
1712 void PushSafepointFPRegisters(); 1709 void PushSafepointFPRegisters();
1713 void PopSafepointFPRegisters(); 1710 void PopSafepointFPRegisters();
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1878 void Abort(BailoutReason reason); 1875 void Abort(BailoutReason reason);
1879 1876
1880 // Conditionally load the cached Array transitioned map of type 1877 // Conditionally load the cached Array transitioned map of type
1881 // transitioned_kind from the native context if the map in register 1878 // transitioned_kind from the native context if the map in register
1882 // map_in_out is the cached Array map in the native context of 1879 // map_in_out is the cached Array map in the native context of
1883 // expected_kind. 1880 // expected_kind.
1884 void LoadTransitionedArrayMapConditional( 1881 void LoadTransitionedArrayMapConditional(
1885 ElementsKind expected_kind, 1882 ElementsKind expected_kind,
1886 ElementsKind transitioned_kind, 1883 ElementsKind transitioned_kind,
1887 Register map_in_out, 1884 Register map_in_out,
1888 Register scratch, 1885 Register scratch1,
1886 Register scratch2,
1889 Label* no_map_match); 1887 Label* no_map_match);
1890 1888
1891 void LoadGlobalFunction(int index, Register function); 1889 void LoadGlobalFunction(int index, Register function);
1892 1890
1893 // Load the initial map from the global function. The registers function and 1891 // Load the initial map from the global function. The registers function and
1894 // map can be the same, function is then overwritten. 1892 // map can be the same, function is then overwritten.
1895 void LoadGlobalFunctionInitialMap(Register function, 1893 void LoadGlobalFunctionInitialMap(Register function,
1896 Register map, 1894 Register map,
1897 Register scratch); 1895 Register scratch);
1898 1896
1899 // -------------------------------------------------------------------------- 1897 CPURegList* TmpList() { return &tmp_list_; }
1900 // Set the registers used internally by the MacroAssembler as scratch 1898 CPURegList* FPTmpList() { return &fptmp_list_; }
1901 // registers. These registers are used to implement behaviours which are not
1902 // directly supported by A64, and where an intermediate result is required.
1903 //
1904 // Both tmp0 and tmp1 may be set to any X register except for xzr, sp,
1905 // and StackPointer(). Also, they must not be the same register (though they
1906 // may both be NoReg).
1907 //
1908 // It is valid to set either or both of these registers to NoReg if you don't
1909 // want the MacroAssembler to use any scratch registers. In a debug build, the
1910 // Assembler will assert that any registers it uses are valid. Be aware that
1911 // this check is not present in release builds. If this is a problem, use the
1912 // Assembler directly.
1913 void SetScratchRegisters(const Register& tmp0, const Register& tmp1) {
1914 // V8 assumes the macro assembler uses ip0 and ip1 as temp registers.
1915 ASSERT(tmp0.IsNone() || tmp0.Is(ip0));
1916 ASSERT(tmp1.IsNone() || tmp1.Is(ip1));
1917
1918 ASSERT(!AreAliased(xzr, csp, tmp0, tmp1));
1919 ASSERT(!AreAliased(StackPointer(), tmp0, tmp1));
1920 tmp0_ = tmp0;
1921 tmp1_ = tmp1;
1922 }
1923
1924 const Register& Tmp0() const {
1925 return tmp0_;
1926 }
1927
1928 const Register& Tmp1() const {
1929 return tmp1_;
1930 }
1931
1932 const Register WTmp0() const {
1933 return Register::Create(tmp0_.code(), kWRegSize);
1934 }
1935
1936 const Register WTmp1() const {
1937 return Register::Create(tmp1_.code(), kWRegSize);
1938 }
1939
1940 void SetFPScratchRegister(const FPRegister& fptmp0) {
1941 fptmp0_ = fptmp0;
1942 }
1943
1944 const FPRegister& FPTmp0() const {
1945 return fptmp0_;
1946 }
1947
1948 const Register AppropriateTempFor(
1949 const Register& target,
1950 const CPURegister& forbidden = NoCPUReg) const {
1951 Register candidate = forbidden.Is(Tmp0()) ? Tmp1() : Tmp0();
1952 ASSERT(!candidate.Is(target));
1953 return Register::Create(candidate.code(), target.SizeInBits());
1954 }
1955
1956 const FPRegister AppropriateTempFor(
1957 const FPRegister& target,
1958 const CPURegister& forbidden = NoCPUReg) const {
1959 USE(forbidden);
1960 FPRegister candidate = FPTmp0();
1961 ASSERT(!candidate.Is(forbidden));
1962 ASSERT(!candidate.Is(target));
1963 return FPRegister::Create(candidate.code(), target.SizeInBits());
1964 }
1965 1899
1966 // Like printf, but print at run-time from generated code. 1900 // Like printf, but print at run-time from generated code.
1967 // 1901 //
1968 // The caller must ensure that arguments for floating-point placeholders 1902 // The caller must ensure that arguments for floating-point placeholders
1969 // (such as %e, %f or %g) are FPRegisters, and that arguments for integer 1903 // (such as %e, %f or %g) are FPRegisters, and that arguments for integer
1970 // placeholders are Registers. 1904 // placeholders are Registers.
1971 // 1905 //
1972 // A maximum of four arguments may be given to any single Printf call. The 1906 // A maximum of four arguments may be given to any single Printf call. The
1973 // arguments must be of the same type, but they do not need to have the same 1907 // arguments must be of the same type, but they do not need to have the same
1974 // size. 1908 // size.
1975 // 1909 //
1976 // The following registers cannot be printed: 1910 // The following registers cannot be printed:
1977 // Tmp0(), Tmp1(), StackPointer(), csp. 1911 // StackPointer(), csp.
1978 // 1912 //
1979 // This function automatically preserves caller-saved registers so that 1913 // This function automatically preserves caller-saved registers so that
1980 // calling code can use Printf at any point without having to worry about 1914 // calling code can use Printf at any point without having to worry about
1981 // corruption. The preservation mechanism generates a lot of code. If this is 1915 // corruption. The preservation mechanism generates a lot of code. If this is
1982 // a problem, preserve the important registers manually and then call 1916 // a problem, preserve the important registers manually and then call
1983 // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are 1917 // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are
1984 // implicitly preserved. 1918 // implicitly preserved.
1985 // 1919 //
1986 // Unlike many MacroAssembler functions, x8 and x9 are guaranteed to be 1920 // Unlike many MacroAssembler functions, x8 and x9 are guaranteed to be
1987 // preserved, and can be printed. This allows Printf to be used during debug 1921 // 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
2052 1986
2053 // Jumps to found label if a prototype map has dictionary elements. 1987 // Jumps to found label if a prototype map has dictionary elements.
2054 void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0, 1988 void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
2055 Register scratch1, Label* found); 1989 Register scratch1, Label* found);
2056 1990
2057 private: 1991 private:
2058 // Helpers for CopyFields. 1992 // Helpers for CopyFields.
2059 // These each implement CopyFields in a different way. 1993 // These each implement CopyFields in a different way.
2060 void CopyFieldsLoopPairsHelper(Register dst, Register src, unsigned count, 1994 void CopyFieldsLoopPairsHelper(Register dst, Register src, unsigned count,
2061 Register scratch1, Register scratch2, 1995 Register scratch1, Register scratch2,
2062 Register scratch3); 1996 Register scratch3, Register scratch4,
1997 Register scratch5);
2063 void CopyFieldsUnrolledPairsHelper(Register dst, Register src, unsigned count, 1998 void CopyFieldsUnrolledPairsHelper(Register dst, Register src, unsigned count,
2064 Register scratch1, Register scratch2); 1999 Register scratch1, Register scratch2,
2000 Register scratch3, Register scratch4);
2065 void CopyFieldsUnrolledHelper(Register dst, Register src, unsigned count, 2001 void CopyFieldsUnrolledHelper(Register dst, Register src, unsigned count,
2066 Register scratch1); 2002 Register scratch1, Register scratch2,
2003 Register scratch3);
2067 2004
2068 // The actual Push and Pop implementations. These don't generate any code 2005 // The actual Push and Pop implementations. These don't generate any code
2069 // other than that required for the push or pop. This allows 2006 // other than that required for the push or pop. This allows
2070 // (Push|Pop)CPURegList to bundle together run-time assertions for a large 2007 // (Push|Pop)CPURegList to bundle together run-time assertions for a large
2071 // block of registers. 2008 // block of registers.
2072 // 2009 //
2073 // Note that size is per register, and is specified in bytes. 2010 // Note that size is per register, and is specified in bytes.
2074 void PushHelper(int count, int size, 2011 void PushHelper(int count, int size,
2075 const CPURegister& src0, const CPURegister& src1, 2012 const CPURegister& src0, const CPURegister& src1,
2076 const CPURegister& src2, const CPURegister& src3); 2013 const CPURegister& src2, const CPURegister& src3);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2137 // The purpose of this is to allow Aborts to be compiled whilst CEntryStub is 2074 // The purpose of this is to allow Aborts to be compiled whilst CEntryStub is
2138 // being generated. 2075 // being generated.
2139 bool use_real_aborts_; 2076 bool use_real_aborts_;
2140 2077
2141 // This handle will be patched with the code object on installation. 2078 // This handle will be patched with the code object on installation.
2142 Handle<Object> code_object_; 2079 Handle<Object> code_object_;
2143 2080
2144 // The register to use as a stack pointer for stack operations. 2081 // The register to use as a stack pointer for stack operations.
2145 Register sp_; 2082 Register sp_;
2146 2083
2147 // Scratch registers used internally by the MacroAssembler. 2084 // Scratch registers available for use by the MacroAssembler.
2148 Register tmp0_; 2085 CPURegList tmp_list_;
2149 Register tmp1_; 2086 CPURegList fptmp_list_;
2150 FPRegister fptmp0_;
2151 2087
2152 void InitializeNewString(Register string, 2088 void InitializeNewString(Register string,
2153 Register length, 2089 Register length,
2154 Heap::RootListIndex map_index, 2090 Heap::RootListIndex map_index,
2155 Register scratch1, 2091 Register scratch1,
2156 Register scratch2); 2092 Register scratch2);
2157 2093
2158 public: 2094 public:
2159 // Far branches resolving. 2095 // Far branches resolving.
2160 // 2096 //
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2248 private: 2184 private:
2249 MacroAssembler* masm_; 2185 MacroAssembler* masm_;
2250 #ifdef DEBUG 2186 #ifdef DEBUG
2251 size_t size_; 2187 size_t size_;
2252 Label start_; 2188 Label start_;
2253 bool previous_allow_macro_instructions_; 2189 bool previous_allow_macro_instructions_;
2254 #endif 2190 #endif
2255 }; 2191 };
2256 2192
2257 2193
2194 // This scope utility allows scratch registers to be managed safely. The
2195 // MacroAssembler's TmpList() (and FPTmpList()) is used as a pool of scratch
2196 // registers. These registers can be allocated on demand, and will be returned
2197 // at the end of the scope.
2198 //
2199 // When the scope ends, the MacroAssembler's lists will be restored to their
2200 // original state, even if the lists were modified by some other means.
2201 class UseScratchRegisterScope {
2202 public:
2203 explicit UseScratchRegisterScope(MacroAssembler* masm)
2204 : available_(masm->TmpList()),
2205 availablefp_(masm->FPTmpList()),
2206 old_available_(available_->list()),
2207 old_availablefp_(availablefp_->list()) {
2208 ASSERT(available_->type() == CPURegister::kRegister);
2209 ASSERT(availablefp_->type() == CPURegister::kFPRegister);
2210 }
2211
2212
rmcilroy 2014/02/28 17:13:34 remove extra newline (only two newlines between fu
jbramley 2014/02/28 17:36:24 Done.
2213 ~UseScratchRegisterScope();
2214
2215
rmcilroy 2014/02/28 17:13:34 ditto
jbramley 2014/02/28 17:36:24 Done.
2216 // Take a register from the appropriate temps list. It will be returned
2217 // automatically when the scope ends.
2218 Register AcquireW() { return AcquireNextAvailable(available_).W(); }
2219 Register AcquireX() { return AcquireNextAvailable(available_).X(); }
2220 FPRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); }
2221 FPRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); }
2222
2223
rmcilroy 2014/02/28 17:13:34 ditto
jbramley 2014/02/28 17:36:24 Done.
2224 Register AcquireSameSizeAs(const Register& reg);
2225 FPRegister AcquireSameSizeAs(const FPRegister& reg);
2226
2227
rmcilroy 2014/02/28 17:13:34 ditto
jbramley 2014/02/28 17:36:24 Done.
2228 private:
2229 static CPURegister AcquireNextAvailable(CPURegList* available);
2230
2231 // Available scratch registers.
2232 CPURegList* available_; // kRegister
2233 CPURegList* availablefp_; // kFPRegister
2234
2235 // The state of the available lists at the start of this scope.
2236 RegList old_available_; // kRegister
2237 RegList old_availablefp_; // kFPRegister
2238 };
2239
2240
2258 inline MemOperand ContextMemOperand(Register context, int index) { 2241 inline MemOperand ContextMemOperand(Register context, int index) {
2259 return MemOperand(context, Context::SlotOffset(index)); 2242 return MemOperand(context, Context::SlotOffset(index));
2260 } 2243 }
2261 2244
2262 inline MemOperand GlobalObjectMemOperand() { 2245 inline MemOperand GlobalObjectMemOperand() {
2263 return ContextMemOperand(cp, Context::GLOBAL_OBJECT_INDEX); 2246 return ContextMemOperand(cp, Context::GLOBAL_OBJECT_INDEX);
2264 } 2247 }
2265 2248
2266 2249
2267 // Encode and decode information about patchable inline SMI checks. 2250 // Encode and decode information about patchable inline SMI checks.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2318 #error "Unsupported option" 2301 #error "Unsupported option"
2319 #define CODE_COVERAGE_STRINGIFY(x) #x 2302 #define CODE_COVERAGE_STRINGIFY(x) #x
2320 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 2303 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
2321 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 2304 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
2322 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm-> 2305 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
2323 #else 2306 #else
2324 #define ACCESS_MASM(masm) masm-> 2307 #define ACCESS_MASM(masm) masm->
2325 #endif 2308 #endif
2326 2309
2327 #endif // V8_A64_MACRO_ASSEMBLER_A64_H_ 2310 #endif // V8_A64_MACRO_ASSEMBLER_A64_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698