diff options
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_bld_intr.c | 112 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_bld_intr.h | 43 |
2 files changed, 136 insertions, 19 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_intr.c b/src/gallium/drivers/llvmpipe/lp_bld_intr.c index c055f8f38c8..a2051211b7a 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_intr.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_intr.c @@ -51,37 +51,113 @@ LLVMValueRef -lp_build_intrinsic_binary(LLVMBuilderRef builder, - const char *name, - LLVMTypeRef ret_type, - LLVMValueRef a, - LLVMValueRef b) +lp_build_intrinsic(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef *args, + unsigned num_args) { LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder))); LLVMValueRef function; - LLVMValueRef args[2]; + + assert(num_args <= LP_MAX_FUNC_ARGS); function = LLVMGetNamedFunction(module, name); if(!function) { - LLVMTypeRef arg_types[2]; - arg_types[0] = LLVMTypeOf(a); - arg_types[1] = LLVMTypeOf(b); - function = LLVMAddFunction(module, name, LLVMFunctionType(ret_type, arg_types, 2, 0)); + LLVMTypeRef arg_types[LP_MAX_FUNC_ARGS]; + unsigned i; + for(i = 0; i < num_args; ++i) { + assert(args[i]); + arg_types[i] = LLVMTypeOf(args[i]); + } + function = LLVMAddFunction(module, name, LLVMFunctionType(ret_type, arg_types, num_args, 0)); LLVMSetFunctionCallConv(function, LLVMCCallConv); LLVMSetLinkage(function, LLVMExternalLinkage); } assert(LLVMIsDeclaration(function)); -#ifdef DEBUG - /* We shouldn't use only constants with intrinsics, as they won't be - * propagated by LLVM optimization passes. - */ - if(LLVMIsConstant(a) && LLVMIsConstant(b)) - debug_printf("warning: invoking intrinsic \"%s\" with constants\n"); -#endif + return LLVMBuildCall(builder, function, args, num_args, ""); +} + + +LLVMValueRef +lp_build_intrinsic_unary(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef a) +{ + return lp_build_intrinsic(builder, name, ret_type, &a, 1); +} + + +LLVMValueRef +lp_build_intrinsic_binary(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef a, + LLVMValueRef b) +{ + LLVMValueRef args[2]; args[0] = a; args[1] = b; - return LLVMBuildCall(builder, function, args, 2, ""); + return lp_build_intrinsic(builder, name, ret_type, args, 2); } + + +LLVMValueRef +lp_build_intrinsic_map(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef *args, + unsigned num_args) +{ + LLVMTypeRef ret_elem_type = LLVMGetElementType(ret_type); + unsigned n = LLVMGetVectorSize(ret_type); + unsigned i, j; + LLVMValueRef res; + + assert(num_args <= LP_MAX_FUNC_ARGS); + + res = LLVMGetUndef(ret_type); + for(i = 0; i < n; ++i) { + LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); + LLVMValueRef arg_elems[LP_MAX_FUNC_ARGS]; + LLVMValueRef res_elem; + for(j = 0; j < num_args; ++j) + arg_elems[j] = LLVMBuildExtractElement(builder, args[j], index, ""); + res_elem = lp_build_intrinsic(builder, name, ret_elem_type, arg_elems, num_args); + res = LLVMBuildInsertElement(builder, res, res_elem, index, ""); + } + + return res; +} + + +LLVMValueRef +lp_build_intrinsic_map_unary(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef a) +{ + return lp_build_intrinsic_map(builder, name, ret_type, &a, 1); +} + + +LLVMValueRef +lp_build_intrinsic_map_binary(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef a, + LLVMValueRef b) +{ + LLVMValueRef args[2]; + + args[0] = a; + args[1] = b; + + return lp_build_intrinsic_map(builder, name, ret_type, args, 2); +} + + diff --git a/src/gallium/drivers/llvmpipe/lp_bld_intr.h b/src/gallium/drivers/llvmpipe/lp_bld_intr.h index 67f596c2b5d..1e8e0edd831 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_intr.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_intr.h @@ -27,7 +27,7 @@ /** * @file - * Helper arithmetic functions. + * Helper functions for calling intrinsics. * * @author Jose Fonseca <[email protected]> */ @@ -40,6 +40,24 @@ #include <llvm-c/Core.h> +#define LP_MAX_FUNC_ARGS 32 + + +LLVMValueRef +lp_build_intrinsic(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef *args, + unsigned num_args); + + +LLVMValueRef +lp_build_intrinsic_unary(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef a); + + LLVMValueRef lp_build_intrinsic_binary(LLVMBuilderRef builder, const char *name, @@ -48,4 +66,27 @@ lp_build_intrinsic_binary(LLVMBuilderRef builder, LLVMValueRef b); +LLVMValueRef +lp_build_intrinsic_map(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef *args, + unsigned num_args); + + +LLVMValueRef +lp_build_intrinsic_map_unary(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef a); + + +LLVMValueRef +lp_build_intrinsic_map_binary(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef a, + LLVMValueRef b); + + #endif /* !LP_BLD_INTR_H */ |