Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Driver/ToolChains/Hexagon.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- Hexagon.cpp - Hexagon ToolChain Implementations --------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "Hexagon.h"
10
#include "CommonArgs.h"
11
#include "InputInfo.h"
12
#include "clang/Driver/Compilation.h"
13
#include "clang/Driver/Driver.h"
14
#include "clang/Driver/DriverDiagnostic.h"
15
#include "clang/Driver/Options.h"
16
#include "llvm/ADT/StringExtras.h"
17
#include "llvm/Option/ArgList.h"
18
#include "llvm/Support/FileSystem.h"
19
#include "llvm/Support/Path.h"
20
#include "llvm/Support/VirtualFileSystem.h"
21
22
using namespace clang::driver;
23
using namespace clang::driver::tools;
24
using namespace clang::driver::toolchains;
25
using namespace clang;
26
using namespace llvm::opt;
27
28
// Default hvx-length for various versions.
29
10
static StringRef getDefaultHvxLength(StringRef Cpu) {
30
10
  return llvm::StringSwitch<StringRef>(Cpu)
31
10
      .Case("v60", "64b")
32
10
      .Case("v62", "64b")
33
10
      .Case("v65", "64b")
34
10
      .Case("v66", "128b")
35
10
      .Default("128b");
36
10
}
37
38
80
static void handleHVXWarnings(const Driver &D, const ArgList &Args) {
39
80
  // Handle the unsupported values passed to mhvx-length.
40
80
  if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
41
10
    StringRef Val = A->getValue();
42
10
    if (!Val.equals_lower("64b") && 
!Val.equals_lower("128b")7
)
43
2
      D.Diag(diag::err_drv_unsupported_option_argument)
44
2
          << A->getOption().getName() << Val;
45
10
  }
46
80
}
47
48
// Handle hvx target features explicitly.
49
static void handleHVXTargetFeatures(const Driver &D, const ArgList &Args,
50
                                    std::vector<StringRef> &Features,
51
80
                                    bool &HasHVX) {
52
80
  // Handle HVX warnings.
53
80
  handleHVXWarnings(D, Args);
54
80
55
80
  // Add the +hvx* features based on commandline flags.
56
80
  StringRef HVXFeature, HVXLength;
57
80
  StringRef Cpu(toolchains::HexagonToolChain::GetTargetCPUVersion(Args));
58
80
59
80
  // Handle -mhvx, -mhvx=, -mno-hvx.
60
80
  if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx,
61
20
                               options::OPT_mhexagon_hvx,
62
20
                               options::OPT_mhexagon_hvx_EQ)) {
63
20
    if (A->getOption().matches(options::OPT_mno_hexagon_hvx))
64
2
      return;
65
18
    if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ)) {
66
2
      HasHVX = true;
67
2
      HVXFeature = Cpu = A->getValue();
68
2
      HVXFeature = Args.MakeArgString(llvm::Twine("+hvx") + HVXFeature.lower());
69
16
    } else if (A->getOption().matches(options::OPT_mhexagon_hvx)) {
70
16
      HasHVX = true;
71
16
      HVXFeature = Args.MakeArgString(llvm::Twine("+hvx") + Cpu);
72
16
    }
73
18
    Features.push_back(HVXFeature);
74
18
  }
75
80
76
80
  // Handle -mhvx-length=.
77
80
  
if (Arg *78
A78
= Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
78
10
    // These flags are valid only if HVX in enabled.
79
10
    if (!HasHVX)
80
2
      D.Diag(diag::err_drv_invalid_hvx_length);
81
8
    else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ))
82
8
      HVXLength = A->getValue();
83
10
  }
84
68
  // Default hvx-length based on Cpu.
85
68
  else if (HasHVX)
86
10
    HVXLength = getDefaultHvxLength(Cpu);
87
78
88
78
  if (!HVXLength.empty()) {
89
18
    HVXFeature =
90
18
        Args.MakeArgString(llvm::Twine("+hvx-length") + HVXLength.lower());
91
18
    Features.push_back(HVXFeature);
92
18
  }
