190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//===- R600MCCodeEmitter.cpp - Code Emitter for R600->Cayman GPU families -===//
290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//
390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//                     The LLVM Compiler Infrastructure
490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//
590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard// This file is distributed under the University of Illinois Open Source
690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard// License. See LICENSE.TXT for details.
790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//
890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//===----------------------------------------------------------------------===//
990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//
1090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard// This code emitters outputs bytecode that is understood by the r600g driver
1190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard// in the Mesa [1] project.  The bytecode is very similar to the hardware's ISA,
1290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard// except that the size of the instruction fields are rounded up to the
1390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard// nearest byte.
1490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//
1590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard// [1] http://www.mesa3d.org/
1690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//
1790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//===----------------------------------------------------------------------===//
1890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
1990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "R600Defines.h"
20228a6641ccddaf24a993f827af1e97379785985aTom Stellard#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
2190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "MCTargetDesc/AMDGPUMCCodeEmitter.h"
2290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "llvm/MC/MCCodeEmitter.h"
2390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "llvm/MC/MCContext.h"
2490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "llvm/MC/MCInst.h"
2590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "llvm/MC/MCInstrInfo.h"
2690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "llvm/MC/MCRegisterInfo.h"
2790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "llvm/MC/MCSubtargetInfo.h"
2890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "llvm/Support/raw_ostream.h"
2990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
3090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include <stdio.h>
3190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
3290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#define SRC_BYTE_COUNT 11
3390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#define DST_BYTE_COUNT 5
3490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
3590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardusing namespace llvm;
3690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
3790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardnamespace {
3890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
3990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardclass R600MCCodeEmitter : public AMDGPUMCCodeEmitter {
4090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  R600MCCodeEmitter(const R600MCCodeEmitter &); // DO NOT IMPLEMENT
4190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void operator=(const R600MCCodeEmitter &); // DO NOT IMPLEMENT
4290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  const MCInstrInfo &MCII;
4390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  const MCSubtargetInfo &STI;
4490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  MCContext &Ctx;
4590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
4690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardpublic:
4790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
4890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  R600MCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
4990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                    MCContext &ctx)
5090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    : MCII(mcii), STI(sti), Ctx(ctx) { }
5190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
5290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  /// EncodeInstruction - Encode the instruction and write it to the OS.
5390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
5490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                         SmallVectorImpl<MCFixup> &Fixups) const;
5590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
5690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  /// getMachineOpValue - Reutrn the encoding for an MCOperand.
5790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
5890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                     SmallVectorImpl<MCFixup> &Fixups) const;
5990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardprivate:
6090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
6190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void EmitALUInstr(const MCInst &MI, SmallVectorImpl<MCFixup> &Fixups,
6290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                    raw_ostream &OS) const;
6390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void EmitSrc(const MCInst &MI, unsigned OpIdx, raw_ostream &OS) const;
6490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void EmitDst(const MCInst &MI, raw_ostream &OS) const;
6590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void EmitALU(const MCInst &MI, unsigned numSrc,
6690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard               SmallVectorImpl<MCFixup> &Fixups,
6790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard               raw_ostream &OS) const;
6890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void EmitTexInstr(const MCInst &MI, SmallVectorImpl<MCFixup> &Fixups,
6990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                    raw_ostream &OS) const;
7090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void EmitFCInstr(const MCInst &MI, raw_ostream &OS) const;
7190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
7290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void EmitNullBytes(unsigned int byteCount, raw_ostream &OS) const;
7390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
7490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void EmitByte(unsigned int byte, raw_ostream &OS) const;
7590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
7690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void EmitTwoBytes(uint32_t bytes, raw_ostream &OS) const;
7790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
7890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void Emit(uint32_t value, raw_ostream &OS) const;
7990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  void Emit(uint64_t value, raw_ostream &OS) const;
8090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
8190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned getHWRegIndex(unsigned reg) const;
8290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned getHWRegChan(unsigned reg) const;
8390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned getHWReg(unsigned regNo) const;
8490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
8590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  bool isFCOp(unsigned opcode) const;
8690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  bool isTexOp(unsigned opcode) const;
8790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  bool isFlagSet(const MCInst &MI, unsigned Operand, unsigned Flag) const;
8890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
8990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  /// getHWRegIndexGen - Get the register's hardware index.  Implemented in
9090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  /// R600HwRegInfo.include.
9190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned getHWRegIndexGen(unsigned int Reg) const;
9290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
9390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  /// getHWRegChanGen - Get the register's channel.  Implemented in
9490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  /// R600HwRegInfo.include.
9590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned getHWRegChanGen(unsigned int Reg) const;
9690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard};
9790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
9890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard} // End anonymous namespace
9990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
10090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardenum RegElement {
10190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  ELEMENT_X = 0,
10290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  ELEMENT_Y,
10390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  ELEMENT_Z,
10490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  ELEMENT_W
10590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard};
10690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
10790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardenum InstrTypes {
10890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  INSTR_ALU = 0,
10990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  INSTR_TEX,
11090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  INSTR_FC,
11190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  INSTR_NATIVE,
11290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  INSTR_VTX
11390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard};
11490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
11590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardenum FCInstr {
11690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_IF = 0,
11790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_IF_INT,
11890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_ELSE,
11990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_ENDIF,
12090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_BGNLOOP,
12190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_ENDLOOP,
12290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_BREAK,
12390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_BREAK_NZ_INT,
12490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_CONTINUE,
12590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_BREAK_Z_INT,
12690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  FC_BREAK_NZ
12790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard};
12890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
12990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardenum TextureTypes {
13090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_1D = 1,
13190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_2D,
13290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_3D,
13390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_CUBE,
13490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_RECT,
13590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_SHADOW1D,
13690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_SHADOW2D,
13790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_SHADOWRECT,
13890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_1D_ARRAY,
13990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_2D_ARRAY,
14090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_SHADOW1D_ARRAY,
14190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  TEXTURE_SHADOW2D_ARRAY
14290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard};
14390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
14490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom StellardMCCodeEmitter *llvm::createR600MCCodeEmitter(const MCInstrInfo &MCII,
14590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                           const MCSubtargetInfo &STI,
14690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                           MCContext &Ctx) {
14790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  return new R600MCCodeEmitter(MCII, STI, Ctx);
14890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
14990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
15090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
15190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                       SmallVectorImpl<MCFixup> &Fixups) const {
15290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (isTexOp(MI.getOpcode())) {
15390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitTexInstr(MI, Fixups, OS);
15490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else if (isFCOp(MI.getOpcode())){
15590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitFCInstr(MI, OS);
15690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else if (MI.getOpcode() == AMDGPU::RETURN ||
15790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    MI.getOpcode() == AMDGPU::BUNDLE ||
15890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    MI.getOpcode() == AMDGPU::KILL) {
15990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    return;
16090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
16190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    switch(MI.getOpcode()) {
16290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    case AMDGPU::RAT_WRITE_CACHELESS_eg:
16390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      {
16490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        uint64_t inst = getBinaryCodeForInstr(MI, Fixups);
16590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        EmitByte(INSTR_NATIVE, OS);
16690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        Emit(inst, OS);
16790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        break;
16890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      }
16990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    case AMDGPU::VTX_READ_PARAM_i32_eg:
17090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    case AMDGPU::VTX_READ_PARAM_f32_eg:
17190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    case AMDGPU::VTX_READ_GLOBAL_i32_eg:
17290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    case AMDGPU::VTX_READ_GLOBAL_f32_eg:
17390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    case AMDGPU::VTX_READ_GLOBAL_v4i32_eg:
17490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    case AMDGPU::VTX_READ_GLOBAL_v4f32_eg:
17590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      {
17690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        uint64_t InstWord01 = getBinaryCodeForInstr(MI, Fixups);
17790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        uint32_t InstWord2 = MI.getOperand(2).getImm(); // Offset
17890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
17990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        EmitByte(INSTR_VTX, OS);
18090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        Emit(InstWord01, OS);
18190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        Emit(InstWord2, OS);
18290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        break;
18390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      }
18490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
18590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    default:
18690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      EmitALUInstr(MI, Fixups, OS);
18790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      break;
18890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    }
18990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
19090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
19190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
19290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::EmitALUInstr(const MCInst &MI,
19390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                     SmallVectorImpl<MCFixup> &Fixups,
19490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                     raw_ostream &OS) const {
19590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode());
19690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned NumOperands = MI.getNumOperands();
19790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
19890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if(MCDesc.findFirstPredOperandIdx() > -1)
19990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    NumOperands--;
20090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
20190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (GET_FLAG_OPERAND_IDX(MCDesc.TSFlags) != 0)
20290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    NumOperands--;
20390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
20490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if(MI.getOpcode() == AMDGPU::PRED_X)
20590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    NumOperands = 2;
20690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
20790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX Check if instruction writes a result
20890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (NumOperands < 1) {
20990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    return;
21090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
21190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
21290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit instruction type
21390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS);
21490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
21590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned int OpIndex;
21690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  for (OpIndex = 1; OpIndex < NumOperands; OpIndex++) {
21790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    // Literal constants are always stored as the last operand.
21890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    if (MI.getOperand(OpIndex).isImm() || MI.getOperand(OpIndex).isFPImm()) {
21990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      break;
22090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    }
22190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitSrc(MI, OpIndex, OS);
22290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
22390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
22490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit zeros for unused sources
22590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  for ( ; OpIndex < 4; OpIndex++) {
22690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitNullBytes(SRC_BYTE_COUNT, OS);
22790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
22890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
22990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitDst(MI, OS);
23090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
23190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitALU(MI, NumOperands - 1, Fixups, OS);
23290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
23390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
23490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::EmitSrc(const MCInst &MI, unsigned OpIdx,
23590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                raw_ostream &OS) const {
23690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  const MCOperand &MO = MI.getOperand(OpIdx);
23790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  union {
23890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    float f;
23990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    uint32_t i;
24090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } Value;
24190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  Value.i = 0;
24290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit the source select (2 bytes).  For GPRs, this is the register index.
24390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // For other potential instruction operands, (e.g. constant registers) the
24490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // value of the source select is defined in the r600isa docs.
24590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (MO.isReg()) {
24690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    unsigned reg = MO.getReg();
24790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitTwoBytes(getHWReg(reg), OS);
24890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    if (reg == AMDGPU::ALU_LITERAL_X) {
24990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      unsigned ImmOpIndex = MI.getNumOperands() - 1;
25090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      MCOperand ImmOp = MI.getOperand(ImmOpIndex);
25190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      if (ImmOp.isFPImm()) {
25290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        Value.f = ImmOp.getFPImm();
25390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      } else {
25490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        assert(ImmOp.isImm());
25590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard        Value.i = ImmOp.getImm();
25690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      }
25790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    }
25890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
25990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    // XXX: Handle other operand types.
26090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitTwoBytes(0, OS);
26190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
26290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
26390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit the source channel (1 byte)
26490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (MO.isReg()) {
26590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(getHWRegChan(MO.getReg()), OS);
26690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
26790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(0, OS);
26890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
26990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
27090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit isNegated (1 byte)
27190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if ((!(isFlagSet(MI, OpIdx, MO_FLAG_ABS)))
27290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      && (isFlagSet(MI, OpIdx, MO_FLAG_NEG) ||
27390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard     (MO.isReg() &&
27490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      (MO.getReg() == AMDGPU::NEG_ONE || MO.getReg() == AMDGPU::NEG_HALF)))){
27590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(1, OS);
27690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
27790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(0, OS);
27890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
27990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
28090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit isAbsolute (1 byte)
28190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (isFlagSet(MI, OpIdx, MO_FLAG_ABS)) {
28290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(1, OS);
28390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
28490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(0, OS);
28590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
28690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
28790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit relative addressing mode (1 byte)
28890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS);
28990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
29090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit kc_bank, This will be adjusted later by r600_asm
29190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS);
29290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
29390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit the literal value, if applicable (4 bytes).
29490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  Emit(Value.i, OS);
29590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
29690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
29790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
29890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::EmitDst(const MCInst &MI, raw_ostream &OS) const {
29990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
30090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  const MCOperand &MO = MI.getOperand(0);
30190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (MO.isReg() && MO.getReg() != AMDGPU::PREDICATE_BIT) {
30290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    // Emit the destination register index (1 byte)
30390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(getHWReg(MO.getReg()), OS);
30490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
30590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    // Emit the element of the destination register (1 byte)
30690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(getHWRegChan(MO.getReg()), OS);
30790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
30890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    // Emit isClamped (1 byte)
30990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    if (isFlagSet(MI, 0, MO_FLAG_CLAMP)) {
31090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      EmitByte(1, OS);
31190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    } else {
31290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      EmitByte(0, OS);
31390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    }
31490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
31590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    // Emit writemask (1 byte).
31690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    if (isFlagSet(MI, 0, MO_FLAG_MASK)) {
31790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      EmitByte(0, OS);
31890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    } else {
31990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      EmitByte(1, OS);
32090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    }
32190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
32290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    // XXX: Emit relative addressing mode
32390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(0, OS);
32490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
32590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    // XXX: Handle other operand types.  Are there any for destination regs?
32690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitNullBytes(DST_BYTE_COUNT, OS);
32790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
32890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
32990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
33090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::EmitALU(const MCInst &MI, unsigned numSrc,
33190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                SmallVectorImpl<MCFixup> &Fixups,
33290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                raw_ostream &OS) const {
33390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode());
33490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
33590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit the instruction (2 bytes)
33690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitTwoBytes(getBinaryCodeForInstr(MI, Fixups), OS);
33790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
33890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit IsLast (for this instruction group) (1 byte)
33990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (isFlagSet(MI, 0, MO_FLAG_NOT_LAST)) {
34090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(0, OS);
34190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
34290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(1, OS);
34390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
34490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
34590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit isOp3 (1 byte)
34690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (numSrc == 3) {
34790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(1, OS);
34890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
34990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(0, OS);
35090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
35190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
35290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit push modifier
35390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    if(isFlagSet(MI, 1,  MO_FLAG_PUSH)) {
35490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(1, OS);
35590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
35690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(0, OS);
35790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
35890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
35990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    // XXX: Emit predicate (1 byte)
36090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  int PredIdx = MCDesc.findFirstPredOperandIdx();
36190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (PredIdx > -1)
36290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    switch(MI.getOperand(PredIdx).getReg()) {
36390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    case AMDGPU::PRED_SEL_ZERO:
36490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      EmitByte(2, OS);
36590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      break;
36690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    case AMDGPU::PRED_SEL_ONE:
36790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      EmitByte(3, OS);
36890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      break;
36990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    default:
37090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      EmitByte(0, OS);
37190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      break;
37290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    }
37390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  else {
37490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(0, OS);
37590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
37690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
37790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
37890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit bank swizzle. (1 byte)  Do we need this?  It looks like
37990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // r600_asm.c sets it.
38090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS);
38190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
38290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit bank_swizzle_force (1 byte) Not sure what this is for.
38390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS);
38490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
38590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit OMOD (1 byte) Not implemented.
38690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS);
38790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
38890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit index_mode.  I think this is for indirect addressing, so we
38990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // don't need to worry about it.
39090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS);
39190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
39290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
39390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::EmitTexInstr(const MCInst &MI,
39490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                     SmallVectorImpl<MCFixup> &Fixups,
39590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                     raw_ostream &OS) const {
39690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
39790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned opcode = MI.getOpcode();
39890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  bool hasOffsets = (opcode == AMDGPU::TEX_LD);
39990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned op_offset = hasOffsets ? 3 : 0;
40090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  int64_t sampler = MI.getOperand(op_offset+2).getImm();
40190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  int64_t textureType = MI.getOperand(op_offset+3).getImm();
40290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned srcSelect[4] = {0, 1, 2, 3};
40390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
40490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit instruction type
40590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(1, OS);
40690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
40790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit instruction
40890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(getBinaryCodeForInstr(MI, Fixups), OS);
40990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
41090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit resource id r600_shader.c uses sampler + 1.  Why?
41190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(sampler + 1 + 1, OS);
41290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
41390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit source register
41490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(getHWReg(MI.getOperand(1).getReg()), OS);
41590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
41690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit src isRelativeAddress
41790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS);
41890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
41990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit destination register
42090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(getHWReg(MI.getOperand(0).getReg()), OS);
42190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
42290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit dst isRealtiveAddress
42390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS);
42490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
42590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit dst select
42690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS); // X
42790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(1, OS); // Y
42890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(2, OS); // Z
42990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(3, OS); // W
43090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
43190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit lod bias
43290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(0, OS);
43390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
43490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit coord types
43590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned coordType[4] = {1, 1, 1, 1};
43690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
43790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (textureType == TEXTURE_RECT
43890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      || textureType == TEXTURE_SHADOWRECT) {
43990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    coordType[ELEMENT_X] = 0;
44090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    coordType[ELEMENT_Y] = 0;
44190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
44290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
44390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (textureType == TEXTURE_1D_ARRAY
44490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      || textureType == TEXTURE_SHADOW1D_ARRAY) {
44590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    if (opcode == AMDGPU::TEX_SAMPLE_C_L || opcode == AMDGPU::TEX_SAMPLE_C_LB) {
44690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      coordType[ELEMENT_Y] = 0;
44790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    } else {
44890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      coordType[ELEMENT_Z] = 0;
44990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      srcSelect[ELEMENT_Z] = ELEMENT_Y;
45090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    }
45190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else if (textureType == TEXTURE_2D_ARRAY
45290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard             || textureType == TEXTURE_SHADOW2D_ARRAY) {
45390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    coordType[ELEMENT_Z] = 0;
45490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
45590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
45690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  for (unsigned i = 0; i < 4; i++) {
45790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(coordType[i], OS);
45890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
45990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
46090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX: Emit offsets
46190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (hasOffsets)
46290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard	  for (unsigned i = 2; i < 5; i++)
46390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard		  EmitByte(MI.getOperand(i).getImm()<<1, OS);
46490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  else
46590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard	  EmitNullBytes(3, OS);
46690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
46790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit sampler id
46890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(sampler, OS);
46990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
47090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // XXX:Emit source select
47190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if ((textureType == TEXTURE_SHADOW1D
47290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      || textureType == TEXTURE_SHADOW2D
47390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      || textureType == TEXTURE_SHADOWRECT
47490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      || textureType == TEXTURE_SHADOW1D_ARRAY)
47590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      && opcode != AMDGPU::TEX_SAMPLE_C_L
47690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard      && opcode != AMDGPU::TEX_SAMPLE_C_LB) {
47790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    srcSelect[ELEMENT_W] = ELEMENT_Z;
47890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
47990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
48090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  for (unsigned i = 0; i < 4; i++) {
48190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(srcSelect[i], OS);
48290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
48390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
48490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
48590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::EmitFCInstr(const MCInst &MI, raw_ostream &OS) const {
48690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
48790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit instruction type
48890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(INSTR_FC, OS);
48990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
49090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit SRC
49190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned NumOperands = MI.getNumOperands();
49290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (NumOperands > 0) {
49390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    assert(NumOperands == 1);
49490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitSrc(MI, 0, OS);
49590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
49690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitNullBytes(SRC_BYTE_COUNT, OS);
49790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
49890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
49990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  // Emit FC Instruction
50090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  enum FCInstr instr;
50190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  switch (MI.getOpcode()) {
50290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::BREAK_LOGICALZ_f32:
50390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_BREAK;
50490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
50590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::BREAK_LOGICALNZ_f32:
50690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_BREAK_NZ;
50790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
50890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::BREAK_LOGICALNZ_i32:
50990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_BREAK_NZ_INT;
51090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
51190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::BREAK_LOGICALZ_i32:
51290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_BREAK_Z_INT;
51390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
51490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::CONTINUE_LOGICALNZ_f32:
51590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::CONTINUE_LOGICALNZ_i32:
51690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_CONTINUE;
51790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
51890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::IF_LOGICALNZ_f32:
51990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_IF;
52090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::IF_LOGICALNZ_i32:
52190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_IF_INT;
52290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
52390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::IF_LOGICALZ_f32:
52490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    abort();
52590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
52690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ELSE:
52790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_ELSE;
52890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
52990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ENDIF:
53090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_ENDIF;
53190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
53290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ENDLOOP:
53390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_ENDLOOP;
53490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
53590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::WHILELOOP:
53690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    instr = FC_BGNLOOP;
53790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
53890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  default:
53990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    abort();
54090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    break;
54190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
54290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  EmitByte(instr, OS);
54390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
54490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
54590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::EmitNullBytes(unsigned int ByteCount,
54690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                      raw_ostream &OS) const {
54790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
54890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  for (unsigned int i = 0; i < ByteCount; i++) {
54990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte(0, OS);
55090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
55190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
55290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
55390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::EmitByte(unsigned int Byte, raw_ostream &OS) const {
55490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  OS.write((uint8_t) Byte & 0xff);
55590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
55690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
55790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::EmitTwoBytes(unsigned int Bytes,
55890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                     raw_ostream &OS) const {
55990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  OS.write((uint8_t) (Bytes & 0xff));
56090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  OS.write((uint8_t) ((Bytes >> 8) & 0xff));
56190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
56290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
56390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::Emit(uint32_t Value, raw_ostream &OS) const {
56490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  for (unsigned i = 0; i < 4; i++) {
56590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    OS.write((uint8_t) ((Value >> (8 * i)) & 0xff));
56690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
56790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
56890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
56990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardvoid R600MCCodeEmitter::Emit(uint64_t Value, raw_ostream &OS) const {
57090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  for (unsigned i = 0; i < 8; i++) {
57190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    EmitByte((Value >> (8 * i)) & 0xff, OS);
57290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
57390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
57490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
57590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardunsigned R600MCCodeEmitter::getHWRegIndex(unsigned reg) const {
57690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  switch(reg) {
57790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ZERO: return 248;
57890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ONE:
57990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::NEG_ONE: return 249;
58090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ONE_INT: return 250;
58190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::HALF:
58290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::NEG_HALF: return 252;
58390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ALU_LITERAL_X: return 253;
58490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::PREDICATE_BIT:
58590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::PRED_SEL_OFF:
58690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::PRED_SEL_ZERO:
58790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::PRED_SEL_ONE:
58890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    return 0;
58990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  default: return getHWRegIndexGen(reg);
59090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
59190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
59290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
59390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardunsigned R600MCCodeEmitter::getHWRegChan(unsigned reg) const {
59490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  switch(reg) {
59590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ZERO:
59690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ONE:
59790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ONE_INT:
59890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::NEG_ONE:
59990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::HALF:
60090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::NEG_HALF:
60190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ALU_LITERAL_X:
60290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::PREDICATE_BIT:
60390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::PRED_SEL_OFF:
60490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::PRED_SEL_ZERO:
60590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::PRED_SEL_ONE:
60690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    return 0;
60790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  default: return getHWRegChanGen(reg);
60890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
60990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
61090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardunsigned R600MCCodeEmitter::getHWReg(unsigned RegNo) const {
61190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned HWReg;
61290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
61390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  HWReg = getHWRegIndex(RegNo);
61490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (AMDGPUMCRegisterClasses[AMDGPU::R600_CReg32RegClassID].contains(RegNo)) {
61590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    HWReg += 512;
61690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
61790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  return HWReg;
61890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
61990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
62090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellarduint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI,
62190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                              const MCOperand &MO,
62290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                        SmallVectorImpl<MCFixup> &Fixup) const {
62390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (MO.isReg()) {
62490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    return getHWReg(MO.getReg());
62590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  } else {
62690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    return MO.getImm();
62790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
62890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
62990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
63090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//===----------------------------------------------------------------------===//
63190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard// Encoding helper functions
63290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard//===----------------------------------------------------------------------===//
63390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
63490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardbool R600MCCodeEmitter::isFCOp(unsigned opcode) const {
63590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  switch(opcode) {
63690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  default: return false;
63790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::BREAK_LOGICALZ_f32:
63890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::BREAK_LOGICALNZ_i32:
63990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::BREAK_LOGICALZ_i32:
64090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::BREAK_LOGICALNZ_f32:
64190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::CONTINUE_LOGICALNZ_f32:
64290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::IF_LOGICALNZ_i32:
64390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::IF_LOGICALZ_f32:
64490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ELSE:
64590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ENDIF:
64690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::ENDLOOP:
64790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::IF_LOGICALNZ_f32:
64890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::WHILELOOP:
64990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    return true;
65090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
65190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
65290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
65390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardbool R600MCCodeEmitter::isTexOp(unsigned opcode) const {
65490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  switch(opcode) {
65590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  default: return false;
65690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_LD:
65790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_GET_TEXTURE_RESINFO:
65890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_SAMPLE:
65990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_SAMPLE_C:
66090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_SAMPLE_L:
66190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_SAMPLE_C_L:
66290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_SAMPLE_LB:
66390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_SAMPLE_C_LB:
66490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_SAMPLE_G:
66590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_SAMPLE_C_G:
66690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_GET_GRADIENTS_H:
66790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_GET_GRADIENTS_V:
66890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_SET_GRADIENTS_H:
66990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  case AMDGPU::TEX_SET_GRADIENTS_V:
67090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    return true;
67190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
67290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
67390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
67490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellardbool R600MCCodeEmitter::isFlagSet(const MCInst &MI, unsigned Operand,
67590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard                                  unsigned Flag) const {
67690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  const MCInstrDesc &MCDesc = MCII.get(MI.getOpcode());
67790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  unsigned FlagIndex = GET_FLAG_OPERAND_IDX(MCDesc.TSFlags);
67890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  if (FlagIndex == 0) {
67990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard    return false;
68090bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  }
68190bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  assert(MI.getOperand(FlagIndex).isImm());
68290bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard  return !!((MI.getOperand(FlagIndex).getImm() >>
68390bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard            (NUM_MO_FLAGS * Operand)) & Flag);
68490bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard}
68590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#define R600RegisterInfo R600MCCodeEmitter
68690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "R600HwRegInfo.include"
68790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#undef R600RegisterInfo
68890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard
68990bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard#include "AMDGPUGenMCCodeEmitter.inc"
690