lp_bld_tgsi_soa.c revision f623d0c1c217d990f207306eb968172af79fa969
163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**************************************************************************
263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca *
363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Copyright 2009 VMware, Inc.
463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * All Rights Reserved.
663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca *
763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Permission is hereby granted, free of charge, to any person obtaining a
863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * copy of this software and associated documentation files (the
963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * "Software"), to deal in the Software without restriction, including
1063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * without limitation the rights to use, copy, modify, merge, publish,
1163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * distribute, sub license, and/or sell copies of the Software, and to
1263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * permit persons to whom the Software is furnished to do so, subject to
1363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * the following conditions:
1463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca *
1563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * The above copyright notice and this permission notice (including the
1663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * next paragraph) shall be included in all copies or substantial portions
1763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * of the Software.
1863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca *
1963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
2363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca *
2763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca **************************************************************************/
2863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
295811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca/**
305811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * @file
315811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * TGSI to LLVM IR translation -- SoA.
325811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca *
335811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * @author Jose Fonseca <jfonseca@vmware.com>
345811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca *
355811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Based on tgsi_sse2.c code written by Michal Krol, Keith Whitwell,
365811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca * Brian Paul, and others.
375811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca */
385811ed87d732101ab8cfbd087bc99d8c6c963f30José Fonseca
3963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "pipe/p_config.h"
4063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "pipe/p_shader_tokens.h"
4163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "util/u_debug.h"
4263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "util/u_math.h"
4363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "util/u_memory.h"
442410125d072faeb83c8373e676422f6c44c78febBrian Paul#include "tgsi/tgsi_dump.h"
457821664b15501b173b2304bbada758c33c5ff972José Fonseca#include "tgsi/tgsi_info.h"
4663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "tgsi/tgsi_parse.h"
4763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "tgsi/tgsi_util.h"
48021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin#include "tgsi/tgsi_scan.h"
4963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_type.h"
5063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_const.h"
5163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_arit.h"
526d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca#include "lp_bld_bitarit.h"
534363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul#include "lp_bld_gather.h"
547821664b15501b173b2304bbada758c33c5ff972José Fonseca#include "lp_bld_logic.h"
5563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_swizzle.h"
563d7a88674f9eb3320eeff511968f041426e25023José Fonseca#include "lp_bld_flow.h"
57ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca#include "lp_bld_quad.h"
5863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_tgsi.h"
596c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca#include "lp_bld_limits.h"
6080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin#include "lp_bld_debug.h"
615b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul#include "lp_bld_printf.h"
6263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define FOR_EACH_CHANNEL( CHAN )\
6563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)
6663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
685b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   ((INST)->Dst[0].Register.WriteMask & (1 << (CHAN)))
6963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
7063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
7163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   if (IS_DST0_CHANNEL_ENABLED( INST, CHAN ))
7263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
7363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\
7463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   FOR_EACH_CHANNEL( CHAN )\
7563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )
7663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
7763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_X 0
7863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_Y 1
7963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_Z 2
8063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_W 3
815a916204179c6787157af3f3be758dc36162ab20Keith Whitwell#define NUM_CHANNELS 4
8263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
830b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin#define LP_MAX_INSTRUCTIONS 256
840b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
8580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
8680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstruct lp_exec_mask {
8780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   struct lp_build_context *bld;
8880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
8980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   boolean has_mask;
9080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
9180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   LLVMTypeRef int_vec_type;
9280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
936c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING];
9480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   int cond_stack_size;
9580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   LLVMValueRef cond_mask;
9680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
972d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBasicBlockRef loop_block;
9818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef cont_mask;
992d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef break_mask;
1002d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef break_var;
1012d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   struct {
1022d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMBasicBlockRef loop_block;
1032d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMValueRef cont_mask;
1042d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMValueRef break_mask;
1052d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMValueRef break_var;
1062d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   } loop_stack[LP_MAX_TGSI_NESTING];
10718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   int loop_stack_size;
10818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
10932a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   LLVMValueRef ret_mask;
1100b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   struct {
1110b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      int pc;
1120b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMValueRef ret_mask;
1130b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   } call_stack[LP_MAX_TGSI_NESTING];
1140b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int call_stack_size;
1150b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
11680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   LLVMValueRef exec_mask;
11780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin};
11863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastruct lp_build_tgsi_soa_context
12063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
12163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_context base;
12263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
123e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   /* Builder for vector integer masks and indices */
1246d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_build_context uint_bld;
125ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
126e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   /* Builder for scalar elements of shader's data type (float) */
127e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   struct lp_build_context elem_bld;
128e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul
12963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef consts_ptr;
130f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   const LLVMValueRef *pos;
131263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   const LLVMValueRef (*inputs)[NUM_CHANNELS];
132263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   LLVMValueRef (*outputs)[NUM_CHANNELS];
133c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca
1343f6dc8e79d918283a6dfcf9c8937a6d52f3bb4f5Brian Paul   const struct lp_build_sampler_soa *sampler;
13563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1366c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][NUM_CHANNELS];
1376c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef temps[LP_MAX_TGSI_TEMPS][NUM_CHANNELS];
1386c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef addr[LP_MAX_TGSI_ADDRS][NUM_CHANNELS];
139ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef preds[LP_MAX_TGSI_PREDS][NUM_CHANNELS];
1401929057eac0c3351e0810612bdae56331a235736José Fonseca
1413662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
1423662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    * set in the indirect_files field.
1433662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    * The temps[] array above is unused then.
1443662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    */
145021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   LLVMValueRef temps_array;
1463662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul
147528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   /* We allocate/use this array of output if (1 << TGSI_FILE_OUTPUT) is
148528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin    * set in the indirect_files field.
149528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin    * The outputs[] array above is unused then.
150528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin    */
151528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   LLVMValueRef outputs_array;
152528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
153f623d0c1c217d990f207306eb968172af79fa969Zack Rusin   /* We allocate/use this array of inputs if (1 << TGSI_FILE_INPUT) is
154f623d0c1c217d990f207306eb968172af79fa969Zack Rusin    * set in the indirect_files field.
155f623d0c1c217d990f207306eb968172af79fa969Zack Rusin    * The inputs[] array above is unused then.
156f623d0c1c217d990f207306eb968172af79fa969Zack Rusin    */
157f623d0c1c217d990f207306eb968172af79fa969Zack Rusin   LLVMValueRef inputs_array;
158f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
1596d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   const struct tgsi_shader_info *info;
1603662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   /** bitmask indicating which register files are accessed indirectly */
1613662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   unsigned indirect_files;
162021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
1633d7a88674f9eb3320eeff511968f041426e25023José Fonseca   struct lp_build_mask_context *mask;
16480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   struct lp_exec_mask exec_mask;
1650b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1660b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   struct tgsi_full_instruction *instructions;
1670b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   uint max_instructions;
16863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca};
16963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
17080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld)
17180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
17280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->bld = bld;
17380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->has_mask = FALSE;
17480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack_size = 0;
17518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->loop_stack_size = 0;
1760b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size = 0;
17780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
17880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->int_vec_type = lp_build_int_vec_type(mask->bld->type);
17932a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->exec_mask = mask->ret_mask = mask->break_mask = mask->cont_mask = mask->cond_mask =
1802d91903882e399e8ea7306fd37d5d214907247e6José Fonseca         LLVMConstAllOnes(mask->int_vec_type);
18180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
18280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
18380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_update(struct lp_exec_mask *mask)
18480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
18518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (mask->loop_stack_size) {
18618a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin      /*for loops we need to update the entire mask at runtime */
18718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef tmp;
1887fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul      assert(mask->break_mask);
18918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      tmp = LLVMBuildAnd(mask->bld->builder,
19018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->cont_mask,
19118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->break_mask,
19218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         "maskcb");
19318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
19418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     mask->cond_mask,
19518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     tmp,
19618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     "maskfull");
19718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   } else
19818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      mask->exec_mask = mask->cond_mask;
19918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
20032a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   if (mask->call_stack_size) {
2010b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
2020b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     mask->exec_mask,
20332a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                     mask->ret_mask,
2040b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     "callmask");
20532a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   }
20618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
20718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->has_mask = (mask->cond_stack_size > 0 ||
2080b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->loop_stack_size > 0 ||
2090b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->call_stack_size > 0);
21080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
21180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
21280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
21380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                   LLVMValueRef val)
21480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2156c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING);
2162d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 0) {
2172d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cond_mask == LLVMConstAllOnes(mask->int_vec_type));
2182d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
21980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask;
2202d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(LLVMTypeOf(val) == mask->int_vec_type);
2213fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul   mask->cond_mask = LLVMBuildAnd(mask->bld->builder,
2223fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  mask->cond_mask,
2233fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  val,
2243fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  "");
22580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
22680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
22780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
22880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_invert(struct lp_exec_mask *mask)
22980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2302d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef prev_mask;
2312d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef inv_mask;
2322d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2332d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
2342d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   prev_mask = mask->cond_stack[mask->cond_stack_size - 1];
2352d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 1) {
2362d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(prev_mask == LLVMConstAllOnes(mask->int_vec_type));
237faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin   }
238faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin
2392d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   inv_mask = LLVMBuildNot(mask->bld->builder, mask->cond_mask, "");
2402d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
24180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_mask = LLVMBuildAnd(mask->bld->builder,
24280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  inv_mask,
24380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  prev_mask, "");
24480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
24580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
24680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
24780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)
24880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2492d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
25080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_mask = mask->cond_stack[--mask->cond_stack_size];
25180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
25280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
25380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
25418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_bgnloop(struct lp_exec_mask *mask)
25518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
2562d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->loop_stack_size == 0) {
2572d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->loop_block == NULL);
2582d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cont_mask == LLVMConstAllOnes(mask->int_vec_type));
2592d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_mask == LLVMConstAllOnes(mask->int_vec_type));
2602d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_var == NULL);
2612d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
2622d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2632d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size < LP_MAX_TGSI_NESTING);
26418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2652d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].loop_block = mask->loop_block;
2662d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].cont_mask = mask->cont_mask;
2672d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_mask = mask->break_mask;
2682d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_var = mask->break_var;
2692d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   ++mask->loop_stack_size;
2703a423dcf9dfa725a4e5dca60f0f2b02599d2ed9bZack Rusin
2712d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_var = lp_build_alloca(mask->bld->builder, mask->int_vec_type, "");
2722d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
2736c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca
27418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->loop_block = lp_build_insert_new_block(mask->bld->builder, "bgnloop");
27518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBuildBr(mask->bld->builder, mask->loop_block);
27618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block);
27718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2782d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_mask = LLVMBuildLoad(mask->bld->builder, mask->break_var, "");
2792d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
28018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
28118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
28218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
28318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_break(struct lp_exec_mask *mask)
28418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
28518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
28618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
28718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "break");
28818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
289d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin   mask->break_mask = LLVMBuildAnd(mask->bld->builder,
290d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   mask->break_mask,
291d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   exec_mask, "break_full");
29218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
29318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
29418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
29518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
29618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_continue(struct lp_exec_mask *mask)
29718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
29818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
29918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
30018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "");
30118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
302d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin   mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
303d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  mask->cont_mask,
304d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  exec_mask, "");
30518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
30618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
30718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
30818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
30918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
31018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_endloop(struct lp_exec_mask *mask)
31118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
31218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBasicBlockRef endloop;
313d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca   LLVMTypeRef reg_type = LLVMIntType(mask->bld->type.width*
314d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca                                      mask->bld->type.length);
3157fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   LLVMValueRef i1cond;
3167fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
3177fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   assert(mask->break_mask);
3187fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
3192d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
3202d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Restore the cont_mask, but don't pop
3212d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
3222d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
3232d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size - 1].cont_mask;
3242d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   lp_exec_mask_update(mask);
3252d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
3262d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
3272d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Unlike the continue mask, the break_mask must be preserved across loop
3282d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * iterations
3292d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
3302d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
3312d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
332d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca   /* i1cond = (mask == 0) */
3337fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   i1cond = LLVMBuildICmp(
334d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      mask->bld->builder,
335d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMIntNE,
3362d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMBuildBitCast(mask->bld->builder, mask->exec_mask, reg_type, ""),
337d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMConstNull(reg_type), "");
33818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
33918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   endloop = lp_build_insert_new_block(mask->bld->builder, "endloop");
34018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
34118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBuildCondBr(mask->bld->builder,
342ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                   i1cond, mask->loop_block, endloop);
34318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
34418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMPositionBuilderAtEnd(mask->bld->builder, endloop);
34518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
3462d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
3472d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   --mask->loop_stack_size;
3482d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_block = mask->loop_stack[mask->loop_stack_size].loop_block;
3492d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size].cont_mask;
3502d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_mask = mask->loop_stack[mask->loop_stack_size].break_mask;
3512d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_var = mask->loop_stack[mask->loop_stack_size].break_var;
35218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
35318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
35418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
35518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
35618a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin/* stores val into an address pointed to by dst.
35718a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * mask->exec_mask is used to figure out which bits of val
35818a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * should be stored into the address
35918a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * (0 means don't store this bit, 1 means do store).
36018a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin */
36180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_store(struct lp_exec_mask *mask,
362ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                               LLVMValueRef pred,
36380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef val,
36480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef dst)
36580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
366ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   /* Mix the predicate and execution mask */
36780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   if (mask->has_mask) {
368ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (pred) {
36954b94ee96a6d750d57d99ae9819fcf8206d4680dJosé Fonseca         pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, "");
370ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
371ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred = mask->exec_mask;
372ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
373ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
374ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
375ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (pred) {
37680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMValueRef real_val, dst_val;
37780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
37880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      dst_val = LLVMBuildLoad(mask->bld->builder, dst, "");
37980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      real_val = lp_build_select(mask->bld,
380ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                 pred,
38180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                 val, dst_val);
38280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
38380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMBuildStore(mask->bld->builder, real_val, dst);
38480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   } else
38580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMBuildStore(mask->bld->builder, val, dst);
38680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
38780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
3880b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_call(struct lp_exec_mask *mask,
3890b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int func,
3900b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int *pc)
3910b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
39232a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size < LP_MAX_TGSI_NESTING);
3930b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack[mask->call_stack_size].pc = *pc;
39432a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack[mask->call_stack_size].ret_mask = mask->ret_mask;
39532a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack_size++;
3960b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = func;
3970b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
3980b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3990b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
4000b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
4010b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   LLVMValueRef exec_mask;
40232a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca
4030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (mask->call_stack_size == 0) {
4040b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      /* returning from main() */
4050b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
4060b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
4070b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
4080b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   exec_mask = LLVMBuildNot(mask->bld->builder,
4090b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            mask->exec_mask,
4100b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            "ret");
4110b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
41232a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->ret_mask = LLVMBuildAnd(mask->bld->builder,
41332a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 mask->ret_mask,
41432a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 exec_mask, "ret_full");
4150b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4160b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   lp_exec_mask_update(mask);
4170b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
4180b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4190b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_bgnsub(struct lp_exec_mask *mask)
4200b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
4210b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
4220b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4230b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
4240b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
42532a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size);
4260b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size--;
4270b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = mask->call_stack[mask->call_stack_size].pc;
42832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->ret_mask = mask->call_stack[mask->call_stack_size].ret_mask;
42932a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   lp_exec_mask_update(mask);
4300b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
43186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
432695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul
433695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul/**
434695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * Return pointer to a temporary register channel (src or dest).
435f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul * Note that indirect addressing cannot be handled here.
436695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param index  which temporary register
437695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param chan  which channel of the temp register.
438695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul */
43986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic LLVMValueRef
440263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonsecaget_temp_ptr(struct lp_build_tgsi_soa_context *bld,
441263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca             unsigned index,
442f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul             unsigned chan)
443263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca{
444263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   assert(chan < 4);
4453662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
446f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan);
447263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      return LLVMBuildGEP(bld->base.builder, bld->temps_array, &lindex, 1, "");
448263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   }
449695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   else {
450695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul      return bld->temps[index][chan];
451695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   }
452263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca}
453263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca
454528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin/**
455528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * Return pointer to a output register channel (src or dest).
456528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * Note that indirect addressing cannot be handled here.
457528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * \param index  which output register
458528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * \param chan  which channel of the output register.
459528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin */
460528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusinstatic LLVMValueRef
461528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusinget_output_ptr(struct lp_build_tgsi_soa_context *bld,
462528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin               unsigned index,
463528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin               unsigned chan)
464528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin{
465528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   assert(chan < 4);
466528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) {
467528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan);
468528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      return LLVMBuildGEP(bld->base.builder, bld->outputs_array, &lindex, 1, "");
469528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   }
470528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   else {
471528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      return bld->outputs[index][chan];
472528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   }
473528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin}
474528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
4754363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul/**
4764363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * Gather vector.
4774363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * XXX the lp_build_gather() function should be capable of doing this
4784363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * with a little work.
4794363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul */
4804363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulstatic LLVMValueRef
4814363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulbuild_gather(struct lp_build_tgsi_soa_context *bld,
4824363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef base_ptr,
4834363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef indexes)
4844363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul{
4854363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   LLVMValueRef res = bld->base.undef;
4864363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   unsigned i;
4874363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4884363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   /*
4894363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    * Loop over elements of index_vec, load scalar value, insert it into 'res'.
4904363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    */
4914363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   for (i = 0; i < bld->base.type.length; i++) {
4924363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0);
4934363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef index = LLVMBuildExtractElement(bld->base.builder,
4944363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                                   indexes, ii, "");
4954363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, base_ptr,
4963ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                             &index, 1, "gather_ptr");
4974363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
4984363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4994363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      res = LLVMBuildInsertElement(bld->base.builder, res, scalar, ii, "");
5004363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   }
5014363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5024363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   return res;
5034363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul}
5044363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5054363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
50663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
5072fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul * Scatter/store vector.
5082fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul */
5092fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paulstatic void
510e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paulemit_mask_scatter(struct lp_build_tgsi_soa_context *bld,
511e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef base_ptr,
512e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef indexes,
513e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef values,
514e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  struct lp_exec_mask *mask,
515e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef pred)
5162fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul{
5172fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   LLVMBuilderRef builder = bld->base.builder;
5182fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   unsigned i;
5192fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
520e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   /* Mix the predicate and execution mask */
521e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   if (mask->has_mask) {
522e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      if (pred) {
523e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, "");
524e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
525e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      else {
526e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         pred = mask->exec_mask;
527e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
528e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   }
529e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul
5302fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   /*
5312fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul    * Loop over elements of index_vec, store scalar value.
5322fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul    */
5332fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   for (i = 0; i < bld->base.type.length; i++) {
5342fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0);
5352fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef index = LLVMBuildExtractElement(builder, indexes, ii, "");
5362fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, &index, 1, "scatter_ptr");
5372fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef val = LLVMBuildExtractElement(builder, values, ii, "scatter_val");
538e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      LLVMValueRef scalar_pred = pred ?
539e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMBuildExtractElement(builder, pred, ii, "scatter_pred") : NULL;
5402fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
541ede232e9898698258391a280a098a7ba951b0099Brian Paul      if (0)
542ede232e9898698258391a280a098a7ba951b0099Brian Paul         lp_build_printf(builder, "scatter %d: val %f at %d %p\n",
543ede232e9898698258391a280a098a7ba951b0099Brian Paul                         ii, val, index, scalar_ptr);
544ede232e9898698258391a280a098a7ba951b0099Brian Paul
545e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      if (scalar_pred) {
546e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMValueRef real_val, dst_val;
547e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         dst_val = LLVMBuildLoad(builder, scalar_ptr, "");
548e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         real_val = lp_build_select(&bld->elem_bld, scalar_pred, val, dst_val);
549e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMBuildStore(builder, real_val, scalar_ptr);
550e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
551e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      else {
552e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMBuildStore(builder, val, scalar_ptr);
553e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
5542fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   }
5552fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul}
5562fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
5572fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
5582fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul/**
5590115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * Read the current value of the ADDR register, convert the floats to
5602fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul * ints, add the base index and return the vector of offsets.
5610115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * The offsets will be used to index into the constant buffer or
5620115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * temporary register file.
5630115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul */
5640115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paulstatic LLVMValueRef
5656d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonsecaget_indirect_index(struct lp_build_tgsi_soa_context *bld,
5666d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                   unsigned reg_file, unsigned reg_index,
5676d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                   const struct tgsi_src_register *indirect_reg)
5680115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul{
5696d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_build_context *uint_bld = &bld->uint_bld;
5700115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* always use X component of address register */
5713d5b9c1f2d3340259dd0d8765090a5a963074f29José Fonseca   unsigned swizzle = indirect_reg->SwizzleX;
5726d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef base;
5736d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef rel;
5746d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef max_index;
5756d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef index;
5760115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5776d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(bld->indirect_files & (1 << reg_file));
5786d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5796d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   base = lp_build_const_int_vec(uint_bld->type, reg_index);
5806d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5816d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(swizzle < 4);
5826d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   rel = LLVMBuildLoad(bld->base.builder,
5836d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                        bld->addr[indirect_reg->Index][swizzle],
5846d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                        "load addr reg");
5850115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5860115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* for indexing we want integers */
5876d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   rel = LLVMBuildFPToSI(bld->base.builder,
5886d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                         rel,
5896d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                         uint_bld->vec_type, "");
5906d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5916d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   index = lp_build_add(uint_bld, base, rel);
5920115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5936d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   max_index = lp_build_const_int_vec(uint_bld->type,
5946d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                      bld->info->file_max[reg_file]);
5950115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5966d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(!uint_bld->type.sign);
5976d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   index = lp_build_min(uint_bld, index, max_index);
5986d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5996d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   return index;
6000115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul}
6010115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
6020115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
6030115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul/**
60463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register fetch.
60563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
60663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic LLVMValueRef
60763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_fetch(
60863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
6092fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   const struct tgsi_full_instruction *inst,
610ec0e7b16bb6753bedbd611a97062934bfca03aa7Brian Paul   unsigned src_op,
61163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const unsigned chan_index )
61263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
6136d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_build_context *uint_bld = &bld->uint_bld;
614ec0e7b16bb6753bedbd611a97062934bfca03aa7Brian Paul   const struct tgsi_full_src_register *reg = &inst->Src[src_op];
61585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   const unsigned swizzle =
61685c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      tgsi_util_get_full_src_register_swizzle(reg, chan_index);
61763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef res;
6186d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef indirect_index = NULL;
61963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
62085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (swizzle > 3) {
62185c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(0 && "invalid swizzle in emit_fetch()");
62285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      return bld->base.undef;
62385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
62485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul
62585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (reg->Register.Indirect) {
6266d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      indirect_index = get_indirect_index(bld,
6276d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.File,
6286d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.Index,
6296d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          &reg->Indirect);
6306d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   } else {
6316d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      assert(reg->Register.Index <= bld->info->file_max[reg->Register.File]);
63285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
633ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
63485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   switch (reg->Register.File) {
63585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_CONSTANT:
636be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      if (reg->Register.Indirect) {
6376d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         LLVMValueRef swizzle_vec =
6386d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca            lp_build_const_int_vec(uint_bld->type, swizzle);
639be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef index_vec;  /* index into the const buffer */
6404363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
6416d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         /* index_vec = indirect_index * 4 + swizzle */
6426d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
6436d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
6444363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
645be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         /* Gather values from the constant buffer */
646be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         res = build_gather(bld, bld->consts_ptr, index_vec);
647be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      }
648be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      else {
649be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef index;  /* index into the const buffer */
650be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef scalar, scalar_ptr;
651ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
652be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         index = lp_build_const_int32(reg->Register.Index*4 + swizzle);
6534363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
654be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
655be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul                                   &index, 1, "");
656be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
6574363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
658be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         res = lp_build_broadcast_scalar(&bld->base, scalar);
65963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
66085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
66163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
66285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_IMMEDIATE:
663263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      res = bld->immediates[reg->Register.Index][swizzle];
66485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(res);
66585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
66663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
66785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_INPUT:
668f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      if (reg->Register.Indirect) {
669f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         LLVMValueRef swizzle_vec =
670f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            lp_build_const_int_vec(uint_bld->type, swizzle);
671f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         LLVMValueRef length_vec =
672f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            lp_build_const_int_vec(uint_bld->type, bld->base.type.length);
673f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         LLVMValueRef index_vec;  /* index into the const buffer */
674f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         LLVMValueRef inputs_array;
675f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         LLVMTypeRef float4_ptr_type;
676f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
677f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         /* index_vec = (indirect_index * 4 + swizzle) * length */
678f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
679f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
680f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
681f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
682f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         /* cast inputs_array pointer to float* */
683f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
684f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         inputs_array = LLVMBuildBitCast(uint_bld->builder, bld->inputs_array,
685f623d0c1c217d990f207306eb968172af79fa969Zack Rusin                                        float4_ptr_type, "");
686f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
687f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         /* Gather values from the temporary register array */
688f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         res = build_gather(bld, inputs_array, index_vec);
689f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      } else {
690f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) {
691f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            LLVMValueRef lindex = lp_build_const_int32(reg->Register.Index * 4 + swizzle);
692f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            LLVMValueRef input_ptr =  LLVMBuildGEP(bld->base.builder,
693f623d0c1c217d990f207306eb968172af79fa969Zack Rusin                                                   bld->inputs_array, &lindex, 1, "");
694f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            res = LLVMBuildLoad(bld->base.builder, input_ptr, "");
695f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         }
696f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         else {
697f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            res = bld->inputs[reg->Register.Index][swizzle];
698f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         }
699f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      }
70085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(res);
70185c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
70263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
70385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_TEMPORARY:
704105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      if (reg->Register.Indirect) {
7056d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         LLVMValueRef swizzle_vec =
7066d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca            lp_build_const_int_vec(uint_bld->type, swizzle);
7076d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         LLVMValueRef length_vec =
7086d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca            lp_build_const_int_vec(uint_bld->type, bld->base.type.length);
709105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef index_vec;  /* index into the const buffer */
710105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef temps_array;
711105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMTypeRef float4_ptr_type;
7124363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
7136d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         /* index_vec = (indirect_index * 4 + swizzle) * length */
7146d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
7156d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
7166d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
717105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
718105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* cast temps_array pointer to float* */
719105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
7206d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         temps_array = LLVMBuildBitCast(uint_bld->builder, bld->temps_array,
721105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul                                        float4_ptr_type, "");
722105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
723105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* Gather values from the temporary register array */
724105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         res = build_gather(bld, temps_array, index_vec);
725105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      }
726105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      else {
727105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef temp_ptr;
728f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         temp_ptr = get_temp_ptr(bld, reg->Register.Index, swizzle);
729021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin         res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
730105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         if (!res)
73163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            return bld->base.undef;
73263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
73363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
73463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
73563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
73685c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(0 && "invalid src register in emit_fetch()");
7374d7a8194c5763f70ba559f32f58dfda36237b666José Fonseca      return bld->base.undef;
73863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
73963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
74063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) {
74163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_CLEAR:
74263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = lp_build_abs( &bld->base, res );
74363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
74463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
74563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_SET:
74663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = lp_build_abs( &bld->base, res );
747fc9a49b638c26801951c33a570178bbb2b67ec60nobled      /* fall through */
74863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_TOGGLE:
7498a3a971743a90463e65b44f1769a5301a31ce4cdJosé Fonseca      res = lp_build_negate( &bld->base, res );
75063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
75163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
75263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_KEEP:
75363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
75463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
75563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
75663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   return res;
75763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
75863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
75963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
76063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
76186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca * Register fetch with derivatives.
76286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca */
76386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic void
76486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecaemit_fetch_deriv(
76586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   struct lp_build_tgsi_soa_context *bld,
76686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   const struct tgsi_full_instruction *inst,
76786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   unsigned index,
76886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   const unsigned chan_index,
76986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *res,
77086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddx,
77186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddy)
77286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca{
77386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef src;
77486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
77586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   src = emit_fetch(bld, inst, index, chan_index);
77686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
77786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(res)
77886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      *res = src;
77986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
78086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   /* TODO: use interpolation coeffs for inputs */
78186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
78286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddx)
783ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca      *ddx = lp_build_ddx(&bld->base, src);
78486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
78586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddy)
786ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca      *ddy = lp_build_ddy(&bld->base, src);
78786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca}
78886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
78986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
79086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca/**
791ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca * Predicate.
792ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca */
793ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecastatic void
794ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecaemit_fetch_predicate(
795ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
796ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   const struct tgsi_full_instruction *inst,
797ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef *pred)
798ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca{
799ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned index;
800ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned char swizzles[4];
801ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef unswizzled[4] = {NULL, NULL, NULL, NULL};
802ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef value;
803ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned chan;
804ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
805ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (!inst->Instruction.Predicate) {
806ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      FOR_EACH_CHANNEL( chan ) {
807ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred[chan] = NULL;
808ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
809ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      return;
810ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
811ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
812ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[0] = inst->Predicate.SwizzleX;
813ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[1] = inst->Predicate.SwizzleY;
814ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[2] = inst->Predicate.SwizzleZ;
815ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[3] = inst->Predicate.SwizzleW;
816ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
817ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   index = inst->Predicate.Index;
818ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   assert(index < LP_MAX_TGSI_PREDS);
819ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
820ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   FOR_EACH_CHANNEL( chan ) {
821ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      unsigned swizzle = swizzles[chan];
822ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
823ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      /*
824ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * Only fetch the predicate register channels that are actually listed
825ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * in the swizzles
826ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       */
827ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (!unswizzled[swizzle]) {
828ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = LLVMBuildLoad(bld->base.builder,
829263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                               bld->preds[index][swizzle], "");
830ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
831ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         /*
832ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * Convert the value to an integer mask.
833ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          *
834ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * TODO: Short-circuit this comparison -- a D3D setp_xx instructions
835ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * is needlessly causing two comparisons due to storing the intermediate
836ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * result as float vector instead of an integer mask vector.
837ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          */
838ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = lp_build_compare(bld->base.builder,
839ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  bld->base.type,
840ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  PIPE_FUNC_NOTEQUAL,
841ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  value,
842ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  bld->base.zero);
843ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         if (inst->Predicate.Negate) {
844ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca            value = LLVMBuildNot(bld->base.builder, value, "");
845ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         }
846ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
847ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         unswizzled[swizzle] = value;
848ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
849ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = unswizzled[swizzle];
850ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
851ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
852ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      pred[chan] = value;
853ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
854ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca}
855ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
856ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
857ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca/**
85863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register store.
85963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
86063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
86163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_store(
86263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
86363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const struct tgsi_full_instruction *inst,
8642fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   unsigned index,
86563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index,
866ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef pred,
86763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef value)
86863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
8697d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_dst_register *reg = &inst->Dst[index];
8702fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   struct lp_build_context *uint_bld = &bld->uint_bld;
8716d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef indirect_index = NULL;
8722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca
87363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( inst->Instruction.Saturate ) {
87463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_NONE:
87563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
87663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
87763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_ZERO_ONE:
8787926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_max(&bld->base, value, bld->base.zero);
8797926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_min(&bld->base, value, bld->base.one);
88063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
88163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
88263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_MINUS_PLUS_ONE:
883185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul      value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.type, -1.0));
8847926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_min(&bld->base, value, bld->base.one);
88563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
8867926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca
8877926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca   default:
8887926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      assert(0);
88963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
89063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
891021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   if (reg->Register.Indirect) {
8926d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      indirect_index = get_indirect_index(bld,
8936d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.File,
8946d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.Index,
8956d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          &reg->Indirect);
8966d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   } else {
8976d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      assert(reg->Register.Index <= bld->info->file_max[reg->Register.File]);
898021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   }
899021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
9005b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   switch( reg->Register.File ) {
90163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_OUTPUT:
902528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      if (reg->Register.Indirect) {
903528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMBuilderRef builder = bld->base.builder;
904528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef chan_vec =
905528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin            lp_build_const_int_vec(uint_bld->type, chan_index);
906528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef length_vec =
907528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin            lp_build_const_int_vec(uint_bld->type, bld->base.type.length);
908528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef index_vec;  /* indexes into the temp registers */
909528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef outputs_array;
910528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef pixel_offsets;
911528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMTypeRef float_ptr_type;
912528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         int i;
913528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
914528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         /* build pixel offset vector: {0, 1, 2, 3, ...} */
915528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         pixel_offsets = uint_bld->undef;
916528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         for (i = 0; i < bld->base.type.length; i++) {
917528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin            LLVMValueRef ii = lp_build_const_int32(i);
918528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin            pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
919528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                                   ii, ii, "");
920528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         }
921528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
922528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */
923528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
924528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_add(uint_bld, index_vec, chan_vec);
925528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
926528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
927528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
928528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         float_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
929528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         outputs_array = LLVMBuildBitCast(builder, bld->outputs_array,
930528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                          float_ptr_type, "");
931528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
932528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         /* Scatter store values into temp registers */
933528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         emit_mask_scatter(bld, outputs_array, index_vec, value,
934528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                           &bld->exec_mask, pred);
935528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      }
936528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      else {
937528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef out_ptr = get_output_ptr(bld, reg->Register.Index,
938528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                               chan_index);
939528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         lp_exec_mask_store(&bld->exec_mask, pred, value, out_ptr);
940528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      }
94163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
94263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
943f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul   case TGSI_FILE_TEMPORARY:
944f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      if (reg->Register.Indirect) {
945ede232e9898698258391a280a098a7ba951b0099Brian Paul         LLVMBuilderRef builder = bld->base.builder;
9462fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef chan_vec =
9472fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul            lp_build_const_int_vec(uint_bld->type, chan_index);
9482fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef length_vec =
9492fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul            lp_build_const_int_vec(uint_bld->type, bld->base.type.length);
9502fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef index_vec;  /* indexes into the temp registers */
9512fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef temps_array;
952ede232e9898698258391a280a098a7ba951b0099Brian Paul         LLVMValueRef pixel_offsets;
9532fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMTypeRef float_ptr_type;
954ede232e9898698258391a280a098a7ba951b0099Brian Paul         int i;
955ede232e9898698258391a280a098a7ba951b0099Brian Paul
956ede232e9898698258391a280a098a7ba951b0099Brian Paul         /* build pixel offset vector: {0, 1, 2, 3, ...} */
957ede232e9898698258391a280a098a7ba951b0099Brian Paul         pixel_offsets = uint_bld->undef;
958ede232e9898698258391a280a098a7ba951b0099Brian Paul         for (i = 0; i < bld->base.type.length; i++) {
959ede232e9898698258391a280a098a7ba951b0099Brian Paul            LLVMValueRef ii = lp_build_const_int32(i);
960ede232e9898698258391a280a098a7ba951b0099Brian Paul            pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
961ede232e9898698258391a280a098a7ba951b0099Brian Paul                                                   ii, ii, "");
962ede232e9898698258391a280a098a7ba951b0099Brian Paul         }
9632fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
964ede232e9898698258391a280a098a7ba951b0099Brian Paul         /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */
9652fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
9662fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_add(uint_bld, index_vec, chan_vec);
9672fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
968ede232e9898698258391a280a098a7ba951b0099Brian Paul         index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
9692fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
9702fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         float_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
971ede232e9898698258391a280a098a7ba951b0099Brian Paul         temps_array = LLVMBuildBitCast(builder, bld->temps_array,
9722fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul                                        float_ptr_type, "");
9732fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
9742fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         /* Scatter store values into temp registers */
975e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         emit_mask_scatter(bld, temps_array, index_vec, value,
976e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                           &bld->exec_mask, pred);
977f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
978f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      else {
979f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
980f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul                                              chan_index);
981f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr);
982f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
98363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
98463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
98563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_ADDRESS:
986ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
987263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                         bld->addr[reg->Indirect.Index][chan_index]);
98863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
98963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
990ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca   case TGSI_FILE_PREDICATE:
991ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
9928690c6a6b4fb0b48e2ae75cd0f64de86b039081cmichal                         bld->preds[reg->Register.Index][chan_index]);
993ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca      break;
994ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca
99563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
99663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert( 0 );
99763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
99863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
99963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
100063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
100163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
100263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * High-level instruction translators.
100363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
100463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
100563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
100663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_tex( struct lp_build_tgsi_soa_context *bld,
100763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca          const struct tgsi_full_instruction *inst,
100858daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca          enum lp_build_tex_modifier modifier,
1009faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca          LLVMValueRef *texel)
101063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
1011962558daaed43b0111cd062e32821aad106869d7José Fonseca   unsigned unit;
1012ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   LLVMValueRef lod_bias, explicit_lod;
101331d1822473bf9d4105bb82b67572cfeea53aaf94Vinson Lee   LLVMValueRef oow = NULL;
1014c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   LLVMValueRef coords[3];
1015962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddx[3];
1016962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddy[3];
1017c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   unsigned num_coords;
101863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
101963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
10209db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   if (!bld->sampler) {
10219db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
10229db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      for (i = 0; i < 4; i++) {
10239db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca         texel[i] = bld->base.undef;
10249db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      }
10259db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      return;
10269db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   }
10279db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca
10287d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   switch (inst->Texture.Texture) {
102963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_1D:
1030c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 1;
103163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
103263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_2D:
103363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_RECT:
1034c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 2;
103563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
1036f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW1D:
1037f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW2D:
1038f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOWRECT:
103963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_3D:
104063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_CUBE:
1041c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 3;
104263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
104363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
104463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert(0);
104563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      return;
104663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
104763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
104858daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS) {
1049ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = emit_fetch( bld, inst, 0, 3 );
1050ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
1051ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
105258daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   else if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
1053ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
1054ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = emit_fetch( bld, inst, 0, 3 );
1055ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
1056ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   else {
1057ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
1058ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
1059ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
106063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
106158daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED) {
10622fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      oow = emit_fetch( bld, inst, 0, 3 );
106363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      oow = lp_build_rcp(&bld->base, oow);
106463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
106563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1066c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   for (i = 0; i < num_coords; i++) {
1067c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      coords[i] = emit_fetch( bld, inst, 0, i );
106858daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED)
1069c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca         coords[i] = lp_build_mul(&bld->base, coords[i], oow);
107063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
1071ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   for (i = num_coords; i < 3; i++) {
1072ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca      coords[i] = bld->base.undef;
1073ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   }
107463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
107558daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
107617dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca      LLVMTypeRef i32t = LLVMInt32Type();
107717dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca      LLVMValueRef index0 = LLVMConstInt(i32t, 0, 0);
1078962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
107917dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         LLVMValueRef src1 = emit_fetch( bld, inst, 1, i );
108017dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         LLVMValueRef src2 = emit_fetch( bld, inst, 2, i );
108117dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         ddx[i] = LLVMBuildExtractElement(bld->base.builder, src1, index0, "");
108217dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         ddy[i] = LLVMBuildExtractElement(bld->base.builder, src2, index0, "");
1083962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
1084962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[3].Register.Index;
1085962558daaed43b0111cd062e32821aad106869d7José Fonseca   }  else {
1086962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
108717dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         ddx[i] = lp_build_scalar_ddx( &bld->base, coords[i] );
108817dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         ddy[i] = lp_build_scalar_ddy( &bld->base, coords[i] );
1089962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
1090962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[1].Register.Index;
1091962558daaed43b0111cd062e32821aad106869d7José Fonseca   }
10924554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   for (i = num_coords; i < 3; i++) {
109317dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca      ddx[i] = LLVMGetUndef(bld->base.elem_type);
109417dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca      ddy[i] = LLVMGetUndef(bld->base.elem_type);
10954554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   }
1096962558daaed43b0111cd062e32821aad106869d7José Fonseca
10978be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld->sampler->emit_fetch_texel(bld->sampler,
10988be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  bld->base.builder,
10998be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  bld->base.type,
1100962558daaed43b0111cd062e32821aad106869d7José Fonseca                                  unit, num_coords, coords,
1101ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  ddx, ddy,
1102ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  lod_bias, explicit_lod,
11038be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  texel);
110463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
110563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
110622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwellstatic boolean
110722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwellnear_end_of_shader(struct lp_build_tgsi_soa_context *bld,
110822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell		   int pc)
110922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell{
111022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   int i;
111122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
111222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   for (i = 0; i < 5; i++) {
111322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      unsigned opcode;
111422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
111522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (pc + i >= bld->info->num_instructions)
111622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return TRUE;
111722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
111822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      opcode = bld->instructions[pc + i].Instruction.Opcode;
111922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
112022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (opcode == TGSI_OPCODE_END)
112122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return TRUE;
112222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
112322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (opcode == TGSI_OPCODE_TEX ||
112422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXP ||
112522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXD ||
112622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXB ||
112722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXL ||
112822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXF ||
112922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXQ ||
113022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_CAL ||
113122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_CALLNZ ||
113222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_IF ||
113322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_IFC ||
113422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_BGNLOOP ||
113522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_SWITCH)
113622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return FALSE;
113722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   }
113822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
113922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   return TRUE;
114022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell}
114122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
114222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
114363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1144feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul/**
1145feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Kill fragment if any of the src register values are negative.
1146feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
114763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
114863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_kil(
114963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
115022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   const struct tgsi_full_instruction *inst,
115122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   int pc)
115263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
11537d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_src_register *reg = &inst->Src[0];
11547821664b15501b173b2304bbada758c33c5ff972José Fonseca   LLVMValueRef terms[NUM_CHANNELS];
11553d7a88674f9eb3320eeff511968f041426e25023José Fonseca   LLVMValueRef mask;
115663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
115763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11587821664b15501b173b2304bbada758c33c5ff972José Fonseca   memset(&terms, 0, sizeof terms);
115963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
116063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   FOR_EACH_CHANNEL( chan_index ) {
116163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      unsigned swizzle;
116263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11637821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Unswizzle channel */
1164b9cb74c7f826dfd320f5e5b54aa933898f7ddd3dKeith Whitwell      swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
116563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11667821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Check if the component has not been already tested. */
11677821664b15501b173b2304bbada758c33c5ff972José Fonseca      assert(swizzle < NUM_CHANNELS);
11687821664b15501b173b2304bbada758c33c5ff972José Fonseca      if( !terms[swizzle] )
11697821664b15501b173b2304bbada758c33c5ff972José Fonseca         /* TODO: change the comparison operator instead of setting the sign */
11702fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         terms[swizzle] =  emit_fetch(bld, inst, 0, chan_index );
117163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
117263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11733d7a88674f9eb3320eeff511968f041426e25023José Fonseca   mask = NULL;
11747821664b15501b173b2304bbada758c33c5ff972José Fonseca   FOR_EACH_CHANNEL( chan_index ) {
1175aede39efd86d200ffbace8fc012104e31f673973José Fonseca      if(terms[chan_index]) {
11763d7a88674f9eb3320eeff511968f041426e25023José Fonseca         LLVMValueRef chan_mask;
1177aede39efd86d200ffbace8fc012104e31f673973José Fonseca
1178feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul         /*
1179feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          * If term < 0 then mask = 0 else mask = ~0.
1180feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          */
11813d7a88674f9eb3320eeff511968f041426e25023José Fonseca         chan_mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero);
1182aede39efd86d200ffbace8fc012104e31f673973José Fonseca
11833d7a88674f9eb3320eeff511968f041426e25023José Fonseca         if(mask)
11843d7a88674f9eb3320eeff511968f041426e25023José Fonseca            mask = LLVMBuildAnd(bld->base.builder, mask, chan_mask, "");
11853d7a88674f9eb3320eeff511968f041426e25023José Fonseca         else
11863d7a88674f9eb3320eeff511968f041426e25023José Fonseca            mask = chan_mask;
1187aede39efd86d200ffbace8fc012104e31f673973José Fonseca      }
118863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
11893d7a88674f9eb3320eeff511968f041426e25023José Fonseca
1190aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell   if(mask) {
11913d7a88674f9eb3320eeff511968f041426e25023José Fonseca      lp_build_mask_update(bld->mask, mask);
1192aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell
119322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (!near_end_of_shader(bld, pc))
119422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 lp_build_mask_check(bld->mask);
1195aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell   }
119663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
119763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
119863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
119963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
1200feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Predicated fragment kill.
1201feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * XXX Actually, we do an unconditional kill (as in tgsi_exec.c).
1202feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * The only predication is the execution mask which will apply if
1203feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * we're inside a loop or conditional.
1204feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
1205feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulstatic void
1206feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulemit_kilp(struct lp_build_tgsi_soa_context *bld,
120722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell          const struct tgsi_full_instruction *inst,
120822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  int pc)
1209feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul{
1210feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   LLVMValueRef mask;
1211feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
1212feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   /* For those channels which are "alive", disable fragment shader
1213feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    * execution.
1214feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    */
1215feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   if (bld->exec_mask.has_mask) {
1216feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul      mask = LLVMBuildNot(bld->base.builder, bld->exec_mask.exec_mask, "kilp");
1217feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
1218feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   else {
1219ec2824cd867d3b782588be1f3b1d5d802eb381abBrian Paul      LLVMValueRef zero = LLVMConstNull(bld->base.int_vec_type);
1220ec2824cd867d3b782588be1f3b1d5d802eb381abBrian Paul      mask = zero;
1221feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
1222feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
1223feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   lp_build_mask_update(bld->mask, mask);
1224aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell
122522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   if (!near_end_of_shader(bld, pc))
122622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      lp_build_mask_check(bld->mask);
1227feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul}
1228feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
12295b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12305b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul/**
12315b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul * Emit code which will dump the value of all the temporary registers
12325b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul * to stdout.
12335b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul */
12345b294a5d17c818ecbb1295fdd20825da9b106792Brian Paulstatic void
12355b294a5d17c818ecbb1295fdd20825da9b106792Brian Paulemit_dump_temps(struct lp_build_tgsi_soa_context *bld)
12365b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul{
12375b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMBuilderRef builder = bld->base.builder;
12385b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef temp_ptr;
12395b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef i0 = lp_build_const_int32(0);
12405b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef i1 = lp_build_const_int32(1);
12415b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef i2 = lp_build_const_int32(2);
12425b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef i3 = lp_build_const_int32(3);
12435b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   int index;
12445b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   int n = bld->info->file_max[TGSI_FILE_TEMPORARY];
12455b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12465b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   for (index = 0; index < n; index++) {
12475b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      LLVMValueRef idx = lp_build_const_int32(index);
12485b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      LLVMValueRef v[4][4], res;
12495b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      int chan;
12505b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12515b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      lp_build_printf(builder, "TEMP[%d]:\n", idx);
12525b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12535b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      for (chan = 0; chan < 4; chan++) {
12545b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         temp_ptr = get_temp_ptr(bld, index, chan);
12555b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
12565b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][0] = LLVMBuildExtractElement(builder, res, i0, "");
12575b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][1] = LLVMBuildExtractElement(builder, res, i1, "");
12585b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][2] = LLVMBuildExtractElement(builder, res, i2, "");
12595b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][3] = LLVMBuildExtractElement(builder, res, i3, "");
12605b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      }
12615b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12625b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      lp_build_printf(builder, "  X: %f %f %f %f\n",
12635b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[0][0], v[0][1], v[0][2], v[0][3]);
12645b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      lp_build_printf(builder, "  Y: %f %f %f %f\n",
12655b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[1][0], v[1][1], v[1][2], v[1][3]);
12665b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      lp_build_printf(builder, "  Z: %f %f %f %f\n",
12675b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[2][0], v[2][1], v[2][2], v[2][3]);
12685b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      lp_build_printf(builder, "  W: %f %f %f %f\n",
12695b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[3][0], v[3][1], v[3][2], v[3][3]);
12705b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   }
12715b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul}
12725b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12735b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12745b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
1275e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonsecastatic void
127685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusinemit_declaration(
127785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   struct lp_build_tgsi_soa_context *bld,
127885c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   const struct tgsi_full_declaration *decl)
127985c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin{
12806d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMTypeRef vec_type = bld->base.vec_type;
128155c5408ad049423597cd274e7abcd2d91a16ead3Brian Paul   const unsigned first = decl->Range.First;
128255c5408ad049423597cd274e7abcd2d91a16ead3Brian Paul   const unsigned last = decl->Range.Last;
128385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned idx, i;
128485c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
128585c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   for (idx = first; idx <= last; ++idx) {
12866d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      assert(last <= bld->info->file_max[decl->Declaration.File]);
128785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      switch (decl->Declaration.File) {
128885c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_TEMPORARY:
12896c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_TEMPS);
129010740acf46e08960dde790005d65a98440f313bcJosé Fonseca         if (!(bld->indirect_files & (1 << TGSI_FILE_TEMPORARY))) {
1291021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin            for (i = 0; i < NUM_CHANNELS; i++)
1292a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca               bld->temps[idx][i] = lp_build_alloca(bld->base.builder,
12933ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                                    vec_type, "temp");
1294021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin         }
129585c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
129685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
129785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_OUTPUT:
129810740acf46e08960dde790005d65a98440f313bcJosé Fonseca         if (!(bld->indirect_files & (1 << TGSI_FILE_OUTPUT))) {
1299528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin            for (i = 0; i < NUM_CHANNELS; i++)
1300528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin               bld->outputs[idx][i] = lp_build_alloca(bld->base.builder,
1301528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                                      vec_type, "output");
1302528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         }
130385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
130485c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
1305ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin      case TGSI_FILE_ADDRESS:
13066c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_ADDRS);
1307263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1308263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->addr[idx][i] = lp_build_alloca(bld->base.builder,
13093ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                                vec_type, "addr");
1310ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         break;
1311ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
1312e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca      case TGSI_FILE_PREDICATE:
1313ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         assert(idx < LP_MAX_TGSI_PREDS);
1314263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1315263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->preds[idx][i] = lp_build_alloca(bld->base.builder,
13163ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                                 vec_type, "predicate");
1317e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         break;
1318e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca
131985c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      default:
132085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         /* don't need to declare other vars */
1321dc886ba1391d7d890bd1f5532bc14553e883a418Zack Rusin         break;
1322012fabca722494162c244a367913562b8cfa4677Zack Rusin      }
132385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   }
132485c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin}
132563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1326fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul
1327fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul/**
1328fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul * Emit LLVM for one TGSI instruction.
1329fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul * \param return TRUE for success, FALSE otherwise
1330fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul */
1331fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paulstatic boolean
133263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_instruction(
133363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
1334faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   const struct tgsi_full_instruction *inst,
13350b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   const struct tgsi_opcode_info *info,
13360b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int *pc)
133763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
133863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
133990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   LLVMValueRef src0, src1, src2;
1340e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp0, tmp1, tmp2;
1341e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp3 = NULL;
1342e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp4 = NULL;
1343e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp5 = NULL;
1344e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp6 = NULL;
1345e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp7 = NULL;
1346faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   LLVMValueRef res;
1347faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   LLVMValueRef dst0[NUM_CHANNELS];
134863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
134989258652b6a1d282bed14549907892bdfda752f0José Fonseca   /*
135089258652b6a1d282bed14549907892bdfda752f0José Fonseca    * Stores and write masks are handled in a general fashion after the long
135189258652b6a1d282bed14549907892bdfda752f0José Fonseca    * instruction opcode switch statement.
135289258652b6a1d282bed14549907892bdfda752f0José Fonseca    *
135389258652b6a1d282bed14549907892bdfda752f0José Fonseca    * Although not stricitly necessary, we avoid generating instructions for
135489258652b6a1d282bed14549907892bdfda752f0José Fonseca    * channels which won't be stored, in cases where's that easy. For some
135589258652b6a1d282bed14549907892bdfda752f0José Fonseca    * complex instructions, like texture sampling, it is more convenient to
135689258652b6a1d282bed14549907892bdfda752f0José Fonseca    * assume a full writemask and then let LLVM optimization passes eliminate
135789258652b6a1d282bed14549907892bdfda752f0José Fonseca    * redundant code.
135889258652b6a1d282bed14549907892bdfda752f0José Fonseca    */
135989258652b6a1d282bed14549907892bdfda752f0José Fonseca
13600b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   (*pc)++;
13610b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1362faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   assert(info->num_dst <= 1);
1363ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (info->num_dst) {
1364faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1365faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.undef;
1366faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
1367faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
1368faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
136963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch (inst->Instruction.Opcode) {
137063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARL:
13712fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1373ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         tmp0 = lp_build_floor(&bld->base, tmp0);
1374faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
137563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
137663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
137763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
137863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MOV:
13792fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1380faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = emit_fetch( bld, inst, 0, chan_index );
138163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
138263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
138363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
138463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LIT:
13852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ) {
1386faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = bld->base.one;
138763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
13882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
13892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
1390faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_max( &bld->base, src0, bld->base.zero);
1391ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca      }
13922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
1393ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[1] = SrcReg[0].yyyy */
13942fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
1395ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[1] = max(XMM[1], 0) */
1396ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         tmp1 = lp_build_max( &bld->base, tmp1, bld->base.zero);
1397ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[2] = SrcReg[0].wwww */
13982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 0, CHAN_W );
1399ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         tmp1 = lp_build_pow( &bld->base, tmp1, tmp2);
14002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1401c5abcac7ef7ebd0167093285b5fc9cf3829c1febJosé Fonseca         tmp2 = lp_build_cmp(&bld->base, PIPE_FUNC_GREATER, tmp0, bld->base.zero);
1402faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = lp_build_select(&bld->base, tmp2, tmp1, bld->base.zero);
1403c5abcac7ef7ebd0167093285b5fc9cf3829c1febJosé Fonseca      }
14042fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) ) {
1405faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
140663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
140763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
140863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
140963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RCP:
141063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_RECIP */
14112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
1412faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_rcp(&bld->base, src0);
14132fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1414faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
141563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
141663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
141763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
141863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RSQ:
141963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_RECIPSQRT */
14202fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
142190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      src0 = lp_build_abs(&bld->base, src0);
1422faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_rsqrt(&bld->base, src0);
14232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1424faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
142563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
142663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
142763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
142863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_EXP:
14292fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
14302fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
14312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
143257907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_exp2_int_part = NULL;
143357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_frac_part = NULL;
143457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_exp2 = NULL;
143557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
14362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
143757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
14382fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
143957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp2_int_part = &tmp0;
14402fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
144157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_frac_part = &tmp1;
14422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
144357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp2 = &tmp2;
144457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
144557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         lp_build_exp2_approx(&bld->base, src0, p_exp2_int_part, p_frac_part, p_exp2);
144657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
14472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
1448faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_X] = tmp0;
14492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
1450faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Y] = tmp1;
14512fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
1452faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Z] = tmp2;
145363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
145463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* dst.w = 1.0 */
14552fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
1456faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
145763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
145863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
145963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
146063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LOG:
14612fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
14622fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
14632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
1464add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_floor_log2 = NULL;
1465add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_exp = NULL;
1466add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_log2 = NULL;
146757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
14682fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
146957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         src0 = lp_build_abs( &bld->base, src0 );
147057907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
14712fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
147257907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_floor_log2 = &tmp0;
14732fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
147457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp = &tmp1;
14752fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
147657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_log2 = &tmp2;
147757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
147857907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         lp_build_log2_approx(&bld->base, src0, p_exp, p_floor_log2, p_log2);
147957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
148057907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.x = floor(lg2(abs(src.x))) */
14812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
1482faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_X] = tmp0;
148357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.y = abs(src)/ex2(floor(lg2(abs(src.x)))) */
14842fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y )) {
1485faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Y] = lp_build_div( &bld->base, src0, tmp1);
148663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
148757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.z = lg2(abs(src.x)) */
14882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
1489faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Z] = tmp2;
149063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
149163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* dst.w = 1.0 */
14922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
1493faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
149463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
149563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
149663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
149763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MUL:
14982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14992fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1501faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_mul(&bld->base, src0, src1);
150263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
150363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
150463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
150563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ADD:
15062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1509faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_add(&bld->base, src0, src1);
151063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
151163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
151263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
151363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP3:
151463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_DOT3 */
15152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
15162fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
151790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
15182fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
15192fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
152090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
152190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
15232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
152490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
152590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1527faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
152863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
152963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
153063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
153163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP4:
153263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_DOT4 */
15332fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
15342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
153590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
15362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
15372fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
153890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
153990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15402fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
15412fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
154290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
154390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15442fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_W );
15452fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_W );
154690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
154790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15482fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1549faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
155063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
155163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
155263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
155363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DST:
15542fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
1555faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = bld->base.one;
155663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
15572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
15582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
15592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, CHAN_Y );
1560faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp0, tmp1);
156163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
15622fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
1563faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = emit_fetch( bld, inst, 0, CHAN_Z );
156463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
15652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1566faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = emit_fetch( bld, inst, 1, CHAN_W );
156763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
156863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
156963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
157063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MIN:
15712fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15732fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1574faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_min( &bld->base, src0, src1 );
157563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
157663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
157763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
157863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MAX:
15792fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1582faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_max( &bld->base, src0, src1 );
158363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
158463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
158563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
158663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SLT:
158763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SETLT */
15882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
15911aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, src1 );
1592faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
15931aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
159463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
159563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
159663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SGE:
159763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SETGE */
15982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15992fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
16002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
16011aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GEQUAL, src0, src1 );
1602faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
16031aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
160463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
160563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
160663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MAD:
160763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_MADD */
16082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16092fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
16102fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, chan_index );
16112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 2, chan_index );
161290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
161390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_add( &bld->base, tmp0, tmp2);
1614faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
161563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
161663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
161763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
161863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SUB:
16192fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16202fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
16212fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, chan_index );
1622faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_sub( &bld->base, tmp0, tmp1);
162363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
162463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
162563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
162663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LRP:
16272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16282fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
16292fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
16302fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
163190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_sub( &bld->base, src1, src2 );
163290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, src0, tmp0 );
1633faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_add( &bld->base, tmp0, src2 );
163463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
163563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
163663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
163763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CND:
1638873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1639873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
1640873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1641873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
1642185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul         tmp1 = lp_build_const_vec(bld->base.type, 0.5);
1643873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src2, tmp1);
1644faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, src0, src1 );
1645873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
164663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
164763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
164863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP2A:
16492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );  /* xmm0 = src[0].x */
16502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );  /* xmm1 = src[1].x */
165190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 * xmm1 */
16522fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );  /* xmm1 = src[0].y */
16532fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );  /* xmm2 = src[1].y */
165490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);              /* xmm1 = xmm1 * xmm2 */
165590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
16562fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 2, CHAN_X );  /* xmm1 = src[2].x */
165790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
16582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1659faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;  /* dest[ch] = xmm0 */
166063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
166163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
166263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
166363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_FRC:
16642fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1665873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
1666873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_floor(&bld->base, src0);
1667f1f49bd465b899d1c85aa07650ca5b62a50303b0Brian Paul         tmp0 = lp_build_sub(&bld->base, src0, tmp0);
1668faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
166963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
167063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
167163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
167263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CLAMP:
1673873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1674873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1675873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1676873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
1677873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_max(&bld->base, tmp0, src1);
1678873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_min(&bld->base, tmp0, src2);
1679faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
1680873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
168163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
168263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
168363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_FLR:
16842fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1686faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_floor(&bld->base, tmp0);
168763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
168863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
168963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
169063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ROUND:
16912fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1693faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_round(&bld->base, tmp0);
169463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
169563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
169663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
169790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   case TGSI_OPCODE_EX2: {
16982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
169990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_exp2( &bld->base, tmp0);
17002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1701faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
170263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
170363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
170490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   }
170563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
170663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LG2:
17072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
170890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_log2( &bld->base, tmp0);
17092fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1710faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
171163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
171263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
171363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
171463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_POW:
17152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
17162fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src1 = emit_fetch( bld, inst, 1, CHAN_X );
1717faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_pow( &bld->base, src0, src1 );
17182fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1719faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
172063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
172163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
172263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
172363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_XPD:
17242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
17252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
17262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, CHAN_Z );
17272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp3 = emit_fetch( bld, inst, 0, CHAN_Z );
172863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17292fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
17302fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
17312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
17322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp4 = emit_fetch( bld, inst, 1, CHAN_Y );
173363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
173590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = tmp0;
173690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = lp_build_mul( &bld->base, tmp2, tmp1);
173790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = tmp3;
173890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
173990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = lp_build_sub( &bld->base, tmp2, tmp5);
1740faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = tmp2;
174163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
17432fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
17442fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 1, CHAN_X );
17452fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp5 = emit_fetch( bld, inst, 0, CHAN_X );
174663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
174890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp3 = lp_build_mul( &bld->base, tmp3, tmp2);
174990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp1 = lp_build_mul( &bld->base, tmp1, tmp5);
175090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp3 = lp_build_sub( &bld->base, tmp3, tmp1);
1751faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = tmp3;
175263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17532fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
175490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
175590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, tmp0, tmp2);
175690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_sub( &bld->base, tmp5, tmp0);
1757faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = tmp5;
175863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1760faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
176163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
176263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
176363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
176463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ABS:
17652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
17662fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1767faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_abs( &bld->base, tmp0 );
176863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
176963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
177063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
177163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RCC:
1772873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1773873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1774fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
177563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
177663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DPH:
17772fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
17782fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
177990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
17802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
17812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
178290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
178390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
17842fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
17852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
178690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
178790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
17882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_W );
178990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
17902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1791faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
179263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
179363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
179463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
179563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_COS:
17962fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
179790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_cos( &bld->base, tmp0 );
17982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1799faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
180063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
180163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
180263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
180363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DDX:
180486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
180586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca         emit_fetch_deriv( bld, inst, 0, chan_index, NULL, &dst0[chan_index], NULL);
180686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      }
180763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
180863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
180963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DDY:
181086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
181186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca         emit_fetch_deriv( bld, inst, 0, chan_index, NULL, NULL, &dst0[chan_index]);
181286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      }
181363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
181463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
181563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_KILP:
181663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* predicated kill */
181722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      emit_kilp( bld, inst, (*pc)-1 );
181863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
181963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
182063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_KIL:
182163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* conditional kill */
182222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      emit_kil( bld, inst, (*pc)-1 );
182363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
182463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
182563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK2H:
1826fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
182763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
182863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
182963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK2US:
1830fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
183163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
183263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
183363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK4B:
1834fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
183563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
183663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
183763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK4UB:
1838fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
183963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
184063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
184163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RFL:
1842fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
184363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
184463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
184563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SEQ:
18462fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
18482fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
18491aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_EQUAL, src0, src1 );
1850faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
18511aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
185263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
185363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
185463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SFL:
1855873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1856faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.zero;
1857873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
185863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
185963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
186063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SGT:
18612fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18622fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
18632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
18641aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src0, src1 );
1865faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
18661aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
186763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
186863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
186963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SIN:
18702fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
187190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_sin( &bld->base, tmp0 );
18722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1873faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
187463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
187563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
187663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
187763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SLE:
18782fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18792fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
18802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
18811aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LEQUAL, src0, src1 );
1882faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
18831aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
188463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
188563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
188663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SNE:
18872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
18892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
18901aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_NOTEQUAL, src0, src1 );
1891faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
18921aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
189363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
189463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
189563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_STR:
1896873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1897faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.one;
1898873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
189963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
190063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
190163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TEX:
190258daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_NONE, dst0 );
190363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
190463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
190563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXD:
190658daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV, dst0 );
190763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
190863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
190963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP2H:
1910873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1911873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert (0);
1912fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
191363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
191463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
191563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP2US:
1916873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1917873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1918fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
191963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
192063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
192163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP4B:
1922873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1923873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1924fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
192563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
192663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
192763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP4UB:
1928873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1929873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1930fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
193163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
193263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
193363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_X2D:
1934873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1935873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1936fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
193763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
193863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
193963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARA:
1940873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1941873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1942fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
194363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
194463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
194563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARR:
19462fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
19472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1948ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         tmp0 = lp_build_round(&bld->base, tmp0);
1949faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
195063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
195163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
195263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
195363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_BRA:
1954873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1955873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1956fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
195763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
195863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1959263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   case TGSI_OPCODE_CAL:
19600b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_call(&bld->exec_mask,
19610b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                        inst->Label.Label,
19620b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                        pc);
19630b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
196463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
196563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
196663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RET:
19670b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_ret(&bld->exec_mask, pc);
196863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
196963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
197063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_END:
19715b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      if (0) {
19725b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         /* for debugging */
19735b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         emit_dump_temps(bld);
19745b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      }
19750b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
197663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
197763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
197863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SSG:
197963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SGN */
19802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
19812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1982faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_sgn( &bld->base, tmp0 );
198363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
198463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
198563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
198663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CMP:
19872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
19882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
19892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
19902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
19911aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, bld->base.zero );
1992faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, src1, src2);
19931aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
199463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
199563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
199663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SCS:
19972fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
19982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1999faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = lp_build_cos( &bld->base, tmp0 );
200063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
20012fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
20022fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
2003faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_sin( &bld->base, tmp0 );
200463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
20052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
2006faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = bld->base.zero;
200763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
20082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
2009faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
201063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
201163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
201263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
201363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXB:
201458daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_LOD_BIAS, dst0 );
201563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
201663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
201763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NRM:
201863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* fall-through */
201963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NRM4:
202063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* 3 or 4-component normalization */
202163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      {
202263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         uint dims = (inst->Instruction.Opcode == TGSI_OPCODE_NRM) ? 3 : 4;
202363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
20242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) ||
20252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y) ||
20262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z) ||
20272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 4)) {
202863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
202963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* NOTE: Cannot use xmm regs 2/3 here (see emit_rsqrt() above). */
203063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
203163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm4 = src.x */
203263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = src.x * src.x */
20332fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
20342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
203590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp4 = tmp0;
203663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
203790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_mul( &bld->base, tmp0, tmp0);
203863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
203963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm5 = src.y */
204063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = xmm0 + src.y * src.y */
20412fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp1 = emit_fetch(bld, inst, 0, CHAN_Y);
20422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
204390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp5 = tmp1;
204463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
204590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
204690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
204763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
204863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm6 = src.z */
204963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = xmm0 + src.z * src.z */
20502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp1 = emit_fetch(bld, inst, 0, CHAN_Z);
20512fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
205290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp6 = tmp1;
205363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
205490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
205590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
205663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
205763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            if (dims == 4) {
205863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               /* xmm7 = src.w */
205963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               /* xmm0 = xmm0 + src.w * src.w */
20602fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca               tmp1 = emit_fetch(bld, inst, 0, CHAN_W);
20612fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca               if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W)) {
206290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca                  tmp7 = tmp1;
206363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               }
206490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
206590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
206663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
206763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
206863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm1 = 1 / sqrt(xmm0) */
206990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_rsqrt( &bld->base, tmp0);
207063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
207163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.x = xmm1 * src.x */
20722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
2073faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_X] = lp_build_mul( &bld->base, tmp4, tmp1);
207463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
207563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
207663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.y = xmm1 * src.y */
20772fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
2078faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp5, tmp1);
207963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
208063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
208163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.z = xmm1 * src.z */
20822fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
2083faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_Z] = lp_build_mul( &bld->base, tmp6, tmp1);
208463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
208563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
208663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.w = xmm1 * src.w */
20872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) && dims == 4) {
2088faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_W] = lp_build_mul( &bld->base, tmp7, tmp1);
208963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
209063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
209163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2092faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         /* dst.w = 1.0 */
20932fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 3) {
2094faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_W] = bld->base.one;
209563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
209663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
209763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
209863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
209963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DIV:
2100873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
2101873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert( 0 );
2102fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
210363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
210463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
210563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP2:
21062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );  /* xmm0 = src[0].x */
21072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );  /* xmm1 = src[1].x */
210890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 * xmm1 */
21092fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );  /* xmm1 = src[0].y */
21102fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );  /* xmm2 = src[1].y */
211190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);              /* xmm1 = xmm1 * xmm2 */
211290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
21132fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
2114faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;  /* dest[ch] = xmm0 */
211563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
211663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
211763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
211863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXL:
211958daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD, dst0 );
212063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
212163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
212263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXP:
212358daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_PROJECTED, dst0 );
212463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
212518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
212663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_BRK:
212718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_break(&bld->exec_mask);
212863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
212963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
213063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_IF:
213180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
2132ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin      tmp0 = lp_build_cmp(&bld->base, PIPE_FUNC_NOTEQUAL,
2133ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                          tmp0, bld->base.zero);
213480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_push(&bld->exec_mask, tmp0);
213563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
213663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
213718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   case TGSI_OPCODE_BGNLOOP:
213818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_bgnloop(&bld->exec_mask);
213918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      break;
214018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
21410b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   case TGSI_OPCODE_BGNSUB:
21420b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_bgnsub(&bld->exec_mask);
21430b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      break;
21440b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
214563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ELSE:
214680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_invert(&bld->exec_mask);
214763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
214863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
214963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ENDIF:
215080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_pop(&bld->exec_mask);
215163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
215263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
215318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   case TGSI_OPCODE_ENDLOOP:
215418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_endloop(&bld->exec_mask);
215518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      break;
215618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
21570b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   case TGSI_OPCODE_ENDSUB:
21580b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_endsub(&bld->exec_mask, pc);
21590b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      break;
21600b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
216163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PUSHA:
2162873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2163873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2164fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
216563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
216663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
216763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_POPA:
2168873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2169873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2170fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
217163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
217263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
217363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CEIL:
2174873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
2175873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
2176faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_ceil(&bld->base, tmp0);
2177873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
217863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
217963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
218063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_I2F:
2181873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2182873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2183fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
218463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
218563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
218663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NOT:
2187873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2188873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2189fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
219063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
219163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
219263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TRUNC:
21932fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
21942fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
2195faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_trunc(&bld->base, tmp0);
219663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
219763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
219863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
219963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SHL:
2200873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2201873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2202fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
220363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
220463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
22052c046034dc5c95dd2fe84d0b4fd44f25235480b9Michal Krol   case TGSI_OPCODE_ISHR:
2206873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2207873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2208fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
220963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
221063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
221163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_AND:
2212873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2213873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2214fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
221563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
221663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
221763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_OR:
2218873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2219873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2220fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
222163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
222263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
222363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MOD:
2224873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2225873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2226fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
222763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
222863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
222963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_XOR:
2230873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2231873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2232fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
223363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
223463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
223563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SAD:
2236873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2237873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2238fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
223963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
224063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
224163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXF:
2242873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2243873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2244fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
224563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
224663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
224763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXQ:
2248873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2249873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2250fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
225163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
225263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
225363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CONT:
225418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_continue(&bld->exec_mask);
225563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
225663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
225763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_EMIT:
2258fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
225963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
226063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
226163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ENDPRIM:
2262fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
226363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
226463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2265873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca   case TGSI_OPCODE_NOP:
2266873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      break;
2267873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca
226863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
2269fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
227063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
227163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2272faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   if(info->num_dst) {
2273ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      LLVMValueRef pred[NUM_CHANNELS];
2274ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
2275ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      emit_fetch_predicate( bld, inst, pred );
2276ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
2277faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
2278ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         emit_store( bld, inst, 0, chan_index, pred[chan_index], dst0[chan_index]);
2279faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
2280faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
2281faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
2282fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul   return TRUE;
228363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
228463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2285c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca
2286c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonsecavoid
228763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecalp_build_tgsi_soa(LLVMBuilderRef builder,
228863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  const struct tgsi_token *tokens,
2289b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca                  struct lp_type type,
22903d7a88674f9eb3320eeff511968f041426e25023José Fonseca                  struct lp_build_mask_context *mask,
229163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  LLVMValueRef consts_ptr,
2292f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef *pos,
2293f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef (*inputs)[NUM_CHANNELS],
2294f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  LLVMValueRef (*outputs)[NUM_CHANNELS],
2295021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                  struct lp_build_sampler_soa *sampler,
22963f6dc8e79d918283a6dfcf9c8937a6d52f3bb4f5Brian Paul                  const struct tgsi_shader_info *info)
229763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
229863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context bld;
229963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct tgsi_parse_context parse;
230063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   uint num_immediates = 0;
23010b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   uint num_instructions = 0;
230263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
23030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int pc = 0;
230463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
23056d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_type res_type;
23066d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
23076d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(type.length <= LP_MAX_VECTOR_LENGTH);
23086d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   memset(&res_type, 0, sizeof res_type);
23096d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.width = type.width;
23106d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.length = type.length;
23116d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.sign = 1;
23126d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
231363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* Setup build context */
231463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   memset(&bld, 0, sizeof bld);
231563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   lp_build_context_init(&bld.base, builder, type);
23166d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   lp_build_context_init(&bld.uint_bld, builder, lp_uint_type(type));
2317e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   lp_build_context_init(&bld.elem_bld, builder, lp_elem_type(type));
2318c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca   bld.mask = mask;
2319f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.pos = pos;
2320f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.inputs = inputs;
232163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.outputs = outputs;
232263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.consts_ptr = consts_ptr;
23238be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld.sampler = sampler;
23246d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   bld.info = info;
23253662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   bld.indirect_files = info->indirect_files;
23260b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   bld.instructions = (struct tgsi_full_instruction *)
23270b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                      MALLOC( LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction) );
23280b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   bld.max_instructions = LP_MAX_INSTRUCTIONS;
23290b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
23300b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (!bld.instructions) {
23310b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
23320b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
233363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
233480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_init(&bld.exec_mask, &bld.base);
233580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
233610740acf46e08960dde790005d65a98440f313bcJosé Fonseca   if (bld.indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
233710740acf46e08960dde790005d65a98440f313bcJosé Fonseca      LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
233810740acf46e08960dde790005d65a98440f313bcJosé Fonseca                                             info->file_max[TGSI_FILE_TEMPORARY]*4 + 4, 0);
233910740acf46e08960dde790005d65a98440f313bcJosé Fonseca      bld.temps_array = lp_build_array_alloca(bld.base.builder,
234010740acf46e08960dde790005d65a98440f313bcJosé Fonseca                                              bld.base.vec_type, array_size,
234110740acf46e08960dde790005d65a98440f313bcJosé Fonseca                                              "temp_array");
234210740acf46e08960dde790005d65a98440f313bcJosé Fonseca   }
234310740acf46e08960dde790005d65a98440f313bcJosé Fonseca
234410740acf46e08960dde790005d65a98440f313bcJosé Fonseca   if (bld.indirect_files & (1 << TGSI_FILE_OUTPUT)) {
234510740acf46e08960dde790005d65a98440f313bcJosé Fonseca      LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
234610740acf46e08960dde790005d65a98440f313bcJosé Fonseca                                             info->file_max[TGSI_FILE_OUTPUT]*4 + 4, 0);
234710740acf46e08960dde790005d65a98440f313bcJosé Fonseca      bld.outputs_array = lp_build_array_alloca(bld.base.builder,
234810740acf46e08960dde790005d65a98440f313bcJosé Fonseca                                                bld.base.vec_type, array_size,
234910740acf46e08960dde790005d65a98440f313bcJosé Fonseca                                                "output_array");
235010740acf46e08960dde790005d65a98440f313bcJosé Fonseca   }
235110740acf46e08960dde790005d65a98440f313bcJosé Fonseca
2352f623d0c1c217d990f207306eb968172af79fa969Zack Rusin   /* If we have indirect addressing in inputs we need to copy them into
2353f623d0c1c217d990f207306eb968172af79fa969Zack Rusin    * our alloca array to be able to iterate over them */
2354f623d0c1c217d990f207306eb968172af79fa969Zack Rusin   if (bld.indirect_files & (1 << TGSI_FILE_INPUT)) {
2355f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      unsigned index, chan;
2356f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      LLVMTypeRef vec_type = bld.base.vec_type;
2357f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
2358f623d0c1c217d990f207306eb968172af79fa969Zack Rusin                                             info->file_max[TGSI_FILE_INPUT]*4 + 4, 0);
2359f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      bld.inputs_array = lp_build_array_alloca(bld.base.builder,
2360f623d0c1c217d990f207306eb968172af79fa969Zack Rusin                                               vec_type, array_size,
2361f623d0c1c217d990f207306eb968172af79fa969Zack Rusin                                               "input_array");
2362f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
2363f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      assert(info->num_inputs <= info->file_max[TGSI_FILE_INPUT] + 1);
2364f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
2365f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      for (index = 0; index < info->num_inputs; ++index) {
2366f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         for (chan = 0; chan < NUM_CHANNELS; ++chan) {
2367f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan);
2368f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            LLVMValueRef input_ptr =
2369f623d0c1c217d990f207306eb968172af79fa969Zack Rusin               LLVMBuildGEP(bld.base.builder, bld.inputs_array,
2370f623d0c1c217d990f207306eb968172af79fa969Zack Rusin                            &lindex, 1, "");
2371f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            LLVMValueRef value = bld.inputs[index][chan];
2372f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            if (value)
2373f623d0c1c217d990f207306eb968172af79fa969Zack Rusin               LLVMBuildStore(bld.base.builder, value, input_ptr);
2374f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         }
2375f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      }
2376f623d0c1c217d990f207306eb968172af79fa969Zack Rusin   }
2377f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
237863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   tgsi_parse_init( &parse, tokens );
237963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
238063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   while( !tgsi_parse_end_of_tokens( &parse ) ) {
238163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      tgsi_parse_token( &parse );
238263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
238363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      switch( parse.FullToken.Token.Type ) {
238463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_DECLARATION:
23851fc41002252419f4688c24ea8c3814553b3d76adJosé Fonseca         /* Inputs already interpolated */
2386e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         emit_declaration( &bld, &parse.FullToken.FullDeclaration );
238763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
238863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
238963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_INSTRUCTION:
2390faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         {
23910b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            /* save expanded instruction */
23920b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            if (num_instructions == bld.max_instructions) {
2393079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               struct tgsi_full_instruction *instructions;
2394079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               instructions = REALLOC(bld.instructions,
2395079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      bld.max_instructions
2396079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      * sizeof(struct tgsi_full_instruction),
2397079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      (bld.max_instructions + LP_MAX_INSTRUCTIONS)
2398079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      * sizeof(struct tgsi_full_instruction));
2399079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               if (!instructions) {
2400079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                  break;
2401079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               }
2402079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               bld.instructions = instructions;
24030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin               bld.max_instructions += LP_MAX_INSTRUCTIONS;
24040b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            }
24050b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
24060b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            memcpy(bld.instructions + num_instructions,
24070b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                   &parse.FullToken.FullInstruction,
24080b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                   sizeof(bld.instructions[0]));
24090b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
24100b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            num_instructions++;
2411faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         }
2412faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
241363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
241463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
241563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_IMMEDIATE:
241663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         /* simply copy the immediate values into the next immediates[] slot */
241763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         {
241863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
241963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            assert(size <= 4);
24206c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca            assert(num_immediates < LP_MAX_TGSI_IMMEDIATES);
242163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            for( i = 0; i < size; ++i )
242263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               bld.immediates[num_immediates][i] =
2423185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul                  lp_build_const_vec(type, parse.FullToken.FullImmediate.u[i].Float);
242463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            for( i = size; i < 4; ++i )
242563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               bld.immediates[num_immediates][i] = bld.base.undef;
242663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            num_immediates++;
242763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
242863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
242963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
24309381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca      case TGSI_TOKEN_TYPE_PROPERTY:
24319381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca         break;
24329381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca
243363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      default:
243463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         assert( 0 );
243563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
243663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
24370b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
24380b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   while (pc != -1) {
24390b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      struct tgsi_full_instruction *instr = bld.instructions + pc;
24400b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      const struct tgsi_opcode_info *opcode_info =
24410b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         tgsi_get_opcode_info(instr->Instruction.Opcode);
24420b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      if (!emit_instruction( &bld, instr, opcode_info, &pc ))
24430b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
24440b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                       opcode_info->mnemonic);
24450b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
24460b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
2447528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   /* If we have indirect addressing in outputs we need to copy our alloca array
2448528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin    * to the outputs slots specified by the called */
2449528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   if (bld.indirect_files & (1 << TGSI_FILE_OUTPUT)) {
245010740acf46e08960dde790005d65a98440f313bcJosé Fonseca      unsigned index, chan;
245110740acf46e08960dde790005d65a98440f313bcJosé Fonseca      assert(info->num_outputs <= info->file_max[TGSI_FILE_OUTPUT] + 1);
245210740acf46e08960dde790005d65a98440f313bcJosé Fonseca      for (index = 0; index < info->num_outputs; ++index) {
245310740acf46e08960dde790005d65a98440f313bcJosé Fonseca         for (chan = 0; chan < NUM_CHANNELS; ++chan) {
245410740acf46e08960dde790005d65a98440f313bcJosé Fonseca            bld.outputs[index][chan] = get_output_ptr(&bld, index, chan);
2455528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         }
2456528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      }
2457528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   }
2458528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
245918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (0) {
246018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
246118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef function = LLVMGetBasicBlockParent(block);
2462263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("11111111111111111111111111111 \n");
246318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      tgsi_dump(tokens, 0);
24648ad3e0b55df50beac8ba3c5cafa0be79641a4977José Fonseca      lp_debug_dump_value(function);
2465263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("2222222222222222222222222222 \n");
246618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   }
246763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   tgsi_parse_free( &parse );
24680b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
24690b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (0) {
24700b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMModuleRef module = LLVMGetGlobalParent(
24710b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld.base.builder)));
24720b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMDumpModule(module);
24730b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
24740b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
24750b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
24760b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   FREE( bld.instructions );
247763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
247863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2479