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