1 //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly writer ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to the SystemZ assembly language.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "asm-printer"
17 #include "SystemZInstrInfo.h"
18 #include "SystemZTargetMachine.h"
19 #include "llvm/Constants.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/Module.h"
22 #include "llvm/Assembly/Writer.h"
23 #include "llvm/CodeGen/AsmPrinter.h"
24 #include "llvm/CodeGen/MachineModuleInfo.h"
25 #include "llvm/CodeGen/MachineFunctionPass.h"
26 #include "llvm/CodeGen/MachineConstantPool.h"
27 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/MC/MCAsmInfo.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/Target/Mangler.h"
31 #include "llvm/Target/TargetData.h"
32 #include "llvm/Target/TargetLoweringObjectFile.h"
33 #include "llvm/Target/TargetRegistry.h"
34 #include "llvm/ADT/SmallString.h"
35 #include "llvm/Support/raw_ostream.h"
39 class SystemZAsmPrinter
: public AsmPrinter
{
41 SystemZAsmPrinter(TargetMachine
&TM
, MCStreamer
&Streamer
)
42 : AsmPrinter(TM
, Streamer
) {}
44 virtual const char *getPassName() const {
45 return "SystemZ Assembly Printer";
48 void printOperand(const MachineInstr
*MI
, int OpNum
, raw_ostream
&O
,
49 const char* Modifier
= 0);
50 void printPCRelImmOperand(const MachineInstr
*MI
, int OpNum
, raw_ostream
&O
);
51 void printRIAddrOperand(const MachineInstr
*MI
, int OpNum
, raw_ostream
&O
,
52 const char* Modifier
= 0);
53 void printRRIAddrOperand(const MachineInstr
*MI
, int OpNum
, raw_ostream
&O
,
54 const char* Modifier
= 0);
55 void printS16ImmOperand(const MachineInstr
*MI
, int OpNum
, raw_ostream
&O
) {
56 O
<< (int16_t)MI
->getOperand(OpNum
).getImm();
58 void printS32ImmOperand(const MachineInstr
*MI
, int OpNum
, raw_ostream
&O
) {
59 O
<< (int32_t)MI
->getOperand(OpNum
).getImm();
62 void printInstruction(const MachineInstr
*MI
, raw_ostream
&O
);
63 static const char *getRegisterName(unsigned RegNo
);
65 void EmitInstruction(const MachineInstr
*MI
);
67 } // end of anonymous namespace
69 #include "SystemZGenAsmWriter.inc"
71 void SystemZAsmPrinter::EmitInstruction(const MachineInstr
*MI
) {
73 raw_svector_ostream
OS(Str
);
74 printInstruction(MI
, OS
);
75 OutStreamer
.EmitRawText(OS
.str());
78 void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr
*MI
, int OpNum
,
80 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
81 switch (MO
.getType()) {
82 case MachineOperand::MO_Immediate
:
85 case MachineOperand::MO_MachineBasicBlock
:
86 O
<< *MO
.getMBB()->getSymbol();
88 case MachineOperand::MO_GlobalAddress
: {
89 const GlobalValue
*GV
= MO
.getGlobal();
90 O
<< *Mang
->getSymbol(GV
);
92 // Assemble calls via PLT for externally visible symbols if PIC.
93 if (TM
.getRelocationModel() == Reloc::PIC_
&&
94 !GV
->hasHiddenVisibility() && !GV
->hasProtectedVisibility() &&
95 !GV
->hasLocalLinkage())
98 printOffset(MO
.getOffset(), O
);
101 case MachineOperand::MO_ExternalSymbol
: {
102 std::string
Name(MAI
->getGlobalPrefix());
103 Name
+= MO
.getSymbolName();
106 if (TM
.getRelocationModel() == Reloc::PIC_
)
112 assert(0 && "Not implemented yet!");
117 void SystemZAsmPrinter::printOperand(const MachineInstr
*MI
, int OpNum
,
118 raw_ostream
&O
, const char *Modifier
) {
119 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
120 switch (MO
.getType()) {
121 case MachineOperand::MO_Register
: {
122 assert (TargetRegisterInfo::isPhysicalRegister(MO
.getReg()) &&
123 "Virtual registers should be already mapped!");
124 unsigned Reg
= MO
.getReg();
125 if (Modifier
&& strncmp(Modifier
, "subreg", 6) == 0) {
126 if (strncmp(Modifier
+ 7, "even", 4) == 0)
127 Reg
= TM
.getRegisterInfo()->getSubReg(Reg
, SystemZ::subreg_32bit
);
128 else if (strncmp(Modifier
+ 7, "odd", 3) == 0)
129 Reg
= TM
.getRegisterInfo()->getSubReg(Reg
, SystemZ::subreg_odd32
);
131 assert(0 && "Invalid subreg modifier");
134 O
<< '%' << getRegisterName(Reg
);
137 case MachineOperand::MO_Immediate
:
140 case MachineOperand::MO_MachineBasicBlock
:
141 O
<< *MO
.getMBB()->getSymbol();
143 case MachineOperand::MO_JumpTableIndex
:
144 O
<< MAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
148 case MachineOperand::MO_ConstantPoolIndex
:
149 O
<< MAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
152 printOffset(MO
.getOffset(), O
);
154 case MachineOperand::MO_GlobalAddress
:
155 O
<< *Mang
->getSymbol(MO
.getGlobal());
157 case MachineOperand::MO_ExternalSymbol
: {
158 O
<< *GetExternalSymbolSymbol(MO
.getSymbolName());
162 assert(0 && "Not implemented yet!");
165 switch (MO
.getTargetFlags()) {
166 default: assert(0 && "Unknown target flag on GV operand");
167 case SystemZII::MO_NO_FLAG
:
169 case SystemZII::MO_GOTENT
: O
<< "@GOTENT"; break;
170 case SystemZII::MO_PLT
: O
<< "@PLT"; break;
173 printOffset(MO
.getOffset(), O
);
176 void SystemZAsmPrinter::printRIAddrOperand(const MachineInstr
*MI
, int OpNum
,
178 const char *Modifier
) {
179 const MachineOperand
&Base
= MI
->getOperand(OpNum
);
181 // Print displacement operand.
182 printOperand(MI
, OpNum
+1, O
);
184 // Print base operand (if any)
187 printOperand(MI
, OpNum
, O
);
192 void SystemZAsmPrinter::printRRIAddrOperand(const MachineInstr
*MI
, int OpNum
,
194 const char *Modifier
) {
195 const MachineOperand
&Base
= MI
->getOperand(OpNum
);
196 const MachineOperand
&Index
= MI
->getOperand(OpNum
+2);
198 // Print displacement operand.
199 printOperand(MI
, OpNum
+1, O
);
201 // Print base operand (if any)
204 printOperand(MI
, OpNum
, O
);
205 if (Index
.getReg()) {
207 printOperand(MI
, OpNum
+2, O
);
211 assert(!Index
.getReg() && "Should allocate base register first!");
214 // Force static initialization.
215 extern "C" void LLVMInitializeSystemZAsmPrinter() {
216 RegisterAsmPrinter
<SystemZAsmPrinter
> X(TheSystemZTarget
);