Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/X86/X86AsmPrinter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===//
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 contains a printer that converts from our internal representation
10
// of machine-dependent LLVM code to X86 machine code.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "X86AsmPrinter.h"
15
#include "MCTargetDesc/X86ATTInstPrinter.h"
16
#include "MCTargetDesc/X86BaseInfo.h"
17
#include "MCTargetDesc/X86TargetStreamer.h"
18
#include "TargetInfo/X86TargetInfo.h"
19
#include "X86InstrInfo.h"
20
#include "X86MachineFunctionInfo.h"
21
#include "llvm/BinaryFormat/COFF.h"
22
#include "llvm/BinaryFormat/ELF.h"
23
#include "llvm/CodeGen/MachineConstantPool.h"
24
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
25
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
26
#include "llvm/IR/DerivedTypes.h"
27
#include "llvm/IR/InlineAsm.h"
28
#include "llvm/IR/Mangler.h"
29
#include "llvm/IR/Module.h"
30
#include "llvm/IR/Type.h"
31
#include "llvm/MC/MCCodeEmitter.h"
32
#include "llvm/MC/MCContext.h"
33
#include "llvm/MC/MCExpr.h"
34
#include "llvm/MC/MCSectionCOFF.h"
35
#include "llvm/MC/MCSectionELF.h"
36
#include "llvm/MC/MCSectionMachO.h"
37
#include "llvm/MC/MCStreamer.h"
38
#include "llvm/MC/MCSymbol.h"
39
#include "llvm/Support/Debug.h"
40
#include "llvm/Support/ErrorHandling.h"
41
#include "llvm/Support/MachineValueType.h"
42
#include "llvm/Support/TargetRegistry.h"
43
using namespace llvm;
44
45
X86AsmPrinter::X86AsmPrinter(TargetMachine &TM,
46
                             std::unique_ptr<MCStreamer> Streamer)
47
12.3k
    : AsmPrinter(TM, std::move(Streamer)), SM(*this), FM(*this) {}
48
49
//===----------------------------------------------------------------------===//
50
// Primitive Helper Functions.
51
//===----------------------------------------------------------------------===//
52
53
/// runOnMachineFunction - Emit the function body.
54
///
55
137k
bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
56
137k
  Subtarget = &MF.getSubtarget<X86Subtarget>();
57
137k
58
137k
  SMShadowTracker.startFunction(MF);
59
137k
  CodeEmitter.reset(TM.getTarget().createMCCodeEmitter(
60
137k
      *Subtarget->getInstrInfo(), *Subtarget->getRegisterInfo(),
61
137k
      MF.getContext()));
62
137k
63
137k
  EmitFPOData =
64
137k
      Subtarget->isTargetWin32() && 
MF.getMMI().getModule()->getCodeViewFlag()1.16k
;
65
137k
66
137k
  SetupMachineFunction(MF);
67
137k
68
137k
  if (Subtarget->isTargetCOFF()) {
69
2.89k
    bool Local = MF.getFunction().hasLocalLinkage();
70
2.89k
    OutStreamer->BeginCOFFSymbolDef(CurrentFnSym);
71
2.89k
    OutStreamer->EmitCOFFSymbolStorageClass(
72
2.89k
        Local ? 
COFF::IMAGE_SYM_CLASS_STATIC88
:
COFF::IMAGE_SYM_CLASS_EXTERNAL2.80k
);
73
2.89k
    OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
74
2.89k
                                               << COFF::SCT_COMPLEX_TYPE_SHIFT);
75
2.89k
    OutStreamer->EndCOFFSymbolDef();
76
2.89k
  }
77
137k
78
137k
  // Emit the rest of the function body.
79
137k
  EmitFunctionBody();
80
137k
81
137k
  // Emit the XRay table for this function.
82
137k
  emitXRayTable();
83
137k
84
137k
  EmitFPOData = false;
85
137k
86
137k
  // We didn't modify anything.
87
137k
  return false;
88
137k
}
89
90
137k
void X86AsmPrinter::EmitFunctionBodyStart() {
91
137k
  if (EmitFPOData) {
92
149
    if (auto *XTS =
93
147
        static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer()))
94
147
      XTS->emitFPOProc(
95
147
          CurrentFnSym,
96
147
          MF->getInfo<X86MachineFunctionInfo>()->getArgumentStackSize());
97
149
  }
