Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
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
// Streams SystemZ assembly language and associated data, in the form of
10
// MCInsts and MCExprs respectively.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "SystemZAsmPrinter.h"
15
#include "MCTargetDesc/SystemZInstPrinter.h"
16
#include "SystemZConstantPoolValue.h"
17
#include "SystemZMCInstLower.h"
18
#include "TargetInfo/SystemZTargetInfo.h"
19
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
20
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
21
#include "llvm/IR/Mangler.h"
22
#include "llvm/MC/MCExpr.h"
23
#include "llvm/MC/MCInstBuilder.h"
24
#include "llvm/MC/MCStreamer.h"
25
#include "llvm/Support/TargetRegistry.h"
26
27
using namespace llvm;
28
29
// Return an RI instruction like MI with opcode Opcode, but with the
30
// GR64 register operands turned into GR32s.
31
136
static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
32
136
  if (MI->isCompare())
33
8
    return MCInstBuilder(Opcode)
34
8
      .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
35
8
      .addImm(MI->getOperand(1).getImm());
36
128
  else
37
128
    return MCInstBuilder(Opcode)
38
128
      .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
39
128
      .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
40
128
      .addImm(MI->getOperand(2).getImm());
41
136
}
42
43
// Return an RI instruction like MI with opcode Opcode, but with the
44
// GR64 register operands turned into GRH32s.
45
80
static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
46
80
  if (MI->isCompare())
47
23
    return MCInstBuilder(Opcode)
48
23
      .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
49
23
      .addImm(MI->getOperand(1).getImm());
50
57
  else
51
57
    return MCInstBuilder(Opcode)
52
57
      .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
53
57
      .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
54
57
      .addImm(MI->getOperand(2).getImm());
55
80
}
56
57
// Return an RI instruction like MI with opcode Opcode, but with the
58
// R2 register turned into a GR64.
59
117
static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
60
117
  return MCInstBuilder(Opcode)
61
117
    .addReg(MI->getOperand(0).getReg())
62
117
    .addReg(MI->getOperand(1).getReg())
63
117
    .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
64
117
    .addImm(MI->getOperand(3).getImm())
65
117
    .addImm(MI->getOperand(4).getImm())
66
117
    .addImm(MI->getOperand(5).getImm());
67
117
}
68
69
10
static const MCSymbolRefExpr *getTLSGetOffset(MCContext &Context) {
70
10
  StringRef Name = "__tls_get_offset";
71
10
  return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
72
10
                                 MCSymbolRefExpr::VK_PLT,
73
10
                                 Context);
74
10
}
75
76
8
static const MCSymbolRefExpr *getGlobalOffsetTable(MCContext &Context) {
77
8
  StringRef Name = "_GLOBAL_OFFSET_TABLE_";
78
8
  return MCSymbolRefExpr::create(Context.getOrCreateSymbol(Name),
79
8
                                 MCSymbolRefExpr::VK_None,
80
8
                                 Context);
81
8
}
82
83
// MI is an instruction that accepts an optional alignment hint,
84
// and which was already lowered to LoweredMI.  If the alignment
85
// of the original memory operand is known, update LoweredMI to
86
// an instruction with the corresponding hint set.
87
static void lowerAlignmentHint(const MachineInstr *MI, MCInst &LoweredMI,
88
5.86k
                               unsigned Opcode) {
89
5.86k
  if (!MI->hasOneMemOperand())
90
0
    return;
91
5.86k
  const MachineMemOperand *MMO = *MI->memoperands_begin();
92
5.86k
  unsigned AlignmentHint = 0;
93
5.86k
  if (MMO->getAlignment() >= 16)
94
50
    AlignmentHint = 4;
95
5.81k
  else if (MMO->getAlignment() >= 8)
96
5.80k
    AlignmentHint = 3;
97
5.86k
  if (AlignmentHint == 0)
98
10
    return;
99
5.85k
100
5.85k
  LoweredMI.setOpcode(Opcode);
101
5.85k
  LoweredMI.addOperand(MCOperand::createImm(AlignmentHint));
102
5.85k
}
103
104
// MI loads the high part of a vector from memory.  Return an instruction
105
// that uses replicating vector load Opcode to do the same thing.
106
82
static MCInst lowerSubvectorLoad(const MachineInstr *MI, unsigned Opcode) {
107
82
  return MCInstBuilder(Opcode)
108
82
    .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
109
82
    .addReg(MI->getOperand(1).getReg())
110
82
    .addImm(MI->getOperand(2).getImm())
111
82
    .addReg(MI->getOperand(3).getReg());
112
82
}
113
114
// MI stores the high part of a vector to memory.  Return an instruction
115
// that uses elemental vector store Opcode to do the same thing.
116
82
static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
117
82
  return MCInstBuilder(Opcode)
