Index: src/lithium.h |
diff --git a/src/lithium.h b/src/lithium.h |
index 24182747e3211a9f5479a622a60b262ee5e6ab6c..25229991a6c2e338b9b7438d80be85bd0b6315d4 100644 |
--- a/src/lithium.h |
+++ b/src/lithium.h |
@@ -92,12 +92,16 @@ class LOperand: public ZoneObject { |
class LUnallocated: public LOperand { |
public: |
- enum Policy { |
+ enum BasicPolicy { |
+ FIXED_SLOT, |
+ EXTENDED_POLICY |
+ }; |
+ |
+ enum ExtendedPolicy { |
NONE, |
ANY, |
FIXED_REGISTER, |
FIXED_DOUBLE_REGISTER, |
- FIXED_SLOT, |
MUST_HAVE_REGISTER, |
WRITABLE_REGISTER, |
SAME_AS_FIRST_INPUT |
@@ -117,99 +121,153 @@ class LUnallocated: public LOperand { |
USED_AT_END |
}; |
- explicit LUnallocated(Policy policy) : LOperand(UNALLOCATED, 0) { |
- Initialize(policy, 0, USED_AT_END); |
+ explicit LUnallocated(ExtendedPolicy policy) : LOperand(UNALLOCATED, 0) { |
+ value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
+ value_ |= ExtendedPolicyField::encode(policy); |
+ value_ |= LifetimeField::encode(USED_AT_END); |
} |
- LUnallocated(Policy policy, int fixed_index) : LOperand(UNALLOCATED, 0) { |
- Initialize(policy, fixed_index, USED_AT_END); |
+ LUnallocated(BasicPolicy policy, int index) : LOperand(UNALLOCATED, 0) { |
+ ASSERT(policy == FIXED_SLOT); |
+ value_ |= BasicPolicyField::encode(policy); |
+ value_ |= index << FixedSlotIndexField::kShift; |
+ ASSERT(this->fixed_slot_index() == index); |
} |
- LUnallocated(Policy policy, Lifetime lifetime) : LOperand(UNALLOCATED, 0) { |
- Initialize(policy, 0, lifetime); |
+ LUnallocated(ExtendedPolicy policy, int index) : LOperand(UNALLOCATED, 0) { |
+ ASSERT(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER); |
+ value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
+ value_ |= ExtendedPolicyField::encode(policy); |
+ value_ |= LifetimeField::encode(USED_AT_END); |
+ value_ |= FixedRegisterField::encode(index); |
} |
- // The superclass has a KindField. Some policies have a signed fixed |
- // index in the upper bits. |
- static const int kPolicyWidth = 3; |
- static const int kLifetimeWidth = 1; |
- static const int kVirtualRegisterWidth = 15; |
- |
- static const int kPolicyShift = kKindFieldWidth; |
- static const int kLifetimeShift = kPolicyShift + kPolicyWidth; |
- static const int kVirtualRegisterShift = kLifetimeShift + kLifetimeWidth; |
- static const int kFixedIndexShift = |
- kVirtualRegisterShift + kVirtualRegisterWidth; |
- static const int kFixedIndexWidth = 32 - kFixedIndexShift; |
- STATIC_ASSERT(kFixedIndexWidth > 5); |
- |
- class PolicyField : public BitField<Policy, kPolicyShift, kPolicyWidth> { }; |
- |
- class LifetimeField |
- : public BitField<Lifetime, kLifetimeShift, kLifetimeWidth> { |
- }; |
+ LUnallocated(ExtendedPolicy policy, Lifetime lifetime) |
+ : LOperand(UNALLOCATED, 0) { |
+ value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
+ value_ |= ExtendedPolicyField::encode(policy); |
+ value_ |= LifetimeField::encode(lifetime); |
+ } |
- class VirtualRegisterField |
- : public BitField<unsigned, |
- kVirtualRegisterShift, |
- kVirtualRegisterWidth> { |
- }; |
+ LUnallocated* CopyUnconstrained(Zone* zone) { |
+ LUnallocated* result = new(zone) LUnallocated(ANY); |
+ result->set_virtual_register(virtual_register()); |
+ return result; |
+ } |
- static const int kMaxVirtualRegisters = 1 << kVirtualRegisterWidth; |
- static const int kMaxFixedIndex = (1 << (kFixedIndexWidth - 1)) - 1; |
- static const int kMinFixedIndex = -(1 << (kFixedIndexWidth - 1)); |
+ static LUnallocated* cast(LOperand* op) { |
+ ASSERT(op->IsUnallocated()); |
+ return reinterpret_cast<LUnallocated*>(op); |
+ } |
+ // The encoding used for LUnallocated operands depends on the policy that is |
+ // stored within the operand. The FIXED_SLOT policy uses a compact encoding |
+ // because it accommodates a larger pay-load. |
+ // |
+ // For FIXED_SLOT policy: |
+ // +------------------------------------------+ |
+ // | slot_index | vreg | 0 | 001 | |
+ // +------------------------------------------+ |
+ // |
+ // For all other (extended) policies: |
+ // +------------------------------------------+ |
+ // | reg_index | L | PPP | vreg | 1 | 001 | L ... Lifetime |
+ // +------------------------------------------+ P ... Policy |
+ // |
+ // The slot index is a signed value which requires us to decode it manually |
+ // instead of using the BitField utility class. |
+ |
+ // The superclass has a KindField. |
+ STATIC_ASSERT(kKindFieldWidth == 3); |
+ |
+ // BitFields for all unallocated operands. |
+ class BasicPolicyField : public BitField<BasicPolicy, 3, 1> {}; |
+ // TODO(mstarzinger): Bump this from 15 bit to 18 bit in a follow-up CL. |
+ class VirtualRegisterField : public BitField<unsigned, 4, 15> {}; |
+ |
+ // BitFields specific to BasicPolicy::FIXED_SLOT. |
+ class FixedSlotIndexField : public BitField<int, 22, 10> {}; |
+ |
+ // BitFields specific to BasicPolicy::EXTENDED_POLICY. |
+ class ExtendedPolicyField : public BitField<ExtendedPolicy, 22, 3> {}; |
+ class LifetimeField : public BitField<Lifetime, 25, 1> {}; |
+ class FixedRegisterField : public BitField<int, 26, 6> {}; |
+ |
+ static const int kMaxVirtualRegisters = VirtualRegisterField::kMax + 1; |
+ static const int kFixedSlotIndexWidth = FixedSlotIndexField::kSize; |
+ static const int kMaxFixedSlotIndex = (1 << (kFixedSlotIndexWidth - 1)) - 1; |
+ static const int kMinFixedSlotIndex = -(1 << (kFixedSlotIndexWidth - 1)); |
+ |
+ // Predicates for the operand policy. |
bool HasAnyPolicy() const { |
- return policy() == ANY; |
+ return basic_policy() == EXTENDED_POLICY && |
+ extended_policy() == ANY; |
} |
bool HasFixedPolicy() const { |
- return policy() == FIXED_REGISTER || |
- policy() == FIXED_DOUBLE_REGISTER || |
- policy() == FIXED_SLOT; |
+ return basic_policy() == FIXED_SLOT || |
+ extended_policy() == FIXED_REGISTER || |
+ extended_policy() == FIXED_DOUBLE_REGISTER; |
} |
bool HasRegisterPolicy() const { |
- return policy() == WRITABLE_REGISTER || policy() == MUST_HAVE_REGISTER; |
+ return basic_policy() == EXTENDED_POLICY && ( |
+ extended_policy() == WRITABLE_REGISTER || |
+ extended_policy() == MUST_HAVE_REGISTER); |
} |
bool HasSameAsInputPolicy() const { |
- return policy() == SAME_AS_FIRST_INPUT; |
+ return basic_policy() == EXTENDED_POLICY && |
+ extended_policy() == SAME_AS_FIRST_INPUT; |
+ } |
+ bool HasFixedSlotPolicy() const { |
+ return basic_policy() == FIXED_SLOT; |
+ } |
+ bool HasFixedRegisterPolicy() const { |
+ return basic_policy() == EXTENDED_POLICY && |
+ extended_policy() == FIXED_REGISTER; |
} |
- Policy policy() const { return PolicyField::decode(value_); } |
- void set_policy(Policy policy) { |
- value_ = PolicyField::update(value_, policy); |
+ bool HasFixedDoubleRegisterPolicy() const { |
+ return basic_policy() == EXTENDED_POLICY && |
+ extended_policy() == FIXED_DOUBLE_REGISTER; |
} |
- int fixed_index() const { |
- return static_cast<int>(value_) >> kFixedIndexShift; |
+ bool HasWritableRegisterPolicy() const { |
+ return basic_policy() == EXTENDED_POLICY && |
+ extended_policy() == WRITABLE_REGISTER; |
} |
- int virtual_register() const { |
- return VirtualRegisterField::decode(value_); |
+ // [basic_policy]: Distinguish between FIXED_SLOT and all other policies. |
+ BasicPolicy basic_policy() const { |
+ return BasicPolicyField::decode(value_); |
} |
- void set_virtual_register(unsigned id) { |
- value_ = VirtualRegisterField::update(value_, id); |
+ // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy. |
+ ExtendedPolicy extended_policy() const { |
+ ASSERT(basic_policy() == EXTENDED_POLICY); |
+ return ExtendedPolicyField::decode(value_); |
} |
- LUnallocated* CopyUnconstrained(Zone* zone) { |
- LUnallocated* result = new(zone) LUnallocated(ANY); |
- result->set_virtual_register(virtual_register()); |
- return result; |
+ // [fixed_slot_index]: Only for FIXED_SLOT. |
+ int fixed_slot_index() const { |
+ ASSERT(HasFixedSlotPolicy()); |
+ return static_cast<int>(value_) >> FixedSlotIndexField::kShift; |
} |
- static LUnallocated* cast(LOperand* op) { |
- ASSERT(op->IsUnallocated()); |
- return reinterpret_cast<LUnallocated*>(op); |
+ // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER. |
+ int fixed_register_index() const { |
+ ASSERT(HasFixedRegisterPolicy() || HasFixedDoubleRegisterPolicy()); |
+ return FixedRegisterField::decode(value_); |
} |
- bool IsUsedAtStart() { |
- return LifetimeField::decode(value_) == USED_AT_START; |
+ // [virtual_register]: The virtual register ID for this operand. |
+ int virtual_register() const { |
+ return VirtualRegisterField::decode(value_); |
+ } |
+ void set_virtual_register(unsigned id) { |
+ value_ = VirtualRegisterField::update(value_, id); |
} |
- private: |
- void Initialize(Policy policy, int fixed_index, Lifetime lifetime) { |
- value_ |= PolicyField::encode(policy); |
- value_ |= LifetimeField::encode(lifetime); |
- value_ |= fixed_index << kFixedIndexShift; |
- ASSERT(this->fixed_index() == fixed_index); |
+ // [lifetime]: Only for non-FIXED_SLOT. |
+ bool IsUsedAtStart() { |
+ ASSERT(basic_policy() == EXTENDED_POLICY); |
+ return LifetimeField::decode(value_) == USED_AT_START; |
} |
}; |