diff options
author | Dylan McKay <dylanmckay34@gmail.com> | 2017-01-05 05:20:27 +0000 |
---|---|---|
committer | Dylan McKay <dylanmckay34@gmail.com> | 2017-01-05 05:20:27 +0000 |
commit | 924fa3abdc1d28f7ecbc69cc70002ad0effe0a4c (patch) | |
tree | d9ad2a8e7849c330d3603b5f72ba0caa655957d8 /clang/lib | |
parent | c1d5d110a1f5d910ee997ce1f08f635c8e7baba2 (diff) | |
download | bcm5719-llvm-924fa3abdc1d28f7ecbc69cc70002ad0effe0a4c.tar.gz bcm5719-llvm-924fa3abdc1d28f7ecbc69cc70002ad0effe0a4c.zip |
Add AVR target and toolchain to Clang
Summary:
Authored by Senthil Kumar Selvaraj
This patch adds barebones support in Clang for the (experimental) AVR target. It uses the integrated assembler for assembly, and the GNU linker for linking, as lld doesn't know about the target yet.
The DataLayout string is the same as the one in AVRTargetMachine.cpp. The alignment specs look wrong to me, as it's an 8 bit target and all types only need 8 bit alignment. Clang failed with a datalayout mismatch error when I tried to change it, so I left it that way for now.
Reviewers: rsmith, dylanmckay, cfe-commits, rengolin
Subscribers: rengolin, jroelofs, wdng
Differential Revision: https://reviews.llvm.org/D27123
llvm-svn: 291082
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/Targets.cpp | 93 | ||||
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains.h | 10 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.h | 13 |
6 files changed, 144 insertions, 0 deletions
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 85a83bca002..00772eb95f7 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -8385,6 +8385,97 @@ public: } }; + +// AVR Target +class AVRTargetInfo : public TargetInfo { +public: + AVRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { + TLSSupported = false; + PointerWidth = 16; + PointerAlign = 8; + IntWidth = 16; + IntAlign = 8; + LongWidth = 32; + LongAlign = 8; + LongLongWidth = 64; + LongLongAlign = 8; + SuitableAlign = 8; + DefaultAlignForAttributeAligned = 8; + HalfWidth = 16; + HalfAlign = 8; + FloatWidth = 32; + FloatAlign = 8; + DoubleWidth = 32; + DoubleAlign = 8; + DoubleFormat = &llvm::APFloat::IEEEsingle(); + LongDoubleWidth = 32; + LongDoubleAlign = 8; + LongDoubleFormat = &llvm::APFloat::IEEEsingle(); + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + IntPtrType = SignedInt; + Char16Type = UnsignedInt; + WCharType = SignedInt; + WIntType = SignedInt; + Char32Type = UnsignedLong; + SigAtomicType = SignedChar; + resetDataLayout("e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + "-f32:32:32-f64:64:64-n8"); + } + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override { + Builder.defineMacro("__AVR__"); + } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return None; + } + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } + const char *getClobbers() const override { + return ""; + } + ArrayRef<const char *> getGCCRegNames() const override { + static const char * const GCCRegNames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "X", "Y", "Z", "SP" + }; + return llvm::makeArrayRef(GCCRegNames); + } + ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { + return None; + } + ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override { + static const TargetInfo::AddlRegName AddlRegNames[] = { + { { "r26", "r27"}, 26 }, + { { "r28", "r29"}, 27 }, + { { "r30", "r31"}, 28 }, + { { "SPL", "SPH"}, 29 }, + }; + return llvm::makeArrayRef(AddlRegNames); + } + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const override { + return false; + } + IntType getIntTypeByWidth(unsigned BitWidth, + bool IsSigned) const final { + // AVR prefers int for 16-bit integers. + return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt) + : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned); + } + IntType getLeastIntTypeByWidth(unsigned BitWidth, + bool IsSigned) const final { + // AVR uses int for int_least16_t and int_fast16_t. + return BitWidth == 16 + ? (IsSigned ? SignedInt : UnsignedInt) + : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); + } +}; + } // end anonymous namespace //===----------------------------------------------------------------------===// @@ -8507,6 +8598,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new ARMbeTargetInfo(Triple, Opts); } + case llvm::Triple::avr: + return new AVRTargetInfo(Triple, Opts); case llvm::Triple::bpfeb: case llvm::Triple::bpfel: return new BPFTargetInfo(Triple, Opts); diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 7bd43ac9da2..15f830d029e 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3764,6 +3764,9 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, case llvm::Triple::wasm64: TC = new toolchains::WebAssembly(*this, Target, Args); break; + case llvm::Triple::avr: + TC = new toolchains::AVRToolChain(*this, Target, Args); + break; default: if (Target.getVendor() == llvm::Triple::Myriad) TC = new toolchains::MyriadToolChain(*this, Target, Args); diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index 968b0cb4724..f15baa840d4 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -5318,3 +5318,12 @@ SanitizerMask Contiki::getSupportedSanitizers() const { Res |= SanitizerKind::SafeStack; return Res; } + +/// AVR Toolchain +AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { } +Tool *AVRToolChain::buildLinker() const { + return new tools::AVR::Linker(*this); +} +// End AVR diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h index 7dab08915d4..e6872224637 100644 --- a/clang/lib/Driver/ToolChains.h +++ b/clang/lib/Driver/ToolChains.h @@ -1349,6 +1349,16 @@ public: SanitizerMask getSupportedSanitizers() const override; }; +class LLVM_LIBRARY_VISIBILITY AVRToolChain : public Generic_ELF { +protected: + Tool *buildLinker() const override; +public: + AVRToolChain(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + bool IsIntegratedAssemblerDefault() const override { return true; } +}; + + } // end namespace toolchains } // end namespace driver } // end namespace clang diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index ea5ad7d051b..62ac95a8697 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -12191,3 +12191,19 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA, const char *Exec = Args.MakeArgString(TC.GetProgramPath("fatbinary")); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); } + +void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + + std::string Linker = getToolChain().GetProgramPath(getShortName()); + ArgStringList CmdArgs; + AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker), + CmdArgs, Inputs)); +} +// AVR tools end. diff --git a/clang/lib/Driver/Tools.h b/clang/lib/Driver/Tools.h index 98dcf841169..9d5b892d424 100644 --- a/clang/lib/Driver/Tools.h +++ b/clang/lib/Driver/Tools.h @@ -990,6 +990,19 @@ class LLVM_LIBRARY_VISIBILITY Linker : public Tool { } // end namespace NVPTX +namespace AVR { +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +public: + Linker(const ToolChain &TC) : GnuTool("AVR::Linker", "avr-ld", TC) {} + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() const override { return true; } + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; +} // end namespace AVR + } // end namespace tools } // end namespace driver } // end namespace clang |