summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:02 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:02 -0500
commit7939b4826506bde98d299e1ba7a38e17cd1fa785 (patch)
tree795354a368ad0d00a88e5d6a75c79e9a8daaa417
parentb66e3aec43a4adc85fb057db350c8984acf0bc40 (diff)
downloadgem5-7939b4826506bde98d299e1ba7a38e17cd1fa785.tar.xz
ARM: Implement disassembly for the new data processing classes.
-rw-r--r--src/arch/arm/insts/pred_inst.cc49
-rw-r--r--src/arch/arm/insts/pred_inst.hh6
-rw-r--r--src/arch/arm/insts/static_inst.cc66
-rw-r--r--src/arch/arm/insts/static_inst.hh8
4 files changed, 100 insertions, 29 deletions
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;