93
78
}
94
95
// Hexagon target features.
96
void hexagon::getHexagonTargetFeatures(const Driver &D, const ArgList &Args,
97
80
                                       std::vector<StringRef> &Features) {
98
80
  handleTargetFeaturesGroup(Args, Features,
99
80
                            options::OPT_m_hexagon_Features_Group);
100
80
101
80
  bool UseLongCalls = false;
102
80
  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
103
2
                               options::OPT_mno_long_calls)) {
104
2
    if (A->getOption().matches(options::OPT_mlong_calls))
105
1
      UseLongCalls = true;
106
2
  }
107
80
108
80
  Features.push_back(UseLongCalls ? 
"+long-calls"1
:
"-long-calls"79
);
109
80
110
80
  bool HasHVX = false;
111
80
  handleHVXTargetFeatures(D, Args, Features, HasHVX);
112
80
113
80
  if (HexagonToolChain::isAutoHVXEnabled(Args) && 
!HasHVX2
)
114
2
    D.Diag(diag::warn_drv_vectorize_needs_hvx);
115
80
}
116
117
// Hexagon tools start.
118
void hexagon::Assembler::RenderExtraToolArgs(const JobAction &JA,
119
5
                                             ArgStringList &CmdArgs) const {
120
5
}
121
122
void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
123
                                      const InputInfo &Output,
124
                                      const InputInfoList &Inputs,
125
                                      const ArgList &Args,
126
5
                                      const char *LinkingOutput) const {
127
5
  claimNoWarnArgs(Args);
128
5
129
5
  auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
130
5
  const Driver &D = HTC.getDriver();
131
5
  ArgStringList CmdArgs;
132
5
133
5
  CmdArgs.push_back("--arch=hexagon");
134
5
135
5
  RenderExtraToolArgs(JA, CmdArgs);
136
5
137
5
  const char *AsName = "llvm-mc";
138
5
  CmdArgs.push_back("-filetype=obj");
139
5
  CmdArgs.push_back(Args.MakeArgString(
140
5
      "-mcpu=hexagon" +
141
5
      toolchains::HexagonToolChain::GetTargetCPUVersion(Args)));
142
5
143
5
  if (Output.isFilename()) {
144
5
    CmdArgs.push_back("-o");
145
5
    CmdArgs.push_back(Output.getFilename());
146
5
  } else {
147
0
    assert(Output.isNothing() && "Unexpected output");
148
0
    CmdArgs.push_back("-fsyntax-only");
149
0
  }
150
5
151
5
  if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
152
3
    CmdArgs.push_back(Args.MakeArgString("-gpsize=" + Twine(G.getValue())));
153
3
  }
154
5
155
5
  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
156
5
157
5
  // Only pass -x if gcc will understand it; otherwise hope gcc
158
5
  // understands the suffix correctly. The main use case this would go
159
5
  // wrong in is for linker inputs if they happened to have an odd
160
5
  // suffix; really the only way to get this to happen is a command
161
5
  // like '-x foobar a.c' which will treat a.c like a linker input.
162
5
  //
163
5
  // FIXME: For the linker case specifically, can we safely convert
164
5
  // inputs into '-Wl,' options?
165
5
  for (const auto &II : Inputs) {
166
5
    // Don't try to pass LLVM or AST inputs to a generic gcc.
167
5
    if (types::isLLVMIR(II.getType()))
168
0
      D.Diag(clang::diag::err_drv_no_linker_llvm_support)
169
0
          << HTC.getTripleString();
170
5
    else if (II.getType() == types::TY_AST)
171
0
      D.Diag(clang::diag::err_drv_no_ast_support)
172
0
          << HTC.getTripleString();
173
5
    else if (II.getType() == types::TY_ModuleFile)
174
0
      D.Diag(diag::err_drv_no_module_support)
175
0
          << HTC.getTripleString();
176
5
177
5
    if (II.isFilename())
178
5
      CmdArgs.push_back(II.getFilename());
179
0
    else
180
0
      // Don't render as input, we need gcc to do the translations.
181
0
      // FIXME: What is this?
182
0
      II.getInputArg().render(Args, CmdArgs);
183
5
  }
