nvc0: force vertex data through FIFO if we need to convert it
[mesa.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 emit_quadop(pc, i);
483 }
484
485 static void
486 emit_ddy(struct nv_pc *pc, struct nv_instruction *i)
487 {
488 i->quadop = 0xa5;
489 i->lanes = 5;
490 emit_quadop(pc, i);
491 }
492
493 /* preparation op (preex2, presin / convert to fixed point) */
494 static void
495 emit_preop(struct nv_pc *pc, struct nv_instruction *i)
496 {
497 pc->emit[0] = 0x00000000;
498 pc->emit[1] = 0x60000000;
499
500 if (i->opcode == NV_OP_PREEX2)
501 pc->emit[0] |= 0x20;
502
503 emit_form_1(pc, i);
504
505 if (i->src[0]->mod & NV_MOD_NEG) pc->emit[0] |= 1 << 8;
506 if (i->src[0]->mod & NV_MOD_ABS) pc->emit[0] |= 1 << 6;
507 }
508
509 static void
510 emit_shift(struct nv_pc *pc, struct nv_instruction *i)
511 {
512 pc->emit[0] = 0x00000003;
513
514 switch (i->opcode) {
515 case NV_OP_SAR:
516 pc->emit[0] |= 0x20; /* fall through */
517 case NV_OP_SHR:
518 pc->emit[1] = 0x58000000;
519 break;
520 case NV_OP_SHL:
521 default:
522 pc->emit[1] = 0x60000000;
523 break;
524 }
525
526 emit_form_0(pc, i);
527 }
528
529 static void
530 emit_bitop(struct nv_pc *pc, struct nv_instruction *i)
531 {
532 if (SFILE(i, 1) == NV_FILE_IMM) {
533 pc->emit[0] = 0x00000002;
534 pc->emit[1] = 0x38000000;
535 } else {
536 pc->emit[0] = 0x00000003;
537 pc->emit[1] = 0x68000000;
538 }
539
540 switch (i->opcode) {
541 case NV_OP_OR:
542 pc->emit[0] |= 0x40;
543 break;
544 case NV_OP_XOR:
545 pc->emit[0] |= 0x80;
546 break;
547 case NV_OP_AND:
548 default:
549 break;
550 }
551
552 emit_form_0(pc, i);
553 }
554
555 static void
556 emit_set(struct nv_pc *pc, struct nv_instruction *i)
557 {
558 pc->emit[0] = 0x00000000;
559
560 switch (i->opcode) {
561 case NV_OP_SET_S32:
562 pc->emit[0] |= 0x20; /* fall through */
563 case NV_OP_SET_U32:
564 pc->emit[0] |= 0x3;
565 pc->emit[1] = 0x100e0000;
566 break;
567 case NV_OP_SET_F32_AND:
568 pc->emit[1] = 0x18000000;
569 break;
570 case NV_OP_SET_F32_OR:
571 pc->emit[1] = 0x18200000;
572 break;
573 case NV_OP_SET_F32_XOR:
574 pc->emit[1] = 0x18400000;
575 break;
576 case NV_OP_FSET_F32:
577 pc->emit[0] |= 0x20; /* fall through */
578 case NV_OP_SET_F32:
579 default:
580 pc->emit[1] = 0x180e0000;
581 break;
582 }
583
584 if (DFILE(i, 0) == NV_FILE_PRED) {
585 pc->emit[0] |= 0x1c000;
586 pc->emit[1] += 0x08000000;
587 }
588
589 pc->emit[1] |= i->set_cond << 23;
590
591 emit_form_0(pc, i);
592
593 emit_neg_abs_1_2(pc, i); /* maybe assert that U/S32 don't use mods */
594 }
595
596 static void
597 emit_selp(struct nv_pc *pc, struct nv_instruction *i)
598 {
599 pc->emit[0] = 0x00000004;
600 pc->emit[1] = 0x20000000;
601
602 emit_form_0(pc, i);
603
604 if (i->cc || (i->src[2]->mod & NV_MOD_NOT))
605 pc->emit[1] |= 1 << 20;
606 }
607
608 static void
609 emit_slct(struct nv_pc *pc, struct nv_instruction *i)
610 {
611 pc->emit[0] = 0x00000000;
612
613 switch (i->opcode) {
614 case NV_OP_SLCT_S32:
615 pc->emit[0] |= 0x20; /* fall through */
616 case NV_OP_SLCT_U32:
617 pc->emit[0] |= 0x3;
618 pc->emit[1] = 0x30000000;
619 break;
620 case NV_OP_SLCT_F32:
621 default:
622 pc->emit[1] = 0x38000000;
623 break;
624 }
625
626 emit_form_0(pc, i);
627
628 pc->emit[1] |= i->set_cond << 23;
629 }
630
631 static void
632 emit_cvt(struct nv_pc *pc, struct nv_instruction *i)
633 {
634 uint32_t rint;
635
636 pc->emit[0] = 0x00000004;
637 pc->emit[1] = 0x10000000;
638
639 /* if no type conversion specified, get type from opcode */
640 if (i->opcode != NV_OP_CVT && i->ext.cvt.d == i->ext.cvt.s)
641 i->ext.cvt.d = i->ext.cvt.s = NV_OPTYPE(i->opcode);
642
643 switch (i->ext.cvt.d) {
644 case NV_TYPE_F32:
645 switch (i->ext.cvt.s) {
646 case NV_TYPE_F32: pc->emit[1] = 0x10000000; break;
647 case NV_TYPE_S32: pc->emit[0] |= 0x200; /* fall through */
648 case NV_TYPE_U32: pc->emit[1] = 0x18000000; break;
649 }
650 break;
651 case NV_TYPE_S32: pc->emit[0] |= 0x80; /* fall through */
652 case NV_TYPE_U32:
653 switch (i->ext.cvt.s) {
654 case NV_TYPE_F32: pc->emit[1] = 0x14000000; break;
655 case NV_TYPE_S32: pc->emit[0] |= 0x200; /* fall through */
656 case NV_TYPE_U32: pc->emit[1] = 0x1c000000; break;
657 }
658 break;
659 default:
660 assert(!"cvt: unknown type");
661 break;
662 }
663
664 rint = (i->ext.cvt.d == NV_TYPE_F32) ? 1 << 7 : 0;
665
666 if (i->opcode == NV_OP_FLOOR) {
667 pc->emit[0] |= rint;
668 pc->emit[1] |= 2 << 16;
669 } else
670 if (i->opcode == NV_OP_CEIL) {
671 pc->emit[0] |= rint;
672 pc->emit[1] |= 4 << 16;
673 } else
674 if (i->opcode == NV_OP_TRUNC) {
675 pc->emit[0] |= rint;
676 pc->emit[1] |= 6 << 16;
677 }
678
679 if (i->saturate || i->opcode == NV_OP_SAT)
680 pc->emit[0] |= 0x20;
681
682 if (NV_BASEOP(i->opcode) == NV_OP_ABS || i->src[0]->mod & NV_MOD_ABS)
683 pc->emit[0] |= 1 << 6;
684 if (NV_BASEOP(i->opcode) == NV_OP_NEG || i->src[0]->mod & NV_MOD_NEG)
685 pc->emit[0] |= 1 << 8;
686
687 pc->emit[0] |= util_logbase2(DREG(i->def[0])->size) << 20;
688 pc->emit[0] |= util_logbase2(SREG(i->src[0])->size) << 23;
689
690 emit_form_1(pc, i);
691 }
692
693 static void
694 emit_interp(struct nv_pc *pc, struct nv_instruction *i)
695 {
696 pc->emit[0] = 0x00000000;
697 pc->emit[1] = 0xc07e0000;
698
699 DID(pc, i->def[0], 14);
700
701 set_pred(pc, i);
702
703 if (i->indirect)
704 SID(pc, i->src[i->indirect], 20);
705 else
706 SID(pc, NULL, 20);
707
708 if (i->opcode == NV_OP_PINTERP) {
709 pc->emit[0] |= 0x040;
710 SID(pc, i->src[1], 26);
711 } else {
712 SID(pc, NULL, 26);
713 }
714
715 pc->emit[1] |= i->src[0]->value->reg.address & 0xffff;
716
717 if (i->centroid)
718 pc->emit[0] |= 0x100;
719 else
720 if (i->flat)
721 pc->emit[0] |= 0x080;
722 }
723
724 static void
725 emit_vfetch(struct nv_pc *pc, struct nv_instruction *i)
726 {
727 pc->emit[0] = 0x03f00006;
728 pc->emit[1] = 0x06000000 | i->src[0]->value->reg.address;
729 if (i->patch)
730 pc->emit[0] |= 0x100;
731
732 set_pred(pc, i);
733
734 DVS(pc, i);
735 DID(pc, i->def[0], 14);
736
737 SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 26);
738 }
739
740 static void
741 emit_export(struct nv_pc *pc, struct nv_instruction *i)
742 {
743 pc->emit[0] = 0x00000006;
744 pc->emit[1] = 0x0a000000;
745 if (i->patch)
746 pc->emit[0] |= 0x100;
747
748 set_pred(pc, i);
749
750 assert(SFILE(i, 0) == NV_FILE_MEM_V);
751 assert(SFILE(i, 1) == NV_FILE_GPR);
752
753 SID(pc, i->src[1], 26); /* register source */
754 SVS(pc, i->src[0]);
755
756 pc->emit[1] |= i->src[0]->value->reg.address & 0xfff;
757
758 SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 20);
759 }
760
761 static void
762 emit_mov(struct nv_pc *pc, struct nv_instruction *i)
763 {
764 if (i->opcode == NV_OP_MOV)
765 i->lanes = 0xf;
766
767 if (SFILE(i, 0) == NV_FILE_IMM) {
768 pc->emit[0] = 0x000001e2;
769 pc->emit[1] = 0x18000000;
770 } else
771 if (SFILE(i, 0) == NV_FILE_PRED) {
772 pc->emit[0] = 0x1c000004;
773 pc->emit[1] = 0x080e0000;
774 } else {
775 pc->emit[0] = 0x00000004 | (i->lanes << 5);
776 pc->emit[1] = 0x28000000;
777 }
778
779 emit_form_1(pc, i);
780 }
781
782 static void
783 emit_ldst_size(struct nv_pc *pc, struct nv_instruction *i)
784 {
785 assert(NV_IS_MEMORY_FILE(SFILE(i, 0)));
786
787 switch (SSIZE(i, 0)) {
788 case 1:
789 if (NV_TYPE_ISSGD(i->ext.cvt.s))
790 pc->emit[0] |= 0x20;
791 break;
792 case 2:
793 pc->emit[0] |= 0x40;
794 if (NV_TYPE_ISSGD(i->ext.cvt.s))
795 pc->emit[0] |= 0x20;
796 break;
797 case 4: pc->emit[0] |= 0x80; break;
798 case 8: pc->emit[0] |= 0xa0; break;
799 case 16: pc->emit[0] |= 0xc0; break;
800 default:
801 NOUVEAU_ERR("invalid load/store size %u\n", SSIZE(i, 0));
802 break;
803 }
804 }
805
806 static void
807 emit_ld_common(struct nv_pc *pc, struct nv_instruction *i)
808 {
809 emit_ldst_size(pc, i);
810
811 set_pred(pc, i);
812 set_address_16(pc, i->src[0]);
813
814 SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 20);
815 DID(pc, i->def[0], 14);
816 }
817
818 static void
819 emit_ld_const(struct nv_pc *pc, struct nv_instruction *i)
820 {
821 pc->emit[0] = 0x00000006;
822 pc->emit[1] = 0x14000000 | (const_space_index(i, 0) << 10);
823
824 emit_ld_common(pc, i);
825 }
826
827 static void
828 emit_ld(struct nv_pc *pc, struct nv_instruction *i)
829 {
830 if (SFILE(i, 0) >= NV_FILE_MEM_C(0) &&
831 SFILE(i, 0) <= NV_FILE_MEM_C(15)) {
832 if (SSIZE(i, 0) == 4 && i->indirect < 0) {
833 i->lanes = 0xf;
834 emit_mov(pc, i);
835 } else {
836 emit_ld_const(pc, i);
837 }
838 } else
839 if (SFILE(i, 0) == NV_FILE_MEM_L) {
840 pc->emit[0] = 0x00000005;
841 pc->emit[1] = 0xc0000000;
842
843 emit_ld_common(pc, i);
844 } else {
845 NOUVEAU_ERR("emit_ld(%u): not handled yet\n", SFILE(i, 0));
846 abort();
847 }
848 }
849
850 static void
851 emit_st(struct nv_pc *pc, struct nv_instruction *i)
852 {
853 if (SFILE(i, 0) != NV_FILE_MEM_L)
854 NOUVEAU_ERR("emit_st(%u): file not handled yet\n", SFILE(i, 0));
855
856 pc->emit[0] = 0x00000005 | (0 << 8); /* write-back caching */
857 pc->emit[1] = 0xc8000000;
858
859 emit_ldst_size(pc, i);
860
861 set_pred(pc, i);
862 set_address_16(pc, i->src[0]);
863
864 SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 20);
865 DID(pc, i->src[1]->value, 14);
866 }
867
868 void
869 nvc0_emit_instruction(struct nv_pc *pc, struct nv_instruction *i)
870 {
871 debug_printf("EMIT: "); nvc0_print_instruction(i);
872
873 switch (i->opcode) {
874 case NV_OP_VFETCH:
875 emit_vfetch(pc, i);
876 break;
877 case NV_OP_EXPORT:
878 if (!pc->is_fragprog)
879 emit_export(pc, i);
880 break;
881 case NV_OP_MOV:
882 emit_mov(pc, i);
883 break;
884 case NV_OP_LD:
885 emit_ld(pc, i);
886 break;
887 case NV_OP_ST:
888 emit_st(pc, i);
889 break;
890 case NV_OP_LINTERP:
891 case NV_OP_PINTERP:
892 emit_interp(pc, i);
893 break;
894 case NV_OP_ADD_F32:
895 emit_add_f32(pc, i);
896 break;
897 case NV_OP_AND:
898 case NV_OP_OR:
899 case NV_OP_XOR:
900 emit_bitop(pc, i);
901 break;
902 case NV_OP_CVT:
903 case NV_OP_ABS_F32:
904 case NV_OP_ABS_S32:
905 case NV_OP_NEG_F32:
906 case NV_OP_NEG_S32:
907 case NV_OP_SAT:
908 case NV_OP_CEIL:
909 case NV_OP_FLOOR:
910 case NV_OP_TRUNC:
911 emit_cvt(pc, i);
912 break;
913 case NV_OP_DFDX:
914 emit_ddx(pc, i);
915 break;
916 case NV_OP_DFDY:
917 emit_ddy(pc, i);
918 break;
919 case NV_OP_COS:
920 emit_flop(pc, i, 0);
921 break;
922 case NV_OP_SIN:
923 emit_flop(pc, i, 1);
924 break;
925 case NV_OP_EX2:
926 emit_flop(pc, i, 2);
927 break;
928 case NV_OP_LG2:
929 emit_flop(pc, i, 3);
930 break;
931 case NV_OP_RCP:
932 emit_flop(pc, i, 4);
933 break;
934 case NV_OP_RSQ:
935 emit_flop(pc, i, 5);
936 break;
937 case NV_OP_PRESIN:
938 case NV_OP_PREEX2:
939 emit_preop(pc, i);
940 break;
941 case NV_OP_MAD_F32:
942 emit_mad_f32(pc, i);
943 break;
944 case NV_OP_MAX_F32:
945 case NV_OP_MAX_S32:
946 case NV_OP_MAX_U32:
947 case NV_OP_MIN_F32:
948 case NV_OP_MIN_S32:
949 case NV_OP_MIN_U32:
950 emit_minmax(pc, i);
951 break;
952 case NV_OP_MUL_F32:
953 emit_mul_f32(pc, i);
954 break;
955 case NV_OP_SET_F32:
956 case NV_OP_SET_F32_AND:
957 case NV_OP_SET_F32_OR:
958 case NV_OP_SET_F32_XOR:
959 case NV_OP_SET_S32:
960 case NV_OP_SET_U32:
961 case NV_OP_FSET_F32:
962 emit_set(pc, i);
963 break;
964 case NV_OP_SHL:
965 case NV_OP_SHR:
966 case NV_OP_SAR:
967 emit_shift(pc, i);
968 break;
969 case NV_OP_TEX:
970 case NV_OP_TXB:
971 case NV_OP_TXL:
972 emit_tex(pc, i);
973 break;
974 case NV_OP_BRA:
975 emit_flow(pc, i, 0x40);
976 break;
977 case NV_OP_CALL:
978 emit_flow(pc, i, 0x50);
979 break;
980 case NV_OP_JOINAT:
981 emit_flow(pc, i, 0x60);
982 break;
983 case NV_OP_EXIT:
984 emit_flow(pc, i, 0x80);
985 break;
986 case NV_OP_RET:
987 emit_flow(pc, i, 0x90);
988 break;
989 case NV_OP_KIL:
990 emit_flow(pc, i, 0x98);
991 break;
992 case NV_OP_JOIN:
993 case NV_OP_NOP:
994 pc->emit[0] = 0x00003de4;
995 pc->emit[1] = 0x40000000;
996 break;
997 case NV_OP_SELP:
998 emit_selp(pc, i);
999 break;
1000 case NV_OP_SLCT_F32:
1001 case NV_OP_SLCT_S32:
1002 case NV_OP_SLCT_U32:
1003 emit_slct(pc, i);
1004 break;
1005 default:
1006 NOUVEAU_ERR("unhandled NV_OP: %d\n", i->opcode);
1007 abort();
1008 break;
1009 }
1010
1011 if (i->join)
1012 pc->emit[0] |= 0x10;
1013 }