LLVMValueRef
lp_build_or(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
{
+ LLVMBuilderRef builder = bld->gallivm->builder;
const struct lp_type type = bld->type;
LLVMValueRef res;
/* can't do bitwise ops on floating-point values */
if (type.floating) {
- a = LLVMBuildBitCast(bld->builder, a, bld->int_vec_type, "");
- b = LLVMBuildBitCast(bld->builder, b, bld->int_vec_type, "");
+ a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
+ b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
}
- res = LLVMBuildOr(bld->builder, a, b, "");
+ res = LLVMBuildOr(builder, a, b, "");
if (type.floating) {
- res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+ res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
}
return res;
}
+/* bitwise XOR (a ^ b) */
+LLVMValueRef
+lp_build_xor(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
+{
+ LLVMBuilderRef builder = bld->gallivm->builder;
+ const struct lp_type type = bld->type;
+ LLVMValueRef res;
+
+ assert(lp_check_value(type, a));
+ assert(lp_check_value(type, b));
+
+ /* can't do bitwise ops on floating-point values */
+ if (type.floating) {
+ a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
+ b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
+ }
+
+ res = LLVMBuildXor(builder, a, b, "");
+
+ if (type.floating) {
+ res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
+ }
+
+ return res;
+}
/**
* Return (a & b)
LLVMValueRef
lp_build_and(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
{
+ LLVMBuilderRef builder = bld->gallivm->builder;
const struct lp_type type = bld->type;
LLVMValueRef res;
/* can't do bitwise ops on floating-point values */
if (type.floating) {
- a = LLVMBuildBitCast(bld->builder, a, bld->int_vec_type, "");
- b = LLVMBuildBitCast(bld->builder, b, bld->int_vec_type, "");
+ a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
+ b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
}
- res = LLVMBuildAnd(bld->builder, a, b, "");
+ res = LLVMBuildAnd(builder, a, b, "");
if (type.floating) {
- res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+ res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
}
return res;
LLVMValueRef
lp_build_andnot(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
{
+ LLVMBuilderRef builder = bld->gallivm->builder;
const struct lp_type type = bld->type;
LLVMValueRef res;
/* can't do bitwise ops on floating-point values */
if (type.floating) {
- a = LLVMBuildBitCast(bld->builder, a, bld->int_vec_type, "");
- b = LLVMBuildBitCast(bld->builder, b, bld->int_vec_type, "");
+ a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
+ b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
}
- res = LLVMBuildNot(bld->builder, b, "");
- res = LLVMBuildAnd(bld->builder, a, res, "");
+ res = LLVMBuildNot(builder, b, "");
+ res = LLVMBuildAnd(builder, a, res, "");
if (type.floating) {
- res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+ res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
}
return res;
}
+/* bitwise NOT */
+LLVMValueRef
+lp_build_not(struct lp_build_context *bld, LLVMValueRef a)
+{
+ LLVMBuilderRef builder = bld->gallivm->builder;
+ const struct lp_type type = bld->type;
+ LLVMValueRef res;
+
+ assert(lp_check_value(type, a));
+
+ if (type.floating) {
+ a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
+ }
+ res = LLVMBuildNot(builder, a, "");
+ if (type.floating) {
+ res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
+ }
+ return res;
+}
/**
* Shift left.
+ * Result is undefined if the shift count is not smaller than the type width.
*/
LLVMValueRef
lp_build_shl(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
{
+ LLVMBuilderRef builder = bld->gallivm->builder;
const struct lp_type type = bld->type;
LLVMValueRef res;
assert(lp_check_value(type, a));
assert(lp_check_value(type, b));
- res = LLVMBuildShl(bld->builder, a, b, "");
+ (void)type;
+
+ res = LLVMBuildShl(builder, a, b, "");
return res;
}
/**
* Shift right.
+ * Result is undefined if the shift count is not smaller than the type width.
*/
LLVMValueRef
lp_build_shr(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
{
+ LLVMBuilderRef builder = bld->gallivm->builder;
const struct lp_type type = bld->type;
LLVMValueRef res;
assert(lp_check_value(type, b));
if (type.sign) {
- res = LLVMBuildAShr(bld->builder, a, b, "");
+ res = LLVMBuildAShr(builder, a, b, "");
} else {
- res = LLVMBuildLShr(bld->builder, a, b, "");
+ res = LLVMBuildLShr(builder, a, b, "");
}
return res;
/**
* Shift left with immediate.
+ * The immediate shift count must be smaller than the type width.
*/
LLVMValueRef
lp_build_shl_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
{
- LLVMValueRef b = lp_build_const_int_vec(bld->type, imm);
- assert(imm <= bld->type.width);
+ LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm);
+ assert(imm < bld->type.width);
return lp_build_shl(bld, a, b);
}
/**
* Shift right with immediate.
+ * The immediate shift count must be smaller than the type width.
*/
LLVMValueRef
lp_build_shr_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
{
- LLVMValueRef b = lp_build_const_int_vec(bld->type, imm);
- assert(imm <= bld->type.width);
+ LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm);
+ assert(imm < bld->type.width);
return lp_build_shr(bld, a, b);
}