lp_bld_tgsi_soa.c revision 6299f241e9fdd86e705d144a42d9b1979c13f9ad
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"
54efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul#include "lp_bld_init.h"
557821664b15501b173b2304bbada758c33c5ff972José Fonseca#include "lp_bld_logic.h"
5663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_swizzle.h"
573d7a88674f9eb3320eeff511968f041426e25023José Fonseca#include "lp_bld_flow.h"
58ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca#include "lp_bld_quad.h"
5963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_tgsi.h"
606c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca#include "lp_bld_limits.h"
6180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin#include "lp_bld_debug.h"
625b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul#include "lp_bld_printf.h"
6363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define FOR_EACH_CHANNEL( CHAN )\
6663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)
6763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
695b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   ((INST)->Dst[0].Register.WriteMask & (1 << (CHAN)))
7063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
7163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
7263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   if (IS_DST0_CHANNEL_ENABLED( INST, CHAN ))
7363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
7463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\
7563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   FOR_EACH_CHANNEL( CHAN )\
7663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )
7763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
7863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_X 0
7963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_Y 1
8063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_Z 2
8163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_W 3
825a916204179c6787157af3f3be758dc36162ab20Keith Whitwell#define NUM_CHANNELS 4
8363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
840b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin#define LP_MAX_INSTRUCTIONS 256
850b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
8680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
8780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstruct lp_exec_mask {
8880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   struct lp_build_context *bld;
8980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
9080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   boolean has_mask;
9180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
9280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   LLVMTypeRef int_vec_type;
9380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
946c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING];
9580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   int cond_stack_size;
9680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   LLVMValueRef cond_mask;
9780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
982d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBasicBlockRef loop_block;
9918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef cont_mask;
1002d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef break_mask;
1012d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef break_var;
1022d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   struct {
1032d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMBasicBlockRef loop_block;
1042d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMValueRef cont_mask;
1052d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMValueRef break_mask;
1062d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMValueRef break_var;
1072d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   } loop_stack[LP_MAX_TGSI_NESTING];
10818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   int loop_stack_size;
10918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
11032a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   LLVMValueRef ret_mask;
1110b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   struct {
1120b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      int pc;
1130b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMValueRef ret_mask;
1140b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   } call_stack[LP_MAX_TGSI_NESTING];
1150b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int call_stack_size;
1160b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
11780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   LLVMValueRef exec_mask;
11880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin};
11963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
12063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastruct lp_build_tgsi_soa_context
12163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
12263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_context base;
12363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
124e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   /* Builder for vector integer masks and indices */
1256d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_build_context uint_bld;
126ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
127e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   /* Builder for scalar elements of shader's data type (float) */
128e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   struct lp_build_context elem_bld;
129e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul
13063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef consts_ptr;
131f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   const LLVMValueRef *pos;
132263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   const LLVMValueRef (*inputs)[NUM_CHANNELS];
133263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   LLVMValueRef (*outputs)[NUM_CHANNELS];
134c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca
1353f6dc8e79d918283a6dfcf9c8937a6d52f3bb4f5Brian Paul   const struct lp_build_sampler_soa *sampler;
13663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1376c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][NUM_CHANNELS];
1386c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef temps[LP_MAX_TGSI_TEMPS][NUM_CHANNELS];
1396c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef addr[LP_MAX_TGSI_ADDRS][NUM_CHANNELS];
140ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef preds[LP_MAX_TGSI_PREDS][NUM_CHANNELS];
1411929057eac0c3351e0810612bdae56331a235736José Fonseca
1423662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
1433662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    * set in the indirect_files field.
1443662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    * The temps[] array above is unused then.
1453662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    */
146021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   LLVMValueRef temps_array;
1473662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul
148528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   /* We allocate/use this array of output if (1 << TGSI_FILE_OUTPUT) is
149528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin    * set in the indirect_files field.
150528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin    * The outputs[] array above is unused then.
151528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin    */
152528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   LLVMValueRef outputs_array;
153528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
154f623d0c1c217d990f207306eb968172af79fa969Zack Rusin   /* We allocate/use this array of inputs if (1 << TGSI_FILE_INPUT) is
155f623d0c1c217d990f207306eb968172af79fa969Zack Rusin    * set in the indirect_files field.
156f623d0c1c217d990f207306eb968172af79fa969Zack Rusin    * The inputs[] array above is unused then.
157f623d0c1c217d990f207306eb968172af79fa969Zack Rusin    */
158f623d0c1c217d990f207306eb968172af79fa969Zack Rusin   LLVMValueRef inputs_array;
159f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
1606d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   const struct tgsi_shader_info *info;
1613662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   /** bitmask indicating which register files are accessed indirectly */
1623662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   unsigned indirect_files;
163021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
1643d7a88674f9eb3320eeff511968f041426e25023José Fonseca   struct lp_build_mask_context *mask;
16580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   struct lp_exec_mask exec_mask;
1660b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1670b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   struct tgsi_full_instruction *instructions;
1680b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   uint max_instructions;
16963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca};
17063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
17180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld)
17280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
17380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->bld = bld;
17480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->has_mask = FALSE;
17580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack_size = 0;
17618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->loop_stack_size = 0;
1770b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size = 0;
17880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
179efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   mask->int_vec_type = lp_build_int_vec_type(bld->gallivm, mask->bld->type);
18032a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->exec_mask = mask->ret_mask = mask->break_mask = mask->cont_mask = mask->cond_mask =
1812d91903882e399e8ea7306fd37d5d214907247e6José Fonseca         LLVMConstAllOnes(mask->int_vec_type);
18280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
18380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
18480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_update(struct lp_exec_mask *mask)
18580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
1866299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
1876299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul
18818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (mask->loop_stack_size) {
18918a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin      /*for loops we need to update the entire mask at runtime */
19018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef tmp;
1917fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul      assert(mask->break_mask);
1926299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      tmp = LLVMBuildAnd(builder,
19318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->cont_mask,
19418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->break_mask,
19518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         "maskcb");
1966299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      mask->exec_mask = LLVMBuildAnd(builder,
19718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     mask->cond_mask,
19818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     tmp,
19918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     "maskfull");
20018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   } else
20118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      mask->exec_mask = mask->cond_mask;
20218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
20332a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   if (mask->call_stack_size) {
2046299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      mask->exec_mask = LLVMBuildAnd(builder,
2050b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     mask->exec_mask,
20632a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                     mask->ret_mask,
2070b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     "callmask");
20832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   }
20918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
21018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->has_mask = (mask->cond_stack_size > 0 ||
2110b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->loop_stack_size > 0 ||
2120b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->call_stack_size > 0);
21380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
21480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
21580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
21680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                   LLVMValueRef val)
21780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2186299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
2196299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul
2206c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING);
2212d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 0) {
2222d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cond_mask == LLVMConstAllOnes(mask->int_vec_type));
2232d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
22480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask;
2252d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(LLVMTypeOf(val) == mask->int_vec_type);
2266299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->cond_mask = LLVMBuildAnd(builder,
2273fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  mask->cond_mask,
2283fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  val,
2293fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  "");
23080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
23180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
23280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
23380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_invert(struct lp_exec_mask *mask)
23480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2356299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
2362d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef prev_mask;
2372d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef inv_mask;
2382d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2392d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
2402d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   prev_mask = mask->cond_stack[mask->cond_stack_size - 1];
2412d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 1) {
2422d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(prev_mask == LLVMConstAllOnes(mask->int_vec_type));
243faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin   }
244faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin
2456299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   inv_mask = LLVMBuildNot(builder, mask->cond_mask, "");
2462d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2476299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->cond_mask = LLVMBuildAnd(builder,
24880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  inv_mask,
24980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  prev_mask, "");
25080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
25180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
25280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
25380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)
25480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2552d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
25680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_mask = mask->cond_stack[--mask->cond_stack_size];
25780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
25880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
25980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
26018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_bgnloop(struct lp_exec_mask *mask)
26118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
2626299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
2636299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul
2642d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->loop_stack_size == 0) {
2652d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->loop_block == NULL);
2662d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cont_mask == LLVMConstAllOnes(mask->int_vec_type));
2672d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_mask == LLVMConstAllOnes(mask->int_vec_type));
2682d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_var == NULL);
2692d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
2702d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2712d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size < LP_MAX_TGSI_NESTING);
27218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2732d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].loop_block = mask->loop_block;
2742d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].cont_mask = mask->cont_mask;
2752d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_mask = mask->break_mask;
2762d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_var = mask->break_var;
2772d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   ++mask->loop_stack_size;
2783a423dcf9dfa725a4e5dca60f0f2b02599d2ed9bZack Rusin
279efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   mask->break_var = lp_build_alloca(mask->bld->gallivm, mask->int_vec_type, "");
2806299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuildStore(builder, mask->break_mask, mask->break_var);
2816c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca
282efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   mask->loop_block = lp_build_insert_new_block(mask->bld->gallivm, "bgnloop");
2836299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuildBr(builder, mask->loop_block);
2846299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMPositionBuilderAtEnd(builder, mask->loop_block);
28518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2866299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->break_mask = LLVMBuildLoad(builder, mask->break_var, "");
2872d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
28818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
28918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
29018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
29118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_break(struct lp_exec_mask *mask)
29218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
2936299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
2946299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMValueRef exec_mask = LLVMBuildNot(builder,
29518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
29618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "break");
29718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2986299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->break_mask = LLVMBuildAnd(builder,
299d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   mask->break_mask,
300d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   exec_mask, "break_full");
30118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
30218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
30318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
30418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
30518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_continue(struct lp_exec_mask *mask)
30618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
3076299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
3086299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMValueRef exec_mask = LLVMBuildNot(builder,
30918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
31018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "");
31118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
3126299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->cont_mask = LLVMBuildAnd(builder,
313d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  mask->cont_mask,
314d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  exec_mask, "");
31518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
31618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
31718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
31818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
31918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
320efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paulstatic void lp_exec_endloop(struct gallivm_state *gallivm,
321efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                            struct lp_exec_mask *mask)
32218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
3236299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
32418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBasicBlockRef endloop;
325efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMTypeRef reg_type = LLVMIntTypeInContext(gallivm->context,
326efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                               mask->bld->type.width *
327efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                               mask->bld->type.length);
3287fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   LLVMValueRef i1cond;
3297fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
3307fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   assert(mask->break_mask);
3317fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
3322d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
3332d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Restore the cont_mask, but don't pop
3342d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
3352d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
3362d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size - 1].cont_mask;
3372d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   lp_exec_mask_update(mask);
3382d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
3392d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
3402d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Unlike the continue mask, the break_mask must be preserved across loop
3412d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * iterations
3422d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
3436299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuildStore(builder, mask->break_mask, mask->break_var);
3442d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
345d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca   /* i1cond = (mask == 0) */
3467fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   i1cond = LLVMBuildICmp(
3476299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      builder,
348d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMIntNE,
3496299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMBuildBitCast(builder, mask->exec_mask, reg_type, ""),
350d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMConstNull(reg_type), "");
35118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
352efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   endloop = lp_build_insert_new_block(mask->bld->gallivm, "endloop");
35318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
3546299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuildCondBr(builder,
355ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                   i1cond, mask->loop_block, endloop);
35618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
3576299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMPositionBuilderAtEnd(builder, endloop);
35818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
3592d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
3602d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   --mask->loop_stack_size;
3612d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_block = mask->loop_stack[mask->loop_stack_size].loop_block;
3622d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size].cont_mask;
3632d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_mask = mask->loop_stack[mask->loop_stack_size].break_mask;
3642d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_var = mask->loop_stack[mask->loop_stack_size].break_var;
36518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
36618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
36718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
36818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
36918a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin/* stores val into an address pointed to by dst.
37018a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * mask->exec_mask is used to figure out which bits of val
37118a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * should be stored into the address
37218a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * (0 means don't store this bit, 1 means do store).
37318a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin */
37480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_store(struct lp_exec_mask *mask,
375ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                               LLVMValueRef pred,
37680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef val,
37780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef dst)
37880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
3796299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
3806299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul
381ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   /* Mix the predicate and execution mask */
38280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   if (mask->has_mask) {
383ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (pred) {
3846299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         pred = LLVMBuildAnd(builder, pred, mask->exec_mask, "");
385ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
386ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred = mask->exec_mask;
387ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
388ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
389ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
390ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (pred) {
39180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMValueRef real_val, dst_val;
39280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
3936299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      dst_val = LLVMBuildLoad(builder, dst, "");
39480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      real_val = lp_build_select(mask->bld,
395ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                 pred,
39680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                 val, dst_val);
39780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
3986299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMBuildStore(builder, real_val, dst);
39980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   } else
4006299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMBuildStore(builder, val, dst);
40180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
40280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
4030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_call(struct lp_exec_mask *mask,
4040b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int func,
4050b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int *pc)
4060b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
40732a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size < LP_MAX_TGSI_NESTING);
4080b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack[mask->call_stack_size].pc = *pc;
40932a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack[mask->call_stack_size].ret_mask = mask->ret_mask;
41032a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack_size++;
4110b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = func;
4120b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
4130b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4140b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
4150b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
4166299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
4170b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   LLVMValueRef exec_mask;
41832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca
4190b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (mask->call_stack_size == 0) {
4200b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      /* returning from main() */
4210b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
4220b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
4230b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
4246299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   exec_mask = LLVMBuildNot(builder,
4250b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            mask->exec_mask,
4260b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            "ret");
4270b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4286299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->ret_mask = LLVMBuildAnd(builder,
42932a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 mask->ret_mask,
43032a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 exec_mask, "ret_full");
4310b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4320b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   lp_exec_mask_update(mask);
4330b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
4340b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4350b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_bgnsub(struct lp_exec_mask *mask)
4360b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
4370b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
4380b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4390b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
4400b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
44132a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size);
4420b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size--;
4430b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = mask->call_stack[mask->call_stack_size].pc;
44432a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->ret_mask = mask->call_stack[mask->call_stack_size].ret_mask;
44532a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   lp_exec_mask_update(mask);
4460b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
44786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
448695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul
449695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul/**
450695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * Return pointer to a temporary register channel (src or dest).
451f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul * Note that indirect addressing cannot be handled here.
452695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param index  which temporary register
453695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param chan  which channel of the temp register.
454695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul */
45586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic LLVMValueRef
456263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonsecaget_temp_ptr(struct lp_build_tgsi_soa_context *bld,
457263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca             unsigned index,
458f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul             unsigned chan)
459263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca{
4606299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = bld->base.gallivm->builder;
461263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   assert(chan < 4);
4623662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
463efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef lindex = lp_build_const_int32(bld->base.gallivm, index * 4 + chan);
4646299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      return LLVMBuildGEP(builder, bld->temps_array, &lindex, 1, "");
465263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   }
466695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   else {
467695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul      return bld->temps[index][chan];
468695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   }
469263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca}
470263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca
471528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin/**
472528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * Return pointer to a output register channel (src or dest).
473528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * Note that indirect addressing cannot be handled here.
474528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * \param index  which output register
475528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * \param chan  which channel of the output register.
476528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin */
477528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusinstatic LLVMValueRef
478528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusinget_output_ptr(struct lp_build_tgsi_soa_context *bld,
479528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin               unsigned index,
480528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin               unsigned chan)
481528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin{
4826299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = bld->base.gallivm->builder;
483528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   assert(chan < 4);
484528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) {
485efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef lindex = lp_build_const_int32(bld->base.gallivm,
486efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                                 index * 4 + chan);
4876299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      return LLVMBuildGEP(builder, bld->outputs_array, &lindex, 1, "");
488528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   }
489528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   else {
490528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      return bld->outputs[index][chan];
491528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   }
492528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin}
493528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
4944363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul/**
4954363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * Gather vector.
4964363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * XXX the lp_build_gather() function should be capable of doing this
4974363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * with a little work.
4984363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul */
4994363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulstatic LLVMValueRef
5004363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulbuild_gather(struct lp_build_tgsi_soa_context *bld,
5014363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef base_ptr,
5024363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef indexes)
5034363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul{
5046299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = bld->base.gallivm->builder;
5054363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   LLVMValueRef res = bld->base.undef;
5064363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   unsigned i;
5074363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5084363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   /*
5094363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    * Loop over elements of index_vec, load scalar value, insert it into 'res'.
5104363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    */
5114363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   for (i = 0; i < bld->base.type.length; i++) {
512efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef ii = lp_build_const_int32(bld->base.gallivm, i);
5136299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMValueRef index = LLVMBuildExtractElement(builder,
5144363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                                   indexes, ii, "");
5156299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr,
5163ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                             &index, 1, "gather_ptr");
5176299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMValueRef scalar = LLVMBuildLoad(builder, scalar_ptr, "");
5184363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5196299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      res = LLVMBuildInsertElement(builder, res, scalar, ii, "");
5204363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   }
5214363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5224363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   return res;
5234363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul}
5244363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5254363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
52663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
5272fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul * Scatter/store vector.
5282fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul */
5292fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paulstatic void
530e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paulemit_mask_scatter(struct lp_build_tgsi_soa_context *bld,
531e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef base_ptr,
532e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef indexes,
533e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef values,
534e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  struct lp_exec_mask *mask,
535e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef pred)
5362fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul{
537efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   struct gallivm_state *gallivm = bld->base.gallivm;
5386299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = builder;
5392fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   unsigned i;
5402fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
541e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   /* Mix the predicate and execution mask */
542e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   if (mask->has_mask) {
543e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      if (pred) {
5446299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         pred = LLVMBuildAnd(builder, pred, mask->exec_mask, "");
545e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
546e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      else {
547e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         pred = mask->exec_mask;
548e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
549e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   }
550e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul
5512fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   /*
5522fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul    * Loop over elements of index_vec, store scalar value.
5532fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul    */
5542fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   for (i = 0; i < bld->base.type.length; i++) {
555efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef ii = lp_build_const_int32(gallivm, i);
5562fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef index = LLVMBuildExtractElement(builder, indexes, ii, "");
5572fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, &index, 1, "scatter_ptr");
5582fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef val = LLVMBuildExtractElement(builder, values, ii, "scatter_val");
559e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      LLVMValueRef scalar_pred = pred ?
560e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMBuildExtractElement(builder, pred, ii, "scatter_pred") : NULL;
5612fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
562ede232e9898698258391a280a098a7ba951b0099Brian Paul      if (0)
563efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         lp_build_printf(gallivm, "scatter %d: val %f at %d %p\n",
564ede232e9898698258391a280a098a7ba951b0099Brian Paul                         ii, val, index, scalar_ptr);
565ede232e9898698258391a280a098a7ba951b0099Brian Paul
566e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      if (scalar_pred) {
567e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMValueRef real_val, dst_val;
568e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         dst_val = LLVMBuildLoad(builder, scalar_ptr, "");
569e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         real_val = lp_build_select(&bld->elem_bld, scalar_pred, val, dst_val);
570e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMBuildStore(builder, real_val, scalar_ptr);
571e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
572e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      else {
573e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMBuildStore(builder, val, scalar_ptr);
574e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
5752fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   }
5762fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul}
5772fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
5782fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
5792fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul/**
5800115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * Read the current value of the ADDR register, convert the floats to
5812fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul * ints, add the base index and return the vector of offsets.
5820115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * The offsets will be used to index into the constant buffer or
5830115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * temporary register file.
5840115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul */
5850115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paulstatic LLVMValueRef
5866d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonsecaget_indirect_index(struct lp_build_tgsi_soa_context *bld,
5876d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                   unsigned reg_file, unsigned reg_index,
5886d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                   const struct tgsi_src_register *indirect_reg)
5890115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul{
5906299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = bld->base.gallivm->builder;
5916d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_build_context *uint_bld = &bld->uint_bld;
5920115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* always use X component of address register */
5933d5b9c1f2d3340259dd0d8765090a5a963074f29José Fonseca   unsigned swizzle = indirect_reg->SwizzleX;
5946d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef base;
5956d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef rel;
5966d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef max_index;
5976d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef index;
5980115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5996d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(bld->indirect_files & (1 << reg_file));
6006d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
601efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   base = lp_build_const_int_vec(bld->base.gallivm, uint_bld->type, reg_index);
6026d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
6036d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(swizzle < 4);
6046299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   rel = LLVMBuildLoad(builder,
6056d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                        bld->addr[indirect_reg->Index][swizzle],
6066d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                        "load addr reg");
6070115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
6080115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* for indexing we want integers */
6096299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   rel = LLVMBuildFPToSI(builder,
6106d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                         rel,
6116d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                         uint_bld->vec_type, "");
6126d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
6136d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   index = lp_build_add(uint_bld, base, rel);
6140115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
615efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   max_index = lp_build_const_int_vec(bld->base.gallivm,
616efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                      uint_bld->type,
6176d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                      bld->info->file_max[reg_file]);
6180115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
6196d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(!uint_bld->type.sign);
6206d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   index = lp_build_min(uint_bld, index, max_index);
6216d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
6226d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   return index;
6230115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul}
6240115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
6250115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
6260115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul/**
62763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register fetch.
62863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
62963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic LLVMValueRef
63063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_fetch(
63163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
6322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   const struct tgsi_full_instruction *inst,
633ec0e7b16bb6753bedbd611a97062934bfca03aa7Brian Paul   unsigned src_op,
63463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const unsigned chan_index )
63563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
636efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   struct gallivm_state *gallivm = bld->base.gallivm;
6376299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = gallivm->builder;
6386d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_build_context *uint_bld = &bld->uint_bld;
639ec0e7b16bb6753bedbd611a97062934bfca03aa7Brian Paul   const struct tgsi_full_src_register *reg = &inst->Src[src_op];
64085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   const unsigned swizzle =
64185c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      tgsi_util_get_full_src_register_swizzle(reg, chan_index);
64263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef res;
6436d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef indirect_index = NULL;
64463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
64585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (swizzle > 3) {
64685c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(0 && "invalid swizzle in emit_fetch()");
64785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      return bld->base.undef;
64885c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
64985c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul
65085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (reg->Register.Indirect) {
6516d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      indirect_index = get_indirect_index(bld,
6526d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.File,
6536d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.Index,
6546d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          &reg->Indirect);
6556d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   } else {
6566d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      assert(reg->Register.Index <= bld->info->file_max[reg->Register.File]);
65785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
658ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
65985c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   switch (reg->Register.File) {
66085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_CONSTANT:
661be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      if (reg->Register.Indirect) {
6626d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         LLVMValueRef swizzle_vec =
663efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(bld->base.gallivm, uint_bld->type, swizzle);
664be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef index_vec;  /* index into the const buffer */
6654363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
6666d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         /* index_vec = indirect_index * 4 + swizzle */
6676d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
6686d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
6694363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
670be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         /* Gather values from the constant buffer */
671be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         res = build_gather(bld, bld->consts_ptr, index_vec);
672be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      }
673be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      else {
674be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef index;  /* index into the const buffer */
675be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef scalar, scalar_ptr;
676ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
677efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         index = lp_build_const_int32(gallivm, reg->Register.Index*4 + swizzle);
6784363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
6796299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         scalar_ptr = LLVMBuildGEP(builder, bld->consts_ptr,
680be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul                                   &index, 1, "");
6816299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         scalar = LLVMBuildLoad(builder, scalar_ptr, "");
6824363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
683be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         res = lp_build_broadcast_scalar(&bld->base, scalar);
68463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
68585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
68663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
68785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_IMMEDIATE:
688263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      res = bld->immediates[reg->Register.Index][swizzle];
68985c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(res);
69085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
69163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
69285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_INPUT:
693f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      if (reg->Register.Indirect) {
694f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         LLVMValueRef swizzle_vec =
695efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(gallivm, uint_bld->type, swizzle);
696f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         LLVMValueRef length_vec =
697efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(gallivm, uint_bld->type, bld->base.type.length);
698f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         LLVMValueRef index_vec;  /* index into the const buffer */
699f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         LLVMValueRef inputs_array;
700f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         LLVMTypeRef float4_ptr_type;
701f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
702f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         /* index_vec = (indirect_index * 4 + swizzle) * length */
703f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
704f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
705f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
706f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
707f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         /* cast inputs_array pointer to float* */
708efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         float4_ptr_type = LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
7096299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         inputs_array = LLVMBuildBitCast(builder, bld->inputs_array,
7106299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul                                         float4_ptr_type, "");
711f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
712f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         /* Gather values from the temporary register array */
713f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         res = build_gather(bld, inputs_array, index_vec);
714f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      } else {
715f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) {
716efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            LLVMValueRef lindex = lp_build_const_int32(gallivm,
717efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                           reg->Register.Index * 4 + swizzle);
7186299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul            LLVMValueRef input_ptr =  LLVMBuildGEP(builder,
719f623d0c1c217d990f207306eb968172af79fa969Zack Rusin                                                   bld->inputs_array, &lindex, 1, "");
7206299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul            res = LLVMBuildLoad(builder, input_ptr, "");
721f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         }
722f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         else {
723f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            res = bld->inputs[reg->Register.Index][swizzle];
724f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         }
725f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      }
72685c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(res);
72785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
72863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
72985c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_TEMPORARY:
730105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      if (reg->Register.Indirect) {
7316d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         LLVMValueRef swizzle_vec =
732efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(bld->base.gallivm, uint_bld->type, swizzle);
7336d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         LLVMValueRef length_vec =
734efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(bld->base.gallivm, uint_bld->type,
735efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                   bld->base.type.length);
736105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef index_vec;  /* index into the const buffer */
737105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef temps_array;
738105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMTypeRef float4_ptr_type;
7394363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
7406d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         /* index_vec = (indirect_index * 4 + swizzle) * length */
7416d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
7426d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
7436d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
744105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
745105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* cast temps_array pointer to float* */
746efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         float4_ptr_type = LLVMPointerType(LLVMFloatTypeInContext(bld->base.gallivm->context), 0);
7476299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         temps_array = LLVMBuildBitCast(builder, bld->temps_array,
748105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul                                        float4_ptr_type, "");
749105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
750105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* Gather values from the temporary register array */
751105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         res = build_gather(bld, temps_array, index_vec);
752105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      }
753105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      else {
754105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef temp_ptr;
755f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         temp_ptr = get_temp_ptr(bld, reg->Register.Index, swizzle);
7566299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         res = LLVMBuildLoad(builder, temp_ptr, "");
757105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         if (!res)
75863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            return bld->base.undef;
75963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
76063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
76163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
76263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
76385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(0 && "invalid src register in emit_fetch()");
7644d7a8194c5763f70ba559f32f58dfda36237b666José Fonseca      return bld->base.undef;
76563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
76663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
76763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) {
76863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_CLEAR:
76963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = lp_build_abs( &bld->base, res );
77063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
77163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
77263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_SET:
77363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = lp_build_abs( &bld->base, res );
774fc9a49b638c26801951c33a570178bbb2b67ec60nobled      /* fall through */
77563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_TOGGLE:
7768a3a971743a90463e65b44f1769a5301a31ce4cdJosé Fonseca      res = lp_build_negate( &bld->base, res );
77763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
77863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
77963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_KEEP:
78063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
78163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
78263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
78363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   return res;
78463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
78563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
78663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
78763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
78886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca * Register fetch with derivatives.
78986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca */
79086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic void
79186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecaemit_fetch_deriv(
79286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   struct lp_build_tgsi_soa_context *bld,
79386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   const struct tgsi_full_instruction *inst,
79486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   unsigned index,
79586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   const unsigned chan_index,
79686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *res,
79786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddx,
79886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddy)
79986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca{
80086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef src;
80186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
80286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   src = emit_fetch(bld, inst, index, chan_index);
80386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
80486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(res)
80586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      *res = src;
80686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
80786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   /* TODO: use interpolation coeffs for inputs */
80886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
80986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddx)
810ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca      *ddx = lp_build_ddx(&bld->base, src);
81186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
81286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddy)
813ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca      *ddy = lp_build_ddy(&bld->base, src);
81486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca}
81586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
81686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
81786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca/**
818ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca * Predicate.
819ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca */
820ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecastatic void
821ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecaemit_fetch_predicate(
822ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
823ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   const struct tgsi_full_instruction *inst,
824ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef *pred)
825ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca{
8266299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = bld->base.gallivm->builder;
827ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned index;
828ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned char swizzles[4];
829ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef unswizzled[4] = {NULL, NULL, NULL, NULL};
830ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef value;
831ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned chan;
832ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
833ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (!inst->Instruction.Predicate) {
834ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      FOR_EACH_CHANNEL( chan ) {
835ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred[chan] = NULL;
836ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
837ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      return;
838ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
839ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
840ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[0] = inst->Predicate.SwizzleX;
841ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[1] = inst->Predicate.SwizzleY;
842ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[2] = inst->Predicate.SwizzleZ;
843ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[3] = inst->Predicate.SwizzleW;
844ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
845ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   index = inst->Predicate.Index;
846ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   assert(index < LP_MAX_TGSI_PREDS);
847ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
848ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   FOR_EACH_CHANNEL( chan ) {
849ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      unsigned swizzle = swizzles[chan];
850ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
851ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      /*
852ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * Only fetch the predicate register channels that are actually listed
853ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * in the swizzles
854ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       */
855ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (!unswizzled[swizzle]) {
8566299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         value = LLVMBuildLoad(builder,
857263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                               bld->preds[index][swizzle], "");
858ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
859ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         /*
860ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * Convert the value to an integer mask.
861ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          *
862ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * TODO: Short-circuit this comparison -- a D3D setp_xx instructions
863ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * is needlessly causing two comparisons due to storing the intermediate
864ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * result as float vector instead of an integer mask vector.
865ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          */
866efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         value = lp_build_compare(bld->base.gallivm,
867ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  bld->base.type,
868ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  PIPE_FUNC_NOTEQUAL,
869ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  value,
870ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  bld->base.zero);
871ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         if (inst->Predicate.Negate) {
8726299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul            value = LLVMBuildNot(builder, value, "");
873ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         }
874ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
875ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         unswizzled[swizzle] = value;
876ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
877ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = unswizzled[swizzle];
878ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
879ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
880ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      pred[chan] = value;
881ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
882ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca}
883ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
884ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
885ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca/**
88663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register store.
88763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
88863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
88963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_store(
89063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
89163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const struct tgsi_full_instruction *inst,
8922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   unsigned index,
89363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index,
894ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef pred,
89563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef value)
89663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
897efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   struct gallivm_state *gallivm = bld->base.gallivm;
8987d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_dst_register *reg = &inst->Dst[index];
8992fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   struct lp_build_context *uint_bld = &bld->uint_bld;
9006d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef indirect_index = NULL;
9012fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca
90263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( inst->Instruction.Saturate ) {
90363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_NONE:
90463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
90563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
90663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_ZERO_ONE:
9077926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_max(&bld->base, value, bld->base.zero);
9087926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_min(&bld->base, value, bld->base.one);
90963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
91063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
91163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_MINUS_PLUS_ONE:
912efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.gallivm, bld->base.type, -1.0));
9137926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_min(&bld->base, value, bld->base.one);
91463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
9157926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca
9167926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca   default:
9177926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      assert(0);
91863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
91963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
920021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   if (reg->Register.Indirect) {
9216d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      indirect_index = get_indirect_index(bld,
9226d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.File,
9236d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.Index,
9246d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          &reg->Indirect);
9256d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   } else {
9266d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      assert(reg->Register.Index <= bld->info->file_max[reg->Register.File]);
927021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   }
928021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
9295b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   switch( reg->Register.File ) {
93063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_OUTPUT:
931528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      if (reg->Register.Indirect) {
9326299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         LLVMBuilderRef builder = builder;
933528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef chan_vec =
934efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(gallivm, uint_bld->type, chan_index);
935528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef length_vec =
936efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(gallivm, uint_bld->type, bld->base.type.length);
937528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef index_vec;  /* indexes into the temp registers */
938528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef outputs_array;
939528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef pixel_offsets;
940528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMTypeRef float_ptr_type;
941528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         int i;
942528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
943528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         /* build pixel offset vector: {0, 1, 2, 3, ...} */
944528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         pixel_offsets = uint_bld->undef;
945528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         for (i = 0; i < bld->base.type.length; i++) {
946efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            LLVMValueRef ii = lp_build_const_int32(gallivm, i);
947528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin            pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
948528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                                   ii, ii, "");
949528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         }
950528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
951528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */
952528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
953528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_add(uint_bld, index_vec, chan_vec);
954528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
955528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
956528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
957efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         float_ptr_type =
958efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
959528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         outputs_array = LLVMBuildBitCast(builder, bld->outputs_array,
960528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                          float_ptr_type, "");
961528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
962528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         /* Scatter store values into temp registers */
963528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         emit_mask_scatter(bld, outputs_array, index_vec, value,
964528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                           &bld->exec_mask, pred);
965528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      }
966528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      else {
967528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef out_ptr = get_output_ptr(bld, reg->Register.Index,
968528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                               chan_index);
969528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         lp_exec_mask_store(&bld->exec_mask, pred, value, out_ptr);
970528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      }
97163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
97263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
973f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul   case TGSI_FILE_TEMPORARY:
974f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      if (reg->Register.Indirect) {
9756299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         LLVMBuilderRef builder = builder;
9762fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef chan_vec =
977efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(gallivm, uint_bld->type, chan_index);
9782fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef length_vec =
979efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(gallivm, uint_bld->type,
980efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                   bld->base.type.length);
9812fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef index_vec;  /* indexes into the temp registers */
9822fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef temps_array;
983ede232e9898698258391a280a098a7ba951b0099Brian Paul         LLVMValueRef pixel_offsets;
9842fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMTypeRef float_ptr_type;
985ede232e9898698258391a280a098a7ba951b0099Brian Paul         int i;
986ede232e9898698258391a280a098a7ba951b0099Brian Paul
987ede232e9898698258391a280a098a7ba951b0099Brian Paul         /* build pixel offset vector: {0, 1, 2, 3, ...} */
988ede232e9898698258391a280a098a7ba951b0099Brian Paul         pixel_offsets = uint_bld->undef;
989ede232e9898698258391a280a098a7ba951b0099Brian Paul         for (i = 0; i < bld->base.type.length; i++) {
990efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            LLVMValueRef ii = lp_build_const_int32(gallivm, i);
991ede232e9898698258391a280a098a7ba951b0099Brian Paul            pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
992ede232e9898698258391a280a098a7ba951b0099Brian Paul                                                   ii, ii, "");
993ede232e9898698258391a280a098a7ba951b0099Brian Paul         }
9942fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
995ede232e9898698258391a280a098a7ba951b0099Brian Paul         /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */
9962fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
9972fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_add(uint_bld, index_vec, chan_vec);
9982fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
999ede232e9898698258391a280a098a7ba951b0099Brian Paul         index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
10002fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
1001efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         float_ptr_type =
1002efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
1003ede232e9898698258391a280a098a7ba951b0099Brian Paul         temps_array = LLVMBuildBitCast(builder, bld->temps_array,
10042fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul                                        float_ptr_type, "");
10052fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
10062fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         /* Scatter store values into temp registers */
1007e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         emit_mask_scatter(bld, temps_array, index_vec, value,
1008e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                           &bld->exec_mask, pred);
1009f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
1010f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      else {
1011f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
1012f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul                                              chan_index);
1013f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr);
1014f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
101563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
101663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
101763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_ADDRESS:
1018ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
1019557280542399629ac64a48f5b618365e2b18fce1Zack Rusin                         bld->addr[reg->Register.Index][chan_index]);
102063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
102163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1022ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca   case TGSI_FILE_PREDICATE:
1023ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
10248690c6a6b4fb0b48e2ae75cd0f64de86b039081cmichal                         bld->preds[reg->Register.Index][chan_index]);
1025ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca      break;
1026ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca
102763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
102863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert( 0 );
102963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
103063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
103163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
103263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
103363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
103463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * High-level instruction translators.
103563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
103663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
103763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
103863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_tex( struct lp_build_tgsi_soa_context *bld,
103963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca          const struct tgsi_full_instruction *inst,
104058daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca          enum lp_build_tex_modifier modifier,
1041faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca          LLVMValueRef *texel)
104263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
10436299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = bld->base.gallivm->builder;
1044962558daaed43b0111cd062e32821aad106869d7José Fonseca   unsigned unit;
1045ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   LLVMValueRef lod_bias, explicit_lod;
104631d1822473bf9d4105bb82b67572cfeea53aaf94Vinson Lee   LLVMValueRef oow = NULL;
1047c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   LLVMValueRef coords[3];
1048962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddx[3];
1049962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddy[3];
1050c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   unsigned num_coords;
105163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
105263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
10539db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   if (!bld->sampler) {
10549db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
10559db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      for (i = 0; i < 4; i++) {
10569db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca         texel[i] = bld->base.undef;
10579db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      }
10589db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      return;
10599db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   }
10609db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca
10617d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   switch (inst->Texture.Texture) {
106263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_1D:
1063c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 1;
106463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
106563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_2D:
106663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_RECT:
1067c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 2;
106863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
1069f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW1D:
1070f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW2D:
1071f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOWRECT:
107263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_3D:
107363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_CUBE:
1074c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 3;
107563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
107663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
107763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert(0);
107863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      return;
107963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
108063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
108158daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS) {
1082ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = emit_fetch( bld, inst, 0, 3 );
1083ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
1084ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
108558daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   else if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
1086ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
1087ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = emit_fetch( bld, inst, 0, 3 );
1088ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
1089ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   else {
1090ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
1091ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
1092ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
109363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
109458daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED) {
10952fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      oow = emit_fetch( bld, inst, 0, 3 );
109663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      oow = lp_build_rcp(&bld->base, oow);
109763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
109863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1099c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   for (i = 0; i < num_coords; i++) {
1100c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      coords[i] = emit_fetch( bld, inst, 0, i );
110158daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED)
1102c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca         coords[i] = lp_build_mul(&bld->base, coords[i], oow);
110363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
1104ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   for (i = num_coords; i < 3; i++) {
1105ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca      coords[i] = bld->base.undef;
1106ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   }
110763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
110858daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
1109efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef index0 = lp_build_const_int32(bld->base.gallivm, 0);
1110962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
111117dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         LLVMValueRef src1 = emit_fetch( bld, inst, 1, i );
111217dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         LLVMValueRef src2 = emit_fetch( bld, inst, 2, i );
11136299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         ddx[i] = LLVMBuildExtractElement(builder, src1, index0, "");
11146299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         ddy[i] = LLVMBuildExtractElement(builder, src2, index0, "");
1115962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
1116962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[3].Register.Index;
1117962558daaed43b0111cd062e32821aad106869d7José Fonseca   }  else {
1118962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
111917dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         ddx[i] = lp_build_scalar_ddx( &bld->base, coords[i] );
112017dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca         ddy[i] = lp_build_scalar_ddy( &bld->base, coords[i] );
1121962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
1122962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[1].Register.Index;
1123962558daaed43b0111cd062e32821aad106869d7José Fonseca   }
11244554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   for (i = num_coords; i < 3; i++) {
112517dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca      ddx[i] = LLVMGetUndef(bld->base.elem_type);
112617dbd41cf23e7e7de2f27e5e9252d7f792d932f3José Fonseca      ddy[i] = LLVMGetUndef(bld->base.elem_type);
11274554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   }
1128962558daaed43b0111cd062e32821aad106869d7José Fonseca
11298be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld->sampler->emit_fetch_texel(bld->sampler,
1130efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                  bld->base.gallivm,
11318be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  bld->base.type,
1132962558daaed43b0111cd062e32821aad106869d7José Fonseca                                  unit, num_coords, coords,
1133ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  ddx, ddy,
1134ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  lod_bias, explicit_lod,
11358be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  texel);
113663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
113763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
113822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwellstatic boolean
113922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwellnear_end_of_shader(struct lp_build_tgsi_soa_context *bld,
114022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell		   int pc)
114122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell{
114222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   int i;
114322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
114422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   for (i = 0; i < 5; i++) {
114522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      unsigned opcode;
114622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
114722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (pc + i >= bld->info->num_instructions)
114822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return TRUE;
114922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
115022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      opcode = bld->instructions[pc + i].Instruction.Opcode;
115122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
115222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (opcode == TGSI_OPCODE_END)
115322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return TRUE;
115422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
115522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (opcode == TGSI_OPCODE_TEX ||
115622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXP ||
115722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXD ||
115822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXB ||
115922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXL ||
116022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXF ||
116122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXQ ||
116222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_CAL ||
116322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_CALLNZ ||
116422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_IF ||
116522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_IFC ||
116622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_BGNLOOP ||
116722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_SWITCH)
116822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return FALSE;
116922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   }
117022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
117122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   return TRUE;
117222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell}
117322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
117422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
117563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1176feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul/**
1177feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Kill fragment if any of the src register values are negative.
1178feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
117963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
118063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_kil(
118163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
118222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   const struct tgsi_full_instruction *inst,
118322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   int pc)
118463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
11856299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = bld->base.gallivm->builder;
11867d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_src_register *reg = &inst->Src[0];
11877821664b15501b173b2304bbada758c33c5ff972José Fonseca   LLVMValueRef terms[NUM_CHANNELS];
11883d7a88674f9eb3320eeff511968f041426e25023José Fonseca   LLVMValueRef mask;
118963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
119063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11917821664b15501b173b2304bbada758c33c5ff972José Fonseca   memset(&terms, 0, sizeof terms);
119263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
119363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   FOR_EACH_CHANNEL( chan_index ) {
119463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      unsigned swizzle;
119563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11967821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Unswizzle channel */
1197b9cb74c7f826dfd320f5e5b54aa933898f7ddd3dKeith Whitwell      swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
119863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11997821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Check if the component has not been already tested. */
12007821664b15501b173b2304bbada758c33c5ff972José Fonseca      assert(swizzle < NUM_CHANNELS);
12017821664b15501b173b2304bbada758c33c5ff972José Fonseca      if( !terms[swizzle] )
12027821664b15501b173b2304bbada758c33c5ff972José Fonseca         /* TODO: change the comparison operator instead of setting the sign */
12032fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         terms[swizzle] =  emit_fetch(bld, inst, 0, chan_index );
120463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
120563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
12063d7a88674f9eb3320eeff511968f041426e25023José Fonseca   mask = NULL;
12077821664b15501b173b2304bbada758c33c5ff972José Fonseca   FOR_EACH_CHANNEL( chan_index ) {
1208aede39efd86d200ffbace8fc012104e31f673973José Fonseca      if(terms[chan_index]) {
12093d7a88674f9eb3320eeff511968f041426e25023José Fonseca         LLVMValueRef chan_mask;
1210aede39efd86d200ffbace8fc012104e31f673973José Fonseca
1211feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul         /*
1212feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          * If term < 0 then mask = 0 else mask = ~0.
1213feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          */
12143d7a88674f9eb3320eeff511968f041426e25023José Fonseca         chan_mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero);
1215aede39efd86d200ffbace8fc012104e31f673973José Fonseca
12163d7a88674f9eb3320eeff511968f041426e25023José Fonseca         if(mask)
12176299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul            mask = LLVMBuildAnd(builder, mask, chan_mask, "");
12183d7a88674f9eb3320eeff511968f041426e25023José Fonseca         else
12193d7a88674f9eb3320eeff511968f041426e25023José Fonseca            mask = chan_mask;
1220aede39efd86d200ffbace8fc012104e31f673973José Fonseca      }
122163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
12223d7a88674f9eb3320eeff511968f041426e25023José Fonseca
1223aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell   if(mask) {
12243d7a88674f9eb3320eeff511968f041426e25023José Fonseca      lp_build_mask_update(bld->mask, mask);
1225aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell
122622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (!near_end_of_shader(bld, pc))
122722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 lp_build_mask_check(bld->mask);
1228aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell   }
122963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
123063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
123163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
123263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
1233feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Predicated fragment kill.
1234feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * XXX Actually, we do an unconditional kill (as in tgsi_exec.c).
1235feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * The only predication is the execution mask which will apply if
1236feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * we're inside a loop or conditional.
1237feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
1238feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulstatic void
1239feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulemit_kilp(struct lp_build_tgsi_soa_context *bld,
124022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell          const struct tgsi_full_instruction *inst,
124122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  int pc)
1242feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul{
12436299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = bld->base.gallivm->builder;
1244feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   LLVMValueRef mask;
1245feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
1246feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   /* For those channels which are "alive", disable fragment shader
1247feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    * execution.
1248feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    */
1249feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   if (bld->exec_mask.has_mask) {
12506299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      mask = LLVMBuildNot(builder, bld->exec_mask.exec_mask, "kilp");
1251feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
1252feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   else {
1253ec2824cd867d3b782588be1f3b1d5d802eb381abBrian Paul      LLVMValueRef zero = LLVMConstNull(bld->base.int_vec_type);
1254ec2824cd867d3b782588be1f3b1d5d802eb381abBrian Paul      mask = zero;
1255feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
1256feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
1257feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   lp_build_mask_update(bld->mask, mask);
1258aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell
125922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   if (!near_end_of_shader(bld, pc))
126022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      lp_build_mask_check(bld->mask);
1261feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul}
1262feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
12635b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12645b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul/**
12655b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul * Emit code which will dump the value of all the temporary registers
12665b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul * to stdout.
12675b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul */
12685b294a5d17c818ecbb1295fdd20825da9b106792Brian Paulstatic void
12695b294a5d17c818ecbb1295fdd20825da9b106792Brian Paulemit_dump_temps(struct lp_build_tgsi_soa_context *bld)
12705b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul{
1271efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   struct gallivm_state *gallivm = bld->base.gallivm;
1272efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMBuilderRef builder = gallivm->builder;
12735b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef temp_ptr;
1274efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMValueRef i0 = lp_build_const_int32(gallivm, 0);
1275efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMValueRef i1 = lp_build_const_int32(gallivm, 1);
1276efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMValueRef i2 = lp_build_const_int32(gallivm, 2);
1277efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMValueRef i3 = lp_build_const_int32(gallivm, 3);
12785b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   int index;
12795b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   int n = bld->info->file_max[TGSI_FILE_TEMPORARY];
12805b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12815b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   for (index = 0; index < n; index++) {
1282efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef idx = lp_build_const_int32(gallivm, index);
12835b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      LLVMValueRef v[4][4], res;
12845b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      int chan;
12855b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
1286efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_build_printf(gallivm, "TEMP[%d]:\n", idx);
12875b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12885b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      for (chan = 0; chan < 4; chan++) {
12895b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         temp_ptr = get_temp_ptr(bld, index, chan);
12906299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         res = LLVMBuildLoad(builder, temp_ptr, "");
12915b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][0] = LLVMBuildExtractElement(builder, res, i0, "");
12925b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][1] = LLVMBuildExtractElement(builder, res, i1, "");
12935b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][2] = LLVMBuildExtractElement(builder, res, i2, "");
12945b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][3] = LLVMBuildExtractElement(builder, res, i3, "");
12955b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      }
12965b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
1297efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_build_printf(gallivm, "  X: %f %f %f %f\n",
12985b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[0][0], v[0][1], v[0][2], v[0][3]);
1299efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_build_printf(gallivm, "  Y: %f %f %f %f\n",
13005b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[1][0], v[1][1], v[1][2], v[1][3]);
1301efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_build_printf(gallivm, "  Z: %f %f %f %f\n",
13025b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[2][0], v[2][1], v[2][2], v[2][3]);
1303efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_build_printf(gallivm, "  W: %f %f %f %f\n",
13045b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[3][0], v[3][1], v[3][2], v[3][3]);
13055b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   }
13065b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul}
13075b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
13085b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
13095b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
1310e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonsecastatic void
131185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusinemit_declaration(
131285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   struct lp_build_tgsi_soa_context *bld,
131385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   const struct tgsi_full_declaration *decl)
131485c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin{
1315efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   struct gallivm_state *gallivm = bld->base.gallivm;
13166d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMTypeRef vec_type = bld->base.vec_type;
131755c5408ad049423597cd274e7abcd2d91a16ead3Brian Paul   const unsigned first = decl->Range.First;
131855c5408ad049423597cd274e7abcd2d91a16ead3Brian Paul   const unsigned last = decl->Range.Last;
131985c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned idx, i;
132085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
132185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   for (idx = first; idx <= last; ++idx) {
13226d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      assert(last <= bld->info->file_max[decl->Declaration.File]);
132385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      switch (decl->Declaration.File) {
132485c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_TEMPORARY:
13256c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_TEMPS);
132610740acf46e08960dde790005d65a98440f313bcJosé Fonseca         if (!(bld->indirect_files & (1 << TGSI_FILE_TEMPORARY))) {
1327021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin            for (i = 0; i < NUM_CHANNELS; i++)
1328efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul               bld->temps[idx][i] = lp_build_alloca(gallivm, vec_type, "temp");
1329021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin         }
133085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
133185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
133285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_OUTPUT:
133310740acf46e08960dde790005d65a98440f313bcJosé Fonseca         if (!(bld->indirect_files & (1 << TGSI_FILE_OUTPUT))) {
1334528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin            for (i = 0; i < NUM_CHANNELS; i++)
1335efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul               bld->outputs[idx][i] = lp_build_alloca(gallivm,
1336528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                                      vec_type, "output");
1337528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         }
133885c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
133985c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
1340ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin      case TGSI_FILE_ADDRESS:
13416c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_ADDRS);
1342263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1343efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            bld->addr[idx][i] = lp_build_alloca(gallivm, vec_type, "addr");
1344ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         break;
1345ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
1346e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca      case TGSI_FILE_PREDICATE:
1347ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         assert(idx < LP_MAX_TGSI_PREDS);
1348263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1349efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            bld->preds[idx][i] = lp_build_alloca(gallivm, vec_type,
1350efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                                 "predicate");
1351e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         break;
1352e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca
135385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      default:
135485c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         /* don't need to declare other vars */
1355dc886ba1391d7d890bd1f5532bc14553e883a418Zack Rusin         break;
1356012fabca722494162c244a367913562b8cfa4677Zack Rusin      }
135785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   }
135885c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin}
135963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1360fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul
1361fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul/**
1362fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul * Emit LLVM for one TGSI instruction.
1363fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul * \param return TRUE for success, FALSE otherwise
1364fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul */
1365fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paulstatic boolean
136663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_instruction(
136763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
1368faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   const struct tgsi_full_instruction *inst,
13690b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   const struct tgsi_opcode_info *info,
13700b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int *pc)
137163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
137263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
137390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   LLVMValueRef src0, src1, src2;
1374e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp0, tmp1, tmp2;
1375e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp3 = NULL;
1376e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp4 = NULL;
1377e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp5 = NULL;
1378e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp6 = NULL;
1379e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp7 = NULL;
1380faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   LLVMValueRef res;
1381faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   LLVMValueRef dst0[NUM_CHANNELS];
138263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
138389258652b6a1d282bed14549907892bdfda752f0José Fonseca   /*
138489258652b6a1d282bed14549907892bdfda752f0José Fonseca    * Stores and write masks are handled in a general fashion after the long
138589258652b6a1d282bed14549907892bdfda752f0José Fonseca    * instruction opcode switch statement.
138689258652b6a1d282bed14549907892bdfda752f0José Fonseca    *
138789258652b6a1d282bed14549907892bdfda752f0José Fonseca    * Although not stricitly necessary, we avoid generating instructions for
138889258652b6a1d282bed14549907892bdfda752f0José Fonseca    * channels which won't be stored, in cases where's that easy. For some
138989258652b6a1d282bed14549907892bdfda752f0José Fonseca    * complex instructions, like texture sampling, it is more convenient to
139089258652b6a1d282bed14549907892bdfda752f0José Fonseca    * assume a full writemask and then let LLVM optimization passes eliminate
139189258652b6a1d282bed14549907892bdfda752f0José Fonseca    * redundant code.
139289258652b6a1d282bed14549907892bdfda752f0José Fonseca    */
139389258652b6a1d282bed14549907892bdfda752f0José Fonseca
13940b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   (*pc)++;
13950b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1396faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   assert(info->num_dst <= 1);
1397ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (info->num_dst) {
1398faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1399faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.undef;
1400faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
1401faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
1402faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
140363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch (inst->Instruction.Opcode) {
140463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARL:
14052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1407ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         tmp0 = lp_build_floor(&bld->base, tmp0);
1408faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
140963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
141063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
141163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
141263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MOV:
14132fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1414faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = emit_fetch( bld, inst, 0, chan_index );
141563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
141663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
141763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
141863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LIT:
14192fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ) {
1420faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = bld->base.one;
142163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
14232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
1424faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_max( &bld->base, src0, bld->base.zero);
1425ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca      }
14262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
1427ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[1] = SrcReg[0].yyyy */
14282fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
1429ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[1] = max(XMM[1], 0) */
1430ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         tmp1 = lp_build_max( &bld->base, tmp1, bld->base.zero);
1431ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[2] = SrcReg[0].wwww */
14322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 0, CHAN_W );
1433ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         tmp1 = lp_build_pow( &bld->base, tmp1, tmp2);
14342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1435c5abcac7ef7ebd0167093285b5fc9cf3829c1febJosé Fonseca         tmp2 = lp_build_cmp(&bld->base, PIPE_FUNC_GREATER, tmp0, bld->base.zero);
1436faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = lp_build_select(&bld->base, tmp2, tmp1, bld->base.zero);
1437c5abcac7ef7ebd0167093285b5fc9cf3829c1febJosé Fonseca      }
14382fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) ) {
1439faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
144063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
144163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
144263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
144363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RCP:
144463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_RECIP */
14452fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
1446faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_rcp(&bld->base, src0);
14472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1448faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
144963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
145063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
145163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
145263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RSQ:
145363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_RECIPSQRT */
14542fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
145590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      src0 = lp_build_abs(&bld->base, src0);
1456faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_rsqrt(&bld->base, src0);
14572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1458faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
145963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
146063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
146163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
146263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_EXP:
14632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
14642fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
14652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
146657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_exp2_int_part = NULL;
146757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_frac_part = NULL;
146857907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_exp2 = NULL;
146957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
14702fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
147157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
14722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
147357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp2_int_part = &tmp0;
14742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
147557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_frac_part = &tmp1;
14762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
147757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp2 = &tmp2;
147857907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
147957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         lp_build_exp2_approx(&bld->base, src0, p_exp2_int_part, p_frac_part, p_exp2);
148057907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
14812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
1482faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_X] = tmp0;
14832fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
1484faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Y] = tmp1;
14852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
1486faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Z] = tmp2;
148763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
148863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* dst.w = 1.0 */
14892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
1490faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
149163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
149263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
149363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
149463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LOG:
14952fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
14962fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
14972fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
1498add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_floor_log2 = NULL;
1499add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_exp = NULL;
1500add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_log2 = NULL;
150157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
15022fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
150357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         src0 = lp_build_abs( &bld->base, src0 );
150457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
15052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
150657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_floor_log2 = &tmp0;
15072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
150857907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp = &tmp1;
15092fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
151057907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_log2 = &tmp2;
151157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
151257907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         lp_build_log2_approx(&bld->base, src0, p_exp, p_floor_log2, p_log2);
151357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
151457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.x = floor(lg2(abs(src.x))) */
15152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
1516faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_X] = tmp0;
151757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.y = abs(src)/ex2(floor(lg2(abs(src.x)))) */
15182fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y )) {
1519faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Y] = lp_build_div( &bld->base, src0, tmp1);
152063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
152157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.z = lg2(abs(src.x)) */
15222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
1523faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Z] = tmp2;
152463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
152563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* dst.w = 1.0 */
15262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
1527faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
152863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
152963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
153063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
153163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MUL:
15322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15332fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1535faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_mul(&bld->base, src0, src1);
153663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
153763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
153863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
153963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ADD:
15402fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15412fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1543faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_add(&bld->base, src0, src1);
154463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
154563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
154663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
154763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP3:
154863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_DOT3 */
15492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
15502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
155190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
15522fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
15532fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
155490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
155590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15562fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
15572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
155890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
155990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15602fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1561faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
156263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
156363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
156463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
156563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP4:
156663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_DOT4 */
15672fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
15682fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
156990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
15702fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
15712fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
157290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
157390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
15752fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
157690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
157790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15782fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_W );
15792fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_W );
158090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
158190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15822fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1583faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
158463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
158563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
158663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
158763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DST:
15882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
1589faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = bld->base.one;
159063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
15912fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
15922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
15932fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, CHAN_Y );
1594faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp0, tmp1);
159563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
15962fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
1597faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = emit_fetch( bld, inst, 0, CHAN_Z );
159863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
15992fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1600faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = emit_fetch( bld, inst, 1, CHAN_W );
160163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
160263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
160363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
160463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MIN:
16052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
16072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1608faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_min( &bld->base, src0, src1 );
160963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
161063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
161163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
161263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MAX:
16132fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16142fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
16152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1616faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_max( &bld->base, src0, src1 );
161763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
161863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
161963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
162063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SLT:
162163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SETLT */
16222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
16242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
16251aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, src1 );
1626faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
16271aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
162863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
162963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
163063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SGE:
163163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SETGE */
16322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16332fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
16342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
16351aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GEQUAL, src0, src1 );
1636faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
16371aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
163863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
163963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
164063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MAD:
164163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_MADD */
16422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16432fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
16442fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, chan_index );
16452fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 2, chan_index );
164690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
164790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_add( &bld->base, tmp0, tmp2);
1648faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
164963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
165063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
165163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
165263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SUB:
16532fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16542fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
16552fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, chan_index );
1656faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_sub( &bld->base, tmp0, tmp1);
165763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
165863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
165963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
166063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LRP:
16612fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16622fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
16632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
16642fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
166590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_sub( &bld->base, src1, src2 );
166690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, src0, tmp0 );
1667faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_add( &bld->base, tmp0, src2 );
166863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
166963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
167063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
167163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CND:
1672873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1673873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
1674873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1675873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
1676efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         tmp1 = lp_build_const_vec(bld->base.gallivm, bld->base.type, 0.5);
1677873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src2, tmp1);
1678faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, src0, src1 );
1679873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
168063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
168163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
168263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP2A:
16832fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );  /* xmm0 = src[0].x */
16842fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );  /* xmm1 = src[1].x */
168590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 * xmm1 */
16862fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );  /* xmm1 = src[0].y */
16872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );  /* xmm2 = src[1].y */
168890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);              /* xmm1 = xmm1 * xmm2 */
168990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
16902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 2, CHAN_X );  /* xmm1 = src[2].x */
169190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
16922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1693faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;  /* dest[ch] = xmm0 */
169463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
169563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
169663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
169763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_FRC:
16982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1699873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
1700873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_floor(&bld->base, src0);
1701f1f49bd465b899d1c85aa07650ca5b62a50303b0Brian Paul         tmp0 = lp_build_sub(&bld->base, src0, tmp0);
1702faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
170363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
170463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
170563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
170663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CLAMP:
1707873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1708873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1709873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1710873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
1711873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_max(&bld->base, tmp0, src1);
1712873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_min(&bld->base, tmp0, src2);
1713faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
1714873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
171563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
171663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
171763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_FLR:
17182fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
17192fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1720faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_floor(&bld->base, tmp0);
172163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
172263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
172363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
172463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ROUND:
17252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
17262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1727faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_round(&bld->base, tmp0);
172863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
172963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
173063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
173190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   case TGSI_OPCODE_EX2: {
17322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
173390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_exp2( &bld->base, tmp0);
17342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1735faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
173663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
173763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
173890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   }
173963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
174063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LG2:
17412fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
174290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_log2( &bld->base, tmp0);
17432fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1744faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
174563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
174663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
174763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
174863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_POW:
17492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
17502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src1 = emit_fetch( bld, inst, 1, CHAN_X );
1751faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_pow( &bld->base, src0, src1 );
17522fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1753faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
175463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
175563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
175663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
175763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_XPD:
17582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
17592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
17602fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, CHAN_Z );
17612fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp3 = emit_fetch( bld, inst, 0, CHAN_Z );
176263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
17642fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
17652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
17662fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp4 = emit_fetch( bld, inst, 1, CHAN_Y );
176763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17682fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
176990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = tmp0;
177090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = lp_build_mul( &bld->base, tmp2, tmp1);
177190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = tmp3;
177290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
177390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = lp_build_sub( &bld->base, tmp2, tmp5);
1774faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = tmp2;
177563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
17772fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
17782fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 1, CHAN_X );
17792fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp5 = emit_fetch( bld, inst, 0, CHAN_X );
178063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
178290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp3 = lp_build_mul( &bld->base, tmp3, tmp2);
178390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp1 = lp_build_mul( &bld->base, tmp1, tmp5);
178490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp3 = lp_build_sub( &bld->base, tmp3, tmp1);
1785faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = tmp3;
178663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
178890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
178990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, tmp0, tmp2);
179090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_sub( &bld->base, tmp5, tmp0);
1791faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = tmp5;
179263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17932fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1794faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
179563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
179663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
179763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
179863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ABS:
17992fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1801faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_abs( &bld->base, tmp0 );
180263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
180363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
180463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
180563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RCC:
1806873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1807873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1808fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
180963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
181063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DPH:
18112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
18122fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
181390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
18142fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
18152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
181690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
181790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
18182fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
18192fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
182090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
182190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
18222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_W );
182390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
18242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1825faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
182663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
182763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
182863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
182963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_COS:
18302fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
183190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_cos( &bld->base, tmp0 );
18322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1833faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
183463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
183563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
183663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
183763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DDX:
183886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
183986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca         emit_fetch_deriv( bld, inst, 0, chan_index, NULL, &dst0[chan_index], NULL);
184086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      }
184163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
184263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
184363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DDY:
184486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
184586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca         emit_fetch_deriv( bld, inst, 0, chan_index, NULL, NULL, &dst0[chan_index]);
184686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      }
184763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
184863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
184963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_KILP:
185063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* predicated kill */
185122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      emit_kilp( bld, inst, (*pc)-1 );
185263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
185363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
185463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_KIL:
185563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* conditional kill */
185622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      emit_kil( bld, inst, (*pc)-1 );
185763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
185863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
185963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK2H:
1860fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
186163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
186263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
186363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK2US:
1864fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
186563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
186663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
186763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK4B:
1868fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
186963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
187063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
187163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK4UB:
1872fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
187363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
187463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
187563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RFL:
1876fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
187763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
187863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
187963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SEQ:
18802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
18822fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
18831aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_EQUAL, src0, src1 );
1884faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
18851aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
188663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
188763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
188863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SFL:
1889873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1890faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.zero;
1891873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
189263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
189363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
189463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SGT:
18952fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18962fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
18972fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
18981aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src0, src1 );
1899faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
19001aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
190163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
190263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
190363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SIN:
19042fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
190590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_sin( &bld->base, tmp0 );
19062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1907faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
190863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
190963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
191063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
191163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SLE:
19122fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
19132fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
19142fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
19151aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LEQUAL, src0, src1 );
1916faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
19171aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
191863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
191963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
192063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SNE:
19212fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
19222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
19232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
19241aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_NOTEQUAL, src0, src1 );
1925faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
19261aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
192763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
192863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
192963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_STR:
1930873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1931faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.one;
1932873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
193363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
193463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
193563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TEX:
193658daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_NONE, dst0 );
193763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
193863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
193963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXD:
194058daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV, dst0 );
194163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
194263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
194363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP2H:
1944873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1945873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert (0);
1946fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
194763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
194863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
194963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP2US:
1950873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1951873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1952fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
195363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
195463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
195563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP4B:
1956873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1957873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1958fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
195963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
196063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
196163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP4UB:
1962873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1963873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1964fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
196563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
196663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
196763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_X2D:
1968873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1969873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1970fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
197163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
197263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
197363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARA:
1974873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1975873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1976fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
197763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
197863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
197963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARR:
19802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
19812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1982ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         tmp0 = lp_build_round(&bld->base, tmp0);
1983faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
198463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
198563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
198663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
198763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_BRA:
1988873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1989873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1990fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
199163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
199263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1993263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   case TGSI_OPCODE_CAL:
19940b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_call(&bld->exec_mask,
19950b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                        inst->Label.Label,
19960b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                        pc);
19970b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
199863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
199963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
200063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RET:
20010b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_ret(&bld->exec_mask, pc);
200263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
200363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
200463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_END:
20055b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      if (0) {
20065b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         /* for debugging */
20075b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         emit_dump_temps(bld);
20085b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      }
20090b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
201063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
201163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
201263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SSG:
201363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SGN */
20142fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
20152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
2016faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_sgn( &bld->base, tmp0 );
201763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
201863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
201963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
202063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CMP:
20212fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
20222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
20232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
20242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
20251aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, bld->base.zero );
2026faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, src1, src2);
20271aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
202863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
202963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
203063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SCS:
20312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
20322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
2033faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = lp_build_cos( &bld->base, tmp0 );
203463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
20352fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
20362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
2037faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_sin( &bld->base, tmp0 );
203863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
20392fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
2040faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = bld->base.zero;
204163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
20422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
2043faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
204463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
204563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
204663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
204763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXB:
204858daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_LOD_BIAS, dst0 );
204963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
205063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
205163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NRM:
205263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* fall-through */
205363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NRM4:
205463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* 3 or 4-component normalization */
205563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      {
205663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         uint dims = (inst->Instruction.Opcode == TGSI_OPCODE_NRM) ? 3 : 4;
205763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
20582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) ||
20592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y) ||
20602fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z) ||
20612fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 4)) {
206263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
206363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* NOTE: Cannot use xmm regs 2/3 here (see emit_rsqrt() above). */
206463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
206563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm4 = src.x */
206663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = src.x * src.x */
20672fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
20682fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
206990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp4 = tmp0;
207063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
207190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_mul( &bld->base, tmp0, tmp0);
207263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
207363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm5 = src.y */
207463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = xmm0 + src.y * src.y */
20752fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp1 = emit_fetch(bld, inst, 0, CHAN_Y);
20762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
207790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp5 = tmp1;
207863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
207990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
208090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
208163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
208263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm6 = src.z */
208363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = xmm0 + src.z * src.z */
20842fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp1 = emit_fetch(bld, inst, 0, CHAN_Z);
20852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
208690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp6 = tmp1;
208763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
208890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
208990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
209063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
209163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            if (dims == 4) {
209263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               /* xmm7 = src.w */
209363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               /* xmm0 = xmm0 + src.w * src.w */
20942fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca               tmp1 = emit_fetch(bld, inst, 0, CHAN_W);
20952fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca               if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W)) {
209690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca                  tmp7 = tmp1;
209763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               }
209890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
209990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
210063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
210163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
210263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm1 = 1 / sqrt(xmm0) */
210390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_rsqrt( &bld->base, tmp0);
210463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
210563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.x = xmm1 * src.x */
21062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
2107faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_X] = lp_build_mul( &bld->base, tmp4, tmp1);
210863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
210963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
211063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.y = xmm1 * src.y */
21112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
2112faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp5, tmp1);
211363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
211463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
211563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.z = xmm1 * src.z */
21162fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
2117faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_Z] = lp_build_mul( &bld->base, tmp6, tmp1);
211863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
211963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
212063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.w = xmm1 * src.w */
21212fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) && dims == 4) {
2122faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_W] = lp_build_mul( &bld->base, tmp7, tmp1);
212363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
212463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
212563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2126faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         /* dst.w = 1.0 */
21272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 3) {
2128faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_W] = bld->base.one;
212963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
213063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
213163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
213263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
213363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DIV:
2134873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
2135873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert( 0 );
2136fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
213763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
213863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
213963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP2:
21402fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );  /* xmm0 = src[0].x */
21412fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );  /* xmm1 = src[1].x */
214290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 * xmm1 */
21432fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );  /* xmm1 = src[0].y */
21442fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );  /* xmm2 = src[1].y */
214590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);              /* xmm1 = xmm1 * xmm2 */
214690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
21472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
2148faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;  /* dest[ch] = xmm0 */
214963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
215063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
215163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
215263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXL:
215358daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD, dst0 );
215463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
215563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
215663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXP:
215758daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      emit_tex( bld, inst, LP_BLD_TEX_MODIFIER_PROJECTED, dst0 );
215863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
215918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
216063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_BRK:
216118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_break(&bld->exec_mask);
216263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
216363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
216463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_IF:
216580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
2166ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin      tmp0 = lp_build_cmp(&bld->base, PIPE_FUNC_NOTEQUAL,
2167ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                          tmp0, bld->base.zero);
216880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_push(&bld->exec_mask, tmp0);
216963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
217063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
217118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   case TGSI_OPCODE_BGNLOOP:
217218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_bgnloop(&bld->exec_mask);
217318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      break;
217418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
21750b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   case TGSI_OPCODE_BGNSUB:
21760b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_bgnsub(&bld->exec_mask);
21770b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      break;
21780b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
217963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ELSE:
218080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_invert(&bld->exec_mask);
218163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
218263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
218363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ENDIF:
218480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_pop(&bld->exec_mask);
218563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
218663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
218718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   case TGSI_OPCODE_ENDLOOP:
2188efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_exec_endloop(bld->base.gallivm, &bld->exec_mask);
218918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      break;
219018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
21910b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   case TGSI_OPCODE_ENDSUB:
21920b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_endsub(&bld->exec_mask, pc);
21930b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      break;
21940b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
219563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PUSHA:
2196873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2197873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2198fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
219963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
220063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
220163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_POPA:
2202873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2203873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2204fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
220563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
220663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
220763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CEIL:
2208873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
2209873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
2210faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_ceil(&bld->base, tmp0);
2211873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
221263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
221363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
221463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_I2F:
2215873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2216873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2217fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
221863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
221963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
222063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NOT:
2221873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2222873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2223fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
222463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
222563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
222663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TRUNC:
22272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
22282fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
2229faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_trunc(&bld->base, tmp0);
223063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
223163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
223263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
223363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SHL:
2234873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2235873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2236fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
223763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
223863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
22392c046034dc5c95dd2fe84d0b4fd44f25235480b9Michal Krol   case TGSI_OPCODE_ISHR:
2240873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2241873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2242fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
224363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
224463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
224563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_AND:
2246873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2247873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2248fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
224963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
225063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
225163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_OR:
2252873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2253873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2254fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
225563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
225663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
225763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MOD:
2258873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2259873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2260fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
226163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
226263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
226363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_XOR:
2264873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2265873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2266fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
226763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
226863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
226963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SAD:
2270873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2271873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2272fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
227363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
227463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
227563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXF:
2276873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2277873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2278fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
227963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
228063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
228163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXQ:
2282873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
2283873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
2284fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
228563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
228663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
228763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CONT:
228818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_continue(&bld->exec_mask);
228963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
229063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
229163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_EMIT:
2292fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
229363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
229463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
229563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ENDPRIM:
2296fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
229763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
229863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2299873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca   case TGSI_OPCODE_NOP:
2300873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      break;
2301873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca
230263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
2303fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
230463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
230563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2306faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   if(info->num_dst) {
2307ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      LLVMValueRef pred[NUM_CHANNELS];
2308ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
2309ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      emit_fetch_predicate( bld, inst, pred );
2310ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
2311faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
2312ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         emit_store( bld, inst, 0, chan_index, pred[chan_index], dst0[chan_index]);
2313faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
2314faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
2315faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
2316fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul   return TRUE;
231763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
231863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2319c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca
2320c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonsecavoid
2321efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_tgsi_soa(struct gallivm_state *gallivm,
232263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  const struct tgsi_token *tokens,
2323b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca                  struct lp_type type,
23243d7a88674f9eb3320eeff511968f041426e25023José Fonseca                  struct lp_build_mask_context *mask,
232563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  LLVMValueRef consts_ptr,
2326f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef *pos,
2327f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef (*inputs)[NUM_CHANNELS],
2328f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  LLVMValueRef (*outputs)[NUM_CHANNELS],
2329021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                  struct lp_build_sampler_soa *sampler,
23303f6dc8e79d918283a6dfcf9c8937a6d52f3bb4f5Brian Paul                  const struct tgsi_shader_info *info)
233163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
233263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context bld;
233363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct tgsi_parse_context parse;
233463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   uint num_immediates = 0;
23350b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   uint num_instructions = 0;
233663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
23370b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int pc = 0;
233863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
23396d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_type res_type;
23406d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
23416d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(type.length <= LP_MAX_VECTOR_LENGTH);
23426d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   memset(&res_type, 0, sizeof res_type);
23436d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.width = type.width;
23446d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.length = type.length;
23456d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.sign = 1;
23466d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
234763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* Setup build context */
234863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   memset(&bld, 0, sizeof bld);
2349efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   lp_build_context_init(&bld.base, gallivm, type);
2350efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   lp_build_context_init(&bld.uint_bld, gallivm, lp_uint_type(type));
2351efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   lp_build_context_init(&bld.elem_bld, gallivm, lp_elem_type(type));
2352c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca   bld.mask = mask;
2353f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.pos = pos;
2354f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.inputs = inputs;
235563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.outputs = outputs;
235663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.consts_ptr = consts_ptr;
23578be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld.sampler = sampler;
23586d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   bld.info = info;
23593662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   bld.indirect_files = info->indirect_files;
23600b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   bld.instructions = (struct tgsi_full_instruction *)
23610b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                      MALLOC( LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction) );
23620b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   bld.max_instructions = LP_MAX_INSTRUCTIONS;
23630b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
23640b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (!bld.instructions) {
23650b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
23660b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
236763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
236880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_init(&bld.exec_mask, &bld.base);
236980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
237010740acf46e08960dde790005d65a98440f313bcJosé Fonseca   if (bld.indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
2371efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef array_size =
2372efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         lp_build_const_int32(gallivm,
2373efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                              info->file_max[TGSI_FILE_TEMPORARY] * 4 + 4);
2374efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      bld.temps_array = lp_build_array_alloca(gallivm,
237510740acf46e08960dde790005d65a98440f313bcJosé Fonseca                                              bld.base.vec_type, array_size,
237610740acf46e08960dde790005d65a98440f313bcJosé Fonseca                                              "temp_array");
237710740acf46e08960dde790005d65a98440f313bcJosé Fonseca   }
237810740acf46e08960dde790005d65a98440f313bcJosé Fonseca
237910740acf46e08960dde790005d65a98440f313bcJosé Fonseca   if (bld.indirect_files & (1 << TGSI_FILE_OUTPUT)) {
2380efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef array_size =
2381efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         lp_build_const_int32(gallivm,
2382efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                              info->file_max[TGSI_FILE_OUTPUT] * 4 + 4);
2383efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      bld.outputs_array = lp_build_array_alloca(gallivm,
238410740acf46e08960dde790005d65a98440f313bcJosé Fonseca                                                bld.base.vec_type, array_size,
238510740acf46e08960dde790005d65a98440f313bcJosé Fonseca                                                "output_array");
238610740acf46e08960dde790005d65a98440f313bcJosé Fonseca   }
238710740acf46e08960dde790005d65a98440f313bcJosé Fonseca
2388f623d0c1c217d990f207306eb968172af79fa969Zack Rusin   /* If we have indirect addressing in inputs we need to copy them into
2389f623d0c1c217d990f207306eb968172af79fa969Zack Rusin    * our alloca array to be able to iterate over them */
2390f623d0c1c217d990f207306eb968172af79fa969Zack Rusin   if (bld.indirect_files & (1 << TGSI_FILE_INPUT)) {
2391f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      unsigned index, chan;
2392f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      LLVMTypeRef vec_type = bld.base.vec_type;
2393efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef array_size =
2394efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         lp_build_const_int32(gallivm, info->file_max[TGSI_FILE_INPUT]*4 + 4);
2395efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      bld.inputs_array = lp_build_array_alloca(gallivm,
2396f623d0c1c217d990f207306eb968172af79fa969Zack Rusin                                               vec_type, array_size,
2397f623d0c1c217d990f207306eb968172af79fa969Zack Rusin                                               "input_array");
2398f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
2399f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      assert(info->num_inputs <= info->file_max[TGSI_FILE_INPUT] + 1);
2400f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
2401f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      for (index = 0; index < info->num_inputs; ++index) {
2402f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         for (chan = 0; chan < NUM_CHANNELS; ++chan) {
2403efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            LLVMValueRef lindex =
2404efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul               lp_build_const_int32(gallivm, index * 4 + chan);
2405f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            LLVMValueRef input_ptr =
24066299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul               LLVMBuildGEP(gallivm->builder, bld.inputs_array,
2407f623d0c1c217d990f207306eb968172af79fa969Zack Rusin                            &lindex, 1, "");
2408f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            LLVMValueRef value = bld.inputs[index][chan];
2409f623d0c1c217d990f207306eb968172af79fa969Zack Rusin            if (value)
24106299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul               LLVMBuildStore(gallivm->builder, value, input_ptr);
2411f623d0c1c217d990f207306eb968172af79fa969Zack Rusin         }
2412f623d0c1c217d990f207306eb968172af79fa969Zack Rusin      }
2413f623d0c1c217d990f207306eb968172af79fa969Zack Rusin   }
2414f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
241563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   tgsi_parse_init( &parse, tokens );
241663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
241763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   while( !tgsi_parse_end_of_tokens( &parse ) ) {
241863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      tgsi_parse_token( &parse );
241963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
242063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      switch( parse.FullToken.Token.Type ) {
242163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_DECLARATION:
24221fc41002252419f4688c24ea8c3814553b3d76adJosé Fonseca         /* Inputs already interpolated */
2423e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         emit_declaration( &bld, &parse.FullToken.FullDeclaration );
242463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
242563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
242663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_INSTRUCTION:
2427faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         {
24280b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            /* save expanded instruction */
24290b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            if (num_instructions == bld.max_instructions) {
2430079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               struct tgsi_full_instruction *instructions;
2431079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               instructions = REALLOC(bld.instructions,
2432079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      bld.max_instructions
2433079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      * sizeof(struct tgsi_full_instruction),
2434079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      (bld.max_instructions + LP_MAX_INSTRUCTIONS)
2435079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                                      * sizeof(struct tgsi_full_instruction));
2436079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               if (!instructions) {
2437079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca                  break;
2438079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               }
2439079763f74648fef051ee5b8f7d730f7fc1ba27d5José Fonseca               bld.instructions = instructions;
24400b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin               bld.max_instructions += LP_MAX_INSTRUCTIONS;
24410b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            }
24420b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
24430b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            memcpy(bld.instructions + num_instructions,
24440b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                   &parse.FullToken.FullInstruction,
24450b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                   sizeof(bld.instructions[0]));
24460b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
24470b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            num_instructions++;
2448faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         }
2449faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
245063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
245163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
245263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_IMMEDIATE:
245363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         /* simply copy the immediate values into the next immediates[] slot */
245463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         {
245563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
245663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            assert(size <= 4);
24576c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca            assert(num_immediates < LP_MAX_TGSI_IMMEDIATES);
245863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            for( i = 0; i < size; ++i )
245963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               bld.immediates[num_immediates][i] =
2460efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                  lp_build_const_vec(gallivm, type, parse.FullToken.FullImmediate.u[i].Float);
246163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            for( i = size; i < 4; ++i )
246263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               bld.immediates[num_immediates][i] = bld.base.undef;
246363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            num_immediates++;
246463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
246563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
246663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
24679381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca      case TGSI_TOKEN_TYPE_PROPERTY:
24689381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca         break;
24699381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca
247063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      default:
247163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         assert( 0 );
247263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
247363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
24740b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
24750b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   while (pc != -1) {
24760b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      struct tgsi_full_instruction *instr = bld.instructions + pc;
24770b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      const struct tgsi_opcode_info *opcode_info =
24780b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         tgsi_get_opcode_info(instr->Instruction.Opcode);
24790b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      if (!emit_instruction( &bld, instr, opcode_info, &pc ))
24800b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
24810b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                       opcode_info->mnemonic);
24820b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
24830b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
2484528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   /* If we have indirect addressing in outputs we need to copy our alloca array
2485528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin    * to the outputs slots specified by the called */
2486528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   if (bld.indirect_files & (1 << TGSI_FILE_OUTPUT)) {
248710740acf46e08960dde790005d65a98440f313bcJosé Fonseca      unsigned index, chan;
248810740acf46e08960dde790005d65a98440f313bcJosé Fonseca      assert(info->num_outputs <= info->file_max[TGSI_FILE_OUTPUT] + 1);
248910740acf46e08960dde790005d65a98440f313bcJosé Fonseca      for (index = 0; index < info->num_outputs; ++index) {
249010740acf46e08960dde790005d65a98440f313bcJosé Fonseca         for (chan = 0; chan < NUM_CHANNELS; ++chan) {
249110740acf46e08960dde790005d65a98440f313bcJosé Fonseca            bld.outputs[index][chan] = get_output_ptr(&bld, index, chan);
2492528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         }
2493528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      }
2494528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   }
2495528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
249618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (0) {
2497efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder);
249818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef function = LLVMGetBasicBlockParent(block);
2499263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("11111111111111111111111111111 \n");
250018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      tgsi_dump(tokens, 0);
25018ad3e0b55df50beac8ba3c5cafa0be79641a4977José Fonseca      lp_debug_dump_value(function);
2502263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("2222222222222222222222222222 \n");
250318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   }
250463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   tgsi_parse_free( &parse );
25050b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
25060b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (0) {
25070b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMModuleRef module = LLVMGetGlobalParent(
25086299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         LLVMGetBasicBlockParent(LLVMGetInsertBlock(gallivm->builder)));
25090b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMDumpModule(module);
25100b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
25110b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
25120b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
25130b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   FREE( bld.instructions );
251463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
251563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2516