summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-06-05 15:20:26 -0700
committerAlyssa Rosenzweig <[email protected]>2019-06-10 06:50:11 -0700
commit2d0bda088593f041e12d373d40f3243212d7d066 (patch)
treeec880596cc9fed0343236369b84df053671646a1
parent6780481a3f49f09692017a926f2b49e38dd169bc (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]>
-rw-r--r--src/gallium/drivers/panfrost/midgard/disassemble.c28
-rw-r--r--src/gallium/drivers/panfrost/midgard/midgard.h4
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)