1349cc55cSDimitry Andric //===-- R600InstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===// 2349cc55cSDimitry Andric // 3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6349cc55cSDimitry Andric // 7349cc55cSDimitry Andric // \file 8349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 9349cc55cSDimitry Andric 10349cc55cSDimitry Andric #include "R600InstPrinter.h" 11349cc55cSDimitry Andric #include "AMDGPUInstPrinter.h" 12349cc55cSDimitry Andric #include "R600MCTargetDesc.h" 13349cc55cSDimitry Andric #include "llvm/MC/MCExpr.h" 14349cc55cSDimitry Andric #include "llvm/MC/MCInst.h" 15349cc55cSDimitry Andric #include "llvm/MC/MCInstrInfo.h" 16349cc55cSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 17349cc55cSDimitry Andric #include "llvm/Support/CommandLine.h" 18349cc55cSDimitry Andric 19349cc55cSDimitry Andric using namespace llvm; 20349cc55cSDimitry Andric 21349cc55cSDimitry Andric void R600InstPrinter::printInst(const MCInst *MI, uint64_t Address, 22349cc55cSDimitry Andric StringRef Annot, const MCSubtargetInfo &STI, 23349cc55cSDimitry Andric raw_ostream &O) { 24349cc55cSDimitry Andric printInstruction(MI, Address, O); 25349cc55cSDimitry Andric printAnnotation(O, Annot); 26349cc55cSDimitry Andric } 27349cc55cSDimitry Andric 28349cc55cSDimitry Andric void R600InstPrinter::printAbs(const MCInst *MI, unsigned OpNo, 29349cc55cSDimitry Andric raw_ostream &O) { 30349cc55cSDimitry Andric AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '|'); 31349cc55cSDimitry Andric } 32349cc55cSDimitry Andric 33349cc55cSDimitry Andric void R600InstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, 34349cc55cSDimitry Andric raw_ostream &O) { 35349cc55cSDimitry Andric int BankSwizzle = MI->getOperand(OpNo).getImm(); 36349cc55cSDimitry Andric switch (BankSwizzle) { 37349cc55cSDimitry Andric case 1: 38349cc55cSDimitry Andric O << "BS:VEC_021/SCL_122"; 39349cc55cSDimitry Andric break; 40349cc55cSDimitry Andric case 2: 41349cc55cSDimitry Andric O << "BS:VEC_120/SCL_212"; 42349cc55cSDimitry Andric break; 43349cc55cSDimitry Andric case 3: 44349cc55cSDimitry Andric O << "BS:VEC_102/SCL_221"; 45349cc55cSDimitry Andric break; 46349cc55cSDimitry Andric case 4: 47349cc55cSDimitry Andric O << "BS:VEC_201"; 48349cc55cSDimitry Andric break; 49349cc55cSDimitry Andric case 5: 50349cc55cSDimitry Andric O << "BS:VEC_210"; 51349cc55cSDimitry Andric break; 52349cc55cSDimitry Andric default: 53349cc55cSDimitry Andric break; 54349cc55cSDimitry Andric } 55349cc55cSDimitry Andric } 56349cc55cSDimitry Andric 57349cc55cSDimitry Andric void R600InstPrinter::printClamp(const MCInst *MI, unsigned OpNo, 58349cc55cSDimitry Andric raw_ostream &O) { 59349cc55cSDimitry Andric AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "_SAT"); 60349cc55cSDimitry Andric } 61349cc55cSDimitry Andric 62349cc55cSDimitry Andric void R600InstPrinter::printCT(const MCInst *MI, unsigned OpNo, raw_ostream &O) { 63349cc55cSDimitry Andric unsigned CT = MI->getOperand(OpNo).getImm(); 64349cc55cSDimitry Andric switch (CT) { 65349cc55cSDimitry Andric case 0: 66349cc55cSDimitry Andric O << 'U'; 67349cc55cSDimitry Andric break; 68349cc55cSDimitry Andric case 1: 69349cc55cSDimitry Andric O << 'N'; 70349cc55cSDimitry Andric break; 71349cc55cSDimitry Andric default: 72349cc55cSDimitry Andric break; 73349cc55cSDimitry Andric } 74349cc55cSDimitry Andric } 75349cc55cSDimitry Andric 76349cc55cSDimitry Andric void R600InstPrinter::printKCache(const MCInst *MI, unsigned OpNo, 77349cc55cSDimitry Andric raw_ostream &O) { 78349cc55cSDimitry Andric int KCacheMode = MI->getOperand(OpNo).getImm(); 79349cc55cSDimitry Andric if (KCacheMode > 0) { 80349cc55cSDimitry Andric int KCacheBank = MI->getOperand(OpNo - 2).getImm(); 81349cc55cSDimitry Andric O << "CB" << KCacheBank << ':'; 82349cc55cSDimitry Andric int KCacheAddr = MI->getOperand(OpNo + 2).getImm(); 83349cc55cSDimitry Andric int LineSize = (KCacheMode == 1) ? 16 : 32; 84349cc55cSDimitry Andric O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize; 85349cc55cSDimitry Andric } 86349cc55cSDimitry Andric } 87349cc55cSDimitry Andric 88349cc55cSDimitry Andric void R600InstPrinter::printLast(const MCInst *MI, unsigned OpNo, 89349cc55cSDimitry Andric raw_ostream &O) { 90349cc55cSDimitry Andric AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "*", " "); 91349cc55cSDimitry Andric } 92349cc55cSDimitry Andric 93349cc55cSDimitry Andric void R600InstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, 94349cc55cSDimitry Andric raw_ostream &O) { 95349cc55cSDimitry Andric const MCOperand &Op = MI->getOperand(OpNo); 96349cc55cSDimitry Andric assert(Op.isImm() || Op.isExpr()); 97349cc55cSDimitry Andric if (Op.isImm()) { 98349cc55cSDimitry Andric int64_t Imm = Op.getImm(); 99*06c3fb27SDimitry Andric O << Imm << '(' << llvm::bit_cast<float>(static_cast<uint32_t>(Imm)) << ')'; 100349cc55cSDimitry Andric } 101349cc55cSDimitry Andric if (Op.isExpr()) { 102349cc55cSDimitry Andric Op.getExpr()->print(O << '@', &MAI); 103349cc55cSDimitry Andric } 104349cc55cSDimitry Andric } 105349cc55cSDimitry Andric 106349cc55cSDimitry Andric void R600InstPrinter::printNeg(const MCInst *MI, unsigned OpNo, 107349cc55cSDimitry Andric raw_ostream &O) { 108349cc55cSDimitry Andric AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '-'); 109349cc55cSDimitry Andric } 110349cc55cSDimitry Andric 111349cc55cSDimitry Andric void R600InstPrinter::printOMOD(const MCInst *MI, unsigned OpNo, 112349cc55cSDimitry Andric raw_ostream &O) { 113349cc55cSDimitry Andric switch (MI->getOperand(OpNo).getImm()) { 114349cc55cSDimitry Andric default: 115349cc55cSDimitry Andric break; 116349cc55cSDimitry Andric case 1: 117349cc55cSDimitry Andric O << " * 2.0"; 118349cc55cSDimitry Andric break; 119349cc55cSDimitry Andric case 2: 120349cc55cSDimitry Andric O << " * 4.0"; 121349cc55cSDimitry Andric break; 122349cc55cSDimitry Andric case 3: 123349cc55cSDimitry Andric O << " / 2.0"; 124349cc55cSDimitry Andric break; 125349cc55cSDimitry Andric } 126349cc55cSDimitry Andric } 127349cc55cSDimitry Andric 128349cc55cSDimitry Andric void R600InstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 129349cc55cSDimitry Andric raw_ostream &O) { 130349cc55cSDimitry Andric printOperand(MI, OpNo, O); 131349cc55cSDimitry Andric O << ", "; 132349cc55cSDimitry Andric printOperand(MI, OpNo + 1, O); 133349cc55cSDimitry Andric } 134349cc55cSDimitry Andric 135349cc55cSDimitry Andric void R600InstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 136349cc55cSDimitry Andric raw_ostream &O) { 137349cc55cSDimitry Andric if (OpNo >= MI->getNumOperands()) { 138349cc55cSDimitry Andric O << "/*Missing OP" << OpNo << "*/"; 139349cc55cSDimitry Andric return; 140349cc55cSDimitry Andric } 141349cc55cSDimitry Andric 142349cc55cSDimitry Andric const MCOperand &Op = MI->getOperand(OpNo); 143349cc55cSDimitry Andric if (Op.isReg()) { 144349cc55cSDimitry Andric switch (Op.getReg()) { 145349cc55cSDimitry Andric // This is the default predicate state, so we don't need to print it. 146349cc55cSDimitry Andric case R600::PRED_SEL_OFF: 147349cc55cSDimitry Andric break; 148349cc55cSDimitry Andric 149349cc55cSDimitry Andric default: 150349cc55cSDimitry Andric O << getRegisterName(Op.getReg()); 151349cc55cSDimitry Andric break; 152349cc55cSDimitry Andric } 153349cc55cSDimitry Andric } else if (Op.isImm()) { 154349cc55cSDimitry Andric O << Op.getImm(); 155349cc55cSDimitry Andric } else if (Op.isDFPImm()) { 156349cc55cSDimitry Andric // We special case 0.0 because otherwise it will be printed as an integer. 157349cc55cSDimitry Andric if (Op.getDFPImm() == 0.0) 158349cc55cSDimitry Andric O << "0.0"; 159349cc55cSDimitry Andric else { 160349cc55cSDimitry Andric O << bit_cast<double>(Op.getDFPImm()); 161349cc55cSDimitry Andric } 162349cc55cSDimitry Andric } else if (Op.isExpr()) { 163349cc55cSDimitry Andric const MCExpr *Exp = Op.getExpr(); 164349cc55cSDimitry Andric Exp->print(O, &MAI); 165349cc55cSDimitry Andric } else { 166349cc55cSDimitry Andric O << "/*INV_OP*/"; 167349cc55cSDimitry Andric } 168349cc55cSDimitry Andric } 169349cc55cSDimitry Andric 170349cc55cSDimitry Andric void R600InstPrinter::printRel(const MCInst *MI, unsigned OpNo, 171349cc55cSDimitry Andric raw_ostream &O) { 172349cc55cSDimitry Andric AMDGPUInstPrinter::printIfSet(MI, OpNo, O, '+'); 173349cc55cSDimitry Andric } 174349cc55cSDimitry Andric 175349cc55cSDimitry Andric void R600InstPrinter::printRSel(const MCInst *MI, unsigned OpNo, 176349cc55cSDimitry Andric raw_ostream &O) { 177349cc55cSDimitry Andric unsigned Sel = MI->getOperand(OpNo).getImm(); 178349cc55cSDimitry Andric switch (Sel) { 179349cc55cSDimitry Andric case 0: 180349cc55cSDimitry Andric O << 'X'; 181349cc55cSDimitry Andric break; 182349cc55cSDimitry Andric case 1: 183349cc55cSDimitry Andric O << 'Y'; 184349cc55cSDimitry Andric break; 185349cc55cSDimitry Andric case 2: 186349cc55cSDimitry Andric O << 'Z'; 187349cc55cSDimitry Andric break; 188349cc55cSDimitry Andric case 3: 189349cc55cSDimitry Andric O << 'W'; 190349cc55cSDimitry Andric break; 191349cc55cSDimitry Andric case 4: 192349cc55cSDimitry Andric O << '0'; 193349cc55cSDimitry Andric break; 194349cc55cSDimitry Andric case 5: 195349cc55cSDimitry Andric O << '1'; 196349cc55cSDimitry Andric break; 197349cc55cSDimitry Andric case 7: 198349cc55cSDimitry Andric O << '_'; 199349cc55cSDimitry Andric break; 200349cc55cSDimitry Andric default: 201349cc55cSDimitry Andric break; 202349cc55cSDimitry Andric } 203349cc55cSDimitry Andric } 204349cc55cSDimitry Andric 205349cc55cSDimitry Andric void R600InstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo, 206349cc55cSDimitry Andric raw_ostream &O) { 207349cc55cSDimitry Andric AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "ExecMask,"); 208349cc55cSDimitry Andric } 209349cc55cSDimitry Andric 210349cc55cSDimitry Andric void R600InstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo, 211349cc55cSDimitry Andric raw_ostream &O) { 212349cc55cSDimitry Andric AMDGPUInstPrinter::printIfSet(MI, OpNo, O, "Pred,"); 213349cc55cSDimitry Andric } 214349cc55cSDimitry Andric 215349cc55cSDimitry Andric void R600InstPrinter::printWrite(const MCInst *MI, unsigned OpNo, 216349cc55cSDimitry Andric raw_ostream &O) { 217349cc55cSDimitry Andric const MCOperand &Op = MI->getOperand(OpNo); 218349cc55cSDimitry Andric if (Op.getImm() == 0) { 219349cc55cSDimitry Andric O << " (MASKED)"; 220349cc55cSDimitry Andric } 221349cc55cSDimitry Andric } 222349cc55cSDimitry Andric 223349cc55cSDimitry Andric #include "R600GenAsmWriter.inc" 224