brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.4 KiB · a24543b Raw
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