nvc0: import nvc0 gallium driver
[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 assert(!(pc->emit[1] & 0xc000));
158 pc->emit[1] |= 0xc000;
159
160 assert(!(u32 & 0xfff));
161 set_immd_u32_l(pc, u32 >> 12);
162 }
163 }
164
165 static INLINE void
166 set_immd(struct nv_pc *pc, struct nv_instruction *i, int s)
167 {
168 set_immd_u32(pc, get_immd_u32(i->src[s]));
169 }
170
171 static INLINE void
172 DVS(struct nv_pc *pc, struct nv_instruction *i)
173 {
174 uint s = i->def[0]->reg.size;
175 int n;
176 for (n = 1; n < 4 && i->def[n]; ++n)
177 s += i->def[n]->reg.size;
178 pc->emit[0] |= ((s / 4) - 1) << 5;
179 }
180
181 static INLINE void
182 SVS(struct nv_pc *pc, struct nv_ref *src)
183 {
184 pc->emit[0] |= (SREG(src)->size / 4 - 1) << 5;
185 }
186
187 static void
188 set_pred(struct nv_pc *pc, struct nv_instruction *i)
189 {
190 if (i->predicate >= 0) {
191 SID(pc, i->src[i->predicate], 6);
192 if (i->cc)
193 pc->emit[0] |= 0x2000; /* negate */
194 } else {
195 pc->emit[0] |= 0x1c00;
196 }
197 }
198
199 static INLINE void
200 set_address_16(struct nv_pc *pc, struct nv_ref *src)
201 {
202 pc->emit[0] |= (src->value->reg.address & 0x003f) << 26;
203 pc->emit[1] |= (src->value->reg.address & 0xffc0) >> 6;
204 }
205
206 static INLINE unsigned
207 const_space_index(struct nv_instruction *i, int s)
208 {
209 return SFILE(i, s) - NV_FILE_MEM_C(0);
210 }
211
212 static void
213 emit_flow(struct nv_pc *pc, struct nv_instruction *i, uint8_t op)
214 {
215 pc->emit[0] = 0x000001e7;
216 pc->emit[1] = op << 24;
217
218 set_pred(pc, i);
219
220 if (i->target) {
221 uint32_t pos = i->target->emit_pos;
222
223 create_fixup(pc, NVC0_FIXUP_CODE_RELOC, 0, pos, 26, 0xfc000000);
224 create_fixup(pc, NVC0_FIXUP_CODE_RELOC, 1, pos, -6, 0x0001ffff);
225
226 pc->emit[0] |= (pos & 0x3f) << 26;
227 pc->emit[1] |= (pos >> 6) & 0x1ffff;
228 }
229 }
230
231 /* doesn't work for vfetch, export, ld, st, mov ... */
232 static void
233 emit_form_0(struct nv_pc *pc, struct nv_instruction *i)
234 {
235 int s;
236
237 set_pred(pc, i);
238
239 DID(pc, i->def[0], 14);
240
241 for (s = 0; s < 3 && i->src[s]; ++s) {
242 if (SFILE(i, s) >= NV_FILE_MEM_C(0) &&
243 SFILE(i, s) <= NV_FILE_MEM_C(15)) {
244 assert(!(pc->emit[1] & 0xc000));
245 assert(s <= 1);
246 pc->emit[1] |= 0x4000 | (const_space_index(i, s) << 10);
247 set_address_16(pc, i->src[s]);
248 } else
249 if (SFILE(i, s) == NV_FILE_GPR) {
250 SID(pc, i->src[s], s ? ((s == 2) ? 49 : 26) : 20);
251 } else
252 if (SFILE(i, s) == NV_FILE_IMM) {
253 assert(!(pc->emit[1] & 0xc000));
254 assert(s == 1 || i->opcode == NV_OP_MOV);
255 set_immd(pc, i, s);
256 }
257 }
258 }
259
260 static void
261 emit_form_1(struct nv_pc *pc, struct nv_instruction *i)
262 {
263 int s;
264
265 set_pred(pc, i);
266
267 DID(pc, i->def[0], 14);
268
269 for (s = 0; s < 1 && i->src[s]; ++s) {
270 if (SFILE(i, s) >= NV_FILE_MEM_C(0) &&
271 SFILE(i, s) <= NV_FILE_MEM_C(15)) {
272 assert(!(pc->emit[1] & 0xc000));
273 assert(s <= 1);
274 pc->emit[1] |= 0x4000 | (const_space_index(i, s) << 10);
275 set_address_16(pc, i->src[s]);
276 } else
277 if (SFILE(i, s) == NV_FILE_GPR) {
278 SID(pc, i->src[s], 26);
279 } else
280 if (SFILE(i, s) == NV_FILE_IMM) {
281 assert(!(pc->emit[1] & 0xc000));
282 assert(s == 1 || i->opcode == NV_OP_MOV);
283 set_immd(pc, i, s);
284 }
285 }
286 }
287
288 static void
289 emit_neg_abs_1_2(struct nv_pc *pc, struct nv_instruction *i)
290 {
291 if (i->src[0]->mod & NV_MOD_ABS)
292 pc->emit[0] |= 1 << 7;
293 if (i->src[0]->mod & NV_MOD_NEG)
294 pc->emit[0] |= 1 << 9;
295 if (i->src[1]->mod & NV_MOD_ABS)
296 pc->emit[0] |= 1 << 6;
297 if (i->src[1]->mod & NV_MOD_NEG)
298 pc->emit[0] |= 1 << 8;
299 }
300
301 static void
302 emit_add_f32(struct nv_pc *pc, struct nv_instruction *i)
303 {
304 pc->emit[0] = 0x00000000;
305 pc->emit[1] = 0x50000000;
306
307 emit_form_0(pc, i);
308
309 emit_neg_abs_1_2(pc, i);
310
311 if (i->saturate)
312 pc->emit[1] |= 1 << 17;
313 }
314
315 static void
316 emit_mul_f32(struct nv_pc *pc, struct nv_instruction *i)
317 {
318 pc->emit[0] = 0x00000000;
319 pc->emit[1] = 0x58000000;
320
321 emit_form_0(pc, i);
322
323 if ((i->src[0]->mod ^ i->src[1]->mod) & NV_MOD_NEG)
324 pc->emit[1] |= 1 << 25;
325
326 if (i->saturate)
327 pc->emit[0] |= 1 << 5;
328 }
329
330 static void
331 emit_mad_f32(struct nv_pc *pc, struct nv_instruction *i)
332 {
333 pc->emit[0] = 0x00000000;
334 pc->emit[1] = 0x30000000;
335
336 emit_form_0(pc, i);
337
338 if ((i->src[0]->mod ^ i->src[1]->mod) & NV_MOD_NEG)
339 pc->emit[0] |= 1 << 9;
340
341 if (i->src[2]->mod & NV_MOD_NEG)
342 pc->emit[0] |= 1 << 8;
343
344 if (i->saturate)
345 pc->emit[0] |= 1 << 5;
346 }
347
348 static void
349 emit_minmax(struct nv_pc *pc, struct nv_instruction *i)
350 {
351 pc->emit[0] = 0x00000000;
352 pc->emit[1] = 0x08000000;
353
354 if (NV_BASEOP(i->opcode) == NV_OP_MAX)
355 pc->emit[1] |= 0x001e0000;
356 else
357 pc->emit[1] |= 0x000e0000; /* predicate ? */
358
359 emit_form_0(pc, i);
360
361 emit_neg_abs_1_2(pc, i);
362
363 switch (i->opcode) {
364 case NV_OP_MIN_U32:
365 case NV_OP_MAX_U32:
366 pc->emit[0] |= 3;
367 break;
368 case NV_OP_MIN_S32:
369 case NV_OP_MAX_S32:
370 pc->emit[0] |= 3 | (1 << 5);
371 break;
372 case NV_OP_MIN_F32:
373 case NV_OP_MAX_F32:
374 default:
375 break;
376 }
377 }
378
379 static void
380 emit_tex(struct nv_pc *pc, struct nv_instruction *i)
381 {
382 pc->emit[0] = 0x00000086;
383 pc->emit[1] = 0x80000000;
384
385 if (i->opcode == NV_OP_TXB) pc->emit[1] |= 0x04000000;
386 else
387 if (i->opcode == NV_OP_TXL) pc->emit[1] |= 0x06000000;
388
389 set_pred(pc, i);
390
391 if (1)
392 pc->emit[0] |= 63 << 26; /* explicit derivatives */
393
394 DID(pc, i->def[0], 14);
395 SID(pc, i->src[0], 20);
396
397 pc->emit[1] |= i->tex_mask << 14;
398 pc->emit[1] |= (i->tex_argc - 1) << 20;
399
400 assert(i->ext.tex.s < 16);
401
402 pc->emit[1] |= i->ext.tex.t;
403 pc->emit[1] |= i->ext.tex.s << 8;
404
405 if (i->tex_live)
406 pc->emit[0] |= 1 << 9;
407 }
408
409 /* 0: cos, 1: sin, 2: ex2, 3: lg2, 4: rcp, 5: rsqrt */
410 static void
411 emit_flop(struct nv_pc *pc, struct nv_instruction *i, ubyte op)
412 {
413 pc->emit[0] = 0x00000000;
414 pc->emit[1] = 0xc8000000;
415
416 set_pred(pc, i);
417
418 DID(pc, i->def[0], 14);
419 SID(pc, i->src[0], 20);
420
421 pc->emit[0] |= op << 26;
422
423 if (op > 4) {
424 if (i->src[0]->mod & NV_MOD_NEG) pc->emit[0] |= 1 << 9;
425 if (i->src[0]->mod & NV_MOD_ABS) pc->emit[0] |= 1 << 7;
426 } else {
427 assert(!i->src[0]->mod);
428 }
429 }
430
431 static void
432 emit_quadop(struct nv_pc *pc, struct nv_instruction *i)
433 {
434 pc->emit[0] = 0x00000000;
435 pc->emit[1] = 0x48000000;
436
437 set_pred(pc, i);
438
439 assert(SFILE(i, 0) == NV_FILE_GPR && SFILE(i, 1) == NV_FILE_GPR);
440
441 DID(pc, i->def[0], 14);
442 SID(pc, i->src[0], 20);
443 SID(pc, i->src[0], 26);
444
445 pc->emit[0] |= i->lanes << 6; /* l0, l1, l2, l3, dx, dy */
446 pc->emit[1] |= i->quadop;
447 }
448
449 static void
450 emit_ddx(struct nv_pc *pc, struct nv_instruction *i)
451 {
452 i->quadop = 0x99;
453 i->lanes = 4;
454 emit_quadop(pc, i);
455 }
456
457 static void
458 emit_ddy(struct nv_pc *pc, struct nv_instruction *i)
459 {
460 i->quadop = 0xa5;
461 i->lanes = 5;
462 emit_quadop(pc, i);
463 }
464
465 /* preparation op (preex2, presin / convert to fixed point) */
466 static void
467 emit_preop(struct nv_pc *pc, struct nv_instruction *i)
468 {
469 pc->emit[0] = 0x00000000;
470 pc->emit[1] = 0x60000000;
471
472 if (i->opcode == NV_OP_PREEX2)
473 pc->emit[0] |= 0x20;
474
475 emit_form_1(pc, i);
476
477 if (i->src[0]->mod & NV_MOD_NEG) pc->emit[0] |= 1 << 8;
478 if (i->src[0]->mod & NV_MOD_ABS) pc->emit[0] |= 1 << 6;
479 }
480
481 static void
482 emit_shift(struct nv_pc *pc, struct nv_instruction *i)
483 {
484 pc->emit[0] = 0x00000003;
485
486 switch (i->opcode) {
487 case NV_OP_SAR:
488 pc->emit[0] |= 0x20; /* fall through */
489 case NV_OP_SHR:
490 pc->emit[1] = 0x58000000;
491 break;
492 case NV_OP_SHL:
493 default:
494 pc->emit[1] = 0x60000000;
495 break;
496 }
497
498 emit_form_0(pc, i);
499 }
500
501 static void
502 emit_bitop(struct nv_pc *pc, struct nv_instruction *i)
503 {
504 if (SFILE(i, 1) == NV_FILE_IMM) {
505 pc->emit[0] = 0x00000002;
506 pc->emit[1] = 0x38000000;
507 } else {
508 pc->emit[0] = 0x00000003;
509 pc->emit[1] = 0x68000000;
510 }
511
512 switch (i->opcode) {
513 case NV_OP_OR:
514 pc->emit[0] |= 0x40;
515 break;
516 case NV_OP_XOR:
517 pc->emit[0] |= 0x80;
518 break;
519 case NV_OP_AND:
520 default:
521 break;
522 }
523
524 emit_form_0(pc, i);
525 }
526
527 static void
528 emit_set(struct nv_pc *pc, struct nv_instruction *i)
529 {
530 pc->emit[0] = 0x00000000;
531
532 switch (i->opcode) {
533 case NV_OP_SET_S32:
534 pc->emit[0] |= 0x20; /* fall through */
535 case NV_OP_SET_U32:
536 pc->emit[0] |= 0x3;
537 pc->emit[1] = 0x100e0000;
538 break;
539 case NV_OP_SET_F32_AND:
540 pc->emit[1] = 0x18000000;
541 break;
542 case NV_OP_SET_F32_OR:
543 pc->emit[1] = 0x18200000;
544 break;
545 case NV_OP_SET_F32_XOR:
546 pc->emit[1] = 0x18400000;
547 break;
548 case NV_OP_FSET_F32:
549 pc->emit[0] |= 0x20; /* fall through */
550 case NV_OP_SET_F32:
551 default:
552 pc->emit[1] = 0x180e0000;
553 break;
554 }
555
556 if (DFILE(i, 0) == NV_FILE_PRED) {
557 pc->emit[0] |= 0x1c000;
558 pc->emit[1] += 0x08000000;
559 }
560
561 pc->emit[1] |= i->set_cond << 23;
562
563 emit_form_0(pc, i);
564
565 emit_neg_abs_1_2(pc, i); /* maybe assert that U/S32 don't use mods */
566 }
567
568 static void
569 emit_selp(struct nv_pc *pc, struct nv_instruction *i)
570 {
571 pc->emit[0] = 0x00000004;
572 pc->emit[1] = 0x20000000;
573
574 emit_form_0(pc, i);
575
576 if (i->cc || (i->src[2]->mod & NV_MOD_NOT))
577 pc->emit[1] |= 1 << 20;
578 }
579
580 static void
581 emit_slct(struct nv_pc *pc, struct nv_instruction *i)
582 {
583 pc->emit[0] = 0x00000000;
584
585 switch (i->opcode) {
586 case NV_OP_SLCT_S32:
587 pc->emit[0] |= 0x20; /* fall through */
588 case NV_OP_SLCT_U32:
589 pc->emit[0] |= 0x3;
590 pc->emit[1] = 0x30000000;
591 break;
592 case NV_OP_SLCT_F32:
593 default:
594 pc->emit[1] = 0x38000000;
595 break;
596 }
597
598 emit_form_0(pc, i);
599
600 pc->emit[1] |= i->set_cond << 23;
601 }
602
603 static void
604 emit_cvt(struct nv_pc *pc, struct nv_instruction *i)
605 {
606 pc->emit[0] = 0x00000004;
607 pc->emit[1] = 0x10000000;
608
609 if (i->opcode != NV_OP_CVT)
610 i->ext.cvt.d = i->ext.cvt.s = NV_OPTYPE(i->opcode);
611
612 switch (i->ext.cvt.d) {
613 case NV_TYPE_F32:
614 switch (i->ext.cvt.s) {
615 case NV_TYPE_F32: pc->emit[1] = 0x10000000; break;
616 case NV_TYPE_S32: pc->emit[0] |= 0x200;
617 case NV_TYPE_U32: pc->emit[1] = 0x18000000; break;
618 }
619 break;
620 case NV_TYPE_S32: pc->emit[0] |= 0x80;
621 case NV_TYPE_U32:
622 switch (i->ext.cvt.s) {
623 case NV_TYPE_F32: pc->emit[1] = 0x14000000; break;
624 case NV_TYPE_S32: pc->emit[0] |= 0x200;
625 case NV_TYPE_U32: pc->emit[1] = 0x1c000000; break;
626 }
627 break;
628 default:
629 assert(!"cvt: unknown type");
630 break;
631 }
632
633 if (i->opcode == NV_OP_FLOOR)
634 pc->emit[1] |= 0x00020000;
635 else
636 if (i->opcode == NV_OP_CEIL)
637 pc->emit[1] |= 0x00040000;
638 else
639 if (i->opcode == NV_OP_TRUNC)
640 pc->emit[1] |= 0x00060000;
641
642 if (i->saturate || i->opcode == NV_OP_SAT)
643 pc->emit[0] |= 0x20;
644
645 if (NV_BASEOP(i->opcode) == NV_OP_ABS || i->src[0]->mod & NV_MOD_ABS)
646 pc->emit[0] |= 1 << 6;
647 if (NV_BASEOP(i->opcode) == NV_OP_NEG || i->src[0]->mod & NV_MOD_NEG)
648 pc->emit[0] |= 1 << 8;
649
650 pc->emit[0] |= util_logbase2(DREG(i->def[0])->size) << 20;
651 pc->emit[0] |= util_logbase2(SREG(i->src[0])->size) << 23;
652
653 emit_form_1(pc, i);
654 }
655
656 static void
657 emit_interp(struct nv_pc *pc, struct nv_instruction *i)
658 {
659 pc->emit[0] = 0x00000000;
660 pc->emit[1] = 0xc07e0000;
661
662 DID(pc, i->def[0], 14);
663
664 set_pred(pc, i);
665
666 if (i->indirect)
667 SID(pc, i->src[i->indirect], 20);
668 else
669 SID(pc, NULL, 20);
670
671 if (i->opcode == NV_OP_PINTERP) {
672 pc->emit[0] |= 0x040;
673 SID(pc, i->src[1], 26);
674 } else {
675 SID(pc, NULL, 26);
676 }
677
678 pc->emit[1] |= i->src[0]->value->reg.address & 0xffff;
679
680 if (i->centroid)
681 pc->emit[0] |= 0x100;
682 else
683 if (i->flat)
684 pc->emit[0] |= 0x080;
685 }
686
687 static void
688 emit_vfetch(struct nv_pc *pc, struct nv_instruction *i)
689 {
690 pc->emit[0] = 0x03f00006;
691 pc->emit[1] = 0x06000000 | i->src[0]->value->reg.address;
692 if (i->patch)
693 pc->emit[0] |= 0x100;
694
695 set_pred(pc, i);
696
697 DVS(pc, i);
698 DID(pc, i->def[0], 14);
699
700 SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 26);
701 }
702
703 static void
704 emit_export(struct nv_pc *pc, struct nv_instruction *i)
705 {
706 pc->emit[0] = 0x00000006;
707 pc->emit[1] = 0x0a000000;
708 if (i->patch)
709 pc->emit[0] |= 0x100;
710
711 set_pred(pc, i);
712
713 assert(SFILE(i, 0) == NV_FILE_MEM_V);
714 assert(SFILE(i, 1) == NV_FILE_GPR);
715
716 SID(pc, i->src[1], 26); /* register source */
717 SVS(pc, i->src[0]);
718
719 pc->emit[1] |= i->src[0]->value->reg.address & 0xfff;
720
721 SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 20);
722 }
723
724 static void
725 emit_mov(struct nv_pc *pc, struct nv_instruction *i)
726 {
727 if (i->opcode == NV_OP_MOV)
728 i->lanes = 0xf;
729
730 if (SFILE(i, 0) == NV_FILE_IMM) {
731 pc->emit[0] = 0x000001e2;
732 pc->emit[1] = 0x18000000;
733 } else
734 if (SFILE(i, 0) == NV_FILE_PRED) {
735 pc->emit[0] = 0x1c000004;
736 pc->emit[1] = 0x080e0000;
737 } else {
738 pc->emit[0] = 0x00000004 | (i->lanes << 5);
739 pc->emit[1] = 0x28000000;
740 }
741
742 emit_form_1(pc, i);
743 }
744
745 static void
746 emit_ldst_size(struct nv_pc *pc, struct nv_instruction *i)
747 {
748 assert(NV_IS_MEMORY_FILE(SFILE(i, 0)));
749
750 switch (SSIZE(i, 0)) {
751 case 1:
752 if (NV_TYPE_ISSGD(i->ext.cvt.s))
753 pc->emit[0] |= 0x20;
754 break;
755 case 2:
756 pc->emit[0] |= 0x40;
757 if (NV_TYPE_ISSGD(i->ext.cvt.s))
758 pc->emit[0] |= 0x20;
759 break;
760 case 4: pc->emit[0] |= 0x80; break;
761 case 8: pc->emit[0] |= 0xa0; break;
762 case 16: pc->emit[0] |= 0xc0; break;
763 default:
764 NOUVEAU_ERR("invalid load/store size %u\n", SSIZE(i, 0));
765 break;
766 }
767 }
768
769 static void
770 emit_ld_const(struct nv_pc *pc, struct nv_instruction *i)
771 {
772 pc->emit[0] = 0x00000006;
773 pc->emit[1] = 0x14000000 | (const_space_index(i, 0) << 10);
774
775 emit_ldst_size(pc, i);
776
777 set_pred(pc, i);
778 set_address_16(pc, i->src[0]);
779
780 SID(pc, (i->indirect >= 0) ? i->src[i->indirect] : NULL, 20);
781 DID(pc, i->def[0], 14);
782 }
783
784 static void
785 emit_ld(struct nv_pc *pc, struct nv_instruction *i)
786 {
787 if (SFILE(i, 0) >= NV_FILE_MEM_C(0) &&
788 SFILE(i, 0) <= NV_FILE_MEM_C(15)) {
789 emit_ld_const(pc, i);
790 } else {
791 NOUVEAU_ERR("emit_ld(%u): not handled yet\n", SFILE(i, 0));
792 abort();
793 }
794 }
795
796 static void
797 emit_st(struct nv_pc *pc, struct nv_instruction *i)
798 {
799 NOUVEAU_ERR("emit_st: not handled yet\n");
800 abort();
801 }
802
803 void
804 nvc0_emit_instruction(struct nv_pc *pc, struct nv_instruction *i)
805 {
806 debug_printf("EMIT: "); nvc0_print_instruction(i);
807
808 switch (i->opcode) {
809 case NV_OP_VFETCH:
810 emit_vfetch(pc, i);
811 break;
812 case NV_OP_EXPORT:
813 if (!pc->is_fragprog)
814 emit_export(pc, i);
815 break;
816 case NV_OP_MOV:
817 emit_mov(pc, i);
818 break;
819 case NV_OP_LD:
820 emit_ld(pc, i);
821 break;
822 case NV_OP_ST:
823 emit_st(pc, i);
824 break;
825 case NV_OP_LINTERP:
826 case NV_OP_PINTERP:
827 emit_interp(pc, i);
828 break;
829 case NV_OP_ADD_F32:
830 emit_add_f32(pc, i);
831 break;
832 case NV_OP_AND:
833 case NV_OP_OR:
834 case NV_OP_XOR:
835 emit_bitop(pc, i);
836 break;
837 case NV_OP_CVT:
838 case NV_OP_ABS_F32:
839 case NV_OP_ABS_S32:
840 case NV_OP_NEG_F32:
841 case NV_OP_NEG_S32:
842 case NV_OP_SAT:
843 case NV_OP_CEIL:
844 case NV_OP_FLOOR:
845 case NV_OP_TRUNC:
846 emit_cvt(pc, i);
847 break;
848 case NV_OP_DFDX:
849 emit_ddx(pc, i);
850 break;
851 case NV_OP_DFDY:
852 emit_ddy(pc, i);
853 break;
854 case NV_OP_COS:
855 emit_flop(pc, i, 0);
856 break;
857 case NV_OP_SIN:
858 emit_flop(pc, i, 1);
859 break;
860 case NV_OP_EX2:
861 emit_flop(pc, i, 2);
862 break;
863 case NV_OP_LG2:
864 emit_flop(pc, i, 3);
865 break;
866 case NV_OP_RCP:
867 emit_flop(pc, i, 4);
868 break;
869 case NV_OP_RSQ:
870 emit_flop(pc, i, 5);
871 break;
872 case NV_OP_PRESIN:
873 case NV_OP_PREEX2:
874 emit_preop(pc, i);
875 break;
876 case NV_OP_MAD_F32:
877 emit_mad_f32(pc, i);
878 break;
879 case NV_OP_MAX_F32:
880 case NV_OP_MAX_S32:
881 case NV_OP_MAX_U32:
882 case NV_OP_MIN_F32:
883 case NV_OP_MIN_S32:
884 case NV_OP_MIN_U32:
885 emit_minmax(pc, i);
886 break;
887 case NV_OP_MUL_F32:
888 emit_mul_f32(pc, i);
889 break;
890 case NV_OP_SET_F32:
891 case NV_OP_FSET_F32:
892 emit_set(pc, i);
893 break;
894 case NV_OP_SHL:
895 case NV_OP_SHR:
896 case NV_OP_SAR:
897 emit_shift(pc, i);
898 break;
899 case NV_OP_TEX:
900 case NV_OP_TXB:
901 case NV_OP_TXL:
902 emit_tex(pc, i);
903 break;
904 case NV_OP_BRA:
905 emit_flow(pc, i, 0x40);
906 break;
907 case NV_OP_CALL:
908 emit_flow(pc, i, 0x50);
909 break;
910 case NV_OP_JOINAT:
911 emit_flow(pc, i, 0x60);
912 break;
913 case NV_OP_EXIT:
914 emit_flow(pc, i, 0x80);
915 break;
916 case NV_OP_RET:
917 emit_flow(pc, i, 0x90);
918 break;
919 case NV_OP_KIL:
920 emit_flow(pc, i, 0x98);
921 break;
922 case NV_OP_JOIN:
923 case NV_OP_NOP:
924 pc->emit[0] = 0x00003c00;
925 pc->emit[1] = 0x00000000;
926 break;
927 case NV_OP_SELP:
928 emit_selp(pc, i);
929 break;
930 case NV_OP_SLCT_F32:
931 case NV_OP_SLCT_S32:
932 case NV_OP_SLCT_U32:
933 emit_slct(pc, i);
934 break;
935 default:
936 NOUVEAU_ERR("unhandled NV_OP: %d\n", i->opcode);
937 abort();
938 break;
939 }
940
941 if (i->join)
942 pc->emit[0] |= 0x10;
943 }