Fix utc_ecore_evas_pointer_xy_get timeout issue
[platform/upstream/mesa.git] / src / gallium / drivers / r300 / compiler / radeon_compiler_util.c
1 /*
2  * Copyright 2010 Tom Stellard <tstellar@gmail.com>
3  *
4  * All Rights Reserved.
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 /**
29  * \file
30  */
31
32 #include "radeon_compiler_util.h"
33
34 #include "radeon_compiler.h"
35 #include "radeon_dataflow.h"
36 #include "r300_fragprog_swizzle.h"
37 /**
38  */
39 unsigned int rc_swizzle_to_writemask(unsigned int swz)
40 {
41         unsigned int mask = 0;
42         unsigned int i;
43
44         for(i = 0; i < 4; i++) {
45                 mask |= 1 << GET_SWZ(swz, i);
46         }
47         mask &= RC_MASK_XYZW;
48
49         return mask;
50 }
51
52 rc_swizzle get_swz(unsigned int swz, rc_swizzle idx)
53 {
54         if (idx & 0x4)
55                 return idx;
56         return GET_SWZ(swz, idx);
57 }
58
59 /**
60  * The purpose of this function is to standardize the number channels used by
61  * swizzles.  All swizzles regardless of what instruction they are a part of
62  * should have 4 channels initialized with values.
63  * @param channels The number of channels in initial_value that have a
64  * meaningful value.
65  * @return An initialized swizzle that has all of the unused channels set to
66  * RC_SWIZZLE_UNUSED.
67  */
68 unsigned int rc_init_swizzle(unsigned int initial_value, unsigned int channels)
69 {
70         unsigned int i;
71         for (i = channels; i < 4; i++) {
72                 SET_SWZ(initial_value, i, RC_SWIZZLE_UNUSED);
73         }
74         return initial_value;
75 }
76
77 unsigned int combine_swizzles4(unsigned int src,
78                 rc_swizzle swz_x, rc_swizzle swz_y, rc_swizzle swz_z, rc_swizzle swz_w)
79 {
80         unsigned int ret = 0;
81
82         ret |= get_swz(src, swz_x);
83         ret |= get_swz(src, swz_y) << 3;
84         ret |= get_swz(src, swz_z) << 6;
85         ret |= get_swz(src, swz_w) << 9;
86
87         return ret;
88 }
89
90 unsigned int combine_swizzles(unsigned int src, unsigned int swz)
91 {
92         unsigned int ret = 0;
93
94         ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_X));
95         ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_Y)) << 3;
96         ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_Z)) << 6;
97         ret |= get_swz(src, GET_SWZ(swz, RC_SWIZZLE_W)) << 9;
98
99         return ret;
100 }
101
102 /**
103  * @param mask Must be either RC_MASK_X, RC_MASK_Y, RC_MASK_Z, or RC_MASK_W
104  */
105 rc_swizzle rc_mask_to_swizzle(unsigned int mask)
106 {
107         switch (mask) {
108         case RC_MASK_X: return RC_SWIZZLE_X;
109         case RC_MASK_Y: return RC_SWIZZLE_Y;
110         case RC_MASK_Z: return RC_SWIZZLE_Z;
111         case RC_MASK_W: return RC_SWIZZLE_W;
112         }
113         return RC_SWIZZLE_UNUSED;
114 }
115
116 /* Reorder mask bits according to swizzle. */
117 unsigned swizzle_mask(unsigned swizzle, unsigned mask)
118 {
119         unsigned ret = 0;
120         for (unsigned chan = 0; chan < 4; ++chan) {
121                 unsigned swz = GET_SWZ(swizzle, chan);
122                 if (swz < 4)
123                         ret |= GET_BIT(mask, swz) << chan;
124         }
125         return ret;
126 }
127
128 static unsigned int srcs_need_rewrite(const struct rc_opcode_info * info)
129 {
130         if (info->HasTexture) {
131                 return 0;
132         }
133         switch (info->Opcode) {
134                 case RC_OPCODE_DP2:
135                 case RC_OPCODE_DP3:
136                 case RC_OPCODE_DP4:
137                 case RC_OPCODE_DDX:
138                 case RC_OPCODE_DDY:
139                         return 0;
140                 default:
141                         return 1;
142         }
143 }
144
145 /**
146  * This function moves the old swizzles to new channels using the values
147  * in the conversion swizzle. For example if the instruction writemask is
148  * changed from x to y, then conversion_swizzle should be y___ and this
149  * function will adjust the old argument swizzles (of the same instruction)
150  * to the new channels, so x___ will become _x__, etc...
151  *
152  * @param old_swizzle The swizzle to change
153  * @param conversion_swizzle Describes the conversion to perform on the swizzle
154  * @return A new swizzle
155  */
156 unsigned int rc_adjust_channels(
157         unsigned int old_swizzle,
158         unsigned int conversion_swizzle)
159 {
160         unsigned int i;
161         unsigned int new_swizzle = rc_init_swizzle(RC_SWIZZLE_UNUSED, 0);
162         for (i = 0; i < 4; i++) {
163                 unsigned int new_chan = get_swz(conversion_swizzle, i);
164                 if (new_chan == RC_SWIZZLE_UNUSED) {
165                         continue;
166                 }
167                 SET_SWZ(new_swizzle, new_chan, GET_SWZ(old_swizzle, i));
168         }
169         return new_swizzle;
170 }
171
172 static unsigned int rewrite_writemask(
173         unsigned int old_mask,
174         unsigned int conversion_swizzle)
175 {
176         unsigned int new_mask = 0;
177         unsigned int i;
178
179         for (i = 0; i < 4; i++) {
180                 if (!GET_BIT(old_mask, i)
181                    || GET_SWZ(conversion_swizzle, i) == RC_SWIZZLE_UNUSED) {
182                         continue;
183                 }
184                 new_mask |= (1 << GET_SWZ(conversion_swizzle, i));
185         }
186
187         return new_mask;
188 }
189
190 /**
191  * This function rewrites the writemask of sub and adjusts the swizzles
192  * of all its source registers based on the conversion_swizzle.
193  * conversion_swizzle represents a mapping of the old writemask to the
194  * new writemask.  For a detailed description of how conversion swizzles
195  * work see rc_rewrite_swizzle().
196  */
197 void rc_pair_rewrite_writemask(
198         struct rc_pair_sub_instruction * sub,
199         unsigned int conversion_swizzle)
200 {
201         const struct rc_opcode_info * info = rc_get_opcode_info(sub->Opcode);
202         unsigned int i;
203
204         sub->WriteMask = rewrite_writemask(sub->WriteMask, conversion_swizzle);
205
206         if (!srcs_need_rewrite(info)) {
207                 return ;
208         }
209
210         for (i = 0; i < info->NumSrcRegs; i++) {
211                 sub->Arg[i].Swizzle =
212                         rc_adjust_channels(sub->Arg[i].Swizzle,
213                                                 conversion_swizzle);
214         }
215 }
216
217 static void normal_rewrite_writemask_cb(
218         void * userdata,
219         struct rc_instruction * inst,
220         struct rc_src_register * src)
221 {
222         unsigned int * conversion_swizzle = (unsigned int *)userdata;
223         src->Swizzle = rc_adjust_channels(src->Swizzle, *conversion_swizzle);
224
225         /* Per-channel negates are possible in vertex shaders,
226          * so we need to rewrite it properly as well. */
227         unsigned int new_negate = 0;
228         for (unsigned int i = 0; i < 4; i++) {
229                 unsigned int new_chan = get_swz(*conversion_swizzle, i);
230
231                 if (new_chan == RC_SWIZZLE_UNUSED)
232                         continue;
233
234                 if ((1 << i) & src->Negate)
235                         new_negate |= 1 << new_chan;
236         }
237         src->Negate = new_negate;
238 }
239
240 /**
241  * This function is the same as rc_pair_rewrite_writemask() except it
242  * operates on normal instructions.
243  */
244 void rc_normal_rewrite_writemask(
245         struct rc_instruction * inst,
246         unsigned int conversion_swizzle)
247 {
248         struct rc_sub_instruction * sub = &inst->U.I;
249         const struct rc_opcode_info * info = rc_get_opcode_info(sub->Opcode);
250         sub->DstReg.WriteMask =
251                 rewrite_writemask(sub->DstReg.WriteMask, conversion_swizzle);
252
253         if (info->HasTexture) {
254                 unsigned int i;
255                 assert(sub->TexSwizzle == RC_SWIZZLE_XYZW);
256                 for (i = 0; i < 4; i++) {
257                         unsigned int swz = GET_SWZ(conversion_swizzle, i);
258                         if (swz > 3)
259                                 continue;
260                         SET_SWZ(sub->TexSwizzle, swz, i);
261                 }
262         }
263
264         if (!srcs_need_rewrite(info)) {
265                 return;
266         }
267
268         rc_for_all_reads_src(inst, normal_rewrite_writemask_cb,
269                                                         &conversion_swizzle);
270 }
271
272 /**
273  * This function replaces each value 'swz' in swizzle with the value of
274  * GET_SWZ(conversion_swizzle, swz).  So, if you want to change all the X's
275  * in swizzle to Y, then conversion_swizzle should be Y___ (0xff9).  If you want
276  * to change all the Y's in swizzle to X, then conversion_swizzle should be
277  * _X__ (0xfc7).  If you want to change the Y's to X and the X's to Y, then
278  * conversion swizzle should be YX__ (0xfc1).
279  * @param swizzle The swizzle to change
280  * @param conversion_swizzle Describes the conversion to perform on the swizzle
281  * @return A converted swizzle
282  */
283 unsigned int rc_rewrite_swizzle(
284         unsigned int swizzle,
285         unsigned int conversion_swizzle)
286 {
287         unsigned int chan;
288         unsigned int out_swizzle = swizzle;
289
290         for (chan = 0; chan < 4; chan++) {
291                 unsigned int swz = GET_SWZ(swizzle, chan);
292                 unsigned int new_swz;
293                 if (swz > 3) {
294                         SET_SWZ(out_swizzle, chan, swz);
295                 } else {
296                         new_swz = GET_SWZ(conversion_swizzle, swz);
297                         if (new_swz != RC_SWIZZLE_UNUSED) {
298                                 SET_SWZ(out_swizzle, chan, new_swz);
299                         } else {
300                                 SET_SWZ(out_swizzle, chan, swz);
301                         }
302                 }
303         }
304         return out_swizzle;
305 }
306
307 /**
308  * Left multiplication of a register with a swizzle
309  */
310 struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg)
311 {
312         struct rc_src_register tmp = srcreg;
313         int i;
314         tmp.Swizzle = 0;
315         tmp.Negate = 0;
316         for(i = 0; i < 4; ++i) {
317                 rc_swizzle swz = GET_SWZ(swizzle, i);
318                 if (swz < 4) {
319                         tmp.Swizzle |= GET_SWZ(srcreg.Swizzle, swz) << (i*3);
320                         tmp.Negate |= GET_BIT(srcreg.Negate, swz) << i;
321                 } else {
322                         tmp.Swizzle |= swz << (i*3);
323                 }
324         }
325         return tmp;
326 }
327
328 void reset_srcreg(struct rc_src_register* reg)
329 {
330         memset(reg, 0, sizeof(struct rc_src_register));
331         reg->Swizzle = RC_SWIZZLE_XYZW;
332 }
333
334 unsigned int rc_src_reads_dst_mask(
335                 rc_register_file src_file,
336                 unsigned int src_idx,
337                 unsigned int src_swz,
338                 rc_register_file dst_file,
339                 unsigned int dst_idx,
340                 unsigned int dst_mask)
341 {
342         if (src_file != dst_file || src_idx != dst_idx) {
343                 return RC_MASK_NONE;
344         }
345         return dst_mask & rc_swizzle_to_writemask(src_swz);
346 }
347
348 /**
349  * @return A bit mask specifying whether this swizzle will select from an RGB
350  * source, an Alpha source, or both.
351  */
352 unsigned int rc_source_type_swz(unsigned int swizzle)
353 {
354         unsigned int chan;
355         unsigned int swz = RC_SWIZZLE_UNUSED;
356         unsigned int ret = RC_SOURCE_NONE;
357
358         for(chan = 0; chan < 4; chan++) {
359                 swz = GET_SWZ(swizzle, chan);
360                 if (swz == RC_SWIZZLE_W) {
361                         ret |= RC_SOURCE_ALPHA;
362                 } else if (swz == RC_SWIZZLE_X || swz == RC_SWIZZLE_Y
363                                                 || swz == RC_SWIZZLE_Z) {
364                         ret |= RC_SOURCE_RGB;
365                 }
366         }
367         return ret;
368 }
369
370 unsigned int rc_source_type_mask(unsigned int mask)
371 {
372         unsigned int ret = RC_SOURCE_NONE;
373
374         if (mask & RC_MASK_XYZ)
375                 ret |= RC_SOURCE_RGB;
376
377         if (mask & RC_MASK_W)
378                 ret |= RC_SOURCE_ALPHA;
379
380         return ret;
381 }
382
383 struct src_select {
384         rc_register_file File;
385         int Index;
386         unsigned int SrcType;
387         unsigned int Swizzle;
388 };
389
390 struct can_use_presub_data {
391         struct src_select Selects[5];
392         unsigned int SelectCount;
393         const struct rc_src_register * ReplaceReg;
394         unsigned int ReplaceRemoved;
395 };
396
397 static void can_use_presub_data_add_select(
398         struct can_use_presub_data * data,
399         rc_register_file file,
400         unsigned int index,
401         unsigned int swizzle)
402 {
403         struct src_select * select;
404
405         select = &data->Selects[data->SelectCount++];
406         select->File = file;
407         select->Index = index;
408         select->SrcType = rc_source_type_swz(swizzle);
409         select->Swizzle = swizzle;
410 }
411
412 /**
413  * This callback function counts the number of sources in inst that are
414  * different from the sources in can_use_presub_data->RemoveSrcs.
415  */
416 static void can_use_presub_read_cb(
417         void * userdata,
418         struct rc_instruction * inst,
419         struct rc_src_register * src)
420 {
421         struct can_use_presub_data * d = userdata;
422
423         if (!d->ReplaceRemoved && src == d->ReplaceReg) {
424                 d->ReplaceRemoved = 1;
425                 return;
426         }
427
428         if (src->File == RC_FILE_NONE)
429                 return;
430
431         can_use_presub_data_add_select(d, src->File, src->Index,
432                                         src->Swizzle);
433 }
434
435 unsigned int rc_inst_can_use_presub(
436         struct radeon_compiler * c,
437         struct rc_instruction * inst,
438         rc_presubtract_op presub_op,
439         unsigned int presub_writemask,
440         const struct rc_src_register * replace_reg,
441         const struct rc_src_register * presub_src0,
442         const struct rc_src_register * presub_src1)
443 {
444         struct can_use_presub_data d;
445         unsigned int num_presub_srcs;
446         unsigned int i;
447         const struct rc_opcode_info * info =
448                                         rc_get_opcode_info(inst->U.I.Opcode);
449         int rgb_count = 0, alpha_count = 0;
450         unsigned int src_type0, src_type1;
451
452         if (presub_op == RC_PRESUB_NONE) {
453                 return 1;
454         }
455
456         if (info->HasTexture) {
457                 return 0;
458         }
459
460         /* We can't allow constant swizzles from presubtract, because it is not possible
461          * to rewrite it to a native swizzle later. */
462         if (!c->is_r500) {
463                 for (i = 0; i < 4; i++) {
464                         rc_swizzle swz = GET_SWZ(replace_reg->Swizzle, i);
465                         if (swz > RC_SWIZZLE_W && swz < RC_SWIZZLE_UNUSED)
466                                 return 0;
467                 }
468         }
469
470         /* We can't use more than one presubtract value in an
471          * instruction, unless the two prsubtract operations
472          * are the same and read from the same registers.
473          * XXX For now we will limit instructions to only one presubtract
474          * value.*/
475         if (inst->U.I.PreSub.Opcode != RC_PRESUB_NONE) {
476                 return 0;
477         }
478
479         memset(&d, 0, sizeof(d));
480         d.ReplaceReg = replace_reg;
481
482         rc_for_all_reads_src(inst, can_use_presub_read_cb, &d);
483
484         num_presub_srcs = rc_presubtract_src_reg_count(presub_op);
485
486         src_type0 = rc_source_type_swz(presub_src0->Swizzle);
487         can_use_presub_data_add_select(&d,
488                 presub_src0->File,
489                 presub_src0->Index,
490                 presub_src0->Swizzle);
491
492         if (num_presub_srcs > 1) {
493                 src_type1 = rc_source_type_swz(presub_src1->Swizzle);
494                 can_use_presub_data_add_select(&d,
495                         presub_src1->File,
496                         presub_src1->Index,
497                         presub_src1->Swizzle);
498
499                 /* Even if both of the presub sources read from the same
500                  * register, we still need to use 2 different source selects
501                  * for them, so we need to increment the count to compensate.
502                  */
503                 if (presub_src0->File == presub_src1->File
504                     && presub_src0->Index == presub_src1->Index) {
505                         if (src_type0 & src_type1 & RC_SOURCE_RGB) {
506                                 rgb_count++;
507                         }
508                         if (src_type0 & src_type1 & RC_SOURCE_ALPHA) {
509                                 alpha_count++;
510                         }
511                 }
512         }
513
514         /* Count the number of source selects for Alpha and RGB.  If we
515          * encounter two of the same source selects then we can ignore the
516          * first one. */
517         for (i = 0; i < d.SelectCount; i++) {
518                 unsigned int j;
519                 unsigned int src_type = d.Selects[i].SrcType;
520                 for (j = i + 1; j < d.SelectCount; j++) {
521                         /* Even if the sources are the same now, they will not be the
522                          * same later, if we have to rewrite some non-native swizzle. */
523                         if(!c->is_r500 && (
524                                 !r300_swizzle_is_native_basic(d.Selects[i].Swizzle) ||
525                                 !r300_swizzle_is_native_basic(d.Selects[j].Swizzle)))
526                                 continue;
527                         if (d.Selects[i].File == d.Selects[j].File
528                             && d.Selects[i].Index == d.Selects[j].Index) {
529                                 src_type &= ~d.Selects[j].SrcType;
530                         }
531                 }
532                 if (src_type & RC_SOURCE_RGB) {
533                         rgb_count++;
534                 }
535
536                 if (src_type & RC_SOURCE_ALPHA) {
537                         alpha_count++;
538                 }
539         }
540
541         if (rgb_count > 3 || alpha_count > 3) {
542                 return 0;
543         }
544
545         return 1;
546 }
547
548 struct max_data {
549         unsigned int Max;
550         unsigned int HasFileType;
551         rc_register_file File;
552 };
553
554 static void max_callback(
555         void * userdata,
556         struct rc_instruction * inst,
557         rc_register_file file,
558         unsigned int index,
559         unsigned int mask)
560 {
561         struct max_data * d = (struct max_data*)userdata;
562         if (file == d->File && (!d->HasFileType || index > d->Max)) {
563                 d->Max = index;
564                 d->HasFileType = 1;
565         }
566 }
567
568 /**
569  * @return The maximum index of the specified register file used by the
570  * program.
571  */
572 int rc_get_max_index(
573         struct radeon_compiler * c,
574         rc_register_file file)
575 {
576         struct max_data data;
577         struct rc_instruction * inst;
578         data.Max = 0;
579         data.HasFileType = 0;
580         data.File = file;
581         for (inst = c->Program.Instructions.Next;
582                                         inst != &c->Program.Instructions;
583                                         inst = inst->Next) {
584                 rc_for_all_reads_mask(inst, max_callback, &data);
585                 rc_for_all_writes_mask(inst, max_callback, &data);
586         }
587         if (!data.HasFileType) {
588                 return -1;
589         } else {
590                 return data.Max;
591         }
592 }
593
594 /**
595  * This function removes a source from a pair instructions.
596  * @param inst
597  * @param src_type RC_SOURCE_RGB, RC_SOURCE_ALPHA, or both bitwise or'd
598  * @param source The index of the source to remove
599
600  */
601 void rc_pair_remove_src(
602         struct rc_instruction * inst,
603         unsigned int src_type,
604         unsigned int source)
605 {
606         if (src_type & RC_SOURCE_RGB) {
607                 memset(&inst->U.P.RGB.Src[source], 0,
608                         sizeof(struct rc_pair_instruction_source));
609         }
610
611         if (src_type & RC_SOURCE_ALPHA) {
612                 memset(&inst->U.P.Alpha.Src[source], 0,
613                         sizeof(struct rc_pair_instruction_source));
614         }
615 }
616
617 /**
618  * @return RC_OPCODE_NOOP if inst is not a flow control instruction.
619  * @return The opcode of inst if it is a flow control instruction.
620  */
621 rc_opcode rc_get_flow_control_inst(struct rc_instruction * inst)
622 {
623         const struct rc_opcode_info * info;
624         if (inst->Type == RC_INSTRUCTION_NORMAL) {
625                 info = rc_get_opcode_info(inst->U.I.Opcode);
626         } else {
627                 info = rc_get_opcode_info(inst->U.P.RGB.Opcode);
628                 /*A flow control instruction shouldn't have an alpha
629                  * instruction.*/
630                 assert(!info->IsFlowControl ||
631                                 inst->U.P.Alpha.Opcode == RC_OPCODE_NOP);
632         }
633
634         if (info->IsFlowControl)
635                 return info->Opcode;
636         else
637                 return RC_OPCODE_NOP;
638
639 }
640
641 /**
642  * @return The BGNLOOP instruction that starts the loop ended by endloop.
643  */
644 struct rc_instruction * rc_match_endloop(struct rc_instruction * endloop)
645 {
646         unsigned int endloop_count = 0;
647         struct rc_instruction * inst;
648         for (inst = endloop->Prev; inst != endloop; inst = inst->Prev) {
649                 rc_opcode op = rc_get_flow_control_inst(inst);
650                 if (op == RC_OPCODE_ENDLOOP) {
651                         endloop_count++;
652                 } else if (op == RC_OPCODE_BGNLOOP) {
653                         if (endloop_count == 0) {
654                                 return inst;
655                         } else {
656                                 endloop_count--;
657                         }
658                 }
659         }
660         return NULL;
661 }
662
663 /**
664  * @return The ENDLOOP instruction that ends the loop started by bgnloop.
665  */
666 struct rc_instruction * rc_match_bgnloop(struct rc_instruction * bgnloop)
667 {
668         unsigned int bgnloop_count = 0;
669         struct rc_instruction * inst;
670         for (inst = bgnloop->Next; inst!=bgnloop; inst = inst->Next) {
671                 rc_opcode op = rc_get_flow_control_inst(inst);
672                 if (op == RC_OPCODE_BGNLOOP) {
673                         bgnloop_count++;
674                 } else if (op == RC_OPCODE_ENDLOOP) {
675                         if (bgnloop_count == 0) {
676                                 return inst;
677                         } else {
678                                 bgnloop_count--;
679                         }
680                 }
681         }
682         return NULL;
683 }
684
685 /**
686  * @return A conversion swizzle for converting from old_mask->new_mask
687  */
688 unsigned int rc_make_conversion_swizzle(
689         unsigned int old_mask,
690         unsigned int new_mask)
691 {
692         unsigned int conversion_swizzle = rc_init_swizzle(RC_SWIZZLE_UNUSED, 0);
693         unsigned int old_idx;
694         unsigned int new_idx = 0;
695         for (old_idx = 0; old_idx < 4; old_idx++) {
696                 if (!GET_BIT(old_mask, old_idx))
697                         continue;
698                 for ( ; new_idx < 4; new_idx++) {
699                         if (GET_BIT(new_mask, new_idx)) {
700                                 SET_SWZ(conversion_swizzle, old_idx, new_idx);
701                                 new_idx++;
702                                 break;
703                         }
704                 }
705         }
706         return conversion_swizzle;
707 }
708
709 /**
710  * @return 1 if the register contains an immediate value, 0 otherwise.
711  */
712 unsigned int rc_src_reg_is_immediate(
713         struct radeon_compiler * c,
714         unsigned int file,
715         unsigned int index)
716 {
717         return file == RC_FILE_CONSTANT &&
718         c->Program.Constants.Constants[index].Type == RC_CONSTANT_IMMEDIATE;
719 }
720
721 /**
722  * @return The immediate value in the specified register.
723  */
724 float rc_get_constant_value(
725         struct radeon_compiler * c,
726         unsigned int index,
727         unsigned int swizzle,
728         unsigned int negate,
729         unsigned int chan)
730 {
731         float base = 1.0f;
732         int swz = GET_SWZ(swizzle, chan);
733         if(swz >= 4 || index >= c->Program.Constants.Count ){
734                 rc_error(c, "get_constant_value: Can't find a value.\n");
735                 return 0.0f;
736         }
737         if(GET_BIT(negate, chan)){
738                 base = -1.0f;
739         }
740         return base *
741                 c->Program.Constants.Constants[index].u.Immediate[swz];
742 }
743
744 /**
745  * This function returns the component value (RC_SWIZZLE_*) of the first used
746  * channel in the swizzle.  This is only useful for scalar instructions that are
747  * known to use only one channel of the swizzle.
748  */
749 unsigned int rc_get_scalar_src_swz(unsigned int swizzle)
750 {
751         unsigned int swz, chan;
752         for (chan = 0; chan < 4; chan++) {
753                 swz = GET_SWZ(swizzle, chan);
754                 if (swz != RC_SWIZZLE_UNUSED) {
755                         break;
756                 }
757         }
758         assert(swz != RC_SWIZZLE_UNUSED);
759         return swz;
760 }
761
762 bool rc_inst_has_three_diff_temp_srcs(struct rc_instruction *inst)
763 {
764         return (inst->U.I.SrcReg[0].File == RC_FILE_TEMPORARY &&
765                 inst->U.I.SrcReg[1].File == RC_FILE_TEMPORARY &&
766                 inst->U.I.SrcReg[2].File == RC_FILE_TEMPORARY &&
767                 inst->U.I.SrcReg[0].Index != inst->U.I.SrcReg[1].Index &&
768                 inst->U.I.SrcReg[1].Index != inst->U.I.SrcReg[2].Index &&
769                 inst->U.I.SrcReg[0].Index != inst->U.I.SrcReg[2].Index);
770 }