1 /*************************************************************************/
2 /* Copyright (C) 2009 */
4 /* This program is free software: you can redistribute it and/or modify */
5 /* it under the terms of the GNU General Public License as published by */
6 /* the Free Software Foundation, either version 3 of the License, or */
7 /* (at your option) any later version. */
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU General Public License for more details. */
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 /*************************************************************************/
18 #include "nv50_context.h"
23 #define FLAGS_CC_SHIFT 7
24 #define FLAGS_ID_SHIFT 12
25 #define FLAGS_WR_ID_SHIFT 4
26 #define FLAGS_CC_MASK (0x1f << FLAGS_CC_SHIFT)
27 #define FLAGS_ID_MASK (0x03 << FLAGS_ID_SHIFT)
28 #define FLAGS_WR_EN (1 << 6)
29 #define FLAGS_WR_ID_MASK (0x3 << FLAGS_WR_ID_SHIFT)
31 const ubyte nv50_inst_min_size_tab
[NV_OP_COUNT
] =
33 0, 0, 0, 8, 8, 4, 4, 4, 8, 4, 4, 8, 8, 8, 8, 8, /* 15 */
34 8, 8, 8, 4, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, /* 31 */
35 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, /* 47 */
36 4, 8, 8, 8, 8, 8, 0, 0
39 /* XXX: silence, you ! */
41 nv50_inst_min_size(struct nv_instruction
*i
);
44 nv50_inst_min_size(struct nv_instruction
*i
)
48 if (nv50_inst_min_size_tab
[i
->opcode
] > 4)
51 if (i
->def
[0] && i
->def
[0]->reg
.file
!= NV_FILE_GPR
)
53 if (i
->def
[0]->join
->reg
.id
> 63)
56 for (n
= 0; n
< 3; ++n
) {
59 if (i
->src
[n
]->value
->reg
.file
!= NV_FILE_GPR
&&
60 i
->src
[n
]->value
->reg
.file
!= NV_FILE_MEM_V
)
62 if (i
->src
[n
]->value
->reg
.id
> 63)
66 if (i
->flags_def
|| i
->flags_src
|| i
->src
[4])
70 if (i
->saturate
|| i
->src
[2]->mod
)
72 if (i
->src
[0]->mod
^ i
->src
[1]->mod
)
74 if ((i
->src
[0]->mod
| i
->src
[1]->mod
) & NV_MOD_ABS
)
76 if (i
->def
[0]->join
->reg
.id
< 0 ||
77 i
->def
[0]->join
->reg
.id
!= i
->src
[2]->value
->join
->reg
.id
)
81 return nv50_inst_min_size_tab
[i
->opcode
];
85 STYPE(struct nv_instruction
*nvi
, int s
)
87 return nvi
->src
[s
]->typecast
;
91 DTYPE(struct nv_instruction
*nvi
, int d
)
93 return nvi
->def
[d
]->reg
.type
;
96 static INLINE
struct nv_reg
*
97 SREG(struct nv_ref
*ref
)
99 return &ref
->value
->join
->reg
;
102 static INLINE
struct nv_reg
*
103 DREG(struct nv_value
*val
)
105 return &val
->join
->reg
;
109 SFILE(struct nv_instruction
*nvi
, int s
)
111 return nvi
->src
[s
]->value
->reg
.file
;
115 DFILE(struct nv_instruction
*nvi
, int d
)
117 return nvi
->def
[0]->reg
.file
;
121 SID(struct nv_pc
*pc
, struct nv_ref
*ref
, int pos
)
123 pc
->emit
[pos
/ 32] |= SREG(ref
)->id
<< (pos
% 32);
127 DID(struct nv_pc
*pc
, struct nv_value
*val
, int pos
)
129 pc
->emit
[pos
/ 32] |= DREG(val
)->id
<< (pos
% 32);
132 static INLINE
uint32_t
133 get_immd_u32(struct nv_ref
*ref
)
135 assert(ref
->value
->reg
.file
== NV_FILE_IMM
);
136 return ref
->value
->reg
.imm
.u32
;
140 set_immd_u32(struct nv_pc
*pc
, uint32_t u32
)
143 pc
->emit
[0] |= (u32
& 0x3f) << 16;
144 pc
->emit
[1] |= (u32
>> 6) << 2;
148 set_immd(struct nv_pc
*pc
, struct nv_ref
*ref
)
150 assert(ref
->value
->reg
.file
== NV_FILE_IMM
);
151 set_immd_u32(pc
, get_immd_u32(ref
));
155 new_fixup(struct nv_pc
*pc
, unsigned type
, uint32_t data
, uint32_t m
, int s
)
157 const unsigned size
= sizeof(struct nv_fixup
);
158 const unsigned n
= pc
->num_fixups
;
162 pc
->fixups
= REALLOC(pc
->fixups
, n
* size
, (n
+ 8) * size
);
164 pc
->fixups
[n
].offset
= pc
->bin_pos
+ (s
/ 32);
165 pc
->fixups
[n
].type
= type
;
166 pc
->fixups
[n
].data
= data
;
167 pc
->fixups
[n
].mask
= m
<< (s
% 32);
168 pc
->fixups
[n
].shift
= s
% 32;
172 assert(((data
<< (s
% 32)) & pc
->fixups
[n
].mask
) == (data
<< (s
% 32)));
176 nv_pc_alloc_immd(struct nv_pc
*pc
, struct nv_ref
*ref
)
178 uint32_t i
, val
= get_immd_u32(ref
);
180 for (i
= 0; i
< pc
->immd_count
; ++i
)
181 if (pc
->immd_buf
[i
] == val
)
184 if (i
== pc
->immd_count
) {
185 if (!(pc
->immd_count
% 8))
186 pc
->immd_buf
= REALLOC(pc
->immd_buf
,
187 pc
->immd_count
* 4, (pc
->immd_count
+ 8) * 4);
188 pc
->immd_buf
[pc
->immd_count
++] = val
;
195 set_pred(struct nv_pc
*pc
, struct nv_instruction
*i
)
197 assert(!(pc
->emit
[1] & 0x00003f80));
199 pc
->emit
[1] |= i
->cc
<< 7;
201 pc
->emit
[1] |= SREG(i
->flags_src
)->id
<< 12;
205 set_pred_wr(struct nv_pc
*pc
, struct nv_instruction
*i
)
207 assert(!(pc
->emit
[1] & 0x00000070));
210 pc
->emit
[1] |= (DREG(i
->flags_def
)->id
<< 4) | 0x40;
214 set_a16_bits(struct nv_pc
*pc
, uint id
)
216 ++id
; /* $a0 is always 0 */
217 pc
->emit
[0] |= (id
& 3) << 26;
218 pc
->emit
[1] |= id
& 4;
222 set_addr(struct nv_pc
*pc
, struct nv_instruction
*i
)
225 set_a16_bits(pc
, SREG(i
->src
[4])->id
);
229 set_dst(struct nv_pc
*pc
, struct nv_value
*value
)
231 struct nv_reg
*reg
= &value
->join
->reg
;
234 debug_printf("WARNING: unused dst, hope we can bucket it !\n");
235 pc
->emit
[0] |= 127 << 2;
240 if (reg
->file
== NV_FILE_OUT
)
243 if (reg
->file
== NV_FILE_ADDR
)
246 pc
->emit
[0] |= reg
->id
<< 2;
250 set_src_0(struct nv_pc
*pc
, struct nv_ref
*ref
)
252 struct nv_reg
*reg
= SREG(ref
);
254 if (reg
->file
== NV_FILE_MEM_S
)
255 pc
->emit
[1] |= 0x00200000;
257 if (reg
->file
== NV_FILE_MEM_P
)
258 pc
->emit
[0] |= 0x01800000;
260 if (reg
->file
!= NV_FILE_GPR
)
261 NOUVEAU_ERR("invalid src0 register file: %d\n", reg
->file
);
263 assert(reg
->id
< 128);
264 pc
->emit
[0] |= reg
->id
<< 9;
268 set_src_1(struct nv_pc
*pc
, struct nv_ref
*ref
)
270 struct nv_reg
*reg
= SREG(ref
);
272 if (reg
->file
>= NV_FILE_MEM_C(0) &&
273 reg
->file
<= NV_FILE_MEM_C(15)) {
274 assert(!(pc
->emit
[1] & 0x01800000));
276 pc
->emit
[0] |= 0x00800000;
277 pc
->emit
[1] |= (reg
->file
- NV_FILE_MEM_C(0)) << 22;
279 if (reg
->file
!= NV_FILE_GPR
)
280 NOUVEAU_ERR("invalid src1 register file: %d\n", reg
->file
);
282 assert(reg
->id
< 128);
283 pc
->emit
[0] |= reg
->id
<< 16;
287 set_src_2(struct nv_pc
*pc
, struct nv_ref
*ref
)
289 struct nv_reg
*reg
= SREG(ref
);
291 if (reg
->file
>= NV_FILE_MEM_C(0) &&
292 reg
->file
<= NV_FILE_MEM_C(15)) {
293 assert(!(pc
->emit
[1] & 0x01800000));
295 pc
->emit
[0] |= 0x01000000;
296 pc
->emit
[1] |= (reg
->file
- NV_FILE_MEM_C(0)) << 22;
298 if (reg
->file
!= NV_FILE_GPR
)
299 NOUVEAU_ERR("invalid src2 register file: %d\n", reg
->file
);
301 assert(reg
->id
< 128);
302 pc
->emit
[1] |= reg
->id
<< 14;
307 * - 1 to 3 sources in slots 0, 1, 2
311 emit_form_MAD(struct nv_pc
*pc
, struct nv_instruction
*i
)
319 set_dst(pc
, i
->def
[0]);
321 pc
->emit
[0] |= 0x01fc;
322 pc
->emit
[1] |= 0x0008;
326 set_src_0(pc
, i
->src
[0]);
329 set_src_1(pc
, i
->src
[1]);
332 set_src_2(pc
, i
->src
[2]);
337 /* like default form, but 2nd source in slot 2, no 3rd source */
339 emit_form_ADD(struct nv_pc
*pc
, struct nv_instruction
*i
)
344 set_dst(pc
, i
->def
[0]);
346 pc
->emit
[0] |= 0x01fc;
347 pc
->emit
[1] |= 0x0008;
354 set_src_0(pc
, i
->src
[0]);
357 set_src_2(pc
, i
->src
[1]);
364 emit_form_MUL(struct nv_pc
*pc
, struct nv_instruction
*i
)
366 assert(!i
->is_long
&& !(pc
->emit
[0] & 1));
369 set_dst(pc
, i
->def
[0]);
372 set_src_0(pc
, i
->src
[0]);
375 set_src_1(pc
, i
->src
[1]);
378 /* default immediate form
379 * - 1 to 3 sources where last is immediate
380 * - no address or predicate possible
383 emit_form_IMM(struct nv_pc
*pc
, struct nv_instruction
*i
, ubyte mod_mask
)
389 set_dst(pc
, i
->def
[0]);
391 assert(!i
->src
[4] && !i
->flags_src
&& !i
->flags_def
);
394 set_immd(pc
, i
->src
[2]);
395 set_src_0(pc
, i
->src
[1]);
396 set_src_1(pc
, i
->src
[0]);
399 set_immd(pc
, i
->src
[1]);
400 set_src_0(pc
, i
->src
[0]);
402 set_immd(pc
, i
->src
[0]);
408 set_ld_st_size(struct nv_pc
*pc
, ubyte type
)
412 pc
->emit
[1] |= 0x8000;
417 pc
->emit
[1] |= 0xc000;
420 pc
->emit
[1] |= 0x6000;
423 pc
->emit
[1] |= 0x4000;
426 pc
->emit
[1] |= 0x2000;
434 emit_ld(struct nv_pc
*pc
, struct nv_instruction
*i
)
436 ubyte sf
= SFILE(i
, 0);
438 if (sf
== NV_FILE_IMM
) {
439 sf
= NV_FILE_MEM_C(0);
440 nv_pc_alloc_immd(pc
, i
->src
[0]);
442 new_fixup(pc
, NV_FIXUP_PARAM_RELOC
, SREG(i
->src
[0])->id
, 0xffff, 9);
445 if (sf
== NV_FILE_MEM_S
||
446 sf
== NV_FILE_MEM_P
) {
447 pc
->emit
[0] = 0x10000001;
448 pc
->emit
[1] = 0x04200000 | (0x3c << 12);
449 if (sf
== NV_FILE_MEM_P
)
450 pc
->emit
[0] |= 0x01800000;
452 if (sf
>= NV_FILE_MEM_C(0) &&
453 sf
<= NV_FILE_MEM_C(15)) {
454 pc
->emit
[0] = 0x10000001;
455 pc
->emit
[1] = 0x24000000;
456 pc
->emit
[1] |= (sf
- NV_FILE_MEM_C(0)) << 22;
458 if (sf
>= NV_FILE_MEM_G(0) &&
459 sf
<= NV_FILE_MEM_G(15)) {
460 pc
->emit
[0] = 0xd0000001 | ((sf
- NV_FILE_MEM_G(0)) << 16);
461 pc
->emit
[1] = 0xa0000000;
463 assert(i
->src
[4] && SREG(i
->src
[4])->file
== NV_FILE_GPR
);
464 SID(pc
, i
->src
[4], 9);
466 if (sf
== NV_FILE_MEM_L
) {
467 pc
->emit
[0] = 0xd0000001;
468 pc
->emit
[1] = 0x40000000;
470 NOUVEAU_ERR("invalid ld source file\n");
474 set_ld_st_size(pc
, STYPE(i
, 0));
476 set_dst(pc
, i
->def
[0]);
481 if (sf
< NV_FILE_MEM_G(0) ||
482 sf
> NV_FILE_MEM_G(15)) {
483 SID(pc
, i
->src
[0], 9);
489 emit_st(struct nv_pc
*pc
, struct nv_instruction
*i
)
495 verify_mov(struct nv_instruction
*i
)
497 ubyte sf
= SFILE(i
, 0);
498 ubyte df
= DFILE(i
, 0);
500 if (df
== NV_FILE_GPR
)
503 if (df
!= NV_FILE_OUT
&&
504 df
!= NV_FILE_FLAGS
&&
508 if (sf
== NV_FILE_FLAGS
)
510 if (sf
== NV_FILE_ADDR
)
512 if (sf
== NV_FILE_IMM
&& df
!= NV_FILE_OUT
)
519 emit_mov(struct nv_pc
*pc
, struct nv_instruction
*i
)
521 assert(!verify_mov(i
));
523 if (SFILE(i
, 0) >= NV_FILE_MEM_S
)
526 if (SFILE(i
, 0) == NV_FILE_FLAGS
) {
527 pc
->emit
[0] = 0x00000001 | (DREG(i
->def
[0])->id
<< 2);
528 pc
->emit
[1] = 0x20000780 | (SREG(i
->src
[0])->id
<< 12);
530 if (SFILE(i
, 0) == NV_FILE_ADDR
) {
531 pc
->emit
[0] = 0x00000001 | (DREG(i
->def
[0])->id
<< 2);
532 pc
->emit
[1] = 0x40000780;
533 set_a16_bits(pc
, SREG(i
->src
[0])->id
);
535 if (DFILE(i
, 0) == NV_FILE_FLAGS
) {
536 pc
->emit
[0] = 0x000001fd;
537 pc
->emit
[1] = 0xa0000788 | (1 << 6);
538 pc
->emit
[0] |= SREG(i
->src
[0])->id
<< 9;
539 pc
->emit
[1] |= DREG(i
->def
[0])->id
<< 4;
541 if (SFILE(i
, 0) == NV_FILE_IMM
) {
542 if (i
->opcode
== NV_OP_LDA
) {
545 pc
->emit
[0] = 0x10008001;
546 pc
->emit
[1] = 0x00000003;
548 emit_form_IMM(pc
, i
, 0);
551 pc
->emit
[0] = 0x10000000;
552 pc
->emit
[0] |= DREG(i
->def
[0])->id
<< 2;
553 pc
->emit
[0] |= SREG(i
->src
[0])->id
<< 9;
556 pc
->emit
[0] |= 0x8000;
558 pc
->emit
[0] |= 0x00000001;
559 pc
->emit
[1] = 0x0403c000;
565 if (DFILE(i
, 0) == NV_FILE_OUT
)
570 emit_interp(struct nv_pc
*pc
, struct nv_instruction
*i
)
572 pc
->emit
[0] = 0x80000000;
574 assert(DFILE(i
, 0) == NV_FILE_GPR
);
575 assert(SFILE(i
, 0) == NV_FILE_MEM_V
);
577 DID(pc
, i
->def
[0], 2);
578 SID(pc
, i
->src
[0], 16);
581 pc
->emit
[0] |= 1 << 8;
583 if (i
->opcode
== NV_OP_PINTERP
) {
584 pc
->emit
[0] |= 1 << 25;
585 pc
->emit
[0] |= SREG(i
->src
[1])->id
<< 9;
589 pc
->emit
[0] |= 1 << 24;
592 pc
->emit
[1] |= 0x0780 |
593 (pc
->emit
[0] & (3 << 24)) >> (24 - 16) |
594 (pc
->emit
[0] & (1 << 8)) >> (18 - 8);
597 pc
->emit
[0] &= ~0x03000100;
602 emit_minmax(struct nv_pc
*pc
, struct nv_instruction
*i
)
604 pc
->emit
[0] = 0x30000000;
605 pc
->emit
[1] = (i
->opcode
== NV_OP_MIN
) ? (2 << 28) : 0;
607 switch (DTYPE(i
, 0)) {
609 pc
->emit
[0] |= 0x80000000;
610 pc
->emit
[1] |= 0x80000000;
613 pc
->emit
[1] |= 0x8c000000;
616 pc
->emit
[1] |= 0x84000000;
620 emit_form_MAD(pc
, i
);
622 if (i
->src
[0]->mod
& NV_MOD_ABS
) pc
->emit
[1] |= 0x00100000;
623 if (i
->src
[1]->mod
& NV_MOD_ABS
) pc
->emit
[1] |= 0x00080000;
627 emit_add_f32(struct nv_pc
*pc
, struct nv_instruction
*i
)
629 pc
->emit
[0] = 0xb0000000;
631 if (SFILE(i
, 1) == NV_FILE_IMM
) {
632 emit_form_IMM(pc
, i
, 0);
634 if (i
->src
[0]->mod
& NV_MOD_NEG
) pc
->emit
[0] |= 0x8000;
635 if (i
->src
[1]->mod
& NV_MOD_NEG
) pc
->emit
[0] |= 1 << 22;
638 emit_form_ADD(pc
, i
);
640 if (i
->src
[0]->mod
& NV_MOD_NEG
) pc
->emit
[1] |= 1 << 26;
641 if (i
->src
[1]->mod
& NV_MOD_NEG
) pc
->emit
[1] |= 1 << 27;
643 emit_form_MUL(pc
, i
);
645 if (i
->src
[0]->mod
& NV_MOD_NEG
) pc
->emit
[0] |= 0x8000;
646 if (i
->src
[1]->mod
& NV_MOD_NEG
) pc
->emit
[0] |= 1 << 22;
651 emit_add_b32(struct nv_pc
*pc
, struct nv_instruction
*i
)
653 pc
->emit
[0] = 0x20008000;
655 if (SFILE(i
, 1) == NV_FILE_IMM
) {
656 emit_form_IMM(pc
, i
, 0);
659 pc
->emit
[0] = 0x20000000;
660 pc
->emit
[1] = 0x04000000;
661 emit_form_ADD(pc
, i
);
663 emit_form_MUL(pc
, i
);
666 if (i
->src
[0]->mod
& NV_MOD_NEG
) pc
->emit
[0] |= 1 << 28;
667 if (i
->src
[1]->mod
& NV_MOD_NEG
) pc
->emit
[0] |= 1 << 22;
671 emit_add_a16(struct nv_pc
*pc
, struct nv_instruction
*i
)
673 pc
->emit
[0] = 0xd0000001 | (get_immd_u32(i
->src
[0]) << 9);
674 pc
->emit
[1] = 0x20000000;
676 pc
->emit
[0] |= (DREG(i
->def
[0])->id
+ 1) << 2;
681 set_a16_bits(pc
, SREG(i
->src
[1])->id
);
685 emit_flow(struct nv_pc
*pc
, struct nv_instruction
*i
, ubyte flow_op
)
687 pc
->emit
[0] = 0x00000003 | (flow_op
<< 28);
688 pc
->emit
[1] = 0x00000000;
693 new_fixup(pc
, NV_FIXUP_CFLOW_RELOC
, i
->target
->bin_pos
, 0x7ff800, 11);
694 pc
->emit
[0] |= (i
->target
->bin_pos
/ 4) << 11;
699 emit_add(struct nv_pc
*pc
, struct nv_instruction
*i
)
701 if (DFILE(i
, 0) == NV_FILE_ADDR
)
704 switch (DTYPE(i
, 0)) {
717 emit_bitop2(struct nv_pc
*pc
, struct nv_instruction
*i
)
719 pc
->emit
[0] = 0xd0000000;
721 if (SFILE(i
, 0) == NV_FILE_IMM
) {
722 emit_form_IMM(pc
, i
, 0);
724 if (i
->opcode
== NV_OP_OR
)
725 pc
->emit
[0] |= 0x0100;
727 if (i
->opcode
== NV_OP_XOR
)
728 pc
->emit
[0] |= 0x8000;
730 emit_form_MAD(pc
, i
);
732 pc
->emit
[1] |= 0x04000000;
734 if (i
->opcode
== NV_OP_OR
)
735 pc
->emit
[1] |= 0x4000;
737 if (i
->opcode
== NV_OP_XOR
)
738 pc
->emit
[1] |= 0x8000;
743 emit_shift(struct nv_pc
*pc
, struct nv_instruction
*i
)
745 pc
->emit
[0] = 0x30000001;
746 pc
->emit
[1] = 0xc4000000;
748 if (i
->opcode
== NV_OP_SHR
)
749 pc
->emit
[1] |= 1 << 29;
751 if (SFILE(i
, 1) == NV_FILE_IMM
) {
752 pc
->emit
[1] |= 1 << 20;
753 pc
->emit
[0] |= (get_immd_u32(i
->src
[1]) & 0x7f) << 16;
757 emit_form_MAD(pc
, i
);
759 if (STYPE(i
, 0) == NV_TYPE_S32
)
760 pc
->emit
[1] |= 1 << 27;
764 emit_flop(struct nv_pc
*pc
, struct nv_instruction
*i
)
766 struct nv_ref
*src0
= i
->src
[0];
768 pc
->emit
[0] = 0x90000000;
770 assert(SREG(src0
)->type
== NV_TYPE_F32
);
771 assert(SREG(src0
)->file
== NV_FILE_GPR
);
774 emit_form_MUL(pc
, i
);
775 assert(i
->opcode
== NV_OP_RCP
&& !src0
->mod
);
779 pc
->emit
[1] = (i
->opcode
- NV_OP_RCP
) << 29;
781 emit_form_MAD(pc
, i
);
783 if (src0
->mod
& NV_MOD_NEG
) pc
->emit
[1] |= 0x04000000;
784 if (src0
->mod
& NV_MOD_ABS
) pc
->emit
[1] |= 0x00100000;
788 emit_mad_f32(struct nv_pc
*pc
, struct nv_instruction
*i
)
790 const boolean neg_mul
= (i
->src
[0]->mod
^ i
->src
[1]->mod
) & NV_MOD_NEG
;
791 const boolean neg_add
= (i
->src
[2]->mod
& NV_MOD_NEG
);
793 pc
->emit
[0] = 0xe0000000;
796 emit_form_MUL(pc
, i
);
797 assert(!neg_mul
&& !neg_add
);
801 emit_form_MAD(pc
, i
);
803 if (neg_mul
) pc
->emit
[1] |= 0x04000000;
804 if (neg_add
) pc
->emit
[1] |= 0x08000000;
807 pc
->emit
[1] |= 0x20000000;
811 emit_mad(struct nv_pc
*pc
, struct nv_instruction
*i
)
817 emit_mul_f32(struct nv_pc
*pc
, struct nv_instruction
*i
)
819 boolean neg
= (i
->src
[0]->mod
^ i
->src
[1]->mod
) & NV_MOD_NEG
;
821 pc
->emit
[0] = 0xc0000000;
823 if (SFILE(i
, 1) == NV_FILE_IMM
) {
824 emit_form_IMM(pc
, i
, 0);
827 pc
->emit
[0] |= 0x8000;
830 emit_form_MAD(pc
, i
);
833 pc
->emit
[1] |= 0x08 << 24;
835 emit_form_MUL(pc
, i
);
838 pc
->emit
[0] |= 0x8000;
843 emit_set(struct nv_pc
*pc
, struct nv_instruction
*nvi
)
845 assert(nvi
->is_long
);
847 pc
->emit
[0] = 0x30000000;
848 pc
->emit
[1] = 0x60000000;
850 pc
->emit
[1] |= nvi
->set_cond
<< 14;
852 switch (STYPE(nvi
, 0)) {
853 case NV_TYPE_U32
: pc
->emit
[1] |= 0x04000000; break;
854 case NV_TYPE_S32
: pc
->emit
[1] |= 0x0c000000; break;
855 case NV_TYPE_F32
: pc
->emit
[0] |= 0x80000000; break;
861 emit_form_MAD(pc
, nvi
);
864 #define CVT_RN (0x00 << 16)
865 #define CVT_FLOOR (0x02 << 16)
866 #define CVT_CEIL (0x04 << 16)
867 #define CVT_TRUNC (0x06 << 16)
868 #define CVT_SAT (0x08 << 16)
869 #define CVT_ABS (0x10 << 16)
871 #define CVT_X32_X32 0x04004000
872 #define CVT_X32_S32 0x04014000
873 #define CVT_F32_F32 ((0xc0 << 24) | CVT_X32_X32)
874 #define CVT_S32_F32 ((0x88 << 24) | CVT_X32_X32)
875 #define CVT_U32_F32 ((0x80 << 24) | CVT_X32_X32)
876 #define CVT_F32_S32 ((0x40 << 24) | CVT_X32_S32)
877 #define CVT_F32_U32 ((0x40 << 24) | CVT_X32_X32)
878 #define CVT_S32_S32 ((0x08 << 24) | CVT_X32_S32)
879 #define CVT_S32_U32 ((0x08 << 24) | CVT_X32_X32)
880 #define CVT_U32_S32 ((0x00 << 24) | CVT_X32_S32)
881 #define CVT_U32_U32 ((0x00 << 24) | CVT_X32_X32)
883 #define CVT_NEG 0x20000000
884 #define CVT_RI 0x08000000
887 emit_cvt(struct nv_pc
*pc
, struct nv_instruction
*nvi
)
889 ubyte dst_type
= nvi
->def
[0] ? DTYPE(nvi
, 0) : STYPE(nvi
, 0);
891 pc
->emit
[0] = 0xa0000000;
895 switch (STYPE(nvi
, 0)) {
896 case NV_TYPE_F32
: pc
->emit
[1] = CVT_F32_F32
; break;
897 case NV_TYPE_S32
: pc
->emit
[1] = CVT_F32_S32
; break;
898 case NV_TYPE_U32
: pc
->emit
[1] = CVT_F32_U32
; break;
902 switch (STYPE(nvi
, 0)) {
903 case NV_TYPE_F32
: pc
->emit
[1] = CVT_S32_F32
; break;
904 case NV_TYPE_S32
: pc
->emit
[1] = CVT_S32_S32
; break;
905 case NV_TYPE_U32
: pc
->emit
[1] = CVT_S32_U32
; break;
909 switch (STYPE(nvi
, 0)) {
910 case NV_TYPE_F32
: pc
->emit
[1] = CVT_U32_F32
; break;
911 case NV_TYPE_S32
: pc
->emit
[1] = CVT_U32_S32
; break;
912 case NV_TYPE_U32
: pc
->emit
[1] = CVT_U32_U32
; break;
916 if (pc
->emit
[1] == CVT_F32_F32
&&
917 (nvi
->opcode
== NV_OP_CEIL
|| nvi
->opcode
== NV_OP_FLOOR
||
918 nvi
->opcode
== NV_OP_TRUNC
))
919 pc
->emit
[1] |= CVT_RI
;
921 switch (nvi
->opcode
) {
922 case NV_OP_CEIL
: pc
->emit
[1] |= CVT_CEIL
; break;
923 case NV_OP_FLOOR
: pc
->emit
[1] |= CVT_FLOOR
; break;
924 case NV_OP_TRUNC
: pc
->emit
[1] |= CVT_TRUNC
; break;
926 case NV_OP_ABS
: pc
->emit
[1] |= CVT_ABS
; break;
927 case NV_OP_SAT
: pc
->emit
[1] |= CVT_SAT
; break;
928 case NV_OP_NEG
: pc
->emit
[1] |= CVT_NEG
; break;
930 assert(nvi
->opcode
== NV_OP_CVT
);
933 assert(nvi
->opcode
!= NV_OP_ABS
|| !(nvi
->src
[0]->mod
& NV_MOD_NEG
));
935 if (nvi
->src
[0]->mod
& NV_MOD_NEG
) pc
->emit
[1] ^= CVT_NEG
;
936 if (nvi
->src
[0]->mod
& NV_MOD_ABS
) pc
->emit
[1] |= CVT_ABS
;
938 emit_form_MAD(pc
, nvi
);
942 emit_tex(struct nv_pc
*pc
, struct nv_instruction
*i
)
944 pc
->emit
[0] = 0xf0000001;
945 pc
->emit
[1] = 0x00000000;
947 DID(pc
, i
->def
[0], 2);
951 pc
->emit
[0] |= i
->tex_t
<< 9;
952 pc
->emit
[0] |= i
->tex_s
<< 17;
954 pc
->emit
[0] |= i
->tex_argc
<< 22;
956 pc
->emit
[0] |= (i
->tex_mask
& 0x3) << 25;
957 pc
->emit
[1] |= (i
->tex_mask
& 0xc) << 12;
963 pc
->emit
[0] |= 0x08000000;
965 if (i
->opcode
== NV_OP_TXB
)
966 pc
->emit
[1] |= 0x20000000;
968 if (i
->opcode
== NV_OP_TXL
)
969 pc
->emit
[1] |= 0x40000000;
971 pc
->emit
[0] -= 1 << 22;
975 emit_cvt2fixed(struct nv_pc
*pc
, struct nv_instruction
*i
)
977 ubyte mod
= i
->src
[0]->mod
;
979 pc
->emit
[0] = 0xb0000000;
980 pc
->emit
[1] = 0xc0000000;
982 if (i
->opcode
== NV_OP_PREEX2
)
983 pc
->emit
[1] |= 0x4000;
985 emit_form_MAD(pc
, i
);
987 if (mod
& NV_MOD_NEG
) pc
->emit
[1] |= 0x04000000;
988 if (mod
& NV_MOD_ABS
) pc
->emit
[1] |= 0x00100000;
992 emit_ddx(struct nv_pc
*pc
, struct nv_instruction
*i
)
994 assert(i
->is_long
&& SFILE(i
, 0) == NV_FILE_GPR
);
996 pc
->emit
[0] = (i
->src
[0]->mod
& NV_MOD_NEG
) ? 0xc0240001 : 0xc0140001;
997 pc
->emit
[1] = (i
->src
[0]->mod
& NV_MOD_NEG
) ? 0x86400000 : 0x89800000;
999 DID(pc
, i
->def
[0], 2);
1000 SID(pc
, i
->src
[0], 9);
1001 SID(pc
, i
->src
[0], 32 + 14);
1008 emit_ddy(struct nv_pc
*pc
, struct nv_instruction
*i
)
1010 assert(i
->is_long
&& SFILE(i
, 0) == NV_FILE_GPR
);
1012 pc
->emit
[0] = (i
->src
[0]->mod
& NV_MOD_NEG
) ? 0xc0250001 : 0xc0150001;
1013 pc
->emit
[1] = (i
->src
[0]->mod
& NV_MOD_NEG
) ? 0x85800000 : 0x8a400000;
1015 DID(pc
, i
->def
[0], 2);
1016 SID(pc
, i
->src
[0], 9);
1017 SID(pc
, i
->src
[0], 32 + 14);
1024 nv50_emit_instruction(struct nv_pc
*pc
, struct nv_instruction
*i
)
1026 // nv_print_instruction(i);
1028 switch (i
->opcode
) {
1030 if (DFILE(i
, 0) == NV_FILE_ADDR
)
1031 emit_add_a16(pc
, i
);
1078 emit_cvt2fixed(pc
, i
);
1088 emit_mul_f32(pc
, i
);
1103 emit_flow(pc
, i
, 0x0);
1106 emit_flow(pc
, i
, 0x1);
1109 emit_flow(pc
, i
, 0x2);
1112 emit_flow(pc
, i
, 0x3);
1114 case NV_OP_BREAKADDR
:
1115 emit_flow(pc
, i
, 0x4);
1118 emit_flow(pc
, i
, 0x5);
1121 emit_flow(pc
, i
, 0xa);
1124 pc
->emit
[0] = 0xf0000001;
1125 pc
->emit
[1] = 0xe0000000;
1129 NOUVEAU_ERR("operation \"%s\" should have been eliminated\n",
1130 nv_opcode_name(i
->opcode
));
1133 NOUVEAU_ERR("unhandled NV_OP: %d\n", i
->opcode
);
1138 assert((pc
->emit
[0] & 1) == i
->is_long
);