16512a8ddStltao //=- SystemZInstPrinterCommon.cpp - Common SystemZ MCInst to assembly funcs -=// 26512a8ddStltao // 36512a8ddStltao // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 46512a8ddStltao // See https://llvm.org/LICENSE.txt for license information. 56512a8ddStltao // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 66512a8ddStltao // 76512a8ddStltao //===----------------------------------------------------------------------===// 86512a8ddStltao 96512a8ddStltao #include "SystemZInstPrinterCommon.h" 106512a8ddStltao #include "llvm/MC/MCExpr.h" 116512a8ddStltao #include "llvm/MC/MCInst.h" 126512a8ddStltao #include "llvm/MC/MCRegister.h" 136512a8ddStltao #include "llvm/MC/MCSymbol.h" 146512a8ddStltao #include "llvm/Support/Casting.h" 156512a8ddStltao #include "llvm/Support/ErrorHandling.h" 166512a8ddStltao #include "llvm/Support/MathExtras.h" 176512a8ddStltao #include "llvm/Support/raw_ostream.h" 186512a8ddStltao #include <cassert> 196512a8ddStltao #include <cstdint> 206512a8ddStltao 216512a8ddStltao using namespace llvm; 226512a8ddStltao 236512a8ddStltao #define DEBUG_TYPE "asm-printer" 246512a8ddStltao 256512a8ddStltao void SystemZInstPrinterCommon::printAddress(const MCAsmInfo *MAI, 266512a8ddStltao MCRegister Base, 276512a8ddStltao const MCOperand &DispMO, 286512a8ddStltao MCRegister Index, raw_ostream &O) { 296512a8ddStltao printOperand(DispMO, MAI, O); 306512a8ddStltao if (Base || Index) { 316512a8ddStltao O << '('; 326512a8ddStltao if (Index) { 336512a8ddStltao printRegName(O, Index); 346512a8ddStltao O << ','; 356512a8ddStltao } 366512a8ddStltao if (Base) 376512a8ddStltao printRegName(O, Base); 386512a8ddStltao else 396512a8ddStltao O << '0'; 406512a8ddStltao O << ')'; 416512a8ddStltao } 426512a8ddStltao } 436512a8ddStltao 446512a8ddStltao void SystemZInstPrinterCommon::printOperand(const MCOperand &MO, 456512a8ddStltao const MCAsmInfo *MAI, 466512a8ddStltao raw_ostream &O) { 476512a8ddStltao if (MO.isReg()) { 486512a8ddStltao if (!MO.getReg()) 496512a8ddStltao O << '0'; 506512a8ddStltao else 516512a8ddStltao printRegName(O, MO.getReg()); 526512a8ddStltao } else if (MO.isImm()) 536512a8ddStltao markup(O, Markup::Immediate) << MO.getImm(); 546512a8ddStltao else if (MO.isExpr()) 556512a8ddStltao MO.getExpr()->print(O, MAI); 566512a8ddStltao else 576512a8ddStltao llvm_unreachable("Invalid operand"); 586512a8ddStltao } 596512a8ddStltao 60facdae62SFangrui Song void SystemZInstPrinterCommon::printRegName(raw_ostream &O, MCRegister Reg) { 616512a8ddStltao printFormattedRegName(&MAI, Reg, O); 626512a8ddStltao } 636512a8ddStltao 646512a8ddStltao template <unsigned N> 656512a8ddStltao void SystemZInstPrinterCommon::printUImmOperand(const MCInst *MI, int OpNum, 666512a8ddStltao raw_ostream &O) { 676512a8ddStltao const MCOperand &MO = MI->getOperand(OpNum); 686512a8ddStltao if (MO.isExpr()) { 696512a8ddStltao O << *MO.getExpr(); 706512a8ddStltao return; 716512a8ddStltao } 726512a8ddStltao uint64_t Value = static_cast<uint64_t>(MO.getImm()); 736512a8ddStltao assert(isUInt<N>(Value) && "Invalid uimm argument"); 746512a8ddStltao markup(O, Markup::Immediate) << Value; 756512a8ddStltao } 766512a8ddStltao 776512a8ddStltao template <unsigned N> 786512a8ddStltao void SystemZInstPrinterCommon::printSImmOperand(const MCInst *MI, int OpNum, 796512a8ddStltao raw_ostream &O) { 806512a8ddStltao const MCOperand &MO = MI->getOperand(OpNum); 816512a8ddStltao if (MO.isExpr()) { 826512a8ddStltao O << *MO.getExpr(); 836512a8ddStltao return; 846512a8ddStltao } 856512a8ddStltao int64_t Value = MI->getOperand(OpNum).getImm(); 866512a8ddStltao assert(isInt<N>(Value) && "Invalid simm argument"); 876512a8ddStltao markup(O, Markup::Immediate) << Value; 886512a8ddStltao } 896512a8ddStltao 906512a8ddStltao void SystemZInstPrinterCommon::printU1ImmOperand(const MCInst *MI, int OpNum, 916512a8ddStltao raw_ostream &O) { 926512a8ddStltao printUImmOperand<1>(MI, OpNum, O); 936512a8ddStltao } 946512a8ddStltao 956512a8ddStltao void SystemZInstPrinterCommon::printU2ImmOperand(const MCInst *MI, int OpNum, 966512a8ddStltao raw_ostream &O) { 976512a8ddStltao printUImmOperand<2>(MI, OpNum, O); 986512a8ddStltao } 996512a8ddStltao 1006512a8ddStltao void SystemZInstPrinterCommon::printU3ImmOperand(const MCInst *MI, int OpNum, 1016512a8ddStltao raw_ostream &O) { 1026512a8ddStltao printUImmOperand<3>(MI, OpNum, O); 1036512a8ddStltao } 1046512a8ddStltao 1056512a8ddStltao void SystemZInstPrinterCommon::printU4ImmOperand(const MCInst *MI, int OpNum, 1066512a8ddStltao raw_ostream &O) { 1076512a8ddStltao printUImmOperand<4>(MI, OpNum, O); 1086512a8ddStltao } 1096512a8ddStltao 1106512a8ddStltao void SystemZInstPrinterCommon::printS8ImmOperand(const MCInst *MI, int OpNum, 1116512a8ddStltao raw_ostream &O) { 1126512a8ddStltao printSImmOperand<8>(MI, OpNum, O); 1136512a8ddStltao } 1146512a8ddStltao 1156512a8ddStltao void SystemZInstPrinterCommon::printU8ImmOperand(const MCInst *MI, int OpNum, 1166512a8ddStltao raw_ostream &O) { 1176512a8ddStltao printUImmOperand<8>(MI, OpNum, O); 1186512a8ddStltao } 1196512a8ddStltao 1206512a8ddStltao void SystemZInstPrinterCommon::printU12ImmOperand(const MCInst *MI, int OpNum, 1216512a8ddStltao raw_ostream &O) { 1226512a8ddStltao printUImmOperand<12>(MI, OpNum, O); 1236512a8ddStltao } 1246512a8ddStltao 1256512a8ddStltao void SystemZInstPrinterCommon::printS16ImmOperand(const MCInst *MI, int OpNum, 1266512a8ddStltao raw_ostream &O) { 1276512a8ddStltao printSImmOperand<16>(MI, OpNum, O); 1286512a8ddStltao } 1296512a8ddStltao 1306512a8ddStltao void SystemZInstPrinterCommon::printU16ImmOperand(const MCInst *MI, int OpNum, 1316512a8ddStltao raw_ostream &O) { 1326512a8ddStltao printUImmOperand<16>(MI, OpNum, O); 1336512a8ddStltao } 1346512a8ddStltao 1356512a8ddStltao void SystemZInstPrinterCommon::printS32ImmOperand(const MCInst *MI, int OpNum, 1366512a8ddStltao raw_ostream &O) { 1376512a8ddStltao printSImmOperand<32>(MI, OpNum, O); 1386512a8ddStltao } 1396512a8ddStltao 1406512a8ddStltao void SystemZInstPrinterCommon::printU32ImmOperand(const MCInst *MI, int OpNum, 1416512a8ddStltao raw_ostream &O) { 1426512a8ddStltao printUImmOperand<32>(MI, OpNum, O); 1436512a8ddStltao } 1446512a8ddStltao 1456512a8ddStltao void SystemZInstPrinterCommon::printU48ImmOperand(const MCInst *MI, int OpNum, 1466512a8ddStltao raw_ostream &O) { 1476512a8ddStltao printUImmOperand<48>(MI, OpNum, O); 1486512a8ddStltao } 1496512a8ddStltao 1506512a8ddStltao void SystemZInstPrinterCommon::printPCRelOperand(const MCInst *MI, int OpNum, 1516512a8ddStltao raw_ostream &O) { 1526512a8ddStltao const MCOperand &MO = MI->getOperand(OpNum); 1536512a8ddStltao if (MO.isImm()) { 1546512a8ddStltao WithMarkup M = markup(O, Markup::Immediate); 1556512a8ddStltao O << "0x"; 1566512a8ddStltao O.write_hex(MO.getImm()); 1576512a8ddStltao } else 1586512a8ddStltao MO.getExpr()->print(O, &MAI); 1596512a8ddStltao } 1606512a8ddStltao 1616512a8ddStltao void SystemZInstPrinterCommon::printPCRelTLSOperand(const MCInst *MI, 1626512a8ddStltao uint64_t Address, int OpNum, 1636512a8ddStltao raw_ostream &O) { 1646512a8ddStltao // Output the PC-relative operand. 1656512a8ddStltao printPCRelOperand(MI, OpNum, O); 1666512a8ddStltao 1676512a8ddStltao // Output the TLS marker if present. 1686512a8ddStltao if ((unsigned)OpNum + 1 < MI->getNumOperands()) { 1696512a8ddStltao const MCOperand &MO = MI->getOperand(OpNum + 1); 1706512a8ddStltao const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr()); 1716512a8ddStltao switch (refExp.getKind()) { 1726512a8ddStltao case MCSymbolRefExpr::VK_TLSGD: 1736512a8ddStltao O << ":tls_gdcall:"; 1746512a8ddStltao break; 1756512a8ddStltao case MCSymbolRefExpr::VK_TLSLDM: 1766512a8ddStltao O << ":tls_ldcall:"; 1776512a8ddStltao break; 1786512a8ddStltao default: 1796512a8ddStltao llvm_unreachable("Unexpected symbol kind"); 1806512a8ddStltao } 1816512a8ddStltao O << refExp.getSymbol().getName(); 1826512a8ddStltao } 1836512a8ddStltao } 1846512a8ddStltao 1856512a8ddStltao void SystemZInstPrinterCommon::printOperand(const MCInst *MI, int OpNum, 1866512a8ddStltao raw_ostream &O) { 1876512a8ddStltao printOperand(MI->getOperand(OpNum), &MAI, O); 1886512a8ddStltao } 1896512a8ddStltao 1906512a8ddStltao void SystemZInstPrinterCommon::printBDAddrOperand(const MCInst *MI, int OpNum, 1916512a8ddStltao raw_ostream &O) { 1926512a8ddStltao printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1), 1936512a8ddStltao 0, O); 1946512a8ddStltao } 1956512a8ddStltao 1966512a8ddStltao void SystemZInstPrinterCommon::printBDXAddrOperand(const MCInst *MI, int OpNum, 1976512a8ddStltao raw_ostream &O) { 1986512a8ddStltao printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1), 1996512a8ddStltao MI->getOperand(OpNum + 2).getReg(), O); 2006512a8ddStltao } 2016512a8ddStltao 2026512a8ddStltao void SystemZInstPrinterCommon::printBDLAddrOperand(const MCInst *MI, int OpNum, 2036512a8ddStltao raw_ostream &O) { 2046512a8ddStltao unsigned Base = MI->getOperand(OpNum).getReg(); 2056512a8ddStltao const MCOperand &DispMO = MI->getOperand(OpNum + 1); 2066512a8ddStltao uint64_t Length = MI->getOperand(OpNum + 2).getImm(); 2076512a8ddStltao printOperand(DispMO, &MAI, O); 2086512a8ddStltao O << '(' << Length; 2096512a8ddStltao if (Base) { 2106512a8ddStltao O << ","; 2116512a8ddStltao printRegName(O, Base); 2126512a8ddStltao } 2136512a8ddStltao O << ')'; 2146512a8ddStltao } 2156512a8ddStltao 2166512a8ddStltao void SystemZInstPrinterCommon::printBDRAddrOperand(const MCInst *MI, int OpNum, 2176512a8ddStltao raw_ostream &O) { 2186512a8ddStltao unsigned Base = MI->getOperand(OpNum).getReg(); 2196512a8ddStltao const MCOperand &DispMO = MI->getOperand(OpNum + 1); 2206512a8ddStltao unsigned Length = MI->getOperand(OpNum + 2).getReg(); 2216512a8ddStltao printOperand(DispMO, &MAI, O); 2226512a8ddStltao O << "("; 2236512a8ddStltao printRegName(O, Length); 2246512a8ddStltao if (Base) { 2256512a8ddStltao O << ","; 2266512a8ddStltao printRegName(O, Base); 2276512a8ddStltao } 2286512a8ddStltao O << ')'; 2296512a8ddStltao } 2306512a8ddStltao 2316512a8ddStltao void SystemZInstPrinterCommon::printBDVAddrOperand(const MCInst *MI, int OpNum, 2326512a8ddStltao raw_ostream &O) { 2336512a8ddStltao printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1), 2346512a8ddStltao MI->getOperand(OpNum + 2).getReg(), O); 2356512a8ddStltao } 2366512a8ddStltao 237*8424bf20SUlrich Weigand void SystemZInstPrinterCommon::printLXAAddrOperand(const MCInst *MI, int OpNum, 238*8424bf20SUlrich Weigand raw_ostream &O) { 239*8424bf20SUlrich Weigand printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1), 240*8424bf20SUlrich Weigand MI->getOperand(OpNum + 2).getReg(), O); 241*8424bf20SUlrich Weigand } 242*8424bf20SUlrich Weigand 2436512a8ddStltao void SystemZInstPrinterCommon::printCond4Operand(const MCInst *MI, int OpNum, 2446512a8ddStltao raw_ostream &O) { 2456512a8ddStltao static const char *const CondNames[] = {"o", "h", "nle", "l", "nhe", 2466512a8ddStltao "lh", "ne", "e", "nlh", "he", 2476512a8ddStltao "nl", "le", "nh", "no"}; 2486512a8ddStltao uint64_t Imm = MI->getOperand(OpNum).getImm(); 2496512a8ddStltao assert(Imm > 0 && Imm < 15 && "Invalid condition"); 2506512a8ddStltao O << CondNames[Imm - 1]; 2516512a8ddStltao } 252