Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
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
// This file provides ARM specific target descriptions.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "ARMMCTargetDesc.h"
14
#include "ARMBaseInfo.h"
15
#include "ARMInstPrinter.h"
16
#include "ARMMCAsmInfo.h"
17
#include "TargetInfo/ARMTargetInfo.h"
18
#include "llvm/ADT/Triple.h"
19
#include "llvm/MC/MCAsmBackend.h"
20
#include "llvm/MC/MCCodeEmitter.h"
21
#include "llvm/MC/MCELFStreamer.h"
22
#include "llvm/MC/MCInstrAnalysis.h"
23
#include "llvm/MC/MCInstrInfo.h"
24
#include "llvm/MC/MCObjectWriter.h"
25
#include "llvm/MC/MCRegisterInfo.h"
26
#include "llvm/MC/MCStreamer.h"
27
#include "llvm/MC/MCSubtargetInfo.h"
28
#include "llvm/Support/ErrorHandling.h"
29
#include "llvm/Support/TargetParser.h"
30
#include "llvm/Support/TargetRegistry.h"
31
32
using namespace llvm;
33
34
#define GET_REGINFO_MC_DESC
35
#include "ARMGenRegisterInfo.inc"
36
37
static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
38
34
                                  std::string &Info) {
39
34
  if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] &&
40
34
      
(29
MI.getOperand(0).isImm()29
&&
MI.getOperand(0).getImm() == 1529
) &&
41
34
      
(12
MI.getOperand(1).isImm()12
&&
MI.getOperand(1).getImm() == 012
) &&
42
34
      // Checks for the deprecated CP15ISB encoding:
43
34
      // mcr p15, #0, rX, c7, c5, #4
44
34
      
(12
MI.getOperand(3).isImm()12
&&
MI.getOperand(3).getImm() == 712
)) {
45
12
    if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
46
8
      if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
47
4
        Info = "deprecated since v7, use 'isb'";
48
4
        return true;
49
4
      }
50
4
51
4
      // Checks for the deprecated CP15DSB encoding:
52
4
      // mcr p15, #0, rX, c7, c10, #4
53
4
      if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
54
4
        Info = "deprecated since v7, use 'dsb'";
55
4
        return true;
56
4
      }
57
4
    }
58
4
    // Checks for the deprecated CP15DMB encoding:
59
4
    // mcr p15, #0, rX, c7, c10, #5
60
4
    if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
61
4
        (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
62
4
      Info = "deprecated since v7, use 'dmb'";
63
4
      return true;
64
4
    }
65
22
  }
66
22
  return false;
67
22
}
68
69
static bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
70
3.82k
                                 std::string &Info) {
71
3.82k
  if (STI.getFeatureBits()[llvm::ARM::HasV8Ops] && 
MI.getOperand(1).isImm()2.23k
&&
72
3.82k
      
MI.getOperand(1).getImm() != 82.23k
) {
73
13
    Info = "applying IT instruction to more than one subsequent instruction is "
74
13
           "deprecated";
75
13
    return true;
76
13
  }
77
3.81k
78
3.81k
  return false;
79
3.81k
}
80
81
static bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
82
132
                                       std::string &Info) {
83
132
  assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
84
132
         "cannot predicate thumb instructions");
85
132
86
132
  assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
87
425
  for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; 
++OI293
) {
88
367
    assert(MI.getOperand(OI).isReg() && "expected register");
89
367
    if (MI.getOperand(OI).getReg() == ARM::SP ||
90
367
        
MI.getOperand(OI).getReg() == ARM::PC313
) {
91
74
      Info = "use of SP or PC in the list is deprecated";
92
74
      return true;
93
74
    }
94
367
  }
95
132
  
