| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 | 53 |
| 54 static const int kRegListSizeInBits = sizeof(RegList) * kBitsPerByte; | 54 static const int kRegListSizeInBits = sizeof(RegList) * kBitsPerByte; |
| 55 | 55 |
| 56 | 56 |
| 57 // Some CPURegister methods can return Register and FPRegister types, so we | 57 // Some CPURegister methods can return Register and FPRegister types, so we |
| 58 // need to declare them in advance. | 58 // need to declare them in advance. |
| 59 class Register; | 59 class Register; |
| 60 class FPRegister; | 60 class FPRegister; |
| 61 | 61 |
| 62 | 62 |
| 63 class CPURegister { | 63 struct CPURegister { |
| 64 public: | |
| 65 enum RegisterType { | 64 enum RegisterType { |
| 66 // The kInvalid value is used to detect uninitialized static instances, | 65 // The kInvalid value is used to detect uninitialized static instances, |
| 67 // which are always zero-initialized before any constructors are called. | 66 // which are always zero-initialized before any constructors are called. |
| 68 kInvalid = 0, | 67 kInvalid = 0, |
| 69 kRegister, | 68 kRegister, |
| 70 kFPRegister, | 69 kFPRegister, |
| 71 kNoRegister | 70 kNoRegister |
| 72 }; | 71 }; |
| 73 | 72 |
| 74 CPURegister() : code_(0), size_(0), type_(kNoRegister) { | 73 static CPURegister Create(unsigned code, unsigned size, RegisterType type) { |
| 75 ASSERT(!IsValid()); | 74 CPURegister r = {code, size, type}; |
| 76 ASSERT(IsNone()); | 75 return r; |
| 77 } | |
| 78 | |
| 79 CPURegister(unsigned code, unsigned size, RegisterType type) | |
| 80 : code_(code), size_(size), type_(type) { | |
| 81 ASSERT(IsValidOrNone()); | |
| 82 } | |
| 83 | |
| 84 // This copy constructor is used by the Register and FPRegister classes for | |
| 85 // converting a CPURegister into a more specialized type. It is necessary | |
| 86 // because (FP)Register cannot directly access other.size_ and suchlike and | |
| 87 // the accessor methods don't allow NoCPUReg. Unfortunately, it cannot be | |
| 88 // explicit because otherwise the simple (FP)Register->CPURegister casts do | |
| 89 // not work. | |
| 90 CPURegister(const CPURegister& other) | |
| 91 : code_(other.code_), size_(other.size_), type_(other.type_) { | |
| 92 ASSERT(IsValidOrNone()); | |
| 93 } | 76 } |
| 94 | 77 |
| 95 unsigned code() const; | 78 unsigned code() const; |
| 96 RegisterType type() const; | 79 RegisterType type() const; |
| 97 RegList Bit() const; | 80 RegList Bit() const; |
| 98 unsigned SizeInBits() const; | 81 unsigned SizeInBits() const; |
| 99 int SizeInBytes() const; | 82 int SizeInBytes() const; |
| 100 bool Is32Bits() const; | 83 bool Is32Bits() const; |
| 101 bool Is64Bits() const; | 84 bool Is64Bits() const; |
| 102 bool IsValid() const; | 85 bool IsValid() const; |
| 103 bool IsValidRegister() const; | 86 bool IsValidRegister() const; |
| 104 bool IsValidFPRegister() const; | 87 bool IsValidFPRegister() const; |
| 105 bool IsNone() const; | 88 bool IsNone() const; |
| 106 bool Is(const CPURegister& other) const; | 89 bool Is(const CPURegister& other) const; |
| 107 | 90 |
| 108 bool IsZero() const; | 91 bool IsZero() const; |
| 109 bool IsSP() const; | 92 bool IsSP() const; |
| 110 | 93 |
| 111 bool IsRegister() const; | 94 bool IsRegister() const; |
| 112 bool IsFPRegister() const; | 95 bool IsFPRegister() const; |
| 113 | 96 |
| 114 const Register& X() const; | 97 Register X() const; |
| 115 const Register& W() const; | 98 Register W() const; |
| 116 const FPRegister& D() const; | 99 FPRegister D() const; |
| 117 const FPRegister& S() const; | 100 FPRegister S() const; |
| 118 | 101 |
| 119 bool IsSameSizeAndType(const CPURegister& other) const; | 102 bool IsSameSizeAndType(const CPURegister& other) const; |
| 120 | 103 |
| 121 // V8 compatibility. | 104 // V8 compatibility. |
| 122 bool is(const CPURegister& other) const { return Is(other); } | 105 bool is(const CPURegister& other) const { return Is(other); } |
| 123 bool is_valid() const { return IsValid(); } | 106 bool is_valid() const { return IsValid(); } |
| 124 | 107 |
| 125 protected: | 108 unsigned reg_code; |
| 126 unsigned code_; | 109 unsigned reg_size; |
| 127 unsigned size_; | 110 RegisterType reg_type; |
| 128 RegisterType type_; | |
| 129 | 111 |
| 130 private: | 112 private: |
| 131 bool IsValidOrNone() const; | 113 bool IsValidOrNone() const; |
| 132 }; | 114 }; |
| 133 | 115 |
| 134 | 116 |
| 135 class Register : public CPURegister { | 117 struct Register : public CPURegister { |
| 136 public: | 118 static Register Create(unsigned code, unsigned size) { |
| 137 Register() : CPURegister() {} | 119 return CPURegister::Create(code, size, CPURegister::kRegister); |
| 138 explicit Register(const CPURegister& other) : CPURegister(other) { | |
| 139 ASSERT(IsValidRegister() || IsNone()); | |
| 140 } | 120 } |
| 141 Register(unsigned code, unsigned size) | 121 |
| 142 : CPURegister(code, size, kRegister) {} | 122 Register() { |
| 123 reg_code = 0; |
| 124 reg_size = 0; |
| 125 reg_type = CPURegister::kNoRegister; |
| 126 } |
| 127 |
| 128 Register(const CPURegister& r) { // NOLINT(runtime/explicit) |
| 129 reg_code = r.reg_code; |
| 130 reg_size = r.reg_size; |
| 131 reg_type = r.reg_type; |
| 132 ASSERT(IsValid()); |
| 133 } |
| 143 | 134 |
| 144 bool IsValid() const { | 135 bool IsValid() const { |
| 145 ASSERT(IsRegister() || IsNone()); | 136 ASSERT(IsRegister() || IsNone()); |
| 146 return IsValidRegister(); | 137 return IsValidRegister(); |
| 147 } | 138 } |
| 148 | 139 |
| 149 static const Register& XRegFromCode(unsigned code); | 140 static Register XRegFromCode(unsigned code); |
| 150 static const Register& WRegFromCode(unsigned code); | 141 static Register WRegFromCode(unsigned code); |
| 151 | 142 |
| 152 // Start of V8 compatibility section --------------------- | 143 // Start of V8 compatibility section --------------------- |
| 153 // These memebers are necessary for compilation. | 144 // These memebers are necessary for compilation. |
| 154 // A few of them may be unused for now. | 145 // A few of them may be unused for now. |
| 155 | 146 |
| 156 static const int kNumRegisters = kNumberOfRegisters; | 147 static const int kNumRegisters = kNumberOfRegisters; |
| 157 static int NumRegisters() { return kNumRegisters; } | 148 static int NumRegisters() { return kNumRegisters; } |
| 158 | 149 |
| 159 // We allow crankshaft to use the following registers: | 150 // We allow crankshaft to use the following registers: |
| 160 // - x0 to x15 | 151 // - x0 to x15 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 174 static const int kAllocatableRangeGapSize = | 165 static const int kAllocatableRangeGapSize = |
| 175 (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1; | 166 (kAllocatableHighRangeBegin - kAllocatableLowRangeEnd) - 1; |
| 176 | 167 |
| 177 static const int kMaxNumAllocatableRegisters = | 168 static const int kMaxNumAllocatableRegisters = |
| 178 (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) + | 169 (kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1) + |
| 179 (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1); | 170 (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1); |
| 180 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } | 171 static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; } |
| 181 | 172 |
| 182 // Return true if the register is one that crankshaft can allocate. | 173 // Return true if the register is one that crankshaft can allocate. |
| 183 bool IsAllocatable() const { | 174 bool IsAllocatable() const { |
| 184 return (code_ <= kAllocatableLowRangeEnd) || | 175 return (reg_code <= kAllocatableLowRangeEnd) || |
| 185 ((code_ >= kAllocatableHighRangeBegin) && | 176 ((reg_code >= kAllocatableHighRangeBegin) && |
| 186 (code_ <= kAllocatableHighRangeEnd)); | 177 (reg_code <= kAllocatableHighRangeEnd)); |
| 187 } | 178 } |
| 188 | 179 |
| 189 static Register FromAllocationIndex(unsigned index) { | 180 static Register FromAllocationIndex(unsigned index) { |
| 190 ASSERT(index < static_cast<unsigned>(NumAllocatableRegisters())); | 181 ASSERT(index < static_cast<unsigned>(NumAllocatableRegisters())); |
| 191 return (index <= kAllocatableLowRangeEnd) | 182 return (index <= kAllocatableLowRangeEnd) |
| 192 ? from_code(index) | 183 ? from_code(index) |
| 193 : from_code(index + kAllocatableRangeGapSize); | 184 : from_code(index + kAllocatableRangeGapSize); |
| 194 } | 185 } |
| 195 | 186 |
| 196 static const char* AllocationIndexToString(int index) { | 187 static const char* AllocationIndexToString(int index) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 212 static int ToAllocationIndex(Register reg) { | 203 static int ToAllocationIndex(Register reg) { |
| 213 ASSERT(reg.IsAllocatable()); | 204 ASSERT(reg.IsAllocatable()); |
| 214 unsigned code = reg.code(); | 205 unsigned code = reg.code(); |
| 215 return (code <= kAllocatableLowRangeEnd) | 206 return (code <= kAllocatableLowRangeEnd) |
| 216 ? code | 207 ? code |
| 217 : code - kAllocatableRangeGapSize; | 208 : code - kAllocatableRangeGapSize; |
| 218 } | 209 } |
| 219 | 210 |
| 220 static Register from_code(int code) { | 211 static Register from_code(int code) { |
| 221 // Always return an X register. | 212 // Always return an X register. |
| 222 Register r(code, kXRegSize); | 213 return Register::Create(code, kXRegSize); |
| 223 return r; | |
| 224 } | 214 } |
| 225 | 215 |
| 226 // End of V8 compatibility section ----------------------- | 216 // End of V8 compatibility section ----------------------- |
| 227 | |
| 228 private: | |
| 229 static const Register xregisters[]; | |
| 230 static const Register wregisters[]; | |
| 231 }; | 217 }; |
| 232 | 218 |
| 233 | 219 |
| 234 class FPRegister : public CPURegister { | 220 struct FPRegister : public CPURegister { |
| 235 public: | 221 static FPRegister Create(unsigned code, unsigned size) { |
| 236 FPRegister() : CPURegister() {} | 222 return CPURegister::Create(code, size, CPURegister::kFPRegister); |
| 237 explicit FPRegister(const CPURegister& other) : CPURegister(other) { | |
| 238 ASSERT(IsValidFPRegister() || IsNone()); | |
| 239 } | 223 } |
| 240 FPRegister(unsigned code, unsigned size) | 224 |
| 241 : CPURegister(code, size, kFPRegister) {} | 225 FPRegister() { |
| 226 reg_code = 0; |
| 227 reg_size = 0; |
| 228 reg_type = CPURegister::kNoRegister; |
| 229 } |
| 230 |
| 231 FPRegister(const CPURegister& r) { // NOLINT(runtime/explicit) |
| 232 reg_code = r.reg_code; |
| 233 reg_size = r.reg_size; |
| 234 reg_type = r.reg_type; |
| 235 ASSERT(IsValid()); |
| 236 } |
| 242 | 237 |
| 243 bool IsValid() const { | 238 bool IsValid() const { |
| 244 ASSERT(IsFPRegister() || IsNone()); | 239 ASSERT(IsFPRegister() || IsNone()); |
| 245 return IsValidFPRegister(); | 240 return IsValidFPRegister(); |
| 246 } | 241 } |
| 247 | 242 |
| 248 static const FPRegister& SRegFromCode(unsigned code); | 243 static FPRegister SRegFromCode(unsigned code); |
| 249 static const FPRegister& DRegFromCode(unsigned code); | 244 static FPRegister DRegFromCode(unsigned code); |
| 250 | 245 |
| 251 // Start of V8 compatibility section --------------------- | 246 // Start of V8 compatibility section --------------------- |
| 252 static const int kMaxNumRegisters = kNumberOfFPRegisters; | 247 static const int kMaxNumRegisters = kNumberOfFPRegisters; |
| 253 | 248 |
| 254 // Crankshaft can use all the FP registers except: | 249 // Crankshaft can use all the FP registers except: |
| 255 // - d29 which is used in crankshaft as a double scratch register | 250 // - d29 which is used in crankshaft as a double scratch register |
| 256 // - d30 which is used to keep the 0 double value | 251 // - d30 which is used to keep the 0 double value |
| 257 // - d31 which is used in the MacroAssembler as a double scratch register | 252 // - d31 which is used in the MacroAssembler as a double scratch register |
| 258 static const int kNumReservedRegisters = 3; | 253 static const int kNumReservedRegisters = 3; |
| 259 static const int kMaxNumAllocatableRegisters = | 254 static const int kMaxNumAllocatableRegisters = |
| (...skipping 19 matching lines...) Expand all Loading... |
| 279 } | 274 } |
| 280 | 275 |
| 281 static int ToAllocationIndex(FPRegister reg) { | 276 static int ToAllocationIndex(FPRegister reg) { |
| 282 int code = reg.code(); | 277 int code = reg.code(); |
| 283 ASSERT(code < NumAllocatableRegisters()); | 278 ASSERT(code < NumAllocatableRegisters()); |
| 284 return code; | 279 return code; |
| 285 } | 280 } |
| 286 | 281 |
| 287 static FPRegister from_code(int code) { | 282 static FPRegister from_code(int code) { |
| 288 // Always return a D register. | 283 // Always return a D register. |
| 289 FPRegister r(code, kDRegSize); | 284 return FPRegister::Create(code, kDRegSize); |
| 290 return r; | |
| 291 } | 285 } |
| 292 // End of V8 compatibility section ----------------------- | 286 // End of V8 compatibility section ----------------------- |
| 293 | |
| 294 private: | |
| 295 static const FPRegister sregisters[]; | |
| 296 static const FPRegister dregisters[]; | |
| 297 }; | 287 }; |
| 298 | 288 |
| 299 | 289 |
| 290 STATIC_ASSERT(sizeof(CPURegister) == sizeof(Register)); |
| 291 STATIC_ASSERT(sizeof(CPURegister) == sizeof(FPRegister)); |
| 292 |
| 293 |
| 294 #if defined(A64_DEFINE_REG_STATICS) |
| 295 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \ |
| 296 const CPURegister init_##register_class##_##name = {code, size, type}; \ |
| 297 const register_class& name = *reinterpret_cast<const register_class*>( \ |
| 298 &init_##register_class##_##name) |
| 299 #define ALIAS_REGISTER(register_class, alias, name) \ |
| 300 const register_class& alias = *reinterpret_cast<const register_class*>( \ |
| 301 &init_##register_class##_##name) |
| 302 #else |
| 303 #define INITIALIZE_REGISTER(register_class, name, code, size, type) \ |
| 304 extern const register_class& name |
| 305 #define ALIAS_REGISTER(register_class, alias, name) \ |
| 306 extern const register_class& alias |
| 307 #endif // defined(A64_DEFINE_REG_STATICS) |
| 308 |
| 300 // No*Reg is used to indicate an unused argument, or an error case. Note that | 309 // No*Reg is used to indicate an unused argument, or an error case. Note that |
| 301 // these all compare equal (using the Is() method). The Register and FPRegister | 310 // these all compare equal (using the Is() method). The Register and FPRegister |
| 302 // variants are provided for convenience. | 311 // variants are provided for convenience. |
| 303 const Register NoReg; | 312 INITIALIZE_REGISTER(Register, NoReg, 0, 0, CPURegister::kNoRegister); |
| 304 const FPRegister NoFPReg; | 313 INITIALIZE_REGISTER(FPRegister, NoFPReg, 0, 0, CPURegister::kNoRegister); |
| 305 const CPURegister NoCPUReg; | 314 INITIALIZE_REGISTER(CPURegister, NoCPUReg, 0, 0, CPURegister::kNoRegister); |
| 306 | 315 |
| 307 const Register no_reg; // v8 compatibility. | 316 // v8 compatibility. |
| 317 INITIALIZE_REGISTER(Register, no_reg, 0, 0, CPURegister::kNoRegister); |
| 308 | 318 |
| 309 | 319 #define DEFINE_REGISTERS(N) \ |
| 310 #define DEFINE_REGISTERS(N) \ | 320 INITIALIZE_REGISTER(Register, w##N, N, kWRegSize, CPURegister::kRegister); \ |
| 311 const Register w##N(N, kWRegSize); \ | 321 INITIALIZE_REGISTER(Register, x##N, N, kXRegSize, CPURegister::kRegister); |
| 312 const Register x##N(N, kXRegSize); | |
| 313 REGISTER_CODE_LIST(DEFINE_REGISTERS) | 322 REGISTER_CODE_LIST(DEFINE_REGISTERS) |
| 314 #undef DEFINE_REGISTERS | 323 #undef DEFINE_REGISTERS |
| 315 const Register wcsp(kSPRegInternalCode, kWRegSize); | |
| 316 const Register csp(kSPRegInternalCode, kXRegSize); | |
| 317 | 324 |
| 325 INITIALIZE_REGISTER(Register, wcsp, kSPRegInternalCode, kWRegSize, |
| 326 CPURegister::kRegister); |
| 327 INITIALIZE_REGISTER(Register, csp, kSPRegInternalCode, kXRegSize, |
| 328 CPURegister::kRegister); |
| 318 | 329 |
| 319 #define DEFINE_FPREGISTERS(N) \ | 330 #define DEFINE_FPREGISTERS(N) \ |
| 320 const FPRegister s##N(N, kSRegSize); \ | 331 INITIALIZE_REGISTER(FPRegister, s##N, N, kSRegSize, \ |
| 321 const FPRegister d##N(N, kDRegSize); | 332 CPURegister::kFPRegister); \ |
| 333 INITIALIZE_REGISTER(FPRegister, d##N, N, kDRegSize, CPURegister::kFPRegister); |
| 322 REGISTER_CODE_LIST(DEFINE_FPREGISTERS) | 334 REGISTER_CODE_LIST(DEFINE_FPREGISTERS) |
| 323 #undef DEFINE_FPREGISTERS | 335 #undef DEFINE_FPREGISTERS |
| 324 | 336 |
| 337 #undef INITIALIZE_REGISTER |
| 325 | 338 |
| 326 // Registers aliases. | 339 // Registers aliases. |
| 327 const Register ip0 = x16; | 340 ALIAS_REGISTER(Register, ip0, x16); |
| 328 const Register ip1 = x17; | 341 ALIAS_REGISTER(Register, ip1, x17); |
| 329 const Register wip0 = w16; | 342 ALIAS_REGISTER(Register, wip0, w16); |
| 330 const Register wip1 = w17; | 343 ALIAS_REGISTER(Register, wip1, w17); |
| 331 // Root register. | 344 // Root register. |
| 332 const Register root = x26; | 345 ALIAS_REGISTER(Register, root, x26); |
| 333 const Register rr = root; | 346 ALIAS_REGISTER(Register, rr, x26); |
| 334 // Context pointer register. | 347 // Context pointer register. |
| 335 const Register cp = x27; | 348 ALIAS_REGISTER(Register, cp, x27); |
| 336 // We use a register as a JS stack pointer to overcome the restriction on the | 349 // We use a register as a JS stack pointer to overcome the restriction on the |
| 337 // architectural SP alignment. | 350 // architectural SP alignment. |
| 338 // We chose x28 because it is contiguous with the other specific purpose | 351 // We chose x28 because it is contiguous with the other specific purpose |
| 339 // registers. | 352 // registers. |
| 340 STATIC_ASSERT(kJSSPCode == 28); | 353 STATIC_ASSERT(kJSSPCode == 28); |
| 341 const Register jssp = x28; | 354 ALIAS_REGISTER(Register, jssp, x28); |
| 342 const Register wjssp = w28; | 355 ALIAS_REGISTER(Register, wjssp, w28); |
| 343 const Register fp = x29; | 356 ALIAS_REGISTER(Register, fp, x29); |
| 344 const Register lr = x30; | 357 ALIAS_REGISTER(Register, lr, x30); |
| 345 const Register xzr = x31; | 358 ALIAS_REGISTER(Register, xzr, x31); |
| 346 const Register wzr = w31; | 359 ALIAS_REGISTER(Register, wzr, w31); |
| 347 | 360 |
| 348 // Crankshaft double scratch register. | 361 // Crankshaft double scratch register. |
| 349 const FPRegister crankshaft_fp_scratch = d29; | 362 ALIAS_REGISTER(FPRegister, crankshaft_fp_scratch, d29); |
| 350 // Keeps the 0 double value. | 363 // Keeps the 0 double value. |
| 351 const FPRegister fp_zero = d30; | 364 ALIAS_REGISTER(FPRegister, fp_zero, d30); |
| 352 // MacroAssembler double scratch register. | 365 // MacroAssembler double scratch register. |
| 353 const FPRegister fp_scratch = d31; | 366 ALIAS_REGISTER(FPRegister, fp_scratch, d31); |
| 367 |
| 368 #undef ALIAS_REGISTER |
| 354 | 369 |
| 355 // AreAliased returns true if any of the named registers overlap. Arguments set | 370 // AreAliased returns true if any of the named registers overlap. Arguments set |
| 356 // to NoReg are ignored. The system stack pointer may be specified. | 371 // to NoReg are ignored. The system stack pointer may be specified. |
| 357 bool AreAliased(const CPURegister& reg1, | 372 bool AreAliased(const CPURegister& reg1, |
| 358 const CPURegister& reg2, | 373 const CPURegister& reg2, |
| 359 const CPURegister& reg3 = NoReg, | 374 const CPURegister& reg3 = NoReg, |
| 360 const CPURegister& reg4 = NoReg, | 375 const CPURegister& reg4 = NoReg, |
| 361 const CPURegister& reg5 = NoReg, | 376 const CPURegister& reg5 = NoReg, |
| 362 const CPURegister& reg6 = NoReg, | 377 const CPURegister& reg6 = NoReg, |
| 363 const CPURegister& reg7 = NoReg, | 378 const CPURegister& reg7 = NoReg, |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 unsigned size_; | 505 unsigned size_; |
| 491 CPURegister::RegisterType type_; | 506 CPURegister::RegisterType type_; |
| 492 | 507 |
| 493 bool IsValid() const { | 508 bool IsValid() const { |
| 494 if ((type_ == CPURegister::kRegister) || | 509 if ((type_ == CPURegister::kRegister) || |
| 495 (type_ == CPURegister::kFPRegister)) { | 510 (type_ == CPURegister::kFPRegister)) { |
| 496 bool is_valid = true; | 511 bool is_valid = true; |
| 497 // Try to create a CPURegister for each element in the list. | 512 // Try to create a CPURegister for each element in the list. |
| 498 for (int i = 0; i < kRegListSizeInBits; i++) { | 513 for (int i = 0; i < kRegListSizeInBits; i++) { |
| 499 if (((list_ >> i) & 1) != 0) { | 514 if (((list_ >> i) & 1) != 0) { |
| 500 is_valid &= CPURegister(i, size_, type_).IsValid(); | 515 is_valid &= CPURegister::Create(i, size_, type_).IsValid(); |
| 501 } | 516 } |
| 502 } | 517 } |
| 503 return is_valid; | 518 return is_valid; |
| 504 } else if (type_ == CPURegister::kNoRegister) { | 519 } else if (type_ == CPURegister::kNoRegister) { |
| 505 // The kNoRegister type is valid only for empty lists. | 520 // The kNoRegister type is valid only for empty lists. |
| 506 // We can't use IsEmpty here because that asserts IsValid(). | 521 // We can't use IsEmpty here because that asserts IsValid(). |
| 507 return list_ == 0; | 522 return list_ == 0; |
| 508 } else { | 523 } else { |
| 509 return false; | 524 return false; |
| 510 } | 525 } |
| 511 } | 526 } |
| 512 }; | 527 }; |
| 513 | 528 |
| 514 | 529 |
| 515 // AAPCS64 callee-saved registers. | 530 // AAPCS64 callee-saved registers. |
| 516 extern const CPURegList kCalleeSaved; | 531 #define kCalleeSaved CPURegList::GetCalleeSaved() |
| 517 extern const CPURegList kCalleeSavedFP; | 532 #define kCalleeSavedFP CPURegList::GetCalleeSavedFP() |
| 518 | 533 |
| 519 | 534 |
| 520 // AAPCS64 caller-saved registers. Note that this includes lr. | 535 // AAPCS64 caller-saved registers. Note that this includes lr. |
| 521 extern const CPURegList kCallerSaved; | 536 #define kCallerSaved CPURegList::GetCallerSaved() |
| 522 extern const CPURegList kCallerSavedFP; | 537 #define kCallerSavedFP CPURegList::GetCallerSavedFP() |
| 523 | 538 |
| 524 | 539 |
| 525 // ----------------------------------------------------------------------------- | 540 // ----------------------------------------------------------------------------- |
| 526 // Operands. | 541 // Operands. |
| 527 const int kSmiShift = kSmiTagSize + kSmiShiftSize; | 542 const int kSmiShift = kSmiTagSize + kSmiShiftSize; |
| 528 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; | 543 const uint64_t kSmiShiftMask = (1UL << kSmiShift) - 1; |
| 529 | 544 |
| 530 // Represents an operand in a machine instruction. | 545 // Represents an operand in a machine instruction. |
| 531 class Operand { | 546 class Operand { |
| 532 // TODO(all): If necessary, study more in details which methods | 547 // TODO(all): If necessary, study more in details which methods |
| (...skipping 1501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2034 class EnsureSpace BASE_EMBEDDED { | 2049 class EnsureSpace BASE_EMBEDDED { |
| 2035 public: | 2050 public: |
| 2036 explicit EnsureSpace(Assembler* assembler) { | 2051 explicit EnsureSpace(Assembler* assembler) { |
| 2037 assembler->CheckBuffer(); | 2052 assembler->CheckBuffer(); |
| 2038 } | 2053 } |
| 2039 }; | 2054 }; |
| 2040 | 2055 |
| 2041 } } // namespace v8::internal | 2056 } } // namespace v8::internal |
| 2042 | 2057 |
| 2043 #endif // V8_A64_ASSEMBLER_A64_H_ | 2058 #endif // V8_A64_ASSEMBLER_A64_H_ |
| OLD | NEW |