mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 02:28:10 +02:00
llvmpipe: Generate instrinsics for integer comparisons.
It is a little messy, given the available instrucions form SIMD integer comparisons is rather limited.
This commit is contained in:
parent
89146cd48d
commit
d07b038366
1 changed files with 71 additions and 0 deletions
|
|
@ -107,6 +107,77 @@ lp_build_cmp(struct lp_build_context *bld,
|
|||
res = LLVMBuildBitCast(bld->builder, res, int_vec_type, "");
|
||||
return res;
|
||||
}
|
||||
else {
|
||||
static const struct {
|
||||
unsigned swap:1;
|
||||
unsigned eq:1;
|
||||
unsigned gt:1;
|
||||
unsigned not:1;
|
||||
} table[] = {
|
||||
{0, 0, 0, 1}, /* PIPE_FUNC_NEVER */
|
||||
{1, 0, 1, 0}, /* PIPE_FUNC_LESS */
|
||||
{0, 1, 0, 0}, /* PIPE_FUNC_EQUAL */
|
||||
{0, 0, 1, 1}, /* PIPE_FUNC_LEQUAL */
|
||||
{0, 0, 1, 0}, /* PIPE_FUNC_GREATER */
|
||||
{0, 1, 0, 1}, /* PIPE_FUNC_NOTEQUAL */
|
||||
{1, 0, 1, 1}, /* PIPE_FUNC_GEQUAL */
|
||||
{0, 0, 0, 0} /* PIPE_FUNC_ALWAYS */
|
||||
};
|
||||
const char *pcmpeq;
|
||||
const char *pcmpgt;
|
||||
LLVMValueRef args[2];
|
||||
LLVMValueRef res;
|
||||
|
||||
switch (type.width) {
|
||||
case 8:
|
||||
pcmpeq = "llvm.x86.sse2.pcmpeq.b";
|
||||
pcmpgt = "llvm.x86.sse2.pcmpgt.b";
|
||||
break;
|
||||
case 16:
|
||||
pcmpeq = "llvm.x86.sse2.pcmpeq.w";
|
||||
pcmpgt = "llvm.x86.sse2.pcmpgt.w";
|
||||
break;
|
||||
case 32:
|
||||
pcmpeq = "llvm.x86.sse2.pcmpeq.d";
|
||||
pcmpgt = "llvm.x86.sse2.pcmpgt.d";
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return bld->undef;
|
||||
}
|
||||
|
||||
/* There are no signed byte and unsigned word/dword comparison
|
||||
* instructions. So flip the sign bit so that the results match.
|
||||
*/
|
||||
if(table[func].gt &&
|
||||
((type.width == 8 && type.sign) ||
|
||||
(type.width != 8 && !type.sign))) {
|
||||
LLVMValueRef msb = lp_build_int_const_uni(type, (unsigned long long)1 << (type.width - 1));
|
||||
a = LLVMBuildXor(bld->builder, a, msb, "");
|
||||
b = LLVMBuildXor(bld->builder, b, msb, "");
|
||||
}
|
||||
|
||||
if(table[func].swap) {
|
||||
args[0] = b;
|
||||
args[1] = a;
|
||||
}
|
||||
else {
|
||||
args[0] = a;
|
||||
args[1] = b;
|
||||
}
|
||||
|
||||
if(table[func].eq)
|
||||
res = lp_build_intrinsic(bld->builder, pcmpeq, vec_type, args, 2);
|
||||
else if (table[func].gt)
|
||||
res = lp_build_intrinsic(bld->builder, pcmpgt, vec_type, args, 2);
|
||||
else
|
||||
res = LLVMConstNull(vec_type);
|
||||
|
||||
if(table[func].not)
|
||||
res = LLVMBuildNot(bld->builder, res, "");
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue