Massive changes to get InstructionAPI working with new MachRegister class.
[dyninst.git] / common / src / dyn_regs.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #define DYN_DEFINE_REGS
33 #include "dynutil/h/dyn_regs.h"
34
35 namespace Dyninst {
36
37 std::map<signed int, const char *> *Dyninst::MachRegister::names;
38
39 MachRegister::MachRegister() :
40    reg(0)
41
42 }
43
44 MachRegister::MachRegister(signed int r) :
45    reg(r)
46 {
47 }
48  
49 MachRegister::MachRegister(const MachRegister& r) :
50         reg(r.reg)
51 {
52 }
53
54 MachRegister::MachRegister(signed int r, const char *n) :
55    reg(r)
56 {
57    if (!names) {
58       names = new std::map<signed int, const char *>();
59    }
60    (*names)[r] = n;
61 }
62
63 MachRegister::~MachRegister() {
64 }
65
66 MachRegister MachRegister::getBaseRegister() const { 
67    switch (getArchitecture()) {
68       case Arch_x86:
69       case Arch_x86_64:
70           return MachRegister(reg & 0xfffff0ff);
71       case Arch_ppc32:
72       case Arch_ppc64:
73          return *this;
74       case Arch_none:
75          return *this;
76    }
77    return InvalidReg;
78 }
79    
80 Architecture MachRegister::getArchitecture() const { 
81    return (Architecture) (reg & 0xff000000);
82 }
83
84 bool MachRegister::isValid() const {
85    return (reg != InvalidReg.reg);
86 }
87
88 MachRegisterVal MachRegister::getSubRegValue(const MachRegister subreg, 
89                                              MachRegisterVal &orig) const
90 {
91    if (subreg.reg == reg || 
92        getArchitecture() == Arch_ppc32 ||
93        getArchitecture() == Arch_ppc64)
94       return orig;
95
96    assert(subreg.getBaseRegister() == getBaseRegister());
97    switch ((subreg.reg & 0x00000f00) >> 8) {
98       case 0x0: return orig;
99       case 0x1: return (orig & 0xff);
100       case 0x2: return (orig & 0xff00) >> 8;              
101       case 0x3: return (orig & 0xffff);
102       case 0xf: return (orig & 0xffffffff);
103       default: assert(0);
104    }
105 }
106
107 const char *MachRegister::name() const { 
108    return (*names)[reg];
109 }
110
111 unsigned int MachRegister::size() const {
112    switch (getArchitecture())
113    {
114       case Arch_x86:
115          switch (reg & 0x0000ff00) {
116              case x86::L_REG: //L_REG
117             case x86::H_REG: //H_REG
118                return 1;
119                case x86::W_REG: //W_REG
120                return 2;
121                case x86::FULL: //FULL
122                return 4;
123              case x86::QUAD:
124                 return 8;
125              case x86::OCT:
126                  return 16;
127              case x86::FPDBL:
128                  return 10;
129              default:
130                assert(0);
131          }
132       case Arch_x86_64:
133          switch (reg & 0x0000ff00) {
134              case x86_64::L_REG: //L_REG
135              case x86_64::H_REG: //H_REG
136                 return 1;
137              case x86_64::W_REG: //W_REG
138                 return 2;
139              case x86_64::FULL: //FULL
140                 return 8;
141              case x86_64::D_REG:
142                  return 4;
143              case x86_64::OCT:
144                  return 16;
145              case x86_64::FPDBL:
146                  return 10;
147              default:
148                assert(0);
149          }
150       case Arch_ppc32: {
151          int reg_class = reg & 0x00ff0000;
152          if (reg_class == ppc32::FPR || reg_class == ppc32::FSR)
153             return 8;
154          return 4;
155       }
156       case Arch_ppc64:
157          return 8;
158       case Arch_none:
159          return 0;
160    }
161    return 0; //Unreachable, but disable warnings
162 }
163    
164 bool MachRegister::operator<(const MachRegister &a) const { 
165    return (reg < a.reg);
166 }
167  
168 bool MachRegister::operator==(const MachRegister &a) const { 
169    return (reg == a.reg);
170 }
171 /* 
172 MachRegister::operator signed int() const {
173    return reg;
174 }
175 */
176 signed int MachRegister::val() const {
177    return reg;
178 }
179
180
181 MachRegister MachRegister::getPC(Dyninst::Architecture arch)
182 {
183    switch (arch)
184    {
185       case Arch_x86:
186          return x86::eip;
187       case Arch_x86_64:
188          return x86_64::rip;
189       case Arch_ppc32:
190          return ppc32::pc;
191       case Arch_ppc64:
192          return ppc64::pc;
193       case Arch_none:
194          return InvalidReg;
195    }
196    return InvalidReg;
197 }
198
199 MachRegister MachRegister::getFramePointer(Dyninst::Architecture arch)
200 {
201    switch (arch)
202    {
203       case Arch_x86:
204          return x86::ebp;
205       case Arch_x86_64:
206          return x86_64::rbp;
207       case Arch_ppc32:
208       case Arch_ppc64:
209          return FrameBase;
210       case Arch_none:
211          return InvalidReg;
212    }
213    return InvalidReg;
214 }
215
216 MachRegister MachRegister::getStackPointer(Dyninst::Architecture arch)
217 {
218    switch (arch)
219    {
220       case Arch_x86:
221          return x86::esp;
222       case Arch_x86_64:
223          return x86_64::rsp;
224       case Arch_ppc32:
225          return ppc32::r1;
226       case Arch_ppc64:
227          return ppc64::r1;
228       case Arch_none:
229          return InvalidReg;
230    }
231    return InvalidReg;
232 }
233
234 bool MachRegister::isPC() const
235 {
236    return (*this == x86_64::rip || *this == x86::eip ||
237            *this == ppc32::pc || *this == ppc64::pc);
238 }
239
240 bool MachRegister::isFramePointer() const
241 {
242    return (*this == x86_64::rbp || *this == x86::ebp ||
243            *this == FrameBase);
244 }
245
246 bool MachRegister::isStackPointer() const
247 {
248    return (*this == x86_64::rsp || *this == x86::esp ||
249            *this == ppc32::r1 || *this == ppc64::r1);
250 }
251
252 }