98
137k
}
99
100
137k
void X86AsmPrinter::EmitFunctionBodyEnd() {
101
137k
  if (EmitFPOData) {
102
149
    if (auto *XTS =
103
147
            static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer()))
104
147
      XTS->emitFPOEndProc();
105
149
  }
106
137k
}
107
108
/// PrintSymbolOperand - Print a raw symbol reference operand.  This handles
109
/// jump tables, constant pools, global address and external symbols, all of
110
/// which print to a label with various suffixes for relocation types etc.
111
void X86AsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
112
87
                                       raw_ostream &O) {
113
87
  switch (MO.getType()) {
114
87
  
default: 0
llvm_unreachable0
("unknown symbol type!");
115
87
  case MachineOperand::MO_ConstantPoolIndex:
116
7
    GetCPISymbol(MO.getIndex())->print(O, MAI);
117
7
    printOffset(MO.getOffset(), O);
118
7
    break;
119
87
  case MachineOperand::MO_GlobalAddress: {
120
80
    const GlobalValue *GV = MO.getGlobal();
121
80
122
80
    MCSymbol *GVSym;
123
80
    if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
124
80
        MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
125
0
      GVSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
126
80
    else
127
80
      GVSym = getSymbol(GV);
128
80
129
80
    // Handle dllimport linkage.
130
80
    if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
131
0
      GVSym = OutContext.getOrCreateSymbol(Twine("__imp_") + GVSym->getName());
132
80
    else if (MO.getTargetFlags() == X86II::MO_COFFSTUB)
133
0
      GVSym =
134
0
          OutContext.getOrCreateSymbol(Twine(".refptr.") + GVSym->getName());
135
80
136
80
    if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
137
80
        MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
138
0
      MCSymbol *Sym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
139
0
      MachineModuleInfoImpl::StubValueTy &StubSym =
140
0
          MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
141
0
      if (!StubSym.getPointer())
142
0
        StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
143
0
                                                     !GV->hasInternalLinkage());
144
0
    }
145
80
146
80
    // If the name begins with a dollar-sign, enclose it in parens.  We do this
147
80
    // to avoid having it look like an integer immediate to the assembler.
148
80
    if (GVSym->getName()[0] != '$')
149
80
      GVSym->print(O, MAI);
150
0
    else {
151
0
      O << '(';
152
0
      GVSym->print(O, MAI);
153
0
      O << ')';
154
0
    }
155
80
    printOffset(MO.getOffset(), O);
156
80
    break;
157
87
  }
158
87
  }
159
87
160
87
  switch (MO.getTargetFlags()) {
161
87
  default:
162
0
    llvm_unreachable("Unknown target flag on GV operand");
163
87
  case X86II::MO_NO_FLAG:    // No flag.
164
87
    break;
165
87
  case X86II::MO_DARWIN_NONLAZY:
166
0
  case X86II::MO_DLLIMPORT:
167
0
  case X86II::MO_COFFSTUB:
168
0
    // These affect the name of the symbol, not any suffix.
169
0
    break;
170
0
  case X86II::MO_GOT_ABSOLUTE_ADDRESS:
171
0
    O << " + [.-";
172
0
    MF->getPICBaseSymbol()->print(O, MAI);
173
0
    O << ']';
174
0
    break;
175
0
  case X86II::MO_PIC_BASE_OFFSET:
176
0
  case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
177
0
    O << '-';
178
0
    MF->getPICBaseSymbol()->print(O, MAI);
179
0
    break;
180
0
  case X86II::MO_TLSGD:     O << "@TLSGD";     break;
181
0
  case X86II::MO_TLSLD:     O << "@TLSLD";     break;
182
0
  case X86II::MO_TLSLDM:    O << "@TLSLDM";    break;
183
0
  case X86II::MO_GOTTPOFF:  O << "@GOTTPOFF";  break;
184
0
  case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;
185
0
  case X86II::MO_TPOFF:     O << "@TPOFF";     break;
186
0
  case X86II::MO_DTPOFF:    O << "@DTPOFF";    break;
187
0
  case X86II::MO_NTPOFF:    O << "@NTPOFF";    break;
188
0
  case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break;
189
0
  case X86II::MO_GOTPCREL:  O << "@GOTPCREL";  break;
190
0
  case X86II::MO_GOT:       O << "@GOT";       break;
191
0
  case X86II::MO_GOTOFF:    O << "@GOTOFF";    break;
192
0
  case X86II::MO_PLT:       O << "@PLT";       break;
193
0
  case X86II::MO_TLVP:      O << "@TLVP";      break;
194
0
  case X86II::MO_TLVP_PIC_BASE:
195
0
    O << "@TLVP" << '-';
196
0
    MF->getPICBaseSymbol()->print(O, MAI);
197
0
    break;
198
0
  case X86II::MO_SECREL:    O << "@SECREL32";  break;
199
87
  }
