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