OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_INSTRUCTION_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_H_ |
6 #define V8_COMPILER_INSTRUCTION_H_ | 6 #define V8_COMPILER_INSTRUCTION_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 #include <map> | 10 #include <map> |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 } | 148 } |
149 | 149 |
150 class UnallocatedOperand : public InstructionOperand { | 150 class UnallocatedOperand : public InstructionOperand { |
151 public: | 151 public: |
152 enum BasicPolicy { FIXED_SLOT, EXTENDED_POLICY }; | 152 enum BasicPolicy { FIXED_SLOT, EXTENDED_POLICY }; |
153 | 153 |
154 enum ExtendedPolicy { | 154 enum ExtendedPolicy { |
155 NONE, | 155 NONE, |
156 ANY, | 156 ANY, |
157 FIXED_REGISTER, | 157 FIXED_REGISTER, |
158 FIXED_DOUBLE_REGISTER, | 158 FIXED_FP_REGISTER, |
159 MUST_HAVE_REGISTER, | 159 MUST_HAVE_REGISTER, |
160 MUST_HAVE_SLOT, | 160 MUST_HAVE_SLOT, |
161 SAME_AS_FIRST_INPUT | 161 SAME_AS_FIRST_INPUT |
162 }; | 162 }; |
163 | 163 |
164 // Lifetime of operand inside the instruction. | 164 // Lifetime of operand inside the instruction. |
165 enum Lifetime { | 165 enum Lifetime { |
166 // USED_AT_START operand is guaranteed to be live only at | 166 // USED_AT_START operand is guaranteed to be live only at |
167 // instruction start. Register allocator is free to assign the same register | 167 // instruction start. Register allocator is free to assign the same register |
168 // to some other operand used inside instruction (i.e. temporary or | 168 // to some other operand used inside instruction (i.e. temporary or |
(...skipping 16 matching lines...) Expand all Loading... |
185 UnallocatedOperand(BasicPolicy policy, int index, int virtual_register) | 185 UnallocatedOperand(BasicPolicy policy, int index, int virtual_register) |
186 : UnallocatedOperand(virtual_register) { | 186 : UnallocatedOperand(virtual_register) { |
187 DCHECK(policy == FIXED_SLOT); | 187 DCHECK(policy == FIXED_SLOT); |
188 value_ |= BasicPolicyField::encode(policy); | 188 value_ |= BasicPolicyField::encode(policy); |
189 value_ |= static_cast<int64_t>(index) << FixedSlotIndexField::kShift; | 189 value_ |= static_cast<int64_t>(index) << FixedSlotIndexField::kShift; |
190 DCHECK(this->fixed_slot_index() == index); | 190 DCHECK(this->fixed_slot_index() == index); |
191 } | 191 } |
192 | 192 |
193 UnallocatedOperand(ExtendedPolicy policy, int index, int virtual_register) | 193 UnallocatedOperand(ExtendedPolicy policy, int index, int virtual_register) |
194 : UnallocatedOperand(virtual_register) { | 194 : UnallocatedOperand(virtual_register) { |
195 DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER); | 195 DCHECK(policy == FIXED_REGISTER || policy == FIXED_FP_REGISTER); |
196 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); | 196 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
197 value_ |= ExtendedPolicyField::encode(policy); | 197 value_ |= ExtendedPolicyField::encode(policy); |
198 value_ |= LifetimeField::encode(USED_AT_END); | 198 value_ |= LifetimeField::encode(USED_AT_END); |
199 value_ |= FixedRegisterField::encode(index); | 199 value_ |= FixedRegisterField::encode(index); |
200 } | 200 } |
201 | 201 |
202 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime, | 202 UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime, |
203 int virtual_register) | 203 int virtual_register) |
204 : UnallocatedOperand(virtual_register) { | 204 : UnallocatedOperand(virtual_register) { |
205 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); | 205 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
206 value_ |= ExtendedPolicyField::encode(policy); | 206 value_ |= ExtendedPolicyField::encode(policy); |
207 value_ |= LifetimeField::encode(lifetime); | 207 value_ |= LifetimeField::encode(lifetime); |
208 } | 208 } |
209 | 209 |
210 UnallocatedOperand(int reg_id, int slot_id, int virtual_register) | 210 UnallocatedOperand(int reg_id, int slot_id, int virtual_register) |
211 : UnallocatedOperand(FIXED_REGISTER, reg_id, virtual_register) { | 211 : UnallocatedOperand(FIXED_REGISTER, reg_id, virtual_register) { |
212 value_ |= HasSecondaryStorageField::encode(true); | 212 value_ |= HasSecondaryStorageField::encode(true); |
213 value_ |= SecondaryStorageField::encode(slot_id); | 213 value_ |= SecondaryStorageField::encode(slot_id); |
214 } | 214 } |
215 | 215 |
216 // Predicates for the operand policy. | 216 // Predicates for the operand policy. |
217 bool HasAnyPolicy() const { | 217 bool HasAnyPolicy() const { |
218 return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY; | 218 return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY; |
219 } | 219 } |
220 bool HasFixedPolicy() const { | 220 bool HasFixedPolicy() const { |
221 return basic_policy() == FIXED_SLOT || | 221 return basic_policy() == FIXED_SLOT || |
222 extended_policy() == FIXED_REGISTER || | 222 extended_policy() == FIXED_REGISTER || |
223 extended_policy() == FIXED_DOUBLE_REGISTER; | 223 extended_policy() == FIXED_FP_REGISTER; |
224 } | 224 } |
225 bool HasRegisterPolicy() const { | 225 bool HasRegisterPolicy() const { |
226 return basic_policy() == EXTENDED_POLICY && | 226 return basic_policy() == EXTENDED_POLICY && |
227 extended_policy() == MUST_HAVE_REGISTER; | 227 extended_policy() == MUST_HAVE_REGISTER; |
228 } | 228 } |
229 bool HasSlotPolicy() const { | 229 bool HasSlotPolicy() const { |
230 return basic_policy() == EXTENDED_POLICY && | 230 return basic_policy() == EXTENDED_POLICY && |
231 extended_policy() == MUST_HAVE_SLOT; | 231 extended_policy() == MUST_HAVE_SLOT; |
232 } | 232 } |
233 bool HasSameAsInputPolicy() const { | 233 bool HasSameAsInputPolicy() const { |
234 return basic_policy() == EXTENDED_POLICY && | 234 return basic_policy() == EXTENDED_POLICY && |
235 extended_policy() == SAME_AS_FIRST_INPUT; | 235 extended_policy() == SAME_AS_FIRST_INPUT; |
236 } | 236 } |
237 bool HasFixedSlotPolicy() const { return basic_policy() == FIXED_SLOT; } | 237 bool HasFixedSlotPolicy() const { return basic_policy() == FIXED_SLOT; } |
238 bool HasFixedRegisterPolicy() const { | 238 bool HasFixedRegisterPolicy() const { |
239 return basic_policy() == EXTENDED_POLICY && | 239 return basic_policy() == EXTENDED_POLICY && |
240 extended_policy() == FIXED_REGISTER; | 240 extended_policy() == FIXED_REGISTER; |
241 } | 241 } |
242 bool HasFixedDoubleRegisterPolicy() const { | 242 bool HasFixedFPRegisterPolicy() const { |
243 return basic_policy() == EXTENDED_POLICY && | 243 return basic_policy() == EXTENDED_POLICY && |
244 extended_policy() == FIXED_DOUBLE_REGISTER; | 244 extended_policy() == FIXED_FP_REGISTER; |
245 } | 245 } |
246 bool HasSecondaryStorage() const { | 246 bool HasSecondaryStorage() const { |
247 return basic_policy() == EXTENDED_POLICY && | 247 return basic_policy() == EXTENDED_POLICY && |
248 extended_policy() == FIXED_REGISTER && | 248 extended_policy() == FIXED_REGISTER && |
249 HasSecondaryStorageField::decode(value_); | 249 HasSecondaryStorageField::decode(value_); |
250 } | 250 } |
251 int GetSecondaryStorage() const { | 251 int GetSecondaryStorage() const { |
252 DCHECK(HasSecondaryStorage()); | 252 DCHECK(HasSecondaryStorage()); |
253 return SecondaryStorageField::decode(value_); | 253 return SecondaryStorageField::decode(value_); |
254 } | 254 } |
(...skipping 10 matching lines...) Expand all Loading... |
265 return ExtendedPolicyField::decode(value_); | 265 return ExtendedPolicyField::decode(value_); |
266 } | 266 } |
267 | 267 |
268 // [fixed_slot_index]: Only for FIXED_SLOT. | 268 // [fixed_slot_index]: Only for FIXED_SLOT. |
269 int fixed_slot_index() const { | 269 int fixed_slot_index() const { |
270 DCHECK(HasFixedSlotPolicy()); | 270 DCHECK(HasFixedSlotPolicy()); |
271 return static_cast<int>(static_cast<int64_t>(value_) >> | 271 return static_cast<int>(static_cast<int64_t>(value_) >> |
272 FixedSlotIndexField::kShift); | 272 FixedSlotIndexField::kShift); |
273 } | 273 } |
274 | 274 |
275 // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER. | 275 // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_FP_REGISTER. |
276 int fixed_register_index() const { | 276 int fixed_register_index() const { |
277 DCHECK(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy()); | 277 DCHECK(HasFixedRegisterPolicy() || HasFixedFPRegisterPolicy()); |
278 return FixedRegisterField::decode(value_); | 278 return FixedRegisterField::decode(value_); |
279 } | 279 } |
280 | 280 |
281 // [virtual_register]: The virtual register ID for this operand. | 281 // [virtual_register]: The virtual register ID for this operand. |
282 int32_t virtual_register() const { | 282 int32_t virtual_register() const { |
283 DCHECK_EQ(UNALLOCATED, kind()); | 283 DCHECK_EQ(UNALLOCATED, kind()); |
284 return static_cast<int32_t>(VirtualRegisterField::decode(value_)); | 284 return static_cast<int32_t>(VirtualRegisterField::decode(value_)); |
285 } | 285 } |
286 | 286 |
287 // TODO(dcarney): remove this. | 287 // TODO(dcarney): remove this. |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 value_ |= LocationKindField::encode(location_kind); | 414 value_ |= LocationKindField::encode(location_kind); |
415 value_ |= RepresentationField::encode(rep); | 415 value_ |= RepresentationField::encode(rep); |
416 value_ |= static_cast<int64_t>(index) << IndexField::kShift; | 416 value_ |= static_cast<int64_t>(index) << IndexField::kShift; |
417 } | 417 } |
418 | 418 |
419 int index() const { | 419 int index() const { |
420 DCHECK(IsStackSlot() || IsFPStackSlot()); | 420 DCHECK(IsStackSlot() || IsFPStackSlot()); |
421 return static_cast<int64_t>(value_) >> IndexField::kShift; | 421 return static_cast<int64_t>(value_) >> IndexField::kShift; |
422 } | 422 } |
423 | 423 |
| 424 int register_code() const { |
| 425 DCHECK(IsRegister() || IsFPRegister()); |
| 426 return static_cast<int64_t>(value_) >> IndexField::kShift; |
| 427 } |
| 428 |
424 Register GetRegister() const { | 429 Register GetRegister() const { |
425 DCHECK(IsRegister()); | 430 DCHECK(IsRegister()); |
426 return Register::from_code(static_cast<int64_t>(value_) >> | 431 return Register::from_code(register_code()); |
427 IndexField::kShift); | |
428 } | 432 } |
429 | 433 |
430 FloatRegister GetFloatRegister() const { | 434 FloatRegister GetFloatRegister() const { |
431 DCHECK(IsFloatRegister()); | 435 DCHECK(IsFloatRegister()); |
432 return FloatRegister::from_code(static_cast<int64_t>(value_) >> | 436 return FloatRegister::from_code(register_code()); |
433 IndexField::kShift); | |
434 } | 437 } |
435 | 438 |
436 DoubleRegister GetDoubleRegister() const { | 439 DoubleRegister GetDoubleRegister() const { |
437 // TODO(bbudge) Tighten this test to IsDoubleRegister when all code | 440 // TODO(bbudge) Tighten this test to IsDoubleRegister when all code |
438 // generators are changed to use the correct Get*Register method. | 441 // generators are changed to use the correct Get*Register method. |
439 DCHECK(IsFPRegister()); | 442 DCHECK(IsFPRegister()); |
440 return DoubleRegister::from_code(static_cast<int64_t>(value_) >> | 443 return DoubleRegister::from_code(register_code()); |
441 IndexField::kShift); | |
442 } | 444 } |
443 | 445 |
444 Simd128Register GetSimd128Register() const { | 446 Simd128Register GetSimd128Register() const { |
445 DCHECK(IsSimd128Register()); | 447 DCHECK(IsSimd128Register()); |
446 return Simd128Register::from_code(static_cast<int64_t>(value_) >> | 448 return Simd128Register::from_code(register_code()); |
447 IndexField::kShift); | |
448 } | 449 } |
449 | 450 |
450 LocationKind location_kind() const { | 451 LocationKind location_kind() const { |
451 return LocationKindField::decode(value_); | 452 return LocationKindField::decode(value_); |
452 } | 453 } |
453 | 454 |
454 MachineRepresentation representation() const { | 455 MachineRepresentation representation() const { |
455 return RepresentationField::decode(value_); | 456 return RepresentationField::decode(value_); |
456 } | 457 } |
457 | 458 |
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1475 | 1476 |
1476 | 1477 |
1477 std::ostream& operator<<(std::ostream& os, | 1478 std::ostream& operator<<(std::ostream& os, |
1478 const PrintableInstructionSequence& code); | 1479 const PrintableInstructionSequence& code); |
1479 | 1480 |
1480 } // namespace compiler | 1481 } // namespace compiler |
1481 } // namespace internal | 1482 } // namespace internal |
1482 } // namespace v8 | 1483 } // namespace v8 |
1483 | 1484 |
1484 #endif // V8_COMPILER_INSTRUCTION_H_ | 1485 #endif // V8_COMPILER_INSTRUCTION_H_ |
OLD | NEW |