Path: blob/main/contrib/llvm-project/llvm/lib/Target/Lanai/MCTargetDesc/LanaiInstPrinter.cpp
35295 views
//===-- LanaiInstPrinter.cpp - Convert Lanai 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 Lanai MCInst to a .s file.9//10//===----------------------------------------------------------------------===//1112#include "LanaiInstPrinter.h"13#include "LanaiMCExpr.h"14#include "LanaiAluCode.h"15#include "LanaiCondCode.h"16#include "MCTargetDesc/LanaiMCTargetDesc.h"17#include "llvm/MC/MCAsmInfo.h"18#include "llvm/MC/MCExpr.h"19#include "llvm/MC/MCInst.h"20#include "llvm/MC/MCRegisterInfo.h"21#include "llvm/MC/MCSymbol.h"22#include "llvm/Support/ErrorHandling.h"23#include "llvm/Support/FormattedStream.h"2425using namespace llvm;2627#define DEBUG_TYPE "asm-printer"2829// Include the auto-generated portion of the assembly writer.30#define PRINT_ALIAS_INSTR31#include "LanaiGenAsmWriter.inc"3233void LanaiInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {34OS << StringRef(getRegisterName(Reg)).lower();35}3637bool LanaiInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,38StringRef Alias, unsigned OpNo0,39unsigned OpNo1) {40OS << "\t" << Alias << " ";41printOperand(MI, OpNo0, OS);42OS << ", ";43printOperand(MI, OpNo1, OS);44return true;45}4647static bool usesGivenOffset(const MCInst *MI, int AddOffset) {48unsigned AluCode = MI->getOperand(3).getImm();49return LPAC::encodeLanaiAluCode(AluCode) == LPAC::ADD &&50(MI->getOperand(2).getImm() == AddOffset ||51MI->getOperand(2).getImm() == -AddOffset);52}5354static bool isPreIncrementForm(const MCInst *MI, int AddOffset) {55unsigned AluCode = MI->getOperand(3).getImm();56return LPAC::isPreOp(AluCode) && usesGivenOffset(MI, AddOffset);57}5859static bool isPostIncrementForm(const MCInst *MI, int AddOffset) {60unsigned AluCode = MI->getOperand(3).getImm();61return LPAC::isPostOp(AluCode) && usesGivenOffset(MI, AddOffset);62}6364static StringRef decIncOperator(const MCInst *MI) {65if (MI->getOperand(2).getImm() < 0)66return "--";67return "++";68}6970bool LanaiInstPrinter::printMemoryLoadIncrement(const MCInst *MI,71raw_ostream &OS,72StringRef Opcode,73int AddOffset) {74if (isPreIncrementForm(MI, AddOffset)) {75OS << "\t" << Opcode << "\t[" << decIncOperator(MI) << "%"76<< getRegisterName(MI->getOperand(1).getReg()) << "], %"77<< getRegisterName(MI->getOperand(0).getReg());78return true;79}80if (isPostIncrementForm(MI, AddOffset)) {81OS << "\t" << Opcode << "\t[%"82<< getRegisterName(MI->getOperand(1).getReg()) << decIncOperator(MI)83<< "], %" << getRegisterName(MI->getOperand(0).getReg());84return true;85}86return false;87}8889bool LanaiInstPrinter::printMemoryStoreIncrement(const MCInst *MI,90raw_ostream &OS,91StringRef Opcode,92int AddOffset) {93if (isPreIncrementForm(MI, AddOffset)) {94OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())95<< ", [" << decIncOperator(MI) << "%"96<< getRegisterName(MI->getOperand(1).getReg()) << "]";97return true;98}99if (isPostIncrementForm(MI, AddOffset)) {100OS << "\t" << Opcode << "\t%" << getRegisterName(MI->getOperand(0).getReg())101<< ", [%" << getRegisterName(MI->getOperand(1).getReg())102<< decIncOperator(MI) << "]";103return true;104}105return false;106}107108bool LanaiInstPrinter::printAlias(const MCInst *MI, raw_ostream &OS) {109switch (MI->getOpcode()) {110case Lanai::LDW_RI:111// ld 4[*%rN], %rX => ld [++imm], %rX112// ld -4[*%rN], %rX => ld [--imm], %rX113// ld 4[%rN*], %rX => ld [imm++], %rX114// ld -4[%rN*], %rX => ld [imm--], %rX115return printMemoryLoadIncrement(MI, OS, "ld", 4);116case Lanai::LDHs_RI:117return printMemoryLoadIncrement(MI, OS, "ld.h", 2);118case Lanai::LDHz_RI:119return printMemoryLoadIncrement(MI, OS, "uld.h", 2);120case Lanai::LDBs_RI:121return printMemoryLoadIncrement(MI, OS, "ld.b", 1);122case Lanai::LDBz_RI:123return printMemoryLoadIncrement(MI, OS, "uld.b", 1);124case Lanai::SW_RI:125// st %rX, 4[*%rN] => st %rX, [++imm]126// st %rX, -4[*%rN] => st %rX, [--imm]127// st %rX, 4[%rN*] => st %rX, [imm++]128// st %rX, -4[%rN*] => st %rX, [imm--]129return printMemoryStoreIncrement(MI, OS, "st", 4);130case Lanai::STH_RI:131return printMemoryStoreIncrement(MI, OS, "st.h", 2);132case Lanai::STB_RI:133return printMemoryStoreIncrement(MI, OS, "st.b", 1);134default:135return false;136}137}138139void LanaiInstPrinter::printInst(const MCInst *MI, uint64_t Address,140StringRef Annotation,141const MCSubtargetInfo & /*STI*/,142raw_ostream &OS) {143if (!printAlias(MI, OS) && !printAliasInstr(MI, Address, OS))144printInstruction(MI, Address, OS);145printAnnotation(OS, Annotation);146}147148void LanaiInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,149raw_ostream &OS, const char *Modifier) {150assert((Modifier == nullptr || Modifier[0] == 0) && "No modifiers supported");151const MCOperand &Op = MI->getOperand(OpNo);152if (Op.isReg())153OS << "%" << getRegisterName(Op.getReg());154else if (Op.isImm())155OS << formatHex(Op.getImm());156else {157assert(Op.isExpr() && "Expected an expression");158Op.getExpr()->print(OS, &MAI);159}160}161162void LanaiInstPrinter::printMemImmOperand(const MCInst *MI, unsigned OpNo,163raw_ostream &OS) {164const MCOperand &Op = MI->getOperand(OpNo);165if (Op.isImm()) {166OS << '[' << formatHex(Op.getImm()) << ']';167} else {168// Symbolic operand will be lowered to immediate value by linker169assert(Op.isExpr() && "Expected an expression");170OS << '[';171Op.getExpr()->print(OS, &MAI);172OS << ']';173}174}175176void LanaiInstPrinter::printHi16ImmOperand(const MCInst *MI, unsigned OpNo,177raw_ostream &OS) {178const MCOperand &Op = MI->getOperand(OpNo);179if (Op.isImm()) {180OS << formatHex(Op.getImm() << 16);181} else {182// Symbolic operand will be lowered to immediate value by linker183assert(Op.isExpr() && "Expected an expression");184Op.getExpr()->print(OS, &MAI);185}186}187188void LanaiInstPrinter::printHi16AndImmOperand(const MCInst *MI, unsigned OpNo,189raw_ostream &OS) {190const MCOperand &Op = MI->getOperand(OpNo);191if (Op.isImm()) {192OS << formatHex((Op.getImm() << 16) | 0xffff);193} else {194// Symbolic operand will be lowered to immediate value by linker195assert(Op.isExpr() && "Expected an expression");196Op.getExpr()->print(OS, &MAI);197}198}199200void LanaiInstPrinter::printLo16AndImmOperand(const MCInst *MI, unsigned OpNo,201raw_ostream &OS) {202const MCOperand &Op = MI->getOperand(OpNo);203if (Op.isImm()) {204OS << formatHex(0xffff0000 | Op.getImm());205} else {206// Symbolic operand will be lowered to immediate value by linker207assert(Op.isExpr() && "Expected an expression");208Op.getExpr()->print(OS, &MAI);209}210}211212static void printMemoryBaseRegister(raw_ostream &OS, const unsigned AluCode,213const MCOperand &RegOp) {214assert(RegOp.isReg() && "Register operand expected");215OS << "[";216if (LPAC::isPreOp(AluCode))217OS << "*";218OS << "%" << LanaiInstPrinter::getRegisterName(RegOp.getReg());219if (LPAC::isPostOp(AluCode))220OS << "*";221OS << "]";222}223224template <unsigned SizeInBits>225static void printMemoryImmediateOffset(const MCAsmInfo &MAI,226const MCOperand &OffsetOp,227raw_ostream &OS) {228assert((OffsetOp.isImm() || OffsetOp.isExpr()) && "Immediate expected");229if (OffsetOp.isImm()) {230assert(isInt<SizeInBits>(OffsetOp.getImm()) && "Constant value truncated");231OS << OffsetOp.getImm();232} else233OffsetOp.getExpr()->print(OS, &MAI);234}235236void LanaiInstPrinter::printMemRiOperand(const MCInst *MI, int OpNo,237raw_ostream &OS,238const char * /*Modifier*/) {239const MCOperand &RegOp = MI->getOperand(OpNo);240const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);241const MCOperand &AluOp = MI->getOperand(OpNo + 2);242const unsigned AluCode = AluOp.getImm();243244// Offset245printMemoryImmediateOffset<16>(MAI, OffsetOp, OS);246247// Register248printMemoryBaseRegister(OS, AluCode, RegOp);249}250251void LanaiInstPrinter::printMemRrOperand(const MCInst *MI, int OpNo,252raw_ostream &OS,253const char * /*Modifier*/) {254const MCOperand &RegOp = MI->getOperand(OpNo);255const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);256const MCOperand &AluOp = MI->getOperand(OpNo + 2);257const unsigned AluCode = AluOp.getImm();258assert(OffsetOp.isReg() && RegOp.isReg() && "Registers expected.");259260// [ Base OP Offset ]261OS << "[";262if (LPAC::isPreOp(AluCode))263OS << "*";264OS << "%" << getRegisterName(RegOp.getReg());265if (LPAC::isPostOp(AluCode))266OS << "*";267OS << " " << LPAC::lanaiAluCodeToString(AluCode) << " ";268OS << "%" << getRegisterName(OffsetOp.getReg());269OS << "]";270}271272void LanaiInstPrinter::printMemSplsOperand(const MCInst *MI, int OpNo,273raw_ostream &OS,274const char * /*Modifier*/) {275const MCOperand &RegOp = MI->getOperand(OpNo);276const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);277const MCOperand &AluOp = MI->getOperand(OpNo + 2);278const unsigned AluCode = AluOp.getImm();279280// Offset281printMemoryImmediateOffset<10>(MAI, OffsetOp, OS);282283// Register284printMemoryBaseRegister(OS, AluCode, RegOp);285}286287void LanaiInstPrinter::printCCOperand(const MCInst *MI, int OpNo,288raw_ostream &OS) {289LPCC::CondCode CC =290static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());291// Handle the undefined value here for printing so we don't abort().292if (CC >= LPCC::UNKNOWN)293OS << "<und>";294else295OS << lanaiCondCodeToString(CC);296}297298void LanaiInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,299raw_ostream &OS) {300LPCC::CondCode CC =301static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());302// Handle the undefined value here for printing so we don't abort().303if (CC >= LPCC::UNKNOWN)304OS << "<und>";305else if (CC != LPCC::ICC_T)306OS << "." << lanaiCondCodeToString(CC);307}308309310