diff --git a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp --- a/llvm/lib/Target/AVR/AVRAsmPrinter.cpp +++ b/llvm/lib/Target/AVR/AVRAsmPrinter.cpp @@ -14,6 +14,7 @@ #include "AVR.h" #include "AVRMCInstLower.h" #include "AVRSubtarget.h" +#include "AVRTargetMachine.h" #include "MCTargetDesc/AVRInstPrinter.h" #include "MCTargetDesc/AVRMCExpr.h" #include "TargetInfo/AVRTargetInfo.h" @@ -21,6 +22,7 @@ #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/Mangler.h" @@ -60,6 +62,8 @@ bool doFinalization(Module &M) override; + void emitStartOfAsmFile(Module &M) override; + private: const MCRegisterInfo &MRI; bool EmittedStructorSymbolAttrs = false; @@ -236,6 +240,45 @@ return AsmPrinter::doFinalization(M); } +void AVRAsmPrinter::emitStartOfAsmFile(Module &M) { + const AVRTargetMachine &TM = (const AVRTargetMachine &)MMI->getTarget(); + const AVRSubtarget *SubTM = (const AVRSubtarget *)TM.getSubtargetImpl(); + if (!SubTM) + return; + + // Emit __tmp_reg__. + OutStreamer->emitAssignment( + MMI->getContext().getOrCreateSymbol(StringRef("__tmp_reg__")), + MCConstantExpr::create(SubTM->getRegTmpIndex(), MMI->getContext())); + // Emit __zero_reg__. + OutStreamer->emitAssignment( + MMI->getContext().getOrCreateSymbol(StringRef("__zero_reg__")), + MCConstantExpr::create(SubTM->getRegZeroIndex(), MMI->getContext())); + // Emit __SREG__. + OutStreamer->emitAssignment( + MMI->getContext().getOrCreateSymbol(StringRef("__SREG__")), + MCConstantExpr::create(SubTM->getIORegSREG(), MMI->getContext())); + // Emit __SP_H__ if available. + if (!SubTM->hasSmallStack()) + OutStreamer->emitAssignment( + MMI->getContext().getOrCreateSymbol(StringRef("__SP_H__")), + MCConstantExpr::create(SubTM->getIORegSPH(), MMI->getContext())); + // Emit __SP_L__. + OutStreamer->emitAssignment( + MMI->getContext().getOrCreateSymbol(StringRef("__SP_L__")), + MCConstantExpr::create(SubTM->getIORegSPL(), MMI->getContext())); + // Emit __EIND__ if available. + if (SubTM->hasEIJMPCALL()) + OutStreamer->emitAssignment( + MMI->getContext().getOrCreateSymbol(StringRef("__EIND__")), + MCConstantExpr::create(SubTM->getIORegEIND(), MMI->getContext())); + // Emit __RAMPZ__ if available. + if (SubTM->hasELPM()) + OutStreamer->emitAssignment( + MMI->getContext().getOrCreateSymbol(StringRef("__RAMPZ__")), + MCConstantExpr::create(SubTM->getIORegRAMPZ(), MMI->getContext())); +} + } // end of namespace llvm extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRAsmPrinter() { diff --git a/llvm/lib/Target/AVR/AVRDevices.td b/llvm/lib/Target/AVR/AVRDevices.td --- a/llvm/lib/Target/AVR/AVRDevices.td +++ b/llvm/lib/Target/AVR/AVRDevices.td @@ -174,15 +174,13 @@ : Family<"avr35", [FamilyAVR3, FeatureMOVW, FeatureLPMX, FeatureSPM, FeatureBREAK]>; -def FamilyAVR4 : Family<"avr4", [ - FamilyAVR2, FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, - FeatureBREAK -]>; +def FamilyAVR4 : Family<"avr4", + [FamilyAVR2, FeatureMultiplication, FeatureMOVW, + FeatureLPMX, FeatureSPM, FeatureBREAK]>; -def FamilyAVR5 : Family<"avr5", [ - FamilyAVR3, FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, - FeatureBREAK -]>; +def FamilyAVR5 : Family<"avr5", + [FamilyAVR3, FeatureMultiplication, FeatureMOVW, + FeatureLPMX, FeatureSPM, FeatureBREAK]>; def FamilyAVR51 : Family<"avr51", [FamilyAVR5, FeatureELPM, FeatureELPMX]>; @@ -190,14 +188,15 @@ def FamilyTiny : Family<"avrtiny", - [FamilyAVR0, FeatureBREAK, FeatureSRAM, FeatureTinyEncoding]>; + [FamilyAVR0, FeatureBREAK, FeatureSRAM, FeatureTinyEncoding, + FeatureSmallStack]>; -def FamilyXMEGA : Family<"xmega", [ - FamilyAVR0, FeatureLPM, FeatureIJMPCALL, FeatureADDSUBIW, FeatureSRAM, - FeatureJMPCALL, FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM, - FeatureBREAK, FeatureEIJMPCALL, FeatureSPMX, FeatureDES, FeatureELPM, - FeatureELPMX -]>; +def FamilyXMEGA : Family<"xmega", + [FamilyAVR0, FeatureLPM, FeatureIJMPCALL, + FeatureADDSUBIW, FeatureSRAM, FeatureJMPCALL, + FeatureMultiplication, FeatureMOVW, FeatureLPMX, + FeatureSPM, FeatureBREAK, FeatureEIJMPCALL, + FeatureSPMX, FeatureDES, FeatureELPM, FeatureELPMX]>; def FamilyXMEGAU : Family<"xmegau", [FamilyXMEGA, FeatureRMW]>; @@ -246,41 +245,42 @@ // Specific MCUs // NOTE: This list has been synchronized with gcc-avr 5.4.0 and avr-libc 2.0.0. -def : Device<"at90s1200", FamilyAVR0, ELFArchAVR1>; -def : Device<"attiny11", FamilyAVR1, ELFArchAVR1>; -def : Device<"attiny12", FamilyAVR1, ELFArchAVR1>; -def : Device<"attiny15", FamilyAVR1, ELFArchAVR1>; -def : Device<"attiny28", FamilyAVR1, ELFArchAVR1>; -def : Device<"at90s2313", FamilyAVR2, ELFArchAVR2>; -def : Device<"at90s2323", FamilyAVR2, ELFArchAVR2>; -def : Device<"at90s2333", FamilyAVR2, ELFArchAVR2>; -def : Device<"at90s2343", FamilyAVR2, ELFArchAVR2>; -def : Device<"attiny22", FamilyAVR2, ELFArchAVR2>; -def : Device<"attiny26", FamilyAVR2, ELFArchAVR2, [FeatureLPMX]>; +def : Device<"at90s1200", FamilyAVR0, ELFArchAVR1, [FeatureSmallStack]>; +def : Device<"attiny11", FamilyAVR1, ELFArchAVR1, [FeatureSmallStack]>; +def : Device<"attiny12", FamilyAVR1, ELFArchAVR1, [FeatureSmallStack]>; +def : Device<"attiny15", FamilyAVR1, ELFArchAVR1, [FeatureSmallStack]>; +def : Device<"attiny28", FamilyAVR1, ELFArchAVR1, [FeatureSmallStack]>; +def : Device<"at90s2313", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>; +def : Device<"at90s2323", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>; +def : Device<"at90s2333", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>; +def : Device<"at90s2343", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>; +def : Device<"attiny22", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>; +def : Device<"attiny26", FamilyAVR2, ELFArchAVR2, + [FeatureLPMX, FeatureSmallStack]>; def : Device<"at86rf401", FamilyAVR2, ELFArchAVR25, [FeatureMOVW, FeatureLPMX]>; -def : Device<"at90s4414", FamilyAVR2, ELFArchAVR2>; -def : Device<"at90s4433", FamilyAVR2, ELFArchAVR2>; -def : Device<"at90s4434", FamilyAVR2, ELFArchAVR2>; +def : Device<"at90s4414", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>; +def : Device<"at90s4433", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>; +def : Device<"at90s4434", FamilyAVR2, ELFArchAVR2, [FeatureSmallStack]>; def : Device<"at90s8515", FamilyAVR2, ELFArchAVR2>; def : Device<"at90c8534", FamilyAVR2, ELFArchAVR2>; def : Device<"at90s8535", FamilyAVR2, ELFArchAVR2>; def : Device<"ata5272", FamilyAVR25, ELFArchAVR25>; -def : Device<"attiny13", FamilyAVR25, ELFArchAVR25>; -def : Device<"attiny13a", FamilyAVR25, ELFArchAVR25>; -def : Device<"attiny2313", FamilyAVR25, ELFArchAVR25>; -def : Device<"attiny2313a", FamilyAVR25, ELFArchAVR25>; -def : Device<"attiny24", FamilyAVR25, ELFArchAVR25>; -def : Device<"attiny24a", FamilyAVR25, ELFArchAVR25>; +def : Device<"attiny13", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>; +def : Device<"attiny13a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>; +def : Device<"attiny2313", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>; +def : Device<"attiny2313a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>; +def : Device<"attiny24", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>; +def : Device<"attiny24a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>; def : Device<"attiny4313", FamilyAVR25, ELFArchAVR25>; def : Device<"attiny44", FamilyAVR25, ELFArchAVR25>; def : Device<"attiny44a", FamilyAVR25, ELFArchAVR25>; def : Device<"attiny84", FamilyAVR25, ELFArchAVR25>; def : Device<"attiny84a", FamilyAVR25, ELFArchAVR25>; -def : Device<"attiny25", FamilyAVR25, ELFArchAVR25>; +def : Device<"attiny25", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>; def : Device<"attiny45", FamilyAVR25, ELFArchAVR25>; def : Device<"attiny85", FamilyAVR25, ELFArchAVR25>; -def : Device<"attiny261", FamilyAVR25, ELFArchAVR25>; -def : Device<"attiny261a", FamilyAVR25, ELFArchAVR25>; +def : Device<"attiny261", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>; +def : Device<"attiny261a", FamilyAVR25, ELFArchAVR25, [FeatureSmallStack]>; def : Device<"attiny441", FamilyAVR25, ELFArchAVR25>; def : Device<"attiny461", FamilyAVR25, ELFArchAVR25>; def : Device<"attiny461a", FamilyAVR25, ELFArchAVR25>; diff --git a/llvm/lib/Target/AVR/AVRSubtarget.h b/llvm/lib/Target/AVR/AVRSubtarget.h --- a/llvm/lib/Target/AVR/AVRSubtarget.h +++ b/llvm/lib/Target/AVR/AVRSubtarget.h @@ -91,10 +91,17 @@ return ELFArch; } - /// Get I/O register address. - int getIORegRAMPZ(void) const { return 0x3b; } + /// Get I/O register addresses. + int getIORegRAMPZ(void) const { return hasELPM() ? 0x3b : -1; } + int getIORegEIND(void) const { return hasEIJMPCALL() ? 0x3c : -1; } + int getIORegSPL(void) const { return 0x3d; } + int getIORegSPH(void) const { return hasSmallStack() ? -1 : 0x3e; } int getIORegSREG(void) const { return 0x3f; } + /// Get GPR aliases. + int getRegTmpIndex(void) const { return hasTinyEncoding() ? 16 : 0; } + int getRegZeroIndex(void) const { return hasTinyEncoding() ? 17 : 1; } + private: /// The ELF e_flags architecture. unsigned ELFArch; diff --git a/llvm/test/CodeGen/AVR/global-aliases.ll b/llvm/test/CodeGen/AVR/global-aliases.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AVR/global-aliases.ll @@ -0,0 +1,18 @@ +; RUN: llc < %s -mtriple=avr -mcpu=atxmega384c3 | FileCheck %s --check-prefixes=MEGA +; RUN: llc < %s -mtriple=avr -mcpu=attiny40 | FileCheck %s --check-prefixes=TINY + +; MEGA: .set __tmp_reg__, 0 +; MEGA: .set __zero_reg__, 1 +; MEGA: .set __SREG__, 63 +; MEGA: .set __SP_H__, 62 +; MEGA: .set __SP_L__, 61 +; MEGA: .set __EIND__, 60 +; MEGA: .set __RAMPZ__, 59 + +; TINY: .set __tmp_reg__, 16 +; TINY: .set __zero_reg__, 17 +; TINY: .set __SREG__, 63 +; TINY-NOT: .set __SP_H__, 62 +; TINY: .set __SP_L__, 61 +; TINY-NOT: .set __EIND__, 60 +; TINY-NOT: .set __RAMPZ__, 59