Coverage Report

Created: 2017-10-03 07:32

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