200
87
}
201
202
void X86AsmPrinter::PrintOperand(const MachineInstr *MI, unsigned OpNo,
203
1.40k
                                 raw_ostream &O) {
204
1.40k
  const MachineOperand &MO = MI->getOperand(OpNo);
205
1.40k
  const bool IsATT = MI->getInlineAsmDialect() == InlineAsm::AD_ATT;
206
1.40k
  switch (MO.getType()) {
207
1.40k
  
default: 0
llvm_unreachable0
("unknown operand type!");
208
1.40k
  case MachineOperand::MO_Register: {
209
1.32k
    if (IsATT)
210
1.30k
      O << '%';
211
1.32k
    O << X86ATTInstPrinter::getRegisterName(MO.getReg());
212
1.32k
    return;
213
1.40k
  }
214
1.40k
215
1.40k
  case MachineOperand::MO_Immediate:
216
55
    if (IsATT)
217
55
      O << '$';
218
55
    O << MO.getImm();
219
55
    return;
220
1.40k
221
1.40k
  case MachineOperand::MO_GlobalAddress: {
222
22
    if (IsATT)
223
12
      O << '$';
224
22
    PrintSymbolOperand(MO, O);
225
22
    break;
226
1.40k
  }
227
1.40k
  case MachineOperand::MO_BlockAddress: {
228
0
    MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
229
0
    Sym->print(O, MAI);
230
0
    break;
231
1.40k
  }
232
1.40k
  }
233
1.40k
}
234
235
/// PrintModifiedOperand - Print subregisters based on supplied modifier,
236
/// deferring to PrintOperand() if no modifier was supplied or if operand is not
237
/// a register.
238
void X86AsmPrinter::PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
239
186
                                         raw_ostream &O, const char *Modifier) {
240
186
  const MachineOperand &MO = MI->getOperand(OpNo);
241
186
  if (!Modifier || 
MO.getType() != MachineOperand::MO_Register2
)
242
184
    return PrintOperand(MI, OpNo, O);
243
2
  if (MI->getInlineAsmDialect() == InlineAsm::AD_ATT)
244
2
    O << '%';
245
2
  unsigned Reg = MO.getReg();
246
2
  if (strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
247
0
    unsigned Size = (strcmp(Modifier+6,"64") == 0) ? 64 :
248
0
        (strcmp(Modifier+6,"32") == 0) ? 32 :
249
0
        (strcmp(Modifier+6,"16") == 0) ? 16 : 8;
250
0
    Reg = getX86SubSuperRegister(Reg, Size);
251
0
  }
252
2
  O << X86ATTInstPrinter::getRegisterName(Reg);
253
2
}
254
255
/// PrintPCRelImm - This is used to print an immediate value that ends up
256
/// being encoded as a pc-relative value.  These print slightly differently, for
257
/// example, a $ is not emitted.
258
void X86AsmPrinter::PrintPCRelImm(const MachineInstr *MI, unsigned OpNo,
259
5
                                  raw_ostream &O) {
260
5
  const MachineOperand &MO = MI->getOperand(OpNo);
261
5
  switch (MO.getType()) {
262
5
  
default: 0
llvm_unreachable0
("Unknown pcrel immediate operand");
263
5
  case MachineOperand::MO_Register:
264
2
    // pc-relativeness was handled when computing the value in the reg.
265
2
    PrintOperand(MI, OpNo, O);
266
2
    return;
267
5
  case MachineOperand::MO_Immediate:
268
1
    O << MO.getImm();
269
1
    return;
270
5
  case MachineOperand::MO_GlobalAddress:
271
2
    PrintSymbolOperand(MO, O);
272
2
    return;
273
5
  }
274
5
}
275
276
void X86AsmPrinter::PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,
277
225
                                         raw_ostream &O, const char *Modifier) {
278
225
  const MachineOperand &BaseReg = MI->getOperand(OpNo + X86::AddrBaseReg);
279
225
  const MachineOperand &IndexReg = MI->getOperand(OpNo + X86::AddrIndexReg);
280
225
  const MachineOperand &DispSpec = MI->getOperand(OpNo + X86::AddrDisp);
281
225
282
225
  // If we really don't want to print out (rip), don't.
283
225
  bool HasBaseReg = BaseReg.getReg() != 0;
284
225
  if (HasBaseReg && 
Modifier177
&&
!strcmp(Modifier, "no-rip")2
&&
285
225
      
BaseReg.getReg() == X86::RIP1
)
286
0
    HasBaseReg = false;
287
225
288
225
  // HasParenPart - True if we will print out the () part of the mem ref.
289
225
  bool HasParenPart = IndexReg.getReg() || 
HasBaseReg216
;
290
225
291
225
  switch (DispSpec.getType()) {
292
225
  default:
293
0
    llvm_unreachable("unknown operand type!");
294
225
  case MachineOperand::MO_Immediate: {
295
179
    int DispVal = DispSpec.getImm();
296
179
    if (DispVal || 
!HasParenPart123
)
297
64
      O << DispVal;
298
179
    break;
299
225
  }
300
225
  case MachineOperand::MO_GlobalAddress:
301
46
  case MachineOperand::MO_ConstantPoolIndex:
302
46
    PrintSymbolOperand(DispSpec, O);
303
46
    break;
304
225
  }
305
225
306
225
  if (Modifier && 
strcmp(Modifier, "H") == 02
)
307
1
    O << "+8";
308
225
309
225
  if (HasParenPart) {
310
177
    assert(IndexReg.getReg() != X86::ESP &&
311
177
           "X86 doesn't allow scaling by ESP");
312
177
313
177
    O << '(';
314
177
    if (HasBaseReg)
315
177
      PrintModifiedOperand(MI, OpNo + X86::AddrBaseReg, O, Modifier);
316
177
317
177
    if (IndexReg.getReg()) {
318
9
      O << ',';
319
9
      PrintModifiedOperand(MI, OpNo + X86::AddrIndexReg, O, Modifier);
320
9
      unsigned ScaleVal = MI->getOperand(OpNo + X86::AddrScaleAmt).getImm();
321
9
      if (ScaleVal != 1)
322
3
        O << ',' << ScaleVal;
323
9
    }
324
177
    O << ')';
325
177
  }
326
225
}
327
328
void X86AsmPrinter::PrintMemReference(const MachineInstr *MI, unsigned OpNo,
329
225
                                      raw_ostream &O, const char *Modifier) {
330
225
  assert(isMem(*MI, OpNo) && "Invalid memory reference!");
331
225
  const MachineOperand &Segment = MI->getOperand(OpNo + X86::AddrSegmentReg);
332
225
  if (Segment.getReg()) {
333
0
    PrintModifiedOperand(MI, OpNo + X86::AddrSegmentReg, O, Modifier);
334
0
    O << ':';
335
0
  }
336
225
  PrintLeaMemReference(MI, OpNo, O, Modifier);
337
225
}
338
339
void X86AsmPrinter::PrintIntelMemReference(const MachineInstr *MI,
340
27
                                           unsigned OpNo, raw_ostream &O) {
341
27
  const MachineOperand &BaseReg = MI->getOperand(OpNo + X86::AddrBaseReg);
342
27
  unsigned ScaleVal = MI->getOperand(OpNo + X86::AddrScaleAmt).getImm();
343
27
  const MachineOperand &IndexReg = MI->getOperand(OpNo + X86::AddrIndexReg);
344
27
  const MachineOperand &DispSpec = MI->getOperand(OpNo + X86::AddrDisp);
345
27
  const MachineOperand &SegReg = MI->getOperand(OpNo + X86::AddrSegmentReg);
346
27
347
27
  // If this has a segment register, print it.
348
27
  if (SegReg.getReg()) {
349
0
    PrintOperand(MI, OpNo + X86::AddrSegmentReg, O);
350
0
    O << ':';
351
0
  }
352
27
353
27
  O << '[';
354
27
355
27
  bool NeedPlus = false;
356
27
  if (BaseReg.getReg()) {
357
19
    PrintOperand(MI, OpNo + X86::AddrBaseReg, O);
358
19
    NeedPlus = true;
359
19
  }
360
27
361
27
  if (IndexReg.getReg()) {
362
0
    if (NeedPlus) O << " + ";
363
0
    if (ScaleVal != 1)
364
0
      O << ScaleVal << '*';
365
0
    PrintOperand(MI, OpNo + X86::AddrIndexReg, O);
366
0
    NeedPlus = true;
367
0
  }
368
27
369
27
  if (!DispSpec.isImm()) {
370
10
    if (NeedPlus) 
O << " + "2
;
371
10
    PrintOperand(MI, OpNo + X86::AddrDisp, O);
372
17
  } else {
373
17
    int64_t DispVal = DispSpec.getImm();
374
17
    if (DispVal || 
(6
!IndexReg.getReg()6
&&
!BaseReg.getReg()6
)) {
375
11
      if (NeedPlus) {
376
11
        if (DispVal > 0)
377
11
          O << " + ";
378
0
        else {
379
0
          O << " - ";
380
0
          DispVal = -DispVal;
381
0
        }
382
11
      }
383
11
      O << DispVal;
384
11
    }
385
17
  }
386
27
  O << ']';
387
27
}
388
389
static bool printAsmMRegister(X86AsmPrinter &P, const MachineOperand &MO,
390
18
                              char Mode, raw_ostream &O) {
391
18
  unsigned Reg = MO.getReg();
392
18
  bool EmitPercent = true;
393
18
394
18
  if (!X86::GR8RegClass.contains(Reg) &&
395
18
      !X86::GR16RegClass.contains(Reg) &&
396
18
      
!X86::GR32RegClass.contains(Reg)4
&&
397
18
      
!X86::GR64RegClass.contains(Reg)2
)
398
0
    return true;
399
18
400
18
  switch (Mode) {
401
18
  
default: return true0
; // Unknown mode.
402
18
  case 'b': // Print QImode register
403
2
    Reg = getX86SubSuperRegister(Reg, 8);
404
2
    break;
405
18
  case 'h': // Print QImode high register
406
1
    Reg = getX86SubSuperRegister(Reg, 8, true);
407
1
    break;
408
18
  case 'w': // Print HImode register
409
12
    Reg = getX86SubSuperRegister(Reg, 16);
410
12
    break;
411
18
  case 'k': // Print SImode register
412
0
    Reg = getX86SubSuperRegister(Reg, 32);
413
0
    break;
414
18
  case 'V':
415
2
    EmitPercent = false;
416
2
    LLVM_FALLTHROUGH;
417
3
  case 'q':
418
3
    // Print 64-bit register names if 64-bit integer registers are available.
419
3
    // Otherwise, print 32-bit register names.
420
3
    Reg = getX86SubSuperRegister(Reg, P.getSubtarget().is64Bit() ? 
641
:
322
);
421
3
    break;
422
18
  }
423
18
424
18
  if (EmitPercent)
425
16
    O << '%';
426
18
427
18
  O << X86ATTInstPrinter::getRegisterName(Reg);
428
18
  return false;
429
18
}
430
431
/// PrintAsmOperand - Print out an operand for an inline asm expression.
432
///
433
bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
434
1.24k
                                    const char *ExtraCode, raw_ostream &O) {
435
1.24k
  // Does this asm operand have a single letter operand modifier?
436
1.24k
  if (ExtraCode && 
ExtraCode[0]59
) {
437
59
    if (ExtraCode[1] != 0) 
return true0
; // Unknown modifier.
438
59
439
59
    const MachineOperand &MO = MI->getOperand(OpNo);
440
59
441
59
    switch (ExtraCode[0]) {
442
59
    default:
443
1
      // See if this is a generic print operand
444
1
      return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
445
59
    case 'a': // This is an address.  Currently only 'i' and 'r' are expected.
446
5
      switch (MO.getType()) {
447
5
      default:
448
0
        return true;
449
5
      case MachineOperand::MO_Immediate:
450
1
        O << MO.getImm();
451
1
        return false;
452
5
      case MachineOperand::MO_ConstantPoolIndex:
453
0
      case MachineOperand::MO_JumpTableIndex:
454
0
      case MachineOperand::MO_ExternalSymbol:
455
0
        llvm_unreachable("unexpected operand type!");
456
2
      case MachineOperand::MO_GlobalAddress:
457
2
        PrintSymbolOperand(MO, O);
458
2
        if (Subtarget->isPICStyleRIPRel())
459
1
          O << "(%rip)";
460
2
        return false;
461
2
      case MachineOperand::MO_Register:
462
2
        O << '(';
463
2
        PrintOperand(MI, OpNo, O);
464
2
        O << ')';
465
2
        return false;
466
0
      }
467
0
468
27
    case 'c': // Don't print "$" before a global var name or constant.
469
27
      switch (MO.getType()) {
470
27
      default:
471
0
        PrintOperand(MI, OpNo, O);
472
0
        break;
473
27
      case MachineOperand::MO_Immediate:
474
12
        O << MO.getImm();
475
12
        break;
476
27
      case MachineOperand::MO_ConstantPoolIndex:
477
0
      case MachineOperand::MO_JumpTableIndex:
478
0
      case MachineOperand::MO_ExternalSymbol:
479
0
        llvm_unreachable("unexpected operand type!");
480
15
      case MachineOperand::MO_GlobalAddress:
481
15
        PrintSymbolOperand(MO, O);
482
15
        break;
483
27
      }
484
27
      return false;
485
27
486
27
    case 'A': // Print '*' before a register (it must be a register)
487
0
      if (MO.isReg()) {
488
0
        O << '*';
489
0
        PrintOperand(MI, OpNo, O);
490
0
        return false;
491
0
      }
492
0
      return true;
493
0
494
19
    case 'b': // Print QImode register
495
19
    case 'h': // Print QImode high register
496
19
    case 'w': // Print HImode register
497
19
    case 'k': // Print SImode register
498
19
    case 'q': // Print DImode register
499
19
    case 'V': // Print native register without '%'
500
19
      if (MO.isReg())
501
18
        return printAsmMRegister(*this, MO, ExtraCode[0], O);
502
1
      PrintOperand(MI, OpNo, O);
503
1
      return false;
504
1
505
5
    case 'P': // This is the operand of a call, treat specially.
506
5
      PrintPCRelImm(MI, OpNo, O);
507
5
      return false;
508
1
509
2
    case 'n': // Negate the immediate or print a '-' before the operand.
510
2
      // Note: this is a temporary solution. It should be handled target
511
2
      // independently as part of the 'MC' work.
512
2
      if (MO.isImm()) {
513
2
        O << -MO.getImm();
514
2
        return false;
515
2
      }
516
0
      O << '-';
517
59
    }
518
59
  }
519
1.24k
520
1.24k
  PrintOperand(MI, OpNo, O);
521
1.18k
  return false;
522
1.24k
}
523
524
bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
525
                                          const char *ExtraCode,
