LLVM  14.0.0git
XCoreAsmPrinter.cpp
Go to the documentation of this file.
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 
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"
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"
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  : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(*this) {}
60 
61  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  void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) {
66  printInlineJT(MI, opNum, O, ".jmptable32");
67  }
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 XCoreTargetStreamer &XCoreAsmPrinter::getTargetStreamer() {
85  return static_cast<XCoreTargetStreamer&>(*OutStreamer->getTargetStreamer());
86 }
87 
88 void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) {
89  assert( ( GV->hasExternalLinkage() || GV->hasWeakLinkage() ||
90  GV->hasLinkOnceLinkage() || GV->hasCommonLinkage() ) &&
91  "Unexpected linkage");
92  if (ArrayType *ATy = dyn_cast<ArrayType>(GV->getValueType())) {
93 
94  MCSymbol *SymGlob = OutContext.getOrCreateSymbol(
95  Twine(Sym->getName() + StringRef(".globound")));
96  OutStreamer->emitSymbolAttribute(SymGlob, MCSA_Global);
97  OutStreamer->emitAssignment(SymGlob,
98  MCConstantExpr::create(ATy->getNumElements(),
99  OutContext));
100  if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
101  GV->hasCommonLinkage()) {
102  OutStreamer->emitSymbolAttribute(SymGlob, MCSA_Weak);
103  }
104  }
105 }
106 
107 void XCoreAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
108  // Check to see if this is a special global used by LLVM, if so, emit it.
109  if (!GV->hasInitializer() || emitSpecialLLVMGlobal(GV))
110  return;
111 
112  const DataLayout &DL = getDataLayout();
113  OutStreamer->SwitchSection(getObjFileLowering().SectionForGlobal(GV, TM));
114 
115  MCSymbol *GVSym = getSymbol(GV);
116  const Constant *C = GV->getInitializer();
117  const Align Alignment(DL.getPrefTypeAlignment(C->getType()));
118 
119  // Mark the start of the global
120  getTargetStreamer().emitCCTopData(GVSym->getName());
121 
122  switch (GV->getLinkage()) {
124  report_fatal_error("AppendingLinkage is not supported by this target!");
131  emitArrayBound(GVSym, GV);
132  OutStreamer->emitSymbolAttribute(GVSym, MCSA_Global);
133 
134  if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
135  GV->hasCommonLinkage())
136  OutStreamer->emitSymbolAttribute(GVSym, MCSA_Weak);
140  break;
141  default:
142  llvm_unreachable("Unknown linkage type!");
143  }
144 
145  emitAlignment(std::max(Alignment, Align(4)), GV);
146 
147  if (GV->isThreadLocal()) {
148  report_fatal_error("TLS is not supported by this target!");
149  }
150  unsigned Size = DL.getTypeAllocSize(C->getType());
151  if (MAI->hasDotTypeDotSizeDirective()) {
152  OutStreamer->emitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
153  OutStreamer->emitELFSize(GVSym, MCConstantExpr::create(Size, OutContext));
154  }
155  OutStreamer->emitLabel(GVSym);
156 
157  emitGlobalConstant(DL, C);
158  // The ABI requires that unsigned scalar types smaller than 32 bits
159  // are padded to 32 bits.
160  if (Size < 4)
161  OutStreamer->emitZeros(4 - Size);
162 
163  // Mark the end of the global
164  getTargetStreamer().emitCCBottomData(GVSym->getName());
165 }
166 
167 void XCoreAsmPrinter::emitFunctionBodyStart() {
168  MCInstLowering.Initialize(&MF->getContext());
169 }
170 
171 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
172 /// the last basic block in the function.
173 void XCoreAsmPrinter::emitFunctionBodyEnd() {
174  // Emit function end directives
175  getTargetStreamer().emitCCBottomFunction(CurrentFnSym->getName());
176 }
177 
178 void XCoreAsmPrinter::emitFunctionEntryLabel() {
179  // Mark the start of the function
180  getTargetStreamer().emitCCTopFunction(CurrentFnSym->getName());
181  OutStreamer->emitLabel(CurrentFnSym);
182 }
183 
184 void XCoreAsmPrinter::
185 printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
186  const std::string &directive) {
187  unsigned JTI = MI->getOperand(opNum).getIndex();
188  const MachineFunction *MF = MI->getParent()->getParent();
189  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
190  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
191  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
192  O << "\t" << directive << " ";
193  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
194  MachineBasicBlock *MBB = JTBBs[i];
195  if (i > 0)
196  O << ",";
197  MBB->getSymbol()->print(O, MAI);
198  }
199 }
200 
201 void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
202  raw_ostream &O) {
203  const DataLayout &DL = getDataLayout();
204  const MachineOperand &MO = MI->getOperand(opNum);
205  switch (MO.getType()) {
208  break;
210  O << MO.getImm();
211  break;
213  MO.getMBB()->getSymbol()->print(O, MAI);
214  break;
216  PrintSymbolOperand(MO, O);
217  break;
219  O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
220  << MO.getIndex();
221  break;
223  GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
224  break;
225  default:
226  llvm_unreachable("not implemented");
227  }
228 }
229 
230 /// PrintAsmOperand - Print out an operand for an inline asm expression.
231 ///
232 bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
233  const char *ExtraCode, raw_ostream &O) {
234  // Print the operand if there is no operand modifier.
235  if (!ExtraCode || !ExtraCode[0]) {
236  printOperand(MI, OpNo, O);
237  return false;
238  }
239 
240  // Otherwise fallback on the default implementation.
241  return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
242 }
243 
244 bool XCoreAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
245  unsigned OpNum,
246  const char *ExtraCode,
247  raw_ostream &O) {
248  if (ExtraCode && ExtraCode[0]) {
249  return true; // Unknown modifier.
250  }
251  printOperand(MI, OpNum, O);
252  O << '[';
253  printOperand(MI, OpNum + 1, O);
254  O << ']';
255  return false;
256 }
257 
258 void XCoreAsmPrinter::emitInstruction(const MachineInstr *MI) {
259  SmallString<128> Str;
260  raw_svector_ostream O(Str);
261 
262  switch (MI->getOpcode()) {
263  case XCore::DBG_VALUE:
264  llvm_unreachable("Should be handled target independently");
265  case XCore::ADD_2rus:
266  if (MI->getOperand(2).getImm() == 0) {
267  O << "\tmov "
268  << XCoreInstPrinter::getRegisterName(MI->getOperand(0).getReg()) << ", "
269  << XCoreInstPrinter::getRegisterName(MI->getOperand(1).getReg());
270  OutStreamer->emitRawText(O.str());
271  return;
272  }
273  break;
274  case XCore::BR_JT:
275  case XCore::BR_JT32:
276  O << "\tbru "
277  << XCoreInstPrinter::getRegisterName(MI->getOperand(1).getReg()) << '\n';
278  if (MI->getOpcode() == XCore::BR_JT)
279  printInlineJT(MI, 0, O);
280  else
281  printInlineJT32(MI, 0, O);
282  O << '\n';
283  OutStreamer->emitRawText(O.str());
284  return;
285  }
286 
287  MCInst TmpInst;
288  MCInstLowering.Lower(MI, TmpInst);
289 
290  EmitToStreamer(*OutStreamer, TmpInst);
291 }
292 
293 // Force static initialization.
296 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
i
i
Definition: README.txt:29
AsmPrinter.h
llvm::MachineOperand::MO_BlockAddress
@ MO_BlockAddress
Address of a basic block.
Definition: MachineOperand.h:63
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
MachineInstr.h
llvm::MachineOperand::MO_Immediate
@ MO_Immediate
Immediate operand.
Definition: MachineOperand.h:53
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::GlobalValue::hasCommonLinkage
bool hasCommonLinkage() const
Definition: GlobalValue.h:449
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:112
llvm::GlobalValue::LinkOnceAnyLinkage
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
Definition: GlobalValue.h:50
llvm::ISD::BR_JT
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:946
llvm::GlobalValue::hasExternalLinkage
bool hasExternalLinkage() const
Definition: GlobalValue.h:431
llvm::GlobalValue::getLinkage
LinkageTypes getLinkage() const
Definition: GlobalValue.h:461
llvm::HexagonISD::JT
@ JT
Definition: HexagonISelLowering.h:52
llvm::XCoreTargetStreamer
Definition: XCoreTargetStreamer.h:15
llvm::MCSA_ELF_TypeObject
@ MCSA_ELF_TypeObject
.type _foo, STT_OBJECT # aka @object
Definition: MCDirectives.h:25
XCore.h
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
llvm::GlobalValue::hasWeakLinkage
bool hasWeakLinkage() const
Definition: GlobalValue.h:439
llvm::MachineOperand::getBlockAddress
const BlockAddress * getBlockAddress() const
Definition: MachineOperand.h:568
ErrorHandling.h
llvm::GlobalVariable
Definition: GlobalVariable.h:40
MachineJumpTableInfo.h
Module.h
printOperand
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
Definition: SelectionDAGDumper.cpp:946
XCoreInstPrinter.h
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::ArrayType
Class to represent array types.
Definition: DerivedTypes.h:357
llvm::MachineOperand::MO_Register
@ MO_Register
Register operand.
Definition: MachineOperand.h:52
llvm::GlobalVariable::hasInitializer
bool hasInitializer() const
Definitions have initializers, declarations don't.
Definition: GlobalVariable.h:92
XCoreMCInstLower.h
llvm::MachineBasicBlock::getSymbol
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Definition: MachineBasicBlock.cpp:60
Constants.h
SmallString.h
llvm::MachineOperand::MO_GlobalAddress
@ MO_GlobalAddress
Address of a global value.
Definition: MachineOperand.h:62
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:537
XCoreTargetStreamer.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
MCSymbolELF.h
XCoreInstrInfo.h
MCInst.h
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::MCSymbol::getName
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:198
XCoreSubtarget.h
Align
uint64_t Align
Definition: ELFObjHandler.cpp:83
llvm::GlobalValue::InternalLinkage
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
llvm::MCSymbol::print
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:59
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::SmallString< 128 >
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:192
llvm::getTheXCoreTarget
Target & getTheXCoreTarget()
Definition: XCoreTargetInfo.cpp:13
llvm::MachineJumpTableInfo::getJumpTables
const std::vector< MachineJumpTableEntry > & getJumpTables() const
Definition: MachineJumpTableInfo.h:99
llvm::GlobalVariable::getInitializer
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Definition: GlobalVariable.h:136
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
llvm::GlobalValue::WeakAnyLinkage
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Definition: GlobalValue.h:52
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
DebugInfo.h
llvm::XCoreInstPrinter::getRegisterName
static const char * getRegisterName(unsigned RegNo)
StringExtras.h
MachineConstantPool.h
llvm::MachineOperand::getType
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Definition: MachineOperand.h:219
MachineFunctionPass.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:79
llvm::GlobalValue::isThreadLocal
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
Definition: GlobalValue.h:244
MachineModuleInfo.h
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::GlobalValue::AppendingLinkage
@ AppendingLinkage
Special purpose, only applies to global arrays.
Definition: GlobalValue.h:54
Mangler.h
llvm::MachineOperand::getMBB
MachineBasicBlock * getMBB() const
Definition: MachineOperand.h:552
MCAsmInfo.h
DataLayout.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
TargetLoweringObjectFile.h
llvm::GlobalValue::WeakODRLinkage
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:53
llvm::MachineOperand::MO_MachineBasicBlock
@ MO_MachineBasicBlock
MachineBasicBlock reference.
Definition: MachineOperand.h:56
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:273
llvm::GlobalValue::CommonLinkage
@ CommonLinkage
Tentative definitions.
Definition: GlobalValue.h:58
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::MachineOperand::getIndex
int getIndex() const
Definition: MachineOperand.h:557
llvm::XCoreMCInstLower
This class is used to lower an MachineInstr into an MCInst.
Definition: XCoreMCInstLower.h:23
llvm::AsmPrinter
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:82
XCoreTargetMachine.h
llvm::MCSA_Global
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
llvm::MCSA_Weak
@ MCSA_Weak
.weak
Definition: MCDirectives.h:44
llvm::GlobalValue::PrivateLinkage
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:56
MCStreamer.h
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:658
llvm::GlobalValue::hasLinkOnceLinkage
bool hasLinkOnceLinkage() const
Definition: GlobalValue.h:435
DerivedTypes.h
llvm::GlobalValue::getValueType
Type * getValueType() const
Definition: GlobalValue.h:273
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::MachineFunction::getJumpTableInfo
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
Definition: MachineFunction.h:649
llvm::RegisterAsmPrinter
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
Definition: TargetRegistry.h:1338
llvm::MachineJumpTableInfo
Definition: MachineJumpTableInfo.h:42
raw_ostream.h
llvm::GlobalValue::LinkOnceODRLinkage
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:51
XCoreTargetInfo.h
TargetRegistry.h
MCExpr.h
llvm::AsmPrinter::PrintAsmOperand
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
Definition: AsmPrinterInlineAsm.cpp:599
llvm::XCoreISD::BR_JT32
@ BR_JT32
Definition: XCoreISelLowering.h:74
LLVMInitializeXCoreAsmPrinter
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXCoreAsmPrinter()
Definition: XCoreAsmPrinter.cpp:294
llvm::MachineOperand::MO_ConstantPoolIndex
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
Definition: MachineOperand.h:58