blob: 547653e07687ae0dd30baa5c8d1f61222c015b32 [file] [log] [blame]
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_CODEGEN_X64_REGISTER_X64_H_
#define V8_CODEGEN_X64_REGISTER_X64_H_
#include "src/codegen/register.h"
#include "src/codegen/reglist.h"
namespace v8 {
namespace internal {
#define GENERAL_REGISTERS(V) \
V(rax) \
V(rcx) \
V(rdx) \
V(rbx) \
V(rsp) \
V(rbp) \
V(rsi) \
V(rdi) \
V(r8) \
V(r9) \
V(r10) \
V(r11) \
V(r12) \
V(r13) \
V(r14) \
V(r15)
#define ALLOCATABLE_GENERAL_REGISTERS(V) \
V(rax) \
V(rbx) \
V(rdx) \
V(rcx) \
V(rsi) \
V(rdi) \
V(r8) \
V(r9) \
V(r11) \
V(r12) \
V(r14) \
V(r15)
enum RegisterCode {
#define REGISTER_CODE(R) kRegCode_##R,
GENERAL_REGISTERS(REGISTER_CODE)
#undef REGISTER_CODE
kRegAfterLast
};
class Register : public RegisterBase<Register, kRegAfterLast> {
public:
bool is_byte_register() const { return reg_code_ <= 3; }
// Return the high bit of the register code as a 0 or 1. Used often
// when constructing the REX prefix byte.
int high_bit() const { return reg_code_ >> 3; }
// Return the 3 low bits of the register code. Used when encoding registers
// in modR/M, SIB, and opcode bytes.
int low_bits() const { return reg_code_ & 0x7; }
private:
friend class RegisterBase<Register, kRegAfterLast>;
explicit constexpr Register(int code) : RegisterBase(code) {}
};
ASSERT_TRIVIALLY_COPYABLE(Register);
static_assert(sizeof(Register) == sizeof(int),
"Register can efficiently be passed by value");
#define DECLARE_REGISTER(R) \
constexpr Register R = Register::from_code<kRegCode_##R>();
GENERAL_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
constexpr Register no_reg = Register::no_reg();
constexpr int kNumRegs = 16;
#if defined(DISABLE_WASM_COMPILER_ISSUE_STARBOARD)
// One particular platform only enable constexpr std::forward in c++14.
const RegList kJSCallerSaved =
#else
constexpr RegList kJSCallerSaved =
#endif
Register::ListOf<rax, rcx, rdx,
rbx, // used as a caller-saved register in JavaScript code
rdi // callee function
>();
constexpr int kNumJSCallerSaved = 5;
// Number of registers for which space is reserved in safepoints.
constexpr int kNumSafepointRegisters = 16;
#ifdef V8_TARGET_OS_WIN
// Windows calling convention
constexpr Register arg_reg_1 = rcx;
constexpr Register arg_reg_2 = rdx;
constexpr Register arg_reg_3 = r8;
constexpr Register arg_reg_4 = r9;
#else
// AMD64 calling convention
constexpr Register arg_reg_1 = rdi;
constexpr Register arg_reg_2 = rsi;
constexpr Register arg_reg_3 = rdx;
constexpr Register arg_reg_4 = rcx;
#endif // V8_TARGET_OS_WIN
#define DOUBLE_REGISTERS(V) \
V(xmm0) \
V(xmm1) \
V(xmm2) \
V(xmm3) \
V(xmm4) \
V(xmm5) \
V(xmm6) \
V(xmm7) \
V(xmm8) \
V(xmm9) \
V(xmm10) \
V(xmm11) \
V(xmm12) \
V(xmm13) \
V(xmm14) \
V(xmm15)
#define FLOAT_REGISTERS DOUBLE_REGISTERS
#define SIMD128_REGISTERS DOUBLE_REGISTERS
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(xmm0) \
V(xmm1) \
V(xmm2) \
V(xmm3) \
V(xmm4) \
V(xmm5) \
V(xmm6) \
V(xmm7) \
V(xmm8) \
V(xmm9) \
V(xmm10) \
V(xmm11) \
V(xmm12) \
V(xmm13) \
V(xmm14)
constexpr bool kPadArguments = false;
constexpr bool kSimpleFPAliasing = true;
constexpr bool kSimdMaskRegisters = false;
enum DoubleRegisterCode {
#define REGISTER_CODE(R) kDoubleCode_##R,
DOUBLE_REGISTERS(REGISTER_CODE)
#undef REGISTER_CODE
kDoubleAfterLast
};
class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> {
public:
// Return the high bit of the register code as a 0 or 1. Used often
// when constructing the REX prefix byte.
int high_bit() const { return reg_code_ >> 3; }
// Return the 3 low bits of the register code. Used when encoding registers
// in modR/M, SIB, and opcode bytes.
int low_bits() const { return reg_code_ & 0x7; }
private:
friend class RegisterBase<XMMRegister, kDoubleAfterLast>;
explicit constexpr XMMRegister(int code) : RegisterBase(code) {}
};
ASSERT_TRIVIALLY_COPYABLE(XMMRegister);
static_assert(sizeof(XMMRegister) == sizeof(int),
"XMMRegister can efficiently be passed by value");
using FloatRegister = XMMRegister;
using DoubleRegister = XMMRegister;
using Simd128Register = XMMRegister;
#define DECLARE_REGISTER(R) \
constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>();
DOUBLE_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
// Define {RegisterName} methods for the register types.
DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS)
DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS)
// Give alias names to registers for calling conventions.
constexpr Register kReturnRegister0 = rax;
constexpr Register kReturnRegister1 = rdx;
constexpr Register kReturnRegister2 = r8;
constexpr Register kJSFunctionRegister = rdi;
constexpr Register kContextRegister = rsi;
constexpr Register kAllocateSizeRegister = rdx;
constexpr Register kSpeculationPoisonRegister = r12;
constexpr Register kInterpreterAccumulatorRegister = rax;
constexpr Register kInterpreterBytecodeOffsetRegister = r9;
constexpr Register kInterpreterBytecodeArrayRegister = r14;
constexpr Register kInterpreterDispatchTableRegister = r15;
constexpr Register kJavaScriptCallArgCountRegister = rax;
constexpr Register kJavaScriptCallCodeStartRegister = rcx;
constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister;
constexpr Register kJavaScriptCallNewTargetRegister = rdx;
constexpr Register kJavaScriptCallExtraArg1Register = rbx;
constexpr Register kRuntimeCallFunctionRegister = rbx;
constexpr Register kRuntimeCallArgCountRegister = rax;
constexpr Register kRuntimeCallArgvRegister = r15;
constexpr Register kWasmInstanceRegister = rsi;
// Default scratch register used by MacroAssembler (and other code that needs
// a spare register). The register isn't callee save, and not used by the
// function calling convention.
constexpr Register kScratchRegister = r10;
constexpr XMMRegister kScratchDoubleReg = xmm15;
constexpr Register kRootRegister = r13; // callee save
constexpr Register kOffHeapTrampolineRegister = kScratchRegister;
} // namespace internal
} // namespace v8
#endif // V8_CODEGEN_X64_REGISTER_X64_H_