11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#ifndef V8_CODEGEN_MIPS_REGISTER_MIPS_H_ 61cb0ef41Sopenharmony_ci#define V8_CODEGEN_MIPS_REGISTER_MIPS_H_ 71cb0ef41Sopenharmony_ci 81cb0ef41Sopenharmony_ci#include "src/codegen/mips/constants-mips.h" 91cb0ef41Sopenharmony_ci#include "src/codegen/register-base.h" 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_cinamespace v8 { 121cb0ef41Sopenharmony_cinamespace internal { 131cb0ef41Sopenharmony_ci 141cb0ef41Sopenharmony_ci// clang-format off 151cb0ef41Sopenharmony_ci#define GENERAL_REGISTERS(V) \ 161cb0ef41Sopenharmony_ci V(zero_reg) V(at) V(v0) V(v1) V(a0) V(a1) V(a2) V(a3) \ 171cb0ef41Sopenharmony_ci V(t0) V(t1) V(t2) V(t3) V(t4) V(t5) V(t6) V(t7) \ 181cb0ef41Sopenharmony_ci V(s0) V(s1) V(s2) V(s3) V(s4) V(s5) V(s6) V(s7) V(t8) V(t9) \ 191cb0ef41Sopenharmony_ci V(k0) V(k1) V(gp) V(sp) V(fp) V(ra) 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci#define ALLOCATABLE_GENERAL_REGISTERS(V) \ 221cb0ef41Sopenharmony_ci V(a0) V(a1) V(a2) V(a3) \ 231cb0ef41Sopenharmony_ci V(t0) V(t1) V(t2) V(t3) V(t4) V(t5) V(t6) V(s7) \ 241cb0ef41Sopenharmony_ci V(v0) V(v1) 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci#define DOUBLE_REGISTERS(V) \ 271cb0ef41Sopenharmony_ci V(f0) V(f1) V(f2) V(f3) V(f4) V(f5) V(f6) V(f7) \ 281cb0ef41Sopenharmony_ci V(f8) V(f9) V(f10) V(f11) V(f12) V(f13) V(f14) V(f15) \ 291cb0ef41Sopenharmony_ci V(f16) V(f17) V(f18) V(f19) V(f20) V(f21) V(f22) V(f23) \ 301cb0ef41Sopenharmony_ci V(f24) V(f25) V(f26) V(f27) V(f28) V(f29) V(f30) V(f31) 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ci// Currently, MIPS just use even float point register, except 331cb0ef41Sopenharmony_ci// for C function param registers. 341cb0ef41Sopenharmony_ci#define DOUBLE_USE_REGISTERS(V) \ 351cb0ef41Sopenharmony_ci V(f0) V(f2) V(f4) V(f6) V(f8) V(f10) V(f12) V(f13) \ 361cb0ef41Sopenharmony_ci V(f14) V(f15) V(f16) V(f18) V(f20) V(f22) V(f24) V(f26) \ 371cb0ef41Sopenharmony_ci V(f28) V(f30) 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci#define FLOAT_REGISTERS DOUBLE_REGISTERS 401cb0ef41Sopenharmony_ci#define SIMD128_REGISTERS(V) \ 411cb0ef41Sopenharmony_ci V(w0) V(w1) V(w2) V(w3) V(w4) V(w5) V(w6) V(w7) \ 421cb0ef41Sopenharmony_ci V(w8) V(w9) V(w10) V(w11) V(w12) V(w13) V(w14) V(w15) \ 431cb0ef41Sopenharmony_ci V(w16) V(w17) V(w18) V(w19) V(w20) V(w21) V(w22) V(w23) \ 441cb0ef41Sopenharmony_ci V(w24) V(w25) V(w26) V(w27) V(w28) V(w29) V(w30) V(w31) 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 471cb0ef41Sopenharmony_ci V(f0) V(f2) V(f4) V(f6) V(f8) V(f10) V(f12) V(f14) \ 481cb0ef41Sopenharmony_ci V(f16) V(f18) V(f20) V(f22) V(f24) 491cb0ef41Sopenharmony_ci// clang-format on 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci// Register lists. 521cb0ef41Sopenharmony_ci// Note that the bit values must match those used in actual instruction 531cb0ef41Sopenharmony_ci// encoding. 541cb0ef41Sopenharmony_ciconst int kNumRegs = 32; 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci// CPU Registers. 571cb0ef41Sopenharmony_ci// 581cb0ef41Sopenharmony_ci// 1) We would prefer to use an enum, but enum values are assignment- 591cb0ef41Sopenharmony_ci// compatible with int, which has caused code-generation bugs. 601cb0ef41Sopenharmony_ci// 611cb0ef41Sopenharmony_ci// 2) We would prefer to use a class instead of a struct but we don't like 621cb0ef41Sopenharmony_ci// the register initialization to depend on the particular initialization 631cb0ef41Sopenharmony_ci// order (which appears to be different on OS X, Linux, and Windows for the 641cb0ef41Sopenharmony_ci// installed versions of C++ we tried). Using a struct permits C-style 651cb0ef41Sopenharmony_ci// "initialization". Also, the Register objects cannot be const as this 661cb0ef41Sopenharmony_ci// forces initialization stubs in MSVC, making us dependent on initialization 671cb0ef41Sopenharmony_ci// order. 681cb0ef41Sopenharmony_ci// 691cb0ef41Sopenharmony_ci// 3) By not using an enum, we are possibly preventing the compiler from 701cb0ef41Sopenharmony_ci// doing certain constant folds, which may significantly reduce the 711cb0ef41Sopenharmony_ci// code generated for some assembly instructions (because they boil down 721cb0ef41Sopenharmony_ci// to a few constants). If this is a problem, we could change the code 731cb0ef41Sopenharmony_ci// such that we use an enum in optimized mode, and the struct in debug 741cb0ef41Sopenharmony_ci// mode. This way we get the compile-time error checking in debug mode 751cb0ef41Sopenharmony_ci// and best performance in optimized code. 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------- 781cb0ef41Sopenharmony_ci// Implementation of Register and FPURegister. 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_cienum RegisterCode { 811cb0ef41Sopenharmony_ci#define REGISTER_CODE(R) kRegCode_##R, 821cb0ef41Sopenharmony_ci GENERAL_REGISTERS(REGISTER_CODE) 831cb0ef41Sopenharmony_ci#undef REGISTER_CODE 841cb0ef41Sopenharmony_ci kRegAfterLast 851cb0ef41Sopenharmony_ci}; 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ciclass Register : public RegisterBase<Register, kRegAfterLast> { 881cb0ef41Sopenharmony_ci public: 891cb0ef41Sopenharmony_ci#if defined(V8_TARGET_LITTLE_ENDIAN) 901cb0ef41Sopenharmony_ci static constexpr int kMantissaOffset = 0; 911cb0ef41Sopenharmony_ci static constexpr int kExponentOffset = 4; 921cb0ef41Sopenharmony_ci#elif defined(V8_TARGET_BIG_ENDIAN) 931cb0ef41Sopenharmony_ci static constexpr int kMantissaOffset = 4; 941cb0ef41Sopenharmony_ci static constexpr int kExponentOffset = 0; 951cb0ef41Sopenharmony_ci#else 961cb0ef41Sopenharmony_ci#error Unknown endianness 971cb0ef41Sopenharmony_ci#endif 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci private: 1001cb0ef41Sopenharmony_ci friend class RegisterBase; 1011cb0ef41Sopenharmony_ci explicit constexpr Register(int code) : RegisterBase(code) {} 1021cb0ef41Sopenharmony_ci}; 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci// s7: context register 1051cb0ef41Sopenharmony_ci// s3: scratch register 1061cb0ef41Sopenharmony_ci// s4: scratch register 2 1071cb0ef41Sopenharmony_ci#define DECLARE_REGISTER(R) \ 1081cb0ef41Sopenharmony_ci constexpr Register R = Register::from_code(kRegCode_##R); 1091cb0ef41Sopenharmony_ciGENERAL_REGISTERS(DECLARE_REGISTER) 1101cb0ef41Sopenharmony_ci#undef DECLARE_REGISTER 1111cb0ef41Sopenharmony_ciconstexpr Register no_reg = Register::no_reg(); 1121cb0ef41Sopenharmony_ci 1131cb0ef41Sopenharmony_ciint ToNumber(Register reg); 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ciRegister ToRegister(int num); 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci// Returns the number of padding slots needed for stack pointer alignment. 1181cb0ef41Sopenharmony_ciconstexpr int ArgumentPaddingSlots(int argument_count) { 1191cb0ef41Sopenharmony_ci // No argument padding required. 1201cb0ef41Sopenharmony_ci return 0; 1211cb0ef41Sopenharmony_ci} 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ciconstexpr AliasingKind kFPAliasing = AliasingKind::kOverlap; 1241cb0ef41Sopenharmony_ciconstexpr bool kSimdMaskRegisters = false; 1251cb0ef41Sopenharmony_ci 1261cb0ef41Sopenharmony_cienum DoubleRegisterCode { 1271cb0ef41Sopenharmony_ci#define REGISTER_CODE(R) kDoubleCode_##R, 1281cb0ef41Sopenharmony_ci DOUBLE_REGISTERS(REGISTER_CODE) 1291cb0ef41Sopenharmony_ci#undef REGISTER_CODE 1301cb0ef41Sopenharmony_ci kDoubleAfterLast 1311cb0ef41Sopenharmony_ci}; 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci// Coprocessor register. 1341cb0ef41Sopenharmony_ciclass FPURegister : public RegisterBase<FPURegister, kDoubleAfterLast> { 1351cb0ef41Sopenharmony_ci public: 1361cb0ef41Sopenharmony_ci FPURegister low() const { 1371cb0ef41Sopenharmony_ci // Find low reg of a Double-reg pair, which is the reg itself. 1381cb0ef41Sopenharmony_ci DCHECK_EQ(code() % 2, 0); // Specified Double reg must be even. 1391cb0ef41Sopenharmony_ci return FPURegister::from_code(code()); 1401cb0ef41Sopenharmony_ci } 1411cb0ef41Sopenharmony_ci FPURegister high() const { 1421cb0ef41Sopenharmony_ci // Find high reg of a Doubel-reg pair, which is reg + 1. 1431cb0ef41Sopenharmony_ci DCHECK_EQ(code() % 2, 0); // Specified Double reg must be even. 1441cb0ef41Sopenharmony_ci return FPURegister::from_code(code() + 1); 1451cb0ef41Sopenharmony_ci } 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci private: 1481cb0ef41Sopenharmony_ci friend class RegisterBase; 1491cb0ef41Sopenharmony_ci explicit constexpr FPURegister(int code) : RegisterBase(code) {} 1501cb0ef41Sopenharmony_ci}; 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_cienum MSARegisterCode { 1531cb0ef41Sopenharmony_ci#define REGISTER_CODE(R) kMsaCode_##R, 1541cb0ef41Sopenharmony_ci SIMD128_REGISTERS(REGISTER_CODE) 1551cb0ef41Sopenharmony_ci#undef REGISTER_CODE 1561cb0ef41Sopenharmony_ci kMsaAfterLast 1571cb0ef41Sopenharmony_ci}; 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ci// MIPS SIMD (MSA) register 1601cb0ef41Sopenharmony_ciclass MSARegister : public RegisterBase<MSARegister, kMsaAfterLast> { 1611cb0ef41Sopenharmony_ci friend class RegisterBase; 1621cb0ef41Sopenharmony_ci explicit constexpr MSARegister(int code) : RegisterBase(code) {} 1631cb0ef41Sopenharmony_ci}; 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci// A few double registers are reserved: one as a scratch register and one to 1661cb0ef41Sopenharmony_ci// hold 0.0. 1671cb0ef41Sopenharmony_ci// f28: 0.0 1681cb0ef41Sopenharmony_ci// f30: scratch register. 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci// V8 now supports the O32 ABI, and the FPU Registers are organized as 32 1711cb0ef41Sopenharmony_ci// 32-bit registers, f0 through f31. When used as 'double' they are used 1721cb0ef41Sopenharmony_ci// in pairs, starting with the even numbered register. So a double operation 1731cb0ef41Sopenharmony_ci// on f0 really uses f0 and f1. 1741cb0ef41Sopenharmony_ci// (Modern mips hardware also supports 32 64-bit registers, via setting 1751cb0ef41Sopenharmony_ci// (priviledged) Status Register FR bit to 1. This is used by the N32 ABI, 1761cb0ef41Sopenharmony_ci// but it is not in common use. Someday we will want to support this in v8.) 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci// For O32 ABI, Floats and Doubles refer to same set of 32 32-bit registers. 1791cb0ef41Sopenharmony_ciusing FloatRegister = FPURegister; 1801cb0ef41Sopenharmony_ci 1811cb0ef41Sopenharmony_ciusing DoubleRegister = FPURegister; 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci#define DECLARE_DOUBLE_REGISTER(R) \ 1841cb0ef41Sopenharmony_ci constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R); 1851cb0ef41Sopenharmony_ciDOUBLE_REGISTERS(DECLARE_DOUBLE_REGISTER) 1861cb0ef41Sopenharmony_ci#undef DECLARE_DOUBLE_REGISTER 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ciconstexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci// SIMD registers. 1911cb0ef41Sopenharmony_ciusing Simd128Register = MSARegister; 1921cb0ef41Sopenharmony_ci 1931cb0ef41Sopenharmony_ci#define DECLARE_SIMD128_REGISTER(R) \ 1941cb0ef41Sopenharmony_ci constexpr Simd128Register R = Simd128Register::from_code(kMsaCode_##R); 1951cb0ef41Sopenharmony_ciSIMD128_REGISTERS(DECLARE_SIMD128_REGISTER) 1961cb0ef41Sopenharmony_ci#undef DECLARE_SIMD128_REGISTER 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ciconst Simd128Register no_msareg = Simd128Register::no_reg(); 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci// Register aliases. 2011cb0ef41Sopenharmony_ci// cp is assumed to be a callee saved register. 2021cb0ef41Sopenharmony_ciconstexpr Register kRootRegister = s6; 2031cb0ef41Sopenharmony_ciconstexpr Register cp = s7; 2041cb0ef41Sopenharmony_ciconstexpr Register kScratchReg = s3; 2051cb0ef41Sopenharmony_ciconstexpr Register kScratchReg2 = s4; 2061cb0ef41Sopenharmony_ciconstexpr DoubleRegister kScratchDoubleReg = f30; 2071cb0ef41Sopenharmony_ciconstexpr DoubleRegister kDoubleRegZero = f28; 2081cb0ef41Sopenharmony_ci// Used on mips32r6 for compare operations. 2091cb0ef41Sopenharmony_ciconstexpr DoubleRegister kDoubleCompareReg = f26; 2101cb0ef41Sopenharmony_ci// MSA zero and scratch regs must have the same numbers as FPU zero and scratch 2111cb0ef41Sopenharmony_ciconstexpr Simd128Register kSimd128RegZero = w28; 2121cb0ef41Sopenharmony_ciconstexpr Simd128Register kSimd128ScratchReg = w30; 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci// FPU (coprocessor 1) control registers. 2151cb0ef41Sopenharmony_ci// Currently only FCSR (#31) is implemented. 2161cb0ef41Sopenharmony_cistruct FPUControlRegister { 2171cb0ef41Sopenharmony_ci bool is_valid() const { return reg_code == kFCSRRegister; } 2181cb0ef41Sopenharmony_ci bool is(FPUControlRegister creg) const { return reg_code == creg.reg_code; } 2191cb0ef41Sopenharmony_ci int code() const { 2201cb0ef41Sopenharmony_ci DCHECK(is_valid()); 2211cb0ef41Sopenharmony_ci return reg_code; 2221cb0ef41Sopenharmony_ci } 2231cb0ef41Sopenharmony_ci int bit() const { 2241cb0ef41Sopenharmony_ci DCHECK(is_valid()); 2251cb0ef41Sopenharmony_ci return 1 << reg_code; 2261cb0ef41Sopenharmony_ci } 2271cb0ef41Sopenharmony_ci void setcode(int f) { 2281cb0ef41Sopenharmony_ci reg_code = f; 2291cb0ef41Sopenharmony_ci DCHECK(is_valid()); 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci // Unfortunately we can't make this private in a struct. 2321cb0ef41Sopenharmony_ci int reg_code; 2331cb0ef41Sopenharmony_ci}; 2341cb0ef41Sopenharmony_ci 2351cb0ef41Sopenharmony_ciconstexpr FPUControlRegister no_fpucreg = {kInvalidFPUControlRegister}; 2361cb0ef41Sopenharmony_ciconstexpr FPUControlRegister FCSR = {kFCSRRegister}; 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci// MSA control registers 2391cb0ef41Sopenharmony_cistruct MSAControlRegister { 2401cb0ef41Sopenharmony_ci bool is_valid() const { 2411cb0ef41Sopenharmony_ci return (reg_code == kMSAIRRegister) || (reg_code == kMSACSRRegister); 2421cb0ef41Sopenharmony_ci } 2431cb0ef41Sopenharmony_ci bool is(MSAControlRegister creg) const { return reg_code == creg.reg_code; } 2441cb0ef41Sopenharmony_ci int code() const { 2451cb0ef41Sopenharmony_ci DCHECK(is_valid()); 2461cb0ef41Sopenharmony_ci return reg_code; 2471cb0ef41Sopenharmony_ci } 2481cb0ef41Sopenharmony_ci int bit() const { 2491cb0ef41Sopenharmony_ci DCHECK(is_valid()); 2501cb0ef41Sopenharmony_ci return 1 << reg_code; 2511cb0ef41Sopenharmony_ci } 2521cb0ef41Sopenharmony_ci void setcode(int f) { 2531cb0ef41Sopenharmony_ci reg_code = f; 2541cb0ef41Sopenharmony_ci DCHECK(is_valid()); 2551cb0ef41Sopenharmony_ci } 2561cb0ef41Sopenharmony_ci // Unfortunately we can't make this private in a struct. 2571cb0ef41Sopenharmony_ci int reg_code; 2581cb0ef41Sopenharmony_ci}; 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ciconstexpr MSAControlRegister no_msacreg = {kInvalidMSAControlRegister}; 2611cb0ef41Sopenharmony_ciconstexpr MSAControlRegister MSAIR = {kMSAIRRegister}; 2621cb0ef41Sopenharmony_ciconstexpr MSAControlRegister MSACSR = {kMSACSRRegister}; 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci// Define {RegisterName} methods for the register types. 2651cb0ef41Sopenharmony_ciDEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS) 2661cb0ef41Sopenharmony_ciDEFINE_REGISTER_NAMES(FPURegister, DOUBLE_REGISTERS) 2671cb0ef41Sopenharmony_ciDEFINE_REGISTER_NAMES(MSARegister, SIMD128_REGISTERS) 2681cb0ef41Sopenharmony_ci 2691cb0ef41Sopenharmony_ci// Give alias names to registers for calling conventions. 2701cb0ef41Sopenharmony_ciconstexpr Register kReturnRegister0 = v0; 2711cb0ef41Sopenharmony_ciconstexpr Register kReturnRegister1 = v1; 2721cb0ef41Sopenharmony_ciconstexpr Register kReturnRegister2 = a0; 2731cb0ef41Sopenharmony_ciconstexpr Register kJSFunctionRegister = a1; 2741cb0ef41Sopenharmony_ciconstexpr Register kContextRegister = s7; 2751cb0ef41Sopenharmony_ciconstexpr Register kAllocateSizeRegister = a0; 2761cb0ef41Sopenharmony_ciconstexpr Register kInterpreterAccumulatorRegister = v0; 2771cb0ef41Sopenharmony_ciconstexpr Register kInterpreterBytecodeOffsetRegister = t4; 2781cb0ef41Sopenharmony_ciconstexpr Register kInterpreterBytecodeArrayRegister = t5; 2791cb0ef41Sopenharmony_ciconstexpr Register kInterpreterDispatchTableRegister = t6; 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ciconstexpr Register kJavaScriptCallArgCountRegister = a0; 2821cb0ef41Sopenharmony_ciconstexpr Register kJavaScriptCallCodeStartRegister = a2; 2831cb0ef41Sopenharmony_ciconstexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister; 2841cb0ef41Sopenharmony_ciconstexpr Register kJavaScriptCallNewTargetRegister = a3; 2851cb0ef41Sopenharmony_ciconstexpr Register kJavaScriptCallExtraArg1Register = a2; 2861cb0ef41Sopenharmony_ci 2871cb0ef41Sopenharmony_ciconstexpr Register kOffHeapTrampolineRegister = at; 2881cb0ef41Sopenharmony_ciconstexpr Register kRuntimeCallFunctionRegister = a1; 2891cb0ef41Sopenharmony_ciconstexpr Register kRuntimeCallArgCountRegister = a0; 2901cb0ef41Sopenharmony_ciconstexpr Register kRuntimeCallArgvRegister = a2; 2911cb0ef41Sopenharmony_ciconstexpr Register kWasmInstanceRegister = a0; 2921cb0ef41Sopenharmony_ciconstexpr Register kWasmCompileLazyFuncIndexRegister = t0; 2931cb0ef41Sopenharmony_ci 2941cb0ef41Sopenharmony_ciconstexpr DoubleRegister kFPReturnRegister0 = f0; 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_ci} // namespace internal 2971cb0ef41Sopenharmony_ci} // namespace v8 2981cb0ef41Sopenharmony_ci 2991cb0ef41Sopenharmony_ci#endif // V8_CODEGEN_MIPS_REGISTER_MIPS_H_ 300