summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2009-06-27 00:30:23 -0700
committerGabe Black <gblack@eecs.umich.edu>2009-06-27 00:30:23 -0700
commit1ea14b8fac34764a219407effba3211e3f8edc90 (patch)
treecd10943dd662c116825242887310aa3424086425 /src/arch/arm
parent56f1845471231f6b063a912c79c38e63cfbd7d59 (diff)
downloadgem5-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')
-rw-r--r--src/arch/arm/insts/pred_inst.cc55
-rw-r--r--src/arch/arm/insts/pred_inst.hh4
-rw-r--r--src/arch/arm/insts/static_inst.cc85
-rw-r--r--src/arch/arm/insts/static_inst.hh3
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;
};
}