Merge branch 'master' into asm-shader-rework-1
[profile/ivi/mesa.git] / src / gallium / auxiliary / tgsi / tgsi_build.c
1 /**************************************************************************
2  * 
3  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * 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, sub license, 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 portions
16  * of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  * 
26  **************************************************************************/
27
28 #include "util/u_debug.h"
29 #include "pipe/p_shader_tokens.h"
30 #include "tgsi_build.h"
31 #include "tgsi_parse.h"
32
33 /*
34  * version
35  */
36
37 struct tgsi_version
38 tgsi_build_version( void )
39 {
40    struct tgsi_version  version;
41
42    version.MajorVersion = 1;
43    version.MinorVersion = 1;
44    version.Padding = 0;
45
46    return version;
47 }
48
49 /*
50  * header
51  */
52
53 struct tgsi_header
54 tgsi_build_header( void )
55 {
56    struct tgsi_header header;
57
58    header.HeaderSize = 1;
59    header.BodySize = 0;
60
61    return header;
62 }
63
64 static void
65 header_headersize_grow( struct tgsi_header *header )
66 {
67    assert( header->HeaderSize < 0xFF );
68    assert( header->BodySize == 0 );
69
70    header->HeaderSize++;
71 }
72
73 static void
74 header_bodysize_grow( struct tgsi_header *header )
75 {
76    assert( header->BodySize < 0xFFFFFF );
77
78    header->BodySize++;
79 }
80
81 struct tgsi_processor
82 tgsi_default_processor( void )
83 {
84    struct tgsi_processor processor;
85
86    processor.Processor = TGSI_PROCESSOR_FRAGMENT;
87    processor.Padding = 0;
88
89    return processor;
90 }
91
92 struct tgsi_processor
93 tgsi_build_processor(
94    unsigned type,
95    struct tgsi_header *header )
96 {
97    struct tgsi_processor processor;
98
99    processor = tgsi_default_processor();
100    processor.Processor = type;
101
102    header_headersize_grow( header );
103
104    return processor;
105 }
106
107 /*
108  * declaration
109  */
110
111 struct tgsi_declaration
112 tgsi_default_declaration( void )
113 {
114    struct tgsi_declaration declaration;
115
116    declaration.Type = TGSI_TOKEN_TYPE_DECLARATION;
117    declaration.NrTokens = 1;
118    declaration.File = TGSI_FILE_NULL;
119    declaration.UsageMask = TGSI_WRITEMASK_XYZW;
120    declaration.Interpolate = TGSI_INTERPOLATE_CONSTANT;
121    declaration.Semantic = 0;
122    declaration.Centroid = 0;
123    declaration.Invariant = 0;
124    declaration.Padding = 0;
125    declaration.Extended = 0;
126
127    return declaration;
128 }
129
130 struct tgsi_declaration
131 tgsi_build_declaration(
132    unsigned file,
133    unsigned usage_mask,
134    unsigned interpolate,
135    unsigned semantic,
136    unsigned centroid,
137    unsigned invariant,
138    struct tgsi_header *header )
139 {
140    struct tgsi_declaration declaration;
141
142    assert( file < TGSI_FILE_COUNT );
143    assert( interpolate < TGSI_INTERPOLATE_COUNT );
144
145    declaration = tgsi_default_declaration();
146    declaration.File = file;
147    declaration.UsageMask = usage_mask;
148    declaration.Interpolate = interpolate;
149    declaration.Semantic = semantic;
150    declaration.Centroid = centroid;
151    declaration.Invariant = invariant;
152
153    header_bodysize_grow( header );
154
155    return declaration;
156 }
157
158 static void
159 declaration_grow(
160    struct tgsi_declaration *declaration,
161    struct tgsi_header *header )
162 {
163    assert( declaration->NrTokens < 0xFF );
164
165    declaration->NrTokens++;
166
167    header_bodysize_grow( header );
168 }
169
170 struct tgsi_full_declaration
171 tgsi_default_full_declaration( void )
172 {
173    struct tgsi_full_declaration  full_declaration;
174
175    full_declaration.Declaration  = tgsi_default_declaration();
176    full_declaration.DeclarationRange = tgsi_default_declaration_range();
177    full_declaration.Semantic = tgsi_default_declaration_semantic();
178
179    return full_declaration;
180 }
181
182 unsigned
183 tgsi_build_full_declaration(
184    const struct tgsi_full_declaration *full_decl,
185    struct tgsi_token *tokens,
186    struct tgsi_header *header,
187    unsigned maxsize )
188 {
189    unsigned size = 0;
190    struct tgsi_declaration *declaration;
191    struct tgsi_declaration_range *dr;
192
193    if( maxsize <= size )
194      return 0;
195    declaration = (struct tgsi_declaration *) &tokens[size];
196    size++;
197
198    *declaration = tgsi_build_declaration(
199       full_decl->Declaration.File,
200       full_decl->Declaration.UsageMask,
201       full_decl->Declaration.Interpolate,
202       full_decl->Declaration.Semantic,
203       full_decl->Declaration.Centroid,
204       full_decl->Declaration.Invariant,
205       header );
206
207    if (maxsize <= size)
208       return 0;
209    dr = (struct tgsi_declaration_range *) &tokens[size];
210    size++;
211
212    *dr = tgsi_build_declaration_range(
213       full_decl->DeclarationRange.First,
214       full_decl->DeclarationRange.Last,
215       declaration,
216       header );
217
218    if( full_decl->Declaration.Semantic ) {
219       struct tgsi_declaration_semantic *ds;
220
221       if( maxsize <= size )
222          return  0;
223       ds = (struct tgsi_declaration_semantic *) &tokens[size];
224       size++;
225
226       *ds = tgsi_build_declaration_semantic(
227          full_decl->Semantic.SemanticName,
228          full_decl->Semantic.SemanticIndex,
229          declaration,
230          header );
231    }
232
233    return size;
234 }
235
236 struct tgsi_declaration_range
237 tgsi_default_declaration_range( void )
238 {
239    struct tgsi_declaration_range dr;
240
241    dr.First = 0;
242    dr.Last = 0;
243
244    return dr;
245 }
246
247 struct tgsi_declaration_range
248 tgsi_build_declaration_range(
249    unsigned first,
250    unsigned last,
251    struct tgsi_declaration *declaration,
252    struct tgsi_header *header )
253 {
254    struct tgsi_declaration_range declaration_range;
255
256    assert( last >= first );
257    assert( last <= 0xFFFF );
258
259    declaration_range = tgsi_default_declaration_range();
260    declaration_range.First = first;
261    declaration_range.Last = last;
262
263    declaration_grow( declaration, header );
264
265    return declaration_range;
266 }
267
268 struct tgsi_declaration_semantic
269 tgsi_default_declaration_semantic( void )
270 {
271    struct tgsi_declaration_semantic ds;
272
273    ds.SemanticName = TGSI_SEMANTIC_POSITION;
274    ds.SemanticIndex = 0;
275    ds.Padding = 0;
276
277    return ds;
278 }
279
280 struct tgsi_declaration_semantic
281 tgsi_build_declaration_semantic(
282    unsigned semantic_name,
283    unsigned semantic_index,
284    struct tgsi_declaration *declaration,
285    struct tgsi_header *header )
286 {
287    struct tgsi_declaration_semantic ds;
288
289    assert( semantic_name <= TGSI_SEMANTIC_COUNT );
290    assert( semantic_index <= 0xFFFF );
291
292    ds = tgsi_default_declaration_semantic();
293    ds.SemanticName = semantic_name;
294    ds.SemanticIndex = semantic_index;
295
296    declaration_grow( declaration, header );
297
298    return ds;
299 }
300
301 /*
302  * immediate
303  */
304
305 struct tgsi_immediate
306 tgsi_default_immediate( void )
307 {
308    struct tgsi_immediate immediate;
309
310    immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
311    immediate.NrTokens = 1;
312    immediate.DataType = TGSI_IMM_FLOAT32;
313    immediate.Padding = 0;
314    immediate.Extended = 0;
315
316    return immediate;
317 }
318
319 struct tgsi_immediate
320 tgsi_build_immediate(
321    struct tgsi_header *header )
322 {
323    struct tgsi_immediate immediate;
324
325    immediate = tgsi_default_immediate();
326
327    header_bodysize_grow( header );
328
329    return immediate;
330 }
331
332 struct tgsi_full_immediate
333 tgsi_default_full_immediate( void )
334 {
335    struct tgsi_full_immediate fullimm;
336
337    fullimm.Immediate = tgsi_default_immediate();
338    fullimm.u[0].Float = 0.0f;
339    fullimm.u[1].Float = 0.0f;
340    fullimm.u[2].Float = 0.0f;
341    fullimm.u[3].Float = 0.0f;
342
343    return fullimm;
344 }
345
346 static void
347 immediate_grow(
348    struct tgsi_immediate *immediate,
349    struct tgsi_header *header )
350 {
351    assert( immediate->NrTokens < 0xFF );
352
353    immediate->NrTokens++;
354
355    header_bodysize_grow( header );
356 }
357
358 union tgsi_immediate_data
359 tgsi_build_immediate_float32(
360    float value,
361    struct tgsi_immediate *immediate,
362    struct tgsi_header *header )
363 {
364    union tgsi_immediate_data immediate_data;
365
366    immediate_data.Float = value;
367
368    immediate_grow( immediate, header );
369
370    return immediate_data;
371 }
372
373 unsigned
374 tgsi_build_full_immediate(
375    const struct tgsi_full_immediate *full_imm,
376    struct tgsi_token *tokens,
377    struct tgsi_header *header,
378    unsigned maxsize )
379 {
380    unsigned size = 0, i;
381    struct tgsi_immediate *immediate;
382
383    if( maxsize <= size )
384       return 0;
385    immediate = (struct tgsi_immediate *) &tokens[size];
386    size++;
387
388    *immediate = tgsi_build_immediate( header );
389
390    assert( full_imm->Immediate.NrTokens <= 4 + 1 );
391
392    for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) {
393       union tgsi_immediate_data *data;
394
395       if( maxsize <= size )
396          return  0;
397       data = (union tgsi_immediate_data *) &tokens[size];
398       size++;
399
400       *data = tgsi_build_immediate_float32(
401          full_imm->u[i].Float,
402          immediate,
403          header );
404    }
405
406    return size;
407 }
408
409 /*
410  * instruction
411  */
412
413 struct tgsi_instruction
414 tgsi_default_instruction( void )
415 {
416    struct tgsi_instruction instruction;
417
418    instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
419    instruction.NrTokens = 1;
420    instruction.Opcode = TGSI_OPCODE_MOV;
421    instruction.Saturate = TGSI_SAT_NONE;
422    instruction.NumDstRegs = 1;
423    instruction.NumSrcRegs = 1;
424    instruction.Padding  = 0;
425    instruction.Extended = 0;
426
427    return instruction;
428 }
429
430 struct tgsi_instruction
431 tgsi_build_instruction(
432    unsigned opcode,
433    unsigned saturate,
434    unsigned num_dst_regs,
435    unsigned num_src_regs,
436    struct tgsi_header *header )
437 {
438    struct tgsi_instruction instruction;
439
440    assert (opcode <= TGSI_OPCODE_LAST);
441    assert (saturate <= TGSI_SAT_MINUS_PLUS_ONE);
442    assert (num_dst_regs <= 3);
443    assert (num_src_regs <= 15);
444
445    instruction = tgsi_default_instruction();
446    instruction.Opcode = opcode;
447    instruction.Saturate = saturate;
448    instruction.NumDstRegs = num_dst_regs;
449    instruction.NumSrcRegs = num_src_regs;
450
451    header_bodysize_grow( header );
452
453    return instruction;
454 }
455
456 static void
457 instruction_grow(
458    struct tgsi_instruction *instruction,
459    struct tgsi_header *header )
460 {
461    assert (instruction->NrTokens <   0xFF);
462
463    instruction->NrTokens++;
464
465    header_bodysize_grow( header );
466 }
467
468 struct tgsi_full_instruction
469 tgsi_default_full_instruction( void )
470 {
471    struct tgsi_full_instruction full_instruction;
472    unsigned i;
473
474    full_instruction.Instruction = tgsi_default_instruction();
475    full_instruction.InstructionExtNv = tgsi_default_instruction_ext_nv();
476    full_instruction.InstructionExtLabel = tgsi_default_instruction_ext_label();
477    full_instruction.InstructionExtTexture = tgsi_default_instruction_ext_texture();
478    for( i = 0;  i < TGSI_FULL_MAX_DST_REGISTERS; i++ ) {
479       full_instruction.FullDstRegisters[i] = tgsi_default_full_dst_register();
480    }
481    for( i = 0;  i < TGSI_FULL_MAX_SRC_REGISTERS; i++ ) {
482       full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register();
483    }
484
485    return full_instruction;
486 }
487
488 unsigned
489 tgsi_build_full_instruction(
490    const struct tgsi_full_instruction *full_inst,
491    struct  tgsi_token *tokens,
492    struct  tgsi_header *header,
493    unsigned  maxsize )
494 {
495    unsigned size = 0;
496    unsigned i;
497    struct tgsi_instruction *instruction;
498    struct tgsi_token *prev_token;
499
500    if( maxsize <= size )
501       return 0;
502    instruction = (struct tgsi_instruction *) &tokens[size];
503    size++;
504
505    *instruction = tgsi_build_instruction(
506       full_inst->Instruction.Opcode,
507       full_inst->Instruction.Saturate,
508       full_inst->Instruction.NumDstRegs,
509       full_inst->Instruction.NumSrcRegs,
510       header );
511    prev_token = (struct tgsi_token  *) instruction;
512
513    if( tgsi_compare_instruction_ext_nv(
514          full_inst->InstructionExtNv,
515          tgsi_default_instruction_ext_nv() ) ) {
516       struct tgsi_instruction_ext_nv *instruction_ext_nv;
517
518       if( maxsize <= size )
519          return 0;
520       instruction_ext_nv =
521          (struct  tgsi_instruction_ext_nv *) &tokens[size];
522       size++;
523
524       *instruction_ext_nv  = tgsi_build_instruction_ext_nv(
525          full_inst->InstructionExtNv.Precision,
526          full_inst->InstructionExtNv.CondDstIndex,
527          full_inst->InstructionExtNv.CondFlowIndex,
528          full_inst->InstructionExtNv.CondMask,
529          full_inst->InstructionExtNv.CondSwizzleX,
530          full_inst->InstructionExtNv.CondSwizzleY,
531          full_inst->InstructionExtNv.CondSwizzleZ,
532          full_inst->InstructionExtNv.CondSwizzleW,
533          full_inst->InstructionExtNv.CondDstUpdate,
534          full_inst->InstructionExtNv.CondFlowEnable,
535          prev_token,
536          instruction,
537          header );
538       prev_token = (struct tgsi_token  *) instruction_ext_nv;
539    }
540
541    if( tgsi_compare_instruction_ext_label(
542          full_inst->InstructionExtLabel,
543          tgsi_default_instruction_ext_label() ) ) {
544       struct tgsi_instruction_ext_label *instruction_ext_label;
545
546       if( maxsize <= size )
547          return 0;
548       instruction_ext_label =
549          (struct  tgsi_instruction_ext_label *) &tokens[size];
550       size++;
551
552       *instruction_ext_label = tgsi_build_instruction_ext_label(
553          full_inst->InstructionExtLabel.Label,
554          prev_token,
555          instruction,
556          header );
557       prev_token = (struct tgsi_token  *) instruction_ext_label;
558    }
559
560    if( tgsi_compare_instruction_ext_texture(
561          full_inst->InstructionExtTexture,
562          tgsi_default_instruction_ext_texture() ) ) {
563       struct tgsi_instruction_ext_texture *instruction_ext_texture;
564
565       if( maxsize <= size )
566          return 0;
567       instruction_ext_texture =
568          (struct  tgsi_instruction_ext_texture *) &tokens[size];
569       size++;
570
571       *instruction_ext_texture = tgsi_build_instruction_ext_texture(
572          full_inst->InstructionExtTexture.Texture,
573          prev_token,
574          instruction,
575          header   );
576       prev_token = (struct tgsi_token  *) instruction_ext_texture;
577    }
578
579    for( i = 0;  i <   full_inst->Instruction.NumDstRegs; i++ ) {
580       const struct tgsi_full_dst_register *reg = &full_inst->FullDstRegisters[i];
581       struct tgsi_dst_register *dst_register;
582       struct tgsi_token *prev_token;
583
584       if( maxsize <= size )
585          return 0;
586       dst_register = (struct tgsi_dst_register *) &tokens[size];
587       size++;
588
589       *dst_register = tgsi_build_dst_register(
590          reg->DstRegister.File,
591          reg->DstRegister.WriteMask,
592          reg->DstRegister.Indirect,
593          reg->DstRegister.Index,
594          instruction,
595          header );
596       prev_token = (struct tgsi_token  *) dst_register;
597
598       if( tgsi_compare_dst_register_ext_concode(
599             reg->DstRegisterExtConcode,
600             tgsi_default_dst_register_ext_concode() ) ) {
601          struct tgsi_dst_register_ext_concode *dst_register_ext_concode;
602
603          if( maxsize <= size )
604             return 0;
605          dst_register_ext_concode =
606             (struct  tgsi_dst_register_ext_concode *) &tokens[size];
607          size++;
608
609          *dst_register_ext_concode =   tgsi_build_dst_register_ext_concode(
610             reg->DstRegisterExtConcode.CondMask,
611             reg->DstRegisterExtConcode.CondSwizzleX,
612             reg->DstRegisterExtConcode.CondSwizzleY,
613             reg->DstRegisterExtConcode.CondSwizzleZ,
614             reg->DstRegisterExtConcode.CondSwizzleW,
615             reg->DstRegisterExtConcode.CondSrcIndex,
616             prev_token,
617             instruction,
618             header );
619          prev_token = (struct tgsi_token  *) dst_register_ext_concode;
620       }
621
622       if( tgsi_compare_dst_register_ext_modulate(
623             reg->DstRegisterExtModulate,
624             tgsi_default_dst_register_ext_modulate() ) ) {
625          struct tgsi_dst_register_ext_modulate *dst_register_ext_modulate;
626
627          if( maxsize <= size )
628             return 0;
629          dst_register_ext_modulate =
630             (struct  tgsi_dst_register_ext_modulate *) &tokens[size];
631          size++;
632
633          *dst_register_ext_modulate = tgsi_build_dst_register_ext_modulate(
634             reg->DstRegisterExtModulate.Modulate,
635             prev_token,
636             instruction,
637             header );
638          prev_token = (struct tgsi_token  *) dst_register_ext_modulate;
639       }
640
641       if( reg->DstRegister.Indirect ) {
642          struct tgsi_src_register *ind;
643
644          if( maxsize <= size )
645             return 0;
646          ind = (struct tgsi_src_register *) &tokens[size];
647          size++;
648
649          *ind = tgsi_build_src_register(
650             reg->DstRegisterInd.File,
651             reg->DstRegisterInd.SwizzleX,
652             reg->DstRegisterInd.SwizzleY,
653             reg->DstRegisterInd.SwizzleZ,
654             reg->DstRegisterInd.SwizzleW,
655             reg->DstRegisterInd.Negate,
656             reg->DstRegisterInd.Indirect,
657             reg->DstRegisterInd.Dimension,
658             reg->DstRegisterInd.Index,
659             instruction,
660             header );
661       }
662    }
663
664    for( i = 0;  i < full_inst->Instruction.NumSrcRegs; i++ ) {
665       const struct tgsi_full_src_register *reg = &full_inst->FullSrcRegisters[i];
666       struct tgsi_src_register *src_register;
667       struct tgsi_token *prev_token;
668
669       if( maxsize <= size )
670          return 0;
671       src_register = (struct tgsi_src_register *)  &tokens[size];
672       size++;
673
674       *src_register = tgsi_build_src_register(
675          reg->SrcRegister.File,
676          reg->SrcRegister.SwizzleX,
677          reg->SrcRegister.SwizzleY,
678          reg->SrcRegister.SwizzleZ,
679          reg->SrcRegister.SwizzleW,
680          reg->SrcRegister.Negate,
681          reg->SrcRegister.Indirect,
682          reg->SrcRegister.Dimension,
683          reg->SrcRegister.Index,
684          instruction,
685          header );
686       prev_token = (struct tgsi_token  *) src_register;
687
688       if( tgsi_compare_src_register_ext_swz(
689             reg->SrcRegisterExtSwz,
690             tgsi_default_src_register_ext_swz() ) ) {
691          struct tgsi_src_register_ext_swz *src_register_ext_swz;
692
693          /* Use of the extended swizzle requires the simple swizzle to be identity.
694           */
695          assert( reg->SrcRegister.SwizzleX == TGSI_SWIZZLE_X );
696          assert( reg->SrcRegister.SwizzleY == TGSI_SWIZZLE_Y );
697          assert( reg->SrcRegister.SwizzleZ == TGSI_SWIZZLE_Z );
698          assert( reg->SrcRegister.SwizzleW == TGSI_SWIZZLE_W );
699          assert( reg->SrcRegister.Negate == FALSE );
700
701          if( maxsize <= size )
702             return 0;
703          src_register_ext_swz =
704             (struct  tgsi_src_register_ext_swz *) &tokens[size];
705          size++;
706
707          *src_register_ext_swz = tgsi_build_src_register_ext_swz(
708             reg->SrcRegisterExtSwz.ExtSwizzleX,
709             reg->SrcRegisterExtSwz.ExtSwizzleY,
710             reg->SrcRegisterExtSwz.ExtSwizzleZ,
711             reg->SrcRegisterExtSwz.ExtSwizzleW,
712             reg->SrcRegisterExtSwz.NegateX,
713             reg->SrcRegisterExtSwz.NegateY,
714             reg->SrcRegisterExtSwz.NegateZ,
715             reg->SrcRegisterExtSwz.NegateW,
716             prev_token,
717             instruction,
718             header );
719          prev_token = (struct tgsi_token  *) src_register_ext_swz;
720       }
721
722       if( tgsi_compare_src_register_ext_mod(
723             reg->SrcRegisterExtMod,
724             tgsi_default_src_register_ext_mod() ) ) {
725          struct tgsi_src_register_ext_mod *src_register_ext_mod;
726
727          if( maxsize <= size )
728             return 0;
729          src_register_ext_mod =
730             (struct  tgsi_src_register_ext_mod *) &tokens[size];
731          size++;
732
733          *src_register_ext_mod = tgsi_build_src_register_ext_mod(
734             reg->SrcRegisterExtMod.Complement,
735             reg->SrcRegisterExtMod.Bias,
736             reg->SrcRegisterExtMod.Scale2X,
737             reg->SrcRegisterExtMod.Absolute,
738             reg->SrcRegisterExtMod.Negate,
739             prev_token,
740             instruction,
741             header );
742          prev_token = (struct tgsi_token  *) src_register_ext_mod;
743       }
744
745       if( reg->SrcRegister.Indirect ) {
746          struct  tgsi_src_register *ind;
747
748          if( maxsize <= size )
749             return 0;
750          ind = (struct tgsi_src_register *) &tokens[size];
751          size++;
752
753          *ind = tgsi_build_src_register(
754             reg->SrcRegisterInd.File,
755             reg->SrcRegisterInd.SwizzleX,
756             reg->SrcRegisterInd.SwizzleY,
757             reg->SrcRegisterInd.SwizzleZ,
758             reg->SrcRegisterInd.SwizzleW,
759             reg->SrcRegisterInd.Negate,
760             reg->SrcRegisterInd.Indirect,
761             reg->SrcRegisterInd.Dimension,
762             reg->SrcRegisterInd.Index,
763             instruction,
764             header );
765       }
766
767       if( reg->SrcRegister.Dimension ) {
768          struct  tgsi_dimension *dim;
769
770          assert( !reg->SrcRegisterDim.Dimension );
771
772          if( maxsize <= size )
773             return 0;
774          dim = (struct tgsi_dimension *) &tokens[size];
775          size++;
776
777          *dim = tgsi_build_dimension(
778             reg->SrcRegisterDim.Indirect,
779             reg->SrcRegisterDim.Index,
780             instruction,
781             header );
782
783          if( reg->SrcRegisterDim.Indirect ) {
784             struct tgsi_src_register *ind;
785
786             if( maxsize <= size )
787                return 0;
788             ind = (struct tgsi_src_register *) &tokens[size];
789             size++;
790
791             *ind = tgsi_build_src_register(
792                reg->SrcRegisterDimInd.File,
793                reg->SrcRegisterDimInd.SwizzleX,
794                reg->SrcRegisterDimInd.SwizzleY,
795                reg->SrcRegisterDimInd.SwizzleZ,
796                reg->SrcRegisterDimInd.SwizzleW,
797                reg->SrcRegisterDimInd.Negate,
798                reg->SrcRegisterDimInd.Indirect,
799                reg->SrcRegisterDimInd.Dimension,
800                reg->SrcRegisterDimInd.Index,
801                instruction,
802                header );
803          }
804       }
805    }
806
807    return size;
808 }
809
810 struct tgsi_instruction_ext_nv
811 tgsi_default_instruction_ext_nv( void )
812 {
813    struct tgsi_instruction_ext_nv instruction_ext_nv;
814
815    instruction_ext_nv.Type = TGSI_INSTRUCTION_EXT_TYPE_NV;
816    instruction_ext_nv.Precision = TGSI_PRECISION_DEFAULT;
817    instruction_ext_nv.CondDstIndex = 0;
818    instruction_ext_nv.CondFlowIndex = 0;
819    instruction_ext_nv.CondMask = TGSI_CC_TR;
820    instruction_ext_nv.CondSwizzleX = TGSI_SWIZZLE_X;
821    instruction_ext_nv.CondSwizzleY = TGSI_SWIZZLE_Y;
822    instruction_ext_nv.CondSwizzleZ = TGSI_SWIZZLE_Z;
823    instruction_ext_nv.CondSwizzleW = TGSI_SWIZZLE_W;
824    instruction_ext_nv.CondDstUpdate = 0;
825    instruction_ext_nv.CondFlowEnable = 0;
826    instruction_ext_nv.Padding = 0;
827    instruction_ext_nv.Extended = 0;
828
829    return instruction_ext_nv;
830 }
831
832
833 /** test for inequality of 32-bit values pointed to by a and b */
834 static INLINE boolean
835 compare32(const void *a, const void *b)
836 {
837    return *((uint32_t *) a) != *((uint32_t *) b);
838 }
839
840
841 unsigned
842 tgsi_compare_instruction_ext_nv(
843    struct tgsi_instruction_ext_nv a,
844    struct tgsi_instruction_ext_nv b )
845 {
846    a.Padding = b.Padding = 0;
847    a.Extended = b.Extended = 0;
848    return compare32(&a, &b);
849 }
850
851 struct tgsi_instruction_ext_nv
852 tgsi_build_instruction_ext_nv(
853    unsigned precision,
854    unsigned cond_dst_index,
855    unsigned cond_flow_index,
856    unsigned cond_mask,
857    unsigned cond_swizzle_x,
858    unsigned cond_swizzle_y,
859    unsigned cond_swizzle_z,
860    unsigned cond_swizzle_w,
861    unsigned cond_dst_update,
862    unsigned cond_flow_enable,
863    struct tgsi_token *prev_token,
864    struct tgsi_instruction *instruction,
865    struct tgsi_header *header )
866 {
867    struct tgsi_instruction_ext_nv instruction_ext_nv;
868
869    instruction_ext_nv = tgsi_default_instruction_ext_nv();
870    instruction_ext_nv.Precision = precision;
871    instruction_ext_nv.CondDstIndex = cond_dst_index;
872    instruction_ext_nv.CondFlowIndex = cond_flow_index;
873    instruction_ext_nv.CondMask = cond_mask;
874    instruction_ext_nv.CondSwizzleX = cond_swizzle_x;
875    instruction_ext_nv.CondSwizzleY = cond_swizzle_y;
876    instruction_ext_nv.CondSwizzleZ = cond_swizzle_z;
877    instruction_ext_nv.CondSwizzleW = cond_swizzle_w;
878    instruction_ext_nv.CondDstUpdate = cond_dst_update;
879    instruction_ext_nv.CondFlowEnable = cond_flow_enable;
880
881    prev_token->Extended = 1;
882    instruction_grow( instruction, header );
883
884    return instruction_ext_nv;
885 }
886
887 struct tgsi_instruction_ext_label
888 tgsi_default_instruction_ext_label( void )
889 {
890    struct tgsi_instruction_ext_label instruction_ext_label;
891
892    instruction_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL;
893    instruction_ext_label.Label = 0;
894    instruction_ext_label.Padding = 0;
895    instruction_ext_label.Extended = 0;
896
897    return instruction_ext_label;
898 }
899
900 unsigned
901 tgsi_compare_instruction_ext_label(
902    struct tgsi_instruction_ext_label a,
903    struct tgsi_instruction_ext_label b )
904 {
905    a.Padding = b.Padding = 0;
906    a.Extended = b.Extended = 0;
907    return compare32(&a, &b);
908 }
909
910 struct tgsi_instruction_ext_label
911 tgsi_build_instruction_ext_label(
912    unsigned label,
913    struct tgsi_token  *prev_token,
914    struct tgsi_instruction *instruction,
915    struct tgsi_header *header )
916 {
917    struct tgsi_instruction_ext_label instruction_ext_label;
918
919    instruction_ext_label = tgsi_default_instruction_ext_label();
920    instruction_ext_label.Label = label;
921
922    prev_token->Extended = 1;
923    instruction_grow( instruction, header );
924
925    return instruction_ext_label;
926 }
927
928 struct tgsi_instruction_ext_texture
929 tgsi_default_instruction_ext_texture( void )
930 {
931    struct tgsi_instruction_ext_texture instruction_ext_texture;
932
933    instruction_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE;
934    instruction_ext_texture.Texture = TGSI_TEXTURE_UNKNOWN;
935    instruction_ext_texture.Padding = 0;
936    instruction_ext_texture.Extended = 0;
937
938    return instruction_ext_texture;
939 }
940
941 unsigned
942 tgsi_compare_instruction_ext_texture(
943    struct tgsi_instruction_ext_texture a,
944    struct tgsi_instruction_ext_texture b )
945 {
946    a.Padding = b.Padding = 0;
947    a.Extended = b.Extended = 0;
948    return compare32(&a, &b);
949 }
950
951 struct tgsi_instruction_ext_texture
952 tgsi_build_instruction_ext_texture(
953    unsigned texture,
954    struct tgsi_token *prev_token,
955    struct tgsi_instruction *instruction,
956    struct tgsi_header *header )
957 {
958    struct tgsi_instruction_ext_texture instruction_ext_texture;
959
960    instruction_ext_texture = tgsi_default_instruction_ext_texture();
961    instruction_ext_texture.Texture = texture;
962
963    prev_token->Extended = 1;
964    instruction_grow( instruction, header );
965
966    return instruction_ext_texture;
967 }
968
969 struct tgsi_src_register
970 tgsi_default_src_register( void )
971 {
972    struct tgsi_src_register src_register;
973
974    src_register.File = TGSI_FILE_NULL;
975    src_register.SwizzleX = TGSI_SWIZZLE_X;
976    src_register.SwizzleY = TGSI_SWIZZLE_Y;
977    src_register.SwizzleZ = TGSI_SWIZZLE_Z;
978    src_register.SwizzleW = TGSI_SWIZZLE_W;
979    src_register.Negate = 0;
980    src_register.Indirect = 0;
981    src_register.Dimension = 0;
982    src_register.Index = 0;
983    src_register.Extended = 0;
984
985    return src_register;
986 }
987
988 struct tgsi_src_register
989 tgsi_build_src_register(
990    unsigned file,
991    unsigned swizzle_x,
992    unsigned swizzle_y,
993    unsigned swizzle_z,
994    unsigned swizzle_w,
995    unsigned negate,
996    unsigned indirect,
997    unsigned dimension,
998    int index,
999    struct tgsi_instruction *instruction,
1000    struct tgsi_header *header )
1001 {
1002    struct tgsi_src_register   src_register;
1003
1004    assert( file < TGSI_FILE_COUNT );
1005    assert( swizzle_x <= TGSI_SWIZZLE_W );
1006    assert( swizzle_y <= TGSI_SWIZZLE_W );
1007    assert( swizzle_z <= TGSI_SWIZZLE_W );
1008    assert( swizzle_w <= TGSI_SWIZZLE_W );
1009    assert( negate <= 1 );
1010    assert( index >= -0x8000 && index <= 0x7FFF );
1011
1012    src_register = tgsi_default_src_register();
1013    src_register.File = file;
1014    src_register.SwizzleX = swizzle_x;
1015    src_register.SwizzleY = swizzle_y;
1016    src_register.SwizzleZ = swizzle_z;
1017    src_register.SwizzleW = swizzle_w;
1018    src_register.Negate = negate;
1019    src_register.Indirect = indirect;
1020    src_register.Dimension = dimension;
1021    src_register.Index = index;
1022
1023    instruction_grow( instruction, header );
1024
1025    return src_register;
1026 }
1027
1028 struct tgsi_full_src_register
1029 tgsi_default_full_src_register( void )
1030 {
1031    struct tgsi_full_src_register full_src_register;
1032
1033    full_src_register.SrcRegister = tgsi_default_src_register();
1034    full_src_register.SrcRegisterExtSwz = tgsi_default_src_register_ext_swz();
1035    full_src_register.SrcRegisterExtMod = tgsi_default_src_register_ext_mod();
1036    full_src_register.SrcRegisterInd = tgsi_default_src_register();
1037    full_src_register.SrcRegisterDim = tgsi_default_dimension();
1038    full_src_register.SrcRegisterDimInd = tgsi_default_src_register();
1039
1040    return full_src_register;
1041 }
1042
1043 struct tgsi_src_register_ext_swz
1044 tgsi_default_src_register_ext_swz( void )
1045 {
1046    struct tgsi_src_register_ext_swz src_register_ext_swz;
1047
1048    src_register_ext_swz.Type = TGSI_SRC_REGISTER_EXT_TYPE_SWZ;
1049    src_register_ext_swz.ExtSwizzleX = TGSI_EXTSWIZZLE_X;
1050    src_register_ext_swz.ExtSwizzleY = TGSI_EXTSWIZZLE_Y;
1051    src_register_ext_swz.ExtSwizzleZ = TGSI_EXTSWIZZLE_Z;
1052    src_register_ext_swz.ExtSwizzleW = TGSI_EXTSWIZZLE_W;
1053    src_register_ext_swz.NegateX = 0;
1054    src_register_ext_swz.NegateY = 0;
1055    src_register_ext_swz.NegateZ = 0;
1056    src_register_ext_swz.NegateW = 0;
1057    src_register_ext_swz.Padding = 0;
1058    src_register_ext_swz.Extended = 0;
1059
1060    return src_register_ext_swz;
1061 }
1062
1063 unsigned
1064 tgsi_compare_src_register_ext_swz(
1065    struct tgsi_src_register_ext_swz a,
1066    struct tgsi_src_register_ext_swz b )
1067 {
1068    a.Padding = b.Padding = 0;
1069    a.Extended = b.Extended = 0;
1070    return compare32(&a, &b);
1071 }
1072
1073 struct tgsi_src_register_ext_swz
1074 tgsi_build_src_register_ext_swz(
1075    unsigned ext_swizzle_x,
1076    unsigned ext_swizzle_y,
1077    unsigned ext_swizzle_z,
1078    unsigned ext_swizzle_w,
1079    unsigned negate_x,
1080    unsigned negate_y,
1081    unsigned negate_z,
1082    unsigned negate_w,
1083    struct tgsi_token *prev_token,
1084    struct tgsi_instruction *instruction,
1085    struct tgsi_header *header )
1086 {
1087    struct tgsi_src_register_ext_swz src_register_ext_swz;
1088
1089    assert( ext_swizzle_x <= TGSI_EXTSWIZZLE_ONE );
1090    assert( ext_swizzle_y <= TGSI_EXTSWIZZLE_ONE );
1091    assert( ext_swizzle_z <= TGSI_EXTSWIZZLE_ONE );
1092    assert( ext_swizzle_w <= TGSI_EXTSWIZZLE_ONE );
1093    assert( negate_x <= 1 );
1094    assert( negate_y <= 1 );
1095    assert( negate_z <= 1 );
1096    assert( negate_w <= 1 );
1097
1098    src_register_ext_swz = tgsi_default_src_register_ext_swz();
1099    src_register_ext_swz.ExtSwizzleX = ext_swizzle_x;
1100    src_register_ext_swz.ExtSwizzleY = ext_swizzle_y;
1101    src_register_ext_swz.ExtSwizzleZ = ext_swizzle_z;
1102    src_register_ext_swz.ExtSwizzleW = ext_swizzle_w;
1103    src_register_ext_swz.NegateX = negate_x;
1104    src_register_ext_swz.NegateY = negate_y;
1105    src_register_ext_swz.NegateZ = negate_z;
1106    src_register_ext_swz.NegateW = negate_w;
1107
1108    prev_token->Extended = 1;
1109    instruction_grow( instruction, header );
1110
1111    return src_register_ext_swz;
1112 }
1113
1114 struct tgsi_src_register_ext_mod
1115 tgsi_default_src_register_ext_mod( void )
1116 {
1117    struct tgsi_src_register_ext_mod src_register_ext_mod;
1118
1119    src_register_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD;
1120    src_register_ext_mod.Complement = 0;
1121    src_register_ext_mod.Bias = 0;
1122    src_register_ext_mod.Scale2X = 0;
1123    src_register_ext_mod.Absolute = 0;
1124    src_register_ext_mod.Negate = 0;
1125    src_register_ext_mod.Padding = 0;
1126    src_register_ext_mod.Extended = 0;
1127
1128    return src_register_ext_mod;
1129 }
1130
1131 unsigned
1132 tgsi_compare_src_register_ext_mod(
1133    struct tgsi_src_register_ext_mod a,
1134    struct tgsi_src_register_ext_mod b )
1135 {
1136    a.Padding = b.Padding = 0;
1137    a.Extended = b.Extended = 0;
1138    return compare32(&a, &b);
1139 }
1140
1141 struct tgsi_src_register_ext_mod
1142 tgsi_build_src_register_ext_mod(
1143    unsigned complement,
1144    unsigned bias,
1145    unsigned scale_2x,
1146    unsigned absolute,
1147    unsigned negate,
1148    struct tgsi_token *prev_token,
1149    struct tgsi_instruction *instruction,
1150    struct tgsi_header *header )
1151 {
1152    struct tgsi_src_register_ext_mod src_register_ext_mod;
1153
1154    assert( complement <= 1 );
1155    assert( bias <= 1 );
1156    assert( scale_2x <= 1 );
1157    assert( absolute <= 1 );
1158    assert( negate <= 1 );
1159
1160    src_register_ext_mod = tgsi_default_src_register_ext_mod();
1161    src_register_ext_mod.Complement = complement;
1162    src_register_ext_mod.Bias = bias;
1163    src_register_ext_mod.Scale2X = scale_2x;
1164    src_register_ext_mod.Absolute = absolute;
1165    src_register_ext_mod.Negate = negate;
1166
1167    prev_token->Extended = 1;
1168    instruction_grow( instruction, header );
1169
1170    return src_register_ext_mod;
1171 }
1172
1173 struct tgsi_dimension
1174 tgsi_default_dimension( void )
1175 {
1176    struct tgsi_dimension dimension;
1177
1178    dimension.Indirect = 0;
1179    dimension.Dimension = 0;
1180    dimension.Padding = 0;
1181    dimension.Index = 0;
1182    dimension.Extended = 0;
1183
1184    return dimension;
1185 }
1186
1187 struct tgsi_dimension
1188 tgsi_build_dimension(
1189    unsigned indirect,
1190    unsigned index,
1191    struct tgsi_instruction *instruction,
1192    struct tgsi_header *header )
1193 {
1194    struct tgsi_dimension dimension;
1195
1196    dimension = tgsi_default_dimension();
1197    dimension.Indirect = indirect;
1198    dimension.Index = index;
1199
1200    instruction_grow( instruction, header );
1201
1202    return dimension;
1203 }
1204
1205 struct tgsi_dst_register
1206 tgsi_default_dst_register( void )
1207 {
1208    struct tgsi_dst_register dst_register;
1209
1210    dst_register.File = TGSI_FILE_NULL;
1211    dst_register.WriteMask = TGSI_WRITEMASK_XYZW;
1212    dst_register.Indirect = 0;
1213    dst_register.Dimension = 0;
1214    dst_register.Index = 0;
1215    dst_register.Padding = 0;
1216    dst_register.Extended = 0;
1217
1218    return dst_register;
1219 }
1220
1221 struct tgsi_dst_register
1222 tgsi_build_dst_register(
1223    unsigned file,
1224    unsigned mask,
1225    unsigned indirect,
1226    int index,
1227    struct tgsi_instruction *instruction,
1228    struct tgsi_header *header )
1229 {
1230    struct tgsi_dst_register dst_register;
1231
1232    assert( file < TGSI_FILE_COUNT );
1233    assert( mask <= TGSI_WRITEMASK_XYZW );
1234    assert( index >= -32768 && index <= 32767 );
1235
1236    dst_register = tgsi_default_dst_register();
1237    dst_register.File = file;
1238    dst_register.WriteMask = mask;
1239    dst_register.Index = index;
1240    dst_register.Indirect = indirect;
1241
1242    instruction_grow( instruction, header );
1243
1244    return dst_register;
1245 }
1246
1247 struct tgsi_full_dst_register
1248 tgsi_default_full_dst_register( void )
1249 {
1250    struct tgsi_full_dst_register full_dst_register;
1251
1252    full_dst_register.DstRegister = tgsi_default_dst_register();
1253    full_dst_register.DstRegisterInd = tgsi_default_src_register();
1254    full_dst_register.DstRegisterExtConcode =
1255       tgsi_default_dst_register_ext_concode();
1256    full_dst_register.DstRegisterExtModulate =
1257       tgsi_default_dst_register_ext_modulate();
1258
1259    return full_dst_register;
1260 }
1261
1262 struct tgsi_dst_register_ext_concode
1263 tgsi_default_dst_register_ext_concode( void )
1264 {
1265    struct tgsi_dst_register_ext_concode dst_register_ext_concode;
1266
1267    dst_register_ext_concode.Type = TGSI_DST_REGISTER_EXT_TYPE_CONDCODE;
1268    dst_register_ext_concode.CondMask = TGSI_CC_TR;
1269    dst_register_ext_concode.CondSwizzleX = TGSI_SWIZZLE_X;
1270    dst_register_ext_concode.CondSwizzleY = TGSI_SWIZZLE_Y;
1271    dst_register_ext_concode.CondSwizzleZ = TGSI_SWIZZLE_Z;
1272    dst_register_ext_concode.CondSwizzleW = TGSI_SWIZZLE_W;
1273    dst_register_ext_concode.CondSrcIndex = 0;
1274    dst_register_ext_concode.Padding = 0;
1275    dst_register_ext_concode.Extended = 0;
1276
1277    return dst_register_ext_concode;
1278 }
1279
1280 unsigned
1281 tgsi_compare_dst_register_ext_concode(
1282    struct tgsi_dst_register_ext_concode a,
1283    struct tgsi_dst_register_ext_concode b )
1284 {
1285    a.Padding = b.Padding = 0;
1286    a.Extended = b.Extended = 0;
1287    return compare32(&a, &b);
1288 }
1289
1290 struct tgsi_dst_register_ext_concode
1291 tgsi_build_dst_register_ext_concode(
1292    unsigned cc,
1293    unsigned swizzle_x,
1294    unsigned swizzle_y,
1295    unsigned swizzle_z,
1296    unsigned swizzle_w,
1297    int index,
1298    struct tgsi_token *prev_token,
1299    struct tgsi_instruction *instruction,
1300    struct tgsi_header *header )
1301 {
1302    struct tgsi_dst_register_ext_concode dst_register_ext_concode;
1303
1304    assert( cc <= TGSI_CC_FL );
1305    assert( swizzle_x <= TGSI_SWIZZLE_W );
1306    assert( swizzle_y <= TGSI_SWIZZLE_W );
1307    assert( swizzle_z <= TGSI_SWIZZLE_W );
1308    assert( swizzle_w <= TGSI_SWIZZLE_W );
1309    assert( index >= -32768 && index <= 32767 );
1310
1311    dst_register_ext_concode = tgsi_default_dst_register_ext_concode();
1312    dst_register_ext_concode.CondMask = cc;
1313    dst_register_ext_concode.CondSwizzleX = swizzle_x;
1314    dst_register_ext_concode.CondSwizzleY = swizzle_y;
1315    dst_register_ext_concode.CondSwizzleZ = swizzle_z;
1316    dst_register_ext_concode.CondSwizzleW = swizzle_w;
1317    dst_register_ext_concode.CondSrcIndex = index;
1318
1319    prev_token->Extended = 1;
1320    instruction_grow( instruction, header );
1321
1322    return dst_register_ext_concode;
1323 }
1324
1325 struct tgsi_dst_register_ext_modulate
1326 tgsi_default_dst_register_ext_modulate( void )
1327 {
1328    struct tgsi_dst_register_ext_modulate dst_register_ext_modulate;
1329
1330    dst_register_ext_modulate.Type = TGSI_DST_REGISTER_EXT_TYPE_MODULATE;
1331    dst_register_ext_modulate.Modulate = TGSI_MODULATE_1X;
1332    dst_register_ext_modulate.Padding = 0;
1333    dst_register_ext_modulate.Extended = 0;
1334
1335    return dst_register_ext_modulate;
1336 }
1337
1338 unsigned
1339 tgsi_compare_dst_register_ext_modulate(
1340    struct tgsi_dst_register_ext_modulate a,
1341    struct tgsi_dst_register_ext_modulate b )
1342 {
1343    a.Padding = b.Padding = 0;
1344    a.Extended = b.Extended = 0;
1345    return compare32(&a, &b);
1346 }
1347
1348 struct tgsi_dst_register_ext_modulate
1349 tgsi_build_dst_register_ext_modulate(
1350    unsigned modulate,
1351    struct tgsi_token *prev_token,
1352    struct tgsi_instruction *instruction,
1353    struct tgsi_header *header )
1354 {
1355    struct tgsi_dst_register_ext_modulate dst_register_ext_modulate;
1356
1357    assert( modulate <= TGSI_MODULATE_EIGHTH );
1358
1359    dst_register_ext_modulate = tgsi_default_dst_register_ext_modulate();
1360    dst_register_ext_modulate.Modulate = modulate;
1361
1362    prev_token->Extended = 1;
1363    instruction_grow( instruction, header );
1364
1365    return dst_register_ext_modulate;
1366 }