From 7d76b07d6bc3572695a7b74bf0c6c160911160e3 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Wed, 28 Oct 2020 13:32:25 +0000 Subject: [PATCH] ac/llvm: implement byte/word extract/insert instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rhys Perry Reviewed-by: Timur Kristóf Part-of: --- src/amd/llvm/ac_nir_to_llvm.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/amd/llvm/ac_nir_to_llvm.c b/src/amd/llvm/ac_nir_to_llvm.c index f2173376cce..f58a5a128d5 100644 --- a/src/amd/llvm/ac_nir_to_llvm.c +++ b/src/amd/llvm/ac_nir_to_llvm.c @@ -1211,6 +1211,31 @@ static void visit_alu(struct ac_nir_context *ctx, const nir_alu_instr *instr) break; } + case nir_op_extract_u8: + case nir_op_extract_i8: + case nir_op_extract_u16: + case nir_op_extract_i16: { + bool is_signed = instr->op == nir_op_extract_i16 || instr->op == nir_op_extract_i8; + unsigned size = instr->op == nir_op_extract_u8 || instr->op == nir_op_extract_i8 ? 8 : 16; + LLVMValueRef offset = LLVMConstInt(LLVMTypeOf(src[0]), nir_src_as_uint(instr->src[1].src) * size, false); + result = LLVMBuildLShr(ctx->ac.builder, src[0], offset, ""); + result = LLVMBuildTrunc(ctx->ac.builder, result, LLVMIntTypeInContext(ctx->ac.context, size), ""); + if (is_signed) + result = LLVMBuildSExt(ctx->ac.builder, result, LLVMTypeOf(src[0]), ""); + else + result = LLVMBuildZExt(ctx->ac.builder, result, LLVMTypeOf(src[0]), ""); + break; + } + + case nir_op_insert_u8: + case nir_op_insert_u16: { + unsigned size = instr->op == nir_op_insert_u8 ? 8 : 16; + LLVMValueRef offset = LLVMConstInt(LLVMTypeOf(src[0]), nir_src_as_uint(instr->src[1].src) * size, false); + LLVMValueRef mask = LLVMConstInt(LLVMTypeOf(src[0]), u_bit_consecutive(0, size), false); + result = LLVMBuildShl(ctx->ac.builder, LLVMBuildAnd(ctx->ac.builder, src[0], mask, ""), offset, ""); + break; + } + default: fprintf(stderr, "Unknown NIR alu instr: "); nir_print_instr(&instr->instr, stderr);