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

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

Issue 2733503003: [assembler] Make register definitions constexpr (Closed)
Patch Set: [assembler] Make register definitions constexpr 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/arm64/assembler-arm64.cc ('k') | src/mips/assembler-mips.h » ('j') | 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 are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 // 109 //
110 struct Register { 110 struct Register {
111 enum Code { 111 enum Code {
112 #define REGISTER_CODE(R) kCode_##R, 112 #define REGISTER_CODE(R) kCode_##R,
113 GENERAL_REGISTERS(REGISTER_CODE) 113 GENERAL_REGISTERS(REGISTER_CODE)
114 #undef REGISTER_CODE 114 #undef REGISTER_CODE
115 kAfterLast, 115 kAfterLast,
116 kCode_no_reg = -1 116 kCode_no_reg = -1
117 }; 117 };
118 118
119 static const int kNumRegisters = Code::kAfterLast; 119 static constexpr int kNumRegisters = Code::kAfterLast;
120 120
121 static Register from_code(int code) { 121 static Register from_code(int code) {
122 DCHECK(code >= 0); 122 DCHECK(code >= 0);
123 DCHECK(code < kNumRegisters); 123 DCHECK(code < kNumRegisters);
124 Register r = {code}; 124 Register r = {code};
125 return r; 125 return r;
126 } 126 }
127 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; } 127 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
128 bool is(Register reg) const { return reg_code == reg.reg_code; } 128 bool is(Register reg) const { return reg_code == reg.reg_code; }
129 int code() const { 129 int code() const {
130 DCHECK(is_valid()); 130 DCHECK(is_valid());
131 return reg_code; 131 return reg_code;
132 } 132 }
133 int bit() const { 133 int bit() const {
134 DCHECK(is_valid()); 134 DCHECK(is_valid());
135 return 1 << reg_code; 135 return 1 << reg_code;
136 } 136 }
137 137
138 bool is_byte_register() const { return reg_code <= 3; } 138 bool is_byte_register() const { return reg_code <= 3; }
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 #define DEFINE_REGISTER(R) constexpr Register R = {Register::kCode_##R};
145 GENERAL_REGISTERS(DEFINE_REGISTER)
146 #undef DEFINE_REGISTER
147 constexpr Register no_reg = {Register::kCode_no_reg};
144 148
145 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R}; 149 constexpr bool kSimpleFPAliasing = true;
146 GENERAL_REGISTERS(DECLARE_REGISTER) 150 constexpr bool kSimdMaskRegisters = false;
147 #undef DECLARE_REGISTER
148 const Register no_reg = {Register::kCode_no_reg};
149
150 static const bool kSimpleFPAliasing = true;
151 static const bool kSimdMaskRegisters = false;
152 151
153 struct XMMRegister { 152 struct XMMRegister {
154 enum Code { 153 enum Code {
155 #define REGISTER_CODE(R) kCode_##R, 154 #define REGISTER_CODE(R) kCode_##R,
156 DOUBLE_REGISTERS(REGISTER_CODE) 155 DOUBLE_REGISTERS(REGISTER_CODE)
157 #undef REGISTER_CODE 156 #undef REGISTER_CODE
158 kAfterLast, 157 kAfterLast,
159 kCode_no_reg = -1 158 kCode_no_reg = -1
160 }; 159 };
161 160
162 static const int kMaxNumRegisters = Code::kAfterLast; 161 static constexpr int kMaxNumRegisters = Code::kAfterLast;
163 162
164 static XMMRegister from_code(int code) { 163 static XMMRegister from_code(int code) {
165 XMMRegister result = {code}; 164 XMMRegister result = {code};
166 return result; 165 return result;
167 } 166 }
168 167
169 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; } 168 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
170 169
171 int code() const { 170 int code() const {
172 DCHECK(is_valid()); 171 DCHECK(is_valid());
173 return reg_code; 172 return reg_code;
174 } 173 }
175 174
176 bool is(XMMRegister reg) const { return reg_code == reg.reg_code; } 175 bool is(XMMRegister reg) const { return reg_code == reg.reg_code; }
177 176
178 int reg_code; 177 int reg_code;
179 }; 178 };
180 179
181 typedef XMMRegister FloatRegister; 180 typedef XMMRegister FloatRegister;
182 181
183 typedef XMMRegister DoubleRegister; 182 typedef XMMRegister DoubleRegister;
184 183
185 typedef XMMRegister Simd128Register; 184 typedef XMMRegister Simd128Register;
186 185
187 #define DECLARE_REGISTER(R) \ 186 #define DEFINE_REGISTER(R) \
188 const DoubleRegister R = {DoubleRegister::kCode_##R}; 187 constexpr DoubleRegister R = {DoubleRegister::kCode_##R};
189 DOUBLE_REGISTERS(DECLARE_REGISTER) 188 DOUBLE_REGISTERS(DEFINE_REGISTER)
190 #undef DECLARE_REGISTER 189 #undef DEFINE_REGISTER
191 const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg}; 190 constexpr DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
192 191
193 enum Condition { 192 enum Condition {
194 // any value < 0 is considered no_condition 193 // any value < 0 is considered no_condition
195 no_condition = -1, 194 no_condition = -1,
196 195
197 overflow = 0, 196 overflow = 0,
198 no_overflow = 1, 197 no_overflow = 1,
199 below = 2, 198 below = 2,
200 above_equal = 3, 199 above_equal = 3,
201 equal = 4, 200 equal = 4,
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 private: 461 private:
463 // We check before assembling an instruction that there is sufficient 462 // We check before assembling an instruction that there is sufficient
464 // space to write an instruction and its relocation information. 463 // space to write an instruction and its relocation information.
465 // The relocation writer's position must be kGap bytes above the end of 464 // The relocation writer's position must be kGap bytes above the end of
466 // the generated instructions. This leaves enough space for the 465 // the generated instructions. This leaves enough space for the
467 // longest possible ia32 instruction, 15 bytes, and the longest possible 466 // longest possible ia32 instruction, 15 bytes, and the longest possible
468 // relocation information encoding, RelocInfoWriter::kMaxLength == 16. 467 // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
469 // (There is a 15 byte limit on ia32 instruction length that rules out some 468 // (There is a 15 byte limit on ia32 instruction length that rules out some
470 // otherwise valid instructions.) 469 // otherwise valid instructions.)
471 // This allows for a single, fast space check per instruction. 470 // This allows for a single, fast space check per instruction.
472 static const int kGap = 32; 471 static constexpr int kGap = 32;
473 472
474 public: 473 public:
475 // Create an assembler. Instructions and relocation information are emitted 474 // Create an assembler. Instructions and relocation information are emitted
476 // into a buffer, with the instructions starting from the beginning and the 475 // into a buffer, with the instructions starting from the beginning and the
477 // relocation information starting from the end of the buffer. See CodeDesc 476 // relocation information starting from the end of the buffer. See CodeDesc
478 // for a detailed comment on the layout (globals.h). 477 // for a detailed comment on the layout (globals.h).
479 // 478 //
480 // If the provided buffer is NULL, the assembler allocates and grows its own 479 // If the provided buffer is NULL, the assembler allocates and grows its own
481 // buffer, and buffer_size determines the initial buffer size. The buffer is 480 // buffer, and buffer_size determines the initial buffer size. The buffer is
482 // owned by the assembler and deallocated upon destruction of the assembler. 481 // owned by the assembler and deallocated upon destruction of the assembler.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 Isolate* isolate, Address instruction_payload, Code* code, 513 Isolate* isolate, Address instruction_payload, Code* code,
515 Address target) { 514 Address target) {
516 set_target_address_at(isolate, instruction_payload, code, target); 515 set_target_address_at(isolate, instruction_payload, code, target);
517 } 516 }
518 517
519 // This sets the internal reference at the pc. 518 // This sets the internal reference at the pc.
520 inline static void deserialization_set_target_internal_reference_at( 519 inline static void deserialization_set_target_internal_reference_at(
521 Isolate* isolate, Address pc, Address target, 520 Isolate* isolate, Address pc, Address target,
522 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE); 521 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
523 522
524 static const int kSpecialTargetSize = kPointerSize; 523 static constexpr int kSpecialTargetSize = kPointerSize;
525 524
526 // Distance between the address of the code target in the call instruction 525 // Distance between the address of the code target in the call instruction
527 // and the return address 526 // and the return address
528 static const int kCallTargetAddressOffset = kPointerSize; 527 static constexpr int kCallTargetAddressOffset = kPointerSize;
529 528
530 static const int kCallInstructionLength = 5; 529 static constexpr int kCallInstructionLength = 5;
531 530
532 // The debug break slot must be able to contain a call instruction. 531 // The debug break slot must be able to contain a call instruction.
533 static const int kDebugBreakSlotLength = kCallInstructionLength; 532 static constexpr int kDebugBreakSlotLength = kCallInstructionLength;
534 533
535 // Distance between start of patched debug break slot and the emitted address 534 // Distance between start of patched debug break slot and the emitted address
536 // to jump to. 535 // to jump to.
537 static const int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32. 536 static constexpr int kPatchDebugBreakSlotAddressOffset = 1; // JMP imm32.
538 537
539 // One byte opcode for test al, 0xXX. 538 // One byte opcode for test al, 0xXX.
540 static const byte kTestAlByte = 0xA8; 539 static constexpr byte kTestAlByte = 0xA8;
541 // One byte opcode for nop. 540 // One byte opcode for nop.
542 static const byte kNopByte = 0x90; 541 static constexpr byte kNopByte = 0x90;
543 542
544 // One byte opcode for a short unconditional jump. 543 // One byte opcode for a short unconditional jump.
545 static const byte kJmpShortOpcode = 0xEB; 544 static constexpr byte kJmpShortOpcode = 0xEB;
546 // One byte prefix for a short conditional jump. 545 // One byte prefix for a short conditional jump.
547 static const byte kJccShortPrefix = 0x70; 546 static constexpr byte kJccShortPrefix = 0x70;
548 static const byte kJncShortOpcode = kJccShortPrefix | not_carry; 547 static constexpr byte kJncShortOpcode = kJccShortPrefix | not_carry;
549 static const byte kJcShortOpcode = kJccShortPrefix | carry; 548 static constexpr byte kJcShortOpcode = kJccShortPrefix | carry;
550 static const byte kJnzShortOpcode = kJccShortPrefix | not_zero; 549 static constexpr byte kJnzShortOpcode = kJccShortPrefix | not_zero;
551 static const byte kJzShortOpcode = kJccShortPrefix | zero; 550 static constexpr byte kJzShortOpcode = kJccShortPrefix | zero;
552
553 551
554 // --------------------------------------------------------------------------- 552 // ---------------------------------------------------------------------------
555 // Code generation 553 // Code generation
556 // 554 //
557 // - function names correspond one-to-one to ia32 instruction mnemonics 555 // - function names correspond one-to-one to ia32 instruction mnemonics
558 // - unless specified otherwise, instructions operate on 32bit operands 556 // - unless specified otherwise, instructions operate on 32bit operands
559 // - instructions on 8bit (byte) operands/registers have a trailing '_b' 557 // - instructions on 8bit (byte) operands/registers have a trailing '_b'
560 // - instructions on 16bit (word) operands/registers have a trailing '_w' 558 // - instructions on 16bit (word) operands/registers have a trailing '_w'
561 // - naming conflicts with C++ keywords are resolved via a trailing '_' 559 // - naming conflicts with C++ keywords are resolved via a trailing '_'
562 560
(...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after
1459 // Get the number of bytes available in the buffer. 1457 // Get the number of bytes available in the buffer.
1460 inline int available_space() const { return reloc_info_writer.pos() - pc_; } 1458 inline int available_space() const { return reloc_info_writer.pos() - pc_; }
1461 1459
1462 static bool IsNop(Address addr); 1460 static bool IsNop(Address addr);
1463 1461
1464 int relocation_writer_size() { 1462 int relocation_writer_size() {
1465 return (buffer_ + buffer_size_) - reloc_info_writer.pos(); 1463 return (buffer_ + buffer_size_) - reloc_info_writer.pos();
1466 } 1464 }
1467 1465
1468 // Avoid overflows for displacements etc. 1466 // Avoid overflows for displacements etc.
1469 static const int kMaximalBufferSize = 512*MB; 1467 static constexpr int kMaximalBufferSize = 512 * MB;
1470 1468
1471 byte byte_at(int pos) { return buffer_[pos]; } 1469 byte byte_at(int pos) { return buffer_[pos]; }
1472 void set_byte_at(int pos, byte value) { buffer_[pos] = value; } 1470 void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
1473 1471
1474 void PatchConstantPoolAccessInstruction(int pc_offset, int offset, 1472 void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1475 ConstantPoolEntry::Access access, 1473 ConstantPoolEntry::Access access,
1476 ConstantPoolEntry::Type type) { 1474 ConstantPoolEntry::Type type) {
1477 // No embedded constant pool support. 1475 // No embedded constant pool support.
1478 UNREACHABLE(); 1476 UNREACHABLE();
1479 } 1477 }
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 Assembler* assembler_; 1591 Assembler* assembler_;
1594 #ifdef DEBUG 1592 #ifdef DEBUG
1595 int space_before_; 1593 int space_before_;
1596 #endif 1594 #endif
1597 }; 1595 };
1598 1596
1599 } // namespace internal 1597 } // namespace internal
1600 } // namespace v8 1598 } // namespace v8
1601 1599
1602 #endif // V8_IA32_ASSEMBLER_IA32_H_ 1600 #endif // V8_IA32_ASSEMBLER_IA32_H_
OLDNEW
« no previous file with comments | « src/arm64/assembler-arm64.cc ('k') | src/mips/assembler-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698