Path: blob/main/contrib/llvm-project/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaInstPrinter.cpp
35295 views
//===- XtensaInstPrinter.cpp - Convert Xtensa MCInst to asm syntax --------===//1//2// The LLVM Compiler Infrastructure3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9//10// This class prints an Xtensa MCInst to a .s file.11//12//===----------------------------------------------------------------------===//1314#include "XtensaInstPrinter.h"15#include "llvm/CodeGen/MachineOperand.h"16#include "llvm/MC/MCExpr.h"17#include "llvm/MC/MCInstrInfo.h"18#include "llvm/MC/MCRegister.h"19#include "llvm/MC/MCSymbol.h"20#include "llvm/Support/Casting.h"21#include "llvm/Support/raw_ostream.h"2223using namespace llvm;2425#define DEBUG_TYPE "asm-printer"2627#include "XtensaGenAsmWriter.inc"2829static void printExpr(const MCExpr *Expr, raw_ostream &OS) {30int Offset = 0;31const MCSymbolRefExpr *SRE;3233if (!(SRE = cast<MCSymbolRefExpr>(Expr)))34assert(false && "Unexpected MCExpr type.");3536MCSymbolRefExpr::VariantKind Kind = SRE->getKind();3738switch (Kind) {39case MCSymbolRefExpr::VK_None:40break;41// TODO42default:43report_fatal_error("Invalid kind!");44}4546OS << SRE->getSymbol();4748if (Offset) {49if (Offset > 0)50OS << '+';51OS << Offset;52}5354if (Kind != MCSymbolRefExpr::VK_None)55OS << ')';56}5758void XtensaInstPrinter::printOperand(const MCOperand &MC, raw_ostream &O) {59if (MC.isReg())60O << getRegisterName(MC.getReg());61else if (MC.isImm())62O << MC.getImm();63else if (MC.isExpr())64printExpr(MC.getExpr(), O);65else66report_fatal_error("Invalid operand");67}6869void XtensaInstPrinter::printInst(const MCInst *MI, uint64_t Address,70StringRef Annot, const MCSubtargetInfo &STI,71raw_ostream &O) {72printInstruction(MI, Address, O);73printAnnotation(O, Annot);74}7576void XtensaInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) const {77O << getRegisterName(Reg);78}7980void XtensaInstPrinter::printOperand(const MCInst *MI, int OpNum,81raw_ostream &O) {82printOperand(MI->getOperand(OpNum), O);83}8485void XtensaInstPrinter::printMemOperand(const MCInst *MI, int OpNum,86raw_ostream &OS) {87OS << getRegisterName(MI->getOperand(OpNum).getReg());88OS << ", ";89printOperand(MI, OpNum + 1, OS);90}9192void XtensaInstPrinter::printBranchTarget(const MCInst *MI, int OpNum,93raw_ostream &OS) {94const MCOperand &MC = MI->getOperand(OpNum);95if (MI->getOperand(OpNum).isImm()) {96int64_t Val = MC.getImm() + 4;97OS << ". ";98if (Val > 0)99OS << '+';100OS << Val;101} else if (MC.isExpr())102MC.getExpr()->print(OS, &MAI, true);103else104llvm_unreachable("Invalid operand");105}106107void XtensaInstPrinter::printJumpTarget(const MCInst *MI, int OpNum,108raw_ostream &OS) {109const MCOperand &MC = MI->getOperand(OpNum);110if (MC.isImm()) {111int64_t Val = MC.getImm() + 4;112OS << ". ";113if (Val > 0)114OS << '+';115OS << Val;116} else if (MC.isExpr())117MC.getExpr()->print(OS, &MAI, true);118else119llvm_unreachable("Invalid operand");120;121}122123void XtensaInstPrinter::printCallOperand(const MCInst *MI, int OpNum,124raw_ostream &OS) {125const MCOperand &MC = MI->getOperand(OpNum);126if (MC.isImm()) {127int64_t Val = MC.getImm() + 4;128OS << ". ";129if (Val > 0)130OS << '+';131OS << Val;132} else if (MC.isExpr())133MC.getExpr()->print(OS, &MAI, true);134else135llvm_unreachable("Invalid operand");136}137138void XtensaInstPrinter::printL32RTarget(const MCInst *MI, int OpNum,139raw_ostream &O) {140const MCOperand &MC = MI->getOperand(OpNum);141if (MC.isImm()) {142int64_t Value = MI->getOperand(OpNum).getImm();143int64_t InstrOff = Value & 0x3;144Value -= InstrOff;145assert((Value >= -262144 && Value <= -4) &&146"Invalid argument, value must be in ranges [-262144,-4]");147Value += ((InstrOff + 0x3) & 0x4) - InstrOff;148O << ". ";149O << Value;150} else if (MC.isExpr())151MC.getExpr()->print(O, &MAI, true);152else153llvm_unreachable("Invalid operand");154}155156void XtensaInstPrinter::printImm8_AsmOperand(const MCInst *MI, int OpNum,157raw_ostream &O) {158if (MI->getOperand(OpNum).isImm()) {159int64_t Value = MI->getOperand(OpNum).getImm();160assert(isInt<8>(Value) &&161"Invalid argument, value must be in ranges [-128,127]");162O << Value;163} else {164printOperand(MI, OpNum, O);165}166}167168void XtensaInstPrinter::printImm8_sh8_AsmOperand(const MCInst *MI, int OpNum,169raw_ostream &O) {170if (MI->getOperand(OpNum).isImm()) {171int64_t Value = MI->getOperand(OpNum).getImm();172assert((isInt<16>(Value) && ((Value & 0xFF) == 0)) &&173"Invalid argument, value must be multiples of 256 in range "174"[-32768,32512]");175O << Value;176} else177printOperand(MI, OpNum, O);178}179180void XtensaInstPrinter::printImm12_AsmOperand(const MCInst *MI, int OpNum,181raw_ostream &O) {182if (MI->getOperand(OpNum).isImm()) {183int64_t Value = MI->getOperand(OpNum).getImm();184assert((Value >= -2048 && Value <= 2047) &&185"Invalid argument, value must be in ranges [-2048,2047]");186O << Value;187} else188printOperand(MI, OpNum, O);189}190191void XtensaInstPrinter::printImm12m_AsmOperand(const MCInst *MI, int OpNum,192raw_ostream &O) {193if (MI->getOperand(OpNum).isImm()) {194int64_t Value = MI->getOperand(OpNum).getImm();195assert((Value >= -2048 && Value <= 2047) &&196"Invalid argument, value must be in ranges [-2048,2047]");197O << Value;198} else199printOperand(MI, OpNum, O);200}201202void XtensaInstPrinter::printUimm4_AsmOperand(const MCInst *MI, int OpNum,203raw_ostream &O) {204if (MI->getOperand(OpNum).isImm()) {205int64_t Value = MI->getOperand(OpNum).getImm();206assert((Value >= 0 && Value <= 15) && "Invalid argument");207O << Value;208} else209printOperand(MI, OpNum, O);210}211212void XtensaInstPrinter::printUimm5_AsmOperand(const MCInst *MI, int OpNum,213raw_ostream &O) {214if (MI->getOperand(OpNum).isImm()) {215int64_t Value = MI->getOperand(OpNum).getImm();216assert((Value >= 0 && Value <= 31) && "Invalid argument");217O << Value;218} else219printOperand(MI, OpNum, O);220}221222void XtensaInstPrinter::printShimm1_31_AsmOperand(const MCInst *MI, int OpNum,223raw_ostream &O) {224if (MI->getOperand(OpNum).isImm()) {225int64_t Value = MI->getOperand(OpNum).getImm();226assert((Value >= 1 && Value <= 31) &&227"Invalid argument, value must be in range [1,31]");228O << Value;229} else230printOperand(MI, OpNum, O);231}232233void XtensaInstPrinter::printImm1_16_AsmOperand(const MCInst *MI, int OpNum,234raw_ostream &O) {235if (MI->getOperand(OpNum).isImm()) {236int64_t Value = MI->getOperand(OpNum).getImm();237assert((Value >= 1 && Value <= 16) &&238"Invalid argument, value must be in range [1,16]");239O << Value;240} else241printOperand(MI, OpNum, O);242}243244void XtensaInstPrinter::printOffset8m8_AsmOperand(const MCInst *MI, int OpNum,245raw_ostream &O) {246if (MI->getOperand(OpNum).isImm()) {247int64_t Value = MI->getOperand(OpNum).getImm();248assert((Value >= 0 && Value <= 255) &&249"Invalid argument, value must be in range [0,255]");250O << Value;251} else252printOperand(MI, OpNum, O);253}254255void XtensaInstPrinter::printOffset8m16_AsmOperand(const MCInst *MI, int OpNum,256raw_ostream &O) {257if (MI->getOperand(OpNum).isImm()) {258int64_t Value = MI->getOperand(OpNum).getImm();259assert((Value >= 0 && Value <= 510 && ((Value & 0x1) == 0)) &&260"Invalid argument, value must be multiples of two in range [0,510]");261O << Value;262} else263printOperand(MI, OpNum, O);264}265266void XtensaInstPrinter::printOffset8m32_AsmOperand(const MCInst *MI, int OpNum,267raw_ostream &O) {268if (MI->getOperand(OpNum).isImm()) {269int64_t Value = MI->getOperand(OpNum).getImm();270assert(271(Value >= 0 && Value <= 1020 && ((Value & 0x3) == 0)) &&272"Invalid argument, value must be multiples of four in range [0,1020]");273O << Value;274} else275printOperand(MI, OpNum, O);276}277278void XtensaInstPrinter::printOffset4m32_AsmOperand(const MCInst *MI, int OpNum,279raw_ostream &O) {280if (MI->getOperand(OpNum).isImm()) {281int64_t Value = MI->getOperand(OpNum).getImm();282assert((Value >= 0 && Value <= 60 && ((Value & 0x3) == 0)) &&283"Invalid argument, value must be multiples of four in range [0,60]");284O << Value;285} else286printOperand(MI, OpNum, O);287}288289void XtensaInstPrinter::printB4const_AsmOperand(const MCInst *MI, int OpNum,290raw_ostream &O) {291if (MI->getOperand(OpNum).isImm()) {292int64_t Value = MI->getOperand(OpNum).getImm();293294switch (Value) {295case -1:296case 1:297case 2:298case 3:299case 4:300case 5:301case 6:302case 7:303case 8:304case 10:305case 12:306case 16:307case 32:308case 64:309case 128:310case 256:311break;312default:313assert((0) && "Invalid B4const argument");314}315O << Value;316} else317printOperand(MI, OpNum, O);318}319320void XtensaInstPrinter::printB4constu_AsmOperand(const MCInst *MI, int OpNum,321raw_ostream &O) {322if (MI->getOperand(OpNum).isImm()) {323int64_t Value = MI->getOperand(OpNum).getImm();324325switch (Value) {326case 32768:327case 65536:328case 2:329case 3:330case 4:331case 5:332case 6:333case 7:334case 8:335case 10:336case 12:337case 16:338case 32:339case 64:340case 128:341case 256:342break;343default:344assert((0) && "Invalid B4constu argument");345}346O << Value;347} else348printOperand(MI, OpNum, O);349}350351352