1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2011 Advanced Micro Devices, Inc.
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"),
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions:
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software.
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE.
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors: Tom Stellard <thomas.stellard@amd.com>
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_llvm.h"
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_const.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_gather.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_flow.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_init.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_intr.h"
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "gallivm/lp_bld_swizzle.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_info.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "tgsi/tgsi_parse.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <llvm-c/Core.h>
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <llvm-c/Transforms/Scalar.h>
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct radeon_llvm_loop * get_current_loop(struct radeon_llvm_context * ctx)
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return ctx->loop_depth > 0 ? ctx->loop + (ctx->loop_depth - 1) : NULL;
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct radeon_llvm_branch * get_current_branch(
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx)
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return ctx->branch_depth > 0 ?
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ctx->branch + (ctx->branch_depth - 1) : NULL;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan)
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (index * 4) + chan;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LLVMValueRef emit_swizzle(
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        LLVMValueRef value,
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned swizzle_x,
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned swizzle_y,
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned swizzle_z,
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned swizzle_w)
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef swizzles[4];
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMTypeRef i32t =
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMInt32TypeInContext(bld_base->base.gallivm->context);
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swizzles[0] = LLVMConstInt(i32t, swizzle_x, 0);
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swizzles[1] = LLVMConstInt(i32t, swizzle_y, 0);
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swizzles[2] = LLVMConstInt(i32t, swizzle_z, 0);
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	swizzles[3] = LLVMConstInt(i32t, swizzle_w, 0);
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return LLVMBuildShuffleVector(bld_base->base.gallivm->builder,
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		value,
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMGetUndef(LLVMTypeOf(value)),
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMConstVector(swizzles, 4), "");
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LLVMValueRef
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_array_index(
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_soa_context *bld,
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_src_register *reg,
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned swizzle)
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state * gallivm = bld->bld_base.base.gallivm;
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef addr = LLVMBuildLoad(gallivm->builder,
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld->addr[reg->Indirect.Index][swizzle], "");
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef offset = lp_build_const_int32(gallivm, reg->Register.Index);
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef hw_index = LLVMBuildAdd(gallivm->builder, addr, offset, "");
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef soa_index = LLVMBuildMul(gallivm->builder, hw_index,
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	lp_build_const_int32(gallivm, 4), "");
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef array_index = LLVMBuildAdd(gallivm->builder, soa_index,
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	lp_build_const_int32(gallivm, swizzle), "");
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return array_index;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LLVMValueRef
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_fetch_immediate(
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context *bld_base,
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_src_register *reg,
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	enum tgsi_opcode_type type,
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned swizzle)
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMTypeRef ctype;
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMContextRef ctx = bld_base->base.gallivm->context;
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (type) {
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_TYPE_UNSIGNED:
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_TYPE_SIGNED:
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctype = LLVMInt32TypeInContext(ctx);
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_TYPE_UNTYPED:
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_TYPE_FLOAT:
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctype = LLVMFloatTypeInContext(ctx);
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctype = 0;
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	return LLVMConstBitCast(bld->immediates[reg->Register.Index][swizzle], ctype);
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LLVMValueRef
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_fetch_input(
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context *bld_base,
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_src_register *reg,
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	enum tgsi_opcode_type type,
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned swizzle)
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (swizzle == ~0) {
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef values[TGSI_NUM_CHANNELS] = {};
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned chan;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			values[chan] = ctx->inputs[radeon_llvm_reg_index_soa(
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						reg->Register.Index, chan)];
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return lp_build_gather_values(bld_base->base.gallivm, values,
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						TGSI_NUM_CHANNELS);
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return bitcast(bld_base, type, ctx->inputs[radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)]);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LLVMValueRef
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_fetch_temporary(
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context *bld_base,
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_src_register *reg,
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	enum tgsi_opcode_type type,
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned swizzle)
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (swizzle == ~0) {
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef values[TGSI_NUM_CHANNELS] = {};
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned chan;
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			values[chan] = emit_fetch_temporary(bld_base, reg, type, chan);
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return lp_build_gather_values(bld_base->base.gallivm, values,
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						TGSI_NUM_CHANNELS);
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (reg->Register.Indirect) {
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef array_index = emit_array_index(bld, reg, swizzle);
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef ptr = LLVMBuildGEP(builder, bld->temps_array, &array_index,
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						1, "");
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return LLVMBuildLoad(builder, ptr, "");
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef temp_ptr;
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle);
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return bitcast(bld_base,type,LLVMBuildLoad(builder, temp_ptr, ""));
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LLVMValueRef
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_fetch_output(
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context *bld_base,
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_src_register *reg,
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	enum tgsi_opcode_type type,
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned swizzle)
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 if (reg->Register.Indirect) {
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef array_index = emit_array_index(bld, reg, swizzle);
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef ptr = LLVMBuildGEP(builder, bld->outputs_array, &array_index,
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						1, "");
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return LLVMBuildLoad(builder, ptr, "");
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef temp_ptr;
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		temp_ptr = lp_get_output_ptr(bld, reg->Register.Index, swizzle);
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return LLVMBuildLoad(builder, temp_ptr, "");
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 }
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_declaration(
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_declaration *decl)
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch(decl->Declaration.File) {
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_FILE_ADDRESS:
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 unsigned idx;
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned chan;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				 ctx->soa.addr[idx][chan] = lp_build_alloca(
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					&ctx->gallivm,
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					ctx->soa.bld_base.uint_bld.elem_type, "");
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_FILE_TEMPORARY:
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		lp_emit_declaration_soa(bld_base, decl);
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_FILE_INPUT:
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned idx;
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ctx->load_input(ctx, idx, decl);
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	break;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_FILE_SYSTEM_VALUE:
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned idx;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ctx->load_system_value(ctx, idx, decl);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	break;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_FILE_OUTPUT:
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	{
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		unsigned idx;
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			unsigned chan;
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			assert(idx < RADEON_LLVM_MAX_OUTPUTS);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				ctx->soa.outputs[idx][chan] = lp_build_alloca(&ctx->gallivm,
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					ctx->soa.bld_base.base.elem_type, "");
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctx->output_reg_count = MAX2(ctx->output_reg_count,
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							 decl->Range.Last + 1);
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		break;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgemit_store(
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_instruction * inst,
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_opcode_info * info,
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef dst[4])
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_context base = bld->bld_base.base;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_dst_register *reg = &inst->Dst[0];
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef temp_ptr;
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned chan, chan_index;
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	boolean is_vec_store = FALSE;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (dst[0]) {
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMTypeKind k = LLVMGetTypeKind(LLVMTypeOf(dst[0]));
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		is_vec_store = (k == LLVMVectorTypeKind);
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (is_vec_store) {
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef values[4] = {};
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		TGSI_FOR_EACH_DST0_ENABLED_CHANNEL(inst, chan) {
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			LLVMValueRef index = lp_build_const_int32(gallivm, chan);
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			values[chan]  = LLVMBuildExtractElement(gallivm->builder,
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							dst[0], index, "");
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		bld_base->emit_store(bld_base, inst, info, values);
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		return;
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef value = dst[chan_index];
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		if (inst->Instruction.Saturate != TGSI_SAT_NONE) {
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			struct lp_build_emit_data clamp_emit_data;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			memset(&clamp_emit_data, 0, sizeof(clamp_emit_data));
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			clamp_emit_data.arg_count = 3;
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			clamp_emit_data.args[0] = value;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			clamp_emit_data.args[2] = base.one;
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			switch(inst->Instruction.Saturate) {
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case TGSI_SAT_ZERO_ONE:
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				clamp_emit_data.args[1] = base.zero;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			case TGSI_SAT_MINUS_PLUS_ONE:
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				clamp_emit_data.args[1] = LLVMConstReal(
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						base.elem_type, -1.0f);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				break;
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			default:
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				assert(0);
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			}
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			value = lp_build_emit_llvm(bld_base, TGSI_OPCODE_CLAMP,
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						&clamp_emit_data);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		switch(reg->Register.File) {
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case TGSI_FILE_OUTPUT:
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			temp_ptr = bld->outputs[reg->Register.Index][chan_index];
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		case TGSI_FILE_TEMPORARY:
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, chan_index);
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			break;
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		default:
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			return;
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		}
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		value = bitcast(bld_base, TGSI_TYPE_FLOAT, value);
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMBuildStore(builder, value, temp_ptr);
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void bgnloop_emit(
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct lp_build_tgsi_action * action,
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state * gallivm = bld_base->base.gallivm;
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBasicBlockRef loop_block;
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBasicBlockRef endloop_block;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	endloop_block = LLVMAppendBasicBlockInContext(gallivm->context,
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						ctx->main_fn, "ENDLOOP");
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	loop_block = LLVMInsertBasicBlockInContext(gallivm->context,
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						endloop_block, "LOOP");
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuildBr(gallivm->builder, loop_block);
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMPositionBuilderAtEnd(gallivm->builder, loop_block);
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->loop_depth++;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->loop[ctx->loop_depth - 1].loop_block = loop_block;
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->loop[ctx->loop_depth - 1].endloop_block = endloop_block;
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void brk_emit(
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct lp_build_tgsi_action * action,
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state * gallivm = bld_base->base.gallivm;
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_loop * current_loop = get_current_loop(ctx);
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuildBr(gallivm->builder, current_loop->endloop_block);
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void cont_emit(
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct lp_build_tgsi_action * action,
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state * gallivm = bld_base->base.gallivm;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_loop * current_loop = get_current_loop(ctx);
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuildBr(gallivm->builder, current_loop->loop_block);
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void else_emit(
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct lp_build_tgsi_action * action,
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state * gallivm = bld_base->base.gallivm;
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_branch * current_branch = get_current_branch(ctx);
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBasicBlockRef current_block = LLVMGetInsertBlock(gallivm->builder);
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* We need to add a terminator to the current block if the previous
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * instruction was an ENDIF.Example:
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * IF
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *   [code]
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *   IF
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *     [code]
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *   ELSE
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *    [code]
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *   ENDIF <--
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * ELSE<--
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 *   [code]
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * ENDIF
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (current_block != current_branch->if_block) {
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!LLVMGetBasicBlockTerminator(current_branch->if_block)) {
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	current_branch->has_else = 1;
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->else_block);
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void endif_emit(
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct lp_build_tgsi_action * action,
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state * gallivm = bld_base->base.gallivm;
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_branch * current_branch = get_current_branch(ctx);
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBasicBlockRef current_block = LLVMGetInsertBlock(gallivm->builder);
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* If we have consecutive ENDIF instructions, then the first ENDIF
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * will not have a terminator, so we need to add one. */
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (current_block != current_branch->if_block
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			&& current_block != current_branch->else_block
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			&& !LLVMGetBasicBlockTerminator(current_block)) {
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 LLVMBuildBr(gallivm->builder, current_branch->endif_block);
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!LLVMGetBasicBlockTerminator(current_branch->else_block)) {
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->else_block);
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!LLVMGetBasicBlockTerminator(current_branch->if_block)) {
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->if_block);
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->endif_block);
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->branch_depth--;
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void endloop_emit(
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct lp_build_tgsi_action * action,
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state * gallivm = bld_base->base.gallivm;
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_loop * current_loop = get_current_loop(ctx);
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (!LLVMGetBasicBlockTerminator(LLVMGetInsertBlock(gallivm->builder))) {
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		 LLVMBuildBr(gallivm->builder, current_loop->loop_block);
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMPositionBuilderAtEnd(gallivm->builder, current_loop->endloop_block);
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->loop_depth--;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void if_emit(
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct lp_build_tgsi_action * action,
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state * gallivm = bld_base->base.gallivm;
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef cond;
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBasicBlockRef if_block, else_block, endif_block;
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE,
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	        bitcast(bld_base, TGSI_TYPE_UNSIGNED, emit_data->args[0]),
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			bld_base->int_bld.zero, "");
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	endif_block = LLVMAppendBasicBlockInContext(gallivm->context,
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						ctx->main_fn, "ENDIF");
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if_block = LLVMInsertBasicBlockInContext(gallivm->context,
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						endif_block, "IF");
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	else_block = LLVMInsertBasicBlockInContext(gallivm->context,
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						endif_block, "ELSE");
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuildCondBr(gallivm->builder, cond, if_block, else_block);
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMPositionBuilderAtEnd(gallivm->builder, if_block);
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->branch_depth++;
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->branch[ctx->branch_depth - 1].endif_block = endif_block;
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->branch[ctx->branch_depth - 1].if_block = if_block;
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->branch[ctx->branch_depth - 1].else_block = else_block;
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->branch[ctx->branch_depth - 1].has_else = 0;
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void kil_emit(
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct lp_build_tgsi_action * action,
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned i;
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < emit_data->arg_count; i++) {
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		emit_data->output[i] = lp_build_intrinsic_unary(
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			bld_base->base.gallivm->builder,
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			action->intr_name,
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->dst_type, emit_data->args[i]);
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_prepare_cube_coords(
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	boolean shadowcube = (emit_data->inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE);
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state * gallivm = bld_base->base.gallivm;
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = gallivm->builder;
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMTypeRef type = bld_base->base.elem_type;
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef coords[4];
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef mad_args[3];
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned i, cnt;
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef v = build_intrinsic(builder, "llvm.AMDGPU.cube",
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			LLVMVectorType(type, 4),
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			&emit_data->args[0],1, LLVMReadNoneAttribute);
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* save src.w for shadow cube */
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cnt = shadowcube ? 3 : 4;
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < cnt; ++i) {
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef idx = lp_build_const_int32(gallivm, i);
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		coords[i] = LLVMBuildExtractElement(builder, v, idx, "");
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	coords[2] = build_intrinsic(builder, "llvm.AMDIL.fabs.",
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			type, &coords[2], 1, LLVMReadNoneAttribute);
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	coords[2] = build_intrinsic(builder, "llvm.AMDGPU.rcp",
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			type, &coords[2], 1, LLVMReadNoneAttribute);
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mad_args[1] = coords[2];
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mad_args[2] = LLVMConstReal(type, 1.5);
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mad_args[0] = coords[0];
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	coords[0] = build_intrinsic(builder, "llvm.AMDIL.mad.",
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			type, mad_args, 3, LLVMReadNoneAttribute);
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	mad_args[0] = coords[1];
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	coords[1] = build_intrinsic(builder, "llvm.AMDIL.mad.",
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			type, mad_args, 3, LLVMReadNoneAttribute);
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* apply yxwy swizzle to cooords */
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	coords[2] = coords[3];
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	coords[3] = coords[1];
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	coords[1] = coords[0];
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	coords[0] = coords[3];
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						coords, 4);
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void txd_fetch_args(
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_instruction * inst = emit_data->inst;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef coords[4];
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned chan, src;
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (src = 0; src < 3; src++) {
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		for (chan = 0; chan < 4; chan++)
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			coords[chan] = lp_build_emit_fetch(bld_base, inst, src, chan);
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		emit_data->args[src] = lp_build_gather_values(bld_base->base.gallivm,
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				coords, 4);
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->arg_count = 3;
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void txp_fetch_args(
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_instruction * inst = emit_data->inst;
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef src_w;
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned chan;
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef coords[4];
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	src_w = lp_build_emit_fetch(bld_base, emit_data->inst, 0, TGSI_CHAN_W);
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (chan = 0; chan < 3; chan++ ) {
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		LLVMValueRef arg = lp_build_emit_fetch(bld_base,
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						emit_data->inst, 0, chan);
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		coords[chan] = lp_build_emit_llvm_binary(bld_base,
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					TGSI_OPCODE_DIV, arg, src_w);
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	coords[3] = bld_base->base.one;
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						coords, 4);
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->arg_count = 1;
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ((inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) &&
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    inst->Instruction.Opcode != TGSI_OPCODE_TXQ) {
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		emit_prepare_cube_coords(bld_base, emit_data);
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void tex_fetch_args(
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* XXX: lp_build_swizzle_aos() was failing with wrong arg types,
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * when we used CHAN_ALL.  We should be able to get this to work,
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * but for now we will swizzle it ourselves
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst,
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						 0, CHAN_ALL);
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	*/
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_instruction * inst = emit_data->inst;
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef coords[4];
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned chan;
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (chan = 0; chan < 4; chan++) {
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		coords[chan] = lp_build_emit_fetch(bld_base, inst, 0, chan);
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->arg_count = 1;
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						coords, 4);
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if ((inst->Texture.Texture == TGSI_TEXTURE_CUBE ||
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	     inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE) &&
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    inst->Instruction.Opcode != TGSI_OPCODE_TXQ) {
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		emit_prepare_cube_coords(bld_base, emit_data);
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void txf_fetch_args(
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base,
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_emit_data * emit_data)
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_full_instruction * inst = emit_data->inst;
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	const struct tgsi_texture_offset * off = inst->TexOffsets;
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMTypeRef offset_type = bld_base->int_bld.elem_type;
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* fetch tex coords */
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	tex_fetch_args(bld_base, emit_data);
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* fetch tex offsets */
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (inst->Texture.NumOffsets) {
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(inst->Texture.NumOffsets == 1);
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		emit_data->args[1] = LLVMConstBitCast(
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			bld->immediates[off->Index][off->SwizzleX],
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			offset_type);
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		emit_data->args[2] = LLVMConstBitCast(
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			bld->immediates[off->Index][off->SwizzleY],
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			offset_type);
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		emit_data->args[3] = LLVMConstBitCast(
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			bld->immediates[off->Index][off->SwizzleZ],
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			offset_type);
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else {
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		emit_data->args[1] = bld_base->int_bld.zero;
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		emit_data->args[2] = bld_base->int_bld.zero;
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		emit_data->args[3] = bld_base->int_bld.zero;
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->arg_count = 4;
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_icmp(
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned pred;
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMContextRef context = bld_base->base.gallivm->context;
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (emit_data->inst->Instruction.Opcode) {
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_USEQ: pred = LLVMIntEQ; break;
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_USNE: pred = LLVMIntNE; break;
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_USGE: pred = LLVMIntUGE; break;
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_USLT: pred = LLVMIntULT; break;
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_ISGE: pred = LLVMIntSGE; break;
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_ISLT: pred = LLVMIntSLT; break;
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default:
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		assert(!"unknown instruction");
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef v = LLVMBuildICmp(builder, pred,
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1],"");
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	v = LLVMBuildSExtOrBitCast(builder, v,
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			LLVMInt32TypeInContext(context), "");
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = v;
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_cmp(
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action *action,
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMRealPredicate pred;
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef cond;
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* XXX I'm not sure whether to do unordered or ordered comparisons,
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * but llvmpipe uses unordered comparisons, so for consistency we use
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * unordered.  (The authors of llvmpipe aren't sure about using
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * unordered vs ordered comparisons either.
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	switch (emit_data->inst->Instruction.Opcode) {
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_SGE: pred = LLVMRealUGE; break;
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_SEQ: pred = LLVMRealUEQ; break;
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_SLE: pred = LLVMRealULE; break;
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_SLT: pred = LLVMRealULT; break;
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_SNE: pred = LLVMRealUNE; break;
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	case TGSI_OPCODE_SGT: pred = LLVMRealUGT; break;
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	default: assert(!"unknown instruction");
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	cond = LLVMBuildFCmp(builder,
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		pred, emit_data->args[0], emit_data->args[1], "");
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildSelect(builder,
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cond, bld_base->base.one, bld_base->base.zero, "");
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_not(
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef v = bitcast(bld_base, TGSI_TYPE_UNSIGNED,
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0]);
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildNot(builder, v, "");
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_and(
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildAnd(builder,
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_or(
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_uadd(
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildAdd(builder,
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_udiv(
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildUDiv(builder,
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_idiv(
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildSDiv(builder,
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_mod(
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildSRem(builder,
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_umod(
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildURem(builder,
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_shl(
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildShl(builder,
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_ushr(
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildLShr(builder,
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_ishr(
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildAShr(builder,
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_xor(
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildXor(builder,
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], emit_data->args[1], "");
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_ssg(
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMValueRef cmp, val;
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_ISSG) {
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cmp = LLVMBuildICmp(builder, LLVMIntSGT, emit_data->args[0], bld_base->int_bld.zero, "");
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		val = LLVMBuildSelect(builder, cmp, bld_base->int_bld.one, emit_data->args[0], "");
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cmp = LLVMBuildICmp(builder, LLVMIntSGE, val, bld_base->int_bld.zero, "");
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		val = LLVMBuildSelect(builder, cmp, val, LLVMConstInt(bld_base->int_bld.elem_type, -1, true), "");
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	} else { // float SSG
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cmp = LLVMBuildFCmp(builder, LLVMRealUGT, emit_data->args[0], bld_base->int_bld.zero, "");
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		val = LLVMBuildSelect(builder, cmp, bld_base->base.one, emit_data->args[0], "");
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		cmp = LLVMBuildFCmp(builder, LLVMRealUGE, val, bld_base->base.zero, "");
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		val = LLVMBuildSelect(builder, cmp, val, LLVMConstReal(bld_base->base.elem_type, -1), "");
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = val;
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_ineg(
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildNeg(builder,
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], "");
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_f2i(
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildFPToSI(builder,
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], bld_base->int_bld.elem_type, "");
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_f2u(
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildFPToUI(builder,
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], bld_base->uint_bld.elem_type, "");
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_i2f(
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildSIToFP(builder,
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], bld_base->base.elem_type, "");
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_u2f(
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct lp_build_tgsi_action * action,
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_tgsi_context * bld_base,
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		struct lp_build_emit_data * emit_data)
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	emit_data->output[emit_data->chan] = LLVMBuildUIToFP(builder,
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			emit_data->args[0], bld_base->base.elem_type, "");
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void emit_immediate(struct lp_build_tgsi_context * bld_base,
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		const struct tgsi_full_immediate *imm)
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	unsigned i;
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (i = 0; i < 4; ++i) {
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org		ctx->soa.immediates[ctx->soa.num_immediates][i] =
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org				LLVMConstInt(bld_base->uint_bld.elem_type, imm->u[i].Uint, false   );
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	}
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->soa.num_immediates++;
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgLLVMValueRef
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbuild_intrinsic(LLVMBuilderRef builder,
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   const char *name,
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   LLVMTypeRef ret_type,
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   LLVMValueRef *args,
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   unsigned num_args,
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   LLVMAttribute attr)
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)));
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   LLVMValueRef function;
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   function = LLVMGetNamedFunction(module, name);
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if(!function) {
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LLVMTypeRef arg_types[LP_MAX_FUNC_ARGS];
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned i;
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(num_args <= LP_MAX_FUNC_ARGS);
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for(i = 0; i < num_args; ++i) {
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(args[i]);
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         arg_types[i] = LLVMTypeOf(args[i]);
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      function = lp_declare_intrinsic(module, name, ret_type, arg_types, num_args);
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (attr)
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          LLVMAddFunctionAttr(function, attr);
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return LLVMBuildCall(builder, function, args, num_args, "");
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbuild_tgsi_intrinsic_nomem(
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct lp_build_tgsi_action * action,
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_tgsi_context * bld_base,
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct lp_build_emit_data * emit_data)
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct lp_build_context * base = &bld_base->base;
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   emit_data->output[emit_data->chan] = build_intrinsic(
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               base->gallivm->builder, action->intr_name,
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               emit_data->dst_type, emit_data->args,
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               emit_data->arg_count, LLVMReadNoneAttribute);
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid radeon_llvm_context_init(struct radeon_llvm_context * ctx)
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_type type;
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMTypeRef main_fn_type;
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBasicBlockRef main_fn_body;
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Initialize the gallivm object:
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * We are only using the module, context, and builder fields of this struct.
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * This should be enough for us to be able to pass our gallivm struct to the
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * helper functions in the gallivm module.
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 */
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	memset(&ctx->gallivm, 0, sizeof (ctx->gallivm));
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	memset(&ctx->soa, 0, sizeof(ctx->soa));
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->gallivm.context = LLVMContextCreate();
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->gallivm.module = LLVMModuleCreateWithNameInContext("tgsi",
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org						ctx->gallivm.context);
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->gallivm.builder = LLVMCreateBuilderInContext(ctx->gallivm.context);
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Setup the module */
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	main_fn_type = LLVMFunctionType(LLVMVoidTypeInContext(ctx->gallivm.context),
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org					 NULL, 0, 0);
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->main_fn = LLVMAddFunction(ctx->gallivm.module, "main", main_fn_type);
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	main_fn_body = LLVMAppendBasicBlockInContext(ctx->gallivm.context,
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org			ctx->main_fn, "main_body");
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 LLVMPositionBuilderAtEnd(ctx->gallivm.builder, main_fn_body);
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->store_output_intr = "llvm.AMDGPU.store.output.";
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->swizzle_intr = "llvm.AMDGPU.swizzle";
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* XXX: We need to revisit this.I think the correct way to do this is
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * to use length = 4 here and use the elem_bld for everything. */
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	type.floating = TRUE;
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	type.sign = TRUE;
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	type.width = 32;
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	type.length = 1;
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	lp_build_context_init(&bld_base->base, &ctx->gallivm, type);
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	lp_build_context_init(&ctx->soa.bld_base.uint_bld, &ctx->gallivm, lp_uint_type(type));
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	lp_build_context_init(&ctx->soa.bld_base.int_bld, &ctx->gallivm, lp_int_type(type));
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->soa = 1;
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->emit_store = emit_store;
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->emit_swizzle = emit_swizzle;
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->emit_declaration = emit_declaration;
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->emit_immediate = emit_immediate;
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate;
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input;
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->emit_fetch_funcs[TGSI_FILE_TEMPORARY] = emit_fetch_temporary;
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = emit_fetch_output;
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Allocate outputs */
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->soa.outputs = ctx->outputs;
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* XXX: Is there a better way to initialize all this ? */
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	lp_set_default_actions(bld_base);
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_IABS].emit = build_tgsi_intrinsic_nomem;
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_IABS].intr_name = "llvm.AMDIL.abs.";
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_NOT].emit = emit_not;
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_AND].emit = emit_and;
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_XOR].emit = emit_xor;
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_OR].emit = emit_or;
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_UADD].emit = emit_uadd;
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_UDIV].emit = emit_udiv;
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_IDIV].emit = emit_idiv;
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MOD].emit = emit_mod;
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_UMOD].emit = emit_umod;
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_INEG].emit = emit_ineg;
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SHL].emit = emit_shl;
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ISHR].emit = emit_ishr;
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_USHR].emit = emit_ushr;
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SSG].emit = emit_ssg;
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ISSG].emit = emit_ssg;
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_I2F].emit = emit_i2f;
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_U2F].emit = emit_u2f;
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_F2I].emit = emit_f2i;
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_F2U].emit = emit_f2u;
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_DDX].intr_name = "llvm.AMDGPU.ddx";
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_DDX].fetch_args = tex_fetch_args;
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_DDY].intr_name = "llvm.AMDGPU.ddy";
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_DDY].fetch_args = tex_fetch_args;
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_USEQ].emit = emit_icmp;
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_USGE].emit = emit_icmp;
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_USLT].emit = emit_icmp;
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_USNE].emit = emit_icmp;
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ISGE].emit = emit_icmp;
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ISLT].emit = emit_icmp;
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ROUND].emit = build_tgsi_intrinsic_nomem;
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ROUND].intr_name = "llvm.AMDIL.round.nearest.";
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MIN].emit = build_tgsi_intrinsic_nomem;
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.AMDIL.min.";
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MAX].emit = build_tgsi_intrinsic_nomem;
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MAX].intr_name = "llvm.AMDIL.max.";
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_IMIN].emit = build_tgsi_intrinsic_nomem;
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_IMIN].intr_name = "llvm.AMDGPU.imin";
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_IMAX].emit = build_tgsi_intrinsic_nomem;
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_IMAX].intr_name = "llvm.AMDGPU.imax";
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_UMIN].emit = build_tgsi_intrinsic_nomem;
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_UMIN].intr_name = "llvm.AMDGPU.umin";
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_UMAX].emit = build_tgsi_intrinsic_nomem;
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_UMAX].intr_name = "llvm.AMDGPU.umax";
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXF].fetch_args = txf_fetch_args;
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXF].intr_name = "llvm.AMDGPU.txf";
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXQ].fetch_args = tex_fetch_args;
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXQ].intr_name = "llvm.AMDGPU.txq";
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_CEIL].emit = build_tgsi_intrinsic_nomem;
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_CEIL].intr_name = "llvm.AMDIL.round.posinf.";
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ABS].emit = build_tgsi_intrinsic_nomem;
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ABS].intr_name = "llvm.AMDIL.fabs.";
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ARL].emit = build_tgsi_intrinsic_nomem;
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ARL].intr_name = "llvm.AMDGPU.arl";
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_BGNLOOP].emit = bgnloop_emit;
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_BRK].emit = brk_emit;
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_CONT].emit = cont_emit;
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_CLAMP].emit = build_tgsi_intrinsic_nomem;
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_CLAMP].intr_name = "llvm.AMDIL.clamp.";
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_CMP].emit = build_tgsi_intrinsic_nomem;
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_CMP].intr_name = "llvm.AMDGPU.cndlt";
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_COS].emit = build_tgsi_intrinsic_nomem;
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_COS].intr_name = "llvm.AMDGPU.cos";
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_DIV].emit = build_tgsi_intrinsic_nomem;
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_DIV].intr_name = "llvm.AMDGPU.div";
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ELSE].emit = else_emit;
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ENDIF].emit = endif_emit;
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_ENDLOOP].emit = endloop_emit;
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_EX2].emit = build_tgsi_intrinsic_nomem;
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_EX2].intr_name = "llvm.AMDIL.exp.";
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_FLR].emit = build_tgsi_intrinsic_nomem;
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_FLR].intr_name = "llvm.AMDGPU.floor";
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_FRC].emit = build_tgsi_intrinsic_nomem;
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_FRC].intr_name = "llvm.AMDIL.fraction.";
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_IF].emit = if_emit;
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_KIL].emit = kil_emit;
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_KIL].intr_name = "llvm.AMDGPU.kill";
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_KILP].emit = lp_build_tgsi_intrinsic;
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_KILP].intr_name = "llvm.AMDGPU.kilp";
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_LG2].emit = build_tgsi_intrinsic_nomem;
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_LG2].intr_name = "llvm.AMDIL.log.";
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_LRP].emit = build_tgsi_intrinsic_nomem;
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_LRP].intr_name = "llvm.AMDGPU.lrp";
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MIN].emit = build_tgsi_intrinsic_nomem;
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.AMDIL.min.";
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MAD].emit = build_tgsi_intrinsic_nomem;
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MAD].intr_name = "llvm.AMDIL.mad.";
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MAX].emit = build_tgsi_intrinsic_nomem;
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MAX].intr_name = "llvm.AMDIL.max.";
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MUL].emit = build_tgsi_intrinsic_nomem;
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_MUL].intr_name = "llvm.AMDGPU.mul";
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_POW].emit = build_tgsi_intrinsic_nomem;
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_POW].intr_name = "llvm.AMDGPU.pow";
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_RCP].emit = build_tgsi_intrinsic_nomem;
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_RCP].intr_name = "llvm.AMDGPU.rcp";
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SSG].emit = build_tgsi_intrinsic_nomem;
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SSG].intr_name = "llvm.AMDGPU.ssg";
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SGE].emit = emit_cmp;
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SEQ].emit = emit_cmp;
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SLE].emit = emit_cmp;
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SLT].emit = emit_cmp;
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SNE].emit = emit_cmp;
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SGT].emit = emit_cmp;
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SIN].emit = build_tgsi_intrinsic_nomem;
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_SIN].intr_name = "llvm.AMDGPU.sin";
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TEX].fetch_args = tex_fetch_args;
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TEX].intr_name = "llvm.AMDGPU.tex";
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXB].fetch_args = tex_fetch_args;
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXB].intr_name = "llvm.AMDGPU.txb";
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXD].fetch_args = txd_fetch_args;
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXD].intr_name = "llvm.AMDGPU.txd";
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXL].fetch_args = tex_fetch_args;
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXL].intr_name = "llvm.AMDGPU.txl";
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXP].fetch_args = txp_fetch_args;
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TXP].intr_name = "llvm.AMDGPU.tex";
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TRUNC].emit = build_tgsi_intrinsic_nomem;
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->op_actions[TGSI_OPCODE_TRUNC].intr_name = "llvm.AMDGPU.trunc";
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->rsq_action.emit = build_tgsi_intrinsic_nomem;
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	bld_base->rsq_action.intr_name = "llvm.AMDGPU.rsq";
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid radeon_llvm_finalize_module(struct radeon_llvm_context * ctx)
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	struct gallivm_state * gallivm = ctx->soa.bld_base.base.gallivm;
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* End the main function with Return*/
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMBuildRetVoid(gallivm->builder);
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Create the pass manager */
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	ctx->gallivm.passmgr = LLVMCreateFunctionPassManagerForModule(
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org							gallivm->module);
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* This pass should eliminate all the load and store instructions */
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Add some optimization passes */
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMAddScalarReplAggregatesPass(gallivm->passmgr);
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMAddCFGSimplificationPass(gallivm->passmgr);
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	/* Run the passs */
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMRunFunctionPassManager(gallivm->passmgr, ctx->main_fn);
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMDisposeBuilder(gallivm->builder);
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMDisposePassManager(gallivm->passmgr);
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid radeon_llvm_dispose(struct radeon_llvm_context * ctx)
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMDisposeModule(ctx->soa.bld_base.base.gallivm->module);
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	LLVMContextDispose(ctx->soa.bld_base.base.gallivm->context);
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1211