LLVM API Documentation
00001 //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Streams SystemZ assembly language and associated data, in the form of 00011 // MCInsts and MCExprs respectively. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "SystemZAsmPrinter.h" 00016 #include "InstPrinter/SystemZInstPrinter.h" 00017 #include "SystemZConstantPoolValue.h" 00018 #include "SystemZMCInstLower.h" 00019 #include "llvm/CodeGen/MachineModuleInfoImpls.h" 00020 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 00021 #include "llvm/IR/Mangler.h" 00022 #include "llvm/MC/MCExpr.h" 00023 #include "llvm/MC/MCInstBuilder.h" 00024 #include "llvm/MC/MCStreamer.h" 00025 #include "llvm/Support/TargetRegistry.h" 00026 00027 using namespace llvm; 00028 00029 // Return an RI instruction like MI with opcode Opcode, but with the 00030 // GR64 register operands turned into GR32s. 00031 static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) { 00032 if (MI->isCompare()) 00033 return MCInstBuilder(Opcode) 00034 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 00035 .addImm(MI->getOperand(1).getImm()); 00036 else 00037 return MCInstBuilder(Opcode) 00038 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 00039 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg())) 00040 .addImm(MI->getOperand(2).getImm()); 00041 } 00042 00043 // Return an RI instruction like MI with opcode Opcode, but with the 00044 // GR64 register operands turned into GRH32s. 00045 static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) { 00046 if (MI->isCompare()) 00047 return MCInstBuilder(Opcode) 00048 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 00049 .addImm(MI->getOperand(1).getImm()); 00050 else 00051 return MCInstBuilder(Opcode) 00052 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 00053 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg())) 00054 .addImm(MI->getOperand(2).getImm()); 00055 } 00056 00057 // Return an RI instruction like MI with opcode Opcode, but with the 00058 // R2 register turned into a GR64. 00059 static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) { 00060 return MCInstBuilder(Opcode) 00061 .addReg(MI->getOperand(0).getReg()) 00062 .addReg(MI->getOperand(1).getReg()) 00063 .addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg())) 00064 .addImm(MI->getOperand(3).getImm()) 00065 .addImm(MI->getOperand(4).getImm()) 00066 .addImm(MI->getOperand(5).getImm()); 00067 } 00068 00069 void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) { 00070 SystemZMCInstLower Lower(MF->getContext(), *this); 00071 MCInst LoweredMI; 00072 switch (MI->getOpcode()) { 00073 case SystemZ::Return: 00074 LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D); 00075 break; 00076 00077 case SystemZ::CallBRASL: 00078 LoweredMI = MCInstBuilder(SystemZ::BRASL) 00079 .addReg(SystemZ::R14D) 00080 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 00081 break; 00082 00083 case SystemZ::CallBASR: 00084 LoweredMI = MCInstBuilder(SystemZ::BASR) 00085 .addReg(SystemZ::R14D) 00086 .addReg(MI->getOperand(0).getReg()); 00087 break; 00088 00089 case SystemZ::CallJG: 00090 LoweredMI = MCInstBuilder(SystemZ::JG) 00091 .addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT)); 00092 break; 00093 00094 case SystemZ::CallBR: 00095 LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D); 00096 break; 00097 00098 case SystemZ::IILF64: 00099 LoweredMI = MCInstBuilder(SystemZ::IILF) 00100 .addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg())) 00101 .addImm(MI->getOperand(2).getImm()); 00102 break; 00103 00104 case SystemZ::IIHF64: 00105 LoweredMI = MCInstBuilder(SystemZ::IIHF) 00106 .addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg())) 00107 .addImm(MI->getOperand(2).getImm()); 00108 break; 00109 00110 case SystemZ::RISBHH: 00111 case SystemZ::RISBHL: 00112 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG); 00113 break; 00114 00115 case SystemZ::RISBLH: 00116 case SystemZ::RISBLL: 00117 LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG); 00118 break; 00119 00120 #define LOWER_LOW(NAME) \ 00121 case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break 00122 00123 LOWER_LOW(IILL); 00124 LOWER_LOW(IILH); 00125 LOWER_LOW(TMLL); 00126 LOWER_LOW(TMLH); 00127 LOWER_LOW(NILL); 00128 LOWER_LOW(NILH); 00129 LOWER_LOW(NILF); 00130 LOWER_LOW(OILL); 00131 LOWER_LOW(OILH); 00132 LOWER_LOW(OILF); 00133 LOWER_LOW(XILF); 00134 00135 #undef LOWER_LOW 00136 00137 #define LOWER_HIGH(NAME) \ 00138 case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break 00139 00140 LOWER_HIGH(IIHL); 00141 LOWER_HIGH(IIHH); 00142 LOWER_HIGH(TMHL); 00143 LOWER_HIGH(TMHH); 00144 LOWER_HIGH(NIHL); 00145 LOWER_HIGH(NIHH); 00146 LOWER_HIGH(NIHF); 00147 LOWER_HIGH(OIHL); 00148 LOWER_HIGH(OIHH); 00149 LOWER_HIGH(OIHF); 00150 LOWER_HIGH(XIHF); 00151 00152 #undef LOWER_HIGH 00153 00154 case SystemZ::Serialize: 00155 if (Subtarget->hasFastSerialization()) 00156 LoweredMI = MCInstBuilder(SystemZ::AsmBCR) 00157 .addImm(14).addReg(SystemZ::R0D); 00158 else 00159 LoweredMI = MCInstBuilder(SystemZ::AsmBCR) 00160 .addImm(15).addReg(SystemZ::R0D); 00161 break; 00162 00163 default: 00164 Lower.lower(MI, LoweredMI); 00165 break; 00166 } 00167 EmitToStreamer(OutStreamer, LoweredMI); 00168 } 00169 00170 // Convert a SystemZ-specific constant pool modifier into the associated 00171 // MCSymbolRefExpr variant kind. 00172 static MCSymbolRefExpr::VariantKind 00173 getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) { 00174 switch (Modifier) { 00175 case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF; 00176 } 00177 llvm_unreachable("Invalid SystemCPModifier!"); 00178 } 00179 00180 void SystemZAsmPrinter:: 00181 EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { 00182 auto *ZCPV = static_cast<SystemZConstantPoolValue*>(MCPV); 00183 00184 const MCExpr *Expr = 00185 MCSymbolRefExpr::Create(getSymbol(ZCPV->getGlobalValue()), 00186 getModifierVariantKind(ZCPV->getModifier()), 00187 OutContext); 00188 uint64_t Size = 00189 TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(ZCPV->getType()); 00190 00191 OutStreamer.EmitValue(Expr, Size); 00192 } 00193 00194 bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI, 00195 unsigned OpNo, 00196 unsigned AsmVariant, 00197 const char *ExtraCode, 00198 raw_ostream &OS) { 00199 if (ExtraCode && *ExtraCode == 'n') { 00200 if (!MI->getOperand(OpNo).isImm()) 00201 return true; 00202 OS << -int64_t(MI->getOperand(OpNo).getImm()); 00203 } else { 00204 SystemZMCInstLower Lower(MF->getContext(), *this); 00205 MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo))); 00206 SystemZInstPrinter::printOperand(MO, OS); 00207 } 00208 return false; 00209 } 00210 00211 bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 00212 unsigned OpNo, 00213 unsigned AsmVariant, 00214 const char *ExtraCode, 00215 raw_ostream &OS) { 00216 SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(), 00217 MI->getOperand(OpNo + 1).getImm(), 00218 MI->getOperand(OpNo + 2).getReg(), OS); 00219 return false; 00220 } 00221 00222 void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) { 00223 if (Subtarget->isTargetELF()) { 00224 auto &TLOFELF = 00225 static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering()); 00226 00227 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>(); 00228 00229 // Output stubs for external and common global variables. 00230 MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList(); 00231 if (!Stubs.empty()) { 00232 OutStreamer.SwitchSection(TLOFELF.getDataRelSection()); 00233 const DataLayout *TD = TM.getSubtargetImpl()->getDataLayout(); 00234 00235 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 00236 OutStreamer.EmitLabel(Stubs[i].first); 00237 OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(), 00238 TD->getPointerSize(0)); 00239 } 00240 Stubs.clear(); 00241 } 00242 } 00243 } 00244 00245 // Force static initialization. 00246 extern "C" void LLVMInitializeSystemZAsmPrinter() { 00247 RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget); 00248 }