118
82
    .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
119
82
    .addReg(MI->getOperand(1).getReg())
120
82
    .addImm(MI->getOperand(2).getImm())
121
82
    .addReg(MI->getOperand(3).getReg())
122
82
    .addImm(0);
123
82
}
124
125
59.9k
void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
126
59.9k
  SystemZMCInstLower Lower(MF->getContext(), *this);
127
59.9k
  MCInst LoweredMI;
128
59.9k
  switch (MI->getOpcode()) {
129
59.9k
  case SystemZ::Return:
130
8.06k
    LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
131
8.06k
    break;
132
59.9k
133
59.9k
  case SystemZ::CondReturn:
134
611
    LoweredMI = MCInstBuilder(SystemZ::BCR)
135
611
      .addImm(MI->getOperand(0).getImm())
136
611
      .addImm(MI->getOperand(1).getImm())
137
611
      .addReg(SystemZ::R14D);
138
611
    break;
139
59.9k
140
59.9k
  case SystemZ::CRBReturn:
141
1
    LoweredMI = MCInstBuilder(SystemZ::CRB)
142
1
      .addReg(MI->getOperand(0).getReg())
143
1
      .addReg(MI->getOperand(1).getReg())
144
1
      .addImm(MI->getOperand(2).getImm())
145
1
      .addReg(SystemZ::R14D)
146
1
      .addImm(0);
147
1
    break;
148
59.9k
149
59.9k
  case SystemZ::CGRBReturn:
150
5
    LoweredMI = MCInstBuilder(SystemZ::CGRB)
151
5
      .addReg(MI->getOperand(0).getReg())
152
5
      .addReg(MI->getOperand(1).getReg())
153
5
      .addImm(MI->getOperand(2).getImm())
154
5
      .addReg(SystemZ::R14D)
155
5
      .addImm(0);
156
5
    break;
157
59.9k
158
59.9k
  case SystemZ::CIBReturn:
159
25
    LoweredMI = MCInstBuilder(SystemZ::CIB)
160
25
      .addReg(MI->getOperand(0).getReg())
161
25
      .addImm(MI->getOperand(1).getImm())
162
25
      .addImm(MI->getOperand(2).getImm())
163
25
      .addReg(SystemZ::R14D)
164
25
      .addImm(0);
165
25
    break;
166
59.9k
167
59.9k
  case SystemZ::CGIBReturn:
168
7
    LoweredMI = MCInstBuilder(SystemZ::CGIB)
169
7
      .addReg(MI->getOperand(0).getReg())
170
7
      .addImm(MI->getOperand(1).getImm())
171
7
      .addImm(MI->getOperand(2).getImm())
172
7
      .addReg(SystemZ::R14D)
173
7
      .addImm(0);
174
7
    break;
175
59.9k
176
59.9k
  case SystemZ::CLRBReturn:
177
7
    LoweredMI = MCInstBuilder(SystemZ::CLRB)
178
7
      .addReg(MI->getOperand(0).getReg())
179
7
      .addReg(MI->getOperand(1).getReg())
180
7
      .addImm(MI->getOperand(2).getImm())
181
7
      .addReg(SystemZ::R14D)
182
7
      .addImm(0);
183
7
    break;
184
59.9k
185
59.9k
  case SystemZ::CLGRBReturn:
186
9
    LoweredMI = MCInstBuilder(SystemZ::CLGRB)
187
9
      .addReg(MI->getOperand(0).getReg())
188
9
      .addReg(MI->getOperand(1).getReg())
189
9
      .addImm(MI->getOperand(2).getImm())
190
9
      .addReg(SystemZ::R14D)
191
9
      .addImm(0);
192
9
    break;
193
59.9k
194
59.9k
  case SystemZ::CLIBReturn:
195
3
    LoweredMI = MCInstBuilder(SystemZ::CLIB)
196
3
      .addReg(MI->getOperand(0).getReg())
197
3
      .addImm(MI->getOperand(1).getImm())
198
3
      .addImm(MI->getOperand(2).getImm())
199
3
      .addReg(SystemZ::R14D)
200
3
      .addImm(0);
201
3
    break;
202
59.9k
203
59.9k
  case SystemZ::CLGIBReturn:
204
1
    LoweredMI = MCInstBuilder(SystemZ::CLGIB)
205
1
      .addReg(MI->getOperand(0).getReg())
206
1
      .addImm(MI->getOperand(1).getImm())
207
1
      .addImm(MI->getOperand(2).getImm())
208
1
      .addReg(SystemZ::R14D)
209
1
      .addImm(0);
210
1
    break;
211
59.9k
212
59.9k
  case SystemZ::CallBRASL:
213
840
    LoweredMI = MCInstBuilder(SystemZ::BRASL)
214
840
      .addReg(SystemZ::R14D)
215
840
      .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
216
840
    break;
217
59.9k
218
59.9k
  case SystemZ::CallBASR:
219
3
    LoweredMI = MCInstBuilder(SystemZ::BASR)
220
3
      .addReg(SystemZ::R14D)
221
3
      .addReg(MI->getOperand(0).getReg());
222
3
    break;
223
59.9k
224
59.9k
  case SystemZ::CallJG:
225
34
    LoweredMI = MCInstBuilder(SystemZ::JG)
226
34
      .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
227
34
    break;
228
59.9k
229
59.9k
  case SystemZ::CallBRCL:
230
106
    LoweredMI = MCInstBuilder(SystemZ::BRCL)
231
106
      .addImm(MI->getOperand(0).getImm())
232
106
      .addImm(MI->getOperand(1).getImm())
233
106
      .addExpr(Lower.getExpr(MI->getOperand(2), MCSymbolRefExpr::VK_PLT));
234
106
    break;
235
59.9k
236
59.9k
  case SystemZ::CallBR:
237
5
    LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
238
5
    break;
239
59.9k
240
59.9k
  case SystemZ::CallBCR:
241
4
    LoweredMI = MCInstBuilder(SystemZ::BCR)
242
4
      .addImm(MI->getOperand(0).getImm())
243
4
      .addImm(MI->getOperand(1).getImm())
244
4
      .addReg(SystemZ::R1D);
245
4
    break;
246
59.9k
247
59.9k
  case SystemZ::CRBCall:
248
7
    LoweredMI = MCInstBuilder(SystemZ::CRB)
249
7
      .addReg(MI->getOperand(0).getReg())
250
7
      .addReg(MI->getOperand(1).getReg())
251
7
      .addImm(MI->getOperand(2).getImm())
252
7
      .addReg(SystemZ::R1D)
253
7
      .addImm(0);
254
7
    break;
255
59.9k
256
59.9k
  case SystemZ::CGRBCall:
257
1
    LoweredMI = MCInstBuilder(SystemZ::CGRB)
258
1
      .addReg(MI->getOperand(0).getReg())
259
1
      .addReg(MI->getOperand(1).getReg())
260
1
      .addImm(MI->getOperand(2).getImm())
261
1
      .addReg(SystemZ::R1D)
262
1
      .addImm(0);
263
1
    break;
264
59.9k
265
59.9k
  case SystemZ::CIBCall:
266
6
    LoweredMI = MCInstBuilder(SystemZ::CIB)
267
6
      .addReg(MI->getOperand(0).getReg())
268
6
      .addImm(MI->getOperand(1).getImm())
269
6
      .addImm(MI->getOperand(2).getImm())
270
6
      .addReg(SystemZ::R1D)
271
6
      .addImm(0);
272
6
    break;
273
59.9k
274
59.9k
  case SystemZ::CGIBCall:
275
1
    LoweredMI = MCInstBuilder(SystemZ::CGIB)
276
1
      .addReg(MI->getOperand(0).getReg())
277
1
      .addImm(MI->getOperand(1).getImm())
278
1
      .addImm(MI->getOperand(2).getImm())
279
1
      .addReg(SystemZ::R1D)
280
1
      .addImm(0);
281
1
    break;
282
59.9k
283
59.9k
  case SystemZ::CLRBCall:
284
1
    LoweredMI = MCInstBuilder(SystemZ::CLRB)
285
1
      .addReg(MI->getOperand(0).getReg())
286
1
      .addReg(MI->getOperand(1).getReg())
287
1
      .addImm(MI->getOperand(2).getImm())
288
1
      .addReg(SystemZ::R1D)
289
1
      .addImm(0);
290
1
    break;
291
59.9k
292
59.9k
  case SystemZ::CLGRBCall:
293
1
    LoweredMI = MCInstBuilder(SystemZ::CLGRB)
294
1
      .addReg(MI->getOperand(0).getReg())
295
1
      .addReg(MI->getOperand(1).getReg())
296
1
      .addImm(MI->getOperand(2).getImm())
297
1
      .addReg(SystemZ::R1D)
298
1
      .addImm(0);
299
1
    break;
300
59.9k
301
59.9k
  case SystemZ::CLIBCall:
302
1
    LoweredMI = MCInstBuilder(SystemZ::CLIB)
303
1
      .addReg(MI->getOperand(0).getReg())
304
1
      .addImm(MI->getOperand(1).getImm())
305
1
      .addImm(MI->getOperand(2).getImm())
306
1
      .addReg(SystemZ::R1D)
307
1
      .addImm(0);
308
1
    break;
309
59.9k
310
59.9k
  case SystemZ::CLGIBCall:
311
1
    LoweredMI = MCInstBuilder(SystemZ::CLGIB)
312
1
      .addReg(MI->getOperand(0).getReg())
313
1
      .addImm(MI->getOperand(1).getImm())
314
1
      .addImm(MI->getOperand(2).getImm())
315
1
      .addReg(SystemZ::R1D)
316
1
      .addImm(0);
317
1
    break;
318
59.9k
319
59.9k
  case SystemZ::TLS_GDCALL:
320
7
    LoweredMI = MCInstBuilder(SystemZ::BRASL)
321
7
      .addReg(SystemZ::R14D)
322
7
      .addExpr(getTLSGetOffset(MF->getContext()))
323
7
      .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSGD));
