1/*
2 * Copyright 2011 Christoph Bumiller
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23#ifndef __NV50_IR_H__
24#define __NV50_IR_H__
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <stdint.h>
29#include <deque>
30#include <list>
31#include <vector>
32
33#include "codegen/unordered_set.h"
34#include "codegen/nv50_ir_util.h"
35#include "codegen/nv50_ir_graph.h"
36
37#include "codegen/nv50_ir_driver.h"
38
39namespace nv50_ir {
40
41enum operation
42{
43   OP_NOP = 0,
44   OP_PHI,
45   OP_UNION, // unify a new definition and several source values
46   OP_SPLIT, // $r0d -> { $r0, $r1 } ($r0d and $r0/$r1 will be coalesced)
47   OP_MERGE, // opposite of split, e.g. combine 2 32 bit into a 64 bit value
48   OP_CONSTRAINT, // copy values into consecutive registers
49   OP_MOV, // simple copy, no modifiers allowed
50   OP_LOAD,
51   OP_STORE,
52   OP_ADD, // NOTE: add u64 + u32 is legal for targets w/o 64-bit integer adds
53   OP_SUB,
54   OP_MUL,
55   OP_DIV,
56   OP_MOD,
57   OP_MAD,
58   OP_FMA,
59   OP_SAD, // abs(src0 - src1) + src2
60   OP_SHLADD,
61   // extended multiply-add (GM107+), does a lot of things.
62   // see envytools for detailed documentation
63   OP_XMAD,
64   OP_ABS,
65   OP_NEG,
66   OP_NOT,
67   OP_AND,
68   OP_OR,
69   OP_XOR,
70   OP_SHL,
71   OP_SHR,
72   OP_MAX,
73   OP_MIN,
74   OP_SAT, // CLAMP(f32, 0.0, 1.0)
75   OP_CEIL,
76   OP_FLOOR,
77   OP_TRUNC,
78   OP_CVT,
79   OP_SET_AND, // dst = (src0 CMP src1) & src2
80   OP_SET_OR,
81   OP_SET_XOR,
82   OP_SET,
83   OP_SELP, // dst = src2 ? src0 : src1
84   OP_SLCT, // dst = (src2 CMP 0) ? src0 : src1
85   OP_RCP,
86   OP_RSQ,
87   OP_LG2,
88   OP_SIN,
89   OP_COS,
90   OP_EX2,
91   OP_EXP, // exponential (base M_E)
92   OP_LOG, // natural logarithm
93   OP_PRESIN,
94   OP_PREEX2,
95   OP_SQRT,
96   OP_POW,
97   OP_BRA,
98   OP_CALL,
99   OP_RET,
100   OP_CONT,
101   OP_BREAK,
102   OP_PRERET,
103   OP_PRECONT,
104   OP_PREBREAK,
105   OP_BRKPT,     // breakpoint (not related to loops)
106   OP_JOINAT,    // push control flow convergence point
107   OP_JOIN,      // converge
108   OP_DISCARD,
109   OP_EXIT,
110   OP_MEMBAR, // memory barrier (mfence, lfence, sfence)
111   OP_VFETCH, // indirection 0 in attribute space, indirection 1 is vertex base
112   OP_PFETCH, // fetch base address of vertex src0 (immediate) [+ src1]
113   OP_AFETCH, // fetch base address of shader input (a[%r1+0x10])
114   OP_EXPORT,
115   OP_LINTERP,
116   OP_PINTERP,
117   OP_EMIT,    // emit vertex
118   OP_RESTART, // restart primitive
119   OP_TEX,
120   OP_TXB, // texture bias
121   OP_TXL, // texure lod
122   OP_TXF, // texel fetch
123   OP_TXQ, // texture size query
124   OP_TXD, // texture derivatives
125   OP_TXG, // texture gather
126   OP_TXLQ, // texture query lod
127   OP_TEXCSAA, // texture op for coverage sampling
128   OP_TEXPREP, // turn cube map array into 2d array coordinates
129   OP_SULDB, // surface load (raw)
130   OP_SULDP, // surface load (formatted)
131   OP_SUSTB, // surface store (raw)
132   OP_SUSTP, // surface store (formatted)
133   OP_SUREDB,
134   OP_SUREDP, // surface reduction (atomic op)
135   OP_SULEA,   // surface load effective address
136   OP_SUBFM,   // surface bitfield manipulation
137   OP_SUCLAMP, // clamp surface coordinates
138   OP_SUEAU,   // surface effective address
139   OP_SUQ,     // surface query
140   OP_MADSP,   // special integer multiply-add
141   OP_TEXBAR, // texture dependency barrier
142   OP_DFDX,
143   OP_DFDY,
144   OP_RDSV, // read system value
145   OP_WRSV, // write system value
146   OP_PIXLD, // get info about raster object or surfaces
147   OP_QUADOP,
148   OP_QUADON,
149   OP_QUADPOP,
150   OP_POPCNT, // bitcount(src0 & src1)
151   OP_INSBF,  // insert first src1[8:15] bits of src0 into src2 at src1[0:7]
152   OP_EXTBF,  // place bits [K,K+N) of src0 into dst, src1 = 0xNNKK
153   OP_BFIND,  // find highest/lowest set bit
154   OP_PERMT,  // dst = bytes from src2,src0 selected by src1 (nvc0's src order)
155   OP_ATOM,
156   OP_BAR,    // execution barrier, sources = { id, thread count, predicate }
157   OP_VADD,   // byte/word vector operations
158   OP_VAVG,
159   OP_VMIN,
160   OP_VMAX,
161   OP_VSAD,
162   OP_VSET,
163   OP_VSHR,
164   OP_VSHL,
165   OP_VSEL,
166   OP_CCTL, // cache control
167   OP_SHFL, // warp shuffle
168   OP_VOTE,
169   OP_BUFQ, // buffer query
170   OP_LAST
171};
172
173// various instruction-specific modifier definitions Instruction::subOp
174// MOV_FINAL marks a MOV originating from an EXPORT (used for placing TEXBARs)
175#define NV50_IR_SUBOP_MUL_HIGH     1
176#define NV50_IR_SUBOP_EMIT_RESTART 1
177#define NV50_IR_SUBOP_LDC_IL       1
178#define NV50_IR_SUBOP_LDC_IS       2
179#define NV50_IR_SUBOP_LDC_ISL      3
180#define NV50_IR_SUBOP_SHIFT_WRAP   1
181#define NV50_IR_SUBOP_SHIFT_HIGH   2
182#define NV50_IR_SUBOP_EMU_PRERET   1
183#define NV50_IR_SUBOP_TEXBAR(n)    n
184#define NV50_IR_SUBOP_MOV_FINAL    1
185#define NV50_IR_SUBOP_EXTBF_REV    1
186#define NV50_IR_SUBOP_BFIND_SAMT   1
187#define NV50_IR_SUBOP_RCPRSQ_64H   1
188#define NV50_IR_SUBOP_PERMT_F4E    1
189#define NV50_IR_SUBOP_PERMT_B4E    2
190#define NV50_IR_SUBOP_PERMT_RC8    3
191#define NV50_IR_SUBOP_PERMT_ECL    4
192#define NV50_IR_SUBOP_PERMT_ECR    5
193#define NV50_IR_SUBOP_PERMT_RC16   6
194#define NV50_IR_SUBOP_BAR_SYNC     0
195#define NV50_IR_SUBOP_BAR_ARRIVE   1
196#define NV50_IR_SUBOP_BAR_RED_AND  2
197#define NV50_IR_SUBOP_BAR_RED_OR   3
198#define NV50_IR_SUBOP_BAR_RED_POPC 4
199#define NV50_IR_SUBOP_MEMBAR_L     1
200#define NV50_IR_SUBOP_MEMBAR_S     2
201#define NV50_IR_SUBOP_MEMBAR_M     3
202#define NV50_IR_SUBOP_MEMBAR_CTA  (0 << 2)
203#define NV50_IR_SUBOP_MEMBAR_GL   (1 << 2)
204#define NV50_IR_SUBOP_MEMBAR_SYS  (2 << 2)
205#define NV50_IR_SUBOP_MEMBAR_DIR(m)   ((m) & 0x3)
206#define NV50_IR_SUBOP_MEMBAR_SCOPE(m) ((m) & ~0x3)
207#define NV50_IR_SUBOP_MEMBAR(d,s) \
208   (NV50_IR_SUBOP_MEMBAR_##d | NV50_IR_SUBOP_MEMBAR_##s)
209#define NV50_IR_SUBOP_ATOM_ADD      0
210#define NV50_IR_SUBOP_ATOM_MIN      1
211#define NV50_IR_SUBOP_ATOM_MAX      2
212#define NV50_IR_SUBOP_ATOM_INC      3
213#define NV50_IR_SUBOP_ATOM_DEC      4
214#define NV50_IR_SUBOP_ATOM_AND      5
215#define NV50_IR_SUBOP_ATOM_OR       6
216#define NV50_IR_SUBOP_ATOM_XOR      7
217#define NV50_IR_SUBOP_ATOM_CAS      8
218#define NV50_IR_SUBOP_ATOM_EXCH     9
219#define NV50_IR_SUBOP_CCTL_IV      5
220#define NV50_IR_SUBOP_CCTL_IVALL   6
221#define NV50_IR_SUBOP_SUST_IGN     0
222#define NV50_IR_SUBOP_SUST_TRAP    1
223#define NV50_IR_SUBOP_SUST_SDCL    3
224#define NV50_IR_SUBOP_SULD_ZERO    0
225#define NV50_IR_SUBOP_SULD_TRAP    1
226#define NV50_IR_SUBOP_SULD_SDCL    3
227#define NV50_IR_SUBOP_SUBFM_3D     1
228#define NV50_IR_SUBOP_SUCLAMP_2D   0x10
229#define NV50_IR_SUBOP_SUCLAMP_SD(r, d) (( 0 + (r)) | ((d == 2) ? 0x10 : 0))
230#define NV50_IR_SUBOP_SUCLAMP_PL(r, d) (( 5 + (r)) | ((d == 2) ? 0x10 : 0))
231#define NV50_IR_SUBOP_SUCLAMP_BL(r, d) ((10 + (r)) | ((d == 2) ? 0x10 : 0))
232#define NV50_IR_SUBOP_PIXLD_COUNT       0
233#define NV50_IR_SUBOP_PIXLD_COVMASK     1
234#define NV50_IR_SUBOP_PIXLD_COVERED     2
235#define NV50_IR_SUBOP_PIXLD_OFFSET      3
236#define NV50_IR_SUBOP_PIXLD_CENT_OFFSET 4
237#define NV50_IR_SUBOP_PIXLD_SAMPLEID    5
238#define NV50_IR_SUBOP_SHFL_IDX  0
239#define NV50_IR_SUBOP_SHFL_UP   1
240#define NV50_IR_SUBOP_SHFL_DOWN 2
241#define NV50_IR_SUBOP_SHFL_BFLY 3
242#define NV50_IR_SUBOP_LOAD_LOCKED    1
243#define NV50_IR_SUBOP_STORE_UNLOCKED 2
244#define NV50_IR_SUBOP_MADSP_SD     0xffff
245// Yes, we could represent those with DataType.
246// Or put the type into operation and have a couple 1000 values in that enum.
247// This will have to do for now.
248// The bitfields are supposed to correspond to nve4 ISA.
249#define NV50_IR_SUBOP_MADSP(a,b,c) (((c) << 8) | ((b) << 4) | (a))
250#define NV50_IR_SUBOP_V1(d,a,b)    (((d) << 10) | ((b) << 5) | (a) | 0x0000)
251#define NV50_IR_SUBOP_V2(d,a,b)    (((d) << 10) | ((b) << 5) | (a) | 0x4000)
252#define NV50_IR_SUBOP_V4(d,a,b)    (((d) << 10) | ((b) << 5) | (a) | 0x8000)
253#define NV50_IR_SUBOP_Vn(n)        ((n) >> 14)
254#define NV50_IR_SUBOP_VOTE_ALL 0
255#define NV50_IR_SUBOP_VOTE_ANY 1
256#define NV50_IR_SUBOP_VOTE_UNI 2
257
258#define NV50_IR_SUBOP_MINMAX_LOW  1
259#define NV50_IR_SUBOP_MINMAX_MED  2
260#define NV50_IR_SUBOP_MINMAX_HIGH 3
261
262// xmad(src0, src1, 0) << 16 + src2
263#define NV50_IR_SUBOP_XMAD_PSL (1 << 0)
264// (xmad(src0, src1, src2) & 0xffff) | (src1 << 16)
265#define NV50_IR_SUBOP_XMAD_MRG (1 << 1)
266// xmad(src0, src1, src2.lo)
267#define NV50_IR_SUBOP_XMAD_CLO (1 << 2)
268// xmad(src0, src1, src2.hi)
269#define NV50_IR_SUBOP_XMAD_CHI (2 << 2)
270// if both operands to the multiplication are non-zero, subtract 65536 for each
271// negative operand
272#define NV50_IR_SUBOP_XMAD_CSFU (3 << 2)
273// xmad(src0, src1, src2) + src1 << 16
274#define NV50_IR_SUBOP_XMAD_CBCC (4 << 2)
275#define NV50_IR_SUBOP_XMAD_CMODE_SHIFT 2
276#define NV50_IR_SUBOP_XMAD_CMODE_MASK (0x7 << NV50_IR_SUBOP_XMAD_CMODE_SHIFT)
277
278// use the high 16 bits instead of the low 16 bits for the multiplication.
279// if the instruction's sType is signed, sign extend the operand from 16 bits
280// to 32 before multiplication.
281#define NV50_IR_SUBOP_XMAD_H1_SHIFT 5
282#define NV50_IR_SUBOP_XMAD_H1(i) (1 << (NV50_IR_SUBOP_XMAD_H1_SHIFT + (i)))
283#define NV50_IR_SUBOP_XMAD_H1_MASK (0x3 << NV50_IR_SUBOP_XMAD_H1_SHIFT)
284
285enum DataType
286{
287   TYPE_NONE,
288   TYPE_U8,
289   TYPE_S8,
290   TYPE_U16,
291   TYPE_S16,
292   TYPE_U32,
293   TYPE_S32,
294   TYPE_U64, // 64 bit operations are only lowered after register allocation
295   TYPE_S64,
296   TYPE_F16,
297   TYPE_F32,
298   TYPE_F64,
299   TYPE_B96,
300   TYPE_B128
301};
302
303enum CondCode
304{
305   CC_FL = 0,
306   CC_NEVER = CC_FL, // when used with FILE_FLAGS
307   CC_LT = 1,
308   CC_EQ = 2,
309   CC_NOT_P = CC_EQ, // when used with FILE_PREDICATE
310   CC_LE = 3,
311   CC_GT = 4,
312   CC_NE = 5,
313   CC_P  = CC_NE,
314   CC_GE = 6,
315   CC_TR = 7,
316   CC_ALWAYS = CC_TR,
317   CC_U  = 8,
318   CC_LTU = 9,
319   CC_EQU = 10,
320   CC_LEU = 11,
321   CC_GTU = 12,
322   CC_NEU = 13,
323   CC_GEU = 14,
324   CC_NO = 0x10,
325   CC_NC = 0x11,
326   CC_NS = 0x12,
327   CC_NA = 0x13,
328   CC_A  = 0x14,
329   CC_S  = 0x15,
330   CC_C  = 0x16,
331   CC_O  = 0x17
332};
333
334enum RoundMode
335{
336   ROUND_N, // nearest
337   ROUND_M, // towards -inf
338   ROUND_Z, // towards 0
339   ROUND_P, // towards +inf
340   ROUND_NI, // nearest integer
341   ROUND_MI, // to integer towards -inf
342   ROUND_ZI, // to integer towards 0
343   ROUND_PI, // to integer towards +inf
344};
345
346enum CacheMode
347{
348   CACHE_CA,            // cache at all levels
349   CACHE_WB = CACHE_CA, // cache write back
350   CACHE_CG,            // cache at global level
351   CACHE_CS,            // cache streaming
352   CACHE_CV,            // cache as volatile
353   CACHE_WT = CACHE_CV  // cache write-through
354};
355
356enum DataFile
357{
358   FILE_NULL = 0,
359   FILE_GPR,
360   FILE_PREDICATE,       // boolean predicate
361   FILE_FLAGS,           // zero/sign/carry/overflow bits
362   FILE_ADDRESS,
363   LAST_REGISTER_FILE = FILE_ADDRESS,
364   FILE_IMMEDIATE,
365   FILE_MEMORY_CONST,
366   FILE_SHADER_INPUT,
367   FILE_SHADER_OUTPUT,
368   FILE_MEMORY_BUFFER,
369   FILE_MEMORY_GLOBAL,
370   FILE_MEMORY_SHARED,
371   FILE_MEMORY_LOCAL,
372   FILE_SYSTEM_VALUE,
373   DATA_FILE_COUNT
374};
375
376enum TexTarget
377{
378   TEX_TARGET_1D,
379   TEX_TARGET_2D,
380   TEX_TARGET_2D_MS,
381   TEX_TARGET_3D,
382   TEX_TARGET_CUBE,
383   TEX_TARGET_1D_SHADOW,
384   TEX_TARGET_2D_SHADOW,
385   TEX_TARGET_CUBE_SHADOW,
386   TEX_TARGET_1D_ARRAY,
387   TEX_TARGET_2D_ARRAY,
388   TEX_TARGET_2D_MS_ARRAY,
389   TEX_TARGET_CUBE_ARRAY,
390   TEX_TARGET_1D_ARRAY_SHADOW,
391   TEX_TARGET_2D_ARRAY_SHADOW,
392   TEX_TARGET_RECT,
393   TEX_TARGET_RECT_SHADOW,
394   TEX_TARGET_CUBE_ARRAY_SHADOW,
395   TEX_TARGET_BUFFER,
396   TEX_TARGET_COUNT
397};
398
399enum ImgFormat
400{
401   FMT_NONE,
402
403   FMT_RGBA32F,
404   FMT_RGBA16F,
405   FMT_RG32F,
406   FMT_RG16F,
407   FMT_R11G11B10F,
408   FMT_R32F,
409   FMT_R16F,
410
411   FMT_RGBA32UI,
412   FMT_RGBA16UI,
413   FMT_RGB10A2UI,
414   FMT_RGBA8UI,
415   FMT_RG32UI,
416   FMT_RG16UI,
417   FMT_RG8UI,
418   FMT_R32UI,
419   FMT_R16UI,
420   FMT_R8UI,
421
422   FMT_RGBA32I,
423   FMT_RGBA16I,
424   FMT_RGBA8I,
425   FMT_RG32I,
426   FMT_RG16I,
427   FMT_RG8I,
428   FMT_R32I,
429   FMT_R16I,
430   FMT_R8I,
431
432   FMT_RGBA16,
433   FMT_RGB10A2,
434   FMT_RGBA8,
435   FMT_RG16,
436   FMT_RG8,
437   FMT_R16,
438   FMT_R8,
439
440   FMT_RGBA16_SNORM,
441   FMT_RGBA8_SNORM,
442   FMT_RG16_SNORM,
443   FMT_RG8_SNORM,
444   FMT_R16_SNORM,
445   FMT_R8_SNORM,
446
447   FMT_BGRA8,
448
449   IMG_FORMAT_COUNT,
450};
451
452enum ImgType {
453   UINT,
454   SINT,
455   UNORM,
456   SNORM,
457   FLOAT,
458};
459
460enum SVSemantic
461{
462   SV_POSITION, // WPOS
463   SV_VERTEX_ID,
464   SV_INSTANCE_ID,
465   SV_INVOCATION_ID,
466   SV_PRIMITIVE_ID,
467   SV_VERTEX_COUNT, // gl_PatchVerticesIn
468   SV_LAYER,
469   SV_VIEWPORT_INDEX,
470   SV_YDIR,
471   SV_FACE,
472   SV_POINT_SIZE,
473   SV_POINT_COORD,
474   SV_CLIP_DISTANCE,
475   SV_SAMPLE_INDEX,
476   SV_SAMPLE_POS,
477   SV_SAMPLE_MASK,
478   SV_TESS_OUTER,
479   SV_TESS_INNER,
480   SV_TESS_COORD,
481   SV_TID,
482   SV_COMBINED_TID,
483   SV_CTAID,
484   SV_NTID,
485   SV_GRIDID,
486   SV_NCTAID,
487   SV_LANEID,
488   SV_PHYSID,
489   SV_NPHYSID,
490   SV_CLOCK,
491   SV_LBASE,
492   SV_SBASE,
493   SV_VERTEX_STRIDE,
494   SV_INVOCATION_INFO,
495   SV_THREAD_KILL,
496   SV_BASEVERTEX,
497   SV_BASEINSTANCE,
498   SV_DRAWID,
499   SV_WORK_DIM,
500   SV_LANEMASK_EQ,
501   SV_LANEMASK_LT,
502   SV_LANEMASK_LE,
503   SV_LANEMASK_GT,
504   SV_LANEMASK_GE,
505   SV_UNDEFINED,
506   SV_LAST
507};
508
509class Program;
510class Function;
511class BasicBlock;
512
513class Target;
514
515class Instruction;
516class CmpInstruction;
517class TexInstruction;
518class FlowInstruction;
519
520class Value;
521class LValue;
522class Symbol;
523class ImmediateValue;
524
525struct Storage
526{
527   DataFile file;
528   int8_t fileIndex; // signed, may be indirect for CONST[]
529   uint8_t size; // this should match the Instruction type's size
530   DataType type; // mainly for pretty printing
531   union {
532      uint64_t u64;    // immediate values
533      uint32_t u32;
534      uint16_t u16;
535      uint8_t u8;
536      int64_t s64;
537      int32_t s32;
538      int16_t s16;
539      int8_t s8;
540      float f32;
541      double f64;
542      int32_t offset; // offset from 0 (base of address space)
543      int32_t id;     // register id (< 0 if virtual/unassigned, in units <= 4)
544      struct {
545         SVSemantic sv;
546         int index;
547      } sv;
548   } data;
549};
550
551// precedence: NOT after SAT after NEG after ABS
552#define NV50_IR_MOD_ABS (1 << 0)
553#define NV50_IR_MOD_NEG (1 << 1)
554#define NV50_IR_MOD_SAT (1 << 2)
555#define NV50_IR_MOD_NOT (1 << 3)
556#define NV50_IR_MOD_NEG_ABS (NV50_IR_MOD_NEG | NV50_IR_MOD_ABS)
557
558#define NV50_IR_INTERP_MODE_MASK   0x3
559#define NV50_IR_INTERP_LINEAR      (0 << 0)
560#define NV50_IR_INTERP_PERSPECTIVE (1 << 0)
561#define NV50_IR_INTERP_FLAT        (2 << 0)
562#define NV50_IR_INTERP_SC          (3 << 0) // what exactly is that ?
563#define NV50_IR_INTERP_SAMPLE_MASK 0xc
564#define NV50_IR_INTERP_DEFAULT     (0 << 2)
565#define NV50_IR_INTERP_CENTROID    (1 << 2)
566#define NV50_IR_INTERP_OFFSET      (2 << 2)
567#define NV50_IR_INTERP_SAMPLEID    (3 << 2)
568
569// do we really want this to be a class ?
570class Modifier
571{
572public:
573   Modifier() : bits(0) { }
574   Modifier(unsigned int m) : bits(m) { }
575   Modifier(operation op);
576
577   // @return new Modifier applying a after b (asserts if unrepresentable)
578   Modifier operator*(const Modifier) const;
579   Modifier operator*=(const Modifier m) { *this = *this * m; return *this; }
580   Modifier operator==(const Modifier m) const { return m.bits == bits; }
581   Modifier operator!=(const Modifier m) const { return m.bits != bits; }
582
583   inline Modifier operator&(const Modifier m) const { return bits & m.bits; }
584   inline Modifier operator|(const Modifier m) const { return bits | m.bits; }
585   inline Modifier operator^(const Modifier m) const { return bits ^ m.bits; }
586
587   operation getOp() const;
588
589   inline int neg() const { return (bits & NV50_IR_MOD_NEG) ? 1 : 0; }
590   inline int abs() const { return (bits & NV50_IR_MOD_ABS) ? 1 : 0; }
591
592   inline operator bool() const { return bits ? true : false; }
593
594   void applyTo(ImmediateValue &imm) const;
595
596   int print(char *buf, size_t size) const;
597
598private:
599   uint8_t bits;
600};
601
602class ValueRef
603{
604public:
605   ValueRef(Value * = NULL);
606   ValueRef(const ValueRef&);
607   ~ValueRef();
608
609   inline bool exists() const { return value != NULL; }
610
611   void set(Value *);
612   void set(const ValueRef&);
613   inline Value *get() const { return value; }
614   inline Value *rep() const;
615
616   inline Instruction *getInsn() const { return insn; }
617   inline void setInsn(Instruction *inst) { insn = inst; }
618
619   inline bool isIndirect(int dim) const { return indirect[dim] >= 0; }
620   inline const ValueRef *getIndirect(int dim) const;
621
622   inline DataFile getFile() const;
623   inline unsigned getSize() const;
624
625   // SSA: return eventual (traverse MOVs) literal value, if it exists
626   bool getImmediate(ImmediateValue&) const;
627
628public:
629   Modifier mod;
630   int8_t indirect[2]; // >= 0 if relative to lvalue in insn->src(indirect[i])
631
632   bool usedAsPtr; // for printing
633
634private:
635   Value *value;
636   Instruction *insn;
637};
638
639class ValueDef
640{
641public:
642   ValueDef(Value * = NULL);
643   ValueDef(const ValueDef&);
644   ~ValueDef();
645
646   inline bool exists() const { return value != NULL; }
647
648   inline Value *get() const { return value; }
649   inline Value *rep() const;
650   void set(Value *);
651   bool mayReplace(const ValueRef &);
652   void replace(const ValueRef &, bool doSet); // replace all uses of the old value
653
654   inline Instruction *getInsn() const { return insn; }
655   inline void setInsn(Instruction *inst) { insn = inst; }
656
657   inline DataFile getFile() const;
658   inline unsigned getSize() const;
659
660   inline void setSSA(LValue *);
661   inline const LValue *preSSA() const;
662
663private:
664   Value *value;   // should make this LValue * ...
665   LValue *origin; // pre SSA value
666   Instruction *insn;
667};
668
669class Value
670{
671public:
672   Value();
673   virtual ~Value() { }
674
675   virtual Value *clone(ClonePolicy<Function>&) const = 0;
676
677   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const = 0;
678
679   virtual bool equals(const Value *, bool strict = false) const;
680   virtual bool interfers(const Value *) const;
681   virtual bool isUniform() const { return true; }
682
683   inline Value *rep() const { return join; }
684
685   inline Instruction *getUniqueInsn() const;
686   inline Instruction *getInsn() const; // use when uniqueness is certain
687
688   inline int refCount() { return uses.size(); }
689
690   inline LValue *asLValue();
691   inline Symbol *asSym();
692   inline ImmediateValue *asImm();
693   inline const Symbol *asSym() const;
694   inline const ImmediateValue *asImm() const;
695
696   inline bool inFile(DataFile f) const { return reg.file == f; }
697
698   static inline Value *get(Iterator&);
699
700   unordered_set<ValueRef *> uses;
701   std::list<ValueDef *> defs;
702   typedef unordered_set<ValueRef *>::iterator UseIterator;
703   typedef unordered_set<ValueRef *>::const_iterator UseCIterator;
704   typedef std::list<ValueDef *>::iterator DefIterator;
705   typedef std::list<ValueDef *>::const_iterator DefCIterator;
706
707   int id;
708   Storage reg;
709
710   // TODO: these should be in LValue:
711   Interval livei;
712   Value *join;
713};
714
715class LValue : public Value
716{
717public:
718   LValue(Function *, DataFile file);
719   LValue(Function *, LValue *);
720   ~LValue() { }
721
722   virtual bool isUniform() const;
723
724   virtual LValue *clone(ClonePolicy<Function>&) const;
725
726   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const;
727
728public:
729   unsigned compMask : 8; // compound/component mask
730   unsigned compound : 1; // used by RA, value involved in split/merge
731   unsigned ssa      : 1;
732   unsigned fixedReg : 1; // set & used by RA, earlier just use (id < 0)
733   unsigned noSpill  : 1; // do not spill (e.g. if spill temporary already)
734};
735
736class Symbol : public Value
737{
738public:
739   Symbol(Program *, DataFile file = FILE_MEMORY_CONST, ubyte fileIdx = 0);
740   ~Symbol() { }
741
742   virtual Symbol *clone(ClonePolicy<Function>&) const;
743
744   virtual bool equals(const Value *that, bool strict) const;
745
746   virtual bool isUniform() const;
747
748   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const;
749
750   // print with indirect values
751   int print(char *, size_t, Value *, Value *, DataType ty = TYPE_NONE) const;
752
753   inline void setFile(DataFile file, ubyte fileIndex = 0)
754   {
755      reg.file = file;
756      reg.fileIndex = fileIndex;
757   }
758
759   inline void setOffset(int32_t offset);
760   inline void setAddress(Symbol *base, int32_t offset);
761   inline void setSV(SVSemantic sv, uint32_t idx = 0);
762
763   inline const Symbol *getBase() const { return baseSym; }
764
765private:
766   Symbol *baseSym; // array base for Symbols representing array elements
767};
768
769class ImmediateValue : public Value
770{
771public:
772   ImmediateValue() { }
773   ImmediateValue(Program *, uint32_t);
774   ImmediateValue(Program *, float);
775   ImmediateValue(Program *, double);
776   // NOTE: not added to program with
777   ImmediateValue(const ImmediateValue *, DataType ty);
778   ~ImmediateValue() { };
779
780   virtual ImmediateValue *clone(ClonePolicy<Function>&) const;
781
782   virtual bool equals(const Value *that, bool strict) const;
783
784   // these only work if 'type' is valid (we mostly use untyped literals):
785   bool isInteger(const int ival) const; // ival is cast to this' type
786   bool isNegative() const;
787   bool isPow2() const;
788
789   void applyLog2();
790
791   // for constant folding:
792   ImmediateValue operator+(const ImmediateValue&) const;
793   ImmediateValue operator-(const ImmediateValue&) const;
794   ImmediateValue operator*(const ImmediateValue&) const;
795   ImmediateValue operator/(const ImmediateValue&) const;
796
797   ImmediateValue& operator=(const ImmediateValue&); // only sets value !
798
799   bool compare(CondCode cc, float fval) const;
800
801   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const;
802};
803
804class Instruction
805{
806public:
807   Instruction();
808   Instruction(Function *, operation, DataType);
809   virtual ~Instruction();
810
811   virtual Instruction *clone(ClonePolicy<Function>&,
812                              Instruction * = NULL) const;
813
814   void setDef(int i, Value *);
815   void setSrc(int s, Value *);
816   void setSrc(int s, const ValueRef&);
817   void swapSources(int a, int b);
818   void moveSources(int s, int delta);
819   bool setIndirect(int s, int dim, Value *);
820
821   inline ValueRef& src(int s) { return srcs[s]; }
822   inline ValueDef& def(int s) { return defs[s]; }
823   inline const ValueRef& src(int s) const { return srcs[s]; }
824   inline const ValueDef& def(int s) const { return defs[s]; }
825
826   inline Value *getDef(int d) const { return defs[d].get(); }
827   inline Value *getSrc(int s) const { return srcs[s].get(); }
828   inline Value *getIndirect(int s, int dim) const;
829
830   inline bool defExists(unsigned d) const
831   {
832      return d < defs.size() && defs[d].exists();
833   }
834   inline bool srcExists(unsigned s) const
835   {
836      return s < srcs.size() && srcs[s].exists();
837   }
838
839   inline bool constrainedDefs() const;
840
841   bool setPredicate(CondCode ccode, Value *);
842   inline Value *getPredicate() const;
843   bool writesPredicate() const;
844   inline bool isPredicated() const { return predSrc >= 0; }
845
846   inline void setFlagsSrc(int s, Value *);
847   inline void setFlagsDef(int d, Value *);
848   inline bool usesFlags() const { return flagsSrc >= 0; }
849
850   unsigned int defCount() const { return defs.size(); };
851   unsigned int defCount(unsigned int mask, bool singleFile = false) const;
852   unsigned int srcCount() const { return srcs.size(); };
853   unsigned int srcCount(unsigned int mask, bool singleFile = false) const;
854
855   // save & remove / set indirect[0,1] and predicate source
856   void takeExtraSources(int s, Value *[3]);
857   void putExtraSources(int s, Value *[3]);
858
859   inline void setType(DataType type) { dType = sType = type; }
860
861   inline void setType(DataType dtype, DataType stype)
862   {
863      dType = dtype;
864      sType = stype;
865   }
866
867   inline bool isPseudo() const { return op < OP_MOV; }
868   bool isDead() const;
869   bool isNop() const;
870   bool isCommutationLegal(const Instruction *) const; // must be adjacent !
871   bool isActionEqual(const Instruction *) const;
872   bool isResultEqual(const Instruction *) const;
873
874   // check whether the defs interfere with srcs and defs of another instruction
875   bool canCommuteDefDef(const Instruction *) const;
876   bool canCommuteDefSrc(const Instruction *) const;
877
878   void print() const;
879
880   inline CmpInstruction *asCmp();
881   inline TexInstruction *asTex();
882   inline FlowInstruction *asFlow();
883   inline const TexInstruction *asTex() const;
884   inline const CmpInstruction *asCmp() const;
885   inline const FlowInstruction *asFlow() const;
886
887public:
888   Instruction *next;
889   Instruction *prev;
890   int id;
891   int serial; // CFG order
892
893   operation op;
894   DataType dType; // destination or defining type
895   DataType sType; // source or secondary type
896   CondCode cc;
897   RoundMode rnd;
898   CacheMode cache;
899
900   uint16_t subOp; // quadop, 1 for mul-high, etc.
901
902   unsigned encSize    : 4; // encoding size in bytes
903   unsigned saturate   : 1; // to [0.0f, 1.0f]
904   unsigned join       : 1; // converge control flow (use OP_JOIN until end)
905   unsigned fixed      : 1; // prevent dead code elimination
906   unsigned terminator : 1; // end of basic block
907   unsigned ftz        : 1; // flush denormal to zero
908   unsigned dnz        : 1; // denormals, NaN are zero
909   unsigned ipa        : 4; // interpolation mode
910   unsigned lanes      : 4;
911   unsigned perPatch   : 1;
912   unsigned exit       : 1; // terminate program after insn
913   unsigned mask       : 4; // for vector ops
914   // prevent algebraic optimisations that aren't bit-for-bit identical
915   unsigned precise    : 1;
916
917   int8_t postFactor; // MUL/DIV(if < 0) by 1 << postFactor
918
919   int8_t predSrc;
920   int8_t flagsDef;
921   int8_t flagsSrc;
922
923   uint32_t sched; // scheduling data (NOTE: maybe move to separate storage)
924
925   BasicBlock *bb;
926
927protected:
928   std::deque<ValueDef> defs; // no gaps !
929   std::deque<ValueRef> srcs; // no gaps !
930
931   // instruction specific methods:
932   // (don't want to subclass, would need more constructors and memory pools)
933public:
934   inline void setInterpolate(unsigned int mode) { ipa = mode; }
935
936   unsigned int getInterpMode() const { return ipa & 0x3; }
937   unsigned int getSampleMode() const { return ipa & 0xc; }
938
939private:
940   void init();
941};
942
943enum TexQuery
944{
945   TXQ_DIMS, /* x, y, z, levels */
946   TXQ_TYPE, /* ?, ?, samples, ? */
947   TXQ_SAMPLE_POSITION,
948   TXQ_FILTER,
949   TXQ_LOD,
950   TXQ_WRAP,
951   TXQ_BORDER_COLOUR
952};
953
954class TexInstruction : public Instruction
955{
956public:
957   class Target
958   {
959   public:
960      Target(TexTarget targ = TEX_TARGET_2D) : target(targ) { }
961
962      const char *getName() const { return descTable[target].name; }
963      unsigned int getArgCount() const { return descTable[target].argc; }
964      unsigned int getDim() const { return descTable[target].dim; }
965      int isArray() const { return descTable[target].array ? 1 : 0; }
966      int isCube() const { return descTable[target].cube ? 1 : 0; }
967      int isShadow() const { return descTable[target].shadow ? 1 : 0; }
968      int isMS() const {
969        return target == TEX_TARGET_2D_MS || target == TEX_TARGET_2D_MS_ARRAY; }
970      void clearMS() {
971         if (isMS()) {
972            if (isArray())
973               target = TEX_TARGET_2D_ARRAY;
974            else
975               target = TEX_TARGET_2D;
976         }
977      }
978
979      Target& operator=(TexTarget targ)
980      {
981         assert(targ < TEX_TARGET_COUNT);
982         target = targ;
983         return *this;
984      }
985
986      inline bool operator==(TexTarget targ) const { return target == targ; }
987      inline bool operator!=(TexTarget targ) const { return target != targ; }
988
989      enum TexTarget getEnum() const { return target; }
990
991   private:
992      struct Desc
993      {
994         char name[19];
995         uint8_t dim;
996         uint8_t argc;
997         bool array;
998         bool cube;
999         bool shadow;
1000      };
1001
1002      static const struct Desc descTable[TEX_TARGET_COUNT];
1003
1004   private:
1005      enum TexTarget target;
1006   };
1007
1008public:
1009   struct ImgFormatDesc
1010   {
1011      char name[19];
1012      uint8_t components;
1013      uint8_t bits[4];
1014      ImgType type;
1015      bool bgra;
1016   };
1017
1018   static const struct ImgFormatDesc formatTable[IMG_FORMAT_COUNT];
1019
1020public:
1021   TexInstruction(Function *, operation);
1022   virtual ~TexInstruction();
1023
1024   virtual TexInstruction *clone(ClonePolicy<Function>&,
1025                                 Instruction * = NULL) const;
1026
1027   inline void setTexture(Target targ, uint8_t r, uint8_t s)
1028   {
1029      tex.r = r;
1030      tex.s = s;
1031      tex.target = targ;
1032   }
1033
1034   void setIndirectR(Value *);
1035   void setIndirectS(Value *);
1036   inline Value *getIndirectR() const;
1037   inline Value *getIndirectS() const;
1038
1039public:
1040   struct {
1041      Target target;
1042
1043      uint16_t r;
1044      uint16_t s;
1045      int8_t rIndirectSrc;
1046      int8_t sIndirectSrc;
1047
1048      uint8_t mask;
1049      uint8_t gatherComp;
1050
1051      bool liveOnly; // only execute on live pixels of a quad (optimization)
1052      bool levelZero;
1053      bool derivAll;
1054      bool bindless;
1055
1056      int8_t useOffsets; // 0, 1, or 4 for textureGatherOffsets
1057      int8_t offset[3]; // only used on nv50
1058
1059      enum TexQuery query;
1060      const struct ImgFormatDesc *format;
1061
1062      bool scalar; // for GM107s TEXS, TLDS, TLD4S
1063   } tex;
1064
1065   ValueRef dPdx[3];
1066   ValueRef dPdy[3];
1067   ValueRef offset[4][3];
1068};
1069
1070class CmpInstruction : public Instruction
1071{
1072public:
1073   CmpInstruction(Function *, operation);
1074
1075   virtual CmpInstruction *clone(ClonePolicy<Function>&,
1076                                 Instruction * = NULL) const;
1077
1078   void setCondition(CondCode cond) { setCond = cond; }
1079   CondCode getCondition() const { return setCond; }
1080
1081public:
1082   CondCode setCond;
1083};
1084
1085class FlowInstruction : public Instruction
1086{
1087public:
1088   FlowInstruction(Function *, operation, void *target);
1089
1090   virtual FlowInstruction *clone(ClonePolicy<Function>&,
1091                                  Instruction * = NULL) const;
1092
1093public:
1094   unsigned allWarp  : 1;
1095   unsigned absolute : 1;
1096   unsigned limit    : 1;
1097   unsigned builtin  : 1; // true for calls to emulation code
1098   unsigned indirect : 1; // target in src(0)
1099
1100   union {
1101      BasicBlock *bb;
1102      int builtin;
1103      Function *fn;
1104   } target;
1105};
1106
1107class BasicBlock
1108{
1109public:
1110   BasicBlock(Function *);
1111   ~BasicBlock();
1112
1113   BasicBlock *clone(ClonePolicy<Function>&) const;
1114
1115   inline int getId() const { return id; }
1116   inline unsigned int getInsnCount() const { return numInsns; }
1117   inline bool isTerminated() const { return exit && exit->terminator; }
1118
1119   bool dominatedBy(BasicBlock *bb);
1120   inline bool reachableBy(const BasicBlock *by, const BasicBlock *term);
1121
1122   // returns mask of conditional out blocks
1123   // e.g. 3 for IF { .. } ELSE { .. } ENDIF, 1 for IF { .. } ENDIF
1124   unsigned int initiatesSimpleConditional() const;
1125
1126public:
1127   Function *getFunction() const { return func; }
1128   Program *getProgram() const { return program; }
1129
1130   Instruction *getEntry() const { return entry; } // first non-phi instruction
1131   Instruction *getPhi() const { return phi; }
1132   Instruction *getFirst() const { return phi ? phi : entry; }
1133   Instruction *getExit() const { return exit; }
1134
1135   void insertHead(Instruction *);
1136   void insertTail(Instruction *);
1137   void insertBefore(Instruction *, Instruction *);
1138   void insertAfter(Instruction *, Instruction *);
1139   void remove(Instruction *);
1140   void permuteAdjacent(Instruction *, Instruction *);
1141
1142   BasicBlock *idom() const;
1143
1144   // NOTE: currently does not rebuild the dominator tree
1145   BasicBlock *splitBefore(Instruction *, bool attach = true);
1146   BasicBlock *splitAfter(Instruction *, bool attach = true);
1147
1148   DLList& getDF() { return df; }
1149   DLList::Iterator iterDF() { return df.iterator(); }
1150
1151   static inline BasicBlock *get(Iterator&);
1152   static inline BasicBlock *get(Graph::Node *);
1153
1154public:
1155   Graph::Node cfg; // first edge is branch *taken* (the ELSE branch)
1156   Graph::Node dom;
1157
1158   BitSet liveSet;
1159   BitSet defSet;
1160
1161   uint32_t binPos;
1162   uint32_t binSize;
1163
1164   Instruction *joinAt; // for quick reference
1165
1166   bool explicitCont; // loop headers: true if loop contains continue stmts
1167
1168private:
1169   int id;
1170   DLList df;
1171
1172   Instruction *phi;
1173   Instruction *entry;
1174   Instruction *exit;
1175
1176   unsigned int numInsns;
1177
1178private:
1179   Function *func;
1180   Program *program;
1181
1182   void splitCommon(Instruction *, BasicBlock *, bool attach);
1183};
1184
1185class Function
1186{
1187public:
1188   Function(Program *, const char *name, uint32_t label);
1189   ~Function();
1190
1191   static inline Function *get(Graph::Node *node);
1192
1193   inline Program *getProgram() const { return prog; }
1194   inline const char *getName() const { return name; }
1195   inline int getId() const { return id; }
1196   inline uint32_t getLabel() const { return label; }
1197
1198   void print();
1199   void printLiveIntervals() const;
1200   void printCFGraph(const char *filePath);
1201
1202   bool setEntry(BasicBlock *);
1203   bool setExit(BasicBlock *);
1204
1205   unsigned int orderInstructions(ArrayList&);
1206
1207   inline void add(BasicBlock *bb, int& id) { allBBlocks.insert(bb, id); }
1208   inline void add(Instruction *insn, int& id) { allInsns.insert(insn, id); }
1209   inline void add(LValue *lval, int& id) { allLValues.insert(lval, id); }
1210
1211   inline LValue *getLValue(int id);
1212
1213   void buildLiveSets();
1214   void buildDefSets();
1215   bool convertToSSA();
1216
1217public:
1218   std::deque<ValueDef> ins;
1219   std::deque<ValueRef> outs;
1220   std::deque<Value *> clobbers;
1221
1222   Graph cfg;
1223   Graph::Node *cfgExit;
1224   Graph *domTree;
1225   Graph::Node call; // node in the call graph
1226
1227   BasicBlock **bbArray; // BBs in emission order
1228   int bbCount;
1229
1230   unsigned int loopNestingBound;
1231   int regClobberMax;
1232
1233   uint32_t binPos;
1234   uint32_t binSize;
1235
1236   Value *stackPtr;
1237
1238   uint32_t tlsBase; // base address for l[] space (if no stack pointer is used)
1239   uint32_t tlsSize;
1240
1241   ArrayList allBBlocks;
1242   ArrayList allInsns;
1243   ArrayList allLValues;
1244
1245private:
1246   void buildLiveSetsPreSSA(BasicBlock *, const int sequence);
1247   void buildDefSetsPreSSA(BasicBlock *bb, const int seq);
1248
1249private:
1250   uint32_t label;
1251   int id;
1252   const char *const name;
1253   Program *prog;
1254};
1255
1256enum CGStage
1257{
1258   CG_STAGE_PRE_SSA,
1259   CG_STAGE_SSA, // expected directly before register allocation
1260   CG_STAGE_POST_RA
1261};
1262
1263class Program
1264{
1265public:
1266   enum Type
1267   {
1268      TYPE_VERTEX,
1269      TYPE_TESSELLATION_CONTROL,
1270      TYPE_TESSELLATION_EVAL,
1271      TYPE_GEOMETRY,
1272      TYPE_FRAGMENT,
1273      TYPE_COMPUTE
1274   };
1275
1276   Program(Type type, Target *targ);
1277   ~Program();
1278
1279   void print();
1280
1281   Type getType() const { return progType; }
1282
1283   inline void add(Function *fn, int& id) { allFuncs.insert(fn, id); }
1284   inline void del(Function *fn, int& id) { allFuncs.remove(id); }
1285   inline void add(Value *rval, int& id) { allRValues.insert(rval, id); }
1286
1287   bool makeFromNIR(struct nv50_ir_prog_info *);
1288   bool makeFromTGSI(struct nv50_ir_prog_info *);
1289   bool convertToSSA();
1290   bool optimizeSSA(int level);
1291   bool optimizePostRA(int level);
1292   bool registerAllocation();
1293   bool emitBinary(struct nv50_ir_prog_info *);
1294
1295   const Target *getTarget() const { return target; }
1296
1297private:
1298   void emitSymbolTable(struct nv50_ir_prog_info *);
1299
1300   Type progType;
1301   Target *target;
1302
1303public:
1304   Function *main;
1305   Graph calls;
1306
1307   ArrayList allFuncs;
1308   ArrayList allRValues;
1309
1310   uint32_t *code;
1311   uint32_t binSize;
1312   uint32_t tlsSize; // size required for FILE_MEMORY_LOCAL
1313
1314   int maxGPR;
1315   bool fp64;
1316
1317   MemoryPool mem_Instruction;
1318   MemoryPool mem_CmpInstruction;
1319   MemoryPool mem_TexInstruction;
1320   MemoryPool mem_FlowInstruction;
1321   MemoryPool mem_LValue;
1322   MemoryPool mem_Symbol;
1323   MemoryPool mem_ImmediateValue;
1324
1325   uint32_t dbgFlags;
1326   uint8_t  optLevel;
1327
1328   void *targetPriv; // e.g. to carry information between passes
1329
1330   const struct nv50_ir_prog_info *driver; // for driver configuration
1331
1332   void releaseInstruction(Instruction *);
1333   void releaseValue(Value *);
1334};
1335
1336// TODO: add const version
1337class Pass
1338{
1339public:
1340   bool run(Program *, bool ordered = false, bool skipPhi = false);
1341   bool run(Function *, bool ordered = false, bool skipPhi = false);
1342
1343private:
1344   // return false to continue with next entity on next higher level
1345   virtual bool visit(Function *) { return true; }
1346   virtual bool visit(BasicBlock *) { return true; }
1347   virtual bool visit(Instruction *) { return false; }
1348
1349   bool doRun(Program *, bool ordered, bool skipPhi);
1350   bool doRun(Function *, bool ordered, bool skipPhi);
1351
1352protected:
1353   bool err;
1354   Function *func;
1355   Program *prog;
1356};
1357
1358// =============================================================================
1359
1360#include "codegen/nv50_ir_inlines.h"
1361
1362} // namespace nv50_ir
1363
1364#endif // __NV50_IR_H__
1365