bld_base->uint_bld.vec_type, "");
}
-/* TGSI_OPCODE_CLAMP */
-static void
-clamp_emit(
- const struct lp_build_tgsi_action * action,
- struct lp_build_tgsi_context * bld_base,
- struct lp_build_emit_data * emit_data)
-{
- LLVMValueRef tmp;
- tmp = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_MAX,
- emit_data->args[0],
- emit_data->args[1]);
- emit_data->output[emit_data->chan] = lp_build_emit_llvm_binary(bld_base,
- TGSI_OPCODE_MIN, tmp, emit_data->args[2]);
-}
-
/* DP* Helper */
static void
dp2_emit /* emit */
};
-/* TGSI_OPCODE_DP2A */
-static void
-dp2a_fetch_args(
- struct lp_build_tgsi_context * bld_base,
- struct lp_build_emit_data * emit_data)
-{
- dp_fetch_args(bld_base, emit_data, 2);
- emit_data->args[5] = lp_build_emit_fetch(bld_base, emit_data->inst,
- 2, TGSI_CHAN_X);
-}
-
-static void
-dp2a_emit(
- const struct lp_build_tgsi_action * action,
- struct lp_build_tgsi_context * bld_base,
- struct lp_build_emit_data * emit_data)
-{
- LLVMValueRef tmp;
- tmp = lp_build_emit_llvm(bld_base, TGSI_OPCODE_DP2, emit_data);
- emit_data->output[emit_data->chan] = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_ADD,
- emit_data->args[5], tmp);
-}
-
-static struct lp_build_tgsi_action dp2a_action = {
- dp2a_fetch_args, /* fetch_args */
- dp2a_emit /* emit */
-};
-
/* TGSI_OPCODE_DP3 */
static void
dp3_fetch_args(
dp4_emit /* emit */
};
-/* TGSI_OPCODE_DPH */
-static void
-dph_fetch_args(
- struct lp_build_tgsi_context * bld_base,
- struct lp_build_emit_data * emit_data)
-{
- dp_fetch_args(bld_base, emit_data, 4);
- /* src0.w */
- emit_data->args[3] = bld_base->base.one;
-}
-
-const struct lp_build_tgsi_action dph_action = {
- dph_fetch_args, /* fetch_args */
- dp4_emit /* emit */
-};
-
/* TGSI_OPCODE_DST */
static void
dst_fetch_args(
TGSI_OPCODE_EX2, floor_x);
/* src0.x - floor( src0.x ) */
- emit_data->output[TGSI_CHAN_Y] = lp_build_emit_llvm_binary(bld_base,
- TGSI_OPCODE_SUB, emit_data->args[0] /* src0.x */, floor_x);
+ emit_data->output[TGSI_CHAN_Y] =
+ lp_build_sub(&bld_base->base, emit_data->args[0] /* src0.x */, floor_x);
/* 2 ^ src0.x */
emit_data->output[TGSI_CHAN_Z] = lp_build_emit_llvm_unary(bld_base,
LLVMValueRef tmp;
tmp = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_FLR,
emit_data->args[0]);
- emit_data->output[emit_data->chan] = lp_build_emit_llvm_binary(bld_base,
- TGSI_OPCODE_SUB, emit_data->args[0], tmp);
+ emit_data->output[emit_data->chan] =
+ lp_build_sub(&bld_base->base, emit_data->args[0], tmp);
}
/* TGSI_OPCODE_KILL_IF */
LLVMValueRef abs_x, log_abs_x, flr_log_abs_x, ex2_flr_log_abs_x;
/* abs( src0.x) */
- abs_x = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_ABS,
- emit_data->args[0] /* src0.x */);
+ abs_x = lp_build_abs(&bld_base->base, emit_data->args[0] /* src0.x */);
/* log( abs( src0.x ) ) */
log_abs_x = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_LG2,
sqrt_emit /* emit */
};
-/* TGSI_OPCODE_SCS */
-static void
-scs_emit(
- const struct lp_build_tgsi_action * action,
- struct lp_build_tgsi_context * bld_base,
- struct lp_build_emit_data * emit_data)
-{
- /* dst.x */
- emit_data->output[TGSI_CHAN_X] = lp_build_emit_llvm_unary(bld_base,
- TGSI_OPCODE_COS, emit_data->args[0]);
- /* dst.y */
- emit_data->output[TGSI_CHAN_Y] = lp_build_emit_llvm_unary(bld_base,
- TGSI_OPCODE_SIN, emit_data->args[0]);
- /* dst.z */
- emit_data->output[TGSI_CHAN_Z] = bld_base->base.zero;
-
- /* dst.w */
- emit_data->output[TGSI_CHAN_W] = bld_base->base.one;
-}
-
-const struct lp_build_tgsi_action scs_action = {
- scalar_unary_fetch_args, /* fetch_args */
- scs_emit /* emit */
-};
-
-/* TGSI_OPCODE_SUB */
-static void
-sub_emit(
- const struct lp_build_tgsi_action * action,
- struct lp_build_tgsi_context * bld_base,
- struct lp_build_emit_data * emit_data)
-{
- emit_data->output[emit_data->chan] =
- LLVMBuildFSub(bld_base->base.gallivm->builder,
- emit_data->args[0],
- emit_data->args[1], "");
-}
-
/* TGSI_OPCODE_F2U */
static void
f2u_emit(
struct lp_build_tgsi_context * bld_base,
struct lp_build_emit_data * emit_data)
{
- LLVMBuilderRef builder = bld_base->base.gallivm->builder;
struct lp_build_context *int_bld = &bld_base->int_bld;
- struct lp_type type = int_bld->type;
- LLVMValueRef src0, src1;
- LLVMValueRef dst64;
- LLVMTypeRef typeRef;
-
- assert(type.width == 32);
- type.width = 64;
- typeRef = lp_build_vec_type(bld_base->base.gallivm, type);
- src0 = LLVMBuildSExt(builder, emit_data->args[0], typeRef, "");
- src1 = LLVMBuildSExt(builder, emit_data->args[1], typeRef, "");
- dst64 = LLVMBuildMul(builder, src0, src1, "");
- dst64 = LLVMBuildAShr(
- builder, dst64,
- lp_build_const_vec(bld_base->base.gallivm, type, 32), "");
- type.width = 32;
- typeRef = lp_build_vec_type(bld_base->base.gallivm, type);
- emit_data->output[emit_data->chan] =
- LLVMBuildTrunc(builder, dst64, typeRef, "");
+ LLVMValueRef hi_bits;
+
+ assert(int_bld->type.width == 32);
+
+ /* low result bits are tossed away */
+ lp_build_mul_32_lohi(int_bld, emit_data->args[0],
+ emit_data->args[1], &hi_bits);
+ emit_data->output[emit_data->chan] = hi_bits;
+}
+
+static void
+imul_hi_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ struct lp_build_context *int_bld = &bld_base->int_bld;
+ LLVMValueRef hi_bits;
+
+ assert(int_bld->type.width == 32);
+
+ /* low result bits are tossed away */
+ lp_build_mul_32_lohi_cpu(int_bld, emit_data->args[0],
+ emit_data->args[1], &hi_bits);
+ emit_data->output[emit_data->chan] = hi_bits;
}
/* TGSI_OPCODE_UMUL_HI */
struct lp_build_tgsi_context * bld_base,
struct lp_build_emit_data * emit_data)
{
- LLVMBuilderRef builder = bld_base->base.gallivm->builder;
struct lp_build_context *uint_bld = &bld_base->uint_bld;
- struct lp_type type = uint_bld->type;
- LLVMValueRef src0, src1;
- LLVMValueRef dst64;
- LLVMTypeRef typeRef;
-
- assert(type.width == 32);
- type.width = 64;
- typeRef = lp_build_vec_type(bld_base->base.gallivm, type);
- src0 = LLVMBuildZExt(builder, emit_data->args[0], typeRef, "");
- src1 = LLVMBuildZExt(builder, emit_data->args[1], typeRef, "");
- dst64 = LLVMBuildMul(builder, src0, src1, "");
- dst64 = LLVMBuildLShr(
- builder, dst64,
- lp_build_const_vec(bld_base->base.gallivm, type, 32), "");
- type.width = 32;
- typeRef = lp_build_vec_type(bld_base->base.gallivm, type);
- emit_data->output[emit_data->chan] =
- LLVMBuildTrunc(builder, dst64, typeRef, "");
+ LLVMValueRef hi_bits;
+
+ assert(uint_bld->type.width == 32);
+
+ /* low result bits are tossed away */
+ lp_build_mul_32_lohi(uint_bld, emit_data->args[0],
+ emit_data->args[1], &hi_bits);
+ emit_data->output[emit_data->chan] = hi_bits;
+}
+
+static void
+umul_hi_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ struct lp_build_context *uint_bld = &bld_base->uint_bld;
+ LLVMValueRef hi_bits;
+
+ assert(uint_bld->type.width == 32);
+
+ /* low result bits are tossed away */
+ lp_build_mul_32_lohi_cpu(uint_bld, emit_data->args[0],
+ emit_data->args[1], &hi_bits);
+ emit_data->output[emit_data->chan] = hi_bits;
}
/* TGSI_OPCODE_MAX */
emit_data->args[1], emit_data->args[0], "");
}
-/* TGSI_OPCODE_XPD */
-
-static void
-xpd_fetch_args(
- struct lp_build_tgsi_context * bld_base,
- struct lp_build_emit_data * emit_data)
-{
- dp_fetch_args(bld_base, emit_data, 3);
-}
-
-/**
- * (a * b) - (c * d)
- */
-static LLVMValueRef
-xpd_helper(
- struct lp_build_tgsi_context * bld_base,
- LLVMValueRef a,
- LLVMValueRef b,
- LLVMValueRef c,
- LLVMValueRef d)
-{
- LLVMValueRef tmp0, tmp1;
-
- tmp0 = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_MUL, a, b);
- tmp1 = lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_MUL, c, d);
-
- return lp_build_emit_llvm_binary(bld_base, TGSI_OPCODE_SUB, tmp0, tmp1);
-}
-
-static void
-xpd_emit(
- const struct lp_build_tgsi_action * action,
- struct lp_build_tgsi_context * bld_base,
- struct lp_build_emit_data * emit_data)
-{
- emit_data->output[TGSI_CHAN_X] = xpd_helper(bld_base,
- emit_data->args[1] /* src0.y */, emit_data->args[5] /* src1.z */,
- emit_data->args[4] /* src1.y */, emit_data->args[2] /* src0.z */);
-
- emit_data->output[TGSI_CHAN_Y] = xpd_helper(bld_base,
- emit_data->args[2] /* src0.z */, emit_data->args[3] /* src1.x */,
- emit_data->args[5] /* src1.z */, emit_data->args[0] /* src0.x */);
-
- emit_data->output[TGSI_CHAN_Z] = xpd_helper(bld_base,
- emit_data->args[0] /* src0.x */, emit_data->args[4] /* src1.y */,
- emit_data->args[3] /* src1.x */, emit_data->args[1] /* src0.y */);
-
- emit_data->output[TGSI_CHAN_W] = bld_base->base.one;
-}
-
-const struct lp_build_tgsi_action xpd_action = {
- xpd_fetch_args, /* fetch_args */
- xpd_emit /* emit */
-};
-
/* TGSI_OPCODE_D2F */
static void
d2f_emit(
emit_data->args[0], tmp, "");
}
+static void
+u64mul_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] = lp_build_mul(&bld_base->uint64_bld,
+ emit_data->args[0], emit_data->args[1]);
+}
+
+static void
+u64mod_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+ LLVMValueRef div_mask = lp_build_cmp(&bld_base->uint64_bld,
+ PIPE_FUNC_EQUAL, emit_data->args[1],
+ bld_base->uint64_bld.zero);
+ /* We want to make sure that we never divide/mod by zero to not
+ * generate sigfpe. We don't want to crash just because the
+ * shader is doing something weird. */
+ LLVMValueRef divisor = LLVMBuildOr(builder,
+ div_mask,
+ emit_data->args[1], "");
+ LLVMValueRef result = lp_build_mod(&bld_base->uint64_bld,
+ emit_data->args[0], divisor);
+ /* umod by zero doesn't have a guaranteed return value chose -1 for now. */
+ emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
+ div_mask,
+ result, "");
+}
+
+static void
+i64mod_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+ LLVMValueRef div_mask = lp_build_cmp(&bld_base->uint64_bld,
+ PIPE_FUNC_EQUAL, emit_data->args[1],
+ bld_base->uint64_bld.zero);
+ /* We want to make sure that we never divide/mod by zero to not
+ * generate sigfpe. We don't want to crash just because the
+ * shader is doing something weird. */
+ LLVMValueRef divisor = LLVMBuildOr(builder,
+ div_mask,
+ emit_data->args[1], "");
+ LLVMValueRef result = lp_build_mod(&bld_base->int64_bld,
+ emit_data->args[0], divisor);
+ /* umod by zero doesn't have a guaranteed return value chose -1 for now. */
+ emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
+ div_mask,
+ result, "");
+}
+
+static void
+u64div_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+
+ LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+ LLVMValueRef div_mask = lp_build_cmp(&bld_base->uint64_bld,
+ PIPE_FUNC_EQUAL, emit_data->args[1],
+ bld_base->uint64_bld.zero);
+ /* We want to make sure that we never divide/mod by zero to not
+ * generate sigfpe. We don't want to crash just because the
+ * shader is doing something weird. */
+ LLVMValueRef divisor = LLVMBuildOr(builder,
+ div_mask,
+ emit_data->args[1], "");
+ LLVMValueRef result = LLVMBuildUDiv(builder,
+ emit_data->args[0], divisor, "");
+ /* udiv by zero is guaranteed to return 0xffffffff at least with d3d10 */
+ emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
+ div_mask,
+ result, "");
+}
+
+static void
+i64div_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+
+ LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+ LLVMValueRef div_mask = lp_build_cmp(&bld_base->int64_bld,
+ PIPE_FUNC_EQUAL, emit_data->args[1],
+ bld_base->int64_bld.zero);
+ /* We want to make sure that we never divide/mod by zero to not
+ * generate sigfpe. We don't want to crash just because the
+ * shader is doing something weird. */
+ LLVMValueRef divisor = LLVMBuildOr(builder,
+ div_mask,
+ emit_data->args[1], "");
+ LLVMValueRef result = LLVMBuildSDiv(builder,
+ emit_data->args[0], divisor, "");
+ /* udiv by zero is guaranteed to return 0xffffffff at least with d3d10 */
+ emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
+ div_mask,
+ result, "");
+}
+
+static void
+f2u64_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] =
+ LLVMBuildFPToUI(bld_base->base.gallivm->builder,
+ emit_data->args[0],
+ bld_base->uint64_bld.vec_type, "");
+}
+
+static void
+f2i64_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] =
+ LLVMBuildFPToSI(bld_base->base.gallivm->builder,
+ emit_data->args[0],
+ bld_base->int64_bld.vec_type, "");
+}
+
+static void
+u2i64_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] =
+ LLVMBuildZExt(bld_base->base.gallivm->builder,
+ emit_data->args[0],
+ bld_base->uint64_bld.vec_type, "");
+}
+
+static void
+i2i64_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] =
+ LLVMBuildSExt(bld_base->base.gallivm->builder,
+ emit_data->args[0],
+ bld_base->int64_bld.vec_type, "");
+}
+
+static void
+i642f_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] =
+ LLVMBuildSIToFP(bld_base->base.gallivm->builder,
+ emit_data->args[0],
+ bld_base->base.vec_type, "");
+}
+
+static void
+u642f_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] =
+ LLVMBuildUIToFP(bld_base->base.gallivm->builder,
+ emit_data->args[0],
+ bld_base->base.vec_type, "");
+}
+
+static void
+i642d_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] =
+ LLVMBuildSIToFP(bld_base->base.gallivm->builder,
+ emit_data->args[0],
+ bld_base->dbl_bld.vec_type, "");
+}
+
+static void
+u642d_emit(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] =
+ LLVMBuildUIToFP(bld_base->base.gallivm->builder,
+ emit_data->args[0],
+ bld_base->dbl_bld.vec_type, "");
+}
+
void
lp_set_default_actions(struct lp_build_tgsi_context * bld_base)
{
bld_base->op_actions[TGSI_OPCODE_DP2] = dp2_action;
bld_base->op_actions[TGSI_OPCODE_DP3] = dp3_action;
bld_base->op_actions[TGSI_OPCODE_DP4] = dp4_action;
- bld_base->op_actions[TGSI_OPCODE_DP2A] = dp2a_action;
- bld_base->op_actions[TGSI_OPCODE_DPH] = dph_action;
bld_base->op_actions[TGSI_OPCODE_DST] = dst_action;
bld_base->op_actions[TGSI_OPCODE_EXP] = exp_action;
bld_base->op_actions[TGSI_OPCODE_LIT] = lit_action;
bld_base->op_actions[TGSI_OPCODE_RSQ] = rsq_action;
bld_base->op_actions[TGSI_OPCODE_SQRT] = sqrt_action;
bld_base->op_actions[TGSI_OPCODE_POW] = pow_action;
- bld_base->op_actions[TGSI_OPCODE_SCS] = scs_action;
bld_base->op_actions[TGSI_OPCODE_UP2H] = up2h_action;
- bld_base->op_actions[TGSI_OPCODE_XPD] = xpd_action;
- bld_base->op_actions[TGSI_OPCODE_BREAKC].fetch_args = scalar_unary_fetch_args;
bld_base->op_actions[TGSI_OPCODE_SWITCH].fetch_args = scalar_unary_fetch_args;
bld_base->op_actions[TGSI_OPCODE_CASE].fetch_args = scalar_unary_fetch_args;
bld_base->op_actions[TGSI_OPCODE_COS].fetch_args = scalar_unary_fetch_args;
bld_base->op_actions[TGSI_OPCODE_ADD].emit = add_emit;
bld_base->op_actions[TGSI_OPCODE_ARR].emit = arr_emit;
- bld_base->op_actions[TGSI_OPCODE_CLAMP].emit = clamp_emit;
bld_base->op_actions[TGSI_OPCODE_END].emit = end_emit;
bld_base->op_actions[TGSI_OPCODE_FRC].emit = frc_emit;
bld_base->op_actions[TGSI_OPCODE_LRP].emit = lrp_emit;
bld_base->op_actions[TGSI_OPCODE_MUL].emit = mul_emit;
bld_base->op_actions[TGSI_OPCODE_DIV].emit = fdiv_emit;
bld_base->op_actions[TGSI_OPCODE_RCP].emit = rcp_emit;
- bld_base->op_actions[TGSI_OPCODE_SUB].emit = sub_emit;
bld_base->op_actions[TGSI_OPCODE_UARL].emit = mov_emit;
bld_base->op_actions[TGSI_OPCODE_F2U].emit = f2u_emit;
bld_base->op_actions[TGSI_OPCODE_DMAX].emit = fmax_emit;
bld_base->op_actions[TGSI_OPCODE_DMIN].emit = fmin_emit;
bld_base->op_actions[TGSI_OPCODE_DMUL].emit = mul_emit;
+ bld_base->op_actions[TGSI_OPCODE_DDIV].emit = fdiv_emit;
bld_base->op_actions[TGSI_OPCODE_D2F].emit = d2f_emit;
bld_base->op_actions[TGSI_OPCODE_D2I].emit = d2i_emit;
bld_base->op_actions[TGSI_OPCODE_DRCP].emit = drcp_emit;
bld_base->op_actions[TGSI_OPCODE_DFRAC].emit = dfrac_emit;
+ bld_base->op_actions[TGSI_OPCODE_U64MUL].emit = u64mul_emit;
+
+ bld_base->op_actions[TGSI_OPCODE_F2I64].emit = f2i64_emit;
+ bld_base->op_actions[TGSI_OPCODE_F2U64].emit = f2u64_emit;
+
+ bld_base->op_actions[TGSI_OPCODE_D2I64].emit = f2i64_emit;
+ bld_base->op_actions[TGSI_OPCODE_D2U64].emit = f2u64_emit;
+
+ bld_base->op_actions[TGSI_OPCODE_I2I64].emit = i2i64_emit;
+ bld_base->op_actions[TGSI_OPCODE_U2I64].emit = u2i64_emit;
+
+ bld_base->op_actions[TGSI_OPCODE_I642F].emit = i642f_emit;
+ bld_base->op_actions[TGSI_OPCODE_U642F].emit = u642f_emit;
+
+ bld_base->op_actions[TGSI_OPCODE_I642F].emit = i642f_emit;
+ bld_base->op_actions[TGSI_OPCODE_U642F].emit = u642f_emit;
+
+ bld_base->op_actions[TGSI_OPCODE_I642D].emit = i642d_emit;
+ bld_base->op_actions[TGSI_OPCODE_U642D].emit = u642d_emit;
+
}
/* CPU Only default actions */
* intrinsics.
*/
-/* TGSI_OPCODE_ABS (CPU Only)*/
-
-static void
-abs_emit_cpu(
- const struct lp_build_tgsi_action * action,
- struct lp_build_tgsi_context * bld_base,
- struct lp_build_emit_data * emit_data)
-{
- emit_data->output[emit_data->chan] = lp_build_abs(&bld_base->base,
- emit_data->args[0]);
-}
-
/* TGSI_OPCODE_ADD (CPU Only) */
static void
add_emit_cpu(
}
+/* TGSI_OPCODE_MAD (CPU Only) */
+
+static void
+mad_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] =
+ lp_build_mad(&bld_base->base,
+ emit_data->args[0], emit_data->args[1], emit_data->args[2]);
+}
+
/* TGSI_OPCODE_MAX (CPU Only) */
static void
emit_data->args[0]);
}
-/* TGSI_OPCODE_SUB (CPU Only) */
-
-static void
-sub_emit_cpu(
- const struct lp_build_tgsi_action * action,
- struct lp_build_tgsi_context * bld_base,
- struct lp_build_emit_data * emit_data)
-{
- emit_data->output[emit_data->chan] = lp_build_sub(&bld_base->base,
- emit_data->args[0],
- emit_data->args[1]);
-}
-
/* TGSI_OPCODE_TRUNC (CPU Only) */
static void
emit_data->args[0]);
}
+static void
+i64abs_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] = lp_build_abs(&bld_base->int64_bld,
+ emit_data->args[0]);
+}
+
+static void
+i64ssg_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] = lp_build_sgn(&bld_base->int64_bld,
+ emit_data->args[0]);
+}
+
+static void
+i64neg_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] = lp_build_sub(&bld_base->int64_bld,
+ bld_base->int64_bld.zero,
+ emit_data->args[0]);
+}
+
+static void
+u64set_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data,
+ unsigned pipe_func)
+{
+ LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+ LLVMValueRef cond = lp_build_cmp(&bld_base->uint64_bld, pipe_func,
+ emit_data->args[0], emit_data->args[1]);
+ /* arguments were 64 bit but store as 32 bit */
+ cond = LLVMBuildTrunc(builder, cond, bld_base->int_bld.int_vec_type, "");
+ emit_data->output[emit_data->chan] = cond;
+}
+
+static void
+u64seq_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ u64set_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_EQUAL);
+}
+
+static void
+u64sne_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ u64set_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_NOTEQUAL);
+}
+
+static void
+u64slt_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ u64set_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_LESS);
+}
+
+static void
+u64sge_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ u64set_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_GEQUAL);
+}
+
+static void
+i64set_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data,
+ unsigned pipe_func)
+{
+ LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+ LLVMValueRef cond = lp_build_cmp(&bld_base->int64_bld, pipe_func,
+ emit_data->args[0], emit_data->args[1]);
+ /* arguments were 64 bit but store as 32 bit */
+ cond = LLVMBuildTrunc(builder, cond, bld_base->int_bld.int_vec_type, "");
+ emit_data->output[emit_data->chan] = cond;
+}
+
+static void
+i64slt_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ i64set_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_LESS);
+}
+
+static void
+i64sge_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ i64set_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_GEQUAL);
+}
+
+static void
+u64max_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] = lp_build_max(&bld_base->uint64_bld,
+ emit_data->args[0], emit_data->args[1]);
+}
+
+static void
+u64min_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] = lp_build_min(&bld_base->uint64_bld,
+ emit_data->args[0], emit_data->args[1]);
+}
+
+static void
+i64max_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] = lp_build_max(&bld_base->int64_bld,
+ emit_data->args[0], emit_data->args[1]);
+}
+
+static void
+i64min_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] = lp_build_min(&bld_base->int64_bld,
+ emit_data->args[0], emit_data->args[1]);
+}
+
+static void
+u64add_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ emit_data->output[emit_data->chan] = lp_build_add(&bld_base->uint64_bld,
+ emit_data->args[0], emit_data->args[1]);
+}
+
+static void
+u64shl_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ struct lp_build_context *uint_bld = &bld_base->uint64_bld;
+ LLVMValueRef mask = lp_build_const_vec(uint_bld->gallivm, uint_bld->type,
+ uint_bld->type.width - 1);
+ LLVMValueRef masked_count = lp_build_and(uint_bld, emit_data->args[1], mask);
+ emit_data->output[emit_data->chan] = lp_build_shl(uint_bld, emit_data->args[0],
+ masked_count);
+}
+
+static void
+i64shr_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ struct lp_build_context *int_bld = &bld_base->int64_bld;
+ LLVMValueRef mask = lp_build_const_vec(int_bld->gallivm, int_bld->type,
+ int_bld->type.width - 1);
+ LLVMValueRef masked_count = lp_build_and(int_bld, emit_data->args[1], mask);
+ emit_data->output[emit_data->chan] = lp_build_shr(int_bld, emit_data->args[0],
+ masked_count);
+}
+
+static void
+u64shr_emit_cpu(
+ const struct lp_build_tgsi_action * action,
+ struct lp_build_tgsi_context * bld_base,
+ struct lp_build_emit_data * emit_data)
+{
+ struct lp_build_context *uint_bld = &bld_base->uint64_bld;
+ LLVMValueRef mask = lp_build_const_vec(uint_bld->gallivm, uint_bld->type,
+ uint_bld->type.width - 1);
+ LLVMValueRef masked_count = lp_build_and(uint_bld, emit_data->args[1], mask);
+ emit_data->output[emit_data->chan] = lp_build_shr(uint_bld, emit_data->args[0],
+ masked_count);
+}
+
void
lp_set_default_actions_cpu(
struct lp_build_tgsi_context * bld_base)
{
lp_set_default_actions(bld_base);
- bld_base->op_actions[TGSI_OPCODE_ABS].emit = abs_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_ADD].emit = add_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_AND].emit = and_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_ARL].emit = arl_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_ISHR].emit = ishr_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_ISLT].emit = islt_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_ISSG].emit = issg_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_IMUL_HI].emit = imul_hi_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_UMUL_HI].emit = umul_hi_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_LG2].emit = lg2_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_LOG].emit = log_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_MAD].emit = mad_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_MAX].emit = max_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_MIN].emit = min_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_MOD].emit = mod_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_SLT].emit = slt_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_SNE].emit = sne_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_SSG].emit = ssg_emit_cpu;
- bld_base->op_actions[TGSI_OPCODE_SUB].emit = sub_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_TRUNC].emit = trunc_emit_cpu;
bld_base->rsq_action.emit = recip_sqrt_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_DRSQ].emit = drecip_sqrt_emit_cpu;
bld_base->op_actions[TGSI_OPCODE_DSQRT].emit = dsqrt_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_I64ABS].emit = i64abs_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_I64SSG].emit = i64ssg_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_I64NEG].emit = i64neg_emit_cpu;
+
+ bld_base->op_actions[TGSI_OPCODE_U64SEQ].emit = u64seq_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_U64SNE].emit = u64sne_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_U64SLT].emit = u64slt_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_U64SGE].emit = u64sge_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_I64SLT].emit = i64slt_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_I64SGE].emit = i64sge_emit_cpu;
+
+ bld_base->op_actions[TGSI_OPCODE_U64MIN].emit = u64min_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_U64MAX].emit = u64max_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_I64MIN].emit = i64min_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_I64MAX].emit = i64max_emit_cpu;
+
+ bld_base->op_actions[TGSI_OPCODE_U64ADD].emit = u64add_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_U64MOD].emit = u64mod_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_I64MOD].emit = i64mod_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_U64DIV].emit = u64div_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_I64DIV].emit = i64div_emit_cpu;
+
+ bld_base->op_actions[TGSI_OPCODE_U64SHL].emit = u64shl_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_I64SHR].emit = i64shr_emit_cpu;
+ bld_base->op_actions[TGSI_OPCODE_U64SHR].emit = u64shr_emit_cpu;
}