return false58
;
96
132
}
97
98
static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
99
120
                                      std::string &Info) {
100
120
  assert(!STI.getFeatureBits()[llvm::ARM::ModeThumb] &&
101
120
         "cannot predicate thumb instructions");
102
120
103
120
  assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
104
120
  bool ListContainsPC = false, ListContainsLR = false;
105
455
  for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; 
++OI335
) {
106
377
    assert(MI.getOperand(OI).isReg() && "expected register");
107
377
    switch (MI.getOperand(OI).getReg()) {
108
377
    default:
109
271
      break;
110
377
    case ARM::LR:
111
33
      ListContainsLR = true;
112
33
      break;
113
377
    case ARM::PC:
114
31
      ListContainsPC = true;
115
31
      break;
116
377
    case ARM::SP:
117
42
      Info = "use of SP in the list is deprecated";
118
42
      return true;
119
377
    }
120
377
  }
121
120
122
120
  
if (78
ListContainsPC78
&&
ListContainsLR31
) {
123
20
    Info = "use of LR and PC simultaneously in the list is deprecated";
124
20
    return true;
125
20
  }
126
58
127
58
  return false;
128
58
}
129
130
#define GET_INSTRINFO_MC_DESC
131
#include "ARMGenInstrInfo.inc"
132
133
#define GET_SUBTARGETINFO_MC_DESC
134
#include "ARMGenSubtargetInfo.inc"
135
136
18.4k
std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
137
18.4k
  std::string ARMArchFeature;
138
18.4k
139
18.4k
  ARM::ArchKind ArchID = ARM::parseArch(TT.getArchName());
140
18.4k
  if (ArchID != ARM::ArchKind::INVALID &&  
(13.8k
CPU.empty()13.8k
||
CPU == "generic"9.44k
))
141
8.67k
    ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str();
142
18.4k
143
18.4k
  if (TT.isThumb()) {
144
10.2k
    if (!ARMArchFeature.empty())
145
5.24k
      ARMArchFeature += ",";
146
10.2k
    ARMArchFeature += "+thumb-mode,+v4t";
147
10.2k
  }
148
18.4k
149
18.4k
  if (TT.isOSNaCl()) {
150
19
    if (!ARMArchFeature.empty())
151
12
      ARMArchFeature += ",";
152
19
    ARMArchFeature += "+nacl-trap";
153
19
  }
154
18.4k
155
18.4k
  if (TT.isOSWindows()) {
156
245
    if (!ARMArchFeature.empty())
157
242
      ARMArchFeature += ",";
158
245
    ARMArchFeature += "+noarm";
159
245
  }
160
18.4k
161
18.4k
  return ARMArchFeature;
162
18.4k
}
163
164
MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
165
8.82k
                                                  StringRef CPU, StringRef FS) {
166
8.82k
  std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
167
8.82k
  if (!FS.empty()) {
168
4.83k
    if (!ArchFS.empty())
169
4.09k
      ArchFS = (Twine(ArchFS) + "," + FS).str();
170
732
    else
171
732
      ArchFS = FS;
172
4.83k
  }
173
8.82k
174
8.82k
  return createARMMCSubtargetInfoImpl(TT, CPU, ArchFS);
175
8.82k
}
176
177
8.92k
static MCInstrInfo *createARMMCInstrInfo() {
178
8.92k
  MCInstrInfo *X = new MCInstrInfo();
179
8.92k
  InitARMMCInstrInfo(X);
180
8.92k
  return X;
181
8.92k
}
182
183
8.61k
static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) {
184
8.61k
  MCRegisterInfo *X = new MCRegisterInfo();
185
8.61k
  InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
186
8.61k
  return X;
187
8.61k
}
188
189
static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI,
190
8.58k
                                     const Triple &TheTriple) {
191
8.58k
  MCAsmInfo *MAI;
192
8.58k
  if (TheTriple.isOSDarwin() || 
TheTriple.isOSBinFormatMachO()5.44k
)
193
3.98k
    MAI = new ARMMCAsmInfoDarwin(TheTriple);
194
4.60k
  else if (TheTriple.isWindowsMSVCEnvironment())
195
91
    MAI = new ARMCOFFMCAsmInfoMicrosoft();
196
4.51k
  else if (TheTriple.isOSWindows())
197
67
    MAI = new ARMCOFFMCAsmInfoGNU();
198
4.44k
  else
199
4.44k
    MAI = new ARMELFMCAsmInfo(TheTriple);
200
8.58k
201
8.58k
  unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
202
8.58k
  MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(nullptr, Reg, 0));
