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