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