DisassemblerPowerpc.h

Go to the documentation of this file.
00001 /* Disassembly specific to the PowerPC architecture. */
00002 
00003 #ifndef ROSE_DISASSEMBLER_POWERPC_H
00004 #define ROSE_DISASSEMBLER_POWERPC_H
00005 
00006 #include "integerOps.h"
00007 #include "sageBuilderAsm.h"
00008 
00010 class DisassemblerPowerpc: public Disassembler {
00011 public:
00012     DisassemblerPowerpc(): ip(0), insn(0) { init(); }
00013     DisassemblerPowerpc(const DisassemblerPowerpc& other): Disassembler(other), ip(other.ip), insn(other.insn) {}
00014     virtual ~DisassemblerPowerpc() {}
00015     virtual DisassemblerPowerpc *clone() const { return new DisassemblerPowerpc(*this); }
00016     virtual bool can_disassemble(SgAsmGenericHeader*) const;
00017     virtual SgAsmInstruction *disassembleOne(const MemoryMap *map, rose_addr_t start_va, AddressSet *successors=NULL);
00018     virtual void assembleOne(SgAsmInstruction*, SgUnsignedCharList&) {abort();}
00019     virtual SgAsmInstruction *make_unknown_instruction(const Exception&);
00020 private:
00024     class ExceptionPowerpc: public Exception {
00025     public:
00026         ExceptionPowerpc(const std::string &mesg, const DisassemblerPowerpc *d, size_t bit=0)
00027             : Exception(mesg, d->ip) {
00028             /* Convert four-byte instruction to big-endian buffer. Note that PowerPC is big-endian, but PowerPC can support
00029              * both big- and little-endian processor modes (with much weirdness; e.g. PDP endian like propoerties). */
00030             bytes.push_back((d->insn>>24) & 0xff);
00031             bytes.push_back((d->insn>>16) & 0xff);
00032             bytes.push_back((d->insn>>8) & 0xff);
00033             bytes.push_back(d->insn & 0xff);
00034             ROSE_ASSERT(bit<=32);
00035             this->bit = 8*(4-(bit/8)) + bit%8; /*convert from native uint32_t bit position to big-endian*/
00036         }
00037     };
00038 
00039     SgAsmPowerpcRegisterReferenceExpression *
00040     makeRegister(PowerpcRegisterClass reg_class, int reg_number,
00041                  PowerpcConditionRegisterAccessGranularity reg_grainularity = powerpc_condreggranularity_whole) const;
00042 
00043     static SgAsmPowerpcInstruction *makeInstructionWithoutOperands(uint64_t address, const std::string& mnemonic,
00044                                                                    PowerpcInstructionKind kind, uint32_t insn);
00045 
00047     template <size_t First, size_t Last> uint32_t fld() const;
00048 
00049     /* Decoded fields from section 1.7.16 of the v2.01 UISA */
00050     bool AA() const {
00051         return fld<30, 30>();
00052     }
00053     SgAsmPowerpcRegisterReferenceExpression *BA() const {
00054         return makeRegister(powerpc_regclass_cr, fld<11, 15>(), powerpc_condreggranularity_bit);
00055     }
00056     SgAsmPowerpcRegisterReferenceExpression *BB() const {
00057         return makeRegister(powerpc_regclass_cr, fld<16, 20>(), powerpc_condreggranularity_bit);
00058     }
00059     uint64_t BD() const {
00060         return IntegerOps::signExtend<16, 64>((uint64_t)insn & 0xfffc);
00061     }
00062     SgAsmPowerpcRegisterReferenceExpression* BF_cr() const {
00063         return makeRegister(powerpc_regclass_cr, fld<6, 8>(), powerpc_condreggranularity_field);
00064     }
00065     SgAsmPowerpcRegisterReferenceExpression* BF_fpscr() const {
00066         return makeRegister(powerpc_regclass_fpscr, fld<6, 8>(), powerpc_condreggranularity_field);
00067     }
00068     SgAsmPowerpcRegisterReferenceExpression* BFA_cr() const {
00069         return makeRegister(powerpc_regclass_cr, fld<11, 13>(), powerpc_condreggranularity_field);
00070     }
00071     SgAsmPowerpcRegisterReferenceExpression* BFA_fpscr() const {
00072         return makeRegister(powerpc_regclass_fpscr, fld<11, 13>(), powerpc_condreggranularity_field);
00073     }
00074     SgAsmValueExpression* BH() const {
00075         return SageBuilderAsm::makeByteValue(fld<19, 20>());
00076     }
00077     SgAsmPowerpcRegisterReferenceExpression* BI() const {
00078         return BA();
00079     }
00080     SgAsmValueExpression* BO() const {
00081         return SageBuilderAsm::makeByteValue(fld<6, 10>());
00082     }
00083     SgAsmPowerpcRegisterReferenceExpression* BT() const {
00084         return makeRegister(powerpc_regclass_cr, fld<6, 10>(), powerpc_condreggranularity_bit);
00085     }
00086     SgAsmValueExpression* D() const {
00087         return SageBuilderAsm::makeQWordValue(IntegerOps::signExtend<16, 64>((uint64_t)fld<16, 31>()));
00088     }
00089     SgAsmValueExpression* DS() const {
00090         return SageBuilderAsm::makeQWordValue(IntegerOps::signExtend<16, 64>((uint64_t)fld<16, 31>() & 0xfffc));
00091     }
00092     SgAsmValueExpression* FLM() const {
00093         return SageBuilderAsm::makeByteValue(fld<7, 14>());
00094     }
00095     SgAsmPowerpcRegisterReferenceExpression* FRA() const {
00096         return makeRegister(powerpc_regclass_fpr, fld<11, 15>());
00097     }
00098     SgAsmPowerpcRegisterReferenceExpression* FRB() const {
00099         return makeRegister(powerpc_regclass_fpr, fld<16, 20>());
00100     }
00101     SgAsmPowerpcRegisterReferenceExpression* FRC() const {
00102         return makeRegister(powerpc_regclass_fpr, fld<21, 25>());
00103     }
00104     SgAsmPowerpcRegisterReferenceExpression* FRS() const {
00105         return makeRegister(powerpc_regclass_fpr, fld<6, 10>());
00106     }
00107     SgAsmPowerpcRegisterReferenceExpression* FRT() const {
00108         return FRS();
00109     }
00110     SgAsmValueExpression* FXM() const {
00111         return SageBuilderAsm::makeByteValue(fld<12, 19>());
00112     }
00113           
00114     SgAsmValueExpression* L_10() const {
00115         return SageBuilderAsm::makeByteValue(fld<10, 10>());
00116     }
00117     SgAsmValueExpression* L_15() const {
00118         return SageBuilderAsm::makeByteValue(fld<15, 15>());
00119     }
00120     uint8_t L_sync() const {
00121         return fld<9, 10>();
00122     }
00123     SgAsmValueExpression* LEV() const {
00124         return SageBuilderAsm::makeByteValue(fld<20, 26>());
00125     }
00126     uint64_t LI() const {
00127         return IntegerOps::signExtend<26, 64>(uint64_t(fld<6, 29>() * 4));
00128     }
00129     bool LK() const {
00130         return fld<31, 31>();
00131     }
00132     SgAsmValueExpression* MB_32bit() const {
00133         return SageBuilderAsm::makeByteValue(fld<21, 25>());
00134     }
00135     SgAsmValueExpression* ME_32bit() const {
00136         return SageBuilderAsm::makeByteValue(fld<26, 30>());
00137     }
00138     SgAsmValueExpression* MB_64bit() const {
00139         return SageBuilderAsm::makeByteValue(fld<21, 26>()); // FIXME check for splitting
00140     } 
00141     SgAsmValueExpression* ME_64bit() const {
00142         return SageBuilderAsm::makeByteValue(fld<21, 26>()); // FIXME check for splitting
00143     }   
00144     SgAsmValueExpression* NB() const {
00145         return SageBuilderAsm::makeByteValue(fld<16, 20>() == 0 ? 32 : fld<16, 20>());
00146     }
00147     bool OE() const {
00148         return fld<21, 21>();
00149     }
00150     SgAsmPowerpcRegisterReferenceExpression* RA() const {
00151         return makeRegister(powerpc_regclass_gpr, fld<11, 15>());
00152     }
00153     SgAsmExpression* RA_or_zero() const {
00154         return fld<11, 15>() == 0 ? (SgAsmExpression*)SageBuilderAsm::makeByteValue(0) : RA();
00155     }
00156     SgAsmPowerpcRegisterReferenceExpression* RB() const {
00157         return makeRegister(powerpc_regclass_gpr, fld<16, 20>());
00158     }
00159     bool Rc() const {
00160         return fld<31, 31>();
00161     }
00162     SgAsmPowerpcRegisterReferenceExpression* RS() const {
00163         return makeRegister(powerpc_regclass_gpr, fld<6, 10>());
00164     }
00165     SgAsmPowerpcRegisterReferenceExpression* RT() const {
00166         return RS();
00167     }
00168     SgAsmValueExpression* SH_32bit() const {
00169         return SageBuilderAsm::makeByteValue(fld<16, 20>());
00170     }
00171     SgAsmValueExpression* SH_64bit() const {
00172         return SageBuilderAsm::makeByteValue(fld<16, 20>() + fld<30, 30>() * 32); // FIXME check
00173     } 
00174     SgAsmValueExpression* SI() const {
00175         return D();
00176     }
00177     SgAsmPowerpcRegisterReferenceExpression* SPR() const {
00178         return makeRegister(powerpc_regclass_spr, fld<16, 20>() * 32 + fld<11, 15>());
00179     }
00180     SgAsmPowerpcRegisterReferenceExpression* SR() const {
00181         return makeRegister(powerpc_regclass_sr, fld<12, 15>());
00182     }
00183     SgAsmPowerpcRegisterReferenceExpression* TBR() const {
00184         return makeRegister(powerpc_regclass_tbr, fld<16, 20>() * 32 + fld<11, 15>());
00185     }
00186     SgAsmValueExpression* TH() const {
00187         return SageBuilderAsm::makeByteValue(fld<9, 10>());
00188     }
00189     SgAsmValueExpression* TO() const {
00190         return SageBuilderAsm::makeByteValue(fld<6, 10>());
00191     }
00192     SgAsmValueExpression* U() const {
00193         return SageBuilderAsm::makeByteValue(fld<16, 19>());
00194     }
00195     SgAsmValueExpression* UI() const {
00196         return SageBuilderAsm::makeQWordValue(fld<16, 31>());
00197     }
00198 
00199     SgAsmMemoryReferenceExpression* memref(SgAsmType* t) const {
00200             return SageBuilderAsm::makeMemoryReference(SageBuilderAsm::makeAdd(RA_or_zero(), D()), NULL, t);
00201     }
00202     SgAsmMemoryReferenceExpression* memrefx(SgAsmType* t) const {
00203             return SageBuilderAsm::makeMemoryReference(SageBuilderAsm::makeAdd(RA_or_zero(), RB()), NULL, t);
00204     }
00205     SgAsmMemoryReferenceExpression* memrefu(SgAsmType* t) const {
00206         if (fld<11, 15>() == 0)
00207             throw ExceptionPowerpc("bits 11-15 must be nonzero", this);
00208         return SageBuilderAsm::makeMemoryReference(SageBuilderAsm::makeAdd(RA(), D()), NULL, t);
00209     }
00210     SgAsmMemoryReferenceExpression* memrefux(SgAsmType* t) const {
00211         if (fld<11, 15>() == 0)
00212             throw ExceptionPowerpc("bits 11-15 must be nonzero", this);
00213         return SageBuilderAsm::makeMemoryReference(SageBuilderAsm::makeAdd(RA(), RB()), NULL, t);
00214     }
00215 
00216     /* There are 15 different forms of PowerPC instructions, but all are 32-bit (fixed length instruction set). */
00217     SgAsmPowerpcInstruction* decode_I_formInstruction();
00218     SgAsmPowerpcInstruction* decode_B_formInstruction();
00219     SgAsmPowerpcInstruction* decode_SC_formInstruction();
00220     SgAsmPowerpcInstruction* decode_DS_formInstruction();
00221     SgAsmPowerpcInstruction* decode_X_formInstruction_00();
00222     SgAsmPowerpcInstruction* decode_X_formInstruction_1F();
00223     SgAsmPowerpcInstruction* decode_X_formInstruction_3F();
00224     SgAsmPowerpcInstruction* decode_XL_formInstruction();
00225     SgAsmPowerpcInstruction* decode_XS_formInstruction();
00226     SgAsmPowerpcInstruction* decode_A_formInstruction_00();
00227     SgAsmPowerpcInstruction* decode_A_formInstruction_04();
00228     SgAsmPowerpcInstruction* decode_A_formInstruction_3B();
00229     SgAsmPowerpcInstruction* decode_A_formInstruction_3F();
00230     SgAsmPowerpcInstruction* decode_MD_formInstruction();
00231     SgAsmPowerpcInstruction* decode_MDS_formInstruction();
00232 
00233     SgAsmQuadWordValueExpression* makeBranchTarget( uint64_t targetAddr ) const;
00234 
00235     SgAsmPowerpcInstruction* disassemble();
00236 
00238     void init();
00239     
00241     void startInstruction(rose_addr_t start_va, uint32_t c) {
00242         ip = start_va;
00243         insn = c;
00244     }
00245     
00246     /* Per-instruction data members (mostly set by startInstruction()) */
00247     uint64_t ip;                                
00248     uint32_t insn;                              
00249 };
00250 
00251 #endif

Generated on Tue Jan 31 05:31:37 2012 for ROSE by  doxygen 1.4.7