| Index: runtime/vm/locations.h
|
| diff --git a/runtime/vm/locations.h b/runtime/vm/locations.h
|
| index 41a9bdc951f9196818c342392b046c93959903c1..2ddc06501605c80b209ac16915e618c8bf2c0c91 100644
|
| --- a/runtime/vm/locations.h
|
| +++ b/runtime/vm/locations.h
|
| @@ -35,6 +35,9 @@ class Location : public ValueObject {
|
| static const intptr_t kStackIndexBias =
|
| static_cast<intptr_t>(1) << (kBitsForPayload - 1);
|
|
|
| + static const intptr_t kMachineRegisterMask = 0x6;
|
| + static const intptr_t kMachineRegister = 0x6;
|
| +
|
| public:
|
| // Constant payload can overlap with kind field so Kind values
|
| // have to be chosen in a way that their last 2 bits are never
|
| @@ -52,13 +55,18 @@ class Location : public ValueObject {
|
| // contains register allocation policy.
|
| kUnallocated = 2,
|
|
|
| + // Spill slot allocated by the register allocator. Payload contains
|
| + // a spill index.
|
| + kStackSlot = 3,
|
| + kDoubleStackSlot = 4,
|
| +
|
| // Register location represents a fixed register. Payload contains
|
| // register code.
|
| - kRegister = 3,
|
| + kRegister = 6,
|
|
|
| - // Spill slot allocated by the register allocator. Payload contains
|
| - // a spill index.
|
| - kStackSlot = 4,
|
| + // XmmRegister location represents a fixed xmm register. Payload contains
|
| + // its code.
|
| + kXmmRegister = 7,
|
| };
|
|
|
| Location() : value_(kInvalidLocation) {
|
| @@ -92,6 +100,7 @@ class Location : public ValueObject {
|
| kAny,
|
| kPrefersRegister,
|
| kRequiresRegister,
|
| + kRequiresXmmRegister,
|
| kSameAsFirstInput,
|
| };
|
|
|
| @@ -120,6 +129,10 @@ class Location : public ValueObject {
|
| return UnallocatedLocation(kRequiresRegister);
|
| }
|
|
|
| + static Location RequiresXmmRegister() {
|
| + return UnallocatedLocation(kRequiresXmmRegister);
|
| + }
|
| +
|
| // The location of the first input to the instruction will be
|
| // used to replace this unallocated location.
|
| static Location SameAsFirstInput() {
|
| @@ -150,6 +163,37 @@ class Location : public ValueObject {
|
| return static_cast<Register>(payload());
|
| }
|
|
|
| + // XmmRegister locations.
|
| + static Location XmmRegisterLocation(XmmRegister reg) {
|
| + return Location(kXmmRegister, static_cast<uword>(reg));
|
| + }
|
| +
|
| + bool IsXmmRegister() const {
|
| + return kind() == kXmmRegister;
|
| + }
|
| +
|
| + XmmRegister xmm_reg() const {
|
| + ASSERT(IsXmmRegister());
|
| + return static_cast<XmmRegister>(payload());
|
| + }
|
| +
|
| + static bool IsMachineRegisterKind(Kind kind) {
|
| + return (kind & kMachineRegisterMask) == kMachineRegister;
|
| + }
|
| +
|
| + static Location MachineRegisterLocation(Kind kind, intptr_t reg) {
|
| + return Location(kind, reg);
|
| + }
|
| +
|
| + bool IsMachineRegister() const {
|
| + return IsMachineRegisterKind(kind());
|
| + }
|
| +
|
| + intptr_t register_code() const {
|
| + ASSERT(IsMachineRegister());
|
| + return static_cast<intptr_t>(payload());
|
| + }
|
| +
|
| // Spill slots.
|
| static Location StackSlot(intptr_t stack_index) {
|
| ASSERT((-kStackIndexBias <= stack_index) &&
|
| @@ -164,8 +208,23 @@ class Location : public ValueObject {
|
| return kind() == kStackSlot;
|
| }
|
|
|
| + static Location DoubleStackSlot(intptr_t stack_index) {
|
| + ASSERT((-kStackIndexBias <= stack_index) &&
|
| + (stack_index < kStackIndexBias));
|
| + Location loc(kDoubleStackSlot,
|
| + static_cast<uword>(kStackIndexBias + stack_index));
|
| + // Ensure that sign is preserved.
|
| + ASSERT(loc.stack_index() == stack_index);
|
| + return loc;
|
| + }
|
| +
|
| + bool IsDoubleStackSlot() const {
|
| + return kind() == kDoubleStackSlot;
|
| + }
|
| +
|
| +
|
| intptr_t stack_index() const {
|
| - ASSERT(IsStackSlot());
|
| + ASSERT(IsStackSlot() || IsDoubleStackSlot());
|
| // Decode stack index manually to preserve sign.
|
| return payload() - kStackIndexBias;
|
| }
|
| @@ -199,7 +258,7 @@ class Location : public ValueObject {
|
| typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField;
|
|
|
| // Layout for kUnallocated locations payload.
|
| - typedef BitField<Policy, 0, 2> PolicyField;
|
| + typedef BitField<Policy, 0, 3> PolicyField;
|
|
|
| // Location either contains kind and payload fields or a tagged handle for
|
| // a constant locations. Values of enumeration Kind are selected in such a
|
| @@ -210,20 +269,49 @@ class Location : public ValueObject {
|
|
|
| class RegisterSet : public ValueObject {
|
| public:
|
| - RegisterSet() : registers_(0) {
|
| + RegisterSet() : cpu_registers_(0), xmm_registers_(0) {
|
| ASSERT(kNumberOfCpuRegisters < (kWordSize * kBitsPerByte));
|
| + ASSERT(kNumberOfXmmRegisters < (kWordSize * kBitsPerByte));
|
| + }
|
| +
|
| +
|
| + void Add(Location loc) {
|
| + if (loc.IsRegister()) {
|
| + cpu_registers_ |= (1 << loc.reg());
|
| + } else if (loc.IsXmmRegister()) {
|
| + xmm_registers_ |= (1 << loc.xmm_reg());
|
| + }
|
| + }
|
| +
|
| + void Remove(Location loc) {
|
| + if (loc.IsRegister()) {
|
| + cpu_registers_ &= ~(1 << loc.reg());
|
| + } else if (loc.IsXmmRegister()) {
|
| + xmm_registers_ &= ~(1 << loc.xmm_reg());
|
| + }
|
| + }
|
| +
|
| + bool ContainsRegister(Register reg) {
|
| + return (cpu_registers_ & (1 << reg)) != 0;
|
| }
|
|
|
| - void Add(Register reg) {
|
| - registers_ |= (1 << reg);
|
| + bool ContainsXmmRegister(XmmRegister xmm_reg) {
|
| + return (xmm_registers_ & (1 << xmm_reg)) != 0;
|
| }
|
|
|
| - bool Contains(Register reg) {
|
| - return (registers_ & (1 << reg)) != 0;
|
| + intptr_t xmm_regs_count() {
|
| + intptr_t count = 0;
|
| + for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; reg_idx++) {
|
| + if (ContainsXmmRegister(static_cast<XmmRegister>(reg_idx))) {
|
| + count++;
|
| + }
|
| + }
|
| + return count;
|
| }
|
|
|
| private:
|
| - intptr_t registers_;
|
| + intptr_t cpu_registers_;
|
| + intptr_t xmm_registers_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(RegisterSet);
|
| };
|
|
|