273 lines · cpp
1//===-- CSKYInstPrinter.cpp - Convert CSKY MCInst to asm syntax ---------===//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// This class prints an CSKY MCInst to a .s file.10//11//===----------------------------------------------------------------------===//12#include "CSKYInstPrinter.h"13#include "MCTargetDesc/CSKYBaseInfo.h"14#include "MCTargetDesc/CSKYMCAsmInfo.h"15#include "llvm/ADT/STLExtras.h"16#include "llvm/ADT/StringExtras.h"17#include "llvm/MC/MCAsmInfo.h"18#include "llvm/MC/MCExpr.h"19#include "llvm/MC/MCInst.h"20#include "llvm/MC/MCInstrInfo.h"21#include "llvm/MC/MCRegisterInfo.h"22#include "llvm/MC/MCSection.h"23#include "llvm/MC/MCSubtargetInfo.h"24#include "llvm/MC/MCSymbol.h"25#include "llvm/Support/CommandLine.h"26#include "llvm/Support/Debug.h"27#include "llvm/Support/ErrorHandling.h"28#include "llvm/Support/FormattedStream.h"29 30using namespace llvm;31 32#define DEBUG_TYPE "csky-asm-printer"33 34// Include the auto-generated portion of the assembly writer.35#define PRINT_ALIAS_INSTR36#include "CSKYGenAsmWriter.inc"37 38static cl::opt<bool>39 NoAliases("csky-no-aliases",40 cl::desc("Disable the emission of assembler pseudo instructions"),41 cl::init(false), cl::Hidden);42 43static cl::opt<bool>44 ArchRegNames("csky-arch-reg-names",45 cl::desc("Print architectural register names rather than the "46 "ABI names (such as r14 instead of sp)"),47 cl::init(false), cl::Hidden);48 49// The command-line flags above are used by llvm-mc and llc. They can be used by50// `llvm-objdump`, but we override their values here to handle options passed to51// `llvm-objdump` with `-M` (which matches GNU objdump). There did not seem to52// be an easier way to allow these options in all these tools, without doing it53// this way.54bool CSKYInstPrinter::applyTargetSpecificCLOption(StringRef Opt) {55 if (Opt == "no-aliases") {56 NoAliases = true;57 return true;58 }59 if (Opt == "numeric") {60 ArchRegNames = true;61 return true;62 }63 if (Opt == "debug") {64 DebugFlag = true;65 return true;66 }67 if (Opt == "abi-names") {68 ABIRegNames = true;69 return true;70 }71 72 return false;73}74 75void CSKYInstPrinter::printInst(const MCInst *MI, uint64_t Address,76 StringRef Annot, const MCSubtargetInfo &STI,77 raw_ostream &O) {78 const MCInst *NewMI = MI;79 80 if (NoAliases || !printAliasInstr(NewMI, Address, STI, O))81 printInstruction(NewMI, Address, STI, O);82 printAnnotation(O, Annot);83}84 85void CSKYInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) {86 if (PrintBranchImmAsAddress)87 O << getRegisterName(Reg, ABIRegNames ? CSKY::ABIRegAltName88 : CSKY::NoRegAltName);89 else90 O << getRegisterName(Reg);91}92 93void CSKYInstPrinter::printFPRRegName(raw_ostream &O, unsigned RegNo) const {94 if (PrintBranchImmAsAddress)95 O << getRegisterName(RegNo, CSKY::NoRegAltName);96 else97 O << getRegisterName(RegNo);98}99 100void CSKYInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,101 const MCSubtargetInfo &STI, raw_ostream &O) {102 const MCOperand &MO = MI->getOperand(OpNo);103 104 if (MO.isReg()) {105 unsigned Reg = MO.getReg();106 bool useABIName = false;107 if (PrintBranchImmAsAddress)108 useABIName = ABIRegNames;109 else110 useABIName = !ArchRegNames;111 112 if (Reg == CSKY::C)113 O << "";114 else if (STI.hasFeature(CSKY::FeatureJAVA)) {115 if (Reg == CSKY::R23)116 O << (useABIName ? "fp" : "r23");117 else if (Reg == CSKY::R24)118 O << (useABIName ? "top" : "r24");119 else if (Reg == CSKY::R25)120 O << (useABIName ? "bsp" : "r25");121 else122 printRegName(O, Reg);123 } else124 printRegName(O, Reg);125 126 return;127 }128 129 if (MO.isImm()) {130 uint64_t TSFlags = MII.get(MI->getOpcode()).TSFlags;131 132 if (((TSFlags & CSKYII::AddrModeMask) != CSKYII::AddrModeNone) &&133 PrintBranchImmAsAddress)134 O << formatHex(MO.getImm());135 else136 O << MO.getImm();137 return;138 }139 140 assert(MO.isExpr() && "Unknown operand kind in printOperand");141 MAI.printExpr(O, *MO.getExpr());142}143 144void CSKYInstPrinter::printDataSymbol(const MCInst *MI, unsigned OpNo,145 const MCSubtargetInfo &STI,146 raw_ostream &O) {147 const MCOperand &MO = MI->getOperand(OpNo);148 149 O << "[";150 if (MO.isImm())151 O << MO.getImm();152 else153 MAI.printExpr(O, *MO.getExpr());154 O << "]";155}156 157void CSKYInstPrinter::printConstpool(const MCInst *MI, uint64_t Address,158 unsigned OpNo, const MCSubtargetInfo &STI,159 raw_ostream &O) {160 const MCOperand &MO = MI->getOperand(OpNo);161 162 if (MO.isImm()) {163 if (PrintBranchImmAsAddress) {164 uint64_t Target = Address + MO.getImm();165 Target &= 0xfffffffc;166 O << formatHex(Target);167 } else {168 O << MO.getImm();169 }170 return;171 }172 173 assert(MO.isExpr() && "Unknown operand kind in printConstpool");174 175 O << "[";176 MAI.printExpr(O, *MO.getExpr());177 O << "]";178}179 180void CSKYInstPrinter::printCSKYSymbolOperand(const MCInst *MI, uint64_t Address,181 unsigned OpNo,182 const MCSubtargetInfo &STI,183 raw_ostream &O) {184 const MCOperand &MO = MI->getOperand(OpNo);185 if (!MO.isImm()) {186 return printOperand(MI, OpNo, STI, O);187 }188 189 if (PrintBranchImmAsAddress) {190 uint64_t Target = Address + MO.getImm();191 Target &= 0xffffffff;192 O << formatHex(Target);193 } else {194 O << MO.getImm();195 }196}197 198void CSKYInstPrinter::printPSRFlag(const MCInst *MI, unsigned OpNo,199 const MCSubtargetInfo &STI, raw_ostream &O) {200 auto V = MI->getOperand(OpNo).getImm();201 202 ListSeparator LS;203 204 if ((V >> 3) & 0x1)205 O << LS << "ee";206 if ((V >> 2) & 0x1)207 O << LS << "ie";208 if ((V >> 1) & 0x1)209 O << LS << "fe";210 if ((V >> 0) & 0x1)211 O << LS << "af";212}213 214void CSKYInstPrinter::printRegisterSeq(const MCInst *MI, unsigned OpNum,215 const MCSubtargetInfo &STI,216 raw_ostream &O) {217 printRegName(O, MI->getOperand(OpNum).getReg());218 O << "-";219 printRegName(O, MI->getOperand(OpNum + 1).getReg());220}221 222void CSKYInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,223 const MCSubtargetInfo &STI,224 raw_ostream &O) {225 auto V = MI->getOperand(OpNum).getImm();226 ListSeparator LS;227 228 if (V & 0xf) {229 O << LS;230 printRegName(O, CSKY::R4);231 auto Offset = (V & 0xf) - 1;232 if (Offset) {233 O << "-";234 printRegName(O, CSKY::R4 + Offset);235 }236 }237 238 if ((V >> 4) & 0x1) {239 O << LS;240 printRegName(O, CSKY::R15);241 }242 243 if ((V >> 5) & 0x7) {244 O << LS;245 printRegName(O, CSKY::R16);246 247 auto Offset = ((V >> 5) & 0x7) - 1;248 249 if (Offset) {250 O << "-";251 printRegName(O, CSKY::R16 + Offset);252 }253 }254 255 if ((V >> 8) & 0x1) {256 O << LS;257 printRegName(O, CSKY::R28);258 }259}260 261const char *CSKYInstPrinter::getRegisterName(MCRegister Reg) {262 return getRegisterName(Reg, ArchRegNames ? CSKY::NoRegAltName263 : CSKY::ABIRegAltName);264}265 266void CSKYInstPrinter::printFPR(const MCInst *MI, unsigned OpNo,267 const MCSubtargetInfo &STI, raw_ostream &O) {268 const MCOperand &MO = MI->getOperand(OpNo);269 assert(MO.isReg());270 271 printFPRRegName(O, MO.getReg());272}273