[assembler] Make register definitions constexpr

I originally needed this for the initialization of a constexpr array in
the wasm lazy compile builtin, but since it's a bigger change, I now
split it off as this separate CL.
The style guide recommends constexpr over const. I thus apply the
constexprificaton over all headers that I touched anyway.

I also remove the ARM64_DEFINE_REG_STATICS hack. It was introduced when
merging in arm64 support more than three years ago, and I don't see the
purpose for this.
Also, some #defines can now be constexpr definitions, which was not
possible before according to the comment.

R=bmeurer@chromium.org, mstarzinger@chromium.org, ishell@chromium.org

Change-Id: I6d743b4462c347d363f99e28007bc9e8c84ae617
Reviewed-on: https://chromium-review.googlesource.com/451277
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43637}
This commit is contained in:
Clemens Hammacher 2017-03-07 09:54:00 +01:00 committed by Commit Bot
parent 8038f1bd67
commit e82b7ccd32
8 changed files with 432 additions and 497 deletions

View File

@ -114,7 +114,7 @@ struct Register {
kCode_no_reg = -1
};
static const int kNumRegisters = Code::kAfterLast;
static constexpr int kNumRegisters = Code::kAfterLast;
static Register from_code(int code) {
DCHECK(code >= 0);
@ -144,13 +144,13 @@ struct Register {
// r7: context register
// r8: constant pool pointer register if FLAG_enable_embedded_constant_pool.
// r9: lithium scratch
#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
#define DECLARE_REGISTER(R) constexpr Register R = {Register::kCode_##R};
GENERAL_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
const Register no_reg = {Register::kCode_no_reg};
constexpr Register no_reg = {Register::kCode_no_reg};
static const bool kSimpleFPAliasing = false;
static const bool kSimdMaskRegisters = false;
constexpr bool kSimpleFPAliasing = false;
constexpr bool kSimdMaskRegisters = false;
// Single word VFP register.
struct SwVfpRegister {
@ -162,9 +162,9 @@ struct SwVfpRegister {
kCode_no_reg = -1
};
static const int kMaxNumRegisters = Code::kAfterLast;
static constexpr int kMaxNumRegisters = Code::kAfterLast;
static const int kSizeInBytes = 4;
static constexpr int kSizeInBytes = 4;
bool is_valid() const { return 0 <= reg_code && reg_code < 32; }
bool is(SwVfpRegister reg) const { return reg_code == reg.reg_code; }
@ -201,7 +201,7 @@ struct DwVfpRegister {
kCode_no_reg = -1
};
static const int kMaxNumRegisters = Code::kAfterLast;
static constexpr int kMaxNumRegisters = Code::kAfterLast;
inline static int NumRegisters();
@ -209,7 +209,7 @@ struct DwVfpRegister {
// hold 0.0, that does not fit in the immediate field of vmov instructions.
// d14: 0.0
// d15: scratch register.
static const int kSizeInBytes = 8;
static constexpr int kSizeInBytes = 8;
bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; }
@ -242,10 +242,9 @@ typedef DwVfpRegister DoubleRegister;
// Double word VFP register d0-15.
struct LowDwVfpRegister {
public:
static const int kMaxNumLowRegisters = 16;
operator DwVfpRegister() const {
DwVfpRegister r = { reg_code };
return r;
static constexpr int kMaxNumLowRegisters = 16;
constexpr operator DwVfpRegister() const {
return DwVfpRegister { reg_code };
}
static LowDwVfpRegister from_code(int code) {
LowDwVfpRegister r = { code };
@ -282,7 +281,7 @@ struct LowDwVfpRegister {
// Quad word NEON register.
struct QwNeonRegister {
static const int kMaxNumRegisters = 16;
static constexpr int kMaxNumRegisters = 16;
static QwNeonRegister from_code(int code) {
QwNeonRegister r = { code };
@ -328,102 +327,100 @@ typedef QwNeonRegister Simd128Register;
// Support for the VFP registers s0 to s31 (d0 to d15).
// Note that "s(N):s(N+1)" is the same as "d(N/2)".
const SwVfpRegister s0 = { 0 };
const SwVfpRegister s1 = { 1 };
const SwVfpRegister s2 = { 2 };
const SwVfpRegister s3 = { 3 };
const SwVfpRegister s4 = { 4 };
const SwVfpRegister s5 = { 5 };
const SwVfpRegister s6 = { 6 };
const SwVfpRegister s7 = { 7 };
const SwVfpRegister s8 = { 8 };
const SwVfpRegister s9 = { 9 };
const SwVfpRegister s10 = { 10 };
const SwVfpRegister s11 = { 11 };
const SwVfpRegister s12 = { 12 };
const SwVfpRegister s13 = { 13 };
const SwVfpRegister s14 = { 14 };
const SwVfpRegister s15 = { 15 };
const SwVfpRegister s16 = { 16 };
const SwVfpRegister s17 = { 17 };
const SwVfpRegister s18 = { 18 };
const SwVfpRegister s19 = { 19 };
const SwVfpRegister s20 = { 20 };
const SwVfpRegister s21 = { 21 };
const SwVfpRegister s22 = { 22 };
const SwVfpRegister s23 = { 23 };
const SwVfpRegister s24 = { 24 };
const SwVfpRegister s25 = { 25 };
const SwVfpRegister s26 = { 26 };
const SwVfpRegister s27 = { 27 };
const SwVfpRegister s28 = { 28 };
const SwVfpRegister s29 = { 29 };
const SwVfpRegister s30 = { 30 };
const SwVfpRegister s31 = { 31 };
constexpr SwVfpRegister s0 = { 0 };
constexpr SwVfpRegister s1 = { 1 };
constexpr SwVfpRegister s2 = { 2 };
constexpr SwVfpRegister s3 = { 3 };
constexpr SwVfpRegister s4 = { 4 };
constexpr SwVfpRegister s5 = { 5 };
constexpr SwVfpRegister s6 = { 6 };
constexpr SwVfpRegister s7 = { 7 };
constexpr SwVfpRegister s8 = { 8 };
constexpr SwVfpRegister s9 = { 9 };
constexpr SwVfpRegister s10 = { 10 };
constexpr SwVfpRegister s11 = { 11 };
constexpr SwVfpRegister s12 = { 12 };
constexpr SwVfpRegister s13 = { 13 };
constexpr SwVfpRegister s14 = { 14 };
constexpr SwVfpRegister s15 = { 15 };
constexpr SwVfpRegister s16 = { 16 };
constexpr SwVfpRegister s17 = { 17 };
constexpr SwVfpRegister s18 = { 18 };
constexpr SwVfpRegister s19 = { 19 };
constexpr SwVfpRegister s20 = { 20 };
constexpr SwVfpRegister s21 = { 21 };
constexpr SwVfpRegister s22 = { 22 };
constexpr SwVfpRegister s23 = { 23 };
constexpr SwVfpRegister s24 = { 24 };
constexpr SwVfpRegister s25 = { 25 };
constexpr SwVfpRegister s26 = { 26 };
constexpr SwVfpRegister s27 = { 27 };
constexpr SwVfpRegister s28 = { 28 };
constexpr SwVfpRegister s29 = { 29 };
constexpr SwVfpRegister s30 = { 30 };
constexpr SwVfpRegister s31 = { 31 };
const DwVfpRegister no_dreg = { -1 };
const LowDwVfpRegister d0 = { 0 };
const LowDwVfpRegister d1 = { 1 };
const LowDwVfpRegister d2 = { 2 };
const LowDwVfpRegister d3 = { 3 };
const LowDwVfpRegister d4 = { 4 };
const LowDwVfpRegister d5 = { 5 };
const LowDwVfpRegister d6 = { 6 };
const LowDwVfpRegister d7 = { 7 };
const LowDwVfpRegister d8 = { 8 };
const LowDwVfpRegister d9 = { 9 };
const LowDwVfpRegister d10 = { 10 };
const LowDwVfpRegister d11 = { 11 };
const LowDwVfpRegister d12 = { 12 };
const LowDwVfpRegister d13 = { 13 };
const LowDwVfpRegister d14 = { 14 };
const LowDwVfpRegister d15 = { 15 };
const DwVfpRegister d16 = { 16 };
const DwVfpRegister d17 = { 17 };
const DwVfpRegister d18 = { 18 };
const DwVfpRegister d19 = { 19 };
const DwVfpRegister d20 = { 20 };
const DwVfpRegister d21 = { 21 };
const DwVfpRegister d22 = { 22 };
const DwVfpRegister d23 = { 23 };
const DwVfpRegister d24 = { 24 };
const DwVfpRegister d25 = { 25 };
const DwVfpRegister d26 = { 26 };
const DwVfpRegister d27 = { 27 };
const DwVfpRegister d28 = { 28 };
const DwVfpRegister d29 = { 29 };
const DwVfpRegister d30 = { 30 };
const DwVfpRegister d31 = { 31 };
constexpr DwVfpRegister no_dreg = { -1 };
constexpr LowDwVfpRegister d0 = { 0 };
constexpr LowDwVfpRegister d1 = { 1 };
constexpr LowDwVfpRegister d2 = { 2 };
constexpr LowDwVfpRegister d3 = { 3 };
constexpr LowDwVfpRegister d4 = { 4 };
constexpr LowDwVfpRegister d5 = { 5 };
constexpr LowDwVfpRegister d6 = { 6 };
constexpr LowDwVfpRegister d7 = { 7 };
constexpr LowDwVfpRegister d8 = { 8 };
constexpr LowDwVfpRegister d9 = { 9 };
constexpr LowDwVfpRegister d10 = { 10 };
constexpr LowDwVfpRegister d11 = { 11 };
constexpr LowDwVfpRegister d12 = { 12 };
constexpr LowDwVfpRegister d13 = { 13 };
constexpr LowDwVfpRegister d14 = { 14 };
constexpr LowDwVfpRegister d15 = { 15 };
constexpr DwVfpRegister d16 = { 16 };
constexpr DwVfpRegister d17 = { 17 };
constexpr DwVfpRegister d18 = { 18 };
constexpr DwVfpRegister d19 = { 19 };
constexpr DwVfpRegister d20 = { 20 };
constexpr DwVfpRegister d21 = { 21 };
constexpr DwVfpRegister d22 = { 22 };
constexpr DwVfpRegister d23 = { 23 };
constexpr DwVfpRegister d24 = { 24 };
constexpr DwVfpRegister d25 = { 25 };
constexpr DwVfpRegister d26 = { 26 };
constexpr DwVfpRegister d27 = { 27 };
constexpr DwVfpRegister d28 = { 28 };
constexpr DwVfpRegister d29 = { 29 };
constexpr DwVfpRegister d30 = { 30 };
constexpr DwVfpRegister d31 = { 31 };
const QwNeonRegister q0 = { 0 };
const QwNeonRegister q1 = { 1 };
const QwNeonRegister q2 = { 2 };
const QwNeonRegister q3 = { 3 };
const QwNeonRegister q4 = { 4 };
const QwNeonRegister q5 = { 5 };
const QwNeonRegister q6 = { 6 };
const QwNeonRegister q7 = { 7 };
const QwNeonRegister q8 = { 8 };
const QwNeonRegister q9 = { 9 };
const QwNeonRegister q10 = { 10 };
const QwNeonRegister q11 = { 11 };
const QwNeonRegister q12 = { 12 };
const QwNeonRegister q13 = { 13 };
const QwNeonRegister q14 = { 14 };
const QwNeonRegister q15 = { 15 };
constexpr QwNeonRegister q0 = { 0 };
constexpr QwNeonRegister q1 = { 1 };
constexpr QwNeonRegister q2 = { 2 };
constexpr QwNeonRegister q3 = { 3 };
constexpr QwNeonRegister q4 = { 4 };
constexpr QwNeonRegister q5 = { 5 };
constexpr QwNeonRegister q6 = { 6 };
constexpr QwNeonRegister q7 = { 7 };
constexpr QwNeonRegister q8 = { 8 };
constexpr QwNeonRegister q9 = { 9 };
constexpr QwNeonRegister q10 = { 10 };
constexpr QwNeonRegister q11 = { 11 };
constexpr QwNeonRegister q12 = { 12 };
constexpr QwNeonRegister q13 = { 13 };
constexpr QwNeonRegister q14 = { 14 };
constexpr QwNeonRegister q15 = { 15 };
// Aliases for double registers. Defined using #define instead of
// "static const DwVfpRegister&" because Clang complains otherwise when a
// compilation unit that includes this header doesn't use the variables.
#define kFirstCalleeSavedDoubleReg d8
#define kLastCalleeSavedDoubleReg d15
// Aliases for double registers.
constexpr LowDwVfpRegister kFirstCalleeSavedDoubleReg = d8;
constexpr LowDwVfpRegister kLastCalleeSavedDoubleReg = d15;
// kDoubleRegZero and kScratchDoubleReg must pair to form kScratchQuadReg. SIMD
// code depends on kDoubleRegZero before kScratchDoubleReg.
#define kDoubleRegZero d14
#define kScratchDoubleReg d15
constexpr LowDwVfpRegister kDoubleRegZero = d14;
constexpr LowDwVfpRegister kScratchDoubleReg = d15;
// After using kScratchQuadReg, kDoubleRegZero must be reset to 0.
#define kScratchQuadReg q7
constexpr QwNeonRegister kScratchQuadReg = q7;
// Coprocessor register
struct CRegister {
@ -443,24 +440,24 @@ struct CRegister {
};
const CRegister no_creg = { -1 };
constexpr CRegister no_creg = { -1 };
const CRegister cr0 = { 0 };
const CRegister cr1 = { 1 };
const CRegister cr2 = { 2 };
const CRegister cr3 = { 3 };
const CRegister cr4 = { 4 };
const CRegister cr5 = { 5 };
const CRegister cr6 = { 6 };
const CRegister cr7 = { 7 };
const CRegister cr8 = { 8 };
const CRegister cr9 = { 9 };
const CRegister cr10 = { 10 };
const CRegister cr11 = { 11 };
const CRegister cr12 = { 12 };
const CRegister cr13 = { 13 };
const CRegister cr14 = { 14 };
const CRegister cr15 = { 15 };
constexpr CRegister cr0 = { 0 };
constexpr CRegister cr1 = { 1 };
constexpr CRegister cr2 = { 2 };
constexpr CRegister cr3 = { 3 };
constexpr CRegister cr4 = { 4 };
constexpr CRegister cr5 = { 5 };
constexpr CRegister cr6 = { 6 };
constexpr CRegister cr7 = { 7 };
constexpr CRegister cr8 = { 8 };
constexpr CRegister cr9 = { 9 };
constexpr CRegister cr10 = { 10 };
constexpr CRegister cr11 = { 11 };
constexpr CRegister cr12 = { 12 };
constexpr CRegister cr13 = { 13 };
constexpr CRegister cr14 = { 14 };
constexpr CRegister cr15 = { 15 };
// Coprocessor number
@ -671,8 +668,8 @@ class NeonListOperand BASE_EMBEDDED {
struct VmovIndex {
unsigned char index;
};
const VmovIndex VmovIndexLo = { 0 };
const VmovIndex VmovIndexHi = { 1 };
constexpr VmovIndex VmovIndexLo = { 0 };
constexpr VmovIndex VmovIndexHi = { 1 };
class Assembler : public AssemblerBase {
public:
@ -760,24 +757,24 @@ class Assembler : public AssemblerBase {
// Here we are patching the address in the constant pool, not the actual call
// instruction. The address in the constant pool is the same size as a
// pointer.
static const int kSpecialTargetSize = kPointerSize;
static constexpr int kSpecialTargetSize = kPointerSize;
// Size of an instruction.
static const int kInstrSize = sizeof(Instr);
static constexpr int kInstrSize = sizeof(Instr);
// Distance between start of patched debug break slot and the emitted address
// to jump to.
// Patched debug break slot code is:
// ldr ip, [pc, #0] @ emited address and start
// blx ip
static const int kPatchDebugBreakSlotAddressOffset = 2 * kInstrSize;
static constexpr int kPatchDebugBreakSlotAddressOffset = 2 * kInstrSize;
// Difference between address of current opcode and value read from pc
// register.
static const int kPcLoadDelta = 8;
static constexpr int kPcLoadDelta = 8;
static const int kDebugBreakSlotInstructions = 4;
static const int kDebugBreakSlotLength =
static constexpr int kDebugBreakSlotInstructions = 4;
static constexpr int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstrSize;
// ---------------------------------------------------------------------------
@ -1592,12 +1589,14 @@ class Assembler : public AssemblerBase {
// reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point
// PC-relative loads, thereby defining a maximum distance between the
// instruction and the accessed constant.
static const int kMaxDistToIntPool = 4*KB;
static const int kMaxDistToFPPool = 1*KB;
static constexpr int kMaxDistToIntPool = 4 * KB;
static constexpr int kMaxDistToFPPool = 1 * KB;
// All relocations could be integer, it therefore acts as the limit.
static const int kMinNumPendingConstants = 4;
static const int kMaxNumPending32Constants = kMaxDistToIntPool / kInstrSize;
static const int kMaxNumPending64Constants = kMaxDistToFPPool / kInstrSize;
static constexpr int kMinNumPendingConstants = 4;
static constexpr int kMaxNumPending32Constants =
kMaxDistToIntPool / kInstrSize;
static constexpr int kMaxNumPending64Constants =
kMaxDistToFPPool / kInstrSize;
// Postpone the generation of the constant pool for the specified number of
// instructions.
@ -1700,7 +1699,7 @@ class Assembler : public AssemblerBase {
// the generated instructions. This is so that multi-instruction sequences do
// not have to check for overflow. The same is true for writes of large
// relocation info entries.
static const int kGap = 32;
static constexpr int kGap = 32;
// Constant pool generation
// Pools are emitted in the instruction stream, preferably after unconditional
@ -1716,8 +1715,8 @@ class Assembler : public AssemblerBase {
// expensive. By default we only check again once a number of instructions
// has been generated. That also means that the sizing of the buffers is not
// an exact science, and that we rely on some slop to not overrun buffers.
static const int kCheckPoolIntervalInst = 32;
static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize;
static constexpr int kCheckPoolIntervalInst = 32;
static constexpr int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize;
// Emission of the constant pool may be blocked in some code sequences.
@ -1731,7 +1730,7 @@ class Assembler : public AssemblerBase {
// Relocation info generation
// Each relocation is encoded as a variable size value
static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize;
RelocInfoWriter reloc_info_writer;
// ConstantPoolEntry records are used during code generation as temporary
@ -1785,7 +1784,7 @@ class Assembler : public AssemblerBase {
friend class EnsureSpace;
};
static const int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize;
constexpr int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize;
class EnsureSpace BASE_EMBEDDED {
public:

View File

@ -28,7 +28,6 @@
#if V8_TARGET_ARCH_ARM64
#define ARM64_DEFINE_REG_STATICS
#include "src/arm64/assembler-arm64.h"
#include "src/arm64/assembler-arm64-inl.h"

View File

@ -63,8 +63,7 @@ namespace internal {
R(d25) R(d26) R(d27) R(d28)
// clang-format on
static const int kRegListSizeInBits = sizeof(RegList) * kBitsPerByte;
constexpr int kRegListSizeInBits = sizeof(RegList) * kBitsPerByte;
// Some CPURegister methods can return Register and FPRegister types, so we
// need to declare them in advance.
@ -90,6 +89,11 @@ struct CPURegister {
kNoRegister
};
constexpr CPURegister() : CPURegister(0, 0, CPURegister::kNoRegister) {}
constexpr CPURegister(int reg_code, int reg_size, RegisterType reg_type)
: reg_code(reg_code), reg_size(reg_size), reg_type(reg_type) {}
static CPURegister Create(int code, int size, RegisterType type) {
CPURegister r = {code, size, type};
return r;
@ -138,25 +142,9 @@ struct Register : public CPURegister {
return Register(CPURegister::Create(code, size, CPURegister::kRegister));
}
Register() {
reg_code = 0;
reg_size = 0;
reg_type = CPURegister::kNoRegister;
}
constexpr Register() : CPURegister() {}
explicit Register(const CPURegister& r) {
reg_code = r.reg_code;
reg_size = r.reg_size;
reg_type = r.reg_type;
DCHECK(IsValidOrNone());
}
Register(const Register& r) { // NOLINT(runtime/explicit)
reg_code = r.reg_code;
reg_size = r.reg_size;
reg_type = r.reg_type;
DCHECK(IsValidOrNone());
}
constexpr explicit Register(const CPURegister& r) : CPURegister(r) {}
bool IsValid() const {
DCHECK(IsRegister() || IsNone());
@ -170,7 +158,7 @@ struct Register : public CPURegister {
// These memebers are necessary for compilation.
// A few of them may be unused for now.
static const int kNumRegisters = kNumberOfRegisters;
static constexpr int kNumRegisters = kNumberOfRegisters;
STATIC_ASSERT(kNumRegisters == Code::kAfterLast);
static int NumRegisters() { return kNumRegisters; }
@ -197,8 +185,8 @@ struct Register : public CPURegister {
// End of V8 compatibility section -----------------------
};
static const bool kSimpleFPAliasing = true;
static const bool kSimdMaskRegisters = false;
constexpr bool kSimpleFPAliasing = true;
constexpr bool kSimdMaskRegisters = false;
struct FPRegister : public CPURegister {
enum Code {
@ -214,25 +202,9 @@ struct FPRegister : public CPURegister {
CPURegister::Create(code, size, CPURegister::kFPRegister));
}
FPRegister() {
reg_code = 0;
reg_size = 0;
reg_type = CPURegister::kNoRegister;
}
constexpr FPRegister() : CPURegister() {}
explicit FPRegister(const CPURegister& r) {
reg_code = r.reg_code;
reg_size = r.reg_size;
reg_type = r.reg_type;
DCHECK(IsValidOrNone());
}
FPRegister(const FPRegister& r) { // NOLINT(runtime/explicit)
reg_code = r.reg_code;
reg_size = r.reg_size;
reg_type = r.reg_type;
DCHECK(IsValidOrNone());
}
constexpr explicit FPRegister(const CPURegister& r) : CPURegister(r) {}
bool IsValid() const {
DCHECK(IsFPRegister() || IsNone());
@ -243,7 +215,7 @@ struct FPRegister : public CPURegister {
static FPRegister DRegFromCode(unsigned code);
// Start of V8 compatibility section ---------------------
static const int kMaxNumRegisters = kNumberOfFPRegisters;
static constexpr int kMaxNumRegisters = kNumberOfFPRegisters;
STATIC_ASSERT(kMaxNumRegisters == Code::kAfterLast);
// Crankshaft can use all the FP registers except:
@ -261,54 +233,41 @@ struct FPRegister : public CPURegister {
STATIC_ASSERT(sizeof(CPURegister) == sizeof(Register));
STATIC_ASSERT(sizeof(CPURegister) == sizeof(FPRegister));
#if defined(ARM64_DEFINE_REG_STATICS)
#define INITIALIZE_REGISTER(register_class, name, code, size, type) \
const CPURegister init_##register_class##_##name = {code, size, type}; \
const register_class& name = *reinterpret_cast<const register_class*>( \
&init_##register_class##_##name)
#define ALIAS_REGISTER(register_class, alias, name) \
const register_class& alias = *reinterpret_cast<const register_class*>( \
&init_##register_class##_##name)
#else
#define INITIALIZE_REGISTER(register_class, name, code, size, type) \
extern const register_class& name
#define DEFINE_REGISTER(register_class, name, code, size, type) \
constexpr register_class name { CPURegister(code, size, type) }
#define ALIAS_REGISTER(register_class, alias, name) \
extern const register_class& alias
#endif // defined(ARM64_DEFINE_REG_STATICS)
constexpr register_class alias = name
// No*Reg is used to indicate an unused argument, or an error case. Note that
// these all compare equal (using the Is() method). The Register and FPRegister
// variants are provided for convenience.
INITIALIZE_REGISTER(Register, NoReg, 0, 0, CPURegister::kNoRegister);
INITIALIZE_REGISTER(FPRegister, NoFPReg, 0, 0, CPURegister::kNoRegister);
INITIALIZE_REGISTER(CPURegister, NoCPUReg, 0, 0, CPURegister::kNoRegister);
DEFINE_REGISTER(Register, NoReg, 0, 0, CPURegister::kNoRegister);
DEFINE_REGISTER(FPRegister, NoFPReg, 0, 0, CPURegister::kNoRegister);
DEFINE_REGISTER(CPURegister, NoCPUReg, 0, 0, CPURegister::kNoRegister);
// v8 compatibility.
INITIALIZE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister);
DEFINE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister);
#define DEFINE_REGISTERS(N) \
INITIALIZE_REGISTER(Register, w##N, N, \
kWRegSizeInBits, CPURegister::kRegister); \
INITIALIZE_REGISTER(Register, x##N, N, \
kXRegSizeInBits, CPURegister::kRegister);
#define DEFINE_REGISTERS(N) \
DEFINE_REGISTER(Register, w##N, N, kWRegSizeInBits, CPURegister::kRegister); \
DEFINE_REGISTER(Register, x##N, N, kXRegSizeInBits, CPURegister::kRegister);
GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS)
#undef DEFINE_REGISTERS
INITIALIZE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits,
CPURegister::kRegister);
INITIALIZE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits,
CPURegister::kRegister);
DEFINE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits,
CPURegister::kRegister);
DEFINE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits,
CPURegister::kRegister);
#define DEFINE_FPREGISTERS(N) \
INITIALIZE_REGISTER(FPRegister, s##N, N, \
kSRegSizeInBits, CPURegister::kFPRegister); \
INITIALIZE_REGISTER(FPRegister, d##N, N, \
kDRegSizeInBits, CPURegister::kFPRegister);
#define DEFINE_FPREGISTERS(N) \
DEFINE_REGISTER(FPRegister, s##N, N, kSRegSizeInBits, \
CPURegister::kFPRegister); \
DEFINE_REGISTER(FPRegister, d##N, N, kDRegSizeInBits, \
CPURegister::kFPRegister);
GENERAL_REGISTER_CODE_LIST(DEFINE_FPREGISTERS)
#undef DEFINE_FPREGISTERS
#undef INITIALIZE_REGISTER
#undef DEFINE_REGISTER
// Registers aliases.
ALIAS_REGISTER(Register, ip0, x16);
@ -566,8 +525,8 @@ class Immediate {
// -----------------------------------------------------------------------------
// Operands.
const int kSmiShift = kSmiTagSize + kSmiShiftSize;
const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1;
constexpr int kSmiShift = kSmiTagSize + kSmiShiftSize;
constexpr uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1;
// Represents an operand in a machine instruction.
class Operand {
@ -836,7 +795,7 @@ class Assembler : public AssemblerBase {
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// All addresses in the constant pool are the same size as pointers.
static const int kSpecialTargetSize = kPointerSize;
static constexpr int kSpecialTargetSize = kPointerSize;
// The sizes of the call sequences emitted by MacroAssembler::Call.
// Wherever possible, use MacroAssembler::CallSize instead of these constants,
@ -851,8 +810,8 @@ class Assembler : public AssemblerBase {
// With relocation:
// ldr temp, =target
// blr temp
static const int kCallSizeWithoutRelocation = 4 * kInstructionSize;
static const int kCallSizeWithRelocation = 2 * kInstructionSize;
static constexpr int kCallSizeWithoutRelocation = 4 * kInstructionSize;
static constexpr int kCallSizeWithRelocation = 2 * kInstructionSize;
// Size of the generated code in bytes
uint64_t SizeOfGeneratedCode() const {
@ -884,12 +843,12 @@ class Assembler : public AssemblerBase {
return SizeOfCodeGeneratedSince(label) / kInstructionSize;
}
static const int kPatchDebugBreakSlotAddressOffset = 0;
static constexpr int kPatchDebugBreakSlotAddressOffset = 0;
// Number of instructions necessary to be able to later patch it to a call.
static const int kDebugBreakSlotInstructions = 5;
static const int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstructionSize;
static constexpr int kDebugBreakSlotInstructions = 5;
static constexpr int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstructionSize;
// Prevent contant pool emission until EndBlockConstPool is called.
// Call to this function can be nested but must be followed by an equal
@ -1847,7 +1806,7 @@ class Assembler : public AssemblerBase {
// The maximum code size generated for a veneer. Currently one branch
// instruction. This is for code size checking purposes, and can be extended
// in the future for example if we decide to add nops between the veneers.
static const int kMaxVeneerCodeSize = 1 * kInstructionSize;
static constexpr int kMaxVeneerCodeSize = 1 * kInstructionSize;
void RecordVeneerPool(int location_offset, int size);
// Emits veneers for branches that are approaching their maximum range.
@ -2000,7 +1959,7 @@ class Assembler : public AssemblerBase {
// suitable for fields that take instruction offsets.
inline int LinkAndGetInstructionOffsetTo(Label* label);
static const int kStartOfLabelLinkChain = 0;
static constexpr int kStartOfLabelLinkChain = 0;
// Verify that a label's link chain is intact.
void CheckLabelLinkChain(Label const * label);
@ -2061,17 +2020,17 @@ class Assembler : public AssemblerBase {
// expensive. By default we only check again once a number of instructions
// has been generated. That also means that the sizing of the buffers is not
// an exact science, and that we rely on some slop to not overrun buffers.
static const int kCheckConstPoolInterval = 128;
static constexpr int kCheckConstPoolInterval = 128;
// Distance to first use after a which a pool will be emitted. Pool entries
// are accessed with pc relative load therefore this cannot be more than
// 1 * MB. Since constant pool emission checks are interval based this value
// is an approximation.
static const int kApproxMaxDistToConstPool = 64 * KB;
static constexpr int kApproxMaxDistToConstPool = 64 * KB;
// Number of pool entries after which a pool will be emitted. Since constant
// pool emission checks are interval based this value is an approximation.
static const int kApproxMaxPoolEntryCount = 512;
static constexpr int kApproxMaxPoolEntryCount = 512;
// Emission of the constant pool may be blocked in some code sequences.
int const_pool_blocked_nesting_; // Block emission if this is not zero.
@ -2082,7 +2041,7 @@ class Assembler : public AssemblerBase {
// Relocation info generation
// Each relocation is encoded as a variable size value
static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize;
RelocInfoWriter reloc_info_writer;
// Internal reference positions, required for (potential) patching in
// GrowBuffer(); contains only those internal references whose labels
@ -2121,7 +2080,7 @@ class Assembler : public AssemblerBase {
// not have to check for overflow. The same is true for writes of large
// relocation info entries, and debug strings encoded in the instruction
// stream.
static const int kGap = 128;
static constexpr int kGap = 128;
public:
class FarBranchInfo {
@ -2151,13 +2110,13 @@ class Assembler : public AssemblerBase {
// We generate a veneer for a branch if we reach within this distance of the
// limit of the range.
static const int kVeneerDistanceMargin = 1 * KB;
static constexpr int kVeneerDistanceMargin = 1 * KB;
// The factor of 2 is a finger in the air guess. With a default margin of
// 1KB, that leaves us an addional 256 instructions to avoid generating a
// protective branch.
static const int kVeneerNoProtectionFactor = 2;
static const int kVeneerDistanceCheckMargin =
kVeneerNoProtectionFactor * kVeneerDistanceMargin;
static constexpr int kVeneerNoProtectionFactor = 2;
static constexpr int kVeneerDistanceCheckMargin =
kVeneerNoProtectionFactor * kVeneerDistanceMargin;
int unresolved_branches_first_limit() const {
DCHECK(!unresolved_branches_.empty());
return unresolved_branches_.begin()->first;
@ -2221,8 +2180,8 @@ class PatchingAssembler : public Assembler {
}
// See definition of PatchAdrFar() for details.
static const int kAdrFarPatchableNNops = 2;
static const int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 2;
static constexpr int kAdrFarPatchableNNops = 2;
static constexpr int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 2;
void PatchAdrFar(int64_t target_offset);
};

View File

@ -116,7 +116,7 @@ struct Register {
kCode_no_reg = -1
};
static const int kNumRegisters = Code::kAfterLast;
static constexpr int kNumRegisters = Code::kAfterLast;
static Register from_code(int code) {
DCHECK(code >= 0);
@ -141,14 +141,13 @@ struct Register {
int reg_code;
};
#define DEFINE_REGISTER(R) constexpr Register R = {Register::kCode_##R};
GENERAL_REGISTERS(DEFINE_REGISTER)
#undef DEFINE_REGISTER
constexpr Register no_reg = {Register::kCode_no_reg};
#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
GENERAL_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
const Register no_reg = {Register::kCode_no_reg};
static const bool kSimpleFPAliasing = true;
static const bool kSimdMaskRegisters = false;
constexpr bool kSimpleFPAliasing = true;
constexpr bool kSimdMaskRegisters = false;
struct XMMRegister {
enum Code {
@ -159,7 +158,7 @@ struct XMMRegister {
kCode_no_reg = -1
};
static const int kMaxNumRegisters = Code::kAfterLast;
static constexpr int kMaxNumRegisters = Code::kAfterLast;
static XMMRegister from_code(int code) {
XMMRegister result = {code};
@ -184,11 +183,11 @@ typedef XMMRegister DoubleRegister;
typedef XMMRegister Simd128Register;
#define DECLARE_REGISTER(R) \
const DoubleRegister R = {DoubleRegister::kCode_##R};
DOUBLE_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
#define DEFINE_REGISTER(R) \
constexpr DoubleRegister R = {DoubleRegister::kCode_##R};
DOUBLE_REGISTERS(DEFINE_REGISTER)
#undef DEFINE_REGISTER
constexpr DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
enum Condition {
// any value < 0 is considered no_condition
@ -469,7 +468,7 @@ class Assembler : public AssemblerBase {
// (There is a 15 byte limit on ia32 instruction length that rules out some
// otherwise valid instructions.)
// This allows for a single, fast space check per instruction.
static const int kGap = 32;
static constexpr int kGap = 32;
public:
// Create an assembler. Instructions and relocation information are emitted
@ -521,35 +520,34 @@ class Assembler : public AssemblerBase {
Isolate* isolate, Address pc, Address target,
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
static const int kSpecialTargetSize = kPointerSize;
static constexpr int kSpecialTargetSize = kPointerSize;
// Distance between the address of the code target in the call instruction
// and the return address
static const int kCallTargetAddressOffset = kPointerSize;
static constexpr int kCallTargetAddressOffset = kPointerSize;
static const int kCallInstructionLength = 5;
static constexpr int kCallInstructionLength = 5;
// The debug break slot must be able to contain a call instruction.
static const int kDebugBreakSlotLength = kCallInstructionLength;
static constexpr int kDebugBreakSlotLength = kCallInstructionLength;
// Distance between start of patched debug break slot and the emitted address
// to jump to.
static const int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32.
static constexpr int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32.
// One byte opcode for test al, 0xXX.
static const byte kTestAlByte = 0xA8;
static constexpr byte kTestAlByte = 0xA8;
// One byte opcode for nop.
static const byte kNopByte = 0x90;
static constexpr byte kNopByte = 0x90;
// One byte opcode for a short unconditional jump.
static const byte kJmpShortOpcode = 0xEB;
static constexpr byte kJmpShortOpcode = 0xEB;
// One byte prefix for a short conditional jump.
static const byte kJccShortPrefix = 0x70;
static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
static const byte kJcShortOpcode = kJccShortPrefix | carry;
static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
static const byte kJzShortOpcode = kJccShortPrefix | zero;
static constexpr byte kJccShortPrefix = 0x70;
static constexpr byte kJncShortOpcode = kJccShortPrefix | not_carry;
static constexpr byte kJcShortOpcode = kJccShortPrefix | carry;
static constexpr byte kJnzShortOpcode = kJccShortPrefix | not_zero;
static constexpr byte kJzShortOpcode = kJccShortPrefix | zero;
// ---------------------------------------------------------------------------
// Code generation
@ -1466,7 +1464,7 @@ class Assembler : public AssemblerBase {
}
// Avoid overflows for displacements etc.
static const int kMaximalBufferSize = 512*MB;
static constexpr int kMaximalBufferSize = 512 * MB;
byte byte_at(int pos) { return buffer_[pos]; }
void set_byte_at(int pos, byte value) { buffer_[pos] = value; }

View File

@ -97,7 +97,7 @@ namespace internal {
// Implementation of Register and FPURegister.
struct Register {
static const int kCpRegister = 23; // cp (s7) is the 23rd register.
static constexpr int kCpRegister = 23; // cp (s7) is the 23rd register.
enum Code {
#define REGISTER_CODE(R) kCode_##R,
@ -107,24 +107,23 @@ struct Register {
kCode_no_reg = -1
};
static const int kNumRegisters = Code::kAfterLast;
static constexpr int kNumRegisters = Code::kAfterLast;
#if defined(V8_TARGET_LITTLE_ENDIAN)
static const int kMantissaOffset = 0;
static const int kExponentOffset = 4;
static constexpr int kMantissaOffset = 0;
static constexpr int kExponentOffset = 4;
#elif defined(V8_TARGET_BIG_ENDIAN)
static const int kMantissaOffset = 4;
static const int kExponentOffset = 0;
static constexpr int kMantissaOffset = 4;
static constexpr int kExponentOffset = 0;
#else
#error Unknown endianness
#endif
static Register from_code(int code) {
DCHECK(code >= 0);
DCHECK(code < kNumRegisters);
Register r = {code};
return r;
DCHECK_LE(0, code);
DCHECK_GT(kNumRegisters, code);
return Register{code};
}
bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
bool is(Register reg) const { return reg_code == reg.reg_code; }
@ -144,18 +143,17 @@ struct Register {
// s7: context register
// s3: lithium scratch
// s4: lithium scratch2
#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
#define DECLARE_REGISTER(R) constexpr Register R = {Register::kCode_##R};
GENERAL_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
const Register no_reg = {Register::kCode_no_reg};
constexpr Register no_reg = {Register::kCode_no_reg};
int ToNumber(Register reg);
Register ToRegister(int num);
static const bool kSimpleFPAliasing = true;
static const bool kSimdMaskRegisters = false;
constexpr bool kSimpleFPAliasing = true;
constexpr bool kSimdMaskRegisters = false;
// Coprocessor register.
struct FPURegister {
@ -167,7 +165,7 @@ struct FPURegister {
kCode_no_reg = -1
};
static const int kMaxNumRegisters = Code::kAfterLast;
static constexpr int kMaxNumRegisters = Code::kAfterLast;
inline static int NumRegisters();
@ -236,54 +234,51 @@ typedef FPURegister DoubleRegister;
// TODO(mips) Define SIMD registers.
typedef FPURegister Simd128Register;
const DoubleRegister no_freg = {-1};
constexpr DoubleRegister no_freg = {-1};
const DoubleRegister f0 = {0}; // Return value in hard float mode.
const DoubleRegister f1 = {1};
const DoubleRegister f2 = {2};
const DoubleRegister f3 = {3};
const DoubleRegister f4 = {4};
const DoubleRegister f5 = {5};
const DoubleRegister f6 = {6};
const DoubleRegister f7 = {7};
const DoubleRegister f8 = {8};
const DoubleRegister f9 = {9};
const DoubleRegister f10 = {10};
const DoubleRegister f11 = {11};
const DoubleRegister f12 = {12}; // Arg 0 in hard float mode.
const DoubleRegister f13 = {13};
const DoubleRegister f14 = {14}; // Arg 1 in hard float mode.
const DoubleRegister f15 = {15};
const DoubleRegister f16 = {16};
const DoubleRegister f17 = {17};
const DoubleRegister f18 = {18};
const DoubleRegister f19 = {19};
const DoubleRegister f20 = {20};
const DoubleRegister f21 = {21};
const DoubleRegister f22 = {22};
const DoubleRegister f23 = {23};
const DoubleRegister f24 = {24};
const DoubleRegister f25 = {25};
const DoubleRegister f26 = {26};
const DoubleRegister f27 = {27};
const DoubleRegister f28 = {28};
const DoubleRegister f29 = {29};
const DoubleRegister f30 = {30};
const DoubleRegister f31 = {31};
constexpr DoubleRegister f0 = {0}; // Return value in hard float mode.
constexpr DoubleRegister f1 = {1};
constexpr DoubleRegister f2 = {2};
constexpr DoubleRegister f3 = {3};
constexpr DoubleRegister f4 = {4};
constexpr DoubleRegister f5 = {5};
constexpr DoubleRegister f6 = {6};
constexpr DoubleRegister f7 = {7};
constexpr DoubleRegister f8 = {8};
constexpr DoubleRegister f9 = {9};
constexpr DoubleRegister f10 = {10};
constexpr DoubleRegister f11 = {11};
constexpr DoubleRegister f12 = {12}; // Arg 0 in hard float mode.
constexpr DoubleRegister f13 = {13};
constexpr DoubleRegister f14 = {14}; // Arg 1 in hard float mode.
constexpr DoubleRegister f15 = {15};
constexpr DoubleRegister f16 = {16};
constexpr DoubleRegister f17 = {17};
constexpr DoubleRegister f18 = {18};
constexpr DoubleRegister f19 = {19};
constexpr DoubleRegister f20 = {20};
constexpr DoubleRegister f21 = {21};
constexpr DoubleRegister f22 = {22};
constexpr DoubleRegister f23 = {23};
constexpr DoubleRegister f24 = {24};
constexpr DoubleRegister f25 = {25};
constexpr DoubleRegister f26 = {26};
constexpr DoubleRegister f27 = {27};
constexpr DoubleRegister f28 = {28};
constexpr DoubleRegister f29 = {29};
constexpr DoubleRegister f30 = {30};
constexpr DoubleRegister f31 = {31};
// Register aliases.
// cp is assumed to be a callee saved register.
// Defined using #define instead of "static const Register&" because Clang
// complains otherwise when a compilation unit that includes this header
// doesn't use the variables.
#define kRootRegister s6
#define cp s7
#define kLithiumScratchReg s3
#define kLithiumScratchReg2 s4
#define kLithiumScratchDouble f30
#define kDoubleRegZero f28
constexpr Register kRootRegister = s6;
constexpr Register cp = s7;
constexpr Register kLithiumScratchReg = s3;
constexpr Register kLithiumScratchReg2 = s4;
constexpr DoubleRegister kLithiumScratchDouble = f30;
constexpr DoubleRegister kDoubleRegZero = f28;
// Used on mips32r6 for compare operations.
#define kDoubleCompareReg f26
constexpr DoubleRegister kDoubleCompareReg = f26;
// FPU (coprocessor 1) control registers.
// Currently only FCSR (#31) is implemented.
@ -306,8 +301,8 @@ struct FPUControlRegister {
int reg_code;
};
const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister };
const FPUControlRegister FCSR = { kFCSRRegister };
constexpr FPUControlRegister no_fpucreg = {kInvalidFPUControlRegister};
constexpr FPUControlRegister FCSR = {kFCSRRegister};
// -----------------------------------------------------------------------------
// Machine instruction Operands.
@ -502,10 +497,10 @@ class Assembler : public AssemblerBase {
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// Size of an instruction.
static const int kInstrSize = sizeof(Instr);
static constexpr int kInstrSize = sizeof(Instr);
// Difference between address of current opcode and target address offset.
static const int kBranchPCOffset = 4;
static constexpr int kBranchPCOffset = 4;
// Here we are patching the address in the LUI/ORI instruction pair.
// These values are used in the serialization process and must be zero for
@ -513,48 +508,48 @@ class Assembler : public AssemblerBase {
// are split across two consecutive instructions and don't exist separately
// in the code, so the serializer should not step forwards in memory after
// a target is resolved and written.
static const int kSpecialTargetSize = 0;
static constexpr int kSpecialTargetSize = 0;
// Number of consecutive instructions used to store 32bit constant. This
// constant is used in RelocInfo::target_address_address() function to tell
// serializer address of the instruction that follows LUI/ORI instruction
// pair.
static const int kInstructionsFor32BitConstant = 2;
static constexpr int kInstructionsFor32BitConstant = 2;
// Distance between the instruction referring to the address of the call
// target and the return address.
#ifdef _MIPS_ARCH_MIPS32R6
static const int kCallTargetAddressOffset = 3 * kInstrSize;
static constexpr int kCallTargetAddressOffset = 3 * kInstrSize;
#else
static const int kCallTargetAddressOffset = 4 * kInstrSize;
static constexpr int kCallTargetAddressOffset = 4 * kInstrSize;
#endif
// Distance between start of patched debug break slot and the emitted address
// to jump to.
static const int kPatchDebugBreakSlotAddressOffset = 4 * kInstrSize;
static constexpr int kPatchDebugBreakSlotAddressOffset = 4 * kInstrSize;
// Difference between address of current opcode and value read from pc
// register.
static const int kPcLoadDelta = 4;
static constexpr int kPcLoadDelta = 4;
#ifdef _MIPS_ARCH_MIPS32R6
static const int kDebugBreakSlotInstructions = 3;
static constexpr int kDebugBreakSlotInstructions = 3;
#else
static const int kDebugBreakSlotInstructions = 4;
static constexpr int kDebugBreakSlotInstructions = 4;
#endif
static const int kDebugBreakSlotLength =
static constexpr int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstrSize;
// Max offset for instructions with 16-bit offset field
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
static constexpr int kMaxBranchOffset = (1 << (18 - 1)) - 1;
// Max offset for compact branch instructions with 26-bit offset field
static const int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1;
static constexpr int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1;
#ifdef _MIPS_ARCH_MIPS32R6
static const int kTrampolineSlotsSize = 2 * kInstrSize;
static constexpr int kTrampolineSlotsSize = 2 * kInstrSize;
#else
static const int kTrampolineSlotsSize = 4 * kInstrSize;
static constexpr int kTrampolineSlotsSize = 4 * kInstrSize;
#endif
// ---------------------------------------------------------------------------
@ -1263,21 +1258,21 @@ class Assembler : public AssemblerBase {
// Buffer size and constant pool distance are checked together at regular
// intervals of kBufferCheckInterval emitted bytes.
static const int kBufferCheckInterval = 1*KB/2;
static constexpr int kBufferCheckInterval = 1 * KB / 2;
// Code generation.
// The relocation writer's position is at least kGap bytes below the end of
// the generated instructions. This is so that multi-instruction sequences do
// not have to check for overflow. The same is true for writes of large
// relocation info entries.
static const int kGap = 32;
static constexpr int kGap = 32;
// Repeated checking whether the trampoline pool should be emitted is rather
// expensive. By default we only check again once a number of instructions
// has been generated.
static const int kCheckConstIntervalInst = 32;
static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize;
static constexpr int kCheckConstIntervalInst = 32;
static constexpr int kCheckConstInterval =
kCheckConstIntervalInst * kInstrSize;
int next_buffer_check_; // pc offset of next buffer check.
@ -1293,7 +1288,7 @@ class Assembler : public AssemblerBase {
// Relocation information generation.
// Each relocation is encoded as a variable size value.
static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize;
RelocInfoWriter reloc_info_writer;
// The bound position, before this we cannot do instruction elimination.
@ -1447,7 +1442,7 @@ class Assembler : public AssemblerBase {
// branch instruction generation, where we use jump instructions rather
// than regular branch instructions.
bool trampoline_emitted_;
static const int kInvalidSlotPos = -1;
static constexpr int kInvalidSlotPos = -1;
// Internal reference positions, required for unbounded internal reference
// labels.

View File

@ -13,20 +13,20 @@ namespace v8 {
namespace internal {
// Give alias names to registers for calling conventions.
const Register kReturnRegister0 = {Register::kCode_v0};
const Register kReturnRegister1 = {Register::kCode_v1};
const Register kReturnRegister2 = {Register::kCode_a0};
const Register kJSFunctionRegister = {Register::kCode_a1};
const Register kContextRegister = {Register::kCpRegister};
const Register kAllocateSizeRegister = {Register::kCode_a0};
const Register kInterpreterAccumulatorRegister = {Register::kCode_v0};
const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_t4};
const Register kInterpreterBytecodeArrayRegister = {Register::kCode_t5};
const Register kInterpreterDispatchTableRegister = {Register::kCode_t6};
const Register kJavaScriptCallArgCountRegister = {Register::kCode_a0};
const Register kJavaScriptCallNewTargetRegister = {Register::kCode_a3};
const Register kRuntimeCallFunctionRegister = {Register::kCode_a1};
const Register kRuntimeCallArgCountRegister = {Register::kCode_a0};
constexpr Register kReturnRegister0 = {Register::kCode_v0};
constexpr Register kReturnRegister1 = {Register::kCode_v1};
constexpr Register kReturnRegister2 = {Register::kCode_a0};
constexpr Register kJSFunctionRegister = {Register::kCode_a1};
constexpr Register kContextRegister = {Register::kCpRegister};
constexpr Register kAllocateSizeRegister = {Register::kCode_a0};
constexpr Register kInterpreterAccumulatorRegister = {Register::kCode_v0};
constexpr Register kInterpreterBytecodeOffsetRegister = {Register::kCode_t4};
constexpr Register kInterpreterBytecodeArrayRegister = {Register::kCode_t5};
constexpr Register kInterpreterDispatchTableRegister = {Register::kCode_t6};
constexpr Register kJavaScriptCallArgCountRegister = {Register::kCode_a0};
constexpr Register kJavaScriptCallNewTargetRegister = {Register::kCode_a3};
constexpr Register kRuntimeCallFunctionRegister = {Register::kCode_a1};
constexpr Register kRuntimeCallArgCountRegister = {Register::kCode_a0};
// Forward declaration.
class JumpTarget;
@ -210,9 +210,9 @@ class MacroAssembler: public Assembler {
// Number of instructions needed for calculation of switch table entry address
#ifdef _MIPS_ARCH_MIPS32R6
static const int kSwitchTablePrologueSize = 5;
static constexpr int kSwitchTablePrologueSize = 5;
#else
static const int kSwitchTablePrologueSize = 10;
static constexpr int kSwitchTablePrologueSize = 10;
#endif
// GetLabelFunction must be lambda '[](size_t index) -> Label*' or a
// functor/function with 'Label *func(size_t index)' declaration.
@ -1632,8 +1632,8 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
template<typename Field>
void DecodeFieldToSmi(Register dst, Register src) {
static const int shift = Field::kShift;
static const int mask = Field::kMask >> shift << kSmiTagSize;
constexpr int shift = Field::kShift;
constexpr int mask = Field::kMask >> shift << kSmiTagSize;
STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0);
STATIC_ASSERT(kSmiTag == 0);
if (shift < kSmiTagSize) {

View File

@ -97,14 +97,14 @@ namespace internal {
// Implementation of Register and FPURegister.
struct Register {
static const int kCpRegister = 23; // cp (s7) is the 23rd register.
static constexpr int kCpRegister = 23; // cp (s7) is the 23rd register.
#if defined(V8_TARGET_LITTLE_ENDIAN)
static const int kMantissaOffset = 0;
static const int kExponentOffset = 4;
static constexpr int kMantissaOffset = 0;
static constexpr int kExponentOffset = 4;
#elif defined(V8_TARGET_BIG_ENDIAN)
static const int kMantissaOffset = 4;
static const int kExponentOffset = 0;
static constexpr int kMantissaOffset = 4;
static constexpr int kExponentOffset = 0;
#else
#error Unknown endianness
#endif
@ -117,7 +117,7 @@ struct Register {
kCode_no_reg = -1
};
static const int kNumRegisters = Code::kAfterLast;
static constexpr int kNumRegisters = Code::kAfterLast;
static Register from_code(int code) {
DCHECK(code >= 0);
@ -132,10 +132,7 @@ struct Register {
DCHECK(is_valid());
return reg_code;
}
int bit() const {
DCHECK(is_valid());
return 1 << reg_code;
}
constexpr int bit() const { return DCHECK(is_valid()), 1 << reg_code; }
// Unfortunately we can't make this private in a struct.
int reg_code;
@ -144,18 +141,17 @@ struct Register {
// s7: context register
// s3: lithium scratch
// s4: lithium scratch2
#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
#define DECLARE_REGISTER(R) constexpr Register R = {Register::kCode_##R};
GENERAL_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
const Register no_reg = {Register::kCode_no_reg};
constexpr Register no_reg = {Register::kCode_no_reg};
int ToNumber(Register reg);
Register ToRegister(int num);
static const bool kSimpleFPAliasing = true;
static const bool kSimdMaskRegisters = false;
constexpr bool kSimpleFPAliasing = true;
constexpr bool kSimdMaskRegisters = false;
// Coprocessor register.
struct FPURegister {
@ -167,7 +163,7 @@ struct FPURegister {
kCode_no_reg = -1
};
static const int kMaxNumRegisters = Code::kAfterLast;
static constexpr int kMaxNumRegisters = Code::kAfterLast;
inline static int NumRegisters();
@ -200,10 +196,7 @@ struct FPURegister {
DCHECK(is_valid());
return reg_code;
}
int bit() const {
DCHECK(is_valid());
return 1 << reg_code;
}
constexpr int bit() const { return DCHECK(is_valid()), 1 << reg_code; }
static FPURegister from_code(int code) {
FPURegister r = {code};
@ -238,55 +231,52 @@ typedef FPURegister DoubleRegister;
// TODO(mips64) Define SIMD registers.
typedef FPURegister Simd128Register;
const DoubleRegister no_freg = {-1};
constexpr DoubleRegister no_freg = {-1};
const DoubleRegister f0 = {0}; // Return value in hard float mode.
const DoubleRegister f1 = {1};
const DoubleRegister f2 = {2};
const DoubleRegister f3 = {3};
const DoubleRegister f4 = {4};
const DoubleRegister f5 = {5};
const DoubleRegister f6 = {6};
const DoubleRegister f7 = {7};
const DoubleRegister f8 = {8};
const DoubleRegister f9 = {9};
const DoubleRegister f10 = {10};
const DoubleRegister f11 = {11};
const DoubleRegister f12 = {12}; // Arg 0 in hard float mode.
const DoubleRegister f13 = {13};
const DoubleRegister f14 = {14}; // Arg 1 in hard float mode.
const DoubleRegister f15 = {15};
const DoubleRegister f16 = {16};
const DoubleRegister f17 = {17};
const DoubleRegister f18 = {18};
const DoubleRegister f19 = {19};
const DoubleRegister f20 = {20};
const DoubleRegister f21 = {21};
const DoubleRegister f22 = {22};
const DoubleRegister f23 = {23};
const DoubleRegister f24 = {24};
const DoubleRegister f25 = {25};
const DoubleRegister f26 = {26};
const DoubleRegister f27 = {27};
const DoubleRegister f28 = {28};
const DoubleRegister f29 = {29};
const DoubleRegister f30 = {30};
const DoubleRegister f31 = {31};
constexpr DoubleRegister f0 = {0}; // Return value in hard float mode.
constexpr DoubleRegister f1 = {1};
constexpr DoubleRegister f2 = {2};
constexpr DoubleRegister f3 = {3};
constexpr DoubleRegister f4 = {4};
constexpr DoubleRegister f5 = {5};
constexpr DoubleRegister f6 = {6};
constexpr DoubleRegister f7 = {7};
constexpr DoubleRegister f8 = {8};
constexpr DoubleRegister f9 = {9};
constexpr DoubleRegister f10 = {10};
constexpr DoubleRegister f11 = {11};
constexpr DoubleRegister f12 = {12}; // Arg 0 in hard float mode.
constexpr DoubleRegister f13 = {13};
constexpr DoubleRegister f14 = {14}; // Arg 1 in hard float mode.
constexpr DoubleRegister f15 = {15};
constexpr DoubleRegister f16 = {16};
constexpr DoubleRegister f17 = {17};
constexpr DoubleRegister f18 = {18};
constexpr DoubleRegister f19 = {19};
constexpr DoubleRegister f20 = {20};
constexpr DoubleRegister f21 = {21};
constexpr DoubleRegister f22 = {22};
constexpr DoubleRegister f23 = {23};
constexpr DoubleRegister f24 = {24};
constexpr DoubleRegister f25 = {25};
constexpr DoubleRegister f26 = {26};
constexpr DoubleRegister f27 = {27};
constexpr DoubleRegister f28 = {28};
constexpr DoubleRegister f29 = {29};
constexpr DoubleRegister f30 = {30};
constexpr DoubleRegister f31 = {31};
// Register aliases.
// cp is assumed to be a callee saved register.
// Defined using #define instead of "static const Register&" because Clang
// complains otherwise when a compilation unit that includes this header
// doesn't use the variables.
#define kRootRegister s6
#define cp s7
#define kLithiumScratchReg s3
#define kLithiumScratchReg2 s4
#define kLithiumScratchDouble f30
#define kDoubleRegZero f28
constexpr Register kRootRegister = s6;
constexpr Register cp = s7;
constexpr Register kLithiumScratchReg = s3;
constexpr Register kLithiumScratchReg2 = s4;
constexpr DoubleRegister kLithiumScratchDouble = f30;
constexpr DoubleRegister kDoubleRegZero = f28;
// Used on mips64r6 for compare operations.
// We use the last non-callee saved odd register for N64 ABI
#define kDoubleCompareReg f23
constexpr DoubleRegister kDoubleCompareReg = f23;
// FPU (coprocessor 1) control registers.
// Currently only FCSR (#31) is implemented.
@ -297,10 +287,7 @@ struct FPUControlRegister {
DCHECK(is_valid());
return reg_code;
}
int bit() const {
DCHECK(is_valid());
return 1 << reg_code;
}
constexpr int bit() const { return DCHECK(is_valid()), 1 << reg_code; }
void setcode(int f) {
reg_code = f;
DCHECK(is_valid());
@ -309,13 +296,13 @@ struct FPUControlRegister {
int reg_code;
};
const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister };
const FPUControlRegister FCSR = { kFCSRRegister };
constexpr FPUControlRegister no_fpucreg = {kInvalidFPUControlRegister};
constexpr FPUControlRegister FCSR = {kFCSRRegister};
// -----------------------------------------------------------------------------
// Machine instruction Operands.
const int kSmiShift = kSmiTagSize + kSmiShiftSize;
const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1;
constexpr int kSmiShift = kSmiTagSize + kSmiShiftSize;
constexpr uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1;
// Class Operand represents a shifter operand in data processing instructions.
class Operand BASE_EMBEDDED {
public:
@ -509,10 +496,10 @@ class Assembler : public AssemblerBase {
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// Size of an instruction.
static const int kInstrSize = sizeof(Instr);
static constexpr int kInstrSize = sizeof(Instr);
// Difference between address of current opcode and target address offset.
static const int kBranchPCOffset = 4;
static constexpr int kBranchPCOffset = 4;
// Here we are patching the address in the LUI/ORI instruction pair.
// These values are used in the serialization process and must be zero for
@ -520,46 +507,46 @@ class Assembler : public AssemblerBase {
// are split across two consecutive instructions and don't exist separately
// in the code, so the serializer should not step forwards in memory after
// a target is resolved and written.
static const int kSpecialTargetSize = 0;
static constexpr int kSpecialTargetSize = 0;
// Number of consecutive instructions used to store 32bit/64bit constant.
// This constant was used in RelocInfo::target_address_address() function
// to tell serializer address of the instruction that follows
// LUI/ORI instruction pair.
static const int kInstructionsFor32BitConstant = 2;
static const int kInstructionsFor64BitConstant = 4;
static constexpr int kInstructionsFor32BitConstant = 2;
static constexpr int kInstructionsFor64BitConstant = 4;
// Distance between the instruction referring to the address of the call
// target and the return address.
#ifdef _MIPS_ARCH_MIPS64R6
static const int kCallTargetAddressOffset = 5 * kInstrSize;
static constexpr int kCallTargetAddressOffset = 5 * kInstrSize;
#else
static const int kCallTargetAddressOffset = 6 * kInstrSize;
static constexpr int kCallTargetAddressOffset = 6 * kInstrSize;
#endif
// Distance between start of patched debug break slot and the emitted address
// to jump to.
static const int kPatchDebugBreakSlotAddressOffset = 6 * kInstrSize;
static constexpr int kPatchDebugBreakSlotAddressOffset = 6 * kInstrSize;
// Difference between address of current opcode and value read from pc
// register.
static const int kPcLoadDelta = 4;
static constexpr int kPcLoadDelta = 4;
#ifdef _MIPS_ARCH_MIPS64R6
static const int kDebugBreakSlotInstructions = 5;
static constexpr int kDebugBreakSlotInstructions = 5;
#else
static const int kDebugBreakSlotInstructions = 6;
static constexpr int kDebugBreakSlotInstructions = 6;
#endif
static const int kDebugBreakSlotLength =
static constexpr int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstrSize;
// Max offset for instructions with 16-bit offset field
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
static constexpr int kMaxBranchOffset = (1 << (18 - 1)) - 1;
// Max offset for compact branch instructions with 26-bit offset field
static const int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1;
static constexpr int kMaxCompactBranchOffset = (1 << (28 - 1)) - 1;
static const int kTrampolineSlotsSize = 2 * kInstrSize;
static constexpr int kTrampolineSlotsSize = 2 * kInstrSize;
// ---------------------------------------------------------------------------
// Code generation.
@ -1313,21 +1300,21 @@ class Assembler : public AssemblerBase {
private:
// Buffer size and constant pool distance are checked together at regular
// intervals of kBufferCheckInterval emitted bytes.
static const int kBufferCheckInterval = 1*KB/2;
static constexpr int kBufferCheckInterval = 1 * KB / 2;
// Code generation.
// The relocation writer's position is at least kGap bytes below the end of
// the generated instructions. This is so that multi-instruction sequences do
// not have to check for overflow. The same is true for writes of large
// relocation info entries.
static const int kGap = 32;
static constexpr int kGap = 32;
// Repeated checking whether the trampoline pool should be emitted is rather
// expensive. By default we only check again once a number of instructions
// has been generated.
static const int kCheckConstIntervalInst = 32;
static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize;
static constexpr int kCheckConstIntervalInst = 32;
static constexpr int kCheckConstInterval =
kCheckConstIntervalInst * kInstrSize;
int next_buffer_check_; // pc offset of next buffer check.
@ -1343,7 +1330,7 @@ class Assembler : public AssemblerBase {
// Relocation information generation.
// Each relocation is encoded as a variable size value.
static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize;
RelocInfoWriter reloc_info_writer;
// The bound position, before this we cannot do instruction elimination.
@ -1497,7 +1484,7 @@ class Assembler : public AssemblerBase {
// branch instruction generation, where we use jump instructions rather
// than regular branch instructions.
bool trampoline_emitted_;
static const int kInvalidSlotPos = -1;
static constexpr int kInvalidSlotPos = -1;
// Internal reference positions, required for unbounded internal reference
// labels.

View File

@ -80,7 +80,7 @@ namespace internal {
V(r15)
// The length of pushq(rbp), movp(rbp, rsp), Push(rsi) and Push(rdi).
static const int kNoCodeAgeSequenceLength = kPointerSize == kInt64Size ? 6 : 17;
constexpr int kNoCodeAgeSequenceLength = kPointerSize == kInt64Size ? 6 : 17;
// CPU Registers.
//
@ -112,7 +112,7 @@ struct Register {
kCode_no_reg = -1
};
static const int kNumRegisters = Code::kAfterLast;
static constexpr int kNumRegisters = Code::kAfterLast;
static Register from_code(int code) {
DCHECK(code >= 0);
@ -144,25 +144,23 @@ struct Register {
int reg_code;
};
#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
#define DECLARE_REGISTER(R) constexpr Register R = {Register::kCode_##R};
GENERAL_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
const Register no_reg = {Register::kCode_no_reg};
constexpr Register no_reg = {Register::kCode_no_reg};
#ifdef _WIN64
// Windows calling convention
const Register arg_reg_1 = {Register::kCode_rcx};
const Register arg_reg_2 = {Register::kCode_rdx};
const Register arg_reg_3 = {Register::kCode_r8};
const Register arg_reg_4 = {Register::kCode_r9};
constexpr Register arg_reg_1 = {Register::kCode_rcx};
constexpr Register arg_reg_2 = {Register::kCode_rdx};
constexpr Register arg_reg_3 = {Register::kCode_r8};
constexpr Register arg_reg_4 = {Register::kCode_r9};
#else
// AMD64 calling convention
const Register arg_reg_1 = {Register::kCode_rdi};
const Register arg_reg_2 = {Register::kCode_rsi};
const Register arg_reg_3 = {Register::kCode_rdx};
const Register arg_reg_4 = {Register::kCode_rcx};
constexpr Register arg_reg_1 = {Register::kCode_rdi};
constexpr Register arg_reg_2 = {Register::kCode_rsi};
constexpr Register arg_reg_3 = {Register::kCode_rdx};
constexpr Register arg_reg_4 = {Register::kCode_rcx};
#endif // _WIN64
@ -204,8 +202,8 @@ const Register arg_reg_4 = {Register::kCode_rcx};
V(xmm13) \
V(xmm14)
static const bool kSimpleFPAliasing = true;
static const bool kSimdMaskRegisters = false;
constexpr bool kSimpleFPAliasing = true;
constexpr bool kSimdMaskRegisters = false;
struct XMMRegister {
enum Code {
@ -216,7 +214,7 @@ struct XMMRegister {
kCode_no_reg = -1
};
static const int kMaxNumRegisters = Code::kAfterLast;
static constexpr int kMaxNumRegisters = Code::kAfterLast;
static XMMRegister from_code(int code) {
XMMRegister result = {code};
@ -249,10 +247,10 @@ typedef XMMRegister DoubleRegister;
typedef XMMRegister Simd128Register;
#define DECLARE_REGISTER(R) \
const DoubleRegister R = {DoubleRegister::kCode_##R};
constexpr DoubleRegister R = {DoubleRegister::kCode_##R};
DOUBLE_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
constexpr DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
enum Condition {
// any value < 0 is considered no_condition
@ -471,7 +469,7 @@ class Assembler : public AssemblerBase {
// (There is a 15 byte limit on x64 instruction length that rules out some
// otherwise valid instructions.)
// This allows for a single, fast space check per instruction.
static const int kGap = 32;
static constexpr int kGap = 32;
public:
// Create an assembler. Instructions and relocation information are emitted
@ -538,42 +536,42 @@ class Assembler : public AssemblerBase {
inline Handle<Code> code_target_object_handle_at(Address pc);
inline Address runtime_entry_at(Address pc);
// Number of bytes taken up by the branch target in the code.
static const int kSpecialTargetSize = 4; // Use 32-bit displacement.
static constexpr int kSpecialTargetSize = 4; // 32-bit displacement.
// Distance between the address of the code target in the call instruction
// and the return address pushed on the stack.
static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement.
static constexpr int kCallTargetAddressOffset = 4; // 32-bit displacement.
// The length of call(kScratchRegister).
static const int kCallScratchRegisterInstructionLength = 3;
static constexpr int kCallScratchRegisterInstructionLength = 3;
// The length of call(Immediate32).
static const int kShortCallInstructionLength = 5;
static constexpr int kShortCallInstructionLength = 5;
// The length of movq(kScratchRegister, address).
static const int kMoveAddressIntoScratchRegisterInstructionLength =
static constexpr int kMoveAddressIntoScratchRegisterInstructionLength =
2 + kPointerSize;
// The length of movq(kScratchRegister, address) and call(kScratchRegister).
static const int kCallSequenceLength =
static constexpr int kCallSequenceLength =
kMoveAddressIntoScratchRegisterInstructionLength +
kCallScratchRegisterInstructionLength;
// The debug break slot must be able to contain an indirect call sequence.
static const int kDebugBreakSlotLength = kCallSequenceLength;
static constexpr int kDebugBreakSlotLength = kCallSequenceLength;
// Distance between start of patched debug break slot and the emitted address
// to jump to.
static const int kPatchDebugBreakSlotAddressOffset =
static constexpr int kPatchDebugBreakSlotAddressOffset =
kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize;
// One byte opcode for test eax,0xXXXXXXXX.
static const byte kTestEaxByte = 0xA9;
static constexpr byte kTestEaxByte = 0xA9;
// One byte opcode for test al, 0xXX.
static const byte kTestAlByte = 0xA8;
static constexpr byte kTestAlByte = 0xA8;
// One byte opcode for nop.
static const byte kNopByte = 0x90;
static constexpr byte kNopByte = 0x90;
// One byte prefix for a short conditional jump.
static const byte kJccShortPrefix = 0x70;
static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
static const byte kJcShortOpcode = kJccShortPrefix | carry;
static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
static const byte kJzShortOpcode = kJccShortPrefix | zero;
static constexpr byte kJccShortPrefix = 0x70;
static constexpr byte kJncShortOpcode = kJccShortPrefix | not_carry;
static constexpr byte kJcShortOpcode = kJccShortPrefix | carry;
static constexpr byte kJnzShortOpcode = kJccShortPrefix | not_zero;
static constexpr byte kJzShortOpcode = kJccShortPrefix | zero;
// VEX prefix encodings.
enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
@ -2019,7 +2017,7 @@ class Assembler : public AssemblerBase {
static bool IsNop(Address addr);
// Avoid overflows for displacements etc.
static const int kMaximalBufferSize = 512*MB;
static constexpr int kMaximalBufferSize = 512 * MB;
byte byte_at(int pos) { return buffer_[pos]; }
void set_byte_at(int pos, byte value) { buffer_[pos] = value; }