From 7939b4826506bde98d299e1ba7a38e17cd1fa785 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 2 Jun 2010 12:58:02 -0500 Subject: ARM: Implement disassembly for the new data processing classes. --- src/arch/arm/insts/pred_inst.cc | 49 +++++++++++++++++++++++++++-- src/arch/arm/insts/pred_inst.hh | 6 ++++ src/arch/arm/insts/static_inst.cc | 66 ++++++++++++++++++++++++--------------- src/arch/arm/insts/static_inst.hh | 8 ++++- 4 files changed, 100 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/arch/arm/insts/pred_inst.cc b/src/arch/arm/insts/pred_inst.cc index b1b21677c..94386e400 100644 --- a/src/arch/arm/insts/pred_inst.cc +++ b/src/arch/arm/insts/pred_inst.cc @@ -48,7 +48,16 @@ std::string PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream ss; - printDataInst(ss, false); + unsigned rotate = machInst.rotate * 2; + uint32_t imm = machInst.imm; + imm = (imm << (32 - rotate)) | (imm >> rotate); + printDataInst(ss, false, machInst.opcode4 == 0, machInst.sField, + (IntRegIndex)(uint32_t)machInst.rd, + (IntRegIndex)(uint32_t)machInst.rn, + (IntRegIndex)(uint32_t)machInst.rm, + (IntRegIndex)(uint32_t)machInst.rs, + machInst.shiftSize, (ArmShiftType)(uint32_t)machInst.shift, + imm); return ss.str(); } @@ -56,7 +65,43 @@ std::string PredImmOpBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream ss; - printDataInst(ss, true); + unsigned rotate = machInst.rotate * 2; + uint32_t imm = machInst.imm; + imm = (imm << (32 - rotate)) | (imm >> rotate); + printDataInst(ss, true, machInst.opcode4 == 0, machInst.sField, + (IntRegIndex)(uint32_t)machInst.rd, + (IntRegIndex)(uint32_t)machInst.rn, + (IntRegIndex)(uint32_t)machInst.rm, + (IntRegIndex)(uint32_t)machInst.rs, + machInst.shiftSize, (ArmShiftType)(uint32_t)machInst.shift, + imm); + return ss.str(); +} + +std::string +DataImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + printDataInst(ss, true, false, /*XXX not really s*/ false, dest, op1, + INTREG_ZERO, INTREG_ZERO, 0, LSL, imm); + return ss.str(); +} + +std::string +DataRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + printDataInst(ss, false, true, /*XXX not really s*/ false, dest, op1, + op2, INTREG_ZERO, shiftAmt, shiftType, 0); + return ss.str(); +} + +std::string +DataRegRegOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + printDataInst(ss, false, false, /*XXX not really s*/ false, dest, op1, + op2, shift, 0, shiftType, 0); return ss.str(); } diff --git a/src/arch/arm/insts/pred_inst.hh b/src/arch/arm/insts/pred_inst.hh index 3231894b0..39d479d4f 100644 --- a/src/arch/arm/insts/pred_inst.hh +++ b/src/arch/arm/insts/pred_inst.hh @@ -193,6 +193,8 @@ class DataImmOp : public PredOp PredOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm), rotC(_rotC) {} + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; class DataRegOp : public PredOp @@ -209,6 +211,8 @@ class DataRegOp : public PredOp dest(_dest), op1(_op1), op2(_op2), shiftAmt(_shiftAmt), shiftType(_shiftType) {} + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; class DataRegRegOp : public PredOp @@ -224,6 +228,8 @@ class DataRegRegOp : public PredOp dest(_dest), op1(_op1), op2(_op2), shift(_shift), shiftType(_shiftType) {} + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /** diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index 7f5f56f19..6d52112e0 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -346,14 +346,20 @@ ArmStaticInstBase::printMemSymbol(std::ostream &os, } void -ArmStaticInstBase::printShiftOperand(std::ostream &os) const +ArmStaticInstBase::printShiftOperand(std::ostream &os, + IntRegIndex rm, + bool immShift, + uint32_t shiftAmt, + IntRegIndex rs, + ArmShiftType type) const { - printReg(os, machInst.rm); + bool firstOp = false; + + if (rm != INTREG_ZERO) { + printReg(os, rm); + } - bool immShift = (machInst.opcode4 == 0); bool done = false; - unsigned shiftAmt = (machInst.shiftSize); - ArmShiftType type = (ArmShiftType)(uint32_t)machInst.shift; if ((type == LSR || type == ASR) && immShift && shiftAmt == 0) shiftAmt = 32; @@ -364,66 +370,74 @@ ArmStaticInstBase::printShiftOperand(std::ostream &os) const done = true; break; } - os << ", LSL"; + if (!firstOp) + os << ", "; + os << "LSL"; break; case LSR: - os << ", LSR"; + if (!firstOp) + os << ", "; + os << "LSR"; break; case ASR: - os << ", ASR"; + if (!firstOp) + os << ", "; + os << "ASR"; break; case ROR: if (immShift && shiftAmt == 0) { - os << ", RRX"; + if (!firstOp) + os << ", "; + os << "RRX"; done = true; break; } - os << ", ROR"; + if (!firstOp) + os << ", "; + os << "ROR"; break; default: panic("Tried to disassemble unrecognized shift type.\n"); } if (!done) { - os << " "; + if (!firstOp) + os << " "; if (immShift) os << "#" << shiftAmt; else - printReg(os, machInst.rs); + printReg(os, rs); } } void -ArmStaticInstBase::printDataInst(std::ostream &os, bool withImm) const +ArmStaticInstBase::printDataInst(std::ostream &os, bool withImm, + bool immShift, bool s, IntRegIndex rd, IntRegIndex rn, + IntRegIndex rm, IntRegIndex rs, uint32_t shiftAmt, + ArmShiftType type, uint32_t imm) const { - printMnemonic(os, machInst.sField ? "s" : ""); - //XXX It would be nice if the decoder figured this all out for us. - unsigned opcode = machInst.opcode; + printMnemonic(os, s ? "s" : ""); bool firstOp = true; // Destination - // Cmp, cmn, teq, and tst don't have one. - if (opcode < 8 || opcode > 0xb) { + if (rd != INTREG_ZERO) { firstOp = false; - printReg(os, machInst.rd); + printReg(os, rd); } // Source 1. - // Mov and Movn don't have one of these. - if (opcode != 0xd && opcode != 0xf) { + if (rn != INTREG_ZERO) { if (!firstOp) os << ", "; firstOp = false; - printReg(os, machInst.rn); + printReg(os, rn); } if (!firstOp) os << ", "; if (withImm) { - unsigned rotate = machInst.rotate * 2; - uint32_t imm = machInst.imm; - ccprintf(os, "#%#x", (imm << (32 - rotate)) | (imm >> rotate)); + ccprintf(os, "#%d", imm); } else { - printShiftOperand(os); + printShiftOperand(os, rm, immShift, shiftAmt, rs, type); } } diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index 99fa819b5..81b480e02 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -82,10 +82,16 @@ class ArmStaticInstBase : public StaticInst void printMemSymbol(std::ostream &os, const SymbolTable *symtab, const std::string &prefix, const Addr addr, const std::string &suffix) const; - void printShiftOperand(std::ostream &os) const; + void printShiftOperand(std::ostream &os, IntRegIndex rm, + bool immShift, uint32_t shiftAmt, + IntRegIndex rs, ArmShiftType type) const; void printDataInst(std::ostream &os, bool withImm) const; + void printDataInst(std::ostream &os, bool withImm, bool immShift, bool s, + IntRegIndex rd, IntRegIndex rn, IntRegIndex rm, + IntRegIndex rs, uint32_t shiftAmt, ArmShiftType type, + uint32_t imm) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; -- cgit v1.2.3