Coverage Report

Created: 2025-07-14 06:17

/src/keystone/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===//
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 provides ARM specific target descriptions.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "ARMBaseInfo.h"
15
#include "ARMMCAsmInfo.h"
16
#include "ARMMCTargetDesc.h"
17
#include "llvm/ADT/Triple.h"
18
#include "llvm/MC/MCELFStreamer.h"
19
#include "llvm/MC/MCInstrInfo.h"
20
#include "llvm/MC/MCRegisterInfo.h"
21
#include "llvm/MC/MCStreamer.h"
22
#include "llvm/MC/MCSubtargetInfo.h"
23
#include "llvm/Support/ErrorHandling.h"
24
#include "llvm/Support/TargetParser.h"
25
#include "llvm/Support/TargetRegistry.h"
26
27
using namespace llvm_ks;
28
29
#define GET_REGINFO_MC_DESC
30
#include "ARMGenRegisterInfo.inc"
31
32
static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
33
0
                                  std::string &Info) {
34
0
  if (STI.getFeatureBits()[llvm_ks::ARM::HasV7Ops] &&
35
0
      (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 15) &&
36
0
      (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) &&
37
      // Checks for the deprecated CP15ISB encoding:
38
      // mcr p15, #0, rX, c7, c5, #4
39
0
      (MI.getOperand(3).isImm() && MI.getOperand(3).getImm() == 7)) {
40
0
    if ((MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 4)) {
41
0
      if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 5) {
42
0
        Info = "deprecated since v7, use 'isb'";
43
0
        return true;
44
0
      }
45
46
      // Checks for the deprecated CP15DSB encoding:
47
      // mcr p15, #0, rX, c7, c10, #4
48
0
      if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10) {
49
0
        Info = "deprecated since v7, use 'dsb'";
50
0
        return true;
51
0
      }
52
0
    }
53
    // Checks for the deprecated CP15DMB encoding:
54
    // mcr p15, #0, rX, c7, c10, #5
55
0
    if (MI.getOperand(4).isImm() && MI.getOperand(4).getImm() == 10 &&
56
0
        (MI.getOperand(5).isImm() && MI.getOperand(5).getImm() == 5)) {
57
0
      Info = "deprecated since v7, use 'dmb'";
58
0
      return true;
59
0
    }
60
0
  }
61
0
  return false;
62
0
}
63
64
static bool getITDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
65
3.40k
                                 std::string &Info) {
66
3.40k
  if (STI.getFeatureBits()[llvm_ks::ARM::HasV8Ops] && MI.getOperand(1).isImm() &&
67
3.40k
      MI.getOperand(1).getImm() != 8) {
68
130
    Info = "applying IT instruction to more than one subsequent instruction is "
69
130
           "deprecated";
70
130
    return true;
71
130
  }
72
73
3.27k
  return false;
74
3.40k
}
75
76
static bool getARMStoreDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
77
0
                                       std::string &Info) {
78
0
  assert(!STI.getFeatureBits()[llvm_ks::ARM::ModeThumb] &&
79
0
         "cannot predicate thumb instructions");
80
81
0
  assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
82
0
  for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
83
0
    assert(MI.getOperand(OI).isReg() && "expected register");
84
0
    if (MI.getOperand(OI).getReg() == ARM::SP ||
85
0
        MI.getOperand(OI).getReg() == ARM::PC) {
86
0
      Info = "use of SP or PC in the list is deprecated";
87
0
      return true;
88
0
    }
89
0
  }
90
0
  return false;
91
0
}
92
93
static bool getARMLoadDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI,
94
0
                                      std::string &Info) {
95
0
  assert(!STI.getFeatureBits()[llvm_ks::ARM::ModeThumb] &&
96
0
         "cannot predicate thumb instructions");
97
98
0
  assert(MI.getNumOperands() >= 4 && "expected >= 4 arguments");
99
0
  bool ListContainsPC = false, ListContainsLR = false;
100
0
  for (unsigned OI = 4, OE = MI.getNumOperands(); OI < OE; ++OI) {
101
0
    assert(MI.getOperand(OI).isReg() && "expected register");
102
0
    switch (MI.getOperand(OI).getReg()) {
103
0
    default:
104
0
      break;
105
0
    case ARM::LR:
106
0
      ListContainsLR = true;
107
0
      break;
108
0
    case ARM::PC:
109
0
      ListContainsPC = true;
110
0
      break;
111
0
    case ARM::SP:
112
0
      Info = "use of SP in the list is deprecated";
113
0
      return true;
114
0
    }
115
0
  }
116
117
0
  if (ListContainsPC && ListContainsLR) {
118
0
    Info = "use of LR and PC simultaneously in the list is deprecated";
119
0
    return true;
120
0
  }
121
122
0
  return false;
123
0
}
124
125
#define GET_INSTRINFO_MC_DESC
126
#include "ARMGenInstrInfo.inc"
127
128
#define GET_SUBTARGETINFO_MC_DESC
129
#include "ARMGenSubtargetInfo.inc"
130
131
121k
std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
132
121k
  bool isThumb =
