269 lines · cpp
1//=- SystemZInstPrinterCommon.cpp - Common SystemZ MCInst to assembly funcs -=//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "SystemZInstPrinterCommon.h"10#include "MCTargetDesc/SystemZMCAsmInfo.h"11#include "llvm/MC/MCExpr.h"12#include "llvm/MC/MCInst.h"13#include "llvm/MC/MCRegister.h"14#include "llvm/MC/MCSymbol.h"15#include "llvm/Support/Casting.h"16#include "llvm/Support/ErrorHandling.h"17#include "llvm/Support/MathExtras.h"18#include "llvm/Support/raw_ostream.h"19#include <cassert>20#include <cstdint>21 22using namespace llvm;23 24#define DEBUG_TYPE "asm-printer"25 26void SystemZInstPrinterCommon::printAddress(const MCAsmInfo *MAI,27 MCRegister Base,28 const MCOperand &DispMO,29 MCRegister Index, raw_ostream &O) {30 printOperand(DispMO, MAI, O);31 if (Base || Index) {32 O << '(';33 if (Index) {34 printRegName(O, Index);35 O << ',';36 }37 if (Base)38 printRegName(O, Base);39 else40 O << '0';41 O << ')';42 }43}44 45void SystemZInstPrinterCommon::printOperand(const MCOperand &MO,46 const MCAsmInfo *MAI,47 raw_ostream &O) {48 if (MO.isReg()) {49 if (!MO.getReg())50 O << '0';51 else52 printRegName(O, MO.getReg());53 } else if (MO.isImm())54 markup(O, Markup::Immediate) << MO.getImm();55 else if (MO.isExpr())56 MAI->printExpr(O, *MO.getExpr());57 else58 llvm_unreachable("Invalid operand");59}60 61void SystemZInstPrinterCommon::printRegName(raw_ostream &O, MCRegister Reg) {62 printFormattedRegName(&MAI, Reg, O);63}64 65template <unsigned N>66void SystemZInstPrinterCommon::printUImmOperand(const MCInst *MI, int OpNum,67 raw_ostream &O) {68 const MCOperand &MO = MI->getOperand(OpNum);69 if (MO.isExpr()) {70 MAI.printExpr(O, *MO.getExpr());71 return;72 }73 uint64_t Value = static_cast<uint64_t>(MO.getImm());74 assert(isUInt<N>(Value) && "Invalid uimm argument");75 markup(O, Markup::Immediate) << Value;76}77 78template <unsigned N>79void SystemZInstPrinterCommon::printSImmOperand(const MCInst *MI, int OpNum,80 raw_ostream &O) {81 const MCOperand &MO = MI->getOperand(OpNum);82 if (MO.isExpr()) {83 MAI.printExpr(O, *MO.getExpr());84 return;85 }86 int64_t Value = MI->getOperand(OpNum).getImm();87 assert(isInt<N>(Value) && "Invalid simm argument");88 markup(O, Markup::Immediate) << Value;89}90 91void SystemZInstPrinterCommon::printU1ImmOperand(const MCInst *MI, int OpNum,92 raw_ostream &O) {93 printUImmOperand<1>(MI, OpNum, O);94}95 96void SystemZInstPrinterCommon::printU2ImmOperand(const MCInst *MI, int OpNum,97 raw_ostream &O) {98 printUImmOperand<2>(MI, OpNum, O);99}100 101void SystemZInstPrinterCommon::printU3ImmOperand(const MCInst *MI, int OpNum,102 raw_ostream &O) {103 printUImmOperand<3>(MI, OpNum, O);104}105 106void SystemZInstPrinterCommon::printU4ImmOperand(const MCInst *MI, int OpNum,107 raw_ostream &O) {108 printUImmOperand<4>(MI, OpNum, O);109}110 111void SystemZInstPrinterCommon::printS8ImmOperand(const MCInst *MI, int OpNum,112 raw_ostream &O) {113 printSImmOperand<8>(MI, OpNum, O);114}115 116void SystemZInstPrinterCommon::printU8ImmOperand(const MCInst *MI, int OpNum,117 raw_ostream &O) {118 printUImmOperand<8>(MI, OpNum, O);119}120 121void SystemZInstPrinterCommon::printU12ImmOperand(const MCInst *MI, int OpNum,122 raw_ostream &O) {123 printUImmOperand<12>(MI, OpNum, O);124}125 126void SystemZInstPrinterCommon::printS16ImmOperand(const MCInst *MI, int OpNum,127 raw_ostream &O) {128 printSImmOperand<16>(MI, OpNum, O);129}130 131void SystemZInstPrinterCommon::printU16ImmOperand(const MCInst *MI, int OpNum,132 raw_ostream &O) {133 printUImmOperand<16>(MI, OpNum, O);134}135 136void SystemZInstPrinterCommon::printS32ImmOperand(const MCInst *MI, int OpNum,137 raw_ostream &O) {138 printSImmOperand<32>(MI, OpNum, O);139}140 141void SystemZInstPrinterCommon::printU32ImmOperand(const MCInst *MI, int OpNum,142 raw_ostream &O) {143 printUImmOperand<32>(MI, OpNum, O);144}145 146void SystemZInstPrinterCommon::printU48ImmOperand(const MCInst *MI, int OpNum,147 raw_ostream &O) {148 printUImmOperand<48>(MI, OpNum, O);149}150 151void SystemZInstPrinterCommon::printPCRelOperand(const MCInst *MI,152 uint64_t Address, int OpNum,153 raw_ostream &O) {154 const MCOperand &MO = MI->getOperand(OpNum);155 156 // If the label has already been resolved to an immediate offset (say, when157 // we're running the disassembler), just print the immediate.158 if (MO.isImm()) {159 int64_t Offset = MO.getImm();160 if (PrintBranchImmAsAddress)161 markup(O, Markup::Target) << formatHex(Address + Offset);162 else163 markup(O, Markup::Immediate) << formatImm(Offset);164 return;165 }166 167 // If the branch target is simply an address then print it in hex.168 const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(MO.getExpr());169 int64_t TargetAddress;170 if (BranchTarget && BranchTarget->evaluateAsAbsolute(TargetAddress)) {171 markup(O, Markup::Target) << formatHex((uint64_t)TargetAddress);172 } else {173 // Otherwise, just print the expression.174 MAI.printExpr(O, *MO.getExpr());175 }176}177 178void SystemZInstPrinterCommon::printPCRelTLSOperand(const MCInst *MI,179 uint64_t Address, int OpNum,180 raw_ostream &O) {181 // Output the PC-relative operand.182 printPCRelOperand(MI, Address, OpNum, O);183 184 // Output the TLS marker if present.185 if ((unsigned)OpNum + 1 < MI->getNumOperands()) {186 const MCOperand &MO = MI->getOperand(OpNum + 1);187 const MCSymbolRefExpr &RefExp = cast<MCSymbolRefExpr>(*MO.getExpr());188 switch (RefExp.getSpecifier()) {189 case SystemZ::S_TLSGD:190 O << ":tls_gdcall:";191 break;192 case SystemZ::S_TLSLDM:193 O << ":tls_ldcall:";194 break;195 default:196 llvm_unreachable("Unexpected symbol kind");197 }198 O << RefExp.getSymbol().getName();199 }200}201 202void SystemZInstPrinterCommon::printOperand(const MCInst *MI, int OpNum,203 raw_ostream &O) {204 printOperand(MI->getOperand(OpNum), &MAI, O);205}206 207void SystemZInstPrinterCommon::printBDAddrOperand(const MCInst *MI, int OpNum,208 raw_ostream &O) {209 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),210 0, O);211}212 213void SystemZInstPrinterCommon::printBDXAddrOperand(const MCInst *MI, int OpNum,214 raw_ostream &O) {215 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),216 MI->getOperand(OpNum + 2).getReg(), O);217}218 219void SystemZInstPrinterCommon::printBDLAddrOperand(const MCInst *MI, int OpNum,220 raw_ostream &O) {221 MCRegister Base = MI->getOperand(OpNum).getReg();222 const MCOperand &DispMO = MI->getOperand(OpNum + 1);223 uint64_t Length = MI->getOperand(OpNum + 2).getImm();224 printOperand(DispMO, &MAI, O);225 O << '(' << Length;226 if (Base) {227 O << ",";228 printRegName(O, Base);229 }230 O << ')';231}232 233void SystemZInstPrinterCommon::printBDRAddrOperand(const MCInst *MI, int OpNum,234 raw_ostream &O) {235 MCRegister Base = MI->getOperand(OpNum).getReg();236 const MCOperand &DispMO = MI->getOperand(OpNum + 1);237 MCRegister Length = MI->getOperand(OpNum + 2).getReg();238 printOperand(DispMO, &MAI, O);239 O << "(";240 printRegName(O, Length);241 if (Base) {242 O << ",";243 printRegName(O, Base);244 }245 O << ')';246}247 248void SystemZInstPrinterCommon::printBDVAddrOperand(const MCInst *MI, int OpNum,249 raw_ostream &O) {250 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),251 MI->getOperand(OpNum + 2).getReg(), O);252}253 254void SystemZInstPrinterCommon::printLXAAddrOperand(const MCInst *MI, int OpNum,255 raw_ostream &O) {256 printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),257 MI->getOperand(OpNum + 2).getReg(), O);258}259 260void SystemZInstPrinterCommon::printCond4Operand(const MCInst *MI, int OpNum,261 raw_ostream &O) {262 static const char *const CondNames[] = {"o", "h", "nle", "l", "nhe",263 "lh", "ne", "e", "nlh", "he",264 "nl", "le", "nh", "no"};265 uint64_t Imm = MI->getOperand(OpNum).getImm();266 assert(Imm > 0 && Imm < 15 && "Invalid condition");267 O << CondNames[Imm - 1];268}269