Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- SparcAsmBackend.cpp - Sparc Assembler Backend ---------------------===//
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 "MCTargetDesc/SparcFixupKinds.h"
10
#include "MCTargetDesc/SparcMCTargetDesc.h"
11
#include "llvm/MC/MCAsmBackend.h"
12
#include "llvm/MC/MCELFObjectWriter.h"
13
#include "llvm/MC/MCExpr.h"
14
#include "llvm/MC/MCFixupKindInfo.h"
15
#include "llvm/MC/MCObjectWriter.h"
16
#include "llvm/MC/MCSubtargetInfo.h"
17
#include "llvm/MC/MCValue.h"
18
#include "llvm/Support/TargetRegistry.h"
19
20
using namespace llvm;
21
22
317
static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
23
317
  switch (Kind) {
24
317
  default:
25
0
    llvm_unreachable("Unknown fixup kind!");
26
317
  case FK_Data_1:
27
129
  case FK_Data_2:
28
129
  case FK_Data_4:
29
129
  case FK_Data_8:
30
129
    return Value;
31
129
32
129
  case Sparc::fixup_sparc_wplt30:
33
17
  case Sparc::fixup_sparc_call30:
34
17
    return (Value >> 2) & 0x3fffffff;
35
17
36
17
  case Sparc::fixup_sparc_br22:
37
1
    return (Value >> 2) & 0x3fffff;
38
17
39
17
  case Sparc::fixup_sparc_br19:
40
0
    return (Value >> 2) & 0x7ffff;
41
17
42
17
  case Sparc::fixup_sparc_br16_2:
43
0
    return (Value >> 2) & 0xc000;
44
17
45
17
  case Sparc::fixup_sparc_br16_14:
46
0
    return (Value >> 2) & 0x3fff;
47
17
48
40
  case Sparc::fixup_sparc_pc22:
49
40
  case Sparc::fixup_sparc_got22:
50
40
  case Sparc::fixup_sparc_tls_gd_hi22:
51
40
  case Sparc::fixup_sparc_tls_ldm_hi22:
52
40
  case Sparc::fixup_sparc_tls_ie_hi22:
53
40
  case Sparc::fixup_sparc_hi22:
54
40
    return (Value >> 10) & 0x3fffff;
55
40
56
40
  case Sparc::fixup_sparc_got13:
57
3
  case Sparc::fixup_sparc_13:
58
3
    return Value & 0x1fff;
59
3
60
40
  case Sparc::fixup_sparc_pc10:
61
40
  case Sparc::fixup_sparc_got10:
62
40
  case Sparc::fixup_sparc_tls_gd_lo10:
63
40
  case Sparc::fixup_sparc_tls_ldm_lo10:
64
40
  case Sparc::fixup_sparc_tls_ie_lo10:
65
40
  case Sparc::fixup_sparc_lo10:
66
40
    return Value & 0x3ff;
67
40
68
40
  case Sparc::fixup_sparc_h44:
69
5
    return (Value >> 22) & 0x3fffff;
70
40
71
40
  case Sparc::fixup_sparc_m44:
72
5
    return (Value >> 12) & 0x3ff;
73
40
74
40
  case Sparc::fixup_sparc_l44:
75
5
    return Value & 0xfff;
76
40
77
40
  case Sparc::fixup_sparc_hh:
78
1
    return (Value >> 42) & 0x3fffff;
79
40
80
40
  case Sparc::fixup_sparc_hm:
81
1
    return (Value >> 32) & 0x3ff;
82
40
83
40
  case Sparc::fixup_sparc_tls_ldo_hix22:
84
24
  case Sparc::fixup_sparc_tls_le_hix22:
85
24
  case Sparc::fixup_sparc_tls_ldo_lox10:
86
24
  case Sparc::fixup_sparc_tls_le_lox10:
87
24
    assert(Value == 0 && "Sparc TLS relocs expect zero Value");
88
24
    return 0;
89
24
90
46
  case Sparc::fixup_sparc_tls_gd_add:
91
46
  case Sparc::fixup_sparc_tls_gd_call:
92
46
  case Sparc::fixup_sparc_tls_ldm_add:
93
46
  case Sparc::fixup_sparc_tls_ldm_call:
94
46
  case Sparc::fixup_sparc_tls_ldo_add:
95
46
  case Sparc::fixup_sparc_tls_ie_ld:
96
46
  case Sparc::fixup_sparc_tls_ie_ldx:
97
46
  case Sparc::fixup_sparc_tls_ie_add:
98
46
    return 0;
99
317
  }
