Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / nvc0 / nvc0_pc_emit.c
1 /*
2  * Copyright 2010 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 #include "nvc0_pc.h"
24 #include "nvc0_program.h"
25
26 #define NVC0_FIXUP_CODE_RELOC 0
27 #define NVC0_FIXUP_DATA_RELOC 1
28
29 struct nvc0_fixup {
30    uint8_t type;
31    int8_t shift;
32    uint32_t mask;
33    uint32_t data;
34    uint32_t ofst;
35 };
36
37 void
38 nvc0_relocate_program(struct nvc0_program *prog,
39                       uint32_t code_base,
40                       uint32_t data_base)
41 {
42    struct nvc0_fixup *f = (struct nvc0_fixup *)prog->relocs;
43    unsigned i;
44
45    for (i = 0; i < prog->num_relocs; ++i) {
46       uint32_t data;
47
48       switch (f[i].type) {
49       case NVC0_FIXUP_CODE_RELOC: data = code_base + f[i].data; break;
50       case NVC0_FIXUP_DATA_RELOC: data = data_base + f[i].data; break;
51       default:
52          data = f[i].data;
53          break;
54       }
55       data = (f[i].shift < 0) ? (data >> -f[i].shift) : (data << f[i].shift);
56
57       prog->code[f[i].ofst / 4] &= ~f[i].mask;
58       prog->code[f[i].ofst / 4] |= data & f[i].mask;
59    }
60 }
61
62 static void
63 create_fixup(struct nv_pc *pc, uint8_t ty,
64              int w, uint32_t data, uint32_t m, int s)
65 {
66    struct nvc0_fixup *f;
67
68    const unsigned size = sizeof(struct nvc0_fixup);
69    const unsigned n = pc->num_relocs;
70
71    if (!(n % 8))
72       pc->reloc_entries = REALLOC(pc->reloc_entries, n * size, (n + 8) * size);
73
74    f = (struct nvc0_fixup *)pc->reloc_entries;
75
76    f[n].ofst = pc->emit_pos + w * 4;
77    f[n].type = ty;
78    f[n].data = data;
79    f[n].mask = m;
80    f[n].shift = s;
81
82    ++pc->num_relocs;
83 }
84
85 static INLINE ubyte
86 SSIZE(struct nv_instruction *nvi, int s)
87 {
88    return nvi->src[s]->value->reg.size;
89 }
90
91 static INLINE ubyte
92 DSIZE(struct nv_instruction *nvi, int d)
93 {
94    return nvi->def[d]->reg.size;
95 }
96
97 static INLINE struct nv_reg *
98 SREG(struct nv_ref *ref)
99 {
100    if (!ref)
101       return NULL;
102    return &ref->value->join->reg;
103 }
104
105 static INLINE struct nv_reg *
106 DREG(struct nv_value *val)
107 {
108    if (!val)
109       return NULL;
110    return &val->join->reg;
111 }
112
113 static INLINE ubyte
114 SFILE(struct nv_instruction *nvi, int s)
115 {
116    return nvi->src[s]->value->reg.file;
117 }
118
119 static INLINE ubyte
120 DFILE(struct nv_instruction *nvi, int d)
121 {
122    return nvi->def[0]->reg.file;
123 }
124
125 static INLINE void
126 SID(struct nv_pc *pc, struct nv_ref *ref, int pos)
127 {
128    pc->emit[pos / 32] |= (SREG(ref) ? SREG(ref)->id : 63) << (pos % 32);
129 }
130
131 static INLINE void
132 DID(struct nv_pc *pc, struct nv_value *val, int pos)
133 {
134    pc->emit[pos / 32] |= (DREG(val) ? DREG(val)->id : 63) << (pos % 32);
135 }
136
137 static INLINE uint32_t
138 get_immd_u32(struct nv_ref *ref) /* XXX: dependent on [0]:2 */
139 {
140    assert(ref->value->reg.file == NV_FILE_IMM);
141    return ref->value->reg.imm.u32;
142 }
143
144 static INLINE void
145 set_immd_u32_l(struct nv_pc *pc, uint32_t u32)
146 {
147    pc->emit[0] |= (u32 & 0x3f) << 26;
148    pc->emit[1] |= u32 >> 6;
149 }
150
151 static INLINE void
152 set_immd_u32(struct nv_pc *pc, uint32_t u32)
153 {
154    if ((pc->emit[0] & 0xf) == 0x2) {
155       set_immd_u32_l(pc, u32);
156    } else
157    if ((pc->emit[0] & 0xf) == 0x3) {
158       assert(!(pc->emit[1] & 0xc000));
159       pc->emit[1] |= 0xc000;
160       assert(!(u32 & 0xfff00000));
161       set_immd_u32_l(pc, u32);
162    } else {
163       assert(!(pc->emit[1] & 0xc000));
164       pc->emit[1] |= 0xc000;
165       assert(!(u32 & 0xfff));
166       set_immd_u32_l(pc, u32 >> 12);
167    }
168 }
169
170 static INLINE void
171 set_immd(struct nv_pc *pc, struct nv_instruction *i, int s)
172 {
173    set_immd_u32(pc, get_immd_u32(i->src[s]));
174 }
175
176 static INLINE void
177 DVS(struct nv_pc *pc, struct nv_instruction *i)
178 {
179    uint s = i->def[0]->reg.size;
180    int n;
181    for (n = 1; n < 4 && i->def[n]; ++n)
182       s += i->def[n]->reg.size;
183    pc->emit[0] |= ((s / 4) - 1) << 5;
184 }
185
186 static INLINE void
187 SVS(struct nv_pc *pc, struct nv_ref *src)
188 {
189    pc->emit[0] |= (SREG(src)->size / 4 - 1) << 5;
190 }
191
192 static void
193 set_pred(struct nv_pc *pc, struct nv_instruction *i)
194 {
195    if (i->predicate >= 0) {
196       SID(pc, i->src[i->predicate], 6);
197       if (i->cc)
198          pc->emit[0] |= 0x2000; /* negate */
199    } else {
200       pc->emit[0] |= 0x1c00;
201    }       
202 }
203
204 static INLINE void
205 set_address_16(struct nv_pc *pc, struct nv_ref *src)
206 {
207    pc->emit[0] |= (src->value->reg.address & 0x003f) << 26;
208    pc->emit[1] |= (src->value->reg.address & 0xffc0) >> 6;
209 }
210
211 static INLINE unsigned
212 const_space_index(struct nv_instruction *i, int s)
213 {
214    return SFILE(i, s) - NV_FILE_MEM_C(0);
215 }
216
217 static void
218 emit_flow(struct nv_pc *pc, struct nv_instruction *i, uint8_t op)
219 {
220    pc->emit[0] = 0x00000007;
221    pc->emit[1] = op << 24;
222
223    if (op == 0x40 || (op >= 0x80 && op <= 0x98)) {
224       /* bra, exit, ret or kil */
225       pc->emit[0] |= 0x1e0;
226       set_pred(pc, i);
227    }
228
229    if (i->target) {
230       int32_t pcrel = i->target->emit_pos - (pc->emit_pos + 8);
231
232       /* we will need relocations only for global functions */
233       /*
234       create_fixup(pc, NVC0_FIXUP_CODE_RELOC, 0, pos, 26, 0xfc000000);
235       create_fixup(pc, NVC0_FIXUP_CODE_RELOC, 1, pos, -6, 0x0001ffff);
236       */
237
238       pc->emit[0] |= (pcrel & 0x3f) << 26;
239       pc->emit[1] |= (pcrel >> 6) & 0x3ffff;
240    }
241 }
242
243 /* doesn't work for vfetch, export, ld, st, mov ... */
244 static void
245 emit_form_0(struct nv_pc *pc, struct nv_instruction *i)
246 {
247    int s;
248
249    set_pred(pc, i);
250
251    DID(pc, i->def[0], 14);
252
253    for (s = 0; s < 3 && i->src[s]; ++s) {
254       if (SFILE(i, s) >= NV_FILE_MEM_C(0) &&
255           SFILE(i, s) <= NV_FILE_MEM_C(15)) {
256          assert(!(pc->emit[1] & 0xc000));
257          assert(s <= 1);
258          pc->emit[1] |= 0x4000 | (const_space_index(i, s) << 10);
259          set_address_16(pc, i->src[s]);
260       } else
261       if (SFILE(i, s) == NV_FILE_GPR) {
262          SID(pc, i->src[s], s ? ((s == 2) ? 49 : 26) : 20);
263       } else
264       if (SFILE(i, s) == NV_FILE_IMM) {
265          assert(!(pc->emit[1] & 0xc000));
266          assert(s == 1 || i->opcode == NV_OP_MOV);
267          set_immd(pc, i, s);
268       }
269    }
270 }
271
272 static void
273 emit_form_1(struct nv_pc *pc, struct nv_instruction *i)
274 {
275    int s;
276
277    set_pred(pc, i);
278
279    DID(pc, i->def[0], 14);
280
281    for (s = 0; s < 1 && i->src[s]; ++s) {
282       if (SFILE(i, s) >= NV_FILE_MEM_C(0) &&
283           SFILE(i, s) <= NV_FILE_MEM_C(15)) {
284          assert(!(pc->emit[1] & 0xc000));
285          assert(s <= 1);
286          pc->emit[1] |= 0x4000 | (const_space_index(i, s) << 10);
287          set_address_16(pc, i->src[s]);
288       } else
289       if (SFILE(i, s) == NV_FILE_GPR) {
290          SID(pc, i->src[s], 26);
291       } else
292       if (SFILE(i, s) == NV_FILE_IMM) {
293          assert(!(pc->emit[1] & 0xc000));
294          assert(s == 1 || i->opcode == NV_OP_MOV);
295          set_immd(pc, i, s);
296       }
297    }
298 }
299
300 static void
301 emit_neg_abs_1_2(struct nv_pc *pc, struct nv_instruction *i)
302 {
303    if (i->src[0]->mod & NV_MOD_ABS)
304       pc->emit[0] |= 1 << 7;
305    if (i->src[0]->mod & NV_MOD_NEG)
306       pc->emit[0] |= 1 << 9;
307    if (i->src[1]->mod & NV_MOD_ABS)
308       pc->emit[0] |= 1 << 6;
309    if (i->src[1]->mod & NV_MOD_NEG)
310       pc->emit[0] |= 1 << 8;
311 }
312
313 static void
314 emit_add_f32(struct nv_pc *pc, struct nv_instruction *i)
315 {
316    pc->emit[0] = 0x00000000;
317    pc->emit[1] = 0x50000000;
318
319    emit_form_0(pc, i);
320
321    emit_neg_abs_1_2(pc, i);
322
323    if (i->saturate)
324       pc->emit[1] |= 1 << 17;
325 }
326
327 static void
328 emit_mul_f32(struct nv_pc *pc, struct nv_instruction *i)
329 {
330    pc->emit[0] = 0x00000000;
331    pc->emit[1] = 0x58000000;
332
333    emit_form_0(pc, i);
334
335    if ((i->src[0]->mod ^ i->src[1]->mod) & NV_MOD_NEG)
336       pc->emit[1] |= 1 << 25;
337
338    if (i->saturate)
339       pc->emit[0] |= 1 << 5;
340 }
341
342 static void
343 emit_mad_f32(struct nv_pc *pc, struct nv_instruction *i)
344 {
345    pc->emit[0] = 0x00000000;
346    pc->emit[1] = 0x30000000;
347
348    emit_form_0(pc, i);
349
350    if ((i->src[0]->mod ^ i->src[1]->mod) & NV_MOD_NEG)
351       pc->emit[0] |= 1 << 9;
352
353    if (i->src[2]->mod & NV_MOD_NEG)
354       pc->emit[0] |= 1 << 8;
355
356    if (i->saturate)
357       pc->emit[0] |= 1 << 5;
358 }
359
360 static void
361 emit_minmax(struct nv_pc *pc, struct nv_instruction *i)
362 {
363    pc->emit[0] = 0x00000000;
364    pc->emit[1] = 0x08000000;
365
366    if (NV_BASEOP(i->opcode) == NV_OP_MAX)
367       pc->emit[1] |= 0x001e0000;
368    else
369       pc->emit[1] |= 0x000e0000; /* predicate ? */
370
371    emit_form_0(pc, i);
372
373    emit_neg_abs_1_2(pc, i);
374
375    switch (i->opcode) {
376    case NV_OP_MIN_U32:
377    case NV_OP_MAX_U32:
378       pc->emit[0] |= 3;
379       break;
380    case NV_OP_MIN_S32:
381    case NV_OP_MAX_S32:
382       pc->emit[0] |= 3 | (1 << 5);
383       break;
384    case NV_OP_MIN_F32:
385    case NV_OP_MAX_F32:
386    default:
387       break;
388    }
389 }
390
391 static void
392 emit_tex(struct nv_pc *pc, struct nv_instruction *i)
393 {
394    int src1 = i->tex_array + i->tex_dim + i->tex_cube;
395
396    assert(src1 < 6);
397
398    pc->emit[0] = 0x00000086;
399    pc->emit[1] = 0x80000000;
400
401    switch (i->opcode) {
402    case NV_OP_TEX: pc->emit[1] = 0x80000000; break;
403    case NV_OP_TXB: pc->emit[1] = 0x84000000; break;
404    case NV_OP_TXL: pc->emit[1] = 0x86000000; break;
405    case NV_OP_TXF: pc->emit[1] = 0x90000000; break;
406    case NV_OP_TXG: pc->emit[1] = 0xe0000000; break;
407    default:
408       assert(0);
409       break;
410    }
411
412    if (i->tex_array)
413       pc->emit[1] |= 0x00080000; /* layer index is u16, first value of SRC0 */
414    if (i->tex_shadow)
415       pc->emit[1] |= 0x01000000; /* shadow is part of SRC1, after bias/lod */
416
417    set_pred(pc, i);
418
419    DID(pc, i->def[0], 14);
420    SID(pc, i->src[0], 20);
421    SID(pc, i->src[src1], 26); /* may be NULL -> $r63 */
422
423    pc->emit[1] |= i->tex_mask << 14;
424    pc->emit[1] |= (i->tex_dim - 1) << 20;
425    if (i->tex_cube)
426       pc->emit[1] |= 3 << 20;
427
428    assert(i->ext.tex.s < 16);
429
430    pc->emit[1] |= i->ext.tex.t;
431    pc->emit[1] |= i->ext.tex.s << 8;
432
433    if (i->tex_live)
434       pc->emit[0] |= 1 << 9;
435 }
436
437 /* 0: cos, 1: sin, 2: ex2, 3: lg2, 4: rcp, 5: rsqrt */
438 static void
439 emit_flop(struct nv_pc *pc, struct nv_instruction *i, ubyte op)
440 {
441    pc->emit[0] = 0x00000000;
442    pc->emit[1] = 0xc8000000;
443
444    set_pred(pc, i);
445
446    DID(pc, i->def[0], 14);
447    SID(pc, i->src[0], 20);
448
449    pc->emit[0] |= op << 26;
450
451    if (op >= 3) {
452       if (i->src[0]->mod & NV_MOD_NEG) pc->emit[0] |= 1 << 9;
453       if (i->src[0]->mod & NV_MOD_ABS) pc->emit[0] |= 1 << 7;
454    } else {
455       assert(!i->src[0]->mod);
456    }
457 }
458
459 static void
460 emit_quadop(struct nv_pc *pc, struct nv_instruction *i)
461 {
462    pc->emit[0] = 0x00000000;
463    pc->emit[1] = 0x48000000;
464
465    set_pred(pc, i);
466
467    assert(SFILE(i, 0) == NV_FILE_GPR && SFILE(i, 1) == NV_FILE_GPR);
468
469    DID(pc, i->def[0], 14);
470    SID(pc, i->src[0], 20);
471    SID(pc, i->src[0], 26);
472
473    pc->emit[0] |= i->lanes << 6; /* l0, l1, l2, l3, dx, dy */
474    pc->emit[1] |= i->quadop;
475 }
476
477 static void
478 emit_ddx(struct nv_pc *pc, struct nv_instruction *i)
479 {
480    i->quadop = 0x99;
481    i->lanes = 4;
482    i->src[1] = i->src[0];
483    emit_quadop(pc, i);
484 }
485
486 static void
487 emit_ddy(struct nv_pc *pc, struct nv_instruction *i)
488 {
489    i->quadop = 0xa5;
490    i->lanes = 5;
491    i->src[1] = i->src[0];
492    emit_quadop(pc, i);
493 }
494
495 /* preparation op (preex2, presin / convert to fixed point) */
496 static void
497 emit_preop(struct nv_pc *pc, struct nv_instruction *i)
498 {
499    pc->emit[0] = 0x00000000;
500    pc->emit[1] = 0x60000000;
501
502    if (i->opcode == NV_OP_PREEX2)
503       pc->emit[0] |= 0x20;
504
505    emit_form_1(pc, i);
506
507    if (i->src[0]->mod & NV_MOD_NEG) pc->emit[0] |= 1 << 8;
508    if (i->src[0]->mod & NV_MOD_ABS) pc->emit[0] |= 1 << 6;
509 }
510
511 static void
512 emit_shift(struct nv_pc *pc, struct nv_instruction *i)
513 {
514    pc->emit[0] = 0x00000003;
515
516    switch (i->opcode) {
517    case NV_OP_SAR:
518       pc->emit[0] |= 0x20; /* fall through */
519    case NV_OP_SHR:
520       pc->emit[1] = 0x58000000;
521       break;
522    case NV_OP_SHL:
523    default:
524       pc->emit[1] = 0x60000000;
525       break;
526    }
527
528    emit_form_0(pc, i);
529 }
530
531 static void
532 emit_bitop(struct nv_pc *pc, struct nv_instruction *i)
533 {
534    if (SFILE(i, 1) == NV_FILE_IMM) {
535       pc->emit[0] = 0x00000002;
536       pc->emit[1] = 0x38000000;
537    } else {
538       pc->emit[0] = 0x00000003;
539       pc->emit[1] = 0x68000000;
540    }
541    
542    switch (i->opcode) {
543    case NV_OP_OR:
544       pc->emit[0] |= 0x40;
545       break;
546    case NV_OP_XOR:
547       pc->emit[0] |= 0x80;
548       break;
549    case NV_OP_AND:
550    default:
551       break;
552    }
553
554    emit_form_0(pc, i);
555 }
556
557 static void
558 emit_set(struct nv_pc *pc, struct nv_instruction *i)
559 {
560    pc->emit[0] = 0x00000000;
561
562    switch (i->opcode) {
563    case NV_OP_SET_S32:
564       pc->emit[0] |= 0x20; /* fall through */
565    case NV_OP_SET_U32:
566       pc->emit[0] |= 0x3;
567       pc->emit[1] = 0x100e0000;
568       break;
569    case NV_OP_SET_F32_AND:
570       pc->emit[1] = 0x18000000;
571       break;
572    case NV_OP_SET_F32_OR:
573       pc->emit[1] = 0x18200000;
574       break;
575    case NV_OP_SET_F32_XOR:
576       pc->emit[1] = 0x18400000;
577       break;
578    case NV_OP_FSET_F32:
579       pc->emit[0] |= 0x20; /* fall through */
580    case NV_OP_SET_F32:
581    default:
582       pc->emit[1] = 0x180e0000;
583       break;
584    }
585
586    if (DFILE(i, 0) == NV_FILE_PRED) {
587       pc->emit[0] |= 0x1c000;
588       pc->emit[1] += 0x08000000;
589    }
590
591    pc->emit[1] |= i->set_cond << 23;
592
593    emit_form_0(pc, i);
594
595    emit_neg_abs_1_2(pc, i); /* maybe assert that U/S32 don't use mods */
596 }
597
598 static void
599 emit_selp(struct nv_pc *pc, struct nv_instruction *i)
600 {
601    pc->emit[0] = 0x00000004;
602    pc->emit[1] = 0x20000000;
603
604    emit_form_0(pc, i);
605
606    if (i->cc || (i->src[2]->mod & NV_MOD_NOT))
607       pc->emit[1] |= 1 << 20;
608 }
609
610 static void
611 emit_slct(struct nv_pc *pc, struct nv_instruction *i)
612 {
613    uint8_t cc = i->set_cond;
614
615    pc->emit[0] = 0x00000000;
616
617    switch (i->opcode) {
618    case NV_OP_SLCT_S32:
619       pc->emit[0] |= 0x20; /* fall through */
620    case NV_OP_SLCT_U32:
621       pc->emit[0] |= 0x3;
622       pc->emit[1] = 0x30000000;
623       break;
624    case NV_OP_SLCT_F32:
625    default:
626       pc->emit[1] = 0x38000000;
627       break;
628    }
629
630    emit_form_0(pc, i);
631
632    if (i->src[2]->mod & NV_MOD_NEG)
633       cc = nvc0_ir_reverse_cc(cc);
634
635    pc->emit[1] |= cc << 23;
636 }
637
638 static void
639 emit_cvt(struct nv_pc *pc, struct nv_instruction *i)
640 {
641    uint32_t rint;
642
643    pc->emit[0] = 0x00000004;
644    pc->emit[1] = 0x10000000;
645
646    /* if no type conversion specified, get type from opcode */
647    if (i->opcode != NV_OP_CVT && i->ext.cvt.d == i->ext.cvt.s)
648       i->ext.cvt.d = i->ext.cvt.s = NV_OPTYPE(i->opcode);
649
650    switch (i->ext.cvt.d) {
651    case NV_TYPE_F32:
652       switch (i->ext.cvt.s) {
653       case NV_TYPE_F32: pc->emit[1] = 0x10000000; break;
654       case NV_TYPE_S32: pc->emit[0] |= 0x200; /* fall through */
655       case NV_TYPE_U32: pc->emit[1] = 0x18000000; break;
656       }
657       break;
658    case NV_TYPE_S32: pc->emit[0] |= 0x80; /* fall through */
659    case NV_TYPE_U32:
660       switch (i->ext.cvt.s) {
661       case NV_TYPE_F32: pc->emit[1] = 0x14000000; break;
662       case NV_TYPE_S32: pc->emit[0] |= 0x200; /* fall through */
663       case NV_TYPE_U32: pc->emit[1] = 0x1c000000; break;
664       }
665       break;
666    default:
667       assert(!"cvt: unknown type");
668       break;
669    }
670
671    rint = (i->ext.cvt.d == NV_TYPE_F32) ? 1 << 7 : 0;
672
673    if (i->opcode == NV_OP_FLOOR) {
674       pc->emit[0] |= rint;
675       pc->emit[1] |= 2 << 16;
676    } else
677    if (i->opcode == NV_OP_CEIL) {
678       pc->emit[0] |= rint;
679       pc->emit[1] |= 4 << 16;
680    } else
681    if (i->opcode == NV_OP_TRUNC) {
682       pc->emit[0] |= rint;
683       pc->emit[1] |= 6 << 16;
684    }
685
686    if (i->saturate || i->opcode == NV_OP_SAT)
687       pc->emit[0] |= 0x20;
688
689    if (NV_BASEOP(i->opcode) == NV_OP_ABS || i->src[0]->mod & NV_MOD_ABS)
690       pc->emit[0] |= 1 << 6;
691    if (NV_BASEOP(i->opcode) == NV_OP_NEG || i->src[0]->mod & NV_MOD_NEG)
692       pc->emit[0] |= 1 << 8;
693
694    pc->emit[0] |= util_logbase2(DREG(i->def[0])->size) << 20;
695    pc->emit[0] |= util_logbase2(SREG(i->src[0])->size) << 23;
696
697    emit_form_1(pc, i);
698 }
699
700 static void
701 emit_interp(struct nv_pc *pc, struct nv_instruction *i)
702 {
703    pc->emit[0] = 0x00000000;
704    pc->emit[1] = 0xc07e0000;
705
706    DID(pc, i->def[0], 14);
707
708    set_pred(pc, i);
709
710    if (i->indirect)
711       SID(pc, i->src[i->indirect], 20);
712    else
713       SID(pc, NULL, 20);
714
715    if (i->opcode == NV_OP_PINTERP) {
716       pc->emit[0] |= 0x040;
717       SID(pc, i->src[1], 26);
718
719       if (i->src[0]->value->reg.address >= 0x280 &&
720           i->src[0]->value->reg.address <= 0x29c)
721          pc->emit[0] |= 0x080; /* XXX: ? */
722    } else {
723       SID(pc, NULL, 26);
724    }
725
726    pc->emit[1] |= i->src[0]->value->reg.address & 0xffff;
727
728    if (i->centroid)
729       pc->emit[0] |= 0x100;
730    else
731    if (i->flat)
732       pc->emit[0] |= 0x080;
733 }
734
735 static void
736 emit_vfetch(struct nv_pc *pc, struct nv_instruction *i)
737 {
738    pc->emit[0] = 0x03f00006;
739    pc->emit[1] = 0x06000000 | i->src[0]->value->reg.address;
740    if (i->patch)
741       pc->emit[0] |= 0x100;
742
743    set_pred(pc, i);
744
745    DVS(pc, i);
746    DID(pc, i->def[0], 14);
747
748    SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 26);
749 }
750
751 static void
752 emit_export(struct nv_pc *pc, struct nv_instruction *i)
753 {
754    pc->emit[0] = 0x00000006;
755    pc->emit[1] = 0x0a000000;
756    if (i->patch)
757       pc->emit[0] |= 0x100;
758
759    set_pred(pc, i);
760
761    assert(SFILE(i, 0) == NV_FILE_MEM_V);
762    assert(SFILE(i, 1) == NV_FILE_GPR);
763
764    SID(pc, i->src[1], 26); /* register source */
765    SVS(pc, i->src[0]);
766
767    pc->emit[1] |= i->src[0]->value->reg.address & 0xfff;
768
769    SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 20);
770 }
771
772 static void
773 emit_mov(struct nv_pc *pc, struct nv_instruction *i)
774 {
775    if (i->opcode == NV_OP_MOV)
776       i->lanes = 0xf;
777
778    if (SFILE(i, 0) == NV_FILE_IMM) {
779       pc->emit[0] = 0x000001e2;
780       pc->emit[1] = 0x18000000;
781    } else
782    if (SFILE(i, 0) == NV_FILE_PRED) {
783       pc->emit[0] = 0x1c000004;
784       pc->emit[1] = 0x080e0000;
785    } else {
786       pc->emit[0] = 0x00000004 | (i->lanes << 5);
787       pc->emit[1] = 0x28000000;
788    }
789
790    emit_form_1(pc, i);
791 }
792
793 static void
794 emit_ldst_size(struct nv_pc *pc, struct nv_instruction *i)
795 {
796    assert(NV_IS_MEMORY_FILE(SFILE(i, 0)));
797
798    switch (SSIZE(i, 0)) {
799    case 1:
800       if (NV_TYPE_ISSGD(i->ext.cvt.s))
801          pc->emit[0] |= 0x20;
802       break;
803    case 2:
804       pc->emit[0] |= 0x40;
805       if (NV_TYPE_ISSGD(i->ext.cvt.s))
806          pc->emit[0] |= 0x20;
807       break;
808    case 4: pc->emit[0] |= 0x80; break;
809    case 8: pc->emit[0] |= 0xa0; break;
810    case 16: pc->emit[0] |= 0xc0; break;
811    default:
812       NOUVEAU_ERR("invalid load/store size %u\n", SSIZE(i, 0));
813       break;
814    }
815 }
816
817 static void
818 emit_ld_common(struct nv_pc *pc, struct nv_instruction *i)
819 {
820    emit_ldst_size(pc, i);
821
822    set_pred(pc, i);
823    set_address_16(pc, i->src[0]);
824
825    SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 20);
826    DID(pc, i->def[0], 14);
827 }
828
829 static void
830 emit_ld_const(struct nv_pc *pc, struct nv_instruction *i)
831 {
832    pc->emit[0] = 0x00000006;
833    pc->emit[1] = 0x14000000 | (const_space_index(i, 0) << 10);
834
835    emit_ld_common(pc, i);
836 }
837
838 static void
839 emit_ld(struct nv_pc *pc, struct nv_instruction *i)
840 {
841    if (SFILE(i, 0) >= NV_FILE_MEM_C(0) &&
842        SFILE(i, 0) <= NV_FILE_MEM_C(15)) {
843       if (SSIZE(i, 0) == 4 && i->indirect < 0) {
844          i->lanes = 0xf;
845          emit_mov(pc, i);
846       } else {
847          emit_ld_const(pc, i);
848       }
849    } else
850    if (SFILE(i, 0) == NV_FILE_MEM_L) {
851       pc->emit[0] = 0x00000005;
852       pc->emit[1] = 0xc0000000;
853
854       emit_ld_common(pc, i);
855    } else {
856       NOUVEAU_ERR("emit_ld(%u): not handled yet\n", SFILE(i, 0));
857       abort();
858    }
859 }
860
861 static void
862 emit_st(struct nv_pc *pc, struct nv_instruction *i)
863 {
864    if (SFILE(i, 0) != NV_FILE_MEM_L)
865       NOUVEAU_ERR("emit_st(%u): file not handled yet\n", SFILE(i, 0));
866
867    pc->emit[0] = 0x00000005 | (0 << 8); /* write-back caching */
868    pc->emit[1] = 0xc8000000;
869
870    emit_ldst_size(pc, i);
871
872    set_pred(pc, i);
873    set_address_16(pc, i->src[0]);
874
875    SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 20);
876    DID(pc, i->src[1]->value, 14);
877 }
878
879 void
880 nvc0_emit_instruction(struct nv_pc *pc, struct nv_instruction *i)
881 {
882 #if NV50_DEBUG & NV50_DEBUG_SHADER
883    debug_printf("EMIT: "); nvc0_print_instruction(i);
884 #endif
885
886    switch (i->opcode) {
887    case NV_OP_VFETCH:
888       emit_vfetch(pc, i);
889       break;
890    case NV_OP_EXPORT:
891       if (!pc->is_fragprog)
892          emit_export(pc, i);
893       break;
894    case NV_OP_MOV:
895       emit_mov(pc, i);
896       break;
897    case NV_OP_LD:
898       emit_ld(pc, i);
899       break;
900    case NV_OP_ST:
901       emit_st(pc, i);
902       break;
903    case NV_OP_LINTERP:
904    case NV_OP_PINTERP:
905       emit_interp(pc, i);
906       break;
907    case NV_OP_ADD_F32:
908       emit_add_f32(pc, i);
909       break;
910    case NV_OP_AND:
911    case NV_OP_OR:
912    case NV_OP_XOR:
913       emit_bitop(pc, i);
914       break;
915    case NV_OP_CVT:
916    case NV_OP_ABS_F32:
917    case NV_OP_ABS_S32:
918    case NV_OP_NEG_F32:
919    case NV_OP_NEG_S32:
920    case NV_OP_SAT:
921    case NV_OP_CEIL:
922    case NV_OP_FLOOR:
923    case NV_OP_TRUNC:
924       emit_cvt(pc, i);
925       break;
926    case NV_OP_DFDX:
927       emit_ddx(pc, i);
928       break;
929    case NV_OP_DFDY:
930       emit_ddy(pc, i);
931       break;
932    case NV_OP_COS:
933       emit_flop(pc, i, 0);
934       break;
935    case NV_OP_SIN:
936       emit_flop(pc, i, 1);
937       break;
938    case NV_OP_EX2:
939       emit_flop(pc, i, 2);
940       break;
941    case NV_OP_LG2:
942       emit_flop(pc, i, 3);
943       break;
944    case NV_OP_RCP:
945       emit_flop(pc, i, 4);
946       break;
947    case NV_OP_RSQ:
948       emit_flop(pc, i, 5);
949       break;
950    case NV_OP_PRESIN:
951    case NV_OP_PREEX2:
952       emit_preop(pc, i);
953       break;
954    case NV_OP_MAD_F32:
955       emit_mad_f32(pc, i);
956       break;
957    case NV_OP_MAX_F32:
958    case NV_OP_MAX_S32:
959    case NV_OP_MAX_U32:
960    case NV_OP_MIN_F32:
961    case NV_OP_MIN_S32:
962    case NV_OP_MIN_U32:
963       emit_minmax(pc, i);
964       break;
965    case NV_OP_MUL_F32:
966       emit_mul_f32(pc, i);
967       break;
968    case NV_OP_SET_F32:
969    case NV_OP_SET_F32_AND:
970    case NV_OP_SET_F32_OR:
971    case NV_OP_SET_F32_XOR:
972    case NV_OP_SET_S32:
973    case NV_OP_SET_U32:
974    case NV_OP_FSET_F32:
975       emit_set(pc, i);
976       break;
977    case NV_OP_SHL:
978    case NV_OP_SHR:
979    case NV_OP_SAR:
980       emit_shift(pc, i);
981       break;
982    case NV_OP_TEX:
983    case NV_OP_TXB:
984    case NV_OP_TXL:
985       emit_tex(pc, i);
986       break;
987    case NV_OP_BRA:
988       emit_flow(pc, i, 0x40);
989       break;
990    case NV_OP_CALL:
991       emit_flow(pc, i, 0x50);
992       break;
993    case NV_OP_JOINAT:
994       emit_flow(pc, i, 0x60);
995       break;
996    case NV_OP_EXIT:
997       emit_flow(pc, i, 0x80);
998       break;
999    case NV_OP_RET:
1000       emit_flow(pc, i, 0x90);
1001       break;
1002    case NV_OP_KIL:
1003       emit_flow(pc, i, 0x98);
1004       break;
1005    case NV_OP_JOIN:
1006    case NV_OP_NOP:
1007       pc->emit[0] = 0x00003de4;
1008       pc->emit[1] = 0x40000000;
1009       break;
1010    case NV_OP_SELP:
1011       emit_selp(pc, i);
1012       break;
1013    case NV_OP_SLCT_F32:
1014    case NV_OP_SLCT_S32:
1015    case NV_OP_SLCT_U32:
1016       emit_slct(pc, i);
1017       break;
1018    default:
1019       NOUVEAU_ERR("unhandled NV_OP: %d\n", i->opcode);
1020       abort();
1021       break;
1022    }
1023
1024    if (i->join)
1025       pc->emit[0] |= 0x10;
1026 }