225 lines · cpp
1//===-- R600InstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===//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// \file8//===----------------------------------------------------------------------===//9 10#include "R600InstPrinter.h"11#include "AMDGPUInstPrinter.h"12#include "R600MCTargetDesc.h"13#include "llvm/MC/MCAsmInfo.h"14#include "llvm/MC/MCExpr.h"15#include "llvm/MC/MCInst.h"16#include "llvm/MC/MCInstrInfo.h"17#include "llvm/MC/MCSubtargetInfo.h"18 19using namespace llvm;20 21void R600InstPrinter::printInst(const MCInst *MI, uint64_t Address,22 StringRef Annot, const MCSubtargetInfo &STI,23 raw_ostream &O) {24 printInstruction(MI, Address, O);25 printAnnotation(O, Annot);26}27 28void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo,29 raw_ostream &O) {30 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|');31}32 33void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,34 raw_ostream &O) {35 int BankSwizzle = MI->getOperand(OpNo).getImm();36 switch (BankSwizzle) {37 case 1:38 O << "BS:VEC_021/SCL_122";39 break;40 case 2:41 O << "BS:VEC_120/SCL_212";42 break;43 case 3:44 O << "BS:VEC_102/SCL_221";45 break;46 case 4:47 O << "BS:VEC_201";48 break;49 case 5:50 O << "BS:VEC_210";51 break;52 default:53 break;54 }55}56 57void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo,58 raw_ostream &O) {59 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT");60}61 62void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo, raw_ostream &O) {63 unsigned CT = MI->getOperand(OpNo).getImm();64 switch (CT) {65 case 0:66 O << 'U';67 break;68 case 1:69 O << 'N';70 break;71 default:72 break;73 }74}75 76void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo,77 raw_ostream &O) {78 int KCacheMode = MI->getOperand(OpNo).getImm();79 if (KCacheMode > 0) {80 int KCacheBank = MI->getOperand(OpNo - 2).getImm();81 O << "CB" << KCacheBank << ':';82 int KCacheAddr = MI->getOperand(OpNo + 2).getImm();83 int LineSize = (KCacheMode == 1) ? 16 : 32;84 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;85 }86}87 88void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo,89 raw_ostream &O) {90 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " ");91}92 93void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,94 raw_ostream &O) {95 const MCOperand &Op = MI->getOperand(OpNo);96 assert(Op.isImm() || Op.isExpr());97 if (Op.isImm()) {98 int64_t Imm = Op.getImm();99 O << Imm << '(' << llvm::bit_cast<float>(static_cast<uint32_t>(Imm)) << ')';100 }101 if (Op.isExpr()) {102 O << '@';103 MAI.printExpr(O, *Op.getExpr());104 }105}106 107void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo,108 raw_ostream &O) {109 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-');110}111 112void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,113 raw_ostream &O) {114 switch (MI->getOperand(OpNo).getImm()) {115 default:116 break;117 case 1:118 O << " * 2.0";119 break;120 case 2:121 O << " * 4.0";122 break;123 case 3:124 O << " / 2.0";125 break;126 }127}128 129void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,130 raw_ostream &O) {131 printOperand(MI, OpNo, O);132 O << ", ";133 printOperand(MI, OpNo + 1, O);134}135 136void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo,137 raw_ostream &O) {138 if (OpNo >= MI->getNumOperands()) {139 O << "/*Missing OP" << OpNo << "*/";140 return;141 }142 143 const MCOperand &Op = MI->getOperand(OpNo);144 if (Op.isReg()) {145 switch (Op.getReg().id()) {146 // This is the default predicate state, so we don't need to print it.147 case R600::PRED_SEL_OFF:148 break;149 150 default:151 O << getRegisterName(Op.getReg());152 break;153 }154 } else if (Op.isImm()) {155 O << Op.getImm();156 } else if (Op.isDFPImm()) {157 // We special case 0.0 because otherwise it will be printed as an integer.158 if (Op.getDFPImm() == 0.0)159 O << "0.0";160 else {161 O << bit_cast<double>(Op.getDFPImm());162 }163 } else if (Op.isExpr()) {164 const MCExpr *Exp = Op.getExpr();165 MAI.printExpr(O, *Exp);166 } else {167 O << "/*INV_OP*/";168 }169}170 171void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo,172 raw_ostream &O) {173 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+');174}175 176void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo,177 raw_ostream &O) {178 unsigned Sel = MI->getOperand(OpNo).getImm();179 switch (Sel) {180 case 0:181 O << 'X';182 break;183 case 1:184 O << 'Y';185 break;186 case 2:187 O << 'Z';188 break;189 case 3:190 O << 'W';191 break;192 case 4:193 O << '0';194 break;195 case 5:196 O << '1';197 break;198 case 7:199 O << '_';200 break;201 default:202 break;203 }204}205 206void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,207 raw_ostream &O) {208 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,");209}210 211void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,212 raw_ostream &O) {213 AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,");214}215 216void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo,217 raw_ostream &O) {218 const MCOperand &Op = MI->getOperand(OpNo);219 if (Op.getImm() == 0) {220 O << " (MASKED)";221 }222}223 224#include "R600GenAsmWriter.inc"225