/*
 * Copyright 2011 Christoph Bumiller
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#ifndef __NV50_IR_H__
#define __NV50_IR_H__

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <deque>
#include <list>
#include <vector>

#include "nv50_ir_util.h"
#include "nv50_ir_graph.h"

#include "nv50_ir_driver.h"

namespace nv50_ir {

enum operation
{
   OP_NOP = 0,
   OP_PHI,
   OP_UNION, // unify a new definition and several source values
   OP_SPLIT, // $r0d -> { $r0, $r1 } ($r0d and $r0/$r1 will be coalesced)
   OP_MERGE, // opposite of split, e.g. combine 2 32 bit into a 64 bit value
   OP_CONSTRAINT, // copy values into consecutive registers
   OP_MOV, // simple copy, no modifiers allowed
   OP_LOAD,
   OP_STORE,
   OP_ADD,
   OP_SUB,
   OP_MUL,
   OP_DIV,
   OP_MOD,
   OP_MAD,
   OP_FMA,
   OP_SAD, // abs(src0 - src1) + src2
   OP_ABS,
   OP_NEG,
   OP_NOT,
   OP_AND,
   OP_OR,
   OP_XOR,
   OP_SHL,
   OP_SHR,
   OP_MAX,
   OP_MIN,
   OP_SAT,  // CLAMP(f32, 0.0, 1.0)
   OP_CEIL,
   OP_FLOOR,
   OP_TRUNC,
   OP_CVT,
   OP_SET_AND, // dst = (src0 CMP src1) & src2
   OP_SET_OR,
   OP_SET_XOR,
   OP_SET,
   OP_SELP, // dst = src2 ? src0 : src1
   OP_SLCT, // dst = (src2 CMP 0) ? src0 : src1
   OP_RCP,
   OP_RSQ,
   OP_LG2,
   OP_SIN,
   OP_COS,
   OP_EX2,
   OP_EXP, // exponential (base M_E)
   OP_LOG, // natural logarithm
   OP_PRESIN,
   OP_PREEX2,
   OP_SQRT,
   OP_POW,
   OP_BRA,
   OP_CALL,
   OP_RET,
   OP_CONT,
   OP_BREAK,
   OP_PRERET,
   OP_PRECONT,
   OP_PREBREAK,
   OP_BRKPT,     // breakpoint (not related to loops)
   OP_JOINAT,    // push control flow convergence point
   OP_JOIN,      // converge
   OP_DISCARD,
   OP_EXIT,
   OP_MEMBAR,
   OP_VFETCH, // indirection 0 in attribute space, indirection 1 is vertex base
   OP_PFETCH, // fetch base address of vertex src0 (immediate) [+ src1]
   OP_EXPORT,
   OP_LINTERP,
   OP_PINTERP,
   OP_EMIT,    // emit vertex
   OP_RESTART, // restart primitive
   OP_TEX,
   OP_TXB, // texture bias
   OP_TXL, // texure lod
   OP_TXF, // texel fetch
   OP_TXQ, // texture size query
   OP_TXD, // texture derivatives
   OP_TXG, // texture gather
   OP_TEXCSAA,
   OP_SULD, // surface load
   OP_SUST, // surface store
   OP_DFDX,
   OP_DFDY,
   OP_RDSV, // read system value
   OP_WRSV, // write system value
   OP_PIXLD,
   OP_QUADOP,
   OP_QUADON,
   OP_QUADPOP,
   OP_POPCNT, // bitcount(src0 & src1)
   OP_INSBF,  // insert first src1[8:15] bits of src0 into src2 at src1[0:7]
   OP_EXTBF,
   OP_TEXBAR,
   OP_LAST
};

// various instruction-specific modifier definitions Instruction::subOp
// MOV_FINAL marks a MOV originating from an EXPORT (used for placing TEXBARs)
#define NV50_IR_SUBOP_MUL_HIGH     1
#define NV50_IR_SUBOP_EMIT_RESTART 1
#define NV50_IR_SUBOP_LDC_IL       1
#define NV50_IR_SUBOP_LDC_IS       2
#define NV50_IR_SUBOP_LDC_ISL      3
#define NV50_IR_SUBOP_SHIFT_WRAP   1
#define NV50_IR_SUBOP_EMU_PRERET   1
#define NV50_IR_SUBOP_TEXBAR(n)    n
#define NV50_IR_SUBOP_MOV_FINAL    1

enum DataType
{
   TYPE_NONE,
   TYPE_U8,
   TYPE_S8,
   TYPE_U16,
   TYPE_S16,
   TYPE_U32,
   TYPE_S32,
   TYPE_U64, // 64 bit operations are only lowered after register allocation
   TYPE_S64,
   TYPE_F16,
   TYPE_F32,
   TYPE_F64,
   TYPE_B96,
   TYPE_B128
};

enum CondCode
{
   CC_FL = 0,
   CC_NEVER = CC_FL, // when used with FILE_FLAGS
   CC_LT = 1,
   CC_EQ = 2,
   CC_NOT_P = CC_EQ, // when used with FILE_PREDICATE
   CC_LE = 3,
   CC_GT = 4,
   CC_NE = 5,
   CC_P  = CC_NE,
   CC_GE = 6,
   CC_TR = 7,
   CC_ALWAYS = CC_TR,
   CC_U  = 8,
   CC_LTU = 9,
   CC_EQU = 10,
   CC_LEU = 11,
   CC_GTU = 12,
   CC_NEU = 13,
   CC_GEU = 14,
   CC_NO = 0x10,
   CC_NC = 0x11,
   CC_NS = 0x12,
   CC_NA = 0x13,
   CC_A  = 0x14,
   CC_S  = 0x15,
   CC_C  = 0x16,
   CC_O  = 0x17
};

enum RoundMode
{
   ROUND_N, // nearest
   ROUND_M, // towards -inf
   ROUND_Z, // towards 0
   ROUND_P, // towards +inf
   ROUND_NI, // nearest integer
   ROUND_MI, // to integer towards -inf
   ROUND_ZI, // to integer towards 0
   ROUND_PI, // to integer towards +inf
};

enum CacheMode
{
   CACHE_CA,            // cache at all levels
   CACHE_WB = CACHE_CA, // cache write back
   CACHE_CG,            // cache at global level
   CACHE_CS,            // cache streaming
   CACHE_CV,            // cache as volatile
   CACHE_WT = CACHE_CV  // cache write-through
};

enum DataFile
{
   FILE_NULL = 0,
   FILE_GPR,
   FILE_PREDICATE,       // boolean predicate
   FILE_FLAGS,           // zero/sign/carry/overflow bits
   FILE_ADDRESS,
   LAST_REGISTER_FILE = FILE_ADDRESS,
   FILE_IMMEDIATE,
   FILE_MEMORY_CONST,
   FILE_SHADER_INPUT,
   FILE_SHADER_OUTPUT,
   FILE_MEMORY_GLOBAL,
   FILE_MEMORY_SHARED,
   FILE_MEMORY_LOCAL,
   FILE_SYSTEM_VALUE,
   DATA_FILE_COUNT
};

enum TexTarget
{
   TEX_TARGET_1D,
   TEX_TARGET_2D,
   TEX_TARGET_2D_MS,
   TEX_TARGET_3D,
   TEX_TARGET_CUBE,
   TEX_TARGET_1D_SHADOW,
   TEX_TARGET_2D_SHADOW,
   TEX_TARGET_CUBE_SHADOW,
   TEX_TARGET_1D_ARRAY,
   TEX_TARGET_2D_ARRAY,
   TEX_TARGET_2D_MS_ARRAY,
   TEX_TARGET_CUBE_ARRAY,
   TEX_TARGET_1D_ARRAY_SHADOW,
   TEX_TARGET_2D_ARRAY_SHADOW,
   TEX_TARGET_RECT,
   TEX_TARGET_RECT_SHADOW,
   TEX_TARGET_CUBE_ARRAY_SHADOW,
   TEX_TARGET_BUFFER,
   TEX_TARGET_COUNT
};

enum SVSemantic
{
   SV_POSITION, // WPOS
   SV_VERTEX_ID,
   SV_INSTANCE_ID,
   SV_INVOCATION_ID,
   SV_PRIMITIVE_ID,
   SV_VERTEX_COUNT, // gl_PatchVerticesIn
   SV_LAYER,
   SV_VIEWPORT_INDEX,
   SV_YDIR,
   SV_FACE,
   SV_POINT_SIZE,
   SV_POINT_COORD,
   SV_CLIP_DISTANCE,
   SV_SAMPLE_INDEX,
   SV_TESS_FACTOR,
   SV_TESS_COORD,
   SV_TID,
   SV_CTAID,
   SV_NTID,
   SV_GRIDID,
   SV_NCTAID,
   SV_LANEID,
   SV_PHYSID,
   SV_NPHYSID,
   SV_CLOCK,
   SV_LBASE,
   SV_SBASE,
   SV_UNDEFINED,
   SV_LAST
};

class Program;
class Function;
class BasicBlock;

class Target;

class Instruction;
class CmpInstruction;
class TexInstruction;
class FlowInstruction;

class Value;
class LValue;
class Symbol;
class ImmediateValue;

struct Storage
{
   DataFile file;
   int8_t fileIndex; // signed, may be indirect for CONST[]
   uint8_t size; // this should match the Instruction type's size
   DataType type; // mainly for pretty printing
   union {
      uint64_t u64;    // immediate values
      uint32_t u32;
      uint16_t u16;
      uint8_t u8;
      int64_t s64;
      int32_t s32;
      int16_t s16;
      int8_t s8;
      float f32;
      double f64;
      int32_t offset; // offset from 0 (base of address space)
      int32_t id;     // register id (< 0 if virtual/unassigned, in units <= 4)
      struct {
         SVSemantic sv;
         int index;
      } sv;
   } data;
};

// precedence: NOT after SAT after NEG after ABS
#define NV50_IR_MOD_ABS (1 << 0)
#define NV50_IR_MOD_NEG (1 << 1)
#define NV50_IR_MOD_SAT (1 << 2)
#define NV50_IR_MOD_NOT (1 << 3)
#define NV50_IR_MOD_NEG_ABS (NV50_IR_MOD_NEG | NV50_IR_MOD_ABS)

#define NV50_IR_INTERP_MODE_MASK   0x3
#define NV50_IR_INTERP_LINEAR      (0 << 0)
#define NV50_IR_INTERP_PERSPECTIVE (1 << 0)
#define NV50_IR_INTERP_FLAT        (2 << 0)
#define NV50_IR_INTERP_SC          (3 << 0) // what exactly is that ?
#define NV50_IR_INTERP_SAMPLE_MASK 0xc
#define NV50_IR_INTERP_DEFAULT     (0 << 2)
#define NV50_IR_INTERP_CENTROID    (1 << 2)
#define NV50_IR_INTERP_OFFSET      (2 << 2)
#define NV50_IR_INTERP_SAMPLEID    (3 << 2)

// do we really want this to be a class ?
class Modifier
{
public:
   Modifier() : bits(0) { }
   Modifier(unsigned int m) : bits(m) { }
   Modifier(operation op);

   // @return new Modifier applying a after b (asserts if unrepresentable)
   Modifier operator*(const Modifier) const;
   Modifier operator*=(const Modifier m) { *this = *this * m; return *this; }
   Modifier operator==(const Modifier m) const { return m.bits == bits; }
   Modifier operator!=(const Modifier m) const { return m.bits != bits; }

   inline Modifier operator&(const Modifier m) const { return bits & m.bits; }
   inline Modifier operator|(const Modifier m) const { return bits | m.bits; }
   inline Modifier operator^(const Modifier m) const { return bits ^ m.bits; }

   operation getOp() const;

   inline int neg() const { return (bits & NV50_IR_MOD_NEG) ? 1 : 0; }
   inline int abs() const { return (bits & NV50_IR_MOD_ABS) ? 1 : 0; }

   inline operator bool() const { return bits ? true : false; }

   void applyTo(ImmediateValue &imm) const;

   int print(char *buf, size_t size) const;

private:
   uint8_t bits;
};

class ValueRef
{
public:
   ValueRef(Value * = NULL);
   ValueRef(const ValueRef&);
   ~ValueRef();

   inline bool exists() const { return value != NULL; }

   void set(Value *);
   void set(const ValueRef&);
   inline Value *get() const { return value; }
   inline Value *rep() const;

   inline Instruction *getInsn() const { return insn; }
   inline void setInsn(Instruction *inst) { insn = inst; }

   inline bool isIndirect(int dim) const { return indirect[dim] >= 0; }
   inline const ValueRef *getIndirect(int dim) const;

   inline DataFile getFile() const;
   inline unsigned getSize() const;

   // SSA: return eventual (traverse MOVs) literal value, if it exists
   bool getImmediate(ImmediateValue&) const;

public:
   Modifier mod;
   int8_t indirect[2]; // >= 0 if relative to lvalue in insn->src(indirect[i])
   uint8_t swizzle;

   bool usedAsPtr; // for printing

private:
   Value *value;
   Instruction *insn;
};

class ValueDef
{
public:
   ValueDef(Value * = NULL);
   ValueDef(const ValueDef&);
   ~ValueDef();

   inline bool exists() const { return value != NULL; }

   inline Value *get() const { return value; }
   inline Value *rep() const;
   void set(Value *);
   bool mayReplace(const ValueRef &);
   void replace(const ValueRef &, bool doSet); // replace all uses of the old value

   inline Instruction *getInsn() const { return insn; }
   inline void setInsn(Instruction *inst) { insn = inst; }

   inline DataFile getFile() const;
   inline unsigned getSize() const;

   inline void setSSA(LValue *);
   inline const LValue *preSSA() const;

private:
   Value *value;   // should make this LValue * ...
   LValue *origin; // pre SSA value
   Instruction *insn;
};

class Value
{
public:
   Value();
   virtual ~Value() { }

   virtual Value *clone(ClonePolicy<Function>&) const = 0;

   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const = 0;

   virtual bool equals(const Value *, bool strict = false) const;
   virtual bool interfers(const Value *) const;
   virtual bool isUniform() const { return true; }

   inline Value *rep() const { return join; }

   inline Instruction *getUniqueInsn() const;
   inline Instruction *getInsn() const; // use when uniqueness is certain

   inline int refCount() { return uses.size(); }

   inline LValue *asLValue();
   inline Symbol *asSym();
   inline ImmediateValue *asImm();
   inline const Symbol *asSym() const;
   inline const ImmediateValue *asImm() const;

   inline bool inFile(DataFile f) { return reg.file == f; }

   static inline Value *get(Iterator&);

   std::list<ValueRef *> uses;
   std::list<ValueDef *> defs;
   typedef std::list<ValueRef *>::iterator UseIterator;
   typedef std::list<ValueRef *>::const_iterator UseCIterator;
   typedef std::list<ValueDef *>::iterator DefIterator;
   typedef std::list<ValueDef *>::const_iterator DefCIterator;

   int id;
   Storage reg;

   // TODO: these should be in LValue:
   Interval livei;
   Value *join;
};

class LValue : public Value
{
public:
   LValue(Function *, DataFile file);
   LValue(Function *, LValue *);
   ~LValue() { }

   virtual bool isUniform() const;

   virtual LValue *clone(ClonePolicy<Function>&) const;

   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const;

public:
   unsigned compMask : 8; // compound/component mask
   unsigned compound : 1; // used by RA, value involved in split/merge
   unsigned ssa      : 1;
   unsigned fixedReg : 1; // set & used by RA, earlier just use (id < 0)
   unsigned noSpill  : 1; // do not spill (e.g. if spill temporary already)
};

class Symbol : public Value
{
public:
   Symbol(Program *, DataFile file = FILE_MEMORY_CONST, ubyte fileIdx = 0);
   ~Symbol() { }

   virtual Symbol *clone(ClonePolicy<Function>&) const;

   virtual bool equals(const Value *that, bool strict) const;

   virtual bool isUniform() const;

   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const;

   // print with indirect values
   int print(char *, size_t, Value *, Value *, DataType ty = TYPE_NONE) const;

   inline void setFile(DataFile file, ubyte fileIndex = 0)
   {
      reg.file = file;
      reg.fileIndex = fileIndex;
   }

   inline void setOffset(int32_t offset);
   inline void setAddress(Symbol *base, int32_t offset);
   inline void setSV(SVSemantic sv, uint32_t idx = 0);

   inline const Symbol *getBase() const { return baseSym; }

private:
   Symbol *baseSym; // array base for Symbols representing array elements
};

class ImmediateValue : public Value
{
public:
   ImmediateValue() { }
   ImmediateValue(Program *, uint32_t);
   ImmediateValue(Program *, float);
   ImmediateValue(Program *, double);
   // NOTE: not added to program with
   ImmediateValue(const ImmediateValue *, DataType ty);
   ~ImmediateValue() { };

   virtual ImmediateValue *clone(ClonePolicy<Function>&) const;

   virtual bool equals(const Value *that, bool strict) const;

   // these only work if 'type' is valid (we mostly use untyped literals):
   bool isInteger(const int ival) const; // ival is cast to this' type
   bool isNegative() const;
   bool isPow2() const;

   void applyLog2();

   // for constant folding:
   ImmediateValue operator+(const ImmediateValue&) const;
   ImmediateValue operator-(const ImmediateValue&) const;
   ImmediateValue operator*(const ImmediateValue&) const;
   ImmediateValue operator/(const ImmediateValue&) const;

   ImmediateValue& operator=(const ImmediateValue&); // only sets value !

   bool compare(CondCode cc, float fval) const;

   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const;
};

class Instruction
{
public:
   Instruction();
   Instruction(Function *, operation, DataType);
   virtual ~Instruction();

   virtual Instruction *clone(ClonePolicy<Function>&,
                              Instruction * = NULL) const;

   void setDef(int i, Value *);
   void setSrc(int s, Value *);
   void setSrc(int s, const ValueRef&);
   void swapSources(int a, int b);
   void moveSources(int s, int delta); // NOTE: only delta > 0 implemented
   bool setIndirect(int s, int dim, Value *);

   inline ValueRef& src(int s) { return srcs[s]; }
   inline ValueDef& def(int s) { return defs[s]; }
   inline const ValueRef& src(int s) const { return srcs[s]; }
   inline const ValueDef& def(int s) const { return defs[s]; }

   inline Value *getDef(int d) const { return defs[d].get(); }
   inline Value *getSrc(int s) const { return srcs[s].get(); }
   inline Value *getIndirect(int s, int dim) const;

   inline bool defExists(unsigned d) const
   {
      return d < defs.size() && defs[d].exists();
   }
   inline bool srcExists(unsigned s) const
   {
      return s < srcs.size() && srcs[s].exists();
   }

   inline bool constrainedDefs() const;

   bool setPredicate(CondCode ccode, Value *);
   inline Value *getPredicate() const;
   bool writesPredicate() const;
   inline bool isPredicated() const { return predSrc >= 0; }

   inline void setFlagsSrc(int s, Value *);
   inline void setFlagsDef(int d, Value *);

   unsigned int defCount() const { return defs.size(); };
   unsigned int defCount(unsigned int mask, bool singleFile = false) const;
   unsigned int srcCount() const { return srcs.size(); };
   unsigned int srcCount(unsigned int mask, bool singleFile = false) const;

   // save & remove / set indirect[0,1] and predicate source
   void takeExtraSources(int s, Value *[3]);
   void putExtraSources(int s, Value *[3]);

   inline void setType(DataType type) { dType = sType = type; }

   inline void setType(DataType dtype, DataType stype)
   {
      dType = dtype;
      sType = stype;
   }

   inline bool isPseudo() const { return op < OP_MOV; }
   bool isDead() const;
   bool isNop() const;
   bool isCommutationLegal(const Instruction *) const; // must be adjacent !
   bool isActionEqual(const Instruction *) const;
   bool isResultEqual(const Instruction *) const;

   void print() const;

   inline CmpInstruction *asCmp();
   inline TexInstruction *asTex();
   inline FlowInstruction *asFlow();
   inline const TexInstruction *asTex() const;
   inline const CmpInstruction *asCmp() const;
   inline const FlowInstruction *asFlow() const;

public:
   Instruction *next;
   Instruction *prev;
   int id;
   int serial; // CFG order

   operation op;
   DataType dType; // destination or defining type
   DataType sType; // source or secondary type
   CondCode cc;
   RoundMode rnd;
   CacheMode cache;

   uint8_t subOp; // quadop, 1 for mul-high, etc.

   uint8_t sched; // scheduling data (NOTE: maybe move to separate storage)

   unsigned encSize    : 4; // encoding size in bytes
   unsigned saturate   : 1; // to [0.0f, 1.0f]
   unsigned join       : 1; // converge control flow (use OP_JOIN until end)
   unsigned fixed      : 1; // prevent dead code elimination
   unsigned terminator : 1; // end of basic block
   unsigned atomic     : 1;
   unsigned ftz        : 1; // flush denormal to zero
   unsigned dnz        : 1; // denormals, NaN are zero
   unsigned ipa        : 4; // interpolation mode
   unsigned lanes      : 4;
   unsigned perPatch   : 1;
   unsigned exit       : 1; // terminate program after insn

   int8_t postFactor; // MUL/DIV(if < 0) by 1 << postFactor

   int8_t predSrc;
   int8_t flagsDef;
   int8_t flagsSrc;

   BasicBlock *bb;

protected:
   std::deque<ValueDef> defs; // no gaps !
   std::deque<ValueRef> srcs; // no gaps !

   // instruction specific methods:
   // (don't want to subclass, would need more constructors and memory pools)
public:
   inline void setInterpolate(unsigned int mode) { ipa = mode; }

   unsigned int getInterpMode() const { return ipa & 0x3; }
   unsigned int getSampleMode() const { return ipa & 0xc; }

private:
   void init();
};

enum TexQuery
{
   TXQ_DIMS,
   TXQ_TYPE,
   TXQ_SAMPLE_POSITION,
   TXQ_FILTER,
   TXQ_LOD,
   TXQ_WRAP,
   TXQ_BORDER_COLOUR
};

class TexInstruction : public Instruction
{
public:
   class Target
   {
   public:
      Target(TexTarget targ = TEX_TARGET_2D) : target(targ) { }

      const char *getName() const { return descTable[target].name; }
      unsigned int getArgCount() const { return descTable[target].argc; }
      unsigned int getDim() const { return descTable[target].dim; }
      int isArray() const { return descTable[target].array ? 1 : 0; }
      int isCube() const { return descTable[target].cube ? 1 : 0; }
      int isShadow() const { return descTable[target].shadow ? 1 : 0; }

      Target& operator=(TexTarget targ)
      {
         assert(targ < TEX_TARGET_COUNT);
         return *this;
      }

      inline bool operator==(TexTarget targ) const { return target == targ; }

   private:
      struct Desc
      {
         char name[19];
         uint8_t dim;
         uint8_t argc;
         bool array;
         bool cube;
         bool shadow;
      };

      static const struct Desc descTable[TEX_TARGET_COUNT];

   private:
      enum TexTarget target;
   };

public:
   TexInstruction(Function *, operation);
   virtual ~TexInstruction();

   virtual TexInstruction *clone(ClonePolicy<Function>&,
                                 Instruction * = NULL) const;

   inline void setTexture(Target targ, uint8_t r, uint8_t s)
   {
      tex.r = r;
      tex.s = s;
      tex.target = targ;
   }

   inline Value *getIndirectR() const;
   inline Value *getIndirectS() const;

public:
   struct {
      Target target;

      uint8_t r;
      int8_t rIndirectSrc;
      uint8_t s;
      int8_t sIndirectSrc;

      uint8_t mask;
      uint8_t gatherComp;

      bool liveOnly; // only execute on live pixels of a quad (optimization)
      bool levelZero;
      bool derivAll;

      int8_t useOffsets; // 0, 1, or 4 for textureGatherOffsets
      int8_t offset[4][3];

      enum TexQuery query;
   } tex;

   ValueRef dPdx[3];
   ValueRef dPdy[3];
};

class CmpInstruction : public Instruction
{
public:
   CmpInstruction(Function *, operation);

   virtual CmpInstruction *clone(ClonePolicy<Function>&,
                                 Instruction * = NULL) const;

   void setCondition(CondCode cond) { setCond = cond; }
   CondCode getCondition() const { return setCond; }

public:
   CondCode setCond;
};

class FlowInstruction : public Instruction
{
public:
   FlowInstruction(Function *, operation, void *target);

   virtual FlowInstruction *clone(ClonePolicy<Function>&,
                                  Instruction * = NULL) const;

public:
   unsigned allWarp  : 1;
   unsigned absolute : 1;
   unsigned limit    : 1;
   unsigned builtin  : 1; // true for calls to emulation code

   union {
      BasicBlock *bb;
      int builtin;
      Function *fn;
   } target;
};

class BasicBlock
{
public:
   BasicBlock(Function *);
   ~BasicBlock();

   BasicBlock *clone(ClonePolicy<Function>&) const;

   inline int getId() const { return id; }
   inline unsigned int getInsnCount() const { return numInsns; }
   inline bool isTerminated() const { return exit && exit->terminator; }

   bool dominatedBy(BasicBlock *bb);
   inline bool reachableBy(const BasicBlock *by, const BasicBlock *term);

   // returns mask of conditional out blocks
   // e.g. 3 for IF { .. } ELSE { .. } ENDIF, 1 for IF { .. } ENDIF
   unsigned int initiatesSimpleConditional() const;

public:
   Function *getFunction() const { return func; }
   Program *getProgram() const { return program; }

   Instruction *getEntry() const { return entry; } // first non-phi instruction
   Instruction *getPhi() const { return phi; }
   Instruction *getFirst() const { return phi ? phi : entry; }
   Instruction *getExit() const { return exit; }

   void insertHead(Instruction *);
   void insertTail(Instruction *);
   void insertBefore(Instruction *, Instruction *);
   void insertAfter(Instruction *, Instruction *);
   void remove(Instruction *);
   void permuteAdjacent(Instruction *, Instruction *);

   BasicBlock *idom() const;

   // NOTE: currently does not rebuild the dominator tree
   BasicBlock *splitBefore(Instruction *, bool attach = true);
   BasicBlock *splitAfter(Instruction *, bool attach = true);

   DLList& getDF() { return df; }
   DLList::Iterator iterDF() { return df.iterator(); }

   static inline BasicBlock *get(Iterator&);
   static inline BasicBlock *get(Graph::Node *);

public:
   Graph::Node cfg; // first edge is branch *taken* (the ELSE branch)
   Graph::Node dom;

   BitSet liveSet;
   BitSet defSet;

   uint32_t binPos;
   uint32_t binSize;

   Instruction *joinAt; // for quick reference

   bool explicitCont; // loop headers: true if loop contains continue stmts

private:
   int id;
   DLList df;

   Instruction *phi;
   Instruction *entry;
   Instruction *exit;

   unsigned int numInsns;

private:
   Function *func;
   Program *program;

   void splitCommon(Instruction *, BasicBlock *, bool attach);
};

class Function
{
public:
   Function(Program *, const char *name, uint32_t label);
   ~Function();

   static inline Function *get(Graph::Node *node);

   inline Program *getProgram() const { return prog; }
   inline const char *getName() const { return name; }
   inline int getId() const { return id; }
   inline uint32_t getLabel() const { return label; }

   void print();
   void printLiveIntervals() const;
   void printCFGraph(const char *filePath);

   bool setEntry(BasicBlock *);
   bool setExit(BasicBlock *);

   unsigned int orderInstructions(ArrayList&);

   inline void add(BasicBlock *bb, int& id) { allBBlocks.insert(bb, id); }
   inline void add(Instruction *insn, int& id) { allInsns.insert(insn, id); }
   inline void add(LValue *lval, int& id) { allLValues.insert(lval, id); }

   inline LValue *getLValue(int id);

   void buildLiveSets();
   void buildDefSets();
   bool convertToSSA();

public:
   std::deque<ValueDef> ins;
   std::deque<ValueRef> outs;
   std::deque<Value *> clobbers;

   Graph cfg;
   Graph::Node *cfgExit;
   Graph *domTree;
   Graph::Node call; // node in the call graph

   BasicBlock **bbArray; // BBs in emission order
   int bbCount;

   unsigned int loopNestingBound;
   int regClobberMax;

   uint32_t binPos;
   uint32_t binSize;

   Value *stackPtr;

   uint32_t tlsBase; // base address for l[] space (if no stack pointer is used)
   uint32_t tlsSize;

   ArrayList allBBlocks;
   ArrayList allInsns;
   ArrayList allLValues;

private:
   void buildLiveSetsPreSSA(BasicBlock *, const int sequence);
   void buildDefSetsPreSSA(BasicBlock *bb, const int seq);

private:
   uint32_t label;
   int id;
   const char *const name;
   Program *prog;
};

enum CGStage
{
   CG_STAGE_PRE_SSA,
   CG_STAGE_SSA, // expected directly before register allocation
   CG_STAGE_POST_RA
};

class Program
{
public:
   enum Type
   {
      TYPE_VERTEX,
      TYPE_TESSELLATION_CONTROL,
      TYPE_TESSELLATION_EVAL,
      TYPE_GEOMETRY,
      TYPE_FRAGMENT,
      TYPE_COMPUTE
   };

   Program(Type type, Target *targ);
   ~Program();

   void print();

   Type getType() const { return progType; }

   inline void add(Function *fn, int& id) { allFuncs.insert(fn, id); }
   inline void del(Function *fn, int& id) { allFuncs.remove(id); }
   inline void add(Value *rval, int& id) { allRValues.insert(rval, id); }

   bool makeFromTGSI(struct nv50_ir_prog_info *);
   bool makeFromSM4(struct nv50_ir_prog_info *);
   bool convertToSSA();
   bool optimizeSSA(int level);
   bool optimizePostRA(int level);
   bool registerAllocation();
   bool emitBinary(struct nv50_ir_prog_info *);

   const Target *getTarget() const { return target; }

private:
   void emitSymbolTable(struct nv50_ir_prog_info *);

   Type progType;
   Target *target;

public:
   Function *main;
   Graph calls;

   ArrayList allFuncs;
   ArrayList allRValues;

   uint32_t *code;
   uint32_t binSize;
   uint32_t tlsSize; // size required for FILE_MEMORY_LOCAL

   int maxGPR;

   MemoryPool mem_Instruction;
   MemoryPool mem_CmpInstruction;
   MemoryPool mem_TexInstruction;
   MemoryPool mem_FlowInstruction;
   MemoryPool mem_LValue;
   MemoryPool mem_Symbol;
   MemoryPool mem_ImmediateValue;

   uint32_t dbgFlags;
   uint8_t  optLevel;

   void *targetPriv; // e.g. to carry information between passes

   void releaseInstruction(Instruction *);
   void releaseValue(Value *);
};

// TODO: add const version
class Pass
{
public:
   bool run(Program *, bool ordered = false, bool skipPhi = false);
   bool run(Function *, bool ordered = false, bool skipPhi = false);

private:
   // return false to continue with next entity on next higher level
   virtual bool visit(Function *) { return true; }
   virtual bool visit(BasicBlock *) { return true; }
   virtual bool visit(Instruction *) { return false; }

   bool doRun(Program *, bool ordered, bool skipPhi);
   bool doRun(Function *, bool ordered, bool skipPhi);

protected:
   bool err;
   Function *func;
   Program *prog;
};

// =============================================================================

#include "nv50_ir_inlines.h"

} // namespace nv50_ir

#endif // __NV50_IR_H__
