Commit e82b7ccd authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[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/451277Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#43637}
parent 8038f1bd
...@@ -114,7 +114,7 @@ struct Register { ...@@ -114,7 +114,7 @@ struct Register {
kCode_no_reg = -1 kCode_no_reg = -1
}; };
static const int kNumRegisters = Code::kAfterLast; static constexpr int kNumRegisters = Code::kAfterLast;
static Register from_code(int code) { static Register from_code(int code) {
DCHECK(code >= 0); DCHECK(code >= 0);
...@@ -144,13 +144,13 @@ struct Register { ...@@ -144,13 +144,13 @@ struct Register {
// r7: context register // r7: context register
// r8: constant pool pointer register if FLAG_enable_embedded_constant_pool. // r8: constant pool pointer register if FLAG_enable_embedded_constant_pool.
// r9: lithium scratch // 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) GENERAL_REGISTERS(DECLARE_REGISTER)
#undef 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; constexpr bool kSimpleFPAliasing = false;
static const bool kSimdMaskRegisters = false; constexpr bool kSimdMaskRegisters = false;
// Single word VFP register. // Single word VFP register.
struct SwVfpRegister { struct SwVfpRegister {
...@@ -162,9 +162,9 @@ struct SwVfpRegister { ...@@ -162,9 +162,9 @@ struct SwVfpRegister {
kCode_no_reg = -1 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_valid() const { return 0 <= reg_code && reg_code < 32; }
bool is(SwVfpRegister reg) const { return reg_code == reg.reg_code; } bool is(SwVfpRegister reg) const { return reg_code == reg.reg_code; }
...@@ -201,7 +201,7 @@ struct DwVfpRegister { ...@@ -201,7 +201,7 @@ struct DwVfpRegister {
kCode_no_reg = -1 kCode_no_reg = -1
}; };
static const int kMaxNumRegisters = Code::kAfterLast; static constexpr int kMaxNumRegisters = Code::kAfterLast;
inline static int NumRegisters(); inline static int NumRegisters();
...@@ -209,7 +209,7 @@ struct DwVfpRegister { ...@@ -209,7 +209,7 @@ struct DwVfpRegister {
// hold 0.0, that does not fit in the immediate field of vmov instructions. // hold 0.0, that does not fit in the immediate field of vmov instructions.
// d14: 0.0 // d14: 0.0
// d15: scratch register. // 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_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; } bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; }
...@@ -242,10 +242,9 @@ typedef DwVfpRegister DoubleRegister; ...@@ -242,10 +242,9 @@ typedef DwVfpRegister DoubleRegister;
// Double word VFP register d0-15. // Double word VFP register d0-15.
struct LowDwVfpRegister { struct LowDwVfpRegister {
public: public:
static const int kMaxNumLowRegisters = 16; static constexpr int kMaxNumLowRegisters = 16;
operator DwVfpRegister() const { constexpr operator DwVfpRegister() const {
DwVfpRegister r = { reg_code }; return DwVfpRegister { reg_code };
return r;
} }
static LowDwVfpRegister from_code(int code) { static LowDwVfpRegister from_code(int code) {
LowDwVfpRegister r = { code }; LowDwVfpRegister r = { code };
...@@ -282,7 +281,7 @@ struct LowDwVfpRegister { ...@@ -282,7 +281,7 @@ struct LowDwVfpRegister {
// Quad word NEON register. // Quad word NEON register.
struct QwNeonRegister { struct QwNeonRegister {
static const int kMaxNumRegisters = 16; static constexpr int kMaxNumRegisters = 16;
static QwNeonRegister from_code(int code) { static QwNeonRegister from_code(int code) {
QwNeonRegister r = { code }; QwNeonRegister r = { code };
...@@ -328,102 +327,100 @@ typedef QwNeonRegister Simd128Register; ...@@ -328,102 +327,100 @@ typedef QwNeonRegister Simd128Register;
// Support for the VFP registers s0 to s31 (d0 to d15). // 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)". // Note that "s(N):s(N+1)" is the same as "d(N/2)".
const SwVfpRegister s0 = { 0 }; constexpr SwVfpRegister s0 = { 0 };
const SwVfpRegister s1 = { 1 }; constexpr SwVfpRegister s1 = { 1 };
const SwVfpRegister s2 = { 2 }; constexpr SwVfpRegister s2 = { 2 };
const SwVfpRegister s3 = { 3 }; constexpr SwVfpRegister s3 = { 3 };
const SwVfpRegister s4 = { 4 }; constexpr SwVfpRegister s4 = { 4 };
const SwVfpRegister s5 = { 5 }; constexpr SwVfpRegister s5 = { 5 };
const SwVfpRegister s6 = { 6 }; constexpr SwVfpRegister s6 = { 6 };
const SwVfpRegister s7 = { 7 }; constexpr SwVfpRegister s7 = { 7 };
const SwVfpRegister s8 = { 8 }; constexpr SwVfpRegister s8 = { 8 };
const SwVfpRegister s9 = { 9 }; constexpr SwVfpRegister s9 = { 9 };
const SwVfpRegister s10 = { 10 }; constexpr SwVfpRegister s10 = { 10 };
const SwVfpRegister s11 = { 11 }; constexpr SwVfpRegister s11 = { 11 };
const SwVfpRegister s12 = { 12 }; constexpr SwVfpRegister s12 = { 12 };
const SwVfpRegister s13 = { 13 }; constexpr SwVfpRegister s13 = { 13 };
const SwVfpRegister s14 = { 14 }; constexpr SwVfpRegister s14 = { 14 };
const SwVfpRegister s15 = { 15 }; constexpr SwVfpRegister s15 = { 15 };
const SwVfpRegister s16 = { 16 }; constexpr SwVfpRegister s16 = { 16 };
const SwVfpRegister s17 = { 17 }; constexpr SwVfpRegister s17 = { 17 };
const SwVfpRegister s18 = { 18 }; constexpr SwVfpRegister s18 = { 18 };
const SwVfpRegister s19 = { 19 }; constexpr SwVfpRegister s19 = { 19 };
const SwVfpRegister s20 = { 20 }; constexpr SwVfpRegister s20 = { 20 };
const SwVfpRegister s21 = { 21 }; constexpr SwVfpRegister s21 = { 21 };
const SwVfpRegister s22 = { 22 }; constexpr SwVfpRegister s22 = { 22 };
const SwVfpRegister s23 = { 23 }; constexpr SwVfpRegister s23 = { 23 };
const SwVfpRegister s24 = { 24 }; constexpr SwVfpRegister s24 = { 24 };
const SwVfpRegister s25 = { 25 }; constexpr SwVfpRegister s25 = { 25 };
const SwVfpRegister s26 = { 26 }; constexpr SwVfpRegister s26 = { 26 };
const SwVfpRegister s27 = { 27 }; constexpr SwVfpRegister s27 = { 27 };
const SwVfpRegister s28 = { 28 }; constexpr SwVfpRegister s28 = { 28 };
const SwVfpRegister s29 = { 29 }; constexpr SwVfpRegister s29 = { 29 };
const SwVfpRegister s30 = { 30 }; constexpr SwVfpRegister s30 = { 30 };
const SwVfpRegister s31 = { 31 }; constexpr SwVfpRegister s31 = { 31 };
const DwVfpRegister no_dreg = { -1 }; constexpr DwVfpRegister no_dreg = { -1 };
const LowDwVfpRegister d0 = { 0 }; constexpr LowDwVfpRegister d0 = { 0 };
const LowDwVfpRegister d1 = { 1 }; constexpr LowDwVfpRegister d1 = { 1 };
const LowDwVfpRegister d2 = { 2 }; constexpr LowDwVfpRegister d2 = { 2 };
const LowDwVfpRegister d3 = { 3 }; constexpr LowDwVfpRegister d3 = { 3 };
const LowDwVfpRegister d4 = { 4 }; constexpr LowDwVfpRegister d4 = { 4 };
const LowDwVfpRegister d5 = { 5 }; constexpr LowDwVfpRegister d5 = { 5 };
const LowDwVfpRegister d6 = { 6 }; constexpr LowDwVfpRegister d6 = { 6 };
const LowDwVfpRegister d7 = { 7 }; constexpr LowDwVfpRegister d7 = { 7 };
const LowDwVfpRegister d8 = { 8 }; constexpr LowDwVfpRegister d8 = { 8 };
const LowDwVfpRegister d9 = { 9 }; constexpr LowDwVfpRegister d9 = { 9 };
const LowDwVfpRegister d10 = { 10 }; constexpr LowDwVfpRegister d10 = { 10 };
const LowDwVfpRegister d11 = { 11 }; constexpr LowDwVfpRegister d11 = { 11 };
const LowDwVfpRegister d12 = { 12 }; constexpr LowDwVfpRegister d12 = { 12 };
const LowDwVfpRegister d13 = { 13 }; constexpr LowDwVfpRegister d13 = { 13 };
const LowDwVfpRegister d14 = { 14 }; constexpr LowDwVfpRegister d14 = { 14 };
const LowDwVfpRegister d15 = { 15 }; constexpr LowDwVfpRegister d15 = { 15 };
const DwVfpRegister d16 = { 16 }; constexpr DwVfpRegister d16 = { 16 };
const DwVfpRegister d17 = { 17 }; constexpr DwVfpRegister d17 = { 17 };
const DwVfpRegister d18 = { 18 }; constexpr DwVfpRegister d18 = { 18 };
const DwVfpRegister d19 = { 19 }; constexpr DwVfpRegister d19 = { 19 };
const DwVfpRegister d20 = { 20 }; constexpr DwVfpRegister d20 = { 20 };
const DwVfpRegister d21 = { 21 }; constexpr DwVfpRegister d21 = { 21 };
const DwVfpRegister d22 = { 22 }; constexpr DwVfpRegister d22 = { 22 };
const DwVfpRegister d23 = { 23 }; constexpr DwVfpRegister d23 = { 23 };
const DwVfpRegister d24 = { 24 }; constexpr DwVfpRegister d24 = { 24 };
const DwVfpRegister d25 = { 25 }; constexpr DwVfpRegister d25 = { 25 };
const DwVfpRegister d26 = { 26 }; constexpr DwVfpRegister d26 = { 26 };
const DwVfpRegister d27 = { 27 }; constexpr DwVfpRegister d27 = { 27 };
const DwVfpRegister d28 = { 28 }; constexpr DwVfpRegister d28 = { 28 };
const DwVfpRegister d29 = { 29 }; constexpr DwVfpRegister d29 = { 29 };
const DwVfpRegister d30 = { 30 }; constexpr DwVfpRegister d30 = { 30 };
const DwVfpRegister d31 = { 31 }; constexpr DwVfpRegister d31 = { 31 };
const QwNeonRegister q0 = { 0 }; constexpr QwNeonRegister q0 = { 0 };
const QwNeonRegister q1 = { 1 }; constexpr QwNeonRegister q1 = { 1 };
const QwNeonRegister q2 = { 2 }; constexpr QwNeonRegister q2 = { 2 };
const QwNeonRegister q3 = { 3 }; constexpr QwNeonRegister q3 = { 3 };
const QwNeonRegister q4 = { 4 }; constexpr QwNeonRegister q4 = { 4 };
const QwNeonRegister q5 = { 5 }; constexpr QwNeonRegister q5 = { 5 };
const QwNeonRegister q6 = { 6 }; constexpr QwNeonRegister q6 = { 6 };
const QwNeonRegister q7 = { 7 }; constexpr QwNeonRegister q7 = { 7 };
const QwNeonRegister q8 = { 8 }; constexpr QwNeonRegister q8 = { 8 };
const QwNeonRegister q9 = { 9 }; constexpr QwNeonRegister q9 = { 9 };
const QwNeonRegister q10 = { 10 }; constexpr QwNeonRegister q10 = { 10 };
const QwNeonRegister q11 = { 11 }; constexpr QwNeonRegister q11 = { 11 };
const QwNeonRegister q12 = { 12 }; constexpr QwNeonRegister q12 = { 12 };
const QwNeonRegister q13 = { 13 }; constexpr QwNeonRegister q13 = { 13 };
const QwNeonRegister q14 = { 14 }; constexpr QwNeonRegister q14 = { 14 };
const QwNeonRegister q15 = { 15 }; constexpr QwNeonRegister q15 = { 15 };
// Aliases for double registers. Defined using #define instead of // Aliases for double registers.
// "static const DwVfpRegister&" because Clang complains otherwise when a constexpr LowDwVfpRegister kFirstCalleeSavedDoubleReg = d8;
// compilation unit that includes this header doesn't use the variables. constexpr LowDwVfpRegister kLastCalleeSavedDoubleReg = d15;
#define kFirstCalleeSavedDoubleReg d8
#define kLastCalleeSavedDoubleReg d15
// kDoubleRegZero and kScratchDoubleReg must pair to form kScratchQuadReg. SIMD // kDoubleRegZero and kScratchDoubleReg must pair to form kScratchQuadReg. SIMD
// code depends on kDoubleRegZero before kScratchDoubleReg. // code depends on kDoubleRegZero before kScratchDoubleReg.
#define kDoubleRegZero d14 constexpr LowDwVfpRegister kDoubleRegZero = d14;
#define kScratchDoubleReg d15 constexpr LowDwVfpRegister kScratchDoubleReg = d15;
// After using kScratchQuadReg, kDoubleRegZero must be reset to 0. // After using kScratchQuadReg, kDoubleRegZero must be reset to 0.
#define kScratchQuadReg q7 constexpr QwNeonRegister kScratchQuadReg = q7;
// Coprocessor register // Coprocessor register
struct CRegister { struct CRegister {
...@@ -443,24 +440,24 @@ struct CRegister { ...@@ -443,24 +440,24 @@ struct CRegister {
}; };
const CRegister no_creg = { -1 }; constexpr CRegister no_creg = { -1 };
const CRegister cr0 = { 0 }; constexpr CRegister cr0 = { 0 };
const CRegister cr1 = { 1 }; constexpr CRegister cr1 = { 1 };
const CRegister cr2 = { 2 }; constexpr CRegister cr2 = { 2 };
const CRegister cr3 = { 3 }; constexpr CRegister cr3 = { 3 };
const CRegister cr4 = { 4 }; constexpr CRegister cr4 = { 4 };
const CRegister cr5 = { 5 }; constexpr CRegister cr5 = { 5 };
const CRegister cr6 = { 6 }; constexpr CRegister cr6 = { 6 };
const CRegister cr7 = { 7 }; constexpr CRegister cr7 = { 7 };
const CRegister cr8 = { 8 }; constexpr CRegister cr8 = { 8 };
const CRegister cr9 = { 9 }; constexpr CRegister cr9 = { 9 };
const CRegister cr10 = { 10 }; constexpr CRegister cr10 = { 10 };
const CRegister cr11 = { 11 }; constexpr CRegister cr11 = { 11 };
const CRegister cr12 = { 12 }; constexpr CRegister cr12 = { 12 };
const CRegister cr13 = { 13 }; constexpr CRegister cr13 = { 13 };
const CRegister cr14 = { 14 }; constexpr CRegister cr14 = { 14 };
const CRegister cr15 = { 15 }; constexpr CRegister cr15 = { 15 };
// Coprocessor number // Coprocessor number
...@@ -671,8 +668,8 @@ class NeonListOperand BASE_EMBEDDED { ...@@ -671,8 +668,8 @@ class NeonListOperand BASE_EMBEDDED {
struct VmovIndex { struct VmovIndex {
unsigned char index; unsigned char index;
}; };
const VmovIndex VmovIndexLo = { 0 }; constexpr VmovIndex VmovIndexLo = { 0 };
const VmovIndex VmovIndexHi = { 1 }; constexpr VmovIndex VmovIndexHi = { 1 };
class Assembler : public AssemblerBase { class Assembler : public AssemblerBase {
public: public:
...@@ -760,24 +757,24 @@ class Assembler : public AssemblerBase { ...@@ -760,24 +757,24 @@ class Assembler : public AssemblerBase {
// Here we are patching the address in the constant pool, not the actual call // 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 // instruction. The address in the constant pool is the same size as a
// pointer. // pointer.
static const int kSpecialTargetSize = kPointerSize; static constexpr int kSpecialTargetSize = kPointerSize;
// Size of an instruction. // 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 // Distance between start of patched debug break slot and the emitted address
// to jump to. // to jump to.
// Patched debug break slot code is: // Patched debug break slot code is:
// ldr ip, [pc, #0] @ emited address and start // ldr ip, [pc, #0] @ emited address and start
// blx ip // 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 // Difference between address of current opcode and value read from pc
// register. // register.
static const int kPcLoadDelta = 8; static constexpr int kPcLoadDelta = 8;
static const int kDebugBreakSlotInstructions = 4; static constexpr int kDebugBreakSlotInstructions = 4;
static const int kDebugBreakSlotLength = static constexpr int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstrSize; kDebugBreakSlotInstructions * kInstrSize;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
...@@ -1592,12 +1589,14 @@ class Assembler : public AssemblerBase { ...@@ -1592,12 +1589,14 @@ class Assembler : public AssemblerBase {
// reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point
// PC-relative loads, thereby defining a maximum distance between the // PC-relative loads, thereby defining a maximum distance between the
// instruction and the accessed constant. // instruction and the accessed constant.
static const int kMaxDistToIntPool = 4*KB; static constexpr int kMaxDistToIntPool = 4 * KB;
static const int kMaxDistToFPPool = 1*KB; static constexpr int kMaxDistToFPPool = 1 * KB;
// All relocations could be integer, it therefore acts as the limit. // All relocations could be integer, it therefore acts as the limit.
static const int kMinNumPendingConstants = 4; static constexpr int kMinNumPendingConstants = 4;
static const int kMaxNumPending32Constants = kMaxDistToIntPool / kInstrSize; static constexpr int kMaxNumPending32Constants =
static const int kMaxNumPending64Constants = kMaxDistToFPPool / kInstrSize; kMaxDistToIntPool / kInstrSize;
static constexpr int kMaxNumPending64Constants =
kMaxDistToFPPool / kInstrSize;
// Postpone the generation of the constant pool for the specified number of // Postpone the generation of the constant pool for the specified number of
// instructions. // instructions.
...@@ -1700,7 +1699,7 @@ class Assembler : public AssemblerBase { ...@@ -1700,7 +1699,7 @@ class Assembler : public AssemblerBase {
// the generated instructions. This is so that multi-instruction sequences do // 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 // not have to check for overflow. The same is true for writes of large
// relocation info entries. // relocation info entries.
static const int kGap = 32; static constexpr int kGap = 32;
// Constant pool generation // Constant pool generation
// Pools are emitted in the instruction stream, preferably after unconditional // Pools are emitted in the instruction stream, preferably after unconditional
...@@ -1716,8 +1715,8 @@ class Assembler : public AssemblerBase { ...@@ -1716,8 +1715,8 @@ class Assembler : public AssemblerBase {
// expensive. By default we only check again once a number of instructions // 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 // 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. // an exact science, and that we rely on some slop to not overrun buffers.
static const int kCheckPoolIntervalInst = 32; static constexpr int kCheckPoolIntervalInst = 32;
static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize; static constexpr int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize;
// Emission of the constant pool may be blocked in some code sequences. // Emission of the constant pool may be blocked in some code sequences.
...@@ -1731,7 +1730,7 @@ class Assembler : public AssemblerBase { ...@@ -1731,7 +1730,7 @@ class Assembler : public AssemblerBase {
// Relocation info generation // Relocation info generation
// Each relocation is encoded as a variable size value // 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; RelocInfoWriter reloc_info_writer;
// ConstantPoolEntry records are used during code generation as temporary // ConstantPoolEntry records are used during code generation as temporary
...@@ -1785,7 +1784,7 @@ class Assembler : public AssemblerBase { ...@@ -1785,7 +1784,7 @@ class Assembler : public AssemblerBase {
friend class EnsureSpace; friend class EnsureSpace;
}; };
static const int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize; constexpr int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize;
class EnsureSpace BASE_EMBEDDED { class EnsureSpace BASE_EMBEDDED {
public: public:
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#if V8_TARGET_ARCH_ARM64 #if V8_TARGET_ARCH_ARM64
#define ARM64_DEFINE_REG_STATICS
#include "src/arm64/assembler-arm64.h" #include "src/arm64/assembler-arm64.h"
#include "src/arm64/assembler-arm64-inl.h" #include "src/arm64/assembler-arm64-inl.h"
......
...@@ -63,8 +63,7 @@ namespace internal { ...@@ -63,8 +63,7 @@ namespace internal {
R(d25) R(d26) R(d27) R(d28) R(d25) R(d26) R(d27) R(d28)
// clang-format on // 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 // Some CPURegister methods can return Register and FPRegister types, so we
// need to declare them in advance. // need to declare them in advance.
...@@ -90,6 +89,11 @@ struct CPURegister { ...@@ -90,6 +89,11 @@ struct CPURegister {
kNoRegister 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) { static CPURegister Create(int code, int size, RegisterType type) {
CPURegister r = {code, size, type}; CPURegister r = {code, size, type};
return r; return r;
...@@ -138,25 +142,9 @@ struct Register : public CPURegister { ...@@ -138,25 +142,9 @@ struct Register : public CPURegister {
return Register(CPURegister::Create(code, size, CPURegister::kRegister)); return Register(CPURegister::Create(code, size, CPURegister::kRegister));
} }
Register() { constexpr Register() : CPURegister() {}
reg_code = 0;
reg_size = 0;
reg_type = CPURegister::kNoRegister;
}
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) constexpr explicit Register(const CPURegister& r) : CPURegister(r) {}
reg_code = r.reg_code;
reg_size = r.reg_size;
reg_type = r.reg_type;
DCHECK(IsValidOrNone());
}
bool IsValid() const { bool IsValid() const {
DCHECK(IsRegister() || IsNone()); DCHECK(IsRegister() || IsNone());
...@@ -170,7 +158,7 @@ struct Register : public CPURegister { ...@@ -170,7 +158,7 @@ struct Register : public CPURegister {
// These memebers are necessary for compilation. // These memebers are necessary for compilation.
// A few of them may be unused for now. // 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_ASSERT(kNumRegisters == Code::kAfterLast);
static int NumRegisters() { return kNumRegisters; } static int NumRegisters() { return kNumRegisters; }
...@@ -197,8 +185,8 @@ struct Register : public CPURegister { ...@@ -197,8 +185,8 @@ struct Register : public CPURegister {
// End of V8 compatibility section ----------------------- // End of V8 compatibility section -----------------------
}; };
static const bool kSimpleFPAliasing = true; constexpr bool kSimpleFPAliasing = true;
static const bool kSimdMaskRegisters = false; constexpr bool kSimdMaskRegisters = false;
struct FPRegister : public CPURegister { struct FPRegister : public CPURegister {
enum Code { enum Code {
...@@ -214,25 +202,9 @@ struct FPRegister : public CPURegister { ...@@ -214,25 +202,9 @@ struct FPRegister : public CPURegister {
CPURegister::Create(code, size, CPURegister::kFPRegister)); CPURegister::Create(code, size, CPURegister::kFPRegister));
} }
FPRegister() { constexpr FPRegister() : CPURegister() {}
reg_code = 0;
reg_size = 0;
reg_type = CPURegister::kNoRegister;
}
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) constexpr explicit FPRegister(const CPURegister& r) : CPURegister(r) {}
reg_code = r.reg_code;
reg_size = r.reg_size;
reg_type = r.reg_type;
DCHECK(IsValidOrNone());
}
bool IsValid() const { bool IsValid() const {
DCHECK(IsFPRegister() || IsNone()); DCHECK(IsFPRegister() || IsNone());
...@@ -243,7 +215,7 @@ struct FPRegister : public CPURegister { ...@@ -243,7 +215,7 @@ struct FPRegister : public CPURegister {
static FPRegister DRegFromCode(unsigned code); static FPRegister DRegFromCode(unsigned code);
// Start of V8 compatibility section --------------------- // Start of V8 compatibility section ---------------------
static const int kMaxNumRegisters = kNumberOfFPRegisters; static constexpr int kMaxNumRegisters = kNumberOfFPRegisters;
STATIC_ASSERT(kMaxNumRegisters == Code::kAfterLast); STATIC_ASSERT(kMaxNumRegisters == Code::kAfterLast);
// Crankshaft can use all the FP registers except: // Crankshaft can use all the FP registers except:
...@@ -261,54 +233,41 @@ struct FPRegister : public CPURegister { ...@@ -261,54 +233,41 @@ struct FPRegister : public CPURegister {
STATIC_ASSERT(sizeof(CPURegister) == sizeof(Register)); STATIC_ASSERT(sizeof(CPURegister) == sizeof(Register));
STATIC_ASSERT(sizeof(CPURegister) == sizeof(FPRegister)); STATIC_ASSERT(sizeof(CPURegister) == sizeof(FPRegister));
#define DEFINE_REGISTER(register_class, name, code, size, type) \
#if defined(ARM64_DEFINE_REG_STATICS) constexpr register_class name { CPURegister(code, size, type) }
#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 ALIAS_REGISTER(register_class, alias, name) \ #define ALIAS_REGISTER(register_class, alias, name) \
extern const register_class& alias constexpr register_class alias = name
#endif // defined(ARM64_DEFINE_REG_STATICS)
// No*Reg is used to indicate an unused argument, or an error case. Note that // 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 // these all compare equal (using the Is() method). The Register and FPRegister
// variants are provided for convenience. // variants are provided for convenience.
INITIALIZE_REGISTER(Register, NoReg, 0, 0, CPURegister::kNoRegister); DEFINE_REGISTER(Register, NoReg, 0, 0, CPURegister::kNoRegister);
INITIALIZE_REGISTER(FPRegister, NoFPReg, 0, 0, CPURegister::kNoRegister); DEFINE_REGISTER(FPRegister, NoFPReg, 0, 0, CPURegister::kNoRegister);
INITIALIZE_REGISTER(CPURegister, NoCPUReg, 0, 0, CPURegister::kNoRegister); DEFINE_REGISTER(CPURegister, NoCPUReg, 0, 0, CPURegister::kNoRegister);
// v8 compatibility. // v8 compatibility.
INITIALIZE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister); DEFINE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister);
#define DEFINE_REGISTERS(N) \ #define DEFINE_REGISTERS(N) \
INITIALIZE_REGISTER(Register, w##N, N, \ DEFINE_REGISTER(Register, w##N, N, kWRegSizeInBits, CPURegister::kRegister); \
kWRegSizeInBits, CPURegister::kRegister); \ DEFINE_REGISTER(Register, x##N, N, kXRegSizeInBits, CPURegister::kRegister);
INITIALIZE_REGISTER(Register, x##N, N, \
kXRegSizeInBits, CPURegister::kRegister);
GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS) GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS)
#undef DEFINE_REGISTERS #undef DEFINE_REGISTERS
INITIALIZE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits, DEFINE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSizeInBits,
CPURegister::kRegister); CPURegister::kRegister);
INITIALIZE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits, DEFINE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSizeInBits,
CPURegister::kRegister); CPURegister::kRegister);
#define DEFINE_FPREGISTERS(N) \ #define DEFINE_FPREGISTERS(N) \
INITIALIZE_REGISTER(FPRegister, s##N, N, \ DEFINE_REGISTER(FPRegister, s##N, N, kSRegSizeInBits, \
kSRegSizeInBits, CPURegister::kFPRegister); \ CPURegister::kFPRegister); \
INITIALIZE_REGISTER(FPRegister, d##N, N, \ DEFINE_REGISTER(FPRegister, d##N, N, kDRegSizeInBits, \
kDRegSizeInBits, CPURegister::kFPRegister); CPURegister::kFPRegister);
GENERAL_REGISTER_CODE_LIST(DEFINE_FPREGISTERS) GENERAL_REGISTER_CODE_LIST(DEFINE_FPREGISTERS)
#undef DEFINE_FPREGISTERS #undef DEFINE_FPREGISTERS
#undef INITIALIZE_REGISTER #undef DEFINE_REGISTER
// Registers aliases. // Registers aliases.
ALIAS_REGISTER(Register, ip0, x16); ALIAS_REGISTER(Register, ip0, x16);
...@@ -566,8 +525,8 @@ class Immediate { ...@@ -566,8 +525,8 @@ class Immediate {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Operands. // Operands.
const int kSmiShift = kSmiTagSize + kSmiShiftSize; constexpr int kSmiShift = kSmiTagSize + kSmiShiftSize;
const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; constexpr uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1;
// Represents an operand in a machine instruction. // Represents an operand in a machine instruction.
class Operand { class Operand {
...@@ -836,7 +795,7 @@ class Assembler : public AssemblerBase { ...@@ -836,7 +795,7 @@ class Assembler : public AssemblerBase {
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// All addresses in the constant pool are the same size as pointers. // 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. // The sizes of the call sequences emitted by MacroAssembler::Call.
// Wherever possible, use MacroAssembler::CallSize instead of these constants, // Wherever possible, use MacroAssembler::CallSize instead of these constants,
...@@ -851,8 +810,8 @@ class Assembler : public AssemblerBase { ...@@ -851,8 +810,8 @@ class Assembler : public AssemblerBase {
// With relocation: // With relocation:
// ldr temp, =target // ldr temp, =target
// blr temp // blr temp
static const int kCallSizeWithoutRelocation = 4 * kInstructionSize; static constexpr int kCallSizeWithoutRelocation = 4 * kInstructionSize;
static const int kCallSizeWithRelocation = 2 * kInstructionSize; static constexpr int kCallSizeWithRelocation = 2 * kInstructionSize;
// Size of the generated code in bytes // Size of the generated code in bytes
uint64_t SizeOfGeneratedCode() const { uint64_t SizeOfGeneratedCode() const {
...@@ -884,12 +843,12 @@ class Assembler : public AssemblerBase { ...@@ -884,12 +843,12 @@ class Assembler : public AssemblerBase {
return SizeOfCodeGeneratedSince(label) / kInstructionSize; 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. // Number of instructions necessary to be able to later patch it to a call.
static const int kDebugBreakSlotInstructions = 5; static constexpr int kDebugBreakSlotInstructions = 5;
static const int kDebugBreakSlotLength = static constexpr int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstructionSize; kDebugBreakSlotInstructions * kInstructionSize;
// Prevent contant pool emission until EndBlockConstPool is called. // Prevent contant pool emission until EndBlockConstPool is called.
// Call to this function can be nested but must be followed by an equal // Call to this function can be nested but must be followed by an equal
...@@ -1847,7 +1806,7 @@ class Assembler : public AssemblerBase { ...@@ -1847,7 +1806,7 @@ class Assembler : public AssemblerBase {
// The maximum code size generated for a veneer. Currently one branch // The maximum code size generated for a veneer. Currently one branch
// instruction. This is for code size checking purposes, and can be extended // 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. // 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); void RecordVeneerPool(int location_offset, int size);
// Emits veneers for branches that are approaching their maximum range. // Emits veneers for branches that are approaching their maximum range.
...@@ -2000,7 +1959,7 @@ class Assembler : public AssemblerBase { ...@@ -2000,7 +1959,7 @@ class Assembler : public AssemblerBase {
// suitable for fields that take instruction offsets. // suitable for fields that take instruction offsets.
inline int LinkAndGetInstructionOffsetTo(Label* label); inline int LinkAndGetInstructionOffsetTo(Label* label);
static const int kStartOfLabelLinkChain = 0; static constexpr int kStartOfLabelLinkChain = 0;
// Verify that a label's link chain is intact. // Verify that a label's link chain is intact.
void CheckLabelLinkChain(Label const * label); void CheckLabelLinkChain(Label const * label);
...@@ -2061,17 +2020,17 @@ class Assembler : public AssemblerBase { ...@@ -2061,17 +2020,17 @@ class Assembler : public AssemblerBase {
// expensive. By default we only check again once a number of instructions // 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 // 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. // 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 // 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 // are accessed with pc relative load therefore this cannot be more than
// 1 * MB. Since constant pool emission checks are interval based this value // 1 * MB. Since constant pool emission checks are interval based this value
// is an approximation. // 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 // Number of pool entries after which a pool will be emitted. Since constant
// pool emission checks are interval based this value is an approximation. // 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. // Emission of the constant pool may be blocked in some code sequences.
int const_pool_blocked_nesting_; // Block emission if this is not zero. int const_pool_blocked_nesting_; // Block emission if this is not zero.
...@@ -2082,7 +2041,7 @@ class Assembler : public AssemblerBase { ...@@ -2082,7 +2041,7 @@ class Assembler : public AssemblerBase {
// Relocation info generation // Relocation info generation
// Each relocation is encoded as a variable size value // 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; RelocInfoWriter reloc_info_writer;
// Internal reference positions, required for (potential) patching in // Internal reference positions, required for (potential) patching in
// GrowBuffer(); contains only those internal references whose labels // GrowBuffer(); contains only those internal references whose labels
...@@ -2121,7 +2080,7 @@ class Assembler : public AssemblerBase { ...@@ -2121,7 +2080,7 @@ class Assembler : public AssemblerBase {
// not have to check for overflow. The same is true for writes of large // not have to check for overflow. The same is true for writes of large
// relocation info entries, and debug strings encoded in the instruction // relocation info entries, and debug strings encoded in the instruction
// stream. // stream.
static const int kGap = 128; static constexpr int kGap = 128;
public: public:
class FarBranchInfo { class FarBranchInfo {
...@@ -2151,13 +2110,13 @@ class Assembler : public AssemblerBase { ...@@ -2151,13 +2110,13 @@ class Assembler : public AssemblerBase {
// We generate a veneer for a branch if we reach within this distance of the // We generate a veneer for a branch if we reach within this distance of the
// limit of the range. // 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 // 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 // 1KB, that leaves us an addional 256 instructions to avoid generating a
// protective branch. // protective branch.
static const int kVeneerNoProtectionFactor = 2; static constexpr int kVeneerNoProtectionFactor = 2;
static const int kVeneerDistanceCheckMargin = static constexpr int kVeneerDistanceCheckMargin =
kVeneerNoProtectionFactor * kVeneerDistanceMargin; kVeneerNoProtectionFactor * kVeneerDistanceMargin;
int unresolved_branches_first_limit() const { int unresolved_branches_first_limit() const {
DCHECK(!unresolved_branches_.empty()); DCHECK(!unresolved_branches_.empty());
return unresolved_branches_.begin()->first; return unresolved_branches_.begin()->first;
...@@ -2221,8 +2180,8 @@ class PatchingAssembler : public Assembler { ...@@ -2221,8 +2180,8 @@ class PatchingAssembler : public Assembler {
} }
// See definition of PatchAdrFar() for details. // See definition of PatchAdrFar() for details.
static const int kAdrFarPatchableNNops = 2; static constexpr int kAdrFarPatchableNNops = 2;
static const int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 2; static constexpr int kAdrFarPatchableNInstrs = kAdrFarPatchableNNops + 2;
void PatchAdrFar(int64_t target_offset); void PatchAdrFar(int64_t target_offset);
}; };
......
...@@ -116,7 +116,7 @@ struct Register { ...@@ -116,7 +116,7 @@ struct Register {
kCode_no_reg = -1 kCode_no_reg = -1
}; };
static const int kNumRegisters = Code::kAfterLast; static constexpr int kNumRegisters = Code::kAfterLast;
static Register from_code(int code) { static Register from_code(int code) {
DCHECK(code >= 0); DCHECK(code >= 0);
...@@ -141,14 +141,13 @@ struct Register { ...@@ -141,14 +141,13 @@ struct Register {
int reg_code; 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}; constexpr bool kSimpleFPAliasing = true;
GENERAL_REGISTERS(DECLARE_REGISTER) constexpr bool kSimdMaskRegisters = false;
#undef DECLARE_REGISTER
const Register no_reg = {Register::kCode_no_reg};
static const bool kSimpleFPAliasing = true;
static const bool kSimdMaskRegisters = false;
struct XMMRegister { struct XMMRegister {
enum Code { enum Code {
...@@ -159,7 +158,7 @@ struct XMMRegister { ...@@ -159,7 +158,7 @@ struct XMMRegister {
kCode_no_reg = -1 kCode_no_reg = -1
}; };
static const int kMaxNumRegisters = Code::kAfterLast; static constexpr int kMaxNumRegisters = Code::kAfterLast;
static XMMRegister from_code(int code) { static XMMRegister from_code(int code) {
XMMRegister result = {code}; XMMRegister result = {code};
...@@ -184,11 +183,11 @@ typedef XMMRegister DoubleRegister; ...@@ -184,11 +183,11 @@ typedef XMMRegister DoubleRegister;
typedef XMMRegister Simd128Register; typedef XMMRegister Simd128Register;
#define DECLARE_REGISTER(R) \ #define DEFINE_REGISTER(R) \
const DoubleRegister R = {DoubleRegister::kCode_##R}; constexpr DoubleRegister R = {DoubleRegister::kCode_##R};
DOUBLE_REGISTERS(DECLARE_REGISTER) DOUBLE_REGISTERS(DEFINE_REGISTER)
#undef DECLARE_REGISTER #undef DEFINE_REGISTER
const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg}; constexpr DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
enum Condition { enum Condition {
// any value < 0 is considered no_condition // any value < 0 is considered no_condition
...@@ -469,7 +468,7 @@ class Assembler : public AssemblerBase { ...@@ -469,7 +468,7 @@ class Assembler : public AssemblerBase {
// (There is a 15 byte limit on ia32 instruction length that rules out some // (There is a 15 byte limit on ia32 instruction length that rules out some
// otherwise valid instructions.) // otherwise valid instructions.)
// This allows for a single, fast space check per instruction. // This allows for a single, fast space check per instruction.
static const int kGap = 32; static constexpr int kGap = 32;
public: public:
// Create an assembler. Instructions and relocation information are emitted // Create an assembler. Instructions and relocation information are emitted
...@@ -521,35 +520,34 @@ class Assembler : public AssemblerBase { ...@@ -521,35 +520,34 @@ class Assembler : public AssemblerBase {
Isolate* isolate, Address pc, Address target, Isolate* isolate, Address pc, Address target,
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 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 // Distance between the address of the code target in the call instruction
// and the return address // 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. // 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 // Distance between start of patched debug break slot and the emitted address
// to jump to. // to jump to.
static const int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32. static constexpr int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32.
// One byte opcode for test al, 0xXX. // One byte opcode for test al, 0xXX.
static const byte kTestAlByte = 0xA8; static constexpr byte kTestAlByte = 0xA8;
// One byte opcode for nop. // One byte opcode for nop.
static const byte kNopByte = 0x90; static constexpr byte kNopByte = 0x90;
// One byte opcode for a short unconditional jump. // 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. // One byte prefix for a short conditional jump.
static const byte kJccShortPrefix = 0x70; static constexpr byte kJccShortPrefix = 0x70;
static const byte kJncShortOpcode = kJccShortPrefix | not_carry; static constexpr byte kJncShortOpcode = kJccShortPrefix | not_carry;
static const byte kJcShortOpcode = kJccShortPrefix | carry; static constexpr byte kJcShortOpcode = kJccShortPrefix | carry;
static const byte kJnzShortOpcode = kJccShortPrefix | not_zero; static constexpr byte kJnzShortOpcode = kJccShortPrefix | not_zero;
static const byte kJzShortOpcode = kJccShortPrefix | zero; static constexpr byte kJzShortOpcode = kJccShortPrefix | zero;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Code generation // Code generation
...@@ -1466,7 +1464,7 @@ class Assembler : public AssemblerBase { ...@@ -1466,7 +1464,7 @@ class Assembler : public AssemblerBase {
} }
// Avoid overflows for displacements etc. // 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]; } byte byte_at(int pos) { return buffer_[pos]; }
void set_byte_at(int pos, byte value) { buffer_[pos] = value; } void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
......
...@@ -97,7 +97,7 @@ namespace internal { ...@@ -97,7 +97,7 @@ namespace internal {
// Implementation of Register and FPURegister. // Implementation of Register and FPURegister.
struct Register { 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 { enum Code {
#define REGISTER_CODE(R) kCode_##R, #define REGISTER_CODE(R) kCode_##R,
...@@ -107,24 +107,23 @@ struct Register { ...@@ -107,24 +107,23 @@ struct Register {
kCode_no_reg = -1 kCode_no_reg = -1
}; };
static const int kNumRegisters = Code::kAfterLast; static constexpr int kNumRegisters = Code::kAfterLast;
#if defined(V8_TARGET_LITTLE_ENDIAN) #if defined(V8_TARGET_LITTLE_ENDIAN)
static const int kMantissaOffset = 0; static constexpr int kMantissaOffset = 0;
static const int kExponentOffset = 4; static constexpr int kExponentOffset = 4;
#elif defined(V8_TARGET_BIG_ENDIAN) #elif defined(V8_TARGET_BIG_ENDIAN)
static const int kMantissaOffset = 4; static constexpr int kMantissaOffset = 4;
static const int kExponentOffset = 0; static constexpr int kExponentOffset = 0;
#else #else
#error Unknown endianness #error Unknown endianness
#endif #endif
static Register from_code(int code) { static Register from_code(int code) {
DCHECK(code >= 0); DCHECK_LE(0, code);
DCHECK(code < kNumRegisters); DCHECK_GT(kNumRegisters, code);
Register r = {code}; return Register{code};
return r;
} }
bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
bool is(Register reg) const { return reg_code == reg.reg_code; } bool is(Register reg) const { return reg_code == reg.reg_code; }
...@@ -144,18 +143,17 @@ struct Register { ...@@ -144,18 +143,17 @@ struct Register {
// s7: context register // s7: context register
// s3: lithium scratch // s3: lithium scratch
// s4: lithium scratch2 // 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) GENERAL_REGISTERS(DECLARE_REGISTER)
#undef 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); int ToNumber(Register reg);
Register ToRegister(int num); Register ToRegister(int num);
static const bool kSimpleFPAliasing = true; constexpr bool kSimpleFPAliasing = true;
static const bool kSimdMaskRegisters = false; constexpr bool kSimdMaskRegisters = false;
// Coprocessor register. // Coprocessor register.
struct FPURegister { struct FPURegister {
...@@ -167,7 +165,7 @@ struct FPURegister { ...@@ -167,7 +165,7 @@ struct FPURegister {
kCode_no_reg = -1 kCode_no_reg = -1
}; };
static const int kMaxNumRegisters = Code::kAfterLast; static constexpr int kMaxNumRegisters = Code::kAfterLast;
inline static int NumRegisters(); inline static int NumRegisters();
...@@ -236,54 +234,51 @@ typedef FPURegister DoubleRegister; ...@@ -236,54 +234,51 @@ typedef FPURegister DoubleRegister;
// TODO(mips) Define SIMD registers. // TODO(mips) Define SIMD registers.
typedef FPURegister Simd128Register; typedef FPURegister Simd128Register;
const DoubleRegister no_freg = {-1}; constexpr DoubleRegister no_freg = {-1};
const DoubleRegister f0 = {0}; // Return value in hard float mode. constexpr DoubleRegister f0 = {0}; // Return value in hard float mode.
const DoubleRegister f1 = {1}; constexpr DoubleRegister f1 = {1};
const DoubleRegister f2 = {2}; constexpr DoubleRegister f2 = {2};
const DoubleRegister f3 = {3}; constexpr DoubleRegister f3 = {3};
const DoubleRegister f4 = {4}; constexpr DoubleRegister f4 = {4};
const DoubleRegister f5 = {5}; constexpr DoubleRegister f5 = {5};
const DoubleRegister f6 = {6}; constexpr DoubleRegister f6 = {6};
const DoubleRegister f7 = {7}; constexpr DoubleRegister f7 = {7};
const DoubleRegister f8 = {8}; constexpr DoubleRegister f8 = {8};
const DoubleRegister f9 = {9}; constexpr DoubleRegister f9 = {9};
const DoubleRegister f10 = {10}; constexpr DoubleRegister f10 = {10};
const DoubleRegister f11 = {11}; constexpr DoubleRegister f11 = {11};
const DoubleRegister f12 = {12}; // Arg 0 in hard float mode. constexpr DoubleRegister f12 = {12}; // Arg 0 in hard float mode.
const DoubleRegister f13 = {13}; constexpr DoubleRegister f13 = {13};
const DoubleRegister f14 = {14}; // Arg 1 in hard float mode. constexpr DoubleRegister f14 = {14}; // Arg 1 in hard float mode.
const DoubleRegister f15 = {15}; constexpr DoubleRegister f15 = {15};
const DoubleRegister f16 = {16}; constexpr DoubleRegister f16 = {16};
const DoubleRegister f17 = {17}; constexpr DoubleRegister f17 = {17};
const DoubleRegister f18 = {18}; constexpr DoubleRegister f18 = {18};
const DoubleRegister f19 = {19}; constexpr DoubleRegister f19 = {19};
const DoubleRegister f20 = {20}; constexpr DoubleRegister f20 = {20};
const DoubleRegister f21 = {21}; constexpr DoubleRegister f21 = {21};
const DoubleRegister f22 = {22}; constexpr DoubleRegister f22 = {22};
const DoubleRegister f23 = {23}; constexpr DoubleRegister f23 = {23};
const DoubleRegister f24 = {24}; constexpr DoubleRegister f24 = {24};
const DoubleRegister f25 = {25}; constexpr DoubleRegister f25 = {25};
const DoubleRegister f26 = {26}; constexpr DoubleRegister f26 = {26};
const DoubleRegister f27 = {27}; constexpr DoubleRegister f27 = {27};
const DoubleRegister f28 = {28}; constexpr DoubleRegister f28 = {28};
const DoubleRegister f29 = {29}; constexpr DoubleRegister f29 = {29};
const DoubleRegister f30 = {30}; constexpr DoubleRegister f30 = {30};
const DoubleRegister f31 = {31}; constexpr DoubleRegister f31 = {31};
// Register aliases. // Register aliases.
// cp is assumed to be a callee saved register. // cp is assumed to be a callee saved register.
// Defined using #define instead of "static const Register&" because Clang constexpr Register kRootRegister = s6;
// complains otherwise when a compilation unit that includes this header constexpr Register cp = s7;
// doesn't use the variables. constexpr Register kLithiumScratchReg = s3;
#define kRootRegister s6 constexpr Register kLithiumScratchReg2 = s4;
#define cp s7 constexpr DoubleRegister kLithiumScratchDouble = f30;
#define kLithiumScratchReg s3 constexpr DoubleRegister kDoubleRegZero = f28;
#define kLithiumScratchReg2 s4
#define kLithiumScratchDouble f30
#define kDoubleRegZero f28
// Used on mips32r6 for compare operations. // Used on mips32r6 for compare operations.
#define kDoubleCompareReg f26 constexpr DoubleRegister kDoubleCompareReg = f26;
// FPU (coprocessor 1) control registers. // FPU (coprocessor 1) control registers.
// Currently only FCSR (#31) is implemented. // Currently only FCSR (#31) is implemented.
...@@ -306,8 +301,8 @@ struct FPUControlRegister { ...@@ -306,8 +301,8 @@ struct FPUControlRegister {
int reg_code; int reg_code;
}; };
const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister }; constexpr FPUControlRegister no_fpucreg = {kInvalidFPUControlRegister};
const FPUControlRegister FCSR = { kFCSRRegister }; constexpr FPUControlRegister FCSR = {kFCSRRegister};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Machine instruction Operands. // Machine instruction Operands.
...@@ -502,10 +497,10 @@ class Assembler : public AssemblerBase { ...@@ -502,10 +497,10 @@ class Assembler : public AssemblerBase {
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// Size of an instruction. // 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. // 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. // 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 // These values are used in the serialization process and must be zero for
...@@ -513,48 +508,48 @@ class Assembler : public AssemblerBase { ...@@ -513,48 +508,48 @@ class Assembler : public AssemblerBase {
// are split across two consecutive instructions and don't exist separately // are split across two consecutive instructions and don't exist separately
// in the code, so the serializer should not step forwards in memory after // in the code, so the serializer should not step forwards in memory after
// a target is resolved and written. // 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 // Number of consecutive instructions used to store 32bit constant. This
// constant is used in RelocInfo::target_address_address() function to tell // constant is used in RelocInfo::target_address_address() function to tell
// serializer address of the instruction that follows LUI/ORI instruction // serializer address of the instruction that follows LUI/ORI instruction
// pair. // pair.
static const int kInstructionsFor32BitConstant = 2; static constexpr int kInstructionsFor32BitConstant = 2;
// Distance between the instruction referring to the address of the call // Distance between the instruction referring to the address of the call
// target and the return address. // target and the return address.
#ifdef _MIPS_ARCH_MIPS32R6 #ifdef _MIPS_ARCH_MIPS32R6
static const int kCallTargetAddressOffset = 3 * kInstrSize; static constexpr int kCallTargetAddressOffset = 3 * kInstrSize;
#else #else
static const int kCallTargetAddressOffset = 4 * kInstrSize; static constexpr int kCallTargetAddressOffset = 4 * kInstrSize;
#endif #endif
// Distance between start of patched debug break slot and the emitted address // Distance between start of patched debug break slot and the emitted address
// to jump to. // 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 // Difference between address of current opcode and value read from pc
// register. // register.
static const int kPcLoadDelta = 4; static constexpr int kPcLoadDelta = 4;
#ifdef _MIPS_ARCH_MIPS32R6 #ifdef _MIPS_ARCH_MIPS32R6
static const int kDebugBreakSlotInstructions = 3; static constexpr int kDebugBreakSlotInstructions = 3;
#else #else
static const int kDebugBreakSlotInstructions = 4; static constexpr int kDebugBreakSlotInstructions = 4;
#endif #endif
static const int kDebugBreakSlotLength = static constexpr int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstrSize; kDebugBreakSlotInstructions * kInstrSize;
// Max offset for instructions with 16-bit offset field // 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 // 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 #ifdef _MIPS_ARCH_MIPS32R6
static const int kTrampolineSlotsSize = 2 * kInstrSize; static constexpr int kTrampolineSlotsSize = 2 * kInstrSize;
#else #else
static const int kTrampolineSlotsSize = 4 * kInstrSize; static constexpr int kTrampolineSlotsSize = 4 * kInstrSize;
#endif #endif
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
...@@ -1263,21 +1258,21 @@ class Assembler : public AssemblerBase { ...@@ -1263,21 +1258,21 @@ class Assembler : public AssemblerBase {
// Buffer size and constant pool distance are checked together at regular // Buffer size and constant pool distance are checked together at regular
// intervals of kBufferCheckInterval emitted bytes. // intervals of kBufferCheckInterval emitted bytes.
static const int kBufferCheckInterval = 1*KB/2; static constexpr int kBufferCheckInterval = 1 * KB / 2;
// Code generation. // Code generation.
// The relocation writer's position is at least kGap bytes below the end of // 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 // 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 // not have to check for overflow. The same is true for writes of large
// relocation info entries. // relocation info entries.
static const int kGap = 32; static constexpr int kGap = 32;
// Repeated checking whether the trampoline pool should be emitted is rather // Repeated checking whether the trampoline pool should be emitted is rather
// expensive. By default we only check again once a number of instructions // expensive. By default we only check again once a number of instructions
// has been generated. // has been generated.
static const int kCheckConstIntervalInst = 32; static constexpr int kCheckConstIntervalInst = 32;
static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; static constexpr int kCheckConstInterval =
kCheckConstIntervalInst * kInstrSize;
int next_buffer_check_; // pc offset of next buffer check. int next_buffer_check_; // pc offset of next buffer check.
...@@ -1293,7 +1288,7 @@ class Assembler : public AssemblerBase { ...@@ -1293,7 +1288,7 @@ class Assembler : public AssemblerBase {
// Relocation information generation. // Relocation information generation.
// Each relocation is encoded as a variable size value. // 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; RelocInfoWriter reloc_info_writer;
// The bound position, before this we cannot do instruction elimination. // The bound position, before this we cannot do instruction elimination.
...@@ -1447,7 +1442,7 @@ class Assembler : public AssemblerBase { ...@@ -1447,7 +1442,7 @@ class Assembler : public AssemblerBase {
// branch instruction generation, where we use jump instructions rather // branch instruction generation, where we use jump instructions rather
// than regular branch instructions. // than regular branch instructions.
bool trampoline_emitted_; bool trampoline_emitted_;
static const int kInvalidSlotPos = -1; static constexpr int kInvalidSlotPos = -1;
// Internal reference positions, required for unbounded internal reference // Internal reference positions, required for unbounded internal reference
// labels. // labels.
......
...@@ -13,20 +13,20 @@ namespace v8 { ...@@ -13,20 +13,20 @@ namespace v8 {
namespace internal { namespace internal {
// Give alias names to registers for calling conventions. // Give alias names to registers for calling conventions.
const Register kReturnRegister0 = {Register::kCode_v0}; constexpr Register kReturnRegister0 = {Register::kCode_v0};
const Register kReturnRegister1 = {Register::kCode_v1}; constexpr Register kReturnRegister1 = {Register::kCode_v1};
const Register kReturnRegister2 = {Register::kCode_a0}; constexpr Register kReturnRegister2 = {Register::kCode_a0};
const Register kJSFunctionRegister = {Register::kCode_a1}; constexpr Register kJSFunctionRegister = {Register::kCode_a1};
const Register kContextRegister = {Register::kCpRegister}; constexpr Register kContextRegister = {Register::kCpRegister};
const Register kAllocateSizeRegister = {Register::kCode_a0}; constexpr Register kAllocateSizeRegister = {Register::kCode_a0};
const Register kInterpreterAccumulatorRegister = {Register::kCode_v0}; constexpr Register kInterpreterAccumulatorRegister = {Register::kCode_v0};
const Register kInterpreterBytecodeOffsetRegister = {Register::kCode_t4}; constexpr Register kInterpreterBytecodeOffsetRegister = {Register::kCode_t4};
const Register kInterpreterBytecodeArrayRegister = {Register::kCode_t5}; constexpr Register kInterpreterBytecodeArrayRegister = {Register::kCode_t5};
const Register kInterpreterDispatchTableRegister = {Register::kCode_t6}; constexpr Register kInterpreterDispatchTableRegister = {Register::kCode_t6};
const Register kJavaScriptCallArgCountRegister = {Register::kCode_a0}; constexpr Register kJavaScriptCallArgCountRegister = {Register::kCode_a0};
const Register kJavaScriptCallNewTargetRegister = {Register::kCode_a3}; constexpr Register kJavaScriptCallNewTargetRegister = {Register::kCode_a3};
const Register kRuntimeCallFunctionRegister = {Register::kCode_a1}; constexpr Register kRuntimeCallFunctionRegister = {Register::kCode_a1};
const Register kRuntimeCallArgCountRegister = {Register::kCode_a0}; constexpr Register kRuntimeCallArgCountRegister = {Register::kCode_a0};
// Forward declaration. // Forward declaration.
class JumpTarget; class JumpTarget;
...@@ -210,9 +210,9 @@ class MacroAssembler: public Assembler { ...@@ -210,9 +210,9 @@ class MacroAssembler: public Assembler {
// Number of instructions needed for calculation of switch table entry address // Number of instructions needed for calculation of switch table entry address
#ifdef _MIPS_ARCH_MIPS32R6 #ifdef _MIPS_ARCH_MIPS32R6
static const int kSwitchTablePrologueSize = 5; static constexpr int kSwitchTablePrologueSize = 5;
#else #else
static const int kSwitchTablePrologueSize = 10; static constexpr int kSwitchTablePrologueSize = 10;
#endif #endif
// GetLabelFunction must be lambda '[](size_t index) -> Label*' or a // GetLabelFunction must be lambda '[](size_t index) -> Label*' or a
// functor/function with 'Label *func(size_t index)' declaration. // functor/function with 'Label *func(size_t index)' declaration.
...@@ -1632,8 +1632,8 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT ...@@ -1632,8 +1632,8 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
template<typename Field> template<typename Field>
void DecodeFieldToSmi(Register dst, Register src) { void DecodeFieldToSmi(Register dst, Register src) {
static const int shift = Field::kShift; constexpr int shift = Field::kShift;
static const int mask = Field::kMask >> shift << kSmiTagSize; constexpr int mask = Field::kMask >> shift << kSmiTagSize;
STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0); STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0);
STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTag == 0);
if (shift < kSmiTagSize) { if (shift < kSmiTagSize) {
......
...@@ -97,14 +97,14 @@ namespace internal { ...@@ -97,14 +97,14 @@ namespace internal {
// Implementation of Register and FPURegister. // Implementation of Register and FPURegister.
struct Register { 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) #if defined(V8_TARGET_LITTLE_ENDIAN)
static const int kMantissaOffset = 0; static constexpr int kMantissaOffset = 0;
static const int kExponentOffset = 4; static constexpr int kExponentOffset = 4;
#elif defined(V8_TARGET_BIG_ENDIAN) #elif defined(V8_TARGET_BIG_ENDIAN)
static const int kMantissaOffset = 4; static constexpr int kMantissaOffset = 4;
static const int kExponentOffset = 0; static constexpr int kExponentOffset = 0;
#else #else
#error Unknown endianness #error Unknown endianness
#endif #endif
...@@ -117,7 +117,7 @@ struct Register { ...@@ -117,7 +117,7 @@ struct Register {
kCode_no_reg = -1 kCode_no_reg = -1
}; };
static const int kNumRegisters = Code::kAfterLast; static constexpr int kNumRegisters = Code::kAfterLast;
static Register from_code(int code) { static Register from_code(int code) {
DCHECK(code >= 0); DCHECK(code >= 0);
...@@ -132,10 +132,7 @@ struct Register { ...@@ -132,10 +132,7 @@ struct Register {
DCHECK(is_valid()); DCHECK(is_valid());
return reg_code; return reg_code;
} }
int bit() const { constexpr int bit() const { return DCHECK(is_valid()), 1 << reg_code; }
DCHECK(is_valid());
return 1 << reg_code;
}
// Unfortunately we can't make this private in a struct. // Unfortunately we can't make this private in a struct.
int reg_code; int reg_code;
...@@ -144,18 +141,17 @@ struct Register { ...@@ -144,18 +141,17 @@ struct Register {
// s7: context register // s7: context register
// s3: lithium scratch // s3: lithium scratch
// s4: lithium scratch2 // 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) GENERAL_REGISTERS(DECLARE_REGISTER)
#undef 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); int ToNumber(Register reg);
Register ToRegister(int num); Register ToRegister(int num);
static const bool kSimpleFPAliasing = true; constexpr bool kSimpleFPAliasing = true;
static const bool kSimdMaskRegisters = false; constexpr bool kSimdMaskRegisters = false;
// Coprocessor register. // Coprocessor register.
struct FPURegister { struct FPURegister {
...@@ -167,7 +163,7 @@ struct FPURegister { ...@@ -167,7 +163,7 @@ struct FPURegister {
kCode_no_reg = -1 kCode_no_reg = -1
}; };
static const int kMaxNumRegisters = Code::kAfterLast; static constexpr int kMaxNumRegisters = Code::kAfterLast;
inline static int NumRegisters(); inline static int NumRegisters();
...@@ -200,10 +196,7 @@ struct FPURegister { ...@@ -200,10 +196,7 @@ struct FPURegister {
DCHECK(is_valid()); DCHECK(is_valid());
return reg_code; return reg_code;
} }
int bit() const { constexpr int bit() const { return DCHECK(is_valid()), 1 << reg_code; }
DCHECK(is_valid());
return 1 << reg_code;
}
static FPURegister from_code(int code) { static FPURegister from_code(int code) {
FPURegister r = {code}; FPURegister r = {code};
...@@ -238,55 +231,52 @@ typedef FPURegister DoubleRegister; ...@@ -238,55 +231,52 @@ typedef FPURegister DoubleRegister;
// TODO(mips64) Define SIMD registers. // TODO(mips64) Define SIMD registers.
typedef FPURegister Simd128Register; typedef FPURegister Simd128Register;
const DoubleRegister no_freg = {-1}; constexpr DoubleRegister no_freg = {-1};
const DoubleRegister f0 = {0}; // Return value in hard float mode. constexpr DoubleRegister f0 = {0}; // Return value in hard float mode.
const DoubleRegister f1 = {1}; constexpr DoubleRegister f1 = {1};
const DoubleRegister f2 = {2}; constexpr DoubleRegister f2 = {2};
const DoubleRegister f3 = {3}; constexpr DoubleRegister f3 = {3};
const DoubleRegister f4 = {4}; constexpr DoubleRegister f4 = {4};
const DoubleRegister f5 = {5}; constexpr DoubleRegister f5 = {5};
const DoubleRegister f6 = {6}; constexpr DoubleRegister f6 = {6};
const DoubleRegister f7 = {7}; constexpr DoubleRegister f7 = {7};
const DoubleRegister f8 = {8}; constexpr DoubleRegister f8 = {8};
const DoubleRegister f9 = {9}; constexpr DoubleRegister f9 = {9};
const DoubleRegister f10 = {10}; constexpr DoubleRegister f10 = {10};
const DoubleRegister f11 = {11}; constexpr DoubleRegister f11 = {11};
const DoubleRegister f12 = {12}; // Arg 0 in hard float mode. constexpr DoubleRegister f12 = {12}; // Arg 0 in hard float mode.
const DoubleRegister f13 = {13}; constexpr DoubleRegister f13 = {13};
const DoubleRegister f14 = {14}; // Arg 1 in hard float mode. constexpr DoubleRegister f14 = {14}; // Arg 1 in hard float mode.
const DoubleRegister f15 = {15}; constexpr DoubleRegister f15 = {15};
const DoubleRegister f16 = {16}; constexpr DoubleRegister f16 = {16};
const DoubleRegister f17 = {17}; constexpr DoubleRegister f17 = {17};
const DoubleRegister f18 = {18}; constexpr DoubleRegister f18 = {18};
const DoubleRegister f19 = {19}; constexpr DoubleRegister f19 = {19};
const DoubleRegister f20 = {20}; constexpr DoubleRegister f20 = {20};
const DoubleRegister f21 = {21}; constexpr DoubleRegister f21 = {21};
const DoubleRegister f22 = {22}; constexpr DoubleRegister f22 = {22};
const DoubleRegister f23 = {23}; constexpr DoubleRegister f23 = {23};
const DoubleRegister f24 = {24}; constexpr DoubleRegister f24 = {24};
const DoubleRegister f25 = {25}; constexpr DoubleRegister f25 = {25};
const DoubleRegister f26 = {26}; constexpr DoubleRegister f26 = {26};
const DoubleRegister f27 = {27}; constexpr DoubleRegister f27 = {27};
const DoubleRegister f28 = {28}; constexpr DoubleRegister f28 = {28};
const DoubleRegister f29 = {29}; constexpr DoubleRegister f29 = {29};
const DoubleRegister f30 = {30}; constexpr DoubleRegister f30 = {30};
const DoubleRegister f31 = {31}; constexpr DoubleRegister f31 = {31};
// Register aliases. // Register aliases.
// cp is assumed to be a callee saved register. // cp is assumed to be a callee saved register.
// Defined using #define instead of "static const Register&" because Clang constexpr Register kRootRegister = s6;
// complains otherwise when a compilation unit that includes this header constexpr Register cp = s7;
// doesn't use the variables. constexpr Register kLithiumScratchReg = s3;
#define kRootRegister s6 constexpr Register kLithiumScratchReg2 = s4;
#define cp s7 constexpr DoubleRegister kLithiumScratchDouble = f30;
#define kLithiumScratchReg s3 constexpr DoubleRegister kDoubleRegZero = f28;
#define kLithiumScratchReg2 s4
#define kLithiumScratchDouble f30
#define kDoubleRegZero f28
// Used on mips64r6 for compare operations. // Used on mips64r6 for compare operations.
// We use the last non-callee saved odd register for N64 ABI // We use the last non-callee saved odd register for N64 ABI
#define kDoubleCompareReg f23 constexpr DoubleRegister kDoubleCompareReg = f23;
// FPU (coprocessor 1) control registers. // FPU (coprocessor 1) control registers.
// Currently only FCSR (#31) is implemented. // Currently only FCSR (#31) is implemented.
...@@ -297,10 +287,7 @@ struct FPUControlRegister { ...@@ -297,10 +287,7 @@ struct FPUControlRegister {
DCHECK(is_valid()); DCHECK(is_valid());
return reg_code; return reg_code;
} }
int bit() const { constexpr int bit() const { return DCHECK(is_valid()), 1 << reg_code; }
DCHECK(is_valid());
return 1 << reg_code;
}
void setcode(int f) { void setcode(int f) {
reg_code = f; reg_code = f;
DCHECK(is_valid()); DCHECK(is_valid());
...@@ -309,13 +296,13 @@ struct FPUControlRegister { ...@@ -309,13 +296,13 @@ struct FPUControlRegister {
int reg_code; int reg_code;
}; };
const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister }; constexpr FPUControlRegister no_fpucreg = {kInvalidFPUControlRegister};
const FPUControlRegister FCSR = { kFCSRRegister }; constexpr FPUControlRegister FCSR = {kFCSRRegister};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Machine instruction Operands. // Machine instruction Operands.
const int kSmiShift = kSmiTagSize + kSmiShiftSize; constexpr int kSmiShift = kSmiTagSize + kSmiShiftSize;
const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; constexpr uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1;
// Class Operand represents a shifter operand in data processing instructions. // Class Operand represents a shifter operand in data processing instructions.
class Operand BASE_EMBEDDED { class Operand BASE_EMBEDDED {
public: public:
...@@ -509,10 +496,10 @@ class Assembler : public AssemblerBase { ...@@ -509,10 +496,10 @@ class Assembler : public AssemblerBase {
RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
// Size of an instruction. // 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. // 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. // 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 // These values are used in the serialization process and must be zero for
...@@ -520,46 +507,46 @@ class Assembler : public AssemblerBase { ...@@ -520,46 +507,46 @@ class Assembler : public AssemblerBase {
// are split across two consecutive instructions and don't exist separately // are split across two consecutive instructions and don't exist separately
// in the code, so the serializer should not step forwards in memory after // in the code, so the serializer should not step forwards in memory after
// a target is resolved and written. // 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. // Number of consecutive instructions used to store 32bit/64bit constant.
// This constant was used in RelocInfo::target_address_address() function // This constant was used in RelocInfo::target_address_address() function
// to tell serializer address of the instruction that follows // to tell serializer address of the instruction that follows
// LUI/ORI instruction pair. // LUI/ORI instruction pair.
static const int kInstructionsFor32BitConstant = 2; static constexpr int kInstructionsFor32BitConstant = 2;
static const int kInstructionsFor64BitConstant = 4; static constexpr int kInstructionsFor64BitConstant = 4;
// Distance between the instruction referring to the address of the call // Distance between the instruction referring to the address of the call
// target and the return address. // target and the return address.
#ifdef _MIPS_ARCH_MIPS64R6 #ifdef _MIPS_ARCH_MIPS64R6
static const int kCallTargetAddressOffset = 5 * kInstrSize; static constexpr int kCallTargetAddressOffset = 5 * kInstrSize;
#else #else
static const int kCallTargetAddressOffset = 6 * kInstrSize; static constexpr int kCallTargetAddressOffset = 6 * kInstrSize;
#endif #endif
// Distance between start of patched debug break slot and the emitted address // Distance between start of patched debug break slot and the emitted address
// to jump to. // 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 // Difference between address of current opcode and value read from pc
// register. // register.
static const int kPcLoadDelta = 4; static constexpr int kPcLoadDelta = 4;
#ifdef _MIPS_ARCH_MIPS64R6 #ifdef _MIPS_ARCH_MIPS64R6
static const int kDebugBreakSlotInstructions = 5; static constexpr int kDebugBreakSlotInstructions = 5;
#else #else
static const int kDebugBreakSlotInstructions = 6; static constexpr int kDebugBreakSlotInstructions = 6;
#endif #endif
static const int kDebugBreakSlotLength = static constexpr int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstrSize; kDebugBreakSlotInstructions * kInstrSize;
// Max offset for instructions with 16-bit offset field // 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 // 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. // Code generation.
...@@ -1313,21 +1300,21 @@ class Assembler : public AssemblerBase { ...@@ -1313,21 +1300,21 @@ class Assembler : public AssemblerBase {
private: private:
// Buffer size and constant pool distance are checked together at regular // Buffer size and constant pool distance are checked together at regular
// intervals of kBufferCheckInterval emitted bytes. // intervals of kBufferCheckInterval emitted bytes.
static const int kBufferCheckInterval = 1*KB/2; static constexpr int kBufferCheckInterval = 1 * KB / 2;
// Code generation. // Code generation.
// The relocation writer's position is at least kGap bytes below the end of // 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 // 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 // not have to check for overflow. The same is true for writes of large
// relocation info entries. // relocation info entries.
static const int kGap = 32; static constexpr int kGap = 32;
// Repeated checking whether the trampoline pool should be emitted is rather // Repeated checking whether the trampoline pool should be emitted is rather
// expensive. By default we only check again once a number of instructions // expensive. By default we only check again once a number of instructions
// has been generated. // has been generated.
static const int kCheckConstIntervalInst = 32; static constexpr int kCheckConstIntervalInst = 32;
static const int kCheckConstInterval = kCheckConstIntervalInst * kInstrSize; static constexpr int kCheckConstInterval =
kCheckConstIntervalInst * kInstrSize;
int next_buffer_check_; // pc offset of next buffer check. int next_buffer_check_; // pc offset of next buffer check.
...@@ -1343,7 +1330,7 @@ class Assembler : public AssemblerBase { ...@@ -1343,7 +1330,7 @@ class Assembler : public AssemblerBase {
// Relocation information generation. // Relocation information generation.
// Each relocation is encoded as a variable size value. // 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; RelocInfoWriter reloc_info_writer;
// The bound position, before this we cannot do instruction elimination. // The bound position, before this we cannot do instruction elimination.
...@@ -1497,7 +1484,7 @@ class Assembler : public AssemblerBase { ...@@ -1497,7 +1484,7 @@ class Assembler : public AssemblerBase {
// branch instruction generation, where we use jump instructions rather // branch instruction generation, where we use jump instructions rather
// than regular branch instructions. // than regular branch instructions.
bool trampoline_emitted_; bool trampoline_emitted_;
static const int kInvalidSlotPos = -1; static constexpr int kInvalidSlotPos = -1;
// Internal reference positions, required for unbounded internal reference // Internal reference positions, required for unbounded internal reference
// labels. // labels.
......
...@@ -80,7 +80,7 @@ namespace internal { ...@@ -80,7 +80,7 @@ namespace internal {
V(r15) V(r15)
// The length of pushq(rbp), movp(rbp, rsp), Push(rsi) and Push(rdi). // 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. // CPU Registers.
// //
...@@ -112,7 +112,7 @@ struct Register { ...@@ -112,7 +112,7 @@ struct Register {
kCode_no_reg = -1 kCode_no_reg = -1
}; };
static const int kNumRegisters = Code::kAfterLast; static constexpr int kNumRegisters = Code::kAfterLast;
static Register from_code(int code) { static Register from_code(int code) {
DCHECK(code >= 0); DCHECK(code >= 0);
...@@ -144,25 +144,23 @@ struct Register { ...@@ -144,25 +144,23 @@ struct Register {
int reg_code; int reg_code;
}; };
#define DECLARE_REGISTER(R) constexpr Register R = {Register::kCode_##R};
#define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
GENERAL_REGISTERS(DECLARE_REGISTER) GENERAL_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER #undef DECLARE_REGISTER
const Register no_reg = {Register::kCode_no_reg}; constexpr Register no_reg = {Register::kCode_no_reg};
#ifdef _WIN64 #ifdef _WIN64
// Windows calling convention // Windows calling convention
const Register arg_reg_1 = {Register::kCode_rcx}; constexpr Register arg_reg_1 = {Register::kCode_rcx};
const Register arg_reg_2 = {Register::kCode_rdx}; constexpr Register arg_reg_2 = {Register::kCode_rdx};
const Register arg_reg_3 = {Register::kCode_r8}; constexpr Register arg_reg_3 = {Register::kCode_r8};
const Register arg_reg_4 = {Register::kCode_r9}; constexpr Register arg_reg_4 = {Register::kCode_r9};
#else #else
// AMD64 calling convention // AMD64 calling convention
const Register arg_reg_1 = {Register::kCode_rdi}; constexpr Register arg_reg_1 = {Register::kCode_rdi};
const Register arg_reg_2 = {Register::kCode_rsi}; constexpr Register arg_reg_2 = {Register::kCode_rsi};
const Register arg_reg_3 = {Register::kCode_rdx}; constexpr Register arg_reg_3 = {Register::kCode_rdx};
const Register arg_reg_4 = {Register::kCode_rcx}; constexpr Register arg_reg_4 = {Register::kCode_rcx};
#endif // _WIN64 #endif // _WIN64
...@@ -204,8 +202,8 @@ const Register arg_reg_4 = {Register::kCode_rcx}; ...@@ -204,8 +202,8 @@ const Register arg_reg_4 = {Register::kCode_rcx};
V(xmm13) \ V(xmm13) \
V(xmm14) V(xmm14)
static const bool kSimpleFPAliasing = true; constexpr bool kSimpleFPAliasing = true;
static const bool kSimdMaskRegisters = false; constexpr bool kSimdMaskRegisters = false;
struct XMMRegister { struct XMMRegister {
enum Code { enum Code {
...@@ -216,7 +214,7 @@ struct XMMRegister { ...@@ -216,7 +214,7 @@ struct XMMRegister {
kCode_no_reg = -1 kCode_no_reg = -1
}; };
static const int kMaxNumRegisters = Code::kAfterLast; static constexpr int kMaxNumRegisters = Code::kAfterLast;
static XMMRegister from_code(int code) { static XMMRegister from_code(int code) {
XMMRegister result = {code}; XMMRegister result = {code};
...@@ -249,10 +247,10 @@ typedef XMMRegister DoubleRegister; ...@@ -249,10 +247,10 @@ typedef XMMRegister DoubleRegister;
typedef XMMRegister Simd128Register; typedef XMMRegister Simd128Register;
#define DECLARE_REGISTER(R) \ #define DECLARE_REGISTER(R) \
const DoubleRegister R = {DoubleRegister::kCode_##R}; constexpr DoubleRegister R = {DoubleRegister::kCode_##R};
DOUBLE_REGISTERS(DECLARE_REGISTER) DOUBLE_REGISTERS(DECLARE_REGISTER)
#undef 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 { enum Condition {
// any value < 0 is considered no_condition // any value < 0 is considered no_condition
...@@ -471,7 +469,7 @@ class Assembler : public AssemblerBase { ...@@ -471,7 +469,7 @@ class Assembler : public AssemblerBase {
// (There is a 15 byte limit on x64 instruction length that rules out some // (There is a 15 byte limit on x64 instruction length that rules out some
// otherwise valid instructions.) // otherwise valid instructions.)
// This allows for a single, fast space check per instruction. // This allows for a single, fast space check per instruction.
static const int kGap = 32; static constexpr int kGap = 32;
public: public:
// Create an assembler. Instructions and relocation information are emitted // Create an assembler. Instructions and relocation information are emitted
...@@ -538,42 +536,42 @@ class Assembler : public AssemblerBase { ...@@ -538,42 +536,42 @@ class Assembler : public AssemblerBase {
inline Handle<Code> code_target_object_handle_at(Address pc); inline Handle<Code> code_target_object_handle_at(Address pc);
inline Address runtime_entry_at(Address pc); inline Address runtime_entry_at(Address pc);
// Number of bytes taken up by the branch target in the code. // 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 // Distance between the address of the code target in the call instruction
// and the return address pushed on the stack. // 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). // The length of call(kScratchRegister).
static const int kCallScratchRegisterInstructionLength = 3; static constexpr int kCallScratchRegisterInstructionLength = 3;
// The length of call(Immediate32). // The length of call(Immediate32).
static const int kShortCallInstructionLength = 5; static constexpr int kShortCallInstructionLength = 5;
// The length of movq(kScratchRegister, address). // The length of movq(kScratchRegister, address).
static const int kMoveAddressIntoScratchRegisterInstructionLength = static constexpr int kMoveAddressIntoScratchRegisterInstructionLength =
2 + kPointerSize; 2 + kPointerSize;
// The length of movq(kScratchRegister, address) and call(kScratchRegister). // The length of movq(kScratchRegister, address) and call(kScratchRegister).
static const int kCallSequenceLength = static constexpr int kCallSequenceLength =
kMoveAddressIntoScratchRegisterInstructionLength + kMoveAddressIntoScratchRegisterInstructionLength +
kCallScratchRegisterInstructionLength; kCallScratchRegisterInstructionLength;
// The debug break slot must be able to contain an indirect call sequence. // 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 // Distance between start of patched debug break slot and the emitted address
// to jump to. // to jump to.
static const int kPatchDebugBreakSlotAddressOffset = static constexpr int kPatchDebugBreakSlotAddressOffset =
kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize; kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize;
// One byte opcode for test eax,0xXXXXXXXX. // One byte opcode for test eax,0xXXXXXXXX.
static const byte kTestEaxByte = 0xA9; static constexpr byte kTestEaxByte = 0xA9;
// One byte opcode for test al, 0xXX. // One byte opcode for test al, 0xXX.
static const byte kTestAlByte = 0xA8; static constexpr byte kTestAlByte = 0xA8;
// One byte opcode for nop. // One byte opcode for nop.
static const byte kNopByte = 0x90; static constexpr byte kNopByte = 0x90;
// One byte prefix for a short conditional jump. // One byte prefix for a short conditional jump.
static const byte kJccShortPrefix = 0x70; static constexpr byte kJccShortPrefix = 0x70;
static const byte kJncShortOpcode = kJccShortPrefix | not_carry; static constexpr byte kJncShortOpcode = kJccShortPrefix | not_carry;
static const byte kJcShortOpcode = kJccShortPrefix | carry; static constexpr byte kJcShortOpcode = kJccShortPrefix | carry;
static const byte kJnzShortOpcode = kJccShortPrefix | not_zero; static constexpr byte kJnzShortOpcode = kJccShortPrefix | not_zero;
static const byte kJzShortOpcode = kJccShortPrefix | zero; static constexpr byte kJzShortOpcode = kJccShortPrefix | zero;
// VEX prefix encodings. // VEX prefix encodings.
enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 }; enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
...@@ -2019,7 +2017,7 @@ class Assembler : public AssemblerBase { ...@@ -2019,7 +2017,7 @@ class Assembler : public AssemblerBase {
static bool IsNop(Address addr); static bool IsNop(Address addr);
// Avoid overflows for displacements etc. // 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]; } byte byte_at(int pos) { return buffer_[pos]; }
void set_byte_at(int pos, byte value) { buffer_[pos] = value; } void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
......
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