Kaynağa Gözat

llvmpipe: Generate instrinsics for integer comparisons.

It is a little messy, given the available instrucions form SIMD
integer comparisons is rather limited.
tags/mesa_7_6_rc1
José Fonseca 16 yıl önce
ebeveyn
işleme
d07b038366
1 değiştirilmiş dosya ile 71 ekleme ve 0 silme
  1. 71
    0
      src/gallium/drivers/llvmpipe/lp_bld_logic.c

+ 71
- 0
src/gallium/drivers/llvmpipe/lp_bld_logic.c Dosyayı Görüntüle

@@ -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…
İptal
Kaydet