ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DisassemblerPowerpc.h
Go to the documentation of this file.
1 /* Disassembly specific to the PowerPC architecture. */
2 
3 #ifndef ROSE_DISASSEMBLER_POWERPC_H
4 #define ROSE_DISASSEMBLER_POWERPC_H
5 
6 #include "integerOps.h"
7 #include "sageBuilderAsm.h"
8 
11 public:
12  DisassemblerPowerpc(): ip(0), insn(0) { init(); }
13  DisassemblerPowerpc(const DisassemblerPowerpc& other): Disassembler(other), ip(other.ip), insn(other.insn) {}
14  virtual ~DisassemblerPowerpc() {}
15  virtual DisassemblerPowerpc *clone() const { return new DisassemblerPowerpc(*this); }
16  virtual bool can_disassemble(SgAsmGenericHeader*) const;
17  virtual SgAsmInstruction *disassembleOne(const MemoryMap *map, rose_addr_t start_va, AddressSet *successors=NULL);
18  virtual void assembleOne(SgAsmInstruction*, SgUnsignedCharList&) {abort();}
19  virtual SgAsmInstruction *make_unknown_instruction(const Exception&);
20 private:
24  class ExceptionPowerpc: public Exception {
25  public:
26  ExceptionPowerpc(const std::string &mesg, const DisassemblerPowerpc *d, size_t bit=0)
27  : Exception(mesg, d->ip) {
28  /* Convert four-byte instruction to big-endian buffer. Note that PowerPC is big-endian, but PowerPC can support
29  * both big- and little-endian processor modes (with much weirdness; e.g. PDP endian like propoerties). */
30  bytes.push_back((d->insn>>24) & 0xff);
31  bytes.push_back((d->insn>>16) & 0xff);
32  bytes.push_back((d->insn>>8) & 0xff);
33  bytes.push_back(d->insn & 0xff);
34  ROSE_ASSERT(bit<=32);
35  this->bit = 8*(4-(bit/8)) + bit%8; /*convert from native uint32_t bit position to big-endian*/
36  }
37  };
38 
40  makeRegister(PowerpcRegisterClass reg_class, int reg_number,
41  PowerpcConditionRegisterAccessGranularity reg_grainularity = powerpc_condreggranularity_whole) const;
42 
43  static SgAsmPowerpcInstruction *makeInstructionWithoutOperands(uint64_t address, const std::string& mnemonic,
44  PowerpcInstructionKind kind, uint32_t insn);
45 
47  template <size_t First, size_t Last> uint32_t fld() const;
48 
49  /* Decoded fields from section 1.7.16 of the v2.01 UISA */
50  bool AA() const {
51  return fld<30, 30>();
52  }
54  return makeRegister(powerpc_regclass_cr, fld<11, 15>(), powerpc_condreggranularity_bit);
55  }
57  return makeRegister(powerpc_regclass_cr, fld<16, 20>(), powerpc_condreggranularity_bit);
58  }
59  uint64_t BD() const {
60  return IntegerOps::signExtend<16, 64>((uint64_t)insn & 0xfffc);
61  }
63  return makeRegister(powerpc_regclass_cr, fld<6, 8>(), powerpc_condreggranularity_field);
64  }
66  return makeRegister(powerpc_regclass_fpscr, fld<6, 8>(), powerpc_condreggranularity_field);
67  }
69  return makeRegister(powerpc_regclass_cr, fld<11, 13>(), powerpc_condreggranularity_field);
70  }
72  return makeRegister(powerpc_regclass_fpscr, fld<11, 13>(), powerpc_condreggranularity_field);
73  }
75  return SageBuilderAsm::makeByteValue(fld<19, 20>());
76  }
78  return BA();
79  }
81  return SageBuilderAsm::makeByteValue(fld<6, 10>());
82  }
84  return makeRegister(powerpc_regclass_cr, fld<6, 10>(), powerpc_condreggranularity_bit);
85  }
87  return SageBuilderAsm::makeQWordValue(IntegerOps::signExtend<16, 64>((uint64_t)fld<16, 31>()));
88  }
90  return SageBuilderAsm::makeQWordValue(IntegerOps::signExtend<16, 64>((uint64_t)fld<16, 31>() & 0xfffc));
91  }
93  return SageBuilderAsm::makeByteValue(fld<7, 14>());
94  }
96  return makeRegister(powerpc_regclass_fpr, fld<11, 15>());
97  }
99  return makeRegister(powerpc_regclass_fpr, fld<16, 20>());
100  }
102  return makeRegister(powerpc_regclass_fpr, fld<21, 25>());
103  }
105  return makeRegister(powerpc_regclass_fpr, fld<6, 10>());
106  }
108  return FRS();
109  }
111  return SageBuilderAsm::makeByteValue(fld<12, 19>());
112  }
113 
115  return SageBuilderAsm::makeByteValue(fld<10, 10>());
116  }
118  return SageBuilderAsm::makeByteValue(fld<15, 15>());
119  }
120  uint8_t L_sync() const {
121  return fld<9, 10>();
122  }
124  return SageBuilderAsm::makeByteValue(fld<20, 26>());
125  }
126  uint64_t LI() const {
127  return IntegerOps::signExtend<26, 64>(uint64_t(fld<6, 29>() * 4));
128  }
129  bool LK() const {
130  return fld<31, 31>();
131  }
133  return SageBuilderAsm::makeByteValue(fld<21, 25>());
134  }
136  return SageBuilderAsm::makeByteValue(fld<26, 30>());
137  }
139  return SageBuilderAsm::makeByteValue(fld<21, 26>()); // FIXME check for splitting
140  }
142  return SageBuilderAsm::makeByteValue(fld<21, 26>()); // FIXME check for splitting
143  }
145  return SageBuilderAsm::makeByteValue(fld<16, 20>() == 0 ? 32 : fld<16, 20>());
146  }
147  bool OE() const {
148  return fld<21, 21>();
149  }
151  return makeRegister(powerpc_regclass_gpr, fld<11, 15>());
152  }
154  return fld<11, 15>() == 0 ? (SgAsmExpression*)SageBuilderAsm::makeByteValue(0) : RA();
155  }
157  return makeRegister(powerpc_regclass_gpr, fld<16, 20>());
158  }
159  bool Rc() const {
160  return fld<31, 31>();
161  }
163  return makeRegister(powerpc_regclass_gpr, fld<6, 10>());
164  }
166  return RS();
167  }
169  return SageBuilderAsm::makeByteValue(fld<16, 20>());
170  }
172  return SageBuilderAsm::makeByteValue(fld<16, 20>() + fld<30, 30>() * 32); // FIXME check
173  }
175  return D();
176  }
178  return makeRegister(powerpc_regclass_spr, fld<16, 20>() * 32 + fld<11, 15>());
179  }
181  return makeRegister(powerpc_regclass_sr, fld<12, 15>());
182  }
184  return makeRegister(powerpc_regclass_tbr, fld<16, 20>() * 32 + fld<11, 15>());
185  }
187  return SageBuilderAsm::makeByteValue(fld<9, 10>());
188  }
190  return SageBuilderAsm::makeByteValue(fld<6, 10>());
191  }
193  return SageBuilderAsm::makeByteValue(fld<16, 19>());
194  }
196  return SageBuilderAsm::makeQWordValue(fld<16, 31>());
197  }
198 
201  }
204  }
206  if (fld<11, 15>() == 0)
207  throw ExceptionPowerpc("bits 11-15 must be nonzero", this);
209  }
211  if (fld<11, 15>() == 0)
212  throw ExceptionPowerpc("bits 11-15 must be nonzero", this);
214  }
215 
216  /* There are 15 different forms of PowerPC instructions, but all are 32-bit (fixed length instruction set). */
232 
233  SgAsmIntegerValueExpression* makeBranchTarget( uint64_t targetAddr ) const;
234 
236 
238  void init();
239 
241  void startInstruction(rose_addr_t start_va, uint32_t c) {
242  ip = start_va;
243  insn = c;
244  }
245 
246  /* Per-instruction data members (mostly set by startInstruction()) */
247  uint64_t ip;
248  uint32_t insn;
249 };
250 
251 #endif