526
252
                                          raw_ostream &O) {
527
252
  if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
528
27
    PrintIntelMemReference(MI, OpNo, O);
529
27
    return false;
530
27
  }
531
225
532
225
  if (ExtraCode && 
ExtraCode[0]3
) {
533
3
    if (ExtraCode[1] != 0) 
return true0
; // Unknown modifier.
534
3
535
3
    switch (ExtraCode[0]) {
536
3
    
default: return true0
; // Unknown modifier.
537
3
    case 'b': // Print QImode register
538
1
    case 'h': // Print QImode high register
539
1
    case 'w': // Print HImode register
540
1
    case 'k': // Print SImode register
541
1
    case 'q': // Print SImode register
542
1
      // These only apply to registers, ignore on mem.
543
1
      break;
544
1
    case 'H':
545
1
      PrintMemReference(MI, OpNo, O, "H");
546
1
      return false;
547
1
    case 'P': // Don't print @PLT, but do print as memory.
548
1
      PrintMemReference(MI, OpNo, O, "no-rip");
549
1
      return false;
550
223
    }
551
223
  }
552
223
  PrintMemReference(MI, OpNo, O, nullptr);
553
223
  return false;
554
223
}
555
556
12.1k
void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
557
12.1k
  const Triple &TT = TM.getTargetTriple();
