mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 13:48:06 +02:00
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@vmware.com> Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
parent
86902b5134
commit
b772d784b2
2 changed files with 89 additions and 0 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -42,6 +42,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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue