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

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

Powered by Google App Engine
This is Rietveld 408576698