558
12.1k
559
12.1k
  if (TT.isOSBinFormatELF()) {
560
6.66k
    // Assemble feature flags that may require creation of a note section.
561
6.66k
    unsigned FeatureFlagsAnd = 0;
562
6.66k
    if (M.getModuleFlag("cf-protection-branch"))
563
7
      FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_IBT;
564
6.66k
    if (M.getModuleFlag("cf-protection-return"))
565
4
      FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_SHSTK;
566
6.66k
567
6.66k
    if (FeatureFlagsAnd) {
568
7
      // Emit a .note.gnu.property section with the flags.
569
7
      if (!TT.isArch32Bit() && 
!TT.isArch64Bit()4
)
570
7
        
llvm_unreachable0
("CFProtection used on invalid architecture!");
571
7
      MCSection *Cur = OutStreamer->getCurrentSectionOnly();
572
7
      MCSection *Nt = MMI->getContext().getELFSection(
573
7
          ".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
574
7
      OutStreamer->SwitchSection(Nt);
575
7
576
7
      // Emitting note header.
577
7
      int WordSize = TT.isArch64Bit() ? 
84
:
43
;
578
7
      EmitAlignment(WordSize == 4 ? 
23
:
34
);
579
7
      OutStreamer->EmitIntValue(4, 4 /*size*/); // data size for "GNU\0"
580
7
      OutStreamer->EmitIntValue(8 + WordSize, 4 /*size*/); // Elf_Prop size
581
7
      OutStreamer->EmitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4 /*size*/);
582
7
      OutStreamer->EmitBytes(StringRef("GNU", 4)); // note name
583
7
584
7
      // Emitting an Elf_Prop for the CET properties.
585
7
      OutStreamer->EmitIntValue(ELF::GNU_PROPERTY_X86_FEATURE_1_AND, 4);
586
7
      OutStreamer->EmitIntValue(4, 4);               // data size
587
7
      OutStreamer->EmitIntValue(FeatureFlagsAnd, 4); // data
588
7
      EmitAlignment(WordSize == 4 ? 
23
:
34
); // padding
589
7
590
7
      OutStreamer->endSection(Nt);
591
7
      OutStreamer->SwitchSection(Cur);
592
7
    }
593
6.66k
  }