184
5
185
5
  auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
186
5
  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
187
5
}
188
189
void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA,
190
0
                                          ArgStringList &CmdArgs) const {
191
0
}
192
193
static void
194
constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
195
                         const toolchains::HexagonToolChain &HTC,
196
                         const InputInfo &Output, const InputInfoList &Inputs,
197
                         const ArgList &Args, ArgStringList &CmdArgs,
198
54
                         const char *LinkingOutput) {
199
54
200
54
  const Driver &D = HTC.getDriver();
201
54
202
54
  //----------------------------------------------------------------------------
203
54
  //
204
54
  //----------------------------------------------------------------------------
205
54
  bool IsStatic = Args.hasArg(options::OPT_static);
206
54
  bool IsShared = Args.hasArg(options::OPT_shared);
207
54
  bool IsPIE = Args.hasArg(options::OPT_pie);
208
54
  bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
209
54
  bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
210
54
  bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
211
54
  bool UseG0 = false;
212
54
  bool UseShared = IsShared && 
!IsStatic3
;
213
54
214
54
  //----------------------------------------------------------------------------
215
54
  // Silence warnings for various options
216
54
  //----------------------------------------------------------------------------
217
54
  Args.ClaimAllArgs(options::OPT_g_Group);
218
54
  Args.ClaimAllArgs(options::OPT_emit_llvm);
219
54
  Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
220
54
                                     // handled somewhere else.
221
54
  Args.ClaimAllArgs(options::OPT_static_libgcc);
222
54
223
54
  //----------------------------------------------------------------------------
224
54
  //
225
54
  //----------------------------------------------------------------------------
226
54
  if (Args.hasArg(options::OPT_s))
227
1
    CmdArgs.push_back("-s");
228
54
229
54
  if (Args.hasArg(options::OPT_r))
230
0
    CmdArgs.push_back("-r");
231
54
232
54
  for (const auto &Opt : HTC.ExtraOpts)
233
0
    CmdArgs.push_back(Opt.c_str());
234
54
235
54
  CmdArgs.push_back("-march=hexagon");
236
54
  StringRef CpuVer = toolchains::HexagonToolChain::GetTargetCPUVersion(Args);
237
54
  CmdArgs.push_back(Args.MakeArgString("-mcpu=hexagon" + CpuVer));
238
54
239
54
  if (IsShared) {
240
3
    CmdArgs.push_back("-shared");
241
3
    // The following should be the default, but doing as hexagon-gcc does.
242
3
    CmdArgs.push_back("-call_shared");
243
3
  }
244
54
245
54
  if (IsStatic)
246
2
    CmdArgs.push_back("-static");
247
54
248
54
  if (IsPIE && 
!IsShared2
)
249
1
    CmdArgs.push_back("-pie");
250
54
251
54
  if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
252
8
    CmdArgs.push_back(Args.MakeArgString("-G" + Twine(G.getValue())));
253
8
    UseG0 = G.getValue() == 0;
254
8
  }
255
54
256
54
  //----------------------------------------------------------------------------
257
54
  //
258
54
  //----------------------------------------------------------------------------
259
54
  CmdArgs.push_back("-o");
260
54
  CmdArgs.push_back(Output.getFilename());
261
54
262
54
  //----------------------------------------------------------------------------
263
54
  // moslib
264
54
  //----------------------------------------------------------------------------
265
54
  std::vector<std::string> OsLibs;
266
54
  bool HasStandalone = false;
267
54
268
54
  for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
269
5
    A->claim();
270
5
    OsLibs.emplace_back(A->getValue());
271
5
    HasStandalone = HasStandalone || (OsLibs.back() == "standalone");
272
5
  }
273
54
  if (OsLibs.empty()) {
274
52
    OsLibs.push_back("standalone");
275
52
    HasStandalone = true;
276
52
  }
277
54
278
54
  //----------------------------------------------------------------------------
279
54
  // Start Files
280
54
  //----------------------------------------------------------------------------
281
54
  const std::string MCpuSuffix = "/" + CpuVer.str();
282
54
  const std::string MCpuG0Suffix = MCpuSuffix + "/G0";
