From 0ba508d7a3b6a006b5b8db1e865d33efc8d0abd5 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 15 Jul 2019 10:31:49 -0500 Subject: nir,intel: Add support for lowering 64-bit nir_opt_extract_* We need this when doing full software 64-bit emulation. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=110309 Fixes: cbad201c2b3 "nir/algebraic: Add missing 64-bit extract_[iu]8..." Reviewed-by: Kenneth Graunke Reviewed-by: Ian Romanick --- src/compiler/nir/nir.h | 1 + src/compiler/nir/nir_lower_int64.c | 38 ++++++++++++++++++++++++++++++++++++++ src/intel/compiler/brw_compiler.c | 3 ++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 2719087e9a4..c7a1bf357c8 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2463,6 +2463,7 @@ typedef enum { nir_lower_minmax64 = (1 << 10), nir_lower_shift64 = (1 << 11), nir_lower_imul_2x32_64 = (1 << 12), + nir_lower_extract64 = (1 << 13), } nir_lower_int64_options; typedef enum { diff --git a/src/compiler/nir/nir_lower_int64.c b/src/compiler/nir/nir_lower_int64.c index b3b78c6649a..84ec2a77f1e 100644 --- a/src/compiler/nir/nir_lower_int64.c +++ b/src/compiler/nir/nir_lower_int64.c @@ -629,6 +629,34 @@ lower_irem64(nir_builder *b, nir_ssa_def *n, nir_ssa_def *d) return nir_bcsel(b, n_is_neg, nir_ineg(b, r), r); } +static nir_ssa_def * +lower_extract(nir_builder *b, nir_op op, nir_ssa_def *x, nir_ssa_def *c) +{ + assert(op == nir_op_extract_u8 || op == nir_op_extract_i8 || + op == nir_op_extract_u16 || op == nir_op_extract_i16); + + const int chunk = nir_src_as_uint(nir_src_for_ssa(c)); + const int chunk_bits = + (op == nir_op_extract_u8 || op == nir_op_extract_i8) ? 8 : 16; + const int num_chunks_in_32 = 32 / chunk_bits; + + nir_ssa_def *extract32; + if (chunk < num_chunks_in_32) { + extract32 = nir_build_alu(b, op, nir_unpack_64_2x32_split_x(b, x), + nir_imm_int(b, chunk), + NULL, NULL); + } else { + extract32 = nir_build_alu(b, op, nir_unpack_64_2x32_split_y(b, x), + nir_imm_int(b, chunk - num_chunks_in_32), + NULL, NULL); + } + + if (op == nir_op_extract_i8 || op == nir_op_extract_i16) + return lower_i2i64(b, extract32); + else + return lower_u2u64(b, extract32); +} + nir_lower_int64_options nir_lower_int64_op_to_options_mask(nir_op opcode) { @@ -685,6 +713,11 @@ nir_lower_int64_op_to_options_mask(nir_op opcode) case nir_op_ishr: case nir_op_ushr: return nir_lower_shift64; + case nir_op_extract_u8: + case nir_op_extract_i8: + case nir_op_extract_u16: + case nir_op_extract_i16: + return nir_lower_extract64; default: return 0; } @@ -779,6 +812,11 @@ lower_int64_alu_instr(nir_builder *b, nir_alu_instr *alu) return lower_ishr64(b, src[0], src[1]); case nir_op_ushr: return lower_ushr64(b, src[0], src[1]); + case nir_op_extract_u8: + case nir_op_extract_i8: + case nir_op_extract_u16: + case nir_op_extract_i16: + return lower_extract(b, alu->op, src[0], src[1]); default: unreachable("Invalid ALU opcode to lower"); } diff --git a/src/intel/compiler/brw_compiler.c b/src/intel/compiler/brw_compiler.c index 3a80f807b87..6d9dac6c3ca 100644 --- a/src/intel/compiler/brw_compiler.c +++ b/src/intel/compiler/brw_compiler.c @@ -143,7 +143,8 @@ brw_compiler_create(void *mem_ctx, const struct gen_device_info *devinfo) nir_lower_ineg64 | nir_lower_logic64 | nir_lower_minmax64 | - nir_lower_shift64; + nir_lower_shift64 | + nir_lower_extract64; fp64_options |= nir_lower_fp64_full_software; } -- cgit v1.2.3