594
12.1k
595
12.1k
  if (TT.isOSBinFormatMachO())
596
4.74k
    OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
597
12.1k
598
12.1k
  if (TT.isOSBinFormatCOFF()) {
599
767
    // Emit an absolute @feat.00 symbol.  This appears to be some kind of
600
767
    // compiler features bitfield read by link.exe.
601
767
    MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00"));
602
767
    OutStreamer->BeginCOFFSymbolDef(S);
603
767
    OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
604
767
    OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
605
767
    OutStreamer->EndCOFFSymbolDef();
606
767
    int64_t Feat00Flags = 0;
607
767
608
767
    if (TT.getArch() == Triple::x86) {
609
310
      // According to the PE-COFF spec, the LSB of this value marks the object
610
310
      // for "registered SEH".  This means that all SEH handler entry points
611
310
      // must be registered in .sxdata.  Use of any unregistered handlers will
612
310
      // cause the process to terminate immediately.  LLVM does not know how to
613
310
      // register any SEH handlers, so its object files should be safe.
614
310
      Feat00Flags |= 1;
615
310
    }
616
767
617
767
    if (M.getModuleFlag("cfguardtable"))
618
1
      Feat00Flags |= 0x800; // Object is CFG-aware.
619
767
620
767
    OutStreamer->EmitSymbolAttribute(S, MCSA_Global);
621
767
    OutStreamer->EmitAssignment(
622
767
        S, MCConstantExpr::create(Feat00Flags, MMI->getContext()));
623
767
  }
