ARM: Implement disassembly for the new data processing classes.
This commit is contained in:
parent
b66e3aec43
commit
7939b48265
4 changed files with 100 additions and 29 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue