ARM: Support forcing load/store multiple to use user registers.
This commit is contained in:
parent
bb903b6514
commit
8a4af3668d
4 changed files with 32 additions and 26 deletions
|
@ -84,33 +84,20 @@ class MicroMemOp : public MicroIntOp
|
|||
*/
|
||||
class ArmMacroMemoryOp : public PredMacroOp
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
/// Memory request flags. See mem_req_base.hh.
|
||||
unsigned memAccessFlags;
|
||||
|
||||
uint32_t reglist;
|
||||
uint32_t ones;
|
||||
uint32_t puswl,
|
||||
prepost,
|
||||
up,
|
||||
psruser,
|
||||
writeback,
|
||||
loadop;
|
||||
|
||||
ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst,
|
||||
OpClass __opClass)
|
||||
: PredMacroOp(mnem, _machInst, __opClass),
|
||||
memAccessFlags(0),
|
||||
reglist(machInst.regList), ones(0),
|
||||
puswl(machInst.puswl),
|
||||
prepost(machInst.puswl.prepost),
|
||||
up(machInst.puswl.up),
|
||||
psruser(machInst.puswl.psruser),
|
||||
writeback(machInst.puswl.writeback),
|
||||
loadop(machInst.puswl.loadOp)
|
||||
: PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0),
|
||||
reglist(machInst.regList), ones(0)
|
||||
{
|
||||
ones = number_of_ones(reglist);
|
||||
numMicroops = ones + writeback + 1;
|
||||
numMicroops = ones + machInst.puswl.writeback + 1;
|
||||
// Remember that writeback adds a uop
|
||||
microOps = new StaticInstPtr[numMicroops];
|
||||
}
|
||||
|
@ -121,7 +108,7 @@ class ArmMacroMemoryOp : public PredMacroOp
|
|||
*/
|
||||
class ArmMacroFPAOp : public PredMacroOp
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
uint32_t puswl,
|
||||
prepost,
|
||||
up,
|
||||
|
@ -150,7 +137,7 @@ class ArmMacroFPAOp : public PredMacroOp
|
|||
*/
|
||||
class ArmMacroFMOp : public PredMacroOp
|
||||
{
|
||||
protected:
|
||||
protected:
|
||||
uint32_t punwl,
|
||||
prepost,
|
||||
up,
|
||||
|
|
|
@ -324,6 +324,13 @@ INTREG_FIQ(unsigned index)
|
|||
return IntRegFiqMap[index];
|
||||
}
|
||||
|
||||
static inline IntRegIndex
|
||||
intRegForceUser(unsigned index)
|
||||
{
|
||||
assert(index < NUM_ARCH_INTREGS);
|
||||
return (IntRegIndex)(index + NUM_INTREGS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -125,8 +125,11 @@ namespace ArmISA
|
|||
assert(reg >= 0);
|
||||
if (reg < NUM_ARCH_INTREGS) {
|
||||
return intRegMap[reg];
|
||||
} else if (reg < NUM_INTREGS) {
|
||||
return reg;
|
||||
} else {
|
||||
assert(reg < NUM_INTREGS);
|
||||
reg -= NUM_INTREGS;
|
||||
assert(reg < NUM_ARCH_INTREGS);
|
||||
return reg;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -180,11 +180,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
|||
%(constructor)s;
|
||||
uint32_t regs = reglist;
|
||||
uint32_t addr = 0;
|
||||
bool up = machInst.puswl.up;
|
||||
|
||||
if (!up)
|
||||
addr = (ones << 2) - 4;
|
||||
|
||||
if (prepost)
|
||||
if (machInst.puswl.prepost)
|
||||
addr += 4;
|
||||
|
||||
// Add 0 to Rn and stick it in ureg0.
|
||||
|
@ -198,10 +199,18 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
|||
reg++;
|
||||
replaceBits(regs, reg, 0);
|
||||
|
||||
if (loadop)
|
||||
microOps[i] = new MicroLdrUop(machInst, reg, INTREG_UREG0, addr);
|
||||
else
|
||||
microOps[i] = new MicroStrUop(machInst, reg, INTREG_UREG0, addr);
|
||||
unsigned regIdx = reg;
|
||||
if (machInst.puswl.psruser) {
|
||||
regIdx = intRegForceUser(regIdx);
|
||||
}
|
||||
|
||||
if (machInst.puswl.loadOp) {
|
||||
microOps[i] =
|
||||
new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr);
|
||||
} else {
|
||||
microOps[i] =
|
||||
new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr);
|
||||
}
|
||||
|
||||
if (up)
|
||||
addr += 4;
|
||||
|
@ -210,7 +219,7 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
|
|||
}
|
||||
|
||||
StaticInstPtr &lastUop = microOps[numMicroops - 1];
|
||||
if (writeback) {
|
||||
if (machInst.puswl.writeback) {
|
||||
if (up) {
|
||||
lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue