- Added MRegisterInfo::getCrossCopyRegClass() hook. For register classes where reg...
authorEvan Cheng <evan.cheng@apple.com>
Wed, 26 Sep 2007 21:31:07 +0000 (21:31 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Wed, 26 Sep 2007 21:31:07 +0000 (21:31 +0000)
- X86 copyRegToReg() now supports copying between EFLAGS and GR32 / GR64 registers.

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

include/llvm/Target/MRegisterInfo.h
lib/Target/X86/X86RegisterInfo.cpp
lib/Target/X86/X86RegisterInfo.h

index 14ed6948e979d43b5a4336045e89e9b6663e7a92..bc58080a5ece2dbac73f95af126953e7f819d68c 100644 (file)
@@ -315,6 +315,11 @@ public:
     return Reg >= FirstVirtualRegister;
   }
 
+  /// getPhysicalRegisterRegClass - Returns the Register Class of a physical
+  /// register of the given type.
+  const TargetRegisterClass *getPhysicalRegisterRegClass(MVT::ValueType VT,
+                                                         unsigned Reg) const;
+
   /// getAllocatableSet - Returns a bitset indexed by register number
   /// indicating if a register is allocatable or not. If a register class is
   /// specified, returns the subset for the class.
@@ -509,6 +514,14 @@ public:
                             const TargetRegisterClass *DestRC,
                             const TargetRegisterClass *SrcRC) const = 0;
 
+  /// getCrossCopyRegClass - Returns a legal register class to copy a register
+  /// in the specified class to or from. Returns NULL if it is possible to copy
+  /// between a two registers of the specified class.
+  virtual const TargetRegisterClass *
+  getCrossCopyRegClass(const TargetRegisterClass *RC) const {
+    return NULL;
+  }
+
   /// reMaterialize - Re-issue the specified 'original' instruction at the
   /// specific location targeting a new destination register.
   virtual void reMaterialize(MachineBasicBlock &MBB,
index 98955a305edae36f02a108e6837c4d9dec4f59d7..fdb259cd0e62f7fcada44e6cdcfb0722457df80b 100644 (file)
@@ -234,6 +234,30 @@ void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
                                    const TargetRegisterClass *DestRC,
                                    const TargetRegisterClass *SrcRC) const {
   if (DestRC != SrcRC) {
+    // Moving EFLAGS to / from another register requires a push and a pop.
+    if (SrcRC == &X86::CCRRegClass) {
+      assert(SrcReg == X86::EFLAGS);
+      if (DestRC == &X86::GR64RegClass) {
+        BuildMI(MBB, MI, TII.get(X86::PUSHFQ));
+        BuildMI(MBB, MI, TII.get(X86::POP64r), DestReg);
+        return;
+      } else if (DestRC == &X86::GR32RegClass) {
+        BuildMI(MBB, MI, TII.get(X86::PUSHFD));
+        BuildMI(MBB, MI, TII.get(X86::POP32r), DestReg);
+        return;
+      }
+    } else if (DestRC == &X86::CCRRegClass) {
+      assert(DestReg == X86::EFLAGS);
+      if (SrcRC == &X86::GR64RegClass) {
+        BuildMI(MBB, MI, TII.get(X86::PUSH64r)).addReg(SrcReg);
+        BuildMI(MBB, MI, TII.get(X86::POPFQ));
+        return;
+      } else if (SrcRC == &X86::GR32RegClass) {
+        BuildMI(MBB, MI, TII.get(X86::PUSH32r)).addReg(SrcReg);
+        BuildMI(MBB, MI, TII.get(X86::POPFD));
+        return;
+      }
+    }
     cerr << "Not yet supported!";
     abort();
   }
@@ -272,6 +296,12 @@ void X86RegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
   BuildMI(MBB, MI, TII.get(Opc), DestReg).addReg(SrcReg);
 }
 
+const TargetRegisterClass *
+X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
+  if (RC == &X86::CCRRegClass)
+    return &X86::GR32RegClass;
+  return NULL;
+}
 
 void X86RegisterInfo::reMaterialize(MachineBasicBlock &MBB,
                                     MachineBasicBlock::iterator I,
index e0d1c6a4bf3e063f87b7b6405a92bbe8b4072b17..fd26d9fd7d1aba435c78bd43838564d609bf9d4e 100644 (file)
@@ -81,6 +81,9 @@ public:
                     const TargetRegisterClass *DestRC,
                     const TargetRegisterClass *SrcRC) const;
  
+  const TargetRegisterClass *
+  getCrossCopyRegClass(const TargetRegisterClass *RC) const;
+
   void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
                      unsigned DestReg, const MachineInstr *Orig) const;