324
7
    break;
325
59.9k
326
59.9k
  case SystemZ::TLS_LDCALL:
327
3
    LoweredMI = MCInstBuilder(SystemZ::BRASL)
328
3
      .addReg(SystemZ::R14D)
329
3
      .addExpr(getTLSGetOffset(MF->getContext()))
330
3
      .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_TLSLDM));
331
3
    break;
332
59.9k
333
59.9k
  case SystemZ::GOT:
334
8
    LoweredMI = MCInstBuilder(SystemZ::LARL)
335
8
      .addReg(MI->getOperand(0).getReg())
336
8
      .addExpr(getGlobalOffsetTable(MF->getContext()));
337
8
    break;
338
59.9k
339
59.9k
  case SystemZ::IILF64:
340
7
    LoweredMI = MCInstBuilder(SystemZ::IILF)
341
7
      .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
342
7
      .addImm(MI->getOperand(2).getImm());
343
7
    break;
344
59.9k
345
59.9k
  case SystemZ::IIHF64:
346
8
    LoweredMI = MCInstBuilder(SystemZ::IIHF)
347
8
      .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
348
8
      .addImm(MI->getOperand(2).getImm());
349
8
    break;
350
59.9k
351
59.9k
  case SystemZ::RISBHH:
352
24
  case SystemZ::RISBHL:
