summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Target/AVR
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Target/AVR')
-rw-r--r--contrib/llvm/lib/Target/AVR/AVR.h2
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRAsmPrinter.cpp13
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRDevices.td23
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp147
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRFrameLowering.cpp29
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp76
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRISelLowering.h2
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRInstrInfo.cpp80
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRInstrInfo.h4
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRInstrInfo.td86
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRInstrumentFunctions.cpp2
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRMCInstLower.cpp18
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRRegisterInfo.cpp37
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRRegisterInfo.td7
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRSubtarget.cpp2
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRSubtarget.h3
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp14
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRTargetMachine.h4
-rw-r--r--contrib/llvm/lib/Target/AVR/AVRTargetObjectFile.cpp2
-rw-r--r--contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp7
-rw-r--r--contrib/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp4
-rw-r--r--contrib/llvm/lib/Target/AVR/InstPrinter/AVRInstPrinter.cpp2
-rw-r--r--contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp47
-rw-r--r--contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h13
-rw-r--r--contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRELFStreamer.cpp6
-rw-r--r--contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp3
-rw-r--r--contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp5
-rw-r--r--contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.h5
-rw-r--r--contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp2
-rw-r--r--contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.cpp2
30 files changed, 421 insertions, 226 deletions
diff --git a/contrib/llvm/lib/Target/AVR/AVR.h b/contrib/llvm/lib/Target/AVR/AVR.h
index 8e5cc53..5eadf7b 100644
--- a/contrib/llvm/lib/Target/AVR/AVR.h
+++ b/contrib/llvm/lib/Target/AVR/AVR.h
@@ -15,8 +15,8 @@
#ifndef LLVM_AVR_H
#define LLVM_AVR_H
-#include "llvm/Target/TargetMachine.h"
#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/Target/TargetMachine.h"
namespace llvm {
diff --git a/contrib/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/contrib/llvm/lib/Target/AVR/AVRAsmPrinter.cpp
index 4afdd3a..c058c9e 100644
--- a/contrib/llvm/lib/Target/AVR/AVRAsmPrinter.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRAsmPrinter.cpp
@@ -18,8 +18,8 @@
#include "InstPrinter/AVRInstPrinter.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
@@ -112,7 +112,8 @@ bool AVRAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
const AVRSubtarget &STI = MF->getSubtarget<AVRSubtarget>();
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
- unsigned BytesPerReg = TRI.getMinimalPhysRegClass(Reg)->getSize();
+ const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
+ unsigned BytesPerReg = TRI.getRegSizeInBits(*RC) / 8;
assert(BytesPerReg <= 2 && "Only 8 and 16 bit regs are supported.");
unsigned RegIdx = ByteNumber / BytesPerReg;
@@ -130,7 +131,8 @@ bool AVRAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
}
}
- printOperand(MI, OpNum, O);
+ if (Error)
+ printOperand(MI, OpNum, O);
return false;
}
@@ -147,7 +149,10 @@ bool AVRAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
(void)MO;
assert(MO.isReg() && "Unexpected inline asm memory operand");
- // TODO: We can look up the alternative name for the register if it's given.
+ // TODO: We should be able to look up the alternative name for
+ // the register if it's given.
+ // TableGen doesn't expose a way of getting retrieving names
+ // for registers.
if (MI->getOperand(OpNum).getReg() == AVR::R31R30) {
O << "Z";
} else {
diff --git a/contrib/llvm/lib/Target/AVR/AVRDevices.td b/contrib/llvm/lib/Target/AVR/AVRDevices.td
index 9224af6..62def45 100644
--- a/contrib/llvm/lib/Target/AVR/AVRDevices.td
+++ b/contrib/llvm/lib/Target/AVR/AVRDevices.td
@@ -6,7 +6,6 @@
// :TODO: We define all devices with SRAM to have all variants of LD/ST/LDD/STD.
// In reality, avr1 (no SRAM) has one variant each of `LD` and `ST`.
// avr2 (with SRAM) adds the rest of the variants.
-// :TODO: s/AVRTiny/Tiny
// A feature set aggregates features, grouping them. We don't want to create a
@@ -136,7 +135,7 @@ def ELFArchAVR4 : ELFArch<"EF_AVR_ARCH_AVR4">;
def ELFArchAVR5 : ELFArch<"EF_AVR_ARCH_AVR5">;
def ELFArchAVR51 : ELFArch<"EF_AVR_ARCH_AVR51">;
def ELFArchAVR6 : ELFArch<"EF_AVR_ARCH_AVR6">;
-def ELFArchAVRTiny : ELFArch<"EF_AVR_ARCH_AVRTINY">;
+def ELFArchTiny : ELFArch<"EF_AVR_ARCH_AVRTINY">;
def ELFArchXMEGA1 : ELFArch<"EF_AVR_ARCH_XMEGA1">;
def ELFArchXMEGA2 : ELFArch<"EF_AVR_ARCH_XMEGA2">;
def ELFArchXMEGA3 : ELFArch<"EF_AVR_ARCH_XMEGA3">;
@@ -189,7 +188,7 @@ def FamilyAVR51 : Family<"avr51",
def FamilyAVR6 : Family<"avr6",
[FamilyAVR51]>;
-def FamilyAVRTiny : Family<"avrtiny",
+def FamilyTiny : Family<"avrtiny",
[FamilyAVR0, FeatureBREAK, FeatureSRAM,
FeatureTinyEncoding]>;
@@ -240,7 +239,7 @@ def : Device<"avrxmega4", FamilyXMEGA, ELFArchXMEGA4>;
def : Device<"avrxmega5", FamilyXMEGA, ELFArchXMEGA5>;
def : Device<"avrxmega6", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"avrxmega7", FamilyXMEGA, ELFArchXMEGA7>;
-def : Device<"avrtiny", FamilyAVRTiny, ELFArchAVRTiny>;
+def : Device<"avrtiny", FamilyTiny, ELFArchTiny>;
// Specific MCUs
def : Device<"at90s1200", FamilyAVR0, ELFArchAVR1>;
@@ -480,12 +479,12 @@ def : Device<"atxmega384d3", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega128a1", FamilyXMEGA, ELFArchXMEGA7>;
def : Device<"atxmega128a1u", FamilyXMEGAU, ELFArchXMEGA7>;
def : Device<"atxmega128a4u", FamilyXMEGAU, ELFArchXMEGA7>;
-def : Device<"attiny4", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny5", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny9", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny10", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny20", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny40", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny102", FamilyAVRTiny, ELFArchAVRTiny>;
-def : Device<"attiny104", FamilyAVRTiny, ELFArchAVRTiny>;
+def : Device<"attiny4", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny5", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny9", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny10", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny20", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny40", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny102", FamilyTiny, ELFArchTiny>;
+def : Device<"attiny104", FamilyTiny, ELFArchTiny>;
diff --git a/contrib/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/contrib/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
index 1b2f2ce..540e05a 100644
--- a/contrib/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRExpandPseudoInsts.cpp
@@ -88,6 +88,9 @@ private:
unsigned ArithOpcode,
Block &MBB,
BlockIt MBBI);
+
+ /// Scavenges a free GPR8 register for use.
+ unsigned scavengeGPR8(MachineInstr &MI);
};
char AVRExpandPseudo::ID = 0;
@@ -509,8 +512,8 @@ bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &MBB, BlockIt MBBI) {
const BlockAddress *BA = MI.getOperand(1).getBlockAddress();
unsigned TF = MI.getOperand(1).getTargetFlags();
- MIBLO.addOperand(MachineOperand::CreateBA(BA, TF | AVRII::MO_LO));
- MIBHI.addOperand(MachineOperand::CreateBA(BA, TF | AVRII::MO_HI));
+ MIBLO.add(MachineOperand::CreateBA(BA, TF | AVRII::MO_LO));
+ MIBHI.add(MachineOperand::CreateBA(BA, TF | AVRII::MO_HI));
break;
}
case MachineOperand::MO_Immediate: {
@@ -577,24 +580,43 @@ bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
MachineInstr &MI = *MBBI;
unsigned OpLo, OpHi, DstLoReg, DstHiReg;
unsigned DstReg = MI.getOperand(0).getReg();
+ unsigned TmpReg = 0; // 0 for no temporary register
unsigned SrcReg = MI.getOperand(1).getReg();
- bool DstIsDead = MI.getOperand(0).isDead();
bool SrcIsKill = MI.getOperand(1).isKill();
OpLo = AVR::LDRdPtr;
OpHi = AVR::LDDRdPtrQ;
TRI->splitReg(DstReg, DstLoReg, DstHiReg);
- assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
+ // Use a temporary register if src and dst registers are the same.
+ if (DstReg == SrcReg)
+ TmpReg = scavengeGPR8(MI);
+
+ unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
+ unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
+ // Load low byte.
auto MIBLO = buildMI(MBB, MBBI, OpLo)
- .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
+ .addReg(CurDstLoReg, RegState::Define)
.addReg(SrcReg);
+ // Push low byte onto stack if necessary.
+ if (TmpReg)
+ buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
+
+ // Load high byte.
auto MIBHI = buildMI(MBB, MBBI, OpHi)
- .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
+ .addReg(CurDstHiReg, RegState::Define)
.addReg(SrcReg, getKillRegState(SrcIsKill))
.addImm(1);
+ if (TmpReg) {
+ // Move the high byte into the final destination.
+ buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
+
+ // Move the low byte from the scratch space into the final destination.
+ buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
+ }
+
MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
@@ -669,9 +691,9 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
MachineInstr &MI = *MBBI;
unsigned OpLo, OpHi, DstLoReg, DstHiReg;
unsigned DstReg = MI.getOperand(0).getReg();
+ unsigned TmpReg = 0; // 0 for no temporary register
unsigned SrcReg = MI.getOperand(1).getReg();
unsigned Imm = MI.getOperand(2).getImm();
- bool DstIsDead = MI.getOperand(0).isDead();
bool SrcIsKill = MI.getOperand(1).isKill();
OpLo = AVR::LDDRdPtrQ;
OpHi = AVR::LDDRdPtrQ;
@@ -679,60 +701,35 @@ bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
assert(Imm <= 63 && "Offset is out of range");
- MachineInstr *MIBLO, *MIBHI;
-
- // HACK: We shouldn't have instances of this instruction
- // where src==dest because the instruction itself is
- // marked earlyclobber. We do however get this instruction when
- // loading from stack slots where the earlyclobber isn't useful.
- //
- // In this case, just use a temporary register.
- if (DstReg == SrcReg) {
- RegScavenger RS;
-
- RS.enterBasicBlock(MBB);
- RS.forward(MBBI);
-
- BitVector Candidates =
- TRI->getAllocatableSet
- (*MBB.getParent(), &AVR::GPR8RegClass);
-
- // Exclude all the registers being used by the instruction.
- for (MachineOperand &MO : MI.operands()) {
- if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
- !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
- Candidates.reset(MO.getReg());
- }
-
- BitVector Available = RS.getRegsAvailable(&AVR::GPR8RegClass);
- Available &= Candidates;
+ // Use a temporary register if src and dst registers are the same.
+ if (DstReg == SrcReg)
+ TmpReg = scavengeGPR8(MI);
- signed TmpReg = Available.find_first();
- assert(TmpReg != -1 && "ran out of registers");
+ unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
+ unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
- MIBLO = buildMI(MBB, MBBI, OpLo)
- .addReg(TmpReg, RegState::Define)
- .addReg(SrcReg)
- .addImm(Imm);
+ // Load low byte.
+ auto MIBLO = buildMI(MBB, MBBI, OpLo)
+ .addReg(CurDstLoReg, RegState::Define)
+ .addReg(SrcReg)
+ .addImm(Imm);
- buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstLoReg).addReg(TmpReg);
+ // Push low byte onto stack if necessary.
+ if (TmpReg)
+ buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
- MIBHI = buildMI(MBB, MBBI, OpHi)
- .addReg(TmpReg, RegState::Define)
- .addReg(SrcReg, getKillRegState(SrcIsKill))
- .addImm(Imm + 1);
+ // Load high byte.
+ auto MIBHI = buildMI(MBB, MBBI, OpHi)
+ .addReg(CurDstHiReg, RegState::Define)
+ .addReg(SrcReg, getKillRegState(SrcIsKill))
+ .addImm(Imm + 1);
+ if (TmpReg) {
+ // Move the high byte into the final destination.
buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
- } else {
- MIBLO = buildMI(MBB, MBBI, OpLo)
- .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(SrcReg)
- .addImm(Imm);
- MIBHI = buildMI(MBB, MBBI, OpHi)
- .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
- .addReg(SrcReg, getKillRegState(SrcIsKill))
- .addImm(Imm + 1);
+ // Move the low byte from the scratch space into the final destination.
+ buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
}
MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
@@ -785,9 +782,8 @@ bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode,
auto Op1 = MI.getOperand(0);
auto Op2 = MI.getOperand(1);
- MachineInstr &NewInst = *buildMI(MBB, MBBI, Opcode)
- .addOperand(Op1).addOperand(Op2)
- .getInstr();
+ MachineInstr &NewInst =
+ *buildMI(MBB, MBBI, Opcode).add(Op1).add(Op2).getInstr();
f(NewInst);
});
}
@@ -810,18 +806,42 @@ bool AVRExpandPseudo::expandAtomicArithmeticOp(unsigned Width,
unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr;
// Create the load
- buildMI(MBB, MBBI, LoadOpcode).addOperand(Op1).addOperand(Op2);
+ buildMI(MBB, MBBI, LoadOpcode).add(Op1).add(Op2);
// Create the arithmetic op
- buildMI(MBB, MBBI, ArithOpcode)
- .addOperand(Op1).addOperand(Op1)
- .addOperand(Op2);
+ buildMI(MBB, MBBI, ArithOpcode).add(Op1).add(Op1).add(Op2);
// Create the store
- buildMI(MBB, MBBI, StoreOpcode).addOperand(Op2).addOperand(Op1);
+ buildMI(MBB, MBBI, StoreOpcode).add(Op2).add(Op1);
});
}
+unsigned AVRExpandPseudo::scavengeGPR8(MachineInstr &MI) {
+ MachineBasicBlock &MBB = *MI.getParent();
+ RegScavenger RS;
+
+ RS.enterBasicBlock(MBB);
+ RS.forward(MI);
+
+ BitVector Candidates =
+ TRI->getAllocatableSet
+ (*MBB.getParent(), &AVR::GPR8RegClass);
+
+ // Exclude all the registers being used by the instruction.
+ for (MachineOperand &MO : MI.operands()) {
+ if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
+ !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
+ Candidates.reset(MO.getReg());
+ }
+
+ BitVector Available = RS.getRegsAvailable(&AVR::GPR8RegClass);
+ Available &= Candidates;
+
+ signed Reg = Available.find_first();
+ assert(Reg != -1 && "ran out of registers");
+ return Reg;
+}
+
template<>
bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) {
return expandAtomicBinaryOp(AVR::LDRdPtr, MBB, MBBI);
@@ -951,7 +971,6 @@ bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) {
unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
unsigned DstReg = MI.getOperand(0).getReg();
unsigned SrcReg = MI.getOperand(1).getReg();
- bool DstIsKill = MI.getOperand(0).isKill();
bool SrcIsKill = MI.getOperand(1).isKill();
OpLo = AVR::STPtrRr;
OpHi = AVR::STDPtrQRr;
@@ -963,7 +982,7 @@ bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) {
.addReg(SrcLoReg, getKillRegState(SrcIsKill));
auto MIBHI = buildMI(MBB, MBBI, OpHi)
- .addReg(DstReg, getKillRegState(DstIsKill))
+ .addReg(DstReg)
.addImm(1)
.addReg(SrcHiReg, getKillRegState(SrcIsKill));
diff --git a/contrib/llvm/lib/Target/AVR/AVRFrameLowering.cpp b/contrib/llvm/lib/Target/AVR/AVRFrameLowering.cpp
index b8cb221..0ec8e8b 100644
--- a/contrib/llvm/lib/Target/AVR/AVRFrameLowering.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRFrameLowering.cpp
@@ -57,6 +57,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
DebugLoc DL = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc();
const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
const AVRInstrInfo &TII = *STI.getInstrInfo();
+ bool HasFP = hasFP(MF);
// Interrupt handlers re-enable interrupts in function entry.
if (CallConv == CallingConv::AVR_INTR) {
@@ -65,6 +66,13 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
.setMIFlag(MachineInstr::FrameSetup);
}
+ // Save the frame pointer if we have one.
+ if (HasFP) {
+ BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr))
+ .addReg(AVR::R29R28, RegState::Kill)
+ .setMIFlag(MachineInstr::FrameSetup);
+ }
+
// Emit special prologue code to save R1, R0 and SREG in interrupt/signal
// handlers before saving any other registers.
if (CallConv == CallingConv::AVR_INTR ||
@@ -72,6 +80,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr))
.addReg(AVR::R1R0, RegState::Kill)
.setMIFlag(MachineInstr::FrameSetup);
+
BuildMI(MBB, MBBI, DL, TII.get(AVR::INRdA), AVR::R0)
.addImm(0x3f)
.setMIFlag(MachineInstr::FrameSetup);
@@ -86,7 +95,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF,
}
// Early exit if the frame pointer is not needed in this function.
- if (!hasFP(MF)) {
+ if (!HasFP) {
return;
}
@@ -165,6 +174,9 @@ void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R1R0);
}
+ if (hasFP(MF))
+ BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R29R28);
+
// Early exit if there is no need to restore the frame pointer.
if (!FrameSize) {
return;
@@ -239,7 +251,7 @@ bool AVRFrameLowering::spillCalleeSavedRegisters(
unsigned Reg = CSI[i - 1].getReg();
bool IsNotLiveIn = !MBB.isLiveIn(Reg);
- assert(TRI->getMinimalPhysRegClass(Reg)->getSize() == 1 &&
+ assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
"Invalid register size");
// Add the callee-saved register as live-in only if it is not already a
@@ -277,7 +289,7 @@ bool AVRFrameLowering::restoreCalleeSavedRegisters(
for (const CalleeSavedInfo &CCSI : CSI) {
unsigned Reg = CCSI.getReg();
- assert(TRI->getMinimalPhysRegClass(Reg)->getSize() == 1 &&
+ assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
"Invalid register size");
BuildMI(MBB, MI, DL, TII.get(AVR::POPRd), Reg);
@@ -363,7 +375,7 @@ MachineBasicBlock::iterator AVRFrameLowering::eliminateCallFramePseudoInstr(
DebugLoc DL = MI->getDebugLoc();
unsigned int Opcode = MI->getOpcode();
- int Amount = MI->getOperand(0).getImm();
+ int Amount = TII.getFrameSize(*MI);
// Adjcallstackup does not need to allocate stack space for the call, instead
// we insert push instructions that will allocate the necessary stack.
@@ -407,12 +419,9 @@ void AVRFrameLowering::determineCalleeSaves(MachineFunction &MF,
RegScavenger *RS) const {
TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
- // Spill register Y when it is used as the frame pointer.
- if (hasFP(MF)) {
- SavedRegs.set(AVR::R29R28);
- SavedRegs.set(AVR::R29);
- SavedRegs.set(AVR::R28);
- }
+ // If we have a frame pointer, the Y register needs to be saved as well.
+ // We don't do that here however - the prologue and epilogue generation
+ // code will handle it specially.
}
/// The frame analyzer pass.
///
diff --git a/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp b/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp
index 07fc3f6..7d3faac 100644
--- a/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -48,6 +48,8 @@ AVRTargetLowering::AVRTargetLowering(AVRTargetMachine &tm)
setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
setOperationAction(ISD::BlockAddress, MVT::i16, Custom);
+ setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
+ setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);
@@ -77,6 +79,11 @@ AVRTargetLowering::AVRTargetLowering(AVRTargetMachine &tm)
setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand);
setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand);
+ setOperationAction(ISD::ROTL, MVT::i8, Custom);
+ setOperationAction(ISD::ROTL, MVT::i16, Custom);
+ setOperationAction(ISD::ROTR, MVT::i8, Custom);
+ setOperationAction(ISD::ROTR, MVT::i16, Custom);
+
setOperationAction(ISD::BR_CC, MVT::i8, Custom);
setOperationAction(ISD::BR_CC, MVT::i16, Custom);
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
@@ -271,6 +278,12 @@ SDValue AVRTargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) const {
case ISD::SRL:
return DAG.getNode(AVRISD::LSRLOOP, dl, VT, N->getOperand(0),
N->getOperand(1));
+ case ISD::ROTL:
+ return DAG.getNode(AVRISD::ROLLOOP, dl, VT, N->getOperand(0),
+ N->getOperand(1));
+ case ISD::ROTR:
+ return DAG.getNode(AVRISD::RORLOOP, dl, VT, N->getOperand(0),
+ N->getOperand(1));
case ISD::SRA:
return DAG.getNode(AVRISD::ASRLOOP, dl, VT, N->getOperand(0),
N->getOperand(1));
@@ -311,7 +324,7 @@ SDValue AVRTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
unsigned Opcode = Op->getOpcode();
assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) &&
"Invalid opcode for Div/Rem lowering");
- bool isSigned = (Opcode == ISD::SDIVREM);
+ bool IsSigned = (Opcode == ISD::SDIVREM);
EVT VT = Op->getValueType(0);
Type *Ty = VT.getTypeForEVT(*DAG.getContext());
@@ -320,16 +333,16 @@ SDValue AVRTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
default:
llvm_unreachable("Unexpected request for libcall!");
case MVT::i8:
- LC = isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
+ LC = IsSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8;
break;
case MVT::i16:
- LC = isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
+ LC = IsSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16;
break;
case MVT::i32:
- LC = isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
+ LC = IsSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
break;
case MVT::i64:
- LC = isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
+ LC = IsSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64;
break;
}
@@ -340,24 +353,24 @@ SDValue AVRTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
for (SDValue const &Value : Op->op_values()) {
Entry.Node = Value;
Entry.Ty = Value.getValueType().getTypeForEVT(*DAG.getContext());
- Entry.isSExt = isSigned;
- Entry.isZExt = !isSigned;
+ Entry.IsSExt = IsSigned;
+ Entry.IsZExt = !IsSigned;
Args.push_back(Entry);
}
SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),
getPointerTy(DAG.getDataLayout()));
- Type *RetTy = (Type *)StructType::get(Ty, Ty, nullptr);
+ Type *RetTy = (Type *)StructType::get(Ty, Ty);
SDLoc dl(Op);
TargetLowering::CallLoweringInfo CLI(DAG);
CLI.setDebugLoc(dl)
.setChain(InChain)
- .setCallee(getLibcallCallingConv(LC), RetTy, Callee, std::move(Args))
+ .setLibCallee(getLibcallCallingConv(LC), RetTy, Callee, std::move(Args))
.setInRegister()
- .setSExtResult(isSigned)
- .setZExtResult(!isSigned);
+ .setSExtResult(IsSigned)
+ .setZExtResult(!IsSigned);
std::pair<SDValue, SDValue> CallInfo = LowerCallTo(CLI);
return CallInfo.first;
@@ -932,6 +945,12 @@ static void analyzeStandardArguments(TargetLowering::CallLoweringInfo *CLI,
bool UsesStack = false;
for (unsigned i = 0, pos = 0, e = Args.size(); i != e; ++i) {
unsigned Size = Args[i];
+
+ // If we have a zero-sized argument, don't attempt to lower it.
+ // AVR-GCC does not support zero-sized arguments and so we need not
+ // worry about ABI compatibility.
+ if (Size == 0) continue;
+
MVT LocVT = (IsCall) ? (*Outs)[pos].VT : (*Ins)[pos].VT;
// If we have plenty of regs to pass the whole argument do it.
@@ -1147,8 +1166,7 @@ SDValue AVRTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Get a count of how many bytes are to be pushed on the stack.
unsigned NumBytes = CCInfo.getNextStackOffset();
- Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, DL, true),
- DL);
+ Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, DL);
SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
@@ -1373,7 +1391,7 @@ AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
// Don't emit the ret/reti instruction when the naked attribute is present in
// the function being compiled.
if (MF.getFunction()->getAttributes().hasAttribute(
- AttributeSet::FunctionIndex, Attribute::Naked)) {
+ AttributeList::FunctionIndex, Attribute::Naked)) {
return Chain;
}
@@ -1432,6 +1450,22 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,
Opc = AVR::LSRWRd;
RC = &AVR::DREGSRegClass;
break;
+ case AVR::Rol8:
+ Opc = AVR::ROLRd;
+ RC = &AVR::GPR8RegClass;
+ break;
+ case AVR::Rol16:
+ Opc = AVR::ROLWRd;
+ RC = &AVR::DREGSRegClass;
+ break;
+ case AVR::Ror8:
+ Opc = AVR::RORRd;
+ RC = &AVR::GPR8RegClass;
+ break;
+ case AVR::Ror16:
+ Opc = AVR::RORWRd;
+ RC = &AVR::DREGSRegClass;
+ break;
}
const BasicBlock *LLVM_BB = BB->getBasicBlock();
@@ -1466,9 +1500,9 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,
unsigned DstReg = MI.getOperand(0).getReg();
// BB:
- // cp 0, N
+ // cpi N, 0
// breq RemBB
- BuildMI(BB, dl, TII.get(AVR::CPRdRr)).addReg(ShiftAmtSrcReg).addReg(AVR::R0);
+ BuildMI(BB, dl, TII.get(AVR::CPIRdK)).addReg(ShiftAmtSrcReg).addImm(0);
BuildMI(BB, dl, TII.get(AVR::BREQk)).addMBB(RemBB);
// LoopBB:
@@ -1544,6 +1578,10 @@ AVRTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
case AVR::Lsl16:
case AVR::Lsr8:
case AVR::Lsr16:
+ case AVR::Rol8:
+ case AVR::Rol16:
+ case AVR::Ror8:
+ case AVR::Ror16:
case AVR::Asr8:
case AVR::Asr16:
return insertShift(MI, MBB);
@@ -1572,8 +1610,9 @@ AVRTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *trueMBB = MF->CreateMachineBasicBlock(LLVM_BB);
MachineBasicBlock *falseMBB = MF->CreateMachineBasicBlock(LLVM_BB);
- MachineFunction::iterator I = MBB->getParent()->begin();
- ++I;
+ MachineFunction::iterator I;
+ for (I = MF->begin(); I != MF->end() && &(*I) != MBB; ++I);
+ if (I != MF->end()) ++I;
MF->insert(I, trueMBB);
MF->insert(I, falseMBB);
@@ -1975,4 +2014,3 @@ unsigned AVRTargetLowering::getRegisterByName(const char *RegName,
}
} // end of namespace llvm
-
diff --git a/contrib/llvm/lib/Target/AVR/AVRISelLowering.h b/contrib/llvm/lib/Target/AVR/AVRISelLowering.h
index a8cdc4e..b44c62a 100644
--- a/contrib/llvm/lib/Target/AVR/AVRISelLowering.h
+++ b/contrib/llvm/lib/Target/AVR/AVRISelLowering.h
@@ -43,6 +43,8 @@ enum NodeType {
ROL, ///< Bit rotate left.
LSLLOOP, ///< A loop of single logical shift left instructions.
LSRLOOP, ///< A loop of single logical shift right instructions.
+ ROLLOOP, ///< A loop of single left bit rotate instructions.
+ RORLOOP, ///< A loop of single right bit rotate instructions.
ASRLOOP, ///< A loop of single arithmetic shift right instructions.
/// AVR conditional branches. Operand 0 is the chain operand, operand 1
/// is the block to branch if condition is true, operand 2 is the
diff --git a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.cpp b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.cpp
index 88f8892..744aa72 100644
--- a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.cpp
@@ -142,9 +142,9 @@ void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
MFI.getObjectAlignment(FrameIndex));
unsigned Opcode = 0;
- if (RC->hasType(MVT::i8)) {
+ if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
Opcode = AVR::STDPtrQRr;
- } else if (RC->hasType(MVT::i16)) {
+ } else if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
Opcode = AVR::STDWPtrQRr;
} else {
llvm_unreachable("Cannot store this register into a stack slot!");
@@ -176,9 +176,9 @@ void AVRInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
MFI.getObjectAlignment(FrameIndex));
unsigned Opcode = 0;
- if (RC->hasType(MVT::i8)) {
+ if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
Opcode = AVR::LDDRdPtrQ;
- } else if (RC->hasType(MVT::i16)) {
+ } else if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
// Opcode = AVR::LDDWRdPtrQ;
//:FIXME: remove this once PR13375 gets fixed
Opcode = AVR::LDDWRdYQ;
@@ -402,7 +402,7 @@ unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
ArrayRef<MachineOperand> Cond,
const DebugLoc &DL,
int *BytesAdded) const {
- assert(!BytesAdded && "code size not handled");
+ if (BytesAdded) *BytesAdded = 0;
// Shouldn't be a fall through.
assert(TBB && "insertBranch must not be told to insert a fallthrough");
@@ -411,19 +411,24 @@ unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
if (Cond.empty()) {
assert(!FBB && "Unconditional branch with multiple successors!");
- BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB);
+ auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB);
+ if (BytesAdded)
+ *BytesAdded += getInstSizeInBytes(MI);
return 1;
}
// Conditional branch.
unsigned Count = 0;
AVRCC::CondCodes CC = (AVRCC::CondCodes)Cond[0].getImm();
- BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
+ auto &CondMI = *BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
+
+ if (BytesAdded) *BytesAdded += getInstSizeInBytes(CondMI);
++Count;
if (FBB) {
// Two-way Conditional branch. Insert the second branch.
- BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB);
+ auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB);
+ if (BytesAdded) *BytesAdded += getInstSizeInBytes(MI);
++Count;
}
@@ -432,7 +437,7 @@ unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
unsigned AVRInstrInfo::removeBranch(MachineBasicBlock &MBB,
int *BytesRemoved) const {
- assert(!BytesRemoved && "code size not handled");
+ if (BytesRemoved) *BytesRemoved = 0;
MachineBasicBlock::iterator I = MBB.end();
unsigned Count = 0;
@@ -450,6 +455,7 @@ unsigned AVRInstrInfo::removeBranch(MachineBasicBlock &MBB,
}
// Remove the branch.
+ if (BytesRemoved) *BytesRemoved += getInstSizeInBytes(*I);
I->eraseFromParent();
I = MBB.end();
++Count;
@@ -494,5 +500,61 @@ unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
}
}
+MachineBasicBlock *
+AVRInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
+ switch (MI.getOpcode()) {
+ default:
+ llvm_unreachable("unexpected opcode!");
+ case AVR::JMPk:
+ case AVR::CALLk:
+ case AVR::RCALLk:
+ case AVR::RJMPk:
+ case AVR::BREQk:
+ case AVR::BRNEk:
+ case AVR::BRSHk:
+ case AVR::BRLOk:
+ case AVR::BRMIk:
+ case AVR::BRPLk:
+ case AVR::BRGEk:
+ case AVR::BRLTk:
+ return MI.getOperand(0).getMBB();
+ case AVR::BRBSsk:
+ case AVR::BRBCsk:
+ return MI.getOperand(1).getMBB();
+ case AVR::SBRCRrB:
+ case AVR::SBRSRrB:
+ case AVR::SBICAb:
+ case AVR::SBISAb:
+ llvm_unreachable("unimplemented branch instructions");
+ }
+}
+
+bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
+ int64_t BrOffset) const {
+
+ switch (BranchOp) {
+ default:
+ llvm_unreachable("unexpected opcode!");
+ case AVR::JMPk:
+ case AVR::CALLk:
+ assert(BrOffset >= 0 && "offset must be absolute address");
+ return isUIntN(16, BrOffset);
+ case AVR::RCALLk:
+ case AVR::RJMPk:
+ return isIntN(13, BrOffset);
+ case AVR::BRBSsk:
+ case AVR::BRBCsk:
+ case AVR::BREQk:
+ case AVR::BRNEk:
+ case AVR::BRSHk:
+ case AVR::BRLOk:
+ case AVR::BRMIk:
+ case AVR::BRPLk:
+ case AVR::BRGEk:
+ case AVR::BRLTk:
+ return isIntN(7, BrOffset);
+ }
+}
+
} // end of namespace llvm
diff --git a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.h b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.h
index c5105da..f42d34f 100644
--- a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.h
+++ b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.h
@@ -103,6 +103,10 @@ public:
bool
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
+ MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
+
+ bool isBranchOffsetInRange(unsigned BranchOpc,
+ int64_t BrOffset) const override;
private:
const AVRRegisterInfo RI;
};
diff --git a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td
index bc66379..184e4d5 100644
--- a/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td
+++ b/contrib/llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -17,7 +17,7 @@ include "AVRInstrFormats.td"
// AVR Type Profiles
//===----------------------------------------------------------------------===//
-def SDT_AVRCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i16>]>;
+def SDT_AVRCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i16>, SDTCisVT<1, i16>]>;
def SDT_AVRCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i16>, SDTCisVT<1, i16>]>;
def SDT_AVRCall : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
def SDT_AVRWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
@@ -64,6 +64,8 @@ def AVRasr : SDNode<"AVRISD::ASR", SDTIntUnaryOp>;
// Pseudo shift nodes for non-constant shift amounts.
def AVRlslLoop : SDNode<"AVRISD::LSLLOOP", SDTIntShiftOp>;
def AVRlsrLoop : SDNode<"AVRISD::LSRLOOP", SDTIntShiftOp>;
+def AVRrolLoop : SDNode<"AVRISD::ROLLOOP", SDTIntShiftOp>;
+def AVRrorLoop : SDNode<"AVRISD::RORLOOP", SDTIntShiftOp>;
def AVRasrLoop : SDNode<"AVRISD::ASRLOOP", SDTIntShiftOp>;
//===----------------------------------------------------------------------===//
@@ -183,33 +185,33 @@ def call_target : Operand<iPTR>
// A 16-bit address (which can lead to an R_AVR_16 relocation).
def imm16 : Operand<i16>
{
- let EncoderMethod = "encodeImm<AVR::fixup_16>";
+ let EncoderMethod = "encodeImm<AVR::fixup_16, 2>";
}
/// A 6-bit immediate used in the ADIW/SBIW instructions.
def imm_arith6 : Operand<i16>
{
- let EncoderMethod = "encodeImm<AVR::fixup_6_adiw>";
+ let EncoderMethod = "encodeImm<AVR::fixup_6_adiw, 0>";
}
/// An 8-bit immediate inside an instruction with the same format
/// as the `LDI` instruction (the `FRdK` format).
def imm_ldi8 : Operand<i8>
{
- let EncoderMethod = "encodeImm<AVR::fixup_ldi>";
+ let EncoderMethod = "encodeImm<AVR::fixup_ldi, 0>";
}
/// A 5-bit port number used in SBIC and friends (the `FIOBIT` format).
def imm_port5 : Operand<i8>
{
- let EncoderMethod = "encodeImm<AVR::fixup_port5>";
+ let EncoderMethod = "encodeImm<AVR::fixup_port5, 0>";
}
/// A 6-bit port number used in the `IN` instruction and friends (the
/// `FIORdA` format.
def imm_port6 : Operand<i8>
{
- let EncoderMethod = "encodeImm<AVR::fixup_port6>";
+ let EncoderMethod = "encodeImm<AVR::fixup_port6, 0>";
}
// Addressing mode pattern reg+imm6
@@ -331,9 +333,9 @@ let Defs = [SP, SREG],
Uses = [SP] in
{
def ADJCALLSTACKDOWN : Pseudo<(outs),
- (ins i16imm:$amt),
+ (ins i16imm:$amt, i16imm:$amt2),
"#ADJCALLSTACKDOWN",
- [(AVRcallseq_start timm:$amt)]>;
+ [(AVRcallseq_start timm:$amt, timm:$amt2)]>;
// R31R30 is used to update SP, since it is a scratch reg and this instruction
// is placed after the function call then R31R30 should be always free.
@@ -694,7 +696,7 @@ Defs = [SREG] in
}
//===----------------------------------------------------------------------===//
-// One's/Two's Compliment
+// One's/Two's Complement
//===----------------------------------------------------------------------===//
let Constraints = "$src = $rd",
Defs = [SREG] in
@@ -900,10 +902,9 @@ let Defs = [SREG] in
// CPI Rd, K
// Compares a register with an 8 bit immediate.
- let Uses = [SREG] in
def CPIRdK : FRdK<0b0011,
(outs),
- (ins GPR8:$rd, imm_ldi8:$k),
+ (ins LD8:$rd, imm_ldi8:$k),
"cpi\t$rd, $k",
[(AVRcmp i8:$rd, imm:$k), (implicit SREG)]>;
}
@@ -1410,17 +1411,11 @@ hasSideEffects = 0 in
def LPMRdZ : FLPMX<0,
0,
(outs GPR8:$dst),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"lpm\t$dst, $z",
[]>,
Requires<[HasLPMX]>;
- def LPMWRdZ : Pseudo<(outs DREGS:$dst),
- (ins ZREGS:$z),
- "lpmw\t$dst, $z",
- []>,
- Requires<[HasLPMX]>;
-
// Load program memory, while postincrementing the Z register.
let mayLoad = 1,
Defs = [R31R30] in
@@ -1428,13 +1423,19 @@ hasSideEffects = 0 in
def LPMRdZPi : FLPMX<0,
1,
(outs GPR8:$dst),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"lpm\t$dst, $z+",
[]>,
Requires<[HasLPMX]>;
+ def LPMWRdZ : Pseudo<(outs DREGS:$dst),
+ (ins ZREG:$z),
+ "lpmw\t$dst, $z",
+ []>,
+ Requires<[HasLPMX]>;
+
def LPMWRdZPi : Pseudo<(outs DREGS:$dst),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"lpmw\t$dst, $z+",
[]>,
Requires<[HasLPMX]>;
@@ -1457,7 +1458,7 @@ hasSideEffects = 0 in
def ELPMRdZ : FLPMX<1,
0,
(outs GPR8:$dst),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"elpm\t$dst, $z",
[]>,
Requires<[HasELPMX]>;
@@ -1466,7 +1467,7 @@ hasSideEffects = 0 in
def ELPMRdZPi : FLPMX<1,
1,
(outs GPR8:$dst),
- (ins ZREGS: $z),
+ (ins ZREG: $z),
"elpm\t$dst, $z+",
[]>,
Requires<[HasELPMX]>;
@@ -1486,7 +1487,7 @@ let Uses = [R1, R0] in
let Defs = [R31R30] in
def SPMZPi : F16<0b1001010111111000,
(outs),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"spm $z+",
[]>,
Requires<[HasSPMX]>;
@@ -1563,28 +1564,28 @@ hasSideEffects = 0 in
// Read-Write-Modify (RMW) instructions.
def XCHZRd : FZRd<0b100,
(outs GPR8:$rd),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"xch\t$z, $rd",
[]>,
Requires<[SupportsRMW]>;
def LASZRd : FZRd<0b101,
(outs GPR8:$rd),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"las\t$z, $rd",
[]>,
Requires<[SupportsRMW]>;
def LACZRd : FZRd<0b110,
(outs GPR8:$rd),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"lac\t$z, $rd",
[]>,
Requires<[SupportsRMW]>;
def LATZRd : FZRd<0b111,
(outs GPR8:$rd),
- (ins ZREGS:$z),
+ (ins ZREG:$z),
"lat\t$z, $rd",
[]>,
Requires<[SupportsRMW]>;
@@ -1718,7 +1719,7 @@ Defs = [SREG] in
(implicit SREG)]>;
// CBR Rd, K
- // Alias for `ANDI Rd, COM(K)` where COM(K) is the compliment of K.
+ // Alias for `ANDI Rd, COM(K)` where COM(K) is the complement of K.
// FIXME: This uses the 'complement' encoder. We need it to also use the
// imm_ldi8 encoder. This will cause no fixups to be created on this instruction.
def CBRRdK : FRdK<0b0111,
@@ -1932,7 +1933,6 @@ def Lsr8 : ShiftPseudo<
[(set i8:$dst, (AVRlsrLoop i8:$src, i8:$cnt))]
>;
-
def Lsr16 : ShiftPseudo<
(outs DREGS:$dst),
(ins DREGS:$src, GPR8:$cnt),
@@ -1940,6 +1940,34 @@ def Lsr16 : ShiftPseudo<
[(set i16:$dst, (AVRlsrLoop i16:$src, i8:$cnt))]
>;
+def Rol8 : ShiftPseudo<
+ (outs GPR8:$dst),
+ (ins GPR8:$src, GPR8:$cnt),
+ "# Rol8 PSEUDO",
+ [(set i8:$dst, (AVRrolLoop i8:$src, i8:$cnt))]
+>;
+
+def Rol16 : ShiftPseudo<
+ (outs DREGS:$dst),
+ (ins DREGS:$src, GPR8:$cnt),
+ "# Rol16 PSEUDO",
+ [(set i16:$dst, (AVRrolLoop i16:$src, i8:$cnt))]
+>;
+
+def Ror8 : ShiftPseudo<
+ (outs GPR8:$dst),
+ (ins GPR8:$src, GPR8:$cnt),
+ "# Ror8 PSEUDO",
+ [(set i8:$dst, (AVRrorLoop i8:$src, i8:$cnt))]
+>;
+
+def Ror16 : ShiftPseudo<
+ (outs DREGS:$dst),
+ (ins DREGS:$src, GPR8:$cnt),
+ "# Ror16 PSEUDO",
+ [(set i16:$dst, (AVRrorLoop i16:$src, i8:$cnt))]
+>;
+
def Asr8 : ShiftPseudo<
(outs GPR8:$dst),
(ins GPR8:$src, GPR8:$cnt),
diff --git a/contrib/llvm/lib/Target/AVR/AVRInstrumentFunctions.cpp b/contrib/llvm/lib/Target/AVR/AVRInstrumentFunctions.cpp
index 5553dc2..e7fca74 100644
--- a/contrib/llvm/lib/Target/AVR/AVRInstrumentFunctions.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRInstrumentFunctions.cpp
@@ -96,7 +96,7 @@ static void BuildSignatureCall(StringRef SymName, BasicBlock &BB, Function &F) {
Value *FunctionName = CreateStringPtr(BB, F.getName());
Value *Args[] = {FunctionName,
- ConstantInt::get(I16, F.getArgumentList().size())};
+ ConstantInt::get(I16, F.arg_size())};
CallInst::Create(Fn, Args, "", &BB);
}
diff --git a/contrib/llvm/lib/Target/AVR/AVRMCInstLower.cpp b/contrib/llvm/lib/Target/AVR/AVRMCInstLower.cpp
index 342fe55..dfefd09 100644
--- a/contrib/llvm/lib/Target/AVR/AVRMCInstLower.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRMCInstLower.cpp
@@ -37,10 +37,22 @@ MCOperand AVRMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
}
+ bool IsFunction = MO.isGlobal() && isa<Function>(MO.getGlobal());
+
if (TF & AVRII::MO_LO) {
- Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx);
+ if (IsFunction) {
+ // N.B. Should we use _GS fixups here to cope with >128k progmem?
+ Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_LO8, Expr, IsNegated, Ctx);
+ } else {
+ Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx);
+ }
} else if (TF & AVRII::MO_HI) {
- Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx);
+ if (IsFunction) {
+ // N.B. Should we use _GS fixups here to cope with >128k progmem?
+ Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_HI8, Expr, IsNegated, Ctx);
+ } else {
+ Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx);
+ }
} else if (TF != 0) {
llvm_unreachable("Unknown target flag on symbol operand");
}
@@ -56,7 +68,7 @@ void AVRMCInstLower::lowerInstruction(const MachineInstr &MI, MCInst &OutMI) con
switch (MO.getType()) {
default:
- MI.dump();
+ MI.print(errs());
llvm_unreachable("unknown operand type");
case MachineOperand::MO_Register:
// Ignore all implicit register operands.
diff --git a/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.cpp b/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.cpp
index 48798bd..249dc55 100644
--- a/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.cpp
@@ -51,8 +51,6 @@ AVRRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
BitVector AVRRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
- const AVRTargetMachine &TM = static_cast<const AVRTargetMachine&>(MF.getTarget());
- const TargetFrameLowering *TFI = TM.getSubtargetImpl()->getFrameLowering();
// Reserve the intermediate result registers r1 and r2
// The result of instructions like 'mul' is always stored here.
@@ -65,12 +63,18 @@ BitVector AVRRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
Reserved.set(AVR::SPH);
Reserved.set(AVR::SP);
- // Reserve the frame pointer registers r28 and r29 if the function requires one.
- if (TFI->hasFP(MF)) {
- Reserved.set(AVR::R28);
- Reserved.set(AVR::R29);
- Reserved.set(AVR::R29R28);
- }
+ // We tenatively reserve the frame pointer register r29:r28 because the
+ // function may require one, but we cannot tell until register allocation
+ // is complete, which can be too late.
+ //
+ // Instead we just unconditionally reserve the Y register.
+ //
+ // TODO: Write a pass to enumerate functions which reserved the Y register
+ // but didn't end up needing a frame pointer. In these, we can
+ // convert one or two of the spills inside to use the Y register.
+ Reserved.set(AVR::R28);
+ Reserved.set(AVR::R29);
+ Reserved.set(AVR::R29R28);
return Reserved;
}
@@ -78,11 +82,12 @@ BitVector AVRRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
const TargetRegisterClass *
AVRRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
const MachineFunction &MF) const {
- if (RC->hasType(MVT::i16)) {
+ const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
+ if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
return &AVR::DREGSRegClass;
}
- if (RC->hasType(MVT::i8)) {
+ if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
return &AVR::GPR8RegClass;
}
@@ -90,7 +95,8 @@ AVRRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
}
/// Fold a frame offset shared between two add instructions into a single one.
-static void foldFrameOffset(MachineInstr &MI, int &Offset, unsigned DstReg) {
+static void foldFrameOffset(MachineBasicBlock::iterator &II, int &Offset, unsigned DstReg) {
+ MachineInstr &MI = *II;
int Opcode = MI.getOpcode();
// Don't bother trying if the next instruction is not an add or a sub.
@@ -115,6 +121,7 @@ static void foldFrameOffset(MachineInstr &MI, int &Offset, unsigned DstReg) {
}
// Finally remove the instruction.
+ II++;
MI.eraseFromParent();
}
@@ -153,6 +160,8 @@ void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
unsigned DstReg = MI.getOperand(0).getReg();
assert(DstReg != AVR::R29R28 && "Dest reg cannot be the frame pointer");
+ II++; // Skip over the FRMIDX (and now MOVW) instruction.
+
// Generally, to load a frame address two add instructions are emitted that
// could get folded into a single one:
// movw r31:r30, r29:r28
@@ -161,7 +170,8 @@ void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
// to:
// movw r31:r30, r29:r28
// adiw r31:r30, 45
- foldFrameOffset(*std::next(II), Offset, DstReg);
+ if (II != MBB.end())
+ foldFrameOffset(II, Offset, DstReg);
// Select the best opcode based on DstReg and the offset size.
switch (DstReg) {
@@ -182,7 +192,7 @@ void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
}
}
- MachineInstr *New = BuildMI(MBB, std::next(II), dl, TII.get(Opcode), DstReg)
+ MachineInstr *New = BuildMI(MBB, II, dl, TII.get(Opcode), DstReg)
.addReg(DstReg, RegState::Kill)
.addImm(Offset);
New->getOperand(3).setIsDead();
@@ -263,4 +273,3 @@ void AVRRegisterInfo::splitReg(unsigned Reg,
}
} // end of namespace llvm
-
diff --git a/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.td b/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.td
index 32650fc..8162f12 100644
--- a/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.td
+++ b/contrib/llvm/lib/Target/AVR/AVRRegisterInfo.td
@@ -110,8 +110,6 @@ CoveredBySubRegs = 1 in
// Register Classes
//===----------------------------------------------------------------------===//
-//:TODO: use proper set instructions instead of using always "add"
-
// Main 8-bit register class.
def GPR8 : RegisterClass<"AVR", [i8], 8,
(
@@ -199,14 +197,11 @@ def PTRDISPREGS : RegisterClass<"AVR", [i16], 8,
// We have a bunch of instructions with an explicit Z register argument. We
// model this using a register class containing only the Z register.
-// :TODO: Rename to 'ZREG'.
-def ZREGS : RegisterClass<"AVR", [i16], 8, (add R31R30)>;
+def ZREG : RegisterClass<"AVR", [i16], 8, (add R31R30)>;
// Register class used for the stack read pseudo instruction.
def GPRSP: RegisterClass<"AVR", [i16], 8, (add SP)>;
-//:TODO: if we remove this we get an error in tablegen
-//:TODO: this is just a hack, remove it once add16 works!
// Status register.
def SREG : AVRReg<14, "FLAGS">, DwarfRegNum<[88]>;
def CCR : RegisterClass<"AVR", [i8], 8, (add SREG)>
diff --git a/contrib/llvm/lib/Target/AVR/AVRSubtarget.cpp b/contrib/llvm/lib/Target/AVR/AVRSubtarget.cpp
index c228d05..556d69e 100644
--- a/contrib/llvm/lib/Target/AVR/AVRSubtarget.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRSubtarget.cpp
@@ -13,7 +13,7 @@
#include "AVRSubtarget.h"
-#include "llvm/Support/ELF.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/Support/TargetRegistry.h"
#include "AVR.h"
diff --git a/contrib/llvm/lib/Target/AVR/AVRSubtarget.h b/contrib/llvm/lib/Target/AVR/AVRSubtarget.h
index a37849c..b0e634f 100644
--- a/contrib/llvm/lib/Target/AVR/AVRSubtarget.h
+++ b/contrib/llvm/lib/Target/AVR/AVRSubtarget.h
@@ -14,10 +14,9 @@
#ifndef LLVM_AVR_SUBTARGET_H
#define LLVM_AVR_SUBTARGET_H
-#include "llvm/Target/TargetSubtargetInfo.h"
-#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
#include "AVRFrameLowering.h"
#include "AVRISelLowering.h"
diff --git a/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp b/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp
index fb32629..a9d61ff 100644
--- a/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRTargetMachine.cpp
@@ -15,12 +15,12 @@
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
-#include "llvm/IR/Module.h"
#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/TargetRegistry.h"
-#include "AVRTargetObjectFile.h"
#include "AVR.h"
+#include "AVRTargetObjectFile.h"
#include "MCTargetDesc/AVRMCTargetDesc.h"
namespace llvm {
@@ -57,7 +57,7 @@ namespace {
/// AVR Code Generator Pass Configuration Options.
class AVRPassConfig : public TargetPassConfig {
public:
- AVRPassConfig(AVRTargetMachine *TM, PassManagerBase &PM)
+ AVRPassConfig(AVRTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
AVRTargetMachine &getAVRTargetMachine() const {
@@ -66,12 +66,13 @@ public:
bool addInstSelector() override;
void addPreSched2() override;
+ void addPreEmitPass() override;
void addPreRegAlloc() override;
};
} // namespace
TargetPassConfig *AVRTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new AVRPassConfig(this, PM);
+ return new AVRPassConfig(*this, PM);
}
extern "C" void LLVMInitializeAVRTarget() {
@@ -115,4 +116,9 @@ void AVRPassConfig::addPreSched2() {
addPass(createAVRExpandPseudoPass());
}
+void AVRPassConfig::addPreEmitPass() {
+ // Must run branch selection immediately preceding the asm printer.
+ addPass(&BranchRelaxationPassID);
+}
+
} // end of namespace llvm
diff --git a/contrib/llvm/lib/Target/AVR/AVRTargetMachine.h b/contrib/llvm/lib/Target/AVR/AVRTargetMachine.h
index 1034519..795e94e 100644
--- a/contrib/llvm/lib/Target/AVR/AVRTargetMachine.h
+++ b/contrib/llvm/lib/Target/AVR/AVRTargetMachine.h
@@ -41,6 +41,10 @@ public:
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
+ bool isMachineVerifierClean() const override {
+ return false;
+ }
+
private:
std::unique_ptr<TargetLoweringObjectFile> TLOF;
AVRSubtarget SubTarget;
diff --git a/contrib/llvm/lib/Target/AVR/AVRTargetObjectFile.cpp b/contrib/llvm/lib/Target/AVR/AVRTargetObjectFile.cpp
index af14d92..0cebb0f 100644
--- a/contrib/llvm/lib/Target/AVR/AVRTargetObjectFile.cpp
+++ b/contrib/llvm/lib/Target/AVR/AVRTargetObjectFile.cpp
@@ -9,12 +9,12 @@
#include "AVRTargetObjectFile.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionELF.h"
-#include "llvm/Support/ELF.h"
#include "AVR.h"
diff --git a/contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp b/contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
index 5b0398c..5004736 100644
--- a/contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
+++ b/contrib/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
@@ -18,12 +18,12 @@
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
@@ -466,6 +466,7 @@ bool AVRAsmParser::parseOperand(OperandVector &Operands) {
if (!tryParseRegisterOperand(Operands)) {
return false;
}
+ LLVM_FALLTHROUGH;
case AsmToken::LParen:
case AsmToken::Integer:
case AsmToken::Dot:
diff --git a/contrib/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp b/contrib/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
index d2a21fb..e69accf 100644
--- a/contrib/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
+++ b/contrib/llvm/lib/Target/AVR/Disassembler/AVRDisassembler.cpp
@@ -16,11 +16,11 @@
#include "AVRSubtarget.h"
#include "MCTargetDesc/AVRMCTargetDesc.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/TargetRegistry.h"
using namespace llvm;
diff --git a/contrib/llvm/lib/Target/AVR/InstPrinter/AVRInstPrinter.cpp b/contrib/llvm/lib/Target/AVR/InstPrinter/AVRInstPrinter.cpp
index 316b783..0f34b8e 100644
--- a/contrib/llvm/lib/Target/AVR/InstPrinter/AVRInstPrinter.cpp
+++ b/contrib/llvm/lib/Target/AVR/InstPrinter/AVRInstPrinter.cpp
@@ -106,7 +106,7 @@ void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
if (Op.isReg()) {
bool isPtrReg = (MOI.RegClass == AVR::PTRREGSRegClassID) ||
(MOI.RegClass == AVR::PTRDISPREGSRegClassID) ||
- (MOI.RegClass == AVR::ZREGSRegClassID);
+ (MOI.RegClass == AVR::ZREGRegClassID);
if (isPtrReg) {
O << getRegisterName(Op.getReg(), AVR::ptr);
diff --git a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
index 081d8b5..d182983 100644
--- a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
+++ b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp
@@ -230,13 +230,25 @@ void ms8(unsigned Size, const MCFixup &Fixup, uint64_t &Value,
namespace llvm {
// Prepare value for the target space for it
-void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t &Value,
+void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup,
+ const MCValue &Target,
+ uint64_t &Value,
MCContext *Ctx) const {
// The size of the fixup in bits.
uint64_t Size = AVRAsmBackend::getFixupKindInfo(Fixup.getKind()).TargetSize;
unsigned Kind = Fixup.getKind();
+ // Parsed LLVM-generated temporary labels are already
+ // adjusted for instruction size, but normal labels aren't.
+ //
+ // To handle both cases, we simply un-adjust the temporary label
+ // case so it acts like all other labels.
+ if (const MCSymbolRefExpr *A = Target.getSymA()) {
+ if (A->getSymbol().isTemporary())
+ Value += 2;
+ }
+
switch (Kind) {
default:
llvm_unreachable("unhandled fixup");
@@ -333,9 +345,10 @@ MCObjectWriter *AVRAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
MCELFObjectTargetWriter::getOSABI(OSType));
}
-void AVRAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
- unsigned DataSize, uint64_t Value,
- bool IsPCRel) const {
+void AVRAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target, MutableArrayRef<char> Data,
+ uint64_t Value, bool IsPCRel) const {
+ adjustFixupValue(Fixup, Target, Value, &Asm.getContext());
if (Value == 0)
return; // Doesn't change encoding.
@@ -349,7 +362,7 @@ void AVRAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
Value <<= Info.TargetOffset;
unsigned Offset = Fixup.getOffset();
- assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!");
+ assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
// For each byte of the fragment that the fixup touches, mask in the
// bits from the fixup value.
@@ -436,30 +449,16 @@ bool AVRAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
return true;
}
-void AVRAsmBackend::processFixupValue(const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFixup &Fixup,
- const MCFragment *DF,
- const MCValue &Target, uint64_t &Value,
- bool &IsResolved) {
+bool AVRAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
+ const MCFixup &Fixup,
+ const MCValue &Target) {
switch ((unsigned) Fixup.getKind()) {
+ default: return false;
// Fixups which should always be recorded as relocations.
case AVR::fixup_7_pcrel:
case AVR::fixup_13_pcrel:
case AVR::fixup_call:
- IsResolved = false;
- break;
- default:
- // Parsed LLVM-generated temporary labels are already
- // adjusted for instruction size, but normal labels aren't.
- //
- // To handle both cases, we simply un-adjust the temporary label
- // case so it acts like all other labels.
- if (Target.getSymA()->getSymbol().isTemporary())
- Value += 2;
-
- adjustFixupValue(Fixup, Value, &Asm.getContext());
- break;
+ return true;
}
}
diff --git a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h
index 7ff4b8f..4a75e3b 100644
--- a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h
+++ b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h
@@ -35,12 +35,13 @@ public:
AVRAsmBackend(Triple::OSType OSType)
: MCAsmBackend(), OSType(OSType) {}
- void adjustFixupValue(const MCFixup &Fixup, uint64_t &Value,
- MCContext *Ctx = nullptr) const;
+ void adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
+ uint64_t &Value, MCContext *Ctx = nullptr) const;
MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
- void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
+ void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target, MutableArrayRef<char> Data,
uint64_t Value, bool IsPCRel) const override;
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
@@ -63,10 +64,8 @@ public:
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
- void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout,
- const MCFixup &Fixup, const MCFragment *DF,
- const MCValue &Target, uint64_t &Value,
- bool &IsResolved) override;
+ bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
+ const MCValue &Target) override;
private:
Triple::OSType OSType;
diff --git a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRELFStreamer.cpp b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRELFStreamer.cpp
index 481de32..6d126ed 100644
--- a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRELFStreamer.cpp
+++ b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRELFStreamer.cpp
@@ -1,6 +1,8 @@
#include "AVRELFStreamer.h"
-#include "llvm/Support/ELF.h"
+#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Support/FormattedStream.h"
#include "AVRMCTargetDesc.h"
@@ -31,7 +33,7 @@ static unsigned getEFlagsForFeatureSet(const FeatureBitset &Features) {
EFlags |= ELF::EF_AVR_ARCH_AVR51;
else if (Features[AVR::ELFArchAVR6])
EFlags |= ELF::EF_AVR_ARCH_AVR6;
- else if (Features[AVR::ELFArchAVRTiny])
+ else if (Features[AVR::ELFArchTiny])
EFlags |= ELF::EF_AVR_ARCH_AVRTINY;
else if (Features[AVR::ELFArchXMEGA1])
EFlags |= ELF::EF_AVR_ARCH_XMEGA1;
diff --git a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp
index cca3bcc..535bb01 100644
--- a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp
+++ b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCAsmInfo.cpp
@@ -18,11 +18,12 @@
namespace llvm {
AVRMCAsmInfo::AVRMCAsmInfo(const Triple &TT) {
- PointerSize = 2;
+ CodePointerSize = 2;
CalleeSaveStackSlotSize = 2;
CommentString = ";";
PrivateGlobalPrefix = ".L";
UsesELFSectionDirectiveForBSS = true;
+ UseIntegratedAssembler = true;
}
} // end of namespace llvm
diff --git a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp
index e6dc886..4dbbce8 100644
--- a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp
+++ b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.cpp
@@ -25,6 +25,7 @@
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#define DEBUG_TYPE "mccodeemitter"
@@ -176,7 +177,7 @@ unsigned AVRMCCodeEmitter::encodeComplement(const MCInst &MI, unsigned OpNo,
return (~0) - Imm;
}
-template <AVR::Fixups Fixup>
+template <AVR::Fixups Fixup, unsigned Offset>
unsigned AVRMCCodeEmitter::encodeImm(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
@@ -192,7 +193,7 @@ unsigned AVRMCCodeEmitter::encodeImm(const MCInst &MI, unsigned OpNo,
}
MCFixupKind FixupKind = static_cast<MCFixupKind>(Fixup);
- Fixups.push_back(MCFixup::create(0, MO.getExpr(), FixupKind, MI.getLoc()));
+ Fixups.push_back(MCFixup::create(Offset, MO.getExpr(), FixupKind, MI.getLoc()));
return 0;
}
diff --git a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.h b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.h
index 5fa425c..883abf8 100644
--- a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.h
+++ b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCCodeEmitter.h
@@ -63,13 +63,14 @@ private:
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
- /// Takes the compliment of a number (~0 - val).
+ /// Takes the complement of a number (~0 - val).
unsigned encodeComplement(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
/// Encodes an immediate value with a given fixup.
- template <AVR::Fixups Fixup>
+ /// \tparam Offset The offset into the instruction for the fixup.
+ template <AVR::Fixups Fixup, unsigned Offset>
unsigned encodeImm(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
diff --git a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp
index 400296b..085afd2 100644
--- a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp
+++ b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp
@@ -9,11 +9,11 @@
#include "AVRMCExpr.h"
+#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCValue.h"
-#include "llvm/MC/MCAsmLayout.h"
namespace llvm {
diff --git a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.cpp b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.cpp
index a4fa5c0..826430e 100644
--- a/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.cpp
+++ b/contrib/llvm/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.cpp
@@ -11,9 +11,9 @@
//
//===----------------------------------------------------------------------===//
+#include "AVRMCTargetDesc.h"
#include "AVRELFStreamer.h"
#include "AVRMCAsmInfo.h"
-#include "AVRMCTargetDesc.h"
#include "AVRTargetStreamer.h"
#include "InstPrinter/AVRInstPrinter.h"
OpenPOWER on IntegriCloud