Add a TargetRegisterInfo::composeSubRegIndices hook with a default

implementation that is correct for most targets. Tablegen will override where
needed.

Add MachineOperand::subst{Virt,Phys}Reg methods that correctly handle existing
subreg indices when sustituting registers.

llvm-svn: 104985
This commit is contained in:
Jakob Stoklund Olesen 2010-05-28 18:18:53 +00:00
parent 7dd85bebee
commit 6a3738d96a
3 changed files with 51 additions and 1 deletions

View File

@ -27,6 +27,7 @@ class MachineInstr;
class MachineRegisterInfo;
class MDNode;
class TargetMachine;
class TargetRegisterInfo;
class raw_ostream;
class MCSymbol;
@ -246,7 +247,20 @@ public:
assert(isReg() && "Wrong MachineOperand accessor");
SubReg = (unsigned char)subReg;
}
/// substVirtReg - Substitute the current register with the virtual
/// subregister Reg:SubReg. Take any existing SubReg index into account,
/// using TargetRegisterInfo to compose the subreg indices if necessary.
/// Reg must be a virtual register, SubIdx can be 0.
///
void substVirtReg(unsigned Reg, unsigned SubIdx, const TargetRegisterInfo&);
/// substPhysReg - Substitute the current register with the physical register
/// Reg, taking any existing SubReg into account. For instance,
/// substPhysReg(%EAX) will change %reg1024:sub_8bit to %AL.
///
void substPhysReg(unsigned Reg, const TargetRegisterInfo&);
void setIsUse(bool Val = true) {
assert(isReg() && "Wrong MachineOperand accessor");
assert((Val || !isDebug()) && "Marking a debug operation as def");

View File

@ -490,6 +490,23 @@ public:
return 0;
}
/// composeSubRegIndices - Return the subregister index you get from composing
/// two subregister indices.
///
/// If R:a:b is the same register as R:c, then composeSubRegIndices(a, b)
/// returns c. Note that composeSubRegIndices does not tell you about illegal
/// compositions. If R does not have a subreg a, or R:a does not have a subreg
/// b, composeSubRegIndices doesn't tell you.
///
/// The ARM register Q0 has two D subregs dsub_0:D0 and dsub_1:D1. It also has
/// ssub_0:S0 - ssub_3:S3 subregs.
/// If you compose subreg indices dsub_1, ssub_0 you get ssub_2.
///
virtual unsigned composeSubRegIndices(unsigned a, unsigned b) const {
// This default implementation is correct for most targets.
return b;
}
//===--------------------------------------------------------------------===//
// Register Class Information
//

View File

@ -111,6 +111,25 @@ void MachineOperand::setReg(unsigned Reg) {
Contents.Reg.RegNo = Reg;
}
void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx,
const TargetRegisterInfo &TRI) {
assert(TargetRegisterInfo::isVirtualRegister(Reg));
if (SubIdx && getSubReg())
SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg());
setReg(Reg);
setSubReg(SubIdx);
}
void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) {
assert(TargetRegisterInfo::isPhysicalRegister(Reg));
if (getSubReg()) {
Reg = TRI.getSubReg(Reg, getSubReg());
assert(Reg && "Invalid SubReg for physical register");
setSubReg(0);
}
setReg(Reg);
}
/// ChangeToImmediate - Replace this operand with a new immediate operand of
/// the specified value. If an operand is known to be an immediate already,
/// the setImm method should be used.