From 2d0bda088593f041e12d373d40f3243212d7d066 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 5 Jun 2019 15:20:26 -0700 Subject: [PATCH] panfrost/midgard: Add shifting int modifiers As a source modifier, shift allows shifting a value left by the bit size, useful in conjunction with a greater register mode, for instance to implement `upsample`. As a concrete example, the following OpenCL: ushort hr0 = /* ... */, uint r1 = /* ... */; uint r2 = (convert_uint(hr0) << 16) ^ b; compiles to the following Midgard assembly: ixor r, (hr0) << 16, b In reverse, the ".hi" output modifier shifts the value right by the bit size, leaving just the carry/overflow at the bottom. To implement *_hi functions in OpenCL (for <64-bit), we do arithmetic in the 2x higher mode with the .hi modifier. (For 64-bit, things are hairier, since there is not an 128-bit int mode). Signed-off-by: Alyssa Rosenzweig --- src/gallium/drivers/panfrost/midgard/disassemble.c | 28 ++++++++++------------ src/gallium/drivers/panfrost/midgard/midgard.h | 4 ++-- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/gallium/drivers/panfrost/midgard/disassemble.c b/src/gallium/drivers/panfrost/midgard/disassemble.c index bf66d1a..7b6ab9e 100644 --- a/src/gallium/drivers/panfrost/midgard/disassemble.c +++ b/src/gallium/drivers/panfrost/midgard/disassemble.c @@ -143,7 +143,14 @@ static char *outmod_names_int[4] = { ".isat", ".usat", "", - ".unk3" + ".hi" +}; + +static char *srcmod_names_int[4] = { + "sext(", + "zext(", + "", + "(" }; static void @@ -176,20 +183,7 @@ print_vector_src(unsigned src_binary, bool out_high, midgard_int_mod int_mod = src->mod; if (is_int) { - switch (int_mod) { - case midgard_int_sign_extend: - printf("sext("); - break; - case midgard_int_zero_extend: - printf("zext("); - break; - case midgard_int_reserved: - printf("unk("); - break; - case midgard_int_normal: - /* Implicit */ - break; - } + printf("%s", srcmod_names_int[int_mod]); } else { if (src->mod & MIDGARD_FLOAT_MOD_NEG) printf("-"); @@ -284,7 +278,9 @@ print_vector_src(unsigned src_binary, bool out_high, /* Since we wrapped with a function-looking thing */ - if ((is_int && (int_mod != midgard_int_normal)) + if (is_int && int_mod == midgard_int_shift) + printf(") << %d", bits); + else if ((is_int && (int_mod != midgard_int_normal)) || (!is_int && src->mod & MIDGARD_FLOAT_MOD_ABS)) printf(")"); } diff --git a/src/gallium/drivers/panfrost/midgard/midgard.h b/src/gallium/drivers/panfrost/midgard/midgard.h index ff853a1..995eaa9 100644 --- a/src/gallium/drivers/panfrost/midgard/midgard.h +++ b/src/gallium/drivers/panfrost/midgard/midgard.h @@ -180,7 +180,7 @@ typedef enum { midgard_outmod_int_saturate = 0, midgard_outmod_uint_saturate = 1, midgard_outmod_int_wrap = 2, - /* 0x3 unknown */ + midgard_outmod_int_high = 3, /* Overflowed portion */ } midgard_outmod_int; typedef enum { @@ -200,7 +200,7 @@ typedef enum { midgard_int_sign_extend = 0, midgard_int_zero_extend = 1, midgard_int_normal = 2, - midgard_int_reserved = 3 + midgard_int_shift = 3 } midgard_int_mod; #define MIDGARD_FLOAT_MOD_ABS (1 << 0) -- 2.7.4