Add a TargetRegisterInfo::composeSubRegIndices hook with a default
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 28 May 2010 18:18:53 +0000 (18:18 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 28 May 2010 18:18:53 +0000 (18:18 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104985 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineOperand.h
include/llvm/Target/TargetRegisterInfo.h
lib/CodeGen/MachineInstr.cpp

index 31858ce8081b8c2173f61f4954157c13434a0fa2..afa2c298a273a09d3f86e7fcbd4632812014ccdd 100644 (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");
index 7c37b73a2b995174e001516b4b26c498357698d4..45d27aad39299db47d89433aeaf42536a9a363f7 100644 (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
   //
index e54cd5cf9492c73dc7e188c231dd17dfb475df56..ce0c5e6a87c3cd2ebe1e5b830cd4794ce862d67b 100644 (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.