aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/MRegisterInfo.h13
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp30
-rw-r--r--lib/Target/X86/X86RegisterInfo.h3
3 files changed, 46 insertions, 0 deletions
diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h
index 14ed6948e9..bc58080a5e 100644
--- a/include/llvm/Target/MRegisterInfo.h
+++ b/include/llvm/Target/MRegisterInfo.h
@@ -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,
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index 98955a305e..fdb259cd0e 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -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,
diff --git a/lib/Target/X86/X86RegisterInfo.h b/lib/Target/X86/X86RegisterInfo.h
index e0d1c6a4bf..fd26d9fd7d 100644
--- a/lib/Target/X86/X86RegisterInfo.h
+++ b/lib/Target/X86/X86RegisterInfo.h
@@ -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;