Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/clang/lib/Basic/Targets/Mips.h
Line
Count
Source (jump to first uncovered line)
1
//===--- Mips.h - Declare Mips target feature support -----------*- C++ -*-===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This file declares Mips TargetInfo objects.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H
15
#define LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H
16
17
#include "clang/Basic/TargetInfo.h"
18
#include "clang/Basic/TargetOptions.h"
19
#include "llvm/ADT/Triple.h"
20
#include "llvm/Support/Compiler.h"
21
22
namespace clang {
23
namespace targets {
24
25
class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
26
191
  void setDataLayout() {
27
191
    StringRef Layout;
28
191
29
191
    if (ABI == "o32")
30
107
      Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64";
31
84
    else 
if (84
ABI == "n32"84
)
32
14
      Layout = "m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128";
33
70
    else 
if (70
ABI == "n64"70
)
34
70
      Layout = "m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128";
35
70
    else
36
0
      llvm_unreachable("Invalid ABI");
37
191
38
191
    
if (191
BigEndian191
)
39
132
      resetDataLayout(("E-" + Layout).str());
40
191
    else
41
59
      resetDataLayout(("e-" + Layout).str());
42
191
  }
43
44
  static const Builtin::Info BuiltinInfo[];
45
  std::string CPU;
46
  bool IsMips16;
47
  bool IsMicromips;
48
  bool IsNan2008;
49
  bool IsAbs2008;
50
  bool IsSingleFloat;
51
  bool IsNoABICalls;
52
  bool CanUseBSDABICalls;
53
  enum MipsFloatABI { HardFloat, SoftFloat } FloatABI;
54
  enum DspRevEnum { NoDSP, DSP1, DSP2 } DspRev;
55
  bool HasMSA;
56
  bool DisableMadd4;
57
58
protected:
59
  bool HasFP64;
60
  std::string ABI;
61
62
public:
63
  MipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
64
      : TargetInfo(Triple), IsMips16(false), IsMicromips(false),
65
        IsNan2008(false), IsAbs2008(false), IsSingleFloat(false),
66
        IsNoABICalls(false), CanUseBSDABICalls(false), FloatABI(HardFloat),
67
194
        DspRev(NoDSP), HasMSA(false), DisableMadd4(false), HasFP64(false) {
68
194
    TheCXXABI.set(TargetCXXABI::GenericMIPS);
69
194
70
194
    setABI((getTriple().getArch() == llvm::Triple::mips ||
71
117
            getTriple().getArch() == llvm::Triple::mipsel)
72
110
               ? "o32"
73
84
               : "n64");
74
194
75
194
    CPU = ABI == "o32" ? 
"mips32r2"110
:
"mips64r2"84
;
76
194
77
194
    CanUseBSDABICalls = Triple.getOS() == llvm::Triple::FreeBSD ||
78
190
                        Triple.getOS() == llvm::Triple::OpenBSD;
79
194
  }
80
81
382
  bool isIEEE754_2008Default() const {
82
374
    return CPU == "mips32r6" || CPU == "mips64r6";
83
382
  }
84
85
191
  bool isFP64Default() const {
86
191
    return CPU == "mips32r6" || 
ABI == "n32"187
||
ABI == "n64"173
||
ABI == "64"103
;
87
191
  }
88
89
40
  bool isNan2008() const override { return IsNan2008; }
90
91
  bool processorSupportsGPR64() const;
92
93
0
  StringRef getABI() const override { return ABI; }
94
95
255
  bool setABI(const std::string &Name) override {
96
255
    if (
Name == "o32"255
) {
97
128
      setO32ABITypes();
98
128
      ABI = Name;
99
128
      return true;
100
128
    }
101
255
102
127
    
if (127
Name == "n32"127
) {
103
14
      setN32ABITypes();
104
14
      ABI = Name;
105
14
      return true;
106
14
    }
107
113
    
if (113
Name == "n64"113
) {
108
111
      setN64ABITypes();
109
111
      ABI = Name;
110
111
      return true;
111
111
    }
112
2
    return false;
113
255
  }
114
115
128
  void setO32ABITypes() {
116
128
    Int64Type = SignedLongLong;
117
128
    IntMaxType = Int64Type;
118
128
    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
119
128
    LongDoubleWidth = LongDoubleAlign = 64;
120
128
    LongWidth = LongAlign = 32;
121
128
    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
122
128
    PointerWidth = PointerAlign = 32;
123
128
    PtrDiffType = SignedInt;
124
128
    SizeType = UnsignedInt;
125
128
    SuitableAlign = 64;
126
128
  }
127
128
125
  void setN32N64ABITypes() {
129
125
    LongDoubleWidth = LongDoubleAlign = 128;
130
125
    LongDoubleFormat = &llvm::APFloat::IEEEquad();
131
125
    if (
getTriple().getOS() == llvm::Triple::FreeBSD125
) {
132
2
      LongDoubleWidth = LongDoubleAlign = 64;
133
2
      LongDoubleFormat = &llvm::APFloat::IEEEdouble();
134
2
    }
135
125
    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
136
125
    SuitableAlign = 128;
137
125
  }
138
139
111
  void setN64ABITypes() {
140
111
    setN32N64ABITypes();
141
111
    if (
getTriple().getOS() == llvm::Triple::OpenBSD111
) {
142
3
      Int64Type = SignedLongLong;
143
111
    } else {
144
108
      Int64Type = SignedLong;
145
108
    }
146
111
    IntMaxType = Int64Type;
147
111
    LongWidth = LongAlign = 64;
148
111
    PointerWidth = PointerAlign = 64;
149
111
    PtrDiffType = SignedLong;
150
111
    SizeType = UnsignedLong;
151
111
  }
152
153
14
  void setN32ABITypes() {
154
14
    setN32N64ABITypes();
155
14
    Int64Type = SignedLongLong;
156
14
    IntMaxType = Int64Type;
157
14
    LongWidth = LongAlign = 32;
158
14
    PointerWidth = PointerAlign = 32;
159
14
    PtrDiffType = SignedInt;
160
14
    SizeType = UnsignedInt;
161
14
  }
162
163
  bool isValidCPUName(StringRef Name) const override;
164
165
61
  bool setCPU(const std::string &Name) override {
166
61
    CPU = Name;
167
61
    return isValidCPUName(Name);
168
61
  }
169
170
318
  const std::string &getCPU() const { return CPU; }
171
  bool
172
  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
173
                 StringRef CPU,
174
191
                 const std::vector<std::string> &FeaturesVec) const override {
175
191
    if (CPU.empty())
176
131
      CPU = getCPU();
177
191
    if (CPU == "octeon")
178
0
      Features["mips64r2"] = Features["cnmips"] = true;
179
191
    else
180
191
      Features[CPU] = true;
181
191
    return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
182
191
  }
183
184
  void getTargetDefines(const LangOptions &Opts,
185
                        MacroBuilder &Builder) const override;
186
187
  ArrayRef<Builtin::Info> getTargetBuiltins() const override;
188
189
  bool hasFeature(StringRef Feature) const override;
190
191
128
  BuiltinVaListKind getBuiltinVaListKind() const override {
192
128
    return TargetInfo::VoidPtrBuiltinVaList;
193
128
  }
194
195
415
  ArrayRef<const char *> getGCCRegNames() const override {
196
415
    static const char *const GCCRegNames[] = {
197
415
        // CPU register names
198
415
        // Must match second column of GCCRegAliases
199
415
        "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10",
200
415
        "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19", "$20",
201
415
        "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$30",
202
415
        "$31",
203
415
        // Floating point register names
204
415
        "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9",
205
415
        "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18",
206
415
        "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27",
207
415
        "$f28", "$f29", "$f30", "$f31",
208
415
        // Hi/lo and condition register names
209
415
        "hi", "lo", "", "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5",
210
415
        "$fcc6", "$fcc7", "$ac1hi", "$ac1lo", "$ac2hi", "$ac2lo", "$ac3hi",
211
415
        "$ac3lo",
212
415
        // MSA register names
213
415
        "$w0", "$w1", "$w2", "$w3", "$w4", "$w5", "$w6", "$w7", "$w8", "$w9",
214
415
        "$w10", "$w11", "$w12", "$w13", "$w14", "$w15", "$w16", "$w17", "$w18",
215
415
        "$w19", "$w20", "$w21", "$w22", "$w23", "$w24", "$w25", "$w26", "$w27",
216
415
        "$w28", "$w29", "$w30", "$w31",
217
415
        // MSA control register names
218
415
        "$msair", "$msacsr", "$msaaccess", "$msasave", "$msamodify",
219
415
        "$msarequest", "$msamap", "$msaunmap"
220
415
    };
221
415
    return llvm::makeArrayRef(GCCRegNames);
222
415
  }
223
224
  bool validateAsmConstraint(const char *&Name,
225
18
                             TargetInfo::ConstraintInfo &Info) const override {
226
18
    switch (*Name) {
227
0
    default:
228
0
      return false;
229
10
    case 'r': // CPU registers.
230
10
    case 'd': // Equivalent to "r" unless generating MIPS16 code.
231
10
    case 'y': // Equivalent to "r", backward compatibility only.
232
10
    case 'f': // floating-point registers.
233
10
    case 'c': // $25 for indirect jumps
234
10
    case 'l': // lo register
235
10
    case 'x': // hilo register pair
236
10
      Info.setAllowsRegister();
237
10
      return true;
238
2
    case 'I': // Signed 16-bit constant
239
2
    case 'J': // Integer 0
240
2
    case 'K': // Unsigned 16-bit constant
241
2
    case 'L': // Signed 32-bit constant, lower 16-bit zeros (for lui)
242
2
    case 'M': // Constants not loadable via lui, addiu, or ori
243
2
    case 'N': // Constant -1 to -65535
244
2
    case 'O': // A signed 15-bit constant
245
2
    case 'P': // A constant between 1 go 65535
246
2
      return true;
247
4
    case 'R': // An address that can be used in a non-macro load or store
248
4
      Info.setAllowsMemory();
249
4
      return true;
250
2
    case 'Z':
251
2
      if (
Name[1] == 'C'2
) { // An address usable by ll, and sc.
252
2
        Info.setAllowsMemory();
253
2
        Name++; // Skip over 'Z'.
254
2
        return true;
255
2
      }
256
0
      return false;
257
18
    }
258
18
  }
259
260
263
  std::string convertConstraint(const char *&Constraint) const override {
261
263
    std::string R;
262
263
    switch (*Constraint) {
263
1
    case 'Z': // Two-character constraint; add "^" hint for later parsing.
264
1
      if (
Constraint[1] == 'C'1
) {
265
1
        R = std::string("^") + std::string(Constraint, 2);
266
1
        Constraint++;
267
1
        return R;
268
1
      }
269
0
      break;
270
263
    }
271
262
    return TargetInfo::convertConstraint(Constraint);
272
263
  }
273
274
220
  const char *getClobbers() const override {
275
220
    // In GCC, $1 is not widely used in generated code (it's used only in a few
276
220
    // specific situations), so there is no real need for users to add it to
277
220
    // the clobbers list if they want to use it in their inline assembly code.
278
220
    //
279
220
    // In LLVM, $1 is treated as a normal GPR and is always allocatable during
280
220
    // code generation, so using it in inline assembly without adding it to the
281
220
    // clobbers list can cause conflicts between the inline assembly code and
282
220
    // the surrounding generated code.
283
220
    //
284
220
    // Another problem is that LLVM is allowed to choose $1 for inline assembly
285
220
    // operands, which will conflict with the ".set at" assembler option (which
286
220
    // we use only for inline assembly, in order to maintain compatibility with
287
220
    // GCC) and will also conflict with the user's usage of $1.
288
220
    //
289
220
    // The easiest way to avoid these conflicts and keep $1 as an allocatable
290
220
    // register for generated code is to automatically clobber $1 for all inline
291
220
    // assembly code.
292
220
    //
293
220
    // FIXME: We should automatically clobber $1 only for inline assembly code
294
220
    // which actually uses it. This would allow LLVM to use $1 for inline
295
220
    // assembly operands if the user's assembly code doesn't use it.
296
220
    return "~{$1}";
297
220
  }
298
299
  bool handleTargetFeatures(std::vector<std::string> &Features,
300
191
                            DiagnosticsEngine &Diags) override {
301
191
    IsMips16 = false;
302
191
    IsMicromips = false;
303
191
    IsNan2008 = isIEEE754_2008Default();
304
191
    IsAbs2008 = isIEEE754_2008Default();
305
191
    IsSingleFloat = false;
306
191
    FloatABI = HardFloat;
307
191
    DspRev = NoDSP;
308
191
    HasFP64 = isFP64Default();
309
191
310
272
    for (const auto &Feature : Features) {
311
272
      if (Feature == "+single-float")
312
4
        IsSingleFloat = true;
313
268
      else 
if (268
Feature == "+soft-float"268
)
314
3
        FloatABI = SoftFloat;
315
265
      else 
if (265
Feature == "+mips16"265
)
316
1
        IsMips16 = true;
317
264
      else 
if (264
Feature == "+micromips"264
)
318
1
        IsMicromips = true;
319
263
      else 
if (263
Feature == "+dsp"263
)
320
1
        DspRev = std::max(DspRev, DSP1);
321
262
      else 
if (262
Feature == "+dspr2"262
)
322
1
        DspRev = std::max(DspRev, DSP2);
323
261
      else 
if (261
Feature == "+msa"261
)
324
3
        HasMSA = true;
325
258
      else 
if (258
Feature == "+nomadd4"258
)
326
3
        DisableMadd4 = true;
327
255
      else 
if (255
Feature == "+fp64"255
)
328
5
        HasFP64 = true;
329
250
      else 
if (250
Feature == "-fp64"250
)
330
2
        HasFP64 = false;
331
248
      else 
if (248
Feature == "+nan2008"248
)
332
6
        IsNan2008 = true;
333
242
      else 
if (242
Feature == "-nan2008"242
)
334
7
        IsNan2008 = false;
335
235
      else 
if (235
Feature == "+abs2008"235
)
336
2
        IsAbs2008 = true;
337
233
      else 
if (233
Feature == "-abs2008"233
)
338
2
        IsAbs2008 = false;
339
231
      else 
if (231
Feature == "+noabicalls"231
)
340
0
        IsNoABICalls = true;
341
272
    }
342
191
343
191
    setDataLayout();
344
191
345
191
    return true;
346
191
  }
347
348
4
  int getEHDataRegisterNumber(unsigned RegNo) const override {
349
4
    if (RegNo == 0)
350
2
      return 4;
351
2
    
if (2
RegNo == 12
)
352
2
      return 5;
353
0
    return -1;
354
4
  }
355
356
6
  bool isCLZForZeroUndef() const override { return false; }
357
358
312
  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
359
312
    static const TargetInfo::GCCRegAlias O32RegAliases[] = {
360
312
        {{"at"}, "$1"},  {{"v0"}, "$2"},         {{"v1"}, "$3"},
361
312
        {{"a0"}, "$4"},  {{"a1"}, "$5"},         {{"a2"}, "$6"},
362
312
        {{"a3"}, "$7"},  {{"t0"}, "$8"},         {{"t1"}, "$9"},
363
312
        {{"t2"}, "$10"}, {{"t3"}, "$11"},        {{"t4"}, "$12"},
364
312
        {{"t5"}, "$13"}, {{"t6"}, "$14"},        {{"t7"}, "$15"},
365
312
        {{"s0"}, "$16"}, {{"s1"}, "$17"},        {{"s2"}, "$18"},
366
312
        {{"s3"}, "$19"}, {{"s4"}, "$20"},        {{"s5"}, "$21"},
367
312
        {{"s6"}, "$22"}, {{"s7"}, "$23"},        {{"t8"}, "$24"},
368
312
        {{"t9"}, "$25"}, {{"k0"}, "$26"},        {{"k1"}, "$27"},
369
312
        {{"gp"}, "$28"}, {{"sp", "$sp"}, "$29"}, {{"fp", "$fp"}, "$30"},
370
312
        {{"ra"}, "$31"}
371
312
    };
372
312
    static const TargetInfo::GCCRegAlias NewABIRegAliases[] = {
373
312
        {{"at"}, "$1"},  {{"v0"}, "$2"},         {{"v1"}, "$3"},
374
312
        {{"a0"}, "$4"},  {{"a1"}, "$5"},         {{"a2"}, "$6"},
375
312
        {{"a3"}, "$7"},  {{"a4"}, "$8"},         {{"a5"}, "$9"},
376
312
        {{"a6"}, "$10"}, {{"a7"}, "$11"},        {{"t0"}, "$12"},
377
312
        {{"t1"}, "$13"}, {{"t2"}, "$14"},        {{"t3"}, "$15"},
378
312
        {{"s0"}, "$16"}, {{"s1"}, "$17"},        {{"s2"}, "$18"},
379
312
        {{"s3"}, "$19"}, {{"s4"}, "$20"},        {{"s5"}, "$21"},
380
312
        {{"s6"}, "$22"}, {{"s7"}, "$23"},        {{"t8"}, "$24"},
381
312
        {{"t9"}, "$25"}, {{"k0"}, "$26"},        {{"k1"}, "$27"},
382
312
        {{"gp"}, "$28"}, {{"sp", "$sp"}, "$29"}, {{"fp", "$fp"}, "$30"},
383
312
        {{"ra"}, "$31"}
384
312
    };
385
312
    if (ABI == "o32")
386
312
      return llvm::makeArrayRef(O32RegAliases);
387
0
    return llvm::makeArrayRef(NewABIRegAliases);
388
312
  }
389
390
512
  bool hasInt128Type() const override 
{ return ABI == "n32" || 512
ABI == "n64"472
; }
391
392
  bool validateTarget(DiagnosticsEngine &Diags) const override;
393
};
394
} // namespace targets
395
} // namespace clang
396
397
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H