Index: include/llvm/ADT/Triple.h =================================================================== --- include/llvm/ADT/Triple.h +++ include/llvm/ADT/Triple.h @@ -50,6 +50,7 @@ armeb, // ARM (big endian): armeb aarch64, // AArch64 (little endian): aarch64 aarch64_be, // AArch64 (big endian): aarch64_be + avr, // AVR: Atmel AVR microcontroller bpfel, // eBPF or extended BPF or 64-bit BPF (little endian) bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian) hexagon, // Hexagon: hexagon @@ -114,6 +115,7 @@ UnknownVendor, Apple, + Atmel, PC, SCEI, BGP, Index: include/llvm/IR/CallingConv.h =================================================================== --- include/llvm/IR/CallingConv.h +++ include/llvm/IR/CallingConv.h @@ -156,7 +156,19 @@ HHVM = 81, /// \brief HHVM calling convention for invoking C/C++ helpers. - HHVM_C = 82 + HHVM_C = 82, + + /// Used for AVR interrupt routines. + AVR_INTR = 83, + + /// AVR_SIGNAL - Used for AVR signal routines. + AVR_SIGNAL = 84, + + /// Calling convention used for special multiplication RTLIB routines. + AVR_RT_MUL = 85, + + /// Calling convention used for special division RTLIB routines. + AVR_RT_DIV = 86 }; } // End CallingConv namespace Index: include/llvm/Object/ELFObjectFile.h =================================================================== --- include/llvm/Object/ELFObjectFile.h +++ include/llvm/Object/ELFObjectFile.h @@ -829,6 +829,8 @@ return "ELF32-x86-64"; case ELF::EM_ARM: return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big"); + case ELF::EM_AVR: + return "ELF32-avr"; case ELF::EM_HEXAGON: return "ELF32-hexagon"; case ELF::EM_MIPS: @@ -878,6 +880,8 @@ return Triple::aarch64; case ELF::EM_ARM: return Triple::arm; + case ELF::EM_AVR: + return Triple::avr; case ELF::EM_HEXAGON: return Triple::hexagon; case ELF::EM_MIPS: Index: include/llvm/Support/ELF.h =================================================================== --- include/llvm/Support/ELF.h +++ include/llvm/Support/ELF.h @@ -429,6 +429,33 @@ #include "ELFRelocs/ARM.def" }; +// AVR specific e_flags +enum : unsigned { + EF_AVR_ARCH_AVR1 = 1, + EF_AVR_ARCH_AVR2 = 2, + EF_AVR_ARCH_AVR25 = 25, + EF_AVR_ARCH_AVR3 = 3, + EF_AVR_ARCH_AVR31 = 31, + EF_AVR_ARCH_AVR35 = 35, + EF_AVR_ARCH_AVR4 = 4, + EF_AVR_ARCH_AVR5 = 5, + EF_AVR_ARCH_AVR51 = 51, + EF_AVR_ARCH_AVR6 = 6, + EF_AVR_ARCH_AVRTINY = 100, + EF_AVR_ARCH_XMEGA1 = 101, + EF_AVR_ARCH_XMEGA2 = 102, + EF_AVR_ARCH_XMEGA3 = 103, + EF_AVR_ARCH_XMEGA4 = 104, + EF_AVR_ARCH_XMEGA5 = 105, + EF_AVR_ARCH_XMEGA6 = 106, + EF_AVR_ARCH_XMEGA7 = 107 +}; + +// ELF Relocation types for AVR +enum { +#include "ELFRelocs/AVR.def" +}; + // Mips Specific e_flags enum : unsigned { EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions Index: include/llvm/Support/ELFRelocs/AVR.def =================================================================== --- /dev/null +++ include/llvm/Support/ELFRelocs/AVR.def @@ -0,0 +1,40 @@ + +#ifndef ELF_RELOC +#error "ELF_RELOC must be defined" +#endif + +ELF_RELOC(R_AVR_NONE, 0) +ELF_RELOC(R_AVR_32, 1) +ELF_RELOC(R_AVR_7_PCREL, 2) +ELF_RELOC(R_AVR_13_PCREL, 3) +ELF_RELOC(R_AVR_16, 4) +ELF_RELOC(R_AVR_16_PM, 5) +ELF_RELOC(R_AVR_LO8_LDI, 6) +ELF_RELOC(R_AVR_HI8_LDI, 7) +ELF_RELOC(R_AVR_HH8_LDI, 8) +ELF_RELOC(R_AVR_LO8_LDI_NEG, 9) +ELF_RELOC(R_AVR_HI8_LDI_NEG, 10) +ELF_RELOC(R_AVR_HH8_LDI_NEG, 11) +ELF_RELOC(R_AVR_LO8_LDI_PM, 12) +ELF_RELOC(R_AVR_HI8_LDI_PM, 13) +ELF_RELOC(R_AVR_HH8_LDI_PM, 14) +ELF_RELOC(R_AVR_LO8_LDI_PM_NEG, 15) +ELF_RELOC(R_AVR_HI8_LDI_PM_NEG, 16) +ELF_RELOC(R_AVR_HH8_LDI_PM_NEG, 17) +ELF_RELOC(R_AVR_CALL, 18) +ELF_RELOC(R_AVR_LDI, 19) +ELF_RELOC(R_AVR_6, 20) +ELF_RELOC(R_AVR_6_ADIW, 21) +ELF_RELOC(R_AVR_MS8_LDI, 22) +ELF_RELOC(R_AVR_MS8_LDI_NEG, 23) +ELF_RELOC(R_AVR_LO8_LDI_GS, 24) +ELF_RELOC(R_AVR_HI8_LDI_GS, 25) +ELF_RELOC(R_AVR_8, 26) +ELF_RELOC(R_AVR_8_LO8, 27) +ELF_RELOC(R_AVR_8_HI8, 28) +ELF_RELOC(R_AVR_8_HLO8, 29) +ELF_RELOC(R_AVR_SYM_DIFF, 30) +ELF_RELOC(R_AVR_16_LDST, 31) +ELF_RELOC(R_AVR_LDS_STS_16, 33) +ELF_RELOC(R_AVR_PORT6, 34) +ELF_RELOC(R_AVR_PORT5, 35) Index: include/llvm/Target/Target.td =================================================================== --- include/llvm/Target/Target.td +++ include/llvm/Target/Target.td @@ -936,6 +936,10 @@ // written register name matcher bit ShouldEmitMatchRegisterName = 1; + // ShouldEmitMatchRegisterAltName - Set to false if the target needs a hand + // written register alternative name matcher + bit ShouldEmitMatchRegisterAltName = 0; + /// Does the instruction mnemonic allow '.' bit MnemonicContainsDot = 0; } Index: lib/Support/Triple.cpp =================================================================== --- lib/Support/Triple.cpp +++ lib/Support/Triple.cpp @@ -25,6 +25,7 @@ case aarch64_be: return "aarch64_be"; case arm: return "arm"; case armeb: return "armeb"; + case avr: return "avr"; case bpfel: return "bpfel"; case bpfeb: return "bpfeb"; case hexagon: return "hexagon"; @@ -80,6 +81,8 @@ case thumb: case thumbeb: return "arm"; + case avr: return "avr"; + case ppc64: case ppc64le: case ppc: return "ppc"; @@ -134,6 +137,7 @@ case UnknownVendor: return "unknown"; case Apple: return "apple"; + case Atmel: return "atmel"; case PC: return "pc"; case SCEI: return "scei"; case BGP: return "bgp"; @@ -227,6 +231,7 @@ .Case("arm64", aarch64) // "arm64" is an alias for "aarch64" .Case("arm", arm) .Case("armeb", armeb) + .Case("avr", avr) .StartsWith("bpf", BPFArch) .Case("mips", mips) .Case("mipsel", mipsel) @@ -343,6 +348,7 @@ .Case("armeb", Triple::armeb) .Case("thumb", Triple::thumb) .Case("thumbeb", Triple::thumbeb) + .Case("avr", Triple::avr) .Case("msp430", Triple::msp430) .Cases("mips", "mipseb", "mipsallegrex", Triple::mips) .Cases("mipsel", "mipsallegrexel", Triple::mipsel) @@ -389,6 +395,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) { return StringSwitch(VendorName) .Case("apple", Triple::Apple) + .Case("atmel", Triple::Atmel) .Case("pc", Triple::PC) .Case("scei", Triple::SCEI) .Case("bgp", Triple::BGP) @@ -1029,6 +1036,7 @@ case llvm::Triple::UnknownArch: return 0; + case llvm::Triple::avr: case llvm::Triple::msp430: return 16; @@ -1098,6 +1106,7 @@ case Triple::aarch64: case Triple::aarch64_be: case Triple::amdgcn: + case Triple::avr: case Triple::bpfel: case Triple::bpfeb: case Triple::msp430: @@ -1152,6 +1161,7 @@ case Triple::UnknownArch: case Triple::arm: case Triple::armeb: + case Triple::avr: case Triple::hexagon: case Triple::kalimba: case Triple::msp430: @@ -1208,6 +1218,7 @@ case Triple::amdgcn: case Triple::amdil64: case Triple::amdil: + case Triple::avr: case Triple::hexagon: case Triple::hsail64: case Triple::hsail: @@ -1280,6 +1291,7 @@ case Triple::amdil64: case Triple::amdil: case Triple::arm: + case Triple::avr: case Triple::bpfel: case Triple::hexagon: case Triple::hsail64: Index: utils/TableGen/AsmMatcherEmitter.cpp =================================================================== --- utils/TableGen/AsmMatcherEmitter.cpp +++ utils/TableGen/AsmMatcherEmitter.cpp @@ -2201,6 +2201,37 @@ OS << "}\n\n"; } +/// Emit the function to match a string to the target +/// specific register enum. +static void emitMatchRegisterAltName(CodeGenTarget &Target, Record *AsmParser, + raw_ostream &OS) { + // Construct the match list. + std::vector Matches; + const auto &Regs = Target.getRegBank().getRegisters(); + for (const CodeGenRegister &Reg : Regs) { + + auto AltNames = Reg.TheDef->getValueAsListOfStrings("AltNames"); + + for(auto AltName : AltNames) { + AltName = StringRef(AltName).trim(); + + // don't handle empty alternative names + if(AltName.empty()) + continue; + + Matches.emplace_back(AltName, + "return " + utostr(Reg.EnumValue) + ";"); + } + } + + OS << "static unsigned MatchRegisterAltName(StringRef Name) {\n"; + + StringMatcher("Name", Matches, OS).Emit(); + + OS << " return 0;\n"; + OS << "}\n\n"; +} + static const char *getMinimalTypeForRange(uint64_t Range) { assert(Range <= 0xFFFFFFFFFFFFFFFFULL && "Enum too large"); if (Range > 0xFFFFFFFFULL) @@ -2730,6 +2761,10 @@ if (AsmParser->getValueAsBit("ShouldEmitMatchRegisterName")) emitMatchRegisterName(Target, AsmParser, OS); + if (AsmParser->getValueAsBit("ShouldEmitMatchRegisterAltName")) { + emitMatchRegisterAltName(Target, AsmParser, OS); + } + OS << "#endif // GET_REGISTER_MATCHER\n\n"; OS << "\n#ifdef GET_SUBTARGET_FEATURE_NAME\n";