SystemZAsmPrinter.cpp revision 1d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07
11d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===// 21d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 31d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// The LLVM Compiler Infrastructure 41d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 51d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file is distributed under the University of Illinois Open Source 61d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// License. See LICENSE.TXT for details. 71d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 81d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 91d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Streams SystemZ assembly language and associated data, in the form of 111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// MCInsts and MCExprs respectively. 121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// 131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===// 141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZAsmPrinter.h" 161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "InstPrinter/SystemZInstPrinter.h" 171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZConstantPoolValue.h" 181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZMCInstLower.h" 191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/CodeGen/MachineModuleInfoImpls.h" 201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCExpr.h" 221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCStreamer.h" 231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/Support/TargetRegistry.h" 241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/Target/Mangler.h" 251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm; 271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) { 291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMCInstLower Lower(Mang, MF->getContext(), *this); 301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MCInst LoweredMI; 311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Lower.lower(MI, LoweredMI); 321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutStreamer.EmitInstruction(LoweredMI); 331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Convert a SystemZ-specific constant pool modifier into the associated 361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// MCSymbolRefExpr variant kind. 371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic MCSymbolRefExpr::VariantKind 381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandgetModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) { 391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand switch (Modifier) { 401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF; 411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand llvm_unreachable("Invalid SystemCPModifier!"); 431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZAsmPrinter:: 461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandEmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZConstantPoolValue *ZCPV = 481d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand static_cast<SystemZConstantPoolValue*>(MCPV); 491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const MCExpr *Expr = 511d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MCSymbolRefExpr::Create(Mang->getSymbol(ZCPV->getGlobalValue()), 521d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand getModifierVariantKind(ZCPV->getModifier()), 531d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutContext); 541d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand uint64_t Size = TM.getDataLayout()->getTypeAllocSize(ZCPV->getType()); 551d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 561d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutStreamer.EmitValue(Expr, Size); 571d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 581d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 591d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, 601d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OpNo, 611d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned AsmVariant, 621d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const char *ExtraCode, 631d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand raw_ostream &OS) { 641d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (ExtraCode && *ExtraCode == 'n') { 651d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!MI->getOperand(OpNo).isImm()) 661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return true; 671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OS << -int64_t(MI->getOperand(OpNo).getImm()); 681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } else { 691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZMCInstLower Lower(Mang, MF->getContext(), *this); 701d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo))); 711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZInstPrinter::printOperand(MO, OS); 721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandbool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned OpNo, 781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand unsigned AsmVariant, 791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const char *ExtraCode, 801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand raw_ostream &OS) { 811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(), 821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(OpNo + 1).getImm(), 831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MI->getOperand(OpNo + 2).getReg(), OS); 841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand return false; 851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) { 881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (Subtarget->isTargetELF()) { 891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const TargetLoweringObjectFileELF &TLOFELF = 901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); 911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); 931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand // Output stubs for external and common global variables. 951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand if (!Stubs.empty()) { 971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); 981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand const DataLayout *TD = TM.getDataLayout(); 991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 1011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutStreamer.EmitLabel(Stubs[i].first); 1021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(), 1031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand TD->getPointerSize(0), 0); 1041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand Stubs.clear(); 1061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand } 1081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 1091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand 1101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Force static initialization. 1111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandextern "C" void LLVMInitializeSystemZAsmPrinter() { 1121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget); 1131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand} 114