1// Copyright 2018 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef V8_CODEGEN_X64_REGISTER_X64_H_ 6#define V8_CODEGEN_X64_REGISTER_X64_H_ 7 8#include "src/codegen/register-base.h" 9 10namespace v8 { 11namespace internal { 12 13#define GENERAL_REGISTERS(V) \ 14 V(rax) \ 15 V(rcx) \ 16 V(rdx) \ 17 V(rbx) \ 18 V(rsp) \ 19 V(rbp) \ 20 V(rsi) \ 21 V(rdi) \ 22 V(r8) \ 23 V(r9) \ 24 V(r10) \ 25 V(r11) \ 26 V(r12) \ 27 V(r13) \ 28 V(r14) \ 29 V(r15) 30 31#define ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(V) \ 32 V(rax) \ 33 V(rbx) \ 34 V(rdx) \ 35 V(rcx) \ 36 V(rsi) \ 37 V(rdi) \ 38 V(r8) \ 39 V(r9) \ 40 V(r11) \ 41 V(r12) \ 42 V(r15) 43 44#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE 45#define MAYBE_ALLOCATABLE_GENERAL_REGISTERS(V) 46#else 47#define MAYBE_ALLOCATABLE_GENERAL_REGISTERS(V) V(r14) 48#endif 49 50#define ALLOCATABLE_GENERAL_REGISTERS(V) \ 51 ALWAYS_ALLOCATABLE_GENERAL_REGISTERS(V) \ 52 MAYBE_ALLOCATABLE_GENERAL_REGISTERS(V) 53 54enum RegisterCode { 55#define REGISTER_CODE(R) kRegCode_##R, 56 GENERAL_REGISTERS(REGISTER_CODE) 57#undef REGISTER_CODE 58 kRegAfterLast 59}; 60 61class Register : public RegisterBase<Register, kRegAfterLast> { 62 public: 63 bool is_byte_register() const { return code() <= 3; } 64 // Return the high bit of the register code as a 0 or 1. Used often 65 // when constructing the REX prefix byte. 66 int high_bit() const { return code() >> 3; } 67 // Return the 3 low bits of the register code. Used when encoding registers 68 // in modR/M, SIB, and opcode bytes. 69 int low_bits() const { return code() & 0x7; } 70 71 private: 72 friend class RegisterBase<Register, kRegAfterLast>; 73 explicit constexpr Register(int code) : RegisterBase(code) {} 74}; 75 76ASSERT_TRIVIALLY_COPYABLE(Register); 77static_assert(sizeof(Register) <= sizeof(int), 78 "Register can efficiently be passed by value"); 79 80#define DECLARE_REGISTER(R) \ 81 constexpr Register R = Register::from_code(kRegCode_##R); 82GENERAL_REGISTERS(DECLARE_REGISTER) 83#undef DECLARE_REGISTER 84constexpr Register no_reg = Register::no_reg(); 85 86constexpr int kNumRegs = 16; 87 88#ifdef V8_TARGET_OS_WIN 89// Windows calling convention 90constexpr Register arg_reg_1 = rcx; 91constexpr Register arg_reg_2 = rdx; 92constexpr Register arg_reg_3 = r8; 93constexpr Register arg_reg_4 = r9; 94#else 95// AMD64 calling convention 96constexpr Register arg_reg_1 = rdi; 97constexpr Register arg_reg_2 = rsi; 98constexpr Register arg_reg_3 = rdx; 99constexpr Register arg_reg_4 = rcx; 100#endif // V8_TARGET_OS_WIN 101 102#define DOUBLE_REGISTERS(V) \ 103 V(xmm0) \ 104 V(xmm1) \ 105 V(xmm2) \ 106 V(xmm3) \ 107 V(xmm4) \ 108 V(xmm5) \ 109 V(xmm6) \ 110 V(xmm7) \ 111 V(xmm8) \ 112 V(xmm9) \ 113 V(xmm10) \ 114 V(xmm11) \ 115 V(xmm12) \ 116 V(xmm13) \ 117 V(xmm14) \ 118 V(xmm15) 119 120#define FLOAT_REGISTERS DOUBLE_REGISTERS 121#define SIMD128_REGISTERS DOUBLE_REGISTERS 122 123#define ALLOCATABLE_DOUBLE_REGISTERS(V) \ 124 V(xmm0) \ 125 V(xmm1) \ 126 V(xmm2) \ 127 V(xmm3) \ 128 V(xmm4) \ 129 V(xmm5) \ 130 V(xmm6) \ 131 V(xmm7) \ 132 V(xmm8) \ 133 V(xmm9) \ 134 V(xmm10) \ 135 V(xmm11) \ 136 V(xmm12) \ 137 V(xmm13) \ 138 V(xmm14) 139 140#define YMM_REGISTERS(V) \ 141 V(ymm0) \ 142 V(ymm1) \ 143 V(ymm2) \ 144 V(ymm3) \ 145 V(ymm4) \ 146 V(ymm5) \ 147 V(ymm6) \ 148 V(ymm7) \ 149 V(ymm8) \ 150 V(ymm9) \ 151 V(ymm10) \ 152 V(ymm11) \ 153 V(ymm12) \ 154 V(ymm13) \ 155 V(ymm14) \ 156 V(ymm15) 157 158// Returns the number of padding slots needed for stack pointer alignment. 159constexpr int ArgumentPaddingSlots(int argument_count) { 160 // No argument padding required. 161 return 0; 162} 163 164constexpr AliasingKind kFPAliasing = AliasingKind::kOverlap; 165constexpr bool kSimdMaskRegisters = false; 166 167enum DoubleRegisterCode { 168#define REGISTER_CODE(R) kDoubleCode_##R, 169 DOUBLE_REGISTERS(REGISTER_CODE) 170#undef REGISTER_CODE 171 kDoubleAfterLast 172}; 173 174enum YMMRegisterCode { 175#define REGISTER_CODE(R) kYMMCode_##R, 176 YMM_REGISTERS(REGISTER_CODE) 177#undef REGISTER_CODE 178 kYMMAfterLast 179}; 180static_assert(static_cast<int>(kDoubleAfterLast) == 181 static_cast<int>(kYMMAfterLast), 182 "The number of XMM register codes must match the number of YMM " 183 "register codes"); 184 185class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> { 186 public: 187 // Return the high bit of the register code as a 0 or 1. Used often 188 // when constructing the REX prefix byte. 189 int high_bit() const { return code() >> 3; } 190 // Return the 3 low bits of the register code. Used when encoding registers 191 // in modR/M, SIB, and opcode bytes. 192 int low_bits() const { return code() & 0x7; } 193 194 protected: 195 friend class RegisterBase<XMMRegister, kDoubleAfterLast>; 196 explicit constexpr XMMRegister(int code) : RegisterBase(code) {} 197}; 198 199ASSERT_TRIVIALLY_COPYABLE(XMMRegister); 200static_assert(sizeof(XMMRegister) <= sizeof(int), 201 "XMMRegister can efficiently be passed by value"); 202 203class YMMRegister : public XMMRegister { 204 public: 205 static constexpr YMMRegister from_code(int code) { 206 DCHECK(base::IsInRange(code, 0, XMMRegister::kNumRegisters - 1)); 207 return YMMRegister(code); 208 } 209 210 private: 211 friend class XMMRegister; 212 explicit constexpr YMMRegister(int code) : XMMRegister(code) {} 213}; 214 215ASSERT_TRIVIALLY_COPYABLE(YMMRegister); 216static_assert(sizeof(YMMRegister) <= sizeof(int), 217 "YMMRegister can efficiently be passed by value"); 218 219using FloatRegister = XMMRegister; 220 221using DoubleRegister = XMMRegister; 222 223using Simd128Register = XMMRegister; 224 225#define DECLARE_REGISTER(R) \ 226 constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R); 227DOUBLE_REGISTERS(DECLARE_REGISTER) 228#undef DECLARE_REGISTER 229constexpr DoubleRegister no_dreg = DoubleRegister::no_reg(); 230 231#define DECLARE_REGISTER(R) \ 232 constexpr YMMRegister R = YMMRegister::from_code(kYMMCode_##R); 233YMM_REGISTERS(DECLARE_REGISTER) 234#undef DECLARE_REGISTER 235 236// Define {RegisterName} methods for the register types. 237DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS) 238DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS) 239DEFINE_REGISTER_NAMES(YMMRegister, YMM_REGISTERS) 240 241// Give alias names to registers for calling conventions. 242constexpr Register kReturnRegister0 = rax; 243constexpr Register kReturnRegister1 = rdx; 244constexpr Register kReturnRegister2 = r8; 245constexpr Register kJSFunctionRegister = rdi; 246constexpr Register kContextRegister = rsi; 247constexpr Register kAllocateSizeRegister = rdx; 248constexpr Register kInterpreterAccumulatorRegister = rax; 249constexpr Register kInterpreterBytecodeOffsetRegister = r9; 250constexpr Register kInterpreterBytecodeArrayRegister = r12; 251constexpr Register kInterpreterDispatchTableRegister = r15; 252 253constexpr Register kJavaScriptCallArgCountRegister = rax; 254constexpr Register kJavaScriptCallCodeStartRegister = rcx; 255constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister; 256constexpr Register kJavaScriptCallNewTargetRegister = rdx; 257constexpr Register kJavaScriptCallExtraArg1Register = rbx; 258 259constexpr Register kRuntimeCallFunctionRegister = rbx; 260constexpr Register kRuntimeCallArgCountRegister = rax; 261constexpr Register kRuntimeCallArgvRegister = r15; 262constexpr Register kWasmInstanceRegister = rsi; 263 264// Default scratch register used by MacroAssembler (and other code that needs 265// a spare register). The register isn't callee save, and not used by the 266// function calling convention. 267constexpr Register kScratchRegister = r10; 268constexpr XMMRegister kScratchDoubleReg = xmm15; 269constexpr Register kRootRegister = r13; // callee save 270#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE 271constexpr Register kPtrComprCageBaseRegister = r14; // callee save 272#else 273constexpr Register kPtrComprCageBaseRegister = kRootRegister; 274#endif 275 276constexpr Register kOffHeapTrampolineRegister = kScratchRegister; 277 278constexpr DoubleRegister kFPReturnRegister0 = xmm0; 279 280} // namespace internal 281} // namespace v8 282 283#endif // V8_CODEGEN_X64_REGISTER_X64_H_ 284