Mesa (master): gallivm: Add byte-swap construct calls

Jose Fonseca jrfonseca at kemper.freedesktop.org
Thu Nov 29 11:54:46 UTC 2012


Module: Mesa
Branch: master
Commit: b772d784b25771ff939e3c0c87fdf0d8053827be
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b772d784b25771ff939e3c0c87fdf0d8053827be

Author: Adhemerval Zanella <azanella at linux.vnet.ibm.com>
Date:   Thu Nov 22 12:23:23 2012 -0600

gallivm: Add byte-swap construct calls

This patch adds two more functions in type conversions header:
* lp_build_bswap: construct a call to llvm.bswap intrinsic for an
  element
* lp_build_bswap_vec: byte swap every element in a vector base on the
  input and output types.

Reviewed-by: Roland Scheidegger <sroland at vmware.com>
Reviewed-by: Jose Fonseca <jfonseca at vmware.com>

---

 src/gallium/auxiliary/gallivm/lp_bld_conv.c |   78 +++++++++++++++++++++++++++
 src/gallium/auxiliary/gallivm/lp_bld_conv.h |   11 ++++
 2 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
index cc44236..cd18b0c 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_conv.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c
@@ -71,6 +71,84 @@
 #include "lp_bld_pack.h"
 #include "lp_bld_conv.h"
 #include "lp_bld_logic.h"
+#include "lp_bld_intr.h"
+
+
+
+/**
+ * Byte swap on element. It will construct a call to intrinsic llvm.bswap
+ * based on the type.
+ *
+ * @param res           element to byte swap.
+ * @param type          int16_t, int32_t, int64_t, float or double
+ * @param 
+ */
+LLVMValueRef
+lp_build_bswap(struct gallivm_state *gallivm,
+               LLVMValueRef res,
+               struct lp_type type)
+{
+   LLVMTypeRef int_type = LLVMIntTypeInContext(gallivm->context,
+                                               type.width);
+   const char *intrinsic = NULL;
+   if (type.width == 8)
+      return res;
+   if (type.width == 16)
+      intrinsic = "llvm.bswap.i16";
+   else if (type.width == 32)
+     intrinsic = "llvm.bswap.i32";
+   else if (type.width == 64)
+      intrinsic = "llvm.bswap.i64";
+
+   assert (intrinsic != NULL);
+
+   /* In case of a floating-point type cast to a int of same size and then
+    * cast back to fp type.
+    */
+   if (type.floating)
+      res = LLVMBuildBitCast(gallivm->builder, res, int_type, "");
+   res = lp_build_intrinsic_unary(gallivm->builder, intrinsic, int_type, res);
+   if (type.floating)
+      res = LLVMBuildBitCast(gallivm->builder, res,
+                             lp_build_elem_type(gallivm, type), "");
+   return res;
+}
+
+
+/**
+ * Byte swap every element in the vector.
+ *
+ * @param packed        <vector> to convert
+ * @param src_type      <vector> type of int16_t, int32_t, int64_t, float or
+ *                      double
+ * @param dst_type      <vector> type to return
+ */
+LLVMValueRef
+lp_build_bswap_vec(struct gallivm_state *gallivm,
+                   LLVMValueRef packed,
+                   struct lp_type src_type_vec,
+                   struct lp_type dst_type_vec)
+{
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMTypeRef dst_type = lp_build_elem_type(gallivm, dst_type_vec);
+   LLVMValueRef res;
+
+   if (src_type_vec.length == 1) {
+      res = lp_build_bswap(gallivm, packed, src_type_vec);
+      res = LLVMBuildBitCast(gallivm->builder, res, dst_type, "");
+   } else {
+      unsigned i;
+      res = LLVMGetUndef(lp_build_vec_type(gallivm, dst_type_vec));
+      for (i = 0; i < src_type_vec.length; ++i) {
+         LLVMValueRef index = lp_build_const_int32(gallivm, i);
+         LLVMValueRef elem = LLVMBuildExtractElement(builder, packed, index, "");
+         elem = lp_build_bswap(gallivm, elem, src_type_vec);
+         elem = LLVMBuildBitCast(gallivm->builder, elem, dst_type, "");
+         res = LLVMBuildInsertElement(gallivm->builder, res, elem, index, "");
+      }
+   }
+   return res;
+}
 
 
 /**
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.h b/src/gallium/auxiliary/gallivm/lp_bld_conv.h
index 42a1113..d7dfed8 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_conv.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.h
@@ -43,6 +43,17 @@
 struct lp_type;
 
 LLVMValueRef
+lp_build_bswap(struct gallivm_state *gallivm,
+               LLVMValueRef res,
+               struct lp_type type);
+
+LLVMValueRef
+lp_build_bswap_vec(struct gallivm_state *gallivm,
+                   LLVMValueRef packed,
+                   struct lp_type src_type,
+                   struct lp_type dst_type);
+
+LLVMValueRef
 lp_build_half_to_float(struct gallivm_state *gallivm,
                        LLVMValueRef src);
 




More information about the mesa-commit mailing list