managed_register_x86.h revision 2c8f653c98d658419f464b6147c10e11a664d2e6
1b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Copyright 2011 Google Inc. All Rights Reserved. 2b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 3b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#ifndef ART_SRC_MANAGED_REGISTER_X86_H_ 4b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#define ART_SRC_MANAGED_REGISTER_X86_H_ 5b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 6578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "constants_x86.h" 72c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#include "managed_register.h" 8b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 9b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersnamespace art { 102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace x86 { 11b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 12b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Values for register pairs. 13b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// The registers in kReservedCpuRegistersArray in x86.cc are not used in pairs. 14b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// The table kRegisterPairs in x86.cc must be kept in sync with this enum. 15b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersenum RegisterPair { 16b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EAX_EDX = 0, 17b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EAX_ECX = 1, 18b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EAX_EBX = 2, 19b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EAX_EDI = 3, 20b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EDX_ECX = 4, 21b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EDX_EBX = 5, 22b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EDX_EDI = 6, 23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ECX_EBX = 7, 24b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ECX_EDI = 8, 25b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers EBX_EDI = 9, 26b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfRegisterPairs = 10, 27b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNoRegisterPair = -1, 28b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 29b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 30b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const RegisterPair& reg); 31b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 32b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfCpuRegIds = kNumberOfCpuRegisters; 33b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfCpuAllocIds = kNumberOfCpuRegisters; 34b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 35b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfXmmRegIds = kNumberOfXmmRegisters; 36b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfXmmAllocIds = kNumberOfXmmRegisters; 37b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 38b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfX87RegIds = kNumberOfX87Registers; 39b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfX87AllocIds = kNumberOfX87Registers; 40b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 41b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfPairRegIds = kNumberOfRegisterPairs; 42b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 43b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfRegIds = kNumberOfCpuRegIds + kNumberOfXmmRegIds + 44b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfX87RegIds + kNumberOfPairRegIds; 45b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersconst int kNumberOfAllocIds = kNumberOfCpuAllocIds + kNumberOfXmmAllocIds + 46b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfX87RegIds; 47b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 48b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Register ids map: 49b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [0..R[ cpu registers (enum Register) 50b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [R..X[ xmm registers (enum XmmRegister) 51b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [X..S[ x87 registers (enum X87Register) 52b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [S..P[ register pairs (enum RegisterPair) 53b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// where 54b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// R = kNumberOfCpuRegIds 55b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// X = R + kNumberOfXmmRegIds 56b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// S = X + kNumberOfX87RegIds 57b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// P = X + kNumberOfRegisterPairs 58b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 59b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Allocation ids map: 60b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [0..R[ cpu registers (enum Register) 61b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [R..X[ xmm registers (enum XmmRegister) 62b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// [X..S[ x87 registers (enum X87Register) 63b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// where 64b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// R = kNumberOfCpuRegIds 65b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// X = R + kNumberOfXmmRegIds 66b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// S = X + kNumberOfX87RegIds 67b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 68b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// An instance of class 'ManagedRegister' represents a single cpu register (enum 70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Register), an xmm register (enum XmmRegister), or a pair of cpu registers 71b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// (enum RegisterPair). 72b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// 'ManagedRegister::NoRegister()' provides an invalid register. 73b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// There is a one-to-one mapping between ManagedRegister and register id. 742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersclass X86ManagedRegister : public ManagedRegister { 75b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public: 76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register AsCpuRegister() const { 77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsCpuRegister()); 78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<Register>(id_); 79b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 80b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers XmmRegister AsXmmRegister() const { 82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsXmmRegister()); 83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<XmmRegister>(id_ - kNumberOfCpuRegIds); 84b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 85b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 86b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers X87Register AsX87Register() const { 87b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsX87Register()); 88b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return static_cast<X87Register>(id_ - 89b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers (kNumberOfCpuRegIds + kNumberOfXmmRegIds)); 90b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 92b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register AsRegisterPairLow() const { 93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsRegisterPair()); 94b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Appropriate mapping of register ids allows to use AllocIdLow(). 95b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(AllocIdLow()).AsCpuRegister(); 96b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 97b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 98b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register AsRegisterPairHigh() const { 99b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsRegisterPair()); 100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Appropriate mapping of register ids allows to use AllocIdHigh(). 101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(AllocIdHigh()).AsCpuRegister(); 102b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 103b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 104b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsCpuRegister() const { 105b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 106b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= id_) && (id_ < kNumberOfCpuRegIds); 107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsXmmRegister() const { 110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = id_ - kNumberOfCpuRegIds; 112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfXmmRegIds); 113b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 114b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 115b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsX87Register() const { 116b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 117b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = id_ - (kNumberOfCpuRegIds + kNumberOfXmmRegIds); 118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfXmmRegIds); 119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 120b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 121b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsRegisterPair() const { 122b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister()); 123b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers const int test = id_ - 124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers (kNumberOfCpuRegIds + kNumberOfXmmRegIds + kNumberOfX87RegIds); 125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= test) && (test < kNumberOfPairRegIds); 126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 128b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void Print(std::ostream& os) const; 129b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Returns true if the two managed-registers ('this' and 'other') overlap. 131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Either managed-register may be the NoRegister. If both are the NoRegister 132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // then false is returned. 1332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers bool Overlaps(const X86ManagedRegister& other) const; 134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static X86ManagedRegister FromCpuRegister(Register r) { 136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoRegister); 137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r); 138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static X86ManagedRegister FromXmmRegister(XmmRegister r) { 141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoXmmRegister); 142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r + kNumberOfCpuRegIds); 143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1452c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static X86ManagedRegister FromX87Register(X87Register r) { 146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoX87Register); 147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r + kNumberOfCpuRegIds + kNumberOfXmmRegIds); 148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static X86ManagedRegister FromRegisterPair(RegisterPair r) { 151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_NE(r, kNoRegisterPair); 152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return FromRegId(r + (kNumberOfCpuRegIds + kNumberOfXmmRegIds + 153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNumberOfX87RegIds)); 154b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 155b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private: 157b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers bool IsValidManagedRegister() const { 158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return (0 <= id_) && (id_ < kNumberOfRegIds); 159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int RegId() const { 162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(!IsNoRegister()); 163b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return id_; 164b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 165b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 166b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int AllocId() const { 167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsValidManagedRegister() && !IsRegisterPair()); 168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_LT(id_, kNumberOfAllocIds); 169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return id_; 170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 172b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int AllocIdLow() const; 173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int AllocIdHigh() const; 174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers friend class ManagedRegister; 1762c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 1772c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers X86ManagedRegister(int reg_id) : ManagedRegister(reg_id) {} 1782c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 1792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers static X86ManagedRegister FromRegId(int reg_id) { 1802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers X86ManagedRegister reg(reg_id); 181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(reg.IsValidManagedRegister()); 182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return reg; 183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 185b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersstd::ostream& operator<<(std::ostream& os, const X86ManagedRegister& reg); 1872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 1882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} // namespace x86 1892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 1902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersinline x86::X86ManagedRegister ManagedRegister::AsX86() const { 1912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers x86::X86ManagedRegister reg(id_); 1922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers CHECK(reg.IsNoRegister() || reg.IsValidManagedRegister()); 1932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return reg; 1942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} 195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} // namespace art 197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#endif // ART_SRC_MANAGED_REGISTER_X86_H_ 199