Path: blob/main/contrib/llvm-project/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp
35294 views
//===- SystemZInstPrinter.cpp - Convert SystemZ MCInst to assembly syntax -===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "SystemZInstPrinter.h"9#include "llvm/MC/MCExpr.h"10#include "llvm/MC/MCInst.h"11#include "llvm/MC/MCRegister.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>1920using namespace llvm;2122#define DEBUG_TYPE "asm-printer"2324#include "SystemZGenAsmWriter.inc"2526void SystemZInstPrinter::printAddress(const MCAsmInfo *MAI, MCRegister Base,27const MCOperand &DispMO, MCRegister Index,28raw_ostream &O) {29printOperand(DispMO, MAI, O);30if (Base || Index) {31O << '(';32if (Index) {33printFormattedRegName(MAI, Index, O);34O << ',';35}36if (Base)37printFormattedRegName(MAI, Base, O);38else39O << '0';40O << ')';41}42}4344void SystemZInstPrinter::printOperand(const MCOperand &MO, const MCAsmInfo *MAI,45raw_ostream &O) {46if (MO.isReg()) {47if (!MO.getReg())48O << '0';49else50printFormattedRegName(MAI, MO.getReg(), O);51}52else if (MO.isImm())53markup(O, Markup::Immediate) << MO.getImm();54else if (MO.isExpr())55MO.getExpr()->print(O, MAI);56else57llvm_unreachable("Invalid operand");58}5960void SystemZInstPrinter::printFormattedRegName(const MCAsmInfo *MAI,61MCRegister Reg,62raw_ostream &O) const {63const char *RegName = getRegisterName(Reg);64if (MAI->getAssemblerDialect() == AD_HLASM) {65// Skip register prefix so that only register number is left66assert(isalpha(RegName[0]) && isdigit(RegName[1]));67markup(O, Markup::Register) << (RegName + 1);68} else69markup(O, Markup::Register) << '%' << RegName;70}7172void SystemZInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {73printFormattedRegName(&MAI, Reg, O);74}7576void SystemZInstPrinter::printInst(const MCInst *MI, uint64_t Address,77StringRef Annot, const MCSubtargetInfo &STI,78raw_ostream &O) {79printInstruction(MI, Address, O);80printAnnotation(O, Annot);81}8283template <unsigned N>84void SystemZInstPrinter::printUImmOperand(const MCInst *MI, int OpNum,85raw_ostream &O) {86const MCOperand &MO = MI->getOperand(OpNum);87if (MO.isExpr()) {88O << *MO.getExpr();89return;90}91uint64_t Value = static_cast<uint64_t>(MO.getImm());92assert(isUInt<N>(Value) && "Invalid uimm argument");93markup(O, Markup::Immediate) << Value;94}9596template <unsigned N>97void SystemZInstPrinter::printSImmOperand(const MCInst *MI, int OpNum,98raw_ostream &O) {99const MCOperand &MO = MI->getOperand(OpNum);100if (MO.isExpr()) {101O << *MO.getExpr();102return;103}104int64_t Value = MI->getOperand(OpNum).getImm();105assert(isInt<N>(Value) && "Invalid simm argument");106markup(O, Markup::Immediate) << Value;107}108109void SystemZInstPrinter::printU1ImmOperand(const MCInst *MI, int OpNum,110raw_ostream &O) {111printUImmOperand<1>(MI, OpNum, O);112}113114void SystemZInstPrinter::printU2ImmOperand(const MCInst *MI, int OpNum,115raw_ostream &O) {116printUImmOperand<2>(MI, OpNum, O);117}118119void SystemZInstPrinter::printU3ImmOperand(const MCInst *MI, int OpNum,120raw_ostream &O) {121printUImmOperand<3>(MI, OpNum, O);122}123124void SystemZInstPrinter::printU4ImmOperand(const MCInst *MI, int OpNum,125raw_ostream &O) {126printUImmOperand<4>(MI, OpNum, O);127}128129void SystemZInstPrinter::printS8ImmOperand(const MCInst *MI, int OpNum,130raw_ostream &O) {131printSImmOperand<8>(MI, OpNum, O);132}133134void SystemZInstPrinter::printU8ImmOperand(const MCInst *MI, int OpNum,135raw_ostream &O) {136printUImmOperand<8>(MI, OpNum, O);137}138139void SystemZInstPrinter::printU12ImmOperand(const MCInst *MI, int OpNum,140raw_ostream &O) {141printUImmOperand<12>(MI, OpNum, O);142}143144void SystemZInstPrinter::printS16ImmOperand(const MCInst *MI, int OpNum,145raw_ostream &O) {146printSImmOperand<16>(MI, OpNum, O);147}148149void SystemZInstPrinter::printU16ImmOperand(const MCInst *MI, int OpNum,150raw_ostream &O) {151printUImmOperand<16>(MI, OpNum, O);152}153154void SystemZInstPrinter::printS32ImmOperand(const MCInst *MI, int OpNum,155raw_ostream &O) {156printSImmOperand<32>(MI, OpNum, O);157}158159void SystemZInstPrinter::printU32ImmOperand(const MCInst *MI, int OpNum,160raw_ostream &O) {161printUImmOperand<32>(MI, OpNum, O);162}163164void SystemZInstPrinter::printU48ImmOperand(const MCInst *MI, int OpNum,165raw_ostream &O) {166printUImmOperand<48>(MI, OpNum, O);167}168169void SystemZInstPrinter::printPCRelOperand(const MCInst *MI, int OpNum,170raw_ostream &O) {171const MCOperand &MO = MI->getOperand(OpNum);172if (MO.isImm()) {173WithMarkup M = markup(O, Markup::Immediate);174O << "0x";175O.write_hex(MO.getImm());176} else177MO.getExpr()->print(O, &MAI);178}179180void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI,181uint64_t Address, int OpNum,182raw_ostream &O) {183// Output the PC-relative operand.184printPCRelOperand(MI, OpNum, O);185186// Output the TLS marker if present.187if ((unsigned)OpNum + 1 < MI->getNumOperands()) {188const MCOperand &MO = MI->getOperand(OpNum + 1);189const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());190switch (refExp.getKind()) {191case MCSymbolRefExpr::VK_TLSGD:192O << ":tls_gdcall:";193break;194case MCSymbolRefExpr::VK_TLSLDM:195O << ":tls_ldcall:";196break;197default:198llvm_unreachable("Unexpected symbol kind");199}200O << refExp.getSymbol().getName();201}202}203204void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,205raw_ostream &O) {206printOperand(MI->getOperand(OpNum), &MAI, O);207}208209void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,210raw_ostream &O) {211printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),2120, O);213}214215void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,216raw_ostream &O) {217printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),218MI->getOperand(OpNum + 2).getReg(), O);219}220221void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,222raw_ostream &O) {223unsigned Base = MI->getOperand(OpNum).getReg();224const MCOperand &DispMO = MI->getOperand(OpNum + 1);225uint64_t Length = MI->getOperand(OpNum + 2).getImm();226printOperand(DispMO, &MAI, O);227O << '(' << Length;228if (Base) {229O << ",";230printRegName(O, Base);231}232O << ')';233}234235void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,236raw_ostream &O) {237unsigned Base = MI->getOperand(OpNum).getReg();238const MCOperand &DispMO = MI->getOperand(OpNum + 1);239unsigned Length = MI->getOperand(OpNum + 2).getReg();240printOperand(DispMO, &MAI, O);241O << "(";242printRegName(O, Length);243if (Base) {244O << ",";245printRegName(O, Base);246}247O << ')';248}249250void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,251raw_ostream &O) {252printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),253MI->getOperand(OpNum + 2).getReg(), O);254}255256void SystemZInstPrinter::printCond4Operand(const MCInst *MI, int OpNum,257raw_ostream &O) {258static const char *const CondNames[] = {259"o", "h", "nle", "l", "nhe", "lh", "ne",260"e", "nlh", "he", "nl", "le", "nh", "no"261};262uint64_t Imm = MI->getOperand(OpNum).getImm();263assert(Imm > 0 && Imm < 15 && "Invalid condition");264O << CondNames[Imm - 1];265}266267268