1 /**************************************************************************
3 * Copyright 2011-2012 Advanced Micro Devices, Inc.
4 * Copyright 2009 VMware, Inc.
5 * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * TGSI to LLVM IR translation.
34 * @author Jose Fonseca <jfonseca@vmware.com>
35 * @author Tom Stellard <thomas.stellard@amd.com>
37 * Based on tgsi_sse2.c code written by Michal Krol, Keith Whitwell,
38 * Brian Paul, and others.
42 #include "lp_bld_tgsi_action.h"
44 #include "lp_bld_tgsi.h"
45 #include "lp_bld_arit.h"
46 #include "lp_bld_const.h"
47 #include "lp_bld_gather.h"
48 #include "lp_bld_logic.h"
50 #include "tgsi/tgsi_exec.h"
52 /* XXX: The CPU only defaults should be repaced by generic ones. In most
53 * cases, the CPU defaults are just wrappers around a function in
54 * lp_build_arit.c and these functions should be inlined here and the CPU
55 * generic code should be removed and placed elsewhere.
60 /* Generic fetch_arg functions */
62 static void scalar_unary_fetch_args(
63 struct lp_build_tgsi_context
* bld_base
,
64 struct lp_build_emit_data
* emit_data
)
67 emit_data
->args
[0] = lp_build_emit_fetch(bld_base
, emit_data
->inst
, 0, 0);
68 emit_data
->arg_count
= 1;
69 emit_data
->dst_type
= LLVMTypeOf(emit_data
->args
[0]);
72 static void scalar_binary_fetch_args(
73 struct lp_build_tgsi_context
* bld_base
,
74 struct lp_build_emit_data
* emit_data
)
77 emit_data
->args
[0] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
80 emit_data
->args
[1] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
82 emit_data
->arg_count
= 2;
83 emit_data
->dst_type
= LLVMTypeOf(emit_data
->args
[0]);
89 const struct lp_build_tgsi_action
* action
,
90 struct lp_build_tgsi_context
* bld_base
,
91 struct lp_build_emit_data
* emit_data
)
93 emit_data
->output
[emit_data
->chan
] = LLVMBuildFAdd(
94 bld_base
->base
.gallivm
->builder
,
95 emit_data
->args
[0], emit_data
->args
[1], "");
101 const struct lp_build_tgsi_action
* action
,
102 struct lp_build_tgsi_context
* bld_base
,
103 struct lp_build_emit_data
* emit_data
)
105 emit_data
->output
[emit_data
->chan
] = lp_build_emit_llvm_unary(bld_base
,
106 TGSI_OPCODE_ROUND
, emit_data
->args
[0]);
109 /* TGSI_OPCODE_CLAMP */
112 const struct lp_build_tgsi_action
* action
,
113 struct lp_build_tgsi_context
* bld_base
,
114 struct lp_build_emit_data
* emit_data
)
117 tmp
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MAX
,
120 emit_data
->output
[emit_data
->chan
] = lp_build_emit_llvm_binary(bld_base
,
121 TGSI_OPCODE_MIN
, tmp
, emit_data
->args
[2]);
128 struct lp_build_tgsi_context
* bld_base
,
129 struct lp_build_emit_data
* emit_data
,
130 unsigned dp_components
)
133 for (src
= 0; src
< 2; src
++) {
134 for (chan
= 0; chan
< dp_components
; chan
++) {
135 emit_data
->args
[(src
* dp_components
) + chan
] =
136 lp_build_emit_fetch(bld_base
, emit_data
->inst
, src
, chan
);
139 emit_data
->dst_type
= bld_base
->base
.elem_type
;
142 /* TGSI_OPCODE_DP2 */
145 struct lp_build_tgsi_context
* bld_base
,
146 struct lp_build_emit_data
* emit_data
)
148 dp_fetch_args(bld_base
, emit_data
, 2);
153 const struct lp_build_tgsi_action
* action
,
154 struct lp_build_tgsi_context
* bld_base
,
155 struct lp_build_emit_data
* emit_data
)
157 LLVMValueRef tmp0
, tmp1
;
158 tmp0
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
,
159 emit_data
->args
[0] /* src0.x */,
160 emit_data
->args
[2] /* src1.x */);
161 tmp1
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
,
162 emit_data
->args
[1] /* src0.y */,
163 emit_data
->args
[3] /* src1.y */);
164 emit_data
->output
[emit_data
->chan
] = lp_build_emit_llvm_binary(bld_base
,
165 TGSI_OPCODE_ADD
, tmp0
, tmp1
);
168 static struct lp_build_tgsi_action dp2_action
= {
169 dp2_fetch_args
, /* fetch_args */
173 /* TGSI_OPCODE_DP2A */
176 struct lp_build_tgsi_context
* bld_base
,
177 struct lp_build_emit_data
* emit_data
)
179 dp_fetch_args(bld_base
, emit_data
, 2);
180 emit_data
->args
[5] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
186 const struct lp_build_tgsi_action
* action
,
187 struct lp_build_tgsi_context
* bld_base
,
188 struct lp_build_emit_data
* emit_data
)
191 tmp
= lp_build_emit_llvm(bld_base
, TGSI_OPCODE_DP2
, emit_data
);
192 emit_data
->output
[emit_data
->chan
] = lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_ADD
,
193 emit_data
->args
[5], tmp
);
196 static struct lp_build_tgsi_action dp2a_action
= {
197 dp2a_fetch_args
, /* fetch_args */
201 /* TGSI_OPCODE_DP3 */
204 struct lp_build_tgsi_context
* bld_base
,
205 struct lp_build_emit_data
* emit_data
)
207 dp_fetch_args(bld_base
, emit_data
, 3);
212 const struct lp_build_tgsi_action
* action
,
213 struct lp_build_tgsi_context
* bld_base
,
214 struct lp_build_emit_data
* emit_data
)
216 LLVMValueRef tmp0
, tmp1
;
217 tmp0
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
,
218 emit_data
->args
[0] /* src0.x */,
219 emit_data
->args
[3] /* src1.x */);
220 tmp1
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
,
221 emit_data
->args
[1] /* src0.y */,
222 emit_data
->args
[4] /* src1.y */);
223 tmp0
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_ADD
, tmp1
, tmp0
);
224 tmp1
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
,
225 emit_data
->args
[2] /* src0.z */,
226 emit_data
->args
[5] /* src1.z */);
227 emit_data
->output
[emit_data
->chan
] = lp_build_emit_llvm_binary(bld_base
,
228 TGSI_OPCODE_ADD
, tmp0
, tmp1
);
231 static struct lp_build_tgsi_action dp3_action
= {
232 dp3_fetch_args
, /* fetch_args */
236 /* TGSI_OPCODDE_DP4 */
240 struct lp_build_tgsi_context
* bld_base
,
241 struct lp_build_emit_data
* emit_data
)
243 dp_fetch_args(bld_base
, emit_data
, 4);
248 const struct lp_build_tgsi_action
* action
,
249 struct lp_build_tgsi_context
* bld_base
,
250 struct lp_build_emit_data
* emit_data
)
252 LLVMValueRef tmp0
, tmp1
;
253 tmp0
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
,
254 emit_data
->args
[0] /* src0.x */,
255 emit_data
->args
[4] /* src1.x */);
256 tmp1
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
,
257 emit_data
->args
[1] /* src0.y */,
258 emit_data
->args
[5] /* src1.y */);
259 tmp0
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_ADD
, tmp0
, tmp1
);
260 tmp1
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
,
261 emit_data
->args
[2] /* src0.z */,
262 emit_data
->args
[6] /* src1.z */);
263 tmp0
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_ADD
, tmp0
, tmp1
);
264 tmp1
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
,
265 emit_data
->args
[3] /* src0.w */,
266 emit_data
->args
[7] /* src1.w */);
267 emit_data
->output
[emit_data
->chan
] = lp_build_emit_llvm_binary(bld_base
,
268 TGSI_OPCODE_ADD
, tmp0
, tmp1
);
271 static struct lp_build_tgsi_action dp4_action
= {
272 dp4_fetch_args
, /* fetch_args */
276 /* TGSI_OPCODE_DPH */
279 struct lp_build_tgsi_context
* bld_base
,
280 struct lp_build_emit_data
* emit_data
)
282 dp_fetch_args(bld_base
, emit_data
, 4);
284 emit_data
->args
[3] = bld_base
->base
.one
;
287 const struct lp_build_tgsi_action dph_action
= {
288 dph_fetch_args
, /* fetch_args */
292 /* TGSI_OPCODE_DST */
295 struct lp_build_tgsi_context
* bld_base
,
296 struct lp_build_emit_data
* emit_data
)
299 emit_data
->args
[0] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
302 emit_data
->args
[1] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
305 emit_data
->args
[2] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
308 emit_data
->args
[3] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
314 const struct lp_build_tgsi_action
* action
,
315 struct lp_build_tgsi_context
* bld_base
,
316 struct lp_build_emit_data
* emit_data
)
319 emit_data
->output
[TGSI_CHAN_X
] = bld_base
->base
.one
;
322 emit_data
->output
[TGSI_CHAN_Y
] = lp_build_emit_llvm_binary(bld_base
,
324 emit_data
->args
[0] /* src0.y */,
325 emit_data
->args
[2] /* src1.y */);
327 emit_data
->output
[TGSI_CHAN_Z
] = emit_data
->args
[1]; /* src0.z */
330 emit_data
->output
[TGSI_CHAN_W
] = emit_data
->args
[3]; /* src1.w */
333 static struct lp_build_tgsi_action dst_action
= {
334 dst_fetch_args
, /* fetch_args */
338 /* TGSI_OPCODE_END */
341 const struct lp_build_tgsi_action
* action
,
342 struct lp_build_tgsi_context
* bld_base
,
343 struct lp_build_emit_data
* emit_data
)
348 /* TGSI_OPCODE_EXP */
352 const struct lp_build_tgsi_action
* action
,
353 struct lp_build_tgsi_context
* bld_base
,
354 struct lp_build_emit_data
* emit_data
)
356 LLVMValueRef floor_x
;
358 /* floor( src0.x ) */
359 floor_x
= lp_build_emit_llvm_unary(bld_base
, TGSI_OPCODE_FLR
,
362 /* 2 ^ floor( src0.x ) */
363 emit_data
->output
[TGSI_CHAN_X
] = lp_build_emit_llvm_unary(bld_base
,
364 TGSI_OPCODE_EX2
, floor_x
);
366 /* src0.x - floor( src0.x ) */
367 emit_data
->output
[TGSI_CHAN_Y
] = lp_build_emit_llvm_binary(bld_base
,
368 TGSI_OPCODE_SUB
, emit_data
->args
[0] /* src0.x */, floor_x
);
371 emit_data
->output
[TGSI_CHAN_Z
] = lp_build_emit_llvm_unary(bld_base
,
372 TGSI_OPCODE_EX2
, emit_data
->args
[0] /* src0.x */);
374 emit_data
->output
[TGSI_CHAN_W
] = bld_base
->base
.one
;
377 const struct lp_build_tgsi_action exp_action
= {
378 scalar_unary_fetch_args
, /* fetch_args */
382 /* TGSI_OPCODE_FRC */
386 const struct lp_build_tgsi_action
* action
,
387 struct lp_build_tgsi_context
* bld_base
,
388 struct lp_build_emit_data
* emit_data
)
391 tmp
= lp_build_emit_llvm_unary(bld_base
, TGSI_OPCODE_FLR
,
393 emit_data
->output
[emit_data
->chan
] = lp_build_emit_llvm_binary(bld_base
,
394 TGSI_OPCODE_SUB
, emit_data
->args
[0], tmp
);
397 /* TGSI_OPCODE_KIL */
401 struct lp_build_tgsi_context
* bld_base
,
402 struct lp_build_emit_data
* emit_data
)
405 emit_data
->args
[0] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
408 emit_data
->args
[1] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
411 emit_data
->args
[2] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
414 emit_data
->args
[3] = lp_build_emit_fetch(bld_base
, emit_data
->inst
,
416 emit_data
->arg_count
= 4;
417 emit_data
->dst_type
= LLVMVoidTypeInContext(bld_base
->base
.gallivm
->context
);
420 /* TGSI_OPCODE_KILP */
424 struct lp_build_tgsi_context
* bld_base
,
425 struct lp_build_emit_data
* emit_data
)
427 emit_data
->dst_type
= LLVMVoidTypeInContext(bld_base
->base
.gallivm
->context
);
430 /* TGSI_OPCODE_LIT */
434 struct lp_build_tgsi_context
* bld_base
,
435 struct lp_build_emit_data
* emit_data
)
438 emit_data
->args
[0] = lp_build_emit_fetch(bld_base
, emit_data
->inst
, 0, TGSI_CHAN_X
);
440 emit_data
->args
[1] = lp_build_emit_fetch(bld_base
, emit_data
->inst
, 0, TGSI_CHAN_Y
);
442 emit_data
->args
[2] = lp_build_emit_fetch(bld_base
, emit_data
->inst
, 0, TGSI_CHAN_W
);
443 emit_data
->arg_count
= 3;
448 const struct lp_build_tgsi_action
* action
,
449 struct lp_build_tgsi_context
* bld_base
,
450 struct lp_build_emit_data
* emit_data
)
452 LLVMValueRef tmp0
, tmp1
, tmp2
;
455 emit_data
->output
[TGSI_CHAN_X
] = bld_base
->base
.one
;
458 emit_data
->output
[TGSI_CHAN_Y
] = lp_build_emit_llvm_binary(bld_base
,
460 emit_data
->args
[0] /* src0.x */,
461 bld_base
->base
.zero
);
464 /* XMM[1] = SrcReg[0].yyyy */
465 tmp1
= emit_data
->args
[1];
466 /* XMM[1] = max(XMM[1], 0) */
467 tmp1
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MAX
,
468 tmp1
, bld_base
->base
.zero
);
469 /* XMM[2] = SrcReg[0].wwww */
470 tmp2
= emit_data
->args
[2];
471 tmp1
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_POW
,
473 tmp0
= emit_data
->args
[0];
474 emit_data
->output
[TGSI_CHAN_Z
] = lp_build_emit_llvm_ternary(bld_base
,
476 tmp0
, bld_base
->base
.zero
, tmp1
);
478 emit_data
->output
[TGSI_CHAN_W
] = bld_base
->base
.one
;
481 static struct lp_build_tgsi_action lit_action
= {
482 lit_fetch_args
, /* fetch_args */
486 /* TGSI_OPCODE_LOG */
490 const struct lp_build_tgsi_action
* action
,
491 struct lp_build_tgsi_context
* bld_base
,
492 struct lp_build_emit_data
* emit_data
)
495 LLVMValueRef abs_x
, log_abs_x
, flr_log_abs_x
, ex2_flr_log_abs_x
;
498 abs_x
= lp_build_emit_llvm_unary(bld_base
, TGSI_OPCODE_ABS
,
499 emit_data
->args
[0] /* src0.x */);
501 /* log( abs( src0.x ) ) */
502 log_abs_x
= lp_build_emit_llvm_unary(bld_base
, TGSI_OPCODE_LG2
,
505 /* floor( log( abs( src0.x ) ) ) */
506 flr_log_abs_x
= lp_build_emit_llvm_unary(bld_base
, TGSI_OPCODE_FLR
,
509 emit_data
->output
[TGSI_CHAN_X
] = flr_log_abs_x
;
512 ex2_flr_log_abs_x
= lp_build_emit_llvm_unary(bld_base
, TGSI_OPCODE_EX2
,
515 /* abs( src0.x ) / 2^( floor( lg2( abs( src0.x ) ) ) ) */
516 emit_data
->output
[TGSI_CHAN_Y
] = lp_build_emit_llvm_binary(bld_base
,
517 TGSI_OPCODE_DIV
, abs_x
, ex2_flr_log_abs_x
);
520 emit_data
->output
[TGSI_CHAN_Z
] = log_abs_x
;
523 emit_data
->output
[TGSI_CHAN_W
] = bld_base
->base
.one
;
526 static struct lp_build_tgsi_action log_action
= {
527 scalar_unary_fetch_args
, /* fetch_args */
531 /* TGSI_OPCODE_LRP */
535 const struct lp_build_tgsi_action
* action
,
536 struct lp_build_tgsi_context
* bld_base
,
537 struct lp_build_emit_data
* emit_data
)
540 tmp
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_SUB
,
543 emit_data
->output
[emit_data
->chan
] = lp_build_emit_llvm_ternary(bld_base
,
544 TGSI_OPCODE_MAD
, emit_data
->args
[0], tmp
, emit_data
->args
[2]);
547 /* TGSI_OPCODE_MAD */
551 const struct lp_build_tgsi_action
* action
,
552 struct lp_build_tgsi_context
* bld_base
,
553 struct lp_build_emit_data
* emit_data
)
556 tmp
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
,
559 emit_data
->output
[emit_data
->chan
] = lp_build_emit_llvm_binary(bld_base
,
560 TGSI_OPCODE_ADD
, tmp
, emit_data
->args
[2]);
563 /* TGSI_OPCODE_MOV */
567 const struct lp_build_tgsi_action
* action
,
568 struct lp_build_tgsi_context
* bld_base
,
569 struct lp_build_emit_data
* emit_data
)
571 emit_data
->output
[emit_data
->chan
] = emit_data
->args
[0];
574 /* TGSI_OPCODE_MUL */
577 const struct lp_build_tgsi_action
* action
,
578 struct lp_build_tgsi_context
* bld_base
,
579 struct lp_build_emit_data
* emit_data
)
581 emit_data
->output
[emit_data
->chan
] = lp_build_mul(&bld_base
->base
,
582 emit_data
->args
[0], emit_data
->args
[1]);
585 /* TGSI_OPCODE_POW */
589 const struct lp_build_tgsi_action
* action
,
590 struct lp_build_tgsi_context
* bld_base
,
591 struct lp_build_emit_data
* emit_data
)
593 emit_data
->output
[emit_data
->chan
] = lp_build_pow(&bld_base
->base
,
594 emit_data
->args
[0], emit_data
->args
[1]);
597 static struct lp_build_tgsi_action pow_action
= {
598 scalar_binary_fetch_args
, /* fetch_args */
602 /* TGSI_OPCODE_RSQ */
606 const struct lp_build_tgsi_action
* action
,
607 struct lp_build_tgsi_context
* bld_base
,
608 struct lp_build_emit_data
* emit_data
)
610 emit_data
->args
[0] = lp_build_emit_llvm_unary(bld_base
, TGSI_OPCODE_ABS
,
612 if (bld_base
->rsq_action
.emit
) {
613 bld_base
->rsq_action
.emit(&bld_base
->rsq_action
, bld_base
, emit_data
);
615 emit_data
->output
[emit_data
->chan
] = bld_base
->base
.undef
;
619 const struct lp_build_tgsi_action rsq_action
= {
620 scalar_unary_fetch_args
, /* fetch_args */
625 /* TGSI_OPCODE_SCS */
628 const struct lp_build_tgsi_action
* action
,
629 struct lp_build_tgsi_context
* bld_base
,
630 struct lp_build_emit_data
* emit_data
)
633 emit_data
->output
[TGSI_CHAN_X
] = lp_build_emit_llvm_unary(bld_base
,
634 TGSI_OPCODE_COS
, emit_data
->args
[0]);
636 emit_data
->output
[TGSI_CHAN_Y
] = lp_build_emit_llvm_unary(bld_base
,
637 TGSI_OPCODE_SIN
, emit_data
->args
[0]);
639 emit_data
->output
[TGSI_CHAN_Z
] = bld_base
->base
.zero
;
642 emit_data
->output
[TGSI_CHAN_W
] = bld_base
->base
.one
;
645 const struct lp_build_tgsi_action scs_action
= {
646 scalar_unary_fetch_args
, /* fetch_args */
650 /* TGSI_OPCODE_SFL */
654 const struct lp_build_tgsi_action
* action
,
655 struct lp_build_tgsi_context
* bld_base
,
656 struct lp_build_emit_data
* emit_data
)
658 emit_data
->output
[emit_data
->chan
] = bld_base
->base
.zero
;
661 /* TGSI_OPCODE_STR */
665 const struct lp_build_tgsi_action
* action
,
666 struct lp_build_tgsi_context
* bld_base
,
667 struct lp_build_emit_data
* emit_data
)
669 emit_data
->output
[emit_data
->chan
] = bld_base
->base
.one
;
672 /* TGSI_OPCODE_SUB */
675 const struct lp_build_tgsi_action
* action
,
676 struct lp_build_tgsi_context
* bld_base
,
677 struct lp_build_emit_data
* emit_data
)
679 emit_data
->output
[emit_data
->chan
] = LLVMBuildFSub(
680 bld_base
->base
.gallivm
->builder
,
682 emit_data
->args
[1], "");
685 /* TGSI_OPCODE_XPD */
689 struct lp_build_tgsi_context
* bld_base
,
690 struct lp_build_emit_data
* emit_data
)
692 dp_fetch_args(bld_base
, emit_data
, 3);
700 struct lp_build_tgsi_context
* bld_base
,
706 LLVMValueRef tmp0
, tmp1
;
708 tmp0
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
, a
, b
);
709 tmp1
= lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_MUL
, c
, d
);
711 return lp_build_emit_llvm_binary(bld_base
, TGSI_OPCODE_SUB
, tmp0
, tmp1
);
716 const struct lp_build_tgsi_action
* action
,
717 struct lp_build_tgsi_context
* bld_base
,
718 struct lp_build_emit_data
* emit_data
)
720 emit_data
->output
[TGSI_CHAN_X
] = xpd_helper(bld_base
,
721 emit_data
->args
[1] /* src0.y */, emit_data
->args
[5] /* src1.z */,
722 emit_data
->args
[4] /* src1.y */, emit_data
->args
[2] /* src0.z */);
724 emit_data
->output
[TGSI_CHAN_Y
] = xpd_helper(bld_base
,
725 emit_data
->args
[2] /* src0.z */, emit_data
->args
[3] /* src1.x */,
726 emit_data
->args
[5] /* src1.z */, emit_data
->args
[0] /* src0.x */);
728 emit_data
->output
[TGSI_CHAN_Z
] = xpd_helper(bld_base
,
729 emit_data
->args
[0] /* src0.x */, emit_data
->args
[4] /* src1.y */,
730 emit_data
->args
[3] /* src1.x */, emit_data
->args
[1] /* src0.y */);
732 emit_data
->output
[TGSI_CHAN_W
] = bld_base
->base
.one
;
735 const struct lp_build_tgsi_action xpd_action
= {
736 xpd_fetch_args
, /* fetch_args */
741 lp_set_default_actions(struct lp_build_tgsi_context
* bld_base
)
743 bld_base
->op_actions
[TGSI_OPCODE_DP2
] = dp2_action
;
744 bld_base
->op_actions
[TGSI_OPCODE_DP3
] = dp3_action
;
745 bld_base
->op_actions
[TGSI_OPCODE_DP4
] = dp4_action
;
746 bld_base
->op_actions
[TGSI_OPCODE_DP2A
] = dp2a_action
;
747 bld_base
->op_actions
[TGSI_OPCODE_DPH
] = dph_action
;
748 bld_base
->op_actions
[TGSI_OPCODE_DST
] = dst_action
;
749 bld_base
->op_actions
[TGSI_OPCODE_EXP
] = exp_action
;
750 bld_base
->op_actions
[TGSI_OPCODE_LIT
] = lit_action
;
751 bld_base
->op_actions
[TGSI_OPCODE_LOG
] = log_action
;
752 bld_base
->op_actions
[TGSI_OPCODE_RSQ
] = rsq_action
;
753 bld_base
->op_actions
[TGSI_OPCODE_POW
] = pow_action
;
754 bld_base
->op_actions
[TGSI_OPCODE_SCS
] = scs_action
;
755 bld_base
->op_actions
[TGSI_OPCODE_XPD
] = xpd_action
;
757 bld_base
->op_actions
[TGSI_OPCODE_COS
].fetch_args
= scalar_unary_fetch_args
;
758 bld_base
->op_actions
[TGSI_OPCODE_EX2
].fetch_args
= scalar_unary_fetch_args
;
759 bld_base
->op_actions
[TGSI_OPCODE_IF
].fetch_args
= scalar_unary_fetch_args
;
760 bld_base
->op_actions
[TGSI_OPCODE_KIL
].fetch_args
= kil_fetch_args
;
761 bld_base
->op_actions
[TGSI_OPCODE_KILP
].fetch_args
= kilp_fetch_args
;
762 bld_base
->op_actions
[TGSI_OPCODE_RCP
].fetch_args
= scalar_unary_fetch_args
;
763 bld_base
->op_actions
[TGSI_OPCODE_SIN
].fetch_args
= scalar_unary_fetch_args
;
764 bld_base
->op_actions
[TGSI_OPCODE_LG2
].fetch_args
= scalar_unary_fetch_args
;
766 bld_base
->op_actions
[TGSI_OPCODE_ADD
].emit
= add_emit
;
767 bld_base
->op_actions
[TGSI_OPCODE_ARR
].emit
= arr_emit
;
768 bld_base
->op_actions
[TGSI_OPCODE_CLAMP
].emit
= clamp_emit
;
769 bld_base
->op_actions
[TGSI_OPCODE_END
].emit
= end_emit
;
770 bld_base
->op_actions
[TGSI_OPCODE_FRC
].emit
= frc_emit
;
771 bld_base
->op_actions
[TGSI_OPCODE_LRP
].emit
= lrp_emit
;
772 bld_base
->op_actions
[TGSI_OPCODE_MAD
].emit
= mad_emit
;
773 bld_base
->op_actions
[TGSI_OPCODE_MOV
].emit
= mov_emit
;
774 bld_base
->op_actions
[TGSI_OPCODE_MUL
].emit
= mul_emit
;
775 bld_base
->op_actions
[TGSI_OPCODE_SFL
].emit
= sfl_emit
;
776 bld_base
->op_actions
[TGSI_OPCODE_STR
].emit
= str_emit
;
777 bld_base
->op_actions
[TGSI_OPCODE_SUB
].emit
= sub_emit
;
780 /* CPU Only default actions */
782 /* These actions are CPU only, because they could potentially output SSE
786 /* TGSI_OPCODE_ABS (CPU Only)*/
790 const struct lp_build_tgsi_action
* action
,
791 struct lp_build_tgsi_context
* bld_base
,
792 struct lp_build_emit_data
* emit_data
)
794 emit_data
->output
[emit_data
->chan
] = lp_build_abs(&bld_base
->base
,
798 /* TGSI_OPCODE_ADD (CPU Only) */
801 const struct lp_build_tgsi_action
* action
,
802 struct lp_build_tgsi_context
* bld_base
,
803 struct lp_build_emit_data
* emit_data
)
805 emit_data
->output
[emit_data
->chan
] = lp_build_add(&bld_base
->base
,
806 emit_data
->args
[0], emit_data
->args
[1]);
809 /* TGSI_OPCODE_ARL (CPU Only) */
812 const struct lp_build_tgsi_action
* action
,
813 struct lp_build_tgsi_context
* bld_base
,
814 struct lp_build_emit_data
* emit_data
)
817 tmp
= lp_build_floor(&bld_base
->base
,
819 emit_data
->output
[emit_data
->chan
] = LLVMBuildFPToSI(bld_base
->base
.gallivm
->builder
, tmp
,
820 bld_base
->uint_bld
.vec_type
, "");
823 /* TGSI_OPCODE_CEIL (CPU Only) */
826 const struct lp_build_tgsi_action
* action
,
827 struct lp_build_tgsi_context
* bld_base
,
828 struct lp_build_emit_data
* emit_data
)
830 emit_data
->output
[emit_data
->chan
] = lp_build_trunc(&bld_base
->base
,
834 /* TGSI_OPCODE_CMP (CPU Only) */
837 const struct lp_build_tgsi_action
* action
,
838 struct lp_build_tgsi_context
* bld_base
,
839 struct lp_build_emit_data
* emit_data
)
841 LLVMValueRef cond
= lp_build_cmp(&bld_base
->base
, PIPE_FUNC_LESS
,
842 emit_data
->args
[0], bld_base
->base
.zero
);
843 emit_data
->output
[emit_data
->chan
] = lp_build_select(&bld_base
->base
,
844 cond
, emit_data
->args
[1], emit_data
->args
[2]);
847 /* TGSI_OPCODE_CND (CPU Only) */
850 const struct lp_build_tgsi_action
* action
,
851 struct lp_build_tgsi_context
* bld_base
,
852 struct lp_build_emit_data
* emit_data
)
854 LLVMValueRef half
, tmp
;
855 half
= lp_build_const_vec(bld_base
->base
.gallivm
, bld_base
->base
.type
, 0.5);
856 tmp
= lp_build_cmp(&bld_base
->base
, PIPE_FUNC_GREATER
,
857 emit_data
->args
[2], half
);
858 emit_data
->output
[emit_data
->chan
] = lp_build_select(&bld_base
->base
,
864 /* TGSI_OPCODE_COS (CPU Only) */
867 const struct lp_build_tgsi_action
* action
,
868 struct lp_build_tgsi_context
* bld_base
,
869 struct lp_build_emit_data
* emit_data
)
871 emit_data
->output
[emit_data
->chan
] = lp_build_cos(&bld_base
->base
,
875 /* TGSI_OPCODE_DIV (CPU Only) */
878 const struct lp_build_tgsi_action
* action
,
879 struct lp_build_tgsi_context
* bld_base
,
880 struct lp_build_emit_data
* emit_data
)
882 emit_data
->output
[emit_data
->chan
] = lp_build_div(&bld_base
->base
,
883 emit_data
->args
[0], emit_data
->args
[1]);
886 /* TGSI_OPCODE_EX2 (CPU Only) */
889 const struct lp_build_tgsi_action
* action
,
890 struct lp_build_tgsi_context
* bld_base
,
891 struct lp_build_emit_data
* emit_data
)
893 emit_data
->output
[emit_data
->chan
] = lp_build_exp2(&bld_base
->base
,
897 /* TGSI_OPCODE_EXP (CPU Only) */
900 const struct lp_build_tgsi_action
* action
,
901 struct lp_build_tgsi_context
* bld_base
,
902 struct lp_build_emit_data
* emit_data
)
904 lp_build_exp2_approx(&bld_base
->base
, emit_data
->args
[0],
905 &emit_data
->output
[TGSI_CHAN_X
],
906 &emit_data
->output
[TGSI_CHAN_Y
],
907 &emit_data
->output
[TGSI_CHAN_Z
]);
908 emit_data
->output
[TGSI_CHAN_W
] = bld_base
->base
.one
;
911 /* TGSI_OPCODE_FLR (CPU Only) */
915 const struct lp_build_tgsi_action
* action
,
916 struct lp_build_tgsi_context
* bld_base
,
917 struct lp_build_emit_data
* emit_data
)
919 emit_data
->output
[emit_data
->chan
] = lp_build_floor(&bld_base
->base
,
923 /* TGSI_OPCODE_LG2 (CPU Only) */
926 const struct lp_build_tgsi_action
* action
,
927 struct lp_build_tgsi_context
* bld_base
,
928 struct lp_build_emit_data
* emit_data
)
930 emit_data
->output
[emit_data
->chan
] = lp_build_log2(&bld_base
->base
,
934 /* TGSI_OPCODE_LOG (CPU Only) */
937 const struct lp_build_tgsi_action
* action
,
938 struct lp_build_tgsi_context
* bld_base
,
939 struct lp_build_emit_data
* emit_data
)
941 LLVMValueRef p_floor_log2
;
944 LLVMValueRef src0
= emit_data
->args
[0];
946 lp_build_log2_approx(&bld_base
->base
, src0
,
947 &p_exp
, &p_floor_log2
, &p_log2
);
949 emit_data
->output
[TGSI_CHAN_X
] = p_floor_log2
;
951 emit_data
->output
[TGSI_CHAN_Y
] = lp_build_emit_llvm_binary(bld_base
,
954 emit_data
->output
[TGSI_CHAN_Z
] = p_log2
;
956 emit_data
->output
[TGSI_CHAN_W
] = bld_base
->base
.one
;
960 /* TGSI_OPCODE_MAX (CPU Only) */
964 const struct lp_build_tgsi_action
* action
,
965 struct lp_build_tgsi_context
* bld_base
,
966 struct lp_build_emit_data
* emit_data
)
968 emit_data
->output
[emit_data
->chan
] = lp_build_max(&bld_base
->base
,
969 emit_data
->args
[0], emit_data
->args
[1]);
972 /* TGSI_OPCODE_MIN (CPU Only) */
975 const struct lp_build_tgsi_action
* action
,
976 struct lp_build_tgsi_context
* bld_base
,
977 struct lp_build_emit_data
* emit_data
)
979 emit_data
->output
[emit_data
->chan
] = lp_build_min(&bld_base
->base
,
980 emit_data
->args
[0], emit_data
->args
[1]);
983 /* TGSI_OPCODE_POW (CPU Only) */
986 const struct lp_build_tgsi_action
* action
,
987 struct lp_build_tgsi_context
* bld_base
,
988 struct lp_build_emit_data
* emit_data
)
990 emit_data
->output
[emit_data
->chan
] = lp_build_pow(&bld_base
->base
,
991 emit_data
->args
[0], emit_data
->args
[1]);
995 /* TGSI_OPCODE_RCP (CPU Only) */
999 const struct lp_build_tgsi_action
* action
,
1000 struct lp_build_tgsi_context
* bld_base
,
1001 struct lp_build_emit_data
* emit_data
)
1003 emit_data
->output
[emit_data
->chan
] = lp_build_rcp(&bld_base
->base
,
1004 emit_data
->args
[0]);
1007 /* Reciprical squareroot (CPU Only) */
1009 /* This is not the same as TGSI_OPCODE_RSQ, which requres the argument to be
1010 * greater than or equal to 0 */
1012 recip_sqrt_emit_cpu(
1013 const struct lp_build_tgsi_action
* action
,
1014 struct lp_build_tgsi_context
* bld_base
,
1015 struct lp_build_emit_data
* emit_data
)
1017 emit_data
->output
[emit_data
->chan
] = lp_build_rsqrt(&bld_base
->base
,
1018 emit_data
->args
[0]);
1021 /* TGSI_OPCODE_ROUND (CPU Only) */
1024 const struct lp_build_tgsi_action
* action
,
1025 struct lp_build_tgsi_context
* bld_base
,
1026 struct lp_build_emit_data
* emit_data
)
1028 emit_data
->output
[emit_data
->chan
] = lp_build_round(&bld_base
->base
,
1029 emit_data
->args
[0]);
1032 /* TGSI_OPCODE_SET Helper (CPU Only) */
1036 const struct lp_build_tgsi_action
* action
,
1037 struct lp_build_tgsi_context
* bld_base
,
1038 struct lp_build_emit_data
* emit_data
,
1041 LLVMValueRef cond
= lp_build_cmp(&bld_base
->base
, pipe_func
,
1042 emit_data
->args
[0], emit_data
->args
[1]);
1043 emit_data
->output
[emit_data
->chan
] = lp_build_select(&bld_base
->base
,
1046 bld_base
->base
.zero
);
1049 /* TGSI_OPCODE_SEQ (CPU Only) */
1053 const struct lp_build_tgsi_action
* action
,
1054 struct lp_build_tgsi_context
* bld_base
,
1055 struct lp_build_emit_data
* emit_data
)
1057 set_emit_cpu(action
, bld_base
, emit_data
, PIPE_FUNC_EQUAL
);
1060 /* TGSI_OPCODE_SGE (CPU Only) */
1063 const struct lp_build_tgsi_action
* action
,
1064 struct lp_build_tgsi_context
* bld_base
,
1065 struct lp_build_emit_data
* emit_data
)
1067 set_emit_cpu(action
, bld_base
, emit_data
, PIPE_FUNC_GEQUAL
);
1070 /* TGSI_OPCODE_SGT (CPU Only)*/
1074 const struct lp_build_tgsi_action
* action
,
1075 struct lp_build_tgsi_context
* bld_base
,
1076 struct lp_build_emit_data
* emit_data
)
1078 set_emit_cpu(action
, bld_base
, emit_data
, PIPE_FUNC_GREATER
);
1081 /* TGSI_OPCODE_SIN (CPU Only) */
1084 const struct lp_build_tgsi_action
* action
,
1085 struct lp_build_tgsi_context
* bld_base
,
1086 struct lp_build_emit_data
* emit_data
)
1088 emit_data
->output
[emit_data
->chan
] = lp_build_sin(&bld_base
->base
,
1089 emit_data
->args
[0]);
1092 /* TGSI_OPCODE_SLE (CPU Only) */
1095 const struct lp_build_tgsi_action
* action
,
1096 struct lp_build_tgsi_context
* bld_base
,
1097 struct lp_build_emit_data
* emit_data
)
1099 set_emit_cpu(action
, bld_base
, emit_data
, PIPE_FUNC_LEQUAL
);
1102 /* TGSI_OPCODE_SLT (CPU Only) */
1106 const struct lp_build_tgsi_action
* action
,
1107 struct lp_build_tgsi_context
* bld_base
,
1108 struct lp_build_emit_data
* emit_data
)
1110 set_emit_cpu(action
, bld_base
, emit_data
, PIPE_FUNC_LESS
);
1113 /* TGSI_OPCODE_SNE (CPU Only) */
1117 const struct lp_build_tgsi_action
* action
,
1118 struct lp_build_tgsi_context
* bld_base
,
1119 struct lp_build_emit_data
* emit_data
)
1121 set_emit_cpu(action
, bld_base
, emit_data
, PIPE_FUNC_NOTEQUAL
);
1124 /* TGSI_OPCODE_SSG (CPU Only) */
1128 const struct lp_build_tgsi_action
* action
,
1129 struct lp_build_tgsi_context
* bld_base
,
1130 struct lp_build_emit_data
* emit_data
)
1132 emit_data
->output
[emit_data
->chan
] = lp_build_sgn(&bld_base
->base
,
1133 emit_data
->args
[0]);
1136 /* TGSI_OPCODE_SUB (CPU Only) */
1140 const struct lp_build_tgsi_action
* action
,
1141 struct lp_build_tgsi_context
* bld_base
,
1142 struct lp_build_emit_data
* emit_data
)
1144 emit_data
->output
[emit_data
->chan
] = lp_build_sub(&bld_base
->base
,
1146 emit_data
->args
[1]);
1149 /* TGSI_OPCODE_TRUNC (CPU Only) */
1153 const struct lp_build_tgsi_action
* action
,
1154 struct lp_build_tgsi_context
* bld_base
,
1155 struct lp_build_emit_data
* emit_data
)
1157 emit_data
->output
[emit_data
->chan
] = lp_build_trunc(&bld_base
->base
,
1158 emit_data
->args
[0]);
1162 lp_set_default_actions_cpu(
1163 struct lp_build_tgsi_context
* bld_base
)
1165 lp_set_default_actions(bld_base
);
1166 bld_base
->op_actions
[TGSI_OPCODE_ABS
].emit
= abs_emit_cpu
;
1167 bld_base
->op_actions
[TGSI_OPCODE_ADD
].emit
= add_emit_cpu
;
1168 bld_base
->op_actions
[TGSI_OPCODE_ARL
].emit
= arl_emit_cpu
;
1169 bld_base
->op_actions
[TGSI_OPCODE_CEIL
].emit
= ceil_emit_cpu
;
1170 bld_base
->op_actions
[TGSI_OPCODE_CND
].emit
= cnd_emit_cpu
;
1171 bld_base
->op_actions
[TGSI_OPCODE_COS
].emit
= cos_emit_cpu
;
1172 bld_base
->op_actions
[TGSI_OPCODE_CMP
].emit
= cmp_emit_cpu
;
1173 bld_base
->op_actions
[TGSI_OPCODE_DIV
].emit
= div_emit_cpu
;
1174 bld_base
->op_actions
[TGSI_OPCODE_EX2
].emit
= ex2_emit_cpu
;
1175 bld_base
->op_actions
[TGSI_OPCODE_EXP
].emit
= exp_emit_cpu
;
1176 bld_base
->op_actions
[TGSI_OPCODE_FLR
].emit
= flr_emit_cpu
;
1177 bld_base
->op_actions
[TGSI_OPCODE_LG2
].emit
= lg2_emit_cpu
;
1178 bld_base
->op_actions
[TGSI_OPCODE_LOG
].emit
= log_emit_cpu
;
1179 bld_base
->op_actions
[TGSI_OPCODE_MAX
].emit
= max_emit_cpu
;
1180 bld_base
->op_actions
[TGSI_OPCODE_MIN
].emit
= min_emit_cpu
;
1181 bld_base
->op_actions
[TGSI_OPCODE_POW
].emit
= pow_emit_cpu
;
1182 bld_base
->op_actions
[TGSI_OPCODE_RCP
].emit
= rcp_emit_cpu
;
1183 bld_base
->op_actions
[TGSI_OPCODE_ROUND
].emit
= round_emit_cpu
;
1184 bld_base
->op_actions
[TGSI_OPCODE_SEQ
].emit
= seq_emit_cpu
;
1185 bld_base
->op_actions
[TGSI_OPCODE_SGE
].emit
= sge_emit_cpu
;
1186 bld_base
->op_actions
[TGSI_OPCODE_SGT
].emit
= sgt_emit_cpu
;
1187 bld_base
->op_actions
[TGSI_OPCODE_SIN
].emit
= sin_emit_cpu
;
1188 bld_base
->op_actions
[TGSI_OPCODE_SLE
].emit
= sle_emit_cpu
;
1189 bld_base
->op_actions
[TGSI_OPCODE_SLT
].emit
= slt_emit_cpu
;
1190 bld_base
->op_actions
[TGSI_OPCODE_SNE
].emit
= sne_emit_cpu
;
1191 bld_base
->op_actions
[TGSI_OPCODE_SSG
].emit
= ssg_emit_cpu
;
1192 bld_base
->op_actions
[TGSI_OPCODE_SUB
].emit
= sub_emit_cpu
;
1193 bld_base
->op_actions
[TGSI_OPCODE_TRUNC
].emit
= trunc_emit_cpu
;
1195 bld_base
->rsq_action
.emit
= recip_sqrt_emit_cpu
;