OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_MIPS_MACRO_ASSEMBLER_MIPS_H_ | 5 #ifndef V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ |
6 #define V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ | 6 #define V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ |
7 | 7 |
8 #include "src/assembler.h" | 8 #include "src/assembler.h" |
9 #include "src/globals.h" | 9 #include "src/globals.h" |
10 #include "src/mips64/assembler-mips64.h" | 10 #include "src/mips64/assembler-mips64.h" |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 } | 229 } |
230 | 230 |
231 bool IsNear(Label* L, Condition cond, int rs_reg); | 231 bool IsNear(Label* L, Condition cond, int rs_reg); |
232 | 232 |
233 void Branch(Label* L, | 233 void Branch(Label* L, |
234 Condition cond, | 234 Condition cond, |
235 Register rs, | 235 Register rs, |
236 Heap::RootListIndex index, | 236 Heap::RootListIndex index, |
237 BranchDelaySlot bdslot = PROTECT); | 237 BranchDelaySlot bdslot = PROTECT); |
238 | 238 |
| 239 // GetLabelFunction must be lambda '[](size_t index) -> Label*' or a |
| 240 // functor/function with 'Label *func(size_t index)' declaration. |
| 241 template <typename Func> |
| 242 void GenerateSwitchTable(Register index, size_t case_count, |
| 243 Func GetLabelFunction); |
239 #undef COND_ARGS | 244 #undef COND_ARGS |
240 | 245 |
241 // Emit code to discard a non-negative number of pointer-sized elements | 246 // Emit code to discard a non-negative number of pointer-sized elements |
242 // from the stack, clobbering only the sp register. | 247 // from the stack, clobbering only the sp register. |
243 void Drop(int count, | 248 void Drop(int count, |
244 Condition cond = cc_always, | 249 Condition cond = cc_always, |
245 Register reg = no_reg, | 250 Register reg = no_reg, |
246 const Operand& op = Operand(no_reg)); | 251 const Operand& op = Operand(no_reg)); |
247 | 252 |
248 // Trivial case of DropAndRet that utilizes the delay slot and only emits | 253 // Trivial case of DropAndRet that utilizes the delay slot and only emits |
(...skipping 1642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1891 // instruction unchanged. | 1896 // instruction unchanged. |
1892 void ChangeBranchCondition(Instr current_instr, uint32_t new_opcode); | 1897 void ChangeBranchCondition(Instr current_instr, uint32_t new_opcode); |
1893 | 1898 |
1894 private: | 1899 private: |
1895 byte* address_; // The address of the code being patched. | 1900 byte* address_; // The address of the code being patched. |
1896 int size_; // Number of bytes of the expected patch size. | 1901 int size_; // Number of bytes of the expected patch size. |
1897 MacroAssembler masm_; // Macro assembler used to generate the code. | 1902 MacroAssembler masm_; // Macro assembler used to generate the code. |
1898 FlushICache flush_cache_; // Whether to flush the I cache after patching. | 1903 FlushICache flush_cache_; // Whether to flush the I cache after patching. |
1899 }; | 1904 }; |
1900 | 1905 |
1901 | 1906 template <typename Func> |
| 1907 void MacroAssembler::GenerateSwitchTable(Register index, size_t case_count, |
| 1908 Func GetLabelFunction) { |
| 1909 // Ensure that dd-ed labels following this instruction use 8 bytes aligned |
| 1910 // addresses. |
| 1911 if (kArchVariant >= kMips64r6) { |
| 1912 BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 + 6); |
| 1913 // Opposite of Align(8) as we have odd number of instructions in this case. |
| 1914 if ((pc_offset() & 7) == 0) { |
| 1915 nop(); |
| 1916 } |
| 1917 addiupc(at, 5); |
| 1918 dlsa(at, at, index, kPointerSizeLog2); |
| 1919 ld(at, MemOperand(at)); |
| 1920 } else { |
| 1921 Label here; |
| 1922 BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 + 7); |
| 1923 Align(8); |
| 1924 bal(&here); |
| 1925 dsll(at, index, kPointerSizeLog2); // Branch delay slot. |
| 1926 bind(&here); |
| 1927 daddu(at, at, ra); |
| 1928 ld(at, MemOperand(at, 4 * v8::internal::Assembler::kInstrSize)); |
| 1929 } |
| 1930 jr(at); |
| 1931 nop(); // Branch delay slot nop. |
| 1932 for (size_t index = 0; index < case_count; ++index) { |
| 1933 dd(GetLabelFunction(index)); |
| 1934 } |
| 1935 } |
1902 | 1936 |
1903 #ifdef GENERATED_CODE_COVERAGE | 1937 #ifdef GENERATED_CODE_COVERAGE |
1904 #define CODE_COVERAGE_STRINGIFY(x) #x | 1938 #define CODE_COVERAGE_STRINGIFY(x) #x |
1905 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) | 1939 #define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) |
1906 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) | 1940 #define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) |
1907 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm-> | 1941 #define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm-> |
1908 #else | 1942 #else |
1909 #define ACCESS_MASM(masm) masm-> | 1943 #define ACCESS_MASM(masm) masm-> |
1910 #endif | 1944 #endif |
1911 | 1945 |
1912 } // namespace internal | 1946 } // namespace internal |
1913 } // namespace v8 | 1947 } // namespace v8 |
1914 | 1948 |
1915 #endif // V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ | 1949 #endif // V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ |
OLD | NEW |