1a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard/*
2a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Copyright 2011 Advanced Micro Devices, Inc.
3a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
4a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Permission is hereby granted, free of charge, to any person obtaining a
5a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * copy of this software and associated documentation files (the "Software"),
6a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * to deal in the Software without restriction, including without limitation
7a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * and/or sell copies of the Software, and to permit persons to whom the
9a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Software is furnished to do so, subject to the following conditions:
10a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
11a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * The above copyright notice and this permission notice (including the next
12a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * paragraph) shall be included in all copies or substantial portions of the
13a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Software.
14a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
15a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * SOFTWARE.
22a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
23a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard * Authors: Tom Stellard <thomas.stellard@amd.com>
24a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard *
25a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard */
26a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "radeon_llvm.h"
27a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
28a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "gallivm/lp_bld_const.h"
29a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "gallivm/lp_bld_gather.h"
30a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "gallivm/lp_bld_flow.h"
31a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "gallivm/lp_bld_init.h"
3277d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard#include "gallivm/lp_bld_intr.h"
33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "gallivm/lp_bld_swizzle.h"
34a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "tgsi/tgsi_info.h"
35a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "tgsi/tgsi_parse.h"
36a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_math.h"
3712a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin#include "util/u_memory.h"
38a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "util/u_debug.h"
39a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
4012a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin#include <llvm-c/Core.h>
41a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include <llvm-c/Transforms/Scalar.h>
42a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
43a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic struct radeon_llvm_loop * get_current_loop(struct radeon_llvm_context * ctx)
44a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
45a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return ctx->loop_depth > 0 ? ctx->loop + (ctx->loop_depth - 1) : NULL;
46a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
47a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
48a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic struct radeon_llvm_branch * get_current_branch(
49a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_context * ctx)
50a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
51a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return ctx->branch_depth > 0 ?
52a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			ctx->branch + (ctx->branch_depth - 1) : NULL;
53a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
54a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
55a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardunsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan)
56a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
57a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return (index * 4) + chan;
58a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
59a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
60a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic LLVMValueRef emit_swizzle(
61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard        LLVMValueRef value,
63a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned swizzle_x,
64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned swizzle_y,
65a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned swizzle_z,
66a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned swizzle_w)
67a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
68f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard	LLVMValueRef swizzles[4];
69f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard	LLVMTypeRef i32t =
70f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard		LLVMInt32TypeInContext(bld_base->base.gallivm->context);
71a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
72f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard	swizzles[0] = LLVMConstInt(i32t, swizzle_x, 0);
73f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard	swizzles[1] = LLVMConstInt(i32t, swizzle_y, 0);
74f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard	swizzles[2] = LLVMConstInt(i32t, swizzle_z, 0);
75f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard	swizzles[3] = LLVMConstInt(i32t, swizzle_w, 0);
76a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
77f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard	return LLVMBuildShuffleVector(bld_base->base.gallivm->builder,
78f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard		value,
79f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard		LLVMGetUndef(LLVMTypeOf(value)),
80f92873be2c7fcb07154282bd0e418a4c88b6507eTom Stellard		LLVMConstVector(swizzles, 4), "");
81a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
82a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
83a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic LLVMValueRef
84a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardemit_array_index(
85a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_soa_context *bld,
86a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct tgsi_full_src_register *reg,
87a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned swizzle)
88a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
89a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct gallivm_state * gallivm = bld->bld_base.base.gallivm;
90a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
91a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMValueRef addr = LLVMBuildLoad(gallivm->builder,
92a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld->addr[reg->Indirect.Index][swizzle], "");
93a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMValueRef offset = lp_build_const_int32(gallivm, reg->Register.Index);
94a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMValueRef hw_index = LLVMBuildAdd(gallivm->builder, addr, offset, "");
95a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMValueRef soa_index = LLVMBuildMul(gallivm->builder, hw_index,
96a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	lp_build_const_int32(gallivm, 4), "");
97a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMValueRef array_index = LLVMBuildAdd(gallivm->builder, soa_index,
98a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	lp_build_const_int32(gallivm, swizzle), "");
99a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
100a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	return array_index;
101a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
102a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
103a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic LLVMValueRef
104a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardemit_fetch_immediate(
105a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context *bld_base,
106a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct tgsi_full_src_register *reg,
107a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	enum tgsi_opcode_type type,
108a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned swizzle)
109a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
1102a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	LLVMTypeRef ctype;
1112a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	LLVMContextRef ctx = bld_base->base.gallivm->context;
1122a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin
1132a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	switch (type) {
1142a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	case TGSI_TYPE_UNSIGNED:
1152a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	case TGSI_TYPE_SIGNED:
1162a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		ctype = LLVMInt32TypeInContext(ctx);
1172a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		break;
1182a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	case TGSI_TYPE_UNTYPED:
1192a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	case TGSI_TYPE_FLOAT:
1202a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		ctype = LLVMFloatTypeInContext(ctx);
1212a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		break;
1222a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	default:
1232a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		ctype = 0;
1242a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		break;
1252a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	}
1262a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin
127a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
1282a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	return LLVMConstBitCast(bld->immediates[reg->Register.Index][swizzle], ctype);
129a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
130a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
131a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic LLVMValueRef
132a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardemit_fetch_input(
133a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context *bld_base,
134a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct tgsi_full_src_register *reg,
135a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	enum tgsi_opcode_type type,
136a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned swizzle)
137a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
138a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
139a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (swizzle == ~0) {
140a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMValueRef values[TGSI_NUM_CHANNELS] = {};
141a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		unsigned chan;
142a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
143a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			values[chan] = ctx->inputs[radeon_llvm_reg_index_soa(
144a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						reg->Register.Index, chan)];
145a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
146a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return lp_build_gather_values(bld_base->base.gallivm, values,
147a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						TGSI_NUM_CHANNELS);
148a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	} else {
1492a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		return bitcast(bld_base, type, ctx->inputs[radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)]);
150a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
151a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
152a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
153a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic LLVMValueRef
154a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardemit_fetch_temporary(
155a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context *bld_base,
156a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct tgsi_full_src_register *reg,
157a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	enum tgsi_opcode_type type,
158a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned swizzle)
159a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
160a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
161a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
1624444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König	if (swizzle == ~0) {
1634444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König		LLVMValueRef values[TGSI_NUM_CHANNELS] = {};
1644444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König		unsigned chan;
1654444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
1664444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König			values[chan] = emit_fetch_temporary(bld_base, reg, type, chan);
1674444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König		}
1684444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König		return lp_build_gather_values(bld_base->base.gallivm, values,
1694444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König						TGSI_NUM_CHANNELS);
1704444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König	}
1714444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König
172a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (reg->Register.Indirect) {
173a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMValueRef array_index = emit_array_index(bld, reg, swizzle);
174a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMValueRef ptr = LLVMBuildGEP(builder, bld->temps_array, &array_index,
175a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						1, "");
1764444b9d1ecddb09468d2878ffb1463a66ea0ffd3Christian König		return LLVMBuildLoad(builder, ptr, "");
177a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	} else {
178a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMValueRef temp_ptr;
179a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle);
1802a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		return bitcast(bld_base,type,LLVMBuildLoad(builder, temp_ptr, ""));
181a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
182a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
183a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
184a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic LLVMValueRef
185a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardemit_fetch_output(
186a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context *bld_base,
187a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct tgsi_full_src_register *reg,
188a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	enum tgsi_opcode_type type,
189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned swizzle)
190a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
191a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
192a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
193a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 if (reg->Register.Indirect) {
194a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMValueRef array_index = emit_array_index(bld, reg, swizzle);
195a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMValueRef ptr = LLVMBuildGEP(builder, bld->outputs_array, &array_index,
196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						1, "");
197a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return LLVMBuildLoad(builder, ptr, "");
198a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	} else {
199a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMValueRef temp_ptr;
200a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		temp_ptr = lp_get_output_ptr(bld, reg->Register.Index, swizzle);
201a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return LLVMBuildLoad(builder, temp_ptr, "");
202a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 }
203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
204a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
205a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void emit_declaration(
206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
207a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct tgsi_full_declaration *decl)
208a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
209a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	switch(decl->Declaration.File) {
211a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case TGSI_FILE_ADDRESS:
212a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	{
213a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		 unsigned idx;
214a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
215a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			unsigned chan;
216a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
217a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				 ctx->soa.addr[idx][chan] = lp_build_alloca(
218a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					&ctx->gallivm,
219a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					ctx->soa.bld_base.uint_bld.elem_type, "");
220a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			}
221a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
222a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
223a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
224a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
225a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case TGSI_FILE_TEMPORARY:
226a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		lp_emit_declaration_soa(bld_base, decl);
227a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
228a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
229a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case TGSI_FILE_INPUT:
230a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	{
231a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		unsigned idx;
232a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
233a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			ctx->load_input(ctx, idx, decl);
234a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
235a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
236a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	break;
237a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
238d8a120485444968c930f0ab675473692b221cb75Vadim Girlin	case TGSI_FILE_SYSTEM_VALUE:
239d8a120485444968c930f0ab675473692b221cb75Vadim Girlin	{
240d8a120485444968c930f0ab675473692b221cb75Vadim Girlin		unsigned idx;
241d8a120485444968c930f0ab675473692b221cb75Vadim Girlin		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
242d8a120485444968c930f0ab675473692b221cb75Vadim Girlin			ctx->load_system_value(ctx, idx, decl);
243d8a120485444968c930f0ab675473692b221cb75Vadim Girlin		}
244d8a120485444968c930f0ab675473692b221cb75Vadim Girlin	}
245d8a120485444968c930f0ab675473692b221cb75Vadim Girlin	break;
246d8a120485444968c930f0ab675473692b221cb75Vadim Girlin
247a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	case TGSI_FILE_OUTPUT:
248a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	{
249a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		unsigned idx;
250a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
251a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			unsigned chan;
252a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			assert(idx < RADEON_LLVM_MAX_OUTPUTS);
253a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
254a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				ctx->soa.outputs[idx][chan] = lp_build_alloca(&ctx->gallivm,
255a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					ctx->soa.bld_base.base.elem_type, "");
256a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			}
257a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
258a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
259a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		ctx->output_reg_count = MAX2(ctx->output_reg_count,
260a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard							 decl->Range.Last + 1);
261a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
262a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
263a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
264a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	default:
265a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		break;
266a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
267a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
268a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
269a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void
270a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardemit_store(
271a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
272a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct tgsi_full_instruction * inst,
273a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct tgsi_opcode_info * info,
274a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMValueRef dst[4])
275a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
276a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
277a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
278a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_context base = bld->bld_base.base;
279a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct tgsi_full_dst_register *reg = &inst->Dst[0];
280a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
281a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMValueRef temp_ptr;
282a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned chan, chan_index;
283a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	boolean is_vec_store = FALSE;
284a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (dst[0]) {
285a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMTypeKind k = LLVMGetTypeKind(LLVMTypeOf(dst[0]));
286a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		is_vec_store = (k == LLVMVectorTypeKind);
287a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
288a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
289a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (is_vec_store) {
290a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMValueRef values[4] = {};
291a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		TGSI_FOR_EACH_DST0_ENABLED_CHANNEL(inst, chan) {
292a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			LLVMValueRef index = lp_build_const_int32(gallivm, chan);
293a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			values[chan]  = LLVMBuildExtractElement(gallivm->builder,
294a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard							dst[0], index, "");
295a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
296a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		bld_base->emit_store(bld_base, inst, info, values);
297a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		return;
298a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
299a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
300a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
301a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMValueRef value = dst[chan_index];
302a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
303a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		if (inst->Instruction.Saturate != TGSI_SAT_NONE) {
304a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			struct lp_build_emit_data clamp_emit_data;
305a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
306a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			memset(&clamp_emit_data, 0, sizeof(clamp_emit_data));
307a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			clamp_emit_data.arg_count = 3;
308a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			clamp_emit_data.args[0] = value;
309a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			clamp_emit_data.args[2] = base.one;
310a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
311a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			switch(inst->Instruction.Saturate) {
312a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			case TGSI_SAT_ZERO_ONE:
313a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				clamp_emit_data.args[1] = base.zero;
314a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				break;
315a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			case TGSI_SAT_MINUS_PLUS_ONE:
316a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				clamp_emit_data.args[1] = LLVMConstReal(
317a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						base.elem_type, -1.0f);
318a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				break;
319a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			default:
320a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard				assert(0);
321a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			}
322a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			value = lp_build_emit_llvm(bld_base, TGSI_OPCODE_CLAMP,
323a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						&clamp_emit_data);
324a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
325a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
326a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		switch(reg->Register.File) {
327a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		case TGSI_FILE_OUTPUT:
328a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			temp_ptr = bld->outputs[reg->Register.Index][chan_index];
329a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			break;
330a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
331a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		case TGSI_FILE_TEMPORARY:
332a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, chan_index);
333a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			break;
334a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
335a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		default:
336a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			return;
337a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		}
3382a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin
3392a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		value = bitcast(bld_base, TGSI_TYPE_FLOAT, value);
3402a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin
341a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMBuildStore(builder, value, temp_ptr);
342a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
343a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
344a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
345a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void bgnloop_emit(
346a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct lp_build_tgsi_action * action,
347a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
348a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_emit_data * emit_data)
349a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
350a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
351a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct gallivm_state * gallivm = bld_base->base.gallivm;
352a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBasicBlockRef loop_block;
353a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBasicBlockRef endloop_block;
354a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	endloop_block = LLVMAppendBasicBlockInContext(gallivm->context,
355a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						ctx->main_fn, "ENDLOOP");
356a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	loop_block = LLVMInsertBasicBlockInContext(gallivm->context,
357a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						endloop_block, "LOOP");
358a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBuildBr(gallivm->builder, loop_block);
359a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMPositionBuilderAtEnd(gallivm->builder, loop_block);
360a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->loop_depth++;
361a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->loop[ctx->loop_depth - 1].loop_block = loop_block;
362a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->loop[ctx->loop_depth - 1].endloop_block = endloop_block;
363a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
364a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
365a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void brk_emit(
366a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct lp_build_tgsi_action * action,
367a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
368a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_emit_data * emit_data)
369a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
370a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
371a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct gallivm_state * gallivm = bld_base->base.gallivm;
372a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_loop * current_loop = get_current_loop(ctx);
373a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
374a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBuildBr(gallivm->builder, current_loop->endloop_block);
375a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
376a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
377a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void cont_emit(
378a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct lp_build_tgsi_action * action,
379a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
380a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_emit_data * emit_data)
381a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
382a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
383a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct gallivm_state * gallivm = bld_base->base.gallivm;
384a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_loop * current_loop = get_current_loop(ctx);
385a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
386a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBuildBr(gallivm->builder, current_loop->loop_block);
387a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
388a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
389a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void else_emit(
390a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct lp_build_tgsi_action * action,
391a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
392a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_emit_data * emit_data)
393a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
394a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
395a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct gallivm_state * gallivm = bld_base->base.gallivm;
396a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_branch * current_branch = get_current_branch(ctx);
397a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBasicBlockRef current_block = LLVMGetInsertBlock(gallivm->builder);
398a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
399a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* We need to add a terminator to the current block if the previous
400a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * instruction was an ENDIF.Example:
401a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * IF
402a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 *   [code]
403a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 *   IF
404a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 *     [code]
405a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 *   ELSE
406a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 *    [code]
407a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 *   ENDIF <--
408a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * ELSE<--
409a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 *   [code]
410a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * ENDIF
411a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 */
412a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
413a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (current_block != current_branch->if_block) {
414a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
415a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
416a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!LLVMGetBasicBlockTerminator(current_branch->if_block)) {
417a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
418a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
419a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	current_branch->has_else = 1;
420a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->else_block);
421a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
422a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
423a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void endif_emit(
424a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct lp_build_tgsi_action * action,
425a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
426a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_emit_data * emit_data)
427a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
428a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
429a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct gallivm_state * gallivm = bld_base->base.gallivm;
430a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_branch * current_branch = get_current_branch(ctx);
431a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBasicBlockRef current_block = LLVMGetInsertBlock(gallivm->builder);
432a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
433a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* If we have consecutive ENDIF instructions, then the first ENDIF
434a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * will not have a terminator, so we need to add one. */
435a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (current_block != current_branch->if_block
436a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			&& current_block != current_branch->else_block
437a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			&& !LLVMGetBasicBlockTerminator(current_block)) {
438a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
439a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		 LLVMBuildBr(gallivm->builder, current_branch->endif_block);
440a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
441a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!LLVMGetBasicBlockTerminator(current_branch->else_block)) {
442a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->else_block);
443a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
444a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
445a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
446a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!LLVMGetBasicBlockTerminator(current_branch->if_block)) {
447a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->if_block);
448a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
449a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
450a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
451a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->endif_block);
452a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->branch_depth--;
453a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
454a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
455a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void endloop_emit(
456a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct lp_build_tgsi_action * action,
457a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
458a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_emit_data * emit_data)
459a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
460a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
461a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct gallivm_state * gallivm = bld_base->base.gallivm;
462a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_loop * current_loop = get_current_loop(ctx);
463a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
464a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if (!LLVMGetBasicBlockTerminator(LLVMGetInsertBlock(gallivm->builder))) {
465a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard		 LLVMBuildBr(gallivm->builder, current_loop->loop_block);
466a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
467a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
468a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMPositionBuilderAtEnd(gallivm->builder, current_loop->endloop_block);
469a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->loop_depth--;
470a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
471a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
472a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void if_emit(
473a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	const struct lp_build_tgsi_action * action,
474a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
475a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_emit_data * emit_data)
476a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
477a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
478a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct gallivm_state * gallivm = bld_base->base.gallivm;
479a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMValueRef cond;
480a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBasicBlockRef if_block, else_block, endif_block;
4813a6a1cd75fc98895569a34d5d7dfdc9e90381691Vadim Girlin
4823a6a1cd75fc98895569a34d5d7dfdc9e90381691Vadim Girlin	cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE,
4833a6a1cd75fc98895569a34d5d7dfdc9e90381691Vadim Girlin	        bitcast(bld_base, TGSI_TYPE_UNSIGNED, emit_data->args[0]),
4843a6a1cd75fc98895569a34d5d7dfdc9e90381691Vadim Girlin			bld_base->int_bld.zero, "");
485a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
486a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	endif_block = LLVMAppendBasicBlockInContext(gallivm->context,
487a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						ctx->main_fn, "ENDIF");
488a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	if_block = LLVMInsertBasicBlockInContext(gallivm->context,
489a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						endif_block, "IF");
490a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	else_block = LLVMInsertBasicBlockInContext(gallivm->context,
491a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						endif_block, "ELSE");
492a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBuildCondBr(gallivm->builder, cond, if_block, else_block);
493a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMPositionBuilderAtEnd(gallivm->builder, if_block);
494a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
495a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->branch_depth++;
496a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->branch[ctx->branch_depth - 1].endif_block = endif_block;
497a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->branch[ctx->branch_depth - 1].if_block = if_block;
498a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->branch[ctx->branch_depth - 1].else_block = else_block;
499a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->branch[ctx->branch_depth - 1].has_else = 0;
500a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
501a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
50277d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellardstatic void kil_emit(
50377d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard	const struct lp_build_tgsi_action * action,
50477d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard	struct lp_build_tgsi_context * bld_base,
50577d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard	struct lp_build_emit_data * emit_data)
50677d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard{
50777d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard	unsigned i;
50877d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard	for (i = 0; i < emit_data->arg_count; i++) {
50977d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard		emit_data->output[i] = lp_build_intrinsic_unary(
51077d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard			bld_base->base.gallivm->builder,
51177d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard			action->intr_name,
51277d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard			emit_data->dst_type, emit_data->args[i]);
51377d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard	}
51477d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard}
51577d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard
516d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
517d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlinstatic void emit_prepare_cube_coords(
518d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin		struct lp_build_tgsi_context * bld_base,
519d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin		struct lp_build_emit_data * emit_data)
520d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin{
521d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	boolean shadowcube = (emit_data->inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE);
522d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	struct gallivm_state * gallivm = bld_base->base.gallivm;
523d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	LLVMBuilderRef builder = gallivm->builder;
524d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	LLVMTypeRef type = bld_base->base.elem_type;
525d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	LLVMValueRef coords[4];
526d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	LLVMValueRef mad_args[3];
527d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	unsigned i, cnt;
528d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
52912a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	LLVMValueRef v = build_intrinsic(builder, "llvm.AMDGPU.cube",
530d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin			LLVMVectorType(type, 4),
53112a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin			&emit_data->args[0],1, LLVMReadNoneAttribute);
532d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
533d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	/* save src.w for shadow cube */
534d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	cnt = shadowcube ? 3 : 4;
535d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
536d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	for (i = 0; i < cnt; ++i) {
537d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin		LLVMValueRef idx = lp_build_const_int32(gallivm, i);
538d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin		coords[i] = LLVMBuildExtractElement(builder, v, idx, "");
539d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	}
540d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
54112a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	coords[2] = build_intrinsic(builder, "llvm.AMDIL.fabs.",
54212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin			type, &coords[2], 1, LLVMReadNoneAttribute);
54312a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	coords[2] = build_intrinsic(builder, "llvm.AMDGPU.rcp",
54412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin			type, &coords[2], 1, LLVMReadNoneAttribute);
545d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
546d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	mad_args[1] = coords[2];
547d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	mad_args[2] = LLVMConstReal(type, 1.5);
548d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
549d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	mad_args[0] = coords[0];
55012a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	coords[0] = build_intrinsic(builder, "llvm.AMDIL.mad.",
55112a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin			type, mad_args, 3, LLVMReadNoneAttribute);
552d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
553d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	mad_args[0] = coords[1];
55412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	coords[1] = build_intrinsic(builder, "llvm.AMDIL.mad.",
55512a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin			type, mad_args, 3, LLVMReadNoneAttribute);
556d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
557d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	/* apply yxwy swizzle to cooords */
558d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	coords[2] = coords[3];
559d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	coords[3] = coords[1];
560d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	coords[1] = coords[0];
561d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	coords[0] = coords[3];
562d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
563d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
564d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin						coords, 4);
565d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin}
566d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
567fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlinstatic void txd_fetch_args(
568fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin	struct lp_build_tgsi_context * bld_base,
569fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin	struct lp_build_emit_data * emit_data)
570fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin{
571fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin	const struct tgsi_full_instruction * inst = emit_data->inst;
572fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin
573fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin	LLVMValueRef coords[4];
574fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin	unsigned chan, src;
575fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin	for (src = 0; src < 3; src++) {
576fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin		for (chan = 0; chan < 4; chan++)
577fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin			coords[chan] = lp_build_emit_fetch(bld_base, inst, src, chan);
578fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin
579fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin		emit_data->args[src] = lp_build_gather_values(bld_base->base.gallivm,
580fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin				coords, 4);
581fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin	}
582fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin	emit_data->arg_count = 3;
583fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
584fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin}
585fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin
5864a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin
587d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlinstatic void txp_fetch_args(
588d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	struct lp_build_tgsi_context * bld_base,
589d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	struct lp_build_emit_data * emit_data)
590d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin{
591d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	const struct tgsi_full_instruction * inst = emit_data->inst;
592d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	LLVMValueRef src_w;
593d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	unsigned chan;
594d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	LLVMValueRef coords[4];
595d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
596d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
597d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	src_w = lp_build_emit_fetch(bld_base, emit_data->inst, 0, TGSI_CHAN_W);
598d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
599d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	for (chan = 0; chan < 3; chan++ ) {
600d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin		LLVMValueRef arg = lp_build_emit_fetch(bld_base,
601d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin						emit_data->inst, 0, chan);
602d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin		coords[chan] = lp_build_emit_llvm_binary(bld_base,
603d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin					TGSI_OPCODE_DIV, arg, src_w);
604d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	}
605d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	coords[3] = bld_base->base.one;
606d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
607d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin						coords, 4);
608d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	emit_data->arg_count = 1;
609d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
610d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	if ((inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
611d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	     inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) &&
612d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	    inst->Instruction.Opcode != TGSI_OPCODE_TXQ) {
613d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin		emit_prepare_cube_coords(bld_base, emit_data);
614d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	}
615d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin}
616d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
617a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardstatic void tex_fetch_args(
618a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base,
619a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_emit_data * emit_data)
620a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
621a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX: lp_build_swizzle_aos() was failing with wrong arg types,
622a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * when we used CHAN_ALL.  We should be able to get this to work,
623a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * but for now we will swizzle it ourselves
624a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst,
625a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						 0, CHAN_ALL);
626a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
627a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	*/
628a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
629d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	const struct tgsi_full_instruction * inst = emit_data->inst;
630d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
631a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMValueRef coords[4];
632a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	unsigned chan;
633a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	for (chan = 0; chan < 4; chan++) {
634d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin		coords[chan] = lp_build_emit_fetch(bld_base, inst, 0, chan);
635a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	}
636a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
637a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	emit_data->arg_count = 1;
638a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
639a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						coords, 4);
640a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
641d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin
642d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	if ((inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
643d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	     inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) &&
644d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	    inst->Instruction.Opcode != TGSI_OPCODE_TXQ) {
645d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin		emit_prepare_cube_coords(bld_base, emit_data);
646d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	}
647a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
648a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
6494a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlinstatic void txf_fetch_args(
6504a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	struct lp_build_tgsi_context * bld_base,
6514a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	struct lp_build_emit_data * emit_data)
6524a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin{
6534a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	const struct tgsi_full_instruction * inst = emit_data->inst;
6544a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
6554a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	const struct tgsi_texture_offset * off = inst->TexOffsets;
6564a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	LLVMTypeRef offset_type = bld_base->int_bld.elem_type;
6574a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin
6584a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	/* fetch tex coords */
6594a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	tex_fetch_args(bld_base, emit_data);
6604a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin
6614a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	/* fetch tex offsets */
6624a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	if (inst->Texture.NumOffsets) {
6634a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin		assert(inst->Texture.NumOffsets == 1);
6644a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin
6654a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin		emit_data->args[1] = LLVMConstBitCast(
6664a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin			bld->immediates[off->Index][off->SwizzleX],
6674a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin			offset_type);
6684a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin		emit_data->args[2] = LLVMConstBitCast(
6694a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin			bld->immediates[off->Index][off->SwizzleY],
6704a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin			offset_type);
6714a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin		emit_data->args[3] = LLVMConstBitCast(
6724a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin			bld->immediates[off->Index][off->SwizzleZ],
6734a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin			offset_type);
6744a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	} else {
6754a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin		emit_data->args[1] = bld_base->int_bld.zero;
6764a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin		emit_data->args[2] = bld_base->int_bld.zero;
6774a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin		emit_data->args[3] = bld_base->int_bld.zero;
6784a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	}
6794a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin
6804a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	emit_data->arg_count = 4;
6814a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin}
6824a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin
683996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_icmp(
684996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
685996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
686996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
687996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
688996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	unsigned pred;
689996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
690996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMContextRef context = bld_base->base.gallivm->context;
691996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
692996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	switch (emit_data->inst->Instruction.Opcode) {
693996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	case TGSI_OPCODE_USEQ: pred = LLVMIntEQ; break;
694996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	case TGSI_OPCODE_USNE: pred = LLVMIntNE; break;
695996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	case TGSI_OPCODE_USGE: pred = LLVMIntUGE; break;
696996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	case TGSI_OPCODE_USLT: pred = LLVMIntULT; break;
697996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	case TGSI_OPCODE_ISGE: pred = LLVMIntSGE; break;
698996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	case TGSI_OPCODE_ISLT: pred = LLVMIntSLT; break;
699996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	default:
700996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		assert(!"unknown instruction");
701996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	}
702996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
703996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMValueRef v = LLVMBuildICmp(builder, pred,
704996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], emit_data->args[1],"");
705996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
706996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	v = LLVMBuildSExtOrBitCast(builder, v,
707996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			LLVMInt32TypeInContext(context), "");
708996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
709996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = v;
710996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
711996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
712cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellardstatic void emit_cmp(
713cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard		const struct lp_build_tgsi_action *action,
714cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard		struct lp_build_tgsi_context * bld_base,
715cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard		struct lp_build_emit_data * emit_data)
716cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard{
717cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
718cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	LLVMRealPredicate pred;
719cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	LLVMValueRef cond;
720cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard
721cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	/* XXX I'm not sure whether to do unordered or ordered comparisons,
722cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	 * but llvmpipe uses unordered comparisons, so for consistency we use
723cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	 * unordered.  (The authors of llvmpipe aren't sure about using
724cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	 * unordered vs ordered comparisons either.
725cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	 */
726cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	switch (emit_data->inst->Instruction.Opcode) {
727cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	case TGSI_OPCODE_SGE: pred = LLVMRealUGE; break;
728cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	case TGSI_OPCODE_SEQ: pred = LLVMRealUEQ; break;
729cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	case TGSI_OPCODE_SLE: pred = LLVMRealULE; break;
730cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	case TGSI_OPCODE_SLT: pred = LLVMRealULT; break;
731cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	case TGSI_OPCODE_SNE: pred = LLVMRealUNE; break;
732cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	case TGSI_OPCODE_SGT: pred = LLVMRealUGT; break;
733cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	default: assert(!"unknown instruction");
734cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	}
735cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard
736cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	cond = LLVMBuildFCmp(builder,
737cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard		pred, emit_data->args[0], emit_data->args[1], "");
738cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard
739cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	emit_data->output[emit_data->chan] = LLVMBuildSelect(builder,
740cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard		cond, bld_base->base.one, bld_base->base.zero, "");
741cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard}
742cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard
743996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_not(
744996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
745996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
746996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
747996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
748996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
749996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMValueRef v = bitcast(bld_base, TGSI_TYPE_UNSIGNED,
750996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0]);
751996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildNot(builder, v, "");
752996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
753996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
754996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_and(
755996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
756996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
757996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
758996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
759996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
760996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildAnd(builder,
761996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], emit_data->args[1], "");
762996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
763996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
764996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_or(
765996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
766996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
767996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
768996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
769996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
770996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
771996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], emit_data->args[1], "");
772996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
773996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
774996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_uadd(
775996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
776996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
777996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
778996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
779996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
780996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildAdd(builder,
781996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], emit_data->args[1], "");
782996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
783996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
784996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_udiv(
785996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
786996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
787996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
788996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
789996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
790996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildUDiv(builder,
791996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], emit_data->args[1], "");
792996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
793996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
794996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_idiv(
795996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
796996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
797996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
798996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
799996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
800996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildSDiv(builder,
801996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], emit_data->args[1], "");
802996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
803996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
804996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_mod(
805996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
806996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
807996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
808996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
809996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
810996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildSRem(builder,
811996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], emit_data->args[1], "");
812996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
813996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
814996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_umod(
815996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
816996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
817996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
818996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
819996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
820996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildURem(builder,
821996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], emit_data->args[1], "");
822996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
823996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
824e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlinstatic void emit_shl(
825e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin		const struct lp_build_tgsi_action * action,
826e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin		struct lp_build_tgsi_context * bld_base,
827e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin		struct lp_build_emit_data * emit_data)
828e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin{
829e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
830e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildShl(builder,
831e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin			emit_data->args[0], emit_data->args[1], "");
832e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin}
833e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin
834e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlinstatic void emit_ushr(
835e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin		const struct lp_build_tgsi_action * action,
836e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin		struct lp_build_tgsi_context * bld_base,
837e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin		struct lp_build_emit_data * emit_data)
838e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin{
839e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
840e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildLShr(builder,
841e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin			emit_data->args[0], emit_data->args[1], "");
842e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin}
843e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlinstatic void emit_ishr(
844e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin		const struct lp_build_tgsi_action * action,
845e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin		struct lp_build_tgsi_context * bld_base,
846e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin		struct lp_build_emit_data * emit_data)
847e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin{
848e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
849e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildAShr(builder,
850e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin			emit_data->args[0], emit_data->args[1], "");
851e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin}
852e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin
853996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_xor(
854996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
855996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
856996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
857996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
858996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
859996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildXor(builder,
860996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], emit_data->args[1], "");
861996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
862996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
863996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_ssg(
864996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
865996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
866996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
867996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
868996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
869996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
870996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMValueRef cmp, val;
871996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
872996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_ISSG) {
873996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		cmp = LLVMBuildICmp(builder, LLVMIntSGT, emit_data->args[0], bld_base->int_bld.zero, "");
874996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		val = LLVMBuildSelect(builder, cmp, bld_base->int_bld.one, emit_data->args[0], "");
875996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		cmp = LLVMBuildICmp(builder, LLVMIntSGE, val, bld_base->int_bld.zero, "");
876996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		val = LLVMBuildSelect(builder, cmp, val, LLVMConstInt(bld_base->int_bld.elem_type, -1, true), "");
877996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	} else { // float SSG
878996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		cmp = LLVMBuildFCmp(builder, LLVMRealUGT, emit_data->args[0], bld_base->int_bld.zero, "");
879996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		val = LLVMBuildSelect(builder, cmp, bld_base->base.one, emit_data->args[0], "");
880996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		cmp = LLVMBuildFCmp(builder, LLVMRealUGE, val, bld_base->base.zero, "");
881996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		val = LLVMBuildSelect(builder, cmp, val, LLVMConstReal(bld_base->base.elem_type, -1), "");
882996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	}
883996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
884996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = val;
885996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
886996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
887996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_ineg(
888996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
889996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
890996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
891996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
892996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
893996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildNeg(builder,
894996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], "");
895996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
896996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
897996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_f2i(
898996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
899996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
900996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
901996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
902996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
903996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildFPToSI(builder,
904996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], bld_base->int_bld.elem_type, "");
905996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
906996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
907996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_f2u(
908996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
909996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
910996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
911996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
912996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
913996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildFPToUI(builder,
914996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], bld_base->uint_bld.elem_type, "");
915996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
916996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
917996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_i2f(
918996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
919996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
920996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
921996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
922996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
923996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildSIToFP(builder,
924996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], bld_base->base.elem_type, "");
925996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
926996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
927996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlinstatic void emit_u2f(
928996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		const struct lp_build_tgsi_action * action,
929996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_tgsi_context * bld_base,
930996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin		struct lp_build_emit_data * emit_data)
931996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin{
932996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
933996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	emit_data->output[emit_data->chan] = LLVMBuildUIToFP(builder,
934996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin			emit_data->args[0], bld_base->base.elem_type, "");
935996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin}
936996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
9372a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlinstatic void emit_immediate(struct lp_build_tgsi_context * bld_base,
9382a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		const struct tgsi_full_immediate *imm)
9392a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin{
9402a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	unsigned i;
9412a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
9422a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin
9432a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	for (i = 0; i < 4; ++i) {
9442a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin		ctx->soa.immediates[ctx->soa.num_immediates][i] =
9452a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin				LLVMConstInt(bld_base->uint_bld.elem_type, imm->u[i].Uint, false   );
9462a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	}
9472a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin
9482a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	ctx->soa.num_immediates++;
9492a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin}
9502a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin
95112a2374da380a9a28cacf968c33b93ba320b0407Vadim GirlinLLVMValueRef
95212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlinbuild_intrinsic(LLVMBuilderRef builder,
95312a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin                   const char *name,
95412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin                   LLVMTypeRef ret_type,
95512a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin                   LLVMValueRef *args,
95612a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin                   unsigned num_args,
95712a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin                   LLVMAttribute attr)
95812a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin{
95912a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin   LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)));
96012a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin   LLVMValueRef function;
96112a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin
96212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin   function = LLVMGetNamedFunction(module, name);
96312a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin   if(!function) {
96412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin      LLVMTypeRef arg_types[LP_MAX_FUNC_ARGS];
96512a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin      unsigned i;
96612a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin
96712a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin      assert(num_args <= LP_MAX_FUNC_ARGS);
96812a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin
96912a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin      for(i = 0; i < num_args; ++i) {
97012a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin         assert(args[i]);
97112a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin         arg_types[i] = LLVMTypeOf(args[i]);
97212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin      }
97312a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin
97412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin      function = lp_declare_intrinsic(module, name, ret_type, arg_types, num_args);
97512a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin
97612a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin      if (attr)
97712a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin          LLVMAddFunctionAttr(function, attr);
97812a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin   }
97912a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin
98012a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin   return LLVMBuildCall(builder, function, args, num_args, "");
98112a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin}
98212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin
98312a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlinvoid
98412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlinbuild_tgsi_intrinsic_nomem(
98512a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin const struct lp_build_tgsi_action * action,
98612a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin struct lp_build_tgsi_context * bld_base,
98712a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin struct lp_build_emit_data * emit_data)
98812a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin{
98912a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin   struct lp_build_context * base = &bld_base->base;
99012a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin   emit_data->output[emit_data->chan] = build_intrinsic(
99112a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin               base->gallivm->builder, action->intr_name,
99212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin               emit_data->dst_type, emit_data->args,
99312a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin               emit_data->arg_count, LLVMReadNoneAttribute);
99412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin}
99512a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin
996a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid radeon_llvm_context_init(struct radeon_llvm_context * ctx)
997a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
998a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_type type;
999a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMTypeRef main_fn_type;
1000a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBasicBlockRef main_fn_body;
1001a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1002a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Initialize the gallivm object:
1003a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * We are only using the module, context, and builder fields of this struct.
1004a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * This should be enough for us to be able to pass our gallivm struct to the
1005a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * helper functions in the gallivm module.
1006a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 */
1007a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	memset(&ctx->gallivm, 0, sizeof (ctx->gallivm));
1008a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	memset(&ctx->soa, 0, sizeof(ctx->soa));
1009a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->gallivm.context = LLVMContextCreate();
1010a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->gallivm.module = LLVMModuleCreateWithNameInContext("tgsi",
1011a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard						ctx->gallivm.context);
1012a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->gallivm.builder = LLVMCreateBuilderInContext(ctx->gallivm.context);
1013a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1014a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Setup the module */
1015a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	main_fn_type = LLVMFunctionType(LLVMVoidTypeInContext(ctx->gallivm.context),
1016a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard					 NULL, 0, 0);
1017a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->main_fn = LLVMAddFunction(ctx->gallivm.module, "main", main_fn_type);
1018a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	main_fn_body = LLVMAppendBasicBlockInContext(ctx->gallivm.context,
1019a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard			ctx->main_fn, "main_body");
1020a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 LLVMPositionBuilderAtEnd(ctx->gallivm.builder, main_fn_body);
1021a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1022a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->store_output_intr = "llvm.AMDGPU.store.output.";
1023a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->swizzle_intr = "llvm.AMDGPU.swizzle";
1024a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
1025a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1026a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX: We need to revisit this.I think the correct way to do this is
1027a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	 * to use length = 4 here and use the elem_bld for everything. */
1028a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	type.floating = TRUE;
1029a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	type.sign = TRUE;
1030a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	type.width = 32;
1031a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	type.length = 1;
1032a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1033a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	lp_build_context_init(&bld_base->base, &ctx->gallivm, type);
1034a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	lp_build_context_init(&ctx->soa.bld_base.uint_bld, &ctx->gallivm, lp_uint_type(type));
10352a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	lp_build_context_init(&ctx->soa.bld_base.int_bld, &ctx->gallivm, lp_int_type(type));
1036a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1037a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->soa = 1;
1038a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->emit_store = emit_store;
1039a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->emit_swizzle = emit_swizzle;
1040a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->emit_declaration = emit_declaration;
10412a88dfc521bff7255e27e2ef8efcd08f9db53747Vadim Girlin	bld_base->emit_immediate = emit_immediate;
1042a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1043a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate;
1044a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input;
1045a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->emit_fetch_funcs[TGSI_FILE_TEMPORARY] = emit_fetch_temporary;
1046a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = emit_fetch_output;
1047a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1048a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Allocate outputs */
1049a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->soa.outputs = ctx->outputs;
1050a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1051a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* XXX: Is there a better way to initialize all this ? */
1052a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1053a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	lp_set_default_actions(bld_base);
1054a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
105512a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_IABS].emit = build_tgsi_intrinsic_nomem;
1056996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_IABS].intr_name = "llvm.AMDIL.abs.";
1057996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_NOT].emit = emit_not;
1058996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_AND].emit = emit_and;
1059996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_XOR].emit = emit_xor;
1060996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_OR].emit = emit_or;
1061996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_UADD].emit = emit_uadd;
1062996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_UDIV].emit = emit_udiv;
1063996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_IDIV].emit = emit_idiv;
1064996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_MOD].emit = emit_mod;
1065996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_UMOD].emit = emit_umod;
1066996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_INEG].emit = emit_ineg;
1067e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin	bld_base->op_actions[TGSI_OPCODE_SHL].emit = emit_shl;
1068e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin	bld_base->op_actions[TGSI_OPCODE_ISHR].emit = emit_ishr;
1069e740b60845b56f9bb08ae751d80b058a27c73d5aVadim Girlin	bld_base->op_actions[TGSI_OPCODE_USHR].emit = emit_ushr;
1070996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_SSG].emit = emit_ssg;
1071996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_ISSG].emit = emit_ssg;
1072996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_I2F].emit = emit_i2f;
1073996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_U2F].emit = emit_u2f;
1074996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_F2I].emit = emit_f2i;
1075996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_F2U].emit = emit_f2u;
107695ed0e9b6b445c70e920d340818fc0f84d45233eVadim Girlin	bld_base->op_actions[TGSI_OPCODE_DDX].intr_name = "llvm.AMDGPU.ddx";
107795ed0e9b6b445c70e920d340818fc0f84d45233eVadim Girlin	bld_base->op_actions[TGSI_OPCODE_DDX].fetch_args = tex_fetch_args;
107895ed0e9b6b445c70e920d340818fc0f84d45233eVadim Girlin	bld_base->op_actions[TGSI_OPCODE_DDY].intr_name = "llvm.AMDGPU.ddy";
107995ed0e9b6b445c70e920d340818fc0f84d45233eVadim Girlin	bld_base->op_actions[TGSI_OPCODE_DDY].fetch_args = tex_fetch_args;
1080996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_USEQ].emit = emit_icmp;
1081996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_USGE].emit = emit_icmp;
1082996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_USLT].emit = emit_icmp;
1083996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_USNE].emit = emit_icmp;
1084996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_ISGE].emit = emit_icmp;
1085996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_ISLT].emit = emit_icmp;
108612a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_ROUND].emit = build_tgsi_intrinsic_nomem;
1087996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_ROUND].intr_name = "llvm.AMDIL.round.nearest.";
108812a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_MIN].emit = build_tgsi_intrinsic_nomem;
1089996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.AMDIL.min.";
109012a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_MAX].emit = build_tgsi_intrinsic_nomem;
1091996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_MAX].intr_name = "llvm.AMDIL.max.";
109212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_IMIN].emit = build_tgsi_intrinsic_nomem;
1093996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_IMIN].intr_name = "llvm.AMDGPU.imin";
109412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_IMAX].emit = build_tgsi_intrinsic_nomem;
1095996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_IMAX].intr_name = "llvm.AMDGPU.imax";
109612a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_UMIN].emit = build_tgsi_intrinsic_nomem;
1097996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_UMIN].intr_name = "llvm.AMDGPU.umin";
109812a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_UMAX].emit = build_tgsi_intrinsic_nomem;
1099996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin	bld_base->op_actions[TGSI_OPCODE_UMAX].intr_name = "llvm.AMDGPU.umax";
11004a8d47c264eb7e01ebfda2fbcbe0bf42f0882d38Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_TXF].fetch_args = txf_fetch_args;
110195ed0e9b6b445c70e920d340818fc0f84d45233eVadim Girlin	bld_base->op_actions[TGSI_OPCODE_TXF].intr_name = "llvm.AMDGPU.txf";
110295ed0e9b6b445c70e920d340818fc0f84d45233eVadim Girlin	bld_base->op_actions[TGSI_OPCODE_TXQ].fetch_args = tex_fetch_args;
110395ed0e9b6b445c70e920d340818fc0f84d45233eVadim Girlin	bld_base->op_actions[TGSI_OPCODE_TXQ].intr_name = "llvm.AMDGPU.txq";
110412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_CEIL].emit = build_tgsi_intrinsic_nomem;
110563a85952711415ab151a39d21c4a67da97f2734eVadim Girlin	bld_base->op_actions[TGSI_OPCODE_CEIL].intr_name = "llvm.AMDIL.round.posinf.";
1106996fa375ec275ab5053855dc95f9cc4f301d596cVadim Girlin
110795ed0e9b6b445c70e920d340818fc0f84d45233eVadim Girlin
110895ed0e9b6b445c70e920d340818fc0f84d45233eVadim Girlin
110912a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_ABS].emit = build_tgsi_intrinsic_nomem;
1110a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_ABS].intr_name = "llvm.AMDIL.fabs.";
111112a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_ARL].emit = build_tgsi_intrinsic_nomem;
1112a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_ARL].intr_name = "llvm.AMDGPU.arl";
1113a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_BGNLOOP].emit = bgnloop_emit;
1114a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_BRK].emit = brk_emit;
1115a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_CONT].emit = cont_emit;
111612a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_CLAMP].emit = build_tgsi_intrinsic_nomem;
1117a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_CLAMP].intr_name = "llvm.AMDIL.clamp.";
111812a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_CMP].emit = build_tgsi_intrinsic_nomem;
1119a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_CMP].intr_name = "llvm.AMDGPU.cndlt";
112012a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_COS].emit = build_tgsi_intrinsic_nomem;
1121a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_COS].intr_name = "llvm.AMDGPU.cos";
112212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_DIV].emit = build_tgsi_intrinsic_nomem;
1123a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_DIV].intr_name = "llvm.AMDGPU.div";
1124a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_ELSE].emit = else_emit;
1125a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_ENDIF].emit = endif_emit;
1126a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_ENDLOOP].emit = endloop_emit;
112712a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_EX2].emit = build_tgsi_intrinsic_nomem;
1128a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_EX2].intr_name = "llvm.AMDIL.exp.";
112912a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_FLR].emit = build_tgsi_intrinsic_nomem;
1130a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_FLR].intr_name = "llvm.AMDGPU.floor";
113112a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_FRC].emit = build_tgsi_intrinsic_nomem;
1132a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_FRC].intr_name = "llvm.AMDIL.fraction.";
1133a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_IF].emit = if_emit;
113477d2780cbc00d525b25c6e625b1faeb37e3ad6d0Tom Stellard	bld_base->op_actions[TGSI_OPCODE_KIL].emit = kil_emit;
1135a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_KIL].intr_name = "llvm.AMDGPU.kill";
1136a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_KILP].emit = lp_build_tgsi_intrinsic;
1137a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_KILP].intr_name = "llvm.AMDGPU.kilp";
113812a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_LG2].emit = build_tgsi_intrinsic_nomem;
1139a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_LG2].intr_name = "llvm.AMDIL.log.";
114012a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_LRP].emit = build_tgsi_intrinsic_nomem;
1141a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_LRP].intr_name = "llvm.AMDGPU.lrp";
114212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_MIN].emit = build_tgsi_intrinsic_nomem;
1143a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.AMDIL.min.";
114412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_MAD].emit = build_tgsi_intrinsic_nomem;
1145a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_MAD].intr_name = "llvm.AMDIL.mad.";
114612a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_MAX].emit = build_tgsi_intrinsic_nomem;
1147a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_MAX].intr_name = "llvm.AMDIL.max.";
114812a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_MUL].emit = build_tgsi_intrinsic_nomem;
1149a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_MUL].intr_name = "llvm.AMDGPU.mul";
115012a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_POW].emit = build_tgsi_intrinsic_nomem;
1151a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_POW].intr_name = "llvm.AMDGPU.pow";
115212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_RCP].emit = build_tgsi_intrinsic_nomem;
1153a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_RCP].intr_name = "llvm.AMDGPU.rcp";
115412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_SSG].emit = build_tgsi_intrinsic_nomem;
1155a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_SSG].intr_name = "llvm.AMDGPU.ssg";
1156cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	bld_base->op_actions[TGSI_OPCODE_SGE].emit = emit_cmp;
1157cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	bld_base->op_actions[TGSI_OPCODE_SEQ].emit = emit_cmp;
1158cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	bld_base->op_actions[TGSI_OPCODE_SLE].emit = emit_cmp;
1159cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	bld_base->op_actions[TGSI_OPCODE_SLT].emit = emit_cmp;
1160cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	bld_base->op_actions[TGSI_OPCODE_SNE].emit = emit_cmp;
1161cee23ab246f22210b3063cdc47bdb45b3d943526Tom Stellard	bld_base->op_actions[TGSI_OPCODE_SGT].emit = emit_cmp;
116212a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_SIN].emit = build_tgsi_intrinsic_nomem;
1163a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_SIN].intr_name = "llvm.AMDGPU.sin";
1164a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_TEX].fetch_args = tex_fetch_args;
1165a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_TEX].intr_name = "llvm.AMDGPU.tex";
1166a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_TXB].fetch_args = tex_fetch_args;
1167a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_TXB].intr_name = "llvm.AMDGPU.txb";
1168fa5a963dd6c2622c416d53e49b08c4b3cbce7483Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_TXD].fetch_args = txd_fetch_args;
1169a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_TXD].intr_name = "llvm.AMDGPU.txd";
1170a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_TXL].fetch_args = tex_fetch_args;
1171a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_TXL].intr_name = "llvm.AMDGPU.txl";
1172d6aa7cd7f82a3695243e1ecb1c73cdb796b12523Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_TXP].fetch_args = txp_fetch_args;
1173a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_TXP].intr_name = "llvm.AMDGPU.tex";
117412a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->op_actions[TGSI_OPCODE_TRUNC].emit = build_tgsi_intrinsic_nomem;
1175a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->op_actions[TGSI_OPCODE_TRUNC].intr_name = "llvm.AMDGPU.trunc";
1176a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
117712a2374da380a9a28cacf968c33b93ba320b0407Vadim Girlin	bld_base->rsq_action.emit = build_tgsi_intrinsic_nomem;
1178a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	bld_base->rsq_action.intr_name = "llvm.AMDGPU.rsq";
1179a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
1180a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1181a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid radeon_llvm_finalize_module(struct radeon_llvm_context * ctx)
1182a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
1183a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	struct gallivm_state * gallivm = ctx->soa.bld_base.base.gallivm;
1184a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* End the main function with Return*/
1185a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMBuildRetVoid(gallivm->builder);
1186a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1187a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Create the pass manager */
1188a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	ctx->gallivm.passmgr = LLVMCreateFunctionPassManagerForModule(
1189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard							gallivm->module);
1190a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1191a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* This pass should eliminate all the load and store instructions */
1192a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
1193a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1194a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Add some optimization passes */
1195a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMAddScalarReplAggregatesPass(gallivm->passmgr);
1196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMAddCFGSimplificationPass(gallivm->passmgr);
1197a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1198a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	/* Run the passs */
1199a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMRunFunctionPassManager(gallivm->passmgr, ctx->main_fn);
1200a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1201a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMDisposeBuilder(gallivm->builder);
1202a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMDisposePassManager(gallivm->passmgr);
1203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1204a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
1205a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard
1206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid radeon_llvm_dispose(struct radeon_llvm_context * ctx)
1207a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard{
1208a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMDisposeModule(ctx->soa.bld_base.base.gallivm->module);
1209a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard	LLVMContextDispose(ctx->soa.bld_base.base.gallivm->context);
1210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard}
1211