diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2009-06-27 00:30:23 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2009-06-27 00:30:23 -0700 |
commit | 1ea14b8fac34764a219407effba3211e3f8edc90 (patch) | |
tree | cd10943dd662c116825242887310aa3424086425 /src/arch/arm/insts | |
parent | 56f1845471231f6b063a912c79c38e63cfbd7d59 (diff) | |
download | gem5-1ea14b8fac34764a219407effba3211e3f8edc90.tar.xz |
ARM: Show more information when disassembling data processing intstructions.
This will need more work, but it should be a lot closer.
Diffstat (limited to 'src/arch/arm/insts')
-rw-r--r-- | src/arch/arm/insts/pred_inst.cc | 55 | ||||
-rw-r--r-- | src/arch/arm/insts/pred_inst.hh | 4 | ||||
-rw-r--r-- | src/arch/arm/insts/static_inst.cc | 85 | ||||
-rw-r--r-- | src/arch/arm/insts/static_inst.hh | 3 |
4 files changed, 89 insertions, 58 deletions
diff --git a/src/arch/arm/insts/pred_inst.cc b/src/arch/arm/insts/pred_inst.cc index 7fd891b19..539cfc2d2 100644 --- a/src/arch/arm/insts/pred_inst.cc +++ b/src/arch/arm/insts/pred_inst.cc @@ -35,60 +35,7 @@ std::string PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream ss; - printMnemonic(ss); - if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - } - - ss << ", "; - - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ", "; - } - - return ss.str(); -} - -std::string -PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const -{ - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - } - - ss << ", "; - - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ", "; - } - - return ss.str(); -} - -std::string -PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const -{ - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - } - - ss << ", "; - - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ", "; - } - + printDataInst(ss); return ss.str(); } diff --git a/src/arch/arm/insts/pred_inst.hh b/src/arch/arm/insts/pred_inst.hh index 65661efdd..38ac69358 100644 --- a/src/arch/arm/insts/pred_inst.hh +++ b/src/arch/arm/insts/pred_inst.hh @@ -82,8 +82,6 @@ class PredImmOp : public PredOp if (rotate != 0) rotated_carry = (rotated_imm >> 31) & 1; } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; /** @@ -102,8 +100,6 @@ class PredIntOp : public PredOp shift_size(machInst.shiftSize), shift(machInst.shift) { } - - 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 a76dbd69c..011604d35 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -327,6 +327,91 @@ ArmStaticInst::printMemSymbol(std::ostream &os, } } +void +ArmStaticInst::printShiftOperand(std::ostream &os) const +{ + // Shifter operand + if (bits((uint32_t)machInst, 25)) { + // Immediate form + unsigned rotate = machInst.rotate * 2; + uint32_t imm = machInst.imm; + ccprintf(os, "#%#x", (imm << (32 - rotate)) | (imm >> rotate)); + } else { + // Register form + printReg(os, machInst.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; + + switch (type) { + case LSL: + if (immShift && shiftAmt == 0) { + done = true; + break; + } + os << ", LSL"; + break; + case LSR: + os << ", LSR"; + break; + case ASR: + os << ", ASR"; + break; + case ROR: + if (immShift && shiftAmt == 0) { + os << ", RRX"; + done = true; + break; + } + os << ", ROR"; + break; + default: + panic("Tried to disassemble unrecognized shift type.\n"); + } + if (!done) { + os << " "; + if (immShift) + os << "#" << shiftAmt; + else + printReg(os, machInst.rs); + } + } +} + +void +ArmStaticInst::printDataInst(std::ostream &os) const +{ + printMnemonic(os, machInst.sField ? "s" : ""); + //XXX It would be nice if the decoder figured this all out for us. + unsigned opcode = machInst.opcode24_21; + bool firstOp = true; + + // Destination + // Cmp, cmn, teq, and tst don't have one. + if (opcode < 8 || opcode > 0xb) { + firstOp = false; + printReg(os, machInst.rd); + } + + // Source 1. + // Mov and Movn don't have one of these. + if (opcode != 0xd && opcode != 0xf) { + if (!firstOp) + os << ", "; + firstOp = false; + printReg(os, machInst.rn); + } + + if (!firstOp) + os << ", "; + printShiftOperand(os); +} + std::string ArmStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index 6b745352e..22b59791c 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -68,8 +68,11 @@ class ArmStaticInst : 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 printDataInst(std::ostream &os) const; + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; } |