203
8.58k
204
8.58k
  return MAI;
205
8.58k
}
206
207
static MCStreamer *createELFStreamer(const Triple &T, MCContext &Ctx,
208
                                     std::unique_ptr<MCAsmBackend> &&MAB,
209
                                     std::unique_ptr<MCObjectWriter> &&OW,
210
                                     std::unique_ptr<MCCodeEmitter> &&Emitter,
211
457
                                     bool RelaxAll) {
212
457
  return createARMELFStreamer(
213
457
      Ctx, std::move(MAB), std::move(OW), std::move(Emitter), false,
214
457
      (T.getArch() == Triple::thumb || 
T.getArch() == Triple::thumbeb355
));
215
457
}
216
217
static MCStreamer *
218
createARMMachOStreamer(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&MAB,
219
                       std::unique_ptr<MCObjectWriter> &&OW,
220
                       std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
221
2.90k
                       bool DWARFMustBeAtTheEnd) {
222
2.90k
  return createMachOStreamer(Ctx, std::move(MAB), std::move(OW),
223
2.90k
                             std::move(Emitter), false, DWARFMustBeAtTheEnd);
224
2.90k
}
225
226
static MCInstPrinter *createARMMCInstPrinter(const Triple &T,
227
                                             unsigned SyntaxVariant,
228
                                             const MCAsmInfo &MAI,
229
                                             const MCInstrInfo &MII,
230
4.11k
                                             const MCRegisterInfo &MRI) {
231
4.11k
  if (SyntaxVariant == 0)
232
4.11k
    return new ARMInstPrinter(MAI, MII, MRI);
233
0
  return nullptr;
234
0
}
235
236
static MCRelocationInfo *createARMMCRelocationInfo(const Triple &TT,
237
39
                                                   MCContext &Ctx) {
238
39
  if (TT.isOSBinFormatMachO())
239
35
    return createARMMachORelocationInfo(Ctx);
240
4
  // Default to the stock relocation info.
241
4
  return llvm::createMCRelocationInfo(TT, Ctx);
242
4
}
243
244
namespace {
245
246
class ARMMCInstrAnalysis : public MCInstrAnalysis {
247
public:
248
239
  ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {}
249
250
11.8k
  bool isUnconditionalBranch(const MCInst &Inst) const override {
251
11.8k
    // BCCs with the "always" predicate are unconditional branches.
252
11.8k
    if (Inst.getOpcode() == ARM::Bcc && 
Inst.getOperand(1).getImm()==ARMCC::AL146
)
253
60
      return true;
254
11.7k
    return MCInstrAnalysis::isUnconditionalBranch(Inst);
255
11.7k
  }
256
257
11.6k
  bool isConditionalBranch(const MCInst &Inst) const override {
258
11.6k
    // BCCs with the "always" predicate are unconditional branches.
259
11.6k
    if (Inst.getOpcode() == ARM::Bcc && 
Inst.getOperand(1).getImm()==ARMCC::AL86
)
260
0
      return false;
261
11.6k
    return MCInstrAnalysis::isConditionalBranch(Inst);
262
11.6k
  }
263
264
  bool evaluateBranch(const MCInst &Inst, uint64_t Addr,
265
358
                      uint64_t Size, uint64_t &Target) const override {
266
358
    // We only handle PCRel branches for now.
267
358
    if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL)
268
25
      return false;
269
333
270
333
    int64_t Imm = Inst.getOperand(0).getImm();
271
333
    Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes.
272
333
    return true;
273
333
  }
274
};
275
276
class ThumbMCInstrAnalysis : public ARMMCInstrAnalysis {
277
public:
278
128
  ThumbMCInstrAnalysis(const MCInstrInfo *Info) : ARMMCInstrAnalysis(Info) {}
279
280
  bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
281
600
                      uint64_t &Target) const override {
282
600
    unsigned OpId;
283
600
    switch (Inst.getOpcode()) {
284
600
    default:
285
600
      OpId = 0;
286
600
      break;
287
600
    case ARM::t2WLS:
288
0
    case ARM::t2LEUpdate:
289
0
      OpId = 2;
290
0
      break;
291
0
    case ARM::t2LE:
292
0
      OpId = 1;
293
0
      break;
294
600
    }
295
600
296
600
    // We only handle PCRel branches for now.
297
600
    if (Info->get(Inst.getOpcode()).OpInfo[OpId].OperandType !=
298
600
        MCOI::OPERAND_PCREL)
299
315
      return false;
300
285
301
285
    // In Thumb mode the PC is always off by 4 bytes.
302
285
    Target = Addr + Inst.getOperand(OpId).getImm() + 4;
303
285
    return true;
304
285
  }
