diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h index 14ed6948e97..bc58080a5ec 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 98955a305ed..fdb259cd0e6 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 e0d1c6a4bf3..fd26d9fd7d1 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;