| Index: src/arm/assembler-arm.h
|
| diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
|
| index 2ada5713271e4e6998db0261cceb0f7b53501ce2..6664c6890549c9e3b4e7e601a3deb96965b79b0e 100644
|
| --- a/src/arm/assembler-arm.h
|
| +++ b/src/arm/assembler-arm.h
|
| @@ -50,6 +50,31 @@
|
| namespace v8 {
|
| namespace internal {
|
|
|
| +// clang-format off
|
| +#define GENERAL_REGISTERS(V) \
|
| + V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) \
|
| + V(r8) V(r9) V(r10) V(fp) V(ip) V(sp) V(lr) V(pc)
|
| +
|
| +#define ALLOCATABLE_GENERAL_REGISTERS(V) \
|
| + V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) V(r8)
|
| +
|
| +#define DOUBLE_REGISTERS(V) \
|
| + V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
|
| + V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) V(d14) V(d15) \
|
| + V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
|
| + V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
|
| +
|
| +#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
|
| + V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
|
| + V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) \
|
| + V(d16) V(d17) V(d18) V(d19) V(d20) V(d21) V(d22) V(d23) \
|
| + V(d24) V(d25) V(d26) V(d27) V(d28) V(d29) V(d30) V(d31)
|
| +
|
| +#define ALLOCATABLE_NO_VFP32_DOUBLE_REGISTERS(V) \
|
| + V(d0) V(d1) V(d2) V(d3) V(d4) V(d5) V(d6) V(d7) \
|
| + V(d8) V(d9) V(d10) V(d11) V(d12) V(d13) \
|
| +// clang-format on
|
| +
|
| // CPU Registers.
|
| //
|
| // 1) We would prefer to use an enum, but enum values are assignment-
|
| @@ -71,190 +96,123 @@ namespace internal {
|
| // mode. This way we get the compile-time error checking in debug mode
|
| // and best performance in optimized code.
|
|
|
| -// These constants are used in several locations, including static initializers
|
| -const int kRegister_no_reg_Code = -1;
|
| -const int kRegister_r0_Code = 0;
|
| -const int kRegister_r1_Code = 1;
|
| -const int kRegister_r2_Code = 2;
|
| -const int kRegister_r3_Code = 3;
|
| -const int kRegister_r4_Code = 4;
|
| -const int kRegister_r5_Code = 5;
|
| -const int kRegister_r6_Code = 6;
|
| -const int kRegister_r7_Code = 7;
|
| -const int kRegister_r8_Code = 8;
|
| -const int kRegister_r9_Code = 9;
|
| -const int kRegister_r10_Code = 10;
|
| -const int kRegister_fp_Code = 11;
|
| -const int kRegister_ip_Code = 12;
|
| -const int kRegister_sp_Code = 13;
|
| -const int kRegister_lr_Code = 14;
|
| -const int kRegister_pc_Code = 15;
|
| -
|
| -// Core register
|
| struct Register {
|
| - static const int kNumRegisters = 16;
|
| - static const int kMaxNumAllocatableRegisters =
|
| - FLAG_enable_embedded_constant_pool ? 8 : 9;
|
| - static const int kSizeInBytes = 4;
|
| -
|
| - inline static int NumAllocatableRegisters();
|
| -
|
| - static int ToAllocationIndex(Register reg) {
|
| - DCHECK(reg.code() < kMaxNumAllocatableRegisters);
|
| - return reg.code();
|
| - }
|
| + enum Code {
|
| +#define REGISTER_CODE(R) kCode_##R,
|
| + GENERAL_REGISTERS(REGISTER_CODE)
|
| +#undef REGISTER_CODE
|
| + kAfterLast,
|
| + kCode_no_reg = -1
|
| + };
|
|
|
| - static Register FromAllocationIndex(int index) {
|
| - DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
|
| - return from_code(index);
|
| - }
|
| -
|
| - static const char* AllocationIndexToString(int index) {
|
| - DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
|
| - const char* const names[] = {
|
| - "r0",
|
| - "r1",
|
| - "r2",
|
| - "r3",
|
| - "r4",
|
| - "r5",
|
| - "r6",
|
| - "r7",
|
| - "r8",
|
| - };
|
| - if (FLAG_enable_embedded_constant_pool && (index >= 7)) {
|
| - return names[index + 1];
|
| - }
|
| - return names[index];
|
| - }
|
| + static const int kNumRegisters = Code::kAfterLast;
|
|
|
| static Register from_code(int code) {
|
| - Register r = { code };
|
| + DCHECK(code >= 0);
|
| + DCHECK(code < kNumRegisters);
|
| + Register r = {code};
|
| return r;
|
| }
|
| -
|
| - bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
|
| - bool is(Register reg) const { return code_ == reg.code_; }
|
| + const char* ToString();
|
| + bool IsAllocatable() const;
|
| + bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
|
| + bool is(Register reg) const { return reg_code == reg.reg_code; }
|
| int code() const {
|
| DCHECK(is_valid());
|
| - return code_;
|
| + return reg_code;
|
| }
|
| int bit() const {
|
| DCHECK(is_valid());
|
| - return 1 << code_;
|
| + return 1 << reg_code;
|
| }
|
| -
|
| void set_code(int code) {
|
| - code_ = code;
|
| + reg_code = code;
|
| DCHECK(is_valid());
|
| }
|
|
|
| // Unfortunately we can't make this private in a struct.
|
| - int code_;
|
| + int reg_code;
|
| };
|
|
|
| -const Register no_reg = { kRegister_no_reg_Code };
|
| -
|
| -const Register r0 = { kRegister_r0_Code };
|
| -const Register r1 = { kRegister_r1_Code };
|
| -const Register r2 = { kRegister_r2_Code };
|
| -const Register r3 = { kRegister_r3_Code };
|
| -const Register r4 = { kRegister_r4_Code };
|
| -const Register r5 = { kRegister_r5_Code };
|
| -const Register r6 = { kRegister_r6_Code };
|
| -// Used as context register.
|
| -const Register r7 = {kRegister_r7_Code};
|
| -// Used as constant pool pointer register if FLAG_enable_embedded_constant_pool.
|
| -const Register r8 = { kRegister_r8_Code };
|
| -// Used as lithium codegen scratch register.
|
| -const Register r9 = { kRegister_r9_Code };
|
| -// Used as roots register.
|
| -const Register r10 = { kRegister_r10_Code };
|
| -const Register fp = { kRegister_fp_Code };
|
| -const Register ip = { kRegister_ip_Code };
|
| -const Register sp = { kRegister_sp_Code };
|
| -const Register lr = { kRegister_lr_Code };
|
| -const Register pc = { kRegister_pc_Code };
|
| +// 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};
|
| +GENERAL_REGISTERS(DECLARE_REGISTER)
|
| +#undef DECLARE_REGISTER
|
| +const Register no_reg = {Register::kCode_no_reg};
|
|
|
| // Single word VFP register.
|
| struct SwVfpRegister {
|
| static const int kSizeInBytes = 4;
|
| - bool is_valid() const { return 0 <= code_ && code_ < 32; }
|
| - bool is(SwVfpRegister reg) const { return code_ == reg.code_; }
|
| + bool is_valid() const { return 0 <= reg_code && reg_code < 32; }
|
| + bool is(SwVfpRegister reg) const { return reg_code == reg.reg_code; }
|
| int code() const {
|
| DCHECK(is_valid());
|
| - return code_;
|
| + return reg_code;
|
| }
|
| int bit() const {
|
| DCHECK(is_valid());
|
| - return 1 << code_;
|
| + return 1 << reg_code;
|
| }
|
| void split_code(int* vm, int* m) const {
|
| DCHECK(is_valid());
|
| - *m = code_ & 0x1;
|
| - *vm = code_ >> 1;
|
| + *m = reg_code & 0x1;
|
| + *vm = reg_code >> 1;
|
| }
|
|
|
| - int code_;
|
| + int reg_code;
|
| };
|
|
|
|
|
| // Double word VFP register.
|
| -struct DwVfpRegister {
|
| - static const int kMaxNumRegisters = 32;
|
| +struct DoubleRegister {
|
| + enum Code {
|
| +#define REGISTER_CODE(R) kCode_##R,
|
| + DOUBLE_REGISTERS(REGISTER_CODE)
|
| +#undef REGISTER_CODE
|
| + kAfterLast,
|
| + kCode_no_reg = -1
|
| + };
|
| +
|
| + static const int kMaxNumRegisters = Code::kAfterLast;
|
| +
|
| + inline static int NumRegisters();
|
| +
|
| // A few double registers are reserved: one as a scratch register and one to
|
| // hold 0.0, that does not fit in the immediate field of vmov instructions.
|
| // d14: 0.0
|
| // d15: scratch register.
|
| - static const int kNumReservedRegisters = 2;
|
| - static const int kMaxNumAllocatableRegisters = kMaxNumRegisters -
|
| - kNumReservedRegisters;
|
| static const int kSizeInBytes = 8;
|
|
|
| - // Note: the number of registers can be different at snapshot and run-time.
|
| - // Any code included in the snapshot must be able to run both with 16 or 32
|
| - // registers.
|
| - inline static int NumRegisters();
|
| - inline static int NumReservedRegisters();
|
| - inline static int NumAllocatableRegisters();
|
| -
|
| - // TODO(turbofan): This is a temporary work-around required because our
|
| - // register allocator does not yet support the aliasing of single/double
|
| - // registers on ARM.
|
| - inline static int NumAllocatableAliasedRegisters();
|
| -
|
| - inline static int ToAllocationIndex(DwVfpRegister reg);
|
| - static const char* AllocationIndexToString(int index);
|
| - inline static DwVfpRegister FromAllocationIndex(int index);
|
| -
|
| - static DwVfpRegister from_code(int code) {
|
| - DwVfpRegister r = { code };
|
| - return r;
|
| - }
|
| -
|
| - bool is_valid() const {
|
| - return 0 <= code_ && code_ < kMaxNumRegisters;
|
| - }
|
| - bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
|
| + const char* ToString();
|
| + bool IsAllocatable() const;
|
| + bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
|
| + bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
|
| int code() const {
|
| DCHECK(is_valid());
|
| - return code_;
|
| + return reg_code;
|
| }
|
| int bit() const {
|
| DCHECK(is_valid());
|
| - return 1 << code_;
|
| + return 1 << reg_code;
|
| + }
|
| +
|
| + static DoubleRegister from_code(int code) {
|
| + DoubleRegister r = {code};
|
| + return r;
|
| }
|
| void split_code(int* vm, int* m) const {
|
| DCHECK(is_valid());
|
| - *m = (code_ & 0x10) >> 4;
|
| - *vm = code_ & 0x0F;
|
| + *m = (reg_code & 0x10) >> 4;
|
| + *vm = reg_code & 0x0F;
|
| }
|
|
|
| - int code_;
|
| + int reg_code;
|
| };
|
|
|
|
|
| -typedef DwVfpRegister DoubleRegister;
|
| +typedef DoubleRegister DwVfpRegister;
|
|
|
|
|
| // Double word VFP register d0-15.
|
| @@ -262,7 +220,7 @@ struct LowDwVfpRegister {
|
| public:
|
| static const int kMaxNumLowRegisters = 16;
|
| operator DwVfpRegister() const {
|
| - DwVfpRegister r = { code_ };
|
| + DwVfpRegister r = { reg_code };
|
| return r;
|
| }
|
| static LowDwVfpRegister from_code(int code) {
|
| @@ -271,30 +229,30 @@ struct LowDwVfpRegister {
|
| }
|
|
|
| bool is_valid() const {
|
| - return 0 <= code_ && code_ < kMaxNumLowRegisters;
|
| + return 0 <= reg_code && reg_code < kMaxNumLowRegisters;
|
| }
|
| - bool is(DwVfpRegister reg) const { return code_ == reg.code_; }
|
| - bool is(LowDwVfpRegister reg) const { return code_ == reg.code_; }
|
| + bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; }
|
| + bool is(LowDwVfpRegister reg) const { return reg_code == reg.reg_code; }
|
| int code() const {
|
| DCHECK(is_valid());
|
| - return code_;
|
| + return reg_code;
|
| }
|
| SwVfpRegister low() const {
|
| SwVfpRegister reg;
|
| - reg.code_ = code_ * 2;
|
| + reg.reg_code = reg_code * 2;
|
|
|
| DCHECK(reg.is_valid());
|
| return reg;
|
| }
|
| SwVfpRegister high() const {
|
| SwVfpRegister reg;
|
| - reg.code_ = (code_ * 2) + 1;
|
| + reg.reg_code = (reg_code * 2) + 1;
|
|
|
| DCHECK(reg.is_valid());
|
| return reg;
|
| }
|
|
|
| - int code_;
|
| + int reg_code;
|
| };
|
|
|
|
|
| @@ -308,21 +266,21 @@ struct QwNeonRegister {
|
| }
|
|
|
| bool is_valid() const {
|
| - return (0 <= code_) && (code_ < kMaxNumRegisters);
|
| + return (0 <= reg_code) && (reg_code < kMaxNumRegisters);
|
| }
|
| - bool is(QwNeonRegister reg) const { return code_ == reg.code_; }
|
| + bool is(QwNeonRegister reg) const { return reg_code == reg.reg_code; }
|
| int code() const {
|
| DCHECK(is_valid());
|
| - return code_;
|
| + return reg_code;
|
| }
|
| void split_code(int* vm, int* m) const {
|
| DCHECK(is_valid());
|
| - int encoded_code = code_ << 1;
|
| + int encoded_code = reg_code << 1;
|
| *m = (encoded_code & 0x10) >> 4;
|
| *vm = encoded_code & 0x0F;
|
| }
|
|
|
| - int code_;
|
| + int reg_code;
|
| };
|
|
|
|
|
| @@ -427,19 +385,19 @@ const QwNeonRegister q15 = { 15 };
|
|
|
| // Coprocessor register
|
| struct CRegister {
|
| - bool is_valid() const { return 0 <= code_ && code_ < 16; }
|
| - bool is(CRegister creg) const { return code_ == creg.code_; }
|
| + bool is_valid() const { return 0 <= reg_code && reg_code < 16; }
|
| + bool is(CRegister creg) const { return reg_code == creg.reg_code; }
|
| int code() const {
|
| DCHECK(is_valid());
|
| - return code_;
|
| + return reg_code;
|
| }
|
| int bit() const {
|
| DCHECK(is_valid());
|
| - return 1 << code_;
|
| + return 1 << reg_code;
|
| }
|
|
|
| // Unfortunately we can't make this private in a struct.
|
| - int code_;
|
| + int reg_code;
|
| };
|
|
|
|
|
|
|