305
};
306
307
}
308
309
111
static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) {
310
111
  return new ARMMCInstrAnalysis(Info);
311
111
}
312
313
128
static MCInstrAnalysis *createThumbMCInstrAnalysis(const MCInstrInfo *Info) {
314
128
  return new ThumbMCInstrAnalysis(Info);
315
128
}
316
317
// Force static initialization.
318
96.4k
extern "C" void LLVMInitializeARMTargetMC() {
319
96.4k
  for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget(),
320
385k
                    &getTheThumbLETarget(), &getTheThumbBETarget()}) {
321
385k
    // Register the MC asm info.
322
385k
    RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo);
323
385k
324
385k
    // Register the MC instruction info.
325
385k
    TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo);
326
385k
327
385k
    // Register the MC register info.
328
385k
    TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo);
329
385k
330
385k
    // Register the MC subtarget info.
331
385k
    TargetRegistry::RegisterMCSubtargetInfo(*T,
332
385k
                                            ARM_MC::createARMMCSubtargetInfo);
333
385k
334
385k
    TargetRegistry::RegisterELFStreamer(*T, createELFStreamer);
335
385k
    TargetRegistry::RegisterCOFFStreamer(*T, createARMWinCOFFStreamer);
336
385k
    TargetRegistry::RegisterMachOStreamer(*T, createARMMachOStreamer);
337
385k
338
385k
    // Register the obj target streamer.
339
385k
    TargetRegistry::RegisterObjectTargetStreamer(*T,
340
385k
                                                 createARMObjectTargetStreamer);
341
385k
342
385k
    // Register the asm streamer.
343
385k
    TargetRegistry::RegisterAsmTargetStreamer(*T, createARMTargetAsmStreamer);
344
385k
345
385k
    // Register the null TargetStreamer.
346
385k
    TargetRegistry::RegisterNullTargetStreamer(*T, createARMNullTargetStreamer);
347
385k
348
385k
    // Register the MCInstPrinter.
349
385k
    TargetRegistry::RegisterMCInstPrinter(*T, createARMMCInstPrinter);
350
385k
351
385k
    // Register the MC relocation info.
352
385k
    TargetRegistry::RegisterMCRelocationInfo(*T, createARMMCRelocationInfo);
353
385k
  }
354
96.4k
355
96.4k
  // Register the MC instruction analyzer.
356
96.4k
  for (Target *T : {&getTheARMLETarget(), &getTheARMBETarget()})
357
192k
    TargetRegistry::RegisterMCInstrAnalysis(*T, createARMMCInstrAnalysis);
358
96.4k
  for (Target *T : {&getTheThumbLETarget(), &getTheThumbBETarget()})
359
192k
    TargetRegistry::RegisterMCInstrAnalysis(*T, createThumbMCInstrAnalysis);
360
96.4k
361
192k
  for (Target *T : {&getTheARMLETarget(), &getTheThumbLETarget()}) {
362
192k
    TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter);
363
192k
    TargetRegistry::RegisterMCAsmBackend(*T, createARMLEAsmBackend);
364
192k
  }
365
192k
  for (Target *T : {&getTheARMBETarget(), &getTheThumbBETarget()}) {
366
192k
    TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter);
367
192k
    TargetRegistry::RegisterMCAsmBackend(*T, createARMBEAsmBackend);
368
192k
  }
369
96.4k
}