blob: f70676943bb3223517ed5b1301b081b3c380f1b7 [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"
12#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000013#include "SIDefines.h"
Christian Konigbf114b42013-02-21 15:17:22 +000014#include "llvm/MC/MCExpr.h"
Benjamin Kramerd78bb462013-05-23 17:10:37 +000015#include "llvm/MC/MCInst.h"
Matt Arsenault303011a2014-12-17 21:04:08 +000016#include "llvm/MC/MCInstrInfo.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,
Akira Hatanakab46d0232015-03-27 20:36:02 +000023 StringRef Annot, const MCSubtargetInfo &STI) {
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) {
Tom Stellard1f3416a2015-04-08 01:09:19 +000092 if (MI->getOperand(OpNo).getImm()) {
93 O << " offset0:";
94 printU8ImmDecOperand(MI, OpNo, O);
95 }
Matt Arsenault61cc9082014-10-10 22:16:07 +000096}
97
98void AMDGPUInstPrinter::printDSOffset1(const MCInst *MI, unsigned OpNo,
99 raw_ostream &O) {
Tom Stellard1f3416a2015-04-08 01:09:19 +0000100 if (MI->getOperand(OpNo).getImm()) {
101 O << " offset1:";
102 printU8ImmDecOperand(MI, OpNo, O);
103 }
Matt Arsenault61cc9082014-10-10 22:16:07 +0000104}
105
Tom Stellard065e3d42015-03-09 18:49:54 +0000106void AMDGPUInstPrinter::printGDS(const MCInst *MI, unsigned OpNo,
107 raw_ostream &O) {
108 if (MI->getOperand(OpNo).getImm())
109 O << " gds";
110}
111
Tom Stellard229d5e62014-08-05 14:48:12 +0000112void AMDGPUInstPrinter::printGLC(const MCInst *MI, unsigned OpNo,
113 raw_ostream &O) {
114 if (MI->getOperand(OpNo).getImm())
115 O << " glc";
116}
117
118void AMDGPUInstPrinter::printSLC(const MCInst *MI, unsigned OpNo,
119 raw_ostream &O) {
120 if (MI->getOperand(OpNo).getImm())
121 O << " slc";
122}
123
124void AMDGPUInstPrinter::printTFE(const MCInst *MI, unsigned OpNo,
125 raw_ostream &O) {
126 if (MI->getOperand(OpNo).getImm())
127 O << " tfe";
128}
129
Tom Stellardd7e6f132015-04-08 01:09:26 +0000130void AMDGPUInstPrinter::printRegOperand(unsigned reg, raw_ostream &O,
131 const MCRegisterInfo &MRI) {
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000132 switch (reg) {
133 case AMDGPU::VCC:
134 O << "vcc";
135 return;
136 case AMDGPU::SCC:
137 O << "scc";
138 return;
139 case AMDGPU::EXEC:
140 O << "exec";
141 return;
142 case AMDGPU::M0:
143 O << "m0";
144 return;
Matt Arsenault3f981402014-09-15 15:41:53 +0000145 case AMDGPU::FLAT_SCR:
146 O << "flat_scratch";
147 return;
148 case AMDGPU::VCC_LO:
149 O << "vcc_lo";
150 return;
151 case AMDGPU::VCC_HI:
152 O << "vcc_hi";
153 return;
154 case AMDGPU::EXEC_LO:
155 O << "exec_lo";
156 return;
157 case AMDGPU::EXEC_HI:
158 O << "exec_hi";
159 return;
160 case AMDGPU::FLAT_SCR_LO:
161 O << "flat_scratch_lo";
162 return;
163 case AMDGPU::FLAT_SCR_HI:
164 O << "flat_scratch_hi";
165 return;
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000166 default:
167 break;
168 }
169
Matt Arsenaultfcf86c52014-04-15 22:32:42 +0000170 char Type;
171 unsigned NumRegs;
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000172
Matt Arsenaultfcf86c52014-04-15 22:32:42 +0000173 if (MRI.getRegClass(AMDGPU::VGPR_32RegClassID).contains(reg)) {
174 Type = 'v';
175 NumRegs = 1;
176 } else if (MRI.getRegClass(AMDGPU::SGPR_32RegClassID).contains(reg)) {
177 Type = 's';
178 NumRegs = 1;
179 } else if (MRI.getRegClass(AMDGPU::VReg_64RegClassID).contains(reg)) {
180 Type = 'v';
181 NumRegs = 2;
182 } else if (MRI.getRegClass(AMDGPU::SReg_64RegClassID).contains(reg)) {
183 Type = 's';
184 NumRegs = 2;
185 } else if (MRI.getRegClass(AMDGPU::VReg_128RegClassID).contains(reg)) {
186 Type = 'v';
187 NumRegs = 4;
188 } else if (MRI.getRegClass(AMDGPU::SReg_128RegClassID).contains(reg)) {
189 Type = 's';
190 NumRegs = 4;
191 } else if (MRI.getRegClass(AMDGPU::VReg_96RegClassID).contains(reg)) {
192 Type = 'v';
193 NumRegs = 3;
194 } else if (MRI.getRegClass(AMDGPU::VReg_256RegClassID).contains(reg)) {
195 Type = 'v';
196 NumRegs = 8;
197 } else if (MRI.getRegClass(AMDGPU::SReg_256RegClassID).contains(reg)) {
198 Type = 's';
199 NumRegs = 8;
200 } else if (MRI.getRegClass(AMDGPU::VReg_512RegClassID).contains(reg)) {
201 Type = 'v';
202 NumRegs = 16;
203 } else if (MRI.getRegClass(AMDGPU::SReg_512RegClassID).contains(reg)) {
204 Type = 's';
205 NumRegs = 16;
206 } else {
207 O << getRegisterName(reg);
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000208 return;
209 }
210
Matt Arsenaultf4d871b2014-06-23 18:00:26 +0000211 // The low 8 bits of the encoding value is the register index, for both VGPRs
212 // and SGPRs.
213 unsigned RegIdx = MRI.getEncodingValue(reg) & ((1 << 8) - 1);
Matt Arsenaultfcf86c52014-04-15 22:32:42 +0000214 if (NumRegs == 1) {
215 O << Type << RegIdx;
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000216 return;
217 }
218
Matt Arsenaultfcf86c52014-04-15 22:32:42 +0000219 O << Type << '[' << RegIdx << ':' << (RegIdx + NumRegs - 1) << ']';
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000220}
221
Tom Stellardc0503922015-03-12 21:34:22 +0000222void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo,
223 raw_ostream &O) {
224 if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3)
225 O << "_e64 ";
226 else
227 O << "_e32 ";
228
229 printOperand(MI, OpNo, O);
230}
231
Matt Arsenault303011a2014-12-17 21:04:08 +0000232void AMDGPUInstPrinter::printImmediate32(uint32_t Imm, raw_ostream &O) {
Matt Arsenault4d7d3832014-04-15 22:32:49 +0000233 int32_t SImm = static_cast<int32_t>(Imm);
234 if (SImm >= -16 && SImm <= 64) {
235 O << SImm;
236 return;
237 }
238
Matt Arsenault02dc2652014-09-17 17:32:13 +0000239 if (Imm == FloatToBits(0.0f))
240 O << "0.0";
241 else if (Imm == FloatToBits(1.0f))
242 O << "1.0";
243 else if (Imm == FloatToBits(-1.0f))
244 O << "-1.0";
245 else if (Imm == FloatToBits(0.5f))
246 O << "0.5";
247 else if (Imm == FloatToBits(-0.5f))
248 O << "-0.5";
249 else if (Imm == FloatToBits(2.0f))
250 O << "2.0";
251 else if (Imm == FloatToBits(-2.0f))
252 O << "-2.0";
253 else if (Imm == FloatToBits(4.0f))
254 O << "4.0";
255 else if (Imm == FloatToBits(-4.0f))
256 O << "-4.0";
Matt Arsenault303011a2014-12-17 21:04:08 +0000257 else
Matt Arsenault02dc2652014-09-17 17:32:13 +0000258 O << formatHex(static_cast<uint64_t>(Imm));
Matt Arsenault303011a2014-12-17 21:04:08 +0000259}
260
261void AMDGPUInstPrinter::printImmediate64(uint64_t Imm, raw_ostream &O) {
262 int64_t SImm = static_cast<int64_t>(Imm);
263 if (SImm >= -16 && SImm <= 64) {
264 O << SImm;
265 return;
Matt Arsenault4d7d3832014-04-15 22:32:49 +0000266 }
Matt Arsenault303011a2014-12-17 21:04:08 +0000267
268 if (Imm == DoubleToBits(0.0))
269 O << "0.0";
270 else if (Imm == DoubleToBits(1.0))
271 O << "1.0";
272 else if (Imm == DoubleToBits(-1.0))
273 O << "-1.0";
274 else if (Imm == DoubleToBits(0.5))
275 O << "0.5";
276 else if (Imm == DoubleToBits(-0.5))
277 O << "-0.5";
278 else if (Imm == DoubleToBits(2.0))
279 O << "2.0";
280 else if (Imm == DoubleToBits(-2.0))
281 O << "-2.0";
282 else if (Imm == DoubleToBits(4.0))
283 O << "4.0";
284 else if (Imm == DoubleToBits(-4.0))
285 O << "-4.0";
286 else
287 llvm_unreachable("64-bit literal constants not supported");
Matt Arsenault4d7d3832014-04-15 22:32:49 +0000288}
289
Tom Stellard75aadc22012-12-11 21:25:42 +0000290void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
291 raw_ostream &O) {
292
293 const MCOperand &Op = MI->getOperand(OpNo);
294 if (Op.isReg()) {
295 switch (Op.getReg()) {
296 // This is the default predicate state, so we don't need to print it.
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000297 case AMDGPU::PRED_SEL_OFF:
298 break;
299
300 default:
Tom Stellardd7e6f132015-04-08 01:09:26 +0000301 printRegOperand(Op.getReg(), O, MRI);
Matt Arsenault72b31ee2013-11-12 02:35:51 +0000302 break;
Tom Stellard75aadc22012-12-11 21:25:42 +0000303 }
304 } else if (Op.isImm()) {
Matt Arsenault303011a2014-12-17 21:04:08 +0000305 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
306 int RCID = Desc.OpInfo[OpNo].RegClass;
307 if (RCID != -1) {
308 const MCRegisterClass &ImmRC = MRI.getRegClass(RCID);
309 if (ImmRC.getSize() == 4)
310 printImmediate32(Op.getImm(), O);
311 else if (ImmRC.getSize() == 8)
312 printImmediate64(Op.getImm(), O);
313 else
314 llvm_unreachable("Invalid register class size");
Matt Arsenault70120fa2015-02-21 21:29:00 +0000315 } else if (Desc.OpInfo[OpNo].OperandType == MCOI::OPERAND_IMMEDIATE) {
316 printImmediate32(Op.getImm(), O);
Matt Arsenault303011a2014-12-17 21:04:08 +0000317 } else {
318 // We hit this for the immediate instruction bits that don't yet have a
319 // custom printer.
320 // TODO: Eventually this should be unnecessary.
321 O << formatDec(Op.getImm());
322 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000323 } else if (Op.isFPImm()) {
Matt Arsenault02dc2652014-09-17 17:32:13 +0000324 // We special case 0.0 because otherwise it will be printed as an integer.
325 if (Op.getFPImm() == 0.0)
326 O << "0.0";
Matt Arsenault303011a2014-12-17 21:04:08 +0000327 else {
328 const MCInstrDesc &Desc = MII.get(MI->getOpcode());
329 const MCRegisterClass &ImmRC = MRI.getRegClass(Desc.OpInfo[OpNo].RegClass);
330
331 if (ImmRC.getSize() == 4)
332 printImmediate32(FloatToBits(Op.getFPImm()), O);
333 else if (ImmRC.getSize() == 8)
334 printImmediate64(DoubleToBits(Op.getFPImm()), O);
335 else
336 llvm_unreachable("Invalid register class size");
337 }
Christian Konigbf114b42013-02-21 15:17:22 +0000338 } else if (Op.isExpr()) {
339 const MCExpr *Exp = Op.getExpr();
Matt Arsenault8b643552015-06-09 00:31:39 +0000340 Exp->print(O, &MAI);
Tom Stellard75aadc22012-12-11 21:25:42 +0000341 } else {
Matt Arsenault393366c2014-09-21 17:27:31 +0000342 llvm_unreachable("unknown operand type in printOperand");
Tom Stellard75aadc22012-12-11 21:25:42 +0000343 }
344}
345
Vincent Lejeune94af31f2014-05-10 19:18:33 +0000346void AMDGPUInstPrinter::printOperandAndMods(const MCInst *MI, unsigned OpNo,
347 raw_ostream &O) {
348 unsigned InputModifiers = MI->getOperand(OpNo).getImm();
Matt Arsenault9783e002014-09-29 15:50:26 +0000349 if (InputModifiers & SISrcMods::NEG)
Matt Arsenault3673eba2014-09-21 17:27:28 +0000350 O << '-';
Matt Arsenault9783e002014-09-29 15:50:26 +0000351 if (InputModifiers & SISrcMods::ABS)
Matt Arsenault3673eba2014-09-21 17:27:28 +0000352 O << '|';
Vincent Lejeune94af31f2014-05-10 19:18:33 +0000353 printOperand(MI, OpNo + 1, O);
Matt Arsenault9783e002014-09-29 15:50:26 +0000354 if (InputModifiers & SISrcMods::ABS)
Matt Arsenault3673eba2014-09-21 17:27:28 +0000355 O << '|';
Vincent Lejeune94af31f2014-05-10 19:18:33 +0000356}
357
Michel Danzere9bb18b2013-02-14 19:03:25 +0000358void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNum,
359 raw_ostream &O) {
360 unsigned Imm = MI->getOperand(OpNum).getImm();
361
362 if (Imm == 2) {
363 O << "P0";
364 } else if (Imm == 1) {
365 O << "P20";
366 } else if (Imm == 0) {
367 O << "P10";
368 } else {
Matt Arsenault393366c2014-09-21 17:27:31 +0000369 llvm_unreachable("Invalid interpolation parameter slot");
Michel Danzere9bb18b2013-02-14 19:03:25 +0000370 }
371}
372
Tom Stellard75aadc22012-12-11 21:25:42 +0000373void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
374 raw_ostream &O) {
375 printOperand(MI, OpNo, O);
376 O << ", ";
377 printOperand(MI, OpNo + 1, O);
378}
379
380void AMDGPUInstPrinter::printIfSet(const MCInst *MI, unsigned OpNo,
Vincent Lejeunef97af792013-05-02 21:52:30 +0000381 raw_ostream &O, StringRef Asm,
382 StringRef Default) {
Tom Stellard75aadc22012-12-11 21:25:42 +0000383 const MCOperand &Op = MI->getOperand(OpNo);
384 assert(Op.isImm());
385 if (Op.getImm() == 1) {
386 O << Asm;
Vincent Lejeunef97af792013-05-02 21:52:30 +0000387 } else {
388 O << Default;
Tom Stellard75aadc22012-12-11 21:25:42 +0000389 }
390}
391
392void AMDGPUInstPrinter::printAbs(const MCInst *MI, unsigned OpNo,
393 raw_ostream &O) {
394 printIfSet(MI, OpNo, O, "|");
395}
396
397void AMDGPUInstPrinter::printClamp(const MCInst *MI, unsigned OpNo,
398 raw_ostream &O) {
399 printIfSet(MI, OpNo, O, "_SAT");
400}
401
Matt Arsenault97069782014-09-30 19:49:48 +0000402void AMDGPUInstPrinter::printClampSI(const MCInst *MI, unsigned OpNo,
403 raw_ostream &O) {
404 if (MI->getOperand(OpNo).getImm())
405 O << " clamp";
406}
407
408void AMDGPUInstPrinter::printOModSI(const MCInst *MI, unsigned OpNo,
409 raw_ostream &O) {
410 int Imm = MI->getOperand(OpNo).getImm();
411 if (Imm == SIOutMods::MUL2)
412 O << " mul:2";
413 else if (Imm == SIOutMods::MUL4)
414 O << " mul:4";
415 else if (Imm == SIOutMods::DIV2)
416 O << " div:2";
417}
418
Tom Stellard75aadc22012-12-11 21:25:42 +0000419void AMDGPUInstPrinter::printLiteral(const MCInst *MI, unsigned OpNo,
420 raw_ostream &O) {
Matt Arsenault762ef012014-06-23 18:00:24 +0000421 int32_t Imm = MI->getOperand(OpNo).getImm();
422 O << Imm << '(' << BitsToFloat(Imm) << ')';
Tom Stellard75aadc22012-12-11 21:25:42 +0000423}
424
425void AMDGPUInstPrinter::printLast(const MCInst *MI, unsigned OpNo,
426 raw_ostream &O) {
Vincent Lejeune709e0162013-05-17 16:49:49 +0000427 printIfSet(MI, OpNo, O.indent(25 - O.GetNumBytesInBuffer()), "*", " ");
Tom Stellard75aadc22012-12-11 21:25:42 +0000428}
429
430void AMDGPUInstPrinter::printNeg(const MCInst *MI, unsigned OpNo,
431 raw_ostream &O) {
432 printIfSet(MI, OpNo, O, "-");
433}
434
435void AMDGPUInstPrinter::printOMOD(const MCInst *MI, unsigned OpNo,
436 raw_ostream &O) {
437 switch (MI->getOperand(OpNo).getImm()) {
438 default: break;
439 case 1:
440 O << " * 2.0";
441 break;
442 case 2:
443 O << " * 4.0";
444 break;
445 case 3:
446 O << " / 2.0";
447 break;
448 }
449}
450
451void AMDGPUInstPrinter::printRel(const MCInst *MI, unsigned OpNo,
452 raw_ostream &O) {
Tom Stellardf3b2a1e2013-02-06 17:32:29 +0000453 printIfSet(MI, OpNo, O, "+");
Tom Stellard75aadc22012-12-11 21:25:42 +0000454}
455
456void AMDGPUInstPrinter::printUpdateExecMask(const MCInst *MI, unsigned OpNo,
457 raw_ostream &O) {
458 printIfSet(MI, OpNo, O, "ExecMask,");
459}
460
461void AMDGPUInstPrinter::printUpdatePred(const MCInst *MI, unsigned OpNo,
462 raw_ostream &O) {
463 printIfSet(MI, OpNo, O, "Pred,");
464}
465
466void AMDGPUInstPrinter::printWrite(const MCInst *MI, unsigned OpNo,
467 raw_ostream &O) {
468 const MCOperand &Op = MI->getOperand(OpNo);
469 if (Op.getImm() == 0) {
470 O << " (MASKED)";
471 }
472}
473
Tom Stellard365366f2013-01-23 02:09:06 +0000474void AMDGPUInstPrinter::printSel(const MCInst *MI, unsigned OpNo,
475 raw_ostream &O) {
476 const char * chans = "XYZW";
477 int sel = MI->getOperand(OpNo).getImm();
478
479 int chan = sel & 3;
480 sel >>= 2;
481
482 if (sel >= 512) {
483 sel -= 512;
484 int cb = sel >> 12;
485 sel &= 4095;
Matt Arsenault3673eba2014-09-21 17:27:28 +0000486 O << cb << '[' << sel << ']';
Tom Stellard365366f2013-01-23 02:09:06 +0000487 } else if (sel >= 448) {
488 sel -= 448;
489 O << sel;
490 } else if (sel >= 0){
491 O << sel;
492 }
493
494 if (sel >= 0)
Matt Arsenault3673eba2014-09-21 17:27:28 +0000495 O << '.' << chans[chan];
Tom Stellard365366f2013-01-23 02:09:06 +0000496}
497
Vincent Lejeunef97af792013-05-02 21:52:30 +0000498void AMDGPUInstPrinter::printBankSwizzle(const MCInst *MI, unsigned OpNo,
499 raw_ostream &O) {
500 int BankSwizzle = MI->getOperand(OpNo).getImm();
501 switch (BankSwizzle) {
502 case 1:
Vincent Lejeunebb8a87212013-06-29 19:32:29 +0000503 O << "BS:VEC_021/SCL_122";
Vincent Lejeunef97af792013-05-02 21:52:30 +0000504 break;
505 case 2:
Vincent Lejeunebb8a87212013-06-29 19:32:29 +0000506 O << "BS:VEC_120/SCL_212";
Vincent Lejeunef97af792013-05-02 21:52:30 +0000507 break;
508 case 3:
Vincent Lejeunebb8a87212013-06-29 19:32:29 +0000509 O << "BS:VEC_102/SCL_221";
Vincent Lejeunef97af792013-05-02 21:52:30 +0000510 break;
511 case 4:
512 O << "BS:VEC_201";
513 break;
514 case 5:
515 O << "BS:VEC_210";
516 break;
517 default:
518 break;
519 }
520 return;
521}
522
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000523void AMDGPUInstPrinter::printRSel(const MCInst *MI, unsigned OpNo,
524 raw_ostream &O) {
525 unsigned Sel = MI->getOperand(OpNo).getImm();
526 switch (Sel) {
527 case 0:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000528 O << 'X';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000529 break;
530 case 1:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000531 O << 'Y';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000532 break;
533 case 2:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000534 O << 'Z';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000535 break;
536 case 3:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000537 O << 'W';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000538 break;
539 case 4:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000540 O << '0';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000541 break;
542 case 5:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000543 O << '1';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000544 break;
545 case 7:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000546 O << '_';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000547 break;
548 default:
549 break;
550 }
551}
552
553void AMDGPUInstPrinter::printCT(const MCInst *MI, unsigned OpNo,
554 raw_ostream &O) {
555 unsigned CT = MI->getOperand(OpNo).getImm();
556 switch (CT) {
557 case 0:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000558 O << 'U';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000559 break;
560 case 1:
Matt Arsenault3673eba2014-09-21 17:27:28 +0000561 O << 'N';
Vincent Lejeuned3eed662013-05-17 16:50:20 +0000562 break;
563 default:
564 break;
565 }
566}
567
Vincent Lejeuneb0422e22013-05-02 21:52:40 +0000568void AMDGPUInstPrinter::printKCache(const MCInst *MI, unsigned OpNo,
569 raw_ostream &O) {
570 int KCacheMode = MI->getOperand(OpNo).getImm();
571 if (KCacheMode > 0) {
572 int KCacheBank = MI->getOperand(OpNo - 2).getImm();
Matt Arsenault3673eba2014-09-21 17:27:28 +0000573 O << "CB" << KCacheBank << ':';
Vincent Lejeuneb0422e22013-05-02 21:52:40 +0000574 int KCacheAddr = MI->getOperand(OpNo + 2).getImm();
Matt Arsenault3673eba2014-09-21 17:27:28 +0000575 int LineSize = (KCacheMode == 1) ? 16 : 32;
576 O << KCacheAddr * 16 << '-' << KCacheAddr * 16 + LineSize;
Vincent Lejeuneb0422e22013-05-02 21:52:40 +0000577 }
578}
579
Michel Danzer6064f572014-01-27 07:20:44 +0000580void AMDGPUInstPrinter::printSendMsg(const MCInst *MI, unsigned OpNo,
581 raw_ostream &O) {
582 unsigned SImm16 = MI->getOperand(OpNo).getImm();
583 unsigned Msg = SImm16 & 0xF;
584 if (Msg == 2 || Msg == 3) {
585 unsigned Op = (SImm16 >> 4) & 0xF;
586 if (Msg == 3)
587 O << "Gs_done(";
588 else
589 O << "Gs(";
590 if (Op == 0) {
591 O << "nop";
592 } else {
593 unsigned Stream = (SImm16 >> 8) & 0x3;
594 if (Op == 1)
595 O << "cut";
596 else if (Op == 2)
597 O << "emit";
598 else if (Op == 3)
599 O << "emit-cut";
600 O << " stream " << Stream;
601 }
602 O << "), [m0] ";
603 } else if (Msg == 1)
604 O << "interrupt ";
605 else if (Msg == 15)
606 O << "system ";
607 else
608 O << "unknown(" << Msg << ") ";
609}
610
Vincent Lejeuned6cbede2013-10-13 17:56:28 +0000611void AMDGPUInstPrinter::printWaitFlag(const MCInst *MI, unsigned OpNo,
612 raw_ostream &O) {
613 // Note: Mask values are taken from SIInsertWaits.cpp and not from ISA docs
614 // SIInsertWaits.cpp bits usage does not match ISA docs description but it
615 // works so it might be a misprint in docs.
616 unsigned SImm16 = MI->getOperand(OpNo).getImm();
617 unsigned Vmcnt = SImm16 & 0xF;
618 unsigned Expcnt = (SImm16 >> 4) & 0xF;
619 unsigned Lgkmcnt = (SImm16 >> 8) & 0xF;
Matt Arsenault3a997592014-09-26 01:09:46 +0000620
621 bool NeedSpace = false;
622
623 if (Vmcnt != 0xF) {
624 O << "vmcnt(" << Vmcnt << ')';
625 NeedSpace = true;
626 }
627
628 if (Expcnt != 0x7) {
629 if (NeedSpace)
630 O << ' ';
631 O << "expcnt(" << Expcnt << ')';
632 NeedSpace = true;
633 }
634
635 if (Lgkmcnt != 0x7) {
636 if (NeedSpace)
637 O << ' ';
Matt Arsenault3673eba2014-09-21 17:27:28 +0000638 O << "lgkmcnt(" << Lgkmcnt << ')';
Matt Arsenault3a997592014-09-26 01:09:46 +0000639 }
Vincent Lejeuned6cbede2013-10-13 17:56:28 +0000640}
641
Tom Stellard75aadc22012-12-11 21:25:42 +0000642#include "AMDGPUGenAsmWriter.inc"