100
317
}
101
102
/// getFixupKindNumBytes - The number of bytes the fixup may change.
103
83
static unsigned getFixupKindNumBytes(unsigned Kind) {
104
83
    switch (Kind) {
105
83
  default:
106
80
    return 4;
107
83
  case FK_Data_1:
108
1
    return 1;
109
83
  case FK_Data_2:
110
1
    return 2;
111
83
  case FK_Data_8:
112
1
    return 8;
113
83
  }
114
83
}
115
116
namespace {
117
  class SparcAsmBackend : public MCAsmBackend {
118
  protected:
119
    const Target &TheTarget;
120
    bool Is64Bit;
121
122
  public:
123
    SparcAsmBackend(const Target &T)
124
        : MCAsmBackend(StringRef(T.getName()) == "sparcel" ? support::little
125
                                                           : support::big),
126
260
          TheTarget(T), Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {}
127
128
0
    unsigned getNumFixupKinds() const override {
129
0
      return Sparc::NumTargetFixupKinds;
130
0
    }
131
132
2.06k
    const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
133
2.06k
      const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = {
134
2.06k
        // name                    offset bits  flags
135
2.06k
        { "fixup_sparc_call30",     2,     30,  MCFixupKindInfo::FKF_IsPCRel },
136
2.06k
        { "fixup_sparc_br22",      10,     22,  MCFixupKindInfo::FKF_IsPCRel },
137
2.06k
        { "fixup_sparc_br19",      13,     19,  MCFixupKindInfo::FKF_IsPCRel },
138
2.06k
        { "fixup_sparc_br16_2",    10,      2,  MCFixupKindInfo::FKF_IsPCRel },
139
2.06k
        { "fixup_sparc_br16_14",   18,     14,  MCFixupKindInfo::FKF_IsPCRel },
140
2.06k
        { "fixup_sparc_13",        19,     13,  0 },
141
2.06k
        { "fixup_sparc_hi22",      10,     22,  0 },
142
2.06k
        { "fixup_sparc_lo10",      22,     10,  0 },
143
2.06k
        { "fixup_sparc_h44",       10,     22,  0 },
144
2.06k
        { "fixup_sparc_m44",       22,     10,  0 },
145
2.06k
        { "fixup_sparc_l44",       20,     12,  0 },
146
2.06k
        { "fixup_sparc_hh",        10,     22,  0 },
147
2.06k
        { "fixup_sparc_hm",        22,     10,  0 },
148
2.06k
        { "fixup_sparc_pc22",      10,     22,  MCFixupKindInfo::FKF_IsPCRel },
149
2.06k
        { "fixup_sparc_pc10",      22,     10,  MCFixupKindInfo::FKF_IsPCRel },
150
2.06k
        { "fixup_sparc_got22",     10,     22,  0 },
151
2.06k
        { "fixup_sparc_got10",     22,     10,  0 },
152
2.06k
        { "fixup_sparc_got13",     19,     13,  0 },
153
2.06k
        { "fixup_sparc_wplt30",     2,     30,  MCFixupKindInfo::FKF_IsPCRel },
154
2.06k
        { "fixup_sparc_tls_gd_hi22",   10, 22,  0 },
155
2.06k
        { "fixup_sparc_tls_gd_lo10",   22, 10,  0 },
156
2.06k
        { "fixup_sparc_tls_gd_add",     0,  0,  0 },
157
2.06k
        { "fixup_sparc_tls_gd_call",    0,  0,  0 },
158
2.06k
        { "fixup_sparc_tls_ldm_hi22",  10, 22,  0 },
159
2.06k
        { "fixup_sparc_tls_ldm_lo10",  22, 10,  0 },
160
2.06k
        { "fixup_sparc_tls_ldm_add",    0,  0,  0 },
161
2.06k
        { "fixup_sparc_tls_ldm_call",   0,  0,  0 },
162
2.06k
        { "fixup_sparc_tls_ldo_hix22", 10, 22,  0 },
163
2.06k
        { "fixup_sparc_tls_ldo_lox10", 22, 10,  0 },
164
2.06k
        { "fixup_sparc_tls_ldo_add",    0,  0,  0 },
165
2.06k
        { "fixup_sparc_tls_ie_hi22",   10, 22,  0 },
166
2.06k
        { "fixup_sparc_tls_ie_lo10",   22, 10,  0 },
167
2.06k
        { "fixup_sparc_tls_ie_ld",      0,  0,  0 },
168
2.06k
        { "fixup_sparc_tls_ie_ldx",     0,  0,  0 },
169
2.06k
        { "fixup_sparc_tls_ie_add",     0,  0,  0 },
170
2.06k
        { "fixup_sparc_tls_le_hix22",   0,  0,  0 },
171
2.06k
        { "fixup_sparc_tls_le_lox10",   0,  0,  0 }
172
2.06k
      };
173
2.06k
174
2.06k
      const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
175
2.06k
        // name                    offset bits  flags
176
2.06k
        { "fixup_sparc_call30",     0,     30,  MCFixupKindInfo::FKF_IsPCRel },
177
2.06k
        { "fixup_sparc_br22",       0,     22,  MCFixupKindInfo::FKF_IsPCRel },
178
2.06k
        { "fixup_sparc_br19",       0,     19,  MCFixupKindInfo::FKF_IsPCRel },
179
2.06k
        { "fixup_sparc_br16_2",    20,      2,  MCFixupKindInfo::FKF_IsPCRel },
180
2.06k
        { "fixup_sparc_br16_14",    0,     14,  MCFixupKindInfo::FKF_IsPCRel },
181
2.06k
        { "fixup_sparc_13",         0,     13,  0 },
182
2.06k
        { "fixup_sparc_hi22",       0,     22,  0 },
183
2.06k
        { "fixup_sparc_lo10",       0,     10,  0 },
184
2.06k
        { "fixup_sparc_h44",        0,     22,  0 },
185
2.06k
        { "fixup_sparc_m44",        0,     10,  0 },
186
2.06k
        { "fixup_sparc_l44",        0,     12,  0 },
187
2.06k
        { "fixup_sparc_hh",         0,     22,  0 },
188
2.06k
        { "fixup_sparc_hm",         0,     10,  0 },
189
2.06k
        { "fixup_sparc_pc22",       0,     22,  MCFixupKindInfo::FKF_IsPCRel },
190
2.06k
        { "fixup_sparc_pc10",       0,     10,  MCFixupKindInfo::FKF_IsPCRel },
191
2.06k
        { "fixup_sparc_got22",      0,     22,  0 },
192
2.06k
        { "fixup_sparc_got10",      0,     10,  0 },
193
2.06k
        { "fixup_sparc_got13",      0,     13,  0 },
194
2.06k
        { "fixup_sparc_wplt30",      0,     30,  MCFixupKindInfo::FKF_IsPCRel },
195
2.06k
        { "fixup_sparc_tls_gd_hi22",    0, 22,  0 },
196
2.06k
        { "fixup_sparc_tls_gd_lo10",    0, 10,  0 },
197
2.06k
        { "fixup_sparc_tls_gd_add",     0,  0,  0 },
198
2.06k
        { "fixup_sparc_tls_gd_call",    0,  0,  0 },
199
2.06k
        { "fixup_sparc_tls_ldm_hi22",   0, 22,  0 },
200
2.06k
        { "fixup_sparc_tls_ldm_lo10",   0, 10,  0 },
201
2.06k
        { "fixup_sparc_tls_ldm_add",    0,  0,  0 },
202
2.06k
        { "fixup_sparc_tls_ldm_call",   0,  0,  0 },
203
2.06k
        { "fixup_sparc_tls_ldo_hix22",  0, 22,  0 },
204
2.06k
        { "fixup_sparc_tls_ldo_lox10",  0, 10,  0 },
205
2.06k
        { "fixup_sparc_tls_ldo_add",    0,  0,  0 },
206
2.06k
        { "fixup_sparc_tls_ie_hi22",    0, 22,  0 },
207
2.06k
        { "fixup_sparc_tls_ie_lo10",    0, 10,  0 },
208
2.06k
        { "fixup_sparc_tls_ie_ld",      0,  0,  0 },
209
2.06k
        { "fixup_sparc_tls_ie_ldx",     0,  0,  0 },
210
2.06k
        { "fixup_sparc_tls_ie_add",     0,  0,  0 },
211
2.06k
        { "fixup_sparc_tls_le_hix22",   0,  0,  0 },
212
2.06k
        { "fixup_sparc_tls_le_lox10",   0,  0,  0 }
213
2.06k
      };
214
2.06k
215
2.06k
      if (Kind < FirstTargetFixupKind)
216
314
        return MCAsmBackend::getFixupKindInfo(Kind);
217
1.75k
218
1.75k
      assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
219
1.75k
             "Invalid kind!");
