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 printU16ImmOperand(const MachineInstr
*MI
, int OpNum
, raw_ostream
&O
) {
59 O
<< (uint16_t)MI
->getOperand(OpNum
).getImm();
61 void printS32ImmOperand(const MachineInstr
*MI
, int OpNum
, raw_ostream
&O
) {
62 O
<< (int32_t)MI
->getOperand(OpNum
).getImm();
64 void printU32ImmOperand(const MachineInstr
*MI
, int OpNum
, raw_ostream
&O
) {
65 O
<< (uint32_t)MI
->getOperand(OpNum
).getImm();
68 void printInstruction(const MachineInstr
*MI
, raw_ostream
&O
);
69 static const char *getRegisterName(unsigned RegNo
);
71 void EmitInstruction(const MachineInstr
*MI
);
73 } // end of anonymous namespace
75 #include "SystemZGenAsmWriter.inc"
77 void SystemZAsmPrinter::EmitInstruction(const MachineInstr
*MI
) {
79 raw_svector_ostream
OS(Str
);
80 printInstruction(MI
, OS
);
81 OutStreamer
.EmitRawText(OS
.str());
84 void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr
*MI
, int OpNum
,
86 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
87 switch (MO
.getType()) {
88 case MachineOperand::MO_Immediate
:
91 case MachineOperand::MO_MachineBasicBlock
:
92 O
<< *MO
.getMBB()->getSymbol();
94 case MachineOperand::MO_GlobalAddress
: {
95 const GlobalValue
*GV
= MO
.getGlobal();
96 O
<< *Mang
->getSymbol(GV
);
98 // Assemble calls via PLT for externally visible symbols if PIC.
99 if (TM
.getRelocationModel() == Reloc::PIC_
&&
100 !GV
->hasHiddenVisibility() && !GV
->hasProtectedVisibility() &&
101 !GV
->hasLocalLinkage())
104 printOffset(MO
.getOffset(), O
);
107 case MachineOperand::MO_ExternalSymbol
: {
108 std::string
Name(MAI
->getGlobalPrefix());
109 Name
+= MO
.getSymbolName();
112 if (TM
.getRelocationModel() == Reloc::PIC_
)
118 assert(0 && "Not implemented yet!");
123 void SystemZAsmPrinter::printOperand(const MachineInstr
*MI
, int OpNum
,
124 raw_ostream
&O
, const char *Modifier
) {
125 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
126 switch (MO
.getType()) {
127 case MachineOperand::MO_Register
: {
128 assert (TargetRegisterInfo::isPhysicalRegister(MO
.getReg()) &&
129 "Virtual registers should be already mapped!");
130 unsigned Reg
= MO
.getReg();
131 if (Modifier
&& strncmp(Modifier
, "subreg", 6) == 0) {
132 if (strncmp(Modifier
+ 7, "even", 4) == 0)
133 Reg
= TM
.getRegisterInfo()->getSubReg(Reg
, SystemZ::subreg_32bit
);
134 else if (strncmp(Modifier
+ 7, "odd", 3) == 0)
135 Reg
= TM
.getRegisterInfo()->getSubReg(Reg
, SystemZ::subreg_odd32
);
137 assert(0 && "Invalid subreg modifier");
140 O
<< '%' << getRegisterName(Reg
);
143 case MachineOperand::MO_Immediate
:
146 case MachineOperand::MO_MachineBasicBlock
:
147 O
<< *MO
.getMBB()->getSymbol();
149 case MachineOperand::MO_JumpTableIndex
:
150 O
<< MAI
->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
154 case MachineOperand::MO_ConstantPoolIndex
:
155 O
<< MAI
->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
158 printOffset(MO
.getOffset(), O
);
160 case MachineOperand::MO_GlobalAddress
:
161 O
<< *Mang
->getSymbol(MO
.getGlobal());
163 case MachineOperand::MO_ExternalSymbol
: {
164 O
<< *GetExternalSymbolSymbol(MO
.getSymbolName());
168 assert(0 && "Not implemented yet!");
171 switch (MO
.getTargetFlags()) {
172 default: assert(0 && "Unknown target flag on GV operand");
173 case SystemZII::MO_NO_FLAG
:
175 case SystemZII::MO_GOTENT
: O
<< "@GOTENT"; break;
176 case SystemZII::MO_PLT
: O
<< "@PLT"; break;
179 printOffset(MO
.getOffset(), O
);
182 void SystemZAsmPrinter::printRIAddrOperand(const MachineInstr
*MI
, int OpNum
,
184 const char *Modifier
) {
185 const MachineOperand
&Base
= MI
->getOperand(OpNum
);
187 // Print displacement operand.
188 printOperand(MI
, OpNum
+1, O
);
190 // Print base operand (if any)
193 printOperand(MI
, OpNum
, O
);
198 void SystemZAsmPrinter::printRRIAddrOperand(const MachineInstr
*MI
, int OpNum
,
200 const char *Modifier
) {
201 const MachineOperand
&Base
= MI
->getOperand(OpNum
);
202 const MachineOperand
&Index
= MI
->getOperand(OpNum
+2);
204 // Print displacement operand.
205 printOperand(MI
, OpNum
+1, O
);
207 // Print base operand (if any)
210 printOperand(MI
, OpNum
, O
);
211 if (Index
.getReg()) {
213 printOperand(MI
, OpNum
+2, O
);
217 assert(!Index
.getReg() && "Should allocate base register first!");
220 // Force static initialization.
221 extern "C" void LLVMInitializeSystemZAsmPrinter() {
222 RegisterAsmPrinter
<SystemZAsmPrinter
> X(TheSystemZTarget
);