1 //===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 // \file 9 //===----------------------------------------------------------------------===// 10 11 #include "AMDGPUInstPrinter.h" 12 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 13 #include "llvm/MC/MCExpr.h" 14 #include "llvm/MC/MCInst.h" 15 16 using namespace llvm; 17 18 void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 19 StringRef Annot) { 20 OS.flush(); 21 printInstruction(MI, OS); 22 23 printAnnotation(OS, Annot); 24 } 25 26 void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 27 raw_ostream &O) { 28 29 const MCOperand &Op = MI->getOperand(OpNo); 30 if (Op.isReg()) { 31 switch (Op.getReg()) { 32 // This is the default predicate state, so we don't need to print it. 33 case AMDGPU::PRED_SEL_OFF: break; 34 default: O << getRegisterName(Op.getReg()); break; 35 } 36 } else if (Op.isImm()) { 37 O << Op.getImm(); 38 } else if (Op.isFPImm()) { 39 O << Op.getFPImm(); 40 } else if (Op.isExpr()) { 41 const MCExpr *Exp = Op.getExpr(); 42 Exp->print(O); 43 } else { 44 assert(!"unknown operand type in printOperand"); 45 } 46 } 47 48 void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum, 49 raw_ostream &O) { 50 unsigned Imm = MI->getOperand(OpNum).getImm(); 51 52 if (Imm == 2) { 53 O << "P0"; 54 } else if (Imm == 1) { 55 O << "P20"; 56 } else if (Imm == 0) { 57 O << "P10"; 58 } else { 59 assert(!"Invalid interpolation parameter slot"); 60 } 61 } 62 63 void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 64 raw_ostream &O) { 65 printOperand(MI, OpNo, O); 66 O << ", "; 67 printOperand(MI, OpNo + 1, O); 68 } 69 70 void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 71 raw_ostream &O, StringRef Asm, 72 StringRef Default) { 73 const MCOperand &Op = MI->getOperand(OpNo); 74 assert(Op.isImm()); 75 if (Op.getImm() == 1) { 76 O << Asm; 77 } else { 78 O << Default; 79 } 80 } 81 82 void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo, 83 raw_ostream &O) { 84 printIfSet(MI, OpNo, O, "|"); 85 } 86 87 void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo, 88 raw_ostream &O) { 89 printIfSet(MI, OpNo, O, "_SAT"); 90 } 91 92 void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, 93 raw_ostream &O) { 94 union Literal { 95 float f; 96 int32_t i; 97 } L; 98 99 L.i = MI->getOperand(OpNo).getImm(); 100 O << L.i << "(" << L.f << ")"; 101 } 102 103 void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo, 104 raw_ostream &O) { 105 printIfSet(MI, OpNo, O.indent(25 - O.GetNumBytesInBuffer()), "*", " "); 106 } 107 108 void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo, 109 raw_ostream &O) { 110 printIfSet(MI, OpNo, O, "-"); 111 } 112 113 void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo, 114 raw_ostream &O) { 115 switch (MI->getOperand(OpNo).getImm()) { 116 default: 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 129 void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo, 130 raw_ostream &O) { 131 printIfSet(MI, OpNo, O, "+"); 132 } 133 134 void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo, 135 raw_ostream &O) { 136 printIfSet(MI, OpNo, O, "ExecMask,"); 137 } 138 139 void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo, 140 raw_ostream &O) { 141 printIfSet(MI, OpNo, O, "Pred,"); 142 } 143 144 void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo, 145 raw_ostream &O) { 146 const MCOperand &Op = MI->getOperand(OpNo); 147 if (Op.getImm() == 0) { 148 O << " (MASKED)"; 149 } 150 } 151 152 void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo, 153 raw_ostream &O) { 154 const char * chans = "XYZW"; 155 int sel = MI->getOperand(OpNo).getImm(); 156 157 int chan = sel & 3; 158 sel >>= 2; 159 160 if (sel >= 512) { 161 sel -= 512; 162 int cb = sel >> 12; 163 sel &= 4095; 164 O << cb << "[" << sel << "]"; 165 } else if (sel >= 448) { 166 sel -= 448; 167 O << sel; 168 } else if (sel >= 0){ 169 O << sel; 170 } 171 172 if (sel >= 0) 173 O << "." << chans[chan]; 174 } 175 176 void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, 177 raw_ostream &O) { 178 int BankSwizzle = MI->getOperand(OpNo).getImm(); 179 switch (BankSwizzle) { 180 case 1: 181 O << "BS:VEC_021/SCL_122"; 182 break; 183 case 2: 184 O << "BS:VEC_120/SCL_212"; 185 break; 186 case 3: 187 O << "BS:VEC_102/SCL_221"; 188 break; 189 case 4: 190 O << "BS:VEC_201"; 191 break; 192 case 5: 193 O << "BS:VEC_210"; 194 break; 195 default: 196 break; 197 } 198 return; 199 } 200 201 void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo, 202 raw_ostream &O) { 203 unsigned Sel = MI->getOperand(OpNo).getImm(); 204 switch (Sel) { 205 case 0: 206 O << "X"; 207 break; 208 case 1: 209 O << "Y"; 210 break; 211 case 2: 212 O << "Z"; 213 break; 214 case 3: 215 O << "W"; 216 break; 217 case 4: 218 O << "0"; 219 break; 220 case 5: 221 O << "1"; 222 break; 223 case 7: 224 O << "_"; 225 break; 226 default: 227 break; 228 } 229 } 230 231 void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo, 232 raw_ostream &O) { 233 unsigned CT = MI->getOperand(OpNo).getImm(); 234 switch (CT) { 235 case 0: 236 O << "U"; 237 break; 238 case 1: 239 O << "N"; 240 break; 241 default: 242 break; 243 } 244 } 245 246 void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo, 247 raw_ostream &O) { 248 int KCacheMode = MI->getOperand(OpNo).getImm(); 249 if (KCacheMode > 0) { 250 int KCacheBank = MI->getOperand(OpNo - 2).getImm(); 251 O << "CB" << KCacheBank <<":"; 252 int KCacheAddr = MI->getOperand(OpNo + 2).getImm(); 253 int LineSize = (KCacheMode == 1)?16:32; 254 O << KCacheAddr * 16 << "-" << KCacheAddr * 16 + LineSize; 255 } 256 } 257 258 #include "AMDGPUGenAsmWriter.inc" 259