lp_bld_tgsi_soa.c revision 66461aa249a95053fd5887df75ab791558c3a486
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"
459ee1bcf7a5442ccb517a5cfbaf024755bd4d2738Tom Stellard#include "tgsi/tgsi_exec.h"
467821664b15501b173b2304bbada758c33c5ff972José Fonseca#include "tgsi/tgsi_info.h"
4763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "tgsi/tgsi_parse.h"
4863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "tgsi/tgsi_util.h"
49021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin#include "tgsi/tgsi_scan.h"
50bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard#include "lp_bld_tgsi_action.h"
5163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_type.h"
5263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_const.h"
5363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_arit.h"
546d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca#include "lp_bld_bitarit.h"
554363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul#include "lp_bld_gather.h"
56efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul#include "lp_bld_init.h"
577821664b15501b173b2304bbada758c33c5ff972José Fonseca#include "lp_bld_logic.h"
5863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_swizzle.h"
593d7a88674f9eb3320eeff511968f041426e25023José Fonseca#include "lp_bld_flow.h"
60ef81779850d1343b3ae284eb9beabeaf11934d4aJosé Fonseca#include "lp_bld_quad.h"
6163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca#include "lp_bld_tgsi.h"
626c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca#include "lp_bld_limits.h"
6380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin#include "lp_bld_debug.h"
645b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul#include "lp_bld_printf.h"
6563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
6780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld)
6880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
6980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->bld = bld;
7080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->has_mask = FALSE;
7180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack_size = 0;
7218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->loop_stack_size = 0;
730b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size = 0;
7480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
75efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   mask->int_vec_type = lp_build_int_vec_type(bld->gallivm, mask->bld->type);
7632a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->exec_mask = mask->ret_mask = mask->break_mask = mask->cont_mask = mask->cond_mask =
772d91903882e399e8ea7306fd37d5d214907247e6José Fonseca         LLVMConstAllOnes(mask->int_vec_type);
7880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
7980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
8080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_update(struct lp_exec_mask *mask)
8180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
826299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
836299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul
8418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (mask->loop_stack_size) {
8518a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin      /*for loops we need to update the entire mask at runtime */
8618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef tmp;
877fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul      assert(mask->break_mask);
886299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      tmp = LLVMBuildAnd(builder,
8918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->cont_mask,
9018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         mask->break_mask,
9118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                         "maskcb");
926299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      mask->exec_mask = LLVMBuildAnd(builder,
9318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     mask->cond_mask,
9418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     tmp,
9518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                     "maskfull");
9618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   } else
9718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      mask->exec_mask = mask->cond_mask;
9818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
9932a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   if (mask->call_stack_size) {
1006299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      mask->exec_mask = LLVMBuildAnd(builder,
1010b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     mask->exec_mask,
10232a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                     mask->ret_mask,
1030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                                     "callmask");
10432a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   }
10518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
10618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   mask->has_mask = (mask->cond_stack_size > 0 ||
1070b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->loop_stack_size > 0 ||
1080b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                     mask->call_stack_size > 0);
10980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
11080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
11180f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
11280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                   LLVMValueRef val)
11380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
1146299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
1156299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul
1166c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca   assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING);
1172d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 0) {
1182d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cond_mask == LLVMConstAllOnes(mask->int_vec_type));
1192d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
12080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask;
1212d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(LLVMTypeOf(val) == mask->int_vec_type);
1226299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->cond_mask = LLVMBuildAnd(builder,
1233fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  mask->cond_mask,
1243fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  val,
1253fa3c33844b8491a204cda6ae8d67cd6ada78b3bBrian Paul                                  "");
12680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
12780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
12880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
12980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_invert(struct lp_exec_mask *mask)
13080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
1316299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
1322d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef prev_mask;
1332d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   LLVMValueRef inv_mask;
1342d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
1352d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
1362d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   prev_mask = mask->cond_stack[mask->cond_stack_size - 1];
1372d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->cond_stack_size == 1) {
1382d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(prev_mask == LLVMConstAllOnes(mask->int_vec_type));
139faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin   }
140faf8215bae70f020420242dc812ef141fdcf5417Zack Rusin
1416299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   inv_mask = LLVMBuildNot(builder, mask->cond_mask, "");
1422d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
1436299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->cond_mask = LLVMBuildAnd(builder,
14480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  inv_mask,
14580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                  prev_mask, "");
14680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
14780f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
14880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
14980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)
15080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
1512d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->cond_stack_size);
15280f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   mask->cond_mask = mask->cond_stack[--mask->cond_stack_size];
15380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   lp_exec_mask_update(mask);
15480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
15580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
15618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_bgnloop(struct lp_exec_mask *mask)
15718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
1586299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
1596299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul
1602d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   if (mask->loop_stack_size == 0) {
1612d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->loop_block == NULL);
1622d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->cont_mask == LLVMConstAllOnes(mask->int_vec_type));
1632d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_mask == LLVMConstAllOnes(mask->int_vec_type));
1642d91903882e399e8ea7306fd37d5d214907247e6José Fonseca      assert(mask->break_var == NULL);
1652d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   }
1662d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
1672d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size < LP_MAX_TGSI_NESTING);
16818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
1692d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].loop_block = mask->loop_block;
1702d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].cont_mask = mask->cont_mask;
1712d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_mask = mask->break_mask;
1722d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_stack[mask->loop_stack_size].break_var = mask->break_var;
1732d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   ++mask->loop_stack_size;
1743a423dcf9dfa725a4e5dca60f0f2b02599d2ed9bZack Rusin
175efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   mask->break_var = lp_build_alloca(mask->bld->gallivm, mask->int_vec_type, "");
1766299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuildStore(builder, mask->break_mask, mask->break_var);
1776c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca
178efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   mask->loop_block = lp_build_insert_new_block(mask->bld->gallivm, "bgnloop");
1796299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuildBr(builder, mask->loop_block);
1806299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMPositionBuilderAtEnd(builder, mask->loop_block);
18118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
1826299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->break_mask = LLVMBuildLoad(builder, mask->break_var, "");
1832d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
18418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
18518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
18618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
18718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_break(struct lp_exec_mask *mask)
18818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
1896299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
1906299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMValueRef exec_mask = LLVMBuildNot(builder,
19118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
19218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "break");
19318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
1946299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->break_mask = LLVMBuildAnd(builder,
195d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   mask->break_mask,
196d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                   exec_mask, "break_full");
19718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
19818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
19918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
20018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
20118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusinstatic void lp_exec_continue(struct lp_exec_mask *mask)
20218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
2036299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
2046299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMValueRef exec_mask = LLVMBuildNot(builder,
20518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         mask->exec_mask,
20618d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin                                         "");
20718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2086299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->cont_mask = LLVMBuildAnd(builder,
209d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  mask->cont_mask,
210d2b6ed7c4daf094bfe3fa4e0318133d0a8ea3cf6Zack Rusin                                  exec_mask, "");
21118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
21218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
21318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
21418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
21518d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
216efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paulstatic void lp_exec_endloop(struct gallivm_state *gallivm,
217efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                            struct lp_exec_mask *mask)
21818d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin{
2196299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
22018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   LLVMBasicBlockRef endloop;
221efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMTypeRef reg_type = LLVMIntTypeInContext(gallivm->context,
222efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                               mask->bld->type.width *
223efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                               mask->bld->type.length);
2247fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   LLVMValueRef i1cond;
2257fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
2267fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   assert(mask->break_mask);
2277fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul
2282d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
2292d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Restore the cont_mask, but don't pop
2302d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
2312d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
2322d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size - 1].cont_mask;
2332d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   lp_exec_mask_update(mask);
2342d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
2352d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   /*
2362d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * Unlike the continue mask, the break_mask must be preserved across loop
2372d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    * iterations
2382d91903882e399e8ea7306fd37d5d214907247e6José Fonseca    */
2396299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuildStore(builder, mask->break_mask, mask->break_var);
2402d91903882e399e8ea7306fd37d5d214907247e6José Fonseca
241d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca   /* i1cond = (mask == 0) */
2427fe93f831d74ce46a161c0b0c89f00b9c18caa2bBrian Paul   i1cond = LLVMBuildICmp(
2436299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      builder,
244d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMIntNE,
2456299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMBuildBitCast(builder, mask->exec_mask, reg_type, ""),
246d42229707ad4be9be5a8e122354be7102d6ec348Jose Fonseca      LLVMConstNull(reg_type), "");
24718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
248efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   endloop = lp_build_insert_new_block(mask->bld->gallivm, "endloop");
24918d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2506299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuildCondBr(builder,
251ac33e7752d22f03db84e6a4c822b3a3f41d05f77Zack Rusin                   i1cond, mask->loop_block, endloop);
25218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2536299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMPositionBuilderAtEnd(builder, endloop);
25418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
2552d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   assert(mask->loop_stack_size);
2562d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   --mask->loop_stack_size;
2572d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->loop_block = mask->loop_stack[mask->loop_stack_size].loop_block;
2582d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->cont_mask = mask->loop_stack[mask->loop_stack_size].cont_mask;
2592d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_mask = mask->loop_stack[mask->loop_stack_size].break_mask;
2602d91903882e399e8ea7306fd37d5d214907247e6José Fonseca   mask->break_var = mask->loop_stack[mask->loop_stack_size].break_var;
26118d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
26218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   lp_exec_mask_update(mask);
26318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin}
26418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
26518a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin/* stores val into an address pointed to by dst.
26618a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * mask->exec_mask is used to figure out which bits of val
26718a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * should be stored into the address
26818a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin * (0 means don't store this bit, 1 means do store).
26918a4a83ddab7655253fdb71d37393a32adcda488Zack Rusin */
27080f3cc36c511f62666162bca1d88c7746b98a27dZack Rusinstatic void lp_exec_mask_store(struct lp_exec_mask *mask,
271639fbe2e75bb23a72262a7bc60d69d026b649609Dave Airlie                               struct lp_build_context *bld_store,
272ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                               LLVMValueRef pred,
27380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef val,
27480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                               LLVMValueRef dst)
27580f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin{
2766299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
2776299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul
278ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   /* Mix the predicate and execution mask */
27980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   if (mask->has_mask) {
280ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (pred) {
2816299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         pred = LLVMBuildAnd(builder, pred, mask->exec_mask, "");
282ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
283ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred = mask->exec_mask;
284ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
285ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
286ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
287ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (pred) {
28880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin      LLVMValueRef real_val, dst_val;
28980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
2906299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      dst_val = LLVMBuildLoad(builder, dst, "");
291639fbe2e75bb23a72262a7bc60d69d026b649609Dave Airlie      real_val = lp_build_select(bld_store,
292ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                 pred,
29380f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin                                 val, dst_val);
29480f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
2956299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMBuildStore(builder, real_val, dst);
29680f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin   } else
2976299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMBuildStore(builder, val, dst);
29880f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin}
29980f3cc36c511f62666162bca1d88c7746b98a27dZack Rusin
3000b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_call(struct lp_exec_mask *mask,
3010b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int func,
3020b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                              int *pc)
3030b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
30432a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size < LP_MAX_TGSI_NESTING);
3050b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack[mask->call_stack_size].pc = *pc;
30632a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack[mask->call_stack_size].ret_mask = mask->ret_mask;
30732a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->call_stack_size++;
3080b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = func;
3090b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
3100b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3110b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
3120b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
3136299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = mask->bld->gallivm->builder;
3140b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   LLVMValueRef exec_mask;
31532a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca
3160b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (mask->call_stack_size == 0) {
3170b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      /* returning from main() */
3180b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      *pc = -1;
3190b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      return;
3200b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
3216299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   exec_mask = LLVMBuildNot(builder,
3220b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            mask->exec_mask,
3230b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin                            "ret");
3240b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3256299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   mask->ret_mask = LLVMBuildAnd(builder,
32632a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 mask->ret_mask,
32732a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca                                 exec_mask, "ret_full");
3280b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3290b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   lp_exec_mask_update(mask);
3300b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
3310b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3320b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_bgnsub(struct lp_exec_mask *mask)
3330b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
3340b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
3350b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
3360b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusinstatic void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
3370b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin{
33832a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   assert(mask->call_stack_size);
3390b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   mask->call_stack_size--;
3400b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   *pc = mask->call_stack[mask->call_stack_size].pc;
34132a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   mask->ret_mask = mask->call_stack[mask->call_stack_size].ret_mask;
34232a7209c0a0d5ae63f12056ed969087d942c6298José Fonseca   lp_exec_mask_update(mask);
3430b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin}
34486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
345695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul
346695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul/**
347695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * Return pointer to a temporary register channel (src or dest).
348f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul * Note that indirect addressing cannot be handled here.
349695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param index  which temporary register
350695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul * \param chan  which channel of the temp register.
351695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul */
352bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom StellardLLVMValueRef
353bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardlp_get_temp_ptr_soa(struct lp_build_tgsi_soa_context *bld,
354263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca             unsigned index,
355f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul             unsigned chan)
356263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca{
357bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
358263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   assert(chan < 4);
3593662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
360bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef lindex = lp_build_const_int32(bld->bld_base.base.gallivm, index * 4 + chan);
3616299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      return LLVMBuildGEP(builder, bld->temps_array, &lindex, 1, "");
362263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca   }
363695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   else {
364695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul      return bld->temps[index][chan];
365695814a15b4d64e1fa829d51f18c4089837929c3Brian Paul   }
366263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca}
367263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca
368528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin/**
369528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * Return pointer to a output register channel (src or dest).
370528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * Note that indirect addressing cannot be handled here.
371528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * \param index  which output register
372528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin * \param chan  which channel of the output register.
373528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin */
374bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom StellardLLVMValueRef
375bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardlp_get_output_ptr(struct lp_build_tgsi_soa_context *bld,
376528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin               unsigned index,
377528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin               unsigned chan)
378528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin{
379bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
380528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   assert(chan < 4);
381528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) {
382bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef lindex = lp_build_const_int32(bld->bld_base.base.gallivm,
383efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                                 index * 4 + chan);
3846299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      return LLVMBuildGEP(builder, bld->outputs_array, &lindex, 1, "");
385528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   }
386528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   else {
387528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      return bld->outputs[index][chan];
388528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin   }
389528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin}
390528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
3914363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul/**
3924363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * Gather vector.
3934363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * XXX the lp_build_gather() function should be capable of doing this
3944363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul * with a little work.
3954363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul */
3964363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paulstatic LLVMValueRef
397f667a6f3cefbfb33478de87c166f7a52ed388fb4Dave Airliebuild_gather(struct lp_build_context *bld,
3984363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef base_ptr,
3994363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul             LLVMValueRef indexes)
4004363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul{
401f667a6f3cefbfb33478de87c166f7a52ed388fb4Dave Airlie   LLVMBuilderRef builder = bld->gallivm->builder;
402f667a6f3cefbfb33478de87c166f7a52ed388fb4Dave Airlie   LLVMValueRef res = bld->undef;
4034363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   unsigned i;
4044363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4054363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   /*
4064363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    * Loop over elements of index_vec, load scalar value, insert it into 'res'.
4074363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul    */
408f667a6f3cefbfb33478de87c166f7a52ed388fb4Dave Airlie   for (i = 0; i < bld->type.length; i++) {
409f667a6f3cefbfb33478de87c166f7a52ed388fb4Dave Airlie      LLVMValueRef ii = lp_build_const_int32(bld->gallivm, i);
4106299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMValueRef index = LLVMBuildExtractElement(builder,
4114363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul                                                   indexes, ii, "");
4126299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr,
4133ded3e98ffc36820c8ab318d736eab99bb16f26bBrian Paul                                             &index, 1, "gather_ptr");
4146299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      LLVMValueRef scalar = LLVMBuildLoad(builder, scalar_ptr, "");
4154363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4166299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      res = LLVMBuildInsertElement(builder, res, scalar, ii, "");
4174363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   }
4184363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4194363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul   return res;
4204363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul}
4214363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
4224363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
42363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
4242fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul * Scatter/store vector.
4252fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul */
4262fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paulstatic void
427e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paulemit_mask_scatter(struct lp_build_tgsi_soa_context *bld,
428e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef base_ptr,
429e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef indexes,
430e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef values,
431e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  struct lp_exec_mask *mask,
432e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                  LLVMValueRef pred)
4332fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul{
434bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
43514746b1d4fc7ae30b557dacc819b81756df2f72fBrian Paul   LLVMBuilderRef builder = gallivm->builder;
4362fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   unsigned i;
4372fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
438e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   /* Mix the predicate and execution mask */
439e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   if (mask->has_mask) {
440e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      if (pred) {
4416299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         pred = LLVMBuildAnd(builder, pred, mask->exec_mask, "");
442e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
443e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      else {
444e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         pred = mask->exec_mask;
445e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
446e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul   }
447e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul
4482fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   /*
4492fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul    * Loop over elements of index_vec, store scalar value.
4502fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul    */
451bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   for (i = 0; i < bld->bld_base.base.type.length; i++) {
452efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef ii = lp_build_const_int32(gallivm, i);
4532fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef index = LLVMBuildExtractElement(builder, indexes, ii, "");
4542fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, &index, 1, "scatter_ptr");
4552fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul      LLVMValueRef val = LLVMBuildExtractElement(builder, values, ii, "scatter_val");
456e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      LLVMValueRef scalar_pred = pred ?
457e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMBuildExtractElement(builder, pred, ii, "scatter_pred") : NULL;
4582fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
459ede232e9898698258391a280a098a7ba951b0099Brian Paul      if (0)
460efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         lp_build_printf(gallivm, "scatter %d: val %f at %d %p\n",
461ede232e9898698258391a280a098a7ba951b0099Brian Paul                         ii, val, index, scalar_ptr);
462ede232e9898698258391a280a098a7ba951b0099Brian Paul
463e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      if (scalar_pred) {
464e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMValueRef real_val, dst_val;
465e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         dst_val = LLVMBuildLoad(builder, scalar_ptr, "");
466e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         real_val = lp_build_select(&bld->elem_bld, scalar_pred, val, dst_val);
467e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMBuildStore(builder, real_val, scalar_ptr);
468e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
469e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      else {
470e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         LLVMBuildStore(builder, val, scalar_ptr);
471e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul      }
4722fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul   }
4732fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul}
4742fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
4752fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
4762fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul/**
4770115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * Read the current value of the ADDR register, convert the floats to
4782fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul * ints, add the base index and return the vector of offsets.
4790115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * The offsets will be used to index into the constant buffer or
4800115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul * temporary register file.
4810115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul */
4820115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paulstatic LLVMValueRef
4836d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonsecaget_indirect_index(struct lp_build_tgsi_soa_context *bld,
4846d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                   unsigned reg_file, unsigned reg_index,
4856d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                   const struct tgsi_src_register *indirect_reg)
4860115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul{
487bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
48866461aa249a95053fd5887df75ab791558c3a486Dave Airlie   struct lp_build_context *uint_bld = &bld->bld_base.uint_bld;
4890115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* always use X component of address register */
4903d5b9c1f2d3340259dd0d8765090a5a963074f29José Fonseca   unsigned swizzle = indirect_reg->SwizzleX;
4916d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef base;
4926d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef rel;
4936d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef max_index;
4946d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef index;
4950115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
4966d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(bld->indirect_files & (1 << reg_file));
4976d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
498bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   base = lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type, reg_index);
4996d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5006d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(swizzle < 4);
5016299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   rel = LLVMBuildLoad(builder,
5026d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                        bld->addr[indirect_reg->Index][swizzle],
5036d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                        "load addr reg");
5040115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5050115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul   /* for indexing we want integers */
5066299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   rel = LLVMBuildFPToSI(builder,
5076d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                         rel,
5086d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                         uint_bld->vec_type, "");
5096d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5106d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   index = lp_build_add(uint_bld, base, rel);
5110115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
512bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   max_index = lp_build_const_int_vec(bld->bld_base.base.gallivm,
513efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                      uint_bld->type,
514bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                      bld->bld_base.info->file_max[reg_file]);
5150115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
5166d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(!uint_bld->type.sign);
5176d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   index = lp_build_min(uint_bld, index, max_index);
5186d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
5196d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   return index;
5200115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul}
5210115f07507fc661a0a19564c496a781c3dcbc7a0Brian Paul
52263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic LLVMValueRef
523bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardemit_fetch_constant(
524bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
525bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct tgsi_full_src_register * reg,
526bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const unsigned swizzle)
52763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
528bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
529bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct gallivm_state *gallivm = bld_base->base.gallivm;
5306299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul   LLVMBuilderRef builder = gallivm->builder;
53166461aa249a95053fd5887df75ab791558c3a486Dave Airlie   struct lp_build_context *uint_bld = &bld_base->uint_bld;
5326d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef indirect_index = NULL;
53363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
534bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   /* XXX: Handle fetching xyzw components as a vector */
535bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   assert(swizzle != ~0);
53685c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul
53785c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   if (reg->Register.Indirect) {
5386d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      indirect_index = get_indirect_index(bld,
5396d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.File,
5406d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.Index,
5416d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          &reg->Indirect);
54285c6799f6e2645e708eb03201e91f3285de7d9e1Brian Paul   }
543ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
544bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (reg->Register.Indirect) {
545bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef swizzle_vec =
546bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type, swizzle);
547bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef index_vec;  /* index into the const buffer */
5484363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
549bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* index_vec = indirect_index * 4 + swizzle */
550bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
551bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
5524363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
553bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* Gather values from the constant buffer */
554f667a6f3cefbfb33478de87c166f7a52ed388fb4Dave Airlie      return build_gather(&bld_base->base, bld->consts_ptr, index_vec);
555bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   }
556bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   else {
557bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef index;  /* index into the const buffer */
558bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef scalar, scalar_ptr;
559ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
560bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      index = lp_build_const_int32(gallivm, reg->Register.Index*4 + swizzle);
5614363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
562bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      scalar_ptr = LLVMBuildGEP(builder, bld->consts_ptr,
563be22e1e781094decfb408ad6d74e3d833b297c87Brian Paul                                   &index, 1, "");
564bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      scalar = LLVMBuildLoad(builder, scalar_ptr, "");
5654363d4d0b945c4ca6c303fb337e1fac39e6e1ad6Brian Paul
566bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      return lp_build_broadcast_scalar(&bld->bld_base.base, scalar);
567bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   }
568bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
56963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
570bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic LLVMValueRef
571bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardemit_fetch_immediate(
572bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
573bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct tgsi_full_src_register * reg,
574bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const unsigned swizzle)
575bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
576bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
577bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef res = bld->immediates[reg->Register.Index][swizzle];
578bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   assert(res);
579bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   return res;
580bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
58163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
582bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic LLVMValueRef
583bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardemit_fetch_input(
584bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
585bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct tgsi_full_src_register * reg,
586bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const unsigned swizzle)
587bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
588bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
589bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
590bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMBuilderRef builder = gallivm->builder;
59166461aa249a95053fd5887df75ab791558c3a486Dave Airlie   struct lp_build_context *uint_bld = &bld_base->uint_bld;
592bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef indirect_index = NULL;
593bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef res;
594f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
595bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (reg->Register.Indirect) {
596bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      indirect_index = get_indirect_index(bld,
597bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                          reg->Register.File,
598bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                          reg->Register.Index,
599bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                          &reg->Indirect);
600bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   }
601f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
602bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (reg->Register.Indirect) {
603bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef swizzle_vec =
604bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         lp_build_const_int_vec(gallivm, uint_bld->type, swizzle);
605bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef length_vec =
606bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         lp_build_const_int_vec(gallivm, uint_bld->type, bld->bld_base.base.type.length);
607bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef index_vec;  /* index into the const buffer */
608bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef inputs_array;
609bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMTypeRef float4_ptr_type;
610bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
611bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* index_vec = (indirect_index * 4 + swizzle) * length */
612bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
613bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
614bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
615bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
616bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* cast inputs_array pointer to float* */
617bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      float4_ptr_type = LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
618bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      inputs_array = LLVMBuildBitCast(builder, bld->inputs_array,
6196299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul                                         float4_ptr_type, "");
620f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
621bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* Gather values from the temporary register array */
622f667a6f3cefbfb33478de87c166f7a52ed388fb4Dave Airlie      res = build_gather(&bld_base->base, inputs_array, index_vec);
623bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   } else {
624bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) {
625bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         LLVMValueRef lindex = lp_build_const_int32(gallivm,
626bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                        reg->Register.Index * 4 + swizzle);
627bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         LLVMValueRef input_ptr =  LLVMBuildGEP(builder,
628bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                                bld->inputs_array, &lindex, 1, "");
629bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         res = LLVMBuildLoad(builder, input_ptr, "");
630105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      }
631105ed7dfd4abc94db1ce0cba2967ac0491158389Brian Paul      else {
632bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         res = bld->inputs[reg->Register.Index][swizzle];
63363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
634bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   }
635bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   assert(res);
636bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   return res;
637bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
6381d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul
639bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic LLVMValueRef
640bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardemit_fetch_temporary(
641bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
642bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct tgsi_full_src_register * reg,
643bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const unsigned swizzle)
644bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
645bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
646bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
647bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMBuilderRef builder = gallivm->builder;
64866461aa249a95053fd5887df75ab791558c3a486Dave Airlie   struct lp_build_context *uint_bld = &bld_base->uint_bld;
649bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef indirect_index = NULL;
650bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef res;
6511d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul
652bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (reg->Register.Indirect) {
653bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      indirect_index = get_indirect_index(bld,
654bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                          reg->Register.File,
655bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                          reg->Register.Index,
656bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                          &reg->Indirect);
65763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
65863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
659bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (reg->Register.Indirect) {
660bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef swizzle_vec =
661bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type, swizzle);
662bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef length_vec =
663bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type,
664bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                bld->bld_base.base.type.length);
665bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef index_vec;  /* index into the const buffer */
666bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef temps_array;
667bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMTypeRef float4_ptr_type;
668bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
669bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* index_vec = (indirect_index * 4 + swizzle) * length */
670bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
671bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
672bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
673bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
674bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* cast temps_array pointer to float* */
675bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      float4_ptr_type = LLVMPointerType(LLVMFloatTypeInContext(bld->bld_base.base.gallivm->context), 0);
676bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      temps_array = LLVMBuildBitCast(builder, bld->temps_array,
677bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                     float4_ptr_type, "");
678bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
679bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* Gather values from the temporary register array */
680f667a6f3cefbfb33478de87c166f7a52ed388fb4Dave Airlie      res = build_gather(&bld_base->base, temps_array, index_vec);
681e1e03ce4928edf4ea0ef43d853cb869f70b126aaJosé Fonseca   }
682bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   else {
683bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef temp_ptr;
684bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle);
685bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      res = LLVMBuildLoad(builder, temp_ptr, "");
686bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (!res)
687bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         return bld->bld_base.base.undef;
68863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
68963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
69063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   return res;
69163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
69263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
693bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic LLVMValueRef
694bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardemit_fetch_system_value(
695bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
696bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct tgsi_full_src_register * reg,
697bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const unsigned swizzle)
698bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
699bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
700bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
701bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMBuilderRef builder = gallivm->builder;
702bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef index;  /* index into the system value array */
703bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef scalar, scalar_ptr;
704bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
705bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   assert(!reg->Register.Indirect);
706bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
707bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   index = lp_build_const_int32(gallivm, reg->Register.Index * 4 + swizzle);
708bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
709bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   scalar_ptr = LLVMBuildGEP(builder, bld->system_values_array, &index, 1, "");
710bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   scalar = LLVMBuildLoad(builder, scalar_ptr, "");
711bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
712bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   return lp_build_broadcast_scalar(&bld->bld_base.base, scalar);
713bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
71463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
71563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
71686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca * Register fetch with derivatives.
71786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca */
71886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecastatic void
71986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonsecaemit_fetch_deriv(
72086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   struct lp_build_tgsi_soa_context *bld,
721bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef src,
72286226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *res,
72386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddx,
72486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   LLVMValueRef *ddy)
72586226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca{
72686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(res)
72786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca      *res = src;
72886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
72986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   /* TODO: use interpolation coeffs for inputs */
73086226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
73186226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddx)
732bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      *ddx = lp_build_ddx(&bld->bld_base.base, src);
73386226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
73486226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca   if(ddy)
735bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      *ddy = lp_build_ddy(&bld->bld_base.base, src);
73686226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca}
73786226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
73886226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca
73986226d5ea186d3fc6013bc40a341e0c0a891de39José Fonseca/**
740ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca * Predicate.
741ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca */
742ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecastatic void
743ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonsecaemit_fetch_predicate(
744ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
745ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   const struct tgsi_full_instruction *inst,
746ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef *pred)
747ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca{
748bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
749ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned index;
750ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned char swizzles[4];
751ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef unswizzled[4] = {NULL, NULL, NULL, NULL};
752ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef value;
753ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   unsigned chan;
754ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
755ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   if (!inst->Instruction.Predicate) {
75682b71db03ddaf0eed504412c9169db37cf9bdadcTom Stellard      TGSI_FOR_EACH_CHANNEL( chan ) {
757ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         pred[chan] = NULL;
758ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
759ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      return;
760ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
761ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
762ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[0] = inst->Predicate.SwizzleX;
763ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[1] = inst->Predicate.SwizzleY;
764ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[2] = inst->Predicate.SwizzleZ;
765ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   swizzles[3] = inst->Predicate.SwizzleW;
766ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
767ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   index = inst->Predicate.Index;
768ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   assert(index < LP_MAX_TGSI_PREDS);
769ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
77082b71db03ddaf0eed504412c9169db37cf9bdadcTom Stellard   TGSI_FOR_EACH_CHANNEL( chan ) {
771ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      unsigned swizzle = swizzles[chan];
772ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
773ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      /*
774ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * Only fetch the predicate register channels that are actually listed
775ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       * in the swizzles
776ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca       */
777ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      if (!unswizzled[swizzle]) {
7786299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         value = LLVMBuildLoad(builder,
779263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca                               bld->preds[index][swizzle], "");
780ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
781ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         /*
782ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * Convert the value to an integer mask.
783ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          *
784ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * TODO: Short-circuit this comparison -- a D3D setp_xx instructions
785ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * is needlessly causing two comparisons due to storing the intermediate
786ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          * result as float vector instead of an integer mask vector.
787ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca          */
788bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         value = lp_build_compare(bld->bld_base.base.gallivm,
789bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                  bld->bld_base.base.type,
790ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  PIPE_FUNC_NOTEQUAL,
791ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca                                  value,
792bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                  bld->bld_base.base.zero);
793ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         if (inst->Predicate.Negate) {
7946299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul            value = LLVMBuildNot(builder, value, "");
795ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         }
796ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
797ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         unswizzled[swizzle] = value;
798ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      } else {
799ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         value = unswizzled[swizzle];
800ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      }
801ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
802ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca      pred[chan] = value;
803ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   }
804ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca}
805ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
806ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
807ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca/**
80863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * Register store.
80963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
81063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
811bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardemit_store_chan(
812bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context *bld_base,
81363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   const struct tgsi_full_instruction *inst,
8142fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca   unsigned index,
81563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index,
816ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca   LLVMValueRef pred,
81763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   LLVMValueRef value)
81863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
819bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
820bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
82114746b1d4fc7ae30b557dacc819b81756df2f72fBrian Paul   LLVMBuilderRef builder = gallivm->builder;
8227d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_dst_register *reg = &inst->Dst[index];
82366461aa249a95053fd5887df75ab791558c3a486Dave Airlie   struct lp_build_context *uint_bld = &bld_base->uint_bld;
8246d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   LLVMValueRef indirect_index = NULL;
825639fbe2e75bb23a72262a7bc60d69d026b649609Dave Airlie   struct lp_build_context *bld_store;
826639fbe2e75bb23a72262a7bc60d69d026b649609Dave Airlie
827639fbe2e75bb23a72262a7bc60d69d026b649609Dave Airlie   bld_store = &bld->bld_base.base;
8282fef9b3369d1b017a5360d53a75286234ace2c9dJosé Fonseca
82963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   switch( inst->Instruction.Saturate ) {
83063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_NONE:
83163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
83263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
83363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_ZERO_ONE:
834bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      value = lp_build_max(&bld->bld_base.base, value, bld->bld_base.base.zero);
835bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      value = lp_build_min(&bld->bld_base.base, value, bld->bld_base.base.one);
83663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
83763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
83863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_SAT_MINUS_PLUS_ONE:
839bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      value = lp_build_max(&bld->bld_base.base, value, lp_build_const_vec(bld->bld_base.base.gallivm, bld->bld_base.base.type, -1.0));
840bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      value = lp_build_min(&bld->bld_base.base, value, bld->bld_base.base.one);
84163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
8427926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca
8437926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca   default:
8447926b42d41058e5d2b99ba0e8810f93bc7c12d36José Fonseca      assert(0);
84563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
84663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
847021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   if (reg->Register.Indirect) {
8486d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca      indirect_index = get_indirect_index(bld,
8496d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.File,
8506d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          reg->Register.Index,
8516d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca                                          &reg->Indirect);
8526d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   } else {
853bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      assert(reg->Register.Index <=
854bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                             bld->bld_base.info->file_max[reg->Register.File]);
855021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin   }
856021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin
8575b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell   switch( reg->Register.File ) {
85863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_OUTPUT:
859528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      if (reg->Register.Indirect) {
860528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef chan_vec =
861efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(gallivm, uint_bld->type, chan_index);
862528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef length_vec =
863bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            lp_build_const_int_vec(gallivm, uint_bld->type, bld->bld_base.base.type.length);
864528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef index_vec;  /* indexes into the temp registers */
865528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef outputs_array;
866528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMValueRef pixel_offsets;
867528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         LLVMTypeRef float_ptr_type;
868528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         int i;
869528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
870528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         /* build pixel offset vector: {0, 1, 2, 3, ...} */
871528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         pixel_offsets = uint_bld->undef;
872bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         for (i = 0; i < bld->bld_base.base.type.length; i++) {
873efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            LLVMValueRef ii = lp_build_const_int32(gallivm, i);
874528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin            pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
875528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                                   ii, ii, "");
876528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         }
877528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
878528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */
879528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
880528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_add(uint_bld, index_vec, chan_vec);
881528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
882528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
883528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
884efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         float_ptr_type =
885efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
886528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         outputs_array = LLVMBuildBitCast(builder, bld->outputs_array,
887528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                          float_ptr_type, "");
888528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
889528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         /* Scatter store values into temp registers */
890528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         emit_mask_scatter(bld, outputs_array, index_vec, value,
891528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                           &bld->exec_mask, pred);
892528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      }
893528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      else {
894bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         LLVMValueRef out_ptr = lp_get_output_ptr(bld, reg->Register.Index,
895528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                               chan_index);
896639fbe2e75bb23a72262a7bc60d69d026b649609Dave Airlie         lp_exec_mask_store(&bld->exec_mask, bld_store, pred, value, out_ptr);
897528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin      }
89863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
89963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
900f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul   case TGSI_FILE_TEMPORARY:
901f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      if (reg->Register.Indirect) {
9022fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef chan_vec =
903efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(gallivm, uint_bld->type, chan_index);
9042fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef length_vec =
905efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            lp_build_const_int_vec(gallivm, uint_bld->type,
906bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                   bld->bld_base.base.type.length);
9072fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef index_vec;  /* indexes into the temp registers */
9082fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMValueRef temps_array;
909ede232e9898698258391a280a098a7ba951b0099Brian Paul         LLVMValueRef pixel_offsets;
9102fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         LLVMTypeRef float_ptr_type;
911ede232e9898698258391a280a098a7ba951b0099Brian Paul         int i;
912ede232e9898698258391a280a098a7ba951b0099Brian Paul
913ede232e9898698258391a280a098a7ba951b0099Brian Paul         /* build pixel offset vector: {0, 1, 2, 3, ...} */
914ede232e9898698258391a280a098a7ba951b0099Brian Paul         pixel_offsets = uint_bld->undef;
915bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         for (i = 0; i < bld->bld_base.base.type.length; i++) {
916efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            LLVMValueRef ii = lp_build_const_int32(gallivm, i);
917ede232e9898698258391a280a098a7ba951b0099Brian Paul            pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
918ede232e9898698258391a280a098a7ba951b0099Brian Paul                                                   ii, ii, "");
919ede232e9898698258391a280a098a7ba951b0099Brian Paul         }
9202fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
921ede232e9898698258391a280a098a7ba951b0099Brian Paul         /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */
9222fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
9232fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_add(uint_bld, index_vec, chan_vec);
9242fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
925ede232e9898698258391a280a098a7ba951b0099Brian Paul         index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
9262fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
927efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul         float_ptr_type =
928efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
929ede232e9898698258391a280a098a7ba951b0099Brian Paul         temps_array = LLVMBuildBitCast(builder, bld->temps_array,
9302fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul                                        float_ptr_type, "");
9312fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul
9322fefbc79ac8bb55197ff817feeca2626585d7a8cBrian Paul         /* Scatter store values into temp registers */
933e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul         emit_mask_scatter(bld, temps_array, index_vec, value,
934e7f5d19a1106351f2db8f62f59f51be86eaa93dfBrian Paul                           &bld->exec_mask, pred);
935f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
936f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      else {
937bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         LLVMValueRef temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index,
938f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul                                              chan_index);
939639fbe2e75bb23a72262a7bc60d69d026b649609Dave Airlie         lp_exec_mask_store(&bld->exec_mask, bld_store, pred, value, temp_ptr);
940f674ed6b0662a15ab8298da0848a4c82694e0c95Brian Paul      }
94163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
94263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
94363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_FILE_ADDRESS:
944639fbe2e75bb23a72262a7bc60d69d026b649609Dave Airlie      lp_exec_mask_store(&bld->exec_mask, bld_store, pred, value,
945557280542399629ac64a48f5b618365e2b18fce1Zack Rusin                         bld->addr[reg->Register.Index][chan_index]);
94663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
94763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
948ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca   case TGSI_FILE_PREDICATE:
949639fbe2e75bb23a72262a7bc60d69d026b649609Dave Airlie      lp_exec_mask_store(&bld->exec_mask, bld_store, pred, value,
9508690c6a6b4fb0b48e2ae75cd0f64de86b039081cmichal                         bld->preds[reg->Register.Index][chan_index]);
951ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca      break;
952ccf57af93f7118a044fa21e874847fa3ed555bcaJosé Fonseca
95363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
95463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert( 0 );
95563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
95663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
95763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
958bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
959bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardemit_store(
960bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
961bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct tgsi_full_instruction * inst,
962bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct tgsi_opcode_info * info,
963bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef dst[4])
964bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
965bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
966bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   unsigned chan_index;
967bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
968bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
969bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if(info->num_dst) {
970bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef pred[TGSI_NUM_CHANNELS];
971bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
972bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      emit_fetch_predicate( bld, inst, pred );
973bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
974bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
975bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         emit_store_chan(bld_base, inst, 0, chan_index, pred[chan_index], dst[chan_index]);
976bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      }
977bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   }
978bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
97963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
98063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
98163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca * High-level instruction translators.
98263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca */
98363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
98463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
98563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_tex( struct lp_build_tgsi_soa_context *bld,
98663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca          const struct tgsi_full_instruction *inst,
98758daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca          enum lp_build_tex_modifier modifier,
988faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca          LLVMValueRef *texel)
98963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
990bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
991962558daaed43b0111cd062e32821aad106869d7José Fonseca   unsigned unit;
992ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   LLVMValueRef lod_bias, explicit_lod;
99331d1822473bf9d4105bb82b67572cfeea53aaf94Vinson Lee   LLVMValueRef oow = NULL;
994c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   LLVMValueRef coords[3];
995962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddx[3];
996962558daaed43b0111cd062e32821aad106869d7José Fonseca   LLVMValueRef ddy[3];
997c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   unsigned num_coords;
99863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned i;
99963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
10009db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   if (!bld->sampler) {
10019db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      _debug_printf("warning: found texture instruction but no sampler generator supplied\n");
10029db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      for (i = 0; i < 4; i++) {
1003bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         texel[i] = bld->bld_base.base.undef;
10049db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      }
10059db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca      return;
10069db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca   }
10079db4a211e96356deb963223038eea074a5fe0edaJosé Fonseca
10087d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   switch (inst->Texture.Texture) {
100963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_1D:
1010c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 1;
101163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
1012d8452a0be810d7176b0cbfe6632fc0f8016b5733Marek Olšák   case TGSI_TEXTURE_1D_ARRAY:
101363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_2D:
101463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_RECT:
1015c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 2;
101663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
1017f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW1D:
1018d8452a0be810d7176b0cbfe6632fc0f8016b5733Marek Olšák   case TGSI_TEXTURE_SHADOW1D_ARRAY:
1019f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOW2D:
1020f04ce6276b64f24cf26ca522f012a1e1a28937feJosé Fonseca   case TGSI_TEXTURE_SHADOWRECT:
1021d8452a0be810d7176b0cbfe6632fc0f8016b5733Marek Olšák   case TGSI_TEXTURE_2D_ARRAY:
102263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_3D:
102363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   case TGSI_TEXTURE_CUBE:
1024c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca      num_coords = 3;
102563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      break;
1026d8452a0be810d7176b0cbfe6632fc0f8016b5733Marek Olšák   case TGSI_TEXTURE_SHADOW2D_ARRAY:
1027d8452a0be810d7176b0cbfe6632fc0f8016b5733Marek Olšák      num_coords = 4;
1028d8452a0be810d7176b0cbfe6632fc0f8016b5733Marek Olšák      break;
102963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   default:
103063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      assert(0);
103163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      return;
103263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
103363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
103458daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS) {
1035bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      lod_bias = lp_build_emit_fetch( &bld->bld_base, inst, 0, 3 );
1036ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
1037ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
103858daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   else if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) {
1039ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
1040bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 3 );
1041ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
1042ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   else {
1043ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      lod_bias = NULL;
1044ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca      explicit_lod = NULL;
1045ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca   }
104663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
104758daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED) {
1048bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      oow = lp_build_emit_fetch( &bld->bld_base, inst, 0, 3 );
1049bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      oow = lp_build_rcp(&bld->bld_base.base, oow);
105063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
105163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1052c40eddd294abfe8af3619d08ccd7e9c8f1660fcbJosé Fonseca   for (i = 0; i < num_coords; i++) {
1053bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      coords[i] = lp_build_emit_fetch( &bld->bld_base, inst, 0, i );
105458daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca      if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED)
1055bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         coords[i] = lp_build_mul(&bld->bld_base.base, coords[i], oow);
105663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
1057ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   for (i = num_coords; i < 3; i++) {
1058bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      coords[i] = bld->bld_base.base.undef;
1059ba33ef00118d1c6017585af1498b89e99fe045beJosé Fonseca   }
106063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
106158daea741fa21fe3f89fd7bf106df1545c5b21afJosé Fonseca   if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) {
1062bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef index0 = lp_build_const_int32(bld->bld_base.base.gallivm, 0);
1063962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
1064bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         LLVMValueRef src1 = lp_build_emit_fetch( &bld->bld_base, inst, 1, i );
1065bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         LLVMValueRef src2 = lp_build_emit_fetch( &bld->bld_base, inst, 2, i );
10666299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         ddx[i] = LLVMBuildExtractElement(builder, src1, index0, "");
10676299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         ddy[i] = LLVMBuildExtractElement(builder, src2, index0, "");
1068962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
1069962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[3].Register.Index;
1070962558daaed43b0111cd062e32821aad106869d7José Fonseca   }  else {
1071962558daaed43b0111cd062e32821aad106869d7José Fonseca      for (i = 0; i < num_coords; i++) {
1072bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         ddx[i] = lp_build_scalar_ddx( &bld->bld_base.base, coords[i] );
1073bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         ddy[i] = lp_build_scalar_ddy( &bld->bld_base.base, coords[i] );
1074962558daaed43b0111cd062e32821aad106869d7José Fonseca      }
1075962558daaed43b0111cd062e32821aad106869d7José Fonseca      unit = inst->Src[1].Register.Index;
1076962558daaed43b0111cd062e32821aad106869d7José Fonseca   }
10774554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   for (i = num_coords; i < 3; i++) {
1078bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      ddx[i] = LLVMGetUndef(bld->bld_base.base.elem_type);
1079bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      ddy[i] = LLVMGetUndef(bld->bld_base.base.elem_type);
10804554cdc289f1d97855825127c0bf8c0e7f6a2edaJosé Fonseca   }
1081962558daaed43b0111cd062e32821aad106869d7José Fonseca
10828be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld->sampler->emit_fetch_texel(bld->sampler,
1083bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                  bld->bld_base.base.gallivm,
1084bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                  bld->bld_base.base.type,
1085962558daaed43b0111cd062e32821aad106869d7José Fonseca                                  unit, num_coords, coords,
1086ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  ddx, ddy,
1087ec43b2eb45a1b2e33f328f76624c987484e329f3José Fonseca                                  lod_bias, explicit_lod,
10888be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca                                  texel);
108963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
109063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
109122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwellstatic boolean
109222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwellnear_end_of_shader(struct lp_build_tgsi_soa_context *bld,
109322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell		   int pc)
109422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell{
109522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   int i;
109622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
109722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   for (i = 0; i < 5; i++) {
109822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      unsigned opcode;
109922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
1100bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (pc + i >= bld->bld_base.info->num_instructions)
110122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return TRUE;
110222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
1103bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      opcode = bld->bld_base.instructions[pc + i].Instruction.Opcode;
110422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
110522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (opcode == TGSI_OPCODE_END)
110622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return TRUE;
110722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
110822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (opcode == TGSI_OPCODE_TEX ||
110922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXP ||
111022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXD ||
111122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXB ||
111222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXL ||
111322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXF ||
111422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_TXQ ||
111522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_CAL ||
111622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_CALLNZ ||
111722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_IF ||
111822ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_IFC ||
111922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_BGNLOOP ||
112022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	  opcode == TGSI_OPCODE_SWITCH)
112122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 return FALSE;
112222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   }
112322ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
112422ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   return TRUE;
112522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell}
112622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
112722ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell
112863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1129feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul/**
1130feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Kill fragment if any of the src register values are negative.
1131feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
113263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecastatic void
113363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonsecaemit_kil(
113463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context *bld,
113522ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   const struct tgsi_full_instruction *inst,
113622ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   int pc)
113763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
1138bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
11397d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell   const struct tgsi_full_src_register *reg = &inst->Src[0];
1140bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef terms[TGSI_NUM_CHANNELS];
11413d7a88674f9eb3320eeff511968f041426e25023José Fonseca   LLVMValueRef mask;
114263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   unsigned chan_index;
114363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11447821664b15501b173b2304bbada758c33c5ff972José Fonseca   memset(&terms, 0, sizeof terms);
114563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
114682b71db03ddaf0eed504412c9169db37cf9bdadcTom Stellard   TGSI_FOR_EACH_CHANNEL( chan_index ) {
114763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      unsigned swizzle;
114863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11497821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Unswizzle channel */
1150b9cb74c7f826dfd320f5e5b54aa933898f7ddd3dKeith Whitwell      swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
115163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11527821664b15501b173b2304bbada758c33c5ff972José Fonseca      /* Check if the component has not been already tested. */
1153bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      assert(swizzle < TGSI_NUM_CHANNELS);
11547821664b15501b173b2304bbada758c33c5ff972José Fonseca      if( !terms[swizzle] )
11557821664b15501b173b2304bbada758c33c5ff972José Fonseca         /* TODO: change the comparison operator instead of setting the sign */
1156bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         terms[swizzle] =  lp_build_emit_fetch(&bld->bld_base, inst, 0, chan_index );
115763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
115863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
11593d7a88674f9eb3320eeff511968f041426e25023José Fonseca   mask = NULL;
116082b71db03ddaf0eed504412c9169db37cf9bdadcTom Stellard   TGSI_FOR_EACH_CHANNEL( chan_index ) {
1161aede39efd86d200ffbace8fc012104e31f673973José Fonseca      if(terms[chan_index]) {
11623d7a88674f9eb3320eeff511968f041426e25023José Fonseca         LLVMValueRef chan_mask;
1163aede39efd86d200ffbace8fc012104e31f673973José Fonseca
1164feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul         /*
1165feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          * If term < 0 then mask = 0 else mask = ~0.
1166feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul          */
1167bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         chan_mask = lp_build_cmp(&bld->bld_base.base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->bld_base.base.zero);
1168aede39efd86d200ffbace8fc012104e31f673973José Fonseca
11693d7a88674f9eb3320eeff511968f041426e25023José Fonseca         if(mask)
11706299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul            mask = LLVMBuildAnd(builder, mask, chan_mask, "");
11713d7a88674f9eb3320eeff511968f041426e25023José Fonseca         else
11723d7a88674f9eb3320eeff511968f041426e25023José Fonseca            mask = chan_mask;
1173aede39efd86d200ffbace8fc012104e31f673973José Fonseca      }
117463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
11753d7a88674f9eb3320eeff511968f041426e25023José Fonseca
1176aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell   if(mask) {
11773d7a88674f9eb3320eeff511968f041426e25023José Fonseca      lp_build_mask_update(bld->mask, mask);
1178aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell
117922ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      if (!near_end_of_shader(bld, pc))
118022ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell	 lp_build_mask_check(bld->mask);
1181aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell   }
118263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
118363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
118463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
118563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca/**
1186feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * Predicated fragment kill.
1187feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * XXX Actually, we do an unconditional kill (as in tgsi_exec.c).
1188feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * The only predication is the execution mask which will apply if
1189feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul * we're inside a loop or conditional.
1190feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul */
1191feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulstatic void
1192feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paulemit_kilp(struct lp_build_tgsi_soa_context *bld,
1193bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard          int pc)
1194feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul{
1195bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
1196feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   LLVMValueRef mask;
1197feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
1198feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   /* For those channels which are "alive", disable fragment shader
1199feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    * execution.
1200feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul    */
1201feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   if (bld->exec_mask.has_mask) {
12026299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul      mask = LLVMBuildNot(builder, bld->exec_mask.exec_mask, "kilp");
1203feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
1204feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   else {
1205bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef zero = LLVMConstNull(bld->bld_base.base.int_vec_type);
1206ec2824cd867d3b782588be1f3b1d5d802eb381abBrian Paul      mask = zero;
1207feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   }
1208feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
1209feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul   lp_build_mask_update(bld->mask, mask);
1210aa4cb5e2d8d48c7dcc9653c61a9e25494e3e7b2aKeith Whitwell
121122ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell   if (!near_end_of_shader(bld, pc))
121222ec25e2bf5c9309610b68e8e40472a8ea695ba9Keith Whitwell      lp_build_mask_check(bld->mask);
1213feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul}
1214feffd259da5f2655222a2f26e2e5665a9e28173fBrian Paul
12155b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12165b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul/**
12175b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul * Emit code which will dump the value of all the temporary registers
12185b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul * to stdout.
12195b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul */
12205b294a5d17c818ecbb1295fdd20825da9b106792Brian Paulstatic void
12215b294a5d17c818ecbb1295fdd20825da9b106792Brian Paulemit_dump_temps(struct lp_build_tgsi_soa_context *bld)
12225b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul{
1223bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
1224efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMBuilderRef builder = gallivm->builder;
12255b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   LLVMValueRef temp_ptr;
1226efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMValueRef i0 = lp_build_const_int32(gallivm, 0);
1227efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMValueRef i1 = lp_build_const_int32(gallivm, 1);
1228efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMValueRef i2 = lp_build_const_int32(gallivm, 2);
1229efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   LLVMValueRef i3 = lp_build_const_int32(gallivm, 3);
12305b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   int index;
1231bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   int n = bld->bld_base.info->file_max[TGSI_FILE_TEMPORARY];
12325b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12335b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   for (index = 0; index < n; index++) {
1234efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMValueRef idx = lp_build_const_int32(gallivm, index);
12355b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      LLVMValueRef v[4][4], res;
12365b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      int chan;
12375b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
1238efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_build_printf(gallivm, "TEMP[%d]:\n", idx);
12395b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12405b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      for (chan = 0; chan < 4; chan++) {
1241bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         temp_ptr = lp_get_temp_ptr_soa(bld, index, chan);
12426299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         res = LLVMBuildLoad(builder, temp_ptr, "");
12435b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][0] = LLVMBuildExtractElement(builder, res, i0, "");
12445b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][1] = LLVMBuildExtractElement(builder, res, i1, "");
12455b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][2] = LLVMBuildExtractElement(builder, res, i2, "");
12465b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul         v[chan][3] = LLVMBuildExtractElement(builder, res, i3, "");
12475b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      }
12485b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
1249efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_build_printf(gallivm, "  X: %f %f %f %f\n",
12505b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[0][0], v[0][1], v[0][2], v[0][3]);
1251efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_build_printf(gallivm, "  Y: %f %f %f %f\n",
12525b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[1][0], v[1][1], v[1][2], v[1][3]);
1253efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_build_printf(gallivm, "  Z: %f %f %f %f\n",
12545b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[2][0], v[2][1], v[2][2], v[2][3]);
1255efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      lp_build_printf(gallivm, "  W: %f %f %f %f\n",
12565b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul                      v[3][0], v[3][1], v[3][2], v[3][3]);
12575b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul   }
12585b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul}
12595b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12605b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
12615b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul
1262bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardvoid
1263bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardlp_emit_declaration_soa(
1264bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context *bld_base,
126585c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   const struct tgsi_full_declaration *decl)
126685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin{
1267bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
1268bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
1269bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMTypeRef vec_type = bld->bld_base.base.vec_type;
127055c5408ad049423597cd274e7abcd2d91a16ead3Brian Paul   const unsigned first = decl->Range.First;
127155c5408ad049423597cd274e7abcd2d91a16ead3Brian Paul   const unsigned last = decl->Range.Last;
127285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   unsigned idx, i;
127385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
127485c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   for (idx = first; idx <= last; ++idx) {
1275bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      assert(last <= bld->bld_base.info->file_max[decl->Declaration.File]);
127685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      switch (decl->Declaration.File) {
127785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_TEMPORARY:
12786c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_TEMPS);
127910740acf46e08960dde790005d65a98440f313bcJosé Fonseca         if (!(bld->indirect_files & (1 << TGSI_FILE_TEMPORARY))) {
1280bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            for (i = 0; i < TGSI_NUM_CHANNELS; i++)
1281efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul               bld->temps[idx][i] = lp_build_alloca(gallivm, vec_type, "temp");
1282021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin         }
128385c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
128485c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
128585c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      case TGSI_FILE_OUTPUT:
128610740acf46e08960dde790005d65a98440f313bcJosé Fonseca         if (!(bld->indirect_files & (1 << TGSI_FILE_OUTPUT))) {
1287bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            for (i = 0; i < TGSI_NUM_CHANNELS; i++)
1288efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul               bld->outputs[idx][i] = lp_build_alloca(gallivm,
1289528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin                                                      vec_type, "output");
1290528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin         }
129185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         break;
129285c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin
1293ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin      case TGSI_FILE_ADDRESS:
12946c8c88f02f0dc9cf39ce51d068525a94fccd5dc7José Fonseca         assert(idx < LP_MAX_TGSI_ADDRS);
1295bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         for (i = 0; i < TGSI_NUM_CHANNELS; i++)
1296efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            bld->addr[idx][i] = lp_build_alloca(gallivm, vec_type, "addr");
1297ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin         break;
1298ded2374e67bdc2c24e868775d2ff77b39b339d56Zack Rusin
1299e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca      case TGSI_FILE_PREDICATE:
1300ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca         assert(idx < LP_MAX_TGSI_PREDS);
1301bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         for (i = 0; i < TGSI_NUM_CHANNELS; i++)
1302efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul            bld->preds[idx][i] = lp_build_alloca(gallivm, vec_type,
1303efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul                                                 "predicate");
1304e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca         break;
1305e27983bc08d4eff5effbbcffbf5c9f5862fca2cfJosé Fonseca
130685c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin      default:
130785c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin         /* don't need to declare other vars */
1308dc886ba1391d7d890bd1f5532bc14553e883a418Zack Rusin         break;
1309012fabca722494162c244a367913562b8cfa4677Zack Rusin      }
131085c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin   }
131185c7ec70ad41c8ada75a4cbace83d16815d3e2c5Zack Rusin}
131263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1313fc9b8cd9dda946d8415732aeeed1eff5541cd1eeBrian Paul
1314bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardvoid lp_emit_immediate_soa(
1315bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context *bld_base,
1316bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct tgsi_full_immediate *imm)
131763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
1318bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
1319bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct gallivm_state * gallivm = bld_base->base.gallivm;
132063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1321bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   /* simply copy the immediate values into the next immediates[] slot */
1322bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   unsigned i;
1323bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const uint size = imm->Immediate.NrTokens - 1;
1324bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   assert(size <= 4);
1325bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   assert(bld->num_immediates < LP_MAX_TGSI_IMMEDIATES);
132689258652b6a1d282bed14549907892bdfda752f0José Fonseca
1327bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   for( i = 0; i < size; ++i )
1328bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      bld->immediates[bld->num_immediates][i] =
1329bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard              lp_build_const_vec(gallivm, bld_base->base.type, imm->u[i].Float);
13300b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1331bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   for( i = size; i < 4; ++i )
1332bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      bld->immediates[bld->num_immediates][i] = bld_base->base.undef;
1333faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca
1334bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld->num_immediates++;
1335bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
133663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1337bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1338bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardddx_emit(
1339bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1340bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1341bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1342bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1343bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
134463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1345bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   emit_fetch_deriv(bld, emit_data->args[0], NULL,
1346bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                    &emit_data->output[emit_data->chan], NULL);
1347bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
134863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1349bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1350bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardddy_emit(
1351bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1352bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1353bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1354bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1355bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
135663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1357bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   emit_fetch_deriv(bld, emit_data->args[0], NULL, NULL,
1358bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                    &emit_data->output[emit_data->chan]);
1359bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
136063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1361bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1362bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardkilp_emit(
1363bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1364bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1365bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1366bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1367bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
136863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1369bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   emit_kilp(bld, bld_base->pc - 1);
1370bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
137163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1372bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1373bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardkil_emit(
1374bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1375bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1376bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1377bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1378bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
137963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1380bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   emit_kil(bld, emit_data->inst, bld_base->pc - 1);
1381bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
138263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1383bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1384bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardtex_emit(
1385bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1386bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1387bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1388bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1389bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
139063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1391bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_NONE, emit_data->output);
1392bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
139363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1394bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1395bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardtxb_emit(
1396bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1397bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1398bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1399bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1400bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
140163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1402bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_LOD_BIAS,
1403bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            emit_data->output);
1404bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
140563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1406bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1407bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardtxd_emit(
1408bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1409bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1410bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1411bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1412bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
141363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1414bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV,
1415bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            emit_data->output);
1416bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
141763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1418bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1419bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardtxl_emit(
1420bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1421bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1422bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1423bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1424bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
142563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1426bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD,
1427bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            emit_data->output);
1428bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
142963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1430bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1431bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardtxp_emit(
1432bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1433bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1434bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1435bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1436bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
143763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1438bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_PROJECTED,
1439bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            emit_data->output);
1440bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
144163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1442bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1443bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardcal_emit(
1444bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1445bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1446bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1447bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1448bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
144963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1450bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_mask_call(&bld->exec_mask, emit_data->inst->Label.Label,
1451bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                     &bld_base->pc);
1452bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
145363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1454bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1455bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardret_emit(
1456bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1457bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1458bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1459bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1460bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
146163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1462bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_mask_ret(&bld->exec_mask, &bld_base->pc);
1463bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
146463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1465bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1466bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardbrk_emit(
1467bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1468bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1469bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1470bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1471bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
147263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1473bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_break(&bld->exec_mask);
1474bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
147563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1476bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1477bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardif_emit(
1478bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1479bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1480bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1481bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1482bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef tmp;
1483bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
148463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1485bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   tmp = lp_build_cmp(&bld_base->base, PIPE_FUNC_NOTEQUAL,
1486bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                      emit_data->args[0], bld->bld_base.base.zero);
1487bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_mask_cond_push(&bld->exec_mask, tmp);
1488bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
148963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1490bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1491bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardbgnloop_emit(
1492bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1493bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1494bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1495bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1496bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
149763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1498bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_bgnloop(&bld->exec_mask);
1499bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
150063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1501bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1502bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardbgnsub_emit(
1503bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1504bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1505bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1506bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1507bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
150863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1509bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_mask_bgnsub(&bld->exec_mask);
1510bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
151163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1512bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1513bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardelse_emit(
1514bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1515bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1516bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1517bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1518bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
151963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1520bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_mask_cond_invert(&bld->exec_mask);
1521bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
152263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1523bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1524bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardendif_emit(
1525bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1526bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1527bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1528bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1529bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
153063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1531bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_mask_cond_pop(&bld->exec_mask);
1532bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
153363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1534bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1535bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardendloop_emit(
1536bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1537bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1538bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1539bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1540bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
154163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1542bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_endloop(bld_base->base.gallivm, &bld->exec_mask);
1543bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
154463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1545bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1546bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardendsub_emit(
1547bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1548bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1549bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1550bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1551bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
155263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1553bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_mask_endsub(&bld->exec_mask, &bld_base->pc);
1554bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
155563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1556bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1557bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardcont_emit(
1558bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1559bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1560bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1561bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1562bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
156363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1564bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_continue(&bld->exec_mask);
1565bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
156663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1567bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard/* XXX: Refactor and move it to lp_bld_tgsi_action.c
1568bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard *
1569bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard * XXX: What do the comments about xmm registers mean?  Maybe they are left over
1570bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard * from old code, but there is no garauntee that LLVM will use those registers
1571bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard * for this code.
1572bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard *
1573bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard * XXX: There should be no calls to lp_build_emit_fetch in this function.  This
1574bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard * should be handled by the emit_data->fetch_args function. */
1575bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void
1576bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardnrm_emit(
1577bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   const struct lp_build_tgsi_action * action,
1578bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_context * bld_base,
1579bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_emit_data * emit_data)
1580bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1581bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef tmp0, tmp1;
1582bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef tmp4 = NULL;
1583bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef tmp5 = NULL;
1584bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef tmp6 = NULL;
1585bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   LLVMValueRef tmp7 = NULL;
1586bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
158763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1588bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   uint dims = (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_NRM) ? 3 : 4;
158963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1590bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard  if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_X) ||
1591bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Y) ||
1592bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Z) ||
1593bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_W) && dims == 4)) {
159463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1595bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* NOTE: Cannot use xmm regs 2/3 here (see emit_rsqrt() above). */
159663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1597bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* xmm4 = src.x */
1598bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* xmm0 = src.x * src.x */
1599bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      tmp0 = lp_build_emit_fetch(&bld->bld_base, emit_data->inst, 0, TGSI_CHAN_X);
1600bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_X)) {
1601bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         tmp4 = tmp0;
16021aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
1603bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      tmp0 = lp_build_mul( &bld->bld_base.base, tmp0, tmp0);
160463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1605bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* xmm5 = src.y */
1606bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* xmm0 = xmm0 + src.y * src.y */
1607bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      tmp1 = lp_build_emit_fetch(&bld->bld_base, emit_data->inst, 0, TGSI_CHAN_Y);
1608bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Y)) {
1609bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         tmp5 = tmp1;
1610873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca      }
1611bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      tmp1 = lp_build_mul( &bld->bld_base.base, tmp1, tmp1);
1612bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      tmp0 = lp_build_add( &bld->bld_base.base, tmp0, tmp1);
161363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1614bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* xmm6 = src.z */
1615bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* xmm0 = xmm0 + src.z * src.z */
1616bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      tmp1 = lp_build_emit_fetch(&bld->bld_base, emit_data->inst, 0, TGSI_CHAN_Z);
1617bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Z)) {
1618bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         tmp6 = tmp1;
161963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
1620bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      tmp1 = lp_build_mul( &bld->bld_base.base, tmp1, tmp1);
1621bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      tmp0 = lp_build_add( &bld->bld_base.base, tmp0, tmp1);
16220b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1623bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (dims == 4) {
1624bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         /* xmm7 = src.w */
1625bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         /* xmm0 = xmm0 + src.w * src.w */
1626bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         tmp1 = lp_build_emit_fetch(&bld->bld_base, emit_data->inst, 0, TGSI_CHAN_W);
1627bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_W)) {
1628bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            tmp7 = tmp1;
1629bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         }
1630bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         tmp1 = lp_build_mul( &bld->bld_base.base, tmp1, tmp1);
1631bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         tmp0 = lp_build_add( &bld->bld_base.base, tmp0, tmp1);
16325b294a5d17c818ecbb1295fdd20825da9b106792Brian Paul      }
1633bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* xmm1 = 1 / sqrt(xmm0) */
1634bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      tmp1 = lp_build_rsqrt( &bld->bld_base.base, tmp0);
1635bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard       /* dst.x = xmm1 * src.x */
1636bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_X)) {
1637bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         emit_data->output[TGSI_CHAN_X] = lp_build_mul( &bld->bld_base.base, tmp4, tmp1);
163863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
1639bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* dst.y = xmm1 * src.y */
1640bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Y)) {
1641bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         emit_data->output[TGSI_CHAN_Y] = lp_build_mul( &bld->bld_base.base, tmp5, tmp1);
16421aae039ee279f8ad300919d8af0fc4691ca2f514José Fonseca      }
164363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1644bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* dst.z = xmm1 * src.z */
1645bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Z)) {
1646bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         emit_data->output[TGSI_CHAN_Z] = lp_build_mul( &bld->bld_base.base, tmp6, tmp1);
164763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
1648bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* dst.w = xmm1 * src.w */
1649bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_X) && dims == 4) {
1650bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         emit_data->output[TGSI_CHAN_W] = lp_build_mul( &bld->bld_base.base, tmp7, tmp1);
165163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
1652bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   }
165318d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin
1654bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   /* dst.w = 1.0 */
1655bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_W) && dims == 3) {
1656bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard       emit_data->output[TGSI_CHAN_W] = bld->bld_base.base.one;
1657bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   }
1658bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
16590b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1660bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void emit_prologue(struct lp_build_tgsi_context * bld_base)
1661bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1662bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
1663bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct gallivm_state * gallivm = bld_base->base.gallivm;
166463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1665bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
1666bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef array_size =
1667bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         lp_build_const_int32(gallivm,
1668bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                         bld_base->info->file_max[TGSI_FILE_TEMPORARY] * 4 + 4);
1669bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      bld->temps_array = lp_build_array_alloca(gallivm,
1670bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                              bld_base->base.vec_type, array_size,
1671bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                              "temp_array");
1672bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   }
167363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1674bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) {
1675bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef array_size =
1676bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         lp_build_const_int32(gallivm,
1677bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                            bld_base->info->file_max[TGSI_FILE_OUTPUT] * 4 + 4);
1678bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      bld->outputs_array = lp_build_array_alloca(gallivm,
1679bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                                bld_base->base.vec_type, array_size,
1680bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                                "output_array");
1681bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   }
168263b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1683bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   /* If we have indirect addressing in inputs we need to copy them into
1684bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard    * our alloca array to be able to iterate over them */
1685bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) {
1686bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      unsigned index, chan;
1687bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMTypeRef vec_type = bld_base->base.vec_type;
1688bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      LLVMValueRef array_size = lp_build_const_int32(gallivm,
1689bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            bld_base->info->file_max[TGSI_FILE_INPUT]*4 + 4);
1690bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      bld->inputs_array = lp_build_array_alloca(gallivm,
1691bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                               vec_type, array_size,
1692bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                                               "input_array");
169363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1694bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      assert(bld_base->info->num_inputs
1695bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                        <= bld_base->info->file_max[TGSI_FILE_INPUT] + 1);
169663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1697bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      for (index = 0; index < bld_base->info->num_inputs; ++index) {
1698bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
1699bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            LLVMValueRef lindex =
1700bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard               lp_build_const_int32(gallivm, index * 4 + chan);
1701bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            LLVMValueRef input_ptr =
1702bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard               LLVMBuildGEP(gallivm->builder, bld->inputs_array,
1703bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                            &lindex, 1, "");
1704bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            LLVMValueRef value = bld->inputs[index][chan];
1705bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            if (value)
1706bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard               LLVMBuildStore(gallivm->builder, value, input_ptr);
1707bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         }
170863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca      }
1709bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   }
1710bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard}
171163b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1712bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellardstatic void emit_epilogue(struct lp_build_tgsi_context * bld_base)
1713bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard{
1714bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
1715873773ee2b034e8df72ddfacc764915b8a76ebe2José Fonseca
1716bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (0) {
1717bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      /* for debugging */
1718bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      emit_dump_temps(bld);
171963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   }
1720ff6c78f44f2f741f4825b07dbc15b3a951fe9b2cJosé Fonseca
1721bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   /* If we have indirect addressing in outputs we need to copy our alloca array
1722bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard    * to the outputs slots specified by the called */
1723bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) {
1724bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      unsigned index, chan;
1725bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      assert(bld_base->info->num_outputs <=
1726bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                        bld_base->info->file_max[TGSI_FILE_OUTPUT] + 1);
1727bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard      for (index = 0; index < bld_base->info->num_outputs; ++index) {
1728bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) {
1729bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard            bld->outputs[index][chan] = lp_get_output_ptr(bld, index, chan);
1730bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard         }
1731faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca      }
1732faec23387e035bcdd413b7364933d36a8ec22dbaJosé Fonseca   }
173363b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
173463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1735c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonsecavoid
1736efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paullp_build_tgsi_soa(struct gallivm_state *gallivm,
173763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  const struct tgsi_token *tokens,
1738b4835ea03d64261da5a892f9590c9977b06920e8José Fonseca                  struct lp_type type,
17393d7a88674f9eb3320eeff511968f041426e25023José Fonseca                  struct lp_build_mask_context *mask,
174063b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca                  LLVMValueRef consts_ptr,
17411d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul                  LLVMValueRef system_values_array,
1742f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca                  const LLVMValueRef *pos,
1743bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                  const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS],
1744bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard                  LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS],
1745021e0dc78b15fab29e761012860276c2597c8d8fZack Rusin                  struct lp_build_sampler_soa *sampler,
17463f6dc8e79d918283a6dfcf9c8937a6d52f3bb4f5Brian Paul                  const struct tgsi_shader_info *info)
174763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca{
174863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   struct lp_build_tgsi_soa_context bld;
174963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
17506d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   struct lp_type res_type;
17516d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
17526d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   assert(type.length <= LP_MAX_VECTOR_LENGTH);
17536d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   memset(&res_type, 0, sizeof res_type);
17546d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.width = type.width;
17556d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.length = type.length;
17566d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca   res_type.sign = 1;
17576d173da5c84142ee64f56f4c2e9e495dc1435e91José Fonseca
175863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   /* Setup build context */
175963b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   memset(&bld, 0, sizeof bld);
1760bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_build_context_init(&bld.bld_base.base, gallivm, type);
176166461aa249a95053fd5887df75ab791558c3a486Dave Airlie   lp_build_context_init(&bld.bld_base.uint_bld, gallivm, lp_uint_type(type));
176266461aa249a95053fd5887df75ab791558c3a486Dave Airlie   lp_build_context_init(&bld.bld_base.int_bld, gallivm, lp_int_type(type));
1763efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul   lp_build_context_init(&bld.elem_bld, gallivm, lp_elem_type(type));
1764c0472f9c34da78bccecb2c790b54b9dd9712a0b9José Fonseca   bld.mask = mask;
1765f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.pos = pos;
1766f85c5f8621382ba1c8baa1582d87b46b388258d2José Fonseca   bld.inputs = inputs;
176763b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.outputs = outputs;
176863b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca   bld.consts_ptr = consts_ptr;
17698be72bb7646d430e66cb36e09c13c13bee030d53José Fonseca   bld.sampler = sampler;
1770bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.info = info;
17713662afd87d61e3f65843b210a7e8c9c8a6cb27f0Brian Paul   bld.indirect_files = info->indirect_files;
17720b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
1773bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.soa = TRUE;
1774bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.emit_fetch_funcs[TGSI_FILE_CONSTANT] = emit_fetch_constant;
1775bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate;
1776bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input;
1777bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.emit_fetch_funcs[TGSI_FILE_TEMPORARY] = emit_fetch_temporary;
1778bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.emit_fetch_funcs[TGSI_FILE_SYSTEM_VALUE] = emit_fetch_system_value;
1779bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.emit_store = emit_store;
1780bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
1781bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.emit_declaration = lp_emit_declaration_soa;
1782bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.emit_immediate = lp_emit_immediate_soa;
1783bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
1784bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.emit_prologue = emit_prologue;
1785bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.emit_epilogue = emit_epilogue;
1786bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
1787bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   /* Set opcode actions */
1788bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_set_default_actions_cpu(&bld.bld_base);
1789bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
1790bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_BGNLOOP].emit = bgnloop_emit;
1791bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_BGNSUB].emit = bgnsub_emit;
1792bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_BRK].emit = brk_emit;
1793bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_CAL].emit = cal_emit;
1794bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_CONT].emit = cont_emit;
1795bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_DDX].emit = ddx_emit;
1796bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_DDY].emit = ddy_emit;
1797bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_ELSE].emit = else_emit;
1798bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_ENDIF].emit = endif_emit;
1799bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_ENDLOOP].emit = endloop_emit;
1800bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_ENDSUB].emit = endsub_emit;
1801bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_IF].emit = if_emit;
1802bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_KIL].emit = kil_emit;
1803bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_KILP].emit = kilp_emit;
1804bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_NRM].emit = nrm_emit;
1805bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_NRM4].emit = nrm_emit;
1806bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_RET].emit = ret_emit;
1807bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_TEX].emit = tex_emit;
1808bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_TXB].emit = txb_emit;
1809bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_TXD].emit = txd_emit;
1810bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_TXL].emit = txl_emit;
1811bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   bld.bld_base.op_actions[TGSI_OPCODE_TXP].emit = txp_emit;
1812bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard
1813bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_exec_mask_init(&bld.exec_mask, &bld.bld_base.base);
181463b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
1815f623d0c1c217d990f207306eb968172af79fa969Zack Rusin
18161d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul   bld.system_values_array = system_values_array;
18171d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul
1818bc2875aa483a0fef7f6e32c1886f6e2edaba7694Tom Stellard   lp_build_tgsi_llvm(&bld.bld_base, tokens);
1819528c3cd24169c6b6c0da60cb2b8f765eb7f05cdcZack Rusin
182018d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   if (0) {
1821efc82aef35a2aac5d2ed9774f6d28f2626796416Brian Paul      LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder);
182218d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      LLVMValueRef function = LLVMGetBasicBlockParent(block);
1823263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("11111111111111111111111111111 \n");
182418d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin      tgsi_dump(tokens, 0);
18258ad3e0b55df50beac8ba3c5cafa0be79641a4977José Fonseca      lp_debug_dump_value(function);
1826263e038431f24f24aaec252e135ffc9f2f09640eJosé Fonseca      debug_printf("2222222222222222222222222222 \n");
182718d406e8a8a838c82ee4ec5dbf244ab8bba0855eZack Rusin   }
18280b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
18290b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   if (0) {
18300b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMModuleRef module = LLVMGetGlobalParent(
18316299f241e9fdd86e705d144a42d9b1979c13f9adBrian Paul         LLVMGetBasicBlockParent(LLVMGetInsertBlock(gallivm->builder)));
18320b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin      LLVMDumpModule(module);
18330b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin
18340b7ca2f8fcb187fb3aa37e0b6dc4b0a84101478fZack Rusin   }
183563b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca}
183663b07618b3e4034e11968f1c5323445dc4a0377fJosé Fonseca
18371d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul
18381d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul/**
18391d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul * Build up the system values array out of individual values such as
18401d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul * the instance ID, front-face, primitive ID, etc.  The shader info is
18411d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul * used to determine which system values are needed and where to put
18421d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul * them in the system values array.
18431d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul *
18441d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul * XXX only instance ID is implemented at this time.
18451d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul *
18461d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul * The system values register file is similar to the constants buffer.
18471d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul * Example declaration:
18481d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul *    DCL SV[0], INSTANCEID
18491d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul * Example instruction:
18501d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul *    MOVE foo, SV[0].xxxx;
18511d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul *
18521d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul * \return  LLVM float array (interpreted as float [][4])
18531d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul */
18541d6f3543a063ab9e740fd0c149dcce26c282d773Brian PaulLLVMValueRef
1855652901e95b4ed406293d0e1fabee857c054119b1Brian Paullp_build_system_values_array(struct gallivm_state *gallivm,
18561d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul                             const struct tgsi_shader_info *info,
18571d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul                             LLVMValueRef instance_id,
18581d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul                             LLVMValueRef facing)
18591d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul{
1860652901e95b4ed406293d0e1fabee857c054119b1Brian Paul   LLVMValueRef size = lp_build_const_int32(gallivm, 4 * info->num_system_values);
1861652901e95b4ed406293d0e1fabee857c054119b1Brian Paul   LLVMTypeRef float_t = LLVMFloatTypeInContext(gallivm->context);
1862652901e95b4ed406293d0e1fabee857c054119b1Brian Paul   LLVMValueRef array = lp_build_array_alloca(gallivm, float_t,
18631d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul                                              size, "sysvals_array");
18641d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul   unsigned i;
18651d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul
18661d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul   for (i = 0; i < info->num_system_values; i++) {
1867652901e95b4ed406293d0e1fabee857c054119b1Brian Paul      LLVMValueRef index = lp_build_const_int32(gallivm, i * 4);
186831200d0688b67a0d764ad7fe4c2761d0f8d993d8Marek Olšák      LLVMValueRef ptr, value = 0;
18691d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul
18701d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul      switch (info->system_value_semantic_name[i]) {
18711d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul      case TGSI_SEMANTIC_INSTANCEID:
18721d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul         /* convert instance ID from int to float */
1873652901e95b4ed406293d0e1fabee857c054119b1Brian Paul         value = LLVMBuildSIToFP(gallivm->builder, instance_id, float_t,
18741d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul                                 "sysval_instanceid");
18751d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul         break;
18761d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul      case TGSI_SEMANTIC_FACE:
18771d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul         /* fall-through */
18781d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul      default:
18791d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul         assert(0 && "unexpected semantic in build_system_values_array()");
18801d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul      }
18811d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul
1882652901e95b4ed406293d0e1fabee857c054119b1Brian Paul      ptr = LLVMBuildGEP(gallivm->builder, array, &index, 1, "");
1883652901e95b4ed406293d0e1fabee857c054119b1Brian Paul      LLVMBuildStore(gallivm->builder, value, ptr);
18841d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul   }
18851d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul
18861d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul   return array;
18871d6f3543a063ab9e740fd0c149dcce26c282d773Brian Paul}
1888