Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- XCoreAsmPrinter.cpp - XCore LLVM assembly writer ------------------===//
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 the XAS-format XCore assembly language.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "MCTargetDesc/XCoreInstPrinter.h"
15
#include "TargetInfo/XCoreTargetInfo.h"
16
#include "XCore.h"
17
#include "XCoreInstrInfo.h"
18
#include "XCoreMCInstLower.h"
19
#include "XCoreSubtarget.h"
20
#include "XCoreTargetMachine.h"
21
#include "XCoreTargetStreamer.h"
22
#include "llvm/ADT/SmallString.h"
23
#include "llvm/ADT/StringExtras.h"
24
#include "llvm/CodeGen/AsmPrinter.h"
25
#include "llvm/CodeGen/MachineConstantPool.h"
26
#include "llvm/CodeGen/MachineFunctionPass.h"
27
#include "llvm/CodeGen/MachineInstr.h"
28
#include "llvm/CodeGen/MachineJumpTableInfo.h"
29
#include "llvm/CodeGen/MachineModuleInfo.h"
30
#include "llvm/IR/Constants.h"
31
#include "llvm/IR/DataLayout.h"
32
#include "llvm/IR/DebugInfo.h"
33
#include "llvm/IR/DerivedTypes.h"
34
#include "llvm/IR/Mangler.h"
35
#include "llvm/IR/Module.h"
36
#include "llvm/MC/MCAsmInfo.h"
37
#include "llvm/MC/MCExpr.h"
38
#include "llvm/MC/MCInst.h"
39
#include "llvm/MC/MCStreamer.h"
40
#include "llvm/MC/MCSymbolELF.h"
41
#include "llvm/Support/ErrorHandling.h"
42
#include "llvm/Support/TargetRegistry.h"
43
#include "llvm/Support/raw_ostream.h"
44
#include "llvm/Target/TargetLoweringObjectFile.h"
45
#include <algorithm>
46
#include <cctype>
47
using namespace llvm;
48
49
#define DEBUG_TYPE "asm-printer"
50
51
namespace {
52
  class XCoreAsmPrinter : public AsmPrinter {
53
    XCoreMCInstLower MCInstLowering;
54
    XCoreTargetStreamer &getTargetStreamer();
55
56
  public:
57
    explicit XCoreAsmPrinter(TargetMachine &TM,
58
                             std::unique_ptr<MCStreamer> Streamer)
59
70
        : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(*this) {}
60
61
279
    StringRef getPassName() const override { return "XCore Assembly Printer"; }
62
63
    void printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
64
                       const std::string &directive = ".jmptable");
65
1
    void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) {
66
1
      printInlineJT(MI, opNum, O, ".jmptable32");
67
1
    }
68
    void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
69
    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
70
                         const char *ExtraCode, raw_ostream &O) override;
71
    bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
72
                               const char *ExtraCode, raw_ostream &O) override;
73
74
    void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV);
75
    void EmitGlobalVariable(const GlobalVariable *GV) override;
76
77
    void EmitFunctionEntryLabel() override;
78
    void EmitInstruction(const MachineInstr *MI) override;
79
    void EmitFunctionBodyStart() override;
80
    void EmitFunctionBodyEnd() override;
81
  };
82
} // end of anonymous namespace
83
84
661
XCoreTargetStreamer &XCoreAsmPrinter::getTargetStreamer() {
85
661
  return static_cast<XCoreTargetStreamer&>(*OutStreamer->getTargetStreamer());
86
661
}
87
88
39
void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) {
89
39
  assert( ( GV->hasExternalLinkage() || GV->hasWeakLinkage() ||
90
39
            GV->hasLinkOnceLinkage() || GV->hasCommonLinkage() ) &&
91
39
          "Unexpected linkage");
92
39
  if (ArrayType *ATy = dyn_cast<ArrayType>(GV->getValueType())) {
93
19
94
19
    MCSymbol *SymGlob = OutContext.getOrCreateSymbol(
95
19
                          Twine(Sym->getName() + StringRef(".globound")));
96
19
    OutStreamer->EmitSymbolAttribute(SymGlob, MCSA_Global);
97
19
    OutStreamer->EmitAssignment(SymGlob,
98
19
                                MCConstantExpr::create(ATy->getNumElements(),
99
19
                                                       OutContext));
100
19
    if (GV->hasWeakLinkage() || 
GV->hasLinkOnceLinkage()18
||
101
19
        
GV->hasCommonLinkage()18
) {
102
2
      OutStreamer->EmitSymbolAttribute(SymGlob, MCSA_Weak);
103
2
    }
104
19
  }
105
39
}
106
107
93
void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
108
93
  // Check to see if this is a special global used by LLVM, if so, emit it.
