OSDN Git Service

b69616d6e5217b106e4cd0e240cac213e686588d
[android-x86/external-mesa.git] / src / mesa / drivers / dri / i965 / brw_vs_emit.c
1 /*
2  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4  develop this 3D driver.
5  
6  Permission is hereby granted, free of charge, to any person obtaining
7  a copy of this software and associated documentation files (the
8  "Software"), to deal in the Software without restriction, including
9  without limitation the rights to use, copy, modify, merge, publish,
10  distribute, sublicense, and/or sell copies of the Software, and to
11  permit persons to whom the Software is furnished to do so, subject to
12  the following conditions:
13  
14  The above copyright notice and this permission notice (including the
15  next paragraph) shall be included in all copies or substantial
16  portions of the Software.
17  
18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  
26  **********************************************************************/
27  /*
28   * Authors:
29   *   Keith Whitwell <keith@tungstengraphics.com>
30   */
31             
32
33 #include "main/macros.h"
34 #include "shader/program.h"
35 #include "shader/prog_parameter.h"
36 #include "shader/prog_print.h"
37 #include "brw_context.h"
38 #include "brw_vs.h"
39
40
41 static struct brw_reg get_tmp( struct brw_vs_compile *c )
42 {
43    struct brw_reg tmp = brw_vec8_grf(c->last_tmp, 0);
44
45    if (++c->last_tmp > c->prog_data.total_grf)
46       c->prog_data.total_grf = c->last_tmp;
47
48    return tmp;
49 }
50
51 static void release_tmp( struct brw_vs_compile *c, struct brw_reg tmp )
52 {
53    if (tmp.nr == c->last_tmp-1)
54       c->last_tmp--;
55 }
56                                
57 static void release_tmps( struct brw_vs_compile *c )
58 {
59    c->last_tmp = c->first_tmp;
60 }
61
62
63 /**
64  * Preallocate GRF register before code emit.
65  * Do things as simply as possible.  Allocate and populate all regs
66  * ahead of time.
67  */
68 static void brw_vs_alloc_regs( struct brw_vs_compile *c )
69 {
70    GLuint i, reg = 0, mrf;
71
72 #if 0
73    if (c->vp->program.Base.Parameters->NumParameters >= 6)
74       c->vp->use_const_buffer = 1;
75    else
76 #endif
77       c->vp->use_const_buffer = GL_FALSE;
78    /*printf("use_const_buffer = %d\n", c->use_const_buffer);*/
79
80    /* r0 -- reserved as usual
81     */
82    c->r0 = brw_vec8_grf(reg, 0);
83    reg++;
84
85    /* User clip planes from curbe: 
86     */
87    if (c->key.nr_userclip) {
88       for (i = 0; i < c->key.nr_userclip; i++) {
89          c->userplane[i] = stride( brw_vec4_grf(reg+3+i/2, (i%2) * 4), 0, 4, 1);
90       }     
91
92       /* Deal with curbe alignment:
93        */
94       reg += ((6 + c->key.nr_userclip + 3) / 4) * 2;
95    }
96
97    /* Vertex program parameters from curbe:
98     */
99    if (c->vp->use_const_buffer) {
100       /* get constants from a real constant buffer */
101       c->prog_data.curb_read_length = 0;
102       c->prog_data.nr_params = 4; /* XXX 0 causes a bug elsewhere... */
103    }
104    else {
105       /* use a section of the GRF for constants */
106       GLuint nr_params = c->vp->program.Base.Parameters->NumParameters;
107       for (i = 0; i < nr_params; i++) {
108          c->regs[PROGRAM_STATE_VAR][i] = stride( brw_vec4_grf(reg+i/2, (i%2) * 4), 0, 4, 1);
109       }
110       reg += (nr_params + 1) / 2;
111       c->prog_data.curb_read_length = reg - 1;
112
113       c->prog_data.nr_params = nr_params * 4;
114    }
115
116    /* Allocate input regs:  
117     */
118    c->nr_inputs = 0;
119    for (i = 0; i < VERT_ATTRIB_MAX; i++) {
120       if (c->prog_data.inputs_read & (1 << i)) {
121          c->nr_inputs++;
122          c->regs[PROGRAM_INPUT][i] = brw_vec8_grf(reg, 0);
123          reg++;
124       }
125    }
126
127    /* Allocate outputs: TODO: could organize the non-position outputs
128     * to go straight into message regs.
129     */
130    c->nr_outputs = 0;
131    c->first_output = reg;
132    mrf = 4;
133    for (i = 0; i < VERT_RESULT_MAX; i++) {
134       if (c->prog_data.outputs_written & (1 << i)) {
135          c->nr_outputs++;
136          if (i == VERT_RESULT_HPOS) {
137             c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
138             reg++;
139          }
140          else if (i == VERT_RESULT_PSIZ) {
141             c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
142             reg++;
143             mrf++;              /* just a placeholder?  XXX fix later stages & remove this */
144          }
145          else {
146             c->regs[PROGRAM_OUTPUT][i] = brw_message_reg(mrf);
147             mrf++;
148          }
149       }
150    }     
151
152    /* Allocate program temporaries:
153     */
154    for (i = 0; i < c->vp->program.Base.NumTemporaries; i++) {
155       c->regs[PROGRAM_TEMPORARY][i] = brw_vec8_grf(reg, 0);
156       reg++;
157    }
158
159    /* Address reg(s).  Don't try to use the internal address reg until
160     * deref time.
161     */
162    for (i = 0; i < c->vp->program.Base.NumAddressRegs; i++) {
163       c->regs[PROGRAM_ADDRESS][i] =  brw_reg(BRW_GENERAL_REGISTER_FILE,
164                                              reg,
165                                              0,
166                                              BRW_REGISTER_TYPE_D,
167                                              BRW_VERTICAL_STRIDE_8,
168                                              BRW_WIDTH_8,
169                                              BRW_HORIZONTAL_STRIDE_1,
170                                              BRW_SWIZZLE_XXXX,
171                                              WRITEMASK_X);
172       reg++;
173    }
174
175    if (c->vp->use_const_buffer) {
176       for (i = 0; i < 3; i++) {
177          c->current_const[i].index = -1;
178          c->current_const[i].reg = brw_vec8_grf(reg, 0);
179          reg++;
180       }
181    }
182
183    for (i = 0; i < 128; i++) {
184       if (c->output_regs[i].used_in_src) {
185          c->output_regs[i].reg = brw_vec8_grf(reg, 0);
186          reg++;
187       }
188    }
189
190    c->stack =  brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, reg, 0);
191    reg += 2;
192
193    /* Some opcodes need an internal temporary:
194     */
195    c->first_tmp = reg;
196    c->last_tmp = reg;           /* for allocation purposes */
197
198    /* Each input reg holds data from two vertices.  The
199     * urb_read_length is the number of registers read from *each*
200     * vertex urb, so is half the amount:
201     */
202    c->prog_data.urb_read_length = (c->nr_inputs + 1) / 2;
203
204    c->prog_data.urb_entry_size = (c->nr_outputs + 2 + 3) / 4;
205    c->prog_data.total_grf = reg;
206
207    if (INTEL_DEBUG & DEBUG_VS) {
208       _mesa_printf("%s NumAddrRegs %d\n", __FUNCTION__, c->vp->program.Base.NumAddressRegs);
209       _mesa_printf("%s NumTemps %d\n", __FUNCTION__, c->vp->program.Base.NumTemporaries);
210       _mesa_printf("%s reg = %d\n", __FUNCTION__, reg);
211    }
212 }
213
214
215 /**
216  * If an instruction uses a temp reg both as a src and the dest, we
217  * sometimes need to allocate an intermediate temporary.
218  */
219 static void unalias1( struct brw_vs_compile *c,
220                       struct brw_reg dst,
221                       struct brw_reg arg0,
222                       void (*func)( struct brw_vs_compile *,
223                                     struct brw_reg,
224                                     struct brw_reg ))
225 {
226    if (dst.file == arg0.file && dst.nr == arg0.nr) {
227       struct brw_compile *p = &c->func;
228       struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
229       func(c, tmp, arg0);
230       brw_MOV(p, dst, tmp);
231       release_tmp(c, tmp);
232    }
233    else {
234       func(c, dst, arg0);
235    }
236 }
237
238 /**
239  * \sa unalias2
240  * Checkes if 2-operand instruction needs an intermediate temporary.
241  */
242 static void unalias2( struct brw_vs_compile *c,
243                       struct brw_reg dst,
244                       struct brw_reg arg0,
245                       struct brw_reg arg1,
246                       void (*func)( struct brw_vs_compile *,
247                                     struct brw_reg,
248                                     struct brw_reg,
249                                     struct brw_reg ))
250 {
251    if ((dst.file == arg0.file && dst.nr == arg0.nr) ||
252        (dst.file == arg1.file && dst.nr == arg1.nr)) {
253       struct brw_compile *p = &c->func;
254       struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
255       func(c, tmp, arg0, arg1);
256       brw_MOV(p, dst, tmp);
257       release_tmp(c, tmp);
258    }
259    else {
260       func(c, dst, arg0, arg1);
261    }
262 }
263
264 /**
265  * \sa unalias2
266  * Checkes if 3-operand instruction needs an intermediate temporary.
267  */
268 static void unalias3( struct brw_vs_compile *c,
269                       struct brw_reg dst,
270                       struct brw_reg arg0,
271                       struct brw_reg arg1,
272                       struct brw_reg arg2,
273                       void (*func)( struct brw_vs_compile *,
274                                     struct brw_reg,
275                                     struct brw_reg,
276                                     struct brw_reg,
277                                     struct brw_reg ))
278 {
279    if ((dst.file == arg0.file && dst.nr == arg0.nr) ||
280        (dst.file == arg1.file && dst.nr == arg1.nr) ||
281        (dst.file == arg2.file && dst.nr == arg2.nr)) {
282       struct brw_compile *p = &c->func;
283       struct brw_reg tmp = brw_writemask(get_tmp(c), dst.dw1.bits.writemask);
284       func(c, tmp, arg0, arg1, arg2);
285       brw_MOV(p, dst, tmp);
286       release_tmp(c, tmp);
287    }
288    else {
289       func(c, dst, arg0, arg1, arg2);
290    }
291 }
292
293 static void emit_sop( struct brw_compile *p,
294                       struct brw_reg dst,
295                       struct brw_reg arg0,
296                       struct brw_reg arg1, 
297                       GLuint cond)
298 {
299    brw_MOV(p, dst, brw_imm_f(0.0f));
300    brw_CMP(p, brw_null_reg(), cond, arg0, arg1);
301    brw_MOV(p, dst, brw_imm_f(1.0f));
302    brw_set_predicate_control_flag_value(p, 0xff);
303 }
304
305 static void emit_seq( struct brw_compile *p,
306                       struct brw_reg dst,
307                       struct brw_reg arg0,
308                       struct brw_reg arg1 )
309 {
310    emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ);
311 }
312
313 static void emit_sne( struct brw_compile *p,
314                       struct brw_reg dst,
315                       struct brw_reg arg0,
316                       struct brw_reg arg1 )
317 {
318    emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ);
319 }
320 static void emit_slt( struct brw_compile *p, 
321                       struct brw_reg dst,
322                       struct brw_reg arg0,
323                       struct brw_reg arg1 )
324 {
325    emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L);
326 }
327
328 static void emit_sle( struct brw_compile *p, 
329                       struct brw_reg dst,
330                       struct brw_reg arg0,
331                       struct brw_reg arg1 )
332 {
333    emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE);
334 }
335
336 static void emit_sgt( struct brw_compile *p, 
337                       struct brw_reg dst,
338                       struct brw_reg arg0,
339                       struct brw_reg arg1 )
340 {
341    emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G);
342 }
343
344 static void emit_sge( struct brw_compile *p, 
345                       struct brw_reg dst,
346                       struct brw_reg arg0,
347                       struct brw_reg arg1 )
348 {
349   emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE);
350 }
351
352 static void emit_max( struct brw_compile *p, 
353                       struct brw_reg dst,
354                       struct brw_reg arg0,
355                       struct brw_reg arg1 )
356 {
357    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1);
358    brw_SEL(p, dst, arg1, arg0);
359    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
360 }
361
362 static void emit_min( struct brw_compile *p, 
363                       struct brw_reg dst,
364                       struct brw_reg arg0,
365                       struct brw_reg arg1 )
366 {
367    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0, arg1);
368    brw_SEL(p, dst, arg0, arg1);
369    brw_set_predicate_control(p, BRW_PREDICATE_NONE);
370 }
371
372
373 static void emit_math1( struct brw_vs_compile *c,
374                         GLuint function,
375                         struct brw_reg dst,
376                         struct brw_reg arg0,
377                         GLuint precision)
378 {
379    /* There are various odd behaviours with SEND on the simulator.  In
380     * addition there are documented issues with the fact that the GEN4
381     * processor doesn't do dependency control properly on SEND
382     * results.  So, on balance, this kludge to get around failures
383     * with writemasked math results looks like it might be necessary
384     * whether that turns out to be a simulator bug or not:
385     */
386    struct brw_compile *p = &c->func;
387    struct brw_reg tmp = dst;
388    GLboolean need_tmp = (dst.dw1.bits.writemask != 0xf ||
389                          dst.file != BRW_GENERAL_REGISTER_FILE);
390
391    if (need_tmp) 
392       tmp = get_tmp(c);
393
394    brw_math(p, 
395             tmp,
396             function,
397             BRW_MATH_SATURATE_NONE,
398             2,
399             arg0,
400             BRW_MATH_DATA_SCALAR,
401             precision);
402
403    if (need_tmp) {
404       brw_MOV(p, dst, tmp);
405       release_tmp(c, tmp);
406    }
407 }
408
409
410 static void emit_math2( struct brw_vs_compile *c, 
411                         GLuint function,
412                         struct brw_reg dst,
413                         struct brw_reg arg0,
414                         struct brw_reg arg1,
415                         GLuint precision)
416 {
417    struct brw_compile *p = &c->func;
418    struct brw_reg tmp = dst;
419    GLboolean need_tmp = (dst.dw1.bits.writemask != 0xf ||
420                          dst.file != BRW_GENERAL_REGISTER_FILE);
421
422    if (need_tmp) 
423       tmp = get_tmp(c);
424
425    brw_MOV(p, brw_message_reg(3), arg1);
426    
427    brw_math(p, 
428             tmp,
429             function,
430             BRW_MATH_SATURATE_NONE,
431             2,
432             arg0,
433             BRW_MATH_DATA_SCALAR,
434             precision);
435
436    if (need_tmp) {
437       brw_MOV(p, dst, tmp);
438       release_tmp(c, tmp);
439    }
440 }
441
442
443 static void emit_exp_noalias( struct brw_vs_compile *c,
444                               struct brw_reg dst,
445                               struct brw_reg arg0 )
446 {
447    struct brw_compile *p = &c->func;
448    
449
450    if (dst.dw1.bits.writemask & WRITEMASK_X) {
451       struct brw_reg tmp = get_tmp(c);
452       struct brw_reg tmp_d = retype(tmp, BRW_REGISTER_TYPE_D);
453
454       /* tmp_d = floor(arg0.x) */
455       brw_RNDD(p, tmp_d, brw_swizzle1(arg0, 0));
456
457       /* result[0] = 2.0 ^ tmp */
458
459       /* Adjust exponent for floating point: 
460        * exp += 127 
461        */
462       brw_ADD(p, brw_writemask(tmp_d, WRITEMASK_X), tmp_d, brw_imm_d(127));
463
464       /* Install exponent and sign.  
465        * Excess drops off the edge: 
466        */
467       brw_SHL(p, brw_writemask(retype(dst, BRW_REGISTER_TYPE_D), WRITEMASK_X), 
468               tmp_d, brw_imm_d(23));
469
470       release_tmp(c, tmp);
471    }
472
473    if (dst.dw1.bits.writemask & WRITEMASK_Y) {
474       /* result[1] = arg0.x - floor(arg0.x) */
475       brw_FRC(p, brw_writemask(dst, WRITEMASK_Y), brw_swizzle1(arg0, 0));
476    }
477    
478    if (dst.dw1.bits.writemask & WRITEMASK_Z) {
479       /* As with the LOG instruction, we might be better off just
480        * doing a taylor expansion here, seeing as we have to do all
481        * the prep work.
482        *
483        * If mathbox partial precision is too low, consider also:
484        * result[3] = result[0] * EXP(result[1])
485        */
486       emit_math1(c, 
487                  BRW_MATH_FUNCTION_EXP, 
488                  brw_writemask(dst, WRITEMASK_Z),
489                  brw_swizzle1(arg0, 0), 
490                  BRW_MATH_PRECISION_FULL);
491    }  
492
493    if (dst.dw1.bits.writemask & WRITEMASK_W) {
494       /* result[3] = 1.0; */
495       brw_MOV(p, brw_writemask(dst, WRITEMASK_W), brw_imm_f(1));
496    }
497 }
498
499
500 static void emit_log_noalias( struct brw_vs_compile *c,
501                               struct brw_reg dst,
502                               struct brw_reg arg0 )
503 {
504    struct brw_compile *p = &c->func;
505    struct brw_reg tmp = dst;
506    struct brw_reg tmp_ud = retype(tmp, BRW_REGISTER_TYPE_UD);
507    struct brw_reg arg0_ud = retype(arg0, BRW_REGISTER_TYPE_UD);
508    GLboolean need_tmp = (dst.dw1.bits.writemask != 0xf ||
509                          dst.file != BRW_GENERAL_REGISTER_FILE);
510
511    if (need_tmp) {
512       tmp = get_tmp(c);
513       tmp_ud = retype(tmp, BRW_REGISTER_TYPE_UD);
514    }
515    
516    /* Perform mant = frexpf(fabsf(x), &exp), adjust exp and mnt
517     * according to spec:
518     *
519     * These almost look likey they could be joined up, but not really
520     * practical:
521     *
522     * result[0].f = (x.i & ((1<<31)-1) >> 23) - 127
523     * result[1].i = (x.i & ((1<<23)-1)        + (127<<23)
524     */
525    if (dst.dw1.bits.writemask & WRITEMASK_XZ) {
526       brw_AND(p, 
527               brw_writemask(tmp_ud, WRITEMASK_X),
528               brw_swizzle1(arg0_ud, 0),
529               brw_imm_ud((1U<<31)-1));
530
531       brw_SHR(p, 
532               brw_writemask(tmp_ud, WRITEMASK_X), 
533               tmp_ud,
534               brw_imm_ud(23));
535
536       brw_ADD(p, 
537               brw_writemask(tmp, WRITEMASK_X), 
538               retype(tmp_ud, BRW_REGISTER_TYPE_D),      /* does it matter? */
539               brw_imm_d(-127));
540    }
541
542    if (dst.dw1.bits.writemask & WRITEMASK_YZ) {
543       brw_AND(p, 
544               brw_writemask(tmp_ud, WRITEMASK_Y),
545               brw_swizzle1(arg0_ud, 0),
546               brw_imm_ud((1<<23)-1));
547
548       brw_OR(p, 
549              brw_writemask(tmp_ud, WRITEMASK_Y), 
550              tmp_ud,
551              brw_imm_ud(127<<23));
552    }
553    
554    if (dst.dw1.bits.writemask & WRITEMASK_Z) {
555       /* result[2] = result[0] + LOG2(result[1]); */
556
557       /* Why bother?  The above is just a hint how to do this with a
558        * taylor series.  Maybe we *should* use a taylor series as by
559        * the time all the above has been done it's almost certainly
560        * quicker than calling the mathbox, even with low precision.
561        * 
562        * Options are:
563        *    - result[0] + mathbox.LOG2(result[1])
564        *    - mathbox.LOG2(arg0.x)
565        *    - result[0] + inline_taylor_approx(result[1])
566        */
567       emit_math1(c, 
568                  BRW_MATH_FUNCTION_LOG, 
569                  brw_writemask(tmp, WRITEMASK_Z), 
570                  brw_swizzle1(tmp, 1), 
571                  BRW_MATH_PRECISION_FULL);
572       
573       brw_ADD(p, 
574               brw_writemask(tmp, WRITEMASK_Z), 
575               brw_swizzle1(tmp, 2), 
576               brw_swizzle1(tmp, 0));
577    }  
578
579    if (dst.dw1.bits.writemask & WRITEMASK_W) {
580       /* result[3] = 1.0; */
581       brw_MOV(p, brw_writemask(tmp, WRITEMASK_W), brw_imm_f(1));
582    }
583
584    if (need_tmp) {
585       brw_MOV(p, dst, tmp);
586       release_tmp(c, tmp);
587    }
588 }
589
590
591 /* Need to unalias - consider swizzles:   r0 = DST r0.xxxx r1
592  */
593 static void emit_dst_noalias( struct brw_vs_compile *c, 
594                               struct brw_reg dst,
595                               struct brw_reg arg0,
596                               struct brw_reg arg1)
597 {
598    struct brw_compile *p = &c->func;
599
600    /* There must be a better way to do this: 
601     */
602    if (dst.dw1.bits.writemask & WRITEMASK_X)
603       brw_MOV(p, brw_writemask(dst, WRITEMASK_X), brw_imm_f(1.0));
604    if (dst.dw1.bits.writemask & WRITEMASK_Y)
605       brw_MUL(p, brw_writemask(dst, WRITEMASK_Y), arg0, arg1);
606    if (dst.dw1.bits.writemask & WRITEMASK_Z)
607       brw_MOV(p, brw_writemask(dst, WRITEMASK_Z), arg0);
608    if (dst.dw1.bits.writemask & WRITEMASK_W)
609       brw_MOV(p, brw_writemask(dst, WRITEMASK_W), arg1);
610 }
611
612
613 static void emit_xpd( struct brw_compile *p,
614                       struct brw_reg dst,
615                       struct brw_reg t,
616                       struct brw_reg u)
617 {
618    brw_MUL(p, brw_null_reg(), brw_swizzle(t, 1,2,0,3),  brw_swizzle(u,2,0,1,3));
619    brw_MAC(p, dst,     negate(brw_swizzle(t, 2,0,1,3)), brw_swizzle(u,1,2,0,3));
620 }
621
622
623 static void emit_lit_noalias( struct brw_vs_compile *c, 
624                               struct brw_reg dst,
625                               struct brw_reg arg0 )
626 {
627    struct brw_compile *p = &c->func;
628    struct brw_instruction *if_insn;
629    struct brw_reg tmp = dst;
630    GLboolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE);
631
632    if (need_tmp) 
633       tmp = get_tmp(c);
634    
635    brw_MOV(p, brw_writemask(dst, WRITEMASK_YZ), brw_imm_f(0)); 
636    brw_MOV(p, brw_writemask(dst, WRITEMASK_XW), brw_imm_f(1)); 
637
638    /* Need to use BRW_EXECUTE_8 and also do an 8-wide compare in order
639     * to get all channels active inside the IF.  In the clipping code
640     * we run with NoMask, so it's not an option and we can use
641     * BRW_EXECUTE_1 for all comparisions.
642     */
643    brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, brw_swizzle1(arg0,0), brw_imm_f(0));
644    if_insn = brw_IF(p, BRW_EXECUTE_8);
645    {
646       brw_MOV(p, brw_writemask(dst, WRITEMASK_Y), brw_swizzle1(arg0,0));
647
648       brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_G, brw_swizzle1(arg0,1), brw_imm_f(0));
649       brw_MOV(p, brw_writemask(tmp, WRITEMASK_Z),  brw_swizzle1(arg0,1));
650       brw_set_predicate_control(p, BRW_PREDICATE_NONE);
651
652       emit_math2(c, 
653                  BRW_MATH_FUNCTION_POW, 
654                  brw_writemask(dst, WRITEMASK_Z),
655                  brw_swizzle1(tmp, 2),
656                  brw_swizzle1(arg0, 3),
657                  BRW_MATH_PRECISION_PARTIAL);      
658    }
659
660    brw_ENDIF(p, if_insn);
661
662    release_tmp(c, tmp);
663 }
664
665 static void emit_lrp_noalias(struct brw_vs_compile *c,
666                              struct brw_reg dst,
667                              struct brw_reg arg0,
668                              struct brw_reg arg1,
669                              struct brw_reg arg2)
670 {
671    struct brw_compile *p = &c->func;
672
673    brw_ADD(p, dst, negate(arg0), brw_imm_f(1.0));
674    brw_MUL(p, brw_null_reg(), dst, arg2);
675    brw_MAC(p, dst, arg0, arg1);
676 }
677
678 /** 3 or 4-component vector normalization */
679 static void emit_nrm( struct brw_vs_compile *c, 
680                       struct brw_reg dst,
681                       struct brw_reg arg0,
682                       int num_comps)
683 {
684    struct brw_compile *p = &c->func;
685    struct brw_reg tmp = get_tmp(c);
686
687    /* tmp = dot(arg0, arg0) */
688    if (num_comps == 3)
689       brw_DP3(p, tmp, arg0, arg0);
690    else
691       brw_DP4(p, tmp, arg0, arg0);
692
693    /* tmp = 1 / sqrt(tmp) */
694    emit_math1(c, BRW_MATH_FUNCTION_RSQ, tmp, tmp, BRW_MATH_PRECISION_FULL);
695
696    /* dst = arg0 * tmp */
697    brw_MUL(p, dst, arg0, tmp);
698
699    release_tmp(c, tmp);
700 }
701
702
703 static struct brw_reg
704 get_constant(struct brw_vs_compile *c,
705              const struct prog_instruction *inst,
706              GLuint argIndex)
707 {
708    const struct prog_src_register *src = &inst->SrcReg[argIndex];
709    struct brw_compile *p = &c->func;
710    struct brw_reg const_reg;
711    struct brw_reg const2_reg;
712
713    assert(argIndex < 3);
714
715    if (c->current_const[argIndex].index != src->Index || src->RelAddr) {
716       struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0];
717
718       c->current_const[argIndex].index = src->Index;
719
720 #if 0
721       printf("  fetch const[%d] for arg %d into reg %d\n",
722              src->Index, argIndex, c->current_const[argIndex].reg.nr);
723 #endif
724       /* need to fetch the constant now */
725       brw_dp_READ_4_vs(p,
726                        c->current_const[argIndex].reg,/* writeback dest */
727                        0,                             /* oword */
728                        src->RelAddr,                  /* relative indexing? */
729                        addrReg,                       /* address register */
730                        16 * src->Index,               /* byte offset */
731                        SURF_INDEX_VERT_CONST_BUFFER   /* binding table index */
732                        );
733
734       if (src->RelAddr) {
735          /* second read */
736          const2_reg = get_tmp(c);
737
738          /* use upper half of address reg for second read */
739          addrReg = stride(addrReg, 0, 4, 0);
740          addrReg.subnr = 16;
741
742          brw_dp_READ_4_vs(p,
743                           const2_reg,              /* writeback dest */
744                           1,                       /* oword */
745                           src->RelAddr,            /* relative indexing? */
746                           addrReg,                 /* address register */
747                           16 * src->Index,         /* byte offset */
748                           SURF_INDEX_VERT_CONST_BUFFER
749                           );
750       }
751    }
752
753    const_reg = c->current_const[argIndex].reg;
754
755    if (src->RelAddr) {
756       /* merge the two Owords into the constant register */
757       /* const_reg[7..4] = const2_reg[7..4] */
758       brw_MOV(p,
759               suboffset(stride(const_reg, 0, 4, 1), 4),
760               suboffset(stride(const2_reg, 0, 4, 1), 4));
761       release_tmp(c, const2_reg);
762    }
763    else {
764       /* replicate lower four floats into upper half (to get XYZWXYZW) */
765       const_reg = stride(const_reg, 0, 4, 0);
766       const_reg.subnr = 0;
767    }
768
769    return const_reg;
770 }
771
772
773
774 /* TODO: relative addressing!
775  */
776 static struct brw_reg get_reg( struct brw_vs_compile *c,
777                                gl_register_file file,
778                                GLuint index )
779 {
780    switch (file) {
781    case PROGRAM_TEMPORARY:
782    case PROGRAM_INPUT:
783    case PROGRAM_OUTPUT:
784       assert(c->regs[file][index].nr != 0);
785       return c->regs[file][index];
786    case PROGRAM_STATE_VAR:
787    case PROGRAM_CONSTANT:
788    case PROGRAM_UNIFORM:
789       assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0);
790       return c->regs[PROGRAM_STATE_VAR][index];
791    case PROGRAM_ADDRESS:
792       assert(index == 0);
793       return c->regs[file][index];
794
795    case PROGRAM_UNDEFINED:                      /* undef values */
796       return brw_null_reg();
797
798    case PROGRAM_LOCAL_PARAM: 
799    case PROGRAM_ENV_PARAM: 
800    case PROGRAM_WRITE_ONLY:
801    default:
802       assert(0);
803       return brw_null_reg();
804    }
805 }
806
807
808 /**
809  * Indirect addressing:  get reg[[arg] + offset].
810  */
811 static struct brw_reg deref( struct brw_vs_compile *c,
812                              struct brw_reg arg,
813                              GLint offset)
814 {
815    struct brw_compile *p = &c->func;
816    struct brw_reg tmp = vec4(get_tmp(c));
817    struct brw_reg addr_reg = c->regs[PROGRAM_ADDRESS][0];
818    struct brw_reg vp_address = retype(vec1(addr_reg), BRW_REGISTER_TYPE_UW);
819    GLuint byte_offset = arg.nr * 32 + arg.subnr + offset * 16;
820    struct brw_reg indirect = brw_vec4_indirect(0,0);
821
822    {
823       brw_push_insn_state(p);
824       brw_set_access_mode(p, BRW_ALIGN_1);
825
826       /* This is pretty clunky - load the address register twice and
827        * fetch each 4-dword value in turn.  There must be a way to do
828        * this in a single pass, but I couldn't get it to work.
829        */
830       brw_ADD(p, brw_address_reg(0), vp_address, brw_imm_d(byte_offset));
831       brw_MOV(p, tmp, indirect);
832
833       brw_ADD(p, brw_address_reg(0), suboffset(vp_address, 8), brw_imm_d(byte_offset));
834       brw_MOV(p, suboffset(tmp, 4), indirect);
835
836       brw_pop_insn_state(p);
837    }
838    
839    /* NOTE: tmp not released */
840    return vec8(tmp);
841 }
842
843
844 /**
845  * Get brw reg corresponding to the instruction's [argIndex] src reg.
846  * TODO: relative addressing!
847  */
848 static struct brw_reg
849 get_src_reg( struct brw_vs_compile *c,
850              const struct prog_instruction *inst,
851              GLuint argIndex )
852 {
853    const GLuint file = inst->SrcReg[argIndex].File;
854    const GLint index = inst->SrcReg[argIndex].Index;
855    const GLboolean relAddr = inst->SrcReg[argIndex].RelAddr;
856
857    switch (file) {
858    case PROGRAM_TEMPORARY:
859    case PROGRAM_INPUT:
860    case PROGRAM_OUTPUT:
861       if (relAddr) {
862          return deref(c, c->regs[file][0], index);
863       }
864       else {
865          assert(c->regs[file][index].nr != 0);
866          return c->regs[file][index];
867       }
868
869    case PROGRAM_STATE_VAR:
870    case PROGRAM_CONSTANT:
871    case PROGRAM_UNIFORM:
872       if (c->vp->use_const_buffer) {
873          return get_constant(c, inst, argIndex);
874       }
875       else if (relAddr) {
876          return deref(c, c->regs[PROGRAM_STATE_VAR][0], index);
877       }
878       else {
879          assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0);
880          return c->regs[PROGRAM_STATE_VAR][index];
881       }
882    case PROGRAM_ADDRESS:
883       assert(index == 0);
884       return c->regs[file][index];
885
886    case PROGRAM_UNDEFINED:
887       /* this is a normal case since we loop over all three src args */
888       return brw_null_reg();
889
890    case PROGRAM_LOCAL_PARAM: 
891    case PROGRAM_ENV_PARAM: 
892    case PROGRAM_WRITE_ONLY:
893    default:
894       assert(0);
895       return brw_null_reg();
896    }
897 }
898
899
900 static void emit_arl( struct brw_vs_compile *c,
901                       struct brw_reg dst,
902                       struct brw_reg arg0 )
903 {
904    struct brw_compile *p = &c->func;
905    struct brw_reg tmp = dst;
906    GLboolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE);
907    
908    if (need_tmp) 
909       tmp = get_tmp(c);
910
911    brw_RNDD(p, tmp, arg0);               /* tmp = round(arg0) */
912    brw_MUL(p, dst, tmp, brw_imm_d(16));  /* dst = tmp * 16 */
913
914    if (need_tmp)
915       release_tmp(c, tmp);
916 }
917
918
919 /**
920  * Return the brw reg for the given instruction's src argument.
921  * Will return mangled results for SWZ op.  The emit_swz() function
922  * ignores this result and recalculates taking extended swizzles into
923  * account.
924  */
925 static struct brw_reg get_arg( struct brw_vs_compile *c,
926                                const struct prog_instruction *inst,
927                                GLuint argIndex )
928 {
929    const struct prog_src_register *src = &inst->SrcReg[argIndex];
930    struct brw_reg reg;
931
932    if (src->File == PROGRAM_UNDEFINED)
933       return brw_null_reg();
934
935    reg = get_src_reg(c, inst, argIndex);
936
937    /* Convert 3-bit swizzle to 2-bit.  
938     */
939    reg.dw1.bits.swizzle = BRW_SWIZZLE4(GET_SWZ(src->Swizzle, 0),
940                                        GET_SWZ(src->Swizzle, 1),
941                                        GET_SWZ(src->Swizzle, 2),
942                                        GET_SWZ(src->Swizzle, 3));
943
944    /* Note this is ok for non-swizzle instructions: 
945     */
946    reg.negate = src->Negate ? 1 : 0;   
947
948    return reg;
949 }
950
951
952 /**
953  * Get brw register for the given program dest register.
954  */
955 static struct brw_reg get_dst( struct brw_vs_compile *c,
956                                struct prog_dst_register dst )
957 {
958    struct brw_reg reg;
959
960    switch (dst.File) {
961    case PROGRAM_TEMPORARY:
962    case PROGRAM_OUTPUT:
963       assert(c->regs[dst.File][dst.Index].nr != 0);
964       reg = c->regs[dst.File][dst.Index];
965       break;
966    case PROGRAM_ADDRESS:
967       assert(dst.Index == 0);
968       reg = c->regs[dst.File][dst.Index];
969       break;
970    case PROGRAM_UNDEFINED:
971       /* we may hit this for OPCODE_END, OPCODE_KIL, etc */
972       reg = brw_null_reg();
973       break;
974    default:
975       assert(0);
976       reg = brw_null_reg();
977    }
978
979    reg.dw1.bits.writemask = dst.WriteMask;
980
981    return reg;
982 }
983
984
985 static void emit_swz( struct brw_vs_compile *c, 
986                       struct brw_reg dst,
987                       const struct prog_instruction *inst)
988 {
989    const GLuint argIndex = 0;
990    const struct prog_src_register src = inst->SrcReg[argIndex];
991    struct brw_compile *p = &c->func;
992    GLuint zeros_mask = 0;
993    GLuint ones_mask = 0;
994    GLuint src_mask = 0;
995    GLubyte src_swz[4];
996    GLboolean need_tmp = (src.Negate &&
997                          dst.file != BRW_GENERAL_REGISTER_FILE);
998    struct brw_reg tmp = dst;
999    GLuint i;
1000
1001    if (need_tmp)
1002       tmp = get_tmp(c);
1003
1004    for (i = 0; i < 4; i++) {
1005       if (dst.dw1.bits.writemask & (1<<i)) {
1006          GLubyte s = GET_SWZ(src.Swizzle, i);
1007          switch (s) {
1008          case SWIZZLE_X:
1009          case SWIZZLE_Y:
1010          case SWIZZLE_Z:
1011          case SWIZZLE_W:
1012             src_mask |= 1<<i;
1013             src_swz[i] = s;
1014             break;
1015          case SWIZZLE_ZERO:
1016             zeros_mask |= 1<<i;
1017             break;
1018          case SWIZZLE_ONE:
1019             ones_mask |= 1<<i;
1020             break;
1021          }
1022       }
1023    }
1024    
1025    /* Do src first, in case dst aliases src:
1026     */
1027    if (src_mask) {
1028       struct brw_reg arg0;
1029
1030       arg0 = get_src_reg(c, inst, argIndex);
1031
1032       arg0 = brw_swizzle(arg0, 
1033                          src_swz[0], src_swz[1], 
1034                          src_swz[2], src_swz[3]);
1035
1036       brw_MOV(p, brw_writemask(tmp, src_mask), arg0);
1037    } 
1038    
1039    if (zeros_mask) 
1040       brw_MOV(p, brw_writemask(tmp, zeros_mask), brw_imm_f(0));
1041
1042    if (ones_mask) 
1043       brw_MOV(p, brw_writemask(tmp, ones_mask), brw_imm_f(1));
1044
1045    if (src.Negate)
1046       brw_MOV(p, brw_writemask(tmp, src.Negate), negate(tmp));
1047    
1048    if (need_tmp) {
1049       brw_MOV(p, dst, tmp);
1050       release_tmp(c, tmp);
1051    }
1052 }
1053
1054
1055 /**
1056  * Post-vertex-program processing.  Send the results to the URB.
1057  */
1058 static void emit_vertex_write( struct brw_vs_compile *c)
1059 {
1060    struct brw_compile *p = &c->func;
1061    struct brw_reg m0 = brw_message_reg(0);
1062    struct brw_reg pos = c->regs[PROGRAM_OUTPUT][VERT_RESULT_HPOS];
1063    struct brw_reg ndc;
1064
1065    if (c->key.copy_edgeflag) {
1066       brw_MOV(p, 
1067               get_reg(c, PROGRAM_OUTPUT, VERT_RESULT_EDGE),
1068               get_reg(c, PROGRAM_INPUT, VERT_ATTRIB_EDGEFLAG));
1069    }
1070
1071    /* Build ndc coords */
1072    ndc = get_tmp(c);
1073    emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL);
1074    brw_MUL(p, brw_writemask(ndc, WRITEMASK_XYZ), pos, ndc);
1075
1076    /* Update the header for point size, user clipping flags, and -ve rhw
1077     * workaround.
1078     */
1079    if ((c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) ||
1080        c->key.nr_userclip || !BRW_IS_G4X(p->brw))
1081    {
1082       struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
1083       GLuint i;
1084
1085       brw_MOV(p, header1, brw_imm_ud(0));
1086
1087       brw_set_access_mode(p, BRW_ALIGN_16);     
1088
1089       if (c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) {
1090          struct brw_reg psiz = c->regs[PROGRAM_OUTPUT][VERT_RESULT_PSIZ];
1091          brw_MUL(p, brw_writemask(header1, WRITEMASK_W), brw_swizzle1(psiz, 0), brw_imm_f(1<<11));
1092          brw_AND(p, brw_writemask(header1, WRITEMASK_W), header1, brw_imm_ud(0x7ff<<8));
1093       }
1094
1095       for (i = 0; i < c->key.nr_userclip; i++) {
1096          brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
1097          brw_DP4(p, brw_null_reg(), pos, c->userplane[i]);
1098          brw_OR(p, brw_writemask(header1, WRITEMASK_W), header1, brw_imm_ud(1<<i));
1099          brw_set_predicate_control(p, BRW_PREDICATE_NONE);
1100       }
1101
1102       /* i965 clipping workaround: 
1103        * 1) Test for -ve rhw
1104        * 2) If set, 
1105        *      set ndc = (0,0,0,0)
1106        *      set ucp[6] = 1
1107        *
1108        * Later, clipping will detect ucp[6] and ensure the primitive is
1109        * clipped against all fixed planes.
1110        */
1111       if (!BRW_IS_G4X(p->brw)) {
1112          brw_CMP(p,
1113                  vec8(brw_null_reg()),
1114                  BRW_CONDITIONAL_L,
1115                  brw_swizzle1(ndc, 3),
1116                  brw_imm_f(0));
1117    
1118          brw_OR(p, brw_writemask(header1, WRITEMASK_W), header1, brw_imm_ud(1<<6));
1119          brw_MOV(p, ndc, brw_imm_f(0));
1120          brw_set_predicate_control(p, BRW_PREDICATE_NONE);
1121       }
1122
1123       brw_set_access_mode(p, BRW_ALIGN_1);      /* why? */
1124       brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), header1);
1125       brw_set_access_mode(p, BRW_ALIGN_16);
1126
1127       release_tmp(c, header1);
1128    }
1129    else {
1130       brw_MOV(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD), brw_imm_ud(0));
1131    }
1132
1133    /* Emit the (interleaved) headers for the two vertices - an 8-reg
1134     * of zeros followed by two sets of NDC coordinates:
1135     */
1136    brw_set_access_mode(p, BRW_ALIGN_1);
1137    brw_MOV(p, offset(m0, 2), ndc);
1138    brw_MOV(p, offset(m0, 3), pos);
1139
1140    brw_urb_WRITE(p, 
1141                  brw_null_reg(), /* dest */
1142                  0,             /* starting mrf reg nr */
1143                  c->r0,         /* src */
1144                  0,             /* allocate */
1145                  1,             /* used */
1146                  c->nr_outputs + 3, /* msg len */
1147                  0,             /* response len */
1148                  1,             /* eot */
1149                  1,             /* writes complete */
1150                  0,             /* urb destination offset */
1151                  BRW_URB_SWIZZLE_INTERLEAVE);
1152 }
1153
1154
1155 /**
1156  * Called after code generation to resolve subroutine calls and the
1157  * END instruction.
1158  * \param end_inst  points to brw code for END instruction
1159  * \param last_inst  points to last instruction emitted before vertex write
1160  */
1161 static void 
1162 post_vs_emit( struct brw_vs_compile *c,
1163               struct brw_instruction *end_inst,
1164               struct brw_instruction *last_inst )
1165 {
1166    GLint offset;
1167
1168    brw_resolve_cals(&c->func);
1169
1170    /* patch up the END code to jump past subroutines, etc */
1171    offset = last_inst - end_inst;
1172    brw_set_src1(end_inst, brw_imm_d(offset * 16));
1173 }
1174
1175
1176 /* Emit the vertex program instructions here.
1177  */
1178 void brw_vs_emit(struct brw_vs_compile *c )
1179 {
1180 #define MAX_IFSN 32
1181    struct brw_compile *p = &c->func;
1182    GLuint nr_insns = c->vp->program.Base.NumInstructions;
1183    GLuint insn, if_insn = 0;
1184    GLuint end_offset = 0;
1185    struct brw_instruction *end_inst, *last_inst;
1186    struct brw_instruction *if_inst[MAX_IFSN];
1187    struct brw_indirect stack_index = brw_indirect(0, 0);   
1188
1189    GLuint index;
1190    GLuint file;
1191
1192    if (INTEL_DEBUG & DEBUG_VS) {
1193       _mesa_printf("vs-emit:\n");
1194       _mesa_print_program(&c->vp->program.Base); 
1195       _mesa_printf("\n");
1196    }
1197
1198    brw_set_compression_control(p, BRW_COMPRESSION_NONE);
1199    brw_set_access_mode(p, BRW_ALIGN_16);
1200    
1201    /* Message registers can't be read, so copy the output into GRF register
1202       if they are used in source registers */
1203    for (insn = 0; insn < nr_insns; insn++) {
1204        GLuint i;
1205        struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];
1206        for (i = 0; i < 3; i++) {
1207            struct prog_src_register *src = &inst->SrcReg[i];
1208            GLuint index = src->Index;
1209            GLuint file = src->File;     
1210            if (file == PROGRAM_OUTPUT && index != VERT_RESULT_HPOS)
1211                c->output_regs[index].used_in_src = GL_TRUE;
1212        }
1213    }
1214
1215    /* Static register allocation
1216     */
1217    brw_vs_alloc_regs(c);
1218    brw_MOV(p, get_addr_reg(stack_index), brw_address(c->stack));
1219
1220    for (insn = 0; insn < nr_insns; insn++) {
1221
1222       struct prog_instruction *inst = &c->vp->program.Base.Instructions[insn];
1223       struct brw_reg args[3], dst;
1224       GLuint i;
1225       
1226 #if 0
1227       printf("%d: ", insn);
1228       _mesa_print_instruction(inst);
1229 #endif
1230
1231       /* Get argument regs.  SWZ is special and does this itself.
1232        */
1233       if (inst->Opcode != OPCODE_SWZ)
1234           for (i = 0; i < 3; i++) {
1235               struct prog_src_register *src = &inst->SrcReg[i];
1236               index = src->Index;
1237               file = src->File; 
1238               if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src)
1239                   args[i] = c->output_regs[index].reg;
1240               else
1241                   args[i] = get_arg(c, inst, i);
1242           }
1243
1244       /* Get dest regs.  Note that it is possible for a reg to be both
1245        * dst and arg, given the static allocation of registers.  So
1246        * care needs to be taken emitting multi-operation instructions.
1247        */ 
1248       index = inst->DstReg.Index;
1249       file = inst->DstReg.File;
1250       if (file == PROGRAM_OUTPUT && c->output_regs[index].used_in_src)
1251           dst = c->output_regs[index].reg;
1252       else
1253           dst = get_dst(c, inst->DstReg);
1254
1255       if (inst->SaturateMode != SATURATE_OFF) {
1256          _mesa_problem(NULL, "Unsupported saturate %d in vertex shader",
1257                        inst->SaturateMode);
1258       }
1259
1260       switch (inst->Opcode) {
1261       case OPCODE_ABS:
1262          brw_MOV(p, dst, brw_abs(args[0]));
1263          break;
1264       case OPCODE_ADD:
1265          brw_ADD(p, dst, args[0], args[1]);
1266          break;
1267       case OPCODE_COS:
1268          emit_math1(c, BRW_MATH_FUNCTION_COS, dst, args[0], BRW_MATH_PRECISION_FULL);
1269          break;
1270       case OPCODE_DP3:
1271          brw_DP3(p, dst, args[0], args[1]);
1272          break;
1273       case OPCODE_DP4:
1274          brw_DP4(p, dst, args[0], args[1]);
1275          break;
1276       case OPCODE_DPH:
1277          brw_DPH(p, dst, args[0], args[1]);
1278          break;
1279       case OPCODE_NRM3:
1280          emit_nrm(c, dst, args[0], 3);
1281          break;
1282       case OPCODE_NRM4:
1283          emit_nrm(c, dst, args[0], 4);
1284          break;
1285       case OPCODE_DST:
1286          unalias2(c, dst, args[0], args[1], emit_dst_noalias); 
1287          break;
1288       case OPCODE_EXP:
1289          unalias1(c, dst, args[0], emit_exp_noalias);
1290          break;
1291       case OPCODE_EX2:
1292          emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, args[0], BRW_MATH_PRECISION_FULL);
1293          break;
1294       case OPCODE_ARL:
1295          emit_arl(c, dst, args[0]);
1296          break;
1297       case OPCODE_FLR:
1298          brw_RNDD(p, dst, args[0]);
1299          break;
1300       case OPCODE_FRC:
1301          brw_FRC(p, dst, args[0]);
1302          break;
1303       case OPCODE_LOG:
1304          unalias1(c, dst, args[0], emit_log_noalias);
1305          break;
1306       case OPCODE_LG2:
1307          emit_math1(c, BRW_MATH_FUNCTION_LOG, dst, args[0], BRW_MATH_PRECISION_FULL);
1308          break;
1309       case OPCODE_LIT:
1310          unalias1(c, dst, args[0], emit_lit_noalias);
1311          break;
1312       case OPCODE_LRP:
1313          unalias3(c, dst, args[0], args[1], args[2], emit_lrp_noalias);
1314          break;
1315       case OPCODE_MAD:
1316          brw_MOV(p, brw_acc_reg(), args[2]);
1317          brw_MAC(p, dst, args[0], args[1]);
1318          break;
1319       case OPCODE_MAX:
1320          emit_max(p, dst, args[0], args[1]);
1321          break;
1322       case OPCODE_MIN:
1323          emit_min(p, dst, args[0], args[1]);
1324          break;
1325       case OPCODE_MOV:
1326          brw_MOV(p, dst, args[0]);
1327          break;
1328       case OPCODE_MUL:
1329          brw_MUL(p, dst, args[0], args[1]);
1330          break;
1331       case OPCODE_POW:
1332          emit_math2(c, BRW_MATH_FUNCTION_POW, dst, args[0], args[1], BRW_MATH_PRECISION_FULL); 
1333          break;
1334       case OPCODE_RCP:
1335          emit_math1(c, BRW_MATH_FUNCTION_INV, dst, args[0], BRW_MATH_PRECISION_FULL);
1336          break;
1337       case OPCODE_RSQ:
1338          emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL);
1339          break;
1340
1341       case OPCODE_SEQ:
1342          emit_seq(p, dst, args[0], args[1]);
1343          break;
1344       case OPCODE_SIN:
1345          emit_math1(c, BRW_MATH_FUNCTION_SIN, dst, args[0], BRW_MATH_PRECISION_FULL);
1346          break;
1347       case OPCODE_SNE:
1348          emit_sne(p, dst, args[0], args[1]);
1349          break;
1350       case OPCODE_SGE:
1351          emit_sge(p, dst, args[0], args[1]);
1352          break;
1353       case OPCODE_SGT:
1354          emit_sgt(p, dst, args[0], args[1]);
1355          break;
1356       case OPCODE_SLT:
1357          emit_slt(p, dst, args[0], args[1]);
1358          break;
1359       case OPCODE_SLE:
1360          emit_sle(p, dst, args[0], args[1]);
1361          break;
1362       case OPCODE_SUB:
1363          brw_ADD(p, dst, args[0], negate(args[1]));
1364          break;
1365       case OPCODE_SWZ:
1366          /* The args[0] value can't be used here as it won't have
1367           * correctly encoded the full swizzle:
1368           */
1369          emit_swz(c, dst, inst);
1370          break;
1371       case OPCODE_TRUNC:
1372          /* round toward zero */
1373          brw_RNDZ(p, dst, args[0]);
1374          break;
1375       case OPCODE_XPD:
1376          emit_xpd(p, dst, args[0], args[1]);
1377          break;
1378       case OPCODE_IF:
1379          assert(if_insn < MAX_IFSN);
1380          if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
1381          break;
1382       case OPCODE_ELSE:
1383          if_inst[if_insn-1] = brw_ELSE(p, if_inst[if_insn-1]);
1384          break;
1385       case OPCODE_ENDIF:
1386          assert(if_insn > 0);
1387          brw_ENDIF(p, if_inst[--if_insn]);
1388          break;                 
1389       case OPCODE_BRA:
1390          brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
1391          brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
1392          brw_set_predicate_control_flag_value(p, 0xff);
1393          break;
1394       case OPCODE_CAL:
1395          brw_set_access_mode(p, BRW_ALIGN_1);
1396          brw_ADD(p, deref_1d(stack_index, 0), brw_ip_reg(), brw_imm_d(3*16));
1397          brw_set_access_mode(p, BRW_ALIGN_16);
1398          brw_ADD(p, get_addr_reg(stack_index),
1399                          get_addr_reg(stack_index), brw_imm_d(4));
1400          brw_save_call(p, inst->Comment, p->nr_insn);
1401          brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
1402          break;
1403       case OPCODE_RET:
1404          brw_ADD(p, get_addr_reg(stack_index),
1405                          get_addr_reg(stack_index), brw_imm_d(-4));
1406          brw_set_access_mode(p, BRW_ALIGN_1);
1407          brw_MOV(p, brw_ip_reg(), deref_1d(stack_index, 0));
1408          brw_set_access_mode(p, BRW_ALIGN_16);
1409          break;
1410       case OPCODE_END:  
1411          end_offset = p->nr_insn;
1412          /* this instruction will get patched later to jump past subroutine
1413           * code, etc.
1414           */
1415          brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
1416          break;
1417       case OPCODE_PRINT:
1418          /* no-op */
1419          break;
1420       case OPCODE_BGNSUB:
1421          brw_save_label(p, inst->Comment, p->nr_insn);
1422          break;
1423       case OPCODE_ENDSUB:
1424          /* no-op */
1425          break;
1426       default:
1427          _mesa_problem(NULL, "Unsupported opcode %i (%s) in vertex shader",
1428                        inst->Opcode, inst->Opcode < MAX_OPCODE ?
1429                                     _mesa_opcode_string(inst->Opcode) :
1430                                     "unknown");
1431       }
1432
1433       if ((inst->DstReg.File == PROGRAM_OUTPUT)
1434           && (inst->DstReg.Index != VERT_RESULT_HPOS)
1435           && c->output_regs[inst->DstReg.Index].used_in_src) {
1436          brw_MOV(p, get_dst(c, inst->DstReg), dst);
1437       }
1438
1439       /* Result color clamping.
1440        *
1441        * When destination register is an output register and
1442        * it's primary/secondary front/back color, we have to clamp
1443        * the result to [0,1]. This is done by enabling the
1444        * saturation bit for the last instruction.
1445        *
1446        * We don't use brw_set_saturate() as it modifies
1447        * p->current->header.saturate, which affects all the subsequent
1448        * instructions. Instead, we directly modify the header
1449        * of the last (already stored) instruction.
1450        */
1451       if (inst->DstReg.File == PROGRAM_OUTPUT) {
1452          if ((inst->DstReg.Index == VERT_RESULT_COL0)
1453              || (inst->DstReg.Index == VERT_RESULT_COL1)
1454              || (inst->DstReg.Index == VERT_RESULT_BFC0)
1455              || (inst->DstReg.Index == VERT_RESULT_BFC1)) {
1456             p->store[p->nr_insn-1].header.saturate = 1;
1457          }
1458       }
1459
1460       release_tmps(c);
1461    }
1462
1463    end_inst = &p->store[end_offset];
1464    last_inst = &p->store[p->nr_insn];
1465
1466    /* The END instruction will be patched to jump to this code */
1467    emit_vertex_write(c);
1468
1469    post_vs_emit(c, end_inst, last_inst);
1470 }