lp_bld_tgsi_soa.c revision ede232e9898698258391a280a098a7ba951b0099
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
123ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   /* Builder for integer masks and indices */
1246d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_build_context uint_bld;
125ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
12663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef consts_ptr;
127f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   const LLVMValueRef *pos;
128263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   const LLVMValueRef (*inputs)[NUM_CHANNELS];
129263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   LLVMValueRef (*outputs)[NUM_CHANNELS];
130c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca
1313f6dc8e79d918283a6dfcf9c8937a6d52f3bb4f5Brian Paul   const struct lp_build_sampler_soa *sampler;
13263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1336c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][NUM_CHANNELS];
1346c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef temps[LP_MAX_TGSI_TEMPS][NUM_CHANNELS];
1356c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef addr[LP_MAX_TGSI_ADDRS][NUM_CHANNELS];
136ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef preds[LP_MAX_TGSI_PREDS][NUM_CHANNELS];
1371929057eac0c3351e0810612bdae56331a235736José Fonseca
1383662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
1393662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    * set in the indirect_files field.
1403662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    * The temps[] array above is unused then.
1413662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    */
142021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   LLVMValueRef temps_array;
1433662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul
1446d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   const struct tgsi_shader_info *info;
1453662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   /** bitmask indicating which register files are accessed indirectly */
1463662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   unsigned indirect_files;
147021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
1483d7a88674f9eb3320eeff511968f041426e25023José Fonseca   struct lp_build_mask_context *mask;
14980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   struct lp_exec_mask exec_mask;
1500b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1510b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   struct tgsi_full_instruction *instructions;
1520b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   uint max_instructions;
15363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca};
15463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
15580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld)
15680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
15780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->bld = bld;
15880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->has_mask = FALSE;
15980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack_size = 0;
16018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->loop_stack_size = 0;
1610b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size = 0;
16280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
16380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->int_vec_type = lp_build_int_vec_type(mask->bld->type);
16432a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->exec_mask = mask->ret_mask = mask->break_mask = mask->cont_mask = mask->cond_mask =
1652d91903882e399e8ea7306fd37d5d214907247e6José Fonseca         LLVMConstAllOnes(mask->int_vec_type);
16680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
16780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
16880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_update(struct lp_exec_mask *mask)
16980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
17018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (mask->loop_stack_size) {
17118a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin      /*for loops we need to update the entire mask at runtime */
17218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef tmp;
1737fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul      assert(mask->break_mask);
17418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      tmp = LLVMBuildAnd(mask->bld->builder,
17518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->cont_mask,
17618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->break_mask,
17718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         "maskcb");
17818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
17918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     mask->cond_mask,
18018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     tmp,
18118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     "maskfull");
18218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   } else
18318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      mask->exec_mask = mask->cond_mask;
18418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
18532a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   if (mask->call_stack_size) {
1860b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
1870b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     mask->exec_mask,
18832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                     mask->ret_mask,
1890b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     "callmask");
19032a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   }
19118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
19218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->has_mask = (mask->cond_stack_size > 0 ||
1930b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->loop_stack_size > 0 ||
1940b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->call_stack_size > 0);
19580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
19680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
19780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
19880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                   LLVMValueRef val)
19980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2006c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING);
2012d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 0) {
2022d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cond_mask == LLVMConstAllOnes(mask->int_vec_type));
2032d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
20480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask;
2052d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(LLVMTypeOf(val) == mask->int_vec_type);
2063fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul   mask->cond_mask = LLVMBuildAnd(mask->bld->builder,
2073fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  mask->cond_mask,
2083fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  val,
2093fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  "");
21080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
21180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
21280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
21380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_invert(struct lp_exec_mask *mask)
21480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2152d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef prev_mask;
2162d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef inv_mask;
2172d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2182d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
2192d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   prev_mask = mask->cond_stack[mask->cond_stack_size - 1];
2202d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 1) {
2212d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(prev_mask == LLVMConstAllOnes(mask->int_vec_type));
222faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin   }
223faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin
2242d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   inv_mask = LLVMBuildNot(mask->bld->builder, mask->cond_mask, "");
2252d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
22680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_mask = LLVMBuildAnd(mask->bld->builder,
22780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  inv_mask,
22880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  prev_mask, "");
22980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
23080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
23180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
23280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)
23380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2342d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
23580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_mask = mask->cond_stack[--mask->cond_stack_size];
23680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
23780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
23880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
23918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_bgnloop(struct lp_exec_mask *mask)
24018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
2412d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->loop_stack_size == 0) {
2422d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->loop_block == NULL);
2432d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cont_mask == LLVMConstAllOnes(mask->int_vec_type));
2442d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_mask == LLVMConstAllOnes(mask->int_vec_type));
2452d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_var == NULL);
2462d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
2472d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2482d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size < LP_MAX_TGSI_NESTING);
24918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2502d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].loop_block = mask->loop_block;
2512d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].cont_mask = mask->cont_mask;
2522d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_mask = mask->break_mask;
2532d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_var = mask->break_var;
2542d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   ++mask->loop_stack_size;
2553a423dcf9dfa725a4e5dca60f0f2b02599d2ed9bZack Rusin
2562d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_var = lp_build_alloca(mask->bld->builder, mask->int_vec_type, "");
2572d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
2586c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca
25918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->loop_block = lp_build_insert_new_block(mask->bld->builder, "bgnloop");
26018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBuildBr(mask->bld->builder, mask->loop_block);
26118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block);
26218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2632d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_mask = LLVMBuildLoad(mask->bld->builder, mask->break_var, "");
2642d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
26518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
26618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
26718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
26818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_break(struct lp_exec_mask *mask)
26918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
27018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
27118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
27218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "break");
27318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
274d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin   mask->break_mask = LLVMBuildAnd(mask->bld->builder,
275d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   mask->break_mask,
276d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   exec_mask, "break_full");
27718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
27818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
27918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
28018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
28118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_continue(struct lp_exec_mask *mask)
28218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
28318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
28418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
28518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "");
28618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
287d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin   mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
288d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  mask->cont_mask,
289d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  exec_mask, "");
29018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
29118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
29218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
29318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
29418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
29518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_endloop(struct lp_exec_mask *mask)
29618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
29718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBasicBlockRef endloop;
298d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca   LLVMTypeRef reg_type = LLVMIntType(mask->bld->type.width*
299d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca                                      mask->bld->type.length);
3007fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   LLVMValueRef i1cond;
3017fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
3027fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   assert(mask->break_mask);
3037fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
3042d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
3052d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Restore the cont_mask, but don't pop
3062d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
3072d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
3082d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size - 1].cont_mask;
3092d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   lp_exec_mask_update(mask);
3102d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
3112d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
3122d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Unlike the continue mask, the break_mask must be preserved across loop
3132d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * iterations
3142d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
3152d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
3162d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
317d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca   /* i1cond = (mask == 0) */
3187fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   i1cond = LLVMBuildICmp(
319d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      mask->bld->builder,
320d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMIntNE,
3212d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMBuildBitCast(mask->bld->builder, mask->exec_mask, reg_type, ""),
322d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMConstNull(reg_type), "");
32318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
32418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   endloop = lp_build_insert_new_block(mask->bld->builder, "endloop");
32518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
32618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBuildCondBr(mask->bld->builder,
327ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                   i1cond, mask->loop_block, endloop);
32818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
32918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMPositionBuilderAtEnd(mask->bld->builder, endloop);
33018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
3312d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
3322d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   --mask->loop_stack_size;
3332d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_block = mask->loop_stack[mask->loop_stack_size].loop_block;
3342d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size].cont_mask;
3352d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_mask = mask->loop_stack[mask->loop_stack_size].break_mask;
3362d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_var = mask->loop_stack[mask->loop_stack_size].break_var;
33718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
33818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
33918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
34018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
34118a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin/* stores val into an address pointed to by dst.
34218a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * mask->exec_mask is used to figure out which bits of val
34318a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * should be stored into the address
34418a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * (0 means don't store this bit, 1 means do store).
34518a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin */
34680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_store(struct lp_exec_mask *mask,
347ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                               LLVMValueRef pred,
34880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef val,
34980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef dst)
35080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
351ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   /* Mix the predicate and execution mask */
35280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   if (mask->has_mask) {
353ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (pred) {
35454b94ee96a6d750d57d99ae9819fcf8206d4680dJosé Fonseca         pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, "");
355ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
356ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred = mask->exec_mask;
357ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
358ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
359ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
360ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (pred) {
36180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMValueRef real_val, dst_val;
36280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
36380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      dst_val = LLVMBuildLoad(mask->bld->builder, dst, "");
36480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      real_val = lp_build_select(mask->bld,
365ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                 pred,
36680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                 val, dst_val);
36780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
36880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMBuildStore(mask->bld->builder, real_val, dst);
36980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   } else
37080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMBuildStore(mask->bld->builder, val, dst);
37180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
37280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
3730b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_call(struct lp_exec_mask *mask,
3740b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int func,
3750b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int *pc)
3760b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
37732a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size < LP_MAX_TGSI_NESTING);
3780b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack[mask->call_stack_size].pc = *pc;
37932a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack[mask->call_stack_size].ret_mask = mask->ret_mask;
38032a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack_size++;
3810b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = func;
3820b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
3830b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3840b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
3850b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
3860b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   LLVMValueRef exec_mask;
38732a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca
3880b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (mask->call_stack_size == 0) {
3890b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      /* returning from main() */
3900b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
3910b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
3920b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
3930b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   exec_mask = LLVMBuildNot(mask->bld->builder,
3940b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            mask->exec_mask,
3950b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            "ret");
3960b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
39732a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->ret_mask = LLVMBuildAnd(mask->bld->builder,
39832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 mask->ret_mask,
39932a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 exec_mask, "ret_full");
4000b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4010b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   lp_exec_mask_update(mask);
4020b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
4030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4040b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_bgnsub(struct lp_exec_mask *mask)
4050b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
4060b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
4070b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4080b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
4090b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
41032a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size);
4110b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size--;
4120b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = mask->call_stack[mask->call_stack_size].pc;
41332a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->ret_mask = mask->call_stack[mask->call_stack_size].ret_mask;
41432a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   lp_exec_mask_update(mask);
4150b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
41686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
417695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul
418695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul/**
419695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * Return pointer to a temporary register channel (src or dest).
420f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul * Note that indirect addressing cannot be handled here.
421695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param index  which temporary register
422695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param chan  which channel of the temp register.
423695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul */
42486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic LLVMValueRef
425263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonsecaget_temp_ptr(struct lp_build_tgsi_soa_context *bld,
426263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca             unsigned index,
427f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul             unsigned chan)
428263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca{
429263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   assert(chan < 4);
4303662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
431f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan);
432263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      return LLVMBuildGEP(bld->base.builder, bld->temps_array, &lindex, 1, "");
433263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   }
434695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   else {
435695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul      return bld->temps[index][chan];
436695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   }
437263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca}
438263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca
4394363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4404363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul/**
4414363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * Gather vector.
4424363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * XXX the lp_build_gather() function should be capable of doing this
4434363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * with a little work.
4444363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul */
4454363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulstatic LLVMValueRef
4464363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulbuild_gather(struct lp_build_tgsi_soa_context *bld,
4474363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef base_ptr,
4484363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef indexes)
4494363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul{
4504363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   LLVMValueRef res = bld->base.undef;
4514363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   unsigned i;
4524363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4534363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   /*
4544363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    * Loop over elements of index_vec, load scalar value, insert it into 'res'.
4554363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    */
4564363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   for (i = 0; i < bld->base.type.length; i++) {
4574363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0);
4584363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef index = LLVMBuildExtractElement(bld->base.builder,
4594363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                                   indexes, ii, "");
4604363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, base_ptr,
4613ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                             &index, 1, "gather_ptr");
4624363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
4634363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4644363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      res = LLVMBuildInsertElement(bld->base.builder, res, scalar, ii, "");
4654363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   }
4664363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4674363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   return res;
4684363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul}
4694363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4704363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
47163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
4722fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul * Scatter/store vector.
4732fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul */
4742fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paulstatic void
4752fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paulbuild_scatter(struct lp_build_tgsi_soa_context *bld,
4762fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul              LLVMValueRef base_ptr,
4772fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul              LLVMValueRef indexes,
4782fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul              LLVMValueRef values)
4792fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul{
4802fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   LLVMBuilderRef builder = bld->base.builder;
4812fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   unsigned i;
4822fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
4832fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   /*
4842fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul    * Loop over elements of index_vec, store scalar value.
4852fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul    */
4862fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   for (i = 0; i < bld->base.type.length; i++) {
4872fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0);
4882fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef index = LLVMBuildExtractElement(builder, indexes, ii, "");
4892fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, &index, 1, "scatter_ptr");
4902fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef val = LLVMBuildExtractElement(builder, values, ii, "scatter_val");
4912fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
492ede232e9898698258391a280a098a7ba951b0099Brian Paul      if (0)
493ede232e9898698258391a280a098a7ba951b0099Brian Paul         lp_build_printf(builder, "scatter %d: val %f at %d %p\n",
494ede232e9898698258391a280a098a7ba951b0099Brian Paul                         ii, val, index, scalar_ptr);
495ede232e9898698258391a280a098a7ba951b0099Brian Paul
4962fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMBuildStore(builder, val, scalar_ptr);
4972fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   }
4982fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul}
4992fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
5002fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
5012fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul/**
5020115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * Read the current value of the ADDR register, convert the floats to
5032fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul * ints, add the base index and return the vector of offsets.
5040115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * The offsets will be used to index into the constant buffer or
5050115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * temporary register file.
5060115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul */
5070115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paulstatic LLVMValueRef
5086d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonsecaget_indirect_index(struct lp_build_tgsi_soa_context *bld,
5096d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                   unsigned reg_file, unsigned reg_index,
5106d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                   const struct tgsi_src_register *indirect_reg)
5110115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul{
5126d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_build_context *uint_bld = &bld->uint_bld;
5130115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* always use X component of address register */
5143d5b9c1f2d3340259dd0d8765090a5a963074f29José Fonseca   unsigned swizzle = indirect_reg->SwizzleX;
5156d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef base;
5166d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef rel;
5176d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef max_index;
5186d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef index;
5190115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5206d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(bld->indirect_files & (1 << reg_file));
5216d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5226d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   base = lp_build_const_int_vec(uint_bld->type, reg_index);
5236d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5246d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(swizzle < 4);
5256d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   rel = LLVMBuildLoad(bld->base.builder,
5266d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                        bld->addr[indirect_reg->Index][swizzle],
5276d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                        "load addr reg");
5280115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5290115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* for indexing we want integers */
5306d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   rel = LLVMBuildFPToSI(bld->base.builder,
5316d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                         rel,
5326d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                         uint_bld->vec_type, "");
5336d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5346d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   index = lp_build_add(uint_bld, base, rel);
5350115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5366d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   max_index = lp_build_const_int_vec(uint_bld->type,
5376d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                      bld->info->file_max[reg_file]);
5380115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5396d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(!uint_bld->type.sign);
5406d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   index = lp_build_min(uint_bld, index, max_index);
5416d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5426d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   return index;
5430115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul}
5440115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5450115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5460115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul/**
54763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register fetch.
54863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
54963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic LLVMValueRef
55063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_fetch(
55163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
5522fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   const struct tgsi_full_instruction *inst,
553ec0e7b16bb6753bedbd611a97062934bfca03aa7Brian Paul   unsigned src_op,
55463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const unsigned chan_index )
55563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
5566d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_build_context *uint_bld = &bld->uint_bld;
557ec0e7b16bb6753bedbd611a97062934bfca03aa7Brian Paul   const struct tgsi_full_src_register *reg = &inst->Src[src_op];
55885c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   const unsigned swizzle =
55985c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      tgsi_util_get_full_src_register_swizzle(reg, chan_index);
56063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef res;
5616d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef indirect_index = NULL;
56263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
56385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (swizzle > 3) {
56485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(0 && "invalid swizzle in emit_fetch()");
56585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      return bld->base.undef;
56685c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
56785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul
56885c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (reg->Register.Indirect) {
5696d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      indirect_index = get_indirect_index(bld,
5706d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.File,
5716d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.Index,
5726d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          &reg->Indirect);
5736d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   } else {
5746d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      assert(reg->Register.Index <= bld->info->file_max[reg->Register.File]);
57585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
576ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
57785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   switch (reg->Register.File) {
57885c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_CONSTANT:
579be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      if (reg->Register.Indirect) {
5806d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         LLVMValueRef swizzle_vec =
5816d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca            lp_build_const_int_vec(uint_bld->type, swizzle);
582be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef index_vec;  /* index into the const buffer */
5834363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5846d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         /* index_vec = indirect_index * 4 + swizzle */
5856d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
5866d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
5874363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
588be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         /* Gather values from the constant buffer */
589be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         res = build_gather(bld, bld->consts_ptr, index_vec);
590be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      }
591be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      else {
592be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef index;  /* index into the const buffer */
593be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef scalar, scalar_ptr;
594ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
595be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         index = lp_build_const_int32(reg->Register.Index*4 + swizzle);
5964363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
597be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
598be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul                                   &index, 1, "");
599be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
6004363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
601be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         res = lp_build_broadcast_scalar(&bld->base, scalar);
60263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
60385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
60463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
60585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_IMMEDIATE:
606263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      res = bld->immediates[reg->Register.Index][swizzle];
60785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(res);
60885c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
60963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
61085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_INPUT:
611263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      res = bld->inputs[reg->Register.Index][swizzle];
61285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(res);
61385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
61463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
61585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_TEMPORARY:
616105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      if (reg->Register.Indirect) {
6176d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         LLVMValueRef swizzle_vec =
6186d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca            lp_build_const_int_vec(uint_bld->type, swizzle);
6196d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         LLVMValueRef length_vec =
6206d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca            lp_build_const_int_vec(uint_bld->type, bld->base.type.length);
621105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef index_vec;  /* index into the const buffer */
622105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef temps_array;
623105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMTypeRef float4_ptr_type;
6244363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
6256d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         /* index_vec = (indirect_index * 4 + swizzle) * length */
6266d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
6276d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
6286d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
629105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
630105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* cast temps_array pointer to float* */
631105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
6326d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         temps_array = LLVMBuildBitCast(uint_bld->builder, bld->temps_array,
633105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul                                        float4_ptr_type, "");
634105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
635105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* Gather values from the temporary register array */
636105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         res = build_gather(bld, temps_array, index_vec);
637105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      }
638105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      else {
639105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef temp_ptr;
640f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         temp_ptr = get_temp_ptr(bld, reg->Register.Index, swizzle);
641021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin         res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
642105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         if (!res)
64363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            return bld->base.undef;
64463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
64563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
64663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
64763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
64885c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(0 && "invalid src register in emit_fetch()");
6494d7a8194c5763f70ba559f32f58dfda36237b666José Fonseca      return bld->base.undef;
65063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
65163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
65263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) {
65363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_CLEAR:
65463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = lp_build_abs( &bld->base, res );
65563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
65663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
65763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_SET:
65863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = lp_build_abs( &bld->base, res );
659fc9a49b638c26801951c33a570178bbb2b67ec60nobled      /* fall through */
66063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_TOGGLE:
6618a3a971743a90463e65b44f1769a5301a31ce4cdJosé Fonseca      res = lp_build_negate( &bld->base, res );
66263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
66363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
66463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_KEEP:
66563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
66663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
66763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
66863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   return res;
66963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
67063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
67163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
67263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
67386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca * Register fetch with derivatives.
67486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca */
67586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic void
67686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecaemit_fetch_deriv(
67786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   struct lp_build_tgsi_soa_context *bld,
67886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   const struct tgsi_full_instruction *inst,
67986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   unsigned index,
68086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   const unsigned chan_index,
68186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *res,
68286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddx,
68386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddy)
68486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca{
68586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef src;
68686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
68786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   src = emit_fetch(bld, inst, index, chan_index);
68886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
68986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(res)
69086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      *res = src;
69186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
69286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   /* TODO: use interpolation coeffs for inputs */
69386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
69486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddx)
695ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca      *ddx = lp_build_ddx(&bld->base, src);
69686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
69786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddy)
698ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca      *ddy = lp_build_ddy(&bld->base, src);
69986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca}
70086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
70186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
70286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca/**
703ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca * Predicate.
704ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca */
705ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecastatic void
706ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecaemit_fetch_predicate(
707ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
708ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   const struct tgsi_full_instruction *inst,
709ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef *pred)
710ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca{
711ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned index;
712ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned char swizzles[4];
713ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef unswizzled[4] = {NULL, NULL, NULL, NULL};
714ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef value;
715ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned chan;
716ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
717ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (!inst->Instruction.Predicate) {
718ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      FOR_EACH_CHANNEL( chan ) {
719ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred[chan] = NULL;
720ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
721ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      return;
722ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
723ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
724ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[0] = inst->Predicate.SwizzleX;
725ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[1] = inst->Predicate.SwizzleY;
726ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[2] = inst->Predicate.SwizzleZ;
727ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[3] = inst->Predicate.SwizzleW;
728ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
729ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   index = inst->Predicate.Index;
730ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   assert(index < LP_MAX_TGSI_PREDS);
731ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
732ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   FOR_EACH_CHANNEL( chan ) {
733ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      unsigned swizzle = swizzles[chan];
734ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
735ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      /*
736ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * Only fetch the predicate register channels that are actually listed
737ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * in the swizzles
738ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       */
739ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (!unswizzled[swizzle]) {
740ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = LLVMBuildLoad(bld->base.builder,
741263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                               bld->preds[index][swizzle], "");
742ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
743ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         /*
744ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * Convert the value to an integer mask.
745ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          *
746ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * TODO: Short-circuit this comparison -- a D3D setp_xx instructions
747ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * is needlessly causing two comparisons due to storing the intermediate
748ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * result as float vector instead of an integer mask vector.
749ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          */
750ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = lp_build_compare(bld->base.builder,
751ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  bld->base.type,
752ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  PIPE_FUNC_NOTEQUAL,
753ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  value,
754ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  bld->base.zero);
755ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         if (inst->Predicate.Negate) {
756ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca            value = LLVMBuildNot(bld->base.builder, value, "");
757ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         }
758ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
759ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         unswizzled[swizzle] = value;
760ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
761ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = unswizzled[swizzle];
762ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
763ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
764ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      pred[chan] = value;
765ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
766ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca}
767ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
768ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
769ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca/**
77063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register store.
77163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
77263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
77363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_store(
77463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
77563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const struct tgsi_full_instruction *inst,
7762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   unsigned index,
77763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index,
778ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef pred,
77963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef value)
78063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
7817d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_dst_register *reg = &inst->Dst[index];
7822fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   struct lp_build_context *uint_bld = &bld->uint_bld;
7836d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef indirect_index = NULL;
7842fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca
78563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( inst->Instruction.Saturate ) {
78663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_NONE:
78763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
78863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
78963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_ZERO_ONE:
7907926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_max(&bld->base, value, bld->base.zero);
7917926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_min(&bld->base, value, bld->base.one);
79263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
79363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
79463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_MINUS_PLUS_ONE:
795185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul      value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.type, -1.0));
7967926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_min(&bld->base, value, bld->base.one);
79763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
7987926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca
7997926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca   default:
8007926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      assert(0);
80163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
80263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
803021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   if (reg->Register.Indirect) {
8046d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      indirect_index = get_indirect_index(bld,
8056d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.File,
8066d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.Index,
8076d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          &reg->Indirect);
8086d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   } else {
8096d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      assert(reg->Register.Index <= bld->info->file_max[reg->Register.File]);
810021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   }
811021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
8125b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   switch( reg->Register.File ) {
81363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_OUTPUT:
814ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
815263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                         bld->outputs[reg->Register.Index][chan_index]);
81663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
81763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
818f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul   case TGSI_FILE_TEMPORARY:
819f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      if (reg->Register.Indirect) {
820ede232e9898698258391a280a098a7ba951b0099Brian Paul         LLVMBuilderRef builder = bld->base.builder;
8212fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef chan_vec =
8222fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul            lp_build_const_int_vec(uint_bld->type, chan_index);
8232fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef length_vec =
8242fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul            lp_build_const_int_vec(uint_bld->type, bld->base.type.length);
8252fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef index_vec;  /* indexes into the temp registers */
8262fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef temps_array;
827ede232e9898698258391a280a098a7ba951b0099Brian Paul         LLVMValueRef pixel_offsets;
8282fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMTypeRef float_ptr_type;
829ede232e9898698258391a280a098a7ba951b0099Brian Paul         int i;
830ede232e9898698258391a280a098a7ba951b0099Brian Paul
831ede232e9898698258391a280a098a7ba951b0099Brian Paul         /* build pixel offset vector: {0, 1, 2, 3, ...} */
832ede232e9898698258391a280a098a7ba951b0099Brian Paul         pixel_offsets = uint_bld->undef;
833ede232e9898698258391a280a098a7ba951b0099Brian Paul         for (i = 0; i < bld->base.type.length; i++) {
834ede232e9898698258391a280a098a7ba951b0099Brian Paul            LLVMValueRef ii = lp_build_const_int32(i);
835ede232e9898698258391a280a098a7ba951b0099Brian Paul            pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
836ede232e9898698258391a280a098a7ba951b0099Brian Paul                                                   ii, ii, "");
837ede232e9898698258391a280a098a7ba951b0099Brian Paul         }
8382fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
839ede232e9898698258391a280a098a7ba951b0099Brian Paul         /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */
8402fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
8412fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_add(uint_bld, index_vec, chan_vec);
8422fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
843ede232e9898698258391a280a098a7ba951b0099Brian Paul         index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
8442fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
8452fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         float_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
846ede232e9898698258391a280a098a7ba951b0099Brian Paul         temps_array = LLVMBuildBitCast(builder, bld->temps_array,
8472fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul                                        float_ptr_type, "");
8482fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
8492fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         /* Scatter store values into temp registers */
8502fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         build_scatter(bld, temps_array, index_vec, value);
851f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
852f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      else {
853f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
854f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul                                              chan_index);
855f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr);
856f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
85763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
85863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
85963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_ADDRESS:
860ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
861263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                         bld->addr[reg->Indirect.Index][chan_index]);
86263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
86363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
864ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca   case TGSI_FILE_PREDICATE:
865ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
8668690c6a6b4fb0b48e2ae75cd0f64de86b039081cmichal                         bld->preds[reg->Register.Index][chan_index]);
867ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca      break;
868ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca
86963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
87063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert( 0 );
87163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
87263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
87363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
87463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
87563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
87663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * High-level instruction translators.
87763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
87863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
87963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
88063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_tex( struct lp_build_tgsi_soa_context *bld,
88163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca          const struct tgsi_full_instruction *inst,
88258daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca          enum lp_build_tex_modifier modifier,
883faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca          LLVMValueRef *texel)
88463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
885962558daaed43b0111cd062e32821aad106869d7José Fonseca   unsigned unit;
886ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   LLVMValueRef lod_bias, explicit_lod;
88731d1822473bf9d4105bb82b67572cfeea53aaf94Vinson Lee   LLVMValueRef oow = NULL;
888c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   LLVMValueRef coords[3];
889962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddx[3];
890962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddy[3];
891c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   unsigned num_coords;
89263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
89363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
8949db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   if (!bld->sampler) {
8959db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
8969db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      for (i = 0; i < 4; i++) {
8979db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca         texel[i] = bld->base.undef;
8989db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      }
8999db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      return;
9009db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   }
9019db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca
9027d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   switch (inst->Texture.Texture) {
90363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_1D:
904c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 1;
90563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
90663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_2D:
90763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_RECT:
908c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 2;
90963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
910f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW1D:
911f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW2D:
912f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOWRECT:
91363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_3D:
91463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_CUBE:
915c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 3;
91663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
91763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
91863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert(0);
91963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      return;
92063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
92163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
92258daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS) {
923ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = emit_fetch( bld, inst, 0, 3 );
924ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
925ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
92658daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   else if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
927ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
928ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = emit_fetch( bld, inst, 0, 3 );
929ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
930ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   else {
931ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
932ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
933ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
93463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
93558daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED) {
9362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      oow = emit_fetch( bld, inst, 0, 3 );
93763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      oow = lp_build_rcp(&bld->base, oow);
93863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
93963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
940c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   for (i = 0; i < num_coords; i++) {
941c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      coords[i] = emit_fetch( bld, inst, 0, i );
94258daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED)
943c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca         coords[i] = lp_build_mul(&bld->base, coords[i], oow);
94463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
945ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   for (i = num_coords; i < 3; i++) {
946ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca      coords[i] = bld->base.undef;
947ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   }
94863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
94958daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
95017dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca      LLVMTypeRef i32t = LLVMInt32Type();
95117dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca      LLVMValueRef index0 = LLVMConstInt(i32t, 0, 0);
952962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
95317dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         LLVMValueRef src1 = emit_fetch( bld, inst, 1, i );
95417dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         LLVMValueRef src2 = emit_fetch( bld, inst, 2, i );
95517dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         ddx[i] = LLVMBuildExtractElement(bld->base.builder, src1, index0, "");
95617dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         ddy[i] = LLVMBuildExtractElement(bld->base.builder, src2, index0, "");
957962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
958962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[3].Register.Index;
959962558daaed43b0111cd062e32821aad106869d7José Fonseca   }  else {
960962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
96117dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         ddx[i] = lp_build_scalar_ddx( &bld->base, coords[i] );
96217dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         ddy[i] = lp_build_scalar_ddy( &bld->base, coords[i] );
963962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
964962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[1].Register.Index;
965962558daaed43b0111cd062e32821aad106869d7José Fonseca   }
9664554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   for (i = num_coords; i < 3; i++) {
96717dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca      ddx[i] = LLVMGetUndef(bld->base.elem_type);
96817dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca      ddy[i] = LLVMGetUndef(bld->base.elem_type);
9694554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   }
970962558daaed43b0111cd062e32821aad106869d7José Fonseca
9718be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld->sampler->emit_fetch_texel(bld->sampler,
9728be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  bld->base.builder,
9738be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  bld->base.type,
974962558daaed43b0111cd062e32821aad106869d7José Fonseca                                  unit, num_coords, coords,
975ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  ddx, ddy,
976ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  lod_bias, explicit_lod,
9778be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  texel);
97863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
97963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
98022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwellstatic boolean
98122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwellnear_end_of_shader(struct lp_build_tgsi_soa_context *bld,
98222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell		   int pc)
98322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell{
98422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   int i;
98522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
98622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   for (i = 0; i < 5; i++) {
98722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      unsigned opcode;
98822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
98922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (pc + i >= bld->info->num_instructions)
99022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return TRUE;
99122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
99222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      opcode = bld->instructions[pc + i].Instruction.Opcode;
99322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
99422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (opcode == TGSI_OPCODE_END)
99522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return TRUE;
99622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
99722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (opcode == TGSI_OPCODE_TEX ||
99822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXP ||
99922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXD ||
100022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXB ||
100122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXL ||
100222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXF ||
100322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXQ ||
100422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_CAL ||
100522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_CALLNZ ||
100622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_IF ||
100722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_IFC ||
100822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_BGNLOOP ||
100922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_SWITCH)
101022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return FALSE;
101122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   }
101222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
101322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   return TRUE;
101422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell}
101522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
101622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
101763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1018feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul/**
1019feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Kill fragment if any of the src register values are negative.
1020feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
102163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
102263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_kil(
102363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
102422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   const struct tgsi_full_instruction *inst,
102522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   int pc)
102663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
10277d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_src_register *reg = &inst->Src[0];
10287821664b15501b173b2304bbada758c33c5ff972José Fonseca   LLVMValueRef terms[NUM_CHANNELS];
10293d7a88674f9eb3320eeff511968f041426e25023José Fonseca   LLVMValueRef mask;
103063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
103163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
10327821664b15501b173b2304bbada758c33c5ff972José Fonseca   memset(&terms, 0, sizeof terms);
103363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
103463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   FOR_EACH_CHANNEL( chan_index ) {
103563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      unsigned swizzle;
103663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
10377821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Unswizzle channel */
1038b9cb74c7f826dfd320f5e5b54aa933898f7ddd3dKeith Whitwell      swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
103963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
10407821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Check if the component has not been already tested. */
10417821664b15501b173b2304bbada758c33c5ff972José Fonseca      assert(swizzle < NUM_CHANNELS);
10427821664b15501b173b2304bbada758c33c5ff972José Fonseca      if( !terms[swizzle] )
10437821664b15501b173b2304bbada758c33c5ff972José Fonseca         /* TODO: change the comparison operator instead of setting the sign */
10442fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         terms[swizzle] =  emit_fetch(bld, inst, 0, chan_index );
104563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
104663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
10473d7a88674f9eb3320eeff511968f041426e25023José Fonseca   mask = NULL;
10487821664b15501b173b2304bbada758c33c5ff972José Fonseca   FOR_EACH_CHANNEL( chan_index ) {
1049aede39efd86d200ffbace8fc012104e31f673973José Fonseca      if(terms[chan_index]) {
10503d7a88674f9eb3320eeff511968f041426e25023José Fonseca         LLVMValueRef chan_mask;
1051aede39efd86d200ffbace8fc012104e31f673973José Fonseca
1052feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul         /*
1053feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          * If term < 0 then mask = 0 else mask = ~0.
1054feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          */
10553d7a88674f9eb3320eeff511968f041426e25023José Fonseca         chan_mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero);
1056aede39efd86d200ffbace8fc012104e31f673973José Fonseca
10573d7a88674f9eb3320eeff511968f041426e25023José Fonseca         if(mask)
10583d7a88674f9eb3320eeff511968f041426e25023José Fonseca            mask = LLVMBuildAnd(bld->base.builder, mask, chan_mask, "");
10593d7a88674f9eb3320eeff511968f041426e25023José Fonseca         else
10603d7a88674f9eb3320eeff511968f041426e25023José Fonseca            mask = chan_mask;
1061aede39efd86d200ffbace8fc012104e31f673973José Fonseca      }
106263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
10633d7a88674f9eb3320eeff511968f041426e25023José Fonseca
1064aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell   if(mask) {
10653d7a88674f9eb3320eeff511968f041426e25023José Fonseca      lp_build_mask_update(bld->mask, mask);
1066aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell
106722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (!near_end_of_shader(bld, pc))
106822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 lp_build_mask_check(bld->mask);
1069aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell   }
107063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
107163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
107263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
107363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
1074feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Predicated fragment kill.
1075feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * XXX Actually, we do an unconditional kill (as in tgsi_exec.c).
1076feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * The only predication is the execution mask which will apply if
1077feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * we're inside a loop or conditional.
1078feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
1079feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulstatic void
1080feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulemit_kilp(struct lp_build_tgsi_soa_context *bld,
108122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell          const struct tgsi_full_instruction *inst,
108222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  int pc)
1083feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul{
1084feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   LLVMValueRef mask;
1085feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
1086feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   /* For those channels which are "alive", disable fragment shader
1087feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    * execution.
1088feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    */
1089feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   if (bld->exec_mask.has_mask) {
1090feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul      mask = LLVMBuildNot(bld->base.builder, bld->exec_mask.exec_mask, "kilp");
1091feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
1092feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   else {
1093ec2824cd867d3b782588be1f3b1d5d802eb381abBrian Paul      LLVMValueRef zero = LLVMConstNull(bld->base.int_vec_type);
1094ec2824cd867d3b782588be1f3b1d5d802eb381abBrian Paul      mask = zero;
1095feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
1096feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
1097feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   lp_build_mask_update(bld->mask, mask);
1098aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell
109922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   if (!near_end_of_shader(bld, pc))
110022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      lp_build_mask_check(bld->mask);
1101feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul}
1102feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
11035b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
11045b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul/**
11055b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul * Emit code which will dump the value of all the temporary registers
11065b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul * to stdout.
11075b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul */
11085b294a5d17c818ecbb1295fdd20825da9b106792Brian Paulstatic void
11095b294a5d17c818ecbb1295fdd20825da9b106792Brian Paulemit_dump_temps(struct lp_build_tgsi_soa_context *bld)
11105b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul{
11115b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMBuilderRef builder = bld->base.builder;
11125b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef temp_ptr;
11135b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef i0 = lp_build_const_int32(0);
11145b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef i1 = lp_build_const_int32(1);
11155b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef i2 = lp_build_const_int32(2);
11165b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef i3 = lp_build_const_int32(3);
11175b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   int index;
11185b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   int n = bld->info->file_max[TGSI_FILE_TEMPORARY];
11195b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
11205b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   for (index = 0; index < n; index++) {
11215b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      LLVMValueRef idx = lp_build_const_int32(index);
11225b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      LLVMValueRef v[4][4], res;
11235b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      int chan;
11245b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
11255b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      lp_build_printf(builder, "TEMP[%d]:\n", idx);
11265b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
11275b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      for (chan = 0; chan < 4; chan++) {
11285b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         temp_ptr = get_temp_ptr(bld, index, chan);
11295b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
11305b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][0] = LLVMBuildExtractElement(builder, res, i0, "");
11315b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][1] = LLVMBuildExtractElement(builder, res, i1, "");
11325b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][2] = LLVMBuildExtractElement(builder, res, i2, "");
11335b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][3] = LLVMBuildExtractElement(builder, res, i3, "");
11345b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      }
11355b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
11365b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      lp_build_printf(builder, "  X: %f %f %f %f\n",
11375b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[0][0], v[0][1], v[0][2], v[0][3]);
11385b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      lp_build_printf(builder, "  Y: %f %f %f %f\n",
11395b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[1][0], v[1][1], v[1][2], v[1][3]);
11405b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      lp_build_printf(builder, "  Z: %f %f %f %f\n",
11415b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[2][0], v[2][1], v[2][2], v[2][3]);
11425b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      lp_build_printf(builder, "  W: %f %f %f %f\n",
11435b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[3][0], v[3][1], v[3][2], v[3][3]);
11445b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   }
11455b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul}
11465b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
11475b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
11485b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
1149e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonsecastatic void
115085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusinemit_declaration(
115185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   struct lp_build_tgsi_soa_context *bld,
115285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   const struct tgsi_full_declaration *decl)
115385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin{
11546d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMTypeRef vec_type = bld->base.vec_type;
1155a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca
115685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned first = decl->Range.First;
115785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned last = decl->Range.Last;
115885c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned idx, i;
115985c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
116085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   for (idx = first; idx <= last; ++idx) {
11616d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      assert(last <= bld->info->file_max[decl->Declaration.File]);
116285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      switch (decl->Declaration.File) {
116385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_TEMPORARY:
11646c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_TEMPS);
11653662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul         if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
1166846b2fccc2a67b08acc6da51f4970fe66ed4559bBrian Paul            LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
1167846b2fccc2a67b08acc6da51f4970fe66ed4559bBrian Paul                                                   last*4 + 4, 0);
1168263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->temps_array = lp_build_array_alloca(bld->base.builder,
11693ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                                     vec_type, array_size, "temparray");
1170263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         } else {
1171021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin            for (i = 0; i < NUM_CHANNELS; i++)
1172a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca               bld->temps[idx][i] = lp_build_alloca(bld->base.builder,
11733ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                                    vec_type, "temp");
1174021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin         }
117585c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
117685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
117785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_OUTPUT:
1178263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1179263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->outputs[idx][i] = lp_build_alloca(bld->base.builder,
11803ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                                   vec_type, "output");
118185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
118285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
1183ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin      case TGSI_FILE_ADDRESS:
11846c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_ADDRS);
1185263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1186263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->addr[idx][i] = lp_build_alloca(bld->base.builder,
11873ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                                vec_type, "addr");
1188ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         break;
1189ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
1190e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca      case TGSI_FILE_PREDICATE:
1191ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         assert(idx < LP_MAX_TGSI_PREDS);
1192263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1193263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->preds[idx][i] = lp_build_alloca(bld->base.builder,
11943ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                                 vec_type, "predicate");
1195e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         break;
1196e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca
119785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      default:
119885c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         /* don't need to declare other vars */
1199dc886ba1391d7d890bd1f5532bc14553e883a418Zack Rusin         break;
1200012fabca722494162c244a367913562b8cfa4677Zack Rusin      }
120185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   }
120285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin}
120363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1204fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul
1205fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul/**
1206fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul * Emit LLVM for one TGSI instruction.
1207fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul * \param return TRUE for success, FALSE otherwise
1208fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul */
1209fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paulstatic boolean
121063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_instruction(
121163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
1212faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   const struct tgsi_full_instruction *inst,
12130b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   const struct tgsi_opcode_info *info,
12140b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int *pc)
121563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
121663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
121790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   LLVMValueRef src0, src1, src2;
1218e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp0, tmp1, tmp2;
1219e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp3 = NULL;
1220e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp4 = NULL;
1221e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp5 = NULL;
1222e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp6 = NULL;
1223e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp7 = NULL;
1224faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   LLVMValueRef res;
1225faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   LLVMValueRef dst0[NUM_CHANNELS];
122663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
122789258652b6a1d282bed14549907892bdfda752f0José Fonseca   /*
122889258652b6a1d282bed14549907892bdfda752f0José Fonseca    * Stores and write masks are handled in a general fashion after the long
122989258652b6a1d282bed14549907892bdfda752f0José Fonseca    * instruction opcode switch statement.
123089258652b6a1d282bed14549907892bdfda752f0José Fonseca    *
123189258652b6a1d282bed14549907892bdfda752f0José Fonseca    * Although not stricitly necessary, we avoid generating instructions for
123289258652b6a1d282bed14549907892bdfda752f0José Fonseca    * channels which won't be stored, in cases where's that easy. For some
123389258652b6a1d282bed14549907892bdfda752f0José Fonseca    * complex instructions, like texture sampling, it is more convenient to
123489258652b6a1d282bed14549907892bdfda752f0José Fonseca    * assume a full writemask and then let LLVM optimization passes eliminate
123589258652b6a1d282bed14549907892bdfda752f0José Fonseca    * redundant code.
123689258652b6a1d282bed14549907892bdfda752f0José Fonseca    */
123789258652b6a1d282bed14549907892bdfda752f0José Fonseca
12380b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   (*pc)++;
12390b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1240faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   assert(info->num_dst <= 1);
1241ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (info->num_dst) {
1242faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1243faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.undef;
1244faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
1245faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
1246faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
124763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch (inst->Instruction.Opcode) {
124863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARL:
12492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
12502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1251ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         tmp0 = lp_build_floor(&bld->base, tmp0);
1252faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
125363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
125463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
125563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
125663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MOV:
12572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1258faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = emit_fetch( bld, inst, 0, chan_index );
125963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
126063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
126163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
126263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LIT:
12632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ) {
1264faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = bld->base.one;
126563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
12662fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
12672fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
1268faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_max( &bld->base, src0, bld->base.zero);
1269ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca      }
12702fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
1271ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[1] = SrcReg[0].yyyy */
12722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
1273ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[1] = max(XMM[1], 0) */
1274ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         tmp1 = lp_build_max( &bld->base, tmp1, bld->base.zero);
1275ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[2] = SrcReg[0].wwww */
12762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 0, CHAN_W );
1277ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         tmp1 = lp_build_pow( &bld->base, tmp1, tmp2);
12782fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1279c5abcac7ef7ebd0167093285b5fc9cf3829c1febJosé Fonseca         tmp2 = lp_build_cmp(&bld->base, PIPE_FUNC_GREATER, tmp0, bld->base.zero);
1280faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = lp_build_select(&bld->base, tmp2, tmp1, bld->base.zero);
1281c5abcac7ef7ebd0167093285b5fc9cf3829c1febJosé Fonseca      }
12822fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) ) {
1283faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
128463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
128563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
128663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
128763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RCP:
128863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_RECIP */
12892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
1290faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_rcp(&bld->base, src0);
12912fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1292faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
129363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
129463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
129563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
129663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RSQ:
129763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_RECIPSQRT */
12982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
129990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      src0 = lp_build_abs(&bld->base, src0);
1300faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_rsqrt(&bld->base, src0);
13012fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1302faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
130363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
130463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
130563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
130663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_EXP:
13072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
13082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
13092fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
131057907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_exp2_int_part = NULL;
131157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_frac_part = NULL;
131257907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_exp2 = NULL;
131357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
13142fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
131557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
13162fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
131757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp2_int_part = &tmp0;
13182fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
131957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_frac_part = &tmp1;
13202fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
132157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp2 = &tmp2;
132257907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
132357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         lp_build_exp2_approx(&bld->base, src0, p_exp2_int_part, p_frac_part, p_exp2);
132457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
13252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
1326faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_X] = tmp0;
13272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
1328faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Y] = tmp1;
13292fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
1330faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Z] = tmp2;
133163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
133263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* dst.w = 1.0 */
13332fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
1334faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
133563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
133663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
133763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
133863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LOG:
13392fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
13402fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
13412fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
1342add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_floor_log2 = NULL;
1343add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_exp = NULL;
1344add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_log2 = NULL;
134557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
13462fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
134757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         src0 = lp_build_abs( &bld->base, src0 );
134857907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
13492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
135057907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_floor_log2 = &tmp0;
13512fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
135257907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp = &tmp1;
13532fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
135457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_log2 = &tmp2;
135557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
135657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         lp_build_log2_approx(&bld->base, src0, p_exp, p_floor_log2, p_log2);
135757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
135857907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.x = floor(lg2(abs(src.x))) */
13592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
1360faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_X] = tmp0;
136157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.y = abs(src)/ex2(floor(lg2(abs(src.x)))) */
13622fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y )) {
1363faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Y] = lp_build_div( &bld->base, src0, tmp1);
136463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
136557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.z = lg2(abs(src.x)) */
13662fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
1367faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Z] = tmp2;
136863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
136963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* dst.w = 1.0 */
13702fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
1371faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
137263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
137363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
137463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
137563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MUL:
13762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13772fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
13782fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1379faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_mul(&bld->base, src0, src1);
138063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
138163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
138263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
138363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ADD:
13842fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
13862fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1387faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_add(&bld->base, src0, src1);
138863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
138963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
139063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
139163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP3:
139263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_DOT3 */
13932fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
13942fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
139590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
13962fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
13972fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
139890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
139990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
14002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
14012fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
140290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
140390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
14042fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1405faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
140663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
140763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
140863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
140963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP4:
141063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_DOT4 */
14112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
14122fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
141390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
14142fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
14152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
141690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
141790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
14182fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
14192fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
142090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
142190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
14222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_W );
14232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_W );
142490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
142590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
14262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1427faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
142863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
142963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
143063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
143163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DST:
14322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
1433faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = bld->base.one;
143463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14352fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
14362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
14372fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, CHAN_Y );
1438faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp0, tmp1);
143963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14402fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
1441faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = emit_fetch( bld, inst, 0, CHAN_Z );
144263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14432fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1444faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = emit_fetch( bld, inst, 1, CHAN_W );
144563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
144663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
144763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
144863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MIN:
14492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
14512fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1452faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_min( &bld->base, src0, src1 );
145363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
145463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
145563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
145663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MAX:
14572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
14592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1460faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_max( &bld->base, src0, src1 );
146163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
146263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
146363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
146463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SLT:
146563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SETLT */
14662fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14672fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
14682fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
14691aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, src1 );
1470faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
14711aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
147263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
147363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
147463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SGE:
147563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SETGE */
14762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14772fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
14782fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
14791aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GEQUAL, src0, src1 );
1480faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
14811aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
148263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
148363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
148463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MAD:
148563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_MADD */
14862fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
14882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, chan_index );
14892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 2, chan_index );
149090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
149190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_add( &bld->base, tmp0, tmp2);
1492faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
149363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
149463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
149563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
149663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SUB:
14972fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
14992fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, chan_index );
1500faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_sub( &bld->base, tmp0, tmp1);
150163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
150263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
150363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
150463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LRP:
15052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
15082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
150990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_sub( &bld->base, src1, src2 );
151090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, src0, tmp0 );
1511faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_add( &bld->base, tmp0, src2 );
151263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
151363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
151463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
151563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CND:
1516873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1517873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
1518873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1519873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
1520185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul         tmp1 = lp_build_const_vec(bld->base.type, 0.5);
1521873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src2, tmp1);
1522faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, src0, src1 );
1523873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
152463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
152563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
152663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP2A:
15272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );  /* xmm0 = src[0].x */
15282fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );  /* xmm1 = src[1].x */
152990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 * xmm1 */
15302fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );  /* xmm1 = src[0].y */
15312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );  /* xmm2 = src[1].y */
153290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);              /* xmm1 = xmm1 * xmm2 */
153390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
15342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 2, CHAN_X );  /* xmm1 = src[2].x */
153590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
15362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1537faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;  /* dest[ch] = xmm0 */
153863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
153963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
154063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
154163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_FRC:
15422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1543873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
1544873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_floor(&bld->base, src0);
1545f1f49bd465b899d1c85aa07650ca5b62a50303b0Brian Paul         tmp0 = lp_build_sub(&bld->base, src0, tmp0);
1546faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
154763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
154863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
154963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
155063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CLAMP:
1551873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1552873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1553873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1554873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
1555873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_max(&bld->base, tmp0, src1);
1556873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_min(&bld->base, tmp0, src2);
1557faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
1558873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
155963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
156063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
156163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_FLR:
15622fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1564faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_floor(&bld->base, tmp0);
156563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
156663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
156763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
156863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ROUND:
15692fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15702fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1571faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_round(&bld->base, tmp0);
157263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
157363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
157463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
157590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   case TGSI_OPCODE_EX2: {
15762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
157790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_exp2( &bld->base, tmp0);
15782fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1579faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
158063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
158163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
158290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   }
158363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
158463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LG2:
15852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
158690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_log2( &bld->base, tmp0);
15872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1588faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
158963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
159063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
159163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
159263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_POW:
15932fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
15942fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src1 = emit_fetch( bld, inst, 1, CHAN_X );
1595faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_pow( &bld->base, src0, src1 );
15962fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1597faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
159863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
159963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
160063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
160163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_XPD:
16022fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
16032fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
16042fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, CHAN_Z );
16052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp3 = emit_fetch( bld, inst, 0, CHAN_Z );
160663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
16072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
16082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
16092fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
16102fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp4 = emit_fetch( bld, inst, 1, CHAN_Y );
161163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
16122fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
161390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = tmp0;
161490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = lp_build_mul( &bld->base, tmp2, tmp1);
161590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = tmp3;
161690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
161790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = lp_build_sub( &bld->base, tmp2, tmp5);
1618faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = tmp2;
161963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
16202fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
16212fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
16222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 1, CHAN_X );
16232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp5 = emit_fetch( bld, inst, 0, CHAN_X );
162463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
16252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
162690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp3 = lp_build_mul( &bld->base, tmp3, tmp2);
162790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp1 = lp_build_mul( &bld->base, tmp1, tmp5);
162890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp3 = lp_build_sub( &bld->base, tmp3, tmp1);
1629faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = tmp3;
163063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
16312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
163290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
163390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, tmp0, tmp2);
163490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_sub( &bld->base, tmp5, tmp0);
1635faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = tmp5;
163663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
16372fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1638faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
163963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
164063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
164163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
164263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ABS:
16432fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16442fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1645faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_abs( &bld->base, tmp0 );
164663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
164763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
164863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
164963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RCC:
1650873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1651873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1652fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
165363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
165463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DPH:
16552fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
16562fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
165790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
16582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
16592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
166090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
166190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
16622fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
16632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
166490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
166590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
16662fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_W );
166790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
16682fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1669faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
167063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
167163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
167263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
167363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_COS:
16742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
167590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_cos( &bld->base, tmp0 );
16762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1677faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
167863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
167963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
168063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
168163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DDX:
168286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
168386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca         emit_fetch_deriv( bld, inst, 0, chan_index, NULL, &dst0[chan_index], NULL);
168486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      }
168563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
168663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
168763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DDY:
168886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
168986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca         emit_fetch_deriv( bld, inst, 0, chan_index, NULL, NULL, &dst0[chan_index]);
169086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      }
169163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
169263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
169363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_KILP:
169463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* predicated kill */
169522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      emit_kilp( bld, inst, (*pc)-1 );
169663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
169763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
169863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_KIL:
169963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* conditional kill */
170022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      emit_kil( bld, inst, (*pc)-1 );
170163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
170263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
170363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK2H:
1704fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
170563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
170663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
170763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK2US:
1708fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
170963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
171063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
171163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK4B:
1712fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
171363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
171463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
171563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK4UB:
1716fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
171763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
171863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
171963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RFL:
1720fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
172163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
172263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
172363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SEQ:
17242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
17252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
17262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
17271aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_EQUAL, src0, src1 );
1728faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
17291aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
173063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
173163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
173263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SFL:
1733873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1734faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.zero;
1735873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
173663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
173763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
173863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SGT:
17392fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
17402fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
17412fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
17421aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src0, src1 );
1743faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
17441aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
174563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
174663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
174763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SIN:
17482fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
174990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_sin( &bld->base, tmp0 );
17502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1751faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
175263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
175363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
175463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
175563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SLE:
17562fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
17572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
17582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
17591aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LEQUAL, src0, src1 );
1760faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
17611aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
176263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
176363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
176463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SNE:
17652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
17662fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
17672fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
17681aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_NOTEQUAL, src0, src1 );
1769faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
17701aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
177163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
177263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
177363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_STR:
1774873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1775faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.one;
1776873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
177763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
177863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
177963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TEX:
178058daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_NONE, dst0 );
178163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
178263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
178363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXD:
178458daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV, dst0 );
178563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
178663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
178763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP2H:
1788873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1789873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert (0);
1790fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
179163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
179263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
179363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP2US:
1794873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1795873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1796fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
179763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
179863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
179963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP4B:
1800873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1801873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1802fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
180363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
180463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
180563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP4UB:
1806873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1807873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1808fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
180963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
181063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
181163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_X2D:
1812873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1813873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1814fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
181563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
181663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
181763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARA:
1818873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1819873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1820fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
182163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
182263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
182363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARR:
18242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1826ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         tmp0 = lp_build_round(&bld->base, tmp0);
1827faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
182863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
182963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
183063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
183163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_BRA:
1832873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1833873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1834fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
183563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
183663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1837263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   case TGSI_OPCODE_CAL:
18380b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_call(&bld->exec_mask,
18390b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                        inst->Label.Label,
18400b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                        pc);
18410b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
184263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
184363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
184463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RET:
18450b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_ret(&bld->exec_mask, pc);
184663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
184763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
184863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_END:
18495b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      if (0) {
18505b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         /* for debugging */
18515b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         emit_dump_temps(bld);
18525b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      }
18530b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
185463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
185563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
185663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SSG:
185763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SGN */
18582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1860faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_sgn( &bld->base, tmp0 );
186163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
186263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
186363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
186463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CMP:
18652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18662fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
18672fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
18682fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
18691aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, bld->base.zero );
1870faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, src1, src2);
18711aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
187263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
187363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
187463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SCS:
18752fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
18762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1877faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = lp_build_cos( &bld->base, tmp0 );
187863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
18792fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
18802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1881faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_sin( &bld->base, tmp0 );
188263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
18832fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
1884faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = bld->base.zero;
188563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
18862fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1887faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
188863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
188963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
189063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
189163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXB:
189258daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_LOD_BIAS, dst0 );
189363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
189463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
189563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NRM:
189663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* fall-through */
189763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NRM4:
189863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* 3 or 4-component normalization */
189963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      {
190063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         uint dims = (inst->Instruction.Opcode == TGSI_OPCODE_NRM) ? 3 : 4;
190163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
19022fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) ||
19032fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y) ||
19042fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z) ||
19052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 4)) {
190663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
190763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* NOTE: Cannot use xmm regs 2/3 here (see emit_rsqrt() above). */
190863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
190963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm4 = src.x */
191063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = src.x * src.x */
19112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
19122fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
191390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp4 = tmp0;
191463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
191590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_mul( &bld->base, tmp0, tmp0);
191663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
191763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm5 = src.y */
191863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = xmm0 + src.y * src.y */
19192fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp1 = emit_fetch(bld, inst, 0, CHAN_Y);
19202fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
192190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp5 = tmp1;
192263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
192390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
192490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
192563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
192663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm6 = src.z */
192763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = xmm0 + src.z * src.z */
19282fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp1 = emit_fetch(bld, inst, 0, CHAN_Z);
19292fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
193090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp6 = tmp1;
193163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
193290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
193390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
193463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
193563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            if (dims == 4) {
193663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               /* xmm7 = src.w */
193763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               /* xmm0 = xmm0 + src.w * src.w */
19382fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca               tmp1 = emit_fetch(bld, inst, 0, CHAN_W);
19392fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca               if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W)) {
194090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca                  tmp7 = tmp1;
194163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               }
194290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
194390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
194463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
194563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
194663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm1 = 1 / sqrt(xmm0) */
194790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_rsqrt( &bld->base, tmp0);
194863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
194963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.x = xmm1 * src.x */
19502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
1951faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_X] = lp_build_mul( &bld->base, tmp4, tmp1);
195263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
195363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
195463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.y = xmm1 * src.y */
19552fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
1956faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp5, tmp1);
195763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
195863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
195963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.z = xmm1 * src.z */
19602fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
1961faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_Z] = lp_build_mul( &bld->base, tmp6, tmp1);
196263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
196363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
196463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.w = xmm1 * src.w */
19652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) && dims == 4) {
1966faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_W] = lp_build_mul( &bld->base, tmp7, tmp1);
196763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
196863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
196963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1970faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         /* dst.w = 1.0 */
19712fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 3) {
1972faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_W] = bld->base.one;
197363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
197463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
197563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
197663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
197763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DIV:
1978873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1979873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert( 0 );
1980fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
198163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
198263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
198363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP2:
19842fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );  /* xmm0 = src[0].x */
19852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );  /* xmm1 = src[1].x */
198690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 * xmm1 */
19872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );  /* xmm1 = src[0].y */
19882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );  /* xmm2 = src[1].y */
198990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);              /* xmm1 = xmm1 * xmm2 */
199090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
19912fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1992faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;  /* dest[ch] = xmm0 */
199363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
199463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
199563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
199663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXL:
199758daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD, dst0 );
199863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
199963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
200063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXP:
200158daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_PROJECTED, dst0 );
200263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
200318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
200463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_BRK:
200518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_break(&bld->exec_mask);
200663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
200763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
200863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_IF:
200980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
2010ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin      tmp0 = lp_build_cmp(&bld->base, PIPE_FUNC_NOTEQUAL,
2011ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                          tmp0, bld->base.zero);
201280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_push(&bld->exec_mask, tmp0);
201363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
201463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
201518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   case TGSI_OPCODE_BGNLOOP:
201618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_bgnloop(&bld->exec_mask);
201718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      break;
201818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
20190b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   case TGSI_OPCODE_BGNSUB:
20200b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_bgnsub(&bld->exec_mask);
20210b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      break;
20220b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
202363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ELSE:
202480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_invert(&bld->exec_mask);
202563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
202663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
202763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ENDIF:
202880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_pop(&bld->exec_mask);
202963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
203063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
203118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   case TGSI_OPCODE_ENDLOOP:
203218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_endloop(&bld->exec_mask);
203318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      break;
203418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
20350b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   case TGSI_OPCODE_ENDSUB:
20360b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_endsub(&bld->exec_mask, pc);
20370b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      break;
20380b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
203963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PUSHA:
2040873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2041873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2042fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
204363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
204463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
204563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_POPA:
2046873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2047873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2048fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
204963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
205063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
205163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CEIL:
2052873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
2053873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
2054faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_ceil(&bld->base, tmp0);
2055873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
205663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
205763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
205863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_I2F:
2059873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2060873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2061fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
206263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
206363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
206463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NOT:
2065873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2066873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2067fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
206863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
206963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
207063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TRUNC:
20712fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
20722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
2073faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_trunc(&bld->base, tmp0);
207463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
207563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
207663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
207763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SHL:
2078873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2079873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2080fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
208163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
208263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
20832c046034dc5c95dd2fe84d0b4fd44f25235480b9Michal Krol   case TGSI_OPCODE_ISHR:
2084873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2085873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2086fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
208763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
208863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
208963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_AND:
2090873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2091873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2092fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
209363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
209463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
209563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_OR:
2096873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2097873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2098fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
209963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
210063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
210163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MOD:
2102873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2103873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2104fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
210563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
210663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
210763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_XOR:
2108873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2109873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2110fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
211163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
211263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
211363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SAD:
2114873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2115873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2116fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
211763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
211863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
211963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXF:
2120873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2121873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2122fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
212363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
212463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
212563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXQ:
2126873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2127873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2128fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
212963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
213063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
213163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CONT:
213218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_continue(&bld->exec_mask);
213363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
213463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
213563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_EMIT:
2136fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
213763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
213863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
213963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ENDPRIM:
2140fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
214163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
214263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2143873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca   case TGSI_OPCODE_NOP:
2144873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      break;
2145873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca
214663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
2147fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
214863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
214963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2150faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   if(info->num_dst) {
2151ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      LLVMValueRef pred[NUM_CHANNELS];
2152ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
2153ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      emit_fetch_predicate( bld, inst, pred );
2154ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
2155faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
2156ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         emit_store( bld, inst, 0, chan_index, pred[chan_index], dst0[chan_index]);
2157faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
2158faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
2159faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
2160fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul   return TRUE;
216163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
216263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2163c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca
2164c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonsecavoid
216563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecalp_build_tgsi_soa(LLVMBuilderRef builder,
216663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  const struct tgsi_token *tokens,
2167b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca                  struct lp_type type,
21683d7a88674f9eb3320eeff511968f041426e25023José Fonseca                  struct lp_build_mask_context *mask,
216963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  LLVMValueRef consts_ptr,
2170f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef *pos,
2171f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef (*inputs)[NUM_CHANNELS],
2172f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  LLVMValueRef (*outputs)[NUM_CHANNELS],
2173021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                  struct lp_build_sampler_soa *sampler,
21743f6dc8e79d918283a6dfcf9c8937a6d52f3bb4f5Brian Paul                  const struct tgsi_shader_info *info)
217563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
217663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context bld;
217763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct tgsi_parse_context parse;
217863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   uint num_immediates = 0;
21790b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   uint num_instructions = 0;
218063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
21810b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int pc = 0;
218263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
21836d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_type res_type;
21846d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
21856d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(type.length <= LP_MAX_VECTOR_LENGTH);
21866d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   memset(&res_type, 0, sizeof res_type);
21876d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.width = type.width;
21886d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.length = type.length;
21896d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.sign = 1;
21906d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
219163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* Setup build context */
219263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   memset(&bld, 0, sizeof bld);
219363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   lp_build_context_init(&bld.base, builder, type);
21946d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   lp_build_context_init(&bld.uint_bld, builder, lp_uint_type(type));
2195c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca   bld.mask = mask;
2196f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.pos = pos;
2197f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.inputs = inputs;
219863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.outputs = outputs;
219963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.consts_ptr = consts_ptr;
22008be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld.sampler = sampler;
22016d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   bld.info = info;
22023662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   bld.indirect_files = info->indirect_files;
22030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   bld.instructions = (struct tgsi_full_instruction *)
22040b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                      MALLOC( LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction) );
22050b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   bld.max_instructions = LP_MAX_INSTRUCTIONS;
22060b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
22070b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (!bld.instructions) {
22080b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
22090b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
221063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
221180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_init(&bld.exec_mask, &bld.base);
221280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
221363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   tgsi_parse_init( &parse, tokens );
221463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
221563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   while( !tgsi_parse_end_of_tokens( &parse ) ) {
221663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      tgsi_parse_token( &parse );
221763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
221863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      switch( parse.FullToken.Token.Type ) {
221963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_DECLARATION:
22201fc41002252419f4688c24ea8c3814553b3d76adJosé Fonseca         /* Inputs already interpolated */
2221e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         emit_declaration( &bld, &parse.FullToken.FullDeclaration );
222263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
222363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
222463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_INSTRUCTION:
2225faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         {
22260b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            /* save expanded instruction */
22270b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            if (num_instructions == bld.max_instructions) {
2228079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               struct tgsi_full_instruction *instructions;
2229079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               instructions = REALLOC(bld.instructions,
2230079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      bld.max_instructions
2231079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      * sizeof(struct tgsi_full_instruction),
2232079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      (bld.max_instructions + LP_MAX_INSTRUCTIONS)
2233079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      * sizeof(struct tgsi_full_instruction));
2234079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               if (!instructions) {
2235079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                  break;
2236079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               }
2237079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               bld.instructions = instructions;
22380b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin               bld.max_instructions += LP_MAX_INSTRUCTIONS;
22390b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            }
22400b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
22410b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            memcpy(bld.instructions + num_instructions,
22420b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                   &parse.FullToken.FullInstruction,
22430b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                   sizeof(bld.instructions[0]));
22440b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
22450b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            num_instructions++;
2246faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         }
2247faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
224863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
224963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
225063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_IMMEDIATE:
225163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         /* simply copy the immediate values into the next immediates[] slot */
225263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         {
225363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
225463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            assert(size <= 4);
22556c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca            assert(num_immediates < LP_MAX_TGSI_IMMEDIATES);
225663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            for( i = 0; i < size; ++i )
225763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               bld.immediates[num_immediates][i] =
2258185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul                  lp_build_const_vec(type, parse.FullToken.FullImmediate.u[i].Float);
225963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            for( i = size; i < 4; ++i )
226063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               bld.immediates[num_immediates][i] = bld.base.undef;
226163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            num_immediates++;
226263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
226363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
226463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
22659381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca      case TGSI_TOKEN_TYPE_PROPERTY:
22669381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca         break;
22679381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca
226863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      default:
226963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         assert( 0 );
227063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
227163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
22720b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
22730b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   while (pc != -1) {
22740b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      struct tgsi_full_instruction *instr = bld.instructions + pc;
22750b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      const struct tgsi_opcode_info *opcode_info =
22760b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         tgsi_get_opcode_info(instr->Instruction.Opcode);
22770b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      if (!emit_instruction( &bld, instr, opcode_info, &pc ))
22780b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
22790b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                       opcode_info->mnemonic);
22800b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
22810b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
228218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (0) {
228318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
228418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef function = LLVMGetBasicBlockParent(block);
2285263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("11111111111111111111111111111 \n");
228618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      tgsi_dump(tokens, 0);
22878ad3e0b55df50beac8ba3c5cafa0be79641a4977José Fonseca      lp_debug_dump_value(function);
2288263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("2222222222222222222222222222 \n");
228918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   }
229063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   tgsi_parse_free( &parse );
22910b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
22920b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (0) {
22930b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMModuleRef module = LLVMGetGlobalParent(
22940b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld.base.builder)));
22950b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMDumpModule(module);
22960b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
22970b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
22980b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
22990b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   FREE( bld.instructions );
230063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
230163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2302