10b57cec5SDimitry Andric //===--- PS4CPU.cpp - PS4CPU 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 "PS4CPU.h" 100b57cec5SDimitry Andric #include "CommonArgs.h" 11*06c3fb27SDimitry Andric #include "clang/Config/config.h" 120b57cec5SDimitry Andric #include "clang/Driver/Compilation.h" 130b57cec5SDimitry Andric #include "clang/Driver/Driver.h" 140b57cec5SDimitry Andric #include "clang/Driver/DriverDiagnostic.h" 150b57cec5SDimitry Andric #include "clang/Driver/Options.h" 160b57cec5SDimitry Andric #include "clang/Driver/SanitizerArgs.h" 170b57cec5SDimitry Andric #include "llvm/Option/ArgList.h" 180b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 190b57cec5SDimitry Andric #include "llvm/Support/Path.h" 200b57cec5SDimitry Andric #include <cstdlib> // ::getenv 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric using namespace clang::driver; 230b57cec5SDimitry Andric using namespace clang; 240b57cec5SDimitry Andric using namespace llvm::opt; 250b57cec5SDimitry Andric 2681ad6265SDimitry Andric // Helper to paste bits of an option together and return a saved string. 2781ad6265SDimitry Andric static const char *makeArgString(const ArgList &Args, const char *Prefix, 2881ad6265SDimitry Andric const char *Base, const char *Suffix) { 2981ad6265SDimitry Andric // Basically "Prefix + Base + Suffix" all converted to Twine then saved. 3081ad6265SDimitry Andric return Args.MakeArgString(Twine(StringRef(Prefix), Base) + Suffix); 3181ad6265SDimitry Andric } 3281ad6265SDimitry Andric 3381ad6265SDimitry Andric void tools::PScpu::addProfileRTArgs(const ToolChain &TC, const ArgList &Args, 340b57cec5SDimitry Andric ArgStringList &CmdArgs) { 3581ad6265SDimitry Andric assert(TC.getTriple().isPS()); 3681ad6265SDimitry Andric auto &PSTC = static_cast<const toolchains::PS4PS5Base &>(TC); 3781ad6265SDimitry Andric 380b57cec5SDimitry Andric if ((Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, 390b57cec5SDimitry Andric false) || 400b57cec5SDimitry Andric Args.hasFlag(options::OPT_fprofile_generate, 415ffd83dbSDimitry Andric options::OPT_fno_profile_generate, false) || 420b57cec5SDimitry Andric Args.hasFlag(options::OPT_fprofile_generate_EQ, 435ffd83dbSDimitry Andric options::OPT_fno_profile_generate, false) || 440b57cec5SDimitry Andric Args.hasFlag(options::OPT_fprofile_instr_generate, 450b57cec5SDimitry Andric options::OPT_fno_profile_instr_generate, false) || 460b57cec5SDimitry Andric Args.hasFlag(options::OPT_fprofile_instr_generate_EQ, 470b57cec5SDimitry Andric options::OPT_fno_profile_instr_generate, false) || 485ffd83dbSDimitry Andric Args.hasFlag(options::OPT_fcs_profile_generate, 495ffd83dbSDimitry Andric options::OPT_fno_profile_generate, false) || 505ffd83dbSDimitry Andric Args.hasFlag(options::OPT_fcs_profile_generate_EQ, 515ffd83dbSDimitry Andric options::OPT_fno_profile_generate, false) || 520b57cec5SDimitry Andric Args.hasArg(options::OPT_fcreate_profile) || 530b57cec5SDimitry Andric Args.hasArg(options::OPT_coverage))) 5481ad6265SDimitry Andric CmdArgs.push_back(makeArgString( 5581ad6265SDimitry Andric Args, "--dependent-lib=", PSTC.getProfileRTLibName(), "")); 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric 5881ad6265SDimitry Andric void tools::PScpu::Assembler::ConstructJob(Compilation &C, const JobAction &JA, 590b57cec5SDimitry Andric const InputInfo &Output, 600b57cec5SDimitry Andric const InputInfoList &Inputs, 610b57cec5SDimitry Andric const ArgList &Args, 620b57cec5SDimitry Andric const char *LinkingOutput) const { 6381ad6265SDimitry Andric auto &TC = static_cast<const toolchains::PS4PS5Base &>(getToolChain()); 640b57cec5SDimitry Andric claimNoWarnArgs(Args); 650b57cec5SDimitry Andric ArgStringList CmdArgs; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric CmdArgs.push_back("-o"); 700b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric assert(Inputs.size() == 1 && "Unexpected number of inputs."); 730b57cec5SDimitry Andric const InputInfo &Input = Inputs[0]; 740b57cec5SDimitry Andric assert(Input.isFilename() && "Invalid input."); 750b57cec5SDimitry Andric CmdArgs.push_back(Input.getFilename()); 760b57cec5SDimitry Andric 7781ad6265SDimitry Andric std::string AsName = TC.qualifyPSCmdName("as"); 7881ad6265SDimitry Andric const char *Exec = Args.MakeArgString(TC.GetProgramPath(AsName.c_str())); 79e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 80e8d8bef9SDimitry Andric ResponseFileSupport::AtFileUTF8(), 81e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric 8481ad6265SDimitry Andric void tools::PScpu::addSanitizerArgs(const ToolChain &TC, const ArgList &Args, 85349cc55cSDimitry Andric ArgStringList &CmdArgs) { 8681ad6265SDimitry Andric assert(TC.getTriple().isPS()); 8781ad6265SDimitry Andric auto &PSTC = static_cast<const toolchains::PS4PS5Base &>(TC); 8881ad6265SDimitry Andric PSTC.addSanitizerArgs(Args, CmdArgs, "--dependent-lib=lib", ".a"); 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 9181ad6265SDimitry Andric void toolchains::PS4CPU::addSanitizerArgs(const ArgList &Args, 9281ad6265SDimitry Andric ArgStringList &CmdArgs, 9381ad6265SDimitry Andric const char *Prefix, 9481ad6265SDimitry Andric const char *Suffix) const { 9581ad6265SDimitry Andric auto arg = [&](const char *Name) -> const char * { 9681ad6265SDimitry Andric return makeArgString(Args, Prefix, Name, Suffix); 9781ad6265SDimitry Andric }; 9881ad6265SDimitry Andric const SanitizerArgs &SanArgs = getSanitizerArgs(Args); 990b57cec5SDimitry Andric if (SanArgs.needsUbsanRt()) 10081ad6265SDimitry Andric CmdArgs.push_back(arg("SceDbgUBSanitizer_stub_weak")); 1010b57cec5SDimitry Andric if (SanArgs.needsAsanRt()) 10281ad6265SDimitry Andric CmdArgs.push_back(arg("SceDbgAddressSanitizer_stub_weak")); 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 10581ad6265SDimitry Andric void toolchains::PS5CPU::addSanitizerArgs(const ArgList &Args, 10681ad6265SDimitry Andric ArgStringList &CmdArgs, 10781ad6265SDimitry Andric const char *Prefix, 10881ad6265SDimitry Andric const char *Suffix) const { 10981ad6265SDimitry Andric auto arg = [&](const char *Name) -> const char * { 11081ad6265SDimitry Andric return makeArgString(Args, Prefix, Name, Suffix); 11181ad6265SDimitry Andric }; 11281ad6265SDimitry Andric const SanitizerArgs &SanArgs = getSanitizerArgs(Args); 11381ad6265SDimitry Andric if (SanArgs.needsUbsanRt()) 11481ad6265SDimitry Andric CmdArgs.push_back(arg("SceUBSanitizer_nosubmission_stub_weak")); 11581ad6265SDimitry Andric if (SanArgs.needsAsanRt()) 11681ad6265SDimitry Andric CmdArgs.push_back(arg("SceAddressSanitizer_nosubmission_stub_weak")); 11781ad6265SDimitry Andric if (SanArgs.needsTsanRt()) 11881ad6265SDimitry Andric CmdArgs.push_back(arg("SceThreadSanitizer_nosubmission_stub_weak")); 11981ad6265SDimitry Andric } 12081ad6265SDimitry Andric 12181ad6265SDimitry Andric void tools::PScpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, 1225ffd83dbSDimitry Andric const InputInfo &Output, 1230b57cec5SDimitry Andric const InputInfoList &Inputs, 1240b57cec5SDimitry Andric const ArgList &Args, 1255ffd83dbSDimitry Andric const char *LinkingOutput) const { 12681ad6265SDimitry Andric auto &TC = static_cast<const toolchains::PS4PS5Base &>(getToolChain()); 12781ad6265SDimitry Andric const Driver &D = TC.getDriver(); 1280b57cec5SDimitry Andric ArgStringList CmdArgs; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric // Silence warning for "clang -g foo.o -o foo" 1310b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_g_Group); 1320b57cec5SDimitry Andric // and "clang -emit-llvm foo.o -o foo" 1330b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_emit_llvm); 1340b57cec5SDimitry Andric // and for "clang -w foo.o -o foo". Other warning options are already 1350b57cec5SDimitry Andric // handled somewhere else. 1360b57cec5SDimitry Andric Args.ClaimAllArgs(options::OPT_w); 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric if (!D.SysRoot.empty()) 1390b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pie)) 1420b57cec5SDimitry Andric CmdArgs.push_back("-pie"); 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric if (Args.hasArg(options::OPT_rdynamic)) 1450b57cec5SDimitry Andric CmdArgs.push_back("-export-dynamic"); 1460b57cec5SDimitry Andric if (Args.hasArg(options::OPT_shared)) 14781ad6265SDimitry Andric CmdArgs.push_back("--shared"); 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric if (Output.isFilename()) { 1500b57cec5SDimitry Andric CmdArgs.push_back("-o"); 1510b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 1520b57cec5SDimitry Andric } else { 1530b57cec5SDimitry Andric assert(Output.isNothing() && "Invalid output."); 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric 156bdd1243dSDimitry Andric const bool UseLTO = D.isUsingLTO(); 157bdd1243dSDimitry Andric const bool UseJMC = 158bdd1243dSDimitry Andric Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false); 159bdd1243dSDimitry Andric const bool IsPS4 = TC.getTriple().isPS4(); 160bdd1243dSDimitry Andric const bool IsPS5 = TC.getTriple().isPS5(); 161bdd1243dSDimitry Andric assert(IsPS4 || IsPS5); 162bdd1243dSDimitry Andric 163*06c3fb27SDimitry Andric const char *PS4LTOArgs = ""; 164bdd1243dSDimitry Andric auto AddCodeGenFlag = [&](Twine Flag) { 165*06c3fb27SDimitry Andric if (IsPS4) 166*06c3fb27SDimitry Andric PS4LTOArgs = Args.MakeArgString(Twine(PS4LTOArgs) + " " + Flag); 167bdd1243dSDimitry Andric else if (IsPS5) 168*06c3fb27SDimitry Andric CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=") + Flag)); 169bdd1243dSDimitry Andric }; 170bdd1243dSDimitry Andric 171bdd1243dSDimitry Andric if (UseLTO) { 172bdd1243dSDimitry Andric // We default to creating the arange section, but LTO does not. Enable it 173bdd1243dSDimitry Andric // here. 174bdd1243dSDimitry Andric AddCodeGenFlag("-generate-arange-section"); 175bdd1243dSDimitry Andric 176bdd1243dSDimitry Andric // This tells LTO to perform JustMyCode instrumentation. 177bdd1243dSDimitry Andric if (UseJMC) 178bdd1243dSDimitry Andric AddCodeGenFlag("-enable-jmc-instrument"); 179bdd1243dSDimitry Andric 180bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir)) 181bdd1243dSDimitry Andric AddCodeGenFlag(Twine("-crash-diagnostics-dir=") + A->getValue()); 182*06c3fb27SDimitry Andric 183*06c3fb27SDimitry Andric StringRef Parallelism = getLTOParallelism(Args, D); 184*06c3fb27SDimitry Andric if (!Parallelism.empty()) { 185*06c3fb27SDimitry Andric if (IsPS4) 186*06c3fb27SDimitry Andric AddCodeGenFlag(Twine("-threads=") + Parallelism); 187*06c3fb27SDimitry Andric else 188*06c3fb27SDimitry Andric CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=jobs=") + Parallelism)); 189*06c3fb27SDimitry Andric } 190*06c3fb27SDimitry Andric 191*06c3fb27SDimitry Andric if (IsPS4) { 192*06c3fb27SDimitry Andric const char *Prefix = nullptr; 193*06c3fb27SDimitry Andric if (D.getLTOMode() == LTOK_Thin) 194*06c3fb27SDimitry Andric Prefix = "-lto-thin-debug-options="; 195*06c3fb27SDimitry Andric else if (D.getLTOMode() == LTOK_Full) 196*06c3fb27SDimitry Andric Prefix = "-lto-debug-options="; 197*06c3fb27SDimitry Andric else 198*06c3fb27SDimitry Andric llvm_unreachable("new LTO mode?"); 199*06c3fb27SDimitry Andric 200*06c3fb27SDimitry Andric CmdArgs.push_back(Args.MakeArgString(Twine(Prefix) + PS4LTOArgs)); 201*06c3fb27SDimitry Andric } 202bdd1243dSDimitry Andric } 203bdd1243dSDimitry Andric 2040b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) 20581ad6265SDimitry Andric TC.addSanitizerArgs(Args, CmdArgs, "-l", ""); 2060b57cec5SDimitry Andric 207*06c3fb27SDimitry Andric if (D.isUsingLTO() && Args.hasArg(options::OPT_funified_lto)) { 208*06c3fb27SDimitry Andric if (D.getLTOMode() == LTOK_Thin) 209*06c3fb27SDimitry Andric CmdArgs.push_back("--lto=thin"); 210*06c3fb27SDimitry Andric else if (D.getLTOMode() == LTOK_Full) 211*06c3fb27SDimitry Andric CmdArgs.push_back("--lto=full"); 212*06c3fb27SDimitry Andric } 213*06c3fb27SDimitry Andric 2140b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_L); 2150b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_T_Group); 2160b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_s); 2170b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_t); 2180b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_r); 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) 2210b57cec5SDimitry Andric CmdArgs.push_back("--no-demangle"); 2220b57cec5SDimitry Andric 22381ad6265SDimitry Andric AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pthread)) { 2260b57cec5SDimitry Andric CmdArgs.push_back("-lpthread"); 2270b57cec5SDimitry Andric } 2280b57cec5SDimitry Andric 229bdd1243dSDimitry Andric if (UseJMC) { 230bdd1243dSDimitry Andric CmdArgs.push_back("--whole-archive"); 231bdd1243dSDimitry Andric if (IsPS4) 232bdd1243dSDimitry Andric CmdArgs.push_back("-lSceDbgJmc"); 233bdd1243dSDimitry Andric else 234bdd1243dSDimitry Andric CmdArgs.push_back("-lSceJmc_nosubmission"); 235bdd1243dSDimitry Andric CmdArgs.push_back("--no-whole-archive"); 236bdd1243dSDimitry Andric } 237bdd1243dSDimitry Andric 2385ffd83dbSDimitry Andric if (Args.hasArg(options::OPT_fuse_ld_EQ)) { 2395ffd83dbSDimitry Andric D.Diag(diag::err_drv_unsupported_opt_for_target) 24081ad6265SDimitry Andric << "-fuse-ld" << TC.getTriple().str(); 2410b57cec5SDimitry Andric } 2420b57cec5SDimitry Andric 24381ad6265SDimitry Andric std::string LdName = TC.qualifyPSCmdName(TC.getLinkerBaseName()); 24481ad6265SDimitry Andric const char *Exec = Args.MakeArgString(TC.GetProgramPath(LdName.c_str())); 2450b57cec5SDimitry Andric 246e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 247e8d8bef9SDimitry Andric ResponseFileSupport::AtFileUTF8(), 248e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric 25181ad6265SDimitry Andric toolchains::PS4PS5Base::PS4PS5Base(const Driver &D, const llvm::Triple &Triple, 25281ad6265SDimitry Andric const ArgList &Args, StringRef Platform, 25381ad6265SDimitry Andric const char *EnvVar) 2540b57cec5SDimitry Andric : Generic_ELF(D, Triple, Args) { 2550b57cec5SDimitry Andric if (Args.hasArg(clang::driver::options::OPT_static)) 25681ad6265SDimitry Andric D.Diag(clang::diag::err_drv_unsupported_opt_for_target) 25781ad6265SDimitry Andric << "-static" << Platform; 2580b57cec5SDimitry Andric 259*06c3fb27SDimitry Andric // Determine where to find the PS4/PS5 libraries. 260*06c3fb27SDimitry Andric // If -isysroot was passed, use that as the SDK base path. 261*06c3fb27SDimitry Andric // If not, we use the EnvVar if it exists; otherwise use the driver's 262*06c3fb27SDimitry Andric // installation path, which should be <SDK_DIR>/host_tools/bin. 263*06c3fb27SDimitry Andric SmallString<80> Whence; 264*06c3fb27SDimitry Andric if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 265*06c3fb27SDimitry Andric SDKRootDir = A->getValue(); 266*06c3fb27SDimitry Andric if (!llvm::sys::fs::exists(SDKRootDir)) 267*06c3fb27SDimitry Andric D.Diag(clang::diag::warn_missing_sysroot) << SDKRootDir; 268*06c3fb27SDimitry Andric Whence = A->getSpelling(); 269*06c3fb27SDimitry Andric } else if (const char *EnvValue = getenv(EnvVar)) { 270*06c3fb27SDimitry Andric SDKRootDir = EnvValue; 271*06c3fb27SDimitry Andric Whence = { "environment variable '", EnvVar, "'" }; 2720b57cec5SDimitry Andric } else { 273*06c3fb27SDimitry Andric SDKRootDir = D.Dir + "/../../"; 274*06c3fb27SDimitry Andric Whence = "compiler's location"; 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 277*06c3fb27SDimitry Andric SmallString<512> SDKIncludeDir(SDKRootDir); 27881ad6265SDimitry Andric llvm::sys::path::append(SDKIncludeDir, "target/include"); 2790b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdinc) && 2800b57cec5SDimitry Andric !Args.hasArg(options::OPT_nostdlibinc) && 2810b57cec5SDimitry Andric !Args.hasArg(options::OPT_isysroot) && 2820b57cec5SDimitry Andric !Args.hasArg(options::OPT__sysroot_EQ) && 28381ad6265SDimitry Andric !llvm::sys::fs::exists(SDKIncludeDir)) { 28481ad6265SDimitry Andric D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected) 285*06c3fb27SDimitry Andric << Twine(Platform, " system headers").str() << SDKIncludeDir << Whence; 2860b57cec5SDimitry Andric } 2870b57cec5SDimitry Andric 288*06c3fb27SDimitry Andric SmallString<512> SDKLibDir(SDKRootDir); 28981ad6265SDimitry Andric llvm::sys::path::append(SDKLibDir, "target/lib"); 2900b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib) && 2910b57cec5SDimitry Andric !Args.hasArg(options::OPT_nodefaultlibs) && 2920b57cec5SDimitry Andric !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) && 2930b57cec5SDimitry Andric !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) && 2940b57cec5SDimitry Andric !Args.hasArg(options::OPT_emit_ast) && 29581ad6265SDimitry Andric !llvm::sys::fs::exists(SDKLibDir)) { 29681ad6265SDimitry Andric D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected) 297*06c3fb27SDimitry Andric << Twine(Platform, " system libraries").str() << SDKLibDir << Whence; 2980b57cec5SDimitry Andric return; 2990b57cec5SDimitry Andric } 30081ad6265SDimitry Andric getFilePaths().push_back(std::string(SDKLibDir.str())); 3010b57cec5SDimitry Andric } 3020b57cec5SDimitry Andric 303*06c3fb27SDimitry Andric void toolchains::PS4PS5Base::AddClangSystemIncludeArgs( 304*06c3fb27SDimitry Andric const ArgList &DriverArgs, 305*06c3fb27SDimitry Andric ArgStringList &CC1Args) const { 306*06c3fb27SDimitry Andric const Driver &D = getDriver(); 307*06c3fb27SDimitry Andric 308*06c3fb27SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdinc)) 309*06c3fb27SDimitry Andric return; 310*06c3fb27SDimitry Andric 311*06c3fb27SDimitry Andric if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 312*06c3fb27SDimitry Andric SmallString<128> Dir(D.ResourceDir); 313*06c3fb27SDimitry Andric llvm::sys::path::append(Dir, "include"); 314*06c3fb27SDimitry Andric addSystemInclude(DriverArgs, CC1Args, Dir.str()); 315*06c3fb27SDimitry Andric } 316*06c3fb27SDimitry Andric 317*06c3fb27SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 318*06c3fb27SDimitry Andric return; 319*06c3fb27SDimitry Andric 320*06c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, 321*06c3fb27SDimitry Andric SDKRootDir + "/target/include"); 322*06c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, 323*06c3fb27SDimitry Andric SDKRootDir + "/target/include_common"); 324*06c3fb27SDimitry Andric } 325*06c3fb27SDimitry Andric 3260b57cec5SDimitry Andric Tool *toolchains::PS4CPU::buildAssembler() const { 32781ad6265SDimitry Andric return new tools::PScpu::Assembler(*this); 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 33081ad6265SDimitry Andric Tool *toolchains::PS5CPU::buildAssembler() const { 33181ad6265SDimitry Andric // PS5 does not support an external assembler. 33281ad6265SDimitry Andric getDriver().Diag(clang::diag::err_no_external_assembler); 33381ad6265SDimitry Andric return nullptr; 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric 33681ad6265SDimitry Andric Tool *toolchains::PS4PS5Base::buildLinker() const { 33781ad6265SDimitry Andric return new tools::PScpu::Linker(*this); 33881ad6265SDimitry Andric } 3390b57cec5SDimitry Andric 34081ad6265SDimitry Andric SanitizerMask toolchains::PS4PS5Base::getSupportedSanitizers() const { 3410b57cec5SDimitry Andric SanitizerMask Res = ToolChain::getSupportedSanitizers(); 3420b57cec5SDimitry Andric Res |= SanitizerKind::Address; 3430b57cec5SDimitry Andric Res |= SanitizerKind::PointerCompare; 3440b57cec5SDimitry Andric Res |= SanitizerKind::PointerSubtract; 3450b57cec5SDimitry Andric Res |= SanitizerKind::Vptr; 3460b57cec5SDimitry Andric return Res; 3470b57cec5SDimitry Andric } 3485ffd83dbSDimitry Andric 34981ad6265SDimitry Andric SanitizerMask toolchains::PS5CPU::getSupportedSanitizers() const { 35081ad6265SDimitry Andric SanitizerMask Res = PS4PS5Base::getSupportedSanitizers(); 35181ad6265SDimitry Andric Res |= SanitizerKind::Thread; 35281ad6265SDimitry Andric return Res; 35381ad6265SDimitry Andric } 35481ad6265SDimitry Andric 35581ad6265SDimitry Andric void toolchains::PS4PS5Base::addClangTargetOptions( 356e8d8bef9SDimitry Andric const ArgList &DriverArgs, ArgStringList &CC1Args, 3575ffd83dbSDimitry Andric Action::OffloadKind DeviceOffloadingKind) const { 35881ad6265SDimitry Andric // PS4/PS5 do not use init arrays. 3595ffd83dbSDimitry Andric if (DriverArgs.hasArg(options::OPT_fuse_init_array)) { 3605ffd83dbSDimitry Andric Arg *A = DriverArgs.getLastArg(options::OPT_fuse_init_array); 3615ffd83dbSDimitry Andric getDriver().Diag(clang::diag::err_drv_unsupported_opt_for_target) 3625ffd83dbSDimitry Andric << A->getAsString(DriverArgs) << getTriple().str(); 3635ffd83dbSDimitry Andric } 3645ffd83dbSDimitry Andric 3655ffd83dbSDimitry Andric CC1Args.push_back("-fno-use-init-array"); 366e8d8bef9SDimitry Andric 367e8d8bef9SDimitry Andric const Arg *A = 368e8d8bef9SDimitry Andric DriverArgs.getLastArg(options::OPT_fvisibility_from_dllstorageclass, 369e8d8bef9SDimitry Andric options::OPT_fno_visibility_from_dllstorageclass); 370e8d8bef9SDimitry Andric if (!A || 371e8d8bef9SDimitry Andric A->getOption().matches(options::OPT_fvisibility_from_dllstorageclass)) { 372e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-from-dllstorageclass"); 373e8d8bef9SDimitry Andric 374e8d8bef9SDimitry Andric if (DriverArgs.hasArg(options::OPT_fvisibility_dllexport_EQ)) 375e8d8bef9SDimitry Andric DriverArgs.AddLastArg(CC1Args, options::OPT_fvisibility_dllexport_EQ); 376e8d8bef9SDimitry Andric else 377e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-dllexport=protected"); 378e8d8bef9SDimitry Andric 379e8d8bef9SDimitry Andric if (DriverArgs.hasArg(options::OPT_fvisibility_nodllstorageclass_EQ)) 380e8d8bef9SDimitry Andric DriverArgs.AddLastArg(CC1Args, 381e8d8bef9SDimitry Andric options::OPT_fvisibility_nodllstorageclass_EQ); 382e8d8bef9SDimitry Andric else 383e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-nodllstorageclass=hidden"); 384e8d8bef9SDimitry Andric 385e8d8bef9SDimitry Andric if (DriverArgs.hasArg(options::OPT_fvisibility_externs_dllimport_EQ)) 386e8d8bef9SDimitry Andric DriverArgs.AddLastArg(CC1Args, 387e8d8bef9SDimitry Andric options::OPT_fvisibility_externs_dllimport_EQ); 388e8d8bef9SDimitry Andric else 389e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-externs-dllimport=default"); 390e8d8bef9SDimitry Andric 391e8d8bef9SDimitry Andric if (DriverArgs.hasArg( 392e8d8bef9SDimitry Andric options::OPT_fvisibility_externs_nodllstorageclass_EQ)) 393e8d8bef9SDimitry Andric DriverArgs.AddLastArg( 394e8d8bef9SDimitry Andric CC1Args, options::OPT_fvisibility_externs_nodllstorageclass_EQ); 395e8d8bef9SDimitry Andric else 396e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-externs-nodllstorageclass=default"); 397e8d8bef9SDimitry Andric } 3985ffd83dbSDimitry Andric } 39981ad6265SDimitry Andric 40081ad6265SDimitry Andric // PS4 toolchain. 40181ad6265SDimitry Andric toolchains::PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, 40281ad6265SDimitry Andric const llvm::opt::ArgList &Args) 40381ad6265SDimitry Andric : PS4PS5Base(D, Triple, Args, "PS4", "SCE_ORBIS_SDK_DIR") {} 40481ad6265SDimitry Andric 40581ad6265SDimitry Andric // PS5 toolchain. 40681ad6265SDimitry Andric toolchains::PS5CPU::PS5CPU(const Driver &D, const llvm::Triple &Triple, 40781ad6265SDimitry Andric const llvm::opt::ArgList &Args) 40881ad6265SDimitry Andric : PS4PS5Base(D, Triple, Args, "PS5", "SCE_PROSPERO_SDK_DIR") {} 409