624
12.1k
  OutStreamer->EmitSyntaxDirective();
625
12.1k
626
12.1k
  // If this is not inline asm and we're in 16-bit
627
12.1k
  // mode prefix assembly with .code16.
628
12.1k
  bool is16 = TT.getEnvironment() == Triple::CODE16;
629
12.1k
  if (M.getModuleInlineAsm().empty() && 
is1611.5k
)
630
1
    OutStreamer->EmitAssemblerFlag(MCAF_Code16);
631
12.1k
}
632
633
static void
634
emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel,
635
623
                         MachineModuleInfoImpl::StubValueTy &MCSym) {
636
623
  // L_foo$stub:
637
623
  OutStreamer.EmitLabel(StubLabel);
638
623
  //   .indirect_symbol _foo
639
623
  OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
640
623
641
623
  if (MCSym.getInt())
642
621
    // External to current translation unit.
643
621
    OutStreamer.EmitIntValue(0, 4/*size*/);
644
2
  else
645
2
    // Internal to current translation unit.
646
2
    //
647
2
    // When we place the LSDA into the TEXT section, the type info
648
2
    // pointers need to be indirect and pc-rel. We accomplish this by
649
2
    // using NLPs; however, sometimes the types are local to the file.
650
2
    // We need to fill in the value for the NLP in those cases.
651
2
    OutStreamer.EmitValue(
652
2
        MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()),
653
2
        4 /*size*/);
