Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYInstPrinter.cpp
35294 views
//===-- CSKYInstPrinter.cpp - Convert CSKY MCInst to asm syntax ---------===//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//===----------------------------------------------------------------------===//7//8// This class prints an CSKY MCInst to a .s file.9//10//===----------------------------------------------------------------------===//11#include "CSKYInstPrinter.h"12#include "MCTargetDesc/CSKYBaseInfo.h"13#include "MCTargetDesc/CSKYMCExpr.h"14#include "llvm/ADT/STLExtras.h"15#include "llvm/ADT/StringExtras.h"16#include "llvm/MC/MCAsmInfo.h"17#include "llvm/MC/MCExpr.h"18#include "llvm/MC/MCInst.h"19#include "llvm/MC/MCInstrInfo.h"20#include "llvm/MC/MCRegisterInfo.h"21#include "llvm/MC/MCSection.h"22#include "llvm/MC/MCSubtargetInfo.h"23#include "llvm/MC/MCSymbol.h"24#include "llvm/Support/CommandLine.h"25#include "llvm/Support/Debug.h"26#include "llvm/Support/ErrorHandling.h"27#include "llvm/Support/FormattedStream.h"2829using namespace llvm;3031#define DEBUG_TYPE "csky-asm-printer"3233// Include the auto-generated portion of the assembly writer.34#define PRINT_ALIAS_INSTR35#include "CSKYGenAsmWriter.inc"3637static cl::opt<bool>38NoAliases("csky-no-aliases",39cl::desc("Disable the emission of assembler pseudo instructions"),40cl::init(false), cl::Hidden);4142static cl::opt<bool>43ArchRegNames("csky-arch-reg-names",44cl::desc("Print architectural register names rather than the "45"ABI names (such as r14 instead of sp)"),46cl::init(false), cl::Hidden);4748// The command-line flags above are used by llvm-mc and llc. They can be used by49// `llvm-objdump`, but we override their values here to handle options passed to50// `llvm-objdump` with `-M` (which matches GNU objdump). There did not seem to51// be an easier way to allow these options in all these tools, without doing it52// this way.53bool CSKYInstPrinter::applyTargetSpecificCLOption(StringRef Opt) {54if (Opt == "no-aliases") {55NoAliases = true;56return true;57}58if (Opt == "numeric") {59ArchRegNames = true;60return true;61}62if (Opt == "debug") {63DebugFlag = true;64return true;65}66if (Opt == "abi-names") {67ABIRegNames = true;68return true;69}7071return false;72}7374void CSKYInstPrinter::printInst(const MCInst *MI, uint64_t Address,75StringRef Annot, const MCSubtargetInfo &STI,76raw_ostream &O) {77const MCInst *NewMI = MI;7879if (NoAliases || !printAliasInstr(NewMI, Address, STI, O))80printInstruction(NewMI, Address, STI, O);81printAnnotation(O, Annot);82}8384void CSKYInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {85if (PrintBranchImmAsAddress)86O << getRegisterName(Reg, ABIRegNames ? CSKY::ABIRegAltName87: CSKY::NoRegAltName);88else89O << getRegisterName(Reg);90}9192void CSKYInstPrinter::printFPRRegName(raw_ostream &O, unsigned RegNo) const {93if (PrintBranchImmAsAddress)94O << getRegisterName(RegNo, CSKY::NoRegAltName);95else96O << getRegisterName(RegNo);97}9899void CSKYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,100const MCSubtargetInfo &STI, raw_ostream &O,101const char *Modifier) {102assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");103const MCOperand &MO = MI->getOperand(OpNo);104105if (MO.isReg()) {106unsigned Reg = MO.getReg();107bool useABIName = false;108if (PrintBranchImmAsAddress)109useABIName = ABIRegNames;110else111useABIName = !ArchRegNames;112113if (Reg == CSKY::C)114O << "";115else if (STI.hasFeature(CSKY::FeatureJAVA)) {116if (Reg == CSKY::R23)117O << (useABIName ? "fp" : "r23");118else if (Reg == CSKY::R24)119O << (useABIName ? "top" : "r24");120else if (Reg == CSKY::R25)121O << (useABIName ? "bsp" : "r25");122else123printRegName(O, Reg);124} else125printRegName(O, Reg);126127return;128}129130if (MO.isImm()) {131uint64_t TSFlags = MII.get(MI->getOpcode()).TSFlags;132133if (((TSFlags & CSKYII::AddrModeMask) != CSKYII::AddrModeNone) &&134PrintBranchImmAsAddress)135O << formatHex(MO.getImm());136else137O << MO.getImm();138return;139}140141assert(MO.isExpr() && "Unknown operand kind in printOperand");142MO.getExpr()->print(O, &MAI);143}144145void CSKYInstPrinter::printDataSymbol(const MCInst *MI, unsigned OpNo,146const MCSubtargetInfo &STI,147raw_ostream &O) {148const MCOperand &MO = MI->getOperand(OpNo);149150O << "[";151if (MO.isImm())152O << MO.getImm();153else154MO.getExpr()->print(O, &MAI);155O << "]";156}157158void CSKYInstPrinter::printConstpool(const MCInst *MI, uint64_t Address,159unsigned OpNo, const MCSubtargetInfo &STI,160raw_ostream &O) {161const MCOperand &MO = MI->getOperand(OpNo);162163if (MO.isImm()) {164if (PrintBranchImmAsAddress) {165uint64_t Target = Address + MO.getImm();166Target &= 0xfffffffc;167O << formatHex(Target);168} else {169O << MO.getImm();170}171return;172}173174assert(MO.isExpr() && "Unknown operand kind in printConstpool");175176O << "[";177MO.getExpr()->print(O, &MAI);178O << "]";179}180181void CSKYInstPrinter::printCSKYSymbolOperand(const MCInst *MI, uint64_t Address,182unsigned OpNo,183const MCSubtargetInfo &STI,184raw_ostream &O) {185const MCOperand &MO = MI->getOperand(OpNo);186if (!MO.isImm()) {187return printOperand(MI, OpNo, STI, O);188}189190if (PrintBranchImmAsAddress) {191uint64_t Target = Address + MO.getImm();192Target &= 0xffffffff;193O << formatHex(Target);194} else {195O << MO.getImm();196}197}198199void CSKYInstPrinter::printPSRFlag(const MCInst *MI, unsigned OpNo,200const MCSubtargetInfo &STI, raw_ostream &O) {201auto V = MI->getOperand(OpNo).getImm();202203ListSeparator LS;204205if ((V >> 3) & 0x1)206O << LS << "ee";207if ((V >> 2) & 0x1)208O << LS << "ie";209if ((V >> 1) & 0x1)210O << LS << "fe";211if ((V >> 0) & 0x1)212O << LS << "af";213}214215void CSKYInstPrinter::printRegisterSeq(const MCInst *MI, unsigned OpNum,216const MCSubtargetInfo &STI,217raw_ostream &O) {218printRegName(O, MI->getOperand(OpNum).getReg());219O << "-";220printRegName(O, MI->getOperand(OpNum + 1).getReg());221}222223void CSKYInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,224const MCSubtargetInfo &STI,225raw_ostream &O) {226auto V = MI->getOperand(OpNum).getImm();227ListSeparator LS;228229if (V & 0xf) {230O << LS;231printRegName(O, CSKY::R4);232auto Offset = (V & 0xf) - 1;233if (Offset) {234O << "-";235printRegName(O, CSKY::R4 + Offset);236}237}238239if ((V >> 4) & 0x1) {240O << LS;241printRegName(O, CSKY::R15);242}243244if ((V >> 5) & 0x7) {245O << LS;246printRegName(O, CSKY::R16);247248auto Offset = ((V >> 5) & 0x7) - 1;249250if (Offset) {251O << "-";252printRegName(O, CSKY::R16 + Offset);253}254}255256if ((V >> 8) & 0x1) {257O << LS;258printRegName(O, CSKY::R28);259}260}261262const char *CSKYInstPrinter::getRegisterName(MCRegister Reg) {263return getRegisterName(Reg, ArchRegNames ? CSKY::NoRegAltName264: CSKY::ABIRegAltName);265}266267void CSKYInstPrinter::printFPR(const MCInst *MI, unsigned OpNo,268const MCSubtargetInfo &STI, raw_ostream &O) {269const MCOperand &MO = MI->getOperand(OpNo);270assert(MO.isReg());271272printFPRRegName(O, MO.getReg());273}274275276