blob: 12d077c0464b00fbf15b79f6e98c77c3f799900c [file] [log] [blame]
Tom Stellard75aadc22012-12-11 21:25:42 +00001//===-- 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"
Matt Arsenault9783e002014-09-29 15:50:26 +000012#include "SIDefines.h"
13
Tom Stellard75aadc22012-12-11 21:25:42 +000014#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
Christian Konigbf114b42013-02-21 15:17:22 +000015#include "llvm/MC/MCExpr.h"
Benjamin Kramerd78bb462013-05-23 17:10:37 +000016#include "llvm/MC/MCInst.h"
Matt Arsenault4d7d3832014-04-15 22:32:49 +000017#include "llvm/MC/MCRegisterInfo.h"
18#include "llvm/Support/MathExtras.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000019
20using namespace llvm;
21
22void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
23 StringRef Annot) {
Vincent Lejeunef97af792013-05-02 21:52:30 +000024 OS.flush();
Tom Stellard75aadc22012-12-11 21:25:42 +000025 printInstruction(MI, OS);
26
27 printAnnotation(OS, Annot);
28}
29
Matt Arsenault4d7d3832014-04-15 22:32:49 +000030void AMDGPUInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
31 raw_ostream &O) {
32 O << formatHex(MI->getOperand(OpNo).getImm() & 0xff);
33}
34
35void AMDGPUInstPrinter::printU16ImmOperand(const MCInst *MI, unsigned OpNo,
36 raw_ostream &O) {
37 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffff);
38}
39
40void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
41 raw_ostream &O) {
42 O << formatHex(MI->getOperand(OpNo).getImm() & 0xffffffff);
43}
44
Matt Arsenault61cc9082014-10-10 22:16:07 +000045void AMDGPUInstPrinter::printU8ImmDecOperand(const MCInst *MI, unsigned OpNo,
46 raw_ostream &O) {
47 O << formatDec(MI->getOperand(OpNo).getImm() & 0xff);
48}
49
50void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
51 raw_ostream &O) {
52 O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
53}
54
Tom Stellard229d5e62014-08-05 14:48:12 +000055void AMDGPUInstPrinter::printOffen(const MCInst *MI, unsigned OpNo,
56 raw_ostream &O) {
57 if (MI->getOperand(OpNo).getImm())
58 O << " offen";
59}
60
61void AMDGPUInstPrinter::printIdxen(const MCInst *MI, unsigned OpNo,
62 raw_ostream &O) {
63 if (MI->getOperand(OpNo).getImm())
64 O << " idxen";
65}
66
67void AMDGPUInstPrinter::printAddr64(const MCInst *MI, unsigned OpNo,
68 raw_ostream &O) {
69 if (MI->getOperand(OpNo).getImm())
70 O << " addr64";
71}
72
73void AMDGPUInstPrinter::printMBUFOffset(const MCInst *MI, unsigned OpNo,
74 raw_ostream &O) {
75 if (MI->getOperand(OpNo).getImm()) {
76 O << " offset:";
Matt Arsenaultfb13b222014-12-03 03:12:13 +000077 printU16ImmDecOperand(MI, OpNo, O);
Tom Stellard229d5e62014-08-05 14:48:12 +000078 }
79}
80
Matt Arsenault61cc9082014-10-10 22:16:07 +000081void AMDGPUInstPrinter::printDSOffset(const MCInst *MI, unsigned OpNo,
82 raw_ostream &O) {
83 uint16_t Imm = MI->getOperand(OpNo).getImm();
84 if (Imm != 0) {
85 O << " offset:";
86 printU16ImmDecOperand(MI, OpNo, O);
87 }
88}
89
90void AMDGPUInstPrinter::printDSOffset0(const MCInst *MI, unsigned OpNo,
91 raw_ostream &O) {
92 O << " offset0:";
93 printU8ImmDecOperand(MI, OpNo, O);
94}
95
96void AMDGPUInstPrinter::printDSOffset1(const MCInst *MI, unsigned OpNo,
97 raw_ostream &O) {
98 O << " offset1:";
99 printU8ImmDecOperand(MI, OpNo, O);
100}
101
Tom Stellard229d5e62014-08-05 14:48:12 +0000102void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo,
103 raw_ostream &O) {
104 if (MI->getOperand(OpNo).getImm())
105 O << " glc";
106}
107
108void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo,
109 raw_ostream &O) {
110 if (MI->getOperand(OpNo).getImm())
111 O << " slc";
112}
113
114void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
115 raw_ostream &O) {
116 if (MI->getOperand(OpNo).getImm())
117 O << " tfe";
118}
119
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000120void AMDGPUInstPrinter::printRegOperand(unsigned reg, raw_ostream &O) {
121 switch (reg) {
122 case AMDGPU::VCC:
123 O << "vcc";
124 return;
125 case AMDGPU::SCC:
126 O << "scc";
127 return;
128 case AMDGPU::EXEC:
129 O << "exec";
130 return;
131 case AMDGPU::M0:
132 O << "m0";
133 return;
Matt Arsenault3f981402014-09-15 15:41:53 +0000134 case AMDGPU::FLAT_SCR:
135 O << "flat_scratch";
136 return;
137 case AMDGPU::VCC_LO:
138 O << "vcc_lo";
139 return;
140 case AMDGPU::VCC_HI:
141 O << "vcc_hi";
142 return;
143 case AMDGPU::EXEC_LO:
144 O << "exec_lo";
145 return;
146 case AMDGPU::EXEC_HI:
147 O << "exec_hi";
148 return;
149 case AMDGPU::FLAT_SCR_LO:
150 O << "flat_scratch_lo";
151 return;
152 case AMDGPU::FLAT_SCR_HI:
153 O << "flat_scratch_hi";
154 return;
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000155 default:
156 break;
157 }
158
Matt Arsenaultfcf86c52014-04-15 22:32:42 +0000159 char Type;
160 unsigned NumRegs;
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000161
Matt Arsenaultfcf86c52014-04-15 22:32:42 +0000162 if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(reg)) {
163 Type = 'v';
164 NumRegs = 1;
165 } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(reg)) {
166 Type = 's';
167 NumRegs = 1;
168 } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(reg)) {
169 Type = 'v';
170 NumRegs = 2;
171 } else if (MRI.getRegClass(AMDGPU::SReg_64RegClassID).contains(reg)) {
172 Type = 's';
173 NumRegs = 2;
174 } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(reg)) {
175 Type = 'v';
176 NumRegs = 4;
177 } else if (MRI.getRegClass(AMDGPU::SReg_128RegClassID).contains(reg)) {
178 Type = 's';
179 NumRegs = 4;
180 } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(reg)) {
181 Type = 'v';
182 NumRegs = 3;
183 } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(reg)) {
184 Type = 'v';
185 NumRegs = 8;
186 } else if (MRI.getRegClass(AMDGPU::SReg_256RegClassID).contains(reg)) {
187 Type = 's';
188 NumRegs = 8;
189 } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(reg)) {
190 Type = 'v';
191 NumRegs = 16;
192 } else if (MRI.getRegClass(AMDGPU::SReg_512RegClassID).contains(reg)) {
193 Type = 's';
194 NumRegs = 16;
195 } else {
196 O << getRegisterName(reg);
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000197 return;
198 }
199
Matt Arsenaultf4d871b2014-06-23 18:00:26 +0000200 // The low 8 bits of the encoding value is the register index, for both VGPRs
201 // and SGPRs.
202 unsigned RegIdx = MRI.getEncodingValue(reg) & ((1 << 8) - 1);
Matt Arsenaultfcf86c52014-04-15 22:32:42 +0000203 if (NumRegs == 1) {
204 O << Type << RegIdx;
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000205 return;
206 }
207
Matt Arsenaultfcf86c52014-04-15 22:32:42 +0000208 O << Type << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']';
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000209}
210
Matt Arsenault4d7d3832014-04-15 22:32:49 +0000211void AMDGPUInstPrinter::printImmediate(uint32_t Imm, raw_ostream &O) {
212 int32_t SImm = static_cast<int32_t>(Imm);
213 if (SImm >= -16 && SImm <= 64) {
214 O << SImm;
215 return;
216 }
217
Matt Arsenault02dc2652014-09-17 17:32:13 +0000218 if (Imm == FloatToBits(0.0f))
219 O << "0.0";
220 else if (Imm == FloatToBits(1.0f))
221 O << "1.0";
222 else if (Imm == FloatToBits(-1.0f))
223 O << "-1.0";
224 else if (Imm == FloatToBits(0.5f))
225 O << "0.5";
226 else if (Imm == FloatToBits(-0.5f))
227 O << "-0.5";
228 else if (Imm == FloatToBits(2.0f))
229 O << "2.0";
230 else if (Imm == FloatToBits(-2.0f))
231 O << "-2.0";
232 else if (Imm == FloatToBits(4.0f))
233 O << "4.0";
234 else if (Imm == FloatToBits(-4.0f))
235 O << "-4.0";
236 else {
237 O << formatHex(static_cast<uint64_t>(Imm));
Matt Arsenault4d7d3832014-04-15 22:32:49 +0000238 }
Matt Arsenault4d7d3832014-04-15 22:32:49 +0000239}
240
Tom Stellard75aadc22012-12-11 21:25:42 +0000241void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
242 raw_ostream &O) {
243
244 const MCOperand &Op = MI->getOperand(OpNo);
245 if (Op.isReg()) {
246 switch (Op.getReg()) {
247 // This is the default predicate state, so we don't need to print it.
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000248 case AMDGPU::PRED_SEL_OFF:
249 break;
250
251 default:
252 printRegOperand(Op.getReg(), O);
253 break;
Tom Stellard75aadc22012-12-11 21:25:42 +0000254 }
255 } else if (Op.isImm()) {
Matt Arsenault4d7d3832014-04-15 22:32:49 +0000256 printImmediate(Op.getImm(), O);
Tom Stellard75aadc22012-12-11 21:25:42 +0000257 } else if (Op.isFPImm()) {
Matt Arsenault02dc2652014-09-17 17:32:13 +0000258
259 // We special case 0.0 because otherwise it will be printed as an integer.
260 if (Op.getFPImm() == 0.0)
261 O << "0.0";
262 else
263 printImmediate(FloatToBits(Op.getFPImm()), O);
Christian Konigbf114b42013-02-21 15:17:22 +0000264 } else if (Op.isExpr()) {
265 const MCExpr *Exp = Op.getExpr();
266 Exp->print(O);
Tom Stellard75aadc22012-12-11 21:25:42 +0000267 } else {
Matt Arsenault393366c2014-09-21 17:27:31 +0000268 llvm_unreachable("unknown operand type in printOperand");
Tom Stellard75aadc22012-12-11 21:25:42 +0000269 }
270}
271
Vincent Lejeune94af31f2014-05-10 19:18:33 +0000272void AMDGPUInstPrinter::printOperandAndMods(const MCInst *MI, unsigned OpNo,
273 raw_ostream &O) {
274 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
Matt Arsenault9783e002014-09-29 15:50:26 +0000275 if (InputModifiers & SISrcMods::NEG)
Matt Arsenault3673eba2014-09-21 17:27:28 +0000276 O << '-';
Matt Arsenault9783e002014-09-29 15:50:26 +0000277 if (InputModifiers & SISrcMods::ABS)
Matt Arsenault3673eba2014-09-21 17:27:28 +0000278 O << '|';
Vincent Lejeune94af31f2014-05-10 19:18:33 +0000279 printOperand(MI, OpNo + 1, O);
Matt Arsenault9783e002014-09-29 15:50:26 +0000280 if (InputModifiers & SISrcMods::ABS)
Matt Arsenault3673eba2014-09-21 17:27:28 +0000281 O << '|';
Vincent Lejeune94af31f2014-05-10 19:18:33 +0000282}
283
Michel Danzere9bb18b2013-02-14 19:03:25 +0000284void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
285 raw_ostream &O) {
286 unsigned Imm = MI->getOperand(OpNum).getImm();
287
288 if (Imm == 2) {
289 O << "P0";
290 } else if (Imm == 1) {
291 O << "P20";
292 } else if (Imm == 0) {
293 O << "P10";
294 } else {
Matt Arsenault393366c2014-09-21 17:27:31 +0000295 llvm_unreachable("Invalid interpolation parameter slot");
Michel Danzere9bb18b2013-02-14 19:03:25 +0000296 }
297}
298
Tom Stellard75aadc22012-12-11 21:25:42 +0000299void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
300 raw_ostream &O) {
301 printOperand(MI, OpNo, O);
302 O << ", ";
303 printOperand(MI, OpNo + 1, O);
304}
305
306void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
Vincent Lejeunef97af792013-05-02 21:52:30 +0000307 raw_ostream &O, StringRef Asm,
308 StringRef Default) {
Tom Stellard75aadc22012-12-11 21:25:42 +0000309 const MCOperand &Op = MI->getOperand(OpNo);
310 assert(Op.isImm());
311 if (Op.getImm() == 1) {
312 O << Asm;
Vincent Lejeunef97af792013-05-02 21:52:30 +0000313 } else {
314 O << Default;
Tom Stellard75aadc22012-12-11 21:25:42 +0000315 }
316}
317
318void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
319 raw_ostream &O) {
320 printIfSet(MI, OpNo, O, "|");
321}
322
323void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
324 raw_ostream &O) {
325 printIfSet(MI, OpNo, O, "_SAT");
326}
327
Matt Arsenault97069782014-09-30 19:49:48 +0000328void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
329 raw_ostream &O) {
330 if (MI->getOperand(OpNo).getImm())
331 O << " clamp";
332}
333
334void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
335 raw_ostream &O) {
336 int Imm = MI->getOperand(OpNo).getImm();
337 if (Imm == SIOutMods::MUL2)
338 O << " mul:2";
339 else if (Imm == SIOutMods::MUL4)
340 O << " mul:4";
341 else if (Imm == SIOutMods::DIV2)
342 O << " div:2";
343}
344
Tom Stellard75aadc22012-12-11 21:25:42 +0000345void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
346 raw_ostream &O) {
Matt Arsenault762ef012014-06-23 18:00:24 +0000347 int32_t Imm = MI->getOperand(OpNo).getImm();
348 O << Imm << '(' << BitsToFloat(Imm) << ')';
Tom Stellard75aadc22012-12-11 21:25:42 +0000349}
350
351void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
352 raw_ostream &O) {
Vincent Lejeune709e0162013-05-17 16:49:49 +0000353 printIfSet(MI, OpNo, O.indent(25 - O.GetNumBytesInBuffer()), "*", " ");
Tom Stellard75aadc22012-12-11 21:25:42 +0000354}
355
356void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
357 raw_ostream &O) {
358 printIfSet(MI, OpNo, O, "-");
359}
360
361void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
362 raw_ostream &O) {
363 switch (MI->getOperand(OpNo).getImm()) {
364 default: break;
365 case 1:
366 O << " * 2.0";
367 break;
368 case 2:
369 O << " * 4.0";
370 break;
371 case 3:
372 O << " / 2.0";
373 break;
374 }
375}
376
377void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
378 raw_ostream &O) {
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000379 printIfSet(MI, OpNo, O, "+");
Tom Stellard75aadc22012-12-11 21:25:42 +0000380}
381
382void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
383 raw_ostream &O) {
384 printIfSet(MI, OpNo, O, "ExecMask,");
385}
386
387void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
388 raw_ostream &O) {
389 printIfSet(MI, OpNo, O, "Pred,");
390}
391
392void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
393 raw_ostream &O) {
394 const MCOperand &Op = MI->getOperand(OpNo);
395 if (Op.getImm() == 0) {
396 O << " (MASKED)";
397 }
398}
399
Tom Stellard365366f2013-01-23 02:09:06 +0000400void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
401 raw_ostream &O) {
402 const char * chans = "XYZW";
403 int sel = MI->getOperand(OpNo).getImm();
404
405 int chan = sel & 3;
406 sel >>= 2;
407
408 if (sel >= 512) {
409 sel -= 512;
410 int cb = sel >> 12;
411 sel &= 4095;
Matt Arsenault3673eba2014-09-21 17:27:28 +0000412 O << cb << '[' << sel << ']';
Tom Stellard365366f2013-01-23 02:09:06 +0000413 } else if (sel >= 448) {
414 sel -= 448;
415 O << sel;
416 } else if (sel >= 0){
417 O << sel;
418 }
419
420 if (sel >= 0)
Matt Arsenault3673eba2014-09-21 17:27:28 +0000421 O << '.' << chans[chan];
Tom Stellard365366f2013-01-23 02:09:06 +0000422}
423
Vincent Lejeunef97af792013-05-02 21:52:30 +0000424void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
425 raw_ostream &O) {
426 int BankSwizzle = MI->getOperand(OpNo).getImm();
427 switch (BankSwizzle) {
428 case 1:
Vincent Lejeunebb8a87212013-06-29 19:32:29 +0000429 O << "BS:VEC_021/SCL_122";
Vincent Lejeunef97af792013-05-02 21:52:30 +0000430 break;
431 case 2:
Vincent Lejeunebb8a87212013-06-29 19:32:29 +0000432 O << "BS:VEC_120/SCL_212";
Vincent Lejeunef97af792013-05-02 21:52:30 +0000433 break;
434 case 3:
Vincent Lejeunebb8a87212013-06-29 19:32:29 +0000435 O << "BS:VEC_102/SCL_221";
Vincent Lejeunef97af792013-05-02 21:52:30 +0000436 break;
437 case 4:
438 O << "BS:VEC_201";
439 break;
440 case 5:
441 O << "BS:VEC_210";
442 break;
443 default:
444 break;
445 }
446 return;
447}
448
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000449void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
450 raw_ostream &O) {
451 unsigned Sel = MI->getOperand(OpNo).getImm();
452 switch (Sel) {
453 case 0:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000454 O << 'X';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000455 break;
456 case 1:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000457 O << 'Y';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000458 break;
459 case 2:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000460 O << 'Z';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000461 break;
462 case 3:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000463 O << 'W';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000464 break;
465 case 4:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000466 O << '0';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000467 break;
468 case 5:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000469 O << '1';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000470 break;
471 case 7:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000472 O << '_';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000473 break;
474 default:
475 break;
476 }
477}
478
479void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo,
480 raw_ostream &O) {
481 unsigned CT = MI->getOperand(OpNo).getImm();
482 switch (CT) {
483 case 0:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000484 O << 'U';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000485 break;
486 case 1:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000487 O << 'N';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000488 break;
489 default:
490 break;
491 }
492}
493
Vincent Lejeuneb0422e22013-05-02 21:52:40 +0000494void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
495 raw_ostream &O) {
496 int KCacheMode = MI->getOperand(OpNo).getImm();
497 if (KCacheMode > 0) {
498 int KCacheBank = MI->getOperand(OpNo - 2).getImm();
Matt Arsenault3673eba2014-09-21 17:27:28 +0000499 O << "CB" << KCacheBank << ':';
Vincent Lejeuneb0422e22013-05-02 21:52:40 +0000500 int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
Matt Arsenault3673eba2014-09-21 17:27:28 +0000501 int LineSize = (KCacheMode == 1) ? 16 : 32;
502 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
Vincent Lejeuneb0422e22013-05-02 21:52:40 +0000503 }
504}
505
Michel Danzer6064f572014-01-27 07:20:44 +0000506void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
507 raw_ostream &O) {
508 unsigned SImm16 = MI->getOperand(OpNo).getImm();
509 unsigned Msg = SImm16 & 0xF;
510 if (Msg == 2 || Msg == 3) {
511 unsigned Op = (SImm16 >> 4) & 0xF;
512 if (Msg == 3)
513 O << "Gs_done(";
514 else
515 O << "Gs(";
516 if (Op == 0) {
517 O << "nop";
518 } else {
519 unsigned Stream = (SImm16 >> 8) & 0x3;
520 if (Op == 1)
521 O << "cut";
522 else if (Op == 2)
523 O << "emit";
524 else if (Op == 3)
525 O << "emit-cut";
526 O << " stream " << Stream;
527 }
528 O << "), [m0] ";
529 } else if (Msg == 1)
530 O << "interrupt ";
531 else if (Msg == 15)
532 O << "system ";
533 else
534 O << "unknown(" << Msg << ") ";
535}
536
Vincent Lejeuned6cbede2013-10-13 17:56:28 +0000537void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
538 raw_ostream &O) {
539 // Note: Mask values are taken from SIInsertWaits.cpp and not from ISA docs
540 // SIInsertWaits.cpp bits usage does not match ISA docs description but it
541 // works so it might be a misprint in docs.
542 unsigned SImm16 = MI->getOperand(OpNo).getImm();
543 unsigned Vmcnt = SImm16 & 0xF;
544 unsigned Expcnt = (SImm16 >> 4) & 0xF;
545 unsigned Lgkmcnt = (SImm16 >> 8) & 0xF;
Matt Arsenault3a997592014-09-26 01:09:46 +0000546
547 bool NeedSpace = false;
548
549 if (Vmcnt != 0xF) {
550 O << "vmcnt(" << Vmcnt << ')';
551 NeedSpace = true;
552 }
553
554 if (Expcnt != 0x7) {
555 if (NeedSpace)
556 O << ' ';
557 O << "expcnt(" << Expcnt << ')';
558 NeedSpace = true;
559 }
560
561 if (Lgkmcnt != 0x7) {
562 if (NeedSpace)
563 O << ' ';
Matt Arsenault3673eba2014-09-21 17:27:28 +0000564 O << "lgkmcnt(" << Lgkmcnt << ')';
Matt Arsenault3a997592014-09-26 01:09:46 +0000565 }
Vincent Lejeuned6cbede2013-10-13 17:56:28 +0000566}
567
Tom Stellard75aadc22012-12-11 21:25:42 +0000568#include "AMDGPUGenAsmWriter.inc"