1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @file
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Helper functions for swizzling/shuffling.
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @author Jose Fonseca <jfonseca@vmware.com>
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_type.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_const.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_init.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_logic.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_swizzle.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "lp_bld_pack.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_broadcast(struct gallivm_state *gallivm,
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   LLVMTypeRef vec_type,
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   LLVMValueRef scalar)
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef res;
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (LLVMGetTypeKind(vec_type) != LLVMVectorTypeKind) {
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* scalar */
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(vec_type == LLVMTypeOf(scalar));
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      res = scalar;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMBuilderRef builder = gallivm->builder;
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const unsigned length = LLVMGetVectorSize(vec_type);
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef undef = LLVMGetUndef(vec_type);
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMTypeRef i32_type = LLVMInt32TypeInContext(gallivm->context);
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(LLVMGetElementType(vec_type) == LLVMTypeOf(scalar));
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (HAVE_LLVM >= 0x207) {
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* The shuffle vector is always made of int32 elements */
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMTypeRef i32_vec_type = LLVMVectorType(i32_type, length);
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         res = LLVMBuildInsertElement(builder, undef, scalar, LLVMConstNull(i32_type), "");
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         res = LLVMBuildShuffleVector(builder, res, undef, LLVMConstNull(i32_vec_type), "");
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* XXX: The above path provokes a bug in LLVM 2.6 */
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         unsigned i;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         res = undef;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for(i = 0; i < length; ++i) {
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef index = lp_build_const_int32(gallivm, i);
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            res = LLVMBuildInsertElement(builder, res, scalar, index, "");
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return res;
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Broadcast
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_broadcast_scalar(struct lp_build_context *bld,
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          LLVMValueRef scalar)
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(lp_check_elem_type(bld->type, LLVMTypeOf(scalar)));
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return lp_build_broadcast(bld->gallivm, bld->vec_type, scalar);
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Combined extract and broadcast (mere shuffle in most cases)
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_extract_broadcast(struct gallivm_state *gallivm,
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct lp_type src_type,
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           struct lp_type dst_type,
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           LLVMValueRef vector,
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           LLVMValueRef index)
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef res;
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(src_type.floating == dst_type.floating);
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(src_type.width    == dst_type.width);
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(lp_check_value(src_type, vector));
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(LLVMTypeOf(index) == i32t);
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (src_type.length == 1) {
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dst_type.length == 1) {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Trivial scalar -> scalar.
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         res = vector;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Broadcast scalar -> vector.
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         res = lp_build_broadcast(gallivm,
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  lp_build_vec_type(gallivm, dst_type),
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  vector);
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dst_type.length > 1) {
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * shuffle - result can be of different length.
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef shuffle;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shuffle = lp_build_broadcast(gallivm,
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      LLVMVectorType(i32t, dst_type.length),
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      index);
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         res = LLVMBuildShuffleVector(gallivm->builder, vector,
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      LLVMGetUndef(lp_build_vec_type(gallivm, src_type)),
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      shuffle, "");
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /*
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          * Trivial extract scalar from vector.
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          */
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          res = LLVMBuildExtractElement(gallivm->builder, vector, index, "");
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return res;
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Swizzle one channel into all other three channels.
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_swizzle_scalar_aos(struct lp_build_context *bld,
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            LLVMValueRef a,
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            unsigned channel)
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct lp_type type = bld->type;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned n = type.length;
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i, j;
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(a == bld->undef || a == bld->zero || a == bld->one)
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return a;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX: SSE3 has PSHUFB which should be better than bitmasks, but forcing
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * using shuffles here actually causes worst results. More investigation is
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    * needed. */
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type.width >= 16) {
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Shuffle.
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMTypeRef elem_type = LLVMInt32TypeInContext(bld->gallivm->context);
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for(j = 0; j < n; j += 4)
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for(i = 0; i < 4; ++i)
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            shuffles[j + i] = LLVMConstInt(elem_type, j + channel, 0);
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LLVMBuildShuffleVector(builder, a, bld->undef, LLVMConstVector(shuffles, n), "");
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Bit mask and recursive shifts
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   XYZW XYZW .... XYZW  <= input
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   0Y00 0Y00 .... 0Y00
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   YY00 YY00 .... YY00
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   YYYY YYYY .... YYYY  <= output
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct lp_type type4;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      const char shifts[4][2] = {
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         { 1,  2},
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {-1,  2},
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         { 1, -2},
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         {-1, -2}
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      };
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned i;
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      a = LLVMBuildAnd(builder, a,
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       lp_build_const_mask_aos(bld->gallivm,
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               type, 1 << channel), "");
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Build a type where each element is an integer that cover the four
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * channels.
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type4 = type;
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type4.floating = FALSE;
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type4.width *= 4;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type4.length /= 4;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      a = LLVMBuildBitCast(builder, a, lp_build_vec_type(bld->gallivm, type4), "");
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for(i = 0; i < 2; ++i) {
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         LLVMValueRef tmp = NULL;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         int shift = shifts[channel][i];
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef PIPE_ARCH_LITTLE_ENDIAN
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         shift = -shift;
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if(shift > 0)
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tmp = LLVMBuildLShr(builder, a, lp_build_const_int_vec(bld->gallivm, type4, shift*type.width), "");
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if(shift < 0)
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tmp = LLVMBuildShl(builder, a, lp_build_const_int_vec(bld->gallivm, type4, -shift*type.width), "");
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(tmp);
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if(tmp)
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            a = LLVMBuildOr(builder, a, tmp, "");
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LLVMBuildBitCast(builder, a, lp_build_vec_type(bld->gallivm, type), "");
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_swizzle_aos(struct lp_build_context *bld,
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     LLVMValueRef a,
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     const unsigned char swizzles[4])
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMBuilderRef builder = bld->gallivm->builder;
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const struct lp_type type = bld->type;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned n = type.length;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i, j;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (swizzles[0] == PIPE_SWIZZLE_RED &&
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       swizzles[1] == PIPE_SWIZZLE_GREEN &&
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       swizzles[2] == PIPE_SWIZZLE_BLUE &&
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       swizzles[3] == PIPE_SWIZZLE_ALPHA) {
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return a;
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (swizzles[0] == swizzles[1] &&
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       swizzles[1] == swizzles[2] &&
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       swizzles[2] == swizzles[3]) {
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (swizzles[0]) {
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_SWIZZLE_RED:
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_SWIZZLE_GREEN:
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_SWIZZLE_BLUE:
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_SWIZZLE_ALPHA:
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return lp_build_swizzle_scalar_aos(bld, a, swizzles[0]);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_SWIZZLE_ZERO:
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return bld->zero;
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case PIPE_SWIZZLE_ONE:
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return bld->one;
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case LP_BLD_SWIZZLE_DONTCARE:
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return bld->undef;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(0);
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return bld->undef;
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (type.width >= 16) {
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Shuffle.
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef undef = LLVMGetUndef(lp_build_elem_type(bld->gallivm, type));
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMTypeRef i32t = LLVMInt32TypeInContext(bld->gallivm->context);
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef aux[LP_MAX_VECTOR_LENGTH];
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      memset(aux, 0, sizeof aux);
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for(j = 0; j < n; j += 4) {
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for(i = 0; i < 4; ++i) {
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            unsigned shuffle;
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            switch (swizzles[i]) {
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            default:
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               assert(0);
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               /* fall through */
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PIPE_SWIZZLE_RED:
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PIPE_SWIZZLE_GREEN:
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PIPE_SWIZZLE_BLUE:
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PIPE_SWIZZLE_ALPHA:
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shuffle = j + swizzles[i];
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shuffles[j + i] = LLVMConstInt(i32t, shuffle, 0);
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PIPE_SWIZZLE_ZERO:
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shuffle = type.length + 0;
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shuffles[j + i] = LLVMConstInt(i32t, shuffle, 0);
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (!aux[0]) {
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  aux[0] = lp_build_const_elem(bld->gallivm, type, 0.0);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case PIPE_SWIZZLE_ONE:
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shuffle = type.length + 1;
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shuffles[j + i] = LLVMConstInt(i32t, shuffle, 0);
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (!aux[1]) {
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  aux[1] = lp_build_const_elem(bld->gallivm, type, 1.0);
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               }
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            case LP_BLD_SWIZZLE_DONTCARE:
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shuffles[j + i] = LLVMGetUndef(i32t);
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               break;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < n; ++i) {
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (!aux[i]) {
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            aux[i] = undef;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LLVMBuildShuffleVector(builder, a,
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMConstVector(aux, n),
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMConstVector(shuffles, n), "");
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Bit mask and shifts.
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * For example, this will convert BGRA to RGBA by doing
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *   rgba = (bgra & 0x00ff0000) >> 16
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *        | (bgra & 0xff00ff00)
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *        | (bgra & 0x000000ff) << 16
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       *
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * This is necessary not only for faster cause, but because X86 backend
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * will refuse shuffles of <4 x i8> vectors
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMValueRef res;
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      struct lp_type type4;
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned cond = 0;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned chan;
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int shift;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Start with a mixture of 1 and 0.
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (chan = 0; chan < 4; ++chan) {
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (swizzles[chan] == PIPE_SWIZZLE_ONE) {
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            cond |= 1 << chan;
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      res = lp_build_select_aos(bld, cond, bld->one, bld->zero);
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Build a type where each element is an integer that cover the four
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * channels.
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type4 = type;
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type4.floating = FALSE;
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type4.width *= 4;
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      type4.length /= 4;
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      a = LLVMBuildBitCast(builder, a, lp_build_vec_type(bld->gallivm, type4), "");
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      res = LLVMBuildBitCast(builder, res, lp_build_vec_type(bld->gallivm, type4), "");
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /*
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * Mask and shift the channels, trying to group as many channels in the
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * same shift as possible
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (shift = -3; shift <= 3; ++shift) {
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         unsigned long long mask = 0;
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(type4.width <= sizeof(mask)*8);
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (chan = 0; chan < 4; ++chan) {
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* FIXME: big endian */
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (swizzles[chan] < 4 &&
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                chan - swizzles[chan] == shift) {
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               mask |= ((1ULL << type.width) - 1) << (swizzles[chan] * type.width);
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (mask) {
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef masked;
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            LLVMValueRef shifted;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (0)
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               debug_printf("shift = %i, mask = 0x%08llx\n", shift, mask);
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            masked = LLVMBuildAnd(builder, a,
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  lp_build_const_int_vec(bld->gallivm, type4, mask), "");
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (shift > 0) {
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shifted = LLVMBuildShl(builder, masked,
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      lp_build_const_int_vec(bld->gallivm, type4, shift*type.width), "");
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            } else if (shift < 0) {
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shifted = LLVMBuildLShr(builder, masked,
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       lp_build_const_int_vec(bld->gallivm, type4, -shift*type.width), "");
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            } else {
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               shifted = masked;
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            res = LLVMBuildOr(builder, res, shifted, "");
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LLVMBuildBitCast(builder, res,
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              lp_build_vec_type(bld->gallivm, type), "");
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Extended swizzle of a single channel of a SoA vector.
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param bld         building context
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param unswizzled  array with the 4 unswizzled values
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param swizzle     one of the PIPE_SWIZZLE_*
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @return  the swizzled value.
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_swizzle_soa_channel(struct lp_build_context *bld,
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             const LLVMValueRef *unswizzled,
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             unsigned swizzle)
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (swizzle) {
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_RED:
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_GREEN:
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_BLUE:
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_ALPHA:
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return unswizzled[swizzle];
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_ZERO:
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->zero;
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_SWIZZLE_ONE:
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->one;
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return bld->undef;
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Extended swizzle of a SoA vector.
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param bld         building context
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param unswizzled  array with the 4 unswizzled values
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param swizzles    array of PIPE_SWIZZLE_*
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param swizzled    output swizzled values
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_swizzle_soa(struct lp_build_context *bld,
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     const LLVMValueRef *unswizzled,
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     const unsigned char swizzles[4],
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     LLVMValueRef *swizzled)
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned chan;
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (chan = 0; chan < 4; ++chan) {
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      swizzled[chan] = lp_build_swizzle_soa_channel(bld, unswizzled,
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    swizzles[chan]);
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do an extended swizzle of a SoA vector inplace.
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param bld         building context
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param values      intput/output array with the 4 values
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param swizzles    array of PIPE_SWIZZLE_*
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_swizzle_soa_inplace(struct lp_build_context *bld,
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             LLVMValueRef *values,
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             const unsigned char swizzles[4])
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef unswizzled[4];
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned chan;
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (chan = 0; chan < 4; ++chan) {
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unswizzled[chan] = values[chan];
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   lp_build_swizzle_soa(bld, unswizzled, swizzles, values);
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Transpose from AOS <-> SOA
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param single_type_lp   type of pixels
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param src              the 4 * n pixel input
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @param dst              the 4 * n pixel output
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_transpose_aos(struct gallivm_state *gallivm,
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       struct lp_type single_type_lp,
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       const LLVMValueRef src[4],
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       LLVMValueRef dst[4])
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_type double_type_lp = single_type_lp;
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef single_type;
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef double_type;
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef t0, t1, t2, t3;
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   double_type_lp.length >>= 1;
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   double_type_lp.width  <<= 1;
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   double_type = lp_build_vec_type(gallivm, double_type_lp);
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   single_type = lp_build_vec_type(gallivm, single_type_lp);
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Interleave x, y, z, w -> xy and zw */
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t0 = lp_build_interleave2_half(gallivm, single_type_lp, src[0], src[1], 0);
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t1 = lp_build_interleave2_half(gallivm, single_type_lp, src[2], src[3], 0);
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t2 = lp_build_interleave2_half(gallivm, single_type_lp, src[0], src[1], 1);
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t3 = lp_build_interleave2_half(gallivm, single_type_lp, src[2], src[3], 1);
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Cast to double width type for second interleave */
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t0 = LLVMBuildBitCast(gallivm->builder, t0, double_type, "t0");
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t1 = LLVMBuildBitCast(gallivm->builder, t1, double_type, "t1");
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t2 = LLVMBuildBitCast(gallivm->builder, t2, double_type, "t2");
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   t3 = LLVMBuildBitCast(gallivm->builder, t3, double_type, "t3");
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Interleave xy, zw -> xyzw */
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst[0] = lp_build_interleave2_half(gallivm, double_type_lp, t0, t1, 0);
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst[1] = lp_build_interleave2_half(gallivm, double_type_lp, t0, t1, 1);
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst[2] = lp_build_interleave2_half(gallivm, double_type_lp, t2, t3, 0);
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst[3] = lp_build_interleave2_half(gallivm, double_type_lp, t2, t3, 1);
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Cast back to original single width type */
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst[0] = LLVMBuildBitCast(gallivm->builder, dst[0], single_type, "dst0");
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst[1] = LLVMBuildBitCast(gallivm->builder, dst[1], single_type, "dst1");
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst[2] = LLVMBuildBitCast(gallivm->builder, dst[2], single_type, "dst2");
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   dst[3] = LLVMBuildBitCast(gallivm->builder, dst[3], single_type, "dst3");
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Pack first element of aos values,
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * pad out to destination size.
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * i.e. x1 _ _ _ x2 _ _ _ will become x1 x2 _ _
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_pack_aos_scalars(struct gallivm_state *gallivm,
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct lp_type src_type,
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct lp_type dst_type,
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          const LLVMValueRef src)
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef undef = LLVMGetUndef(i32t);
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned num_src = src_type.length / 4;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned num_dst = dst_type.length;
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(num_src <= num_dst);
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < num_src; i++) {
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shuffles[i] = LLVMConstInt(i32t, i * 4, 0);
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = num_src; i < num_dst; i++) {
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shuffles[i] = undef;
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (num_dst == 1) {
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LLVMBuildExtractElement(gallivm->builder, src, shuffles[0], "");
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LLVMBuildShuffleVector(gallivm->builder, src, src,
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMConstVector(shuffles, num_dst), "");
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Unpack and broadcast packed aos values consisting of only the
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * first value, i.e. x1 x2 _ _ will become x1 x1 x1 x1 x2 x2 x2 x2
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_unpack_broadcast_aos_scalars(struct gallivm_state *gallivm,
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      struct lp_type src_type,
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      struct lp_type dst_type,
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      const LLVMValueRef src)
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context);
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned num_dst = dst_type.length;
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned num_src = dst_type.length / 4;
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(num_dst / 4 <= src_type.length);
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (i = 0; i < num_src; i++) {
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shuffles[i*4] = LLVMConstInt(i32t, i, 0);
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shuffles[i*4+1] = LLVMConstInt(i32t, i, 0);
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shuffles[i*4+2] = LLVMConstInt(i32t, i, 0);
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      shuffles[i*4+3] = LLVMConstInt(i32t, i, 0);
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (num_src == 1) {
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return lp_build_extract_broadcast(gallivm, src_type, dst_type,
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        src, shuffles[0]);
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   else {
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return LLVMBuildShuffleVector(gallivm->builder, src, src,
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    LLVMConstVector(shuffles, num_dst), "");
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
629