1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2011-2012 Advanced Micro Devices, Inc. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2010 VMware, Inc. 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 VMware, Inc. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software. 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_tgsi.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_arit.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_gather.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_init.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_intr.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_info.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_parse.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_util.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* The user is responsible for freeing list->instructions */ 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned lp_bld_tgsi_list_init(struct lp_build_tgsi_context * bld_base) 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->instructions = (struct tgsi_full_instruction *) 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org MALLOC( LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction) ); 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!bld_base->instructions) { 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->max_instructions = LP_MAX_INSTRUCTIONS; 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned lp_bld_tgsi_add_instruction( 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context * bld_base, 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_instruction *inst_to_add) 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (bld_base->num_instructions == bld_base->max_instructions) { 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_instruction *instructions; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org instructions = REALLOC(bld_base->instructions, bld_base->max_instructions 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * sizeof(struct tgsi_full_instruction), 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (bld_base->max_instructions + LP_MAX_INSTRUCTIONS) 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * sizeof(struct tgsi_full_instruction)); 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!instructions) { 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->instructions = instructions; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->max_instructions += LP_MAX_INSTRUCTIONS; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(bld_base->instructions + bld_base->num_instructions, inst_to_add, 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sizeof(bld_base->instructions[0])); 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->num_instructions++; 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function assumes that all the args in emit_data have been set. 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_action_set_dst_type( 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_emit_data * emit_data, 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context *bld_base, 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tgsi_opcode) 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (emit_data->arg_count == 0) { 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data->dst_type = LLVMVoidTypeInContext(bld_base->base.gallivm->context); 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX: Not all opcodes have the same src and dst types. */ 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data->dst_type = LLVMTypeOf(emit_data->args[0]); 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_tgsi_intrinsic( 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct lp_build_tgsi_action * action, 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context * bld_base, 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_emit_data * emit_data) 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_context * base = &bld_base->base; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data->output[emit_data->chan] = lp_build_intrinsic( 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org base->gallivm->builder, action->intr_name, 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data->dst_type, emit_data->args, emit_data->arg_count); 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_emit_llvm( 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context *bld_base, 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tgsi_opcode, 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_emit_data * emit_data) 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_action * action = &bld_base->op_actions[tgsi_opcode]; 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX: Assert that this is a componentwise or replicate instruction */ 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lp_build_action_set_dst_type(emit_data, bld_base, tgsi_opcode); 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data->chan = 0; 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(action->emit); 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org action->emit(action, bld_base, emit_data); 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return emit_data->output[0]; 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_emit_llvm_unary( 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context *bld_base, 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tgsi_opcode, 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LLVMValueRef arg0) 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_emit_data emit_data; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.arg_count = 1; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.args[0] = arg0; 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return lp_build_emit_llvm(bld_base, tgsi_opcode, &emit_data); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_emit_llvm_binary( 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context *bld_base, 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tgsi_opcode, 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LLVMValueRef arg0, 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LLVMValueRef arg1) 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_emit_data emit_data; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.arg_count = 2; 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.args[0] = arg0; 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.args[1] = arg1; 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return lp_build_emit_llvm(bld_base, tgsi_opcode, &emit_data); 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_emit_llvm_ternary( 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context *bld_base, 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tgsi_opcode, 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LLVMValueRef arg0, 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LLVMValueRef arg1, 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LLVMValueRef arg2) 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_emit_data emit_data; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.arg_count = 3; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.args[0] = arg0; 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.args[1] = arg1; 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.args[2] = arg2; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return lp_build_emit_llvm(bld_base, tgsi_opcode, &emit_data); 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The default fetch implementation. 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid lp_build_fetch_args( 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context * bld_base, 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_emit_data * emit_data) 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned src; 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (src = 0; src < emit_data->info->num_src; src++) { 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data->args[src] = lp_build_emit_fetch(bld_base, emit_data->inst, src, 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data->chan); 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data->arg_count = emit_data->info->num_src; 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lp_build_action_set_dst_type(emit_data, bld_base, 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data->inst->Instruction.Opcode); 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* XXX: COMMENT 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It should be assumed that this function ignores writemasks 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_tgsi_inst_llvm( 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context * bld_base, 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct tgsi_full_instruction * inst) 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tgsi_opcode = inst->Instruction.Opcode; 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct tgsi_opcode_info * info = tgsi_get_opcode_info(tgsi_opcode); 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct lp_build_tgsi_action * action = 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &bld_base->op_actions[tgsi_opcode]; 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_emit_data emit_data; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned chan_index; 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LLVMValueRef val; 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->pc++; 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Ignore deprecated instructions */ 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (inst->Instruction.Opcode) { 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_RCC: 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_UP2H: 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_UP2US: 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_UP4B: 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_UP4UB: 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_X2D: 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_ARA: 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_BRA: 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_DIV: 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_PUSHA: 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_POPA: 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_OPCODE_SAD: 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* deprecated? */ 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Check if the opcode has been implemented */ 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!action->emit) { 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(&emit_data, 0, sizeof(emit_data)); 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(info->num_dst <= 1); 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->num_dst) { 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) { 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.output[chan_index] = bld_base->base.undef; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.inst = inst; 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.info = info; 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Emit the instructions */ 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->output_mode == TGSI_OUTPUT_COMPONENTWISE && bld_base->soa) { 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_FOR_EACH_DST0_ENABLED_CHANNEL(inst, chan_index) { 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.chan = chan_index; 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!action->fetch_args) { 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lp_build_fetch_args(bld_base, &emit_data); 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org action->fetch_args(bld_base, &emit_data); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org action->emit(action, bld_base, &emit_data); 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.chan = LP_CHAN_ALL; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (action->fetch_args) { 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org action->fetch_args(bld_base, &emit_data); 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Make sure the output value is stored in emit_data.output[0], unless 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the opcode is channel dependent */ 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->output_mode != TGSI_OUTPUT_CHAN_DEPENDENT) { 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.chan = 0; 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org action->emit(action, bld_base, &emit_data); 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Replicate the output values */ 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->output_mode == TGSI_OUTPUT_REPLICATE && bld_base->soa) { 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org val = emit_data.output[0]; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(emit_data.output, 0, sizeof(emit_data.output)); 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org TGSI_FOR_EACH_DST0_ENABLED_CHANNEL(inst, chan_index) { 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org emit_data.output[chan_index] = val; 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->num_dst > 0) { 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->emit_store(bld_base, inst, info, emit_data.output); 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_emit_fetch( 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context *bld_base, 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct tgsi_full_instruction *inst, 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned src_op, 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const unsigned chan_index) 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct tgsi_full_src_register *reg = &inst->Src[src_op]; 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned swizzle; 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LLVMValueRef res; 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org enum tgsi_opcode_type stype = tgsi_opcode_infer_src_type(inst->Instruction.Opcode); 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (chan_index == LP_CHAN_ALL) { 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzle = ~0; 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzle = tgsi_util_get_full_src_register_swizzle(reg, chan_index); 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (swizzle > 3) { 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0 && "invalid swizzle in emit_fetch()"); 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return bld_base->base.undef; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(reg->Register.Index <= bld_base->info->file_max[reg->Register.File]); 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (bld_base->emit_fetch_funcs[reg->Register.File]) { 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org res = bld_base->emit_fetch_funcs[reg->Register.File](bld_base, reg, stype, 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swizzle); 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0 && "invalid src register in emit_fetch()"); 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return bld_base->base.undef; 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg->Register.Absolute) { 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org res = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_ABS, res); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (reg->Register.Negate) { 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org res = lp_build_negate( &bld_base->base, res ); 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Swizzle the argument 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (swizzle == ~0) { 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org res = bld_base->emit_swizzle(bld_base, res, 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg->Register.SwizzleX, 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg->Register.SwizzleY, 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg->Register.SwizzleZ, 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg->Register.SwizzleW); 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return res; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgboolean 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orglp_build_tgsi_llvm( 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context * bld_base, 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct tgsi_token *tokens) 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_parse_context parse; 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (bld_base->emit_prologue) { 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->emit_prologue(bld_base); 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!lp_bld_tgsi_list_init(bld_base)) { 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_parse_init( &parse, tokens ); 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while( !tgsi_parse_end_of_tokens( &parse ) ) { 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_parse_token( &parse ); 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch( parse.FullToken.Token.Type ) { 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_TOKEN_TYPE_DECLARATION: 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Inputs already interpolated */ 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->emit_declaration(bld_base, &parse.FullToken.FullDeclaration); 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_TOKEN_TYPE_INSTRUCTION: 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org lp_bld_tgsi_add_instruction(bld_base, &parse.FullToken.FullInstruction); 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_TOKEN_TYPE_IMMEDIATE: 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->emit_immediate(bld_base, &parse.FullToken.FullImmediate); 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case TGSI_TOKEN_TYPE_PROPERTY: 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert( 0 ); 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (bld_base->pc != -1) { 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct tgsi_full_instruction *instr = bld_base->instructions + 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->pc; 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct tgsi_opcode_info *opcode_info = 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_get_opcode_info(instr->Instruction.Opcode); 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!lp_build_tgsi_inst_llvm(bld_base, instr)) { 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n", 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org opcode_info->mnemonic); 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return FALSE; 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tgsi_parse_free(&parse); 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org FREE(bld_base->instructions); 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (bld_base->emit_epilogue) { 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bld_base->emit_epilogue(bld_base); 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return TRUE; 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 401