lp_bld_tgsi_soa.c revision f674ed6b0662a15ab8298da0848a4c82694e0c95
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
136263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   /* we allocate an array of temps if we have indirect
137021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin    * addressing and then the temps above is unused */
138021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   LLVMValueRef temps_array;
139021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   boolean has_indirect_addressing;
140021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
1413d7a88674f9eb3320eeff511968f041426e25023José Fonseca   struct lp_build_mask_context *mask;
14280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   struct lp_exec_mask exec_mask;
1430b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1440b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   struct tgsi_full_instruction *instructions;
1450b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   uint max_instructions;
14663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca};
14763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
14880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld)
14980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
15080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->bld = bld;
15180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->has_mask = FALSE;
15280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack_size = 0;
15318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->loop_stack_size = 0;
1540b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size = 0;
15580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
15680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->int_vec_type = lp_build_int_vec_type(mask->bld->type);
15732a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->exec_mask = mask->ret_mask = mask->break_mask = mask->cont_mask = mask->cond_mask =
1582d91903882e399e8ea7306fd37d5d214907247e6José Fonseca         LLVMConstAllOnes(mask->int_vec_type);
15980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
16080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
16180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_update(struct lp_exec_mask *mask)
16280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
16318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (mask->loop_stack_size) {
16418a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin      /*for loops we need to update the entire mask at runtime */
16518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef tmp;
1667fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul      assert(mask->break_mask);
16718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      tmp = LLVMBuildAnd(mask->bld->builder,
16818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->cont_mask,
16918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->break_mask,
17018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         "maskcb");
17118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
17218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     mask->cond_mask,
17318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     tmp,
17418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     "maskfull");
17518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   } else
17618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      mask->exec_mask = mask->cond_mask;
17718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
17832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   if (mask->call_stack_size) {
1790b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
1800b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     mask->exec_mask,
18132a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                     mask->ret_mask,
1820b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     "callmask");
18332a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   }
18418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
18518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->has_mask = (mask->cond_stack_size > 0 ||
1860b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->loop_stack_size > 0 ||
1870b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->call_stack_size > 0);
18880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
18980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
19080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
19180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                   LLVMValueRef val)
19280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
1936c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING);
1942d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 0) {
1952d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cond_mask == LLVMConstAllOnes(mask->int_vec_type));
1962d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
19780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask;
1982d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(LLVMTypeOf(val) == mask->int_vec_type);
1992d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cond_mask = val;
20080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
20180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
20280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
20380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
20480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_invert(struct lp_exec_mask *mask)
20580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2062d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef prev_mask;
2072d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef inv_mask;
2082d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2092d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
2102d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   prev_mask = mask->cond_stack[mask->cond_stack_size - 1];
2112d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 1) {
2122d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(prev_mask == LLVMConstAllOnes(mask->int_vec_type));
213faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin   }
214faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin
2152d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   inv_mask = LLVMBuildNot(mask->bld->builder, mask->cond_mask, "");
2162d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
21780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_mask = LLVMBuildAnd(mask->bld->builder,
21880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  inv_mask,
21980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  prev_mask, "");
22080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
22180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
22280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
22380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)
22480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2252d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
22680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_mask = mask->cond_stack[--mask->cond_stack_size];
22780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
22880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
22980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
23018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_bgnloop(struct lp_exec_mask *mask)
23118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
2322d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->loop_stack_size == 0) {
2332d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->loop_block == NULL);
2342d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cont_mask == LLVMConstAllOnes(mask->int_vec_type));
2352d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_mask == LLVMConstAllOnes(mask->int_vec_type));
2362d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_var == NULL);
2372d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
2382d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2392d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size < LP_MAX_TGSI_NESTING);
24018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2412d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].loop_block = mask->loop_block;
2422d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].cont_mask = mask->cont_mask;
2432d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_mask = mask->break_mask;
2442d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_var = mask->break_var;
2452d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   ++mask->loop_stack_size;
2463a423dcf9dfa725a4e5dca60f0f2b02599d2ed9bZack Rusin
2472d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_var = lp_build_alloca(mask->bld->builder, mask->int_vec_type, "");
2482d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
2496c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca
25018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->loop_block = lp_build_insert_new_block(mask->bld->builder, "bgnloop");
25118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBuildBr(mask->bld->builder, mask->loop_block);
25218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block);
25318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2542d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_mask = LLVMBuildLoad(mask->bld->builder, mask->break_var, "");
2552d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
25618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
25718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
25818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
25918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_break(struct lp_exec_mask *mask)
26018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
26118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
26218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
26318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "break");
26418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
265d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin   mask->break_mask = LLVMBuildAnd(mask->bld->builder,
266d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   mask->break_mask,
267d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   exec_mask, "break_full");
26818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
26918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
27018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
27118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
27218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_continue(struct lp_exec_mask *mask)
27318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
27418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder,
27518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
27618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "");
27718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
278d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin   mask->cont_mask = LLVMBuildAnd(mask->bld->builder,
279d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  mask->cont_mask,
280d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  exec_mask, "");
28118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
28218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
28318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
28418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
28518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
28618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_endloop(struct lp_exec_mask *mask)
28718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
28818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBasicBlockRef endloop;
289d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca   LLVMTypeRef reg_type = LLVMIntType(mask->bld->type.width*
290d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca                                      mask->bld->type.length);
2917fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   LLVMValueRef i1cond;
2927fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
2937fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   assert(mask->break_mask);
2947fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
2952d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
2962d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Restore the cont_mask, but don't pop
2972d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
2982d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
2992d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size - 1].cont_mask;
3002d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   lp_exec_mask_update(mask);
3012d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
3022d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
3032d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Unlike the continue mask, the break_mask must be preserved across loop
3042d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * iterations
3052d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
3062d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMBuildStore(mask->bld->builder, mask->break_mask, mask->break_var);
3072d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
308d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca   /* i1cond = (mask == 0) */
3097fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   i1cond = LLVMBuildICmp(
310d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      mask->bld->builder,
311d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMIntNE,
3122d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      LLVMBuildBitCast(mask->bld->builder, mask->exec_mask, reg_type, ""),
313d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMConstNull(reg_type), "");
31418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
31518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   endloop = lp_build_insert_new_block(mask->bld->builder, "endloop");
31618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
31718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBuildCondBr(mask->bld->builder,
318ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                   i1cond, mask->loop_block, endloop);
31918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
32018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMPositionBuilderAtEnd(mask->bld->builder, endloop);
32118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
3222d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
3232d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   --mask->loop_stack_size;
3242d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_block = mask->loop_stack[mask->loop_stack_size].loop_block;
3252d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size].cont_mask;
3262d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_mask = mask->loop_stack[mask->loop_stack_size].break_mask;
3272d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_var = mask->loop_stack[mask->loop_stack_size].break_var;
32818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
32918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
33018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
33118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
33218a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin/* stores val into an address pointed to by dst.
33318a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * mask->exec_mask is used to figure out which bits of val
33418a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * should be stored into the address
33518a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * (0 means don't store this bit, 1 means do store).
33618a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin */
33780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_store(struct lp_exec_mask *mask,
338ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                               LLVMValueRef pred,
33980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef val,
34080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef dst)
34180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
342ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   /* Mix the predicate and execution mask */
34380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   if (mask->has_mask) {
344ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (pred) {
34554b94ee96a6d750d57d99ae9819fcf8206d4680dJosé Fonseca         pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, "");
346ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
347ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred = mask->exec_mask;
348ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
349ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
350ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
351ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (pred) {
35280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMValueRef real_val, dst_val;
35380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
35480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      dst_val = LLVMBuildLoad(mask->bld->builder, dst, "");
35580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      real_val = lp_build_select(mask->bld,
356ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                 pred,
35780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                 val, dst_val);
35880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
35980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMBuildStore(mask->bld->builder, real_val, dst);
36080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   } else
36180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMBuildStore(mask->bld->builder, val, dst);
36280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
36380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
3640b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_call(struct lp_exec_mask *mask,
3650b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int func,
3660b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int *pc)
3670b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
36832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size < LP_MAX_TGSI_NESTING);
3690b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack[mask->call_stack_size].pc = *pc;
37032a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack[mask->call_stack_size].ret_mask = mask->ret_mask;
37132a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack_size++;
3720b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = func;
3730b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
3740b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3750b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
3760b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
3770b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   LLVMValueRef exec_mask;
37832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca
3790b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (mask->call_stack_size == 0) {
3800b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      /* returning from main() */
3810b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
3820b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
3830b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
3840b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   exec_mask = LLVMBuildNot(mask->bld->builder,
3850b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            mask->exec_mask,
3860b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            "ret");
3870b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
38832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->ret_mask = LLVMBuildAnd(mask->bld->builder,
38932a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 mask->ret_mask,
39032a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 exec_mask, "ret_full");
3910b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3920b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   lp_exec_mask_update(mask);
3930b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
3940b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3950b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_bgnsub(struct lp_exec_mask *mask)
3960b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
3970b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
3980b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3990b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
4000b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
40132a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size);
4020b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size--;
4030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = mask->call_stack[mask->call_stack_size].pc;
40432a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->ret_mask = mask->call_stack[mask->call_stack_size].ret_mask;
40532a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   lp_exec_mask_update(mask);
4060b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
40786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
408695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul
409695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul/**
410695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * Return pointer to a temporary register channel (src or dest).
411f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul * Note that indirect addressing cannot be handled here.
412695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param index  which temporary register
413695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param chan  which channel of the temp register.
414695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul */
41586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic LLVMValueRef
416263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonsecaget_temp_ptr(struct lp_build_tgsi_soa_context *bld,
417263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca             unsigned index,
418f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul             unsigned chan)
419263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca{
420263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   assert(chan < 4);
421695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   if (bld->has_indirect_addressing) {
422f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan);
423263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      return LLVMBuildGEP(bld->base.builder, bld->temps_array, &lindex, 1, "");
424263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   }
425695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   else {
426695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul      return bld->temps[index][chan];
427695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   }
428263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca}
429263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca
4304363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4314363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul/**
4324363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * Gather vector.
4334363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * XXX the lp_build_gather() function should be capable of doing this
4344363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * with a little work.
4354363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul */
4364363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulstatic LLVMValueRef
4374363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulbuild_gather(struct lp_build_tgsi_soa_context *bld,
4384363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef base_ptr,
4394363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef indexes)
4404363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul{
4414363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   LLVMValueRef res = bld->base.undef;
4424363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   unsigned i;
4434363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4444363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   /*
4454363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    * Loop over elements of index_vec, load scalar value, insert it into 'res'.
4464363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    */
4474363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   for (i = 0; i < bld->base.type.length; i++) {
4484363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0);
4494363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef index = LLVMBuildExtractElement(bld->base.builder,
4504363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                                   indexes, ii, "");
4514363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, base_ptr,
4524363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                             &index, 1, "");
4534363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
4544363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4554363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      res = LLVMBuildInsertElement(bld->base.builder, res, scalar, ii, "");
4564363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   }
4574363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4584363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   return res;
4594363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul}
4604363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4614363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
46263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
46363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register fetch.
46463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
46563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic LLVMValueRef
46663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_fetch(
46763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
4682fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   const struct tgsi_full_instruction *inst,
469ec0e7b16bb6753bedbd611a97062934bfca03aa7Brian Paul   unsigned src_op,
47063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const unsigned chan_index )
47163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
472ec0e7b16bb6753bedbd611a97062934bfca03aa7Brian Paul   const struct tgsi_full_src_register *reg = &inst->Src[src_op];
47385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   const unsigned swizzle =
47485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      tgsi_util_get_full_src_register_swizzle(reg, chan_index);
47563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef res;
4764363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   LLVMValueRef addr_vec = NULL;
47763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
47885c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (swizzle > 3) {
47985c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(0 && "invalid swizzle in emit_fetch()");
48085c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      return bld->base.undef;
48185c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
48285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul
48385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (reg->Register.Indirect) {
48485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type);
48585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      unsigned swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, chan_index );
4864363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4874363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      LLVMValueRef vec4 = lp_build_const_int_vec(bld->int_bld.type, 4);
4884363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4894363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      assert(bld->has_indirect_addressing);
4904363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4914363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      addr_vec = LLVMBuildLoad(bld->base.builder,
4924363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                               bld->addr[reg->Indirect.Index][swizzle],
4934363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                               "load addr");
4944363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
49585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      /* for indexing we want integers */
4964363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      addr_vec = LLVMBuildFPToSI(bld->base.builder, addr_vec,
4974363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                 int_vec_type, "");
4984363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4994363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      /* addr_vec = addr_vec * 4 */
5004363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul      addr_vec = lp_build_mul(&bld->base, addr_vec, vec4);
50185c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
502ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
50385c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   switch (reg->Register.File) {
50485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_CONSTANT:
50585c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      {
506ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         if (reg->Register.Indirect) {
5074363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            LLVMValueRef index_vec;  /* index into the const buffer */
5084363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5094363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            /* index_vec = broadcast(reg->Register.Index * 4 + swizzle) */
5104363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            index_vec = lp_build_const_int_vec(bld->int_bld.type,
5114363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                   reg->Register.Index * 4 + swizzle);
5124363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5134363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            /* index_vec = index_vec + addr_vec */
5144363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            index_vec = lp_build_add(&bld->base, index_vec, addr_vec);
5154363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5164363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            /* Gather values from the constant buffer */
5174363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            res = build_gather(bld, bld->consts_ptr, index_vec);
518ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         }
5194363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul         else {
5204363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            LLVMValueRef index;  /* index into the const buffer */
5214363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            LLVMValueRef scalar, scalar_ptr;
522ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
5234363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            index = lp_build_const_int32(reg->Register.Index*4 + swizzle);
5244363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5254363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
5264363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                      &index, 1, "");
5274363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
5284363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
5294363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul            res = lp_build_broadcast_scalar(&bld->base, scalar);
5304363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul         }
53163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
53285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
53363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
53485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_IMMEDIATE:
535263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      res = bld->immediates[reg->Register.Index][swizzle];
53685c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(res);
53785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
53863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
53985c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_INPUT:
540263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      res = bld->inputs[reg->Register.Index][swizzle];
54185c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(res);
54285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      break;
54363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
54485c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   case TGSI_FILE_TEMPORARY:
545105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      if (reg->Register.Indirect) {
546105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef vec_len =
547105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul            lp_build_const_int_vec(bld->int_bld.type, bld->base.type.length);
548105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef index_vec;  /* index into the const buffer */
549105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef temps_array;
550105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMTypeRef float4_ptr_type;
5514363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
552105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         assert(bld->has_indirect_addressing);
553105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
554105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* index_vec = broadcast(reg->Register.Index * 4 + swizzle) */
555105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         index_vec = lp_build_const_int_vec(bld->int_bld.type,
556105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul                                            reg->Register.Index * 4 + swizzle);
5574363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
558105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* index_vec += addr_vec */
559105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         index_vec = lp_build_add(&bld->int_bld, index_vec, addr_vec);
560105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
561105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* index_vec *= vector_length */
562105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         index_vec = lp_build_mul(&bld->int_bld, index_vec, vec_len);
563105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
564105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* cast temps_array pointer to float* */
565105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
566105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         temps_array = LLVMBuildBitCast(bld->int_bld.builder, bld->temps_array,
567105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul                                        float4_ptr_type, "");
568105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul
569105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         /* Gather values from the temporary register array */
570105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         res = build_gather(bld, temps_array, index_vec);
571105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      }
572105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      else {
573105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         LLVMValueRef temp_ptr;
574f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         temp_ptr = get_temp_ptr(bld, reg->Register.Index, swizzle);
575021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin         res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
576105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul         if (!res)
57763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            return bld->base.undef;
57863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
57963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
58063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
58163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
58285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul      assert(0 && "invalid src register in emit_fetch()");
5834d7a8194c5763f70ba559f32f58dfda36237b666José Fonseca      return bld->base.undef;
58463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
58563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
58663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) {
58763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_CLEAR:
58863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = lp_build_abs( &bld->base, res );
58963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
59063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
59163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_SET:
5921fc41002252419f4688c24ea8c3814553b3d76adJosé Fonseca      /* TODO: Use bitwese OR for floating point */
59363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = lp_build_abs( &bld->base, res );
59463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = LLVMBuildNeg( bld->base.builder, res, "" );
59563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
59663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
59763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_TOGGLE:
59863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      res = LLVMBuildNeg( bld->base.builder, res, "" );
59963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
60063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
60163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_UTIL_SIGN_KEEP:
60263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
60363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
60463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
60563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   return res;
60663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
60763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
60863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
60963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
61086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca * Register fetch with derivatives.
61186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca */
61286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic void
61386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecaemit_fetch_deriv(
61486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   struct lp_build_tgsi_soa_context *bld,
61586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   const struct tgsi_full_instruction *inst,
61686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   unsigned index,
61786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   const unsigned chan_index,
61886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *res,
61986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddx,
62086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddy)
62186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca{
62286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef src;
62386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
62486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   src = emit_fetch(bld, inst, index, chan_index);
62586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
62686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(res)
62786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      *res = src;
62886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
62986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   /* TODO: use interpolation coeffs for inputs */
63086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
63186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddx)
632ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca      *ddx = lp_build_ddx(&bld->base, src);
63386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
63486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddy)
635ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca      *ddy = lp_build_ddy(&bld->base, src);
63686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca}
63786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
63886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
63986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca/**
640ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca * Predicate.
641ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca */
642ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecastatic void
643ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecaemit_fetch_predicate(
644ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
645ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   const struct tgsi_full_instruction *inst,
646ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef *pred)
647ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca{
648ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned index;
649ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned char swizzles[4];
650ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef unswizzled[4] = {NULL, NULL, NULL, NULL};
651ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef value;
652ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned chan;
653ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
654ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (!inst->Instruction.Predicate) {
655ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      FOR_EACH_CHANNEL( chan ) {
656ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred[chan] = NULL;
657ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
658ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      return;
659ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
660ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
661ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[0] = inst->Predicate.SwizzleX;
662ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[1] = inst->Predicate.SwizzleY;
663ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[2] = inst->Predicate.SwizzleZ;
664ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[3] = inst->Predicate.SwizzleW;
665ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
666ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   index = inst->Predicate.Index;
667ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   assert(index < LP_MAX_TGSI_PREDS);
668ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
669ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   FOR_EACH_CHANNEL( chan ) {
670ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      unsigned swizzle = swizzles[chan];
671ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
672ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      /*
673ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * Only fetch the predicate register channels that are actually listed
674ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * in the swizzles
675ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       */
676ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (!unswizzled[swizzle]) {
677ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = LLVMBuildLoad(bld->base.builder,
678263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                               bld->preds[index][swizzle], "");
679ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
680ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         /*
681ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * Convert the value to an integer mask.
682ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          *
683ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * TODO: Short-circuit this comparison -- a D3D setp_xx instructions
684ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * is needlessly causing two comparisons due to storing the intermediate
685ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * result as float vector instead of an integer mask vector.
686ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          */
687ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = lp_build_compare(bld->base.builder,
688ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  bld->base.type,
689ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  PIPE_FUNC_NOTEQUAL,
690ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  value,
691ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  bld->base.zero);
692ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         if (inst->Predicate.Negate) {
693ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca            value = LLVMBuildNot(bld->base.builder, value, "");
694ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         }
695ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
696ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         unswizzled[swizzle] = value;
697ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
698ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = unswizzled[swizzle];
699ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
700ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
701ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      pred[chan] = value;
702ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
703ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca}
704ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
705ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
706ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca/**
70763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register store.
70863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
70963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
71063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_store(
71163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
71263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const struct tgsi_full_instruction *inst,
7132fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   unsigned index,
71463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index,
715ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef pred,
71663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef value)
71763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
7187d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_dst_register *reg = &inst->Dst[index];
719415c40735dfd110bf902ce43968c8d7bd23ff111Brian Paul   LLVMValueRef addr = NULL;
7202fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca
72163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( inst->Instruction.Saturate ) {
72263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_NONE:
72363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
72463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
72563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_ZERO_ONE:
7267926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_max(&bld->base, value, bld->base.zero);
7277926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_min(&bld->base, value, bld->base.one);
72863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
72963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
73063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_MINUS_PLUS_ONE:
731185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul      value = lp_build_max(&bld->base, value, lp_build_const_vec(bld->base.type, -1.0));
7327926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      value = lp_build_min(&bld->base, value, bld->base.one);
73363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
7347926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca
7357926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca   default:
7367926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      assert(0);
73763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
73863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
739021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   if (reg->Register.Indirect) {
740021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type);
741021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      unsigned swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, chan_index );
742021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      addr = LLVMBuildLoad(bld->base.builder,
743263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                           bld->addr[reg->Indirect.Index][swizzle],
744021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                           "");
745021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      /* for indexing we want integers */
746021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      addr = LLVMBuildFPToSI(bld->base.builder, addr,
747021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                             int_vec_type, "");
748021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      addr = LLVMBuildExtractElement(bld->base.builder,
749021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                                     addr, LLVMConstInt(LLVMInt32Type(), 0, 0),
750021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                                     "");
751021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin      addr = lp_build_mul(&bld->base, addr, LLVMConstInt(LLVMInt32Type(), 4, 0));
752021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   }
753021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
7545b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   switch( reg->Register.File ) {
75563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_OUTPUT:
756ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
757263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                         bld->outputs[reg->Register.Index][chan_index]);
75863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
75963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
760f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul   case TGSI_FILE_TEMPORARY:
761f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      if (reg->Register.Indirect) {
762f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         /* XXX not done yet */
763f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         debug_printf("WARNING: LLVM scatter store of temp regs"
764f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul                      " not implemented\n");
765f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
766f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      else {
767f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
768f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul                                              chan_index);
769f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul         lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr);
770f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
77163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
77263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
77363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_ADDRESS:
774ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
775263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                         bld->addr[reg->Indirect.Index][chan_index]);
77663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
77763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
778ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca   case TGSI_FILE_PREDICATE:
779ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      lp_exec_mask_store(&bld->exec_mask, pred, value,
780263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                         bld->preds[index][chan_index]);
781ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca      break;
782ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca
78363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
78463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert( 0 );
78563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
78663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
78763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
78863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
78963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
79063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * High-level instruction translators.
79163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
79263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
793962558daaed43b0111cd062e32821aad106869d7José Fonsecaenum tex_modifier {
794962558daaed43b0111cd062e32821aad106869d7José Fonseca   TEX_MODIFIER_NONE = 0,
795962558daaed43b0111cd062e32821aad106869d7José Fonseca   TEX_MODIFIER_PROJECTED,
796962558daaed43b0111cd062e32821aad106869d7José Fonseca   TEX_MODIFIER_LOD_BIAS,
797962558daaed43b0111cd062e32821aad106869d7José Fonseca   TEX_MODIFIER_EXPLICIT_LOD,
798962558daaed43b0111cd062e32821aad106869d7José Fonseca   TEX_MODIFIER_EXPLICIT_DERIV
799962558daaed43b0111cd062e32821aad106869d7José Fonseca};
80086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
80163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
80263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_tex( struct lp_build_tgsi_soa_context *bld,
80363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca          const struct tgsi_full_instruction *inst,
804962558daaed43b0111cd062e32821aad106869d7José Fonseca          enum tex_modifier modifier,
805faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca          LLVMValueRef *texel)
80663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
807962558daaed43b0111cd062e32821aad106869d7José Fonseca   unsigned unit;
808ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   LLVMValueRef lod_bias, explicit_lod;
80931d1822473bf9d4105bb82b67572cfeea53aaf94Vinson Lee   LLVMValueRef oow = NULL;
810c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   LLVMValueRef coords[3];
811962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddx[3];
812962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddy[3];
813c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   unsigned num_coords;
81463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
81563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
8169db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   if (!bld->sampler) {
8179db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
8189db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      for (i = 0; i < 4; i++) {
8199db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca         texel[i] = bld->base.undef;
8209db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      }
8219db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      return;
8229db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   }
8239db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca
8247d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   switch (inst->Texture.Texture) {
82563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_1D:
826c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 1;
82763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
82863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_2D:
82963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_RECT:
830c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 2;
83163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
832f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW1D:
833f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW2D:
834f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOWRECT:
83563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_3D:
83663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_CUBE:
837c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 3;
83863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
83963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
84063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert(0);
84163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      return;
84263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
84363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
844ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   if (modifier == TEX_MODIFIER_LOD_BIAS) {
845ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = emit_fetch( bld, inst, 0, 3 );
846ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
847ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
848ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   else if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
849ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
850ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = emit_fetch( bld, inst, 0, 3 );
851ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
852ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   else {
853ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
854ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
855ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
85663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
857962558daaed43b0111cd062e32821aad106869d7José Fonseca   if (modifier == TEX_MODIFIER_PROJECTED) {
8582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      oow = emit_fetch( bld, inst, 0, 3 );
85963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      oow = lp_build_rcp(&bld->base, oow);
86063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
86163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
862c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   for (i = 0; i < num_coords; i++) {
863c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      coords[i] = emit_fetch( bld, inst, 0, i );
864962558daaed43b0111cd062e32821aad106869d7José Fonseca      if (modifier == TEX_MODIFIER_PROJECTED)
865c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca         coords[i] = lp_build_mul(&bld->base, coords[i], oow);
86663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
867ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   for (i = num_coords; i < 3; i++) {
868ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca      coords[i] = bld->base.undef;
869ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   }
87063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
871962558daaed43b0111cd062e32821aad106869d7José Fonseca   if (modifier == TEX_MODIFIER_EXPLICIT_DERIV) {
872962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
873962558daaed43b0111cd062e32821aad106869d7José Fonseca         ddx[i] = emit_fetch( bld, inst, 1, i );
874962558daaed43b0111cd062e32821aad106869d7José Fonseca         ddy[i] = emit_fetch( bld, inst, 2, i );
875962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
876962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[3].Register.Index;
877962558daaed43b0111cd062e32821aad106869d7José Fonseca   }  else {
878962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
879ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca         ddx[i] = lp_build_ddx( &bld->base, coords[i] );
880ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca         ddy[i] = lp_build_ddy( &bld->base, coords[i] );
881962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
882962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[1].Register.Index;
883962558daaed43b0111cd062e32821aad106869d7José Fonseca   }
8844554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   for (i = num_coords; i < 3; i++) {
8854554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca      ddx[i] = bld->base.undef;
8864554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca      ddy[i] = bld->base.undef;
8874554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   }
888962558daaed43b0111cd062e32821aad106869d7José Fonseca
8898be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld->sampler->emit_fetch_texel(bld->sampler,
8908be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  bld->base.builder,
8918be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  bld->base.type,
892962558daaed43b0111cd062e32821aad106869d7José Fonseca                                  unit, num_coords, coords,
893ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  ddx, ddy,
894ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  lod_bias, explicit_lod,
8958be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  texel);
89663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
89763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
89863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
899feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul/**
900feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Kill fragment if any of the src register values are negative.
901feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
90263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
90363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_kil(
90463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
9052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   const struct tgsi_full_instruction *inst )
90663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
9077d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_src_register *reg = &inst->Src[0];
9087821664b15501b173b2304bbada758c33c5ff972José Fonseca   LLVMValueRef terms[NUM_CHANNELS];
9093d7a88674f9eb3320eeff511968f041426e25023José Fonseca   LLVMValueRef mask;
91063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
91163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
9127821664b15501b173b2304bbada758c33c5ff972José Fonseca   memset(&terms, 0, sizeof terms);
91363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
91463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   FOR_EACH_CHANNEL( chan_index ) {
91563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      unsigned swizzle;
91663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
9177821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Unswizzle channel */
918b9cb74c7f826dfd320f5e5b54aa933898f7ddd3dKeith Whitwell      swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
91963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
9207821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Check if the component has not been already tested. */
9217821664b15501b173b2304bbada758c33c5ff972José Fonseca      assert(swizzle < NUM_CHANNELS);
9227821664b15501b173b2304bbada758c33c5ff972José Fonseca      if( !terms[swizzle] )
9237821664b15501b173b2304bbada758c33c5ff972José Fonseca         /* TODO: change the comparison operator instead of setting the sign */
9242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         terms[swizzle] =  emit_fetch(bld, inst, 0, chan_index );
92563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
92663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
9273d7a88674f9eb3320eeff511968f041426e25023José Fonseca   mask = NULL;
9287821664b15501b173b2304bbada758c33c5ff972José Fonseca   FOR_EACH_CHANNEL( chan_index ) {
929aede39efd86d200ffbace8fc012104e31f673973José Fonseca      if(terms[chan_index]) {
9303d7a88674f9eb3320eeff511968f041426e25023José Fonseca         LLVMValueRef chan_mask;
931aede39efd86d200ffbace8fc012104e31f673973José Fonseca
932feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul         /*
933feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          * If term < 0 then mask = 0 else mask = ~0.
934feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          */
9353d7a88674f9eb3320eeff511968f041426e25023José Fonseca         chan_mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero);
936aede39efd86d200ffbace8fc012104e31f673973José Fonseca
9373d7a88674f9eb3320eeff511968f041426e25023José Fonseca         if(mask)
9383d7a88674f9eb3320eeff511968f041426e25023José Fonseca            mask = LLVMBuildAnd(bld->base.builder, mask, chan_mask, "");
9393d7a88674f9eb3320eeff511968f041426e25023José Fonseca         else
9403d7a88674f9eb3320eeff511968f041426e25023José Fonseca            mask = chan_mask;
941aede39efd86d200ffbace8fc012104e31f673973José Fonseca      }
94263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
9433d7a88674f9eb3320eeff511968f041426e25023José Fonseca
9443d7a88674f9eb3320eeff511968f041426e25023José Fonseca   if(mask)
9453d7a88674f9eb3320eeff511968f041426e25023José Fonseca      lp_build_mask_update(bld->mask, mask);
94663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
94763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
94863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
94963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
950feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Predicated fragment kill.
951feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * XXX Actually, we do an unconditional kill (as in tgsi_exec.c).
952feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * The only predication is the execution mask which will apply if
953feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * we're inside a loop or conditional.
954feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
955feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulstatic void
956feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulemit_kilp(struct lp_build_tgsi_soa_context *bld,
957feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          const struct tgsi_full_instruction *inst)
958feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul{
959feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   LLVMValueRef mask;
960feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
961feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   /* For those channels which are "alive", disable fragment shader
962feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    * execution.
963feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    */
964feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   if (bld->exec_mask.has_mask) {
965feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul      mask = LLVMBuildNot(bld->base.builder, bld->exec_mask.exec_mask, "kilp");
966feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
967feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   else {
968feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul      mask = bld->base.zero;
969feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
970feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
971feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   lp_build_mask_update(bld->mask, mask);
972feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul}
973feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
974e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonsecastatic void
97585c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusinemit_declaration(
97685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   struct lp_build_tgsi_soa_context *bld,
97785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   const struct tgsi_full_declaration *decl)
97885c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin{
979a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca   LLVMTypeRef vec_type = lp_build_vec_type(bld->base.type);
980a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca
98185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned first = decl->Range.First;
98285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned last = decl->Range.Last;
98385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned idx, i;
98485c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
98585c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   for (idx = first; idx <= last; ++idx) {
98685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      switch (decl->Declaration.File) {
98785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_TEMPORARY:
9886c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_TEMPS);
989263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         if (bld->has_indirect_addressing) {
990846b2fccc2a67b08acc6da51f4970fe66ed4559bBrian Paul            LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
991846b2fccc2a67b08acc6da51f4970fe66ed4559bBrian Paul                                                   last*4 + 4, 0);
992263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->temps_array = lp_build_array_alloca(bld->base.builder,
993846b2fccc2a67b08acc6da51f4970fe66ed4559bBrian Paul                                                     vec_type, array_size, "");
994263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         } else {
995021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin            for (i = 0; i < NUM_CHANNELS; i++)
996a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca               bld->temps[idx][i] = lp_build_alloca(bld->base.builder,
997a18c210a95794c79c6f26dbf4c66d4a85e29169dJosé Fonseca                                                    vec_type, "");
998021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin         }
99985c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
100085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
100185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_OUTPUT:
1002263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1003263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->outputs[idx][i] = lp_build_alloca(bld->base.builder,
1004263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                                                   vec_type, "");
100585c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
100685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
1007ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin      case TGSI_FILE_ADDRESS:
10086c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_ADDRS);
1009263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1010263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->addr[idx][i] = lp_build_alloca(bld->base.builder,
1011263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                                                vec_type, "");
1012ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         break;
1013ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
1014e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca      case TGSI_FILE_PREDICATE:
1015ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         assert(idx < LP_MAX_TGSI_PREDS);
1016263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca         for (i = 0; i < NUM_CHANNELS; i++)
1017263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca            bld->preds[idx][i] = lp_build_alloca(bld->base.builder,
1018263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                                                 vec_type, "");
1019e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         break;
1020e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca
102185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      default:
102285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         /* don't need to declare other vars */
1023dc886ba1391d7d890bd1f5532bc14553e883a418Zack Rusin         break;
1024012fabca722494162c244a367913562b8cfa4677Zack Rusin      }
102585c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   }
102685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin}
102763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1028fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul
1029fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul/**
1030fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul * Emit LLVM for one TGSI instruction.
1031fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul * \param return TRUE for success, FALSE otherwise
1032fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul */
1033fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paulstatic boolean
103463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_instruction(
103563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
1036faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   const struct tgsi_full_instruction *inst,
10370b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   const struct tgsi_opcode_info *info,
10380b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int *pc)
103963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
104063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
104190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   LLVMValueRef src0, src1, src2;
1042e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp0, tmp1, tmp2;
1043e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp3 = NULL;
1044e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp4 = NULL;
1045e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp5 = NULL;
1046e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp6 = NULL;
1047e049ddb7549a45adde521d6f2899c2b74b4ff972Vinson Lee   LLVMValueRef tmp7 = NULL;
1048faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   LLVMValueRef res;
1049faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   LLVMValueRef dst0[NUM_CHANNELS];
105063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
105189258652b6a1d282bed14549907892bdfda752f0José Fonseca   /*
105289258652b6a1d282bed14549907892bdfda752f0José Fonseca    * Stores and write masks are handled in a general fashion after the long
105389258652b6a1d282bed14549907892bdfda752f0José Fonseca    * instruction opcode switch statement.
105489258652b6a1d282bed14549907892bdfda752f0José Fonseca    *
105589258652b6a1d282bed14549907892bdfda752f0José Fonseca    * Although not stricitly necessary, we avoid generating instructions for
105689258652b6a1d282bed14549907892bdfda752f0José Fonseca    * channels which won't be stored, in cases where's that easy. For some
105789258652b6a1d282bed14549907892bdfda752f0José Fonseca    * complex instructions, like texture sampling, it is more convenient to
105889258652b6a1d282bed14549907892bdfda752f0José Fonseca    * assume a full writemask and then let LLVM optimization passes eliminate
105989258652b6a1d282bed14549907892bdfda752f0José Fonseca    * redundant code.
106089258652b6a1d282bed14549907892bdfda752f0José Fonseca    */
106189258652b6a1d282bed14549907892bdfda752f0José Fonseca
10620b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   (*pc)++;
10630b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1064faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   assert(info->num_dst <= 1);
1065ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (info->num_dst) {
1066faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1067faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.undef;
1068faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
1069faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
1070faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
107163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch (inst->Instruction.Opcode) {
107263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARL:
10732fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
10742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1075ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         tmp0 = lp_build_floor(&bld->base, tmp0);
1076faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
107763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
107863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
107963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
108063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MOV:
10812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1082faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = emit_fetch( bld, inst, 0, chan_index );
108363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
108463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
108563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
108663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LIT:
10872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ) {
1088faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = bld->base.one;
108963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
10902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
10912fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
1092faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_max( &bld->base, src0, bld->base.zero);
1093ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca      }
10942fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
1095ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[1] = SrcReg[0].yyyy */
10962fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
1097ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[1] = max(XMM[1], 0) */
1098ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         tmp1 = lp_build_max( &bld->base, tmp1, bld->base.zero);
1099ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         /* XMM[2] = SrcReg[0].wwww */
11002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 0, CHAN_W );
1101ef1fddb36a91a3b272a3c74d104033cd99556cfaJosé Fonseca         tmp1 = lp_build_pow( &bld->base, tmp1, tmp2);
11022fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1103c5abcac7ef7ebd0167093285b5fc9cf3829c1febJosé Fonseca         tmp2 = lp_build_cmp(&bld->base, PIPE_FUNC_GREATER, tmp0, bld->base.zero);
1104faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = lp_build_select(&bld->base, tmp2, tmp1, bld->base.zero);
1105c5abcac7ef7ebd0167093285b5fc9cf3829c1febJosé Fonseca      }
11062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) ) {
1107faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
110863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
110963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
111063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
111163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RCP:
111263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_RECIP */
11132fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
1114faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_rcp(&bld->base, src0);
11152fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1116faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
111763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
111863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
111963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
112063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RSQ:
112163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_RECIPSQRT */
11222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
112390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      src0 = lp_build_abs(&bld->base, src0);
1124faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_rsqrt(&bld->base, src0);
11252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1126faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
112763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
112863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
112963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
113063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_EXP:
11312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
11322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
11332fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
113457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_exp2_int_part = NULL;
113557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_frac_part = NULL;
113657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         LLVMValueRef *p_exp2 = NULL;
113757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
11382fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
113957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
11402fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
114157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp2_int_part = &tmp0;
11422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
114357907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_frac_part = &tmp1;
11442fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
114557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp2 = &tmp2;
114657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
114757907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         lp_build_exp2_approx(&bld->base, src0, p_exp2_int_part, p_frac_part, p_exp2);
114857907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
11492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
1150faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_X] = tmp0;
11512fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
1152faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Y] = tmp1;
11532fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
1154faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Z] = tmp2;
115563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
115663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* dst.w = 1.0 */
11572fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
1158faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
115963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
116063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
116163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
116263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LOG:
11632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
11642fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
11652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
1166add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_floor_log2 = NULL;
1167add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_exp = NULL;
1168add6dfbba64260c9b314b4a95c8def084e05bd3bVinson Lee         LLVMValueRef *p_log2 = NULL;
116957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
11702fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, CHAN_X );
117157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         src0 = lp_build_abs( &bld->base, src0 );
117257907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
11732fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
117457907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_floor_log2 = &tmp0;
11752fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
117657907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_exp = &tmp1;
11772fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
117857907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca            p_log2 = &tmp2;
117957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
118057907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         lp_build_log2_approx(&bld->base, src0, p_exp, p_floor_log2, p_log2);
118157907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca
118257907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.x = floor(lg2(abs(src.x))) */
11832fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
1184faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_X] = tmp0;
118557907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.y = abs(src)/ex2(floor(lg2(abs(src.x)))) */
11862fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y )) {
1187faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Y] = lp_build_div( &bld->base, src0, tmp1);
118863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
118957907e7fd9fc63b9023d0e2b08934c2d0acf2953José Fonseca         /* dst.z = lg2(abs(src.x)) */
11902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
1191faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_Z] = tmp2;
119263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
119363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* dst.w = 1.0 */
11942fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
1195faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
119663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
119763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
119863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
119963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MUL:
12002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
12012fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
12022fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1203faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_mul(&bld->base, src0, src1);
120463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
120563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
120663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
120763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ADD:
12082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
12092fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
12102fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1211faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_add(&bld->base, src0, src1);
121263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
121363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
121463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
121563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP3:
121663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_DOT3 */
12172fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
12182fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
121990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
12202fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
12212fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
122290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
122390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
12242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
12252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
122690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
122790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
12282fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1229faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
123063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
123163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
123263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
123363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP4:
123463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_DOT4 */
12352fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
12362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
123790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
12382fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
12392fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
124090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
124190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
12422fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
12432fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
124490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
124590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
12462fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_W );
12472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_W );
124890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
124990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
12502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1251faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
125263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
125363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
125463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
125563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DST:
12562fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
1257faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = bld->base.one;
125863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
12592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
12602fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
12612fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, CHAN_Y );
1262faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp0, tmp1);
126363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
12642fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
1265faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = emit_fetch( bld, inst, 0, CHAN_Z );
126663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
12672fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1268faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = emit_fetch( bld, inst, 1, CHAN_W );
126963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
127063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
127163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
127263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MIN:
12732fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
12742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
12752fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1276faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_min( &bld->base, src0, src1 );
127763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
127863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
127963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
128063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MAX:
12812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
12822fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
12832fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1284faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_max( &bld->base, src0, src1 );
128563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
128663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
128763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
128863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SLT:
128963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SETLT */
12902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
12912fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
12922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
12931aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, src1 );
1294faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
12951aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
129663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
129763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
129863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SGE:
129963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SETGE */
13002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13012fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
13022fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
13031aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GEQUAL, src0, src1 );
1304faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
13051aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
130663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
130763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
130863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MAD:
130963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_MADD */
13102fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
13122fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, chan_index );
13132fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 2, chan_index );
131490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
131590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_add( &bld->base, tmp0, tmp2);
1316faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
131763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
131863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
131963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
132063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SUB:
13212fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
13232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, chan_index );
1324faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_sub( &bld->base, tmp0, tmp1);
132563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
132663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
132763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
132863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LRP:
13292fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13302fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
13312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
13322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
133390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_sub( &bld->base, src1, src2 );
133490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, src0, tmp0 );
1335faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_add( &bld->base, tmp0, src2 );
133663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
133763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
133863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
133963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CND:
1340873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1341873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
1342873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1343873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
1344185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul         tmp1 = lp_build_const_vec(bld->base.type, 0.5);
1345873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src2, tmp1);
1346faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, src0, src1 );
1347873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
134863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
134963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
135063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP2A:
13512fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );  /* xmm0 = src[0].x */
13522fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );  /* xmm1 = src[1].x */
135390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 * xmm1 */
13542fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );  /* xmm1 = src[0].y */
13552fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );  /* xmm2 = src[1].y */
135690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);              /* xmm1 = xmm1 * xmm2 */
135790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
13582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 2, CHAN_X );  /* xmm1 = src[2].x */
135990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
13602fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1361faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;  /* dest[ch] = xmm0 */
136263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
136363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
136463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
136563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_FRC:
13662fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1367873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
1368873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_floor(&bld->base, src0);
1369f1f49bd465b899d1c85aa07650ca5b62a50303b0Brian Paul         tmp0 = lp_build_sub(&bld->base, src0, tmp0);
1370faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
137163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
137263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
137363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
137463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CLAMP:
1375873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1376873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1377873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
1378873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
1379873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_max(&bld->base, tmp0, src1);
1380873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = lp_build_min(&bld->base, tmp0, src2);
1381faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
1382873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
138363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
138463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
138563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_FLR:
13862fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1388faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_floor(&bld->base, tmp0);
138963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
139063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
139163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
139263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ROUND:
13932fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
13942fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1395faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_round(&bld->base, tmp0);
139663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
139763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
139863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
139990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   case TGSI_OPCODE_EX2: {
14002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
140190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_exp2( &bld->base, tmp0);
14022fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1403faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
140463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
140563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
140690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca   }
140763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
140863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_LG2:
14092fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
141090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_log2( &bld->base, tmp0);
14112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1412faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
141363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
141463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
141563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
141663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_POW:
14172fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src0 = emit_fetch( bld, inst, 0, CHAN_X );
14182fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      src1 = emit_fetch( bld, inst, 1, CHAN_X );
1419faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      res = lp_build_pow( &bld->base, src0, src1 );
14202fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1421faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = res;
142263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
142363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
142463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
142563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_XPD:
14262fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
14272fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
14282fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp1 = emit_fetch( bld, inst, 1, CHAN_Z );
14292fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp3 = emit_fetch( bld, inst, 0, CHAN_Z );
143063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
14322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
14332fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
14342fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp4 = emit_fetch( bld, inst, 1, CHAN_Y );
143563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14362fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
143790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = tmp0;
143890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = lp_build_mul( &bld->base, tmp2, tmp1);
143990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = tmp3;
144090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
144190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp2 = lp_build_sub( &bld->base, tmp2, tmp5);
1442faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = tmp2;
144363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14442fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
14452fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca          IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
14462fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp2 = emit_fetch( bld, inst, 1, CHAN_X );
14472fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp5 = emit_fetch( bld, inst, 0, CHAN_X );
144863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
145090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp3 = lp_build_mul( &bld->base, tmp3, tmp2);
145190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp1 = lp_build_mul( &bld->base, tmp1, tmp5);
145290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp3 = lp_build_sub( &bld->base, tmp3, tmp1);
1453faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = tmp3;
145463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14552fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
145690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
145790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp0 = lp_build_mul( &bld->base, tmp0, tmp2);
145890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca         tmp5 = lp_build_sub( &bld->base, tmp5, tmp0);
1459faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = tmp5;
146063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
14612fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1462faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
146363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
146463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
146563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
146663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ABS:
14672fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
14682fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1469faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_abs( &bld->base, tmp0 );
147063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
147163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
147263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
147363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RCC:
1474873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1475873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1476fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
147763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
147863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DPH:
14792fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
14802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
148190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
14822fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
14832fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
148490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
148590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
14862fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
14872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
148890e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
148990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
14902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_W );
149190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
14922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1493faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
149463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
149563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
149663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
149763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_COS:
14982fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
149990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_cos( &bld->base, tmp0 );
15002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1501faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
150263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
150363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
150463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
150563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DDX:
150686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
150786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca         emit_fetch_deriv( bld, inst, 0, chan_index, NULL, &dst0[chan_index], NULL);
150886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      }
150963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
151063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
151163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DDY:
151286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
151386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca         emit_fetch_deriv( bld, inst, 0, chan_index, NULL, NULL, &dst0[chan_index]);
151486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      }
151563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
151663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
151763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_KILP:
151863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* predicated kill */
1519feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul      emit_kilp( bld, inst );
152063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
152163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
152263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_KIL:
152363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* conditional kill */
15242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      emit_kil( bld, inst );
152563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
152663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
152763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK2H:
1528fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
152963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
153063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
153163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK2US:
1532fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
153363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
153463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
153563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK4B:
1536fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
153763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
153863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
153963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PK4UB:
1540fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
154163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
154263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
154363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RFL:
1544fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
154563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
154663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
154763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SEQ:
15482fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15502fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
15511aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_EQUAL, src0, src1 );
1552faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
15531aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
155463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
155563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
155663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SFL:
1557873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1558faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.zero;
1559873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
156063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
156163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
156263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SGT:
15632fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15642fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15652fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
15661aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src0, src1 );
1567faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
15681aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
156963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
157063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
157163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SIN:
15722fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
157390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_sin( &bld->base, tmp0 );
15742fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1575faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
157663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
157763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
157863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
157963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SLE:
15802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15812fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15822fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
15831aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LEQUAL, src0, src1 );
1584faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
15851aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
158663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
158763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
158863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SNE:
15892fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
15902fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
15912fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
15921aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_NOTEQUAL, src0, src1 );
1593faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
15941aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
159563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
159663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
159763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_STR:
1598873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1599faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = bld->base.one;
1600873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
160163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
160263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
160363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TEX:
1604962558daaed43b0111cd062e32821aad106869d7José Fonseca      emit_tex( bld, inst, TEX_MODIFIER_NONE, dst0 );
160563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
160663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
160763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXD:
1608962558daaed43b0111cd062e32821aad106869d7José Fonseca      emit_tex( bld, inst, TEX_MODIFIER_EXPLICIT_DERIV, dst0 );
160963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
161063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
161163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP2H:
1612873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1613873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert (0);
1614fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
161563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
161663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
161763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP2US:
1618873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1619873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1620fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
162163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
162263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
162363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP4B:
1624873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1625873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1626fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
162763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
162863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
162963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_UP4UB:
1630873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1631873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1632fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
163363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
163463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
163563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_X2D:
1636873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1637873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1638fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
163963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
164063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
164163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARA:
1642873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1643873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1644fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
164563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
164663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
164763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ARR:
16482fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1650ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         tmp0 = lp_build_round(&bld->base, tmp0);
1651faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;
165263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
165363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
165463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
165563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_BRA:
1656873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1657873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1658fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
165963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
166063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1661263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   case TGSI_OPCODE_CAL:
16620b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_call(&bld->exec_mask,
16630b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                        inst->Label.Label,
16640b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                        pc);
16650b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
166663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
166763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
166863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_RET:
16690b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_ret(&bld->exec_mask, pc);
167063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
167163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
167263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_END:
16730b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
167463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
167563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
167663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SSG:
167763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* TGSI_OPCODE_SGN */
16782fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16792fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1680faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_sgn( &bld->base, tmp0 );
168163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
168263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
168363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
168463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CMP:
16852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
16862fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src0 = emit_fetch( bld, inst, 0, chan_index );
16872fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src1 = emit_fetch( bld, inst, 1, chan_index );
16882fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         src2 = emit_fetch( bld, inst, 2, chan_index );
16891aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca         tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, bld->base.zero );
1690faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_select( &bld->base, tmp0, src1, src2);
16911aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
169263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
169363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
169463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SCS:
16952fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
16962fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1697faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_X] = lp_build_cos( &bld->base, tmp0 );
169863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
16992fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
17002fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
1701faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Y] = lp_build_sin( &bld->base, tmp0 );
170263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17032fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
1704faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_Z] = bld->base.zero;
170563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
17062fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
1707faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[CHAN_W] = bld->base.one;
170863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
170963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
171063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
171163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXB:
1712962558daaed43b0111cd062e32821aad106869d7José Fonseca      emit_tex( bld, inst, TEX_MODIFIER_LOD_BIAS, dst0 );
171363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
171463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
171563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NRM:
171663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* fall-through */
171763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NRM4:
171863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      /* 3 or 4-component normalization */
171963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      {
172063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         uint dims = (inst->Instruction.Opcode == TGSI_OPCODE_NRM) ? 3 : 4;
172163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
17222fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) ||
17232fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y) ||
17242fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z) ||
17252fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca             (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 4)) {
172663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
172763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* NOTE: Cannot use xmm regs 2/3 here (see emit_rsqrt() above). */
172863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
172963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm4 = src.x */
173063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = src.x * src.x */
17312fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
17322fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
173390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp4 = tmp0;
173463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
173590e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_mul( &bld->base, tmp0, tmp0);
173663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
173763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm5 = src.y */
173863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = xmm0 + src.y * src.y */
17392fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp1 = emit_fetch(bld, inst, 0, CHAN_Y);
17402fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
174190e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp5 = tmp1;
174263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
174390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
174490e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
174563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
174663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm6 = src.z */
174763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm0 = xmm0 + src.z * src.z */
17482fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            tmp1 = emit_fetch(bld, inst, 0, CHAN_Z);
17492fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
175090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp6 = tmp1;
175163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
175290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
175390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
175463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
175563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            if (dims == 4) {
175663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               /* xmm7 = src.w */
175763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               /* xmm0 = xmm0 + src.w * src.w */
17582fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca               tmp1 = emit_fetch(bld, inst, 0, CHAN_W);
17592fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca               if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W)) {
176090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca                  tmp7 = tmp1;
176163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               }
176290e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
176390e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca               tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
176463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
176563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
176663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* xmm1 = 1 / sqrt(xmm0) */
176790e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca            tmp1 = lp_build_rsqrt( &bld->base, tmp0);
176863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
176963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.x = xmm1 * src.x */
17702fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
1771faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_X] = lp_build_mul( &bld->base, tmp4, tmp1);
177263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
177363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
177463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.y = xmm1 * src.y */
17752fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
1776faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp5, tmp1);
177763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
177863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
177963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.z = xmm1 * src.z */
17802fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
1781faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_Z] = lp_build_mul( &bld->base, tmp6, tmp1);
178263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
178363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
178463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            /* dst.w = xmm1 * src.w */
17852fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca            if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) && dims == 4) {
1786faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca               dst0[CHAN_W] = lp_build_mul( &bld->base, tmp7, tmp1);
178763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            }
178863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
178963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1790faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         /* dst.w = 1.0 */
17912fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 3) {
1792faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca            dst0[CHAN_W] = bld->base.one;
179363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
179463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
179563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
179663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
179763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DIV:
1798873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated */
1799873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert( 0 );
1800fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
180163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
180263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
180363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_DP2:
18042fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp0 = emit_fetch( bld, inst, 0, CHAN_X );  /* xmm0 = src[0].x */
18052fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 1, CHAN_X );  /* xmm1 = src[1].x */
180690e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 * xmm1 */
18072fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );  /* xmm1 = src[0].y */
18082fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );  /* xmm2 = src[1].y */
180990e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);              /* xmm1 = xmm1 * xmm2 */
181090e9a4d4f99e722d8f0f2050e134a3c69863541bJosé Fonseca      tmp0 = lp_build_add( &bld->base, tmp0, tmp1);              /* xmm0 = xmm0 + xmm1 */
18112fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1812faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = tmp0;  /* dest[ch] = xmm0 */
181363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
181463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
181563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
181663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXL:
1817962558daaed43b0111cd062e32821aad106869d7José Fonseca      emit_tex( bld, inst, TEX_MODIFIER_EXPLICIT_LOD, dst0 );
181863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
181963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
182063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXP:
1821962558daaed43b0111cd062e32821aad106869d7José Fonseca      emit_tex( bld, inst, TEX_MODIFIER_PROJECTED, dst0 );
182263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
182318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
182463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_BRK:
182518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_break(&bld->exec_mask);
182663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
182763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
182863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_IF:
182980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
1830ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin      tmp0 = lp_build_cmp(&bld->base, PIPE_FUNC_NOTEQUAL,
1831ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                          tmp0, bld->base.zero);
183280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_push(&bld->exec_mask, tmp0);
183363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
183463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
183518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   case TGSI_OPCODE_BGNLOOP:
183618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_bgnloop(&bld->exec_mask);
183718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      break;
183818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
18390b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   case TGSI_OPCODE_BGNSUB:
18400b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_bgnsub(&bld->exec_mask);
18410b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      break;
18420b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
184363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ELSE:
184480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_invert(&bld->exec_mask);
184563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
184663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
184763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ENDIF:
184880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      lp_exec_mask_cond_pop(&bld->exec_mask);
184963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
185063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
185118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   case TGSI_OPCODE_ENDLOOP:
185218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_endloop(&bld->exec_mask);
185318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      break;
185418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
18550b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   case TGSI_OPCODE_ENDSUB:
18560b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      lp_exec_mask_endsub(&bld->exec_mask, pc);
18570b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      break;
18580b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
185963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_PUSHA:
1860873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1861873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1862fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
186363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
186463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
186563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_POPA:
1866873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1867873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1868fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
186963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
187063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
187163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CEIL:
1872873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1873873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1874faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_ceil(&bld->base, tmp0);
1875873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
187663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
187763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
187863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_I2F:
1879873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1880873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1881fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
188263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
188363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
188463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_NOT:
1885873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1886873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1887fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
188863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
188963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
189063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TRUNC:
18912fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
18922fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca         tmp0 = emit_fetch( bld, inst, 0, chan_index );
1893faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         dst0[chan_index] = lp_build_trunc(&bld->base, tmp0);
189463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
189563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
189663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
189763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SHL:
1898873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1899873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1900fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
190163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
190263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
19032c046034dc5c95dd2fe84d0b4fd44f25235480b9Michal Krol   case TGSI_OPCODE_ISHR:
1904873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1905873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1906fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
190763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
190863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
190963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_AND:
1910873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1911873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1912fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
191363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
191463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
191563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_OR:
1916873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1917873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1918fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
191963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
192063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
192163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_MOD:
1922873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1923873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1924fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
192563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
192663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
192763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_XOR:
1928873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1929873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1930fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
193163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
193263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
193363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_SAD:
1934873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1935873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1936fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
193763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
193863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
193963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXF:
1940873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1941873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1942fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
194363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
194463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
194563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_TXQ:
1946873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      /* deprecated? */
1947873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      assert(0);
1948fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
194963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
195063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
195163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_CONT:
195218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      lp_exec_continue(&bld->exec_mask);
195363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
195463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
195563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_EMIT:
1956fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
195763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
195863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
195963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_OPCODE_ENDPRIM:
1960fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
196163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
196263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1963873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca   case TGSI_OPCODE_NOP:
1964873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      break;
1965873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca
196663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
1967fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul      return FALSE;
196863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
196963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1970faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   if(info->num_dst) {
1971ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      LLVMValueRef pred[NUM_CHANNELS];
1972ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
1973ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      emit_fetch_predicate( bld, inst, pred );
1974ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
1975faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
1976ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         emit_store( bld, inst, 0, chan_index, pred[chan_index], dst0[chan_index]);
1977faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
1978faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
1979faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
1980fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul   return TRUE;
198163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
198263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1983c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca
1984c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonsecavoid
198563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecalp_build_tgsi_soa(LLVMBuilderRef builder,
198663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  const struct tgsi_token *tokens,
1987b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca                  struct lp_type type,
19883d7a88674f9eb3320eeff511968f041426e25023José Fonseca                  struct lp_build_mask_context *mask,
198963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  LLVMValueRef consts_ptr,
1990f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef *pos,
1991f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef (*inputs)[NUM_CHANNELS],
1992f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  LLVMValueRef (*outputs)[NUM_CHANNELS],
1993021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                  struct lp_build_sampler_soa *sampler,
19943f6dc8e79d918283a6dfcf9c8937a6d52f3bb4f5Brian Paul                  const struct tgsi_shader_info *info)
199563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
199663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context bld;
199763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct tgsi_parse_context parse;
199863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   uint num_immediates = 0;
19990b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   uint num_instructions = 0;
200063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
20010b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   int pc = 0;
200263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
200363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* Setup build context */
200463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   memset(&bld, 0, sizeof bld);
200563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   lp_build_context_init(&bld.base, builder, type);
2006ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   lp_build_context_init(&bld.int_bld, builder, lp_int_type(type));
2007c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca   bld.mask = mask;
2008f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.pos = pos;
2009f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.inputs = inputs;
201063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.outputs = outputs;
201163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.consts_ptr = consts_ptr;
20128be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld.sampler = sampler;
2013021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   bld.has_indirect_addressing = info->opcode_count[TGSI_OPCODE_ARR] > 0 ||
2014021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                                 info->opcode_count[TGSI_OPCODE_ARL] > 0;
20150b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   bld.instructions = (struct tgsi_full_instruction *)
20160b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                      MALLOC( LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction) );
20170b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   bld.max_instructions = LP_MAX_INSTRUCTIONS;
20180b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
20190b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (!bld.instructions) {
20200b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
20210b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
202263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
202380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_init(&bld.exec_mask, &bld.base);
202480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
202563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   tgsi_parse_init( &parse, tokens );
202663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
202763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   while( !tgsi_parse_end_of_tokens( &parse ) ) {
202863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      tgsi_parse_token( &parse );
202963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
203063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      switch( parse.FullToken.Token.Type ) {
203163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_DECLARATION:
20321fc41002252419f4688c24ea8c3814553b3d76adJosé Fonseca         /* Inputs already interpolated */
2033e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         emit_declaration( &bld, &parse.FullToken.FullDeclaration );
203463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
203563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
203663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_INSTRUCTION:
2037faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         {
20380b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            /* save expanded instruction */
20390b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            if (num_instructions == bld.max_instructions) {
20400b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin               bld.instructions = REALLOC(bld.instructions,
20410b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                          bld.max_instructions
20420b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                          * sizeof(struct tgsi_full_instruction),
20430b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                          (bld.max_instructions + LP_MAX_INSTRUCTIONS)
20440b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                          * sizeof(struct tgsi_full_instruction));
20450b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin               bld.max_instructions += LP_MAX_INSTRUCTIONS;
20460b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            }
20470b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
20480b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            memcpy(bld.instructions + num_instructions,
20490b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                   &parse.FullToken.FullInstruction,
20500b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                   sizeof(bld.instructions[0]));
20510b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
20520b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin            num_instructions++;
2053faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca         }
2054faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
205563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
205663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
205763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      case TGSI_TOKEN_TYPE_IMMEDIATE:
205863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         /* simply copy the immediate values into the next immediates[] slot */
205963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         {
206063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
206163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            assert(size <= 4);
20626c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca            assert(num_immediates < LP_MAX_TGSI_IMMEDIATES);
206363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            for( i = 0; i < size; ++i )
206463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               bld.immediates[num_immediates][i] =
2065185be3a87a5b38e8821a560c073975c11dcbd3e9Brian Paul                  lp_build_const_vec(type, parse.FullToken.FullImmediate.u[i].Float);
206663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            for( i = size; i < 4; ++i )
206763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca               bld.immediates[num_immediates][i] = bld.base.undef;
206863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca            num_immediates++;
206963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         }
207063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         break;
207163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
20729381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca      case TGSI_TOKEN_TYPE_PROPERTY:
20739381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca         break;
20749381dd590f2e45acb8fbb0aa5503c917b832204dJosé Fonseca
207563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      default:
207663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca         assert( 0 );
207763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
207863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
20790b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
20800b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   while (pc != -1) {
20810b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      struct tgsi_full_instruction *instr = bld.instructions + pc;
20820b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      const struct tgsi_opcode_info *opcode_info =
20830b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         tgsi_get_opcode_info(instr->Instruction.Opcode);
20840b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      if (!emit_instruction( &bld, instr, opcode_info, &pc ))
20850b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
20860b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                       opcode_info->mnemonic);
20870b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
20880b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
208918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (0) {
209018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
209118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef function = LLVMGetBasicBlockParent(block);
2092263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("11111111111111111111111111111 \n");
209318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      tgsi_dump(tokens, 0);
20948ad3e0b55df50beac8ba3c5cafa0be79641a4977José Fonseca      lp_debug_dump_value(function);
2095263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("2222222222222222222222222222 \n");
209618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   }
209763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   tgsi_parse_free( &parse );
20980b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
20990b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (0) {
21000b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMModuleRef module = LLVMGetGlobalParent(
21010b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin         LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld.base.builder)));
21020b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMDumpModule(module);
21030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
21040b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
21050b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
21060b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   FREE( bld.instructions );
210763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
210863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
2109