Commit 206dde8c authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[x64] Make Operand constexpr

This allows to turn two field in the LiftoffAssembler into constants.

R=thibaudm@chromium.org

Bug: v8:12425
Change-Id: Ie39ca73d6bb704b42bd449eed984f426e69deeb5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3585956Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79989}
parent 8de92b4b
...@@ -172,13 +172,13 @@ class V8_EXPORT_PRIVATE Operand { ...@@ -172,13 +172,13 @@ class V8_EXPORT_PRIVATE Operand {
public: public:
struct Data { struct Data {
byte rex = 0; byte rex = 0;
byte buf[9]; byte buf[9] = {0};
byte len = 1; // number of bytes of buf_ in use. byte len = 1; // number of bytes of buf_ in use.
int8_t addend; // for rip + offset + addend. int8_t addend = 0; // for rip + offset + addend.
}; };
// [base + disp/r] // [base + disp/r]
V8_INLINE Operand(Register base, int32_t disp) { V8_INLINE constexpr Operand(Register base, int32_t disp) {
if (base == rsp || base == r12) { if (base == rsp || base == r12) {
// SIB byte is needed to encode (rsp + offset) or (r12 + offset). // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
set_sib(times_1, rsp, base); set_sib(times_1, rsp, base);
...@@ -245,14 +245,15 @@ class V8_EXPORT_PRIVATE Operand { ...@@ -245,14 +245,15 @@ class V8_EXPORT_PRIVATE Operand {
bool AddressUsesRegister(Register reg) const; bool AddressUsesRegister(Register reg) const;
private: private:
V8_INLINE void set_modrm(int mod, Register rm_reg) { V8_INLINE constexpr void set_modrm(int mod, Register rm_reg) {
DCHECK(is_uint2(mod)); DCHECK(is_uint2(mod));
data_.buf[0] = mod << 6 | rm_reg.low_bits(); data_.buf[0] = mod << 6 | rm_reg.low_bits();
// Set REX.B to the high bit of rm.code(). // Set REX.B to the high bit of rm.code().
data_.rex |= rm_reg.high_bit(); data_.rex |= rm_reg.high_bit();
} }
V8_INLINE void set_sib(ScaleFactor scale, Register index, Register base) { V8_INLINE constexpr void set_sib(ScaleFactor scale, Register index,
Register base) {
DCHECK_EQ(data_.len, 1); DCHECK_EQ(data_.len, 1);
DCHECK(is_uint2(scale)); DCHECK(is_uint2(scale));
// Use SIB with no index register only for base rsp or r12. Otherwise we // Use SIB with no index register only for base rsp or r12. Otherwise we
...@@ -263,11 +264,10 @@ class V8_EXPORT_PRIVATE Operand { ...@@ -263,11 +264,10 @@ class V8_EXPORT_PRIVATE Operand {
data_.len = 2; data_.len = 2;
} }
V8_INLINE void set_disp8(int disp) { V8_INLINE constexpr void set_disp8(int disp) {
DCHECK(is_int8(disp)); DCHECK(is_int8(disp));
DCHECK(data_.len == 1 || data_.len == 2); DCHECK(data_.len == 1 || data_.len == 2);
int8_t* p = reinterpret_cast<int8_t*>(&data_.buf[data_.len]); data_.buf[data_.len] = disp;
*p = disp;
data_.len += sizeof(int8_t); data_.len += sizeof(int8_t);
} }
......
...@@ -60,13 +60,13 @@ enum RegisterCode { ...@@ -60,13 +60,13 @@ enum RegisterCode {
class Register : public RegisterBase<Register, kRegAfterLast> { class Register : public RegisterBase<Register, kRegAfterLast> {
public: public:
bool is_byte_register() const { return code() <= 3; } constexpr bool is_byte_register() const { return code() <= 3; }
// Return the high bit of the register code as a 0 or 1. Used often // Return the high bit of the register code as a 0 or 1. Used often
// when constructing the REX prefix byte. // when constructing the REX prefix byte.
int high_bit() const { return code() >> 3; } constexpr int high_bit() const { return code() >> 3; }
// Return the 3 low bits of the register code. Used when encoding registers // Return the 3 low bits of the register code. Used when encoding registers
// in modR/M, SIB, and opcode bytes. // in modR/M, SIB, and opcode bytes.
int low_bits() const { return code() & 0x7; } constexpr int low_bits() const { return code() & 0x7; }
private: private:
friend class RegisterBase<Register, kRegAfterLast>; friend class RegisterBase<Register, kRegAfterLast>;
......
...@@ -395,19 +395,19 @@ inline int32_t signed_bitextract_32(int msb, int lsb, uint32_t x) { ...@@ -395,19 +395,19 @@ inline int32_t signed_bitextract_32(int msb, int lsb, uint32_t x) {
} }
// Check number width. // Check number width.
inline bool is_intn(int64_t x, unsigned n) { inline constexpr bool is_intn(int64_t x, unsigned n) {
DCHECK((0 < n) && (n < 64)); DCHECK((0 < n) && (n < 64));
int64_t limit = static_cast<int64_t>(1) << (n - 1); int64_t limit = static_cast<int64_t>(1) << (n - 1);
return (-limit <= x) && (x < limit); return (-limit <= x) && (x < limit);
} }
inline bool is_uintn(int64_t x, unsigned n) { inline constexpr bool is_uintn(int64_t x, unsigned n) {
DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte))); DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
return !(x >> n); return !(x >> n);
} }
template <class T> template <class T>
inline T truncate_to_intn(T x, unsigned n) { inline constexpr T truncate_to_intn(T x, unsigned n) {
DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte))); DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
return (x & ((static_cast<T>(1) << n) - 1)); return (x & ((static_cast<T>(1) << n) - 1));
} }
...@@ -424,15 +424,15 @@ inline T truncate_to_intn(T x, unsigned n) { ...@@ -424,15 +424,15 @@ inline T truncate_to_intn(T x, unsigned n) {
// clang-format on // clang-format on
#define DECLARE_IS_INT_N(N) \ #define DECLARE_IS_INT_N(N) \
inline bool is_int##N(int64_t x) { return is_intn(x, N); } inline constexpr bool is_int##N(int64_t x) { return is_intn(x, N); }
#define DECLARE_IS_UINT_N(N) \ #define DECLARE_IS_UINT_N(N) \
template <class T> \ template <class T> \
inline bool is_uint##N(T x) { \ inline constexpr bool is_uint##N(T x) { \
return is_uintn(x, N); \ return is_uintn(x, N); \
} }
#define DECLARE_TRUNCATE_TO_INT_N(N) \ #define DECLARE_TRUNCATE_TO_INT_N(N) \
template <class T> \ template <class T> \
inline T truncate_to_int##N(T x) { \ inline constexpr T truncate_to_int##N(T x) { \
return truncate_to_intn(x, N); \ return truncate_to_intn(x, N); \
} }
INT_1_TO_63_LIST(DECLARE_IS_INT_N) INT_1_TO_63_LIST(DECLARE_IS_INT_N)
......
...@@ -69,12 +69,13 @@ constexpr int kInstanceOffset = 16; ...@@ -69,12 +69,13 @@ constexpr int kInstanceOffset = 16;
constexpr int kFeedbackVectorOffset = 24; // rbp-24 is the feedback vector. constexpr int kFeedbackVectorOffset = 24; // rbp-24 is the feedback vector.
constexpr int kTierupBudgetOffset = 32; // rbp-32 is the feedback vector. constexpr int kTierupBudgetOffset = 32; // rbp-32 is the feedback vector.
inline Operand GetStackSlot(int offset) { return Operand(rbp, -offset); } inline constexpr Operand GetStackSlot(int offset) {
return Operand(rbp, -offset);
}
// TODO(clemensb): Make this a constexpr variable once Operand is constexpr. constexpr Operand kInstanceOperand = GetStackSlot(kInstanceOffset);
inline Operand GetInstanceOperand() { return GetStackSlot(kInstanceOffset); }
inline Operand GetOSRTargetSlot() { return GetStackSlot(kOSRTargetOffset); } constexpr Operand kOSRTargetSlot = GetStackSlot(kOSRTargetOffset);
inline Operand GetMemOp(LiftoffAssembler* assm, Register addr, Register offset, inline Operand GetMemOp(LiftoffAssembler* assm, Register addr, Register offset,
uintptr_t offset_imm) { uintptr_t offset_imm) {
...@@ -329,7 +330,7 @@ void LiftoffAssembler::LoadConstant(LiftoffRegister reg, WasmValue value, ...@@ -329,7 +330,7 @@ void LiftoffAssembler::LoadConstant(LiftoffRegister reg, WasmValue value,
} }
void LiftoffAssembler::LoadInstanceFromFrame(Register dst) { void LiftoffAssembler::LoadInstanceFromFrame(Register dst) {
movq(dst, liftoff::GetInstanceOperand()); movq(dst, liftoff::kInstanceOperand);
} }
void LiftoffAssembler::LoadFromInstance(Register dst, Register instance, void LiftoffAssembler::LoadFromInstance(Register dst, Register instance,
...@@ -367,11 +368,11 @@ void LiftoffAssembler::LoadExternalPointer(Register dst, Register instance, ...@@ -367,11 +368,11 @@ void LiftoffAssembler::LoadExternalPointer(Register dst, Register instance,
} }
void LiftoffAssembler::SpillInstance(Register instance) { void LiftoffAssembler::SpillInstance(Register instance) {
movq(liftoff::GetInstanceOperand(), instance); movq(liftoff::kInstanceOperand, instance);
} }
void LiftoffAssembler::ResetOSRTarget() { void LiftoffAssembler::ResetOSRTarget() {
movq(liftoff::GetOSRTargetSlot(), Immediate(0)); movq(liftoff::kOSRTargetSlot, Immediate(0));
} }
void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr, void LiftoffAssembler::LoadTaggedPointer(Register dst, Register src_addr,
...@@ -4164,7 +4165,7 @@ void LiftoffAssembler::DeallocateStackSlot(uint32_t size) { ...@@ -4164,7 +4165,7 @@ void LiftoffAssembler::DeallocateStackSlot(uint32_t size) {
} }
void LiftoffAssembler::MaybeOSR() { void LiftoffAssembler::MaybeOSR() {
cmpq(liftoff::GetOSRTargetSlot(), Immediate(0)); cmpq(liftoff::kOSRTargetSlot, Immediate(0));
j(not_equal, static_cast<Address>(WasmCode::kWasmOnStackReplace), j(not_equal, static_cast<Address>(WasmCode::kWasmOnStackReplace),
RelocInfo::WASM_STUB_CALL); RelocInfo::WASM_STUB_CALL);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment