109467b48Spatrick //===-- NVPTXInstPrinter.cpp - PTX assembly instruction printing ----------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // Print MCInst instructions to .ptx format.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick
1309467b48Spatrick #include "MCTargetDesc/NVPTXInstPrinter.h"
1409467b48Spatrick #include "MCTargetDesc/NVPTXBaseInfo.h"
1509467b48Spatrick #include "NVPTX.h"
1609467b48Spatrick #include "llvm/MC/MCExpr.h"
1709467b48Spatrick #include "llvm/MC/MCInst.h"
1809467b48Spatrick #include "llvm/MC/MCInstrInfo.h"
1909467b48Spatrick #include "llvm/MC/MCSubtargetInfo.h"
2009467b48Spatrick #include "llvm/MC/MCSymbol.h"
2109467b48Spatrick #include "llvm/Support/ErrorHandling.h"
2209467b48Spatrick #include "llvm/Support/FormattedStream.h"
2309467b48Spatrick #include <cctype>
2409467b48Spatrick using namespace llvm;
2509467b48Spatrick
2609467b48Spatrick #define DEBUG_TYPE "asm-printer"
2709467b48Spatrick
2809467b48Spatrick #include "NVPTXGenAsmWriter.inc"
2909467b48Spatrick
NVPTXInstPrinter(const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI)3009467b48Spatrick NVPTXInstPrinter::NVPTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
3109467b48Spatrick const MCRegisterInfo &MRI)
3209467b48Spatrick : MCInstPrinter(MAI, MII, MRI) {}
3309467b48Spatrick
printRegName(raw_ostream & OS,MCRegister Reg) const34*d415bd75Srobert void NVPTXInstPrinter::printRegName(raw_ostream &OS, MCRegister Reg) const {
3509467b48Spatrick // Decode the virtual register
3609467b48Spatrick // Must be kept in sync with NVPTXAsmPrinter::encodeVirtualRegister
37*d415bd75Srobert unsigned RCId = (Reg.id() >> 28);
3809467b48Spatrick switch (RCId) {
3909467b48Spatrick default: report_fatal_error("Bad virtual register encoding");
4009467b48Spatrick case 0:
4109467b48Spatrick // This is actually a physical register, so defer to the autogenerated
4209467b48Spatrick // register printer
43*d415bd75Srobert OS << getRegisterName(Reg);
4409467b48Spatrick return;
4509467b48Spatrick case 1:
4609467b48Spatrick OS << "%p";
4709467b48Spatrick break;
4809467b48Spatrick case 2:
4909467b48Spatrick OS << "%rs";
5009467b48Spatrick break;
5109467b48Spatrick case 3:
5209467b48Spatrick OS << "%r";
5309467b48Spatrick break;
5409467b48Spatrick case 4:
5509467b48Spatrick OS << "%rd";
5609467b48Spatrick break;
5709467b48Spatrick case 5:
5809467b48Spatrick OS << "%f";
5909467b48Spatrick break;
6009467b48Spatrick case 6:
6109467b48Spatrick OS << "%fd";
6209467b48Spatrick break;
6309467b48Spatrick case 7:
6409467b48Spatrick OS << "%h";
6509467b48Spatrick break;
6609467b48Spatrick case 8:
6709467b48Spatrick OS << "%hh";
6809467b48Spatrick break;
6909467b48Spatrick }
7009467b48Spatrick
71*d415bd75Srobert unsigned VReg = Reg.id() & 0x0FFFFFFF;
7209467b48Spatrick OS << VReg;
7309467b48Spatrick }
7409467b48Spatrick
printInst(const MCInst * MI,uint64_t Address,StringRef Annot,const MCSubtargetInfo & STI,raw_ostream & OS)7509467b48Spatrick void NVPTXInstPrinter::printInst(const MCInst *MI, uint64_t Address,
7609467b48Spatrick StringRef Annot, const MCSubtargetInfo &STI,
7709467b48Spatrick raw_ostream &OS) {
7809467b48Spatrick printInstruction(MI, Address, OS);
7909467b48Spatrick
8009467b48Spatrick // Next always print the annotation.
8109467b48Spatrick printAnnotation(OS, Annot);
8209467b48Spatrick }
8309467b48Spatrick
printOperand(const MCInst * MI,unsigned OpNo,raw_ostream & O)8409467b48Spatrick void NVPTXInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
8509467b48Spatrick raw_ostream &O) {
8609467b48Spatrick const MCOperand &Op = MI->getOperand(OpNo);
8709467b48Spatrick if (Op.isReg()) {
8809467b48Spatrick unsigned Reg = Op.getReg();
8909467b48Spatrick printRegName(O, Reg);
9009467b48Spatrick } else if (Op.isImm()) {
9109467b48Spatrick O << markup("<imm:") << formatImm(Op.getImm()) << markup(">");
9209467b48Spatrick } else {
9309467b48Spatrick assert(Op.isExpr() && "Unknown operand kind in printOperand");
9409467b48Spatrick Op.getExpr()->print(O, &MAI);
9509467b48Spatrick }
9609467b48Spatrick }
9709467b48Spatrick
printCvtMode(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)9809467b48Spatrick void NVPTXInstPrinter::printCvtMode(const MCInst *MI, int OpNum, raw_ostream &O,
9909467b48Spatrick const char *Modifier) {
10009467b48Spatrick const MCOperand &MO = MI->getOperand(OpNum);
10109467b48Spatrick int64_t Imm = MO.getImm();
10209467b48Spatrick
10309467b48Spatrick if (strcmp(Modifier, "ftz") == 0) {
10409467b48Spatrick // FTZ flag
10509467b48Spatrick if (Imm & NVPTX::PTXCvtMode::FTZ_FLAG)
10609467b48Spatrick O << ".ftz";
10709467b48Spatrick } else if (strcmp(Modifier, "sat") == 0) {
10809467b48Spatrick // SAT flag
10909467b48Spatrick if (Imm & NVPTX::PTXCvtMode::SAT_FLAG)
11009467b48Spatrick O << ".sat";
111*d415bd75Srobert } else if (strcmp(Modifier, "relu") == 0) {
112*d415bd75Srobert // RELU flag
113*d415bd75Srobert if (Imm & NVPTX::PTXCvtMode::RELU_FLAG)
114*d415bd75Srobert O << ".relu";
11509467b48Spatrick } else if (strcmp(Modifier, "base") == 0) {
11609467b48Spatrick // Default operand
11709467b48Spatrick switch (Imm & NVPTX::PTXCvtMode::BASE_MASK) {
11809467b48Spatrick default:
11909467b48Spatrick return;
12009467b48Spatrick case NVPTX::PTXCvtMode::NONE:
12109467b48Spatrick break;
12209467b48Spatrick case NVPTX::PTXCvtMode::RNI:
12309467b48Spatrick O << ".rni";
12409467b48Spatrick break;
12509467b48Spatrick case NVPTX::PTXCvtMode::RZI:
12609467b48Spatrick O << ".rzi";
12709467b48Spatrick break;
12809467b48Spatrick case NVPTX::PTXCvtMode::RMI:
12909467b48Spatrick O << ".rmi";
13009467b48Spatrick break;
13109467b48Spatrick case NVPTX::PTXCvtMode::RPI:
13209467b48Spatrick O << ".rpi";
13309467b48Spatrick break;
13409467b48Spatrick case NVPTX::PTXCvtMode::RN:
13509467b48Spatrick O << ".rn";
13609467b48Spatrick break;
13709467b48Spatrick case NVPTX::PTXCvtMode::RZ:
13809467b48Spatrick O << ".rz";
13909467b48Spatrick break;
14009467b48Spatrick case NVPTX::PTXCvtMode::RM:
14109467b48Spatrick O << ".rm";
14209467b48Spatrick break;
14309467b48Spatrick case NVPTX::PTXCvtMode::RP:
14409467b48Spatrick O << ".rp";
14509467b48Spatrick break;
146*d415bd75Srobert case NVPTX::PTXCvtMode::RNA:
147*d415bd75Srobert O << ".rna";
148*d415bd75Srobert break;
14909467b48Spatrick }
15009467b48Spatrick } else {
15109467b48Spatrick llvm_unreachable("Invalid conversion modifier");
15209467b48Spatrick }
15309467b48Spatrick }
15409467b48Spatrick
printCmpMode(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)15509467b48Spatrick void NVPTXInstPrinter::printCmpMode(const MCInst *MI, int OpNum, raw_ostream &O,
15609467b48Spatrick const char *Modifier) {
15709467b48Spatrick const MCOperand &MO = MI->getOperand(OpNum);
15809467b48Spatrick int64_t Imm = MO.getImm();
15909467b48Spatrick
16009467b48Spatrick if (strcmp(Modifier, "ftz") == 0) {
16109467b48Spatrick // FTZ flag
16209467b48Spatrick if (Imm & NVPTX::PTXCmpMode::FTZ_FLAG)
16309467b48Spatrick O << ".ftz";
16409467b48Spatrick } else if (strcmp(Modifier, "base") == 0) {
16509467b48Spatrick switch (Imm & NVPTX::PTXCmpMode::BASE_MASK) {
16609467b48Spatrick default:
16709467b48Spatrick return;
16809467b48Spatrick case NVPTX::PTXCmpMode::EQ:
16909467b48Spatrick O << ".eq";
17009467b48Spatrick break;
17109467b48Spatrick case NVPTX::PTXCmpMode::NE:
17209467b48Spatrick O << ".ne";
17309467b48Spatrick break;
17409467b48Spatrick case NVPTX::PTXCmpMode::LT:
17509467b48Spatrick O << ".lt";
17609467b48Spatrick break;
17709467b48Spatrick case NVPTX::PTXCmpMode::LE:
17809467b48Spatrick O << ".le";
17909467b48Spatrick break;
18009467b48Spatrick case NVPTX::PTXCmpMode::GT:
18109467b48Spatrick O << ".gt";
18209467b48Spatrick break;
18309467b48Spatrick case NVPTX::PTXCmpMode::GE:
18409467b48Spatrick O << ".ge";
18509467b48Spatrick break;
18609467b48Spatrick case NVPTX::PTXCmpMode::LO:
18709467b48Spatrick O << ".lo";
18809467b48Spatrick break;
18909467b48Spatrick case NVPTX::PTXCmpMode::LS:
19009467b48Spatrick O << ".ls";
19109467b48Spatrick break;
19209467b48Spatrick case NVPTX::PTXCmpMode::HI:
19309467b48Spatrick O << ".hi";
19409467b48Spatrick break;
19509467b48Spatrick case NVPTX::PTXCmpMode::HS:
19609467b48Spatrick O << ".hs";
19709467b48Spatrick break;
19809467b48Spatrick case NVPTX::PTXCmpMode::EQU:
19909467b48Spatrick O << ".equ";
20009467b48Spatrick break;
20109467b48Spatrick case NVPTX::PTXCmpMode::NEU:
20209467b48Spatrick O << ".neu";
20309467b48Spatrick break;
20409467b48Spatrick case NVPTX::PTXCmpMode::LTU:
20509467b48Spatrick O << ".ltu";
20609467b48Spatrick break;
20709467b48Spatrick case NVPTX::PTXCmpMode::LEU:
20809467b48Spatrick O << ".leu";
20909467b48Spatrick break;
21009467b48Spatrick case NVPTX::PTXCmpMode::GTU:
21109467b48Spatrick O << ".gtu";
21209467b48Spatrick break;
21309467b48Spatrick case NVPTX::PTXCmpMode::GEU:
21409467b48Spatrick O << ".geu";
21509467b48Spatrick break;
21609467b48Spatrick case NVPTX::PTXCmpMode::NUM:
21709467b48Spatrick O << ".num";
21809467b48Spatrick break;
21909467b48Spatrick case NVPTX::PTXCmpMode::NotANumber:
22009467b48Spatrick O << ".nan";
22109467b48Spatrick break;
22209467b48Spatrick }
22309467b48Spatrick } else {
22409467b48Spatrick llvm_unreachable("Empty Modifier");
22509467b48Spatrick }
22609467b48Spatrick }
22709467b48Spatrick
printLdStCode(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)22809467b48Spatrick void NVPTXInstPrinter::printLdStCode(const MCInst *MI, int OpNum,
22909467b48Spatrick raw_ostream &O, const char *Modifier) {
23009467b48Spatrick if (Modifier) {
23109467b48Spatrick const MCOperand &MO = MI->getOperand(OpNum);
23209467b48Spatrick int Imm = (int) MO.getImm();
23309467b48Spatrick if (!strcmp(Modifier, "volatile")) {
23409467b48Spatrick if (Imm)
23509467b48Spatrick O << ".volatile";
23609467b48Spatrick } else if (!strcmp(Modifier, "addsp")) {
23709467b48Spatrick switch (Imm) {
23809467b48Spatrick case NVPTX::PTXLdStInstCode::GLOBAL:
23909467b48Spatrick O << ".global";
24009467b48Spatrick break;
24109467b48Spatrick case NVPTX::PTXLdStInstCode::SHARED:
24209467b48Spatrick O << ".shared";
24309467b48Spatrick break;
24409467b48Spatrick case NVPTX::PTXLdStInstCode::LOCAL:
24509467b48Spatrick O << ".local";
24609467b48Spatrick break;
24709467b48Spatrick case NVPTX::PTXLdStInstCode::PARAM:
24809467b48Spatrick O << ".param";
24909467b48Spatrick break;
25009467b48Spatrick case NVPTX::PTXLdStInstCode::CONSTANT:
25109467b48Spatrick O << ".const";
25209467b48Spatrick break;
25309467b48Spatrick case NVPTX::PTXLdStInstCode::GENERIC:
25409467b48Spatrick break;
25509467b48Spatrick default:
25609467b48Spatrick llvm_unreachable("Wrong Address Space");
25709467b48Spatrick }
25809467b48Spatrick } else if (!strcmp(Modifier, "sign")) {
25909467b48Spatrick if (Imm == NVPTX::PTXLdStInstCode::Signed)
26009467b48Spatrick O << "s";
26109467b48Spatrick else if (Imm == NVPTX::PTXLdStInstCode::Unsigned)
26209467b48Spatrick O << "u";
26309467b48Spatrick else if (Imm == NVPTX::PTXLdStInstCode::Untyped)
26409467b48Spatrick O << "b";
26509467b48Spatrick else if (Imm == NVPTX::PTXLdStInstCode::Float)
26609467b48Spatrick O << "f";
26709467b48Spatrick else
26809467b48Spatrick llvm_unreachable("Unknown register type");
26909467b48Spatrick } else if (!strcmp(Modifier, "vec")) {
27009467b48Spatrick if (Imm == NVPTX::PTXLdStInstCode::V2)
27109467b48Spatrick O << ".v2";
27209467b48Spatrick else if (Imm == NVPTX::PTXLdStInstCode::V4)
27309467b48Spatrick O << ".v4";
27409467b48Spatrick } else
27509467b48Spatrick llvm_unreachable("Unknown Modifier");
27609467b48Spatrick } else
27709467b48Spatrick llvm_unreachable("Empty Modifier");
27809467b48Spatrick }
27909467b48Spatrick
printMmaCode(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)28009467b48Spatrick void NVPTXInstPrinter::printMmaCode(const MCInst *MI, int OpNum, raw_ostream &O,
28109467b48Spatrick const char *Modifier) {
28209467b48Spatrick const MCOperand &MO = MI->getOperand(OpNum);
28309467b48Spatrick int Imm = (int)MO.getImm();
28409467b48Spatrick if (Modifier == nullptr || strcmp(Modifier, "version") == 0) {
28509467b48Spatrick O << Imm; // Just print out PTX version
28609467b48Spatrick } else if (strcmp(Modifier, "aligned") == 0) {
28709467b48Spatrick // PTX63 requires '.aligned' in the name of the instruction.
28809467b48Spatrick if (Imm >= 63)
28909467b48Spatrick O << ".aligned";
29009467b48Spatrick } else
29109467b48Spatrick llvm_unreachable("Unknown Modifier");
29209467b48Spatrick }
29309467b48Spatrick
printMemOperand(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)29409467b48Spatrick void NVPTXInstPrinter::printMemOperand(const MCInst *MI, int OpNum,
29509467b48Spatrick raw_ostream &O, const char *Modifier) {
29609467b48Spatrick printOperand(MI, OpNum, O);
29709467b48Spatrick
29809467b48Spatrick if (Modifier && !strcmp(Modifier, "add")) {
29909467b48Spatrick O << ", ";
30009467b48Spatrick printOperand(MI, OpNum + 1, O);
30109467b48Spatrick } else {
30209467b48Spatrick if (MI->getOperand(OpNum + 1).isImm() &&
30309467b48Spatrick MI->getOperand(OpNum + 1).getImm() == 0)
30409467b48Spatrick return; // don't print ',0' or '+0'
30509467b48Spatrick O << "+";
30609467b48Spatrick printOperand(MI, OpNum + 1, O);
30709467b48Spatrick }
30809467b48Spatrick }
30909467b48Spatrick
printProtoIdent(const MCInst * MI,int OpNum,raw_ostream & O,const char * Modifier)31009467b48Spatrick void NVPTXInstPrinter::printProtoIdent(const MCInst *MI, int OpNum,
31109467b48Spatrick raw_ostream &O, const char *Modifier) {
31209467b48Spatrick const MCOperand &Op = MI->getOperand(OpNum);
31309467b48Spatrick assert(Op.isExpr() && "Call prototype is not an MCExpr?");
31409467b48Spatrick const MCExpr *Expr = Op.getExpr();
31509467b48Spatrick const MCSymbol &Sym = cast<MCSymbolRefExpr>(Expr)->getSymbol();
31609467b48Spatrick O << Sym.getName();
31709467b48Spatrick }
318