283
54
  const std::string RootDir =
284
54
      HTC.getHexagonTargetDir(D.InstalledDir, D.PrefixDirs) + "/";
285
54
  const std::string StartSubDir =
286
54
      "hexagon/lib" + (UseG0 ? 
MCpuG0Suffix5
:
MCpuSuffix49
);
287
54
288
54
  auto Find = [&HTC] (const std::string &RootDir, const std::string &SubDir,
289
201
                      const char *Name) -> std::string {
290
201
    std::string RelName = SubDir + Name;
291
201
    std::string P = HTC.GetFilePath(RelName.c_str());
292
201
    if (llvm::sys::fs::exists(P))
293
0
      return P;
294
201
    return RootDir + RelName;
295
201
  };
296
54
297
54
  if (IncStdLib && 
IncStartFiles53
) {
298
52
    if (!IsShared) {
299
49
      if (HasStandalone) {
300
48
        std::string Crt0SA = Find(RootDir, StartSubDir, "/crt0_standalone.o");
301
48
        CmdArgs.push_back(Args.MakeArgString(Crt0SA));
302
48
      }
303
49
      std::string Crt0 = Find(RootDir, StartSubDir, "/crt0.o");
304
49
      CmdArgs.push_back(Args.MakeArgString(Crt0));
305
49
    }
306
52
    std::string Init = UseShared
307
52
          ? 
Find(RootDir, StartSubDir + "/pic", "/initS.o")2
308
52
          : 
Find(RootDir, StartSubDir, "/init.o")50
;
309
52
    CmdArgs.push_back(Args.MakeArgString(Init));
310
52
  }
311
54
312
54
  //----------------------------------------------------------------------------
313
54
  // Library Search Paths
314
54
  //----------------------------------------------------------------------------
315
54
  const ToolChain::path_list &LibPaths = HTC.getFilePaths();
316
54
  for (const auto &LibPath : LibPaths)
317
118
    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
318
54
319
54
  //----------------------------------------------------------------------------
320
54
  //
321
54
  //----------------------------------------------------------------------------
322
54
  Args.AddAllArgs(CmdArgs,
323
54
                  {options::OPT_T_Group, options::OPT_e, options::OPT_s,
324
54
                   options::OPT_t, options::OPT_u_Group});
325
54
326
54
  AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
327
54
328
54
  //----------------------------------------------------------------------------
329
54
  // Libraries
330
54
  //----------------------------------------------------------------------------
331
54
  if (IncStdLib && 
IncDefLibs53
) {
332
52
    if (D.CCCIsCXX()) {
333
6
      if (HTC.ShouldLinkCXXStdlib(Args))
334
6
        HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
335
6
      CmdArgs.push_back("-lm");
336
6
    }
337
52
338
52
    CmdArgs.push_back("--start-group");
339
52
340
52
    if (!IsShared) {
341
49
      for (StringRef Lib : OsLibs)
342
52
        CmdArgs.push_back(Args.MakeArgString("-l" + Lib));
343
49
      CmdArgs.push_back("-lc");
344
49
    }
345
52
    CmdArgs.push_back("-lgcc");
346
52
347
52
    CmdArgs.push_back("--end-group");
348
52
  }
349
54
350
54
  //----------------------------------------------------------------------------
351
54
  // End files
352
54
  //----------------------------------------------------------------------------
353
54
  if (IncStdLib && 
IncStartFiles53
) {
354
52
    std::string Fini = UseShared
355
52
          ? 
Find(RootDir, StartSubDir + "/pic", "/finiS.o")2
356
52
          : 
Find(RootDir, StartSubDir, "/fini.o")50
;
357
52
    CmdArgs.push_back(Args.MakeArgString(Fini));
358
52
  }
359
54
}
360
361
void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,
362
                                   const InputInfo &Output,
363
                                   const InputInfoList &Inputs,
364
                                   const ArgList &Args,
