nv50_program.c revision 34a039ae7b158cacb5b20d91067e9d6458d30a56
1#include "pipe/p_context.h"
2#include "pipe/p_defines.h"
3#include "pipe/p_state.h"
4#include "pipe/p_inlines.h"
5
6#include "pipe/p_shader_tokens.h"
7#include "tgsi/util/tgsi_parse.h"
8#include "tgsi/util/tgsi_util.h"
9
10#include "nv50_context.h"
11#include "nv50_state.h"
12
13#define NV50_SU_MAX_TEMP 64
14
15/* ARL - gallium craps itself on progs/vp/arl.txt
16 *
17 * MSB - Like MAD, but MUL+SUB
18 * 	- Fuck it off, introduce a way to negate args for ops that
19 * 	  support it.
20 *
21 * Look into inlining IMMD for ops other than MOV (make it general?)
22 * 	- Maybe even relax restrictions a bit, can't do P_RESULT + P_IMMD,
23 * 	  but can emit to P_TEMP first - then MOV later. NVIDIA does this
24 *
25 * Verify half-insns work where expected - and force disable them where they
26 * don't work - MUL has it forcibly disabled atm as it fixes POW..
27 *
28 * FUCK! watch dst==src vectors, can overwrite components that are needed.
29 * 	ie. SUB R0, R0.yzxw, R0
30 */
31struct nv50_reg {
32	enum {
33		P_TEMP,
34		P_ATTR,
35		P_RESULT,
36		P_CONST,
37		P_IMMD
38	} type;
39	int index;
40
41	int hw;
42	int neg;
43};
44
45struct nv50_pc {
46	struct nv50_program *p;
47
48	/* hw resources */
49	struct nv50_reg *r_temp[NV50_SU_MAX_TEMP];
50
51	/* tgsi resources */
52	struct nv50_reg *temp;
53	int temp_nr;
54	struct nv50_reg *attr;
55	int attr_nr;
56	struct nv50_reg *result;
57	int result_nr;
58	struct nv50_reg *param;
59	int param_nr;
60	struct nv50_reg *immd;
61	float *immd_buf;
62	int immd_nr;
63
64	struct nv50_reg *temp_temp[8];
65	unsigned temp_temp_nr;
66};
67
68static void
69alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg)
70{
71	int i;
72
73	if (reg->type != P_TEMP)
74		return;
75
76	if (reg->hw >= 0) {
77		/*XXX: do this here too to catch FP temp-as-attr usage..
78		 *     not clean, but works */
79		if (pc->p->cfg.high_temp < (reg->hw + 1))
80			pc->p->cfg.high_temp = reg->hw + 1;
81		return;
82	}
83
84	for (i = 0; i < NV50_SU_MAX_TEMP; i++) {
85		if (!(pc->r_temp[i])) {
86			pc->r_temp[i] = reg;
87			reg->hw = i;
88			if (pc->p->cfg.high_temp < (i + 1))
89				pc->p->cfg.high_temp = i + 1;
90			return;
91		}
92	}
93
94	assert(0);
95}
96
97static struct nv50_reg *
98alloc_temp(struct nv50_pc *pc, struct nv50_reg *dst)
99{
100	struct nv50_reg *r;
101	int i;
102
103	if (dst && dst->type == P_TEMP && dst->hw == -1)
104		return dst;
105
106	for (i = 0; i < NV50_SU_MAX_TEMP; i++) {
107		if (!pc->r_temp[i]) {
108			r = CALLOC_STRUCT(nv50_reg);
109			r->type = P_TEMP;
110			r->index = -1;
111			r->hw = i;
112			pc->r_temp[i] = r;
113			return r;
114		}
115	}
116
117	assert(0);
118	return NULL;
119}
120
121static void
122free_temp(struct nv50_pc *pc, struct nv50_reg *r)
123{
124	if (r->index == -1) {
125		FREE(pc->r_temp[r->hw]);
126		pc->r_temp[r->hw] = NULL;
127	}
128}
129
130static struct nv50_reg *
131temp_temp(struct nv50_pc *pc)
132{
133	if (pc->temp_temp_nr >= 8)
134		assert(0);
135
136	pc->temp_temp[pc->temp_temp_nr] = alloc_temp(pc, NULL);
137	return pc->temp_temp[pc->temp_temp_nr++];
138}
139
140static void
141kill_temp_temp(struct nv50_pc *pc)
142{
143	int i;
144
145	for (i = 0; i < pc->temp_temp_nr; i++)
146		free_temp(pc, pc->temp_temp[i]);
147	pc->temp_temp_nr = 0;
148}
149
150static int
151ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w)
152{
153	pc->immd_buf = realloc(pc->immd_buf, (pc->immd_nr + 1) * 4 *
154					     sizeof(float));
155	pc->immd_buf[(pc->immd_nr * 4) + 0] = x;
156	pc->immd_buf[(pc->immd_nr * 4) + 1] = y;
157	pc->immd_buf[(pc->immd_nr * 4) + 2] = z;
158	pc->immd_buf[(pc->immd_nr * 4) + 3] = w;
159
160	return pc->immd_nr++;
161}
162
163static struct nv50_reg *
164alloc_immd(struct nv50_pc *pc, float f)
165{
166	struct nv50_reg *r = CALLOC_STRUCT(nv50_reg);
167	unsigned hw;
168
169	hw = ctor_immd(pc, f, 0, 0, 0) * 4;
170	r->type = P_IMMD;
171	r->hw = hw;
172	r->index = -1;
173	return r;
174}
175
176static void
177emit(struct nv50_pc *pc, unsigned *inst)
178{
179	struct nv50_program *p = pc->p;
180
181	if (inst[0] & 1) {
182		p->insns_nr += 2;
183		p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr);
184		memcpy(p->insns + (p->insns_nr - 2), inst, sizeof(unsigned)*2);
185	} else {
186		p->insns_nr += 1;
187		p->insns = realloc(p->insns, sizeof(unsigned) * p->insns_nr);
188		memcpy(p->insns + (p->insns_nr - 1), inst, sizeof(unsigned));
189	}
190}
191
192static INLINE void set_long(struct nv50_pc *, unsigned *);
193
194static boolean
195is_long(unsigned *inst)
196{
197	if (inst[0] & 1)
198		return TRUE;
199	return FALSE;
200}
201
202static boolean
203is_immd(unsigned *inst)
204{
205	if (is_long(inst) && (inst[1] & 3) == 3)
206		return TRUE;
207	return FALSE;
208}
209
210static INLINE void
211set_pred(struct nv50_pc *pc, unsigned pred, unsigned idx, unsigned *inst)
212{
213	set_long(pc, inst);
214	inst[1] &= ~((0x1f << 7) | (0x3 << 12));
215	inst[1] |= (pred << 7) | (idx << 12);
216}
217
218static INLINE void
219set_pred_wr(struct nv50_pc *pc, unsigned on, unsigned idx, unsigned *inst)
220{
221	set_long(pc, inst);
222	inst[1] &= ~((0x3 << 4) | (1 << 6));
223	inst[1] |= (idx << 4) | (on << 6);
224}
225
226static INLINE void
227set_long(struct nv50_pc *pc, unsigned *inst)
228{
229	if (is_long(inst))
230		return;
231
232	inst[0] |= 1;
233	set_pred(pc, 0xf, 0, inst);
234	set_pred_wr(pc, 0, 0, inst);
235}
236
237static INLINE void
238set_dst(struct nv50_pc *pc, struct nv50_reg *dst, unsigned *inst)
239{
240	if (dst->type == P_RESULT) {
241		set_long(pc, inst);
242		inst[1] |= 0x00000008;
243	}
244
245	alloc_reg(pc, dst);
246	inst[0] |= (dst->hw << 2);
247}
248
249static INLINE void
250set_immd(struct nv50_pc *pc, struct nv50_reg *imm, unsigned *inst)
251{
252	unsigned val = fui(pc->immd_buf[imm->hw]); /* XXX */
253
254	set_long(pc, inst);
255	/*XXX: can't be predicated - bits overlap.. catch cases where both
256	 *     are required and avoid them. */
257	set_pred(pc, 0, 0, inst);
258	set_pred_wr(pc, 0, 0, inst);
259
260	inst[1] |= 0x00000002 | 0x00000001;
261	inst[0] |= (val & 0x3f) << 16;
262	inst[1] |= (val >> 6) << 2;
263}
264
265static void
266emit_interp(struct nv50_pc *pc, struct nv50_reg *dst,
267	    struct nv50_reg *src, struct nv50_reg *iv, boolean noperspective)
268{
269	unsigned inst[2] = { 0, 0 };
270
271	inst[0] |= 0x80000000;
272	set_dst(pc, dst, inst);
273	alloc_reg(pc, iv);
274	inst[0] |= (iv->hw << 9);
275	alloc_reg(pc, src);
276	inst[0] |= (src->hw << 16);
277	if (noperspective)
278		inst[0] |= (1 << 25);
279
280	emit(pc, inst);
281}
282
283static void
284set_cseg(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst)
285{
286	set_long(pc, inst);
287	if (src->type == P_IMMD) {
288		inst[1] |= (NV50_CB_PMISC << 22);
289	} else {
290		if (pc->p->type == NV50_PROG_VERTEX)
291			inst[1] |= (NV50_CB_PVP << 22);
292		else
293			inst[1] |= (NV50_CB_PFP << 22);
294	}
295}
296
297static void
298emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
299{
300	unsigned inst[2] = { 0, 0 };
301
302	inst[0] |= 0x10000000;
303
304	set_dst(pc, dst, inst);
305
306	if (dst->type != P_RESULT && src->type == P_IMMD) {
307		set_immd(pc, src, inst);
308		/*XXX: 32-bit, but steals part of "half" reg space - need to
309		 *     catch and handle this case if/when we do half-regs
310		 */
311		inst[0] |= 0x00008000;
312	} else
313	if (src->type == P_IMMD || src->type == P_CONST) {
314		set_long(pc, inst);
315		set_cseg(pc, src, inst);
316		inst[0] |= (src->hw << 9);
317		inst[1] |= 0x20000000; /* src0 const? */
318	} else {
319		if (src->type == P_ATTR) {
320			set_long(pc, inst);
321			inst[1] |= 0x00200000;
322		}
323
324		alloc_reg(pc, src);
325		inst[0] |= (src->hw << 9);
326	}
327
328	/* We really should support "half" instructions here at some point,
329	 * but I don't feel confident enough about them yet.
330	 */
331	set_long(pc, inst);
332	if (is_long(inst) && !is_immd(inst)) {
333		inst[1] |= 0x04000000; /* 32-bit */
334		inst[1] |= 0x0003c000; /* "subsubop" 0xf == mov */
335	}
336
337	emit(pc, inst);
338}
339
340static boolean
341check_swap_src_0_1(struct nv50_pc *pc,
342		   struct nv50_reg **s0, struct nv50_reg **s1)
343{
344	struct nv50_reg *src0 = *s0, *src1 = *s1;
345
346	if (src0->type == P_CONST) {
347		if (src1->type != P_CONST) {
348			*s0 = src1;
349			*s1 = src0;
350			return TRUE;
351		}
352	} else
353	if (src1->type == P_ATTR) {
354		if (src0->type != P_ATTR) {
355			*s0 = src1;
356			*s1 = src0;
357			return TRUE;
358		}
359	}
360
361	return FALSE;
362}
363
364static void
365set_src_0(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst)
366{
367	if (src->type == P_ATTR) {
368		set_long(pc, inst);
369		inst[1] |= 0x00200000;
370	} else
371	if (src->type == P_CONST || src->type == P_IMMD) {
372		struct nv50_reg *temp = temp_temp(pc);
373
374		emit_mov(pc, temp, src);
375		src = temp;
376	}
377
378	alloc_reg(pc, src);
379	inst[0] |= (src->hw << 9);
380}
381
382static void
383set_src_1(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst)
384{
385	if (src->type == P_ATTR) {
386		struct nv50_reg *temp = temp_temp(pc);
387
388		emit_mov(pc, temp, src);
389		src = temp;
390	} else
391	if (src->type == P_CONST || src->type == P_IMMD) {
392		assert(!(inst[0] & 0x00800000));
393		if (inst[0] & 0x01000000) {
394			struct nv50_reg *temp = temp_temp(pc);
395
396			emit_mov(pc, temp, src);
397			src = temp;
398		} else {
399			set_cseg(pc, src, inst);
400			inst[0] |= 0x00800000;
401		}
402	}
403
404	alloc_reg(pc, src);
405	inst[0] |= (src->hw << 16);
406}
407
408static void
409set_src_2(struct nv50_pc *pc, struct nv50_reg *src, unsigned *inst)
410{
411	set_long(pc, inst);
412
413	if (src->type == P_ATTR) {
414		struct nv50_reg *temp = temp_temp(pc);
415
416		emit_mov(pc, temp, src);
417		src = temp;
418	} else
419	if (src->type == P_CONST || src->type == P_IMMD) {
420		assert(!(inst[0] & 0x01000000));
421		if (inst[0] & 0x00800000) {
422			struct nv50_reg *temp = temp_temp(pc);
423
424			emit_mov(pc, temp, src);
425			src = temp;
426		} else {
427			set_cseg(pc, src, inst);
428			inst[0] |= 0x01000000;
429		}
430	}
431
432	alloc_reg(pc, src);
433	inst[1] |= (src->hw << 14);
434}
435
436static void
437emit_mul(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
438	 struct nv50_reg *src1)
439{
440	unsigned inst[2] = { 0, 0 };
441
442	inst[0] |= 0xc0000000;
443	set_long(pc, inst);
444
445	check_swap_src_0_1(pc, &src0, &src1);
446	set_dst(pc, dst, inst);
447	set_src_0(pc, src0, inst);
448	set_src_1(pc, src1, inst);
449
450	emit(pc, inst);
451}
452
453static void
454emit_add(struct nv50_pc *pc, struct nv50_reg *dst,
455	 struct nv50_reg *src0, struct nv50_reg *src1)
456{
457	unsigned inst[2] = { 0, 0 };
458
459	inst[0] |= 0xb0000000;
460
461	check_swap_src_0_1(pc, &src0, &src1);
462	set_dst(pc, dst, inst);
463	set_src_0(pc, src0, inst);
464	if (is_long(inst))
465		set_src_2(pc, src1, inst);
466	else
467		set_src_1(pc, src1, inst);
468
469	emit(pc, inst);
470}
471
472static void
473emit_minmax(struct nv50_pc *pc, unsigned sub, struct nv50_reg *dst,
474	    struct nv50_reg *src0, struct nv50_reg *src1)
475{
476	unsigned inst[2] = { 0, 0 };
477
478	set_long(pc, inst);
479	inst[0] |= 0xb0000000;
480	inst[1] |= (sub << 29);
481
482	check_swap_src_0_1(pc, &src0, &src1);
483	set_dst(pc, dst, inst);
484	set_src_0(pc, src0, inst);
485	set_src_1(pc, src1, inst);
486
487	emit(pc, inst);
488}
489
490static void
491emit_sub(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
492	 struct nv50_reg *src1)
493{
494	unsigned inst[2] = { 0, 0 };
495
496	inst[0] |= 0xb0000000;
497
498	set_long(pc, inst);
499	if (check_swap_src_0_1(pc, &src0, &src1))
500		inst[1] |= 0x04000000;
501	else
502		inst[1] |= 0x08000000;
503
504	set_dst(pc, dst, inst);
505	set_src_0(pc, src0, inst);
506	set_src_2(pc, src1, inst);
507
508	emit(pc, inst);
509}
510
511static void
512emit_mad(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
513	 struct nv50_reg *src1, struct nv50_reg *src2)
514{
515	unsigned inst[2] = { 0, 0 };
516
517	inst[0] |= 0xe0000000;
518
519	check_swap_src_0_1(pc, &src0, &src1);
520	set_dst(pc, dst, inst);
521	set_src_0(pc, src0, inst);
522	set_src_1(pc, src1, inst);
523	set_src_2(pc, src2, inst);
524
525	emit(pc, inst);
526}
527
528static void
529emit_msb(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
530	 struct nv50_reg *src1, struct nv50_reg *src2)
531{
532	unsigned inst[2] = { 0, 0 };
533
534	inst[0] |= 0xe0000000;
535	set_long(pc, inst);
536	inst[1] |= 0x08000000; /* src0 * src1 - src2 */
537
538	check_swap_src_0_1(pc, &src0, &src1);
539	set_dst(pc, dst, inst);
540	set_src_0(pc, src0, inst);
541	set_src_1(pc, src1, inst);
542	set_src_2(pc, src2, inst);
543
544	emit(pc, inst);
545}
546
547static void
548emit_flop(struct nv50_pc *pc, unsigned sub,
549	  struct nv50_reg *dst, struct nv50_reg *src)
550{
551	unsigned inst[2] = { 0, 0 };
552
553	inst[0] |= 0x90000000;
554	if (sub) {
555		set_long(pc, inst);
556		inst[1] |= (sub << 29);
557	}
558
559	set_dst(pc, dst, inst);
560	set_src_0(pc, src, inst);
561
562	emit(pc, inst);
563}
564
565static void
566emit_preex2(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
567{
568	unsigned inst[2] = { 0, 0 };
569
570	inst[0] |= 0xb0000000;
571
572	set_dst(pc, dst, inst);
573	set_src_0(pc, src, inst);
574	set_long(pc, inst);
575	inst[1] |= (6 << 29) | 0x00004000;
576
577	emit(pc, inst);
578}
579
580/*XXX: inaccurate results.. why? */
581#define ALLOW_SET_SWAP 0
582
583static void
584emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst,
585	 struct nv50_reg *src0, struct nv50_reg *src1)
586{
587	unsigned inst[2] = { 0, 0 };
588#if ALLOW_SET_SWAP
589	unsigned inv_cop[8] = { 0, 6, 2, 4, 3, 5, 1, 7 };
590#endif
591	struct nv50_reg *rdst;
592
593#if ALLOW_SET_SWAP
594	assert(c_op <= 7);
595	if (check_swap_src_0_1(pc, &src0, &src1))
596		c_op = inv_cop[c_op];
597#endif
598
599	rdst = dst;
600	if (dst->type != P_TEMP)
601		dst = alloc_temp(pc, NULL);
602
603	/* set.u32 */
604	set_long(pc, inst);
605	inst[0] |= 0xb0000000;
606	inst[1] |= (3 << 29);
607	inst[1] |= (c_op << 14);
608	/*XXX: breaks things, .u32 by default?
609	 *     decuda will disasm as .u16 and use .lo/.hi regs, but this
610	 *     doesn't seem to match what the hw actually does.
611	inst[1] |= 0x04000000; << breaks things.. .u32 by default?
612	 */
613	set_dst(pc, dst, inst);
614	set_src_0(pc, src0, inst);
615	set_src_1(pc, src1, inst);
616	emit(pc, inst);
617
618	/* cvt.f32.u32 */
619	inst[0] = 0xa0000001;
620	inst[1] = 0x64014780;
621	set_dst(pc, rdst, inst);
622	set_src_0(pc, dst, inst);
623	emit(pc, inst);
624
625	if (dst != rdst)
626		free_temp(pc, dst);
627}
628
629static void
630emit_flr(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
631{
632	unsigned inst[2] = { 0, 0 };
633
634	inst[0] = 0xa0000000; /* cvt */
635	set_long(pc, inst);
636	inst[1] |= (6 << 29); /* cvt */
637	inst[1] |= 0x08000000; /* integer mode */
638	inst[1] |= 0x04000000; /* 32 bit */
639	inst[1] |= ((0x1 << 3)) << 14; /* .rn */
640	inst[1] |= (1 << 14); /* src .f32 */
641	set_dst(pc, dst, inst);
642	set_src_0(pc, src, inst);
643
644	emit(pc, inst);
645}
646
647static void
648emit_pow(struct nv50_pc *pc, struct nv50_reg *dst,
649	 struct nv50_reg *v, struct nv50_reg *e)
650{
651	struct nv50_reg *temp = alloc_temp(pc, NULL);
652
653	emit_flop(pc, 3, temp, v);
654	emit_mul(pc, temp, temp, e);
655	emit_preex2(pc, temp, temp);
656	emit_flop(pc, 6, dst, temp);
657
658	free_temp(pc, temp);
659}
660
661static void
662emit_abs(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
663{
664	unsigned inst[2] = { 0, 0 };
665
666	inst[0] = 0xa0000000; /* cvt */
667	set_long(pc, inst);
668	inst[1] |= (6 << 29); /* cvt */
669	inst[1] |= 0x04000000; /* 32 bit */
670	inst[1] |= (1 << 14); /* src .f32 */
671	inst[1] |= ((1 << 6) << 14); /* .abs */
672	set_dst(pc, dst, inst);
673	set_src_0(pc, src, inst);
674
675	emit(pc, inst);
676}
677
678static void
679emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, struct nv50_reg **src)
680{
681	struct nv50_reg *one = alloc_immd(pc, 1.0);
682	struct nv50_reg *zero = alloc_immd(pc, 0.0);
683	struct nv50_reg *neg128 = alloc_immd(pc, -127.999999);
684	struct nv50_reg *pos128 = alloc_immd(pc,  127.999999);
685	struct nv50_reg *tmp[4];
686
687	emit_mov(pc, dst[0], one);
688	emit_mov(pc, dst[3], one);
689
690	tmp[0] = temp_temp(pc);
691	emit_minmax(pc, 4, dst[1], src[0], zero);
692	set_pred_wr(pc, 1, 0, &pc->p->insns[pc->p->insns_nr - 2]);
693
694	tmp[1] = temp_temp(pc);
695	emit_minmax(pc, 4, tmp[1], src[1], zero);
696
697	tmp[3] = temp_temp(pc);
698	emit_minmax(pc, 4, tmp[3], src[3], neg128);
699	emit_minmax(pc, 5, tmp[3], tmp[3], pos128);
700
701	emit_pow(pc, dst[2], tmp[1], tmp[3]);
702	emit_mov(pc, dst[2], zero);
703	set_pred(pc, 3, 0, &pc->p->insns[pc->p->insns_nr - 2]);
704}
705
706static struct nv50_reg *
707tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst)
708{
709	switch (dst->DstRegister.File) {
710	case TGSI_FILE_TEMPORARY:
711		return &pc->temp[dst->DstRegister.Index * 4 + c];
712	case TGSI_FILE_OUTPUT:
713		return &pc->result[dst->DstRegister.Index * 4 + c];
714	case TGSI_FILE_NULL:
715		return NULL;
716	default:
717		break;
718	}
719
720	return NULL;
721}
722
723static struct nv50_reg *
724tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src)
725{
726	struct nv50_reg *r = NULL;
727	struct nv50_reg *temp;
728	unsigned c;
729
730	c = tgsi_util_get_full_src_register_extswizzle(src, chan);
731	switch (c) {
732	case TGSI_EXTSWIZZLE_X:
733	case TGSI_EXTSWIZZLE_Y:
734	case TGSI_EXTSWIZZLE_Z:
735	case TGSI_EXTSWIZZLE_W:
736		switch (src->SrcRegister.File) {
737		case TGSI_FILE_INPUT:
738			r = &pc->attr[src->SrcRegister.Index * 4 + c];
739			break;
740		case TGSI_FILE_TEMPORARY:
741			r = &pc->temp[src->SrcRegister.Index * 4 + c];
742			break;
743		case TGSI_FILE_CONSTANT:
744			r = &pc->param[src->SrcRegister.Index * 4 + c];
745			break;
746		case TGSI_FILE_IMMEDIATE:
747			r = &pc->immd[src->SrcRegister.Index * 4 + c];
748			break;
749		default:
750			assert(0);
751			break;
752		}
753		break;
754	case TGSI_EXTSWIZZLE_ZERO:
755		r = alloc_immd(pc, 0.0);
756		break;
757	case TGSI_EXTSWIZZLE_ONE:
758		r = alloc_immd(pc, 1.0);
759		break;
760	default:
761		assert(0);
762		break;
763	}
764
765	switch (tgsi_util_get_full_src_register_sign_mode(src, chan)) {
766	case TGSI_UTIL_SIGN_KEEP:
767		break;
768	case TGSI_UTIL_SIGN_CLEAR:
769		temp = temp_temp(pc);
770		emit_abs(pc, temp, r);
771		r = temp;
772		break;
773	default:
774		assert(0);
775		break;
776	}
777
778	return r;
779}
780
781static boolean
782nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
783{
784	const struct tgsi_full_instruction *inst = &tok->FullInstruction;
785	struct nv50_reg *rdst[4], *dst[4], *src[3][4], *temp;
786	unsigned mask, sat;
787	int i, c;
788
789	NOUVEAU_ERR("insn %p\n", tok);
790
791	mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
792	sat = inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE;
793
794	for (c = 0; c < 4; c++) {
795		if (mask & (1 << c))
796			dst[c] = tgsi_dst(pc, c, &inst->FullDstRegisters[0]);
797		else
798			dst[c] = NULL;
799	}
800
801	for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
802		for (c = 0; c < 4; c++)
803			src[i][c] = tgsi_src(pc, c, &inst->FullSrcRegisters[i]);
804	}
805
806	if (sat) {
807		for (c = 0; c < 4; c++) {
808			rdst[c] = dst[c];
809			dst[c] = temp_temp(pc);
810		}
811	}
812
813	switch (inst->Instruction.Opcode) {
814	case TGSI_OPCODE_ABS:
815		for (c = 0; c < 4; c++) {
816			if (!(mask & (1 << c)))
817				continue;
818			emit_abs(pc, dst[c], src[0][c]);
819		}
820		break;
821	case TGSI_OPCODE_ADD:
822		for (c = 0; c < 4; c++) {
823			if (!(mask & (1 << c)))
824				continue;
825			emit_add(pc, dst[c], src[0][c], src[1][c]);
826		}
827		break;
828	case TGSI_OPCODE_COS:
829		for (c = 0; c < 4; c++) {
830			if (!(mask & (1 << c)))
831				continue;
832			emit_flop(pc, 5, dst[c], src[0][c]);
833		}
834		break;
835	case TGSI_OPCODE_DP3:
836		temp = alloc_temp(pc, NULL);
837		emit_mul(pc, temp, src[0][0], src[1][0]);
838		emit_mad(pc, temp, src[0][1], src[1][1], temp);
839		emit_mad(pc, temp, src[0][2], src[1][2], temp);
840		for (c = 0; c < 4; c++) {
841			if (!(mask & (1 << c)))
842				continue;
843			emit_mov(pc, dst[c], temp);
844		}
845		free_temp(pc, temp);
846		break;
847	case TGSI_OPCODE_DP4:
848		temp = alloc_temp(pc, NULL);
849		emit_mul(pc, temp, src[0][0], src[1][0]);
850		emit_mad(pc, temp, src[0][1], src[1][1], temp);
851		emit_mad(pc, temp, src[0][2], src[1][2], temp);
852		emit_mad(pc, temp, src[0][3], src[1][3], temp);
853		for (c = 0; c < 4; c++) {
854			if (!(mask & (1 << c)))
855				continue;
856			emit_mov(pc, dst[c], temp);
857		}
858		free_temp(pc, temp);
859		break;
860	case TGSI_OPCODE_DPH:
861		temp = alloc_temp(pc, NULL);
862		emit_mul(pc, temp, src[0][0], src[1][0]);
863		emit_mad(pc, temp, src[0][1], src[1][1], temp);
864		emit_mad(pc, temp, src[0][2], src[1][2], temp);
865		emit_add(pc, temp, src[1][3], temp);
866		for (c = 0; c < 4; c++) {
867			if (!(mask & (1 << c)))
868				continue;
869			emit_mov(pc, dst[c], temp);
870		}
871		free_temp(pc, temp);
872		break;
873	case TGSI_OPCODE_DST:
874	{
875		struct nv50_reg *one = alloc_immd(pc, 1.0);
876		if (mask & (1 << 0))
877			emit_mov(pc, dst[0], one);
878		if (mask & (1 << 1))
879			emit_mul(pc, dst[1], src[0][1], src[1][1]);
880		if (mask & (1 << 2))
881			emit_mov(pc, dst[2], src[0][2]);
882		if (mask & (1 << 3))
883			emit_mov(pc, dst[3], src[1][3]);
884		FREE(one);
885	}
886		break;
887	case TGSI_OPCODE_EX2:
888		temp = alloc_temp(pc, NULL);
889		for (c = 0; c < 4; c++) {
890			if (!(mask & (1 << c)))
891				continue;
892			emit_preex2(pc, temp, src[0][c]);
893			emit_flop(pc, 6, dst[c], temp);
894		}
895		free_temp(pc, temp);
896		break;
897	case TGSI_OPCODE_FLR:
898		for (c = 0; c < 4; c++) {
899			if (!(mask & (1 << c)))
900				continue;
901			emit_flr(pc, dst[c], src[0][c]);
902		}
903		break;
904	case TGSI_OPCODE_FRC:
905		temp = alloc_temp(pc, NULL);
906		for (c = 0; c < 4; c++) {
907			if (!(mask & (1 << c)))
908				continue;
909			emit_flr(pc, temp, src[0][c]);
910			emit_sub(pc, dst[c], src[0][c], temp);
911		}
912		free_temp(pc, temp);
913		break;
914	case TGSI_OPCODE_LIT:
915		/*XXX: writemask */
916		emit_lit(pc, &dst[0], &src[0][0]);
917		break;
918	case TGSI_OPCODE_LG2:
919		for (c = 0; c < 4; c++) {
920			if (!(mask & (1 << c)))
921				continue;
922			emit_flop(pc, 3, dst[c], src[0][c]);
923		}
924		break;
925	case TGSI_OPCODE_MAD:
926		for (c = 0; c < 4; c++) {
927			if (!(mask & (1 << c)))
928				continue;
929			emit_mad(pc, dst[c], src[0][c], src[1][c], src[2][c]);
930		}
931		break;
932	case TGSI_OPCODE_MAX:
933		for (c = 0; c < 4; c++) {
934			if (!(mask & (1 << c)))
935				continue;
936			emit_minmax(pc, 4, dst[c], src[0][c], src[1][c]);
937		}
938		break;
939	case TGSI_OPCODE_MIN:
940		for (c = 0; c < 4; c++) {
941			if (!(mask & (1 << c)))
942				continue;
943			emit_minmax(pc, 5, dst[c], src[0][c], src[1][c]);
944		}
945		break;
946	case TGSI_OPCODE_MOV:
947		for (c = 0; c < 4; c++) {
948			if (!(mask & (1 << c)))
949				continue;
950			emit_mov(pc, dst[c], src[0][c]);
951		}
952		break;
953	case TGSI_OPCODE_MUL:
954		for (c = 0; c < 4; c++) {
955			if (!(mask & (1 << c)))
956				continue;
957			emit_mul(pc, dst[c], src[0][c], src[1][c]);
958		}
959		break;
960	case TGSI_OPCODE_POW:
961		temp = alloc_temp(pc, NULL);
962		emit_pow(pc, temp, src[0][0], src[1][0]);
963		for (c = 0; c < 4; c++) {
964			if (!(mask & (1 << c)))
965				continue;
966			emit_mov(pc, dst[c], temp);
967		}
968		free_temp(pc, temp);
969		break;
970	case TGSI_OPCODE_RCP:
971		for (c = 0; c < 4; c++) {
972			if (!(mask & (1 << c)))
973				continue;
974			emit_flop(pc, 0, dst[c], src[0][c]);
975		}
976		break;
977	case TGSI_OPCODE_RSQ:
978		for (c = 0; c < 4; c++) {
979			if (!(mask & (1 << c)))
980				continue;
981			emit_flop(pc, 2, dst[c], src[0][c]);
982		}
983		break;
984	case TGSI_OPCODE_SGE:
985		for (c = 0; c < 4; c++) {
986			if (!(mask & (1 << c)))
987				continue;
988			emit_set(pc, 6, dst[c], src[0][c], src[1][c]);
989		}
990		break;
991	case TGSI_OPCODE_SIN:
992		for (c = 0; c < 4; c++) {
993			if (!(mask & (1 << c)))
994				continue;
995			emit_flop(pc, 4, dst[c], src[0][c]);
996		}
997		break;
998	case TGSI_OPCODE_SLT:
999		for (c = 0; c < 4; c++) {
1000			if (!(mask & (1 << c)))
1001				continue;
1002			emit_set(pc, 1, dst[c], src[0][c], src[1][c]);
1003		}
1004		break;
1005	case TGSI_OPCODE_SUB:
1006		for (c = 0; c < 4; c++) {
1007			if (!(mask & (1 << c)))
1008				continue;
1009			emit_sub(pc, dst[c], src[0][c], src[1][c]);
1010		}
1011		break;
1012	case TGSI_OPCODE_XPD:
1013		temp = alloc_temp(pc, NULL);
1014		if (mask & (1 << 0)) {
1015			emit_mul(pc, temp, src[0][2], src[1][1]);
1016			emit_msb(pc, dst[0], src[0][1], src[1][2], temp);
1017		}
1018		if (mask & (1 << 1)) {
1019			emit_mul(pc, temp, src[0][0], src[1][2]);
1020			emit_msb(pc, dst[1], src[0][2], src[1][0], temp);
1021		}
1022		if (mask & (1 << 2)) {
1023			emit_mul(pc, temp, src[0][1], src[1][0]);
1024			emit_msb(pc, dst[2], src[0][0], src[1][1], temp);
1025		}
1026		free_temp(pc, temp);
1027		break;
1028	case TGSI_OPCODE_END:
1029		break;
1030	default:
1031		NOUVEAU_ERR("invalid opcode %d\n", inst->Instruction.Opcode);
1032		return FALSE;
1033	}
1034
1035	if (sat) {
1036		for (c = 0; c < 4; c++) {
1037			unsigned inst[2] = { 0, 0 };
1038
1039			if (!(mask & (1 << c)))
1040				continue;
1041
1042			inst[0] = 0xa0000000; /* cvt */
1043			set_long(pc, inst);
1044			inst[1] |= (6 << 29); /* cvt */
1045			inst[1] |= 0x04000000; /* 32 bit */
1046			inst[1] |= (1 << 14); /* src .f32 */
1047			inst[1] |= ((1 << 5) << 14); /* .sat */
1048			set_dst(pc, rdst[c], inst);
1049			set_src_0(pc, dst[c], inst);
1050			emit(pc, inst);
1051		}
1052	}
1053
1054	kill_temp_temp(pc);
1055	return TRUE;
1056}
1057
1058static boolean
1059nv50_program_tx_prep(struct nv50_pc *pc)
1060{
1061	struct tgsi_parse_context p;
1062	boolean ret = FALSE;
1063	unsigned i, c;
1064
1065	tgsi_parse_init(&p, pc->p->pipe.tokens);
1066	while (!tgsi_parse_end_of_tokens(&p)) {
1067		const union tgsi_full_token *tok = &p.FullToken;
1068
1069		tgsi_parse_token(&p);
1070		switch (tok->Token.Type) {
1071		case TGSI_TOKEN_TYPE_IMMEDIATE:
1072		{
1073			const struct tgsi_full_immediate *imm =
1074				&p.FullToken.FullImmediate;
1075
1076			ctor_immd(pc, imm->u.ImmediateFloat32[0].Float,
1077				      imm->u.ImmediateFloat32[1].Float,
1078				      imm->u.ImmediateFloat32[2].Float,
1079				      imm->u.ImmediateFloat32[3].Float);
1080		}
1081			break;
1082		case TGSI_TOKEN_TYPE_DECLARATION:
1083		{
1084			const struct tgsi_full_declaration *d;
1085			unsigned last;
1086
1087			d = &p.FullToken.FullDeclaration;
1088			last = d->u.DeclarationRange.Last;
1089
1090			switch (d->Declaration.File) {
1091			case TGSI_FILE_TEMPORARY:
1092				if (pc->temp_nr < (last + 1))
1093					pc->temp_nr = last + 1;
1094				break;
1095			case TGSI_FILE_OUTPUT:
1096				if (pc->result_nr < (last + 1))
1097					pc->result_nr = last + 1;
1098				break;
1099			case TGSI_FILE_INPUT:
1100				if (pc->attr_nr < (last + 1))
1101					pc->attr_nr = last + 1;
1102				break;
1103			case TGSI_FILE_CONSTANT:
1104				if (pc->param_nr < (last + 1))
1105					pc->param_nr = last + 1;
1106				break;
1107			default:
1108				NOUVEAU_ERR("bad decl file %d\n",
1109					    d->Declaration.File);
1110				goto out_err;
1111			}
1112		}
1113			break;
1114		case TGSI_TOKEN_TYPE_INSTRUCTION:
1115			break;
1116		default:
1117			break;
1118		}
1119	}
1120
1121	NOUVEAU_ERR("%d temps\n", pc->temp_nr);
1122	if (pc->temp_nr) {
1123		pc->temp = calloc(pc->temp_nr * 4, sizeof(struct nv50_reg));
1124		if (!pc->temp)
1125			goto out_err;
1126
1127		for (i = 0; i < pc->temp_nr; i++) {
1128			for (c = 0; c < 4; c++) {
1129				pc->temp[i*4+c].type = P_TEMP;
1130				pc->temp[i*4+c].hw = -1;
1131				pc->temp[i*4+c].index = i;
1132			}
1133		}
1134	}
1135
1136	NOUVEAU_ERR("%d attrib regs\n", pc->attr_nr);
1137	if (pc->attr_nr) {
1138		struct nv50_reg *iv = NULL, *tmp = NULL;
1139		int aid = 0;
1140
1141		pc->attr = calloc(pc->attr_nr * 4, sizeof(struct nv50_reg));
1142		if (!pc->attr)
1143			goto out_err;
1144
1145		if (pc->p->type == NV50_PROG_FRAGMENT) {
1146			iv = alloc_temp(pc, NULL);
1147			aid++;
1148		}
1149
1150		for (i = 0; i < pc->attr_nr; i++) {
1151			struct nv50_reg *a = &pc->attr[i*4];
1152
1153			for (c = 0; c < 4; c++) {
1154				if (pc->p->type == NV50_PROG_FRAGMENT) {
1155					struct nv50_reg *at =
1156						alloc_temp(pc, NULL);
1157					pc->attr[i*4+c].type = at->type;
1158					pc->attr[i*4+c].hw = at->hw;
1159					pc->attr[i*4+c].index = at->index;
1160				} else {
1161					pc->p->cfg.vp.attr[aid/32] |=
1162						(1 << (aid % 32));
1163					pc->attr[i*4+c].type = P_ATTR;
1164					pc->attr[i*4+c].hw = aid++;
1165					pc->attr[i*4+c].index = i;
1166				}
1167			}
1168
1169			if (pc->p->type != NV50_PROG_FRAGMENT)
1170				continue;
1171
1172			emit_interp(pc, iv, iv, iv, FALSE);
1173			tmp = alloc_temp(pc, NULL);
1174			{
1175				unsigned inst[2] = { 0, 0 };
1176				inst[0]  = 0x90000000;
1177				inst[0] |= (tmp->hw << 2);
1178				emit(pc, inst);
1179			}
1180			emit_interp(pc, &a[0], &a[0], tmp, TRUE);
1181			emit_interp(pc, &a[1], &a[1], tmp, TRUE);
1182			emit_interp(pc, &a[2], &a[2], tmp, TRUE);
1183			emit_interp(pc, &a[3], &a[3], tmp, TRUE);
1184			free_temp(pc, tmp);
1185		}
1186
1187		if (iv)
1188			free_temp(pc, iv);
1189	}
1190
1191	NOUVEAU_ERR("%d result regs\n", pc->result_nr);
1192	if (pc->result_nr) {
1193		int rid = 0;
1194
1195		pc->result = calloc(pc->result_nr * 4, sizeof(struct nv50_reg));
1196		if (!pc->result)
1197			goto out_err;
1198
1199		for (i = 0; i < pc->result_nr; i++) {
1200			for (c = 0; c < 4; c++) {
1201				if (pc->p->type == NV50_PROG_FRAGMENT)
1202					pc->result[i*4+c].type = P_TEMP;
1203				else
1204					pc->result[i*4+c].type = P_RESULT;
1205				pc->result[i*4+c].hw = rid++;
1206				pc->result[i*4+c].index = i;
1207			}
1208		}
1209	}
1210
1211	NOUVEAU_ERR("%d param regs\n", pc->param_nr);
1212	if (pc->param_nr) {
1213		int rid = 0;
1214
1215		pc->param = calloc(pc->param_nr * 4, sizeof(struct nv50_reg));
1216		if (!pc->param)
1217			goto out_err;
1218
1219		for (i = 0; i < pc->param_nr; i++) {
1220			for (c = 0; c < 4; c++) {
1221				pc->param[i*4+c].type = P_CONST;
1222				pc->param[i*4+c].hw = rid++;
1223				pc->param[i*4+c].index = i;
1224			}
1225		}
1226	}
1227
1228	if (pc->immd_nr) {
1229		int rid = 0;
1230
1231		pc->immd = calloc(pc->immd_nr * 4, sizeof(struct nv50_reg));
1232		if (!pc->immd)
1233			goto out_err;
1234
1235		for (i = 0; i < pc->immd_nr; i++) {
1236			for (c = 0; c < 4; c++) {
1237				pc->immd[i*4+c].type = P_IMMD;
1238				pc->immd[i*4+c].hw = rid++;
1239				pc->immd[i*4+c].index = i;
1240			}
1241		}
1242	}
1243
1244	ret = TRUE;
1245out_err:
1246	tgsi_parse_free(&p);
1247	return ret;
1248}
1249
1250static boolean
1251nv50_program_tx(struct nv50_program *p)
1252{
1253	struct tgsi_parse_context parse;
1254	struct nv50_pc *pc;
1255	boolean ret;
1256
1257	pc = CALLOC_STRUCT(nv50_pc);
1258	if (!pc)
1259		return FALSE;
1260	pc->p = p;
1261	pc->p->cfg.high_temp = 4;
1262
1263	ret = nv50_program_tx_prep(pc);
1264	if (ret == FALSE)
1265		goto out_cleanup;
1266
1267	tgsi_parse_init(&parse, pc->p->pipe.tokens);
1268	while (!tgsi_parse_end_of_tokens(&parse)) {
1269		const union tgsi_full_token *tok = &parse.FullToken;
1270
1271		tgsi_parse_token(&parse);
1272
1273		switch (tok->Token.Type) {
1274		case TGSI_TOKEN_TYPE_INSTRUCTION:
1275			ret = nv50_program_tx_insn(pc, tok);
1276			if (ret == FALSE)
1277				goto out_err;
1278			break;
1279		default:
1280			break;
1281		}
1282	}
1283
1284	p->immd_nr = pc->immd_nr * 4;
1285	p->immd = pc->immd_buf;
1286
1287out_err:
1288	tgsi_parse_free(&parse);
1289
1290out_cleanup:
1291	return ret;
1292}
1293
1294static void
1295nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p)
1296{
1297	int i;
1298
1299	if (nv50_program_tx(p) == FALSE)
1300		assert(0);
1301	/* *not* sufficient, it's fine if last inst is long and
1302	 * NOT immd - otherwise it's fucked fucked fucked */
1303	p->insns[p->insns_nr - 1] |= 0x00000001;
1304
1305	if (p->type == NV50_PROG_VERTEX) {
1306	for (i = 0; i < p->insns_nr; i++)
1307		NOUVEAU_ERR("VP0x%08x\n", p->insns[i]);
1308	} else {
1309	for (i = 0; i < p->insns_nr; i++)
1310		NOUVEAU_ERR("FP0x%08x\n", p->insns[i]);
1311	}
1312
1313	p->translated = TRUE;
1314}
1315
1316static void
1317nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
1318{
1319	int i;
1320
1321	for (i = 0; i < p->immd_nr; i++) {
1322		BEGIN_RING(tesla, 0x0f00, 2);
1323		OUT_RING  ((NV50_CB_PMISC << 16) | (i << 8));
1324		OUT_RING  (fui(p->immd[i]));
1325	}
1326}
1327
1328static void
1329nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
1330{
1331	struct pipe_winsys *ws = nv50->pipe.winsys;
1332	void *map;
1333
1334	if (!p->buffer)
1335		p->buffer = ws->buffer_create(ws, 0x100, 0, p->insns_nr * 4);
1336	map = ws->buffer_map(ws, p->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
1337	memcpy(map, p->insns, p->insns_nr * 4);
1338	ws->buffer_unmap(ws, p->buffer);
1339}
1340
1341void
1342nv50_vertprog_validate(struct nv50_context *nv50)
1343{
1344	struct nouveau_grobj *tesla = nv50->screen->tesla;
1345	struct nv50_program *p = nv50->vertprog;
1346	struct nouveau_stateobj *so;
1347
1348	if (!p->translated) {
1349		nv50_program_validate(nv50, p);
1350		if (!p->translated)
1351			assert(0);
1352	}
1353
1354	nv50_program_validate_data(nv50, p);
1355	nv50_program_validate_code(nv50, p);
1356
1357	so = so_new(11, 2);
1358	so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2);
1359	so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
1360		  NOUVEAU_BO_HIGH, 0, 0);
1361	so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
1362		  NOUVEAU_BO_LOW, 0, 0);
1363	so_method(so, tesla, 0x1650, 2);
1364	so_data  (so, p->cfg.vp.attr[0]);
1365	so_data  (so, p->cfg.vp.attr[1]);
1366	so_method(so, tesla, 0x16ac, 2);
1367	so_data  (so, 8);
1368	so_data  (so, p->cfg.high_temp);
1369	so_method(so, tesla, 0x140c, 1);
1370	so_data  (so, 0); /* program start offset */
1371	so_emit(nv50->screen->nvws, so);
1372	so_ref(NULL, &so);
1373}
1374
1375void
1376nv50_fragprog_validate(struct nv50_context *nv50)
1377{
1378	struct nouveau_grobj *tesla = nv50->screen->tesla;
1379	struct nv50_program *p = nv50->fragprog;
1380	struct nouveau_stateobj *so;
1381
1382	if (!p->translated) {
1383		nv50_program_validate(nv50, p);
1384		if (!p->translated)
1385			assert(0);
1386	}
1387
1388	nv50_program_validate_data(nv50, p);
1389	nv50_program_validate_code(nv50, p);
1390
1391	so = so_new(7, 2);
1392	so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2);
1393	so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
1394		  NOUVEAU_BO_HIGH, 0, 0);
1395	so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
1396		  NOUVEAU_BO_LOW, 0, 0);
1397	so_method(so, tesla, 0x198c, 1);
1398	so_data  (so, p->cfg.high_temp);
1399	so_method(so, tesla, 0x1414, 1);
1400	so_data  (so, 0); /* program start offset */
1401	so_emit(nv50->screen->nvws, so);
1402	so_ref(NULL, &so);
1403}
1404
1405void
1406nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
1407{
1408	struct pipe_winsys *ws = nv50->pipe.winsys;
1409
1410	if (p->insns_nr) {
1411		if (p->insns)
1412			FREE(p->insns);
1413		p->insns_nr = 0;
1414	}
1415
1416	if (p->buffer)
1417		pipe_buffer_reference(ws, &p->buffer, NULL);
1418
1419	p->translated = 0;
1420}
1421
1422