Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Side by Side Diff: src/s390/assembler-s390.h

Issue 2733323003: PPC/s390: [assembler] Make register definitions constexpr (Closed)
Patch Set: addressed comments Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ppc/assembler-ppc.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 // and best performance in optimized code. 120 // and best performance in optimized code.
121 121
122 struct Register { 122 struct Register {
123 enum Code { 123 enum Code {
124 #define REGISTER_CODE(R) kCode_##R, 124 #define REGISTER_CODE(R) kCode_##R,
125 GENERAL_REGISTERS(REGISTER_CODE) 125 GENERAL_REGISTERS(REGISTER_CODE)
126 #undef REGISTER_CODE 126 #undef REGISTER_CODE
127 kAfterLast, 127 kAfterLast,
128 kCode_no_reg = -1 128 kCode_no_reg = -1
129 }; 129 };
130 static const int kNumRegisters = Code::kAfterLast; 130 static constexpr int kNumRegisters = Code::kAfterLast;
131 131
132 #define REGISTER_COUNT(R) 1 + 132 #define REGISTER_COUNT(R) 1 +
133 static const int kNumAllocatable = 133 static constexpr int kNumAllocatable =
134 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT) 0; 134 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT) 0;
135 #undef REGISTER_COUNT 135 #undef REGISTER_COUNT
136 136
137 #define REGISTER_BIT(R) 1 << kCode_##R | 137 #define REGISTER_BIT(R) 1 << kCode_##R |
138 static const RegList kAllocatable = 138 static constexpr RegList kAllocatable =
139 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT) 0; 139 ALLOCATABLE_GENERAL_REGISTERS(REGISTER_BIT) 0;
140 #undef REGISTER_BIT 140 #undef REGISTER_BIT
141 141
142 static Register from_code(int code) { 142 static Register from_code(int code) {
143 DCHECK(code >= 0); 143 DCHECK(code >= 0);
144 DCHECK(code < kNumRegisters); 144 DCHECK(code < kNumRegisters);
145 Register r = {code}; 145 Register r = {code};
146 return r; 146 return r;
147 } 147 }
148 148
149 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } 149 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
150 bool is(Register reg) const { return reg_code == reg.reg_code; } 150 bool is(Register reg) const { return reg_code == reg.reg_code; }
151 int code() const { 151 int code() const {
152 DCHECK(is_valid()); 152 DCHECK(is_valid());
153 return reg_code; 153 return reg_code;
154 } 154 }
155 int bit() const { 155 int bit() const {
156 DCHECK(is_valid()); 156 DCHECK(is_valid());
157 return 1 << reg_code; 157 return 1 << reg_code;
158 } 158 }
159 159
160 void set_code(int code) { 160 void set_code(int code) {
161 reg_code = code; 161 reg_code = code;
162 DCHECK(is_valid()); 162 DCHECK(is_valid());
163 } 163 }
164 164
165 #if V8_TARGET_LITTLE_ENDIAN 165 #if V8_TARGET_LITTLE_ENDIAN
166 static const int kMantissaOffset = 0; 166 static constexpr int kMantissaOffset = 0;
167 static const int kExponentOffset = 4; 167 static constexpr int kExponentOffset = 4;
168 #else 168 #else
169 static const int kMantissaOffset = 4; 169 static constexpr int kMantissaOffset = 4;
170 static const int kExponentOffset = 0; 170 static constexpr int kExponentOffset = 0;
171 #endif 171 #endif
172 172
173 // Unfortunately we can't make this private in a struct. 173 // Unfortunately we can't make this private in a struct.
174 int reg_code; 174 int reg_code;
175 }; 175 };
176 176
177 typedef struct Register Register; 177 typedef struct Register Register;
178 178
179 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; 179 #define DEFINE_REGISTER(R) constexpr Register R = {Register::kCode_##R};
180 GENERAL_REGISTERS(DECLARE_REGISTER) 180 GENERAL_REGISTERS(DEFINE_REGISTER)
181 #undef DECLARE_REGISTER 181 #undef DEFINE_REGISTER
182 const Register no_reg = {Register::kCode_no_reg}; 182 constexpr Register no_reg = {Register::kCode_no_reg};
183 183
184 // Register aliases 184 // Register aliases
185 const Register kLithiumScratch = r1; // lithium scratch. 185 constexpr Register kLithiumScratch = r1; // lithium scratch.
186 const Register kRootRegister = r10; // Roots array pointer. 186 constexpr Register kRootRegister = r10; // Roots array pointer.
187 const Register cp = r13; // JavaScript context pointer. 187 constexpr Register cp = r13; // JavaScript context pointer.
188 188
189 static const bool kSimpleFPAliasing = true; 189 constexpr bool kSimpleFPAliasing = true;
190 static const bool kSimdMaskRegisters = false; 190 constexpr bool kSimdMaskRegisters = false;
191 191
192 // Double word FP register. 192 // Double word FP register.
193 struct DoubleRegister { 193 struct DoubleRegister {
194 enum Code { 194 enum Code {
195 #define REGISTER_CODE(R) kCode_##R, 195 #define REGISTER_CODE(R) kCode_##R,
196 DOUBLE_REGISTERS(REGISTER_CODE) 196 DOUBLE_REGISTERS(REGISTER_CODE)
197 #undef REGISTER_CODE 197 #undef REGISTER_CODE
198 kAfterLast, 198 kAfterLast,
199 kCode_no_reg = -1 199 kCode_no_reg = -1
200 }; 200 };
201 201
202 static const int kNumRegisters = Code::kAfterLast; 202 static constexpr int kNumRegisters = Code::kAfterLast;
203 static const int kMaxNumRegisters = kNumRegisters; 203 static constexpr int kMaxNumRegisters = kNumRegisters;
204 204
205 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } 205 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
206 bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; } 206 bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
207 207
208 int code() const { 208 int code() const {
209 DCHECK(is_valid()); 209 DCHECK(is_valid());
210 return reg_code; 210 return reg_code;
211 } 211 }
212 212
213 int bit() const { 213 int bit() const {
214 DCHECK(is_valid()); 214 DCHECK(is_valid());
215 return 1 << reg_code; 215 return 1 << reg_code;
216 } 216 }
217 217
218 static DoubleRegister from_code(int code) { 218 static DoubleRegister from_code(int code) {
219 DoubleRegister r = {code}; 219 DoubleRegister r = {code};
220 return r; 220 return r;
221 } 221 }
222 222
223 int reg_code; 223 int reg_code;
224 }; 224 };
225 225
226 typedef DoubleRegister FloatRegister; 226 typedef DoubleRegister FloatRegister;
227 227
228 // TODO(john.yan) Define SIMD registers. 228 // TODO(john.yan) Define SIMD registers.
229 typedef DoubleRegister Simd128Register; 229 typedef DoubleRegister Simd128Register;
230 230
231 #define DECLARE_REGISTER(R) \ 231 #define DEFINE_REGISTER(R) \
232 const DoubleRegister R = {DoubleRegister::kCode_##R}; 232 constexpr DoubleRegister R = {DoubleRegister::kCode_##R};
233 DOUBLE_REGISTERS(DECLARE_REGISTER) 233 DOUBLE_REGISTERS(DEFINE_REGISTER)
234 #undef DECLARE_REGISTER 234 #undef DEFINE_REGISTER
235 const Register no_dreg = {Register::kCode_no_reg}; 235 constexpr Register no_dreg = {Register::kCode_no_reg};
236 236
237 // Aliases for double registers. Defined using #define instead of 237 constexpr DoubleRegister kDoubleRegZero = d14;
238 // "static const DoubleRegister&" because Clang complains otherwise when a 238 constexpr DoubleRegister kScratchDoubleReg = d13;
239 // compilation unit that includes this header doesn't use the variables.
240 #define kDoubleRegZero d14
241 #define kScratchDoubleReg d13
242 239
243 Register ToRegister(int num); 240 Register ToRegister(int num);
244 241
245 // Coprocessor register 242 // Coprocessor register
246 struct CRegister { 243 struct CRegister {
247 bool is_valid() const { return 0 <= reg_code && reg_code < 8; } 244 bool is_valid() const { return 0 <= reg_code && reg_code < 8; }
248 bool is(CRegister creg) const { return reg_code == creg.reg_code; } 245 bool is(CRegister creg) const { return reg_code == creg.reg_code; }
249 int code() const { 246 int code() const {
250 DCHECK(is_valid()); 247 DCHECK(is_valid());
251 return reg_code; 248 return reg_code;
252 } 249 }
253 int bit() const { 250 int bit() const {
254 DCHECK(is_valid()); 251 DCHECK(is_valid());
255 return 1 << reg_code; 252 return 1 << reg_code;
256 } 253 }
257 254
258 // Unfortunately we can't make this private in a struct. 255 // Unfortunately we can't make this private in a struct.
259 int reg_code; 256 int reg_code;
260 }; 257 };
261 258
262 const CRegister no_creg = {-1}; 259 constexpr CRegister no_creg = {-1};
263 260
264 const CRegister cr0 = {0}; 261 constexpr CRegister cr0 = {0};
265 const CRegister cr1 = {1}; 262 constexpr CRegister cr1 = {1};
266 const CRegister cr2 = {2}; 263 constexpr CRegister cr2 = {2};
267 const CRegister cr3 = {3}; 264 constexpr CRegister cr3 = {3};
268 const CRegister cr4 = {4}; 265 constexpr CRegister cr4 = {4};
269 const CRegister cr5 = {5}; 266 constexpr CRegister cr5 = {5};
270 const CRegister cr6 = {6}; 267 constexpr CRegister cr6 = {6};
271 const CRegister cr7 = {7}; 268 constexpr CRegister cr7 = {7};
272 269
273 // ----------------------------------------------------------------------------- 270 // -----------------------------------------------------------------------------
274 // Machine instruction Operands 271 // Machine instruction Operands
275 272
276 #if V8_TARGET_ARCH_S390X 273 #if V8_TARGET_ARCH_S390X
277 const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE64; 274 constexpr RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE64;
278 #else 275 #else
279 const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE32; 276 constexpr RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE32;
280 #endif 277 #endif
281 278
282 // Class Operand represents a shifter operand in data processing instructions 279 // Class Operand represents a shifter operand in data processing instructions
283 // defining immediate numbers and masks 280 // defining immediate numbers and masks
284 typedef uint8_t Length; 281 typedef uint8_t Length;
285 282
286 struct Mask { 283 struct Mask {
287 uint8_t mask; 284 uint8_t mask;
288 uint8_t value() { return mask; } 285 uint8_t value() { return mask; }
289 static Mask from_value(uint8_t input) { 286 static Mask from_value(uint8_t input) {
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 inline static void deserialization_set_target_internal_reference_at( 469 inline static void deserialization_set_target_internal_reference_at(
473 Isolate* isolate, Address pc, Address target, 470 Isolate* isolate, Address pc, Address target,
474 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 471 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
475 472
476 // Here we are patching the address in the IIHF/IILF instruction pair. 473 // Here we are patching the address in the IIHF/IILF instruction pair.
477 // These values are used in the serialization process and must be zero for 474 // These values are used in the serialization process and must be zero for
478 // S390 platform, as Code, Embedded Object or External-reference pointers 475 // S390 platform, as Code, Embedded Object or External-reference pointers
479 // are split across two consecutive instructions and don't exist separately 476 // are split across two consecutive instructions and don't exist separately
480 // in the code, so the serializer should not step forwards in memory after 477 // in the code, so the serializer should not step forwards in memory after
481 // a target is resolved and written. 478 // a target is resolved and written.
482 static const int kSpecialTargetSize = 0; 479 static constexpr int kSpecialTargetSize = 0;
483 480
484 // Number of bytes for instructions used to store pointer sized constant. 481 // Number of bytes for instructions used to store pointer sized constant.
485 #if V8_TARGET_ARCH_S390X 482 #if V8_TARGET_ARCH_S390X
486 static const int kBytesForPtrConstant = 12; // IIHF + IILF 483 static constexpr int kBytesForPtrConstant = 12; // IIHF + IILF
487 #else 484 #else
488 static const int kBytesForPtrConstant = 6; // IILF 485 static constexpr int kBytesForPtrConstant = 6; // IILF
489 #endif 486 #endif
490 487
491 // Distance between the instruction referring to the address of the call 488 // Distance between the instruction referring to the address of the call
492 // target and the return address. 489 // target and the return address.
493 490
494 // Offset between call target address and return address 491 // Offset between call target address and return address
495 // for BRASL calls 492 // for BRASL calls
496 // Patch will be appiled to other FIXED_SEQUENCE call 493 // Patch will be appiled to other FIXED_SEQUENCE call
497 static const int kCallTargetAddressOffset = 6; 494 static constexpr int kCallTargetAddressOffset = 6;
498 495
499 // The length of FIXED_SEQUENCE call 496 // The length of FIXED_SEQUENCE call
500 // iihf r8, <address_hi> // <64-bit only> 497 // iihf r8, <address_hi> // <64-bit only>
501 // iilf r8, <address_lo> 498 // iilf r8, <address_lo>
502 // basr r14, r8 499 // basr r14, r8
503 #if V8_TARGET_ARCH_S390X 500 #if V8_TARGET_ARCH_S390X
504 static const int kCallSequenceLength = 14; 501 static constexpr int kCallSequenceLength = 14;
505 #else 502 #else
506 static const int kCallSequenceLength = 8; 503 static constexpr int kCallSequenceLength = 8;
507 #endif 504 #endif
508 505
509 // This is the length of the BreakLocationIterator::SetDebugBreakAtReturn() 506 // This is the length of the BreakLocationIterator::SetDebugBreakAtReturn()
510 // code patch FIXED_SEQUENCE in bytes! 507 // code patch FIXED_SEQUENCE in bytes!
511 // JS Return Sequence = Call Sequence + BKPT 508 // JS Return Sequence = Call Sequence + BKPT
512 // static const int kJSReturnSequenceLength = kCallSequenceLength + 2; 509 // static constexpr int kJSReturnSequenceLength = kCallSequenceLength + 2;
513 510
514 // This is the length of the code sequence from SetDebugBreakAtSlot() 511 // This is the length of the code sequence from SetDebugBreakAtSlot()
515 // FIXED_SEQUENCE in bytes! 512 // FIXED_SEQUENCE in bytes!
516 static const int kDebugBreakSlotLength = kCallSequenceLength; 513 static constexpr int kDebugBreakSlotLength = kCallSequenceLength;
517 static const int kPatchDebugBreakSlotReturnOffset = kCallTargetAddressOffset; 514 static constexpr int kPatchDebugBreakSlotReturnOffset =
515 kCallTargetAddressOffset;
518 516
519 // Length to patch between the start of the JS return sequence 517 // Length to patch between the start of the JS return sequence
520 // from SetDebugBreakAtReturn and the address from 518 // from SetDebugBreakAtReturn and the address from
521 // break_address_from_return_address. 519 // break_address_from_return_address.
522 // 520 //
523 // frame->pc() in Debug::SetAfterBreakTarget will point to BKPT in 521 // frame->pc() in Debug::SetAfterBreakTarget will point to BKPT in
524 // JS return sequence, so the length to patch will not include BKPT 522 // JS return sequence, so the length to patch will not include BKPT
525 // instruction length. 523 // instruction length.
526 // static const int kPatchReturnSequenceAddressOffset = 524 // static constexpr int kPatchReturnSequenceAddressOffset =
527 // kCallSequenceLength - kPatchDebugBreakSlotReturnOffset; 525 // kCallSequenceLength - kPatchDebugBreakSlotReturnOffset;
528 526
529 // Length to patch between the start of the FIXED call sequence from 527 // Length to patch between the start of the FIXED call sequence from
530 // SetDebugBreakAtSlot() and the the address from 528 // SetDebugBreakAtSlot() and the the address from
531 // break_address_from_return_address. 529 // break_address_from_return_address.
532 static const int kPatchDebugBreakSlotAddressOffset = 530 static constexpr int kPatchDebugBreakSlotAddressOffset =
533 kDebugBreakSlotLength - kPatchDebugBreakSlotReturnOffset; 531 kDebugBreakSlotLength - kPatchDebugBreakSlotReturnOffset;
534 532
535 static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) { 533 static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) {
536 return ((cr.code() * CRWIDTH) + crbit); 534 return ((cr.code() * CRWIDTH) + crbit);
537 } 535 }
538 536
539 // --------------------------------------------------------------------------- 537 // ---------------------------------------------------------------------------
540 // Code generation 538 // Code generation
541 539
542 template <class T, int size, int lo, int hi> 540 template <class T, int size, int lo, int hi>
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
1358 1356
1359 // Record reloc info for current pc_ 1357 // Record reloc info for current pc_
1360 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); 1358 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1361 1359
1362 private: 1360 private:
1363 // Code generation 1361 // Code generation
1364 // The relocation writer's position is at least kGap bytes below the end of 1362 // The relocation writer's position is at least kGap bytes below the end of
1365 // the generated instructions. This is so that multi-instruction sequences do 1363 // the generated instructions. This is so that multi-instruction sequences do
1366 // not have to check for overflow. The same is true for writes of large 1364 // not have to check for overflow. The same is true for writes of large
1367 // relocation info entries. 1365 // relocation info entries.
1368 static const int kGap = 32; 1366 static constexpr int kGap = 32;
1369 1367
1370 // Relocation info generation 1368 // Relocation info generation
1371 // Each relocation is encoded as a variable size value 1369 // Each relocation is encoded as a variable size value
1372 static const int kMaxRelocSize = RelocInfoWriter::kMaxSize; 1370 static constexpr int kMaxRelocSize = RelocInfoWriter::kMaxSize;
1373 RelocInfoWriter reloc_info_writer; 1371 RelocInfoWriter reloc_info_writer;
1374 std::vector<DeferredRelocInfo> relocations_; 1372 std::vector<DeferredRelocInfo> relocations_;
1375 1373
1376 // The bound position, before this we cannot do instruction elimination. 1374 // The bound position, before this we cannot do instruction elimination.
1377 int last_bound_pos_; 1375 int last_bound_pos_;
1378 1376
1379 // Code emission 1377 // Code emission
1380 inline void CheckBuffer(); 1378 inline void CheckBuffer();
1381 void GrowBuffer(int needed = 0); 1379 void GrowBuffer(int needed = 0);
1382 inline void TrackBranch(); 1380 inline void TrackBranch();
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1469 1467
1470 class EnsureSpace BASE_EMBEDDED { 1468 class EnsureSpace BASE_EMBEDDED {
1471 public: 1469 public:
1472 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); } 1470 explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
1473 }; 1471 };
1474 1472
1475 } // namespace internal 1473 } // namespace internal
1476 } // namespace v8 1474 } // namespace v8
1477 1475
1478 #endif // V8_S390_ASSEMBLER_S390_H_ 1476 #endif // V8_S390_ASSEMBLER_S390_H_
OLDNEW
« no previous file with comments | « src/ppc/assembler-ppc.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698