1351278Sdim//===- ARCInstPrinter.cpp - ARC MCInst to assembly syntax -------*- C++ -*-===// 2351278Sdim// 3351278Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4351278Sdim// See https://llvm.org/LICENSE.txt for license information. 5351278Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6351278Sdim// 7351278Sdim//===----------------------------------------------------------------------===// 8351278Sdim// 9351278Sdim// This class prints an ARC MCInst to a .s file. 10351278Sdim// 11351278Sdim//===----------------------------------------------------------------------===// 12351278Sdim 13351278Sdim#include "ARCInstPrinter.h" 14351278Sdim#include "MCTargetDesc/ARCInfo.h" 15351278Sdim#include "llvm/ADT/StringExtras.h" 16351278Sdim#include "llvm/MC/MCExpr.h" 17351278Sdim#include "llvm/MC/MCInst.h" 18351278Sdim#include "llvm/MC/MCInstrInfo.h" 19351278Sdim#include "llvm/MC/MCSymbol.h" 20351278Sdim#include "llvm/Support/Casting.h" 21351278Sdim#include "llvm/Support/Debug.h" 22351278Sdim#include "llvm/Support/raw_ostream.h" 23351278Sdim 24351278Sdimusing namespace llvm; 25351278Sdim 26351278Sdim#define DEBUG_TYPE "asm-printer" 27351278Sdim 28351278Sdim#include "ARCGenAsmWriter.inc" 29351278Sdim 30351278Sdimtemplate <class T> 31351278Sdimstatic const char *BadConditionCode(T cc) { 32351278Sdim LLVM_DEBUG(dbgs() << "Unknown condition code passed: " << cc << "\n"); 33351278Sdim return "{unknown-cc}"; 34351278Sdim} 35351278Sdim 36351278Sdimstatic const char *ARCBRCondCodeToString(ARCCC::BRCondCode BRCC) { 37351278Sdim switch (BRCC) { 38351278Sdim case ARCCC::BREQ: 39351278Sdim return "eq"; 40351278Sdim case ARCCC::BRNE: 41351278Sdim return "ne"; 42351278Sdim case ARCCC::BRLT: 43351278Sdim return "lt"; 44351278Sdim case ARCCC::BRGE: 45351278Sdim return "ge"; 46351278Sdim case ARCCC::BRLO: 47351278Sdim return "lo"; 48351278Sdim case ARCCC::BRHS: 49351278Sdim return "hs"; 50351278Sdim } 51351278Sdim return BadConditionCode(BRCC); 52351278Sdim} 53351278Sdim 54351278Sdimstatic const char *ARCCondCodeToString(ARCCC::CondCode CC) { 55351278Sdim switch (CC) { 56351278Sdim case ARCCC::EQ: 57351278Sdim return "eq"; 58351278Sdim case ARCCC::NE: 59351278Sdim return "ne"; 60351278Sdim case ARCCC::P: 61351278Sdim return "p"; 62351278Sdim case ARCCC::N: 63351278Sdim return "n"; 64351278Sdim case ARCCC::HS: 65351278Sdim return "hs"; 66351278Sdim case ARCCC::LO: 67351278Sdim return "lo"; 68351278Sdim case ARCCC::GT: 69351278Sdim return "gt"; 70351278Sdim case ARCCC::GE: 71351278Sdim return "ge"; 72351278Sdim case ARCCC::VS: 73351278Sdim return "vs"; 74351278Sdim case ARCCC::VC: 75351278Sdim return "vc"; 76351278Sdim case ARCCC::LT: 77351278Sdim return "lt"; 78351278Sdim case ARCCC::LE: 79351278Sdim return "le"; 80351278Sdim case ARCCC::HI: 81351278Sdim return "hi"; 82351278Sdim case ARCCC::LS: 83351278Sdim return "ls"; 84351278Sdim case ARCCC::PNZ: 85351278Sdim return "pnz"; 86351278Sdim case ARCCC::AL: 87351278Sdim return "al"; 88351278Sdim case ARCCC::NZ: 89351278Sdim return "nz"; 90351278Sdim case ARCCC::Z: 91351278Sdim return "z"; 92351278Sdim } 93351278Sdim return BadConditionCode(CC); 94351278Sdim} 95351278Sdim 96351278Sdimvoid ARCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { 97351278Sdim OS << StringRef(getRegisterName(RegNo)).lower(); 98351278Sdim} 99351278Sdim 100360784Sdimvoid ARCInstPrinter::printInst(const MCInst *MI, uint64_t Address, 101360784Sdim StringRef Annot, const MCSubtargetInfo &STI, 102360784Sdim raw_ostream &O) { 103360784Sdim printInstruction(MI, Address, O); 104351278Sdim printAnnotation(O, Annot); 105351278Sdim} 106351278Sdim 107351278Sdimstatic void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI, 108351278Sdim raw_ostream &OS) { 109351278Sdim int Offset = 0; 110351278Sdim const MCSymbolRefExpr *SRE; 111351278Sdim 112351278Sdim if (const auto *CE = dyn_cast<MCConstantExpr>(Expr)) { 113351278Sdim OS << "0x"; 114351278Sdim OS.write_hex(CE->getValue()); 115351278Sdim return; 116351278Sdim } 117351278Sdim 118351278Sdim if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr)) { 119351278Sdim SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS()); 120351278Sdim const auto *CE = dyn_cast<MCConstantExpr>(BE->getRHS()); 121351278Sdim assert(SRE && CE && "Binary expression must be sym+const."); 122351278Sdim Offset = CE->getValue(); 123351278Sdim } else { 124351278Sdim SRE = dyn_cast<MCSymbolRefExpr>(Expr); 125351278Sdim assert(SRE && "Unexpected MCExpr type."); 126351278Sdim } 127351278Sdim assert(SRE->getKind() == MCSymbolRefExpr::VK_None); 128351278Sdim 129351278Sdim // Symbols are prefixed with '@' 130351278Sdim OS << '@'; 131351278Sdim SRE->getSymbol().print(OS, MAI); 132351278Sdim 133351278Sdim if (Offset) { 134351278Sdim if (Offset > 0) 135351278Sdim OS << '+'; 136351278Sdim OS << Offset; 137351278Sdim } 138351278Sdim} 139351278Sdim 140351278Sdimvoid ARCInstPrinter::printOperand(const MCInst *MI, unsigned OpNum, 141351278Sdim raw_ostream &O) { 142351278Sdim const MCOperand &Op = MI->getOperand(OpNum); 143351278Sdim if (Op.isReg()) { 144351278Sdim printRegName(O, Op.getReg()); 145351278Sdim return; 146351278Sdim } 147351278Sdim 148351278Sdim if (Op.isImm()) { 149351278Sdim O << Op.getImm(); 150351278Sdim return; 151351278Sdim } 152351278Sdim 153351278Sdim assert(Op.isExpr() && "unknown operand kind in printOperand"); 154351278Sdim printExpr(Op.getExpr(), &MAI, O); 155351278Sdim} 156351278Sdim 157351278Sdimvoid ARCInstPrinter::printMemOperandRI(const MCInst *MI, unsigned OpNum, 158351278Sdim raw_ostream &O) { 159351278Sdim const MCOperand &base = MI->getOperand(OpNum); 160351278Sdim const MCOperand &offset = MI->getOperand(OpNum + 1); 161351278Sdim assert(base.isReg() && "Base should be register."); 162351278Sdim assert(offset.isImm() && "Offset should be immediate."); 163351278Sdim printRegName(O, base.getReg()); 164351278Sdim O << "," << offset.getImm(); 165351278Sdim} 166351278Sdim 167351278Sdimvoid ARCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum, 168351278Sdim raw_ostream &O) { 169351278Sdim 170351278Sdim const MCOperand &Op = MI->getOperand(OpNum); 171351278Sdim assert(Op.isImm() && "Predicate operand is immediate."); 172351278Sdim O << ARCCondCodeToString((ARCCC::CondCode)Op.getImm()); 173351278Sdim} 174351278Sdim 175351278Sdimvoid ARCInstPrinter::printBRCCPredicateOperand(const MCInst *MI, unsigned OpNum, 176351278Sdim raw_ostream &O) { 177351278Sdim const MCOperand &Op = MI->getOperand(OpNum); 178351278Sdim assert(Op.isImm() && "Predicate operand is immediate."); 179351278Sdim O << ARCBRCondCodeToString((ARCCC::BRCondCode)Op.getImm()); 180351278Sdim} 181