365
54
                                   const char *LinkingOutput) const {
366
54
  auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
367
54
368
54
  ArgStringList CmdArgs;
369
54
  constructHexagonLinkArgs(C, JA, HTC, Output, Inputs, Args, CmdArgs,
370
54
                           LinkingOutput);
371
54
372
54
  const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
373
54
  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
374
54
}
375
// Hexagon tools end.
376
377
/// Hexagon Toolchain
378
379
std::string HexagonToolChain::getHexagonTargetDir(
380
      const std::string &InstalledDir,
381
298
      const SmallVectorImpl<std::string> &PrefixDirs) const {
382
298
  std::string InstallRelDir;
383
298
  const Driver &D = getDriver();
384
298
385
298
  // Locate the rest of the toolchain ...
386
298
  for (auto &I : PrefixDirs)
387
0
    if (D.getVFS().exists(I))
388
0
      return I;
389
298
390
298
  if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
391
144
    return InstallRelDir;
392
154
393
154
  return InstalledDir;
394
154
}
395
396
Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
397
219
      const ArgList &Args) {
398
219
  StringRef Gn = "";
399
219
  if (Arg *A = Args.getLastArg(options::OPT_G)) {
400
12
    Gn = A->getValue();
401
207
  } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
402
207
                             options::OPT_fPIC)) {
403
15
    Gn = "0";
404
15
  }
405
219
406
219
  unsigned G;
407
219
  if (!Gn.getAsInteger(10, G))
408
27
    return G;
409
192
410
192
  return None;
411
192
}
412
413
void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
414
80
      ToolChain::path_list &LibPaths) const {
415
80
  const Driver &D = getDriver();
416
80
417
80
  //----------------------------------------------------------------------------
418
80
  // -L Args
419
80
  //----------------------------------------------------------------------------
420
80
  for (Arg *A : Args.filtered(options::OPT_L))
421
3
    for (const char *Value : A->getValues())
422
3
      LibPaths.push_back(Value);
423
80
424
80
  //----------------------------------------------------------------------------
425
80
  // Other standard paths
426
80
  //----------------------------------------------------------------------------
427
80
  std::vector<std::string> RootDirs;
428
80
  std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
429
80
            std::back_inserter(RootDirs));
430
80
431
80
  std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
432
80
                                              D.PrefixDirs);
433
80
  if (llvm::find(RootDirs, TargetDir) == RootDirs.end())
434
80
    RootDirs.push_back(TargetDir);
435
80
436
80
  bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
437
80
  // Assume G0 with -shared.
438
80
  bool HasG0 = Args.hasArg(options::OPT_shared);
439
80
  if (auto G = getSmallDataThreshold(Args))
440
8
    HasG0 = G.getValue() == 0;
441
80
442
80
  const std::string CpuVer = GetTargetCPUVersion(Args).str();
443
80
  for (auto &Dir : RootDirs) {
444
80
    std::string LibDir = Dir + "/hexagon/lib";
445
80
    std::string LibDirCpu = LibDir + '/' + CpuVer;
446
80
    if (HasG0) {
447
5
      if (HasPIC)
448
2
        LibPaths.push_back(LibDirCpu + "/G0/pic");
449
5
      LibPaths.push_back(LibDirCpu + "/G0");
450
5
    }
451
80
    LibPaths.push_back(LibDirCpu);
452
80
    LibPaths.push_back(LibDir);
453
80
  }
454
80
}
455
456
HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
457
                                   const llvm::opt::ArgList &Args)
458
80
    : Linux(D, Triple, Args) {
459
80
  const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
460
80
                                                    D.PrefixDirs);
461
80
462
80
  // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
463
80
  // program paths
464
80
  const std::string BinDir(TargetDir + "/bin");
465
80
  if (D.getVFS().exists(BinDir))
466
0
    getProgramPaths().push_back(BinDir);
467
80
468
80
  ToolChain::path_list &LibPaths = getFilePaths();
469
80
470
80
  // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
471
80
  // 'elf' OS type, so the Linux paths are not appropriate. When we actually
472
80
  // support 'linux' we'll need to fix this up
473
80
  LibPaths.clear();
474
80
  getHexagonLibraryPaths(Args, LibPaths);
