2 * Copyright 2010 Christoph Bumiller
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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
24 #include "nvc0_program.h"
26 #define NVC0_FIXUP_CODE_RELOC 0
27 #define NVC0_FIXUP_DATA_RELOC 1
38 nvc0_relocate_program(struct nvc0_program
*prog
,
42 struct nvc0_fixup
*f
= (struct nvc0_fixup
*)prog
->relocs
;
45 for (i
= 0; i
< prog
->num_relocs
; ++i
) {
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;
55 data
= (f
[i
].shift
< 0) ? (data
>> -f
[i
].shift
) : (data
<< f
[i
].shift
);
57 prog
->code
[f
[i
].ofst
/ 4] &= ~f
[i
].mask
;
58 prog
->code
[f
[i
].ofst
/ 4] |= data
& f
[i
].mask
;
62 #ifdef USE_UNUSED_CODE
64 create_fixup(struct nv_pc
*pc
, uint8_t ty
,
65 int w
, uint32_t data
, uint32_t m
, int s
)
69 const unsigned size
= sizeof(struct nvc0_fixup
);
70 const unsigned n
= pc
->num_relocs
;
73 pc
->reloc_entries
= REALLOC(pc
->reloc_entries
, n
* size
, (n
+ 8) * size
);
75 f
= (struct nvc0_fixup
*)pc
->reloc_entries
;
77 f
[n
].ofst
= pc
->emit_pos
+ w
* 4;
88 SSIZE(struct nv_instruction
*nvi
, int s
)
90 return nvi
->src
[s
]->value
->reg
.size
;
94 DSIZE(struct nv_instruction
*nvi
, int d
)
96 return nvi
->def
[d
]->reg
.size
;
99 static INLINE
struct nv_reg
*
100 SREG(struct nv_ref
*ref
)
104 return &ref
->value
->join
->reg
;
107 static INLINE
struct nv_reg
*
108 DREG(struct nv_value
*val
)
112 return &val
->join
->reg
;
116 SFILE(struct nv_instruction
*nvi
, int s
)
118 return nvi
->src
[s
]->value
->reg
.file
;
122 DFILE(struct nv_instruction
*nvi
, int d
)
124 return nvi
->def
[0]->reg
.file
;
128 SID(struct nv_pc
*pc
, struct nv_ref
*ref
, int pos
)
130 pc
->emit
[pos
/ 32] |= (SREG(ref
) ? SREG(ref
)->id
: 63) << (pos
% 32);
134 DID(struct nv_pc
*pc
, struct nv_value
*val
, int pos
)
136 pc
->emit
[pos
/ 32] |= (DREG(val
) ? DREG(val
)->id
: 63) << (pos
% 32);
139 static INLINE
uint32_t
140 get_immd_u32(struct nv_ref
*ref
) /* XXX: dependent on [0]:2 */
142 assert(ref
->value
->reg
.file
== NV_FILE_IMM
);
143 return ref
->value
->reg
.imm
.u32
;
147 set_immd_u32_l(struct nv_pc
*pc
, uint32_t u32
)
149 pc
->emit
[0] |= (u32
& 0x3f) << 26;
150 pc
->emit
[1] |= u32
>> 6;
154 set_immd_u32(struct nv_pc
*pc
, uint32_t u32
)
156 if ((pc
->emit
[0] & 0xf) == 0x2) {
157 set_immd_u32_l(pc
, u32
);
159 if ((pc
->emit
[0] & 0xf) == 0x3) {
160 assert(!(pc
->emit
[1] & 0xc000));
161 pc
->emit
[1] |= 0xc000;
162 assert(!(u32
& 0xfff00000));
163 set_immd_u32_l(pc
, u32
);
165 assert(!(pc
->emit
[1] & 0xc000));
166 pc
->emit
[1] |= 0xc000;
167 assert(!(u32
& 0xfff));
168 set_immd_u32_l(pc
, u32
>> 12);
173 set_immd(struct nv_pc
*pc
, struct nv_instruction
*i
, int s
)
175 set_immd_u32(pc
, get_immd_u32(i
->src
[s
]));
179 DVS(struct nv_pc
*pc
, struct nv_instruction
*i
)
181 uint s
= i
->def
[0]->reg
.size
;
183 for (n
= 1; n
< 4 && i
->def
[n
]; ++n
)
184 s
+= i
->def
[n
]->reg
.size
;
185 pc
->emit
[0] |= ((s
/ 4) - 1) << 5;
189 SVS(struct nv_pc
*pc
, struct nv_ref
*src
)
191 pc
->emit
[0] |= (SREG(src
)->size
/ 4 - 1) << 5;
195 set_pred(struct nv_pc
*pc
, struct nv_instruction
*i
)
197 if (i
->predicate
>= 0) {
198 SID(pc
, i
->src
[i
->predicate
], 6);
200 pc
->emit
[0] |= 0x2000; /* negate */
202 pc
->emit
[0] |= 0x1c00;
207 set_address_16(struct nv_pc
*pc
, struct nv_ref
*src
)
209 pc
->emit
[0] |= (src
->value
->reg
.address
& 0x003f) << 26;
210 pc
->emit
[1] |= (src
->value
->reg
.address
& 0xffc0) >> 6;
213 static INLINE
unsigned
214 const_space_index(struct nv_instruction
*i
, int s
)
216 return SFILE(i
, s
) - NV_FILE_MEM_C(0);
220 emit_flow(struct nv_pc
*pc
, struct nv_instruction
*i
, uint8_t op
)
222 pc
->emit
[0] = 0x00000007;
223 pc
->emit
[1] = op
<< 24;
225 if (op
== 0x40 || (op
>= 0x80 && op
<= 0x98)) {
226 /* bra, exit, ret or kil */
227 pc
->emit
[0] |= 0x1e0;
232 int32_t pcrel
= i
->target
->emit_pos
- (pc
->emit_pos
+ 8);
234 /* we will need relocations only for global functions */
236 create_fixup(pc, NVC0_FIXUP_CODE_RELOC, 0, pos, 26, 0xfc000000);
237 create_fixup(pc, NVC0_FIXUP_CODE_RELOC, 1, pos, -6, 0x0001ffff);
240 pc
->emit
[0] |= (pcrel
& 0x3f) << 26;
241 pc
->emit
[1] |= (pcrel
>> 6) & 0x3ffff;
245 /* doesn't work for vfetch, export, ld, st, mov ... */
247 emit_form_0(struct nv_pc
*pc
, struct nv_instruction
*i
)
253 DID(pc
, i
->def
[0], 14);
255 for (s
= 0; s
< 3 && i
->src
[s
]; ++s
) {
256 if (SFILE(i
, s
) >= NV_FILE_MEM_C(0) &&
257 SFILE(i
, s
) <= NV_FILE_MEM_C(15)) {
258 assert(!(pc
->emit
[1] & 0xc000));
260 pc
->emit
[1] |= 0x4000 | (const_space_index(i
, s
) << 10);
261 set_address_16(pc
, i
->src
[s
]);
263 if (SFILE(i
, s
) == NV_FILE_GPR
) {
264 SID(pc
, i
->src
[s
], s
? ((s
== 2) ? 49 : 26) : 20);
266 if (SFILE(i
, s
) == NV_FILE_IMM
) {
267 assert(!(pc
->emit
[1] & 0xc000));
268 assert(s
== 1 || i
->opcode
== NV_OP_MOV
);
275 emit_form_1(struct nv_pc
*pc
, struct nv_instruction
*i
)
281 DID(pc
, i
->def
[0], 14);
283 for (s
= 0; s
< 1 && i
->src
[s
]; ++s
) {
284 if (SFILE(i
, s
) >= NV_FILE_MEM_C(0) &&
285 SFILE(i
, s
) <= NV_FILE_MEM_C(15)) {
286 assert(!(pc
->emit
[1] & 0xc000));
288 pc
->emit
[1] |= 0x4000 | (const_space_index(i
, s
) << 10);
289 set_address_16(pc
, i
->src
[s
]);
291 if (SFILE(i
, s
) == NV_FILE_GPR
) {
292 SID(pc
, i
->src
[s
], 26);
294 if (SFILE(i
, s
) == NV_FILE_IMM
) {
295 assert(!(pc
->emit
[1] & 0xc000));
296 assert(s
== 1 || i
->opcode
== NV_OP_MOV
);
303 emit_neg_abs_1_2(struct nv_pc
*pc
, struct nv_instruction
*i
)
305 if (i
->src
[0]->mod
& NV_MOD_ABS
)
306 pc
->emit
[0] |= 1 << 7;
307 if (i
->src
[0]->mod
& NV_MOD_NEG
)
308 pc
->emit
[0] |= 1 << 9;
309 if (i
->src
[1]->mod
& NV_MOD_ABS
)
310 pc
->emit
[0] |= 1 << 6;
311 if (i
->src
[1]->mod
& NV_MOD_NEG
)
312 pc
->emit
[0] |= 1 << 8;
316 emit_add_f32(struct nv_pc
*pc
, struct nv_instruction
*i
)
318 pc
->emit
[0] = 0x00000000;
319 pc
->emit
[1] = 0x50000000;
323 emit_neg_abs_1_2(pc
, i
);
326 pc
->emit
[1] |= 1 << 17;
330 emit_mul_f32(struct nv_pc
*pc
, struct nv_instruction
*i
)
332 pc
->emit
[0] = 0x00000000;
333 pc
->emit
[1] = 0x58000000;
337 if ((i
->src
[0]->mod
^ i
->src
[1]->mod
) & NV_MOD_NEG
)
338 pc
->emit
[1] |= 1 << 25;
341 pc
->emit
[0] |= 1 << 5;
345 emit_mad_f32(struct nv_pc
*pc
, struct nv_instruction
*i
)
347 pc
->emit
[0] = 0x00000000;
348 pc
->emit
[1] = 0x30000000;
352 if ((i
->src
[0]->mod
^ i
->src
[1]->mod
) & NV_MOD_NEG
)
353 pc
->emit
[0] |= 1 << 9;
355 if (i
->src
[2]->mod
& NV_MOD_NEG
)
356 pc
->emit
[0] |= 1 << 8;
359 pc
->emit
[0] |= 1 << 5;
363 emit_minmax(struct nv_pc
*pc
, struct nv_instruction
*i
)
365 pc
->emit
[0] = 0x00000000;
366 pc
->emit
[1] = 0x08000000;
368 if (NV_BASEOP(i
->opcode
) == NV_OP_MAX
)
369 pc
->emit
[1] |= 0x001e0000;
371 pc
->emit
[1] |= 0x000e0000; /* predicate ? */
375 emit_neg_abs_1_2(pc
, i
);
384 pc
->emit
[0] |= 3 | (1 << 5);
394 emit_tex(struct nv_pc
*pc
, struct nv_instruction
*i
)
396 int src1
= i
->tex_array
+ i
->tex_dim
+ i
->tex_cube
;
400 pc
->emit
[0] = 0x00000086;
401 pc
->emit
[1] = 0x80000000;
404 case NV_OP_TEX
: pc
->emit
[1] = 0x80000000; break;
405 case NV_OP_TXB
: pc
->emit
[1] = 0x84000000; break;
406 case NV_OP_TXL
: pc
->emit
[1] = 0x86000000; break;
407 case NV_OP_TXF
: pc
->emit
[1] = 0x90000000; break;
408 case NV_OP_TXG
: pc
->emit
[1] = 0xe0000000; break;
415 pc
->emit
[1] |= 0x00080000; /* layer index is u16, first value of SRC0 */
417 pc
->emit
[1] |= 0x01000000; /* shadow is part of SRC1, after bias/lod */
421 DID(pc
, i
->def
[0], 14);
422 SID(pc
, i
->src
[0], 20);
423 SID(pc
, i
->src
[src1
], 26); /* may be NULL -> $r63 */
425 pc
->emit
[1] |= i
->tex_mask
<< 14;
426 pc
->emit
[1] |= (i
->tex_dim
- 1) << 20;
428 pc
->emit
[1] |= 3 << 20;
430 assert(i
->ext
.tex
.s
< 16);
432 pc
->emit
[1] |= i
->ext
.tex
.t
;
433 pc
->emit
[1] |= i
->ext
.tex
.s
<< 8;
436 pc
->emit
[0] |= 1 << 9;
439 /* 0: cos, 1: sin, 2: ex2, 3: lg2, 4: rcp, 5: rsqrt */
441 emit_flop(struct nv_pc
*pc
, struct nv_instruction
*i
, ubyte op
)
443 pc
->emit
[0] = 0x00000000;
444 pc
->emit
[1] = 0xc8000000;
448 DID(pc
, i
->def
[0], 14);
449 SID(pc
, i
->src
[0], 20);
451 pc
->emit
[0] |= op
<< 26;
454 if (i
->src
[0]->mod
& NV_MOD_NEG
) pc
->emit
[0] |= 1 << 9;
455 if (i
->src
[0]->mod
& NV_MOD_ABS
) pc
->emit
[0] |= 1 << 7;
457 assert(!i
->src
[0]->mod
);
462 emit_quadop(struct nv_pc
*pc
, struct nv_instruction
*i
)
464 pc
->emit
[0] = 0x00000000;
465 pc
->emit
[1] = 0x48000000;
469 assert(SFILE(i
, 0) == NV_FILE_GPR
&& SFILE(i
, 1) == NV_FILE_GPR
);
471 DID(pc
, i
->def
[0], 14);
472 SID(pc
, i
->src
[0], 20);
473 SID(pc
, i
->src
[0], 26);
475 pc
->emit
[0] |= i
->lanes
<< 6; /* l0, l1, l2, l3, dx, dy */
476 pc
->emit
[1] |= i
->quadop
;
480 emit_ddx(struct nv_pc
*pc
, struct nv_instruction
*i
)
484 i
->src
[1] = i
->src
[0];
489 emit_ddy(struct nv_pc
*pc
, struct nv_instruction
*i
)
493 i
->src
[1] = i
->src
[0];
497 /* preparation op (preex2, presin / convert to fixed point) */
499 emit_preop(struct nv_pc
*pc
, struct nv_instruction
*i
)
501 pc
->emit
[0] = 0x00000000;
502 pc
->emit
[1] = 0x60000000;
504 if (i
->opcode
== NV_OP_PREEX2
)
509 if (i
->src
[0]->mod
& NV_MOD_NEG
) pc
->emit
[0] |= 1 << 8;
510 if (i
->src
[0]->mod
& NV_MOD_ABS
) pc
->emit
[0] |= 1 << 6;
514 emit_shift(struct nv_pc
*pc
, struct nv_instruction
*i
)
516 pc
->emit
[0] = 0x00000003;
520 pc
->emit
[0] |= 0x20; /* fall through */
522 pc
->emit
[1] = 0x58000000;
526 pc
->emit
[1] = 0x60000000;
534 emit_bitop(struct nv_pc
*pc
, struct nv_instruction
*i
)
536 if (SFILE(i
, 1) == NV_FILE_IMM
) {
537 pc
->emit
[0] = 0x00000002;
538 pc
->emit
[1] = 0x38000000;
540 pc
->emit
[0] = 0x00000003;
541 pc
->emit
[1] = 0x68000000;
560 emit_set(struct nv_pc
*pc
, struct nv_instruction
*i
)
562 pc
->emit
[0] = 0x00000000;
566 pc
->emit
[0] |= 0x20; /* fall through */
569 pc
->emit
[1] = 0x100e0000;
571 case NV_OP_SET_F32_AND
:
572 pc
->emit
[1] = 0x18000000;
574 case NV_OP_SET_F32_OR
:
575 pc
->emit
[1] = 0x18200000;
577 case NV_OP_SET_F32_XOR
:
578 pc
->emit
[1] = 0x18400000;
581 pc
->emit
[0] |= 0x20; /* fall through */
584 pc
->emit
[1] = 0x180e0000;
588 if (DFILE(i
, 0) == NV_FILE_PRED
) {
589 pc
->emit
[0] |= 0x1c000;
590 pc
->emit
[1] += 0x08000000;
593 pc
->emit
[1] |= i
->set_cond
<< 23;
597 emit_neg_abs_1_2(pc
, i
); /* maybe assert that U/S32 don't use mods */
601 emit_selp(struct nv_pc
*pc
, struct nv_instruction
*i
)
603 pc
->emit
[0] = 0x00000004;
604 pc
->emit
[1] = 0x20000000;
608 if (i
->cc
|| (i
->src
[2]->mod
& NV_MOD_NOT
))
609 pc
->emit
[1] |= 1 << 20;
613 emit_slct(struct nv_pc
*pc
, struct nv_instruction
*i
)
615 uint8_t cc
= i
->set_cond
;
617 pc
->emit
[0] = 0x00000000;
621 pc
->emit
[0] |= 0x20; /* fall through */
624 pc
->emit
[1] = 0x30000000;
628 pc
->emit
[1] = 0x38000000;
634 if (i
->src
[2]->mod
& NV_MOD_NEG
)
635 cc
= nvc0_ir_reverse_cc(cc
);
637 pc
->emit
[1] |= cc
<< 23;
641 emit_cvt(struct nv_pc
*pc
, struct nv_instruction
*i
)
645 pc
->emit
[0] = 0x00000004;
646 pc
->emit
[1] = 0x10000000;
648 /* if no type conversion specified, get type from opcode */
649 if (i
->opcode
!= NV_OP_CVT
&& i
->ext
.cvt
.d
== i
->ext
.cvt
.s
)
650 i
->ext
.cvt
.d
= i
->ext
.cvt
.s
= NV_OPTYPE(i
->opcode
);
652 switch (i
->ext
.cvt
.d
) {
654 switch (i
->ext
.cvt
.s
) {
655 case NV_TYPE_F32
: pc
->emit
[1] = 0x10000000; break;
656 case NV_TYPE_S32
: pc
->emit
[0] |= 0x200; /* fall through */
657 case NV_TYPE_U32
: pc
->emit
[1] = 0x18000000; break;
660 case NV_TYPE_S32
: pc
->emit
[0] |= 0x80; /* fall through */
662 switch (i
->ext
.cvt
.s
) {
663 case NV_TYPE_F32
: pc
->emit
[1] = 0x14000000; break;
664 case NV_TYPE_S32
: pc
->emit
[0] |= 0x200; /* fall through */
665 case NV_TYPE_U32
: pc
->emit
[1] = 0x1c000000; break;
669 assert(!"cvt: unknown type");
673 rint
= (i
->ext
.cvt
.d
== NV_TYPE_F32
) ? 1 << 7 : 0;
675 if (i
->opcode
== NV_OP_FLOOR
) {
677 pc
->emit
[1] |= 2 << 16;
679 if (i
->opcode
== NV_OP_CEIL
) {
681 pc
->emit
[1] |= 4 << 16;
683 if (i
->opcode
== NV_OP_TRUNC
) {
685 pc
->emit
[1] |= 6 << 16;
688 if (i
->saturate
|| i
->opcode
== NV_OP_SAT
)
691 if (NV_BASEOP(i
->opcode
) == NV_OP_ABS
|| i
->src
[0]->mod
& NV_MOD_ABS
)
692 pc
->emit
[0] |= 1 << 6;
693 if (NV_BASEOP(i
->opcode
) == NV_OP_NEG
|| i
->src
[0]->mod
& NV_MOD_NEG
)
694 pc
->emit
[0] |= 1 << 8;
696 pc
->emit
[0] |= util_logbase2(DREG(i
->def
[0])->size
) << 20;
697 pc
->emit
[0] |= util_logbase2(SREG(i
->src
[0])->size
) << 23;
703 emit_interp(struct nv_pc
*pc
, struct nv_instruction
*i
)
705 pc
->emit
[0] = 0x00000000;
706 pc
->emit
[1] = 0xc07e0000;
708 DID(pc
, i
->def
[0], 14);
713 SID(pc
, i
->src
[i
->indirect
], 20);
717 if (i
->opcode
== NV_OP_PINTERP
) {
718 pc
->emit
[0] |= 0x040;
719 SID(pc
, i
->src
[1], 26);
721 if (i
->src
[0]->value
->reg
.address
>= 0x280 &&
722 i
->src
[0]->value
->reg
.address
<= 0x29c)
723 pc
->emit
[0] |= 0x080; /* XXX: ? */
728 pc
->emit
[1] |= i
->src
[0]->value
->reg
.address
& 0xffff;
731 pc
->emit
[0] |= 0x100;
734 pc
->emit
[0] |= 0x080;
738 emit_vfetch(struct nv_pc
*pc
, struct nv_instruction
*i
)
740 pc
->emit
[0] = 0x03f00006;
741 pc
->emit
[1] = 0x06000000 | i
->src
[0]->value
->reg
.address
;
743 pc
->emit
[0] |= 0x100;
748 DID(pc
, i
->def
[0], 14);
750 SID(pc
, (i
->indirect
>= 0) ? i
->src
[i
->indirect
] : NULL
, 26);
754 emit_export(struct nv_pc
*pc
, struct nv_instruction
*i
)
756 pc
->emit
[0] = 0x00000006;
757 pc
->emit
[1] = 0x0a000000;
759 pc
->emit
[0] |= 0x100;
763 assert(SFILE(i
, 0) == NV_FILE_MEM_V
);
764 assert(SFILE(i
, 1) == NV_FILE_GPR
);
766 SID(pc
, i
->src
[1], 26); /* register source */
769 pc
->emit
[1] |= i
->src
[0]->value
->reg
.address
& 0xfff;
771 SID(pc
, (i
->indirect
>= 0) ? i
->src
[i
->indirect
] : NULL
, 20);
775 emit_mov(struct nv_pc
*pc
, struct nv_instruction
*i
)
777 if (i
->opcode
== NV_OP_MOV
)
780 if (SFILE(i
, 0) == NV_FILE_IMM
) {
781 pc
->emit
[0] = 0x000001e2;
782 pc
->emit
[1] = 0x18000000;
784 if (SFILE(i
, 0) == NV_FILE_PRED
) {
785 pc
->emit
[0] = 0x1c000004;
786 pc
->emit
[1] = 0x080e0000;
788 pc
->emit
[0] = 0x00000004 | (i
->lanes
<< 5);
789 pc
->emit
[1] = 0x28000000;
796 emit_ldst_size(struct nv_pc
*pc
, struct nv_instruction
*i
)
798 assert(NV_IS_MEMORY_FILE(SFILE(i
, 0)));
800 switch (SSIZE(i
, 0)) {
802 if (NV_TYPE_ISSGD(i
->ext
.cvt
.s
))
807 if (NV_TYPE_ISSGD(i
->ext
.cvt
.s
))
810 case 4: pc
->emit
[0] |= 0x80; break;
811 case 8: pc
->emit
[0] |= 0xa0; break;
812 case 16: pc
->emit
[0] |= 0xc0; break;
814 NOUVEAU_ERR("invalid load/store size %u\n", SSIZE(i
, 0));
820 emit_ld_common(struct nv_pc
*pc
, struct nv_instruction
*i
)
822 emit_ldst_size(pc
, i
);
825 set_address_16(pc
, i
->src
[0]);
827 SID(pc
, (i
->indirect
>= 0) ? i
->src
[i
->indirect
] : NULL
, 20);
828 DID(pc
, i
->def
[0], 14);
832 emit_ld_const(struct nv_pc
*pc
, struct nv_instruction
*i
)
834 pc
->emit
[0] = 0x00000006;
835 pc
->emit
[1] = 0x14000000 | (const_space_index(i
, 0) << 10);
837 emit_ld_common(pc
, i
);
841 emit_ld(struct nv_pc
*pc
, struct nv_instruction
*i
)
843 if (SFILE(i
, 0) >= NV_FILE_MEM_C(0) &&
844 SFILE(i
, 0) <= NV_FILE_MEM_C(15)) {
845 if (SSIZE(i
, 0) == 4 && i
->indirect
< 0) {
849 emit_ld_const(pc
, i
);
852 if (SFILE(i
, 0) == NV_FILE_MEM_L
) {
853 pc
->emit
[0] = 0x00000005;
854 pc
->emit
[1] = 0xc0000000;
856 emit_ld_common(pc
, i
);
858 NOUVEAU_ERR("emit_ld(%u): not handled yet\n", SFILE(i
, 0));
864 emit_st(struct nv_pc
*pc
, struct nv_instruction
*i
)
866 if (SFILE(i
, 0) != NV_FILE_MEM_L
)
867 NOUVEAU_ERR("emit_st(%u): file not handled yet\n", SFILE(i
, 0));
869 pc
->emit
[0] = 0x00000005 | (0 << 8); /* write-back caching */
870 pc
->emit
[1] = 0xc8000000;
872 emit_ldst_size(pc
, i
);
875 set_address_16(pc
, i
->src
[0]);
877 SID(pc
, (i
->indirect
>= 0) ? i
->src
[i
->indirect
] : NULL
, 20);
878 DID(pc
, i
->src
[1]->value
, 14);
882 nvc0_emit_instruction(struct nv_pc
*pc
, struct nv_instruction
*i
)
884 #if NV50_DEBUG & NV50_DEBUG_SHADER
885 debug_printf("EMIT: "); nvc0_print_instruction(i
);
893 if (!pc
->is_fragprog
)
971 case NV_OP_SET_F32_AND
:
972 case NV_OP_SET_F32_OR
:
973 case NV_OP_SET_F32_XOR
:
990 emit_flow(pc
, i
, 0x40);
993 emit_flow(pc
, i
, 0x50);
996 emit_flow(pc
, i
, 0x60);
999 emit_flow(pc
, i
, 0x80);
1002 emit_flow(pc
, i
, 0x90);
1005 emit_flow(pc
, i
, 0x98);
1009 pc
->emit
[0] = 0x00003de4;
1010 pc
->emit
[1] = 0x40000000;
1015 case NV_OP_SLCT_F32
:
1016 case NV_OP_SLCT_S32
:
1017 case NV_OP_SLCT_U32
:
1021 NOUVEAU_ERR("unhandled NV_OP: %d\n", i
->opcode
);
1027 pc
->emit
[0] |= 0x10;