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