220
1.75k
      if (Endian == support::little)
221
4
        return InfosLE[Kind - FirstTargetFixupKind];
222
1.74k
223
1.74k
      return InfosBE[Kind - FirstTargetFixupKind];
224
1.74k
    }
225
226
    bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
227
83
                               const MCValue &Target) override {
228
83
      switch ((Sparc::Fixups)Fixup.getKind()) {
229
83
      default:
230
81
        return false;
231
83
      case Sparc::fixup_sparc_wplt30:
232
2
        if (Target.getSymA()->getSymbol().isTemporary())
233
2
          return false;
234
0
        LLVM_FALLTHROUGH;
235
0
      case Sparc::fixup_sparc_tls_gd_hi22:
236
0
      case Sparc::fixup_sparc_tls_gd_lo10:
237
0
      case Sparc::fixup_sparc_tls_gd_add:
238
0
      case Sparc::fixup_sparc_tls_gd_call:
239
0
      case Sparc::fixup_sparc_tls_ldm_hi22:
240
0
      case Sparc::fixup_sparc_tls_ldm_lo10:
241
0
      case Sparc::fixup_sparc_tls_ldm_add:
242
0
      case Sparc::fixup_sparc_tls_ldm_call:
243
0
      case Sparc::fixup_sparc_tls_ldo_hix22:
244
0
      case Sparc::fixup_sparc_tls_ldo_lox10:
245
0
      case Sparc::fixup_sparc_tls_ldo_add:
246
0
      case Sparc::fixup_sparc_tls_ie_hi22:
247
0
      case Sparc::fixup_sparc_tls_ie_lo10:
248
0
      case Sparc::fixup_sparc_tls_ie_ld:
249
0
      case Sparc::fixup_sparc_tls_ie_ldx:
250
0
      case Sparc::fixup_sparc_tls_ie_add:
251
0
      case Sparc::fixup_sparc_tls_le_hix22:
252
0
      case Sparc::fixup_sparc_tls_le_lox10:
253
0
        return true;
254
83
      }
255
83
    }
