radeon_setup_tgsi_llvm.c revision 3a6a1cd75fc98895569a34d5d7dfdc9e90381691
1/*
2 * Copyright 2011 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors: Tom Stellard <thomas.stellard@amd.com>
24 *
25 */
26#include "radeon_llvm.h"
27
28#include "gallivm/lp_bld_const.h"
29#include "gallivm/lp_bld_gather.h"
30#include "gallivm/lp_bld_flow.h"
31#include "gallivm/lp_bld_init.h"
32#include "gallivm/lp_bld_intr.h"
33#include "gallivm/lp_bld_swizzle.h"
34#include "tgsi/tgsi_info.h"
35#include "tgsi/tgsi_parse.h"
36#include "util/u_math.h"
37#include "util/u_debug.h"
38
39#include <llvm-c/Transforms/Scalar.h>
40
41static struct radeon_llvm_loop * get_current_loop(struct radeon_llvm_context * ctx)
42{
43	return ctx->loop_depth > 0 ? ctx->loop + (ctx->loop_depth - 1) : NULL;
44}
45
46static struct radeon_llvm_branch * get_current_branch(
47	struct radeon_llvm_context * ctx)
48{
49	return ctx->branch_depth > 0 ?
50			ctx->branch + (ctx->branch_depth - 1) : NULL;
51}
52
53unsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan)
54{
55 return (index * 4) + chan;
56}
57
58static void radeon_llvm_fetch_args_2_reverse_soa(
59	struct lp_build_tgsi_context * bld_base,
60	struct lp_build_emit_data * emit_data)
61{
62	assert(emit_data->info->num_src == 2);
63	emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst,
64							1, emit_data->chan);
65	emit_data->args[1] = lp_build_emit_fetch(bld_base, emit_data->inst,
66							0, emit_data->chan);
67	emit_data->arg_count = 2;
68	emit_data->dst_type = LLVMTypeOf(emit_data->args[0]);
69}
70
71static LLVMValueRef emit_swizzle(
72	struct lp_build_tgsi_context * bld_base,
73        LLVMValueRef value,
74	unsigned swizzle_x,
75	unsigned swizzle_y,
76	unsigned swizzle_z,
77	unsigned swizzle_w)
78{
79	unsigned char swizzles[4];
80	swizzles[0] = swizzle_x;
81	swizzles[1] = swizzle_y;
82	swizzles[2] = swizzle_z;
83	swizzles[3] = swizzle_w;
84
85
86	return lp_build_swizzle_aos(&bld_base->base, value, swizzles);
87}
88
89static LLVMValueRef
90emit_array_index(
91	struct lp_build_tgsi_soa_context *bld,
92	const struct tgsi_full_src_register *reg,
93	unsigned swizzle)
94{
95	struct gallivm_state * gallivm = bld->bld_base.base.gallivm;
96
97	LLVMValueRef addr = LLVMBuildLoad(gallivm->builder,
98	bld->addr[reg->Indirect.Index][swizzle], "");
99	LLVMValueRef offset = lp_build_const_int32(gallivm, reg->Register.Index);
100	LLVMValueRef hw_index = LLVMBuildAdd(gallivm->builder, addr, offset, "");
101	LLVMValueRef soa_index = LLVMBuildMul(gallivm->builder, hw_index,
102	lp_build_const_int32(gallivm, 4), "");
103	LLVMValueRef array_index = LLVMBuildAdd(gallivm->builder, soa_index,
104	lp_build_const_int32(gallivm, swizzle), "");
105
106	return array_index;
107}
108
109static LLVMValueRef
110emit_fetch_immediate(
111	struct lp_build_tgsi_context *bld_base,
112	const struct tgsi_full_src_register *reg,
113	enum tgsi_opcode_type type,
114	unsigned swizzle)
115{
116	LLVMTypeRef ctype;
117	LLVMContextRef ctx = bld_base->base.gallivm->context;
118
119	switch (type) {
120	case TGSI_TYPE_UNSIGNED:
121	case TGSI_TYPE_SIGNED:
122		ctype = LLVMInt32TypeInContext(ctx);
123		break;
124	case TGSI_TYPE_UNTYPED:
125	case TGSI_TYPE_FLOAT:
126		ctype = LLVMFloatTypeInContext(ctx);
127		break;
128	default:
129		ctype = 0;
130		break;
131	}
132
133	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
134	return LLVMConstBitCast(bld->immediates[reg->Register.Index][swizzle], ctype);
135}
136
137static LLVMValueRef
138emit_fetch_input(
139	struct lp_build_tgsi_context *bld_base,
140	const struct tgsi_full_src_register *reg,
141	enum tgsi_opcode_type type,
142	unsigned swizzle)
143{
144	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
145	if (swizzle == ~0) {
146		LLVMValueRef values[TGSI_NUM_CHANNELS] = {};
147		unsigned chan;
148		for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
149			values[chan] = ctx->inputs[radeon_llvm_reg_index_soa(
150						reg->Register.Index, chan)];
151		}
152		return lp_build_gather_values(bld_base->base.gallivm, values,
153						TGSI_NUM_CHANNELS);
154	} else {
155		return bitcast(bld_base, type, ctx->inputs[radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)]);
156	}
157}
158
159static LLVMValueRef
160emit_fetch_temporary(
161	struct lp_build_tgsi_context *bld_base,
162	const struct tgsi_full_src_register *reg,
163	enum tgsi_opcode_type type,
164	unsigned swizzle)
165{
166	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
167	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
168	if (reg->Register.Indirect) {
169		LLVMValueRef array_index = emit_array_index(bld, reg, swizzle);
170		LLVMValueRef ptr = LLVMBuildGEP(builder, bld->temps_array, &array_index,
171						1, "");
172	return LLVMBuildLoad(builder, ptr, "");
173	} else {
174		LLVMValueRef temp_ptr;
175		temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle);
176		return bitcast(bld_base,type,LLVMBuildLoad(builder, temp_ptr, ""));
177	}
178}
179
180static LLVMValueRef
181emit_fetch_output(
182	struct lp_build_tgsi_context *bld_base,
183	const struct tgsi_full_src_register *reg,
184	enum tgsi_opcode_type type,
185	unsigned swizzle)
186{
187	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
188	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
189	 if (reg->Register.Indirect) {
190		LLVMValueRef array_index = emit_array_index(bld, reg, swizzle);
191		LLVMValueRef ptr = LLVMBuildGEP(builder, bld->outputs_array, &array_index,
192						1, "");
193		return LLVMBuildLoad(builder, ptr, "");
194	} else {
195		LLVMValueRef temp_ptr;
196		temp_ptr = lp_get_output_ptr(bld, reg->Register.Index, swizzle);
197		return LLVMBuildLoad(builder, temp_ptr, "");
198	 }
199}
200
201static void emit_declaration(
202	struct lp_build_tgsi_context * bld_base,
203	const struct tgsi_full_declaration *decl)
204{
205	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
206	switch(decl->Declaration.File) {
207	case TGSI_FILE_ADDRESS:
208	{
209		 unsigned idx;
210		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
211			unsigned chan;
212			for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
213				 ctx->soa.addr[idx][chan] = lp_build_alloca(
214					&ctx->gallivm,
215					ctx->soa.bld_base.uint_bld.elem_type, "");
216			}
217		}
218		break;
219	}
220
221	case TGSI_FILE_TEMPORARY:
222		lp_emit_declaration_soa(bld_base, decl);
223		break;
224
225	case TGSI_FILE_INPUT:
226	{
227		unsigned idx;
228		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
229			ctx->load_input(ctx, idx, decl);
230		}
231	}
232	break;
233
234	case TGSI_FILE_OUTPUT:
235	{
236		unsigned idx;
237		for (idx = decl->Range.First; idx <= decl->Range.Last; idx++) {
238			unsigned chan;
239			assert(idx < RADEON_LLVM_MAX_OUTPUTS);
240			for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
241				ctx->soa.outputs[idx][chan] = lp_build_alloca(&ctx->gallivm,
242					ctx->soa.bld_base.base.elem_type, "");
243			}
244		}
245
246		ctx->output_reg_count = MAX2(ctx->output_reg_count,
247							 decl->Range.Last + 1);
248		break;
249	}
250
251	default:
252		break;
253	}
254}
255
256static void
257emit_store(
258	struct lp_build_tgsi_context * bld_base,
259	const struct tgsi_full_instruction * inst,
260	const struct tgsi_opcode_info * info,
261	LLVMValueRef dst[4])
262{
263	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
264	struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
265	struct lp_build_context base = bld->bld_base.base;
266	const struct tgsi_full_dst_register *reg = &inst->Dst[0];
267	LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder;
268	LLVMValueRef temp_ptr;
269	unsigned chan, chan_index;
270	boolean is_vec_store = FALSE;
271	if (dst[0]) {
272		LLVMTypeKind k = LLVMGetTypeKind(LLVMTypeOf(dst[0]));
273		is_vec_store = (k == LLVMVectorTypeKind);
274	}
275
276	if (is_vec_store) {
277		LLVMValueRef values[4] = {};
278		TGSI_FOR_EACH_DST0_ENABLED_CHANNEL(inst, chan) {
279			LLVMValueRef index = lp_build_const_int32(gallivm, chan);
280			values[chan]  = LLVMBuildExtractElement(gallivm->builder,
281							dst[0], index, "");
282		}
283		bld_base->emit_store(bld_base, inst, info, values);
284		return;
285	}
286
287	TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
288		LLVMValueRef value = dst[chan_index];
289
290		if (inst->Instruction.Saturate != TGSI_SAT_NONE) {
291			struct lp_build_emit_data clamp_emit_data;
292
293			memset(&clamp_emit_data, 0, sizeof(clamp_emit_data));
294			clamp_emit_data.arg_count = 3;
295			clamp_emit_data.args[0] = value;
296			clamp_emit_data.args[2] = base.one;
297
298			switch(inst->Instruction.Saturate) {
299			case TGSI_SAT_ZERO_ONE:
300				clamp_emit_data.args[1] = base.zero;
301				break;
302			case TGSI_SAT_MINUS_PLUS_ONE:
303				clamp_emit_data.args[1] = LLVMConstReal(
304						base.elem_type, -1.0f);
305				break;
306			default:
307				assert(0);
308			}
309			value = lp_build_emit_llvm(bld_base, TGSI_OPCODE_CLAMP,
310						&clamp_emit_data);
311		}
312
313		switch(reg->Register.File) {
314		case TGSI_FILE_OUTPUT:
315			temp_ptr = bld->outputs[reg->Register.Index][chan_index];
316			break;
317
318		case TGSI_FILE_TEMPORARY:
319			temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, chan_index);
320			break;
321
322		default:
323			return;
324		}
325
326		value = bitcast(bld_base, TGSI_TYPE_FLOAT, value);
327
328		LLVMBuildStore(builder, value, temp_ptr);
329	}
330}
331
332static void bgnloop_emit(
333	const struct lp_build_tgsi_action * action,
334	struct lp_build_tgsi_context * bld_base,
335	struct lp_build_emit_data * emit_data)
336{
337	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
338	struct gallivm_state * gallivm = bld_base->base.gallivm;
339	LLVMBasicBlockRef loop_block;
340	LLVMBasicBlockRef endloop_block;
341	endloop_block = LLVMAppendBasicBlockInContext(gallivm->context,
342						ctx->main_fn, "ENDLOOP");
343	loop_block = LLVMInsertBasicBlockInContext(gallivm->context,
344						endloop_block, "LOOP");
345	LLVMBuildBr(gallivm->builder, loop_block);
346	LLVMPositionBuilderAtEnd(gallivm->builder, loop_block);
347	ctx->loop_depth++;
348	ctx->loop[ctx->loop_depth - 1].loop_block = loop_block;
349	ctx->loop[ctx->loop_depth - 1].endloop_block = endloop_block;
350}
351
352static void brk_emit(
353	const struct lp_build_tgsi_action * action,
354	struct lp_build_tgsi_context * bld_base,
355	struct lp_build_emit_data * emit_data)
356{
357	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
358	struct gallivm_state * gallivm = bld_base->base.gallivm;
359	struct radeon_llvm_loop * current_loop = get_current_loop(ctx);
360
361	LLVMBuildBr(gallivm->builder, current_loop->endloop_block);
362}
363
364static void cont_emit(
365	const struct lp_build_tgsi_action * action,
366	struct lp_build_tgsi_context * bld_base,
367	struct lp_build_emit_data * emit_data)
368{
369	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
370	struct gallivm_state * gallivm = bld_base->base.gallivm;
371	struct radeon_llvm_loop * current_loop = get_current_loop(ctx);
372
373	LLVMBuildBr(gallivm->builder, current_loop->loop_block);
374}
375
376static void else_emit(
377	const struct lp_build_tgsi_action * action,
378	struct lp_build_tgsi_context * bld_base,
379	struct lp_build_emit_data * emit_data)
380{
381	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
382	struct gallivm_state * gallivm = bld_base->base.gallivm;
383	struct radeon_llvm_branch * current_branch = get_current_branch(ctx);
384	LLVMBasicBlockRef current_block = LLVMGetInsertBlock(gallivm->builder);
385
386	/* We need to add a terminator to the current block if the previous
387	 * instruction was an ENDIF.Example:
388	 * IF
389	 *   [code]
390	 *   IF
391	 *     [code]
392	 *   ELSE
393	 *    [code]
394	 *   ENDIF <--
395	 * ELSE<--
396	 *   [code]
397	 * ENDIF
398	 */
399
400	if (current_block != current_branch->if_block) {
401		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
402	}
403	if (!LLVMGetBasicBlockTerminator(current_branch->if_block)) {
404		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
405	}
406	current_branch->has_else = 1;
407	LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->else_block);
408}
409
410static void endif_emit(
411	const struct lp_build_tgsi_action * action,
412	struct lp_build_tgsi_context * bld_base,
413	struct lp_build_emit_data * emit_data)
414{
415	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
416	struct gallivm_state * gallivm = bld_base->base.gallivm;
417	struct radeon_llvm_branch * current_branch = get_current_branch(ctx);
418	LLVMBasicBlockRef current_block = LLVMGetInsertBlock(gallivm->builder);
419
420	/* If we have consecutive ENDIF instructions, then the first ENDIF
421	 * will not have a terminator, so we need to add one. */
422	if (current_block != current_branch->if_block
423			&& current_block != current_branch->else_block
424			&& !LLVMGetBasicBlockTerminator(current_block)) {
425
426		 LLVMBuildBr(gallivm->builder, current_branch->endif_block);
427	}
428	if (!LLVMGetBasicBlockTerminator(current_branch->else_block)) {
429		LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->else_block);
430		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
431	}
432
433	if (!LLVMGetBasicBlockTerminator(current_branch->if_block)) {
434		LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->if_block);
435		LLVMBuildBr(gallivm->builder, current_branch->endif_block);
436	}
437
438	LLVMPositionBuilderAtEnd(gallivm->builder, current_branch->endif_block);
439	ctx->branch_depth--;
440}
441
442static void endloop_emit(
443	const struct lp_build_tgsi_action * action,
444	struct lp_build_tgsi_context * bld_base,
445	struct lp_build_emit_data * emit_data)
446{
447	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
448	struct gallivm_state * gallivm = bld_base->base.gallivm;
449	struct radeon_llvm_loop * current_loop = get_current_loop(ctx);
450
451	if (!LLVMGetBasicBlockTerminator(LLVMGetInsertBlock(gallivm->builder))) {
452		 LLVMBuildBr(gallivm->builder, current_loop->loop_block);
453	}
454
455	LLVMPositionBuilderAtEnd(gallivm->builder, current_loop->endloop_block);
456	ctx->loop_depth--;
457}
458
459static void if_emit(
460	const struct lp_build_tgsi_action * action,
461	struct lp_build_tgsi_context * bld_base,
462	struct lp_build_emit_data * emit_data)
463{
464	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
465	struct gallivm_state * gallivm = bld_base->base.gallivm;
466	LLVMValueRef cond;
467	LLVMBasicBlockRef if_block, else_block, endif_block;
468
469	cond = LLVMBuildICmp(gallivm->builder, LLVMIntNE,
470	        bitcast(bld_base, TGSI_TYPE_UNSIGNED, emit_data->args[0]),
471			bld_base->int_bld.zero, "");
472
473	endif_block = LLVMAppendBasicBlockInContext(gallivm->context,
474						ctx->main_fn, "ENDIF");
475	if_block = LLVMInsertBasicBlockInContext(gallivm->context,
476						endif_block, "IF");
477	else_block = LLVMInsertBasicBlockInContext(gallivm->context,
478						endif_block, "ELSE");
479	LLVMBuildCondBr(gallivm->builder, cond, if_block, else_block);
480	LLVMPositionBuilderAtEnd(gallivm->builder, if_block);
481
482	ctx->branch_depth++;
483	ctx->branch[ctx->branch_depth - 1].endif_block = endif_block;
484	ctx->branch[ctx->branch_depth - 1].if_block = if_block;
485	ctx->branch[ctx->branch_depth - 1].else_block = else_block;
486	ctx->branch[ctx->branch_depth - 1].has_else = 0;
487}
488
489static void kil_emit(
490	const struct lp_build_tgsi_action * action,
491	struct lp_build_tgsi_context * bld_base,
492	struct lp_build_emit_data * emit_data)
493{
494	unsigned i;
495	for (i = 0; i < emit_data->arg_count; i++) {
496		emit_data->output[i] = lp_build_intrinsic_unary(
497			bld_base->base.gallivm->builder,
498			action->intr_name,
499			emit_data->dst_type, emit_data->args[i]);
500	}
501}
502
503static void tex_fetch_args(
504	struct lp_build_tgsi_context * bld_base,
505	struct lp_build_emit_data * emit_data)
506{
507	/* XXX: lp_build_swizzle_aos() was failing with wrong arg types,
508	 * when we used CHAN_ALL.  We should be able to get this to work,
509	 * but for now we will swizzle it ourselves
510	emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst,
511						 0, CHAN_ALL);
512
513	*/
514
515	LLVMValueRef coords[4];
516	unsigned chan;
517	for (chan = 0; chan < 4; chan++) {
518		coords[chan] = lp_build_emit_fetch(bld_base, emit_data->inst, 0, chan);
519	}
520
521	emit_data->arg_count = 1;
522	emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
523						coords, 4);
524	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
525}
526
527static void emit_immediate(struct lp_build_tgsi_context * bld_base,
528		const struct tgsi_full_immediate *imm)
529{
530	unsigned i;
531	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
532
533	for (i = 0; i < 4; ++i) {
534		ctx->soa.immediates[ctx->soa.num_immediates][i] =
535				LLVMConstInt(bld_base->uint_bld.elem_type, imm->u[i].Uint, false   );
536	}
537
538	ctx->soa.num_immediates++;
539}
540
541void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
542{
543	struct lp_type type;
544	LLVMTypeRef main_fn_type;
545	LLVMBasicBlockRef main_fn_body;
546
547	/* Initialize the gallivm object:
548	 * We are only using the module, context, and builder fields of this struct.
549	 * This should be enough for us to be able to pass our gallivm struct to the
550	 * helper functions in the gallivm module.
551	 */
552	memset(&ctx->gallivm, 0, sizeof (ctx->gallivm));
553	memset(&ctx->soa, 0, sizeof(ctx->soa));
554	ctx->gallivm.context = LLVMContextCreate();
555	ctx->gallivm.module = LLVMModuleCreateWithNameInContext("tgsi",
556						ctx->gallivm.context);
557	ctx->gallivm.builder = LLVMCreateBuilderInContext(ctx->gallivm.context);
558
559	/* Setup the module */
560	main_fn_type = LLVMFunctionType(LLVMVoidTypeInContext(ctx->gallivm.context),
561					 NULL, 0, 0);
562	ctx->main_fn = LLVMAddFunction(ctx->gallivm.module, "main", main_fn_type);
563	main_fn_body = LLVMAppendBasicBlockInContext(ctx->gallivm.context,
564			ctx->main_fn, "main_body");
565	 LLVMPositionBuilderAtEnd(ctx->gallivm.builder, main_fn_body);
566
567	ctx->store_output_intr = "llvm.AMDGPU.store.output.";
568	ctx->swizzle_intr = "llvm.AMDGPU.swizzle";
569	struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
570
571	/* XXX: We need to revisit this.I think the correct way to do this is
572	 * to use length = 4 here and use the elem_bld for everything. */
573	type.floating = TRUE;
574	type.sign = TRUE;
575	type.width = 32;
576	type.length = 1;
577
578	lp_build_context_init(&bld_base->base, &ctx->gallivm, type);
579	lp_build_context_init(&ctx->soa.bld_base.uint_bld, &ctx->gallivm, lp_uint_type(type));
580	lp_build_context_init(&ctx->soa.bld_base.int_bld, &ctx->gallivm, lp_int_type(type));
581
582	bld_base->soa = 1;
583	bld_base->emit_store = emit_store;
584	bld_base->emit_swizzle = emit_swizzle;
585	bld_base->emit_declaration = emit_declaration;
586	bld_base->emit_immediate = emit_immediate;
587
588	bld_base->emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate;
589	bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input;
590	bld_base->emit_fetch_funcs[TGSI_FILE_TEMPORARY] = emit_fetch_temporary;
591	bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = emit_fetch_output;
592
593	/* Allocate outputs */
594	ctx->soa.outputs = ctx->outputs;
595
596	/* XXX: Is there a better way to initialize all this ? */
597
598	lp_set_default_actions(bld_base);
599
600	bld_base->op_actions[TGSI_OPCODE_ABS].emit = lp_build_tgsi_intrinsic;
601	bld_base->op_actions[TGSI_OPCODE_ABS].intr_name = "llvm.AMDIL.fabs.";
602	bld_base->op_actions[TGSI_OPCODE_ARL].emit = lp_build_tgsi_intrinsic;
603	bld_base->op_actions[TGSI_OPCODE_ARL].intr_name = "llvm.AMDGPU.arl";
604	bld_base->op_actions[TGSI_OPCODE_BGNLOOP].emit = bgnloop_emit;
605	bld_base->op_actions[TGSI_OPCODE_BRK].emit = brk_emit;
606	bld_base->op_actions[TGSI_OPCODE_CONT].emit = cont_emit;
607	bld_base->op_actions[TGSI_OPCODE_CLAMP].emit = lp_build_tgsi_intrinsic;
608	bld_base->op_actions[TGSI_OPCODE_CLAMP].intr_name = "llvm.AMDIL.clamp.";
609	bld_base->op_actions[TGSI_OPCODE_CMP].emit = lp_build_tgsi_intrinsic;
610	bld_base->op_actions[TGSI_OPCODE_CMP].intr_name = "llvm.AMDGPU.cndlt";
611	bld_base->op_actions[TGSI_OPCODE_COS].emit = lp_build_tgsi_intrinsic;
612	bld_base->op_actions[TGSI_OPCODE_COS].intr_name = "llvm.AMDGPU.cos";
613	bld_base->op_actions[TGSI_OPCODE_DDX].emit = lp_build_tgsi_intrinsic;
614	bld_base->op_actions[TGSI_OPCODE_DDX].intr_name = "llvm.AMDGPU.ddx";
615	bld_base->op_actions[TGSI_OPCODE_DDY].emit = lp_build_tgsi_intrinsic;
616	bld_base->op_actions[TGSI_OPCODE_DDY].intr_name = "llvm.AMDGPU.ddy";
617	bld_base->op_actions[TGSI_OPCODE_DIV].emit = lp_build_tgsi_intrinsic;
618	bld_base->op_actions[TGSI_OPCODE_DIV].intr_name = "llvm.AMDGPU.div";
619	bld_base->op_actions[TGSI_OPCODE_ELSE].emit = else_emit;
620	bld_base->op_actions[TGSI_OPCODE_ENDIF].emit = endif_emit;
621	bld_base->op_actions[TGSI_OPCODE_ENDLOOP].emit = endloop_emit;
622	bld_base->op_actions[TGSI_OPCODE_EX2].emit = lp_build_tgsi_intrinsic;
623	bld_base->op_actions[TGSI_OPCODE_EX2].intr_name = "llvm.AMDIL.exp.";
624	bld_base->op_actions[TGSI_OPCODE_FLR].emit = lp_build_tgsi_intrinsic;
625	bld_base->op_actions[TGSI_OPCODE_FLR].intr_name = "llvm.AMDGPU.floor";
626	bld_base->op_actions[TGSI_OPCODE_FRC].emit = lp_build_tgsi_intrinsic;
627	bld_base->op_actions[TGSI_OPCODE_FRC].intr_name = "llvm.AMDIL.fraction.";
628	bld_base->op_actions[TGSI_OPCODE_IF].emit = if_emit;
629	bld_base->op_actions[TGSI_OPCODE_KIL].emit = kil_emit;
630	bld_base->op_actions[TGSI_OPCODE_KIL].intr_name = "llvm.AMDGPU.kill";
631	bld_base->op_actions[TGSI_OPCODE_KILP].emit = lp_build_tgsi_intrinsic;
632	bld_base->op_actions[TGSI_OPCODE_KILP].intr_name = "llvm.AMDGPU.kilp";
633	bld_base->op_actions[TGSI_OPCODE_LG2].emit = lp_build_tgsi_intrinsic;
634	bld_base->op_actions[TGSI_OPCODE_LG2].intr_name = "llvm.AMDIL.log.";
635	bld_base->op_actions[TGSI_OPCODE_LRP].emit = lp_build_tgsi_intrinsic;
636	bld_base->op_actions[TGSI_OPCODE_LRP].intr_name = "llvm.AMDGPU.lrp";
637	bld_base->op_actions[TGSI_OPCODE_MIN].emit = lp_build_tgsi_intrinsic;
638	bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.AMDIL.min.";
639	bld_base->op_actions[TGSI_OPCODE_MAD].emit = lp_build_tgsi_intrinsic;
640	bld_base->op_actions[TGSI_OPCODE_MAD].intr_name = "llvm.AMDIL.mad.";
641	bld_base->op_actions[TGSI_OPCODE_MAX].emit = lp_build_tgsi_intrinsic;
642	bld_base->op_actions[TGSI_OPCODE_MAX].intr_name = "llvm.AMDIL.max.";
643	bld_base->op_actions[TGSI_OPCODE_MUL].emit = lp_build_tgsi_intrinsic;
644	bld_base->op_actions[TGSI_OPCODE_MUL].intr_name = "llvm.AMDGPU.mul";
645	bld_base->op_actions[TGSI_OPCODE_POW].emit = lp_build_tgsi_intrinsic;
646	bld_base->op_actions[TGSI_OPCODE_POW].intr_name = "llvm.AMDGPU.pow";
647	bld_base->op_actions[TGSI_OPCODE_RCP].emit = lp_build_tgsi_intrinsic;
648	bld_base->op_actions[TGSI_OPCODE_RCP].intr_name = "llvm.AMDGPU.rcp";
649	bld_base->op_actions[TGSI_OPCODE_SSG].emit = lp_build_tgsi_intrinsic;
650	bld_base->op_actions[TGSI_OPCODE_SSG].intr_name = "llvm.AMDGPU.ssg";
651	bld_base->op_actions[TGSI_OPCODE_SGE].emit = lp_build_tgsi_intrinsic;
652	bld_base->op_actions[TGSI_OPCODE_SGE].intr_name = "llvm.AMDGPU.sge.";
653	bld_base->op_actions[TGSI_OPCODE_SEQ].emit = lp_build_tgsi_intrinsic;
654	bld_base->op_actions[TGSI_OPCODE_SEQ].intr_name = "llvm.AMDGPU.seq";
655	bld_base->op_actions[TGSI_OPCODE_SLE].fetch_args = radeon_llvm_fetch_args_2_reverse_soa;
656	bld_base->op_actions[TGSI_OPCODE_SLE].emit = lp_build_tgsi_intrinsic;
657	bld_base->op_actions[TGSI_OPCODE_SLE].intr_name = "llvm.AMDGPU.sge";
658	bld_base->op_actions[TGSI_OPCODE_SLT].fetch_args = radeon_llvm_fetch_args_2_reverse_soa;
659	bld_base->op_actions[TGSI_OPCODE_SLT].emit = lp_build_tgsi_intrinsic;
660	bld_base->op_actions[TGSI_OPCODE_SLT].intr_name = "llvm.AMDGPU.sgt";
661	bld_base->op_actions[TGSI_OPCODE_SNE].emit = lp_build_tgsi_intrinsic;
662	bld_base->op_actions[TGSI_OPCODE_SNE].intr_name = "llvm.AMDGPU.sne";
663	bld_base->op_actions[TGSI_OPCODE_SGT].emit = lp_build_tgsi_intrinsic;
664	bld_base->op_actions[TGSI_OPCODE_SGT].intr_name = "llvm.AMDGPU.sgt";
665	bld_base->op_actions[TGSI_OPCODE_SIN].emit = lp_build_tgsi_intrinsic;
666	bld_base->op_actions[TGSI_OPCODE_SIN].intr_name = "llvm.AMDGPU.sin";
667	bld_base->op_actions[TGSI_OPCODE_TEX].fetch_args = tex_fetch_args;
668	bld_base->op_actions[TGSI_OPCODE_TEX].intr_name = "llvm.AMDGPU.tex";
669	bld_base->op_actions[TGSI_OPCODE_TXB].fetch_args = tex_fetch_args;
670	bld_base->op_actions[TGSI_OPCODE_TXB].intr_name = "llvm.AMDGPU.txb";
671	bld_base->op_actions[TGSI_OPCODE_TXD].fetch_args = tex_fetch_args;
672	bld_base->op_actions[TGSI_OPCODE_TXD].intr_name = "llvm.AMDGPU.txd";
673	bld_base->op_actions[TGSI_OPCODE_TXL].fetch_args = tex_fetch_args;
674	bld_base->op_actions[TGSI_OPCODE_TXL].intr_name = "llvm.AMDGPU.txl";
675	bld_base->op_actions[TGSI_OPCODE_TXP].intr_name = "llvm.AMDGPU.tex";
676	bld_base->op_actions[TGSI_OPCODE_TRUNC].emit = lp_build_tgsi_intrinsic;
677	bld_base->op_actions[TGSI_OPCODE_TRUNC].intr_name = "llvm.AMDGPU.trunc";
678
679	bld_base->rsq_action.emit = lp_build_tgsi_intrinsic;
680	bld_base->rsq_action.intr_name = "llvm.AMDGPU.rsq";
681}
682
683void radeon_llvm_finalize_module(struct radeon_llvm_context * ctx)
684{
685	struct gallivm_state * gallivm = ctx->soa.bld_base.base.gallivm;
686	/* End the main function with Return*/
687	LLVMBuildRetVoid(gallivm->builder);
688
689	/* Create the pass manager */
690	ctx->gallivm.passmgr = LLVMCreateFunctionPassManagerForModule(
691							gallivm->module);
692
693	/* This pass should eliminate all the load and store instructions */
694	LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
695
696	/* Add some optimization passes */
697	LLVMAddScalarReplAggregatesPass(gallivm->passmgr);
698	LLVMAddCFGSimplificationPass(gallivm->passmgr);
699
700	/* Run the passs */
701	LLVMRunFunctionPassManager(gallivm->passmgr, ctx->main_fn);
702
703	LLVMDisposeBuilder(gallivm->builder);
704	LLVMDisposePassManager(gallivm->passmgr);
705
706}
707
708void radeon_llvm_dispose(struct radeon_llvm_context * ctx)
709{
710	LLVMDisposeModule(ctx->soa.bld_base.base.gallivm->module);
711	LLVMContextDispose(ctx->soa.bld_base.base.gallivm->context);
712}
713