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 |