353
24
    LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
354
24
    break;
355
24
356
93
  case SystemZ::RISBLH:
357
93
  case SystemZ::RISBLL:
358
93
    LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
359
93
    break;
360
93
361
93
  case SystemZ::VLVGP32:
362
11
    LoweredMI = MCInstBuilder(SystemZ::VLVGP)
363
11
      .addReg(MI->getOperand(0).getReg())
364
11
      .addReg(SystemZMC::getRegAsGR64(MI->getOperand(1).getReg()))
365
11
      .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()));
366
11
    break;
367
93
368
93
  case SystemZ::VLR32:
369
0
  case SystemZ::VLR64:
370
0
    LoweredMI = MCInstBuilder(SystemZ::VLR)
371
0
      .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
372
0
      .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()));
373
0
    break;
374
0
375
4.01k
  case SystemZ::VL:
376
4.01k
    Lower.lower(MI, LoweredMI);
377
4.01k
    lowerAlignmentHint(MI, LoweredMI, SystemZ::VLAlign);
378
4.01k
    break;
379
0
380
1.85k
  case SystemZ::VST:
381
1.85k
    Lower.lower(MI, LoweredMI);
382
1.85k
    lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTAlign);
383
1.85k
    break;
384
0
385
0
  case SystemZ::VLM:
