R600MCCodeEmitter.cpp revision 90bd1d52bbf95947955a66ec67f5f6c7dc87119a
1//===- R600MCCodeEmitter.cpp - Code Emitter for R600->Cayman GPU families -===//
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//===----------------------------------------------------------------------===//
9//
10// This code emitters outputs bytecode that is understood by the r600g driver
11// in the Mesa [1] project.  The bytecode is very similar to the hardware's ISA,
12// except that the size of the instruction fields are rounded up to the
13// nearest byte.
14//
15// [1] http://www.mesa3d.org/
16//
17//===----------------------------------------------------------------------===//
18
19#include "R600Defines.h"
20#include "MCTargetDesc/AMDILMCTargetDesc.h"
21#include "MCTargetDesc/AMDGPUMCCodeEmitter.h"
22#include "llvm/MC/MCCodeEmitter.h"
23#include "llvm/MC/MCContext.h"
24#include "llvm/MC/MCInst.h"
25#include "llvm/MC/MCInstrInfo.h"
26#include "llvm/MC/MCRegisterInfo.h"
27#include "llvm/MC/MCSubtargetInfo.h"
28#include "llvm/Support/raw_ostream.h"
29
30#include <stdio.h>
31
32#define SRC_BYTE_COUNT 11
33#define DST_BYTE_COUNT 5
34
35using namespace llvm;
36
37namespace {
38
39class R600MCCodeEmitter : public AMDGPUMCCodeEmitter {
40  R600MCCodeEmitter(const R600MCCodeEmitter &); // DO NOT IMPLEMENT
41  void operator=(const R600MCCodeEmitter &); // DO NOT IMPLEMENT
42  const MCInstrInfo &MCII;
43  const MCSubtargetInfo &STI;
44  MCContext &Ctx;
45
46public:
47
48  R600MCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
49                    MCContext &ctx)
50    : MCII(mcii), STI(sti), Ctx(ctx) { }
51
52  /// EncodeInstruction - Encode the instruction and write it to the OS.
53  virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
54                         SmallVectorImpl<MCFixup> &Fixups) const;
55
56  /// getMachineOpValue - Reutrn the encoding for an MCOperand.
57  virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
58                                     SmallVectorImpl<MCFixup> &Fixups) const;
59private:
60
61  void EmitALUInstr(const MCInst &MI, SmallVectorImpl<MCFixup> &Fixups,
62                    raw_ostream &OS) const;
63  void EmitSrc(const MCInst &MI, unsigned OpIdx, raw_ostream &OS) const;
64  void EmitDst(const MCInst &MI, raw_ostream &OS) const;
65  void EmitALU(const MCInst &MI, unsigned numSrc,
66               SmallVectorImpl<MCFixup> &Fixups,
67               raw_ostream &OS) const;
68  void EmitTexInstr(const MCInst &MI, SmallVectorImpl<MCFixup> &Fixups,
69                    raw_ostream &OS) const;
70  void EmitFCInstr(const MCInst &MI, raw_ostream &OS) const;
71
72  void EmitNullBytes(unsigned int byteCount, raw_ostream &OS) const;
73
74  void EmitByte(unsigned int byte, raw_ostream &OS) const;
75
76  void EmitTwoBytes(uint32_t bytes, raw_ostream &OS) const;
77
78  void Emit(uint32_t value, raw_ostream &OS) const;
79  void Emit(uint64_t value, raw_ostream &OS) const;
80
81  unsigned getHWRegIndex(unsigned reg) const;
82  unsigned getHWRegChan(unsigned reg) const;
83  unsigned getHWReg(unsigned regNo) const;
84
85  bool isFCOp(unsigned opcode) const;
86  bool isTexOp(unsigned opcode) const;
87  bool isFlagSet(const MCInst &MI, unsigned Operand, unsigned Flag) const;
88
89  /// getHWRegIndexGen - Get the register's hardware index.  Implemented in
90  /// R600HwRegInfo.include.
91  unsigned getHWRegIndexGen(unsigned int Reg) const;
92
93  /// getHWRegChanGen - Get the register's channel.  Implemented in
94  /// R600HwRegInfo.include.
95  unsigned getHWRegChanGen(unsigned int Reg) const;
96};
97
98} // End anonymous namespace
99
100enum RegElement {
101  ELEMENT_X = 0,
102  ELEMENT_Y,
103  ELEMENT_Z,
104  ELEMENT_W
105};
106
107enum InstrTypes {
108  INSTR_ALU = 0,
109  INSTR_TEX,
110  INSTR_FC,
111  INSTR_NATIVE,
112  INSTR_VTX
113};
114
115enum FCInstr {
116  FC_IF = 0,
117  FC_IF_INT,
118  FC_ELSE,
119  FC_ENDIF,
120  FC_BGNLOOP,
121  FC_ENDLOOP,
122  FC_BREAK,
123  FC_BREAK_NZ_INT,
124  FC_CONTINUE,
125  FC_BREAK_Z_INT,
126  FC_BREAK_NZ
127};
128
129enum TextureTypes {
130  TEXTURE_1D = 1,
131  TEXTURE_2D,
132  TEXTURE_3D,
133  TEXTURE_CUBE,
134  TEXTURE_RECT,
135  TEXTURE_SHADOW1D,
136  TEXTURE_SHADOW2D,
137  TEXTURE_SHADOWRECT,
138  TEXTURE_1D_ARRAY,
139  TEXTURE_2D_ARRAY,
140  TEXTURE_SHADOW1D_ARRAY,
141  TEXTURE_SHADOW2D_ARRAY
142};
143
144MCCodeEmitter *llvm::createR600MCCodeEmitter(const MCInstrInfo &MCII,
145                                           const MCSubtargetInfo &STI,
146                                           MCContext &Ctx) {
147  return new R600MCCodeEmitter(MCII, STI, Ctx);
148}
149
150void R600MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
151                                       SmallVectorImpl<MCFixup> &Fixups) const {
152/*
153  if (MI.getNumOperands() > 1 && MI.getOperand(0).isReg() &&
154      MI.getOperand(0).isDead()) {
155    return;
156  }
157*/
158  if (isTexOp(MI.getOpcode())) {
159    EmitTexInstr(MI, Fixups, OS);
160  } else if (isFCOp(MI.getOpcode())){
161    EmitFCInstr(MI, OS);
162  } else if (MI.getOpcode() == AMDGPU::RETURN ||
163    MI.getOpcode() == AMDGPU::BUNDLE ||
164    MI.getOpcode() == AMDGPU::KILL) {
165    return;
166  } else {
167    switch(MI.getOpcode()) {
168    case AMDGPU::RAT_WRITE_CACHELESS_eg:
169      {
170        uint64_t inst = getBinaryCodeForInstr(MI, Fixups);
171        // XXX: Set End Of Program bit when necessary
172        //  inst |= (((uint64_t)1) << 53);
173        EmitByte(INSTR_NATIVE, OS);
174        Emit(inst, OS);
175        break;
176      }
177    case AMDGPU::VTX_READ_PARAM_i32_eg:
178    case AMDGPU::VTX_READ_PARAM_f32_eg:
179    case AMDGPU::VTX_READ_GLOBAL_i32_eg:
180    case AMDGPU::VTX_READ_GLOBAL_f32_eg:
181    case AMDGPU::VTX_READ_GLOBAL_v4i32_eg:
182    case AMDGPU::VTX_READ_GLOBAL_v4f32_eg:
183      {
184        uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups);
185        uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset
186
187        EmitByte(INSTR_VTX, OS);
188        Emit(InstWord01, OS);
189        Emit(InstWord2, OS);
190        break;
191      }
192
193    default:
194      EmitALUInstr(MI, Fixups, OS);
195      break;
196    }
197  }
198}
199
200void R600MCCodeEmitter::EmitALUInstr(const MCInst &MI,
201                                     SmallVectorImpl<MCFixup> &Fixups,
202                                     raw_ostream &OS) const {
203  const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode());
204  unsigned NumOperands = MI.getNumOperands();
205
206  if(MCDesc.findFirstPredOperandIdx() > -1)
207    NumOperands--;
208
209  if (GET_FLAG_OPERAND_IDX(MCDesc.TSFlags) != 0)
210    NumOperands--;
211
212   // Some instructions are just place holder instructions that represent
213   // operations that the GPU does automatically.  They should be ignored.
214//  if (TII->isPlaceHolderOpcode(MI.getOpcode())) {
215//    return;
216//  }
217
218  if(MI.getOpcode() == AMDGPU::PRED_X)
219    NumOperands = 2;
220
221  // XXX Check if instruction writes a result
222  if (NumOperands < 1) {
223    return;
224  }
225
226  // Emit instruction type
227  EmitByte(0, OS);
228
229  unsigned int OpIndex;
230  for (OpIndex = 1; OpIndex < NumOperands; OpIndex++) {
231    // Literal constants are always stored as the last operand.
232    if (MI.getOperand(OpIndex).isImm() || MI.getOperand(OpIndex).isFPImm()) {
233      break;
234    }
235    EmitSrc(MI, OpIndex, OS);
236  }
237
238  // Emit zeros for unused sources
239  for ( ; OpIndex < 4; OpIndex++) {
240    EmitNullBytes(SRC_BYTE_COUNT, OS);
241  }
242
243  EmitDst(MI, OS);
244
245  EmitALU(MI, NumOperands - 1, Fixups, OS);
246}
247
248void R600MCCodeEmitter::EmitSrc(const MCInst &MI, unsigned OpIdx,
249                                raw_ostream &OS) const {
250  const MCOperand &MO = MI.getOperand(OpIdx);
251  union {
252    float f;
253    uint32_t i;
254  } Value;
255  Value.i = 0;
256  // Emit the source select (2 bytes).  For GPRs, this is the register index.
257  // For other potential instruction operands, (e.g. constant registers) the
258  // value of the source select is defined in the r600isa docs.
259  if (MO.isReg()) {
260    unsigned reg = MO.getReg();
261    EmitTwoBytes(getHWReg(reg), OS);
262    if (reg == AMDGPU::ALU_LITERAL_X) {
263      unsigned ImmOpIndex = MI.getNumOperands() - 1;
264      MCOperand ImmOp = MI.getOperand(ImmOpIndex);
265      if (ImmOp.isFPImm()) {
266        Value.f = ImmOp.getFPImm();
267      } else {
268        assert(ImmOp.isImm());
269        Value.i = ImmOp.getImm();
270      }
271    }
272  } else {
273    // XXX: Handle other operand types.
274    EmitTwoBytes(0, OS);
275  }
276
277  // Emit the source channel (1 byte)
278  if (MO.isReg()) {
279    EmitByte(getHWRegChan(MO.getReg()), OS);
280  } else {
281    EmitByte(0, OS);
282  }
283
284  // XXX: Emit isNegated (1 byte)
285  if ((!(isFlagSet(MI, OpIdx, MO_FLAG_ABS)))
286      && (isFlagSet(MI, OpIdx, MO_FLAG_NEG) ||
287     (MO.isReg() &&
288      (MO.getReg() == AMDGPU::NEG_ONE || MO.getReg() == AMDGPU::NEG_HALF)))){
289    EmitByte(1, OS);
290  } else {
291    EmitByte(0, OS);
292  }
293
294  // Emit isAbsolute (1 byte)
295  if (isFlagSet(MI, OpIdx, MO_FLAG_ABS)) {
296    EmitByte(1, OS);
297  } else {
298    EmitByte(0, OS);
299  }
300
301  // XXX: Emit relative addressing mode (1 byte)
302  EmitByte(0, OS);
303
304  // Emit kc_bank, This will be adjusted later by r600_asm
305  EmitByte(0, OS);
306
307  // Emit the literal value, if applicable (4 bytes).
308  Emit(Value.i, OS);
309
310}
311
312void R600MCCodeEmitter::EmitDst(const MCInst &MI, raw_ostream &OS) const {
313
314  const MCOperand &MO = MI.getOperand(0);
315  if (MO.isReg() && MO.getReg() != AMDGPU::PREDICATE_BIT) {
316    // Emit the destination register index (1 byte)
317    EmitByte(getHWReg(MO.getReg()), OS);
318
319    // Emit the element of the destination register (1 byte)
320    EmitByte(getHWRegChan(MO.getReg()), OS);
321
322    // Emit isClamped (1 byte)
323    if (isFlagSet(MI, 0, MO_FLAG_CLAMP)) {
324      EmitByte(1, OS);
325    } else {
326      EmitByte(0, OS);
327    }
328
329    // Emit writemask (1 byte).
330    if (isFlagSet(MI, 0, MO_FLAG_MASK)) {
331      EmitByte(0, OS);
332    } else {
333      EmitByte(1, OS);
334    }
335
336    // XXX: Emit relative addressing mode
337    EmitByte(0, OS);
338  } else {
339    // XXX: Handle other operand types.  Are there any for destination regs?
340    EmitNullBytes(DST_BYTE_COUNT, OS);
341  }
342}
343
344void R600MCCodeEmitter::EmitALU(const MCInst &MI, unsigned numSrc,
345                                SmallVectorImpl<MCFixup> &Fixups,
346                                raw_ostream &OS) const {
347  const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode());
348
349  // Emit the instruction (2 bytes)
350  EmitTwoBytes(getBinaryCodeForInstr(MI, Fixups), OS);
351
352  // Emit IsLast (for this instruction group) (1 byte)
353  if (isFlagSet(MI, 0, MO_FLAG_NOT_LAST)) {
354    EmitByte(0, OS);
355  } else {
356    EmitByte(1, OS);
357  }
358
359  // Emit isOp3 (1 byte)
360  if (numSrc == 3) {
361    EmitByte(1, OS);
362  } else {
363    EmitByte(0, OS);
364  }
365
366  // XXX: Emit push modifier
367    if(isFlagSet(MI, 1,  MO_FLAG_PUSH)) {
368    EmitByte(1, OS);
369  } else {
370    EmitByte(0, OS);
371  }
372
373    // XXX: Emit predicate (1 byte)
374  int PredIdx = MCDesc.findFirstPredOperandIdx();
375  if (PredIdx > -1)
376    switch(MI.getOperand(PredIdx).getReg()) {
377    case AMDGPU::PRED_SEL_ZERO:
378      EmitByte(2, OS);
379      break;
380    case AMDGPU::PRED_SEL_ONE:
381      EmitByte(3, OS);
382      break;
383    default:
384      EmitByte(0, OS);
385      break;
386    }
387  else {
388    EmitByte(0, OS);
389  }
390
391
392  // XXX: Emit bank swizzle. (1 byte)  Do we need this?  It looks like
393  // r600_asm.c sets it.
394  EmitByte(0, OS);
395
396  // XXX: Emit bank_swizzle_force (1 byte) Not sure what this is for.
397  EmitByte(0, OS);
398
399  // XXX: Emit OMOD (1 byte) Not implemented.
400  EmitByte(0, OS);
401
402  // XXX: Emit index_mode.  I think this is for indirect addressing, so we
403  // don't need to worry about it.
404  EmitByte(0, OS);
405}
406
407void R600MCCodeEmitter::EmitTexInstr(const MCInst &MI,
408                                     SmallVectorImpl<MCFixup> &Fixups,
409                                     raw_ostream &OS) const {
410
411  unsigned opcode = MI.getOpcode();
412  bool hasOffsets = (opcode == AMDGPU::TEX_LD);
413  unsigned op_offset = hasOffsets ? 3 : 0;
414  int64_t sampler = MI.getOperand(op_offset+2).getImm();
415  int64_t textureType = MI.getOperand(op_offset+3).getImm();
416  unsigned srcSelect[4] = {0, 1, 2, 3};
417
418  // Emit instruction type
419  EmitByte(1, OS);
420
421  // Emit instruction
422  EmitByte(getBinaryCodeForInstr(MI, Fixups), OS);
423
424  // XXX: Emit resource id r600_shader.c uses sampler + 1.  Why?
425  EmitByte(sampler + 1 + 1, OS);
426
427  // Emit source register
428  EmitByte(getHWReg(MI.getOperand(1).getReg()), OS);
429
430  // XXX: Emit src isRelativeAddress
431  EmitByte(0, OS);
432
433  // Emit destination register
434  EmitByte(getHWReg(MI.getOperand(0).getReg()), OS);
435
436  // XXX: Emit dst isRealtiveAddress
437  EmitByte(0, OS);
438
439  // XXX: Emit dst select
440  EmitByte(0, OS); // X
441  EmitByte(1, OS); // Y
442  EmitByte(2, OS); // Z
443  EmitByte(3, OS); // W
444
445  // XXX: Emit lod bias
446  EmitByte(0, OS);
447
448  // XXX: Emit coord types
449  unsigned coordType[4] = {1, 1, 1, 1};
450
451  if (textureType == TEXTURE_RECT
452      || textureType == TEXTURE_SHADOWRECT) {
453    coordType[ELEMENT_X] = 0;
454    coordType[ELEMENT_Y] = 0;
455  }
456
457  if (textureType == TEXTURE_1D_ARRAY
458      || textureType == TEXTURE_SHADOW1D_ARRAY) {
459    if (opcode == AMDGPU::TEX_SAMPLE_C_L || opcode == AMDGPU::TEX_SAMPLE_C_LB) {
460      coordType[ELEMENT_Y] = 0;
461    } else {
462      coordType[ELEMENT_Z] = 0;
463      srcSelect[ELEMENT_Z] = ELEMENT_Y;
464    }
465  } else if (textureType == TEXTURE_2D_ARRAY
466             || textureType == TEXTURE_SHADOW2D_ARRAY) {
467    coordType[ELEMENT_Z] = 0;
468  }
469
470  for (unsigned i = 0; i < 4; i++) {
471    EmitByte(coordType[i], OS);
472  }
473
474  // XXX: Emit offsets
475  if (hasOffsets)
476	  for (unsigned i = 2; i < 5; i++)
477		  EmitByte(MI.getOperand(i).getImm()<<1, OS);
478  else
479	  EmitNullBytes(3, OS);
480
481  // Emit sampler id
482  EmitByte(sampler, OS);
483
484  // XXX:Emit source select
485  if ((textureType == TEXTURE_SHADOW1D
486      || textureType == TEXTURE_SHADOW2D
487      || textureType == TEXTURE_SHADOWRECT
488      || textureType == TEXTURE_SHADOW1D_ARRAY)
489      && opcode != AMDGPU::TEX_SAMPLE_C_L
490      && opcode != AMDGPU::TEX_SAMPLE_C_LB) {
491    srcSelect[ELEMENT_W] = ELEMENT_Z;
492  }
493
494  for (unsigned i = 0; i < 4; i++) {
495    EmitByte(srcSelect[i], OS);
496  }
497}
498
499void R600MCCodeEmitter::EmitFCInstr(const MCInst &MI, raw_ostream &OS) const {
500
501  // Emit instruction type
502  EmitByte(INSTR_FC, OS);
503
504  // Emit SRC
505  unsigned NumOperands = MI.getNumOperands();
506  if (NumOperands > 0) {
507    assert(NumOperands == 1);
508    EmitSrc(MI, 0, OS);
509  } else {
510    EmitNullBytes(SRC_BYTE_COUNT, OS);
511  }
512
513  // Emit FC Instruction
514  enum FCInstr instr;
515  switch (MI.getOpcode()) {
516  case AMDGPU::BREAK_LOGICALZ_f32:
517    instr = FC_BREAK;
518    break;
519  case AMDGPU::BREAK_LOGICALNZ_f32:
520    instr = FC_BREAK_NZ;
521    break;
522  case AMDGPU::BREAK_LOGICALNZ_i32:
523    instr = FC_BREAK_NZ_INT;
524    break;
525  case AMDGPU::BREAK_LOGICALZ_i32:
526    instr = FC_BREAK_Z_INT;
527    break;
528  case AMDGPU::CONTINUE_LOGICALNZ_f32:
529  case AMDGPU::CONTINUE_LOGICALNZ_i32:
530    instr = FC_CONTINUE;
531    break;
532  case AMDGPU::IF_LOGICALNZ_f32:
533    instr = FC_IF;
534  case AMDGPU::IF_LOGICALNZ_i32:
535    instr = FC_IF_INT;
536    break;
537  case AMDGPU::IF_LOGICALZ_f32:
538    abort();
539    break;
540  case AMDGPU::ELSE:
541    instr = FC_ELSE;
542    break;
543  case AMDGPU::ENDIF:
544    instr = FC_ENDIF;
545    break;
546  case AMDGPU::ENDLOOP:
547    instr = FC_ENDLOOP;
548    break;
549  case AMDGPU::WHILELOOP:
550    instr = FC_BGNLOOP;
551    break;
552  default:
553    abort();
554    break;
555  }
556  EmitByte(instr, OS);
557}
558
559void R600MCCodeEmitter::EmitNullBytes(unsigned int ByteCount,
560                                      raw_ostream &OS) const {
561
562  for (unsigned int i = 0; i < ByteCount; i++) {
563    EmitByte(0, OS);
564  }
565}
566
567void R600MCCodeEmitter::EmitByte(unsigned int Byte, raw_ostream &OS) const {
568  OS.write((uint8_t) Byte & 0xff);
569}
570
571void R600MCCodeEmitter::EmitTwoBytes(unsigned int Bytes,
572                                     raw_ostream &OS) const {
573  OS.write((uint8_t) (Bytes & 0xff));
574  OS.write((uint8_t) ((Bytes >> 8) & 0xff));
575}
576
577void R600MCCodeEmitter::Emit(uint32_t Value, raw_ostream &OS) const {
578  for (unsigned i = 0; i < 4; i++) {
579    OS.write((uint8_t) ((Value >> (8 * i)) & 0xff));
580  }
581}
582
583void R600MCCodeEmitter::Emit(uint64_t Value, raw_ostream &OS) const {
584  for (unsigned i = 0; i < 8; i++) {
585    EmitByte((Value >> (8 * i)) & 0xff, OS);
586  }
587}
588
589unsigned R600MCCodeEmitter::getHWRegIndex(unsigned reg) const {
590  switch(reg) {
591  case AMDGPU::ZERO: return 248;
592  case AMDGPU::ONE:
593  case AMDGPU::NEG_ONE: return 249;
594  case AMDGPU::ONE_INT: return 250;
595  case AMDGPU::HALF:
596  case AMDGPU::NEG_HALF: return 252;
597  case AMDGPU::ALU_LITERAL_X: return 253;
598  case AMDGPU::PREDICATE_BIT:
599  case AMDGPU::PRED_SEL_OFF:
600  case AMDGPU::PRED_SEL_ZERO:
601  case AMDGPU::PRED_SEL_ONE:
602    return 0;
603  default: return getHWRegIndexGen(reg);
604  }
605}
606
607unsigned R600MCCodeEmitter::getHWRegChan(unsigned reg) const {
608  switch(reg) {
609  case AMDGPU::ZERO:
610  case AMDGPU::ONE:
611  case AMDGPU::ONE_INT:
612  case AMDGPU::NEG_ONE:
613  case AMDGPU::HALF:
614  case AMDGPU::NEG_HALF:
615  case AMDGPU::ALU_LITERAL_X:
616  case AMDGPU::PREDICATE_BIT:
617  case AMDGPU::PRED_SEL_OFF:
618  case AMDGPU::PRED_SEL_ZERO:
619  case AMDGPU::PRED_SEL_ONE:
620    return 0;
621  default: return getHWRegChanGen(reg);
622  }
623}
624unsigned R600MCCodeEmitter::getHWReg(unsigned RegNo) const {
625  unsigned HWReg;
626
627  HWReg = getHWRegIndex(RegNo);
628  if (AMDGPUMCRegisterClasses[AMDGPU::R600_CReg32RegClassID].contains(RegNo)) {
629    HWReg += 512;
630  }
631  return HWReg;
632}
633
634uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI,
635                                              const MCOperand &MO,
636                                        SmallVectorImpl<MCFixup> &Fixup) const {
637  if (MO.isReg()) {
638    return getHWReg(MO.getReg());
639  } else {
640    return MO.getImm();
641  }
642}
643
644//===----------------------------------------------------------------------===//
645// Encoding helper functions
646//===----------------------------------------------------------------------===//
647
648bool R600MCCodeEmitter::isFCOp(unsigned opcode) const {
649  switch(opcode) {
650  default: return false;
651  case AMDGPU::BREAK_LOGICALZ_f32:
652  case AMDGPU::BREAK_LOGICALNZ_i32:
653  case AMDGPU::BREAK_LOGICALZ_i32:
654  case AMDGPU::BREAK_LOGICALNZ_f32:
655  case AMDGPU::CONTINUE_LOGICALNZ_f32:
656  case AMDGPU::IF_LOGICALNZ_i32:
657  case AMDGPU::IF_LOGICALZ_f32:
658  case AMDGPU::ELSE:
659  case AMDGPU::ENDIF:
660  case AMDGPU::ENDLOOP:
661  case AMDGPU::IF_LOGICALNZ_f32:
662  case AMDGPU::WHILELOOP:
663    return true;
664  }
665}
666
667bool R600MCCodeEmitter::isTexOp(unsigned opcode) const {
668  switch(opcode) {
669  default: return false;
670  case AMDGPU::TEX_LD:
671  case AMDGPU::TEX_GET_TEXTURE_RESINFO:
672  case AMDGPU::TEX_SAMPLE:
673  case AMDGPU::TEX_SAMPLE_C:
674  case AMDGPU::TEX_SAMPLE_L:
675  case AMDGPU::TEX_SAMPLE_C_L:
676  case AMDGPU::TEX_SAMPLE_LB:
677  case AMDGPU::TEX_SAMPLE_C_LB:
678  case AMDGPU::TEX_SAMPLE_G:
679  case AMDGPU::TEX_SAMPLE_C_G:
680  case AMDGPU::TEX_GET_GRADIENTS_H:
681  case AMDGPU::TEX_GET_GRADIENTS_V:
682  case AMDGPU::TEX_SET_GRADIENTS_H:
683  case AMDGPU::TEX_SET_GRADIENTS_V:
684    return true;
685  }
686}
687
688bool R600MCCodeEmitter::isFlagSet(const MCInst &MI, unsigned Operand,
689                                  unsigned Flag) const {
690  const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode());
691  unsigned FlagIndex = GET_FLAG_OPERAND_IDX(MCDesc.TSFlags);
692  if (FlagIndex == 0) {
693    return false;
694  }
695  assert(MI.getOperand(FlagIndex).isImm());
696  return !!((MI.getOperand(FlagIndex).getImm() >>
697            (NUM_MO_FLAGS * Operand)) & Flag);
698}
699#define R600RegisterInfo R600MCCodeEmitter
700#include "R600HwRegInfo.include"
701#undef R600RegisterInfo
702
703#include "AMDGPUGenMCCodeEmitter.inc"
704