654
623
}
655
656
4.74k
static void emitNonLazyStubs(MachineModuleInfo *MMI, MCStreamer &OutStreamer) {
657
4.74k
658
4.74k
  MachineModuleInfoMachO &MMIMacho =
659
4.74k
      MMI->getObjFileInfo<MachineModuleInfoMachO>();
660
4.74k
661
4.74k
  // Output stubs for dynamically-linked functions.
662
4.74k
  MachineModuleInfoMachO::SymbolListTy Stubs;
663
4.74k
664
4.74k
  // Output stubs for external and common global variables.
665
4.74k
  Stubs = MMIMacho.GetGVStubList();
666
4.74k
  if (!Stubs.empty()) {
667
194
    OutStreamer.SwitchSection(MMI->getContext().getMachOSection(
668
194
        "__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS,
669
194
        SectionKind::getMetadata()));
670
194
671
194
    for (auto &Stub : Stubs)
672
623
      emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
673
194
674
194
    Stubs.clear();
675
194
    OutStreamer.AddBlankLine();
676
194
  }
677
4.74k
}
678
679
12.1k
void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
680
12.1k
  const Triple &TT = TM.getTargetTriple();
681
12.1k
682
12.1k
  if (TT.isOSBinFormatMachO()) {
683
4.74k
    // Mach-O uses non-lazy symbol stubs to encode per-TU information into
684
4.74k
    // global table for symbol lookup.
685
4.74k
    emitNonLazyStubs(MMI, *OutStreamer);
686
4.74k
687
4.74k
    // Emit stack and fault map information.
688
4.74k
    emitStackMaps(SM);
689
4.74k
    FM.serializeToFaultMapSection();
690
4.74k
691
4.74k
    // This flag tells the linker that no global symbols contain code that fall
692
4.74k
    // through to other global symbols (e.g. an implementation of multiple entry
693
4.74k
    // points). If this doesn't occur, the linker can safely perform dead code
694
4.74k
    // stripping. Since LLVM never generates code that does this, it is always
695
4.74k
    // safe to set.
696
4.74k
    OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
697
7.37k
  } else if (TT.isOSBinFormatCOFF()) {
698
763
    if (MMI->usesMSVCFloatingPoint()) {
699
94
      // In Windows' libcmt.lib, there is a file which is linked in only if the
700
94
      // symbol _fltused is referenced. Linking this in causes some
701
94
      // side-effects:
702
94
      //
703
94
      // 1. For x86-32, it will set the x87 rounding mode to 53-bit instead of
704
94
      // 64-bit mantissas at program start.
705
94
      //
706
94
      // 2. It links in support routines for floating-point in scanf and printf.
707
94
      //
708
94
      // MSVC emits an undefined reference to _fltused when there are any
709
94
      // floating point operations in the program (including calls). A program
710
94
      // that only has: `scanf("%f", &global_float);` may fail to trigger this,
711
94
      // but oh well...that's a documented issue.
712
94
      StringRef SymbolName =
713
94
          (TT.getArch() == Triple::x86) ? 
"__fltused"38
:
"_fltused"56
;
714
94
      MCSymbol *S = MMI->getContext().getOrCreateSymbol(SymbolName);
715
94
      OutStreamer->EmitSymbolAttribute(S, MCSA_Global);
716
94
      return;
717
94
    }
718
669
    emitStackMaps(SM);
719
6.61k
  } else 
if (6.61k
TT.isOSBinFormatELF()6.61k
) {
720
6.61k
    emitStackMaps(SM);
721
6.61k
    FM.serializeToFaultMapSection();
722
6.61k
  }
723
12.1k
}
724
725
//===----------------------------------------------------------------------===//
726
// Target Registry Stuff
727
//===----------------------------------------------------------------------===//
728
729
// Force static initialization.
730
79.2k
extern "C" void LLVMInitializeX86AsmPrinter() {
731
79.2k
  RegisterAsmPrinter<X86AsmPrinter> X(getTheX86_32Target());
732
79.2k
  RegisterAsmPrinter<X86AsmPrinter> Y(getTheX86_64Target());
733
79.2k
}