llvmpipe: refactor lp_build_cmp() to use lp_build_compare()

This commit is contained in:
Brian Paul 2009-12-16 12:32:45 -07:00
parent cdbcd96fdf
commit 2297bc9233
2 changed files with 56 additions and 33 deletions

View file

@ -42,16 +42,16 @@
/**
* Build code to compare two values 'a' and 'b' using the given func.
* \parm func one of PIPE_FUNC_x
* Build code to compare two values 'a' and 'b' of 'type' using the given func.
* \param func one of PIPE_FUNC_x
*/
LLVMValueRef
lp_build_cmp(struct lp_build_context *bld,
unsigned func,
LLVMValueRef a,
LLVMValueRef b)
lp_build_compare(LLVMBuilderRef builder,
const struct lp_type type,
unsigned func,
LLVMValueRef a,
LLVMValueRef b)
{
const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
LLVMValueRef zeros = LLVMConstNull(int_vec_type);
@ -104,7 +104,7 @@ lp_build_cmp(struct lp_build_context *bld,
break;
default:
assert(0);
return bld->undef;
return lp_build_undef(type);
}
if(swap) {
@ -117,11 +117,11 @@ lp_build_cmp(struct lp_build_context *bld,
}
args[2] = LLVMConstInt(LLVMInt8Type(), cc, 0);
res = lp_build_intrinsic(bld->builder,
res = lp_build_intrinsic(builder,
"llvm.x86.sse.cmp.ps",
vec_type,
args, 3);
res = LLVMBuildBitCast(bld->builder, res, int_vec_type, "");
res = LLVMBuildBitCast(builder, res, int_vec_type, "");
return res;
}
else if(util_cpu_caps.has_sse2) {
@ -161,7 +161,7 @@ lp_build_cmp(struct lp_build_context *bld,
break;
default:
assert(0);
return bld->undef;
return lp_build_undef(type);
}
/* There are no signed byte and unsigned word/dword comparison
@ -171,8 +171,8 @@ lp_build_cmp(struct lp_build_context *bld,
((type.width == 8 && type.sign) ||
(type.width != 8 && !type.sign))) {
LLVMValueRef msb = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
a = LLVMBuildXor(bld->builder, a, msb, "");
b = LLVMBuildXor(bld->builder, b, msb, "");
a = LLVMBuildXor(builder, a, msb, "");
b = LLVMBuildXor(builder, b, msb, "");
}
if(table[func].swap) {
@ -185,14 +185,14 @@ lp_build_cmp(struct lp_build_context *bld,
}
if(table[func].eq)
res = lp_build_intrinsic(bld->builder, pcmpeq, vec_type, args, 2);
res = lp_build_intrinsic(builder, pcmpeq, vec_type, args, 2);
else if (table[func].gt)
res = lp_build_intrinsic(bld->builder, pcmpgt, vec_type, args, 2);
res = lp_build_intrinsic(builder, pcmpgt, vec_type, args, 2);
else
res = LLVMConstNull(vec_type);
if(table[func].not)
res = LLVMBuildNot(bld->builder, res, "");
res = LLVMBuildNot(builder, res, "");
return res;
}
@ -228,28 +228,28 @@ lp_build_cmp(struct lp_build_context *bld,
break;
default:
assert(0);
return bld->undef;
return lp_build_undef(type);
}
#if 0
/* XXX: Although valid IR, no LLVM target currently support this */
cond = LLVMBuildFCmp(bld->builder, op, a, b, "");
res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
cond = LLVMBuildFCmp(builder, op, a, b, "");
res = LLVMBuildSelect(builder, cond, ones, zeros, "");
#else
debug_printf("%s: warning: using slow element-wise vector comparison\n",
__FUNCTION__);
res = LLVMGetUndef(int_vec_type);
for(i = 0; i < type.length; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
cond = LLVMBuildFCmp(bld->builder, op,
LLVMBuildExtractElement(bld->builder, a, index, ""),
LLVMBuildExtractElement(bld->builder, b, index, ""),
cond = LLVMBuildFCmp(builder, op,
LLVMBuildExtractElement(builder, a, index, ""),
LLVMBuildExtractElement(builder, b, index, ""),
"");
cond = LLVMBuildSelect(bld->builder, cond,
cond = LLVMBuildSelect(builder, cond,
LLVMConstExtractElement(ones, index),
LLVMConstExtractElement(zeros, index),
"");
res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
res = LLVMBuildInsertElement(builder, res, cond, index, "");
}
#endif
}
@ -276,28 +276,28 @@ lp_build_cmp(struct lp_build_context *bld,
break;
default:
assert(0);
return bld->undef;
return lp_build_undef(type);
}
#if 0
/* XXX: Although valid IR, no LLVM target currently support this */
cond = LLVMBuildICmp(bld->builder, op, a, b, "");
res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
cond = LLVMBuildICmp(builder, op, a, b, "");
res = LLVMBuildSelect(builder, cond, ones, zeros, "");
#else
debug_printf("%s: warning: using slow element-wise vector comparison\n",
debug_printf("%s: warning: using slow element-wise int vector comparison\n",
__FUNCTION__);
res = LLVMGetUndef(int_vec_type);
for(i = 0; i < type.length; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
cond = LLVMBuildICmp(bld->builder, op,
LLVMBuildExtractElement(bld->builder, a, index, ""),
LLVMBuildExtractElement(bld->builder, b, index, ""),
cond = LLVMBuildICmp(builder, op,
LLVMBuildExtractElement(builder, a, index, ""),
LLVMBuildExtractElement(builder, b, index, ""),
"");
cond = LLVMBuildSelect(bld->builder, cond,
cond = LLVMBuildSelect(builder, cond,
LLVMConstExtractElement(ones, index),
LLVMConstExtractElement(zeros, index),
"");
res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
res = LLVMBuildInsertElement(builder, res, cond, index, "");
}
#endif
}
@ -306,6 +306,21 @@ lp_build_cmp(struct lp_build_context *bld,
}
/**
* Build code to compare two values 'a' and 'b' using the given func.
* \param func one of PIPE_FUNC_x
*/
LLVMValueRef
lp_build_cmp(struct lp_build_context *bld,
unsigned func,
LLVMValueRef a,
LLVMValueRef b)
{
return lp_build_compare(bld->builder, bld->type, func, a, b);
}
LLVMValueRef
lp_build_select(struct lp_build_context *bld,
LLVMValueRef mask,

View file

@ -46,6 +46,14 @@ struct lp_type type;
struct lp_build_context;
LLVMValueRef
lp_build_compare(LLVMBuilderRef builder,
const struct lp_type type,
unsigned func,
LLVMValueRef a,
LLVMValueRef b);
/**
* @param func is one of PIPE_FUNC_xxx
*/