386
0
    Lower.lower(MI, LoweredMI);
387
0
    lowerAlignmentHint(MI, LoweredMI, SystemZ::VLMAlign);
388
0
    break;
389
0
390
0
  case SystemZ::VSTM:
391
0
    Lower.lower(MI, LoweredMI);
392
0
    lowerAlignmentHint(MI, LoweredMI, SystemZ::VSTMAlign);
393
0
    break;
394
0
395
9
  case SystemZ::VL32:
396
9
    LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPF);
397
9
    break;
398
0
399
73
  case SystemZ::VL64:
400
73
    LoweredMI = lowerSubvectorLoad(MI, SystemZ::VLREPG);
401
73
    break;
402
0
403
9
  case SystemZ::VST32:
404
9
    LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEF);
405
9
    break;
406
0
407
73
  case SystemZ::VST64:
408
73
    LoweredMI = lowerSubvectorStore(MI, SystemZ::VSTEG);
409
73
    break;
410
0
411
7
  case SystemZ::LFER:
412
7
    LoweredMI = MCInstBuilder(SystemZ::VLGVF)
413
7
      .addReg(SystemZMC::getRegAsGR64(MI->getOperand(0).getReg()))
414
7
      .addReg(SystemZMC::getRegAsVR128(MI->getOperand(1).getReg()))
415
7
      .addReg(0).addImm(0);
416
7
    break;
417
0
418
2
  case SystemZ::LEFR:
419
2
    LoweredMI = MCInstBuilder(SystemZ::VLVGF)
420
2
      .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
421
2
      .addReg(SystemZMC::getRegAsVR128(MI->getOperand(0).getReg()))
422
2
      .addReg(MI->getOperand(1).getReg())
423
2
      .addReg(0).addImm(0);
424
2
    break;
425
0
426
0
#define LOWER_LOW(NAME)                                                 \
427
136
  case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
428
0
429
3
  LOWER_LOW(IILL);
430
3
  LOWER_LOW(IILH);
431
4
  LOWER_LOW(TMLL);
432
4
  LOWER_LOW(TMLH);
433
35
  LOWER_LOW(NILL);
434
6
  LOWER_LOW(NILH);
