1 //===- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax -===// 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 #include "SystemZInstPrinter.h" 11 #include "llvm/MC/MCExpr.h" 12 #include "llvm/MC/MCInst.h" 13 #include "llvm/MC/MCSymbol.h" 14 #include "llvm/Support/Casting.h" 15 #include "llvm/Support/ErrorHandling.h" 16 #include "llvm/Support/MathExtras.h" 17 #include "llvm/Support/raw_ostream.h" 18 #include <cassert> 19 #include <cstdint> 20 21 using namespace llvm; 22 23 #define DEBUG_TYPE "asm-printer" 24 25 #include "SystemZGenAsmWriter.inc" 26 27 void SystemZInstPrinter::printAddress(unsigned Base, int64_t Disp, 28 unsigned Index, raw_ostream &O) { 29 O << Disp; 30 if (Base || Index) { 31 O << '('; 32 if (Index) { 33 O << '%' << getRegisterName(Index); 34 if (Base) 35 O << ','; 36 } 37 if (Base) 38 O << '%' << getRegisterName(Base); 39 O << ')'; 40 } 41 } 42 43 void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI, 44 raw_ostream &O) { 45 if (MO.isReg()) 46 O << '%' << getRegisterName(MO.getReg()); 47 else if (MO.isImm()) 48 O << MO.getImm(); 49 else if (MO.isExpr()) 50 MO.getExpr()->print(O, MAI); 51 else 52 llvm_unreachable("Invalid operand"); 53 } 54 55 void SystemZInstPrinter::printInst(const MCInst *MI, raw_ostream &O, 56 StringRef Annot, 57 const MCSubtargetInfo &STI) { 58 printInstruction(MI, O); 59 printAnnotation(O, Annot); 60 } 61 62 void SystemZInstPrinter::printRegName(raw_ostream &O, unsigned RegNo) const { 63 O << '%' << getRegisterName(RegNo); 64 } 65 66 template <unsigned N> 67 static void printUImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) { 68 int64_t Value = MI->getOperand(OpNum).getImm(); 69 assert(isUInt<N>(Value) && "Invalid uimm argument"); 70 O << Value; 71 } 72 73 template <unsigned N> 74 static void printSImmOperand(const MCInst *MI, int OpNum, raw_ostream &O) { 75 int64_t Value = MI->getOperand(OpNum).getImm(); 76 assert(isInt<N>(Value) && "Invalid simm argument"); 77 O << Value; 78 } 79 80 void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum, 81 raw_ostream &O) { 82 printUImmOperand<1>(MI, OpNum, O); 83 } 84 85 void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum, 86 raw_ostream &O) { 87 printUImmOperand<2>(MI, OpNum, O); 88 } 89 90 void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum, 91 raw_ostream &O) { 92 printUImmOperand<3>(MI, OpNum, O); 93 } 94 95 void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum, 96 raw_ostream &O) { 97 printUImmOperand<4>(MI, OpNum, O); 98 } 99 100 void SystemZInstPrinter::printU6ImmOperand(const MCInst *MI, int OpNum, 101 raw_ostream &O) { 102 printUImmOperand<6>(MI, OpNum, O); 103 } 104 105 void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum, 106 raw_ostream &O) { 107 printSImmOperand<8>(MI, OpNum, O); 108 } 109 110 void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum, 111 raw_ostream &O) { 112 printUImmOperand<8>(MI, OpNum, O); 113 } 114 115 void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum, 116 raw_ostream &O) { 117 printUImmOperand<12>(MI, OpNum, O); 118 } 119 120 void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum, 121 raw_ostream &O) { 122 printSImmOperand<16>(MI, OpNum, O); 123 } 124 125 void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum, 126 raw_ostream &O) { 127 printUImmOperand<16>(MI, OpNum, O); 128 } 129 130 void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum, 131 raw_ostream &O) { 132 printSImmOperand<32>(MI, OpNum, O); 133 } 134 135 void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum, 136 raw_ostream &O) { 137 printUImmOperand<32>(MI, OpNum, O); 138 } 139 140 void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum, 141 raw_ostream &O) { 142 printUImmOperand<48>(MI, OpNum, O); 143 } 144 145 void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum, 146 raw_ostream &O) { 147 const MCOperand &MO = MI->getOperand(OpNum); 148 if (MO.isImm()) { 149 O << "0x"; 150 O.write_hex(MO.getImm()); 151 } else 152 MO.getExpr()->print(O, &MAI); 153 } 154 155 void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum, 156 raw_ostream &O) { 157 // Output the PC-relative operand. 158 printPCRelOperand(MI, OpNum, O); 159 160 // Output the TLS marker if present. 161 if ((unsigned)OpNum + 1 < MI->getNumOperands()) { 162 const MCOperand &MO = MI->getOperand(OpNum + 1); 163 const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr()); 164 switch (refExp.getKind()) { 165 case MCSymbolRefExpr::VK_TLSGD: 166 O << ":tls_gdcall:"; 167 break; 168 case MCSymbolRefExpr::VK_TLSLDM: 169 O << ":tls_ldcall:"; 170 break; 171 default: 172 llvm_unreachable("Unexpected symbol kind"); 173 } 174 O << refExp.getSymbol().getName(); 175 } 176 } 177 178 void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum, 179 raw_ostream &O) { 180 printOperand(MI->getOperand(OpNum), &MAI, O); 181 } 182 183 void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum, 184 raw_ostream &O) { 185 printAddress(MI->getOperand(OpNum).getReg(), 186 MI->getOperand(OpNum + 1).getImm(), 0, O); 187 } 188 189 void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum, 190 raw_ostream &O) { 191 printAddress(MI->getOperand(OpNum).getReg(), 192 MI->getOperand(OpNum + 1).getImm(), 193 MI->getOperand(OpNum + 2).getReg(), O); 194 } 195 196 void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum, 197 raw_ostream &O) { 198 unsigned Base = MI->getOperand(OpNum).getReg(); 199 uint64_t Disp = MI->getOperand(OpNum + 1).getImm(); 200 uint64_t Length = MI->getOperand(OpNum + 2).getImm(); 201 O << Disp << '(' << Length; 202 if (Base) 203 O << ",%" << getRegisterName(Base); 204 O << ')'; 205 } 206 207 void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum, 208 raw_ostream &O) { 209 unsigned Base = MI->getOperand(OpNum).getReg(); 210 uint64_t Disp = MI->getOperand(OpNum + 1).getImm(); 211 unsigned Length = MI->getOperand(OpNum + 2).getReg(); 212 O << Disp << "(%" << getRegisterName(Length); 213 if (Base) 214 O << ",%" << getRegisterName(Base); 215 O << ')'; 216 } 217 218 void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum, 219 raw_ostream &O) { 220 printAddress(MI->getOperand(OpNum).getReg(), 221 MI->getOperand(OpNum + 1).getImm(), 222 MI->getOperand(OpNum + 2).getReg(), O); 223 } 224 225 void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum, 226 raw_ostream &O) { 227 static const char *const CondNames[] = { 228 "o", "h", "nle", "l", "nhe", "lh", "ne", 229 "e", "nlh", "he", "nl", "le", "nh", "no" 230 }; 231 uint64_t Imm = MI->getOperand(OpNum).getImm(); 232 assert(Imm > 0 && Imm < 15 && "Invalid condition"); 233 O << CondNames[Imm - 1]; 234 } 235