From 3f993cdf6db5cf344179fcb4fbf899f6ef9a6b2b Mon Sep 17 00:00:00 2001 From: Ben Crocker Date: Tue, 30 May 2017 12:34:23 -0400 Subject: [PATCH] llvmpipe: lp_build_gather_elem_vec BE fix for 3x16 load Fix loading of a 3x16 vector as a single 48-bit load on big-endian systems (PPC64, S390). Signed-off-by: Ben Crocker --- src/gallium/auxiliary/gallivm/lp_bld_gather.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_gather.c b/src/gallium/auxiliary/gallivm/lp_bld_gather.c index ccd0376..8e56e42 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_gather.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_gather.c @@ -234,13 +234,26 @@ lp_build_gather_elem_vec(struct gallivm_state *gallivm, */ res = LLVMBuildZExt(gallivm->builder, res, dst_elem_type, ""); - if (vector_justify) { #ifdef PIPE_ARCH_BIG_ENDIAN + if (vector_justify) { res = LLVMBuildShl(gallivm->builder, res, LLVMConstInt(dst_elem_type, dst_type.width - src_width, 0), ""); -#endif } + if (src_width == 48) { + LLVMValueRef shuffles[4] = { + lp_build_const_int32(gallivm, 2), + lp_build_const_int32(gallivm, 1), + lp_build_const_int32(gallivm, 0), + lp_build_const_int32(gallivm, 3), + }; + struct lp_type type16 = {FALSE, FALSE, TRUE, FALSE, 16, 4}; + res = LLVMBuildBitCast(gallivm->builder, res, + lp_build_vec_type(gallivm, type16), ""); + res = LLVMBuildShuffleVector(gallivm->builder, res, res, LLVMConstVector(shuffles, 4), ""); + res = LLVMBuildBitCast(gallivm->builder, res, dst_elem_type, ""); + } +#endif } } return res; -- 2.7.4