ARM: Support forcing load/store multiple to use user registers.

This commit is contained in:
Gabe Black 2009-11-08 15:49:03 -08:00
parent bb903b6514
commit 8a4af3668d
4 changed files with 32 additions and 26 deletions

View file

@ -84,33 +84,20 @@ class MicroMemOp : public MicroIntOp
*/ */
class ArmMacroMemoryOp : public PredMacroOp class ArmMacroMemoryOp : public PredMacroOp
{ {
protected: protected:
/// Memory request flags. See mem_req_base.hh. /// Memory request flags. See mem_req_base.hh.
unsigned memAccessFlags; unsigned memAccessFlags;
uint32_t reglist; uint32_t reglist;
uint32_t ones; uint32_t ones;
uint32_t puswl,
prepost,
up,
psruser,
writeback,
loadop;
ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst, ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst,
OpClass __opClass) OpClass __opClass)
: PredMacroOp(mnem, _machInst, __opClass), : PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0),
memAccessFlags(0), reglist(machInst.regList), ones(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)
{ {
ones = number_of_ones(reglist); ones = number_of_ones(reglist);
numMicroops = ones + writeback + 1; numMicroops = ones + machInst.puswl.writeback + 1;
// Remember that writeback adds a uop // Remember that writeback adds a uop
microOps = new StaticInstPtr[numMicroops]; microOps = new StaticInstPtr[numMicroops];
} }
@ -121,7 +108,7 @@ class ArmMacroMemoryOp : public PredMacroOp
*/ */
class ArmMacroFPAOp : public PredMacroOp class ArmMacroFPAOp : public PredMacroOp
{ {
protected: protected:
uint32_t puswl, uint32_t puswl,
prepost, prepost,
up, up,
@ -150,7 +137,7 @@ class ArmMacroFPAOp : public PredMacroOp
*/ */
class ArmMacroFMOp : public PredMacroOp class ArmMacroFMOp : public PredMacroOp
{ {
protected: protected:
uint32_t punwl, uint32_t punwl,
prepost, prepost,
up, up,

View file

@ -324,6 +324,13 @@ INTREG_FIQ(unsigned index)
return IntRegFiqMap[index]; return IntRegFiqMap[index];
} }
static inline IntRegIndex
intRegForceUser(unsigned index)
{
assert(index < NUM_ARCH_INTREGS);
return (IntRegIndex)(index + NUM_INTREGS);
}
} }
#endif #endif

View file

@ -125,8 +125,11 @@ namespace ArmISA
assert(reg >= 0); assert(reg >= 0);
if (reg < NUM_ARCH_INTREGS) { if (reg < NUM_ARCH_INTREGS) {
return intRegMap[reg]; return intRegMap[reg];
} else if (reg < NUM_INTREGS) {
return reg;
} else { } else {
assert(reg < NUM_INTREGS); reg -= NUM_INTREGS;
assert(reg < NUM_ARCH_INTREGS);
return reg; return reg;
} }
} }

View file

@ -180,11 +180,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
%(constructor)s; %(constructor)s;
uint32_t regs = reglist; uint32_t regs = reglist;
uint32_t addr = 0; uint32_t addr = 0;
bool up = machInst.puswl.up;
if (!up) if (!up)
addr = (ones << 2) - 4; addr = (ones << 2) - 4;
if (prepost) if (machInst.puswl.prepost)
addr += 4; addr += 4;
// Add 0 to Rn and stick it in ureg0. // Add 0 to Rn and stick it in ureg0.
@ -198,10 +199,18 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
reg++; reg++;
replaceBits(regs, reg, 0); replaceBits(regs, reg, 0);
if (loadop) unsigned regIdx = reg;
microOps[i] = new MicroLdrUop(machInst, reg, INTREG_UREG0, addr); if (machInst.puswl.psruser) {
else regIdx = intRegForceUser(regIdx);
microOps[i] = new MicroStrUop(machInst, reg, INTREG_UREG0, addr); }
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) if (up)
addr += 4; addr += 4;
@ -210,7 +219,7 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
} }
StaticInstPtr &lastUop = microOps[numMicroops - 1]; StaticInstPtr &lastUop = microOps[numMicroops - 1];
if (writeback) { if (machInst.puswl.writeback) {
if (up) { if (up) {
lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4); lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4);
} else { } else {