From afff169f17cd66a9d0399c2ae560e12b4925ef25 Mon Sep 17 00:00:00 2001 From: Dylan McKay Date: Wed, 5 Oct 2016 13:38:29 +0000 Subject: [PATCH] [AVR] Don't select 'MOVW' instructions when they are not supported We have a subtarget feature which we were ignoring, which was causing us to generate unsupported instructions for some older chips. llvm-svn: 283317 --- llvm/lib/Target/AVR/AVRInstrInfo.cpp | 56 ++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.cpp b/llvm/lib/Target/AVR/AVRInstrInfo.cpp index 634d83d..88f8892 100644 --- a/llvm/lib/Target/AVR/AVRInstrInfo.cpp +++ b/llvm/lib/Target/AVR/AVRInstrInfo.cpp @@ -27,6 +27,7 @@ #include "AVR.h" #include "AVRMachineFunctionInfo.h" +#include "AVRRegisterInfo.h" #include "AVRTargetMachine.h" #include "MCTargetDesc/AVRMCTargetDesc.h" @@ -42,22 +43,41 @@ void AVRInstrInfo::copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const { + const AVRSubtarget &STI = MBB.getParent()->getSubtarget(); + const AVRRegisterInfo &TRI = *STI.getRegisterInfo(); unsigned Opc; - if (AVR::GPR8RegClass.contains(DestReg, SrcReg)) { - Opc = AVR::MOVRdRr; - } else if (AVR::DREGSRegClass.contains(DestReg, SrcReg)) { - Opc = AVR::MOVWRdRr; - } else if (SrcReg == AVR::SP && AVR::DREGSRegClass.contains(DestReg)) { - Opc = AVR::SPREAD; - } else if (DestReg == AVR::SP && AVR::DREGSRegClass.contains(SrcReg)) { - Opc = AVR::SPWRITE; + // Not all AVR devices support the 16-bit `MOVW` instruction. + if (AVR::DREGSRegClass.contains(DestReg, SrcReg)) { + if (STI.hasMOVW()) { + BuildMI(MBB, MI, DL, get(AVR::MOVWRdRr), DestReg) + .addReg(SrcReg, getKillRegState(KillSrc)); + } else { + unsigned DestLo, DestHi, SrcLo, SrcHi; + + TRI.splitReg(DestReg, DestLo, DestHi); + TRI.splitReg(SrcReg, SrcLo, SrcHi); + + // Copy each individual register with the `MOV` instruction. + BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestLo) + .addReg(SrcLo, getKillRegState(KillSrc)); + BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestHi) + .addReg(SrcHi, getKillRegState(KillSrc)); + } } else { - llvm_unreachable("Impossible reg-to-reg copy"); - } + if (AVR::GPR8RegClass.contains(DestReg, SrcReg)) { + Opc = AVR::MOVRdRr; + } else if (SrcReg == AVR::SP && AVR::DREGSRegClass.contains(DestReg)) { + Opc = AVR::SPREAD; + } else if (DestReg == AVR::SP && AVR::DREGSRegClass.contains(SrcReg)) { + Opc = AVR::SPWRITE; + } else { + llvm_unreachable("Impossible reg-to-reg copy"); + } - BuildMI(MBB, MI, DL, get(Opc), DestReg) - .addReg(SrcReg, getKillRegState(KillSrc)); + BuildMI(MBB, MI, DL, get(Opc), DestReg) + .addReg(SrcReg, getKillRegState(KillSrc)); + } } unsigned AVRInstrInfo::isLoadFromStackSlot(const MachineInstr &MI, @@ -105,6 +125,9 @@ void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const { MachineFunction &MF = *MBB.getParent(); + AVRMachineFunctionInfo *AFI = MF.getInfo(); + + AFI->setHasSpills(true); DebugLoc DL; if (MI != MBB.end()) { @@ -460,9 +483,11 @@ unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { case TargetOpcode::DBG_VALUE: return 0; case TargetOpcode::INLINEASM: { - const MachineFunction *MF = MI.getParent()->getParent(); - const AVRTargetMachine &TM = static_cast(MF->getTarget()); - const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo(); + const MachineFunction &MF = *MI.getParent()->getParent(); + const AVRTargetMachine &TM = static_cast(MF.getTarget()); + const AVRSubtarget &STI = MF.getSubtarget(); + const TargetInstrInfo &TII = *STI.getInstrInfo(); + return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(), *TM.getMCAsmInfo()); } @@ -470,3 +495,4 @@ unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { } } // end of namespace llvm + -- 2.7.4