radeon/llvm: use bitcasts for integers
[mesa.git] / src / gallium / drivers / radeon / radeon_setup_tgsi_llvm.c
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
41 static 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
46 static 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
53 unsigned radeon_llvm_reg_index_soa(unsigned index, unsigned chan)
54 {
55 return (index * 4) + chan;
56 }
57
58 static 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
71 static 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
89 static LLVMValueRef
90 emit_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
109 static LLVMValueRef
110 emit_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
137 static LLVMValueRef
138 emit_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
159 static LLVMValueRef
160 emit_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
180 static LLVMValueRef
181 emit_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
201 static 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
256 static void
257 emit_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
332 static 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
352 static 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
364 static 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
376 static 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
410 static 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
442 static 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
459 static 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 cond = LLVMBuildFCmp(gallivm->builder, LLVMRealOEQ, emit_data->args[0],
469 bld_base->base.one, "");
470
471 endif_block = LLVMAppendBasicBlockInContext(gallivm->context,
472 ctx->main_fn, "ENDIF");
473 if_block = LLVMInsertBasicBlockInContext(gallivm->context,
474 endif_block, "IF");
475 else_block = LLVMInsertBasicBlockInContext(gallivm->context,
476 endif_block, "ELSE");
477 LLVMBuildCondBr(gallivm->builder, cond, if_block, else_block);
478 LLVMPositionBuilderAtEnd(gallivm->builder, if_block);
479
480 ctx->branch_depth++;
481 ctx->branch[ctx->branch_depth - 1].endif_block = endif_block;
482 ctx->branch[ctx->branch_depth - 1].if_block = if_block;
483 ctx->branch[ctx->branch_depth - 1].else_block = else_block;
484 ctx->branch[ctx->branch_depth - 1].has_else = 0;
485 }
486
487 static void kil_emit(
488 const struct lp_build_tgsi_action * action,
489 struct lp_build_tgsi_context * bld_base,
490 struct lp_build_emit_data * emit_data)
491 {
492 unsigned i;
493 for (i = 0; i < emit_data->arg_count; i++) {
494 emit_data->output[i] = lp_build_intrinsic_unary(
495 bld_base->base.gallivm->builder,
496 action->intr_name,
497 emit_data->dst_type, emit_data->args[i]);
498 }
499 }
500
501 static void tex_fetch_args(
502 struct lp_build_tgsi_context * bld_base,
503 struct lp_build_emit_data * emit_data)
504 {
505 /* XXX: lp_build_swizzle_aos() was failing with wrong arg types,
506 * when we used CHAN_ALL. We should be able to get this to work,
507 * but for now we will swizzle it ourselves
508 emit_data->args[0] = lp_build_emit_fetch(bld_base, emit_data->inst,
509 0, CHAN_ALL);
510
511 */
512
513 LLVMValueRef coords[4];
514 unsigned chan;
515 for (chan = 0; chan < 4; chan++) {
516 coords[chan] = lp_build_emit_fetch(bld_base, emit_data->inst, 0, chan);
517 }
518
519 emit_data->arg_count = 1;
520 emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
521 coords, 4);
522 emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
523 }
524
525 static void emit_immediate(struct lp_build_tgsi_context * bld_base,
526 const struct tgsi_full_immediate *imm)
527 {
528 unsigned i;
529 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
530
531 for (i = 0; i < 4; ++i) {
532 ctx->soa.immediates[ctx->soa.num_immediates][i] =
533 LLVMConstInt(bld_base->uint_bld.elem_type, imm->u[i].Uint, false );
534 }
535
536 ctx->soa.num_immediates++;
537 }
538
539 void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
540 {
541 struct lp_type type;
542 LLVMTypeRef main_fn_type;
543 LLVMBasicBlockRef main_fn_body;
544
545 /* Initialize the gallivm object:
546 * We are only using the module, context, and builder fields of this struct.
547 * This should be enough for us to be able to pass our gallivm struct to the
548 * helper functions in the gallivm module.
549 */
550 memset(&ctx->gallivm, 0, sizeof (ctx->gallivm));
551 memset(&ctx->soa, 0, sizeof(ctx->soa));
552 ctx->gallivm.context = LLVMContextCreate();
553 ctx->gallivm.module = LLVMModuleCreateWithNameInContext("tgsi",
554 ctx->gallivm.context);
555 ctx->gallivm.builder = LLVMCreateBuilderInContext(ctx->gallivm.context);
556
557 /* Setup the module */
558 main_fn_type = LLVMFunctionType(LLVMVoidTypeInContext(ctx->gallivm.context),
559 NULL, 0, 0);
560 ctx->main_fn = LLVMAddFunction(ctx->gallivm.module, "main", main_fn_type);
561 main_fn_body = LLVMAppendBasicBlockInContext(ctx->gallivm.context,
562 ctx->main_fn, "main_body");
563 LLVMPositionBuilderAtEnd(ctx->gallivm.builder, main_fn_body);
564
565 ctx->store_output_intr = "llvm.AMDGPU.store.output.";
566 ctx->swizzle_intr = "llvm.AMDGPU.swizzle";
567 struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
568
569 /* XXX: We need to revisit this.I think the correct way to do this is
570 * to use length = 4 here and use the elem_bld for everything. */
571 type.floating = TRUE;
572 type.sign = TRUE;
573 type.width = 32;
574 type.length = 1;
575
576 lp_build_context_init(&bld_base->base, &ctx->gallivm, type);
577 lp_build_context_init(&ctx->soa.bld_base.uint_bld, &ctx->gallivm, lp_uint_type(type));
578 lp_build_context_init(&ctx->soa.bld_base.int_bld, &ctx->gallivm, lp_int_type(type));
579
580 bld_base->soa = 1;
581 bld_base->emit_store = emit_store;
582 bld_base->emit_swizzle = emit_swizzle;
583 bld_base->emit_declaration = emit_declaration;
584 bld_base->emit_immediate = emit_immediate;
585
586 bld_base->emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate;
587 bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input;
588 bld_base->emit_fetch_funcs[TGSI_FILE_TEMPORARY] = emit_fetch_temporary;
589 bld_base->emit_fetch_funcs[TGSI_FILE_OUTPUT] = emit_fetch_output;
590
591 /* Allocate outputs */
592 ctx->soa.outputs = ctx->outputs;
593
594 /* XXX: Is there a better way to initialize all this ? */
595
596 lp_set_default_actions(bld_base);
597
598 bld_base->op_actions[TGSI_OPCODE_ABS].emit = lp_build_tgsi_intrinsic;
599 bld_base->op_actions[TGSI_OPCODE_ABS].intr_name = "llvm.AMDIL.fabs.";
600 bld_base->op_actions[TGSI_OPCODE_ARL].emit = lp_build_tgsi_intrinsic;
601 bld_base->op_actions[TGSI_OPCODE_ARL].intr_name = "llvm.AMDGPU.arl";
602 bld_base->op_actions[TGSI_OPCODE_BGNLOOP].emit = bgnloop_emit;
603 bld_base->op_actions[TGSI_OPCODE_BRK].emit = brk_emit;
604 bld_base->op_actions[TGSI_OPCODE_CONT].emit = cont_emit;
605 bld_base->op_actions[TGSI_OPCODE_CLAMP].emit = lp_build_tgsi_intrinsic;
606 bld_base->op_actions[TGSI_OPCODE_CLAMP].intr_name = "llvm.AMDIL.clamp.";
607 bld_base->op_actions[TGSI_OPCODE_CMP].emit = lp_build_tgsi_intrinsic;
608 bld_base->op_actions[TGSI_OPCODE_CMP].intr_name = "llvm.AMDGPU.cndlt";
609 bld_base->op_actions[TGSI_OPCODE_COS].emit = lp_build_tgsi_intrinsic;
610 bld_base->op_actions[TGSI_OPCODE_COS].intr_name = "llvm.AMDGPU.cos";
611 bld_base->op_actions[TGSI_OPCODE_DDX].emit = lp_build_tgsi_intrinsic;
612 bld_base->op_actions[TGSI_OPCODE_DDX].intr_name = "llvm.AMDGPU.ddx";
613 bld_base->op_actions[TGSI_OPCODE_DDY].emit = lp_build_tgsi_intrinsic;
614 bld_base->op_actions[TGSI_OPCODE_DDY].intr_name = "llvm.AMDGPU.ddy";
615 bld_base->op_actions[TGSI_OPCODE_DIV].emit = lp_build_tgsi_intrinsic;
616 bld_base->op_actions[TGSI_OPCODE_DIV].intr_name = "llvm.AMDGPU.div";
617 bld_base->op_actions[TGSI_OPCODE_ELSE].emit = else_emit;
618 bld_base->op_actions[TGSI_OPCODE_ENDIF].emit = endif_emit;
619 bld_base->op_actions[TGSI_OPCODE_ENDLOOP].emit = endloop_emit;
620 bld_base->op_actions[TGSI_OPCODE_EX2].emit = lp_build_tgsi_intrinsic;
621 bld_base->op_actions[TGSI_OPCODE_EX2].intr_name = "llvm.AMDIL.exp.";
622 bld_base->op_actions[TGSI_OPCODE_FLR].emit = lp_build_tgsi_intrinsic;
623 bld_base->op_actions[TGSI_OPCODE_FLR].intr_name = "llvm.AMDGPU.floor";
624 bld_base->op_actions[TGSI_OPCODE_FRC].emit = lp_build_tgsi_intrinsic;
625 bld_base->op_actions[TGSI_OPCODE_FRC].intr_name = "llvm.AMDIL.fraction.";
626 bld_base->op_actions[TGSI_OPCODE_IF].emit = if_emit;
627 bld_base->op_actions[TGSI_OPCODE_KIL].emit = kil_emit;
628 bld_base->op_actions[TGSI_OPCODE_KIL].intr_name = "llvm.AMDGPU.kill";
629 bld_base->op_actions[TGSI_OPCODE_KILP].emit = lp_build_tgsi_intrinsic;
630 bld_base->op_actions[TGSI_OPCODE_KILP].intr_name = "llvm.AMDGPU.kilp";
631 bld_base->op_actions[TGSI_OPCODE_LG2].emit = lp_build_tgsi_intrinsic;
632 bld_base->op_actions[TGSI_OPCODE_LG2].intr_name = "llvm.AMDIL.log.";
633 bld_base->op_actions[TGSI_OPCODE_LRP].emit = lp_build_tgsi_intrinsic;
634 bld_base->op_actions[TGSI_OPCODE_LRP].intr_name = "llvm.AMDGPU.lrp";
635 bld_base->op_actions[TGSI_OPCODE_MIN].emit = lp_build_tgsi_intrinsic;
636 bld_base->op_actions[TGSI_OPCODE_MIN].intr_name = "llvm.AMDIL.min.";
637 bld_base->op_actions[TGSI_OPCODE_MAD].emit = lp_build_tgsi_intrinsic;
638 bld_base->op_actions[TGSI_OPCODE_MAD].intr_name = "llvm.AMDIL.mad.";
639 bld_base->op_actions[TGSI_OPCODE_MAX].emit = lp_build_tgsi_intrinsic;
640 bld_base->op_actions[TGSI_OPCODE_MAX].intr_name = "llvm.AMDIL.max.";
641 bld_base->op_actions[TGSI_OPCODE_MUL].emit = lp_build_tgsi_intrinsic;
642 bld_base->op_actions[TGSI_OPCODE_MUL].intr_name = "llvm.AMDGPU.mul";
643 bld_base->op_actions[TGSI_OPCODE_POW].emit = lp_build_tgsi_intrinsic;
644 bld_base->op_actions[TGSI_OPCODE_POW].intr_name = "llvm.AMDGPU.pow";
645 bld_base->op_actions[TGSI_OPCODE_RCP].emit = lp_build_tgsi_intrinsic;
646 bld_base->op_actions[TGSI_OPCODE_RCP].intr_name = "llvm.AMDGPU.rcp";
647 bld_base->op_actions[TGSI_OPCODE_SSG].emit = lp_build_tgsi_intrinsic;
648 bld_base->op_actions[TGSI_OPCODE_SSG].intr_name = "llvm.AMDGPU.ssg";
649 bld_base->op_actions[TGSI_OPCODE_SGE].emit = lp_build_tgsi_intrinsic;
650 bld_base->op_actions[TGSI_OPCODE_SGE].intr_name = "llvm.AMDGPU.sge.";
651 bld_base->op_actions[TGSI_OPCODE_SEQ].emit = lp_build_tgsi_intrinsic;
652 bld_base->op_actions[TGSI_OPCODE_SEQ].intr_name = "llvm.AMDGPU.seq";
653 bld_base->op_actions[TGSI_OPCODE_SLE].fetch_args = radeon_llvm_fetch_args_2_reverse_soa;
654 bld_base->op_actions[TGSI_OPCODE_SLE].emit = lp_build_tgsi_intrinsic;
655 bld_base->op_actions[TGSI_OPCODE_SLE].intr_name = "llvm.AMDGPU.sge";
656 bld_base->op_actions[TGSI_OPCODE_SLT].fetch_args = radeon_llvm_fetch_args_2_reverse_soa;
657 bld_base->op_actions[TGSI_OPCODE_SLT].emit = lp_build_tgsi_intrinsic;
658 bld_base->op_actions[TGSI_OPCODE_SLT].intr_name = "llvm.AMDGPU.sgt";
659 bld_base->op_actions[TGSI_OPCODE_SNE].emit = lp_build_tgsi_intrinsic;
660 bld_base->op_actions[TGSI_OPCODE_SNE].intr_name = "llvm.AMDGPU.sne";
661 bld_base->op_actions[TGSI_OPCODE_SGT].emit = lp_build_tgsi_intrinsic;
662 bld_base->op_actions[TGSI_OPCODE_SGT].intr_name = "llvm.AMDGPU.sgt";
663 bld_base->op_actions[TGSI_OPCODE_SIN].emit = lp_build_tgsi_intrinsic;
664 bld_base->op_actions[TGSI_OPCODE_SIN].intr_name = "llvm.AMDGPU.sin";
665 bld_base->op_actions[TGSI_OPCODE_TEX].fetch_args = tex_fetch_args;
666 bld_base->op_actions[TGSI_OPCODE_TEX].intr_name = "llvm.AMDGPU.tex";
667 bld_base->op_actions[TGSI_OPCODE_TXB].fetch_args = tex_fetch_args;
668 bld_base->op_actions[TGSI_OPCODE_TXB].intr_name = "llvm.AMDGPU.txb";
669 bld_base->op_actions[TGSI_OPCODE_TXD].fetch_args = tex_fetch_args;
670 bld_base->op_actions[TGSI_OPCODE_TXD].intr_name = "llvm.AMDGPU.txd";
671 bld_base->op_actions[TGSI_OPCODE_TXL].fetch_args = tex_fetch_args;
672 bld_base->op_actions[TGSI_OPCODE_TXL].intr_name = "llvm.AMDGPU.txl";
673 bld_base->op_actions[TGSI_OPCODE_TXP].intr_name = "llvm.AMDGPU.tex";
674 bld_base->op_actions[TGSI_OPCODE_TRUNC].emit = lp_build_tgsi_intrinsic;
675 bld_base->op_actions[TGSI_OPCODE_TRUNC].intr_name = "llvm.AMDGPU.trunc";
676
677 bld_base->rsq_action.emit = lp_build_tgsi_intrinsic;
678 bld_base->rsq_action.intr_name = "llvm.AMDGPU.rsq";
679 }
680
681 void radeon_llvm_finalize_module(struct radeon_llvm_context * ctx)
682 {
683 struct gallivm_state * gallivm = ctx->soa.bld_base.base.gallivm;
684 /* End the main function with Return*/
685 LLVMBuildRetVoid(gallivm->builder);
686
687 /* Create the pass manager */
688 ctx->gallivm.passmgr = LLVMCreateFunctionPassManagerForModule(
689 gallivm->module);
690
691 /* This pass should eliminate all the load and store instructions */
692 LLVMAddPromoteMemoryToRegisterPass(gallivm->passmgr);
693
694 /* Add some optimization passes */
695 LLVMAddScalarReplAggregatesPass(gallivm->passmgr);
696 LLVMAddCFGSimplificationPass(gallivm->passmgr);
697
698 /* Run the passs */
699 LLVMRunFunctionPassManager(gallivm->passmgr, ctx->main_fn);
700
701 LLVMDisposeBuilder(gallivm->builder);
702 LLVMDisposePassManager(gallivm->passmgr);
703
704 }
705
706 void radeon_llvm_dispose(struct radeon_llvm_context * ctx)
707 {
708 LLVMDisposeModule(ctx->soa.bld_base.base.gallivm->module);
709 LLVMContextDispose(ctx->soa.bld_base.base.gallivm->context);
710 }