xref: /openbsd-src/gnu/llvm/clang/lib/Driver/ToolChains/AVR.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===--- AVR.cpp - AVR ToolChain Implementations ----------------*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick 
9e5dd7070Spatrick #include "AVR.h"
10e5dd7070Spatrick #include "CommonArgs.h"
11e5dd7070Spatrick #include "clang/Driver/Compilation.h"
12e5dd7070Spatrick #include "clang/Driver/DriverDiagnostic.h"
13a9ac8606Spatrick #include "clang/Driver/InputInfo.h"
14e5dd7070Spatrick #include "clang/Driver/Options.h"
15a9ac8606Spatrick #include "llvm/ADT/StringExtras.h"
16e5dd7070Spatrick #include "llvm/MC/MCSubtargetInfo.h"
17e5dd7070Spatrick #include "llvm/MC/SubtargetFeature.h"
18e5dd7070Spatrick #include "llvm/Option/ArgList.h"
19e5dd7070Spatrick #include "llvm/Support/FileSystem.h"
20*12c85518Srobert #include "llvm/Support/Path.h"
21e5dd7070Spatrick 
22e5dd7070Spatrick using namespace clang::driver;
23e5dd7070Spatrick using namespace clang::driver::toolchains;
24e5dd7070Spatrick using namespace clang::driver::tools;
25e5dd7070Spatrick using namespace clang;
26e5dd7070Spatrick using namespace llvm::opt;
27e5dd7070Spatrick 
28e5dd7070Spatrick namespace {
29e5dd7070Spatrick 
30*12c85518Srobert // NOTE: This list has been synchronized with gcc-avr 7.3.0 and avr-libc 2.0.0.
31*12c85518Srobert constexpr struct {
32a9ac8606Spatrick   StringRef Name;
33*12c85518Srobert   StringRef SubPath;
34a9ac8606Spatrick   StringRef Family;
35a9ac8606Spatrick   unsigned DataAddr;
36a9ac8606Spatrick } MCUInfo[] = {
37a9ac8606Spatrick     {"at90s1200", "", "avr1", 0},
38a9ac8606Spatrick     {"attiny11", "", "avr1", 0},
39a9ac8606Spatrick     {"attiny12", "", "avr1", 0},
40a9ac8606Spatrick     {"attiny15", "", "avr1", 0},
41a9ac8606Spatrick     {"attiny28", "", "avr1", 0},
42a9ac8606Spatrick     {"at90s2313", "tiny-stack", "avr2", 0x800060},
43a9ac8606Spatrick     {"at90s2323", "tiny-stack", "avr2", 0x800060},
44a9ac8606Spatrick     {"at90s2333", "tiny-stack", "avr2", 0x800060},
45a9ac8606Spatrick     {"at90s2343", "tiny-stack", "avr2", 0x800060},
46a9ac8606Spatrick     {"at90s4433", "tiny-stack", "avr2", 0x800060},
47a9ac8606Spatrick     {"attiny22", "tiny-stack", "avr2", 0x800060},
48a9ac8606Spatrick     {"attiny26", "tiny-stack", "avr2", 0x800060},
49a9ac8606Spatrick     {"at90s4414", "", "avr2", 0x800060},
50a9ac8606Spatrick     {"at90s4434", "", "avr2", 0x800060},
51a9ac8606Spatrick     {"at90s8515", "", "avr2", 0x800060},
52a9ac8606Spatrick     {"at90c8534", "", "avr2", 0x800060},
53a9ac8606Spatrick     {"at90s8535", "", "avr2", 0x800060},
54a9ac8606Spatrick     {"attiny13", "avr25/tiny-stack", "avr25", 0x800060},
55a9ac8606Spatrick     {"attiny13a", "avr25/tiny-stack", "avr25", 0x800060},
56a9ac8606Spatrick     {"attiny2313", "avr25/tiny-stack", "avr25", 0x800060},
57a9ac8606Spatrick     {"attiny2313a", "avr25/tiny-stack", "avr25", 0x800060},
58a9ac8606Spatrick     {"attiny24", "avr25/tiny-stack", "avr25", 0x800060},
59a9ac8606Spatrick     {"attiny24a", "avr25/tiny-stack", "avr25", 0x800060},
60a9ac8606Spatrick     {"attiny25", "avr25/tiny-stack", "avr25", 0x800060},
61a9ac8606Spatrick     {"attiny261", "avr25/tiny-stack", "avr25", 0x800060},
62a9ac8606Spatrick     {"attiny261a", "avr25/tiny-stack", "avr25", 0x800060},
63a9ac8606Spatrick     {"at86rf401", "avr25", "avr25", 0x800060},
64a9ac8606Spatrick     {"ata5272", "avr25", "avr25", 0x800100},
65*12c85518Srobert     {"ata6616c", "avr25", "avr25", 0x800100},
66a9ac8606Spatrick     {"attiny4313", "avr25", "avr25", 0x800060},
67a9ac8606Spatrick     {"attiny44", "avr25", "avr25", 0x800060},
68a9ac8606Spatrick     {"attiny44a", "avr25", "avr25", 0x800060},
69a9ac8606Spatrick     {"attiny84", "avr25", "avr25", 0x800060},
70a9ac8606Spatrick     {"attiny84a", "avr25", "avr25", 0x800060},
71a9ac8606Spatrick     {"attiny45", "avr25", "avr25", 0x800060},
72a9ac8606Spatrick     {"attiny85", "avr25", "avr25", 0x800060},
73a9ac8606Spatrick     {"attiny441", "avr25", "avr25", 0x800100},
74a9ac8606Spatrick     {"attiny461", "avr25", "avr25", 0x800060},
75a9ac8606Spatrick     {"attiny461a", "avr25", "avr25", 0x800060},
76a9ac8606Spatrick     {"attiny841", "avr25", "avr25", 0x800100},
77a9ac8606Spatrick     {"attiny861", "avr25", "avr25", 0x800060},
78a9ac8606Spatrick     {"attiny861a", "avr25", "avr25", 0x800060},
79a9ac8606Spatrick     {"attiny87", "avr25", "avr25", 0x800100},
80a9ac8606Spatrick     {"attiny43u", "avr25", "avr25", 0x800060},
81a9ac8606Spatrick     {"attiny48", "avr25", "avr25", 0x800100},
82a9ac8606Spatrick     {"attiny88", "avr25", "avr25", 0x800100},
83a9ac8606Spatrick     {"attiny828", "avr25", "avr25", 0x800100},
84a9ac8606Spatrick     {"at43usb355", "avr3", "avr3", 0x800100},
85a9ac8606Spatrick     {"at76c711", "avr3", "avr3", 0x800060},
86a9ac8606Spatrick     {"atmega103", "avr31", "avr31", 0x800060},
87a9ac8606Spatrick     {"at43usb320", "avr31", "avr31", 0x800060},
88a9ac8606Spatrick     {"attiny167", "avr35", "avr35", 0x800100},
89a9ac8606Spatrick     {"at90usb82", "avr35", "avr35", 0x800100},
90a9ac8606Spatrick     {"at90usb162", "avr35", "avr35", 0x800100},
91a9ac8606Spatrick     {"ata5505", "avr35", "avr35", 0x800100},
92*12c85518Srobert     {"ata6617c", "avr35", "avr35", 0x800100},
93*12c85518Srobert     {"ata664251", "avr35", "avr35", 0x800100},
94a9ac8606Spatrick     {"atmega8u2", "avr35", "avr35", 0x800100},
95a9ac8606Spatrick     {"atmega16u2", "avr35", "avr35", 0x800100},
96a9ac8606Spatrick     {"atmega32u2", "avr35", "avr35", 0x800100},
97a9ac8606Spatrick     {"attiny1634", "avr35", "avr35", 0x800100},
98a9ac8606Spatrick     {"atmega8", "avr4", "avr4", 0x800060},
99a9ac8606Spatrick     {"ata6289", "avr4", "avr4", 0x800100},
100a9ac8606Spatrick     {"atmega8a", "avr4", "avr4", 0x800060},
101a9ac8606Spatrick     {"ata6285", "avr4", "avr4", 0x800100},
102a9ac8606Spatrick     {"ata6286", "avr4", "avr4", 0x800100},
103*12c85518Srobert     {"ata6612c", "avr4", "avr4", 0x800100},
104a9ac8606Spatrick     {"atmega48", "avr4", "avr4", 0x800100},
105a9ac8606Spatrick     {"atmega48a", "avr4", "avr4", 0x800100},
106a9ac8606Spatrick     {"atmega48pa", "avr4", "avr4", 0x800100},
107a9ac8606Spatrick     {"atmega48pb", "avr4", "avr4", 0x800100},
108a9ac8606Spatrick     {"atmega48p", "avr4", "avr4", 0x800100},
109a9ac8606Spatrick     {"atmega88", "avr4", "avr4", 0x800100},
110a9ac8606Spatrick     {"atmega88a", "avr4", "avr4", 0x800100},
111a9ac8606Spatrick     {"atmega88p", "avr4", "avr4", 0x800100},
112a9ac8606Spatrick     {"atmega88pa", "avr4", "avr4", 0x800100},
113a9ac8606Spatrick     {"atmega88pb", "avr4", "avr4", 0x800100},
114a9ac8606Spatrick     {"atmega8515", "avr4", "avr4", 0x800060},
115a9ac8606Spatrick     {"atmega8535", "avr4", "avr4", 0x800060},
116a9ac8606Spatrick     {"atmega8hva", "avr4", "avr4", 0x800100},
117a9ac8606Spatrick     {"at90pwm1", "avr4", "avr4", 0x800100},
118a9ac8606Spatrick     {"at90pwm2", "avr4", "avr4", 0x800100},
119a9ac8606Spatrick     {"at90pwm2b", "avr4", "avr4", 0x800100},
120a9ac8606Spatrick     {"at90pwm3", "avr4", "avr4", 0x800100},
121a9ac8606Spatrick     {"at90pwm3b", "avr4", "avr4", 0x800100},
122a9ac8606Spatrick     {"at90pwm81", "avr4", "avr4", 0x800100},
123*12c85518Srobert     {"ata5702m322", "avr5", "avr5", 0x800200},
124*12c85518Srobert     {"ata5782", "avr5", "avr5", 0x800200},
125a9ac8606Spatrick     {"ata5790", "avr5", "avr5", 0x800100},
126*12c85518Srobert     {"ata5790n", "avr5", "avr5", 0x800100},
127*12c85518Srobert     {"ata5791", "avr5", "avr5", 0x800100},
128a9ac8606Spatrick     {"ata5795", "avr5", "avr5", 0x800100},
129*12c85518Srobert     {"ata5831", "avr5", "avr5", 0x800200},
130*12c85518Srobert     {"ata6613c", "avr5", "avr5", 0x800100},
131*12c85518Srobert     {"ata6614q", "avr5", "avr5", 0x800100},
132*12c85518Srobert     {"ata8210", "avr5", "avr5", 0x800200},
133*12c85518Srobert     {"ata8510", "avr5", "avr5", 0x800200},
134a9ac8606Spatrick     {"atmega16", "avr5", "avr5", 0x800060},
135a9ac8606Spatrick     {"atmega16a", "avr5", "avr5", 0x800060},
136a9ac8606Spatrick     {"atmega161", "avr5", "avr5", 0x800060},
137a9ac8606Spatrick     {"atmega162", "avr5", "avr5", 0x800100},
138a9ac8606Spatrick     {"atmega163", "avr5", "avr5", 0x800060},
139a9ac8606Spatrick     {"atmega164a", "avr5", "avr5", 0x800100},
140a9ac8606Spatrick     {"atmega164p", "avr5", "avr5", 0x800100},
141a9ac8606Spatrick     {"atmega164pa", "avr5", "avr5", 0x800100},
142a9ac8606Spatrick     {"atmega165", "avr5", "avr5", 0x800100},
143a9ac8606Spatrick     {"atmega165a", "avr5", "avr5", 0x800100},
144a9ac8606Spatrick     {"atmega165p", "avr5", "avr5", 0x800100},
145a9ac8606Spatrick     {"atmega165pa", "avr5", "avr5", 0x800100},
146a9ac8606Spatrick     {"atmega168", "avr5", "avr5", 0x800100},
147a9ac8606Spatrick     {"atmega168a", "avr5", "avr5", 0x800100},
148a9ac8606Spatrick     {"atmega168p", "avr5", "avr5", 0x800100},
149a9ac8606Spatrick     {"atmega168pa", "avr5", "avr5", 0x800100},
150a9ac8606Spatrick     {"atmega168pb", "avr5", "avr5", 0x800100},
151a9ac8606Spatrick     {"atmega169", "avr5", "avr5", 0x800100},
152a9ac8606Spatrick     {"atmega169a", "avr5", "avr5", 0x800100},
153a9ac8606Spatrick     {"atmega169p", "avr5", "avr5", 0x800100},
154a9ac8606Spatrick     {"atmega169pa", "avr5", "avr5", 0x800100},
155a9ac8606Spatrick     {"atmega32", "avr5", "avr5", 0x800060},
156a9ac8606Spatrick     {"atmega32a", "avr5", "avr5", 0x800060},
157a9ac8606Spatrick     {"atmega323", "avr5", "avr5", 0x800060},
158a9ac8606Spatrick     {"atmega324a", "avr5", "avr5", 0x800100},
159a9ac8606Spatrick     {"atmega324p", "avr5", "avr5", 0x800100},
160a9ac8606Spatrick     {"atmega324pa", "avr5", "avr5", 0x800100},
161*12c85518Srobert     {"atmega324pb", "avr5", "avr5", 0x800100},
162a9ac8606Spatrick     {"atmega325", "avr5", "avr5", 0x800100},
163a9ac8606Spatrick     {"atmega325a", "avr5", "avr5", 0x800100},
164a9ac8606Spatrick     {"atmega325p", "avr5", "avr5", 0x800100},
165a9ac8606Spatrick     {"atmega325pa", "avr5", "avr5", 0x800100},
166a9ac8606Spatrick     {"atmega3250", "avr5", "avr5", 0x800100},
167a9ac8606Spatrick     {"atmega3250a", "avr5", "avr5", 0x800100},
168a9ac8606Spatrick     {"atmega3250p", "avr5", "avr5", 0x800100},
169a9ac8606Spatrick     {"atmega3250pa", "avr5", "avr5", 0x800100},
170a9ac8606Spatrick     {"atmega328", "avr5", "avr5", 0x800100},
171a9ac8606Spatrick     {"atmega328p", "avr5", "avr5", 0x800100},
172*12c85518Srobert     {"atmega328pb", "avr5", "avr5", 0x800100},
173a9ac8606Spatrick     {"atmega329", "avr5", "avr5", 0x800100},
174a9ac8606Spatrick     {"atmega329a", "avr5", "avr5", 0x800100},
175a9ac8606Spatrick     {"atmega329p", "avr5", "avr5", 0x800100},
176a9ac8606Spatrick     {"atmega329pa", "avr5", "avr5", 0x800100},
177a9ac8606Spatrick     {"atmega3290", "avr5", "avr5", 0x800100},
178a9ac8606Spatrick     {"atmega3290a", "avr5", "avr5", 0x800100},
179a9ac8606Spatrick     {"atmega3290p", "avr5", "avr5", 0x800100},
180a9ac8606Spatrick     {"atmega3290pa", "avr5", "avr5", 0x800100},
181a9ac8606Spatrick     {"atmega406", "avr5", "avr5", 0x800100},
182a9ac8606Spatrick     {"atmega64", "avr5", "avr5", 0x800100},
183a9ac8606Spatrick     {"atmega64a", "avr5", "avr5", 0x800100},
184a9ac8606Spatrick     {"atmega640", "avr5", "avr5", 0x800200},
185a9ac8606Spatrick     {"atmega644", "avr5", "avr5", 0x800100},
186a9ac8606Spatrick     {"atmega644a", "avr5", "avr5", 0x800100},
187a9ac8606Spatrick     {"atmega644p", "avr5", "avr5", 0x800100},
188a9ac8606Spatrick     {"atmega644pa", "avr5", "avr5", 0x800100},
189a9ac8606Spatrick     {"atmega645", "avr5", "avr5", 0x800100},
190a9ac8606Spatrick     {"atmega645a", "avr5", "avr5", 0x800100},
191a9ac8606Spatrick     {"atmega645p", "avr5", "avr5", 0x800100},
192a9ac8606Spatrick     {"atmega649", "avr5", "avr5", 0x800100},
193a9ac8606Spatrick     {"atmega649a", "avr5", "avr5", 0x800100},
194a9ac8606Spatrick     {"atmega649p", "avr5", "avr5", 0x800100},
195a9ac8606Spatrick     {"atmega6450", "avr5", "avr5", 0x800100},
196a9ac8606Spatrick     {"atmega6450a", "avr5", "avr5", 0x800100},
197a9ac8606Spatrick     {"atmega6450p", "avr5", "avr5", 0x800100},
198a9ac8606Spatrick     {"atmega6490", "avr5", "avr5", 0x800100},
199a9ac8606Spatrick     {"atmega6490a", "avr5", "avr5", 0x800100},
200a9ac8606Spatrick     {"atmega6490p", "avr5", "avr5", 0x800100},
201a9ac8606Spatrick     {"atmega64rfr2", "avr5", "avr5", 0x800200},
202a9ac8606Spatrick     {"atmega644rfr2", "avr5", "avr5", 0x800200},
203a9ac8606Spatrick     {"atmega16hva", "avr5", "avr5", 0x800100},
204a9ac8606Spatrick     {"atmega16hva2", "avr5", "avr5", 0x800100},
205a9ac8606Spatrick     {"atmega16hvb", "avr5", "avr5", 0x800100},
206a9ac8606Spatrick     {"atmega16hvbrevb", "avr5", "avr5", 0x800100},
207a9ac8606Spatrick     {"atmega32hvb", "avr5", "avr5", 0x800100},
208a9ac8606Spatrick     {"atmega32hvbrevb", "avr5", "avr5", 0x800100},
209a9ac8606Spatrick     {"atmega64hve", "avr5", "avr5", 0x800100},
210*12c85518Srobert     {"atmega64hve2", "avr5", "avr5", 0x800100},
211a9ac8606Spatrick     {"at90can32", "avr5", "avr5", 0x800100},
212a9ac8606Spatrick     {"at90can64", "avr5", "avr5", 0x800100},
213a9ac8606Spatrick     {"at90pwm161", "avr5", "avr5", 0x800100},
214a9ac8606Spatrick     {"at90pwm216", "avr5", "avr5", 0x800100},
215a9ac8606Spatrick     {"at90pwm316", "avr5", "avr5", 0x800100},
216a9ac8606Spatrick     {"atmega32c1", "avr5", "avr5", 0x800100},
217a9ac8606Spatrick     {"atmega64c1", "avr5", "avr5", 0x800100},
218a9ac8606Spatrick     {"atmega16m1", "avr5", "avr5", 0x800100},
219a9ac8606Spatrick     {"atmega32m1", "avr5", "avr5", 0x800100},
220a9ac8606Spatrick     {"atmega64m1", "avr5", "avr5", 0x800100},
221a9ac8606Spatrick     {"atmega16u4", "avr5", "avr5", 0x800100},
222a9ac8606Spatrick     {"atmega32u4", "avr5", "avr5", 0x800100},
223a9ac8606Spatrick     {"atmega32u6", "avr5", "avr5", 0x800100},
224a9ac8606Spatrick     {"at90usb646", "avr5", "avr5", 0x800100},
225a9ac8606Spatrick     {"at90usb647", "avr5", "avr5", 0x800100},
226a9ac8606Spatrick     {"at90scr100", "avr5", "avr5", 0x800100},
227a9ac8606Spatrick     {"at94k", "avr5", "avr5", 0x800060},
228a9ac8606Spatrick     {"m3000", "avr5", "avr5", 0x800060},
229a9ac8606Spatrick     {"atmega128", "avr51", "avr51", 0x800100},
230a9ac8606Spatrick     {"atmega128a", "avr51", "avr51", 0x800100},
231a9ac8606Spatrick     {"atmega1280", "avr51", "avr51", 0x800200},
232a9ac8606Spatrick     {"atmega1281", "avr51", "avr51", 0x800200},
233a9ac8606Spatrick     {"atmega1284", "avr51", "avr51", 0x800100},
234a9ac8606Spatrick     {"atmega1284p", "avr51", "avr51", 0x800100},
235a9ac8606Spatrick     {"atmega128rfa1", "avr51", "avr51", 0x800200},
236a9ac8606Spatrick     {"atmega128rfr2", "avr51", "avr51", 0x800200},
237a9ac8606Spatrick     {"atmega1284rfr2", "avr51", "avr51", 0x800200},
238a9ac8606Spatrick     {"at90can128", "avr51", "avr51", 0x800200},
239a9ac8606Spatrick     {"at90usb1286", "avr51", "avr51", 0x800200},
240a9ac8606Spatrick     {"at90usb1287", "avr51", "avr51", 0x800200},
241a9ac8606Spatrick     {"atmega2560", "avr6", "avr6", 0x800200},
242a9ac8606Spatrick     {"atmega2561", "avr6", "avr6", 0x800200},
243a9ac8606Spatrick     {"atmega256rfr2", "avr6", "avr6", 0x800200},
244a9ac8606Spatrick     {"atmega2564rfr2", "avr6", "avr6", 0x800200},
245a9ac8606Spatrick     {"attiny4", "avrtiny", "avrtiny", 0x800040},
246a9ac8606Spatrick     {"attiny5", "avrtiny", "avrtiny", 0x800040},
247a9ac8606Spatrick     {"attiny9", "avrtiny", "avrtiny", 0x800040},
248a9ac8606Spatrick     {"attiny10", "avrtiny", "avrtiny", 0x800040},
249a9ac8606Spatrick     {"attiny20", "avrtiny", "avrtiny", 0x800040},
250a9ac8606Spatrick     {"attiny40", "avrtiny", "avrtiny", 0x800040},
251*12c85518Srobert     {"attiny102", "avrtiny", "avrtiny", 0x800040},
252*12c85518Srobert     {"attiny104", "avrtiny", "avrtiny", 0x800040},
253a9ac8606Spatrick     {"atxmega16a4", "avrxmega2", "avrxmega2", 0x802000},
254a9ac8606Spatrick     {"atxmega16a4u", "avrxmega2", "avrxmega2", 0x802000},
255a9ac8606Spatrick     {"atxmega16c4", "avrxmega2", "avrxmega2", 0x802000},
256a9ac8606Spatrick     {"atxmega16d4", "avrxmega2", "avrxmega2", 0x802000},
257a9ac8606Spatrick     {"atxmega32a4", "avrxmega2", "avrxmega2", 0x802000},
258a9ac8606Spatrick     {"atxmega32a4u", "avrxmega2", "avrxmega2", 0x802000},
259*12c85518Srobert     {"atxmega32c3", "avrxmega2", "avrxmega2", 0x802000},
260a9ac8606Spatrick     {"atxmega32c4", "avrxmega2", "avrxmega2", 0x802000},
261*12c85518Srobert     {"atxmega32d3", "avrxmega2", "avrxmega2", 0x802000},
262a9ac8606Spatrick     {"atxmega32d4", "avrxmega2", "avrxmega2", 0x802000},
263a9ac8606Spatrick     {"atxmega32e5", "avrxmega2", "avrxmega2", 0x802000},
264a9ac8606Spatrick     {"atxmega16e5", "avrxmega2", "avrxmega2", 0x802000},
265a9ac8606Spatrick     {"atxmega8e5", "avrxmega2", "avrxmega2", 0x802000},
266*12c85518Srobert     {"atxmega64a3", "avrxmega4", "avrxmega4", 0x802000},
267a9ac8606Spatrick     {"atxmega64a3u", "avrxmega4", "avrxmega4", 0x802000},
268a9ac8606Spatrick     {"atxmega64a4u", "avrxmega4", "avrxmega4", 0x802000},
269a9ac8606Spatrick     {"atxmega64b1", "avrxmega4", "avrxmega4", 0x802000},
270a9ac8606Spatrick     {"atxmega64b3", "avrxmega4", "avrxmega4", 0x802000},
271a9ac8606Spatrick     {"atxmega64c3", "avrxmega4", "avrxmega4", 0x802000},
272a9ac8606Spatrick     {"atxmega64d3", "avrxmega4", "avrxmega4", 0x802000},
273a9ac8606Spatrick     {"atxmega64d4", "avrxmega4", "avrxmega4", 0x802000},
274a9ac8606Spatrick     {"atxmega64a1", "avrxmega5", "avrxmega5", 0x802000},
275a9ac8606Spatrick     {"atxmega64a1u", "avrxmega5", "avrxmega5", 0x802000},
276a9ac8606Spatrick     {"atxmega128a3", "avrxmega6", "avrxmega6", 0x802000},
277a9ac8606Spatrick     {"atxmega128a3u", "avrxmega6", "avrxmega6", 0x802000},
278a9ac8606Spatrick     {"atxmega128b1", "avrxmega6", "avrxmega6", 0x802000},
279a9ac8606Spatrick     {"atxmega128b3", "avrxmega6", "avrxmega6", 0x802000},
280a9ac8606Spatrick     {"atxmega128c3", "avrxmega6", "avrxmega6", 0x802000},
281a9ac8606Spatrick     {"atxmega128d3", "avrxmega6", "avrxmega6", 0x802000},
282a9ac8606Spatrick     {"atxmega128d4", "avrxmega6", "avrxmega6", 0x802000},
283a9ac8606Spatrick     {"atxmega192a3", "avrxmega6", "avrxmega6", 0x802000},
284a9ac8606Spatrick     {"atxmega192a3u", "avrxmega6", "avrxmega6", 0x802000},
285a9ac8606Spatrick     {"atxmega192c3", "avrxmega6", "avrxmega6", 0x802000},
286a9ac8606Spatrick     {"atxmega192d3", "avrxmega6", "avrxmega6", 0x802000},
287a9ac8606Spatrick     {"atxmega256a3", "avrxmega6", "avrxmega6", 0x802000},
288a9ac8606Spatrick     {"atxmega256a3u", "avrxmega6", "avrxmega6", 0x802000},
289a9ac8606Spatrick     {"atxmega256a3b", "avrxmega6", "avrxmega6", 0x802000},
290a9ac8606Spatrick     {"atxmega256a3bu", "avrxmega6", "avrxmega6", 0x802000},
291a9ac8606Spatrick     {"atxmega256c3", "avrxmega6", "avrxmega6", 0x802000},
292a9ac8606Spatrick     {"atxmega256d3", "avrxmega6", "avrxmega6", 0x802000},
293a9ac8606Spatrick     {"atxmega384c3", "avrxmega6", "avrxmega6", 0x802000},
294a9ac8606Spatrick     {"atxmega384d3", "avrxmega6", "avrxmega6", 0x802000},
295a9ac8606Spatrick     {"atxmega128a1", "avrxmega7", "avrxmega7", 0x802000},
296a9ac8606Spatrick     {"atxmega128a1u", "avrxmega7", "avrxmega7", 0x802000},
297a9ac8606Spatrick     {"atxmega128a4u", "avrxmega7", "avrxmega7", 0x802000},
298*12c85518Srobert     {"attiny202", "avrxmega3/short-calls", "avrxmega3", 0x803F80},
299*12c85518Srobert     {"attiny204", "avrxmega3/short-calls", "avrxmega3", 0x803F80},
300*12c85518Srobert     {"attiny212", "avrxmega3/short-calls", "avrxmega3", 0x803F80},
301*12c85518Srobert     {"attiny214", "avrxmega3/short-calls", "avrxmega3", 0x803F80},
302*12c85518Srobert     {"attiny402", "avrxmega3/short-calls", "avrxmega3", 0x803F00},
303*12c85518Srobert     {"attiny404", "avrxmega3/short-calls", "avrxmega3", 0x803F00},
304*12c85518Srobert     {"attiny406", "avrxmega3/short-calls", "avrxmega3", 0x803F00},
305*12c85518Srobert     {"attiny412", "avrxmega3/short-calls", "avrxmega3", 0x803F00},
306*12c85518Srobert     {"attiny414", "avrxmega3/short-calls", "avrxmega3", 0x803F00},
307*12c85518Srobert     {"attiny416", "avrxmega3/short-calls", "avrxmega3", 0x803F00},
308*12c85518Srobert     {"attiny417", "avrxmega3/short-calls", "avrxmega3", 0x803F00},
309*12c85518Srobert     {"attiny804", "avrxmega3/short-calls", "avrxmega3", 0x803E00},
310*12c85518Srobert     {"attiny806", "avrxmega3/short-calls", "avrxmega3", 0x803E00},
311*12c85518Srobert     {"attiny807", "avrxmega3/short-calls", "avrxmega3", 0x803E00},
312*12c85518Srobert     {"attiny814", "avrxmega3/short-calls", "avrxmega3", 0x803E00},
313*12c85518Srobert     {"attiny816", "avrxmega3/short-calls", "avrxmega3", 0x803E00},
314*12c85518Srobert     {"attiny817", "avrxmega3/short-calls", "avrxmega3", 0x803E00},
315*12c85518Srobert     {"atmega808", "avrxmega3/short-calls", "avrxmega3", 0x803C00},
316*12c85518Srobert     {"atmega809", "avrxmega3/short-calls", "avrxmega3", 0x803C00},
317*12c85518Srobert     {"atmega1608", "avrxmega3", "avrxmega3", 0x803800},
318*12c85518Srobert     {"atmega1609", "avrxmega3", "avrxmega3", 0x803800},
319*12c85518Srobert     {"atmega3208", "avrxmega3", "avrxmega3", 0x803000},
320*12c85518Srobert     {"atmega3209", "avrxmega3", "avrxmega3", 0x803000},
321*12c85518Srobert     {"atmega4808", "avrxmega3", "avrxmega3", 0x802800},
322*12c85518Srobert     {"atmega4809", "avrxmega3", "avrxmega3", 0x802800},
323*12c85518Srobert     {"attiny1604", "avrxmega3", "avrxmega3", 0x803C00},
324*12c85518Srobert     {"attiny1606", "avrxmega3", "avrxmega3", 0x803C00},
325*12c85518Srobert     {"attiny1607", "avrxmega3", "avrxmega3", 0x803C00},
326*12c85518Srobert     {"attiny1614", "avrxmega3", "avrxmega3", 0x803800},
327*12c85518Srobert     {"attiny1616", "avrxmega3", "avrxmega3", 0x803800},
328*12c85518Srobert     {"attiny1617", "avrxmega3", "avrxmega3", 0x803800},
329*12c85518Srobert     {"attiny1624", "avrxmega3", "avrxmega3", 0x803800},
330*12c85518Srobert     {"attiny1626", "avrxmega3", "avrxmega3", 0x803800},
331*12c85518Srobert     {"attiny1627", "avrxmega3", "avrxmega3", 0x803800},
332*12c85518Srobert     {"attiny3216", "avrxmega3", "avrxmega3", 0x803800},
333*12c85518Srobert     {"attiny3217", "avrxmega3", "avrxmega3", 0x803800},
334a9ac8606Spatrick };
335a9ac8606Spatrick 
GetMCUSubPath(StringRef MCUName)336a9ac8606Spatrick std::string GetMCUSubPath(StringRef MCUName) {
337a9ac8606Spatrick   for (const auto &MCU : MCUInfo)
338a9ac8606Spatrick     if (MCU.Name == MCUName)
339a9ac8606Spatrick       return std::string(MCU.SubPath);
340a9ac8606Spatrick   return "";
341a9ac8606Spatrick }
342a9ac8606Spatrick 
GetMCUFamilyName(StringRef MCUName)343*12c85518Srobert std::optional<StringRef> GetMCUFamilyName(StringRef MCUName) {
344a9ac8606Spatrick   for (const auto &MCU : MCUInfo)
345a9ac8606Spatrick     if (MCU.Name == MCUName)
346*12c85518Srobert       return std::optional<StringRef>(MCU.Family);
347*12c85518Srobert   return std::nullopt;
348a9ac8606Spatrick }
349a9ac8606Spatrick 
GetMCUSectionAddressData(StringRef MCUName)350*12c85518Srobert std::optional<unsigned> GetMCUSectionAddressData(StringRef MCUName) {
351a9ac8606Spatrick   for (const auto &MCU : MCUInfo)
352a9ac8606Spatrick     if (MCU.Name == MCUName && MCU.DataAddr > 0)
353*12c85518Srobert       return std::optional<unsigned>(MCU.DataAddr);
354*12c85518Srobert   return std::nullopt;
355e5dd7070Spatrick }
356e5dd7070Spatrick 
357e5dd7070Spatrick const StringRef PossibleAVRLibcLocations[] = {
358*12c85518Srobert     "/avr",
359e5dd7070Spatrick     "/usr/avr",
360e5dd7070Spatrick     "/usr/lib/avr",
361e5dd7070Spatrick };
362e5dd7070Spatrick 
363e5dd7070Spatrick } // end anonymous namespace
364e5dd7070Spatrick 
365e5dd7070Spatrick /// AVR Toolchain
AVRToolChain(const Driver & D,const llvm::Triple & Triple,const ArgList & Args)366e5dd7070Spatrick AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple,
367e5dd7070Spatrick                            const ArgList &Args)
368*12c85518Srobert     : Generic_ELF(D, Triple, Args) {
369e5dd7070Spatrick   GCCInstallation.init(Triple, Args);
370e5dd7070Spatrick 
371*12c85518Srobert   if (getCPUName(D, Args, Triple).empty())
372*12c85518Srobert     D.Diag(diag::warn_drv_avr_mcu_not_specified);
373*12c85518Srobert 
374e5dd7070Spatrick   // Only add default libraries if the user hasn't explicitly opted out.
375e5dd7070Spatrick   if (!Args.hasArg(options::OPT_nostdlib) &&
376*12c85518Srobert       !Args.hasArg(options::OPT_nodefaultlibs) && GCCInstallation.isValid()) {
377*12c85518Srobert     GCCInstallPath = GCCInstallation.getInstallPath();
378a9ac8606Spatrick     std::string GCCParentPath(GCCInstallation.getParentLibPath());
379a9ac8606Spatrick     getProgramPaths().push_back(GCCParentPath + "/../bin");
380e5dd7070Spatrick   }
381e5dd7070Spatrick }
382e5dd7070Spatrick 
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const383a9ac8606Spatrick void AVRToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
384a9ac8606Spatrick                                              ArgStringList &CC1Args) const {
385a9ac8606Spatrick   if (DriverArgs.hasArg(options::OPT_nostdinc) ||
386a9ac8606Spatrick       DriverArgs.hasArg(options::OPT_nostdlibinc))
387a9ac8606Spatrick     return;
388a9ac8606Spatrick 
389a9ac8606Spatrick   // Omit if there is no avr-libc installed.
390*12c85518Srobert   std::optional<std::string> AVRLibcRoot = findAVRLibcInstallation();
391*12c85518Srobert   if (!AVRLibcRoot)
392a9ac8606Spatrick     return;
393a9ac8606Spatrick 
394a9ac8606Spatrick   // Add 'avr-libc/include' to clang system include paths if applicable.
395*12c85518Srobert   std::string AVRInc = *AVRLibcRoot + "/include";
396a9ac8606Spatrick   if (llvm::sys::fs::is_directory(AVRInc))
397a9ac8606Spatrick     addSystemInclude(DriverArgs, CC1Args, AVRInc);
398a9ac8606Spatrick }
399a9ac8606Spatrick 
addClangTargetOptions(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args,Action::OffloadKind DeviceOffloadKind) const400*12c85518Srobert void AVRToolChain::addClangTargetOptions(
401*12c85518Srobert     const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
402*12c85518Srobert     Action::OffloadKind DeviceOffloadKind) const {
403*12c85518Srobert   // By default, use `.ctors` (not `.init_array`), as required by libgcc, which
404*12c85518Srobert   // runs constructors/destructors on AVR.
405*12c85518Srobert   if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
406*12c85518Srobert                           options::OPT_fno_use_init_array, false))
407*12c85518Srobert     CC1Args.push_back("-fno-use-init-array");
408*12c85518Srobert   // Use `-fno-use-cxa-atexit` as default, since avr-libc does not support
409*12c85518Srobert   // `__cxa_atexit()`.
410*12c85518Srobert   if (!DriverArgs.hasFlag(options::OPT_fuse_cxa_atexit,
411*12c85518Srobert                           options::OPT_fno_use_cxa_atexit, false))
412*12c85518Srobert     CC1Args.push_back("-fno-use-cxa-atexit");
413*12c85518Srobert }
414*12c85518Srobert 
buildLinker() const415e5dd7070Spatrick Tool *AVRToolChain::buildLinker() const {
416*12c85518Srobert   return new tools::AVR::Linker(getTriple(), *this);
417*12c85518Srobert }
418*12c85518Srobert 
419*12c85518Srobert std::string
getCompilerRT(const llvm::opt::ArgList & Args,StringRef Component,FileType Type=ToolChain::FT_Static) const420*12c85518Srobert AVRToolChain::getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
421*12c85518Srobert                             FileType Type = ToolChain::FT_Static) const {
422*12c85518Srobert   assert(Type == ToolChain::FT_Static && "AVR only supports static libraries");
423*12c85518Srobert   // Since AVR can never be a host environment, its compiler-rt library files
424*12c85518Srobert   // should always have ".a" suffix, even on windows.
425*12c85518Srobert   SmallString<32> File("/libclang_rt.");
426*12c85518Srobert   File += Component.str();
427*12c85518Srobert   File += ".a";
428*12c85518Srobert   // Return the default compiler-rt path appended with
429*12c85518Srobert   // "avr/libclang_rt.$COMPONENT.a".
430*12c85518Srobert   SmallString<256> Path(ToolChain::getCompilerRTPath());
431*12c85518Srobert   llvm::sys::path::append(Path, "avr");
432*12c85518Srobert   llvm::sys::path::append(Path, File.str());
433*12c85518Srobert   return std::string(Path.str());
434e5dd7070Spatrick }
435e5dd7070Spatrick 
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const436e5dd7070Spatrick void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
437e5dd7070Spatrick                                const InputInfo &Output,
438a9ac8606Spatrick                                const InputInfoList &Inputs, const ArgList &Args,
439e5dd7070Spatrick                                const char *LinkingOutput) const {
440*12c85518Srobert   const auto &TC = static_cast<const AVRToolChain &>(getToolChain());
441*12c85518Srobert   const Driver &D = getToolChain().getDriver();
442e5dd7070Spatrick 
443*12c85518Srobert   // Compute information about the target AVR.
444*12c85518Srobert   std::string CPU = getCPUName(D, Args, getToolChain().getTriple());
445*12c85518Srobert   std::optional<StringRef> FamilyName = GetMCUFamilyName(CPU);
446*12c85518Srobert   std::optional<std::string> AVRLibcRoot = TC.findAVRLibcInstallation();
447*12c85518Srobert   std::optional<unsigned> SectionAddressData = GetMCUSectionAddressData(CPU);
448*12c85518Srobert 
449*12c85518Srobert   // Compute the linker program path, and use GNU "avr-ld" as default.
450*12c85518Srobert   const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ);
451*12c85518Srobert   std::string Linker = A ? getToolChain().GetLinkerPath(nullptr)
452*12c85518Srobert                          : getToolChain().GetProgramPath(getShortName());
453*12c85518Srobert 
454e5dd7070Spatrick   ArgStringList CmdArgs;
455e5dd7070Spatrick 
456e5dd7070Spatrick   CmdArgs.push_back("-o");
457e5dd7070Spatrick   CmdArgs.push_back(Output.getFilename());
458e5dd7070Spatrick 
459e5dd7070Spatrick   // Enable garbage collection of unused sections.
460e5dd7070Spatrick   CmdArgs.push_back("--gc-sections");
461e5dd7070Spatrick 
462e5dd7070Spatrick   // Add library search paths before we specify libraries.
463e5dd7070Spatrick   Args.AddAllArgs(CmdArgs, options::OPT_L);
464e5dd7070Spatrick   getToolChain().AddFilePathLibArgs(Args, CmdArgs);
465e5dd7070Spatrick 
466*12c85518Srobert   // Currently we only support libgcc and compiler-rt.
467*12c85518Srobert   auto RtLib = TC.GetRuntimeLibType(Args);
468*12c85518Srobert   assert(
469*12c85518Srobert       (RtLib == ToolChain::RLT_Libgcc || RtLib == ToolChain::RLT_CompilerRT) &&
470*12c85518Srobert       "unknown runtime library");
471*12c85518Srobert 
472*12c85518Srobert   // Only add default libraries if the user hasn't explicitly opted out.
473*12c85518Srobert   bool LinkStdlib = false;
474*12c85518Srobert   if (!Args.hasArg(options::OPT_nostdlib) &&
475*12c85518Srobert       !Args.hasArg(options::OPT_nodefaultlibs)) {
476*12c85518Srobert     if (!CPU.empty()) {
477*12c85518Srobert       if (!FamilyName) {
478*12c85518Srobert         // We do not have an entry for this CPU in the family
479*12c85518Srobert         // mapping table yet.
480*12c85518Srobert         D.Diag(diag::warn_drv_avr_family_linking_stdlibs_not_implemented)
481*12c85518Srobert             << CPU;
482*12c85518Srobert       } else if (!AVRLibcRoot) {
483*12c85518Srobert         // No avr-libc found and so no runtime linked.
484*12c85518Srobert         D.Diag(diag::warn_drv_avr_libc_not_found);
485*12c85518Srobert       } else {
486*12c85518Srobert         std::string SubPath = GetMCUSubPath(CPU);
487*12c85518Srobert         // Add path of avr-libc.
488*12c85518Srobert         CmdArgs.push_back(
489*12c85518Srobert             Args.MakeArgString(Twine("-L") + *AVRLibcRoot + "/lib/" + SubPath));
490*12c85518Srobert         if (RtLib == ToolChain::RLT_Libgcc)
491*12c85518Srobert           CmdArgs.push_back(Args.MakeArgString("-L" + TC.getGCCInstallPath() +
492*12c85518Srobert                                                "/" + SubPath));
493*12c85518Srobert         LinkStdlib = true;
494*12c85518Srobert       }
495*12c85518Srobert     }
496*12c85518Srobert     if (!LinkStdlib)
497*12c85518Srobert       D.Diag(diag::warn_drv_avr_stdlib_not_linked);
498*12c85518Srobert   }
499*12c85518Srobert 
500*12c85518Srobert   if (SectionAddressData) {
501*12c85518Srobert     CmdArgs.push_back(Args.MakeArgString(
502*12c85518Srobert         "-Tdata=0x" + Twine::utohexstr(*SectionAddressData)));
503a9ac8606Spatrick   } else {
504a9ac8606Spatrick     // We do not have an entry for this CPU in the address mapping table yet.
505*12c85518Srobert     D.Diag(diag::warn_drv_avr_linker_section_addresses_not_implemented) << CPU;
506a9ac8606Spatrick   }
507a9ac8606Spatrick 
508e5dd7070Spatrick   // If the family name is known, we can link with the device-specific libgcc.
509e5dd7070Spatrick   // Without it, libgcc will simply not be linked. This matches avr-gcc
510e5dd7070Spatrick   // behavior.
511e5dd7070Spatrick   if (LinkStdlib) {
512e5dd7070Spatrick     assert(!CPU.empty() && "CPU name must be known in order to link stdlibs");
513e5dd7070Spatrick 
514*12c85518Srobert     CmdArgs.push_back("--start-group");
515*12c85518Srobert 
516e5dd7070Spatrick     // Add the object file for the CRT.
517e5dd7070Spatrick     std::string CrtFileName = std::string("-l:crt") + CPU + std::string(".o");
518e5dd7070Spatrick     CmdArgs.push_back(Args.MakeArgString(CrtFileName));
519e5dd7070Spatrick 
520*12c85518Srobert     // Link to libgcc.
521*12c85518Srobert     if (RtLib == ToolChain::RLT_Libgcc)
522e5dd7070Spatrick       CmdArgs.push_back("-lgcc");
523*12c85518Srobert 
524*12c85518Srobert     // Link to generic libraries of avr-libc.
525e5dd7070Spatrick     CmdArgs.push_back("-lm");
526e5dd7070Spatrick     CmdArgs.push_back("-lc");
527e5dd7070Spatrick 
528e5dd7070Spatrick     // Add the link library specific to the MCU.
529e5dd7070Spatrick     CmdArgs.push_back(Args.MakeArgString(std::string("-l") + CPU));
530e5dd7070Spatrick 
531*12c85518Srobert     // Add the relocatable inputs.
532*12c85518Srobert     AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
533*12c85518Srobert 
534*12c85518Srobert     // We directly use libclang_rt.builtins.a as input file, instead of using
535*12c85518Srobert     // '-lclang_rt.builtins'.
536*12c85518Srobert     if (RtLib == ToolChain::RLT_CompilerRT) {
537*12c85518Srobert       std::string RtLib =
538*12c85518Srobert           getToolChain().getCompilerRT(Args, "builtins", ToolChain::FT_Static);
539*12c85518Srobert       if (llvm::sys::fs::exists(RtLib))
540*12c85518Srobert         CmdArgs.push_back(Args.MakeArgString(RtLib));
541*12c85518Srobert     }
542*12c85518Srobert 
543*12c85518Srobert     CmdArgs.push_back("--end-group");
544*12c85518Srobert 
545*12c85518Srobert     // Add user specified linker script.
546*12c85518Srobert     Args.AddAllArgs(CmdArgs, options::OPT_T);
547*12c85518Srobert 
548e5dd7070Spatrick     // Specify the family name as the emulation mode to use.
549e5dd7070Spatrick     // This is almost always required because otherwise avr-ld
550e5dd7070Spatrick     // will assume 'avr2' and warn about the program being larger
551e5dd7070Spatrick     // than the bare minimum supports.
552*12c85518Srobert     if (Linker.find("avr-ld") != std::string::npos)
553e5dd7070Spatrick       CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName));
554*12c85518Srobert   } else {
555*12c85518Srobert     AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
556e5dd7070Spatrick   }
557e5dd7070Spatrick 
558a9ac8606Spatrick   C.addCommand(std::make_unique<Command>(
559a9ac8606Spatrick       JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),
560a9ac8606Spatrick       CmdArgs, Inputs, Output));
561e5dd7070Spatrick }
562e5dd7070Spatrick 
findAVRLibcInstallation() const563*12c85518Srobert std::optional<std::string> AVRToolChain::findAVRLibcInstallation() const {
564*12c85518Srobert   // Search avr-libc installation according to avr-gcc installation.
565*12c85518Srobert   std::string GCCParent(GCCInstallation.getParentLibPath());
566*12c85518Srobert   std::string Path(GCCParent + "/avr");
567*12c85518Srobert   if (llvm::sys::fs::is_directory(Path))
568*12c85518Srobert     return Path;
569*12c85518Srobert   Path = GCCParent + "/../avr";
570*12c85518Srobert   if (llvm::sys::fs::is_directory(Path))
571*12c85518Srobert     return Path;
572*12c85518Srobert 
573*12c85518Srobert   // Search avr-libc installation from possible locations, and return the first
574*12c85518Srobert   // one that exists, if there is no avr-gcc installed.
575e5dd7070Spatrick   for (StringRef PossiblePath : PossibleAVRLibcLocations) {
576a9ac8606Spatrick     std::string Path = getDriver().SysRoot + PossiblePath.str();
577a9ac8606Spatrick     if (llvm::sys::fs::is_directory(Path))
578*12c85518Srobert       return Path;
579e5dd7070Spatrick   }
580e5dd7070Spatrick 
581*12c85518Srobert   return std::nullopt;
582e5dd7070Spatrick }
583