475
80
}
476
477
80
HexagonToolChain::~HexagonToolChain() {}
478
479
5
Tool *HexagonToolChain::buildAssembler() const {
480
5
  return new tools::hexagon::Assembler(*this);
481
5
}
482
483
54
Tool *HexagonToolChain::buildLinker() const {
484
54
  return new tools::hexagon::Linker(*this);
485
54
}
486
487
unsigned HexagonToolChain::getOptimizationLevel(
488
0
    const llvm::opt::ArgList &DriverArgs) const {
489
0
  // Copied in large part from lib/Frontend/CompilerInvocation.cpp.
490
0
  Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
491
0
  if (!A)
492
0
    return 0;
493
0
494
0
  if (A->getOption().matches(options::OPT_O0))
495
0
    return 0;
496
0
  if (A->getOption().matches(options::OPT_Ofast) ||
497
0
      A->getOption().matches(options::OPT_O4))
498
0
    return 3;
499
0
  assert(A->getNumValues() != 0);
500
0
  StringRef S(A->getValue());
501
0
  if (S == "s" || S == "z" || S.empty())
502
0
    return 2;
503
0
  if (S == "g")
504
0
    return 1;
505
0
506
0
  unsigned OptLevel;
507
0
  if (S.getAsInteger(10, OptLevel))
508
0
    return 0;
509
0
  return OptLevel;
510
0
}
511
512
void HexagonToolChain::addClangTargetOptions(const ArgList &DriverArgs,
513
                                             ArgStringList &CC1Args,
514
81
                                             Action::OffloadKind) const {
515
81
  if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
516
3
    CC1Args.push_back("-target-feature");
517
3
    CC1Args.push_back("+reserved-r19");
518
3
  }
519
81
  if (isAutoHVXEnabled(DriverArgs)) {
520
2
    CC1Args.push_back("-mllvm");
521
2
    CC1Args.push_back("-hexagon-autohvx");
522
2
  }
523
81
}
524
525
void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
526
80
                                                 ArgStringList &CC1Args) const {
527
80
  if (DriverArgs.hasArg(options::OPT_nostdinc) ||
528
80
      
DriverArgs.hasArg(options::OPT_nostdlibinc)79
)
529
3
    return;
530
77
531
77
  const Driver &D = getDriver();
532
77
  std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
533
77
                                              D.PrefixDirs);
534
77
  addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
535
77
}
536
537
538
void HexagonToolChain::addLibStdCxxIncludePaths(
539
    const llvm::opt::ArgList &DriverArgs,
540
7
    llvm::opt::ArgStringList &CC1Args) const {
541
7
  const Driver &D = getDriver();
542
7
  std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
543
7
  addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++", "", "", "", "",
544
7
                           DriverArgs, CC1Args);
545
7
}
546
547
ToolChain::CXXStdlibType
548
13
HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
549
13
  Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
550
13
  if (!A)
551
13
    return ToolChain::CST_Libstdcxx;
552
0
553
0
  StringRef Value = A->getValue();
554
0
  if (Value != "libstdc++")
555
0
    getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
556
0
557
0
  return ToolChain::CST_Libstdcxx;
558
0
}
559
560
161
bool HexagonToolChain::isAutoHVXEnabled(const llvm::opt::ArgList &Args) {
561
161
  if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
562
6
                               options::OPT_fno_vectorize))
563
6
    return A->getOption().matches(options::OPT_fvectorize);
564
155
  return false;
565
155
}
566
567
//
568
// Returns the default CPU for Hexagon. This is the default compilation target
569
// if no Hexagon processor is selected at the command-line.
570
//
571
123
const StringRef HexagonToolChain::GetDefaultCPU() {
572
123
  return "hexagonv60";
573
123
}
574
575
299
const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
576
299
  Arg *CpuArg = nullptr;
577
299
  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
578
176
    CpuArg = A;
579
299
580
299
  StringRef CPU = CpuArg ? 
CpuArg->getValue()176
:
GetDefaultCPU()123
;
581
299
  if (CPU.startswith("hexagon"))
582
299
    return CPU.substr(sizeof("hexagon") - 1);
583
0
  return CPU;
584
0
}