r600g/llvm: Add dummy export for vs output
[mesa.git] / src / gallium / drivers / r600 / r600_llvm.c
1 #include "r600_llvm.h"
2
3 #include "gallivm/lp_bld_const.h"
4 #include "gallivm/lp_bld_intr.h"
5 #include "gallivm/lp_bld_gather.h"
6 #include "tgsi/tgsi_parse.h"
7 #include "util/u_double_list.h"
8 #include "util/u_memory.h"
9
10 #include "r600.h"
11 #include "r600_asm.h"
12 #include "r600_sq.h"
13 #include "r600_opcodes.h"
14 #include "r600_shader.h"
15 #include "r600_pipe.h"
16 #include "radeon_llvm.h"
17 #include "radeon_llvm_emit.h"
18
19 #include <stdio.h>
20
21 #if defined R600_USE_LLVM || defined HAVE_OPENCL
22
23 #define CONSTANT_BUFFER_0_ADDR_SPACE 9
24 #define CONSTANT_BUFFER_1_ADDR_SPACE (CONSTANT_BUFFER_0_ADDR_SPACE + R600_UCP_CONST_BUFFER)
25
26 static LLVMValueRef llvm_fetch_const(
27 struct lp_build_tgsi_context * bld_base,
28 const struct tgsi_full_src_register *reg,
29 enum tgsi_opcode_type type,
30 unsigned swizzle)
31 {
32 LLVMValueRef offset[2] = {
33 LLVMConstInt(LLVMInt64TypeInContext(bld_base->base.gallivm->context), 0, false),
34 lp_build_const_int32(bld_base->base.gallivm, reg->Register.Index)
35 };
36 if (reg->Register.Indirect) {
37 struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
38 LLVMValueRef index = LLVMBuildLoad(bld_base->base.gallivm->builder, bld->addr[reg->Indirect.Index][reg->Indirect.SwizzleX], "");
39 offset[1] = LLVMBuildAdd(bld_base->base.gallivm->builder, offset[1], index, "");
40 }
41 LLVMTypeRef const_ptr_type = LLVMPointerType(LLVMArrayType(LLVMVectorType(bld_base->base.elem_type, 4), 1024),
42 CONSTANT_BUFFER_0_ADDR_SPACE);
43 LLVMValueRef const_ptr = LLVMBuildIntToPtr(bld_base->base.gallivm->builder, lp_build_const_int32(bld_base->base.gallivm, 0), const_ptr_type, "");
44 LLVMValueRef ptr = LLVMBuildGEP(bld_base->base.gallivm->builder, const_ptr, offset, 2, "");
45 LLVMValueRef cvecval = LLVMBuildLoad(bld_base->base.gallivm->builder, ptr, "");
46 LLVMValueRef cval = LLVMBuildExtractElement(bld_base->base.gallivm->builder, cvecval, lp_build_const_int32(bld_base->base.gallivm, swizzle), "");
47 return bitcast(bld_base, type, cval);
48 }
49
50 static void llvm_load_system_value(
51 struct radeon_llvm_context * ctx,
52 unsigned index,
53 const struct tgsi_full_declaration *decl)
54 {
55 unsigned chan;
56
57 switch (decl->Semantic.Name) {
58 case TGSI_SEMANTIC_INSTANCEID: chan = 3; break;
59 case TGSI_SEMANTIC_VERTEXID: chan = 0; break;
60 default: assert(!"unknown system value");
61 }
62
63 LLVMValueRef reg = lp_build_const_int32(
64 ctx->soa.bld_base.base.gallivm, chan);
65 ctx->system_values[index] = build_intrinsic(
66 ctx->soa.bld_base.base.gallivm->builder,
67 "llvm.R600.load.input",
68 ctx->soa.bld_base.base.elem_type, &reg, 1,
69 LLVMReadNoneAttribute);
70 }
71
72 static LLVMValueRef llvm_fetch_system_value(
73 struct lp_build_tgsi_context * bld_base,
74 const struct tgsi_full_src_register *reg,
75 enum tgsi_opcode_type type,
76 unsigned swizzle)
77 {
78 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
79 LLVMValueRef cval = ctx->system_values[reg->Register.Index];
80 return bitcast(bld_base, type, cval);
81 }
82
83 static LLVMValueRef
84 llvm_load_input_helper(
85 struct radeon_llvm_context * ctx,
86 const char *intrinsic, unsigned idx)
87 {
88 LLVMValueRef reg = lp_build_const_int32(
89 ctx->soa.bld_base.base.gallivm,
90 idx);
91 return build_intrinsic(
92 ctx->soa.bld_base.base.gallivm->builder,
93 intrinsic,
94 ctx->soa.bld_base.base.elem_type, &reg, 1,
95 LLVMReadNoneAttribute);
96 }
97
98 static LLVMValueRef
99 llvm_face_select_helper(
100 struct radeon_llvm_context * ctx,
101 const char *intrinsic, unsigned face_register,
102 unsigned frontcolor_register, unsigned backcolor_regiser)
103 {
104
105 LLVMValueRef backcolor = llvm_load_input_helper(
106 ctx,
107 intrinsic,
108 backcolor_regiser);
109 LLVMValueRef front_color = llvm_load_input_helper(
110 ctx,
111 intrinsic,
112 frontcolor_register);
113 LLVMValueRef face = llvm_load_input_helper(
114 ctx,
115 "llvm.R600.load.input",
116 face_register);
117 LLVMValueRef is_face_positive = LLVMBuildFCmp(
118 ctx->soa.bld_base.base.gallivm->builder,
119 LLVMRealUGT, face,
120 lp_build_const_float(ctx->soa.bld_base.base.gallivm, 0.0f),
121 "");
122 return LLVMBuildSelect(
123 ctx->soa.bld_base.base.gallivm->builder,
124 is_face_positive,
125 front_color,
126 backcolor,
127 "");
128 }
129
130 static void llvm_load_input(
131 struct radeon_llvm_context * ctx,
132 unsigned input_index,
133 const struct tgsi_full_declaration *decl)
134 {
135 unsigned chan;
136
137 const char *intrinsics = "llvm.R600.load.input";
138 unsigned offset = 4 * ctx->reserved_reg_count;
139
140 if (ctx->type == TGSI_PROCESSOR_FRAGMENT && ctx->chip_class >= EVERGREEN) {
141 switch (decl->Interp.Interpolate) {
142 case TGSI_INTERPOLATE_COLOR:
143 case TGSI_INTERPOLATE_PERSPECTIVE:
144 offset = 0;
145 intrinsics = "llvm.R600.load.input.perspective";
146 break;
147 case TGSI_INTERPOLATE_LINEAR:
148 offset = 0;
149 intrinsics = "llvm.R600.load.input.linear";
150 break;
151 case TGSI_INTERPOLATE_CONSTANT:
152 offset = 0;
153 intrinsics = "llvm.R600.load.input.constant";
154 break;
155 default:
156 assert(0 && "Unknow Interpolate mode");
157 }
158 }
159
160 for (chan = 0; chan < 4; chan++) {
161 unsigned soa_index = radeon_llvm_reg_index_soa(input_index,
162 chan);
163
164 switch (decl->Semantic.Name) {
165 case TGSI_SEMANTIC_FACE:
166 ctx->inputs[soa_index] = llvm_load_input_helper(ctx,
167 "llvm.R600.load.input",
168 4 * ctx->face_input);
169 break;
170 case TGSI_SEMANTIC_POSITION:
171 if (ctx->type != TGSI_PROCESSOR_FRAGMENT || chan != 3) {
172 ctx->inputs[soa_index] = llvm_load_input_helper(ctx,
173 "llvm.R600.load.input",
174 soa_index + (ctx->reserved_reg_count * 4));
175 } else {
176 LLVMValueRef w_coord = llvm_load_input_helper(ctx,
177 "llvm.R600.load.input",
178 soa_index + (ctx->reserved_reg_count * 4));
179 ctx->inputs[soa_index] = LLVMBuildFDiv(ctx->gallivm.builder,
180 lp_build_const_float(&(ctx->gallivm), 1.0f), w_coord, "");
181 }
182 break;
183 case TGSI_SEMANTIC_COLOR:
184 if (ctx->two_side) {
185 unsigned front_location, back_location;
186 unsigned back_reg = ctx->r600_inputs[input_index]
187 .potential_back_facing_reg;
188 if (ctx->chip_class >= EVERGREEN) {
189 front_location = 4 * ctx->r600_inputs[input_index].lds_pos + chan;
190 back_location = 4 * ctx->r600_inputs[back_reg].lds_pos + chan;
191 } else {
192 front_location = soa_index + 4 * ctx->reserved_reg_count;
193 back_location = radeon_llvm_reg_index_soa(
194 ctx->r600_inputs[back_reg].gpr,
195 chan);
196 }
197 ctx->inputs[soa_index] = llvm_face_select_helper(ctx,
198 intrinsics,
199 4 * ctx->face_input, front_location, back_location);
200 break;
201 }
202 default:
203 {
204 unsigned location;
205 if (ctx->chip_class >= EVERGREEN) {
206 location = 4 * ctx->r600_inputs[input_index].lds_pos + chan;
207 } else {
208 location = soa_index + 4 * ctx->reserved_reg_count;
209 }
210 /* The * 4 is assuming that we are in soa mode. */
211 ctx->inputs[soa_index] = llvm_load_input_helper(ctx,
212 intrinsics, location);
213
214 break;
215 }
216 }
217 }
218 }
219
220 static void llvm_emit_prologue(struct lp_build_tgsi_context * bld_base)
221 {
222 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
223 struct lp_build_context * base = &bld_base->base;
224 unsigned i;
225
226 /* Reserve special input registers */
227 for (i = 0; i < ctx->reserved_reg_count; i++) {
228 unsigned chan;
229 for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
230 LLVMValueRef reg_index = lp_build_const_int32(
231 base->gallivm,
232 radeon_llvm_reg_index_soa(i, chan));
233 lp_build_intrinsic_unary(base->gallivm->builder,
234 "llvm.AMDGPU.reserve.reg",
235 LLVMVoidTypeInContext(base->gallivm->context),
236 reg_index);
237 }
238 }
239 }
240
241 static void llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
242 {
243 struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
244 struct lp_build_context * base = &bld_base->base;
245 struct pipe_stream_output_info * so = ctx->stream_outputs;
246 unsigned i;
247 unsigned next_pos = 60;
248 unsigned next_param = 0;
249
250 unsigned color_count = 0;
251 boolean has_color = false;
252
253 if (ctx->type == TGSI_PROCESSOR_VERTEX && so->num_outputs) {
254 for (i = 0; i < so->num_outputs; i++) {
255 unsigned register_index = so->output[i].register_index;
256 unsigned start_component = so->output[i].start_component;
257 unsigned num_components = so->output[i].num_components;
258 unsigned dst_offset = so->output[i].dst_offset;
259 unsigned chan;
260 LLVMValueRef elements[4];
261 if (dst_offset < start_component) {
262 for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
263 elements[chan] = LLVMBuildLoad(base->gallivm->builder,
264 ctx->soa.outputs[register_index][(chan + start_component) % TGSI_NUM_CHANNELS], "");
265 }
266 start_component = 0;
267 } else {
268 for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
269 elements[chan] = LLVMBuildLoad(base->gallivm->builder,
270 ctx->soa.outputs[register_index][chan], "");
271 }
272 }
273 LLVMValueRef output = lp_build_gather_values(base->gallivm, elements, 4);
274 LLVMValueRef args[4];
275 args[0] = output;
276 args[1] = lp_build_const_int32(base->gallivm, dst_offset - start_component);
277 args[2] = lp_build_const_int32(base->gallivm, so->output[i].output_buffer);
278 args[3] = lp_build_const_int32(base->gallivm, ((1 << num_components) - 1) << start_component);
279 lp_build_intrinsic(base->gallivm->builder, "llvm.R600.store.stream.output",
280 LLVMVoidTypeInContext(base->gallivm->context), args, 4);
281 }
282 }
283
284 /* Add the necessary export instructions */
285 for (i = 0; i < ctx->output_reg_count; i++) {
286 unsigned chan;
287 LLVMValueRef elements[4];
288 for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
289 elements[chan] = LLVMBuildLoad(base->gallivm->builder,
290 ctx->soa.outputs[i][chan], "");
291 }
292 LLVMValueRef output = lp_build_gather_values(base->gallivm, elements, 4);
293
294 if (ctx->type == TGSI_PROCESSOR_VERTEX) {
295 switch (ctx->r600_outputs[i].name) {
296 case TGSI_SEMANTIC_POSITION:
297 case TGSI_SEMANTIC_PSIZE: {
298 LLVMValueRef args[3];
299 args[0] = output;
300 args[1] = lp_build_const_int32(base->gallivm, next_pos++);
301 args[2] = lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS);
302 build_intrinsic(
303 base->gallivm->builder,
304 "llvm.R600.store.swizzle",
305 LLVMVoidTypeInContext(base->gallivm->context),
306 args, 3, 0);
307 break;
308 }
309 case TGSI_SEMANTIC_CLIPVERTEX: {
310 LLVMValueRef args[3];
311 unsigned reg_index;
312 unsigned base_vector_chan;
313 LLVMValueRef adjusted_elements[4];
314 for (reg_index = 0; reg_index < 2; reg_index ++) {
315 for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
316 LLVMValueRef offset[2] = {
317 LLVMConstInt(LLVMInt64TypeInContext(bld_base->base.gallivm->context), 0, false),
318 lp_build_const_int32(bld_base->base.gallivm, reg_index * 4 + chan)
319 };
320 LLVMTypeRef const_ptr_type = LLVMPointerType(LLVMArrayType(LLVMVectorType(bld_base->base.elem_type, 4), 1024), CONSTANT_BUFFER_1_ADDR_SPACE);
321 LLVMValueRef const_ptr = LLVMBuildIntToPtr(bld_base->base.gallivm->builder, lp_build_const_int32(bld_base->base.gallivm, 0), const_ptr_type, "");
322 LLVMValueRef ptr = LLVMBuildGEP(bld_base->base.gallivm->builder, const_ptr, offset, 2, "");
323 LLVMValueRef base_vector = LLVMBuildLoad(bld_base->base.gallivm->builder, ptr, "");
324 args[0] = output;
325 args[1] = base_vector;
326 adjusted_elements[chan] = build_intrinsic(base->gallivm->builder,
327 "llvm.AMDGPU.dp4", bld_base->base.elem_type,
328 args, 2, LLVMReadNoneAttribute);
329 }
330 args[0] = lp_build_gather_values(base->gallivm,
331 adjusted_elements, 4);
332 args[1] = lp_build_const_int32(base->gallivm, next_pos++);
333 args[2] = lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS);
334 build_intrinsic(
335 base->gallivm->builder,
336 "llvm.R600.store.swizzle",
337 LLVMVoidTypeInContext(base->gallivm->context),
338 args, 3, 0);
339 }
340 break;
341 }
342 case TGSI_SEMANTIC_CLIPDIST : {
343 LLVMValueRef args[3];
344 args[0] = output;
345 args[1] = lp_build_const_int32(base->gallivm, next_pos++);
346 args[2] = lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS);
347 build_intrinsic(
348 base->gallivm->builder,
349 "llvm.R600.store.swizzle",
350 LLVMVoidTypeInContext(base->gallivm->context),
351 args, 3, 0);
352 args[1] = lp_build_const_int32(base->gallivm, next_param++);
353 args[2] = lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM);
354 build_intrinsic(
355 base->gallivm->builder,
356 "llvm.R600.store.swizzle",
357 LLVMVoidTypeInContext(base->gallivm->context),
358 args, 3, 0);
359 break;
360 }
361 case TGSI_SEMANTIC_FOG: {
362 elements[0] = LLVMBuildLoad(base->gallivm->builder,
363 ctx->soa.outputs[i][0], "");
364 elements[1] = elements[2] = lp_build_const_float(base->gallivm, 0.0f);
365 elements[3] = lp_build_const_float(base->gallivm, 1.0f);
366
367 LLVMValueRef args[3];
368 args[0] = lp_build_gather_values(base->gallivm, elements, 4);
369 args[1] = lp_build_const_int32(base->gallivm, next_param++);
370 args[2] = lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM);
371 build_intrinsic(
372 base->gallivm->builder,
373 "llvm.R600.store.swizzle",
374 LLVMVoidTypeInContext(base->gallivm->context),
375 args, 3, 0);
376 break;
377 }
378 default: {
379 LLVMValueRef args[3];
380 args[0] = output;
381 args[1] = lp_build_const_int32(base->gallivm, next_param++);
382 args[2] = lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM);
383 build_intrinsic(
384 base->gallivm->builder,
385 "llvm.R600.store.swizzle",
386 LLVMVoidTypeInContext(base->gallivm->context),
387 args, 3, 0);
388 break;
389 }
390 }
391 } else if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
392 switch (ctx->r600_outputs[i].name) {
393 case TGSI_SEMANTIC_COLOR:
394 has_color = true;
395 if ( color_count < ctx->color_buffer_count) {
396 LLVMValueRef args[3];
397 args[0] = output;
398 if (ctx->fs_color_all) {
399 for (unsigned j = 0; j < ctx->color_buffer_count; j++) {
400 args[1] = lp_build_const_int32(base->gallivm, j);
401 args[2] = lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL);
402 build_intrinsic(
403 base->gallivm->builder,
404 "llvm.R600.store.swizzle",
405 LLVMVoidTypeInContext(base->gallivm->context),
406 args, 3, 0);
407 }
408 } else {
409 args[1] = lp_build_const_int32(base->gallivm, color_count++);
410 args[2] = lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL);
411 build_intrinsic(
412 base->gallivm->builder,
413 "llvm.R600.store.swizzle",
414 LLVMVoidTypeInContext(base->gallivm->context),
415 args, 3, 0);
416 }
417 }
418 break;
419 case TGSI_SEMANTIC_POSITION:
420 lp_build_intrinsic_unary(
421 base->gallivm->builder,
422 "llvm.R600.store.pixel.depth",
423 LLVMVoidTypeInContext(base->gallivm->context),
424 LLVMBuildLoad(base->gallivm->builder, ctx->soa.outputs[i][2], ""));
425 break;
426 case TGSI_SEMANTIC_STENCIL:
427 lp_build_intrinsic_unary(
428 base->gallivm->builder,
429 "llvm.R600.store.pixel.stencil",
430 LLVMVoidTypeInContext(base->gallivm->context),
431 LLVMBuildLoad(base->gallivm->builder, ctx->soa.outputs[i][1], ""));
432 break;
433 }
434 }
435 }
436 // Add dummy exports
437 if (ctx->type == TGSI_PROCESSOR_VERTEX) {
438 if (!next_param) {
439 lp_build_intrinsic_unary(base->gallivm->builder, "llvm.R600.store.dummy",
440 LLVMVoidTypeInContext(base->gallivm->context),
441 lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM));
442 }
443 if (!(next_pos-60)) {
444 lp_build_intrinsic_unary(base->gallivm->builder, "llvm.R600.store.dummy",
445 LLVMVoidTypeInContext(base->gallivm->context),
446 lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS));
447 }
448 }
449 if (ctx->type == TGSI_PROCESSOR_FRAGMENT) {
450 if (!has_color) {
451 lp_build_intrinsic_unary(base->gallivm->builder, "llvm.R600.store.dummy",
452 LLVMVoidTypeInContext(base->gallivm->context),
453 lp_build_const_int32(base->gallivm, V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL));
454 }
455 }
456
457 }
458
459 static void llvm_emit_tex(
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 gallivm_state * gallivm = bld_base->base.gallivm;
465 LLVMValueRef args[6];
466 unsigned c, sampler_src;
467
468 assert(emit_data->arg_count + 2 <= Elements(args));
469
470 for (c = 0; c < emit_data->arg_count; ++c)
471 args[c] = emit_data->args[c];
472
473 sampler_src = emit_data->inst->Instruction.NumSrcRegs-1;
474
475 args[c++] = lp_build_const_int32(gallivm,
476 emit_data->inst->Src[sampler_src].Register.Index + R600_MAX_CONST_BUFFERS);
477 args[c++] = lp_build_const_int32(gallivm,
478 emit_data->inst->Src[sampler_src].Register.Index);
479 args[c++] = lp_build_const_int32(gallivm,
480 emit_data->inst->Texture.Texture);
481
482 emit_data->output[0] = build_intrinsic(gallivm->builder,
483 action->intr_name,
484 emit_data->dst_type, args, c, LLVMReadNoneAttribute);
485 }
486
487 static void emit_cndlt(
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 LLVMBuilderRef builder = bld_base->base.gallivm->builder;
493 LLVMValueRef float_zero = lp_build_const_float(
494 bld_base->base.gallivm, 0.0f);
495 LLVMValueRef cmp = LLVMBuildFCmp(
496 builder, LLVMRealULT, emit_data->args[0], float_zero, "");
497 emit_data->output[emit_data->chan] = LLVMBuildSelect(builder,
498 cmp, emit_data->args[1], emit_data->args[2], "");
499 }
500
501 static void dp_fetch_args(
502 struct lp_build_tgsi_context * bld_base,
503 struct lp_build_emit_data * emit_data)
504 {
505 struct lp_build_context * base = &bld_base->base;
506 unsigned chan;
507 LLVMValueRef elements[2][4];
508 unsigned opcode = emit_data->inst->Instruction.Opcode;
509 unsigned dp_components = (opcode == TGSI_OPCODE_DP2 ? 2 :
510 (opcode == TGSI_OPCODE_DP3 ? 3 : 4));
511 for (chan = 0 ; chan < dp_components; chan++) {
512 elements[0][chan] = lp_build_emit_fetch(bld_base,
513 emit_data->inst, 0, chan);
514 elements[1][chan] = lp_build_emit_fetch(bld_base,
515 emit_data->inst, 1, chan);
516 }
517
518 for ( ; chan < 4; chan++) {
519 elements[0][chan] = base->zero;
520 elements[1][chan] = base->zero;
521 }
522
523 /* Fix up for DPH */
524 if (opcode == TGSI_OPCODE_DPH) {
525 elements[0][TGSI_CHAN_W] = base->one;
526 }
527
528 emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm,
529 elements[0], 4);
530 emit_data->args[1] = lp_build_gather_values(bld_base->base.gallivm,
531 elements[1], 4);
532 emit_data->arg_count = 2;
533
534 emit_data->dst_type = base->elem_type;
535 }
536
537 static struct lp_build_tgsi_action dot_action = {
538 .fetch_args = dp_fetch_args,
539 .emit = build_tgsi_intrinsic_nomem,
540 .intr_name = "llvm.AMDGPU.dp4"
541 };
542
543
544
545 LLVMModuleRef r600_tgsi_llvm(
546 struct radeon_llvm_context * ctx,
547 const struct tgsi_token * tokens)
548 {
549 struct tgsi_shader_info shader_info;
550 struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
551 radeon_llvm_context_init(ctx);
552 tgsi_scan_shader(tokens, &shader_info);
553
554 bld_base->info = &shader_info;
555 bld_base->userdata = ctx;
556 bld_base->emit_fetch_funcs[TGSI_FILE_CONSTANT] = llvm_fetch_const;
557 bld_base->emit_fetch_funcs[TGSI_FILE_SYSTEM_VALUE] = llvm_fetch_system_value;
558 bld_base->emit_prologue = llvm_emit_prologue;
559 bld_base->emit_epilogue = llvm_emit_epilogue;
560 ctx->userdata = ctx;
561 ctx->load_input = llvm_load_input;
562 ctx->load_system_value = llvm_load_system_value;
563
564 bld_base->op_actions[TGSI_OPCODE_DP2] = dot_action;
565 bld_base->op_actions[TGSI_OPCODE_DP3] = dot_action;
566 bld_base->op_actions[TGSI_OPCODE_DP4] = dot_action;
567 bld_base->op_actions[TGSI_OPCODE_DPH] = dot_action;
568 bld_base->op_actions[TGSI_OPCODE_DDX].emit = llvm_emit_tex;
569 bld_base->op_actions[TGSI_OPCODE_DDY].emit = llvm_emit_tex;
570 bld_base->op_actions[TGSI_OPCODE_TEX].emit = llvm_emit_tex;
571 bld_base->op_actions[TGSI_OPCODE_TEX2].emit = llvm_emit_tex;
572 bld_base->op_actions[TGSI_OPCODE_TXB].emit = llvm_emit_tex;
573 bld_base->op_actions[TGSI_OPCODE_TXB2].emit = llvm_emit_tex;
574 bld_base->op_actions[TGSI_OPCODE_TXD].emit = llvm_emit_tex;
575 bld_base->op_actions[TGSI_OPCODE_TXL].emit = llvm_emit_tex;
576 bld_base->op_actions[TGSI_OPCODE_TXL2].emit = llvm_emit_tex;
577 bld_base->op_actions[TGSI_OPCODE_TXF].emit = llvm_emit_tex;
578 bld_base->op_actions[TGSI_OPCODE_TXQ].emit = llvm_emit_tex;
579 bld_base->op_actions[TGSI_OPCODE_TXP].emit = llvm_emit_tex;
580 bld_base->op_actions[TGSI_OPCODE_CMP].emit = emit_cndlt;
581
582 lp_build_tgsi_llvm(bld_base, tokens);
583
584 radeon_llvm_finalize_module(ctx);
585
586 return ctx->gallivm.module;
587 }
588
589 const char * r600_llvm_gpu_string(enum radeon_family family)
590 {
591 const char * gpu_family;
592
593 switch (family) {
594 case CHIP_R600:
595 case CHIP_RV610:
596 case CHIP_RV630:
597 case CHIP_RV620:
598 case CHIP_RV635:
599 case CHIP_RS780:
600 case CHIP_RS880:
601 gpu_family = "r600";
602 break;
603 case CHIP_RV710:
604 gpu_family = "rv710";
605 break;
606 case CHIP_RV730:
607 gpu_family = "rv730";
608 break;
609 case CHIP_RV670:
610 case CHIP_RV740:
611 case CHIP_RV770:
612 gpu_family = "rv770";
613 break;
614 case CHIP_PALM:
615 case CHIP_CEDAR:
616 gpu_family = "cedar";
617 break;
618 case CHIP_SUMO:
619 case CHIP_SUMO2:
620 case CHIP_REDWOOD:
621 gpu_family = "redwood";
622 break;
623 case CHIP_JUNIPER:
624 gpu_family = "juniper";
625 break;
626 case CHIP_HEMLOCK:
627 case CHIP_CYPRESS:
628 gpu_family = "cypress";
629 break;
630 case CHIP_BARTS:
631 gpu_family = "barts";
632 break;
633 case CHIP_TURKS:
634 gpu_family = "turks";
635 break;
636 case CHIP_CAICOS:
637 gpu_family = "caicos";
638 break;
639 case CHIP_CAYMAN:
640 case CHIP_ARUBA:
641 gpu_family = "cayman";
642 break;
643 default:
644 gpu_family = "";
645 fprintf(stderr, "Chip not supported by r600 llvm "
646 "backend, please file a bug at bugs.freedesktop.org\n");
647 break;
648 }
649 return gpu_family;
650 }
651
652 unsigned r600_llvm_compile(
653 LLVMModuleRef mod,
654 unsigned char ** inst_bytes,
655 unsigned * inst_byte_count,
656 enum radeon_family family,
657 unsigned dump)
658 {
659 const char * gpu_family = r600_llvm_gpu_string(family);
660 return radeon_llvm_compile(mod, inst_bytes, inst_byte_count,
661 gpu_family, dump);
662 }
663
664 #endif