nv50_program.c revision 7df7f7bb99441ed8e2fba2840e0459e72691f272
1f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs#include "pipe/p_context.h"
2f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs#include "pipe/p_defines.h"
3f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs#include "pipe/p_state.h"
4f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs#include "pipe/p_inlines.h"
5f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
6f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs#include "pipe/p_shader_tokens.h"
7f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs#include "tgsi/util/tgsi_parse.h"
8f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs#include "tgsi/util/tgsi_util.h"
9f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
10f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs#include "nv50_context.h"
11f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs#include "nv50_state.h"
12f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
13f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs#define NV50_SU_MAX_TEMP 64
14f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
15f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstruct nv50_reg {
16f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	enum {
17f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		P_TEMP,
18f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		P_ATTR,
19f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		P_RESULT,
20f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		P_CONST,
21f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		P_IMMD
22f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	} type;
23f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	int index;
24f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
25f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	int hw;
2638ce697e5942550888c28bd4859ca2a92f247bf7Ben Skeggs	int neg;
27f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs};
28f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
29f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstruct nv50_pc {
30f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_program *p;
31f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
32f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	/* hw resources */
33f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_reg *r_temp[NV50_SU_MAX_TEMP];
34f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
35f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	/* tgsi resources */
36f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_reg *temp;
37f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	int temp_nr;
38f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_reg *attr;
39f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	int attr_nr;
40f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_reg *result;
41f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	int result_nr;
42f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_reg *param;
43f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	int param_nr;
44f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_reg *immd;
45f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	float *immd_buf;
46f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	int immd_nr;
472a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4852a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	struct nv50_reg *temp_temp[8];
492a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	unsigned temp_temp_nr;
50f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs};
51f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
52f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstatic void
53f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsalloc_reg(struct nv50_pc *pc, struct nv50_reg *reg)
54f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
55f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	int i;
56f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
578ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	if (reg->type != P_TEMP)
58f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return;
59f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
608ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	if (reg->hw >= 0) {
618ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs		/*XXX: do this here too to catch FP temp-as-attr usage..
628ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs		 *     not clean, but works */
638ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs		if (pc->p->cfg.high_temp < (reg->hw + 1))
648ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			pc->p->cfg.high_temp = reg->hw + 1;
658ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs		return;
668ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	}
678ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs
68f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	for (i = 0; i < NV50_SU_MAX_TEMP; i++) {
69f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (!(pc->r_temp[i])) {
70f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			pc->r_temp[i] = reg;
71f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			reg->hw = i;
728ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			if (pc->p->cfg.high_temp < (i + 1))
738ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				pc->p->cfg.high_temp = i + 1;
74f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			return;
75f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
76f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
77f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
78f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	assert(0);
79f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
80f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
81f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstatic struct nv50_reg *
82f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsalloc_temp(struct nv50_pc *pc, struct nv50_reg *dst)
83f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
84f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_reg *r;
85f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	int i;
86f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
87f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (dst && dst->type == P_TEMP && dst->hw == -1)
88f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return dst;
89f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
90f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	for (i = 0; i < NV50_SU_MAX_TEMP; i++) {
91f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (!pc->r_temp[i]) {
92f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			r = CALLOC_STRUCT(nv50_reg);
93f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			r->type = P_TEMP;
94f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			r->index = -1;
95f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			r->hw = i;
96f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			pc->r_temp[i] = r;
97f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			return r;
98f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
99f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
100f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
101f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	assert(0);
102f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	return NULL;
103f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
104f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
105f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstatic void
106f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsfree_temp(struct nv50_pc *pc, struct nv50_reg *r)
107f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
108f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (r->index == -1) {
109f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		FREE(pc->r_temp[r->hw]);
110f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		pc->r_temp[r->hw] = NULL;
111f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
112f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
113f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
114f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstatic struct nv50_reg *
1152a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggstemp_temp(struct nv50_pc *pc)
1162a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
11752a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	if (pc->temp_temp_nr >= 8)
1182a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		assert(0);
1192a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
1202a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	pc->temp_temp[pc->temp_temp_nr] = alloc_temp(pc, NULL);
1212a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	return pc->temp_temp[pc->temp_temp_nr++];
1222a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
1232a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
1242a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic void
1252a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggskill_temp_temp(struct nv50_pc *pc)
1262a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
1272a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	int i;
1282a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
1292a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	for (i = 0; i < pc->temp_temp_nr; i++)
1302a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		free_temp(pc, pc->temp_temp[i]);
1312a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	pc->temp_temp_nr = 0;
1322a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
1332a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
1342a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic struct nv50_reg *
135f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggstgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst)
136f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
137f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	switch (dst->DstRegister.File) {
138f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case TGSI_FILE_TEMPORARY:
139f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return &pc->temp[dst->DstRegister.Index * 4 + c];
140f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case TGSI_FILE_OUTPUT:
141f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return &pc->result[dst->DstRegister.Index * 4 + c];
142f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case TGSI_FILE_NULL:
143f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return NULL;
144f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	default:
145f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		break;
146f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
147f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
148f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	return NULL;
149f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
150f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
151f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstatic struct nv50_reg *
152f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggstgsi_src(struct nv50_pc *pc, int c, const struct tgsi_full_src_register *src)
153f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
154f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	/* Handle swizzling */
155f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	switch (c) {
156f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case 0: c = src->SrcRegister.SwizzleX; break;
157f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case 1: c = src->SrcRegister.SwizzleY; break;
158f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case 2: c = src->SrcRegister.SwizzleZ; break;
159f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case 3: c = src->SrcRegister.SwizzleW; break;
160f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	default:
161f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		assert(0);
162f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
163f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
164f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	switch (src->SrcRegister.File) {
165f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case TGSI_FILE_INPUT:
166f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return &pc->attr[src->SrcRegister.Index * 4 + c];
167f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case TGSI_FILE_TEMPORARY:
168f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return &pc->temp[src->SrcRegister.Index * 4 + c];
169f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case TGSI_FILE_CONSTANT:
170f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return &pc->param[src->SrcRegister.Index * 4 + c];
171f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case TGSI_FILE_IMMEDIATE:
172f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return &pc->immd[src->SrcRegister.Index * 4 + c];
173f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	default:
174f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		break;
175f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
176f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
177f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	return NULL;
178f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
179f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
18055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsstatic void
18155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsemit(struct nv50_pc *pc, unsigned *inst)
18255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs{
18355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	struct nv50_program *p = pc->p;
18455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
18555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs       if (inst[0] & 1) {
18655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs               p->insns_nr += 2;
18755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs               p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr);
18855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs               memcpy(p->insns + (p->insns_nr - 2), inst, sizeof(unsigned)*2);
18955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs       } else {
19055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs               p->insns_nr += 1;
19155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs               p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr);
19255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs               memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned));
19355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs       }
19455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs}
19555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
19655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsstatic INLINE void set_long(struct nv50_pc *, unsigned *);
19755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
19855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsstatic boolean
19955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsis_long(unsigned *inst)
20055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs{
20155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	if (inst[0] & 1)
20255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		return TRUE;
20355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	return FALSE;
20455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs}
20555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
20655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsstatic boolean
20755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsis_immd(unsigned *inst)
20855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs{
20955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	if (is_long(inst) && (inst[1] & 3) == 3)
21055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		return TRUE;
21155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	return FALSE;
21255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs}
21355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
21455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsstatic INLINE void
21555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsset_pred(struct nv50_pc *pc, unsigned pred, unsigned idx, unsigned *inst)
21655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs{
21755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	set_long(pc, inst);
21855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	inst[1] &= ~((0x1f << 7) | (0x3 << 12));
21955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	inst[1] |= (pred << 7) | (idx << 12);
22055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs}
22155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
22255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsstatic INLINE void
22355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsset_pred_wr(struct nv50_pc *pc, unsigned on, unsigned idx, unsigned *inst)
22455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs{
22555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	set_long(pc, inst);
22655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	inst[1] &= ~((0x3 << 4) | (1 << 6));
22755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	inst[1] |= (idx << 4) | (on << 6);
22855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs}
22955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
23055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsstatic INLINE void
23155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsset_long(struct nv50_pc *pc, unsigned *inst)
23255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs{
23355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	if (is_long(inst))
23455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		return;
23555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
23655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	inst[0] |= 1;
23755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	set_pred(pc, 0xf, 0, inst);
23855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	set_pred_wr(pc, 0, 0, inst);
23955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs}
24055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
24155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsstatic INLINE void
24255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsset_dst(struct nv50_pc *pc, struct nv50_reg *dst, unsigned *inst)
24355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs{
24455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	if (dst->type == P_RESULT) {
24555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		set_long(pc, inst);
24655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		inst[1] |= 0x00000008;
24755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	}
24855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
24955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	alloc_reg(pc, dst);
25055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	inst[0] |= (dst->hw << 2);
25155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs}
25255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
25355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsstatic INLINE void
25455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsset_immd(struct nv50_pc *pc, struct nv50_reg *imm, unsigned *inst)
25555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs{
25655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	unsigned val = fui(pc->immd_buf[imm->hw]); /* XXX */
25755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
25855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	set_long(pc, inst);
25955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	/*XXX: can't be predicated - bits overlap.. catch cases where both
26055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	 *     are required and avoid them. */
26155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	set_pred(pc, 0, 0, inst);
26255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	set_pred_wr(pc, 0, 0, inst);
26355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
26455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	inst[1] |= 0x00000002 | 0x00000001;
26555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	inst[0] |= (val & 0x3f) << 16;
26655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	inst[1] |= (val >> 6) << 2;
26755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs}
26855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
26955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsstatic void
2708ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggsemit_interp(struct nv50_pc *pc, struct nv50_reg *dst,
2718ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	    struct nv50_reg *src, struct nv50_reg *iv, boolean noperspective)
2728ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs{
2738ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	unsigned inst[2] = { 0, 0 };
2748ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs
2758ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	inst[0] |= 0x80000000;
2768ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	set_dst(pc, dst, inst);
2778ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	alloc_reg(pc, iv);
2788ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	inst[0] |= (iv->hw << 9);
2798ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	alloc_reg(pc, src);
2808ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	inst[0] |= (src->hw << 16);
2818ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	if (noperspective)
2828ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs		inst[0] |= (1 << 25);
2838ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs
2848ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	emit(pc, inst);
2858ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs}
2868ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs
2878ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggsstatic void
2882a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsset_cseg(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst)
2892a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
2902a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_long(pc, inst);
2912a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (src->type == P_IMMD) {
2922a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		inst[1] |= (NV50_CB_PMISC << 22);
2932a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	} else {
2942a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		if (pc->p->type == NV50_PROG_VERTEX)
2952a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			inst[1] |= (NV50_CB_PVP << 22);
2962a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		else
2972a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			inst[1] |= (NV50_CB_PFP << 22);
2982a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	}
2992a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
3002a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
3012a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic void
30255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggsemit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
30355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs{
30455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	unsigned inst[2] = { 0, 0 };
30555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
30655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	inst[0] |= 0x10000000;
30755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
30855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	set_dst(pc, dst, inst);
30955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
31055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	if (dst->type != P_RESULT && src->type == P_IMMD) {
31155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		set_immd(pc, src, inst);
31255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		/*XXX: 32-bit, but steals part of "half" reg space - need to
31355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		 *     catch and handle this case if/when we do half-regs
31455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		 */
31555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		inst[0] |= 0x00008000;
31655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	} else
31755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	if (src->type == P_IMMD || src->type == P_CONST) {
31855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		set_long(pc, inst);
3192a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		set_cseg(pc, src, inst);
32055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		inst[0] |= (src->hw << 9);
32155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		inst[1] |= 0x20000000; /* src0 const? */
32255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	} else {
32355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		if (src->type == P_ATTR) {
32455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs			set_long(pc, inst);
32555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs			inst[1] |= 0x00200000;
32655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		}
32755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
32855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		alloc_reg(pc, src);
32955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		inst[0] |= (src->hw << 9);
33055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	}
33155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
33255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	/* We really should support "half" instructions here at some point,
33355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	 * but I don't feel confident enough about them yet.
33455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	 */
33555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	set_long(pc, inst);
33655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	if (is_long(inst) && !is_immd(inst)) {
33755b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		inst[1] |= 0x04000000; /* 32-bit */
33855b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs		inst[1] |= 0x0003c000; /* "subsubop" 0xf == mov */
33955b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	}
34055b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
34155b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	emit(pc, inst);
34255b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs}
34355b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs
344f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstatic boolean
3452a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggscheck_swap_src_0_1(struct nv50_pc *pc,
3462a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		   struct nv50_reg **s0, struct nv50_reg **s1)
3472a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
3482a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	struct nv50_reg *src0 = *s0, *src1 = *s1;
3492a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
3502a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (src0->type == P_CONST) {
3512a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		if (src1->type != P_CONST) {
3522a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			*s0 = src1;
3532a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			*s1 = src0;
3542a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			return TRUE;
3552a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		}
3562a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	} else
3572a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (src1->type == P_ATTR) {
3582a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		if (src0->type != P_ATTR) {
3592a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			*s0 = src1;
3602a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			*s1 = src0;
3612a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			return TRUE;
3622a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		}
3632a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	}
3642a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
3652a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	return FALSE;
3662a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
3672a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
3682a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic void
3692a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsset_src_0(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst)
3702a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
3712a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (src->type == P_ATTR) {
3722a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		set_long(pc, inst);
3732a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		inst[1] |= 0x00200000;
3742a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	} else
3752a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (src->type == P_CONST || src->type == P_IMMD) {
3762a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		struct nv50_reg *temp = temp_temp(pc);
3772a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
3782a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		emit_mov(pc, temp, src);
3792a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		src = temp;
3802a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	}
3812a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
3822a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	alloc_reg(pc, src);
3832a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	inst[0] |= (src->hw << 9);
3842a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
3852a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
3862a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic void
3872a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsset_src_1(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst)
3882a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
3892a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (src->type == P_ATTR) {
3902a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		struct nv50_reg *temp = temp_temp(pc);
3912a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
3922a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		emit_mov(pc, temp, src);
3932a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		src = temp;
3942a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	} else
3952a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (src->type == P_CONST || src->type == P_IMMD) {
3962a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		set_cseg(pc, src, inst);
3972a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		inst[0] |= 0x00800000;
3982a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	}
3992a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4002a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	alloc_reg(pc, src);
4012a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	inst[0] |= (src->hw << 16);
4022a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
4032a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4042a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic void
4052a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsset_src_2(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst)
4062a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
4072a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_long(pc, inst);
4082a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4092a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (src->type == P_ATTR) {
4102a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		struct nv50_reg *temp = temp_temp(pc);
4112a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4122a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		emit_mov(pc, temp, src);
4132a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		src = temp;
4142a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	} else
4152a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (src->type == P_CONST || src->type == P_IMMD) {
4162a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		set_cseg(pc, src, inst);
4172a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		inst[0] |= 0x01000000;
4182a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	}
4192a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4202a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	alloc_reg(pc, src);
4212a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	inst[1] |= (src->hw << 14);
4222a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
4232a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4242a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic void
4252a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsemit_mul(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
4262a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	 struct nv50_reg *src1)
4272a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
4282a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	unsigned inst[2] = { 0, 0 };
4292a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4302a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	inst[0] |= 0xc0000000;
4312a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4322a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	check_swap_src_0_1(pc, &src0, &src1);
4332a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_dst(pc, dst, inst);
4342a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_src_0(pc, src0, inst);
4352a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_src_1(pc, src1, inst);
4362a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4372a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	emit(pc, inst);
4382a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
4392a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4402a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic void
44152a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggsemit_add(struct nv50_pc *pc, struct nv50_reg *dst,
44252a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	 struct nv50_reg *src0, struct nv50_reg *src1)
4432a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
4442a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	unsigned inst[2] = { 0, 0 };
4452a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4462a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	inst[0] |= 0xb0000000;
4472a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4482a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	check_swap_src_0_1(pc, &src0, &src1);
4492a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_dst(pc, dst, inst);
4502a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_src_0(pc, src0, inst);
45152a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	if (is_long(inst))
45252a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs		set_src_2(pc, src1, inst);
45352a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	else
45452a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs		set_src_1(pc, src1, inst);
45552a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs
45652a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	emit(pc, inst);
45752a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs}
45852a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs
45952a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggsstatic void
46052a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggsemit_minmax(struct nv50_pc *pc, unsigned sub, struct nv50_reg *dst,
46152a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	    struct nv50_reg *src0, struct nv50_reg *src1)
46252a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs{
46352a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	unsigned inst[2] = { 0, 0 };
46452a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs
46552a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	set_long(pc, inst);
46652a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	inst[0] |= 0xb0000000;
46752a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	inst[1] |= (sub << 29);
46852a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs
46952a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	check_swap_src_0_1(pc, &src0, &src1);
47052a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	set_dst(pc, dst, inst);
47152a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	set_src_0(pc, src0, inst);
47252a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	set_src_1(pc, src1, inst);
4732a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4742a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	emit(pc, inst);
4752a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
4762a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4772a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic void
4782a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsemit_sub(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
4792a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	 struct nv50_reg *src1)
4802a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
4812a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	unsigned inst[2] = { 0, 0 };
4822a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4832a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	inst[0] |= 0xb0000000;
4842a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4852a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_long(pc, inst);
4862a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (check_swap_src_0_1(pc, &src0, &src1))
4872a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		inst[1] |= 0x04000000;
4882a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	else
4892a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		inst[1] |= 0x08000000;
4902a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4912a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_dst(pc, dst, inst);
4922a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_src_0(pc, src0, inst);
4932a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_src_2(pc, src1, inst);
4942a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4952a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	emit(pc, inst);
4962a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
4972a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
4982a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic void
4992a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsemit_mad(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
5002a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	 struct nv50_reg *src1, struct nv50_reg *src2)
5012a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
5022a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	unsigned inst[2] = { 0, 0 };
5032a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
5042a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	inst[0] |= 0xe0000000;
5052a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
5062a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	check_swap_src_0_1(pc, &src0, &src1);
5072a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_dst(pc, dst, inst);
5082a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_src_0(pc, src0, inst);
5092a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_src_1(pc, src1, inst);
5102a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_src_2(pc, src2, inst);
5112a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
5122a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	emit(pc, inst);
5132a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
5142a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
5152a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic void
5162a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsemit_flop(struct nv50_pc *pc, unsigned sub,
5172a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	  struct nv50_reg *dst, struct nv50_reg *src)
5182a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs{
5192a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	unsigned inst[2] = { 0, 0 };
5202a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
5212a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	inst[0] |= 0x90000000;
52252a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	if (sub) {
52352a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs		set_long(pc, inst);
52452a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs		inst[1] |= (sub << 29);
52552a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	}
5262a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
5272a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_dst(pc, dst, inst);
5282a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	set_src_0(pc, src, inst);
5292a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
5302a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	emit(pc, inst);
5312a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs}
5322a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs
5332a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggsstatic boolean
534f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsnv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
535f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
536f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	const struct tgsi_full_instruction *inst = &tok->FullInstruction;
5372a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	struct nv50_reg *dst[4], *src[3][4], *temp;
538f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	unsigned mask;
539f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	int i, c;
540f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
541f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	NOUVEAU_ERR("insn %p\n", tok);
542f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
543f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
544f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
545f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	for (c = 0; c < 4; c++) {
546f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (mask & (1 << c))
547f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			dst[c] = tgsi_dst(pc, c, &inst->FullDstRegisters[0]);
548f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		else
549f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			dst[c] = NULL;
550f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
551f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
552f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
553f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		for (c = 0; c < 4; c++)
554f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			src[i][c] = tgsi_src(pc, c, &inst->FullSrcRegisters[i]);
555f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
556f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
557f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	switch (inst->Instruction.Opcode) {
5582a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_ADD:
5597df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
5607df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
5617df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
5622a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_add(pc, dst[c], src[0][c], src[1][c]);
5637df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
5642a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
5652a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_COS:
5667df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
5677df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
5687df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
5692a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_flop(pc, 5, dst[c], src[0][c]);
5707df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
5712a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
5722a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_DP3:
5732a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		temp = alloc_temp(pc, NULL);
5742a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		emit_mul(pc, temp, src[0][0], src[1][0]);
5752a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		emit_mad(pc, temp, src[0][1], src[1][1], temp);
5762a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		emit_mad(pc, temp, src[0][2], src[1][2], temp);
5777df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
5787df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
5797df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
5802a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_mov(pc, dst[c], temp);
5817df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
5822a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		free_temp(pc, temp);
5832a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
5842a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_DP4:
5852a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		temp = alloc_temp(pc, NULL);
5862a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		emit_mul(pc, temp, src[0][0], src[1][0]);
5872a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		emit_mad(pc, temp, src[0][1], src[1][1], temp);
5882a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		emit_mad(pc, temp, src[0][2], src[1][2], temp);
5892a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		emit_mad(pc, temp, src[0][3], src[1][3], temp);
5907df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
5917df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
5927df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
5932a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_mov(pc, dst[c], temp);
5947df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
5952a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		free_temp(pc, temp);
5962a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
5972a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_EX2:
5987df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
5997df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6007df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
6012a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_flop(pc, 6, dst[c], src[0][c]);
6027df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
6032a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
6042a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_LG2:
6057df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
6067df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6077df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
6082a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_flop(pc, 3, dst[c], src[0][c]);
6097df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
6102a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
6112a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_MAD:
6127df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
6137df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6147df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
6152a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_mad(pc, dst[c], src[0][c], src[1][c], src[2][c]);
6167df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
6172a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
61852a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	case TGSI_OPCODE_MAX:
6197df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
6207df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6217df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
62252a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs			emit_minmax(pc, 4, dst[c], src[0][c], src[1][c]);
6237df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
62452a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs		break;
62552a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	case TGSI_OPCODE_MIN:
6267df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
6277df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6287df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
62952a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs			emit_minmax(pc, 5, dst[c], src[0][c], src[1][c]);
6307df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
63152a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs		break;
632f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case TGSI_OPCODE_MOV:
6337df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
6347df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6357df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
63655b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs			emit_mov(pc, dst[c], src[0][c]);
6377df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
63838ce697e5942550888c28bd4859ca2a92f247bf7Ben Skeggs		break;
6392a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_MUL:
6407df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
6417df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6427df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
6432a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_mul(pc, dst[c], src[0][c], src[1][c]);
6447df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
6452a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
6462a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_RCP:
6477df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
6487df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6497df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
6502a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_flop(pc, 0, dst[c], src[0][c]);
6517df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
6522a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
6532a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_RSQ:
6547df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
6557df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6567df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
6572a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_flop(pc, 2, dst[c], src[0][c]);
6587df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
6592a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
6602a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_SIN:
6617df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
6627df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6637df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
6642a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_flop(pc, 4, dst[c], src[0][c]);
6657df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
6662a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
6672a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	case TGSI_OPCODE_SUB:
6687df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		for (c = 0; c < 4; c++) {
6697df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs			if (!(mask & (1 << c)))
6707df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs				continue;
6712a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs			emit_sub(pc, dst[c], src[0][c], src[1][c]);
6727df7f7bb99441ed8e2fba2840e0459e72691f272Ben Skeggs		}
6732a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		break;
674f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	case TGSI_OPCODE_END:
675f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		break;
676f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	default:
677f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		NOUVEAU_ERR("invalid opcode %d\n", inst->Instruction.Opcode);
678f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return FALSE;
679f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
680f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
68152a69196c1680ff16d1ad1fc88e5869bc6055d00Ben Skeggs	kill_temp_temp(pc);
682f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	return TRUE;
683f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
684f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
685f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstatic boolean
686f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsnv50_program_tx_prep(struct nv50_pc *pc)
687f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
688f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct tgsi_parse_context p;
689f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	boolean ret = FALSE;
690f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	unsigned i, c;
691f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
692f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	tgsi_parse_init(&p, pc->p->pipe.tokens);
693f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	while (!tgsi_parse_end_of_tokens(&p)) {
694f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		const union tgsi_full_token *tok = &p.FullToken;
695f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
696f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		tgsi_parse_token(&p);
697f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		switch (tok->Token.Type) {
698f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		case TGSI_TOKEN_TYPE_IMMEDIATE:
699f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		{
700f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			const struct tgsi_full_immediate *imm =
701f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				&p.FullToken.FullImmediate;
702f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
703f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			pc->immd_nr++;
704f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			pc->immd_buf = realloc(pc->immd_buf, 4 * pc->immd_nr *
705f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs							     sizeof(float));
706f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			pc->immd_buf[4 * (pc->immd_nr - 1) + 0] =
707f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				imm->u.ImmediateFloat32[0].Float;
708f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			pc->immd_buf[4 * (pc->immd_nr - 1) + 1] =
709f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				imm->u.ImmediateFloat32[1].Float;
710f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			pc->immd_buf[4 * (pc->immd_nr - 1) + 2] =
711f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				imm->u.ImmediateFloat32[2].Float;
712f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			pc->immd_buf[4 * (pc->immd_nr - 1) + 3] =
713f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				imm->u.ImmediateFloat32[3].Float;
714f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
715f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			break;
716f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		case TGSI_TOKEN_TYPE_DECLARATION:
717f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		{
718f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			const struct tgsi_full_declaration *d;
719f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			unsigned last;
720f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
721f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			d = &p.FullToken.FullDeclaration;
722f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			last = d->u.DeclarationRange.Last;
723f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
724f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			switch (d->Declaration.File) {
725f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			case TGSI_FILE_TEMPORARY:
726f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				if (pc->temp_nr < (last + 1))
727f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs					pc->temp_nr = last + 1;
728f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				break;
729f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			case TGSI_FILE_OUTPUT:
730f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				if (pc->result_nr < (last + 1))
731f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs					pc->result_nr = last + 1;
732f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				break;
733f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			case TGSI_FILE_INPUT:
734f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				if (pc->attr_nr < (last + 1))
735f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs					pc->attr_nr = last + 1;
736f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				break;
737f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			case TGSI_FILE_CONSTANT:
738f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				if (pc->param_nr < (last + 1))
739f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs					pc->param_nr = last + 1;
740f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				break;
741f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			default:
742f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				NOUVEAU_ERR("bad decl file %d\n",
743f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs					    d->Declaration.File);
744f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				goto out_err;
745f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			}
746f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
747f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			break;
748f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		case TGSI_TOKEN_TYPE_INSTRUCTION:
749f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			break;
750f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		default:
751f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			break;
752f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
753f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
754f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
755f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	NOUVEAU_ERR("%d temps\n", pc->temp_nr);
756f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (pc->temp_nr) {
757f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		pc->temp = calloc(pc->temp_nr * 4, sizeof(struct nv50_reg));
758f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (!pc->temp)
759f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			goto out_err;
760f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
761f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		for (i = 0; i < pc->temp_nr; i++) {
762f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			for (c = 0; c < 4; c++) {
763f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->temp[i*4+c].type = P_TEMP;
764f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->temp[i*4+c].hw = -1;
765f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->temp[i*4+c].index = i;
766f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			}
767f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
768f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
769f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
770f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	NOUVEAU_ERR("%d attrib regs\n", pc->attr_nr);
771f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (pc->attr_nr) {
7728ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs		struct nv50_reg *iv = NULL, *tmp = NULL;
773f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		int aid = 0;
774f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
775f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		pc->attr = calloc(pc->attr_nr * 4, sizeof(struct nv50_reg));
776f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (!pc->attr)
777f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			goto out_err;
778f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
7798ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs		if (pc->p->type == NV50_PROG_FRAGMENT) {
7808ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			iv = alloc_temp(pc, NULL);
7818ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			aid++;
7828ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs		}
7838ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs
784f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		for (i = 0; i < pc->attr_nr; i++) {
7858ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			struct nv50_reg *a = &pc->attr[i*4];
7868ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs
787f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			for (c = 0; c < 4; c++) {
7888ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				if (pc->p->type == NV50_PROG_FRAGMENT) {
7898ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs					struct nv50_reg *at =
7908ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs						alloc_temp(pc, NULL);
7918ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs					pc->attr[i*4+c].type = at->type;
7928ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs					pc->attr[i*4+c].hw = at->hw;
7938ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs					pc->attr[i*4+c].index = at->index;
7948ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				} else {
7958ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs					pc->p->cfg.vp.attr[aid/32] |=
7968ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs						(1 << (aid % 32));
7978ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs					pc->attr[i*4+c].type = P_ATTR;
7988ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs					pc->attr[i*4+c].hw = aid++;
7998ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs					pc->attr[i*4+c].index = i;
8008ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				}
801f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			}
8028ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs
8038ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			if (pc->p->type != NV50_PROG_FRAGMENT)
8048ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				continue;
8058ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs
8068ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			emit_interp(pc, iv, iv, iv, FALSE);
8078ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			tmp = alloc_temp(pc, NULL);
8088ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			{
8098ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				unsigned inst[2] = { 0, 0 };
8108ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				inst[0]  = 0x90000000;
8118ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				inst[0] |= (tmp->hw << 2);
8128ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				emit(pc, inst);
8138ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			}
8148ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			emit_interp(pc, &a[0], &a[0], tmp, TRUE);
8158ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			emit_interp(pc, &a[1], &a[1], tmp, TRUE);
8168ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			emit_interp(pc, &a[2], &a[2], tmp, TRUE);
8178ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			emit_interp(pc, &a[3], &a[3], tmp, TRUE);
8188ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			free_temp(pc, tmp);
819f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
8208ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs
8218ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs		if (iv)
8228ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs			free_temp(pc, iv);
823f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
824f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
825f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	NOUVEAU_ERR("%d result regs\n", pc->result_nr);
826f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (pc->result_nr) {
827f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		int rid = 0;
828f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
829f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		pc->result = calloc(pc->result_nr * 4, sizeof(struct nv50_reg));
830f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (!pc->result)
831f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			goto out_err;
832f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
833f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		for (i = 0; i < pc->result_nr; i++) {
834f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			for (c = 0; c < 4; c++) {
8358ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				if (pc->p->type == NV50_PROG_FRAGMENT)
8368ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs					pc->result[i*4+c].type = P_TEMP;
8378ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs				else
8388ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs					pc->result[i*4+c].type = P_RESULT;
839f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->result[i*4+c].hw = rid++;
840f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->result[i*4+c].index = i;
841f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			}
842f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
843f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
844f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
845f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	NOUVEAU_ERR("%d param regs\n", pc->param_nr);
846f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (pc->param_nr) {
847f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		int rid = 0;
848f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
849f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		pc->param = calloc(pc->param_nr * 4, sizeof(struct nv50_reg));
850f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (!pc->param)
851f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			goto out_err;
852f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
853f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		for (i = 0; i < pc->param_nr; i++) {
854f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			for (c = 0; c < 4; c++) {
855f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->param[i*4+c].type = P_CONST;
856f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->param[i*4+c].hw = rid++;
857f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->param[i*4+c].index = i;
858f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			}
859f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
860f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
861f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
862f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (pc->immd_nr) {
863716c1cd2ecbc1e86c0fd747c9fa9e095ded5fd5dBen Skeggs		int rid = 0;
864f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
865f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		pc->immd = calloc(pc->immd_nr * 4, sizeof(struct nv50_reg));
866f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (!pc->immd)
867f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			goto out_err;
868f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
869f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		for (i = 0; i < pc->immd_nr; i++) {
870f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			for (c = 0; c < 4; c++) {
871f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->immd[i*4+c].type = P_IMMD;
872f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->immd[i*4+c].hw = rid++;
873f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				pc->immd[i*4+c].index = i;
874f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			}
875f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
876f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
877f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
878f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	ret = TRUE;
879f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsout_err:
880f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	tgsi_parse_free(&p);
881f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	return ret;
882f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
883f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
884f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstatic boolean
885f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsnv50_program_tx(struct nv50_program *p)
886f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
887f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct tgsi_parse_context parse;
888f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_pc *pc;
889f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	boolean ret;
890f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
891f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	pc = CALLOC_STRUCT(nv50_pc);
892f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (!pc)
893f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		return FALSE;
894f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	pc->p = p;
8958ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	pc->p->cfg.high_temp = 4;
896f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
897f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	ret = nv50_program_tx_prep(pc);
898f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (ret == FALSE)
899f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		goto out_cleanup;
900f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
901f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	tgsi_parse_init(&parse, pc->p->pipe.tokens);
902f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	while (!tgsi_parse_end_of_tokens(&parse)) {
903f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		const union tgsi_full_token *tok = &parse.FullToken;
904f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
905f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		tgsi_parse_token(&parse);
906f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
907f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		switch (tok->Token.Type) {
908f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		case TGSI_TOKEN_TYPE_INSTRUCTION:
909f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			ret = nv50_program_tx_insn(pc, tok);
910f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			if (ret == FALSE)
911f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs				goto out_err;
912f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			break;
913f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		default:
914f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			break;
915f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		}
916f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
917f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
918f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	p->immd_nr = pc->immd_nr * 4;
919f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	p->immd = pc->immd_buf;
920f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
921f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsout_err:
922f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	tgsi_parse_free(&parse);
923f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
924f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsout_cleanup:
925f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	return ret;
926f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
927f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
928f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsstatic void
929f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsnv50_program_validate(struct nv50_context *nv50, struct nv50_program *p)
930f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
931e55964099b0d47dea80920765daac09b9e2a61a7Ben Skeggs	int i;
932e55964099b0d47dea80920765daac09b9e2a61a7Ben Skeggs
933e55964099b0d47dea80920765daac09b9e2a61a7Ben Skeggs	if (nv50_program_tx(p) == FALSE)
934e55964099b0d47dea80920765daac09b9e2a61a7Ben Skeggs		assert(0);
935e55964099b0d47dea80920765daac09b9e2a61a7Ben Skeggs	/* *not* sufficient, it's fine if last inst is long and
936e55964099b0d47dea80920765daac09b9e2a61a7Ben Skeggs	 * NOT immd - otherwise it's fucked fucked fucked */
937e55964099b0d47dea80920765daac09b9e2a61a7Ben Skeggs	p->insns[p->insns_nr - 1] |= 0x00000001;
938f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
9392a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	if (p->type == NV50_PROG_VERTEX) {
9402a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	for (i = 0; i < p->insns_nr; i++)
9412a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		NOUVEAU_ERR("VP0x%08x\n", p->insns[i]);
9422a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	} else {
943e55964099b0d47dea80920765daac09b9e2a61a7Ben Skeggs	for (i = 0; i < p->insns_nr; i++)
9442a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs		NOUVEAU_ERR("FP0x%08x\n", p->insns[i]);
9452a1fb44d75364f2492a1ae5d232218a92b8ca807Ben Skeggs	}
946f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
947f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	p->translated = TRUE;
948f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
949f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
95022e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggsstatic void
95122e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggsnv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
95222e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs{
95322e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	int i;
95422e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs
95522e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	for (i = 0; i < p->immd_nr; i++) {
95622e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs		BEGIN_RING(tesla, 0x0f00, 2);
95722e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs		OUT_RING  ((NV50_CB_PMISC << 16) | (i << 8));
95822e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs		OUT_RING  (fui(p->immd[i]));
95922e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	}
96022e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs}
96122e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs
96222e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggsstatic void
96322e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggsnv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
96422e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs{
96522e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	struct pipe_winsys *ws = nv50->pipe.winsys;
96622e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	void *map;
96722e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs
96822e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	if (!p->buffer)
96922e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs		p->buffer = ws->buffer_create(ws, 0x100, 0, p->insns_nr * 4);
97022e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
97122e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	memcpy(map, p->insns, p->insns_nr * 4);
97222e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	ws->buffer_unmap(ws, p->buffer);
97322e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs}
97422e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs
975f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsvoid
976f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsnv50_vertprog_validate(struct nv50_context *nv50)
977f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
978f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nouveau_grobj *tesla = nv50->screen->tesla;
979f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_program *p = nv50->vertprog;
980f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nouveau_stateobj *so;
981f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
982f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (!p->translated) {
983f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		nv50_program_validate(nv50, p);
984f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (!p->translated)
985f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			assert(0);
986f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
987f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
98822e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	nv50_program_validate_data(nv50, p);
98922e0acc466947b203574c88f4964f61ef46ae3fdBen Skeggs	nv50_program_validate_code(nv50, p);
990f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
991f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so = so_new(11, 2);
992f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2);
993f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
994f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		  NOUVEAU_BO_HIGH, 0, 0);
995f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
996f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		  NOUVEAU_BO_LOW, 0, 0);
997f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_method(so, tesla, 0x1650, 2);
998f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_data  (so, p->cfg.vp.attr[0]);
999f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_data  (so, p->cfg.vp.attr[1]);
1000f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_method(so, tesla, 0x16ac, 2);
1001f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_data  (so, 8);
10028ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	so_data  (so, p->cfg.high_temp);
1003f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_method(so, tesla, 0x140c, 1);
1004f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_data  (so, 0); /* program start offset */
1005f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_emit(nv50->screen->nvws, so);
1006f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_ref(NULL, &so);
1007f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
1008f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
1009f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsvoid
1010f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsnv50_fragprog_validate(struct nv50_context *nv50)
1011f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
1012f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct pipe_winsys *ws = nv50->pipe.winsys;
1013f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nouveau_grobj *tesla = nv50->screen->tesla;
1014f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nv50_program *p = nv50->fragprog;
1015f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct nouveau_stateobj *so;
1016f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	void *map;
1017f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
1018f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (!p->translated) {
1019f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		nv50_program_validate(nv50, p);
1020f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (!p->translated)
1021f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			assert(0);
1022f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
1023f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
102455b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	nv50_program_validate_data(nv50, p);
102555b2fe1047b37d0d86641a252e1c745111030393Ben Skeggs	nv50_program_validate_code(nv50, p);
1026f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
10278ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	so = so_new(7, 2);
1028f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2);
1029f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
1030f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		  NOUVEAU_BO_HIGH, 0, 0);
1031f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
1032f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		  NOUVEAU_BO_LOW, 0, 0);
10338ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	so_method(so, tesla, 0x198c, 1);
10348ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	so_data  (so, p->cfg.high_temp);
10358ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	so_method(so, tesla, 0x1414, 1);
10368ec6415e9fcf876c67bc1624f3eb7dd7624b7791Ben Skeggs	so_data  (so, 0); /* program start offset */
1037f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_emit(nv50->screen->nvws, so);
1038f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	so_ref(NULL, &so);
1039f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
1040f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
1041f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsvoid
1042f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggsnv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
1043f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs{
1044f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	struct pipe_winsys *ws = nv50->pipe.winsys;
1045f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
1046f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (p->insns_nr) {
1047f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		if (p->insns)
1048f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs			FREE(p->insns);
1049f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		p->insns_nr = 0;
1050f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	}
1051f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
1052f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	if (p->buffer)
1053f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs		pipe_buffer_reference(ws, &p->buffer, NULL);
1054f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
1055f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs	p->translated = 0;
1056f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs}
1057f722fd937db2f3cacf1947d538c66528fd16eb89Ben Skeggs
1058