435
10
  LOWER_LOW(NILF);
436
21
  LOWER_LOW(OILL);
437
7
  LOWER_LOW(OILH);
438
35
  LOWER_LOW(OILF);
439
8
  LOWER_LOW(XILF);
440
0
441
0
#undef LOWER_LOW
442
0
443
0
#define LOWER_HIGH(NAME) \
444
80
  case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
445
0
446
3
  LOWER_HIGH(IIHL);
447
3
  LOWER_HIGH(IIHH);
448
7
  LOWER_HIGH(TMHL);
449
16
  LOWER_HIGH(TMHH);
450
6
  LOWER_HIGH(NIHL);
451
8
  LOWER_HIGH(NIHH);
452
6
  LOWER_HIGH(NIHF);
453
10
  LOWER_HIGH(OIHL);
454
6
  LOWER_HIGH(OIHH);
455
5
  LOWER_HIGH(OIHF);
456
10
  LOWER_HIGH(XIHF);
457
0
458
0
#undef LOWER_HIGH
459
0
460
9
  case SystemZ::Serialize:
461
9
    if (MF->getSubtarget<SystemZSubtarget>().hasFastSerialization())
462
3
      LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
463
3
        .addImm(14).addReg(SystemZ::R0D);
464
6
    else
465
6
      LoweredMI = MCInstBuilder(SystemZ::BCRAsm)
466
6
        .addImm(15).addReg(SystemZ::R0D);
467
9
    break;
468
0
469
0
  // Emit nothing here but a comment if we can.
470
3
  case SystemZ::MemBarrier:
471
3
    OutStreamer->emitRawComment("MEMBARRIER");
472
3
    return;
473
0
474
0
  // We want to emit "j .+2" for traps, jumping to the relative immediate field
475
0
  // of the jump instruction, which is an illegal instruction. We cannot emit a
476
0
  // "." symbol, so create and emit a temp label before the instruction and use
477
0
  // that instead.
478
1
  case SystemZ::Trap: {
479
1
    MCSymbol *DotSym = OutContext.createTempSymbol();
480
1
    OutStreamer->EmitLabel(DotSym);
481
1
482
1
    const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
483
1
    const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
484
1
    LoweredMI = MCInstBuilder(SystemZ::J)
485
1
      .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
486
1
    }
487
1
    break;
488
0
489
0
  // Conditional traps will create a branch on condition instruction that jumps
490
0
  // to the relative immediate field of the jump instruction. (eg. "jo .+2")
491
3
  case SystemZ::CondTrap: {
492
3
    MCSymbol *DotSym = OutContext.createTempSymbol();
493
3
    OutStreamer->EmitLabel(DotSym);
494
3
495
3
    const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(DotSym, OutContext);
496
3
    const MCConstantExpr *ConstExpr = MCConstantExpr::create(2, OutContext);
497
3
    LoweredMI = MCInstBuilder(SystemZ::BRC)
498
3
      .addImm(MI->getOperand(0).getImm())
499
3
      .addImm(MI->getOperand(1).getImm())
500
3
      .addExpr(MCBinaryExpr::createAdd(Expr, ConstExpr, OutContext));
501
3
    }
502
3
    break;
503
0
504
28
  case TargetOpcode::STACKMAP:
505
28
    LowerSTACKMAP(*MI);
506
28
    return;
507
0
508
28
  case TargetOpcode::PATCHPOINT:
509
28
    LowerPATCHPOINT(*MI, Lower);
510
28
    return;
511
0
512
43.7k
  default:
513
43.7k
    Lower.lower(MI, LoweredMI);
514
43.7k
    break;
515
59.9k
  }
516
59.9k
  EmitToStreamer(*OutStreamer, LoweredMI);