133
121k
      TT.getArch() == Triple::thumb || TT.getArch() == Triple::thumbeb;
134
135
121k
  std::string ARMArchFeature;
136
137
121k
  unsigned ArchID = ARM::parseArch(TT.getArchName());
138
121k
  if (ArchID != ARM::AK_INVALID &&  (CPU.empty() || CPU == "generic"))
139
121k
    ARMArchFeature = (ARMArchFeature + "+" + ARM::getArchName(ArchID)).str();
140
141
121k
  if (isThumb) {
142
65.0k
    if (ARMArchFeature.empty())
143
0
      ARMArchFeature = "+thumb-mode";
144
65.0k
    else
145
65.0k
      ARMArchFeature += ",+thumb-mode";
146
65.0k
  }
147
148
121k
  if (TT.isOSNaCl()) {
149
0
    if (ARMArchFeature.empty())
150
0
      ARMArchFeature = "+nacl-trap";
151
0
    else
152
0
      ARMArchFeature += ",+nacl-trap";
153
0
  }
154
155
121k
  return ARMArchFeature;
156
121k
}
157
158
MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(const Triple &TT,
159
121k
                                                  StringRef CPU, StringRef FS) {
160
121k
  std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU);
161
121k
  if (!FS.empty()) {
162
0
    if (!ArchFS.empty())
163
0
      ArchFS = (Twine(ArchFS) + "," + FS).str();
164
0
    else
165
0
      ArchFS = FS;
166
0
  }
167
168
121k
  return createARMMCSubtargetInfoImpl(TT, CPU, ArchFS);
169
121k
}
170
171
60.5k
static MCInstrInfo *createARMMCInstrInfo() {
172
60.5k
  MCInstrInfo *X = new MCInstrInfo();
173
60.5k
  InitARMMCInstrInfo(X);
174
60.5k
  return X;
175
60.5k
}
176
177
60.5k
static MCRegisterInfo *createARMMCRegisterInfo(const Triple &Triple) {
178
60.5k
  MCRegisterInfo *X = new MCRegisterInfo();
179
60.5k
  InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
180
60.5k
  return X;
181
60.5k
}
182
183
static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI,
184
60.5k
                                     const Triple &TheTriple) {
185
60.5k
  MCAsmInfo *MAI;
186
60.5k
  if (TheTriple.isOSDarwin() || TheTriple.isOSBinFormatMachO())
187
0
    MAI = new ARMMCAsmInfoDarwin(TheTriple);
188
60.5k
  else if (TheTriple.isWindowsMSVCEnvironment())
189
0
    MAI = new ARMCOFFMCAsmInfoMicrosoft();
190
60.5k
  else if (TheTriple.isOSWindows())
191
0
    MAI = new ARMCOFFMCAsmInfoGNU();
192
60.5k
  else
193
60.5k
    MAI = new ARMELFMCAsmInfo(TheTriple);
194
195
60.5k
  return MAI;
196
60.5k
}
197
198
// Force static initialization.
199
26
extern "C" void LLVMInitializeARMTargetMC() {
200
26
  for (Target *T : {&TheARMLETarget, &TheARMBETarget, &TheThumbLETarget,
201
104
                    &TheThumbBETarget}) {
202
    // Register the MC asm info.
203
104
    RegisterMCAsmInfoFn X(*T, createARMMCAsmInfo);
204
205
    // Register the MC instruction info.
206
104
    TargetRegistry::RegisterMCInstrInfo(*T, createARMMCInstrInfo);
207
208
    // Register the MC register info.
209
104
    TargetRegistry::RegisterMCRegInfo(*T, createARMMCRegisterInfo);
210
211
    // Register the MC subtarget info.
212
104
    TargetRegistry::RegisterMCSubtargetInfo(*T,
213
104
                                            ARM_MC::createARMMCSubtargetInfo);
214
104
  }
215
216
  // Register the MC Code Emitter
217
26
  for (Target *T : {&TheARMLETarget, &TheThumbLETarget})
218
52
    TargetRegistry::RegisterMCCodeEmitter(*T, createARMLEMCCodeEmitter);
219
26
  for (Target *T : {&TheARMBETarget, &TheThumbBETarget})
220
52
    TargetRegistry::RegisterMCCodeEmitter(*T, createARMBEMCCodeEmitter);
221
222
  // Register the asm backend.
223
26
  TargetRegistry::RegisterMCAsmBackend(TheARMLETarget, createARMLEAsmBackend);
224
26
  TargetRegistry::RegisterMCAsmBackend(TheARMBETarget, createARMBEAsmBackend);
225
26
  TargetRegistry::RegisterMCAsmBackend(TheThumbLETarget,
226
26
                                       createThumbLEAsmBackend);
227
26
  TargetRegistry::RegisterMCAsmBackend(TheThumbBETarget,
228
26
                                       createThumbBEAsmBackend);
229
26
}