109
93
  if (!GV->hasInitializer() ||
110
93
      
EmitSpecialLLVMGlobal(GV)52
)
111
41
    return;
112
52
113
52
  const DataLayout &DL = getDataLayout();
114
52
  OutStreamer->SwitchSection(getObjFileLowering().SectionForGlobal(GV, TM));
115
52
116
52
  MCSymbol *GVSym = getSymbol(GV);
117
52
  const Constant *C = GV->getInitializer();
118
52
  unsigned Align = (unsigned)DL.getPreferredTypeAlignmentShift(C->getType());
119
52
120
52
  // Mark the start of the global
121
52
  getTargetStreamer().emitCCTopData(GVSym->getName());
122
52
123
52
  switch (GV->getLinkage()) {
124
52
  case GlobalValue::AppendingLinkage:
125
0
    report_fatal_error("AppendingLinkage is not supported by this target!");
126
52
  case GlobalValue::LinkOnceAnyLinkage:
127
39
  case GlobalValue::LinkOnceODRLinkage:
128
39
  case GlobalValue::WeakAnyLinkage:
129
39
  case GlobalValue::WeakODRLinkage:
130
39
  case GlobalValue::ExternalLinkage:
131
39
  case GlobalValue::CommonLinkage:
132
39
    emitArrayBound(GVSym, GV);
133
39
    OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Global);
134
39
135
39
    if (GV->hasWeakLinkage() || 
GV->hasLinkOnceLinkage()37
||
136
39
        
GV->hasCommonLinkage()37
)
137
4
      OutStreamer->EmitSymbolAttribute(GVSym, MCSA_Weak);
138
39
    LLVM_FALLTHROUGH;
139
52
  case GlobalValue::InternalLinkage:
140
52
  case GlobalValue::PrivateLinkage:
141
52
    break;
142
52
  default:
143
0
    llvm_unreachable("Unknown linkage type!");
144
52
  }
145
52
146
52
  EmitAlignment(Align > 2 ? 
Align0
: 2, GV);
147
52
148
52
  if (GV->isThreadLocal()) {
149
0
    report_fatal_error("TLS is not supported by this target!");
150
0
  }
151
52
  unsigned Size = DL.getTypeAllocSize(C->getType());
152
52
  if (MAI->hasDotTypeDotSizeDirective()) {
153
52
    OutStreamer->EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
154
52
    OutStreamer->emitELFSize(GVSym, MCConstantExpr::create(Size, OutContext));
155
52
  }
156
52
  OutStreamer->EmitLabel(GVSym);
157
52
158
52
  EmitGlobalConstant(DL, C);
159
52
  // The ABI requires that unsigned scalar types smaller than 32 bits
160
52
  // are padded to 32 bits.
161
52
  if (Size < 4)
162
0
    OutStreamer->EmitZeros(4 - Size);
163
52
164
52
  // Mark the end of the global
165
52
  getTargetStreamer().emitCCBottomData(GVSym->getName());
