AMDGPUInstPrinter.cpp revision 263508
1272343Sngie//===-- AMDGPUInstPrinter.cpp - AMDGPU MC Inst -> ASM ---------------------===// 2272343Sngie// 3272343Sngie// The LLVM Compiler Infrastructure 4272343Sngie// 5272343Sngie// This file is distributed under the University of Illinois Open Source 6272343Sngie// License. See LICENSE.TXT for details. 7272343Sngie// 8272343Sngie// \file 9272343Sngie//===----------------------------------------------------------------------===// 10272343Sngie 11272343Sngie#include "AMDGPUInstPrinter.h" 12272343Sngie#include "MCTargetDesc/AMDGPUMCTargetDesc.h" 13272343Sngie#include "llvm/MC/MCExpr.h" 14272343Sngie#include "llvm/MC/MCInst.h" 15272343Sngie 16272343Sngieusing namespace llvm; 17272343Sngie 18272343Sngievoid AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS, 19272343Sngie StringRef Annot) { 20272343Sngie OS.flush(); 21272343Sngie printInstruction(MI, OS); 22272343Sngie 23272343Sngie printAnnotation(OS, Annot); 24272343Sngie} 25272343Sngie 26272343Sngievoid AMDGPUInstPrinter::printRegOperand(unsigned reg, raw_ostream &O) { 27272343Sngie switch (reg) { 28272343Sngie case AMDGPU::VCC: 29272343Sngie O << "vcc"; 30272343Sngie return; 31272343Sngie case AMDGPU::SCC: 32272343Sngie O << "scc"; 33272343Sngie return; 34272343Sngie case AMDGPU::EXEC: 35272343Sngie O << "exec"; 36272343Sngie return; 37272343Sngie case AMDGPU::M0: 38272343Sngie O << "m0"; 39272343Sngie return; 40272343Sngie default: 41272343Sngie break; 42272343Sngie } 43272343Sngie 44272343Sngie // It's seems there's no way to use SIRegisterInfo here, and dealing with the 45272343Sngie // giant enum of all the different shifted sets of registers is pretty 46272343Sngie // unmanagable, so parse the name and reformat it to be prettier. 47272343Sngie StringRef Name(getRegisterName(reg)); 48272343Sngie 49272343Sngie std::pair<StringRef, StringRef> Split = Name.split('_'); 50272343Sngie StringRef SubRegName = Split.first; 51272343Sngie StringRef Rest = Split.second; 52272343Sngie 53272343Sngie if (SubRegName.size() <= 4) { // Must at least be as long as "SGPR"/"VGPR". 54272343Sngie O << Name; 55272343Sngie return; 56272343Sngie } 57272343Sngie 58272343Sngie unsigned RegIndex; 59272343Sngie StringRef RegIndexStr = SubRegName.drop_front(4); 60272343Sngie 61272343Sngie if (RegIndexStr.getAsInteger(10, RegIndex)) { 62272343Sngie O << Name; 63272343Sngie return; 64272343Sngie } 65272343Sngie 66272343Sngie if (SubRegName.front() == 'V') 67272343Sngie O << 'v'; 68272343Sngie else if (SubRegName.front() == 'S') 69272343Sngie O << 's'; 70272343Sngie else { 71272343Sngie O << Name; 72272343Sngie return; 73272343Sngie } 74272343Sngie 75272343Sngie if (Rest.empty()) // Only 1 32-bit register 76272343Sngie O << RegIndex; 77272343Sngie else { 78272343Sngie unsigned NumReg = Rest.count('_') + 2; 79272343Sngie O << '[' << RegIndex << ':' << (RegIndex + NumReg - 1) << ']'; 80272343Sngie } 81272343Sngie} 82272343Sngie 83272343Sngievoid AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 84272343Sngie raw_ostream &O) { 85272343Sngie 86272343Sngie const MCOperand &Op = MI->getOperand(OpNo); 87272343Sngie if (Op.isReg()) { 88272343Sngie switch (Op.getReg()) { 89272343Sngie // This is the default predicate state, so we don't need to print it. 90272343Sngie case AMDGPU::PRED_SEL_OFF: 91272343Sngie break; 92272343Sngie 93272343Sngie default: 94272343Sngie printRegOperand(Op.getReg(), O); 95272343Sngie break; 96272343Sngie } 97272343Sngie } else if (Op.isImm()) { 98272343Sngie O << Op.getImm(); 99272343Sngie } else if (Op.isFPImm()) { 100272343Sngie O << Op.getFPImm(); 101272343Sngie } else if (Op.isExpr()) { 102272343Sngie const MCExpr *Exp = Op.getExpr(); 103272343Sngie Exp->print(O); 104272343Sngie } else { 105272343Sngie assert(!"unknown operand type in printOperand"); 106272343Sngie } 107272343Sngie} 108272343Sngie 109272343Sngievoid AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum, 110272343Sngie raw_ostream &O) { 111272343Sngie unsigned Imm = MI->getOperand(OpNum).getImm(); 112272343Sngie 113272343Sngie if (Imm == 2) { 114272343Sngie O << "P0"; 115272343Sngie } else if (Imm == 1) { 116272343Sngie O << "P20"; 117272343Sngie } else if (Imm == 0) { 118272343Sngie O << "P10"; 119272343Sngie } else { 120272343Sngie assert(!"Invalid interpolation parameter slot"); 121272343Sngie } 122272343Sngie} 123272343Sngie 124272343Sngievoid AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo, 125272343Sngie raw_ostream &O) { 126272343Sngie printOperand(MI, OpNo, O); 127272343Sngie O << ", "; 128272343Sngie printOperand(MI, OpNo + 1, O); 129272343Sngie} 130272343Sngie 131272343Sngievoid AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo, 132272343Sngie raw_ostream &O, StringRef Asm, 133272343Sngie StringRef Default) { 134272343Sngie const MCOperand &Op = MI->getOperand(OpNo); 135272343Sngie assert(Op.isImm()); 136272343Sngie if (Op.getImm() == 1) { 137272343Sngie O << Asm; 138272343Sngie } else { 139272343Sngie O << Default; 140272343Sngie } 141272343Sngie} 142272343Sngie 143272343Sngievoid AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo, 144 raw_ostream &O) { 145 printIfSet(MI, OpNo, O, "|"); 146} 147 148void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo, 149 raw_ostream &O) { 150 printIfSet(MI, OpNo, O, "_SAT"); 151} 152 153void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo, 154 raw_ostream &O) { 155 union Literal { 156 float f; 157 int32_t i; 158 } L; 159 160 L.i = MI->getOperand(OpNo).getImm(); 161 O << L.i << "(" << L.f << ")"; 162} 163 164void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo, 165 raw_ostream &O) { 166 printIfSet(MI, OpNo, O.indent(25 - O.GetNumBytesInBuffer()), "*", " "); 167} 168 169void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo, 170 raw_ostream &O) { 171 printIfSet(MI, OpNo, O, "-"); 172} 173 174void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo, 175 raw_ostream &O) { 176 switch (MI->getOperand(OpNo).getImm()) { 177 default: break; 178 case 1: 179 O << " * 2.0"; 180 break; 181 case 2: 182 O << " * 4.0"; 183 break; 184 case 3: 185 O << " / 2.0"; 186 break; 187 } 188} 189 190void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo, 191 raw_ostream &O) { 192 printIfSet(MI, OpNo, O, "+"); 193} 194 195void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo, 196 raw_ostream &O) { 197 printIfSet(MI, OpNo, O, "ExecMask,"); 198} 199 200void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo, 201 raw_ostream &O) { 202 printIfSet(MI, OpNo, O, "Pred,"); 203} 204 205void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo, 206 raw_ostream &O) { 207 const MCOperand &Op = MI->getOperand(OpNo); 208 if (Op.getImm() == 0) { 209 O << " (MASKED)"; 210 } 211} 212 213void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo, 214 raw_ostream &O) { 215 const char * chans = "XYZW"; 216 int sel = MI->getOperand(OpNo).getImm(); 217 218 int chan = sel & 3; 219 sel >>= 2; 220 221 if (sel >= 512) { 222 sel -= 512; 223 int cb = sel >> 12; 224 sel &= 4095; 225 O << cb << "[" << sel << "]"; 226 } else if (sel >= 448) { 227 sel -= 448; 228 O << sel; 229 } else if (sel >= 0){ 230 O << sel; 231 } 232 233 if (sel >= 0) 234 O << "." << chans[chan]; 235} 236 237void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo, 238 raw_ostream &O) { 239 int BankSwizzle = MI->getOperand(OpNo).getImm(); 240 switch (BankSwizzle) { 241 case 1: 242 O << "BS:VEC_021/SCL_122"; 243 break; 244 case 2: 245 O << "BS:VEC_120/SCL_212"; 246 break; 247 case 3: 248 O << "BS:VEC_102/SCL_221"; 249 break; 250 case 4: 251 O << "BS:VEC_201"; 252 break; 253 case 5: 254 O << "BS:VEC_210"; 255 break; 256 default: 257 break; 258 } 259 return; 260} 261 262void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo, 263 raw_ostream &O) { 264 unsigned Sel = MI->getOperand(OpNo).getImm(); 265 switch (Sel) { 266 case 0: 267 O << "X"; 268 break; 269 case 1: 270 O << "Y"; 271 break; 272 case 2: 273 O << "Z"; 274 break; 275 case 3: 276 O << "W"; 277 break; 278 case 4: 279 O << "0"; 280 break; 281 case 5: 282 O << "1"; 283 break; 284 case 7: 285 O << "_"; 286 break; 287 default: 288 break; 289 } 290} 291 292void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo, 293 raw_ostream &O) { 294 unsigned CT = MI->getOperand(OpNo).getImm(); 295 switch (CT) { 296 case 0: 297 O << "U"; 298 break; 299 case 1: 300 O << "N"; 301 break; 302 default: 303 break; 304 } 305} 306 307void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo, 308 raw_ostream &O) { 309 int KCacheMode = MI->getOperand(OpNo).getImm(); 310 if (KCacheMode > 0) { 311 int KCacheBank = MI->getOperand(OpNo - 2).getImm(); 312 O << "CB" << KCacheBank <<":"; 313 int KCacheAddr = MI->getOperand(OpNo + 2).getImm(); 314 int LineSize = (KCacheMode == 1)?16:32; 315 O << KCacheAddr * 16 << "-" << KCacheAddr * 16 + LineSize; 316 } 317} 318 319void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo, 320 raw_ostream &O) { 321 // Note: Mask values are taken from SIInsertWaits.cpp and not from ISA docs 322 // SIInsertWaits.cpp bits usage does not match ISA docs description but it 323 // works so it might be a misprint in docs. 324 unsigned SImm16 = MI->getOperand(OpNo).getImm(); 325 unsigned Vmcnt = SImm16 & 0xF; 326 unsigned Expcnt = (SImm16 >> 4) & 0xF; 327 unsigned Lgkmcnt = (SImm16 >> 8) & 0xF; 328 if (Vmcnt != 0xF) 329 O << "vmcnt(" << Vmcnt << ") "; 330 if (Expcnt != 0x7) 331 O << "expcnt(" << Expcnt << ") "; 332 if (Lgkmcnt != 0x7) 333 O << "lgkmcnt(" << Lgkmcnt << ")"; 334} 335 336#include "AMDGPUGenAsmWriter.inc" 337