lp_bld_tgsi_soa.c revision 8690c6a6b4fb0b48e2ae75cd0f64de86b039081c
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"
524363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul#include "lp_bld_gather.h"
537821664b15501b173b2304bbada758c33c5ff972José Fonseca#include "lp_bld_logic.h"
5463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_swizzle.h"
553d7a88674f9eb3320eeff511968f041426e25023José Fonseca#include "lp_bld_flow.h"
56ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca#include "lp_bld_quad.h"
5763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_tgsi.h"
586c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca#include "lp_bld_limits.h"
5980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin#include "lp_bld_debug.h"
6063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define FOR_EACH_CHANNEL( CHAN )\
6363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)
6463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
665b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   ((INST)->Dst[0].Register.WriteMask & (1 << (CHAN)))
6763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
6963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   if (IS_DST0_CHANNEL_ENABLED( INST, CHAN ))
7063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
7163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\
7263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   FOR_EACH_CHANNEL( CHAN )\
7363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )
7463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
7563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_X 0
7663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_Y 1
7763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_Z 2
7863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#define CHAN_W 3
795a916204179c6787157af3f3be758dc36162ab20Keith Whitwell#define NUM_CHANNELS 4
8063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
810b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin#define LP_MAX_INSTRUCTIONS 256
820b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
8380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
8480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstruct lp_exec_mask {
8580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   struct lp_build_context *bld;
8680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
8780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   boolean has_mask;
8880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
8980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   LLVMTypeRef int_vec_type;
9080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
916c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING];
9280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   int cond_stack_size;
9380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   LLVMValueRef cond_mask;
9480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
952d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBasicBlockRef loop_block;
9618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef cont_mask;
972d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef break_mask;
982d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef break_var;
992d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   struct {
1002d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMBasicBlockRef loop_block;
1012d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMValueRef cont_mask;
1022d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMValueRef break_mask;
1032d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMValueRef break_var;
1042d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   } loop_stack[LP_MAX_TGSI_NESTING];
10518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   int loop_stack_size;
10618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
10732a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   LLVMValueRef ret_mask;
1080b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   struct {
1090b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      int pc;
1100b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMValueRef ret_mask;
1110b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   } call_stack[LP_MAX_TGSI_NESTING];
1120b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int call_stack_size;
1130b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
11480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   LLVMValueRef exec_mask;
11580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin};
11663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastruct lp_build_tgsi_soa_context
11863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
11963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_context base;
12063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
121ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   /* Builder for integer masks and indices */
122ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   struct lp_build_context int_bld;
123ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
12463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef consts_ptr;
125f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   const LLVMValueRef *pos;
126263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   const LLVMValueRef (*inputs)[NUM_CHANNELS];
127263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   LLVMValueRef (*outputs)[NUM_CHANNELS];
128c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca
1293f6dc8e79d918283a6dfcf9c8937a6d52f3bb4f5Brian Paul   const struct lp_build_sampler_soa *sampler;
13063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1316c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef immediates[LP_MAX_TGSI_IMMEDIATES][NUM_CHANNELS];
1326c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef temps[LP_MAX_TGSI_TEMPS][NUM_CHANNELS];
1336c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   LLVMValueRef addr[LP_MAX_TGSI_ADDRS][NUM_CHANNELS];
134ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef preds[LP_MAX_TGSI_PREDS][NUM_CHANNELS];
1351929057eac0c3351e0810612bdae56331a235736José Fonseca
1363662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
1373662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    * set in the indirect_files field.
1383662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    * The temps[] array above is unused then.
1393662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul    */
140021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   LLVMValueRef temps_array;
1413662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul
1423662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   /** bitmask indicating which register files are accessed indirectly */
1433662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   unsigned indirect_files;
144021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
1453d7a88674f9eb3320eeff511968f041426e25023José Fonseca   struct lp_build_mask_context *mask;
14680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   struct lp_exec_mask exec_mask;
1470b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1480b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   struct tgsi_full_instruction *instructions;
1490b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   uint max_instructions;
15063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca};
15163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
15280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld)
15380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
15480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->bld = bld;
15580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->has_mask = FALSE;
15680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack_size = 0;
15718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->loop_stack_size = 0;
1580b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size = 0;
15980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
16080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->int_vec_type = lp_build_int_vec_type(mask->bld->type);
16132a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->exec_mask = mask->ret_mask = mask->break_mask = mask->cont_mask = mask->cond_mask =
1622d91903882e399e8ea7306fd37d5d214907247e6José Fonseca         LLVMConstAllOnes(mask->int_vec_type);
16380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
16480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
16580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_update(struct lp_exec_mask *mask)
16680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
16718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (mask->loop_stack_size) {
16818a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin      /*for loops we need to update the entire mask at runtime */
16918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef tmp;
1707fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul      assert(mask->break_mask);
17118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      tmp = LLVMBuildAnd(mask->bld->builder,
17218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->cont_mask,
17318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->break_mask,
17418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         "maskcb");
17518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
17618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     mask->cond_mask,
17718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     tmp,
17818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     "maskfull");
17918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   } else
18018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      mask->exec_mask = mask->cond_mask;
18118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
18232a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   if (mask->call_stack_size) {
1830b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
1840b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     mask->exec_mask,
18532a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                     mask->ret_mask,
1860b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     "callmask");
18732a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   }
18818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
18918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->has_mask = (mask->cond_stack_size > 0 ||
1900b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->loop_stack_size > 0 ||
1910b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->call_stack_size > 0);
19280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
19380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
19480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
19580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                   LLVMValueRef val)
19680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
1976c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING);
1982d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 0) {
1992d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cond_mask == LLVMConstAllOnes(mask->int_vec_type));
2002d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
20180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask;
2022d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(LLVMTypeOf(val) == mask->int_vec_type);
2032d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cond_mask = val;
20480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
20580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
20680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
20780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
20880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_invert(struct lp_exec_mask *mask)
20980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2102d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef prev_mask;
2112d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef inv_mask;
2122d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2132d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
2142d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   prev_mask = mask->cond_stack[mask->cond_stack_size - 1];
2152d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 1) {
2162d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(prev_mask == LLVMConstAllOnes(mask->int_vec_type));
217faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin   }
218faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin
2192d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   inv_mask = LLVMBuildNot(mask->bld->builder, mask->cond_mask, "");
2202d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
22180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_mask = LLVMBuildAnd(mask->bld->builder,
22280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  inv_mask,
22380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  prev_mask, "");
22480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
22580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
22680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
22780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)
22880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2292d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
23080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_mask = mask->cond_stack[--mask->cond_stack_size];
23180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
23280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
23380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
23418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_bgnloop(struct lp_exec_mask *mask)
23518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
2362d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->loop_stack_size == 0) {
2372d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->loop_block == NULL);
2382d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cont_mask == LLVMConstAllOnes(mask->int_vec_type));
2392d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_mask == LLVMConstAllOnes(mask->int_vec_type));
2402d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_var == NULL);
2412d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
2422d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2432d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size < LP_MAX_TGSI_NESTING);
24418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2452d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].loop_block = mask->loop_block;
2462d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].cont_mask = mask->cont_mask;
2472d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_mask = mask->break_mask;
2482d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_var = mask->break_var;
2492d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   ++mask->loop_stack_size;
2503a423dcf9dfa725a4e5dca60f0f2b02599d2ed9bZack Rusin
2512d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_var = lp_build_alloca(mask->bld->builder, mask->int_vec_type, "");
2522d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
2536c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca
25418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->loop_block = lp_build_insert_new_block(mask->bld->builder, "bgnloop");
25518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBuildBr(mask->bld->builder, mask->loop_block);
25618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block);
25718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2582d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_mask = LLVMBuildLoad(mask->bld->builder, mask->break_var, "");
2592d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
26018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
26118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
26218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
26318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_break(struct lp_exec_mask *mask)
26418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
26518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
26618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
26718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "break");
26818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
269d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin   mask->break_mask = LLVMBuildAnd(mask->bld->builder,
270d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   mask->break_mask,
271d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   exec_mask, "break_full");
27218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
27318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
27418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
27518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
27618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_continue(struct lp_exec_mask *mask)
27718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
27818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
27918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
28018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "");
28118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
282d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin   mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
283d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  mask->cont_mask,
284d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  exec_mask, "");
28518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
28618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
28718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
28818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
28918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
29018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_endloop(struct lp_exec_mask *mask)
29118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
29218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBasicBlockRef endloop;
293d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca   LLVMTypeRef reg_type = LLVMIntType(mask->bld->type.width*
294d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca                                      mask->bld->type.length);
2957fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   LLVMValueRef i1cond;
2967fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
2977fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   assert(mask->break_mask);
2987fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
2992d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
3002d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Restore the cont_mask, but don't pop
3012d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
3022d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
3032d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size - 1].cont_mask;
3042d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   lp_exec_mask_update(mask);
3052d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
3062d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
3072d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Unlike the continue mask, the break_mask must be preserved across loop
3082d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * iterations
3092d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
3102d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
3112d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
312d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca   /* i1cond = (mask == 0) */
3137fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   i1cond = LLVMBuildICmp(
314d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      mask->bld->builder,
315d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMIntNE,
3162d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMBuildBitCast(mask->bld->builder, mask->exec_mask, reg_type, ""),
317d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMConstNull(reg_type), "");
31818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
31918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   endloop = lp_build_insert_new_block(mask->bld->builder, "endloop");
32018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
32118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBuildCondBr(mask->bld->builder,
322ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                   i1cond, mask->loop_block, endloop);
32318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
32418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMPositionBuilderAtEnd(mask->bld->builder, endloop);
32518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
3262d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
3272d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   --mask->loop_stack_size;
3282d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_block = mask->loop_stack[mask->loop_stack_size].loop_block;
3292d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size].cont_mask;
3302d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_mask = mask->loop_stack[mask->loop_stack_size].break_mask;
3312d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_var = mask->loop_stack[mask->loop_stack_size].break_var;
33218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
33318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
33418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
33518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
33618a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin/* stores val into an address pointed to by dst.
33718a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * mask->exec_mask is used to figure out which bits of val
33818a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * should be stored into the address
33918a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * (0 means don't store this bit, 1 means do store).
34018a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin */
34180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_store(struct lp_exec_mask *mask,
342ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                               LLVMValueRef pred,
34380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef val,
34480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef dst)
34580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
346ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   /* Mix the predicate and execution mask */
34780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   if (mask->has_mask) {
348ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (pred) {
34954b94ee96a6d750d57d99ae9819fcf8206d4680dJosé Fonseca         pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, "");
350ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
351ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred = mask->exec_mask;
352ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
353ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
354ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
355ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (pred) {
35680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMValueRef real_val, dst_val;
35780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
35880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      dst_val = LLVMBuildLoad(mask->bld->builder, dst, "");
35980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      real_val = lp_build_select(mask->bld,
360ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                 pred,
36180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                 val, dst_val);
36280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
36380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMBuildStore(mask->bld->builder, real_val, dst);
36480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   } else
36580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMBuildStore(mask->bld->builder, val, dst);
36680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
36780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
3680b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_call(struct lp_exec_mask *mask,
3690b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int func,
3700b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int *pc)
3710b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
37232a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size < LP_MAX_TGSI_NESTING);
3730b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack[mask->call_stack_size].pc = *pc;
37432a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack[mask->call_stack_size].ret_mask = mask->ret_mask;
37532a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack_size++;
3760b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = func;
3770b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
3780b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3790b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
3800b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
3810b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   LLVMValueRef exec_mask;
38232a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca
3830b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (mask->call_stack_size == 0) {
3840b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      /* returning from main() */
3850b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
3860b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
3870b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
3880b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   exec_mask = LLVMBuildNot(mask->bld->builder,
3890b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            mask->exec_mask,
3900b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            "ret");
3910b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
39232a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->ret_mask = LLVMBuildAnd(mask->bld->builder,
39332a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 mask->ret_mask,
39432a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 exec_mask, "ret_full");
3950b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3960b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   lp_exec_mask_update(mask);
3970b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
3980b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3990b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_bgnsub(struct lp_exec_mask *mask)
4000b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
4010b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
4020b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
4030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
4040b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
40532a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size);
4060b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size--;
4070b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = mask->call_stack[mask->call_stack_size].pc;
40832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->ret_mask = mask->call_stack[mask->call_stack_size].ret_mask;
40932a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   lp_exec_mask_update(mask);
4100b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
41186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
412695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul
413695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul/**
414695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * Return pointer to a temporary register channel (src or dest).
415f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul * Note that indirect addressing cannot be handled here.
416695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param index  which temporary register
417695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param chan  which channel of the temp register.
418695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul */
41986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic LLVMValueRef
420263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonsecaget_temp_ptr(struct lp_build_tgsi_soa_context *bld,
421263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca             unsigned index,
422f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul             unsigned chan)
423263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca{
424263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   assert(chan < 4);
4253662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
426f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan);
427263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      return LLVMBuildGEP(bld->base.builder, bld->temps_array, &lindex, 1, "");
428263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   }
429695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   else {
430695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul      return bld->temps[index][chan];
431695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   }
432263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca}
433263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca
4344363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4354363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul/**
4364363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * Gather vector.
4374363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * XXX the lp_build_gather() function should be capable of doing this
4384363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * with a little work.
4394363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul */
4404363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulstatic LLVMValueRef
4414363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulbuild_gather(struct lp_build_tgsi_soa_context *bld,
4424363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef base_ptr,
4434363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef indexes)
4444363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul{
4454363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   LLVMValueRef res = bld->base.undef;
4464363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   unsigned i;
4474363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4484363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   /*
4494363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    * Loop over elements of index_vec, load scalar value, insert it into 'res'.
4504363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    */
4514363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   for (i = 0; i < bld->base.type.length; i++) {
4524363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0);
4534363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef index = LLVMBuildExtractElement(bld->base.builder,
4544363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                                   indexes, ii, "");
4554363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, base_ptr,
4564363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                             &index, 1, "");
4574363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
4584363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4594363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      res = LLVMBuildInsertElement(bld->base.builder, res, scalar, ii, "");
4604363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   }
4614363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4624363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   return res;
4634363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul}
4644363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4654363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
46663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
4670115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * Read the current value of the ADDR register, convert the floats to
4680115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * ints, multiply by four and return the vector of offsets.
4690115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * The offsets will be used to index into the constant buffer or
4700115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * temporary register file.
4710115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul */
4720115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paulstatic LLVMValueRef
4730115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paulget_indirect_offsets(struct lp_build_tgsi_soa_context *bld,
4740115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul                     const struct tgsi_src_register *indirect_reg)
4750115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul{
4760115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* always use X component of address register */
4770115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   const int x = indirect_reg->SwizzleX;
4780115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type);
4790115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   uint swizzle = tgsi_util_get_src_register_swizzle(indirect_reg, x);
4800115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   LLVMValueRef vec4 = lp_build_const_int_vec(bld->int_bld.type, 4);
4810115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   LLVMValueRef addr_vec;
4820115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
4830115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   addr_vec = LLVMBuildLoad(bld->base.builder,
4840115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul                            bld->addr[indirect_reg->Index][swizzle],
4850115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul                            "load addr reg");
4860115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
4870115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* for indexing we want integers */
4880115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   addr_vec = LLVMBuildFPToSI(bld->base.builder, addr_vec,
4890115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul                              int_vec_type, "");
4900115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
4910115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* addr_vec = addr_vec * 4 */
49212f5c0f9ce497e99854e0a3a7f5ff297a2a0a1e3José Fonseca   addr_vec = lp_build_mul(&bld->int_bld, addr_vec, vec4);
4930115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
4940115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   return addr_vec;
4950115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul}
4960115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
4970115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
4980115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul/**
49963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register fetch.
50063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
50163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic LLVMValueRef
50263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_fetch(
50363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
5042fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   const struct tgsi_full_instruction *inst,
505ec0e7b16bb6753bedbd611a97062934bfca03aa7Brian Paul   unsigned src_op,
50663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const unsigned chan_index )
50763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
508ec0e7b16bb6753bedbd611a97062934bfca03aa7Brian Paul   const struct tgsi_full_src_register *reg = &inst->Src[src_op];
50985c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   const unsigned swizzle =
51085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      tgsi_util_get_full_src_register_swizzle(reg, chan_index);
51163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef res;
5124363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   LLVMValueRef addr_vec = NULL;
51363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
51485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (swizzle > 3) {
51585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(0 && "invalid swizzle in emit_fetch()");
51685c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      return bld->base.undef;
51785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
51885c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul
51985c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (reg->Register.Indirect) {
5203662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul      assert(bld->indirect_files);
5210115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul      addr_vec = get_indirect_offsets(bld, &reg->Indirect);
52285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
523ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
52485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   switch (reg->Register.File) {
52585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_CONSTANT:
526be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      if (reg->Register.Indirect) {
527be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef index_vec;  /* index into the const buffer */
5284363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5293662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul         assert(bld->indirect_files & (1 << TGSI_FILE_CONSTANT));
5303662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul
531be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         /* index_vec = broadcast(reg->Register.Index * 4 + swizzle) */
532be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         index_vec = lp_build_const_int_vec(bld->int_bld.type,
533be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul                                            reg->Register.Index * 4 + swizzle);
5344363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
535be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         /* index_vec = index_vec + addr_vec */
536cd5af8c703d84dd856528554fa615e9787ebe75fnobled         index_vec = lp_build_add(&bld->int_bld, index_vec, addr_vec);
5374363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
538be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         /* Gather values from the constant buffer */
539be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         res = build_gather(bld, bld->consts_ptr, index_vec);
540be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      }
541be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul      else {
542be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef index;  /* index into the const buffer */
543be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         LLVMValueRef scalar, scalar_ptr;
544ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
545be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         index = lp_build_const_int32(reg->Register.Index*4 + swizzle);
5464363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
547be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
548be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul                                   &index, 1, "");
549be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
5504363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
551be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul         res = lp_build_broadcast_scalar(&bld->base, scalar);
55263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
55385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
55463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
55585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_IMMEDIATE:
556263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      res = bld->immediates[reg->Register.Index][swizzle];
55785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(res);
55885c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
55963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
56085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_INPUT:
561263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      res = bld->inputs[reg->Register.Index][swizzle];
56285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(res);
56385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
56463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
56585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_TEMPORARY:
566105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      if (reg->Register.Indirect) {
567105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef vec_len =
568105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul            lp_build_const_int_vec(bld->int_bld.type, bld->base.type.length);
569105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef index_vec;  /* index into the const buffer */
570105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef temps_array;
571105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMTypeRef float4_ptr_type;
5724363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5733662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul         assert(bld->indirect_files & (1 << TGSI_FILE_TEMPORARY));
574105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
575105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* index_vec = broadcast(reg->Register.Index * 4 + swizzle) */
576105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         index_vec = lp_build_const_int_vec(bld->int_bld.type,
577105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul                                            reg->Register.Index * 4 + swizzle);
5784363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
579105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* index_vec += addr_vec */
580105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         index_vec = lp_build_add(&bld->int_bld, index_vec, addr_vec);
581105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
582105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* index_vec *= vector_length */
583105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         index_vec = lp_build_mul(&bld->int_bld, index_vec, vec_len);
584105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
585105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* cast temps_array pointer to float* */
586105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
587105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         temps_array = LLVMBuildBitCast(bld->int_bld.builder, bld->temps_array,
588105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul                                        float4_ptr_type, "");
589105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
590105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* Gather values from the temporary register array */
591105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         res = build_gather(bld, temps_array, index_vec);
592105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      }
593105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      else {
594105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef temp_ptr;
595f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         temp_ptr = get_temp_ptr(bld, reg->Register.Index, swizzle);
596021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin         res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
597105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         if (!res)
59863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            return bld->base.undef;
59963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
60063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
60163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
60263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
60385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(0 && "invalid src register in emit_fetch()");
6044d7a8194c5763f70ba559f32f58dfda36237b666José Fonseca      return bld->base.undef;
60563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
60663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
60763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) {
60863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_CLEAR:
60963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = lp_build_abs( &bld->base, res );
61063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
61163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
61263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_SET:
6131fc41002252419f4688c24ea8c3814553b3d76adJosé Fonseca      /* TODO: Use bitwese OR for floating point */
61463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = lp_build_abs( &bld->base, res );
615fc9a49b638c26801951c33a570178bbb2b67ec60nobled      /* fall through */
61663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_TOGGLE:
6178a3a971743a90463e65b44f1769a5301a31ce4cdJosé Fonseca      res = lp_build_negate( &bld->base, res );
61863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
61963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
62063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_KEEP:
62163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
62263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
62363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
62463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   return res;
62563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
62663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
62763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
62863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
62986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca * Register fetch with derivatives.
63086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca */
63186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic void
63286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecaemit_fetch_deriv(
63386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   struct lp_build_tgsi_soa_context *bld,
63486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   const struct tgsi_full_instruction *inst,
63586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   unsigned index,
63686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   const unsigned chan_index,
63786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *res,
63886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddx,
63986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddy)
64086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca{
64186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef src;
64286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
64386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   src = emit_fetch(bld, inst, index, chan_index);
64486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
64586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(res)
64686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      *res = src;
64786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
64886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   /* TODO: use interpolation coeffs for inputs */
64986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
65086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddx)
651ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca      *ddx = lp_build_ddx(&bld->base, src);
65286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
65386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddy)
654ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca      *ddy = lp_build_ddy(&bld->base, src);
65586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca}
65686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
65786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
65886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca/**
659ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca * Predicate.
660ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca */
661ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecastatic void
662ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecaemit_fetch_predicate(
663ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
664ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   const struct tgsi_full_instruction *inst,
665ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef *pred)
666ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca{
667ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned index;
668ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned char swizzles[4];
669ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef unswizzled[4] = {NULL, NULL, NULL, NULL};
670ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef value;
671ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned chan;
672ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
673ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (!inst->Instruction.Predicate) {
674ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      FOR_EACH_CHANNEL( chan ) {
675ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred[chan] = NULL;
676ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
677ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      return;
678ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
679ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
680ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[0] = inst->Predicate.SwizzleX;
681ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[1] = inst->Predicate.SwizzleY;
682ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[2] = inst->Predicate.SwizzleZ;
683ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[3] = inst->Predicate.SwizzleW;
684ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
685ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   index = inst->Predicate.Index;
686ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   assert(index < LP_MAX_TGSI_PREDS);
687ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
688ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   FOR_EACH_CHANNEL( chan ) {
689ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      unsigned swizzle = swizzles[chan];
690ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
691ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      /*
692ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * Only fetch the predicate register channels that are actually listed
693ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * in the swizzles
694ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       */
695ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (!unswizzled[swizzle]) {
696ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = LLVMBuildLoad(bld->base.builder,
697263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                               bld->preds[index][swizzle], "");
698ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
699ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         /*
700ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * Convert the value to an integer mask.
701ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          *
702ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * TODO: Short-circuit this comparison -- a D3D setp_xx instructions
703ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * is needlessly causing two comparisons due to storing the intermediate
704ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * result as float vector instead of an integer mask vector.
705ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          */
706ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = lp_build_compare(bld->base.builder,
707ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  bld->base.type,
708ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  PIPE_FUNC_NOTEQUAL,
709ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  value,
710ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  bld->base.zero);
711ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         if (inst->Predicate.Negate) {
712ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca            value = LLVMBuildNot(bld->base.builder, value, "");
713ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         }
714ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
715ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         unswizzled[swizzle] = value;
716ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
717ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = unswizzled[swizzle];
718ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
719ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
720ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      pred[chan] = value;
721ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
722ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca}
723ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
724ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
725ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca/**
72663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register store.
72763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
72863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
72963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_store(
73063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
73163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const struct tgsi_full_instruction *inst,
7322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   unsigned index,
73363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index,
734ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef pred,
73563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef value)
73663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
7377d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_dst_register *reg = &inst->Dst[index];
738415c40735dfd110bf902ce43968c8d7bd23ff111Brian Paul   LLVMValueRef addr = NULL;
7392fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca
74063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( inst->Instruction.Saturate ) {
74163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_NONE:
74263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
74363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
74463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_ZERO_ONE:
7457926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_max(&bld->base, value, bld->base.zero);
7467926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_min(&bld->base, value, bld->base.one);
74763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
74863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
74963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_MINUS_PLUS_ONE:
750185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul      value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.type, -1.0));
7517926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_min(&bld->base, value, bld->base.one);
75263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
7537926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca
7547926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca   default:
7557926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      assert(0);
75663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
75763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
758021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   if (reg->Register.Indirect) {
7590115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul      /* XXX use get_indirect_offsets() here eventually */
760021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type);
761021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      unsigned swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, chan_index );
7623662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul
7633662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul      assert(bld->indirect_files);
7643662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul
765021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      addr = LLVMBuildLoad(bld->base.builder,
766263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                           bld->addr[reg->Indirect.Index][swizzle],
767021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                           "");
768021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      /* for indexing we want integers */
769021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      addr = LLVMBuildFPToSI(bld->base.builder, addr,
770021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                             int_vec_type, "");
771021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      addr = LLVMBuildExtractElement(bld->base.builder,
772021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                                     addr, LLVMConstInt(LLVMInt32Type(), 0, 0),
773021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                                     "");
77412f5c0f9ce497e99854e0a3a7f5ff297a2a0a1e3José Fonseca      addr = LLVMBuildMul(bld->base.builder,
77512f5c0f9ce497e99854e0a3a7f5ff297a2a0a1e3José Fonseca                          addr, LLVMConstInt(LLVMInt32Type(), 4, 0),
77612f5c0f9ce497e99854e0a3a7f5ff297a2a0a1e3José Fonseca                          "");
777021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   }
778021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
7795b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   switch( reg->Register.File ) {
78063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_OUTPUT:
781ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
782263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                         bld->outputs[reg->Register.Index][chan_index]);
78363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
78463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
785f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul   case TGSI_FILE_TEMPORARY:
786f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      if (reg->Register.Indirect) {
787f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         /* XXX not done yet */
788f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         debug_printf("WARNING: LLVM scatter store of temp regs"
789f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul                      " not implemented\n");
790f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
791f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      else {
792f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
793f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul                                              chan_index);
794f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr);
795f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
79663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
79763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
79863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_ADDRESS:
799ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
800263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                         bld->addr[reg->Indirect.Index][chan_index]);
80163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
80263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
803ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca   case TGSI_FILE_PREDICATE:
804ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
8058690c6a6b4fb0b48e2ae75cd0f64de86b039081cmichal                         bld->preds[reg->Register.Index][chan_index]);
806ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca      break;
807ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca
80863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
80963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert( 0 );
81063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
81163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
81263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
81363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
81463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
81563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * High-level instruction translators.
81663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
81763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
818962558daaed43b0111cd062e32821aad106869d7José Fonsecaenum tex_modifier {
819962558daaed43b0111cd062e32821aad106869d7José Fonseca   TEX_MODIFIER_NONE = 0,
820962558daaed43b0111cd062e32821aad106869d7José Fonseca   TEX_MODIFIER_PROJECTED,
821962558daaed43b0111cd062e32821aad106869d7José Fonseca   TEX_MODIFIER_LOD_BIAS,
822962558daaed43b0111cd062e32821aad106869d7José Fonseca   TEX_MODIFIER_EXPLICIT_LOD,
823962558daaed43b0111cd062e32821aad106869d7José Fonseca   TEX_MODIFIER_EXPLICIT_DERIV
824962558daaed43b0111cd062e32821aad106869d7José Fonseca};
82586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
82663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
82763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_tex( struct lp_build_tgsi_soa_context *bld,
82863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca          const struct tgsi_full_instruction *inst,
829962558daaed43b0111cd062e32821aad106869d7José Fonseca          enum tex_modifier modifier,
830faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca          LLVMValueRef *texel)
83163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
832962558daaed43b0111cd062e32821aad106869d7José Fonseca   unsigned unit;
833ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   LLVMValueRef lod_bias, explicit_lod;
83431d1822473bf9d4105bb82b67572cfeea53aaf94Vinson Lee   LLVMValueRef oow = NULL;
835c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   LLVMValueRef coords[3];
836962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddx[3];
837962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddy[3];
838c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   unsigned num_coords;
83963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
84063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
8419db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   if (!bld->sampler) {
8429db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
8439db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      for (i = 0; i < 4; i++) {
8449db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca         texel[i] = bld->base.undef;
8459db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      }
8469db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      return;
8479db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   }
8489db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca
8497d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   switch (inst->Texture.Texture) {
85063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_1D:
851c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 1;
85263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
85363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_2D:
85463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_RECT:
855c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 2;
85663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
857f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW1D:
858f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW2D:
859f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOWRECT:
86063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_3D:
86163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_CUBE:
862c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 3;
86363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
86463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
86563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert(0);
86663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      return;
86763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
86863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
869ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   if (modifier == TEX_MODIFIER_LOD_BIAS) {
870ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = emit_fetch( bld, inst, 0, 3 );
871ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
872ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
873ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   else if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
874ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
875ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = emit_fetch( bld, inst, 0, 3 );
876ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
877ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   else {
878ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
879ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
880ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
88163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
882962558daaed43b0111cd062e32821aad106869d7José Fonseca   if (modifier == TEX_MODIFIER_PROJECTED) {
8832fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      oow = emit_fetch( bld, inst, 0, 3 );
88463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      oow = lp_build_rcp(&bld->base, oow);
88563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
88663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
887c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   for (i = 0; i < num_coords; i++) {
888c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      coords[i] = emit_fetch( bld, inst, 0, i );
889962558daaed43b0111cd062e32821aad106869d7José Fonseca      if (modifier == TEX_MODIFIER_PROJECTED)
890c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca         coords[i] = lp_build_mul(&bld->base, coords[i], oow);
89163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
892ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   for (i = num_coords; i < 3; i++) {
893ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca      coords[i] = bld->base.undef;
894ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   }
89563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
896962558daaed43b0111cd062e32821aad106869d7José Fonseca   if (modifier == TEX_MODIFIER_EXPLICIT_DERIV) {
897962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
898962558daaed43b0111cd062e32821aad106869d7José Fonseca         ddx[i] = emit_fetch( bld, inst, 1, i );
899962558daaed43b0111cd062e32821aad106869d7José Fonseca         ddy[i] = emit_fetch( bld, inst, 2, i );
900962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
901962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[3].Register.Index;
902962558daaed43b0111cd062e32821aad106869d7José Fonseca   }  else {
903962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
904ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca         ddx[i] = lp_build_ddx( &bld->base, coords[i] );
905ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca         ddy[i] = lp_build_ddy( &bld->base, coords[i] );
906962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
907962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[1].Register.Index;
908962558daaed43b0111cd062e32821aad106869d7José Fonseca   }
9094554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   for (i = num_coords; i < 3; i++) {
9104554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca      ddx[i] = bld->base.undef;
9114554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca      ddy[i] = bld->base.undef;
9124554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   }
913962558daaed43b0111cd062e32821aad106869d7José Fonseca
9148be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld->sampler->emit_fetch_texel(bld->sampler,
9158be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  bld->base.builder,
9168be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  bld->base.type,
917962558daaed43b0111cd062e32821aad106869d7José Fonseca                                  unit, num_coords, coords,
918ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  ddx, ddy,
919ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  lod_bias, explicit_lod,
9208be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  texel);
92163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
92263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
92363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
924feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul/**
925feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Kill fragment if any of the src register values are negative.
926feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
92763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
92863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_kil(
92963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
9302fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   const struct tgsi_full_instruction *inst )
93163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
9327d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_src_register *reg = &inst->Src[0];
9337821664b15501b173b2304bbada758c33c5ff972José Fonseca   LLVMValueRef terms[NUM_CHANNELS];
9343d7a88674f9eb3320eeff511968f041426e25023José Fonseca   LLVMValueRef mask;
93563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
93663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
9377821664b15501b173b2304bbada758c33c5ff972José Fonseca   memset(&terms, 0, sizeof terms);
93863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
93963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   FOR_EACH_CHANNEL( chan_index ) {
94063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      unsigned swizzle;
94163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
9427821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Unswizzle channel */
943b9cb74c7f826dfd320f5e5b54aa933898f7ddd3dKeith Whitwell      swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
94463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
9457821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Check if the component has not been already tested. */
9467821664b15501b173b2304bbada758c33c5ff972José Fonseca      assert(swizzle < NUM_CHANNELS);
9477821664b15501b173b2304bbada758c33c5ff972José Fonseca      if( !terms[swizzle] )
9487821664b15501b173b2304bbada758c33c5ff972José Fonseca         /* TODO: change the comparison operator instead of setting the sign */
9492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         terms[swizzle] =  emit_fetch(bld, inst, 0, chan_index );
95063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
95163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
9523d7a88674f9eb3320eeff511968f041426e25023José Fonseca   mask = NULL;
9537821664b15501b173b2304bbada758c33c5ff972José Fonseca   FOR_EACH_CHANNEL( chan_index ) {
954aede39efd86d200ffbace8fc012104e31f673973José Fonseca      if(terms[chan_index]) {
9553d7a88674f9eb3320eeff511968f041426e25023José Fonseca         LLVMValueRef chan_mask;
956aede39efd86d200ffbace8fc012104e31f673973José Fonseca
957feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul         /*
958feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          * If term < 0 then mask = 0 else mask = ~0.
959feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          */
9603d7a88674f9eb3320eeff511968f041426e25023José Fonseca         chan_mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero);
961aede39efd86d200ffbace8fc012104e31f673973José Fonseca
9623d7a88674f9eb3320eeff511968f041426e25023José Fonseca         if(mask)
9633d7a88674f9eb3320eeff511968f041426e25023José Fonseca            mask = LLVMBuildAnd(bld->base.builder, mask, chan_mask, "");
9643d7a88674f9eb3320eeff511968f041426e25023José Fonseca         else
9653d7a88674f9eb3320eeff511968f041426e25023José Fonseca            mask = chan_mask;
966aede39efd86d200ffbace8fc012104e31f673973José Fonseca      }
96763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
9683d7a88674f9eb3320eeff511968f041426e25023José Fonseca
9693d7a88674f9eb3320eeff511968f041426e25023José Fonseca   if(mask)
9703d7a88674f9eb3320eeff511968f041426e25023José Fonseca      lp_build_mask_update(bld->mask, mask);
97163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
97263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
97363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
97463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
975feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Predicated fragment kill.
976feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * XXX Actually, we do an unconditional kill (as in tgsi_exec.c).
977feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * The only predication is the execution mask which will apply if
978feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * we're inside a loop or conditional.
979feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
980feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulstatic void
981feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulemit_kilp(struct lp_build_tgsi_soa_context *bld,
982feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          const struct tgsi_full_instruction *inst)
983feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul{
984feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   LLVMValueRef mask;
985feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
986feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   /* For those channels which are "alive", disable fragment shader
987feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    * execution.
988feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    */
989feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   if (bld->exec_mask.has_mask) {
990feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul      mask = LLVMBuildNot(bld->base.builder, bld->exec_mask.exec_mask, "kilp");
991feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
992feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   else {
993feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul      mask = bld->base.zero;
994feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
995feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
996feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   lp_build_mask_update(bld->mask, mask);
997feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul}
998feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
999e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonsecastatic void
100085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusinemit_declaration(
100185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   struct lp_build_tgsi_soa_context *bld,
100285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   const struct tgsi_full_declaration *decl)
100385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin{
1004a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca   LLVMTypeRef vec_type = lp_build_vec_type(bld->base.type);
1005a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca
100685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned first = decl->Range.First;
100785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned last = decl->Range.Last;
100885c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned idx, i;
100985c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
101085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   for (idx = first; idx <= last; ++idx) {
101185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      switch (decl->Declaration.File) {
101285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_TEMPORARY:
10136c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_TEMPS);
10143662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul         if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
1015846b2fccc2a67b08acc6da51f4970fe66ed4559bBrian Paul            LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
1016846b2fccc2a67b08acc6da51f4970fe66ed4559bBrian Paul                                                   last*4 + 4, 0);
1017263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->temps_array = lp_build_array_alloca(bld->base.builder,
1018846b2fccc2a67b08acc6da51f4970fe66ed4559bBrian Paul                                                     vec_type, array_size, "");
1019263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         } else {
1020021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin            for (i = 0; i < NUM_CHANNELS; i++)
1021a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca               bld->temps[idx][i] = lp_build_alloca(bld->base.builder,
1022a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca                                                    vec_type, "");
1023021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin         }
102485c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
102585c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
102685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_OUTPUT:
1027263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1028263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->outputs[idx][i] = lp_build_alloca(bld->base.builder,
1029263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                                                   vec_type, "");
103085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
103185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
1032ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin      case TGSI_FILE_ADDRESS:
10336c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_ADDRS);
1034263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1035263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->addr[idx][i] = lp_build_alloca(bld->base.builder,
1036263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                                                vec_type, "");
1037ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         break;
1038ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
1039e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca      case TGSI_FILE_PREDICATE:
1040ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         assert(idx < LP_MAX_TGSI_PREDS);
1041263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1042263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->preds[idx][i] = lp_build_alloca(bld->base.builder,
1043263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                                                 vec_type, "");
1044e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         break;
1045e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca
104685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      default:
104785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         /* don't need to declare other vars */
1048dc886ba1391d7d890bd1f5532bc14553e883a418Zack Rusin         break;
1049012fabca722494162c244a367913562b8cfa4677Zack Rusin      }
105085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   }
105185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin}
105263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1053fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul
1054fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul/**
1055fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul * Emit LLVM for one TGSI instruction.
1056fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul * \param return TRUE for success, FALSE otherwise
1057fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul */
1058fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paulstatic boolean
105963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_instruction(
106063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
1061faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   const struct tgsi_full_instruction *inst,
10620b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   const struct tgsi_opcode_info *info,
10630b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int *pc)
106463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
106563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
106690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   LLVMValueRef src0, src1, src2;
1067e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp0, tmp1, tmp2;
1068e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp3 = NULL;
1069e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp4 = NULL;
1070e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp5 = NULL;
1071e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp6 = NULL;
1072e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp7 = NULL;
1073faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   LLVMValueRef res;
1074faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   LLVMValueRef dst0[NUM_CHANNELS];
107563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
107689258652b6a1d282bed14549907892bdfda752f0José Fonseca   /*
107789258652b6a1d282bed14549907892bdfda752f0José Fonseca    * Stores and write masks are handled in a general fashion after the long
107889258652b6a1d282bed14549907892bdfda752f0José Fonseca    * instruction opcode switch statement.
107989258652b6a1d282bed14549907892bdfda752f0José Fonseca    *
108089258652b6a1d282bed14549907892bdfda752f0José Fonseca    * Although not stricitly necessary, we avoid generating instructions for
108189258652b6a1d282bed14549907892bdfda752f0José Fonseca    * channels which won't be stored, in cases where's that easy. For some
108289258652b6a1d282bed14549907892bdfda752f0José Fonseca    * complex instructions, like texture sampling, it is more convenient to
108389258652b6a1d282bed14549907892bdfda752f0José Fonseca    * assume a full writemask and then let LLVM optimization passes eliminate
108489258652b6a1d282bed14549907892bdfda752f0José Fonseca    * redundant code.
108589258652b6a1d282bed14549907892bdfda752f0José Fonseca    */
108689258652b6a1d282bed14549907892bdfda752f0José Fonseca
10870b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   (*pc)++;
10880b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1089faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   assert(info->num_dst <= 1);
1090ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (info->num_dst) {
1091faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1092faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.undef;
1093faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
1094faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
1095faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
109663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch (inst->Instruction.Opcode) {
109763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARL:
10982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
10992fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1100ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         tmp0 = lp_build_floor(&bld->base, tmp0);
1101faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
110263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
110363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
110463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
110563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MOV:
11062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1107faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = emit_fetch( bld, inst, 0, chan_index );
110863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
110963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
111063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
111163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LIT:
11122fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ) {
1113faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = bld->base.one;
111463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
11152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
11162fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
1117faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_max( &bld->base, src0, bld->base.zero);
1118ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca      }
11192fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
1120ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[1] = SrcReg[0].yyyy */
11212fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
1122ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[1] = max(XMM[1], 0) */
1123ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         tmp1 = lp_build_max( &bld->base, tmp1, bld->base.zero);
1124ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[2] = SrcReg[0].wwww */
11252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 0, CHAN_W );
1126ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         tmp1 = lp_build_pow( &bld->base, tmp1, tmp2);
11272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1128c5abcac7ef7ebd0167093285b5fc9cf3829c1febJosé Fonseca         tmp2 = lp_build_cmp(&bld->base, PIPE_FUNC_GREATER, tmp0, bld->base.zero);
1129faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = lp_build_select(&bld->base, tmp2, tmp1, bld->base.zero);
1130c5abcac7ef7ebd0167093285b5fc9cf3829c1febJosé Fonseca      }
11312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) ) {
1132faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
113363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
113463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
113563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
113663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RCP:
113763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_RECIP */
11382fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
1139faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_rcp(&bld->base, src0);
11402fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1141faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
114263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
114363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
114463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
114563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RSQ:
114663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_RECIPSQRT */
11472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
114890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      src0 = lp_build_abs(&bld->base, src0);
1149faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_rsqrt(&bld->base, src0);
11502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1151faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
115263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
115363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
115463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
115563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_EXP:
11562fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
11572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
11582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
115957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_exp2_int_part = NULL;
116057907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_frac_part = NULL;
116157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_exp2 = NULL;
116257907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
11632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
116457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
11652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
116657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp2_int_part = &tmp0;
11672fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
116857907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_frac_part = &tmp1;
11692fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
117057907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp2 = &tmp2;
117157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
117257907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         lp_build_exp2_approx(&bld->base, src0, p_exp2_int_part, p_frac_part, p_exp2);
117357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
11742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
1175faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_X] = tmp0;
11762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
1177faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Y] = tmp1;
11782fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
1179faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Z] = tmp2;
118063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
118163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* dst.w = 1.0 */
11822fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
1183faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
118463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
118563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
118663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
118763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LOG:
11882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
11892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
11902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
1191add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_floor_log2 = NULL;
1192add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_exp = NULL;
1193add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_log2 = NULL;
119457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
11952fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
119657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         src0 = lp_build_abs( &bld->base, src0 );
119757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
11982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
119957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_floor_log2 = &tmp0;
12002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
120157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp = &tmp1;
12022fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
120357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_log2 = &tmp2;
120457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
120557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         lp_build_log2_approx(&bld->base, src0, p_exp, p_floor_log2, p_log2);
120657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
120757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.x = floor(lg2(abs(src.x))) */
12082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
1209faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_X] = tmp0;
121057907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.y = abs(src)/ex2(floor(lg2(abs(src.x)))) */
12112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y )) {
1212faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Y] = lp_build_div( &bld->base, src0, tmp1);
121363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
121457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.z = lg2(abs(src.x)) */
12152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
1216faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Z] = tmp2;
121763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
121863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* dst.w = 1.0 */
12192fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
1220faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
122163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
122263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
122363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
122463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MUL:
12252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
12262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
12272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1228faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_mul(&bld->base, src0, src1);
122963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
123063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
123163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
123263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ADD:
12332fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
12342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
12352fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1236faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_add(&bld->base, src0, src1);
123763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
123863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
123963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
124063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP3:
124163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_DOT3 */
12422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
12432fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
124490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
12452fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
12462fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
124790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
124890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
12492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
12502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
125190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
125290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
12532fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1254faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
125563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
125663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
125763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
125863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP4:
125963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_DOT4 */
12602fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
12612fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
126290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
12632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
12642fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
126590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
126690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
12672fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
12682fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
126990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
127090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
12712fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_W );
12722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_W );
127390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
127490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
12752fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1276faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
127763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
127863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
127963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
128063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DST:
12812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
1282faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = bld->base.one;
128363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
12842fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
12852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
12862fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, CHAN_Y );
1287faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp0, tmp1);
128863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
12892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
1290faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = emit_fetch( bld, inst, 0, CHAN_Z );
129163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
12922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1293faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = emit_fetch( bld, inst, 1, CHAN_W );
129463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
129563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
129663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
129763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MIN:
12982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
12992fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
13002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1301faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_min( &bld->base, src0, src1 );
130263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
130363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
130463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
130563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MAX:
13062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
13082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1309faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_max( &bld->base, src0, src1 );
131063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
131163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
131263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
131363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SLT:
131463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SETLT */
13152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13162fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
13172fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
13181aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, src1 );
1319faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
13201aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
132163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
132263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
132363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SGE:
132463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SETGE */
13252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
13272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
13281aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GEQUAL, src0, src1 );
1329faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
13301aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
133163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
133263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
133363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MAD:
133463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_MADD */
13352fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
13372fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, chan_index );
13382fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 2, chan_index );
133990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
134090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_add( &bld->base, tmp0, tmp2);
1341faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
134263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
134363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
134463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
134563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SUB:
13462fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
13482fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, chan_index );
1349faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_sub( &bld->base, tmp0, tmp1);
135063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
135163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
135263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
135363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LRP:
13542fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13552fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
13562fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
13572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
135890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_sub( &bld->base, src1, src2 );
135990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, src0, tmp0 );
1360faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_add( &bld->base, tmp0, src2 );
136163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
136263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
136363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
136463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CND:
1365873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1366873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
1367873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1368873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
1369185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul         tmp1 = lp_build_const_vec(bld->base.type, 0.5);
1370873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src2, tmp1);
1371faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, src0, src1 );
1372873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
137363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
137463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
137563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP2A:
13762fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );  /* xmm0 = src[0].x */
13772fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );  /* xmm1 = src[1].x */
137890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 * xmm1 */
13792fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );  /* xmm1 = src[0].y */
13802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );  /* xmm2 = src[1].y */
138190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);              /* xmm1 = xmm1 * xmm2 */
138290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
13832fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 2, CHAN_X );  /* xmm1 = src[2].x */
138490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
13852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1386faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;  /* dest[ch] = xmm0 */
138763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
138863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
138963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
139063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_FRC:
13912fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1392873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
1393873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_floor(&bld->base, src0);
1394f1f49bd465b899d1c85aa07650ca5b62a50303b0Brian Paul         tmp0 = lp_build_sub(&bld->base, src0, tmp0);
1395faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
139663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
139763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
139863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
139963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CLAMP:
1400873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1401873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1402873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1403873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
1404873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_max(&bld->base, tmp0, src1);
1405873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_min(&bld->base, tmp0, src2);
1406faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
1407873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
140863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
140963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
141063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_FLR:
14112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14122fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1413faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_floor(&bld->base, tmp0);
141463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
141563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
141663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
141763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ROUND:
14182fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14192fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1420faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_round(&bld->base, tmp0);
142163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
142263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
142363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
142490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   case TGSI_OPCODE_EX2: {
14252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
142690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_exp2( &bld->base, tmp0);
14272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1428faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
142963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
143063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
143190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   }
143263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
143363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LG2:
14342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
143590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_log2( &bld->base, tmp0);
14362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1437faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
143863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
143963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
144063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
144163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_POW:
14422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
14432fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src1 = emit_fetch( bld, inst, 1, CHAN_X );
1444faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_pow( &bld->base, src0, src1 );
14452fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1446faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
144763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
144863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
144963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
145063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_XPD:
14512fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
14522fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
14532fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, CHAN_Z );
14542fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp3 = emit_fetch( bld, inst, 0, CHAN_Z );
145563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14562fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
14572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
14582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
14592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp4 = emit_fetch( bld, inst, 1, CHAN_Y );
146063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14612fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
146290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = tmp0;
146390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = lp_build_mul( &bld->base, tmp2, tmp1);
146490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = tmp3;
146590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
146690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = lp_build_sub( &bld->base, tmp2, tmp5);
1467faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = tmp2;
146863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14692fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
14702fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
14712fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 1, CHAN_X );
14722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp5 = emit_fetch( bld, inst, 0, CHAN_X );
147363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
147590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp3 = lp_build_mul( &bld->base, tmp3, tmp2);
147690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp1 = lp_build_mul( &bld->base, tmp1, tmp5);
147790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp3 = lp_build_sub( &bld->base, tmp3, tmp1);
1478faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = tmp3;
147963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
148190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
148290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, tmp0, tmp2);
148390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_sub( &bld->base, tmp5, tmp0);
1484faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = tmp5;
148563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14862fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1487faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
148863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
148963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
149063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
149163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ABS:
14922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14932fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1494faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_abs( &bld->base, tmp0 );
149563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
149663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
149763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
149863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RCC:
1499873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1500873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1501fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
150263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
150363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DPH:
15042fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
15052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
150690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
15072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
15082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
150990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
151090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
15122fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
151390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
151490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_W );
151690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
15172fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1518faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
151963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
152063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
152163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
152263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_COS:
15232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
152490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_cos( &bld->base, tmp0 );
15252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1526faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
152763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
152863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
152963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
153063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DDX:
153186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
153286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca         emit_fetch_deriv( bld, inst, 0, chan_index, NULL, &dst0[chan_index], NULL);
153386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      }
153463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
153563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
153663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DDY:
153786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
153886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca         emit_fetch_deriv( bld, inst, 0, chan_index, NULL, NULL, &dst0[chan_index]);
153986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      }
154063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
154163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
154263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_KILP:
154363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* predicated kill */
1544feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul      emit_kilp( bld, inst );
154563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
154663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
154763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_KIL:
154863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* conditional kill */
15492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      emit_kil( bld, inst );
155063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
155163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
155263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK2H:
1553fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
155463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
155563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
155663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK2US:
1557fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
155863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
155963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
156063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK4B:
1561fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
156263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
156363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
156463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK4UB:
1565fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
156663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
156763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
156863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RFL:
1569fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
157063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
157163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
157263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SEQ:
15732fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15752fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
15761aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_EQUAL, src0, src1 );
1577faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
15781aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
157963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
158063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
158163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SFL:
1582873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1583faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.zero;
1584873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
158563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
158663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
158763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SGT:
15882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
15911aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src0, src1 );
1592faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
15931aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
159463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
159563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
159663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SIN:
15972fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
159890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_sin( &bld->base, tmp0 );
15992fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1600faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
160163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
160263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
160363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
160463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SLE:
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 );
16081aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LEQUAL, src0, src1 );
1609faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
16101aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
161163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
161263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
161363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SNE:
16142fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
16162fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
16171aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_NOTEQUAL, src0, src1 );
1618faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
16191aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
162063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
162163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
162263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_STR:
1623873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1624faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.one;
1625873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
162663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
162763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
162863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TEX:
1629962558daaed43b0111cd062e32821aad106869d7José Fonseca      emit_tex( bld, inst, TEX_MODIFIER_NONE, dst0 );
163063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
163163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
163263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXD:
1633962558daaed43b0111cd062e32821aad106869d7José Fonseca      emit_tex( bld, inst, TEX_MODIFIER_EXPLICIT_DERIV, dst0 );
163463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
163563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
163663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP2H:
1637873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1638873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert (0);
1639fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
164063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
164163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
164263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP2US:
1643873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1644873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1645fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
164663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
164763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
164863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP4B:
1649873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1650873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1651fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
165263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
165363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
165463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP4UB:
1655873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1656873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1657fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
165863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
165963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
166063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_X2D:
1661873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1662873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1663fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
166463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
166563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
166663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARA:
1667873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1668873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1669fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
167063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
167163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
167263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARR:
16732fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1675ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         tmp0 = lp_build_round(&bld->base, tmp0);
1676faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
167763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
167863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
167963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
168063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_BRA:
1681873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1682873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1683fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
168463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
168563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1686263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   case TGSI_OPCODE_CAL:
16870b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_call(&bld->exec_mask,
16880b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                        inst->Label.Label,
16890b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                        pc);
16900b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
169163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
169263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
169363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RET:
16940b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_ret(&bld->exec_mask, pc);
169563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
169663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
169763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_END:
16980b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
169963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
170063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
170163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SSG:
170263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SGN */
17032fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
17042fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1705faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_sgn( &bld->base, tmp0 );
170663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
170763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
170863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
170963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CMP:
17102fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
17112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
17122fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
17132fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
17141aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, bld->base.zero );
1715faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, src1, src2);
17161aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
171763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
171863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
171963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SCS:
17202fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
17212fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1722faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = lp_build_cos( &bld->base, tmp0 );
172363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
17252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1726faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_sin( &bld->base, tmp0 );
172763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17282fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
1729faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = bld->base.zero;
173063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1732faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
173363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
173463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
173563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
173663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXB:
1737962558daaed43b0111cd062e32821aad106869d7José Fonseca      emit_tex( bld, inst, TEX_MODIFIER_LOD_BIAS, dst0 );
173863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
173963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
174063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NRM:
174163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* fall-through */
174263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NRM4:
174363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* 3 or 4-component normalization */
174463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      {
174563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         uint dims = (inst->Instruction.Opcode == TGSI_OPCODE_NRM) ? 3 : 4;
174663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
17472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) ||
17482fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y) ||
17492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z) ||
17502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 4)) {
175163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
175263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* NOTE: Cannot use xmm regs 2/3 here (see emit_rsqrt() above). */
175363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
175463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm4 = src.x */
175563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = src.x * src.x */
17562fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
17572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
175890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp4 = tmp0;
175963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
176090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_mul( &bld->base, tmp0, tmp0);
176163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
176263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm5 = src.y */
176363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = xmm0 + src.y * src.y */
17642fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp1 = emit_fetch(bld, inst, 0, CHAN_Y);
17652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
176690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp5 = tmp1;
176763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
176890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
176990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
177063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
177163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm6 = src.z */
177263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = xmm0 + src.z * src.z */
17732fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp1 = emit_fetch(bld, inst, 0, CHAN_Z);
17742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
177590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp6 = tmp1;
177663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
177790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
177890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
177963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
178063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            if (dims == 4) {
178163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               /* xmm7 = src.w */
178263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               /* xmm0 = xmm0 + src.w * src.w */
17832fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca               tmp1 = emit_fetch(bld, inst, 0, CHAN_W);
17842fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca               if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W)) {
178590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca                  tmp7 = tmp1;
178663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               }
178790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
178890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
178963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
179063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
179163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm1 = 1 / sqrt(xmm0) */
179290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_rsqrt( &bld->base, tmp0);
179363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
179463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.x = xmm1 * src.x */
17952fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
1796faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_X] = lp_build_mul( &bld->base, tmp4, tmp1);
179763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
179863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
179963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.y = xmm1 * src.y */
18002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
1801faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp5, tmp1);
180263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
180363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
180463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.z = xmm1 * src.z */
18052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
1806faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_Z] = lp_build_mul( &bld->base, tmp6, tmp1);
180763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
180863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
180963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.w = xmm1 * src.w */
18102fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) && dims == 4) {
1811faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_W] = lp_build_mul( &bld->base, tmp7, tmp1);
181263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
181363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
181463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1815faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         /* dst.w = 1.0 */
18162fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 3) {
1817faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_W] = bld->base.one;
181863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
181963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
182063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
182163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
182263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DIV:
1823873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1824873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert( 0 );
1825fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
182663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
182763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
182863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP2:
18292fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );  /* xmm0 = src[0].x */
18302fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );  /* xmm1 = src[1].x */
183190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 * xmm1 */
18322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );  /* xmm1 = src[0].y */
18332fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );  /* xmm2 = src[1].y */
183490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);              /* xmm1 = xmm1 * xmm2 */
183590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
18362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1837faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;  /* dest[ch] = xmm0 */
183863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
183963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
184063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
184163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXL:
1842962558daaed43b0111cd062e32821aad106869d7José Fonseca      emit_tex( bld, inst, TEX_MODIFIER_EXPLICIT_LOD, dst0 );
184363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
184463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
184563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXP:
1846962558daaed43b0111cd062e32821aad106869d7José Fonseca      emit_tex( bld, inst, TEX_MODIFIER_PROJECTED, dst0 );
184763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
184818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
184963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_BRK:
185018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_break(&bld->exec_mask);
185163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
185263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
185363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_IF:
185480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
1855ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin      tmp0 = lp_build_cmp(&bld->base, PIPE_FUNC_NOTEQUAL,
1856ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                          tmp0, bld->base.zero);
185780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_push(&bld->exec_mask, tmp0);
185863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
185963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
186018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   case TGSI_OPCODE_BGNLOOP:
186118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_bgnloop(&bld->exec_mask);
186218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      break;
186318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
18640b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   case TGSI_OPCODE_BGNSUB:
18650b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_bgnsub(&bld->exec_mask);
18660b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      break;
18670b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
186863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ELSE:
186980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_invert(&bld->exec_mask);
187063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
187163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
187263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ENDIF:
187380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_pop(&bld->exec_mask);
187463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
187563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
187618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   case TGSI_OPCODE_ENDLOOP:
187718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_endloop(&bld->exec_mask);
187818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      break;
187918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
18800b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   case TGSI_OPCODE_ENDSUB:
18810b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_endsub(&bld->exec_mask, pc);
18820b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      break;
18830b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
188463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PUSHA:
1885873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1886873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1887fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
188863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
188963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
189063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_POPA:
1891873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1892873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1893fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
189463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
189563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
189663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CEIL:
1897873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1898873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1899faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_ceil(&bld->base, tmp0);
1900873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
190163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
190263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
190363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_I2F:
1904873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1905873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1906fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
190763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
190863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
190963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NOT:
1910873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1911873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1912fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
191363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
191463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
191563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TRUNC:
19162fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
19172fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1918faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_trunc(&bld->base, tmp0);
191963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
192063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
192163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
192263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SHL:
1923873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1924873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1925fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
192663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
192763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
19282c046034dc5c95dd2fe84d0b4fd44f25235480b9Michal Krol   case TGSI_OPCODE_ISHR:
1929873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1930873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1931fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
193263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
193363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
193463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_AND:
1935873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1936873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1937fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
193863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
193963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
194063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_OR:
1941873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1942873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1943fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
194463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
194563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
194663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MOD:
1947873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1948873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1949fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
195063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
195163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
195263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_XOR:
1953873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1954873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1955fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
195663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
195763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
195863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SAD:
1959873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1960873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1961fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
196263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
196363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
196463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXF:
1965873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1966873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1967fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
196863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
196963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
197063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXQ:
1971873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1972873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1973fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
197463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
197563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
197663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CONT:
197718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_continue(&bld->exec_mask);
197863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
197963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
198063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_EMIT:
1981fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
198263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
198363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
198463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ENDPRIM:
1985fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
198663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
198763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1988873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca   case TGSI_OPCODE_NOP:
1989873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      break;
1990873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca
199163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
1992fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
199363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
199463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1995faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   if(info->num_dst) {
1996ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      LLVMValueRef pred[NUM_CHANNELS];
1997ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
1998ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      emit_fetch_predicate( bld, inst, pred );
1999ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
2000faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
2001ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         emit_store( bld, inst, 0, chan_index, pred[chan_index], dst0[chan_index]);
2002faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
2003faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
2004faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
2005fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul   return TRUE;
200663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
200763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2008c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca
2009c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonsecavoid
201063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecalp_build_tgsi_soa(LLVMBuilderRef builder,
201163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  const struct tgsi_token *tokens,
2012b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca                  struct lp_type type,
20133d7a88674f9eb3320eeff511968f041426e25023José Fonseca                  struct lp_build_mask_context *mask,
201463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  LLVMValueRef consts_ptr,
2015f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef *pos,
2016f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef (*inputs)[NUM_CHANNELS],
2017f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  LLVMValueRef (*outputs)[NUM_CHANNELS],
2018021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                  struct lp_build_sampler_soa *sampler,
20193f6dc8e79d918283a6dfcf9c8937a6d52f3bb4f5Brian Paul                  const struct tgsi_shader_info *info)
202063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
202163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context bld;
202263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct tgsi_parse_context parse;
202363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   uint num_immediates = 0;
20240b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   uint num_instructions = 0;
202563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
20260b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int pc = 0;
202763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
202863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* Setup build context */
202963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   memset(&bld, 0, sizeof bld);
203063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   lp_build_context_init(&bld.base, builder, type);
2031ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   lp_build_context_init(&bld.int_bld, builder, lp_int_type(type));
2032c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca   bld.mask = mask;
2033f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.pos = pos;
2034f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.inputs = inputs;
203563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.outputs = outputs;
203663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.consts_ptr = consts_ptr;
20378be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld.sampler = sampler;
20383662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   bld.indirect_files = info->indirect_files;
20390b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   bld.instructions = (struct tgsi_full_instruction *)
20400b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                      MALLOC( LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction) );
20410b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   bld.max_instructions = LP_MAX_INSTRUCTIONS;
20420b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
20430b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (!bld.instructions) {
20440b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
20450b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
204663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
204780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_init(&bld.exec_mask, &bld.base);
204880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
204963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   tgsi_parse_init( &parse, tokens );
205063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
205163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   while( !tgsi_parse_end_of_tokens( &parse ) ) {
205263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      tgsi_parse_token( &parse );
205363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
205463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      switch( parse.FullToken.Token.Type ) {
205563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_DECLARATION:
20561fc41002252419f4688c24ea8c3814553b3d76adJosé Fonseca         /* Inputs already interpolated */
2057e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         emit_declaration( &bld, &parse.FullToken.FullDeclaration );
205863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
205963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
206063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_INSTRUCTION:
2061faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         {
20620b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            /* save expanded instruction */
20630b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            if (num_instructions == bld.max_instructions) {
20640b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin               bld.instructions = REALLOC(bld.instructions,
20650b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                          bld.max_instructions
20660b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                          * sizeof(struct tgsi_full_instruction),
20670b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                          (bld.max_instructions + LP_MAX_INSTRUCTIONS)
20680b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                          * sizeof(struct tgsi_full_instruction));
20690b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin               bld.max_instructions += LP_MAX_INSTRUCTIONS;
20700b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            }
20710b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
20720b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            memcpy(bld.instructions + num_instructions,
20730b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                   &parse.FullToken.FullInstruction,
20740b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                   sizeof(bld.instructions[0]));
20750b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
20760b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            num_instructions++;
2077faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         }
2078faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
207963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
208063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
208163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_IMMEDIATE:
208263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         /* simply copy the immediate values into the next immediates[] slot */
208363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         {
208463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
208563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            assert(size <= 4);
20866c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca            assert(num_immediates < LP_MAX_TGSI_IMMEDIATES);
208763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            for( i = 0; i < size; ++i )
208863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               bld.immediates[num_immediates][i] =
2089185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul                  lp_build_const_vec(type, parse.FullToken.FullImmediate.u[i].Float);
209063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            for( i = size; i < 4; ++i )
209163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               bld.immediates[num_immediates][i] = bld.base.undef;
209263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            num_immediates++;
209363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
209463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
209563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
20969381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca      case TGSI_TOKEN_TYPE_PROPERTY:
20979381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca         break;
20989381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca
209963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      default:
210063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         assert( 0 );
210163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
210263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
21030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
21040b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   while (pc != -1) {
21050b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      struct tgsi_full_instruction *instr = bld.instructions + pc;
21060b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      const struct tgsi_opcode_info *opcode_info =
21070b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         tgsi_get_opcode_info(instr->Instruction.Opcode);
21080b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      if (!emit_instruction( &bld, instr, opcode_info, &pc ))
21090b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
21100b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                       opcode_info->mnemonic);
21110b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
21120b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
211318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (0) {
211418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
211518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef function = LLVMGetBasicBlockParent(block);
2116263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("11111111111111111111111111111 \n");
211718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      tgsi_dump(tokens, 0);
21188ad3e0b55df50beac8ba3c5cafa0be79641a4977José Fonseca      lp_debug_dump_value(function);
2119263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("2222222222222222222222222222 \n");
212018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   }
212163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   tgsi_parse_free( &parse );
21220b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
21230b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (0) {
21240b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMModuleRef module = LLVMGetGlobalParent(
21250b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld.base.builder)));
21260b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMDumpModule(module);
21270b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
21280b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
21290b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
21300b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   FREE( bld.instructions );
213163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
213263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2133