166
52
}
167
168
278
void XCoreAsmPrinter::EmitFunctionBodyStart() {
169
278
  MCInstLowering.Initialize(&MF->getContext());
170
278
}
171
172
/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
173
/// the last basic block in the function.
174
278
void XCoreAsmPrinter::EmitFunctionBodyEnd() {
175
278
  // Emit function end directives
176
278
  getTargetStreamer().emitCCBottomFunction(CurrentFnSym->getName());
177
278
}
178
179
279
void XCoreAsmPrinter::EmitFunctionEntryLabel() {
180
279
  // Mark the start of the function
181
279
  getTargetStreamer().emitCCTopFunction(CurrentFnSym->getName());
182
279
  OutStreamer->EmitLabel(CurrentFnSym);
183
279
}
184
185
void XCoreAsmPrinter::
186
printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
187
2
              const std::string &directive) {
188
2
  unsigned JTI = MI->getOperand(opNum).getIndex();
189
2
  const MachineFunction *MF = MI->getParent()->getParent();
190
2
  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
191
2
  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
192
2
  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
193
2
  O << "\t" << directive << " ";
194
46
  for (unsigned i = 0, e = JTBBs.size(); i != e; 
++i44
) {
195
44
    MachineBasicBlock *MBB = JTBBs[i];
196
44
    if (i > 0)
197
42
      O << ",";
198
44
    MBB->getSymbol()->print(O, MAI);
199
44
  }
200
2
}
201
202
void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
203
8
                                   raw_ostream &O) {
204
8
  const DataLayout &DL = getDataLayout();
205
8
  const MachineOperand &MO = MI->getOperand(opNum);
206
8
  switch (MO.getType()) {
207
8
  case MachineOperand::MO_Register:
208
5
    O << XCoreInstPrinter::getRegisterName(MO.getReg());
209
5
    break;
210
8
  case MachineOperand::MO_Immediate:
211
1
    O << MO.getImm();
212
1
    break;
213
8
  case MachineOperand::MO_MachineBasicBlock:
214
0
    MO.getMBB()->getSymbol()->print(O, MAI);
215
0
    break;
216
8
  case MachineOperand::MO_GlobalAddress:
217
2
    PrintSymbolOperand(MO, O);
218
2
    break;
219
8
  case MachineOperand::MO_ConstantPoolIndex:
220
0
    O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
221
0
      << MO.getIndex();
222
0
    break;
223
8
  case MachineOperand::MO_BlockAddress:
224
0
    GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
225
0
    break;
226
8
  default:
227
0
    llvm_unreachable("not implemented");
228
8
  }
229
8
}
230
231
/// PrintAsmOperand - Print out an operand for an inline asm expression.
232
///
233
bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
234
9
                                      const char *ExtraCode, raw_ostream &O) {
235
9
  // Print the operand if there is no operand modifier.
236
9
  if (!ExtraCode || 
!ExtraCode[0]5
) {
237
4
    printOperand(MI, OpNo, O);
238
4
    return false;
239
4
  }
240
5
241
5
  // Otherwise fallback on the default implementation.
242
5
  return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
243
5
}
244
245
bool XCoreAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
246
                                            unsigned OpNum,
247
                                            const char *ExtraCode,
248
2
                                            raw_ostream &O) {
249
2
  if (ExtraCode && 
ExtraCode[0]0
) {
250
0
    return true; // Unknown modifier.
251
0
  }
252
2
  printOperand(MI, OpNum, O);
253
2
  O << '[';
254
2
  printOperand(MI, OpNum + 1, O);
255
2
  O << ']';
256
2
  return false;
257
2
}
258
259
1.56k
void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) {
260
1.56k
  SmallString<128> Str;
261
1.56k
  raw_svector_ostream O(Str);
262
1.56k
263
1.56k
  switch (MI->getOpcode()) {
264
1.56k
  case XCore::DBG_VALUE:
265
0
    llvm_unreachable("Should be handled target independently");
266
1.56k
  case XCore::ADD_2rus:
267
87
    if (MI->getOperand(2).getImm() == 0) {
268
82
      O << "\tmov "
269
82
        << XCoreInstPrinter::getRegisterName(MI->getOperand(0).getReg()) << ", "
270
82
        << XCoreInstPrinter::getRegisterName(MI->getOperand(1).getReg());
271
82
      OutStreamer->EmitRawText(O.str());
272
82
      return;
273
82
    }
274
5
    break;
275
5
  case XCore::BR_JT:
276
2
  case XCore::BR_JT32:
277
2
    O << "\tbru "
278
2
      << XCoreInstPrinter::getRegisterName(MI->getOperand(1).getReg()) << '\n';
279
2
    if (MI->getOpcode() == XCore::BR_JT)
280
1
      printInlineJT(MI, 0, O);
281
1
    else
282
1
      printInlineJT32(MI, 0, O);
283
2
    O << '\n';
284
2
    OutStreamer->EmitRawText(O.str());
285
2
    return;
286
1.48k
  }
287
1.48k
288
1.48k
  MCInst TmpInst;
289
1.48k
  MCInstLowering.Lower(MI, TmpInst);
290
1.48k
291
1.48k
  EmitToStreamer(*OutStreamer, TmpInst);
292
1.48k
}
293
294
// Force static initialization.
295
78.9k
extern "C" void LLVMInitializeXCoreAsmPrinter() {
296
78.9k
  RegisterAsmPrinter<XCoreAsmPrinter> X(getTheXCoreTarget());
297
78.9k
}