10b57cec5SDimitry Andric //===--- AVR.cpp - AVR ToolChain Implementations ----------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "AVR.h" 100b57cec5SDimitry Andric #include "CommonArgs.h" 110b57cec5SDimitry Andric #include "clang/Driver/Compilation.h" 120b57cec5SDimitry Andric #include "clang/Driver/DriverDiagnostic.h" 13fe6060f1SDimitry Andric #include "clang/Driver/InputInfo.h" 140b57cec5SDimitry Andric #include "clang/Driver/Options.h" 15e8d8bef9SDimitry Andric #include "llvm/ADT/StringExtras.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 170b57cec5SDimitry Andric #include "llvm/Option/ArgList.h" 180b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 19bdd1243dSDimitry Andric #include "llvm/Support/Path.h" 2006c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric using namespace clang::driver; 230b57cec5SDimitry Andric using namespace clang::driver::toolchains; 240b57cec5SDimitry Andric using namespace clang::driver::tools; 250b57cec5SDimitry Andric using namespace clang; 260b57cec5SDimitry Andric using namespace llvm::opt; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace { 290b57cec5SDimitry Andric 3081ad6265SDimitry Andric // NOTE: This list has been synchronized with gcc-avr 7.3.0 and avr-libc 2.0.0. 31349cc55cSDimitry Andric constexpr struct { 32e8d8bef9SDimitry Andric StringRef Name; 33349cc55cSDimitry Andric StringRef SubPath; 34e8d8bef9SDimitry Andric StringRef Family; 35fe6060f1SDimitry Andric unsigned DataAddr; 36e8d8bef9SDimitry Andric } MCUInfo[] = { 37fe6060f1SDimitry Andric {"at90s1200", "", "avr1", 0}, 38fe6060f1SDimitry Andric {"attiny11", "", "avr1", 0}, 39fe6060f1SDimitry Andric {"attiny12", "", "avr1", 0}, 40fe6060f1SDimitry Andric {"attiny15", "", "avr1", 0}, 41fe6060f1SDimitry Andric {"attiny28", "", "avr1", 0}, 42fe6060f1SDimitry Andric {"at90s2313", "tiny-stack", "avr2", 0x800060}, 43fe6060f1SDimitry Andric {"at90s2323", "tiny-stack", "avr2", 0x800060}, 44fe6060f1SDimitry Andric {"at90s2333", "tiny-stack", "avr2", 0x800060}, 45fe6060f1SDimitry Andric {"at90s2343", "tiny-stack", "avr2", 0x800060}, 46fe6060f1SDimitry Andric {"at90s4433", "tiny-stack", "avr2", 0x800060}, 47fe6060f1SDimitry Andric {"attiny22", "tiny-stack", "avr2", 0x800060}, 48fe6060f1SDimitry Andric {"attiny26", "tiny-stack", "avr2", 0x800060}, 49fe6060f1SDimitry Andric {"at90s4414", "", "avr2", 0x800060}, 50fe6060f1SDimitry Andric {"at90s4434", "", "avr2", 0x800060}, 51fe6060f1SDimitry Andric {"at90s8515", "", "avr2", 0x800060}, 52fe6060f1SDimitry Andric {"at90c8534", "", "avr2", 0x800060}, 53fe6060f1SDimitry Andric {"at90s8535", "", "avr2", 0x800060}, 54fe6060f1SDimitry Andric {"attiny13", "avr25/tiny-stack", "avr25", 0x800060}, 55fe6060f1SDimitry Andric {"attiny13a", "avr25/tiny-stack", "avr25", 0x800060}, 56fe6060f1SDimitry Andric {"attiny2313", "avr25/tiny-stack", "avr25", 0x800060}, 57fe6060f1SDimitry Andric {"attiny2313a", "avr25/tiny-stack", "avr25", 0x800060}, 58fe6060f1SDimitry Andric {"attiny24", "avr25/tiny-stack", "avr25", 0x800060}, 59fe6060f1SDimitry Andric {"attiny24a", "avr25/tiny-stack", "avr25", 0x800060}, 60fe6060f1SDimitry Andric {"attiny25", "avr25/tiny-stack", "avr25", 0x800060}, 61fe6060f1SDimitry Andric {"attiny261", "avr25/tiny-stack", "avr25", 0x800060}, 62fe6060f1SDimitry Andric {"attiny261a", "avr25/tiny-stack", "avr25", 0x800060}, 63fe6060f1SDimitry Andric {"at86rf401", "avr25", "avr25", 0x800060}, 64fe6060f1SDimitry Andric {"ata5272", "avr25", "avr25", 0x800100}, 6581ad6265SDimitry Andric {"ata6616c", "avr25", "avr25", 0x800100}, 66fe6060f1SDimitry Andric {"attiny4313", "avr25", "avr25", 0x800060}, 67fe6060f1SDimitry Andric {"attiny44", "avr25", "avr25", 0x800060}, 68fe6060f1SDimitry Andric {"attiny44a", "avr25", "avr25", 0x800060}, 69fe6060f1SDimitry Andric {"attiny84", "avr25", "avr25", 0x800060}, 70fe6060f1SDimitry Andric {"attiny84a", "avr25", "avr25", 0x800060}, 71fe6060f1SDimitry Andric {"attiny45", "avr25", "avr25", 0x800060}, 72fe6060f1SDimitry Andric {"attiny85", "avr25", "avr25", 0x800060}, 73fe6060f1SDimitry Andric {"attiny441", "avr25", "avr25", 0x800100}, 74fe6060f1SDimitry Andric {"attiny461", "avr25", "avr25", 0x800060}, 75fe6060f1SDimitry Andric {"attiny461a", "avr25", "avr25", 0x800060}, 76fe6060f1SDimitry Andric {"attiny841", "avr25", "avr25", 0x800100}, 77fe6060f1SDimitry Andric {"attiny861", "avr25", "avr25", 0x800060}, 78fe6060f1SDimitry Andric {"attiny861a", "avr25", "avr25", 0x800060}, 79fe6060f1SDimitry Andric {"attiny87", "avr25", "avr25", 0x800100}, 80fe6060f1SDimitry Andric {"attiny43u", "avr25", "avr25", 0x800060}, 81fe6060f1SDimitry Andric {"attiny48", "avr25", "avr25", 0x800100}, 82fe6060f1SDimitry Andric {"attiny88", "avr25", "avr25", 0x800100}, 83fe6060f1SDimitry Andric {"attiny828", "avr25", "avr25", 0x800100}, 84fe6060f1SDimitry Andric {"at43usb355", "avr3", "avr3", 0x800100}, 85fe6060f1SDimitry Andric {"at76c711", "avr3", "avr3", 0x800060}, 86fe6060f1SDimitry Andric {"atmega103", "avr31", "avr31", 0x800060}, 87fe6060f1SDimitry Andric {"at43usb320", "avr31", "avr31", 0x800060}, 88fe6060f1SDimitry Andric {"attiny167", "avr35", "avr35", 0x800100}, 89fe6060f1SDimitry Andric {"at90usb82", "avr35", "avr35", 0x800100}, 90fe6060f1SDimitry Andric {"at90usb162", "avr35", "avr35", 0x800100}, 91fe6060f1SDimitry Andric {"ata5505", "avr35", "avr35", 0x800100}, 9281ad6265SDimitry Andric {"ata6617c", "avr35", "avr35", 0x800100}, 9381ad6265SDimitry Andric {"ata664251", "avr35", "avr35", 0x800100}, 94fe6060f1SDimitry Andric {"atmega8u2", "avr35", "avr35", 0x800100}, 95fe6060f1SDimitry Andric {"atmega16u2", "avr35", "avr35", 0x800100}, 96fe6060f1SDimitry Andric {"atmega32u2", "avr35", "avr35", 0x800100}, 97fe6060f1SDimitry Andric {"attiny1634", "avr35", "avr35", 0x800100}, 98fe6060f1SDimitry Andric {"atmega8", "avr4", "avr4", 0x800060}, 99fe6060f1SDimitry Andric {"ata6289", "avr4", "avr4", 0x800100}, 100fe6060f1SDimitry Andric {"atmega8a", "avr4", "avr4", 0x800060}, 101fe6060f1SDimitry Andric {"ata6285", "avr4", "avr4", 0x800100}, 102fe6060f1SDimitry Andric {"ata6286", "avr4", "avr4", 0x800100}, 10381ad6265SDimitry Andric {"ata6612c", "avr4", "avr4", 0x800100}, 104fe6060f1SDimitry Andric {"atmega48", "avr4", "avr4", 0x800100}, 105fe6060f1SDimitry Andric {"atmega48a", "avr4", "avr4", 0x800100}, 106fe6060f1SDimitry Andric {"atmega48pa", "avr4", "avr4", 0x800100}, 107fe6060f1SDimitry Andric {"atmega48pb", "avr4", "avr4", 0x800100}, 108fe6060f1SDimitry Andric {"atmega48p", "avr4", "avr4", 0x800100}, 109fe6060f1SDimitry Andric {"atmega88", "avr4", "avr4", 0x800100}, 110fe6060f1SDimitry Andric {"atmega88a", "avr4", "avr4", 0x800100}, 111fe6060f1SDimitry Andric {"atmega88p", "avr4", "avr4", 0x800100}, 112fe6060f1SDimitry Andric {"atmega88pa", "avr4", "avr4", 0x800100}, 113fe6060f1SDimitry Andric {"atmega88pb", "avr4", "avr4", 0x800100}, 114fe6060f1SDimitry Andric {"atmega8515", "avr4", "avr4", 0x800060}, 115fe6060f1SDimitry Andric {"atmega8535", "avr4", "avr4", 0x800060}, 116fe6060f1SDimitry Andric {"atmega8hva", "avr4", "avr4", 0x800100}, 117fe6060f1SDimitry Andric {"at90pwm1", "avr4", "avr4", 0x800100}, 118fe6060f1SDimitry Andric {"at90pwm2", "avr4", "avr4", 0x800100}, 119fe6060f1SDimitry Andric {"at90pwm2b", "avr4", "avr4", 0x800100}, 120fe6060f1SDimitry Andric {"at90pwm3", "avr4", "avr4", 0x800100}, 121fe6060f1SDimitry Andric {"at90pwm3b", "avr4", "avr4", 0x800100}, 122fe6060f1SDimitry Andric {"at90pwm81", "avr4", "avr4", 0x800100}, 12381ad6265SDimitry Andric {"ata5702m322", "avr5", "avr5", 0x800200}, 12481ad6265SDimitry Andric {"ata5782", "avr5", "avr5", 0x800200}, 125fe6060f1SDimitry Andric {"ata5790", "avr5", "avr5", 0x800100}, 12681ad6265SDimitry Andric {"ata5790n", "avr5", "avr5", 0x800100}, 12781ad6265SDimitry Andric {"ata5791", "avr5", "avr5", 0x800100}, 128fe6060f1SDimitry Andric {"ata5795", "avr5", "avr5", 0x800100}, 12981ad6265SDimitry Andric {"ata5831", "avr5", "avr5", 0x800200}, 13081ad6265SDimitry Andric {"ata6613c", "avr5", "avr5", 0x800100}, 13181ad6265SDimitry Andric {"ata6614q", "avr5", "avr5", 0x800100}, 13281ad6265SDimitry Andric {"ata8210", "avr5", "avr5", 0x800200}, 13381ad6265SDimitry Andric {"ata8510", "avr5", "avr5", 0x800200}, 134fe6060f1SDimitry Andric {"atmega16", "avr5", "avr5", 0x800060}, 135fe6060f1SDimitry Andric {"atmega16a", "avr5", "avr5", 0x800060}, 136fe6060f1SDimitry Andric {"atmega161", "avr5", "avr5", 0x800060}, 137fe6060f1SDimitry Andric {"atmega162", "avr5", "avr5", 0x800100}, 138fe6060f1SDimitry Andric {"atmega163", "avr5", "avr5", 0x800060}, 139fe6060f1SDimitry Andric {"atmega164a", "avr5", "avr5", 0x800100}, 140fe6060f1SDimitry Andric {"atmega164p", "avr5", "avr5", 0x800100}, 141fe6060f1SDimitry Andric {"atmega164pa", "avr5", "avr5", 0x800100}, 142fe6060f1SDimitry Andric {"atmega165", "avr5", "avr5", 0x800100}, 143fe6060f1SDimitry Andric {"atmega165a", "avr5", "avr5", 0x800100}, 144fe6060f1SDimitry Andric {"atmega165p", "avr5", "avr5", 0x800100}, 145fe6060f1SDimitry Andric {"atmega165pa", "avr5", "avr5", 0x800100}, 146fe6060f1SDimitry Andric {"atmega168", "avr5", "avr5", 0x800100}, 147fe6060f1SDimitry Andric {"atmega168a", "avr5", "avr5", 0x800100}, 148fe6060f1SDimitry Andric {"atmega168p", "avr5", "avr5", 0x800100}, 149fe6060f1SDimitry Andric {"atmega168pa", "avr5", "avr5", 0x800100}, 150fe6060f1SDimitry Andric {"atmega168pb", "avr5", "avr5", 0x800100}, 151fe6060f1SDimitry Andric {"atmega169", "avr5", "avr5", 0x800100}, 152fe6060f1SDimitry Andric {"atmega169a", "avr5", "avr5", 0x800100}, 153fe6060f1SDimitry Andric {"atmega169p", "avr5", "avr5", 0x800100}, 154fe6060f1SDimitry Andric {"atmega169pa", "avr5", "avr5", 0x800100}, 155fe6060f1SDimitry Andric {"atmega32", "avr5", "avr5", 0x800060}, 156fe6060f1SDimitry Andric {"atmega32a", "avr5", "avr5", 0x800060}, 157fe6060f1SDimitry Andric {"atmega323", "avr5", "avr5", 0x800060}, 158fe6060f1SDimitry Andric {"atmega324a", "avr5", "avr5", 0x800100}, 159fe6060f1SDimitry Andric {"atmega324p", "avr5", "avr5", 0x800100}, 160fe6060f1SDimitry Andric {"atmega324pa", "avr5", "avr5", 0x800100}, 16181ad6265SDimitry Andric {"atmega324pb", "avr5", "avr5", 0x800100}, 162fe6060f1SDimitry Andric {"atmega325", "avr5", "avr5", 0x800100}, 163fe6060f1SDimitry Andric {"atmega325a", "avr5", "avr5", 0x800100}, 164fe6060f1SDimitry Andric {"atmega325p", "avr5", "avr5", 0x800100}, 165fe6060f1SDimitry Andric {"atmega325pa", "avr5", "avr5", 0x800100}, 166fe6060f1SDimitry Andric {"atmega3250", "avr5", "avr5", 0x800100}, 167fe6060f1SDimitry Andric {"atmega3250a", "avr5", "avr5", 0x800100}, 168fe6060f1SDimitry Andric {"atmega3250p", "avr5", "avr5", 0x800100}, 169fe6060f1SDimitry Andric {"atmega3250pa", "avr5", "avr5", 0x800100}, 170fe6060f1SDimitry Andric {"atmega328", "avr5", "avr5", 0x800100}, 171fe6060f1SDimitry Andric {"atmega328p", "avr5", "avr5", 0x800100}, 17281ad6265SDimitry Andric {"atmega328pb", "avr5", "avr5", 0x800100}, 173fe6060f1SDimitry Andric {"atmega329", "avr5", "avr5", 0x800100}, 174fe6060f1SDimitry Andric {"atmega329a", "avr5", "avr5", 0x800100}, 175fe6060f1SDimitry Andric {"atmega329p", "avr5", "avr5", 0x800100}, 176fe6060f1SDimitry Andric {"atmega329pa", "avr5", "avr5", 0x800100}, 177fe6060f1SDimitry Andric {"atmega3290", "avr5", "avr5", 0x800100}, 178fe6060f1SDimitry Andric {"atmega3290a", "avr5", "avr5", 0x800100}, 179fe6060f1SDimitry Andric {"atmega3290p", "avr5", "avr5", 0x800100}, 180fe6060f1SDimitry Andric {"atmega3290pa", "avr5", "avr5", 0x800100}, 181fe6060f1SDimitry Andric {"atmega406", "avr5", "avr5", 0x800100}, 182fe6060f1SDimitry Andric {"atmega64", "avr5", "avr5", 0x800100}, 183fe6060f1SDimitry Andric {"atmega64a", "avr5", "avr5", 0x800100}, 184fe6060f1SDimitry Andric {"atmega640", "avr5", "avr5", 0x800200}, 185fe6060f1SDimitry Andric {"atmega644", "avr5", "avr5", 0x800100}, 186fe6060f1SDimitry Andric {"atmega644a", "avr5", "avr5", 0x800100}, 187fe6060f1SDimitry Andric {"atmega644p", "avr5", "avr5", 0x800100}, 188fe6060f1SDimitry Andric {"atmega644pa", "avr5", "avr5", 0x800100}, 189fe6060f1SDimitry Andric {"atmega645", "avr5", "avr5", 0x800100}, 190fe6060f1SDimitry Andric {"atmega645a", "avr5", "avr5", 0x800100}, 191fe6060f1SDimitry Andric {"atmega645p", "avr5", "avr5", 0x800100}, 192fe6060f1SDimitry Andric {"atmega649", "avr5", "avr5", 0x800100}, 193fe6060f1SDimitry Andric {"atmega649a", "avr5", "avr5", 0x800100}, 194fe6060f1SDimitry Andric {"atmega649p", "avr5", "avr5", 0x800100}, 195fe6060f1SDimitry Andric {"atmega6450", "avr5", "avr5", 0x800100}, 196fe6060f1SDimitry Andric {"atmega6450a", "avr5", "avr5", 0x800100}, 197fe6060f1SDimitry Andric {"atmega6450p", "avr5", "avr5", 0x800100}, 198fe6060f1SDimitry Andric {"atmega6490", "avr5", "avr5", 0x800100}, 199fe6060f1SDimitry Andric {"atmega6490a", "avr5", "avr5", 0x800100}, 200fe6060f1SDimitry Andric {"atmega6490p", "avr5", "avr5", 0x800100}, 201fe6060f1SDimitry Andric {"atmega64rfr2", "avr5", "avr5", 0x800200}, 202fe6060f1SDimitry Andric {"atmega644rfr2", "avr5", "avr5", 0x800200}, 203fe6060f1SDimitry Andric {"atmega16hva", "avr5", "avr5", 0x800100}, 204fe6060f1SDimitry Andric {"atmega16hva2", "avr5", "avr5", 0x800100}, 205fe6060f1SDimitry Andric {"atmega16hvb", "avr5", "avr5", 0x800100}, 206fe6060f1SDimitry Andric {"atmega16hvbrevb", "avr5", "avr5", 0x800100}, 207fe6060f1SDimitry Andric {"atmega32hvb", "avr5", "avr5", 0x800100}, 208fe6060f1SDimitry Andric {"atmega32hvbrevb", "avr5", "avr5", 0x800100}, 209fe6060f1SDimitry Andric {"atmega64hve", "avr5", "avr5", 0x800100}, 21081ad6265SDimitry Andric {"atmega64hve2", "avr5", "avr5", 0x800100}, 211fe6060f1SDimitry Andric {"at90can32", "avr5", "avr5", 0x800100}, 212fe6060f1SDimitry Andric {"at90can64", "avr5", "avr5", 0x800100}, 213fe6060f1SDimitry Andric {"at90pwm161", "avr5", "avr5", 0x800100}, 214fe6060f1SDimitry Andric {"at90pwm216", "avr5", "avr5", 0x800100}, 215fe6060f1SDimitry Andric {"at90pwm316", "avr5", "avr5", 0x800100}, 216fe6060f1SDimitry Andric {"atmega32c1", "avr5", "avr5", 0x800100}, 217fe6060f1SDimitry Andric {"atmega64c1", "avr5", "avr5", 0x800100}, 218fe6060f1SDimitry Andric {"atmega16m1", "avr5", "avr5", 0x800100}, 219fe6060f1SDimitry Andric {"atmega32m1", "avr5", "avr5", 0x800100}, 220fe6060f1SDimitry Andric {"atmega64m1", "avr5", "avr5", 0x800100}, 221fe6060f1SDimitry Andric {"atmega16u4", "avr5", "avr5", 0x800100}, 222fe6060f1SDimitry Andric {"atmega32u4", "avr5", "avr5", 0x800100}, 223fe6060f1SDimitry Andric {"atmega32u6", "avr5", "avr5", 0x800100}, 224fe6060f1SDimitry Andric {"at90usb646", "avr5", "avr5", 0x800100}, 225fe6060f1SDimitry Andric {"at90usb647", "avr5", "avr5", 0x800100}, 226fe6060f1SDimitry Andric {"at90scr100", "avr5", "avr5", 0x800100}, 227fe6060f1SDimitry Andric {"at94k", "avr5", "avr5", 0x800060}, 228fe6060f1SDimitry Andric {"m3000", "avr5", "avr5", 0x800060}, 229fe6060f1SDimitry Andric {"atmega128", "avr51", "avr51", 0x800100}, 230fe6060f1SDimitry Andric {"atmega128a", "avr51", "avr51", 0x800100}, 231fe6060f1SDimitry Andric {"atmega1280", "avr51", "avr51", 0x800200}, 232fe6060f1SDimitry Andric {"atmega1281", "avr51", "avr51", 0x800200}, 233fe6060f1SDimitry Andric {"atmega1284", "avr51", "avr51", 0x800100}, 234fe6060f1SDimitry Andric {"atmega1284p", "avr51", "avr51", 0x800100}, 235fe6060f1SDimitry Andric {"atmega128rfa1", "avr51", "avr51", 0x800200}, 236fe6060f1SDimitry Andric {"atmega128rfr2", "avr51", "avr51", 0x800200}, 237fe6060f1SDimitry Andric {"atmega1284rfr2", "avr51", "avr51", 0x800200}, 238fe6060f1SDimitry Andric {"at90can128", "avr51", "avr51", 0x800200}, 239fe6060f1SDimitry Andric {"at90usb1286", "avr51", "avr51", 0x800200}, 240fe6060f1SDimitry Andric {"at90usb1287", "avr51", "avr51", 0x800200}, 241fe6060f1SDimitry Andric {"atmega2560", "avr6", "avr6", 0x800200}, 242fe6060f1SDimitry Andric {"atmega2561", "avr6", "avr6", 0x800200}, 243fe6060f1SDimitry Andric {"atmega256rfr2", "avr6", "avr6", 0x800200}, 244fe6060f1SDimitry Andric {"atmega2564rfr2", "avr6", "avr6", 0x800200}, 245fe6060f1SDimitry Andric {"attiny4", "avrtiny", "avrtiny", 0x800040}, 246fe6060f1SDimitry Andric {"attiny5", "avrtiny", "avrtiny", 0x800040}, 247fe6060f1SDimitry Andric {"attiny9", "avrtiny", "avrtiny", 0x800040}, 248fe6060f1SDimitry Andric {"attiny10", "avrtiny", "avrtiny", 0x800040}, 249fe6060f1SDimitry Andric {"attiny20", "avrtiny", "avrtiny", 0x800040}, 250fe6060f1SDimitry Andric {"attiny40", "avrtiny", "avrtiny", 0x800040}, 25181ad6265SDimitry Andric {"attiny102", "avrtiny", "avrtiny", 0x800040}, 25281ad6265SDimitry Andric {"attiny104", "avrtiny", "avrtiny", 0x800040}, 253fe6060f1SDimitry Andric {"atxmega16a4", "avrxmega2", "avrxmega2", 0x802000}, 254fe6060f1SDimitry Andric {"atxmega16a4u", "avrxmega2", "avrxmega2", 0x802000}, 255fe6060f1SDimitry Andric {"atxmega16c4", "avrxmega2", "avrxmega2", 0x802000}, 256fe6060f1SDimitry Andric {"atxmega16d4", "avrxmega2", "avrxmega2", 0x802000}, 257fe6060f1SDimitry Andric {"atxmega32a4", "avrxmega2", "avrxmega2", 0x802000}, 258fe6060f1SDimitry Andric {"atxmega32a4u", "avrxmega2", "avrxmega2", 0x802000}, 25981ad6265SDimitry Andric {"atxmega32c3", "avrxmega2", "avrxmega2", 0x802000}, 260fe6060f1SDimitry Andric {"atxmega32c4", "avrxmega2", "avrxmega2", 0x802000}, 26181ad6265SDimitry Andric {"atxmega32d3", "avrxmega2", "avrxmega2", 0x802000}, 262fe6060f1SDimitry Andric {"atxmega32d4", "avrxmega2", "avrxmega2", 0x802000}, 263fe6060f1SDimitry Andric {"atxmega32e5", "avrxmega2", "avrxmega2", 0x802000}, 264fe6060f1SDimitry Andric {"atxmega16e5", "avrxmega2", "avrxmega2", 0x802000}, 265fe6060f1SDimitry Andric {"atxmega8e5", "avrxmega2", "avrxmega2", 0x802000}, 26681ad6265SDimitry Andric {"atxmega64a3", "avrxmega4", "avrxmega4", 0x802000}, 267fe6060f1SDimitry Andric {"atxmega64a3u", "avrxmega4", "avrxmega4", 0x802000}, 268fe6060f1SDimitry Andric {"atxmega64a4u", "avrxmega4", "avrxmega4", 0x802000}, 269fe6060f1SDimitry Andric {"atxmega64b1", "avrxmega4", "avrxmega4", 0x802000}, 270fe6060f1SDimitry Andric {"atxmega64b3", "avrxmega4", "avrxmega4", 0x802000}, 271fe6060f1SDimitry Andric {"atxmega64c3", "avrxmega4", "avrxmega4", 0x802000}, 272fe6060f1SDimitry Andric {"atxmega64d3", "avrxmega4", "avrxmega4", 0x802000}, 273fe6060f1SDimitry Andric {"atxmega64d4", "avrxmega4", "avrxmega4", 0x802000}, 274fe6060f1SDimitry Andric {"atxmega64a1", "avrxmega5", "avrxmega5", 0x802000}, 275fe6060f1SDimitry Andric {"atxmega64a1u", "avrxmega5", "avrxmega5", 0x802000}, 276fe6060f1SDimitry Andric {"atxmega128a3", "avrxmega6", "avrxmega6", 0x802000}, 277fe6060f1SDimitry Andric {"atxmega128a3u", "avrxmega6", "avrxmega6", 0x802000}, 278fe6060f1SDimitry Andric {"atxmega128b1", "avrxmega6", "avrxmega6", 0x802000}, 279fe6060f1SDimitry Andric {"atxmega128b3", "avrxmega6", "avrxmega6", 0x802000}, 280fe6060f1SDimitry Andric {"atxmega128c3", "avrxmega6", "avrxmega6", 0x802000}, 281fe6060f1SDimitry Andric {"atxmega128d3", "avrxmega6", "avrxmega6", 0x802000}, 282fe6060f1SDimitry Andric {"atxmega128d4", "avrxmega6", "avrxmega6", 0x802000}, 283fe6060f1SDimitry Andric {"atxmega192a3", "avrxmega6", "avrxmega6", 0x802000}, 284fe6060f1SDimitry Andric {"atxmega192a3u", "avrxmega6", "avrxmega6", 0x802000}, 285fe6060f1SDimitry Andric {"atxmega192c3", "avrxmega6", "avrxmega6", 0x802000}, 286fe6060f1SDimitry Andric {"atxmega192d3", "avrxmega6", "avrxmega6", 0x802000}, 287fe6060f1SDimitry Andric {"atxmega256a3", "avrxmega6", "avrxmega6", 0x802000}, 288fe6060f1SDimitry Andric {"atxmega256a3u", "avrxmega6", "avrxmega6", 0x802000}, 289fe6060f1SDimitry Andric {"atxmega256a3b", "avrxmega6", "avrxmega6", 0x802000}, 290fe6060f1SDimitry Andric {"atxmega256a3bu", "avrxmega6", "avrxmega6", 0x802000}, 291fe6060f1SDimitry Andric {"atxmega256c3", "avrxmega6", "avrxmega6", 0x802000}, 292fe6060f1SDimitry Andric {"atxmega256d3", "avrxmega6", "avrxmega6", 0x802000}, 293fe6060f1SDimitry Andric {"atxmega384c3", "avrxmega6", "avrxmega6", 0x802000}, 294fe6060f1SDimitry Andric {"atxmega384d3", "avrxmega6", "avrxmega6", 0x802000}, 295fe6060f1SDimitry Andric {"atxmega128a1", "avrxmega7", "avrxmega7", 0x802000}, 296fe6060f1SDimitry Andric {"atxmega128a1u", "avrxmega7", "avrxmega7", 0x802000}, 297fe6060f1SDimitry Andric {"atxmega128a4u", "avrxmega7", "avrxmega7", 0x802000}, 29881ad6265SDimitry Andric {"attiny202", "avrxmega3/short-calls", "avrxmega3", 0x803F80}, 29981ad6265SDimitry Andric {"attiny204", "avrxmega3/short-calls", "avrxmega3", 0x803F80}, 30081ad6265SDimitry Andric {"attiny212", "avrxmega3/short-calls", "avrxmega3", 0x803F80}, 30181ad6265SDimitry Andric {"attiny214", "avrxmega3/short-calls", "avrxmega3", 0x803F80}, 30281ad6265SDimitry Andric {"attiny402", "avrxmega3/short-calls", "avrxmega3", 0x803F00}, 30381ad6265SDimitry Andric {"attiny404", "avrxmega3/short-calls", "avrxmega3", 0x803F00}, 30481ad6265SDimitry Andric {"attiny406", "avrxmega3/short-calls", "avrxmega3", 0x803F00}, 30581ad6265SDimitry Andric {"attiny412", "avrxmega3/short-calls", "avrxmega3", 0x803F00}, 30681ad6265SDimitry Andric {"attiny414", "avrxmega3/short-calls", "avrxmega3", 0x803F00}, 30781ad6265SDimitry Andric {"attiny416", "avrxmega3/short-calls", "avrxmega3", 0x803F00}, 30881ad6265SDimitry Andric {"attiny417", "avrxmega3/short-calls", "avrxmega3", 0x803F00}, 30981ad6265SDimitry Andric {"attiny804", "avrxmega3/short-calls", "avrxmega3", 0x803E00}, 31081ad6265SDimitry Andric {"attiny806", "avrxmega3/short-calls", "avrxmega3", 0x803E00}, 31181ad6265SDimitry Andric {"attiny807", "avrxmega3/short-calls", "avrxmega3", 0x803E00}, 31281ad6265SDimitry Andric {"attiny814", "avrxmega3/short-calls", "avrxmega3", 0x803E00}, 31381ad6265SDimitry Andric {"attiny816", "avrxmega3/short-calls", "avrxmega3", 0x803E00}, 31481ad6265SDimitry Andric {"attiny817", "avrxmega3/short-calls", "avrxmega3", 0x803E00}, 31581ad6265SDimitry Andric {"atmega808", "avrxmega3/short-calls", "avrxmega3", 0x803C00}, 31681ad6265SDimitry Andric {"atmega809", "avrxmega3/short-calls", "avrxmega3", 0x803C00}, 31781ad6265SDimitry Andric {"atmega1608", "avrxmega3", "avrxmega3", 0x803800}, 31881ad6265SDimitry Andric {"atmega1609", "avrxmega3", "avrxmega3", 0x803800}, 31981ad6265SDimitry Andric {"atmega3208", "avrxmega3", "avrxmega3", 0x803000}, 32081ad6265SDimitry Andric {"atmega3209", "avrxmega3", "avrxmega3", 0x803000}, 32181ad6265SDimitry Andric {"atmega4808", "avrxmega3", "avrxmega3", 0x802800}, 32281ad6265SDimitry Andric {"atmega4809", "avrxmega3", "avrxmega3", 0x802800}, 32381ad6265SDimitry Andric {"attiny1604", "avrxmega3", "avrxmega3", 0x803C00}, 32481ad6265SDimitry Andric {"attiny1606", "avrxmega3", "avrxmega3", 0x803C00}, 32581ad6265SDimitry Andric {"attiny1607", "avrxmega3", "avrxmega3", 0x803C00}, 32681ad6265SDimitry Andric {"attiny1614", "avrxmega3", "avrxmega3", 0x803800}, 32781ad6265SDimitry Andric {"attiny1616", "avrxmega3", "avrxmega3", 0x803800}, 32881ad6265SDimitry Andric {"attiny1617", "avrxmega3", "avrxmega3", 0x803800}, 32981ad6265SDimitry Andric {"attiny1624", "avrxmega3", "avrxmega3", 0x803800}, 33081ad6265SDimitry Andric {"attiny1626", "avrxmega3", "avrxmega3", 0x803800}, 33181ad6265SDimitry Andric {"attiny1627", "avrxmega3", "avrxmega3", 0x803800}, 33281ad6265SDimitry Andric {"attiny3216", "avrxmega3", "avrxmega3", 0x803800}, 33381ad6265SDimitry Andric {"attiny3217", "avrxmega3", "avrxmega3", 0x803800}, 334e8d8bef9SDimitry Andric }; 335e8d8bef9SDimitry Andric 336e8d8bef9SDimitry Andric std::string GetMCUSubPath(StringRef MCUName) { 337e8d8bef9SDimitry Andric for (const auto &MCU : MCUInfo) 338e8d8bef9SDimitry Andric if (MCU.Name == MCUName) 339e8d8bef9SDimitry Andric return std::string(MCU.SubPath); 340e8d8bef9SDimitry Andric return ""; 341e8d8bef9SDimitry Andric } 342e8d8bef9SDimitry Andric 343bdd1243dSDimitry Andric std::optional<StringRef> GetMCUFamilyName(StringRef MCUName) { 344e8d8bef9SDimitry Andric for (const auto &MCU : MCUInfo) 345e8d8bef9SDimitry Andric if (MCU.Name == MCUName) 346bdd1243dSDimitry Andric return std::optional<StringRef>(MCU.Family); 347bdd1243dSDimitry Andric return std::nullopt; 348e8d8bef9SDimitry Andric } 349e8d8bef9SDimitry Andric 350bdd1243dSDimitry Andric std::optional<unsigned> GetMCUSectionAddressData(StringRef MCUName) { 351fe6060f1SDimitry Andric for (const auto &MCU : MCUInfo) 352fe6060f1SDimitry Andric if (MCU.Name == MCUName && MCU.DataAddr > 0) 353bdd1243dSDimitry Andric return std::optional<unsigned>(MCU.DataAddr); 354bdd1243dSDimitry Andric return std::nullopt; 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric const StringRef PossibleAVRLibcLocations[] = { 358349cc55cSDimitry Andric "/avr", 3590b57cec5SDimitry Andric "/usr/avr", 3600b57cec5SDimitry Andric "/usr/lib/avr", 3610b57cec5SDimitry Andric }; 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric } // end anonymous namespace 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric /// AVR Toolchain 3660b57cec5SDimitry Andric AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple, 3670b57cec5SDimitry Andric const ArgList &Args) 36881ad6265SDimitry Andric : Generic_ELF(D, Triple, Args) { 3690b57cec5SDimitry Andric GCCInstallation.init(Triple, Args); 3700b57cec5SDimitry Andric 371bdd1243dSDimitry Andric if (getCPUName(D, Args, Triple).empty()) 37281ad6265SDimitry Andric D.Diag(diag::warn_drv_avr_mcu_not_specified); 37381ad6265SDimitry Andric 3740b57cec5SDimitry Andric // Only add default libraries if the user hasn't explicitly opted out. 3750b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib) && 37681ad6265SDimitry Andric !Args.hasArg(options::OPT_nodefaultlibs) && GCCInstallation.isValid()) { 37781ad6265SDimitry Andric GCCInstallPath = GCCInstallation.getInstallPath(); 378fe6060f1SDimitry Andric std::string GCCParentPath(GCCInstallation.getParentLibPath()); 379fe6060f1SDimitry Andric getProgramPaths().push_back(GCCParentPath + "/../bin"); 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 383fe6060f1SDimitry Andric void AVRToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 384fe6060f1SDimitry Andric ArgStringList &CC1Args) const { 385fe6060f1SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdinc) || 386fe6060f1SDimitry Andric DriverArgs.hasArg(options::OPT_nostdlibinc)) 387fe6060f1SDimitry Andric return; 388fe6060f1SDimitry Andric 389fe6060f1SDimitry Andric // Omit if there is no avr-libc installed. 390bdd1243dSDimitry Andric std::optional<std::string> AVRLibcRoot = findAVRLibcInstallation(); 39181ad6265SDimitry Andric if (!AVRLibcRoot) 392fe6060f1SDimitry Andric return; 393fe6060f1SDimitry Andric 394fe6060f1SDimitry Andric // Add 'avr-libc/include' to clang system include paths if applicable. 39581ad6265SDimitry Andric std::string AVRInc = *AVRLibcRoot + "/include"; 396fe6060f1SDimitry Andric if (llvm::sys::fs::is_directory(AVRInc)) 397fe6060f1SDimitry Andric addSystemInclude(DriverArgs, CC1Args, AVRInc); 398fe6060f1SDimitry Andric } 399fe6060f1SDimitry Andric 400349cc55cSDimitry Andric void AVRToolChain::addClangTargetOptions( 401349cc55cSDimitry Andric const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, 402349cc55cSDimitry Andric Action::OffloadKind DeviceOffloadKind) const { 403349cc55cSDimitry Andric // By default, use `.ctors` (not `.init_array`), as required by libgcc, which 404349cc55cSDimitry Andric // runs constructors/destructors on AVR. 405349cc55cSDimitry Andric if (!DriverArgs.hasFlag(options::OPT_fuse_init_array, 406349cc55cSDimitry Andric options::OPT_fno_use_init_array, false)) 407349cc55cSDimitry Andric CC1Args.push_back("-fno-use-init-array"); 4081fd87a68SDimitry Andric // Use `-fno-use-cxa-atexit` as default, since avr-libc does not support 4091fd87a68SDimitry Andric // `__cxa_atexit()`. 4101fd87a68SDimitry Andric if (!DriverArgs.hasFlag(options::OPT_fuse_cxa_atexit, 4111fd87a68SDimitry Andric options::OPT_fno_use_cxa_atexit, false)) 4121fd87a68SDimitry Andric CC1Args.push_back("-fno-use-cxa-atexit"); 413349cc55cSDimitry Andric } 414349cc55cSDimitry Andric 4150b57cec5SDimitry Andric Tool *AVRToolChain::buildLinker() const { 41681ad6265SDimitry Andric return new tools::AVR::Linker(getTriple(), *this); 4170b57cec5SDimitry Andric } 4180b57cec5SDimitry Andric 419bdd1243dSDimitry Andric std::string 420bdd1243dSDimitry Andric AVRToolChain::getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, 421bdd1243dSDimitry Andric FileType Type = ToolChain::FT_Static) const { 422bdd1243dSDimitry Andric assert(Type == ToolChain::FT_Static && "AVR only supports static libraries"); 423bdd1243dSDimitry Andric // Since AVR can never be a host environment, its compiler-rt library files 424bdd1243dSDimitry Andric // should always have ".a" suffix, even on windows. 425bdd1243dSDimitry Andric SmallString<32> File("/libclang_rt."); 426bdd1243dSDimitry Andric File += Component.str(); 427bdd1243dSDimitry Andric File += ".a"; 428bdd1243dSDimitry Andric // Return the default compiler-rt path appended with 429bdd1243dSDimitry Andric // "avr/libclang_rt.$COMPONENT.a". 430bdd1243dSDimitry Andric SmallString<256> Path(ToolChain::getCompilerRTPath()); 431bdd1243dSDimitry Andric llvm::sys::path::append(Path, "avr"); 432bdd1243dSDimitry Andric llvm::sys::path::append(Path, File.str()); 433*7a6dacacSDimitry Andric return std::string(Path); 434bdd1243dSDimitry Andric } 435bdd1243dSDimitry Andric 4360b57cec5SDimitry Andric void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, 4370b57cec5SDimitry Andric const InputInfo &Output, 438e8d8bef9SDimitry Andric const InputInfoList &Inputs, const ArgList &Args, 4390b57cec5SDimitry Andric const char *LinkingOutput) const { 44081ad6265SDimitry Andric const auto &TC = static_cast<const AVRToolChain &>(getToolChain()); 441349cc55cSDimitry Andric const Driver &D = getToolChain().getDriver(); 442349cc55cSDimitry Andric 4430b57cec5SDimitry Andric // Compute information about the target AVR. 444349cc55cSDimitry Andric std::string CPU = getCPUName(D, Args, getToolChain().getTriple()); 445bdd1243dSDimitry Andric std::optional<StringRef> FamilyName = GetMCUFamilyName(CPU); 446bdd1243dSDimitry Andric std::optional<std::string> AVRLibcRoot = TC.findAVRLibcInstallation(); 447bdd1243dSDimitry Andric std::optional<unsigned> SectionAddressData = GetMCUSectionAddressData(CPU); 4480b57cec5SDimitry Andric 44981ad6265SDimitry Andric // Compute the linker program path, and use GNU "avr-ld" as default. 45081ad6265SDimitry Andric const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ); 45181ad6265SDimitry Andric std::string Linker = A ? getToolChain().GetLinkerPath(nullptr) 45281ad6265SDimitry Andric : getToolChain().GetProgramPath(getShortName()); 45381ad6265SDimitry Andric 4540b57cec5SDimitry Andric ArgStringList CmdArgs; 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric CmdArgs.push_back("-o"); 4570b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric // Enable garbage collection of unused sections. 4605f757f3fSDimitry Andric if (!Args.hasArg(options::OPT_r)) 4610b57cec5SDimitry Andric CmdArgs.push_back("--gc-sections"); 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric // Add library search paths before we specify libraries. 4640b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_L); 4650b57cec5SDimitry Andric getToolChain().AddFilePathLibArgs(Args, CmdArgs); 4660b57cec5SDimitry Andric 467bdd1243dSDimitry Andric // Currently we only support libgcc and compiler-rt. 468bdd1243dSDimitry Andric auto RtLib = TC.GetRuntimeLibType(Args); 469bdd1243dSDimitry Andric assert( 470bdd1243dSDimitry Andric (RtLib == ToolChain::RLT_Libgcc || RtLib == ToolChain::RLT_CompilerRT) && 471bdd1243dSDimitry Andric "unknown runtime library"); 472bdd1243dSDimitry Andric 47381ad6265SDimitry Andric // Only add default libraries if the user hasn't explicitly opted out. 47481ad6265SDimitry Andric bool LinkStdlib = false; 4755f757f3fSDimitry Andric if (!Args.hasArg(options::OPT_nostdlib) && !Args.hasArg(options::OPT_r) && 47681ad6265SDimitry Andric !Args.hasArg(options::OPT_nodefaultlibs)) { 47781ad6265SDimitry Andric if (!CPU.empty()) { 47881ad6265SDimitry Andric if (!FamilyName) { 47981ad6265SDimitry Andric // We do not have an entry for this CPU in the family 48081ad6265SDimitry Andric // mapping table yet. 48181ad6265SDimitry Andric D.Diag(diag::warn_drv_avr_family_linking_stdlibs_not_implemented) 48281ad6265SDimitry Andric << CPU; 48381ad6265SDimitry Andric } else if (!AVRLibcRoot) { 48481ad6265SDimitry Andric // No avr-libc found and so no runtime linked. 48581ad6265SDimitry Andric D.Diag(diag::warn_drv_avr_libc_not_found); 48681ad6265SDimitry Andric } else { 48781ad6265SDimitry Andric std::string SubPath = GetMCUSubPath(CPU); 488bdd1243dSDimitry Andric // Add path of avr-libc. 48981ad6265SDimitry Andric CmdArgs.push_back( 49081ad6265SDimitry Andric Args.MakeArgString(Twine("-L") + *AVRLibcRoot + "/lib/" + SubPath)); 491bdd1243dSDimitry Andric if (RtLib == ToolChain::RLT_Libgcc) 492bdd1243dSDimitry Andric CmdArgs.push_back(Args.MakeArgString("-L" + TC.getGCCInstallPath() + 493bdd1243dSDimitry Andric "/" + SubPath)); 49481ad6265SDimitry Andric LinkStdlib = true; 49581ad6265SDimitry Andric } 49681ad6265SDimitry Andric } 49781ad6265SDimitry Andric if (!LinkStdlib) 49881ad6265SDimitry Andric D.Diag(diag::warn_drv_avr_stdlib_not_linked); 49981ad6265SDimitry Andric } 50081ad6265SDimitry Andric 5015f757f3fSDimitry Andric if (!Args.hasArg(options::OPT_r)) { 50281ad6265SDimitry Andric if (SectionAddressData) { 50306c3fb27SDimitry Andric CmdArgs.push_back( 50406c3fb27SDimitry Andric Args.MakeArgString("--defsym=__DATA_REGION_ORIGIN__=0x" + 50506c3fb27SDimitry Andric Twine::utohexstr(*SectionAddressData))); 506e8d8bef9SDimitry Andric } else { 5075f757f3fSDimitry Andric // We do not have an entry for this CPU in the address mapping table 5085f757f3fSDimitry Andric // yet. 5095f757f3fSDimitry Andric D.Diag(diag::warn_drv_avr_linker_section_addresses_not_implemented) 5105f757f3fSDimitry Andric << CPU; 5115f757f3fSDimitry Andric } 512e8d8bef9SDimitry Andric } 513e8d8bef9SDimitry Andric 51406c3fb27SDimitry Andric if (D.isUsingLTO()) { 51506c3fb27SDimitry Andric assert(!Inputs.empty() && "Must have at least one input."); 5165f757f3fSDimitry Andric // Find the first filename InputInfo object. 5175f757f3fSDimitry Andric auto Input = llvm::find_if( 5185f757f3fSDimitry Andric Inputs, [](const InputInfo &II) -> bool { return II.isFilename(); }); 5195f757f3fSDimitry Andric if (Input == Inputs.end()) 5205f757f3fSDimitry Andric // For a very rare case, all of the inputs to the linker are 5215f757f3fSDimitry Andric // InputArg. If that happens, just use the first InputInfo. 5225f757f3fSDimitry Andric Input = Inputs.begin(); 5235f757f3fSDimitry Andric 5245f757f3fSDimitry Andric addLTOOptions(TC, Args, CmdArgs, Output, *Input, 52506c3fb27SDimitry Andric D.getLTOMode() == LTOK_Thin); 52606c3fb27SDimitry Andric } 52706c3fb27SDimitry Andric 5280b57cec5SDimitry Andric // If the family name is known, we can link with the device-specific libgcc. 5290b57cec5SDimitry Andric // Without it, libgcc will simply not be linked. This matches avr-gcc 5300b57cec5SDimitry Andric // behavior. 5310b57cec5SDimitry Andric if (LinkStdlib) { 5320b57cec5SDimitry Andric assert(!CPU.empty() && "CPU name must be known in order to link stdlibs"); 5330b57cec5SDimitry Andric 534349cc55cSDimitry Andric CmdArgs.push_back("--start-group"); 535349cc55cSDimitry Andric 5360b57cec5SDimitry Andric // Add the object file for the CRT. 5370b57cec5SDimitry Andric std::string CrtFileName = std::string("-l:crt") + CPU + std::string(".o"); 5380b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(CrtFileName)); 5390b57cec5SDimitry Andric 540bdd1243dSDimitry Andric // Link to libgcc. 541bdd1243dSDimitry Andric if (RtLib == ToolChain::RLT_Libgcc) 5420b57cec5SDimitry Andric CmdArgs.push_back("-lgcc"); 543bdd1243dSDimitry Andric 544bdd1243dSDimitry Andric // Link to generic libraries of avr-libc. 5450b57cec5SDimitry Andric CmdArgs.push_back("-lm"); 5460b57cec5SDimitry Andric CmdArgs.push_back("-lc"); 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric // Add the link library specific to the MCU. 5490b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(std::string("-l") + CPU)); 5500b57cec5SDimitry Andric 551bdd1243dSDimitry Andric // Add the relocatable inputs. 552753f127fSDimitry Andric AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); 553bdd1243dSDimitry Andric 554bdd1243dSDimitry Andric // We directly use libclang_rt.builtins.a as input file, instead of using 555bdd1243dSDimitry Andric // '-lclang_rt.builtins'. 556bdd1243dSDimitry Andric if (RtLib == ToolChain::RLT_CompilerRT) { 557bdd1243dSDimitry Andric std::string RtLib = 558bdd1243dSDimitry Andric getToolChain().getCompilerRT(Args, "builtins", ToolChain::FT_Static); 559bdd1243dSDimitry Andric if (llvm::sys::fs::exists(RtLib)) 560bdd1243dSDimitry Andric CmdArgs.push_back(Args.MakeArgString(RtLib)); 561bdd1243dSDimitry Andric } 562bdd1243dSDimitry Andric 563349cc55cSDimitry Andric CmdArgs.push_back("--end-group"); 564349cc55cSDimitry Andric 5655f757f3fSDimitry Andric // Add avr-libc's linker script to lld by default, if it exists. 5665f757f3fSDimitry Andric if (!Args.hasArg(options::OPT_T) && 5675f757f3fSDimitry Andric Linker.find("avr-ld") == std::string::npos) { 5685f757f3fSDimitry Andric std::string Path(*AVRLibcRoot + "/lib/ldscripts/"); 5695f757f3fSDimitry Andric Path += *FamilyName; 5705f757f3fSDimitry Andric Path += ".x"; 5715f757f3fSDimitry Andric if (llvm::sys::fs::exists(Path)) 5725f757f3fSDimitry Andric CmdArgs.push_back(Args.MakeArgString("-T" + Path)); 5735f757f3fSDimitry Andric } 5745f757f3fSDimitry Andric // Otherwise add user specified linker script to either avr-ld or lld. 5755f757f3fSDimitry Andric else 57681ad6265SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_T); 57781ad6265SDimitry Andric 57806c3fb27SDimitry Andric if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) 57906c3fb27SDimitry Andric CmdArgs.push_back("--relax"); 5805f757f3fSDimitry Andric } else { 5815f757f3fSDimitry Andric AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); 5825f757f3fSDimitry Andric } 58306c3fb27SDimitry Andric 5840b57cec5SDimitry Andric // Specify the family name as the emulation mode to use. 5850b57cec5SDimitry Andric // This is almost always required because otherwise avr-ld 5860b57cec5SDimitry Andric // will assume 'avr2' and warn about the program being larger 5870b57cec5SDimitry Andric // than the bare minimum supports. 5885f757f3fSDimitry Andric if (Linker.find("avr-ld") != std::string::npos && FamilyName) 5890b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); 5900b57cec5SDimitry Andric 591e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>( 592e8d8bef9SDimitry Andric JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker), 593e8d8bef9SDimitry Andric CmdArgs, Inputs, Output)); 5940b57cec5SDimitry Andric } 5950b57cec5SDimitry Andric 596bdd1243dSDimitry Andric std::optional<std::string> AVRToolChain::findAVRLibcInstallation() const { 597349cc55cSDimitry Andric // Search avr-libc installation according to avr-gcc installation. 598349cc55cSDimitry Andric std::string GCCParent(GCCInstallation.getParentLibPath()); 599349cc55cSDimitry Andric std::string Path(GCCParent + "/avr"); 600349cc55cSDimitry Andric if (llvm::sys::fs::is_directory(Path)) 601349cc55cSDimitry Andric return Path; 602349cc55cSDimitry Andric Path = GCCParent + "/../avr"; 603349cc55cSDimitry Andric if (llvm::sys::fs::is_directory(Path)) 604349cc55cSDimitry Andric return Path; 605349cc55cSDimitry Andric 606349cc55cSDimitry Andric // Search avr-libc installation from possible locations, and return the first 607349cc55cSDimitry Andric // one that exists, if there is no avr-gcc installed. 6080b57cec5SDimitry Andric for (StringRef PossiblePath : PossibleAVRLibcLocations) { 609fe6060f1SDimitry Andric std::string Path = getDriver().SysRoot + PossiblePath.str(); 610fe6060f1SDimitry Andric if (llvm::sys::fs::is_directory(Path)) 611349cc55cSDimitry Andric return Path; 6120b57cec5SDimitry Andric } 6130b57cec5SDimitry Andric 614bdd1243dSDimitry Andric return std::nullopt; 6150b57cec5SDimitry Andric } 616