#include "AVR.h"
#include "AVRMachineFunctionInfo.h"
+#include "AVRRegisterInfo.h"
#include "AVRTargetMachine.h"
#include "MCTargetDesc/AVRMCTargetDesc.h"
MachineBasicBlock::iterator MI,
const DebugLoc &DL, unsigned DestReg,
unsigned SrcReg, bool KillSrc) const {
+ const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
+ 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,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
MachineFunction &MF = *MBB.getParent();
+ AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
+
+ AFI->setHasSpills(true);
DebugLoc DL;
if (MI != MBB.end()) {
case TargetOpcode::DBG_VALUE:
return 0;
case TargetOpcode::INLINEASM: {
- const MachineFunction *MF = MI.getParent()->getParent();
- const AVRTargetMachine &TM = static_cast<const AVRTargetMachine&>(MF->getTarget());
- const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo();
+ const MachineFunction &MF = *MI.getParent()->getParent();
+ const AVRTargetMachine &TM = static_cast<const AVRTargetMachine&>(MF.getTarget());
+ const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
+ const TargetInstrInfo &TII = *STI.getInstrInfo();
+
return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
*TM.getMCAsmInfo());
}
}
} // end of namespace llvm
+