517
59.9k
}
518
519
520
// Emit the largest nop instruction smaller than or equal to NumBytes
521
// bytes.  Return the size of nop emitted.
522
static unsigned EmitNop(MCContext &OutContext, MCStreamer &OutStreamer,
523
79
                        unsigned NumBytes, const MCSubtargetInfo &STI) {
524
79
  if (NumBytes < 2) {
525
0
    llvm_unreachable("Zero nops?");
526
0
    return 0;
527
79
  }
528
79
  else if (NumBytes < 4) {
529
16
    OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCRAsm)
530
16
                                  .addImm(0).addReg(SystemZ::R0D), STI);
531
16
    return 2;
532
16
  }
533
63
  else if (NumBytes < 6) {
534
6
    OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BCAsm)
535
6
                                  .addImm(0).addReg(0).addImm(0).addReg(0),
536
6
                                STI);
537
6
    return 4;
538
6
  }
539
57
  else {
540
57
    MCSymbol *DotSym = OutContext.createTempSymbol();
541
57
    const MCSymbolRefExpr *Dot = MCSymbolRefExpr::create(DotSym, OutContext);
542
57
    OutStreamer.EmitInstruction(MCInstBuilder(SystemZ::BRCLAsm)
543
57
                                  .addImm(0).addExpr(Dot), STI);
544
57
    OutStreamer.EmitLabel(DotSym);
545
57
    return 6;
546
57
  }
547
79
}
548
549
28
void SystemZAsmPrinter::LowerSTACKMAP(const MachineInstr &MI) {
550
28
  const SystemZInstrInfo *TII =
551
28
    static_cast<const SystemZInstrInfo *>(MF->getSubtarget().getInstrInfo());
552
28
553
28
  unsigned NumNOPBytes = MI.getOperand(1).getImm();
554
28
555
28
  SM.recordStackMap(MI);
556
28
  assert(NumNOPBytes % 2 == 0 && "Invalid number of NOP bytes requested!");
557
28
558
28
  // Scan ahead to trim the shadow.
559
28
  unsigned ShadowBytes = 0;
560
28
  const MachineBasicBlock &MBB = *MI.getParent();
561
28
  MachineBasicBlock::const_iterator MII(MI);
562
28
  ++MII;
563
39
  while (ShadowBytes < NumNOPBytes) {
564
30
    if (MII == MBB.end() ||
565
30
        
MII->getOpcode() == TargetOpcode::PATCHPOINT27
||
566
30
        
MII->getOpcode() == TargetOpcode::STACKMAP27
)
567
18
      break;
568
12
    ShadowBytes += TII->getInstSizeInBytes(*MII);
569
12
    if (MII->isCall())
570
1
      break;
571
11
    ++MII;
572
11
  }
573
28
574
28
  // Emit nops.
575
78
  while (ShadowBytes < NumNOPBytes)
576
50
    ShadowBytes += EmitNop(OutContext, *OutStreamer, NumNOPBytes - ShadowBytes,
577
50
                           getSubtargetInfo());
578
28
}
579
580
// Lower a patchpoint of the form:
581
// [<def>], <id>, <numBytes>, <target>, <numArgs>
582
void SystemZAsmPrinter::LowerPATCHPOINT(const MachineInstr &MI,
583
28
                                        SystemZMCInstLower &Lower) {
584
28
  SM.recordPatchPoint(MI);
585
28
  PatchPointOpers Opers(&MI);
586
28
587
28
  unsigned EncodedBytes = 0;
588
28
  const MachineOperand &CalleeMO = Opers.getCallTarget();
589
28
590
28
  if (CalleeMO.isImm()) {
591
27
    uint64_t CallTarget = CalleeMO.getImm();
592
27
    if (CallTarget) {
593
15
      unsigned ScratchIdx = -1;
594
15
      unsigned ScratchReg = 0;
595
30
      do {
596
30
        ScratchIdx = Opers.getNextScratchIdx(ScratchIdx + 1);
597
30
        ScratchReg = MI.getOperand(ScratchIdx).getReg();
598
30
      } while (ScratchReg == SystemZ::R0D);
599
15
600
15
      // Materialize the call target address
601
15
      EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::LLILF)
602
15
                                      .addReg(ScratchReg)
603
15
                                      .addImm(CallTarget & 0xFFFFFFFF));
604
15
      EncodedBytes += 6;
605
15
      if (CallTarget >> 32) {
606
11
        EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::IIHF)
607
11
                                        .addReg(ScratchReg)
608
11
                                        .addImm(CallTarget >> 32));
