1*5f613dfdSUlrich Weigand //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
2*5f613dfdSUlrich Weigand //
3*5f613dfdSUlrich Weigand //                     The LLVM Compiler Infrastructure
4*5f613dfdSUlrich Weigand //
5*5f613dfdSUlrich Weigand // This file is distributed under the University of Illinois Open Source
6*5f613dfdSUlrich Weigand // License. See LICENSE.TXT for details.
7*5f613dfdSUlrich Weigand //
8*5f613dfdSUlrich Weigand //===----------------------------------------------------------------------===//
9*5f613dfdSUlrich Weigand //
10*5f613dfdSUlrich Weigand // Streams SystemZ assembly language and associated data, in the form of
11*5f613dfdSUlrich Weigand // MCInsts and MCExprs respectively.
12*5f613dfdSUlrich Weigand //
13*5f613dfdSUlrich Weigand //===----------------------------------------------------------------------===//
14*5f613dfdSUlrich Weigand 
15*5f613dfdSUlrich Weigand #include "SystemZAsmPrinter.h"
16*5f613dfdSUlrich Weigand #include "InstPrinter/SystemZInstPrinter.h"
17*5f613dfdSUlrich Weigand #include "SystemZConstantPoolValue.h"
18*5f613dfdSUlrich Weigand #include "SystemZMCInstLower.h"
19*5f613dfdSUlrich Weigand #include "llvm/CodeGen/MachineModuleInfoImpls.h"
20*5f613dfdSUlrich Weigand #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
21*5f613dfdSUlrich Weigand #include "llvm/MC/MCExpr.h"
22*5f613dfdSUlrich Weigand #include "llvm/MC/MCStreamer.h"
23*5f613dfdSUlrich Weigand #include "llvm/Support/TargetRegistry.h"
24*5f613dfdSUlrich Weigand #include "llvm/Target/Mangler.h"
25*5f613dfdSUlrich Weigand 
26*5f613dfdSUlrich Weigand using namespace llvm;
27*5f613dfdSUlrich Weigand 
28*5f613dfdSUlrich Weigand void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
29*5f613dfdSUlrich Weigand   SystemZMCInstLower Lower(Mang, MF->getContext(), *this);
30*5f613dfdSUlrich Weigand   MCInst LoweredMI;
31*5f613dfdSUlrich Weigand   Lower.lower(MI, LoweredMI);
32*5f613dfdSUlrich Weigand   OutStreamer.EmitInstruction(LoweredMI);
33*5f613dfdSUlrich Weigand }
34*5f613dfdSUlrich Weigand 
35*5f613dfdSUlrich Weigand // Convert a SystemZ-specific constant pool modifier into the associated
36*5f613dfdSUlrich Weigand // MCSymbolRefExpr variant kind.
37*5f613dfdSUlrich Weigand static MCSymbolRefExpr::VariantKind
38*5f613dfdSUlrich Weigand getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
39*5f613dfdSUlrich Weigand   switch (Modifier) {
40*5f613dfdSUlrich Weigand   case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
41*5f613dfdSUlrich Weigand   }
42*5f613dfdSUlrich Weigand   llvm_unreachable("Invalid SystemCPModifier!");
43*5f613dfdSUlrich Weigand }
44*5f613dfdSUlrich Weigand 
45*5f613dfdSUlrich Weigand void SystemZAsmPrinter::
46*5f613dfdSUlrich Weigand EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
47*5f613dfdSUlrich Weigand   SystemZConstantPoolValue *ZCPV =
48*5f613dfdSUlrich Weigand     static_cast<SystemZConstantPoolValue*>(MCPV);
49*5f613dfdSUlrich Weigand 
50*5f613dfdSUlrich Weigand   const MCExpr *Expr =
51*5f613dfdSUlrich Weigand     MCSymbolRefExpr::Create(Mang->getSymbol(ZCPV->getGlobalValue()),
52*5f613dfdSUlrich Weigand                             getModifierVariantKind(ZCPV->getModifier()),
53*5f613dfdSUlrich Weigand                             OutContext);
54*5f613dfdSUlrich Weigand   uint64_t Size = TM.getDataLayout()->getTypeAllocSize(ZCPV->getType());
55*5f613dfdSUlrich Weigand 
56*5f613dfdSUlrich Weigand   OutStreamer.EmitValue(Expr, Size);
57*5f613dfdSUlrich Weigand }
58*5f613dfdSUlrich Weigand 
59*5f613dfdSUlrich Weigand bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
60*5f613dfdSUlrich Weigand                                         unsigned OpNo,
61*5f613dfdSUlrich Weigand                                         unsigned AsmVariant,
62*5f613dfdSUlrich Weigand                                         const char *ExtraCode,
63*5f613dfdSUlrich Weigand                                         raw_ostream &OS) {
64*5f613dfdSUlrich Weigand   if (ExtraCode && *ExtraCode == 'n') {
65*5f613dfdSUlrich Weigand     if (!MI->getOperand(OpNo).isImm())
66*5f613dfdSUlrich Weigand       return true;
67*5f613dfdSUlrich Weigand     OS << -int64_t(MI->getOperand(OpNo).getImm());
68*5f613dfdSUlrich Weigand   } else {
69*5f613dfdSUlrich Weigand     SystemZMCInstLower Lower(Mang, MF->getContext(), *this);
70*5f613dfdSUlrich Weigand     MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
71*5f613dfdSUlrich Weigand     SystemZInstPrinter::printOperand(MO, OS);
72*5f613dfdSUlrich Weigand   }
73*5f613dfdSUlrich Weigand   return false;
74*5f613dfdSUlrich Weigand }
75*5f613dfdSUlrich Weigand 
76*5f613dfdSUlrich Weigand bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
77*5f613dfdSUlrich Weigand                                               unsigned OpNo,
78*5f613dfdSUlrich Weigand                                               unsigned AsmVariant,
79*5f613dfdSUlrich Weigand                                               const char *ExtraCode,
80*5f613dfdSUlrich Weigand                                               raw_ostream &OS) {
81*5f613dfdSUlrich Weigand   SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
82*5f613dfdSUlrich Weigand                                    MI->getOperand(OpNo + 1).getImm(),
83*5f613dfdSUlrich Weigand                                    MI->getOperand(OpNo + 2).getReg(), OS);
84*5f613dfdSUlrich Weigand   return false;
85*5f613dfdSUlrich Weigand }
86*5f613dfdSUlrich Weigand 
87*5f613dfdSUlrich Weigand void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
88*5f613dfdSUlrich Weigand   if (Subtarget->isTargetELF()) {
89*5f613dfdSUlrich Weigand     const TargetLoweringObjectFileELF &TLOFELF =
90*5f613dfdSUlrich Weigand       static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());
91*5f613dfdSUlrich Weigand 
92*5f613dfdSUlrich Weigand     MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
93*5f613dfdSUlrich Weigand 
94*5f613dfdSUlrich Weigand     // Output stubs for external and common global variables.
95*5f613dfdSUlrich Weigand     MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
96*5f613dfdSUlrich Weigand     if (!Stubs.empty()) {
97*5f613dfdSUlrich Weigand       OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
98*5f613dfdSUlrich Weigand       const DataLayout *TD = TM.getDataLayout();
99*5f613dfdSUlrich Weigand 
100*5f613dfdSUlrich Weigand       for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
101*5f613dfdSUlrich Weigand         OutStreamer.EmitLabel(Stubs[i].first);
102*5f613dfdSUlrich Weigand         OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(),
103*5f613dfdSUlrich Weigand                                     TD->getPointerSize(0), 0);
104*5f613dfdSUlrich Weigand       }
105*5f613dfdSUlrich Weigand       Stubs.clear();
106*5f613dfdSUlrich Weigand     }
107*5f613dfdSUlrich Weigand   }
108*5f613dfdSUlrich Weigand }
109*5f613dfdSUlrich Weigand 
110*5f613dfdSUlrich Weigand // Force static initialization.
111*5f613dfdSUlrich Weigand extern "C" void LLVMInitializeSystemZAsmPrinter() {
112*5f613dfdSUlrich Weigand   RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
113*5f613dfdSUlrich Weigand }
114