xref: /llvm-project/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinterCommon.cpp (revision 8424bf207efd89eacf2fe893b67be98d535e1db6)
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