609
11
        EncodedBytes += 6;
610
11
      }
611
15
612
15
      EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
613
15
                                     .addReg(SystemZ::R14D)
614
15
                                     .addReg(ScratchReg));
615
15
      EncodedBytes += 2;
616
15
    }
617
27
  } else 
if (1
CalleeMO.isGlobal()1
) {
618
1
    const MCExpr *Expr = Lower.getExpr(CalleeMO, MCSymbolRefExpr::VK_PLT);
619
1
    EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
620
1
                                   .addReg(SystemZ::R14D)
621
1
                                   .addExpr(Expr));
622
1
    EncodedBytes += 6;
623
1
  }
624
28
625
28
  // Emit padding.
626
28
  unsigned NumBytes = Opers.getNumPatchBytes();
627
28
  assert(NumBytes >= EncodedBytes &&
628
28
         "Patchpoint can't request size less than the length of a call.");
629
28
  assert((NumBytes - EncodedBytes) % 2 == 0 &&
630
28
         "Invalid number of NOP bytes requested!");
631
57
  while (EncodedBytes < NumBytes)
632
29
    EncodedBytes += EmitNop(OutContext, *OutStreamer, NumBytes - EncodedBytes,
633
29
                            getSubtargetInfo());
634
28
}
635
636
// Convert a SystemZ-specific constant pool modifier into the associated
637
// MCSymbolRefExpr variant kind.
638
static MCSymbolRefExpr::VariantKind
639
17
getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
640
17
  switch (Modifier) {
641
17
  
case SystemZCP::TLSGD: return MCSymbolRefExpr::VK_TLSGD7
;
642
17
  
case SystemZCP::TLSLDM: return MCSymbolRefExpr::VK_TLSLDM4
;
643
17
  
case SystemZCP::DTPOFF: return MCSymbolRefExpr::VK_DTPOFF4
;
644
17
  
case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF2
;
645
0
  }
646
0
  llvm_unreachable("Invalid SystemCPModifier!");
647
0
}
648
649
void SystemZAsmPrinter::
650
17
EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
651
17
  auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV);
652
17
653
17
  const MCExpr *Expr =
654
17
    MCSymbolRefExpr::create(getSymbol(ZCPV->getGlobalValue()),
655
17
                            getModifierVariantKind(ZCPV->getModifier()),
656
17
                            OutContext);
657
17
  uint64_t Size = getDataLayout().getTypeAllocSize(ZCPV->getType());
658
17
659
17
  OutStreamer->EmitValue(Expr, Size);
660
17
}
661
662
bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
663
                                        const char *ExtraCode,
664
469
                                        raw_ostream &OS) {
665
469
  if (ExtraCode)
666
4
    return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS);
667
465
  SystemZMCInstLower Lower(MF->getContext(), *this);
668
465
  MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
669
465
  SystemZInstPrinter::printOperand(MO, MAI, OS);
670
465
  return false;
671
465
}
672
673
bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
674
                                              unsigned OpNo,
675
                                              const char *ExtraCode,
676
24
                                              raw_ostream &OS) {
677
24
  SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
678
24
                                   MI->getOperand(OpNo + 1).getImm(),
679
24
                                   MI->getOperand(OpNo + 2).getReg(), OS);
680
24
  return false;
681
24
}
682
683
999
void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
684
999
  emitStackMaps(SM);
685
999
}
686
687
// Force static initialization.
688
78.9k
extern "C" void LLVMInitializeSystemZAsmPrinter() {
689
78.9k
  RegisterAsmPrinter<SystemZAsmPrinter> X(getTheSystemZTarget());
690
78.9k
}