~ubuntu-branches/ubuntu/precise/mesa/precise-updates

« back to all changes in this revision

Viewing changes to src/gallium/drivers/nv50/codegen/nv50_ir.h

  • Committer: Package Import Robot
  • Author(s): Robert Hooker
  • Date: 2012-02-02 12:05:48 UTC
  • mfrom: (1.7.1) (3.3.27 sid)
  • Revision ID: package-import@ubuntu.com-20120202120548-nvkma85jq0h4coix
Tags: 8.0~rc2-0ubuntu4
Drop drisearchdir handling, it is no longer needed with multiarch
and dri-alternates being removed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 
18
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 
19
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 
20
 * 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
 
 
30
#include "nv50_ir_util.h"
 
31
#include "nv50_ir_graph.h"
 
32
 
 
33
#include "nv50_ir_driver.h"
 
34
 
 
35
namespace nv50_ir {
 
36
 
 
37
enum operation
 
38
{
 
39
   OP_NOP = 0,
 
40
   OP_PHI,
 
41
   OP_UNION, // unify a new definition and several source values
 
42
   OP_SPLIT, // $r0d -> { $r0, $r1 } ($r0d and $r0/$r1 will be coalesced)
 
43
   OP_MERGE, // opposite of split, e.g. combine 2 32 bit into a 64 bit value
 
44
   OP_CONSTRAINT, // copy values into consecutive registers
 
45
   OP_MOV,
 
46
   OP_LOAD,
 
47
   OP_STORE,
 
48
   OP_ADD,
 
49
   OP_SUB,
 
50
   OP_MUL,
 
51
   OP_DIV,
 
52
   OP_MOD,
 
53
   OP_MAD,
 
54
   OP_FMA,
 
55
   OP_SAD, // abs(src0 - src1) + src2
 
56
   OP_ABS,
 
57
   OP_NEG,
 
58
   OP_NOT,
 
59
   OP_AND,
 
60
   OP_OR,
 
61
   OP_XOR,
 
62
   OP_SHL,
 
63
   OP_SHR,
 
64
   OP_MAX,
 
65
   OP_MIN,
 
66
   OP_SAT,  // CLAMP(f32, 0.0, 1.0)
 
67
   OP_CEIL,
 
68
   OP_FLOOR,
 
69
   OP_TRUNC,
 
70
   OP_CVT,
 
71
   OP_SET_AND, // dst = (src0 CMP src1) & src2
 
72
   OP_SET_OR,
 
73
   OP_SET_XOR,
 
74
   OP_SET,
 
75
   OP_SELP, // dst = src2 ? src0 : src1
 
76
   OP_SLCT, // dst = (src2 CMP 0) ? src0 : src1
 
77
   OP_RCP,
 
78
   OP_RSQ,
 
79
   OP_LG2,
 
80
   OP_SIN,
 
81
   OP_COS,
 
82
   OP_EX2,
 
83
   OP_EXP, // exponential (base M_E)
 
84
   OP_LOG, // natural logarithm
 
85
   OP_PRESIN,
 
86
   OP_PREEX2,
 
87
   OP_SQRT,
 
88
   OP_POW,
 
89
   OP_BRA,
 
90
   OP_CALL,
 
91
   OP_RET,
 
92
   OP_CONT,
 
93
   OP_BREAK,
 
94
   OP_PRERET,
 
95
   OP_PRECONT,
 
96
   OP_PREBREAK,
 
97
   OP_BRKPT,     // breakpoint (not related to loops)
 
98
   OP_JOINAT,    // push control flow convergence point
 
99
   OP_JOIN,      // converge
 
100
   OP_DISCARD,
 
101
   OP_EXIT,
 
102
   OP_MEMBAR,
 
103
   OP_VFETCH, // indirection 0 in attribute space, indirection 1 is vertex base
 
104
   OP_PFETCH, // fetch base address of vertex src0 (immediate) [+ src1]
 
105
   OP_EXPORT,
 
106
   OP_LINTERP,
 
107
   OP_PINTERP,
 
108
   OP_EMIT,    // emit vertex
 
109
   OP_RESTART, // restart primitive
 
110
   OP_TEX,
 
111
   OP_TXB, // texture bias
 
112
   OP_TXL, // texure lod
 
113
   OP_TXF, // texel fetch
 
114
   OP_TXQ, // texture size query
 
115
   OP_TXD, // texture derivatives
 
116
   OP_TXG, // texture gather
 
117
   OP_TEXCSAA,
 
118
   OP_SULD, // surface load
 
119
   OP_SUST, // surface store
 
120
   OP_DFDX,
 
121
   OP_DFDY,
 
122
   OP_RDSV, // read system value
 
123
   OP_WRSV, // write system value
 
124
   OP_PIXLD,
 
125
   OP_QUADOP,
 
126
   OP_QUADON,
 
127
   OP_QUADPOP,
 
128
   OP_POPCNT, // bitcount(src0 & src1)
 
129
   OP_INSBF,  // insert first src1[8:15] bits of src0 into src2 at src1[0:7]
 
130
   OP_EXTBF,
 
131
   OP_LAST
 
132
};
 
133
 
 
134
#define NV50_IR_SUBOP_MUL_HIGH     1
 
135
#define NV50_IR_SUBOP_EMIT_RESTART 1
 
136
#define NV50_IR_SUBOP_LDC_IL       1
 
137
#define NV50_IR_SUBOP_LDC_IS       2
 
138
#define NV50_IR_SUBOP_LDC_ISL      3
 
139
#define NV50_IR_SUBOP_SHIFT_WRAP   1
 
140
 
 
141
enum DataType
 
142
{
 
143
   TYPE_NONE,
 
144
   TYPE_U8,
 
145
   TYPE_S8,
 
146
   TYPE_U16,
 
147
   TYPE_S16,
 
148
   TYPE_U32,
 
149
   TYPE_S32,
 
150
   TYPE_U64, // 64 bit operations are only lowered after register allocation
 
151
   TYPE_S64,
 
152
   TYPE_F16,
 
153
   TYPE_F32,
 
154
   TYPE_F64,
 
155
   TYPE_B96,
 
156
   TYPE_B128
 
157
};
 
158
 
 
159
enum CondCode
 
160
{
 
161
   CC_FL = 0,
 
162
   CC_NEVER = CC_FL, // when used with FILE_FLAGS
 
163
   CC_LT = 1,
 
164
   CC_EQ = 2,
 
165
   CC_NOT_P = CC_EQ, // when used with FILE_PREDICATE
 
166
   CC_LE = 3,
 
167
   CC_GT = 4,
 
168
   CC_NE = 5,
 
169
   CC_P  = CC_NE,
 
170
   CC_GE = 6,
 
171
   CC_TR = 7,
 
172
   CC_ALWAYS = CC_TR,
 
173
   CC_U  = 8,
 
174
   CC_LTU = 9,
 
175
   CC_EQU = 10,
 
176
   CC_LEU = 11,
 
177
   CC_GTU = 12,
 
178
   CC_NEU = 13,
 
179
   CC_GEU = 14,
 
180
   CC_NO = 0x10,
 
181
   CC_NC = 0x11,
 
182
   CC_NS = 0x12,
 
183
   CC_NA = 0x13,
 
184
   CC_A  = 0x14,
 
185
   CC_S  = 0x15,
 
186
   CC_C  = 0x16,
 
187
   CC_O  = 0x17
 
188
};
 
189
 
 
190
enum RoundMode
 
191
{
 
192
   ROUND_N, // nearest
 
193
   ROUND_M, // towards -inf
 
194
   ROUND_Z, // towards 0
 
195
   ROUND_P, // towards +inf
 
196
   ROUND_NI, // nearest integer
 
197
   ROUND_MI, // to integer towards -inf
 
198
   ROUND_ZI, // to integer towards 0
 
199
   ROUND_PI, // to integer towards +inf
 
200
};
 
201
 
 
202
enum CacheMode
 
203
{
 
204
   CACHE_CA,            // cache at all levels
 
205
   CACHE_WB = CACHE_CA, // cache write back
 
206
   CACHE_CG,            // cache at global level
 
207
   CACHE_CS,            // cache streaming
 
208
   CACHE_CV,            // cache as volatile
 
209
   CACHE_WT = CACHE_CV  // cache write-through
 
210
};
 
211
 
 
212
enum DataFile
 
213
{
 
214
   FILE_NULL = 0,
 
215
   FILE_GPR,
 
216
   FILE_PREDICATE,       // boolean predicate
 
217
   FILE_FLAGS,           // zero/sign/carry/overflow bits
 
218
   FILE_ADDRESS,
 
219
   FILE_IMMEDIATE,
 
220
   FILE_MEMORY_CONST,
 
221
   FILE_SHADER_INPUT,
 
222
   FILE_SHADER_OUTPUT,
 
223
   FILE_MEMORY_GLOBAL,
 
224
   FILE_MEMORY_SHARED,
 
225
   FILE_MEMORY_LOCAL,
 
226
   FILE_SYSTEM_VALUE,
 
227
   DATA_FILE_COUNT
 
228
};
 
229
 
 
230
enum TexTarget
 
231
{
 
232
   TEX_TARGET_1D,
 
233
   TEX_TARGET_2D,
 
234
   TEX_TARGET_2D_MS,
 
235
   TEX_TARGET_3D,
 
236
   TEX_TARGET_CUBE,
 
237
   TEX_TARGET_1D_SHADOW,
 
238
   TEX_TARGET_2D_SHADOW,
 
239
   TEX_TARGET_CUBE_SHADOW,
 
240
   TEX_TARGET_1D_ARRAY,
 
241
   TEX_TARGET_2D_ARRAY,
 
242
   TEX_TARGET_2D_MS_ARRAY,
 
243
   TEX_TARGET_CUBE_ARRAY,
 
244
   TEX_TARGET_1D_ARRAY_SHADOW,
 
245
   TEX_TARGET_2D_ARRAY_SHADOW,
 
246
   TEX_TARGET_RECT,
 
247
   TEX_TARGET_RECT_SHADOW,
 
248
   TEX_TARGET_CUBE_ARRAY_SHADOW,
 
249
   TEX_TARGET_BUFFER,
 
250
   TEX_TARGET_COUNT
 
251
};
 
252
 
 
253
enum SVSemantic
 
254
{
 
255
   SV_POSITION, // WPOS
 
256
   SV_VERTEX_ID,
 
257
   SV_INSTANCE_ID,
 
258
   SV_INVOCATION_ID,
 
259
   SV_PRIMITIVE_ID,
 
260
   SV_VERTEX_COUNT, // gl_PatchVerticesIn
 
261
   SV_LAYER,
 
262
   SV_VIEWPORT_INDEX,
 
263
   SV_YDIR,
 
264
   SV_FACE,
 
265
   SV_POINT_SIZE,
 
266
   SV_POINT_COORD,
 
267
   SV_CLIP_DISTANCE,
 
268
   SV_SAMPLE_INDEX,
 
269
   SV_TESS_FACTOR,
 
270
   SV_TESS_COORD,
 
271
   SV_TID,
 
272
   SV_CTAID,
 
273
   SV_NTID,
 
274
   SV_GRIDID,
 
275
   SV_NCTAID,
 
276
   SV_LANEID,
 
277
   SV_PHYSID,
 
278
   SV_NPHYSID,
 
279
   SV_CLOCK,
 
280
   SV_LBASE,
 
281
   SV_SBASE,
 
282
   SV_UNDEFINED,
 
283
   SV_LAST
 
284
};
 
285
 
 
286
class Program;
 
287
class Function;
 
288
class BasicBlock;
 
289
 
 
290
class Target;
 
291
 
 
292
class Instruction;
 
293
class CmpInstruction;
 
294
class TexInstruction;
 
295
class FlowInstruction;
 
296
 
 
297
class Value;
 
298
class LValue;
 
299
class Symbol;
 
300
class ImmediateValue;
 
301
 
 
302
struct Storage
 
303
{
 
304
   DataFile file;
 
305
   int8_t fileIndex; // signed, may be indirect for CONST[]
 
306
   uint8_t size; // this should match the Instruction type's size
 
307
   DataType type; // mainly for pretty printing
 
308
   union {
 
309
      uint64_t u64;    // immediate values
 
310
      uint32_t u32;
 
311
      uint16_t u16;
 
312
      uint8_t u8;
 
313
      int64_t s64;
 
314
      int32_t s32;
 
315
      int16_t s16;
 
316
      int8_t s8;
 
317
      float f32;
 
318
      double f64;
 
319
      int32_t offset; // offset from 0 (base of address space)
 
320
      int32_t id;     // register id (< 0 if virtual/unassigned)
 
321
      struct {
 
322
         SVSemantic sv;
 
323
         int index;
 
324
      } sv;
 
325
   } data;
 
326
};
 
327
 
 
328
// precedence: NOT after SAT after NEG after ABS
 
329
#define NV50_IR_MOD_ABS (1 << 0)
 
330
#define NV50_IR_MOD_NEG (1 << 1)
 
331
#define NV50_IR_MOD_SAT (1 << 2)
 
332
#define NV50_IR_MOD_NOT (1 << 3)
 
333
#define NV50_IR_MOD_NEG_ABS (NV50_IR_MOD_NEG | NV50_IR_MOD_ABS)
 
334
 
 
335
#define NV50_IR_INTERP_MODE_MASK   0x3
 
336
#define NV50_IR_INTERP_LINEAR      (0 << 0)
 
337
#define NV50_IR_INTERP_PERSPECTIVE (1 << 0)
 
338
#define NV50_IR_INTERP_FLAT        (2 << 0)
 
339
#define NV50_IR_INTERP_SC          (3 << 0) // what exactly is that ?
 
340
#define NV50_IR_INTERP_SAMPLE_MASK 0xc
 
341
#define NV50_IR_INTERP_DEFAULT     (0 << 2)
 
342
#define NV50_IR_INTERP_CENTROID    (1 << 2)
 
343
#define NV50_IR_INTERP_OFFSET      (2 << 2)
 
344
#define NV50_IR_INTERP_SAMPLEID    (3 << 2)
 
345
 
 
346
// do we really want this to be a class ?
 
347
class Modifier
 
348
{
 
349
public:
 
350
   Modifier() : bits(0) { }
 
351
   Modifier(unsigned int m) : bits(m) { }
 
352
   Modifier(operation op);
 
353
 
 
354
   // @return new Modifier applying a after b (asserts if unrepresentable)
 
355
   Modifier operator*(const Modifier) const;
 
356
   Modifier operator==(const Modifier m) const { return m.bits == bits; }
 
357
   Modifier operator!=(const Modifier m) const { return m.bits != bits; }
 
358
 
 
359
   inline Modifier operator&(const Modifier m) const { return bits & m.bits; }
 
360
   inline Modifier operator|(const Modifier m) const { return bits | m.bits; }
 
361
   inline Modifier operator^(const Modifier m) const { return bits ^ m.bits; }
 
362
 
 
363
   operation getOp() const;
 
364
 
 
365
   inline int neg() const { return (bits & NV50_IR_MOD_NEG) ? 1 : 0; }
 
366
   inline int abs() const { return (bits & NV50_IR_MOD_ABS) ? 1 : 0; }
 
367
 
 
368
   inline operator bool() { return bits ? true : false; }
 
369
 
 
370
   void applyTo(ImmediateValue &imm) const;
 
371
 
 
372
   int print(char *buf, size_t size) const;
 
373
 
 
374
private:
 
375
   uint8_t bits;
 
376
};
 
377
 
 
378
class ValueRef
 
379
{
 
380
public:
 
381
   ValueRef();
 
382
   ~ValueRef();
 
383
 
 
384
   inline ValueRef& operator=(Value *val) { this->set(val); return *this; }
 
385
 
 
386
   inline bool exists() const { return value != NULL; }
 
387
 
 
388
   void set(Value *);
 
389
   void set(const ValueRef&);
 
390
   inline Value *get() const { return value; }
 
391
   inline Value *rep() const;
 
392
 
 
393
   inline Instruction *getInsn() const { return insn; }
 
394
   inline void setInsn(Instruction *inst) { insn = inst; }
 
395
 
 
396
   inline bool isIndirect(int dim) const { return indirect[dim] >= 0; }
 
397
   inline const ValueRef *getIndirect(int dim) const;
 
398
 
 
399
   inline DataFile getFile() const;
 
400
   inline unsigned getSize() const;
 
401
 
 
402
   // SSA: return eventual (traverse MOVs) literal value, if it exists
 
403
   ImmediateValue *getImmediate() const;
 
404
 
 
405
   class Iterator
 
406
   {
 
407
   public:
 
408
      Iterator(ValueRef *ref) : pos(ref), ini(ref) { }
 
409
 
 
410
      inline ValueRef *get() const { return pos; }
 
411
      inline bool end() const { return pos == NULL; }
 
412
      inline void next() { pos = (pos->next != ini) ? pos->next : 0; }
 
413
 
 
414
   private:
 
415
      ValueRef *pos, *ini;
 
416
   };
 
417
 
 
418
   inline Iterator iterator() { return Iterator(this); }
 
419
 
 
420
public:
 
421
   Modifier mod;
 
422
   int8_t indirect[2]; // >= 0 if relative to lvalue in insn->src[indirect[i]]
 
423
   uint8_t swizzle;
 
424
 
 
425
   bool usedAsPtr; // for printing
 
426
 
 
427
private:
 
428
   Value *value;
 
429
   Instruction *insn;
 
430
   ValueRef *next; // to link uses of the value
 
431
   ValueRef *prev;
 
432
};
 
433
 
 
434
class ValueDef
 
435
{
 
436
public:
 
437
   ValueDef();
 
438
   ~ValueDef();
 
439
 
 
440
   inline ValueDef& operator=(Value *val) { this->set(val); return *this; }
 
441
 
 
442
   inline bool exists() const { return value != NULL; }
 
443
 
 
444
   inline Value *get() const { return value; }
 
445
   inline Value *rep() const;
 
446
   void set(Value *);
 
447
   void replace(Value *, bool doSet); // replace all uses of the old value
 
448
 
 
449
   inline Instruction *getInsn() const { return insn; }
 
450
   inline void setInsn(Instruction *inst) { insn = inst; }
 
451
 
 
452
   inline DataFile getFile() const;
 
453
   inline unsigned getSize() const;
 
454
 
 
455
   // HACK: save the pre-SSA value in 'prev', in SSA we don't need the def list
 
456
   //  but we'll use it again for coalescing in register allocation
 
457
   inline void setSSA(LValue *);
 
458
   inline const LValue *preSSA() const;
 
459
   inline void restoreDefList(); // after having been abused for SSA hack
 
460
   void mergeDefs(ValueDef *);
 
461
 
 
462
   class Iterator
 
463
   {
 
464
   public:
 
465
      Iterator(ValueDef *def) : pos(def), ini(def) { }
 
466
 
 
467
      inline ValueDef *get() const { return pos; }
 
468
      inline bool end() const { return pos == NULL; }
 
469
      inline void next() { pos = (pos->next != ini) ? pos->next : NULL; }
 
470
 
 
471
   private:
 
472
      ValueDef *pos, *ini;
 
473
   };
 
474
 
 
475
   inline Iterator iterator() { return Iterator(this); }
 
476
 
 
477
private:
 
478
   Value *value;   // should make this LValue * ...
 
479
   Instruction *insn;
 
480
   ValueDef *next; // circular list of all definitions of the same value
 
481
   ValueDef *prev;
 
482
};
 
483
 
 
484
class Value
 
485
{
 
486
public:
 
487
   Value();
 
488
 
 
489
   virtual Value *clone(Function *) const { return NULL; }
 
490
 
 
491
   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const = 0;
 
492
 
 
493
   virtual bool equals(const Value *, bool strict = false) const;
 
494
   virtual bool interfers(const Value *) const;
 
495
 
 
496
   inline Instruction *getUniqueInsn() const;
 
497
   inline Instruction *getInsn() const; // use when uniqueness is certain
 
498
 
 
499
   inline int refCount() { return refCnt; }
 
500
   inline int ref() { return ++refCnt; }
 
501
   inline int unref() { --refCnt; assert(refCnt >= 0); return refCnt; }
 
502
 
 
503
   inline LValue *asLValue();
 
504
   inline Symbol *asSym();
 
505
   inline ImmediateValue *asImm();
 
506
   inline const Symbol *asSym() const;
 
507
   inline const ImmediateValue *asImm() const;
 
508
 
 
509
   bool coalesce(Value *, bool force = false);
 
510
 
 
511
   inline bool inFile(DataFile f) { return reg.file == f; }
 
512
 
 
513
   static inline Value *get(Iterator&);
 
514
 
 
515
protected:
 
516
   int refCnt;
 
517
 
 
518
   friend class ValueDef;
 
519
   friend class ValueRef;
 
520
 
 
521
public:
 
522
   int id;
 
523
   ValueRef *uses;
 
524
   ValueDef *defs;
 
525
   Storage reg;
 
526
 
 
527
   // TODO: these should be in LValue:
 
528
   Interval livei;
 
529
   Value *join;
 
530
};
 
531
 
 
532
class LValue : public Value
 
533
{
 
534
public:
 
535
   LValue(Function *, DataFile file);
 
536
   LValue(Function *, LValue *);
 
537
 
 
538
   virtual Value *clone(Function *) const;
 
539
 
 
540
   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const;
 
541
 
 
542
public:
 
543
   unsigned ssa : 1;
 
544
 
 
545
   int affinity;
 
546
};
 
547
 
 
548
class Symbol : public Value
 
549
{
 
550
public:
 
551
   Symbol(Program *, DataFile file = FILE_MEMORY_CONST, ubyte fileIdx = 0);
 
552
 
 
553
   virtual Value *clone(Function *) const;
 
554
 
 
555
   virtual bool equals(const Value *that, bool strict) const;
 
556
 
 
557
   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const;
 
558
 
 
559
   // print with indirect values
 
560
   int print(char *, size_t, Value *, Value *, DataType ty = TYPE_NONE) const;
 
561
 
 
562
   inline void setFile(DataFile file, ubyte fileIndex = 0)
 
563
   {
 
564
      reg.file = file;
 
565
      reg.fileIndex = fileIndex;
 
566
   }
 
567
 
 
568
   inline void setOffset(int32_t offset);
 
569
   inline void setAddress(Symbol *base, int32_t offset);
 
570
   inline void setSV(SVSemantic sv, uint32_t idx = 0);
 
571
 
 
572
   inline const Symbol *getBase() const { return baseSym; }
 
573
 
 
574
private:
 
575
   Symbol *baseSym; // array base for Symbols representing array elements
 
576
};
 
577
 
 
578
class ImmediateValue : public Value
 
579
{
 
580
public:
 
581
   ImmediateValue(Program *, uint32_t);
 
582
   ImmediateValue(Program *, float);
 
583
   ImmediateValue(Program *, double);
 
584
 
 
585
   // NOTE: not added to program with
 
586
   ImmediateValue(const ImmediateValue *, DataType ty);
 
587
 
 
588
   virtual bool equals(const Value *that, bool strict) const;
 
589
 
 
590
   // these only work if 'type' is valid (we mostly use untyped literals):
 
591
   bool isInteger(const int ival) const; // ival is cast to this' type
 
592
   bool isNegative() const;
 
593
   bool isPow2() const;
 
594
 
 
595
   void applyLog2();
 
596
 
 
597
   // for constant folding:
 
598
   ImmediateValue operator+(const ImmediateValue&) const;
 
599
   ImmediateValue operator-(const ImmediateValue&) const;
 
600
   ImmediateValue operator*(const ImmediateValue&) const;
 
601
   ImmediateValue operator/(const ImmediateValue&) const;
 
602
 
 
603
   bool compare(CondCode cc, float fval) const;
 
604
 
 
605
   virtual int print(char *, size_t, DataType ty = TYPE_NONE) const;
 
606
};
 
607
 
 
608
 
 
609
#define NV50_IR_MAX_DEFS 4
 
610
#define NV50_IR_MAX_SRCS 8
 
611
 
 
612
class Instruction
 
613
{
 
614
public:
 
615
   Instruction();
 
616
   Instruction(Function *, operation, DataType);
 
617
   virtual ~Instruction();
 
618
 
 
619
   virtual Instruction *clone(bool deep) const;
 
620
 
 
621
   inline void setDef(int i, Value *val) { def[i].set(val); }
 
622
   inline void setSrc(int s, Value *val) { src[s].set(val); }
 
623
   void setSrc(int s, ValueRef&);
 
624
   void swapSources(int a, int b);
 
625
   bool setIndirect(int s, int dim, Value *);
 
626
 
 
627
   inline Value *getDef(int d) const { return def[d].get(); }
 
628
   inline Value *getSrc(int s) const { return src[s].get(); }
 
629
   inline Value *getIndirect(int s, int dim) const;
 
630
 
 
631
   inline bool defExists(int d) const { return d < 4 && def[d].exists(); }
 
632
   inline bool srcExists(int s) const { return s < 8 && src[s].exists(); }
 
633
 
 
634
   inline bool constrainedDefs() const { return def[1].exists(); }
 
635
 
 
636
   bool setPredicate(CondCode ccode, Value *);
 
637
   inline Value *getPredicate() const;
 
638
   bool writesPredicate() const;
 
639
 
 
640
   unsigned int defCount(unsigned int mask) const;
 
641
   unsigned int srcCount(unsigned int mask) const;
 
642
 
 
643
   // save & remove / set indirect[0,1] and predicate source
 
644
   void takeExtraSources(int s, Value *[3]);
 
645
   void putExtraSources(int s, Value *[3]);
 
646
 
 
647
   inline void setType(DataType type) { dType = sType = type; }
 
648
 
 
649
   inline void setType(DataType dtype, DataType stype)
 
650
   {
 
651
      dType = dtype;
 
652
      sType = stype;
 
653
   }
 
654
 
 
655
   inline bool isPseudo() const { return op < OP_MOV; }
 
656
   bool isDead() const;
 
657
   bool isNop() const;
 
658
   bool isCommutationLegal(const Instruction *) const; // must be adjacent !
 
659
   bool isActionEqual(const Instruction *) const;
 
660
   bool isResultEqual(const Instruction *) const;
 
661
 
 
662
   void print() const;
 
663
 
 
664
   inline CmpInstruction *asCmp();
 
665
   inline TexInstruction *asTex();
 
666
   inline FlowInstruction *asFlow();
 
667
   inline const TexInstruction *asTex() const;
 
668
   inline const CmpInstruction *asCmp() const;
 
669
   inline const FlowInstruction *asFlow() const;
 
670
 
 
671
public:
 
672
   Instruction *next;
 
673
   Instruction *prev;
 
674
   int id;
 
675
   int serial; // CFG order
 
676
 
 
677
   operation op;
 
678
   DataType dType; // destination or defining type
 
679
   DataType sType; // source or secondary type
 
680
   CondCode cc;
 
681
   RoundMode rnd;
 
682
   CacheMode cache;
 
683
 
 
684
   uint8_t subOp; // quadop, 1 for mul-high, etc.
 
685
 
 
686
   unsigned encSize    : 4; // encoding size in bytes
 
687
   unsigned saturate   : 1; // to [0.0f, 1.0f]
 
688
   unsigned join       : 1; // converge control flow (use OP_JOIN until end)
 
689
   unsigned fixed      : 1; // prevent dead code elimination
 
690
   unsigned terminator : 1; // end of basic block
 
691
   unsigned atomic     : 1;
 
692
   unsigned ftz        : 1; // flush denormal to zero
 
693
   unsigned dnz        : 1; // denormals, NaN are zero
 
694
   unsigned ipa        : 4; // interpolation mode
 
695
   unsigned lanes      : 4;
 
696
   unsigned perPatch   : 1;
 
697
   unsigned exit       : 1; // terminate program after insn
 
698
 
 
699
   int8_t postFactor; // MUL/DIV(if < 0) by 1 << postFactor
 
700
 
 
701
   int8_t predSrc;
 
702
   int8_t flagsDef;
 
703
   int8_t flagsSrc;
 
704
 
 
705
   // NOTE: should make these pointers, saves space and work on shuffling
 
706
   ValueDef def[NV50_IR_MAX_DEFS]; // no gaps !
 
707
   ValueRef src[NV50_IR_MAX_SRCS]; // no gaps !
 
708
 
 
709
   BasicBlock *bb;
 
710
 
 
711
   // instruction specific methods:
 
712
   // (don't want to subclass, would need more constructors and memory pools)
 
713
public:
 
714
   inline void setInterpolate(unsigned int mode) { ipa = mode; }
 
715
 
 
716
   unsigned int getInterpMode() const { return ipa & 0x3; }
 
717
   unsigned int getSampleMode() const { return ipa & 0xc; }
 
718
 
 
719
private:
 
720
   void init();
 
721
protected:
 
722
   void cloneBase(Instruction *clone, bool deep) const;
 
723
};
 
724
 
 
725
enum TexQuery
 
726
{
 
727
   TXQ_DIMS,
 
728
   TXQ_TYPE,
 
729
   TXQ_SAMPLE_POSITION,
 
730
   TXQ_FILTER,
 
731
   TXQ_LOD,
 
732
   TXQ_WRAP,
 
733
   TXQ_BORDER_COLOUR
 
734
};
 
735
 
 
736
class TexInstruction : public Instruction
 
737
{
 
738
public:
 
739
   class Target
 
740
   {
 
741
   public:
 
742
      Target(TexTarget targ = TEX_TARGET_2D) : target(targ) { }
 
743
 
 
744
      const char *getName() const { return descTable[target].name; }
 
745
      unsigned int getArgCount() const { return descTable[target].argc; }
 
746
      unsigned int getDim() const { return descTable[target].dim; }
 
747
      int isArray() const { return descTable[target].array ? 1 : 0; }
 
748
      int isCube() const { return descTable[target].cube ? 1 : 0; }
 
749
      int isShadow() const { return descTable[target].shadow ? 1 : 0; }
 
750
 
 
751
      Target& operator=(TexTarget targ)
 
752
      {
 
753
         assert(targ < TEX_TARGET_COUNT);
 
754
         return *this;
 
755
      }
 
756
 
 
757
      inline bool operator==(TexTarget targ) const { return target == targ; }
 
758
 
 
759
   private:
 
760
      struct Desc
 
761
      {
 
762
         char name[19];
 
763
         uint8_t dim;
 
764
         uint8_t argc;
 
765
         bool array;
 
766
         bool cube;
 
767
         bool shadow;
 
768
      };
 
769
 
 
770
      static const struct Desc descTable[TEX_TARGET_COUNT];
 
771
 
 
772
   private:
 
773
      enum TexTarget target;
 
774
   };
 
775
 
 
776
public:
 
777
   TexInstruction(Function *, operation);
 
778
   virtual ~TexInstruction();
 
779
 
 
780
   virtual Instruction *clone(bool deep) const;
 
781
 
 
782
   inline void setTexture(Target targ, uint8_t r, uint8_t s)
 
783
   {
 
784
      tex.r = r;
 
785
      tex.s = s;
 
786
      tex.target = targ;
 
787
   }
 
788
 
 
789
   inline Value *getIndirectR() const;
 
790
   inline Value *getIndirectS() const;
 
791
 
 
792
public:
 
793
   struct {
 
794
      Target target;
 
795
 
 
796
      uint8_t r;
 
797
      int8_t rIndirectSrc;
 
798
      uint8_t s;
 
799
      int8_t sIndirectSrc;
 
800
 
 
801
      uint8_t mask;
 
802
      uint8_t gatherComp;
 
803
 
 
804
      bool liveOnly; // only execute on live pixels of a quad (optimization)
 
805
      bool levelZero;
 
806
      bool derivAll;
 
807
 
 
808
      int8_t useOffsets; // 0, 1, or 4 for textureGatherOffsets
 
809
      int8_t offset[4][3];
 
810
 
 
811
      enum TexQuery query;
 
812
   } tex;
 
813
 
 
814
   ValueRef dPdx[3];
 
815
   ValueRef dPdy[3];
 
816
};
 
817
 
 
818
class CmpInstruction : public Instruction
 
819
{
 
820
public:
 
821
   CmpInstruction(Function *, operation);
 
822
 
 
823
   virtual Instruction *clone(bool deep) const;
 
824
 
 
825
   void setCondition(CondCode cond) { setCond = cond; }
 
826
   CondCode getCondition() const { return setCond; }
 
827
 
 
828
public:
 
829
   CondCode setCond;
 
830
};
 
831
 
 
832
class FlowInstruction : public Instruction
 
833
{
 
834
public:
 
835
   FlowInstruction(Function *, operation, BasicBlock *target);
 
836
 
 
837
public:
 
838
   unsigned allWarp  : 1;
 
839
   unsigned absolute : 1;
 
840
   unsigned limit    : 1;
 
841
   unsigned builtin  : 1; // true for calls to emulation code
 
842
 
 
843
   union {
 
844
      BasicBlock *bb;
 
845
      int builtin;
 
846
      Function *fn;
 
847
   } target;
 
848
};
 
849
 
 
850
class BasicBlock
 
851
{
 
852
public:
 
853
   BasicBlock(Function *);
 
854
   ~BasicBlock();
 
855
 
 
856
   inline int getId() const { return id; }
 
857
   inline unsigned int getInsnCount() const { return numInsns; }
 
858
   inline bool isTerminated() const { return exit && exit->terminator; }
 
859
 
 
860
   bool dominatedBy(BasicBlock *bb);
 
861
   inline bool reachableBy(BasicBlock *by, BasicBlock *term);
 
862
 
 
863
   // returns mask of conditional out blocks
 
864
   // e.g. 3 for IF { .. } ELSE { .. } ENDIF, 1 for IF { .. } ENDIF
 
865
   unsigned int initiatesSimpleConditional() const;
 
866
 
 
867
public:
 
868
   Function *getFunction() const { return func; }
 
869
   Program *getProgram() const { return program; }
 
870
 
 
871
   Instruction *getEntry() const { return entry; } // first non-phi instruction
 
872
   Instruction *getPhi() const { return phi; }
 
873
   Instruction *getFirst() const { return phi ? phi : entry; }
 
874
   Instruction *getExit() const { return exit; }
 
875
 
 
876
   void insertHead(Instruction *);
 
877
   void insertTail(Instruction *);
 
878
   void insertBefore(Instruction *, Instruction *);
 
879
   void insertAfter(Instruction *, Instruction *);
 
880
   void remove(Instruction *);
 
881
   void permuteAdjacent(Instruction *, Instruction *);
 
882
 
 
883
   BasicBlock *idom() const;
 
884
 
 
885
   DLList& getDF() { return df; }
 
886
   DLList::Iterator iterDF() { return df.iterator(); }
 
887
 
 
888
   static inline BasicBlock *get(Iterator&);
 
889
   static inline BasicBlock *get(Graph::Node *);
 
890
 
 
891
public:
 
892
   Graph::Node cfg; // first edge is branch *taken* (the ELSE branch)
 
893
   Graph::Node dom;
 
894
 
 
895
   BitSet liveSet;
 
896
 
 
897
   uint32_t binPos;
 
898
   uint32_t binSize;
 
899
 
 
900
   Instruction *joinAt; // for quick reference
 
901
 
 
902
   bool explicitCont; // loop headers: true if loop contains continue stmts
 
903
 
 
904
private:
 
905
   int id;
 
906
   DLList df;
 
907
 
 
908
   Instruction *phi;
 
909
   Instruction *entry;
 
910
   Instruction *exit;
 
911
 
 
912
   unsigned int numInsns;
 
913
 
 
914
private:
 
915
   Function *func;
 
916
   Program *program;
 
917
};
 
918
 
 
919
class Function
 
920
{
 
921
public:
 
922
   Function(Program *, const char *name);
 
923
   ~Function();
 
924
 
 
925
   inline Program *getProgram() const { return prog; }
 
926
   inline const char *getName() const { return name; }
 
927
   inline int getId() const { return id; }
 
928
 
 
929
   void print();
 
930
   void printLiveIntervals() const;
 
931
   void printCFGraph(const char *filePath);
 
932
 
 
933
   bool setEntry(BasicBlock *);
 
934
   bool setExit(BasicBlock *);
 
935
 
 
936
   unsigned int orderInstructions(ArrayList&);
 
937
 
 
938
   inline void add(BasicBlock *bb, int& id) { allBBlocks.insert(bb, id); }
 
939
   inline void add(Instruction *insn, int& id) { allInsns.insert(insn, id); }
 
940
   inline void add(LValue *lval, int& id) { allLValues.insert(lval, id); }
 
941
 
 
942
   inline LValue *getLValue(int id);
 
943
 
 
944
   bool convertToSSA();
 
945
 
 
946
public:
 
947
   Graph cfg;
 
948
   Graph::Node *cfgExit;
 
949
   Graph *domTree;
 
950
   Graph::Node call; // node in the call graph
 
951
 
 
952
   BasicBlock **bbArray; // BBs in emission order
 
953
   int bbCount;
 
954
 
 
955
   unsigned int loopNestingBound;
 
956
   int regClobberMax;
 
957
 
 
958
   uint32_t binPos;
 
959
   uint32_t binSize;
 
960
 
 
961
   ArrayList allBBlocks;
 
962
   ArrayList allInsns;
 
963
   ArrayList allLValues;
 
964
 
 
965
private:
 
966
   void buildLiveSetsPreSSA(BasicBlock *, const int sequence);
 
967
 
 
968
private:
 
969
   int id;
 
970
   const char *const name;
 
971
   Program *prog;
 
972
};
 
973
 
 
974
enum CGStage
 
975
{
 
976
   CG_STAGE_PRE_SSA,
 
977
   CG_STAGE_SSA, // expected directly before register allocation
 
978
   CG_STAGE_POST_RA
 
979
};
 
980
 
 
981
class Program
 
982
{
 
983
public:
 
984
   enum Type
 
985
   {
 
986
      TYPE_VERTEX,
 
987
      TYPE_TESSELLATION_CONTROL,
 
988
      TYPE_TESSELLATION_EVAL,
 
989
      TYPE_GEOMETRY,
 
990
      TYPE_FRAGMENT,
 
991
      TYPE_COMPUTE
 
992
   };
 
993
 
 
994
   Program(Type type, Target *targ);
 
995
   ~Program();
 
996
 
 
997
   void print();
 
998
 
 
999
   Type getType() const { return progType; }
 
1000
 
 
1001
   inline void add(Function *fn, int& id) { allFuncs.insert(fn, id); }
 
1002
   inline void add(Value *rval, int& id) { allRValues.insert(rval, id); }
 
1003
 
 
1004
   bool makeFromTGSI(struct nv50_ir_prog_info *);
 
1005
   bool makeFromSM4(struct nv50_ir_prog_info *);
 
1006
   bool convertToSSA();
 
1007
   bool optimizeSSA(int level);
 
1008
   bool optimizePostRA(int level);
 
1009
   bool registerAllocation();
 
1010
   bool emitBinary(struct nv50_ir_prog_info *);
 
1011
 
 
1012
   const Target *getTarget() const { return target; }
 
1013
 
 
1014
private:
 
1015
   Type progType;
 
1016
   Target *target;
 
1017
 
 
1018
public:
 
1019
   Function *main;
 
1020
   Graph calls;
 
1021
 
 
1022
   ArrayList allFuncs;
 
1023
   ArrayList allRValues;
 
1024
 
 
1025
   uint32_t *code;
 
1026
   uint32_t binSize;
 
1027
 
 
1028
   int maxGPR;
 
1029
 
 
1030
   MemoryPool mem_Instruction;
 
1031
   MemoryPool mem_CmpInstruction;
 
1032
   MemoryPool mem_TexInstruction;
 
1033
   MemoryPool mem_FlowInstruction;
 
1034
   MemoryPool mem_LValue;
 
1035
   MemoryPool mem_Symbol;
 
1036
   MemoryPool mem_ImmediateValue;
 
1037
 
 
1038
   uint32_t dbgFlags;
 
1039
 
 
1040
   void releaseInstruction(Instruction *);
 
1041
   void releaseValue(Value *);
 
1042
};
 
1043
 
 
1044
// TODO: add const version
 
1045
class Pass
 
1046
{
 
1047
public:
 
1048
   bool run(Program *, bool ordered = false, bool skipPhi = false);
 
1049
   bool run(Function *, bool ordered = false, bool skipPhi = false);
 
1050
 
 
1051
private:
 
1052
   // return false to continue with next entity on next higher level
 
1053
   virtual bool visit(Function *) { return true; }
 
1054
   virtual bool visit(BasicBlock *) { return true; }
 
1055
   virtual bool visit(Instruction *) { return false; }
 
1056
 
 
1057
   bool doRun(Program *, bool ordered, bool skipPhi);
 
1058
   bool doRun(Function *, bool ordered, bool skipPhi);
 
1059
 
 
1060
protected:
 
1061
   bool err;
 
1062
   Function *func;
 
1063
   Program *prog;
 
1064
};
 
1065
 
 
1066
// =============================================================================
 
1067
 
 
1068
#include "nv50_ir_inlines.h"
 
1069
 
 
1070
} // namespace nv50_ir
 
1071
 
 
1072
#endif // __NV50_IR_H__