256
257
    bool mayNeedRelaxation(const MCInst &Inst,
258
320
                           const MCSubtargetInfo &STI) const override {
259
320
      // FIXME.
260
320
      return false;
261
320
    }
262
263
    /// fixupNeedsRelaxation - Target specific predicate for whether a given
264
    /// fixup requires the associated instruction to be relaxed.
265
    bool fixupNeedsRelaxation(const MCFixup &Fixup,
266
                              uint64_t Value,
267
                              const MCRelaxableFragment *DF,
268
0
                              const MCAsmLayout &Layout) const override {
269
0
      // FIXME.
270
0
      llvm_unreachable("fixupNeedsRelaxation() unimplemented");
271
0
      return false;
272
0
    }
273
    void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
274
0
                          MCInst &Res) const override {
275
0
      // FIXME.
276
0
      llvm_unreachable("relaxInstruction() unimplemented");
277
0
    }
278
279
45
    bool writeNopData(raw_ostream &OS, uint64_t Count) const override {
280
45
      // Cannot emit NOP with size not multiple of 32 bits.
281
45
      if (Count % 4 != 0)
282
0
        return false;
283
45
284
45
      uint64_t NumNops = Count / 4;
285
51
      for (uint64_t i = 0; i != NumNops; 
++i6
)
286
6
        support::endian::write<uint32_t>(OS, 0x01000000, Endian);
287
45
288
45
      return true;
289
45
    }
290
  };
291
292
  class ELFSparcAsmBackend : public SparcAsmBackend {
293
    Triple::OSType OSType;
294
  public:
295
    ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
296
260
      SparcAsmBackend(T), OSType(OSType) { }
297
298
    void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
299
                    const MCValue &Target, MutableArrayRef<char> Data,
300
                    uint64_t Value, bool IsResolved,
301
317
                    const MCSubtargetInfo *STI) const override {
302
317
303
317
      Value = adjustFixupValue(Fixup.getKind(), Value);
304
317
      if (!Value) 
return234
; // Doesn't change encoding.
305
83
306
83
      unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
307
83
      unsigned Offset = Fixup.getOffset();
308
83
      // For each byte of the fragment that the fixup touches, mask in the bits
309
83
      // from the fixup value. The Value has been "split up" into the
310
83
      // appropriate bitfields above.
311
414
      for (unsigned i = 0; i != NumBytes; 
++i331
) {
312
331
        unsigned Idx = Endian == support::little ? 
i4
:
(NumBytes - 1) - i327
;
313
331
        Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
314
331
      }
315
83
    }
316
317
    std::unique_ptr<MCObjectTargetWriter>
318
260
    createObjectTargetWriter() const override {
319
260
      uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
320
260
      return createSparcELFObjectWriter(Is64Bit, OSABI);
321
260
    }
322
  };
323
324
} // end anonymous namespace
325
326
MCAsmBackend *llvm::createSparcAsmBackend(const Target &T,
327
                                          const MCSubtargetInfo &STI,
328
                                          const MCRegisterInfo &MRI,
329
260
                                          const MCTargetOptions &Options) {
330
260
  return new ELFSparcAsmBackend(T, STI.getTargetTriple().getOS());
331
260
}