diff options
author | Alyssa Rosenzweig <[email protected]> | 2019-06-05 15:20:26 -0700 |
---|---|---|
committer | Alyssa Rosenzweig <[email protected]> | 2019-06-10 06:50:11 -0700 |
commit | 2d0bda088593f041e12d373d40f3243212d7d066 (patch) | |
tree | ec880596cc9fed0343236369b84df053671646a1 /src/gallium | |
parent | 6780481a3f49f09692017a926f2b49e38dd169bc (diff) |
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 <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/panfrost/midgard/disassemble.c | 28 | ||||
-rw-r--r-- | 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 bf66d1a7da7..7b6ab9ecd68 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 ff853a19733..995eaa9a90a 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) |