llvmpipe: More intrinsic helpers.
authorJosé Fonseca <jfonseca@vmware.com>
Mon, 10 Aug 2009 22:22:40 +0000 (23:22 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 29 Aug 2009 08:21:29 +0000 (09:21 +0100)
src/gallium/drivers/llvmpipe/lp_bld_intr.c
src/gallium/drivers/llvmpipe/lp_bld_intr.h

index c055f8f38c84e4bd76a812f7fb88de64b4f583ae..a2051211b7a13780cee70150c22d7101db207b11 100644 (file)
 
 
 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);
+}
+
+
index 67f596c2b5de9e405388b99854d7bfedbb9a9476..1e8e0edd8312bd82bee2931697f28ee422f1048a 100644 (file)
@@ -27,7 +27,7 @@
 
 /**
  * @file
- * Helper arithmetic functions.
+ * Helper functions for calling intrinsics.
  *
  * @author Jose Fonseca <jfonseca@vmware.com>
  */
 #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 */