| 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 |