Path: blob/main/contrib/llvm-project/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.cpp
213845 views
//=- SystemZInstPrinterCommon.cpp - Common SystemZ MCInst to assembly funcs -=//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 "SystemZInstPrinterCommon.h"9#include "MCTargetDesc/SystemZMCAsmInfo.h"10#include "llvm/MC/MCExpr.h"11#include "llvm/MC/MCInst.h"12#include "llvm/MC/MCRegister.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>2021using namespace llvm;2223#define DEBUG_TYPE "asm-printer"2425void SystemZInstPrinterCommon::printAddress(const MCAsmInfo *MAI,26MCRegister Base,27const MCOperand &DispMO,28MCRegister Index, raw_ostream &O) {29printOperand(DispMO, MAI, O);30if (Base || Index) {31O << '(';32if (Index) {33printRegName(O, Index);34O << ',';35}36if (Base)37printRegName(O, Base);38else39O << '0';40O << ')';41}42}4344void SystemZInstPrinterCommon::printOperand(const MCOperand &MO,45const MCAsmInfo *MAI,46raw_ostream &O) {47if (MO.isReg()) {48if (!MO.getReg())49O << '0';50else51printRegName(O, MO.getReg());52} else if (MO.isImm())53markup(O, Markup::Immediate) << MO.getImm();54else if (MO.isExpr())55MAI->printExpr(O, *MO.getExpr());56else57llvm_unreachable("Invalid operand");58}5960void SystemZInstPrinterCommon::printRegName(raw_ostream &O, MCRegister Reg) {61printFormattedRegName(&MAI, Reg, O);62}6364template <unsigned N>65void SystemZInstPrinterCommon::printUImmOperand(const MCInst *MI, int OpNum,66raw_ostream &O) {67const MCOperand &MO = MI->getOperand(OpNum);68if (MO.isExpr()) {69MAI.printExpr(O, *MO.getExpr());70return;71}72uint64_t Value = static_cast<uint64_t>(MO.getImm());73assert(isUInt<N>(Value) && "Invalid uimm argument");74markup(O, Markup::Immediate) << Value;75}7677template <unsigned N>78void SystemZInstPrinterCommon::printSImmOperand(const MCInst *MI, int OpNum,79raw_ostream &O) {80const MCOperand &MO = MI->getOperand(OpNum);81if (MO.isExpr()) {82MAI.printExpr(O, *MO.getExpr());83return;84}85int64_t Value = MI->getOperand(OpNum).getImm();86assert(isInt<N>(Value) && "Invalid simm argument");87markup(O, Markup::Immediate) << Value;88}8990void SystemZInstPrinterCommon::printU1ImmOperand(const MCInst *MI, int OpNum,91raw_ostream &O) {92printUImmOperand<1>(MI, OpNum, O);93}9495void SystemZInstPrinterCommon::printU2ImmOperand(const MCInst *MI, int OpNum,96raw_ostream &O) {97printUImmOperand<2>(MI, OpNum, O);98}99100void SystemZInstPrinterCommon::printU3ImmOperand(const MCInst *MI, int OpNum,101raw_ostream &O) {102printUImmOperand<3>(MI, OpNum, O);103}104105void SystemZInstPrinterCommon::printU4ImmOperand(const MCInst *MI, int OpNum,106raw_ostream &O) {107printUImmOperand<4>(MI, OpNum, O);108}109110void SystemZInstPrinterCommon::printS8ImmOperand(const MCInst *MI, int OpNum,111raw_ostream &O) {112printSImmOperand<8>(MI, OpNum, O);113}114115void SystemZInstPrinterCommon::printU8ImmOperand(const MCInst *MI, int OpNum,116raw_ostream &O) {117printUImmOperand<8>(MI, OpNum, O);118}119120void SystemZInstPrinterCommon::printU12ImmOperand(const MCInst *MI, int OpNum,121raw_ostream &O) {122printUImmOperand<12>(MI, OpNum, O);123}124125void SystemZInstPrinterCommon::printS16ImmOperand(const MCInst *MI, int OpNum,126raw_ostream &O) {127printSImmOperand<16>(MI, OpNum, O);128}129130void SystemZInstPrinterCommon::printU16ImmOperand(const MCInst *MI, int OpNum,131raw_ostream &O) {132printUImmOperand<16>(MI, OpNum, O);133}134135void SystemZInstPrinterCommon::printS32ImmOperand(const MCInst *MI, int OpNum,136raw_ostream &O) {137printSImmOperand<32>(MI, OpNum, O);138}139140void SystemZInstPrinterCommon::printU32ImmOperand(const MCInst *MI, int OpNum,141raw_ostream &O) {142printUImmOperand<32>(MI, OpNum, O);143}144145void SystemZInstPrinterCommon::printU48ImmOperand(const MCInst *MI, int OpNum,146raw_ostream &O) {147printUImmOperand<48>(MI, OpNum, O);148}149150void SystemZInstPrinterCommon::printPCRelOperand(const MCInst *MI,151uint64_t Address, int OpNum,152raw_ostream &O) {153const MCOperand &MO = MI->getOperand(OpNum);154155// If the label has already been resolved to an immediate offset (say, when156// we're running the disassembler), just print the immediate.157if (MO.isImm()) {158int64_t Offset = MO.getImm();159if (PrintBranchImmAsAddress)160markup(O, Markup::Target) << formatHex(Address + Offset);161else162markup(O, Markup::Immediate) << formatImm(Offset);163return;164}165166// If the branch target is simply an address then print it in hex.167const MCConstantExpr *BranchTarget = dyn_cast<MCConstantExpr>(MO.getExpr());168int64_t TargetAddress;169if (BranchTarget && BranchTarget->evaluateAsAbsolute(TargetAddress)) {170markup(O, Markup::Target) << formatHex((uint64_t)TargetAddress);171} else {172// Otherwise, just print the expression.173MAI.printExpr(O, *MO.getExpr());174}175}176177void SystemZInstPrinterCommon::printPCRelTLSOperand(const MCInst *MI,178uint64_t Address, int OpNum,179raw_ostream &O) {180// Output the PC-relative operand.181printPCRelOperand(MI, Address, OpNum, O);182183// Output the TLS marker if present.184if ((unsigned)OpNum + 1 < MI->getNumOperands()) {185const MCOperand &MO = MI->getOperand(OpNum + 1);186const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());187switch (refExp.getSpecifier()) {188case SystemZ::S_TLSGD:189O << ":tls_gdcall:";190break;191case SystemZ::S_TLSLDM:192O << ":tls_ldcall:";193break;194default:195llvm_unreachable("Unexpected symbol kind");196}197O << refExp.getSymbol().getName();198}199}200201void SystemZInstPrinterCommon::printOperand(const MCInst *MI, int OpNum,202raw_ostream &O) {203printOperand(MI->getOperand(OpNum), &MAI, O);204}205206void SystemZInstPrinterCommon::printBDAddrOperand(const MCInst *MI, int OpNum,207raw_ostream &O) {208printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),2090, O);210}211212void SystemZInstPrinterCommon::printBDXAddrOperand(const MCInst *MI, int OpNum,213raw_ostream &O) {214printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),215MI->getOperand(OpNum + 2).getReg(), O);216}217218void SystemZInstPrinterCommon::printBDLAddrOperand(const MCInst *MI, int OpNum,219raw_ostream &O) {220unsigned Base = MI->getOperand(OpNum).getReg();221const MCOperand &DispMO = MI->getOperand(OpNum + 1);222uint64_t Length = MI->getOperand(OpNum + 2).getImm();223printOperand(DispMO, &MAI, O);224O << '(' << Length;225if (Base) {226O << ",";227printRegName(O, Base);228}229O << ')';230}231232void SystemZInstPrinterCommon::printBDRAddrOperand(const MCInst *MI, int OpNum,233raw_ostream &O) {234unsigned Base = MI->getOperand(OpNum).getReg();235const MCOperand &DispMO = MI->getOperand(OpNum + 1);236unsigned Length = MI->getOperand(OpNum + 2).getReg();237printOperand(DispMO, &MAI, O);238O << "(";239printRegName(O, Length);240if (Base) {241O << ",";242printRegName(O, Base);243}244O << ')';245}246247void SystemZInstPrinterCommon::printBDVAddrOperand(const MCInst *MI, int OpNum,248raw_ostream &O) {249printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),250MI->getOperand(OpNum + 2).getReg(), O);251}252253void SystemZInstPrinterCommon::printLXAAddrOperand(const MCInst *MI, int OpNum,254raw_ostream &O) {255printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),256MI->getOperand(OpNum + 2).getReg(), O);257}258259void SystemZInstPrinterCommon::printCond4Operand(const MCInst *MI, int OpNum,260raw_ostream &O) {261static const char *const CondNames[] = {"o", "h", "nle", "l", "nhe",262"lh", "ne", "e", "nlh", "he",263"nl", "le", "nh", "no"};264uint64_t Imm = MI->getOperand(OpNum).getImm();265assert(Imm > 0 && Imm < 15 && "Invalid condition");266O << CondNames[Imm - 1];267}268269270