ARM: Tune up predicated instruction decoding.

This commit is contained in:
Gabe Black 2009-07-08 23:02:19 -07:00
parent ddcf084f16
commit 2fb8d481ab
4 changed files with 113 additions and 106 deletions

View file

@ -32,10 +32,18 @@
namespace ArmISA namespace ArmISA
{ {
std::string std::string
PredOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const PredIntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{ {
std::stringstream ss; std::stringstream ss;
printDataInst(ss); printDataInst(ss, false);
return ss.str();
}
std::string
PredImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
printDataInst(ss, true);
return ss.str(); return ss.str();
} }

View file

@ -56,8 +56,6 @@ class PredOp : public ArmStaticInst
condCode((ConditionCode)(unsigned)machInst.condCode) condCode((ConditionCode)(unsigned)machInst.condCode)
{ {
} }
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
}; };
/** /**
@ -65,23 +63,25 @@ class PredOp : public ArmStaticInst
*/ */
class PredImmOp : public PredOp class PredImmOp : public PredOp
{ {
protected: protected:
uint32_t imm; uint32_t imm;
uint32_t rotate; uint32_t rotate;
uint32_t rotated_imm; uint32_t rotated_imm;
uint32_t rotated_carry; uint32_t rotated_carry;
/// Constructor /// Constructor
PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : PredImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass), PredOp(mnem, _machInst, __opClass),
imm(machInst.imm), rotate(machInst.rotate << 1), imm(machInst.imm), rotate(machInst.rotate << 1),
rotated_imm(0), rotated_carry(0) rotated_imm(0), rotated_carry(0)
{ {
rotated_imm = rotate_imm(imm, rotate); rotated_imm = rotate_imm(imm, rotate);
if (rotate != 0) if (rotate != 0)
rotated_carry = (rotated_imm >> 31) & 1; rotated_carry = (rotated_imm >> 31) & 1;
} }
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
}; };
/** /**
@ -89,17 +89,19 @@ class PredImmOp : public PredOp
*/ */
class PredIntOp : public PredOp class PredIntOp : public PredOp
{ {
protected: protected:
uint32_t shift_size; uint32_t shift_size;
uint32_t shift; uint32_t shift;
/// Constructor /// Constructor
PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) : PredIntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass), PredOp(mnem, _machInst, __opClass),
shift_size(machInst.shiftSize), shift(machInst.shift) shift_size(machInst.shiftSize), shift(machInst.shift)
{ {
} }
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
}; };
/** /**
@ -107,36 +109,36 @@ class PredIntOp : public PredOp
*/ */
class PredMacroOp : public PredOp class PredMacroOp : public PredOp
{ {
protected: protected:
uint32_t numMicroops; uint32_t numMicroops;
StaticInstPtr * microOps; StaticInstPtr * microOps;
/// Constructor /// Constructor
PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) : PredMacroOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass), PredOp(mnem, _machInst, __opClass),
numMicroops(0) numMicroops(0)
{ {
// We rely on the subclasses of this object to handle the // We rely on the subclasses of this object to handle the
// initialization of the micro-operations, since they are // initialization of the micro-operations, since they are
// all of variable length // all of variable length
flags[IsMacroop] = true; flags[IsMacroop] = true;
} }
~PredMacroOp() ~PredMacroOp()
{ {
if (numMicroops) if (numMicroops)
delete [] microOps; delete [] microOps;
} }
StaticInstPtr StaticInstPtr
fetchMicroop(MicroPC microPC) fetchMicroop(MicroPC microPC)
{ {
assert(microPC < numMicroops); assert(microPC < numMicroops);
return microOps[microPC]; return microOps[microPC];
} }
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
}; };
/** /**
@ -144,12 +146,12 @@ class PredMacroOp : public PredOp
*/ */
class PredMicroop : public PredOp class PredMicroop : public PredOp
{ {
/// Constructor /// Constructor
PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) : PredMicroop(const char *mnem, MachInst _machInst, OpClass __opClass) :
PredOp(mnem, _machInst, __opClass) PredOp(mnem, _machInst, __opClass)
{ {
flags[IsMicroop] = true; flags[IsMicroop] = true;
} }
}; };
} }

View file

@ -330,61 +330,52 @@ ArmStaticInst::printMemSymbol(std::ostream &os,
void void
ArmStaticInst::printShiftOperand(std::ostream &os) const ArmStaticInst::printShiftOperand(std::ostream &os) const
{ {
// Shifter operand printReg(os, machInst.rm);
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 immShift = (machInst.opcode4 == 0);
bool done = false; bool done = false;
unsigned shiftAmt = (machInst.shiftSize); unsigned shiftAmt = (machInst.shiftSize);
ArmShiftType type = (ArmShiftType)(uint32_t)machInst.shift; ArmShiftType type = (ArmShiftType)(uint32_t)machInst.shift;
if ((type == LSR || type == ASR) && immShift && shiftAmt == 0) if ((type == LSR || type == ASR) && immShift && shiftAmt == 0)
shiftAmt = 32; shiftAmt = 32;
switch (type) { switch (type) {
case LSL: case LSL:
if (immShift && shiftAmt == 0) { if (immShift && shiftAmt == 0) {
done = true; done = true;
break;
}
os << ", LSL";
break; 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 << ", LSL";
os << " "; break;
if (immShift) case LSR:
os << "#" << shiftAmt; os << ", LSR";
else break;
printReg(os, machInst.rs); 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 void
ArmStaticInst::printDataInst(std::ostream &os) const ArmStaticInst::printDataInst(std::ostream &os, bool withImm) const
{ {
printMnemonic(os, machInst.sField ? "s" : ""); printMnemonic(os, machInst.sField ? "s" : "");
//XXX It would be nice if the decoder figured this all out for us. //XXX It would be nice if the decoder figured this all out for us.
@ -409,7 +400,13 @@ ArmStaticInst::printDataInst(std::ostream &os) const
if (!firstOp) if (!firstOp)
os << ", "; os << ", ";
printShiftOperand(os); if (withImm) {
unsigned rotate = machInst.rotate * 2;
uint32_t imm = machInst.imm;
ccprintf(os, "#%#x", (imm << (32 - rotate)) | (imm >> rotate));
} else {
printShiftOperand(os);
}
} }
std::string std::string

View file

@ -71,7 +71,7 @@ class ArmStaticInst : public StaticInst
void printShiftOperand(std::ostream &os) const; void printShiftOperand(std::ostream &os) const;
void printDataInst(std::ostream &os) const; void printDataInst(std::ostream &os, bool withImm) const;
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
}; };