From 64824ea99ff662768450503278096ad76087bf89 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 28 May 2010 18:18:53 +0000 Subject: [PATCH] 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 --- llvm/include/llvm/CodeGen/MachineOperand.h | 16 +++++++++++++++- llvm/include/llvm/Target/TargetRegisterInfo.h | 17 +++++++++++++++++ llvm/lib/CodeGen/MachineInstr.cpp | 19 +++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/CodeGen/MachineOperand.h b/llvm/include/llvm/CodeGen/MachineOperand.h index 31858ce8081b..afa2c298a273 100644 --- a/llvm/include/llvm/CodeGen/MachineOperand.h +++ b/llvm/include/llvm/CodeGen/MachineOperand.h @@ -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"); diff --git a/llvm/include/llvm/Target/TargetRegisterInfo.h b/llvm/include/llvm/Target/TargetRegisterInfo.h index 7c37b73a2b99..45d27aad3929 100644 --- a/llvm/include/llvm/Target/TargetRegisterInfo.h +++ b/llvm/include/llvm/Target/TargetRegisterInfo.h @@ -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 // diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index e54cd5cf9492..ce0c5e6a87c3 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -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.