ARM: Tune up predicated instruction decoding.
This commit is contained in:
parent
ddcf084f16
commit
2fb8d481ab
4 changed files with 113 additions and 106 deletions
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue