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