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" 1106c3fb27SDimitry 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 149*5f757f3fSDimitry Andric assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); 1500b57cec5SDimitry Andric if (Output.isFilename()) { 1510b57cec5SDimitry Andric CmdArgs.push_back("-o"); 1520b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 155bdd1243dSDimitry Andric const bool UseLTO = D.isUsingLTO(); 156bdd1243dSDimitry Andric const bool UseJMC = 157bdd1243dSDimitry Andric Args.hasFlag(options::OPT_fjmc, options::OPT_fno_jmc, false); 158bdd1243dSDimitry Andric const bool IsPS4 = TC.getTriple().isPS4(); 159bdd1243dSDimitry Andric 16006c3fb27SDimitry Andric const char *PS4LTOArgs = ""; 161bdd1243dSDimitry Andric auto AddCodeGenFlag = [&](Twine Flag) { 16206c3fb27SDimitry Andric if (IsPS4) 16306c3fb27SDimitry Andric PS4LTOArgs = Args.MakeArgString(Twine(PS4LTOArgs) + " " + Flag); 164*5f757f3fSDimitry Andric else 16506c3fb27SDimitry Andric CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=") + Flag)); 166bdd1243dSDimitry Andric }; 167bdd1243dSDimitry Andric 168bdd1243dSDimitry Andric if (UseLTO) { 169bdd1243dSDimitry Andric // We default to creating the arange section, but LTO does not. Enable it 170bdd1243dSDimitry Andric // here. 171bdd1243dSDimitry Andric AddCodeGenFlag("-generate-arange-section"); 172bdd1243dSDimitry Andric 173bdd1243dSDimitry Andric // This tells LTO to perform JustMyCode instrumentation. 174bdd1243dSDimitry Andric if (UseJMC) 175bdd1243dSDimitry Andric AddCodeGenFlag("-enable-jmc-instrument"); 176bdd1243dSDimitry Andric 177bdd1243dSDimitry Andric if (Arg *A = Args.getLastArg(options::OPT_fcrash_diagnostics_dir)) 178bdd1243dSDimitry Andric AddCodeGenFlag(Twine("-crash-diagnostics-dir=") + A->getValue()); 17906c3fb27SDimitry Andric 18006c3fb27SDimitry Andric StringRef Parallelism = getLTOParallelism(Args, D); 18106c3fb27SDimitry Andric if (!Parallelism.empty()) { 18206c3fb27SDimitry Andric if (IsPS4) 18306c3fb27SDimitry Andric AddCodeGenFlag(Twine("-threads=") + Parallelism); 18406c3fb27SDimitry Andric else 18506c3fb27SDimitry Andric CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=jobs=") + Parallelism)); 18606c3fb27SDimitry Andric } 18706c3fb27SDimitry Andric 18806c3fb27SDimitry Andric if (IsPS4) { 18906c3fb27SDimitry Andric const char *Prefix = nullptr; 19006c3fb27SDimitry Andric if (D.getLTOMode() == LTOK_Thin) 19106c3fb27SDimitry Andric Prefix = "-lto-thin-debug-options="; 19206c3fb27SDimitry Andric else if (D.getLTOMode() == LTOK_Full) 19306c3fb27SDimitry Andric Prefix = "-lto-debug-options="; 19406c3fb27SDimitry Andric else 19506c3fb27SDimitry Andric llvm_unreachable("new LTO mode?"); 19606c3fb27SDimitry Andric 19706c3fb27SDimitry Andric CmdArgs.push_back(Args.MakeArgString(Twine(Prefix) + PS4LTOArgs)); 19806c3fb27SDimitry Andric } 199bdd1243dSDimitry Andric } 200bdd1243dSDimitry Andric 2010b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) 20281ad6265SDimitry Andric TC.addSanitizerArgs(Args, CmdArgs, "-l", ""); 2030b57cec5SDimitry Andric 20406c3fb27SDimitry Andric if (D.isUsingLTO() && Args.hasArg(options::OPT_funified_lto)) { 20506c3fb27SDimitry Andric if (D.getLTOMode() == LTOK_Thin) 20606c3fb27SDimitry Andric CmdArgs.push_back("--lto=thin"); 20706c3fb27SDimitry Andric else if (D.getLTOMode() == LTOK_Full) 20806c3fb27SDimitry Andric CmdArgs.push_back("--lto=full"); 20906c3fb27SDimitry Andric } 21006c3fb27SDimitry Andric 211*5f757f3fSDimitry Andric Args.addAllArgs(CmdArgs, 212*5f757f3fSDimitry Andric {options::OPT_L, options::OPT_T_Group, options::OPT_s, 213*5f757f3fSDimitry Andric options::OPT_t, options::OPT_r}); 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle)) 2160b57cec5SDimitry Andric CmdArgs.push_back("--no-demangle"); 2170b57cec5SDimitry Andric 21881ad6265SDimitry Andric AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA); 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric if (Args.hasArg(options::OPT_pthread)) { 2210b57cec5SDimitry Andric CmdArgs.push_back("-lpthread"); 2220b57cec5SDimitry Andric } 2230b57cec5SDimitry Andric 224bdd1243dSDimitry Andric if (UseJMC) { 225bdd1243dSDimitry Andric CmdArgs.push_back("--whole-archive"); 226bdd1243dSDimitry Andric if (IsPS4) 227bdd1243dSDimitry Andric CmdArgs.push_back("-lSceDbgJmc"); 228bdd1243dSDimitry Andric else 229bdd1243dSDimitry Andric CmdArgs.push_back("-lSceJmc_nosubmission"); 230bdd1243dSDimitry Andric CmdArgs.push_back("--no-whole-archive"); 231bdd1243dSDimitry Andric } 232bdd1243dSDimitry Andric 2335ffd83dbSDimitry Andric if (Args.hasArg(options::OPT_fuse_ld_EQ)) { 2345ffd83dbSDimitry Andric D.Diag(diag::err_drv_unsupported_opt_for_target) 23581ad6265SDimitry Andric << "-fuse-ld" << TC.getTriple().str(); 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric 23881ad6265SDimitry Andric std::string LdName = TC.qualifyPSCmdName(TC.getLinkerBaseName()); 23981ad6265SDimitry Andric const char *Exec = Args.MakeArgString(TC.GetProgramPath(LdName.c_str())); 2400b57cec5SDimitry Andric 241e8d8bef9SDimitry Andric C.addCommand(std::make_unique<Command>(JA, *this, 242e8d8bef9SDimitry Andric ResponseFileSupport::AtFileUTF8(), 243e8d8bef9SDimitry Andric Exec, CmdArgs, Inputs, Output)); 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 24681ad6265SDimitry Andric toolchains::PS4PS5Base::PS4PS5Base(const Driver &D, const llvm::Triple &Triple, 24781ad6265SDimitry Andric const ArgList &Args, StringRef Platform, 24881ad6265SDimitry Andric const char *EnvVar) 2490b57cec5SDimitry Andric : Generic_ELF(D, Triple, Args) { 2500b57cec5SDimitry Andric if (Args.hasArg(clang::driver::options::OPT_static)) 25181ad6265SDimitry Andric D.Diag(clang::diag::err_drv_unsupported_opt_for_target) 25281ad6265SDimitry Andric << "-static" << Platform; 2530b57cec5SDimitry Andric 25406c3fb27SDimitry Andric // Determine where to find the PS4/PS5 libraries. 25506c3fb27SDimitry Andric // If -isysroot was passed, use that as the SDK base path. 25606c3fb27SDimitry Andric // If not, we use the EnvVar if it exists; otherwise use the driver's 25706c3fb27SDimitry Andric // installation path, which should be <SDK_DIR>/host_tools/bin. 25806c3fb27SDimitry Andric SmallString<80> Whence; 25906c3fb27SDimitry Andric if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { 26006c3fb27SDimitry Andric SDKRootDir = A->getValue(); 26106c3fb27SDimitry Andric if (!llvm::sys::fs::exists(SDKRootDir)) 26206c3fb27SDimitry Andric D.Diag(clang::diag::warn_missing_sysroot) << SDKRootDir; 26306c3fb27SDimitry Andric Whence = A->getSpelling(); 26406c3fb27SDimitry Andric } else if (const char *EnvValue = getenv(EnvVar)) { 26506c3fb27SDimitry Andric SDKRootDir = EnvValue; 26606c3fb27SDimitry Andric Whence = { "environment variable '", EnvVar, "'" }; 2670b57cec5SDimitry Andric } else { 26806c3fb27SDimitry Andric SDKRootDir = D.Dir + "/../../"; 26906c3fb27SDimitry Andric Whence = "compiler's location"; 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric 27206c3fb27SDimitry Andric SmallString<512> SDKIncludeDir(SDKRootDir); 27381ad6265SDimitry Andric llvm::sys::path::append(SDKIncludeDir, "target/include"); 2740b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdinc) && 2750b57cec5SDimitry Andric !Args.hasArg(options::OPT_nostdlibinc) && 2760b57cec5SDimitry Andric !Args.hasArg(options::OPT_isysroot) && 2770b57cec5SDimitry Andric !Args.hasArg(options::OPT__sysroot_EQ) && 27881ad6265SDimitry Andric !llvm::sys::fs::exists(SDKIncludeDir)) { 27981ad6265SDimitry Andric D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected) 28006c3fb27SDimitry Andric << Twine(Platform, " system headers").str() << SDKIncludeDir << Whence; 2810b57cec5SDimitry Andric } 2820b57cec5SDimitry Andric 28306c3fb27SDimitry Andric SmallString<512> SDKLibDir(SDKRootDir); 28481ad6265SDimitry Andric llvm::sys::path::append(SDKLibDir, "target/lib"); 2850b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib) && 2860b57cec5SDimitry Andric !Args.hasArg(options::OPT_nodefaultlibs) && 2870b57cec5SDimitry Andric !Args.hasArg(options::OPT__sysroot_EQ) && !Args.hasArg(options::OPT_E) && 2880b57cec5SDimitry Andric !Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S) && 2890b57cec5SDimitry Andric !Args.hasArg(options::OPT_emit_ast) && 29081ad6265SDimitry Andric !llvm::sys::fs::exists(SDKLibDir)) { 29181ad6265SDimitry Andric D.Diag(clang::diag::warn_drv_unable_to_find_directory_expected) 29206c3fb27SDimitry Andric << Twine(Platform, " system libraries").str() << SDKLibDir << Whence; 2930b57cec5SDimitry Andric return; 2940b57cec5SDimitry Andric } 29581ad6265SDimitry Andric getFilePaths().push_back(std::string(SDKLibDir.str())); 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 29806c3fb27SDimitry Andric void toolchains::PS4PS5Base::AddClangSystemIncludeArgs( 29906c3fb27SDimitry Andric const ArgList &DriverArgs, 30006c3fb27SDimitry Andric ArgStringList &CC1Args) const { 30106c3fb27SDimitry Andric const Driver &D = getDriver(); 30206c3fb27SDimitry Andric 30306c3fb27SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdinc)) 30406c3fb27SDimitry Andric return; 30506c3fb27SDimitry Andric 30606c3fb27SDimitry Andric if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { 30706c3fb27SDimitry Andric SmallString<128> Dir(D.ResourceDir); 30806c3fb27SDimitry Andric llvm::sys::path::append(Dir, "include"); 30906c3fb27SDimitry Andric addSystemInclude(DriverArgs, CC1Args, Dir.str()); 31006c3fb27SDimitry Andric } 31106c3fb27SDimitry Andric 31206c3fb27SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdlibinc)) 31306c3fb27SDimitry Andric return; 31406c3fb27SDimitry Andric 31506c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, 31606c3fb27SDimitry Andric SDKRootDir + "/target/include"); 31706c3fb27SDimitry Andric addExternCSystemInclude(DriverArgs, CC1Args, 31806c3fb27SDimitry Andric SDKRootDir + "/target/include_common"); 31906c3fb27SDimitry Andric } 32006c3fb27SDimitry Andric 3210b57cec5SDimitry Andric Tool *toolchains::PS4CPU::buildAssembler() const { 32281ad6265SDimitry Andric return new tools::PScpu::Assembler(*this); 3230b57cec5SDimitry Andric } 3240b57cec5SDimitry Andric 32581ad6265SDimitry Andric Tool *toolchains::PS5CPU::buildAssembler() const { 32681ad6265SDimitry Andric // PS5 does not support an external assembler. 32781ad6265SDimitry Andric getDriver().Diag(clang::diag::err_no_external_assembler); 32881ad6265SDimitry Andric return nullptr; 3290b57cec5SDimitry Andric } 3300b57cec5SDimitry Andric 33181ad6265SDimitry Andric Tool *toolchains::PS4PS5Base::buildLinker() const { 33281ad6265SDimitry Andric return new tools::PScpu::Linker(*this); 33381ad6265SDimitry Andric } 3340b57cec5SDimitry Andric 33581ad6265SDimitry Andric SanitizerMask toolchains::PS4PS5Base::getSupportedSanitizers() const { 3360b57cec5SDimitry Andric SanitizerMask Res = ToolChain::getSupportedSanitizers(); 3370b57cec5SDimitry Andric Res |= SanitizerKind::Address; 3380b57cec5SDimitry Andric Res |= SanitizerKind::PointerCompare; 3390b57cec5SDimitry Andric Res |= SanitizerKind::PointerSubtract; 3400b57cec5SDimitry Andric Res |= SanitizerKind::Vptr; 3410b57cec5SDimitry Andric return Res; 3420b57cec5SDimitry Andric } 3435ffd83dbSDimitry Andric 34481ad6265SDimitry Andric SanitizerMask toolchains::PS5CPU::getSupportedSanitizers() const { 34581ad6265SDimitry Andric SanitizerMask Res = PS4PS5Base::getSupportedSanitizers(); 34681ad6265SDimitry Andric Res |= SanitizerKind::Thread; 34781ad6265SDimitry Andric return Res; 34881ad6265SDimitry Andric } 34981ad6265SDimitry Andric 35081ad6265SDimitry Andric void toolchains::PS4PS5Base::addClangTargetOptions( 351e8d8bef9SDimitry Andric const ArgList &DriverArgs, ArgStringList &CC1Args, 3525ffd83dbSDimitry Andric Action::OffloadKind DeviceOffloadingKind) const { 35381ad6265SDimitry Andric // PS4/PS5 do not use init arrays. 3545ffd83dbSDimitry Andric if (DriverArgs.hasArg(options::OPT_fuse_init_array)) { 3555ffd83dbSDimitry Andric Arg *A = DriverArgs.getLastArg(options::OPT_fuse_init_array); 3565ffd83dbSDimitry Andric getDriver().Diag(clang::diag::err_drv_unsupported_opt_for_target) 3575ffd83dbSDimitry Andric << A->getAsString(DriverArgs) << getTriple().str(); 3585ffd83dbSDimitry Andric } 3595ffd83dbSDimitry Andric 3605ffd83dbSDimitry Andric CC1Args.push_back("-fno-use-init-array"); 361e8d8bef9SDimitry Andric 362e8d8bef9SDimitry Andric const Arg *A = 363e8d8bef9SDimitry Andric DriverArgs.getLastArg(options::OPT_fvisibility_from_dllstorageclass, 364e8d8bef9SDimitry Andric options::OPT_fno_visibility_from_dllstorageclass); 365e8d8bef9SDimitry Andric if (!A || 366e8d8bef9SDimitry Andric A->getOption().matches(options::OPT_fvisibility_from_dllstorageclass)) { 367e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-from-dllstorageclass"); 368e8d8bef9SDimitry Andric 369e8d8bef9SDimitry Andric if (DriverArgs.hasArg(options::OPT_fvisibility_dllexport_EQ)) 370e8d8bef9SDimitry Andric DriverArgs.AddLastArg(CC1Args, options::OPT_fvisibility_dllexport_EQ); 371e8d8bef9SDimitry Andric else 372e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-dllexport=protected"); 373e8d8bef9SDimitry Andric 374e8d8bef9SDimitry Andric if (DriverArgs.hasArg(options::OPT_fvisibility_nodllstorageclass_EQ)) 375e8d8bef9SDimitry Andric DriverArgs.AddLastArg(CC1Args, 376e8d8bef9SDimitry Andric options::OPT_fvisibility_nodllstorageclass_EQ); 377e8d8bef9SDimitry Andric else 378e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-nodllstorageclass=hidden"); 379e8d8bef9SDimitry Andric 380e8d8bef9SDimitry Andric if (DriverArgs.hasArg(options::OPT_fvisibility_externs_dllimport_EQ)) 381e8d8bef9SDimitry Andric DriverArgs.AddLastArg(CC1Args, 382e8d8bef9SDimitry Andric options::OPT_fvisibility_externs_dllimport_EQ); 383e8d8bef9SDimitry Andric else 384e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-externs-dllimport=default"); 385e8d8bef9SDimitry Andric 386e8d8bef9SDimitry Andric if (DriverArgs.hasArg( 387e8d8bef9SDimitry Andric options::OPT_fvisibility_externs_nodllstorageclass_EQ)) 388e8d8bef9SDimitry Andric DriverArgs.AddLastArg( 389e8d8bef9SDimitry Andric CC1Args, options::OPT_fvisibility_externs_nodllstorageclass_EQ); 390e8d8bef9SDimitry Andric else 391e8d8bef9SDimitry Andric CC1Args.push_back("-fvisibility-externs-nodllstorageclass=default"); 392e8d8bef9SDimitry Andric } 3935ffd83dbSDimitry Andric } 39481ad6265SDimitry Andric 39581ad6265SDimitry Andric // PS4 toolchain. 39681ad6265SDimitry Andric toolchains::PS4CPU::PS4CPU(const Driver &D, const llvm::Triple &Triple, 39781ad6265SDimitry Andric const llvm::opt::ArgList &Args) 39881ad6265SDimitry Andric : PS4PS5Base(D, Triple, Args, "PS4", "SCE_ORBIS_SDK_DIR") {} 39981ad6265SDimitry Andric 40081ad6265SDimitry Andric // PS5 toolchain. 40181ad6265SDimitry Andric toolchains::PS5CPU::PS5CPU(const Driver &D, const llvm::Triple &Triple, 40281ad6265SDimitry Andric const llvm::opt::ArgList &Args) 40381ad6265SDimitry Andric : PS4PS5Base(D, Triple, Args, "PS5", "SCE_PROSPERO_SDK_DIR") {} 404