Path: blob/main/contrib/llvm-project/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.cpp
35295 views
//===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===//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// Print MCInst instructions to .ptx format.9//10//===----------------------------------------------------------------------===//1112#include "MCTargetDesc/NVPTXInstPrinter.h"13#include "MCTargetDesc/NVPTXBaseInfo.h"14#include "NVPTX.h"15#include "llvm/MC/MCExpr.h"16#include "llvm/MC/MCInst.h"17#include "llvm/MC/MCInstrInfo.h"18#include "llvm/MC/MCSubtargetInfo.h"19#include "llvm/MC/MCSymbol.h"20#include "llvm/Support/ErrorHandling.h"21#include "llvm/Support/FormattedStream.h"22#include <cctype>23using namespace llvm;2425#define DEBUG_TYPE "asm-printer"2627#include "NVPTXGenAsmWriter.inc"2829NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,30const MCRegisterInfo &MRI)31: MCInstPrinter(MAI, MII, MRI) {}3233void NVPTXInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {34// Decode the virtual register35// Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister36unsigned RCId = (Reg.id() >> 28);37switch (RCId) {38default: report_fatal_error("Bad virtual register encoding");39case 0:40// This is actually a physical register, so defer to the autogenerated41// register printer42OS << getRegisterName(Reg);43return;44case 1:45OS << "%p";46break;47case 2:48OS << "%rs";49break;50case 3:51OS << "%r";52break;53case 4:54OS << "%rd";55break;56case 5:57OS << "%f";58break;59case 6:60OS << "%fd";61break;62case 7:63OS << "%rq";64break;65}6667unsigned VReg = Reg.id() & 0x0FFFFFFF;68OS << VReg;69}7071void NVPTXInstPrinter::printInst(const MCInst *MI, uint64_t Address,72StringRef Annot, const MCSubtargetInfo &STI,73raw_ostream &OS) {74printInstruction(MI, Address, OS);7576// Next always print the annotation.77printAnnotation(OS, Annot);78}7980void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,81raw_ostream &O) {82const MCOperand &Op = MI->getOperand(OpNo);83if (Op.isReg()) {84unsigned Reg = Op.getReg();85printRegName(O, Reg);86} else if (Op.isImm()) {87markup(O, Markup::Immediate) << formatImm(Op.getImm());88} else {89assert(Op.isExpr() && "Unknown operand kind in printOperand");90Op.getExpr()->print(O, &MAI);91}92}9394void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O,95const char *Modifier) {96const MCOperand &MO = MI->getOperand(OpNum);97int64_t Imm = MO.getImm();9899if (strcmp(Modifier, "ftz") == 0) {100// FTZ flag101if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)102O << ".ftz";103} else if (strcmp(Modifier, "sat") == 0) {104// SAT flag105if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)106O << ".sat";107} else if (strcmp(Modifier, "relu") == 0) {108// RELU flag109if (Imm & NVPTX::PTXCvtMode::RELU_FLAG)110O << ".relu";111} else if (strcmp(Modifier, "base") == 0) {112// Default operand113switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {114default:115return;116case NVPTX::PTXCvtMode::NONE:117break;118case NVPTX::PTXCvtMode::RNI:119O << ".rni";120break;121case NVPTX::PTXCvtMode::RZI:122O << ".rzi";123break;124case NVPTX::PTXCvtMode::RMI:125O << ".rmi";126break;127case NVPTX::PTXCvtMode::RPI:128O << ".rpi";129break;130case NVPTX::PTXCvtMode::RN:131O << ".rn";132break;133case NVPTX::PTXCvtMode::RZ:134O << ".rz";135break;136case NVPTX::PTXCvtMode::RM:137O << ".rm";138break;139case NVPTX::PTXCvtMode::RP:140O << ".rp";141break;142case NVPTX::PTXCvtMode::RNA:143O << ".rna";144break;145}146} else {147llvm_unreachable("Invalid conversion modifier");148}149}150151void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O,152const char *Modifier) {153const MCOperand &MO = MI->getOperand(OpNum);154int64_t Imm = MO.getImm();155156if (strcmp(Modifier, "ftz") == 0) {157// FTZ flag158if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)159O << ".ftz";160} else if (strcmp(Modifier, "base") == 0) {161switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {162default:163return;164case NVPTX::PTXCmpMode::EQ:165O << ".eq";166break;167case NVPTX::PTXCmpMode::NE:168O << ".ne";169break;170case NVPTX::PTXCmpMode::LT:171O << ".lt";172break;173case NVPTX::PTXCmpMode::LE:174O << ".le";175break;176case NVPTX::PTXCmpMode::GT:177O << ".gt";178break;179case NVPTX::PTXCmpMode::GE:180O << ".ge";181break;182case NVPTX::PTXCmpMode::LO:183O << ".lo";184break;185case NVPTX::PTXCmpMode::LS:186O << ".ls";187break;188case NVPTX::PTXCmpMode::HI:189O << ".hi";190break;191case NVPTX::PTXCmpMode::HS:192O << ".hs";193break;194case NVPTX::PTXCmpMode::EQU:195O << ".equ";196break;197case NVPTX::PTXCmpMode::NEU:198O << ".neu";199break;200case NVPTX::PTXCmpMode::LTU:201O << ".ltu";202break;203case NVPTX::PTXCmpMode::LEU:204O << ".leu";205break;206case NVPTX::PTXCmpMode::GTU:207O << ".gtu";208break;209case NVPTX::PTXCmpMode::GEU:210O << ".geu";211break;212case NVPTX::PTXCmpMode::NUM:213O << ".num";214break;215case NVPTX::PTXCmpMode::NotANumber:216O << ".nan";217break;218}219} else {220llvm_unreachable("Empty Modifier");221}222}223224void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum,225raw_ostream &O, const char *Modifier) {226if (Modifier) {227const MCOperand &MO = MI->getOperand(OpNum);228int Imm = (int) MO.getImm();229if (!strcmp(Modifier, "volatile")) {230if (Imm)231O << ".volatile";232} else if (!strcmp(Modifier, "addsp")) {233switch (Imm) {234case NVPTX::PTXLdStInstCode::GLOBAL:235O << ".global";236break;237case NVPTX::PTXLdStInstCode::SHARED:238O << ".shared";239break;240case NVPTX::PTXLdStInstCode::LOCAL:241O << ".local";242break;243case NVPTX::PTXLdStInstCode::PARAM:244O << ".param";245break;246case NVPTX::PTXLdStInstCode::CONSTANT:247O << ".const";248break;249case NVPTX::PTXLdStInstCode::GENERIC:250break;251default:252llvm_unreachable("Wrong Address Space");253}254} else if (!strcmp(Modifier, "sign")) {255if (Imm == NVPTX::PTXLdStInstCode::Signed)256O << "s";257else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)258O << "u";259else if (Imm == NVPTX::PTXLdStInstCode::Untyped)260O << "b";261else if (Imm == NVPTX::PTXLdStInstCode::Float)262O << "f";263else264llvm_unreachable("Unknown register type");265} else if (!strcmp(Modifier, "vec")) {266if (Imm == NVPTX::PTXLdStInstCode::V2)267O << ".v2";268else if (Imm == NVPTX::PTXLdStInstCode::V4)269O << ".v4";270} else271llvm_unreachable("Unknown Modifier");272} else273llvm_unreachable("Empty Modifier");274}275276void NVPTXInstPrinter::printMmaCode(const MCInst *MI, int OpNum, raw_ostream &O,277const char *Modifier) {278const MCOperand &MO = MI->getOperand(OpNum);279int Imm = (int)MO.getImm();280if (Modifier == nullptr || strcmp(Modifier, "version") == 0) {281O << Imm; // Just print out PTX version282} else if (strcmp(Modifier, "aligned") == 0) {283// PTX63 requires '.aligned' in the name of the instruction.284if (Imm >= 63)285O << ".aligned";286} else287llvm_unreachable("Unknown Modifier");288}289290void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,291raw_ostream &O, const char *Modifier) {292printOperand(MI, OpNum, O);293294if (Modifier && !strcmp(Modifier, "add")) {295O << ", ";296printOperand(MI, OpNum + 1, O);297} else {298if (MI->getOperand(OpNum + 1).isImm() &&299MI->getOperand(OpNum + 1).getImm() == 0)300return; // don't print ',0' or '+0'301O << "+";302printOperand(MI, OpNum + 1, O);303}304}305306void NVPTXInstPrinter::printProtoIdent(const MCInst *MI, int OpNum,307raw_ostream &O, const char *Modifier) {308const MCOperand &Op = MI->getOperand(OpNum);309assert(Op.isExpr() && "Call prototype is not an MCExpr?");310const MCExpr *Expr = Op.getExpr();311const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();312O << Sym.getName();313}314315void NVPTXInstPrinter::printPrmtMode(const MCInst *MI, int OpNum,316raw_ostream &O, const char *Modifier) {317const MCOperand &MO = MI->getOperand(OpNum);318int64_t Imm = MO.getImm();319320switch (Imm) {321default:322return;323case NVPTX::PTXPrmtMode::NONE:324break;325case NVPTX::PTXPrmtMode::F4E:326O << ".f4e";327break;328case NVPTX::PTXPrmtMode::B4E:329O << ".b4e";330break;331case NVPTX::PTXPrmtMode::RC8:332O << ".rc8";333break;334case NVPTX::PTXPrmtMode::ECL:335O << ".ecl";336break;337case NVPTX::PTXPrmtMode::ECR:338O << ".ecr";339break;340case NVPTX::PTXPrmtMode::RC16:341O << ".rc16";342break;343}344}345346347