summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/AVR/AVRInstrInfo.cpp56
1 files changed, 41 insertions, 15 deletions
diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.cpp b/llvm/lib/Target/AVR/AVRInstrInfo.cpp
index 634d83de148..88f889260cc 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<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,
@@ -105,6 +125,9 @@ void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
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()) {
@@ -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<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());
}
@@ -470,3 +495,4 @@ unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
}
} // end of namespace llvm
+
OpenPOWER on IntegriCloud