| OLD | NEW |
| 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
| 2 // All Rights Reserved. | 2 // All Rights Reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
| 6 // are met: | 6 // are met: |
| 7 // | 7 // |
| 8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
| 9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
| 10 // | 10 // |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 | 107 |
| 108 struct Register { | 108 struct Register { |
| 109 enum Code { | 109 enum Code { |
| 110 #define REGISTER_CODE(R) kCode_##R, | 110 #define REGISTER_CODE(R) kCode_##R, |
| 111 GENERAL_REGISTERS(REGISTER_CODE) | 111 GENERAL_REGISTERS(REGISTER_CODE) |
| 112 #undef REGISTER_CODE | 112 #undef REGISTER_CODE |
| 113 kAfterLast, | 113 kAfterLast, |
| 114 kCode_no_reg = -1 | 114 kCode_no_reg = -1 |
| 115 }; | 115 }; |
| 116 | 116 |
| 117 static const int kNumRegisters = Code::kAfterLast; | 117 static constexpr int kNumRegisters = Code::kAfterLast; |
| 118 | 118 |
| 119 static Register from_code(int code) { | 119 static Register from_code(int code) { |
| 120 DCHECK(code >= 0); | 120 DCHECK(code >= 0); |
| 121 DCHECK(code < kNumRegisters); | 121 DCHECK(code < kNumRegisters); |
| 122 Register r = {code}; | 122 Register r = {code}; |
| 123 return r; | 123 return r; |
| 124 } | 124 } |
| 125 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } | 125 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } |
| 126 bool is(Register reg) const { return reg_code == reg.reg_code; } | 126 bool is(Register reg) const { return reg_code == reg.reg_code; } |
| 127 int code() const { | 127 int code() const { |
| 128 DCHECK(is_valid()); | 128 DCHECK(is_valid()); |
| 129 return reg_code; | 129 return reg_code; |
| 130 } | 130 } |
| 131 int bit() const { | 131 int bit() const { |
| 132 DCHECK(is_valid()); | 132 DCHECK(is_valid()); |
| 133 return 1 << reg_code; | 133 return 1 << reg_code; |
| 134 } | 134 } |
| 135 void set_code(int code) { | 135 void set_code(int code) { |
| 136 reg_code = code; | 136 reg_code = code; |
| 137 DCHECK(is_valid()); | 137 DCHECK(is_valid()); |
| 138 } | 138 } |
| 139 | 139 |
| 140 // Unfortunately we can't make this private in a struct. | 140 // Unfortunately we can't make this private in a struct. |
| 141 int reg_code; | 141 int reg_code; |
| 142 }; | 142 }; |
| 143 | 143 |
| 144 // r7: context register | 144 // r7: context register |
| 145 // r8: constant pool pointer register if FLAG_enable_embedded_constant_pool. | 145 // r8: constant pool pointer register if FLAG_enable_embedded_constant_pool. |
| 146 // r9: lithium scratch | 146 // r9: lithium scratch |
| 147 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; | 147 #define DECLARE_REGISTER(R) constexpr Register R = {Register::kCode_##R}; |
| 148 GENERAL_REGISTERS(DECLARE_REGISTER) | 148 GENERAL_REGISTERS(DECLARE_REGISTER) |
| 149 #undef DECLARE_REGISTER | 149 #undef DECLARE_REGISTER |
| 150 const Register no_reg = {Register::kCode_no_reg}; | 150 constexpr Register no_reg = {Register::kCode_no_reg}; |
| 151 | 151 |
| 152 static const bool kSimpleFPAliasing = false; | 152 constexpr bool kSimpleFPAliasing = false; |
| 153 static const bool kSimdMaskRegisters = false; | 153 constexpr bool kSimdMaskRegisters = false; |
| 154 | 154 |
| 155 // Single word VFP register. | 155 // Single word VFP register. |
| 156 struct SwVfpRegister { | 156 struct SwVfpRegister { |
| 157 enum Code { | 157 enum Code { |
| 158 #define REGISTER_CODE(R) kCode_##R, | 158 #define REGISTER_CODE(R) kCode_##R, |
| 159 FLOAT_REGISTERS(REGISTER_CODE) | 159 FLOAT_REGISTERS(REGISTER_CODE) |
| 160 #undef REGISTER_CODE | 160 #undef REGISTER_CODE |
| 161 kAfterLast, | 161 kAfterLast, |
| 162 kCode_no_reg = -1 | 162 kCode_no_reg = -1 |
| 163 }; | 163 }; |
| 164 | 164 |
| 165 static const int kMaxNumRegisters = Code::kAfterLast; | 165 static constexpr int kMaxNumRegisters = Code::kAfterLast; |
| 166 | 166 |
| 167 static const int kSizeInBytes = 4; | 167 static constexpr int kSizeInBytes = 4; |
| 168 | 168 |
| 169 bool is_valid() const { return 0 <= reg_code && reg_code < 32; } | 169 bool is_valid() const { return 0 <= reg_code && reg_code < 32; } |
| 170 bool is(SwVfpRegister reg) const { return reg_code == reg.reg_code; } | 170 bool is(SwVfpRegister reg) const { return reg_code == reg.reg_code; } |
| 171 int code() const { | 171 int code() const { |
| 172 DCHECK(is_valid()); | 172 DCHECK(is_valid()); |
| 173 return reg_code; | 173 return reg_code; |
| 174 } | 174 } |
| 175 int bit() const { | 175 int bit() const { |
| 176 DCHECK(is_valid()); | 176 DCHECK(is_valid()); |
| 177 return 1 << reg_code; | 177 return 1 << reg_code; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 194 // Double word VFP register. | 194 // Double word VFP register. |
| 195 struct DwVfpRegister { | 195 struct DwVfpRegister { |
| 196 enum Code { | 196 enum Code { |
| 197 #define REGISTER_CODE(R) kCode_##R, | 197 #define REGISTER_CODE(R) kCode_##R, |
| 198 DOUBLE_REGISTERS(REGISTER_CODE) | 198 DOUBLE_REGISTERS(REGISTER_CODE) |
| 199 #undef REGISTER_CODE | 199 #undef REGISTER_CODE |
| 200 kAfterLast, | 200 kAfterLast, |
| 201 kCode_no_reg = -1 | 201 kCode_no_reg = -1 |
| 202 }; | 202 }; |
| 203 | 203 |
| 204 static const int kMaxNumRegisters = Code::kAfterLast; | 204 static constexpr int kMaxNumRegisters = Code::kAfterLast; |
| 205 | 205 |
| 206 inline static int NumRegisters(); | 206 inline static int NumRegisters(); |
| 207 | 207 |
| 208 // A few double registers are reserved: one as a scratch register and one to | 208 // A few double registers are reserved: one as a scratch register and one to |
| 209 // hold 0.0, that does not fit in the immediate field of vmov instructions. | 209 // hold 0.0, that does not fit in the immediate field of vmov instructions. |
| 210 // d14: 0.0 | 210 // d14: 0.0 |
| 211 // d15: scratch register. | 211 // d15: scratch register. |
| 212 static const int kSizeInBytes = 8; | 212 static constexpr int kSizeInBytes = 8; |
| 213 | 213 |
| 214 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } | 214 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } |
| 215 bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; } | 215 bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; } |
| 216 int code() const { | 216 int code() const { |
| 217 DCHECK(is_valid()); | 217 DCHECK(is_valid()); |
| 218 return reg_code; | 218 return reg_code; |
| 219 } | 219 } |
| 220 int bit() const { | 220 int bit() const { |
| 221 DCHECK(is_valid()); | 221 DCHECK(is_valid()); |
| 222 return 1 << reg_code; | 222 return 1 << reg_code; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 235 int reg_code; | 235 int reg_code; |
| 236 }; | 236 }; |
| 237 | 237 |
| 238 | 238 |
| 239 typedef DwVfpRegister DoubleRegister; | 239 typedef DwVfpRegister DoubleRegister; |
| 240 | 240 |
| 241 | 241 |
| 242 // Double word VFP register d0-15. | 242 // Double word VFP register d0-15. |
| 243 struct LowDwVfpRegister { | 243 struct LowDwVfpRegister { |
| 244 public: | 244 public: |
| 245 static const int kMaxNumLowRegisters = 16; | 245 static constexpr int kMaxNumLowRegisters = 16; |
| 246 operator DwVfpRegister() const { | 246 constexpr operator DwVfpRegister() const { |
| 247 DwVfpRegister r = { reg_code }; | 247 return DwVfpRegister { reg_code }; |
| 248 return r; | |
| 249 } | 248 } |
| 250 static LowDwVfpRegister from_code(int code) { | 249 static LowDwVfpRegister from_code(int code) { |
| 251 LowDwVfpRegister r = { code }; | 250 LowDwVfpRegister r = { code }; |
| 252 return r; | 251 return r; |
| 253 } | 252 } |
| 254 | 253 |
| 255 bool is_valid() const { | 254 bool is_valid() const { |
| 256 return 0 <= reg_code && reg_code < kMaxNumLowRegisters; | 255 return 0 <= reg_code && reg_code < kMaxNumLowRegisters; |
| 257 } | 256 } |
| 258 bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; } | 257 bool is(DwVfpRegister reg) const { return reg_code == reg.reg_code; } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 275 DCHECK(reg.is_valid()); | 274 DCHECK(reg.is_valid()); |
| 276 return reg; | 275 return reg; |
| 277 } | 276 } |
| 278 | 277 |
| 279 int reg_code; | 278 int reg_code; |
| 280 }; | 279 }; |
| 281 | 280 |
| 282 | 281 |
| 283 // Quad word NEON register. | 282 // Quad word NEON register. |
| 284 struct QwNeonRegister { | 283 struct QwNeonRegister { |
| 285 static const int kMaxNumRegisters = 16; | 284 static constexpr int kMaxNumRegisters = 16; |
| 286 | 285 |
| 287 static QwNeonRegister from_code(int code) { | 286 static QwNeonRegister from_code(int code) { |
| 288 QwNeonRegister r = { code }; | 287 QwNeonRegister r = { code }; |
| 289 return r; | 288 return r; |
| 290 } | 289 } |
| 291 | 290 |
| 292 bool is_valid() const { | 291 bool is_valid() const { |
| 293 return (0 <= reg_code) && (reg_code < kMaxNumRegisters); | 292 return (0 <= reg_code) && (reg_code < kMaxNumRegisters); |
| 294 } | 293 } |
| 295 bool is(QwNeonRegister reg) const { return reg_code == reg.reg_code; } | 294 bool is(QwNeonRegister reg) const { return reg_code == reg.reg_code; } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 321 int reg_code; | 320 int reg_code; |
| 322 }; | 321 }; |
| 323 | 322 |
| 324 | 323 |
| 325 typedef QwNeonRegister QuadRegister; | 324 typedef QwNeonRegister QuadRegister; |
| 326 | 325 |
| 327 typedef QwNeonRegister Simd128Register; | 326 typedef QwNeonRegister Simd128Register; |
| 328 | 327 |
| 329 // Support for the VFP registers s0 to s31 (d0 to d15). | 328 // Support for the VFP registers s0 to s31 (d0 to d15). |
| 330 // Note that "s(N):s(N+1)" is the same as "d(N/2)". | 329 // Note that "s(N):s(N+1)" is the same as "d(N/2)". |
| 331 const SwVfpRegister s0 = { 0 }; | 330 constexpr SwVfpRegister s0 = { 0 }; |
| 332 const SwVfpRegister s1 = { 1 }; | 331 constexpr SwVfpRegister s1 = { 1 }; |
| 333 const SwVfpRegister s2 = { 2 }; | 332 constexpr SwVfpRegister s2 = { 2 }; |
| 334 const SwVfpRegister s3 = { 3 }; | 333 constexpr SwVfpRegister s3 = { 3 }; |
| 335 const SwVfpRegister s4 = { 4 }; | 334 constexpr SwVfpRegister s4 = { 4 }; |
| 336 const SwVfpRegister s5 = { 5 }; | 335 constexpr SwVfpRegister s5 = { 5 }; |
| 337 const SwVfpRegister s6 = { 6 }; | 336 constexpr SwVfpRegister s6 = { 6 }; |
| 338 const SwVfpRegister s7 = { 7 }; | 337 constexpr SwVfpRegister s7 = { 7 }; |
| 339 const SwVfpRegister s8 = { 8 }; | 338 constexpr SwVfpRegister s8 = { 8 }; |
| 340 const SwVfpRegister s9 = { 9 }; | 339 constexpr SwVfpRegister s9 = { 9 }; |
| 341 const SwVfpRegister s10 = { 10 }; | 340 constexpr SwVfpRegister s10 = { 10 }; |
| 342 const SwVfpRegister s11 = { 11 }; | 341 constexpr SwVfpRegister s11 = { 11 }; |
| 343 const SwVfpRegister s12 = { 12 }; | 342 constexpr SwVfpRegister s12 = { 12 }; |
| 344 const SwVfpRegister s13 = { 13 }; | 343 constexpr SwVfpRegister s13 = { 13 }; |
| 345 const SwVfpRegister s14 = { 14 }; | 344 constexpr SwVfpRegister s14 = { 14 }; |
| 346 const SwVfpRegister s15 = { 15 }; | 345 constexpr SwVfpRegister s15 = { 15 }; |
| 347 const SwVfpRegister s16 = { 16 }; | 346 constexpr SwVfpRegister s16 = { 16 }; |
| 348 const SwVfpRegister s17 = { 17 }; | 347 constexpr SwVfpRegister s17 = { 17 }; |
| 349 const SwVfpRegister s18 = { 18 }; | 348 constexpr SwVfpRegister s18 = { 18 }; |
| 350 const SwVfpRegister s19 = { 19 }; | 349 constexpr SwVfpRegister s19 = { 19 }; |
| 351 const SwVfpRegister s20 = { 20 }; | 350 constexpr SwVfpRegister s20 = { 20 }; |
| 352 const SwVfpRegister s21 = { 21 }; | 351 constexpr SwVfpRegister s21 = { 21 }; |
| 353 const SwVfpRegister s22 = { 22 }; | 352 constexpr SwVfpRegister s22 = { 22 }; |
| 354 const SwVfpRegister s23 = { 23 }; | 353 constexpr SwVfpRegister s23 = { 23 }; |
| 355 const SwVfpRegister s24 = { 24 }; | 354 constexpr SwVfpRegister s24 = { 24 }; |
| 356 const SwVfpRegister s25 = { 25 }; | 355 constexpr SwVfpRegister s25 = { 25 }; |
| 357 const SwVfpRegister s26 = { 26 }; | 356 constexpr SwVfpRegister s26 = { 26 }; |
| 358 const SwVfpRegister s27 = { 27 }; | 357 constexpr SwVfpRegister s27 = { 27 }; |
| 359 const SwVfpRegister s28 = { 28 }; | 358 constexpr SwVfpRegister s28 = { 28 }; |
| 360 const SwVfpRegister s29 = { 29 }; | 359 constexpr SwVfpRegister s29 = { 29 }; |
| 361 const SwVfpRegister s30 = { 30 }; | 360 constexpr SwVfpRegister s30 = { 30 }; |
| 362 const SwVfpRegister s31 = { 31 }; | 361 constexpr SwVfpRegister s31 = { 31 }; |
| 363 | 362 |
| 364 const DwVfpRegister no_dreg = { -1 }; | 363 constexpr DwVfpRegister no_dreg = { -1 }; |
| 365 const LowDwVfpRegister d0 = { 0 }; | 364 constexpr LowDwVfpRegister d0 = { 0 }; |
| 366 const LowDwVfpRegister d1 = { 1 }; | 365 constexpr LowDwVfpRegister d1 = { 1 }; |
| 367 const LowDwVfpRegister d2 = { 2 }; | 366 constexpr LowDwVfpRegister d2 = { 2 }; |
| 368 const LowDwVfpRegister d3 = { 3 }; | 367 constexpr LowDwVfpRegister d3 = { 3 }; |
| 369 const LowDwVfpRegister d4 = { 4 }; | 368 constexpr LowDwVfpRegister d4 = { 4 }; |
| 370 const LowDwVfpRegister d5 = { 5 }; | 369 constexpr LowDwVfpRegister d5 = { 5 }; |
| 371 const LowDwVfpRegister d6 = { 6 }; | 370 constexpr LowDwVfpRegister d6 = { 6 }; |
| 372 const LowDwVfpRegister d7 = { 7 }; | 371 constexpr LowDwVfpRegister d7 = { 7 }; |
| 373 const LowDwVfpRegister d8 = { 8 }; | 372 constexpr LowDwVfpRegister d8 = { 8 }; |
| 374 const LowDwVfpRegister d9 = { 9 }; | 373 constexpr LowDwVfpRegister d9 = { 9 }; |
| 375 const LowDwVfpRegister d10 = { 10 }; | 374 constexpr LowDwVfpRegister d10 = { 10 }; |
| 376 const LowDwVfpRegister d11 = { 11 }; | 375 constexpr LowDwVfpRegister d11 = { 11 }; |
| 377 const LowDwVfpRegister d12 = { 12 }; | 376 constexpr LowDwVfpRegister d12 = { 12 }; |
| 378 const LowDwVfpRegister d13 = { 13 }; | 377 constexpr LowDwVfpRegister d13 = { 13 }; |
| 379 const LowDwVfpRegister d14 = { 14 }; | 378 constexpr LowDwVfpRegister d14 = { 14 }; |
| 380 const LowDwVfpRegister d15 = { 15 }; | 379 constexpr LowDwVfpRegister d15 = { 15 }; |
| 381 const DwVfpRegister d16 = { 16 }; | 380 constexpr DwVfpRegister d16 = { 16 }; |
| 382 const DwVfpRegister d17 = { 17 }; | 381 constexpr DwVfpRegister d17 = { 17 }; |
| 383 const DwVfpRegister d18 = { 18 }; | 382 constexpr DwVfpRegister d18 = { 18 }; |
| 384 const DwVfpRegister d19 = { 19 }; | 383 constexpr DwVfpRegister d19 = { 19 }; |
| 385 const DwVfpRegister d20 = { 20 }; | 384 constexpr DwVfpRegister d20 = { 20 }; |
| 386 const DwVfpRegister d21 = { 21 }; | 385 constexpr DwVfpRegister d21 = { 21 }; |
| 387 const DwVfpRegister d22 = { 22 }; | 386 constexpr DwVfpRegister d22 = { 22 }; |
| 388 const DwVfpRegister d23 = { 23 }; | 387 constexpr DwVfpRegister d23 = { 23 }; |
| 389 const DwVfpRegister d24 = { 24 }; | 388 constexpr DwVfpRegister d24 = { 24 }; |
| 390 const DwVfpRegister d25 = { 25 }; | 389 constexpr DwVfpRegister d25 = { 25 }; |
| 391 const DwVfpRegister d26 = { 26 }; | 390 constexpr DwVfpRegister d26 = { 26 }; |
| 392 const DwVfpRegister d27 = { 27 }; | 391 constexpr DwVfpRegister d27 = { 27 }; |
| 393 const DwVfpRegister d28 = { 28 }; | 392 constexpr DwVfpRegister d28 = { 28 }; |
| 394 const DwVfpRegister d29 = { 29 }; | 393 constexpr DwVfpRegister d29 = { 29 }; |
| 395 const DwVfpRegister d30 = { 30 }; | 394 constexpr DwVfpRegister d30 = { 30 }; |
| 396 const DwVfpRegister d31 = { 31 }; | 395 constexpr DwVfpRegister d31 = { 31 }; |
| 397 | 396 |
| 398 const QwNeonRegister q0 = { 0 }; | 397 constexpr QwNeonRegister q0 = { 0 }; |
| 399 const QwNeonRegister q1 = { 1 }; | 398 constexpr QwNeonRegister q1 = { 1 }; |
| 400 const QwNeonRegister q2 = { 2 }; | 399 constexpr QwNeonRegister q2 = { 2 }; |
| 401 const QwNeonRegister q3 = { 3 }; | 400 constexpr QwNeonRegister q3 = { 3 }; |
| 402 const QwNeonRegister q4 = { 4 }; | 401 constexpr QwNeonRegister q4 = { 4 }; |
| 403 const QwNeonRegister q5 = { 5 }; | 402 constexpr QwNeonRegister q5 = { 5 }; |
| 404 const QwNeonRegister q6 = { 6 }; | 403 constexpr QwNeonRegister q6 = { 6 }; |
| 405 const QwNeonRegister q7 = { 7 }; | 404 constexpr QwNeonRegister q7 = { 7 }; |
| 406 const QwNeonRegister q8 = { 8 }; | 405 constexpr QwNeonRegister q8 = { 8 }; |
| 407 const QwNeonRegister q9 = { 9 }; | 406 constexpr QwNeonRegister q9 = { 9 }; |
| 408 const QwNeonRegister q10 = { 10 }; | 407 constexpr QwNeonRegister q10 = { 10 }; |
| 409 const QwNeonRegister q11 = { 11 }; | 408 constexpr QwNeonRegister q11 = { 11 }; |
| 410 const QwNeonRegister q12 = { 12 }; | 409 constexpr QwNeonRegister q12 = { 12 }; |
| 411 const QwNeonRegister q13 = { 13 }; | 410 constexpr QwNeonRegister q13 = { 13 }; |
| 412 const QwNeonRegister q14 = { 14 }; | 411 constexpr QwNeonRegister q14 = { 14 }; |
| 413 const QwNeonRegister q15 = { 15 }; | 412 constexpr QwNeonRegister q15 = { 15 }; |
| 414 | 413 |
| 415 | 414 |
| 416 // Aliases for double registers. Defined using #define instead of | 415 // Aliases for double registers. |
| 417 // "static const DwVfpRegister&" because Clang complains otherwise when a | 416 constexpr LowDwVfpRegister kFirstCalleeSavedDoubleReg = d8; |
| 418 // compilation unit that includes this header doesn't use the variables. | 417 constexpr LowDwVfpRegister kLastCalleeSavedDoubleReg = d15; |
| 419 #define kFirstCalleeSavedDoubleReg d8 | |
| 420 #define kLastCalleeSavedDoubleReg d15 | |
| 421 // kDoubleRegZero and kScratchDoubleReg must pair to form kScratchQuadReg. SIMD | 418 // kDoubleRegZero and kScratchDoubleReg must pair to form kScratchQuadReg. SIMD |
| 422 // code depends on kDoubleRegZero before kScratchDoubleReg. | 419 // code depends on kDoubleRegZero before kScratchDoubleReg. |
| 423 #define kDoubleRegZero d14 | 420 constexpr LowDwVfpRegister kDoubleRegZero = d14; |
| 424 #define kScratchDoubleReg d15 | 421 constexpr LowDwVfpRegister kScratchDoubleReg = d15; |
| 425 // After using kScratchQuadReg, kDoubleRegZero must be reset to 0. | 422 // After using kScratchQuadReg, kDoubleRegZero must be reset to 0. |
| 426 #define kScratchQuadReg q7 | 423 constexpr QwNeonRegister kScratchQuadReg = q7; |
| 427 | 424 |
| 428 // Coprocessor register | 425 // Coprocessor register |
| 429 struct CRegister { | 426 struct CRegister { |
| 430 bool is_valid() const { return 0 <= reg_code && reg_code < 16; } | 427 bool is_valid() const { return 0 <= reg_code && reg_code < 16; } |
| 431 bool is(CRegister creg) const { return reg_code == creg.reg_code; } | 428 bool is(CRegister creg) const { return reg_code == creg.reg_code; } |
| 432 int code() const { | 429 int code() const { |
| 433 DCHECK(is_valid()); | 430 DCHECK(is_valid()); |
| 434 return reg_code; | 431 return reg_code; |
| 435 } | 432 } |
| 436 int bit() const { | 433 int bit() const { |
| 437 DCHECK(is_valid()); | 434 DCHECK(is_valid()); |
| 438 return 1 << reg_code; | 435 return 1 << reg_code; |
| 439 } | 436 } |
| 440 | 437 |
| 441 // Unfortunately we can't make this private in a struct. | 438 // Unfortunately we can't make this private in a struct. |
| 442 int reg_code; | 439 int reg_code; |
| 443 }; | 440 }; |
| 444 | 441 |
| 445 | 442 |
| 446 const CRegister no_creg = { -1 }; | 443 constexpr CRegister no_creg = { -1 }; |
| 447 | 444 |
| 448 const CRegister cr0 = { 0 }; | 445 constexpr CRegister cr0 = { 0 }; |
| 449 const CRegister cr1 = { 1 }; | 446 constexpr CRegister cr1 = { 1 }; |
| 450 const CRegister cr2 = { 2 }; | 447 constexpr CRegister cr2 = { 2 }; |
| 451 const CRegister cr3 = { 3 }; | 448 constexpr CRegister cr3 = { 3 }; |
| 452 const CRegister cr4 = { 4 }; | 449 constexpr CRegister cr4 = { 4 }; |
| 453 const CRegister cr5 = { 5 }; | 450 constexpr CRegister cr5 = { 5 }; |
| 454 const CRegister cr6 = { 6 }; | 451 constexpr CRegister cr6 = { 6 }; |
| 455 const CRegister cr7 = { 7 }; | 452 constexpr CRegister cr7 = { 7 }; |
| 456 const CRegister cr8 = { 8 }; | 453 constexpr CRegister cr8 = { 8 }; |
| 457 const CRegister cr9 = { 9 }; | 454 constexpr CRegister cr9 = { 9 }; |
| 458 const CRegister cr10 = { 10 }; | 455 constexpr CRegister cr10 = { 10 }; |
| 459 const CRegister cr11 = { 11 }; | 456 constexpr CRegister cr11 = { 11 }; |
| 460 const CRegister cr12 = { 12 }; | 457 constexpr CRegister cr12 = { 12 }; |
| 461 const CRegister cr13 = { 13 }; | 458 constexpr CRegister cr13 = { 13 }; |
| 462 const CRegister cr14 = { 14 }; | 459 constexpr CRegister cr14 = { 14 }; |
| 463 const CRegister cr15 = { 15 }; | 460 constexpr CRegister cr15 = { 15 }; |
| 464 | 461 |
| 465 | 462 |
| 466 // Coprocessor number | 463 // Coprocessor number |
| 467 enum Coprocessor { | 464 enum Coprocessor { |
| 468 p0 = 0, | 465 p0 = 0, |
| 469 p1 = 1, | 466 p1 = 1, |
| 470 p2 = 2, | 467 p2 = 2, |
| 471 p3 = 3, | 468 p3 = 3, |
| 472 p4 = 4, | 469 p4 = 4, |
| 473 p5 = 5, | 470 p5 = 5, |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 } | 661 } |
| 665 private: | 662 private: |
| 666 DoubleRegister base_; | 663 DoubleRegister base_; |
| 667 int register_count_; | 664 int register_count_; |
| 668 }; | 665 }; |
| 669 | 666 |
| 670 | 667 |
| 671 struct VmovIndex { | 668 struct VmovIndex { |
| 672 unsigned char index; | 669 unsigned char index; |
| 673 }; | 670 }; |
| 674 const VmovIndex VmovIndexLo = { 0 }; | 671 constexpr VmovIndex VmovIndexLo = { 0 }; |
| 675 const VmovIndex VmovIndexHi = { 1 }; | 672 constexpr VmovIndex VmovIndexHi = { 1 }; |
| 676 | 673 |
| 677 class Assembler : public AssemblerBase { | 674 class Assembler : public AssemblerBase { |
| 678 public: | 675 public: |
| 679 // Create an assembler. Instructions and relocation information are emitted | 676 // Create an assembler. Instructions and relocation information are emitted |
| 680 // into a buffer, with the instructions starting from the beginning and the | 677 // into a buffer, with the instructions starting from the beginning and the |
| 681 // relocation information starting from the end of the buffer. See CodeDesc | 678 // relocation information starting from the end of the buffer. See CodeDesc |
| 682 // for a detailed comment on the layout (globals.h). | 679 // for a detailed comment on the layout (globals.h). |
| 683 // | 680 // |
| 684 // If the provided buffer is NULL, the assembler allocates and grows its own | 681 // If the provided buffer is NULL, the assembler allocates and grows its own |
| 685 // buffer, and buffer_size determines the initial buffer size. The buffer is | 682 // buffer, and buffer_size determines the initial buffer size. The buffer is |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 Address target); | 750 Address target); |
| 754 | 751 |
| 755 // This sets the internal reference at the pc. | 752 // This sets the internal reference at the pc. |
| 756 inline static void deserialization_set_target_internal_reference_at( | 753 inline static void deserialization_set_target_internal_reference_at( |
| 757 Isolate* isolate, Address pc, Address target, | 754 Isolate* isolate, Address pc, Address target, |
| 758 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); | 755 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); |
| 759 | 756 |
| 760 // Here we are patching the address in the constant pool, not the actual call | 757 // Here we are patching the address in the constant pool, not the actual call |
| 761 // instruction. The address in the constant pool is the same size as a | 758 // instruction. The address in the constant pool is the same size as a |
| 762 // pointer. | 759 // pointer. |
| 763 static const int kSpecialTargetSize = kPointerSize; | 760 static constexpr int kSpecialTargetSize = kPointerSize; |
| 764 | 761 |
| 765 // Size of an instruction. | 762 // Size of an instruction. |
| 766 static const int kInstrSize = sizeof(Instr); | 763 static constexpr int kInstrSize = sizeof(Instr); |
| 767 | 764 |
| 768 // Distance between start of patched debug break slot and the emitted address | 765 // Distance between start of patched debug break slot and the emitted address |
| 769 // to jump to. | 766 // to jump to. |
| 770 // Patched debug break slot code is: | 767 // Patched debug break slot code is: |
| 771 // ldr ip, [pc, #0] @ emited address and start | 768 // ldr ip, [pc, #0] @ emited address and start |
| 772 // blx ip | 769 // blx ip |
| 773 static const int kPatchDebugBreakSlotAddressOffset = 2 * kInstrSize; | 770 static constexpr int kPatchDebugBreakSlotAddressOffset = 2 * kInstrSize; |
| 774 | 771 |
| 775 // Difference between address of current opcode and value read from pc | 772 // Difference between address of current opcode and value read from pc |
| 776 // register. | 773 // register. |
| 777 static const int kPcLoadDelta = 8; | 774 static constexpr int kPcLoadDelta = 8; |
| 778 | 775 |
| 779 static const int kDebugBreakSlotInstructions = 4; | 776 static constexpr int kDebugBreakSlotInstructions = 4; |
| 780 static const int kDebugBreakSlotLength = | 777 static constexpr int kDebugBreakSlotLength = |
| 781 kDebugBreakSlotInstructions * kInstrSize; | 778 kDebugBreakSlotInstructions * kInstrSize; |
| 782 | 779 |
| 783 // --------------------------------------------------------------------------- | 780 // --------------------------------------------------------------------------- |
| 784 // Code generation | 781 // Code generation |
| 785 | 782 |
| 786 // Insert the smallest number of nop instructions | 783 // Insert the smallest number of nop instructions |
| 787 // possible to align the pc offset to a multiple | 784 // possible to align the pc offset to a multiple |
| 788 // of m. m must be a power of 2 (>= 4). | 785 // of m. m must be a power of 2 (>= 4). |
| 789 void Align(int m); | 786 void Align(int m); |
| 790 // Insert the smallest number of zero bytes possible to align the pc offset | 787 // Insert the smallest number of zero bytes possible to align the pc offset |
| (...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1585 static Instr GetMovWPattern(); | 1582 static Instr GetMovWPattern(); |
| 1586 static Instr EncodeMovwImmediate(uint32_t immediate); | 1583 static Instr EncodeMovwImmediate(uint32_t immediate); |
| 1587 static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate); | 1584 static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate); |
| 1588 static int DecodeShiftImm(Instr instr); | 1585 static int DecodeShiftImm(Instr instr); |
| 1589 static Instr PatchShiftImm(Instr instr, int immed); | 1586 static Instr PatchShiftImm(Instr instr, int immed); |
| 1590 | 1587 |
| 1591 // Constants in pools are accessed via pc relative addressing, which can | 1588 // Constants in pools are accessed via pc relative addressing, which can |
| 1592 // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point | 1589 // reach +/-4KB for integer PC-relative loads and +/-1KB for floating-point |
| 1593 // PC-relative loads, thereby defining a maximum distance between the | 1590 // PC-relative loads, thereby defining a maximum distance between the |
| 1594 // instruction and the accessed constant. | 1591 // instruction and the accessed constant. |
| 1595 static const int kMaxDistToIntPool = 4*KB; | 1592 static constexpr int kMaxDistToIntPool = 4 * KB; |
| 1596 static const int kMaxDistToFPPool = 1*KB; | 1593 static constexpr int kMaxDistToFPPool = 1 * KB; |
| 1597 // All relocations could be integer, it therefore acts as the limit. | 1594 // All relocations could be integer, it therefore acts as the limit. |
| 1598 static const int kMinNumPendingConstants = 4; | 1595 static constexpr int kMinNumPendingConstants = 4; |
| 1599 static const int kMaxNumPending32Constants = kMaxDistToIntPool / kInstrSize; | 1596 static constexpr int kMaxNumPending32Constants = |
| 1600 static const int kMaxNumPending64Constants = kMaxDistToFPPool / kInstrSize; | 1597 kMaxDistToIntPool / kInstrSize; |
| 1598 static constexpr int kMaxNumPending64Constants = |
| 1599 kMaxDistToFPPool / kInstrSize; |
| 1601 | 1600 |
| 1602 // Postpone the generation of the constant pool for the specified number of | 1601 // Postpone the generation of the constant pool for the specified number of |
| 1603 // instructions. | 1602 // instructions. |
| 1604 void BlockConstPoolFor(int instructions); | 1603 void BlockConstPoolFor(int instructions); |
| 1605 | 1604 |
| 1606 // Check if is time to emit a constant pool. | 1605 // Check if is time to emit a constant pool. |
| 1607 void CheckConstPool(bool force_emit, bool require_jump); | 1606 void CheckConstPool(bool force_emit, bool require_jump); |
| 1608 | 1607 |
| 1609 void MaybeCheckConstPool() { | 1608 void MaybeCheckConstPool() { |
| 1610 if (pc_offset() >= next_buffer_check_) { | 1609 if (pc_offset() >= next_buffer_check_) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1693 } | 1692 } |
| 1694 | 1693 |
| 1695 private: | 1694 private: |
| 1696 int next_buffer_check_; // pc offset of next buffer check | 1695 int next_buffer_check_; // pc offset of next buffer check |
| 1697 | 1696 |
| 1698 // Code generation | 1697 // Code generation |
| 1699 // The relocation writer's position is at least kGap bytes below the end of | 1698 // The relocation writer's position is at least kGap bytes below the end of |
| 1700 // the generated instructions. This is so that multi-instruction sequences do | 1699 // the generated instructions. This is so that multi-instruction sequences do |
| 1701 // not have to check for overflow. The same is true for writes of large | 1700 // not have to check for overflow. The same is true for writes of large |
| 1702 // relocation info entries. | 1701 // relocation info entries. |
| 1703 static const int kGap = 32; | 1702 static constexpr int kGap = 32; |
| 1704 | 1703 |
| 1705 // Constant pool generation | 1704 // Constant pool generation |
| 1706 // Pools are emitted in the instruction stream, preferably after unconditional | 1705 // Pools are emitted in the instruction stream, preferably after unconditional |
| 1707 // jumps or after returns from functions (in dead code locations). | 1706 // jumps or after returns from functions (in dead code locations). |
| 1708 // If a long code sequence does not contain unconditional jumps, it is | 1707 // If a long code sequence does not contain unconditional jumps, it is |
| 1709 // necessary to emit the constant pool before the pool gets too far from the | 1708 // necessary to emit the constant pool before the pool gets too far from the |
| 1710 // location it is accessed from. In this case, we emit a jump over the emitted | 1709 // location it is accessed from. In this case, we emit a jump over the emitted |
| 1711 // constant pool. | 1710 // constant pool. |
| 1712 // Constants in the pool may be addresses of functions that gets relocated; | 1711 // Constants in the pool may be addresses of functions that gets relocated; |
| 1713 // if so, a relocation info entry is associated to the constant pool entry. | 1712 // if so, a relocation info entry is associated to the constant pool entry. |
| 1714 | 1713 |
| 1715 // Repeated checking whether the constant pool should be emitted is rather | 1714 // Repeated checking whether the constant pool should be emitted is rather |
| 1716 // expensive. By default we only check again once a number of instructions | 1715 // expensive. By default we only check again once a number of instructions |
| 1717 // has been generated. That also means that the sizing of the buffers is not | 1716 // has been generated. That also means that the sizing of the buffers is not |
| 1718 // an exact science, and that we rely on some slop to not overrun buffers. | 1717 // an exact science, and that we rely on some slop to not overrun buffers. |
| 1719 static const int kCheckPoolIntervalInst = 32; | 1718 static constexpr int kCheckPoolIntervalInst = 32; |
| 1720 static const int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize; | 1719 static constexpr int kCheckPoolInterval = kCheckPoolIntervalInst * kInstrSize; |
| 1721 | 1720 |
| 1722 | 1721 |
| 1723 // Emission of the constant pool may be blocked in some code sequences. | 1722 // Emission of the constant pool may be blocked in some code sequences. |
| 1724 int const_pool_blocked_nesting_; // Block emission if this is not zero. | 1723 int const_pool_blocked_nesting_; // Block emission if this is not zero. |
| 1725 int no_const_pool_before_; // Block emission before this pc offset. | 1724 int no_const_pool_before_; // Block emission before this pc offset. |
| 1726 | 1725 |
| 1727 // Keep track of the first instruction requiring a constant pool entry | 1726 // Keep track of the first instruction requiring a constant pool entry |
| 1728 // since the previous constant pool was emitted. | 1727 // since the previous constant pool was emitted. |
| 1729 int first_const_pool_32_use_; | 1728 int first_const_pool_32_use_; |
| 1730 int first_const_pool_64_use_; | 1729 int first_const_pool_64_use_; |
| 1731 | 1730 |
| 1732 // Relocation info generation | 1731 // Relocation info generation |
| 1733 // Each relocation is encoded as a variable size value | 1732 // Each relocation is encoded as a variable size value |
| 1734 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; | 1733 static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize; |
| 1735 RelocInfoWriter reloc_info_writer; | 1734 RelocInfoWriter reloc_info_writer; |
| 1736 | 1735 |
| 1737 // ConstantPoolEntry records are used during code generation as temporary | 1736 // ConstantPoolEntry records are used during code generation as temporary |
| 1738 // containers for constants and code target addresses until they are emitted | 1737 // containers for constants and code target addresses until they are emitted |
| 1739 // to the constant pool. These records are temporarily stored in a separate | 1738 // to the constant pool. These records are temporarily stored in a separate |
| 1740 // buffer until a constant pool is emitted. | 1739 // buffer until a constant pool is emitted. |
| 1741 // If every instruction in a long sequence is accessing the pool, we need one | 1740 // If every instruction in a long sequence is accessing the pool, we need one |
| 1742 // pending relocation entry per instruction. | 1741 // pending relocation entry per instruction. |
| 1743 | 1742 |
| 1744 // The buffers of pending constant pool entries. | 1743 // The buffers of pending constant pool entries. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1778 RelocInfo::Mode rmode, | 1777 RelocInfo::Mode rmode, |
| 1779 intptr_t value); | 1778 intptr_t value); |
| 1780 ConstantPoolEntry::Access ConstantPoolAddEntry(int position, double value); | 1779 ConstantPoolEntry::Access ConstantPoolAddEntry(int position, double value); |
| 1781 | 1780 |
| 1782 friend class RelocInfo; | 1781 friend class RelocInfo; |
| 1783 friend class CodePatcher; | 1782 friend class CodePatcher; |
| 1784 friend class BlockConstPoolScope; | 1783 friend class BlockConstPoolScope; |
| 1785 friend class EnsureSpace; | 1784 friend class EnsureSpace; |
| 1786 }; | 1785 }; |
| 1787 | 1786 |
| 1788 static const int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize; | 1787 constexpr int kNoCodeAgeSequenceLength = 3 * Assembler::kInstrSize; |
| 1789 | 1788 |
| 1790 class EnsureSpace BASE_EMBEDDED { | 1789 class EnsureSpace BASE_EMBEDDED { |
| 1791 public: | 1790 public: |
| 1792 INLINE(explicit EnsureSpace(Assembler* assembler)); | 1791 INLINE(explicit EnsureSpace(Assembler* assembler)); |
| 1793 }; | 1792 }; |
| 1794 | 1793 |
| 1795 | 1794 |
| 1796 } // namespace internal | 1795 } // namespace internal |
| 1797 } // namespace v8 | 1796 } // namespace v8 |
| 1798 | 1797 |
| 1799 #endif // V8_ARM_ASSEMBLER_ARM_H_ | 1798 #endif // V8_ARM_ASSEMBLER_ARM_H_ |
| OLD | NEW |