From c74a70df6ded8b538cc13be0f13db62d30a7c71f Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 27 May 2014 12:16:02 +0000 Subject: [PATCH] AArch64: implement copies to/from NZCV as a last ditch effort. A test in test/Generic creates a DAG where the NZCV output of an ADCS is used by multiple nodes. This makes LLVM want to save a copy of NZCV for later, which it couldn't do before. This should be the last fix required for the aarch64 buildbot. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209651 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64InstrInfo.cpp | 20 +++++++++++++++++++- lib/Target/AArch64/AArch64RegisterInfo.cpp | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/Target/AArch64/AArch64InstrInfo.cpp b/lib/Target/AArch64/AArch64InstrInfo.cpp index 52e3b333eb0..ff115c0bd5e 100644 --- a/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -1507,7 +1507,25 @@ void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB, return; } - assert(0 && "unimplemented reg-to-reg copy"); + if (DestReg == AArch64::NZCV) { + assert(AArch64::GPR64RegClass.contains(SrcReg) && "Invalid NZCV copy"); + BuildMI(MBB, I, DL, get(AArch64::MSR)) + .addImm(AArch64SysReg::NZCV) + .addReg(SrcReg, getKillRegState(KillSrc)) + .addReg(AArch64::NZCV, RegState::Implicit | RegState::Define); + return; + } + + if (SrcReg == AArch64::NZCV) { + assert(AArch64::GPR64RegClass.contains(DestReg) && "Invalid NZCV copy"); + BuildMI(MBB, I, DL, get(AArch64::MRS)) + .addReg(DestReg) + .addImm(AArch64SysReg::NZCV) + .addReg(AArch64::NZCV, RegState::Implicit | getKillRegState(KillSrc)); + return; + } + + llvm_unreachable("unimplemented reg-to-reg copy"); } void AArch64InstrInfo::storeRegToStackSlot( diff --git a/lib/Target/AArch64/AArch64RegisterInfo.cpp b/lib/Target/AArch64/AArch64RegisterInfo.cpp index 48a361d50e5..01b9587b317 100644 --- a/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -138,7 +138,7 @@ AArch64RegisterInfo::getPointerRegClass(const MachineFunction &MF, const TargetRegisterClass * AArch64RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { if (RC == &AArch64::CCRRegClass) - return nullptr; // Can't copy NZCV. + return &AArch64::GPR64RegClass; // Only MSR & MRS copy NZCV. return RC; }