summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-04-22 03:08:25 +0000
committerAlyssa Rosenzweig <[email protected]>2019-04-24 02:22:32 +0000
commit422aceb407f63ef23659c890a9536101e4f654f7 (patch)
tree691ad32f39763d723986804a4e1ce4744eeb2c6c
parentb453c877d91839cf4af32456ee39843433f43b65 (diff)
panfrost/midgard: Document sign-extension/zero-extension bits (vector)
For floating point ops, these bits determine the "negate?" and "abs?" modifiers. For integer ops, it turns out they control how sign/zero extension work, useful for mixing types. Signed-off-by: Alyssa Rosenzweig <[email protected]>
-rw-r--r--src/gallium/drivers/panfrost/midgard/disassemble.c43
-rw-r--r--src/gallium/drivers/panfrost/midgard/midgard.h15
-rw-r--r--src/gallium/drivers/panfrost/midgard/midgard_compile.c17
3 files changed, 57 insertions, 18 deletions
diff --git a/src/gallium/drivers/panfrost/midgard/disassemble.c b/src/gallium/drivers/panfrost/midgard/disassemble.c
index 21a01aa9b0e..be0d250f7e5 100644
--- a/src/gallium/drivers/panfrost/midgard/disassemble.c
+++ b/src/gallium/drivers/panfrost/midgard/disassemble.c
@@ -32,6 +32,7 @@
#include "midgard.h"
#include "midgard-parse.h"
#include "disassemble.h"
+#include "helpers.h"
#include "util/half_float.h"
#define DEFINE_CASE(define, str) case define: { printf(str); break; }
@@ -110,15 +111,37 @@ print_quad_word(uint32_t *words, unsigned tabs)
static void
print_vector_src(unsigned src_binary, bool out_high,
- bool out_half, unsigned reg)
+ bool out_half, unsigned reg,
+ bool is_int)
{
midgard_vector_alu_src *src = (midgard_vector_alu_src *)&src_binary;
- if (src->negate)
- printf("-");
+ /* Modifiers change meaning depending on the op's context */
+
+ 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;
+ }
+ } else {
+ if (src->mod & MIDGARD_FLOAT_MOD_NEG)
+ printf("-");
- if (src->abs)
- printf("abs(");
+ if (src->mod & MIDGARD_FLOAT_MOD_ABS)
+ printf("abs(");
+ }
//register
@@ -173,7 +196,10 @@ print_vector_src(unsigned src_binary, bool out_high,
printf("%c", c[(src->swizzle >> (i * 2)) & 3]);
}
- if (src->abs)
+ /* Since we wrapped with a function-looking thing */
+
+ if ((is_int && (int_mod != midgard_int_normal))
+ || (!is_int && src->mod & MIDGARD_FLOAT_MOD_ABS))
printf(")");
}
@@ -277,7 +303,8 @@ print_vector_field(const char *name, uint16_t *words, uint16_t reg_word,
printf(", ");
- print_vector_src(alu_field->src1, out_high, half, reg_info->src1_reg);
+ bool is_int = midgard_is_integer_op(alu_field->op);
+ print_vector_src(alu_field->src1, out_high, half, reg_info->src1_reg, is_int);
printf(", ");
@@ -286,7 +313,7 @@ print_vector_field(const char *name, uint16_t *words, uint16_t reg_word,
print_immediate(imm);
} else {
print_vector_src(alu_field->src2, out_high, half,
- reg_info->src2_reg);
+ reg_info->src2_reg, is_int);
}
printf("\n");
diff --git a/src/gallium/drivers/panfrost/midgard/midgard.h b/src/gallium/drivers/panfrost/midgard/midgard.h
index 6176dfbb1c9..f426b9712b1 100644
--- a/src/gallium/drivers/panfrost/midgard/midgard.h
+++ b/src/gallium/drivers/panfrost/midgard/midgard.h
@@ -161,11 +161,22 @@ typedef enum {
midgard_dest_override_none = 2
} midgard_dest_override;
+typedef enum {
+ midgard_int_sign_extend = 0,
+ midgard_int_zero_extend = 1,
+ midgard_int_normal = 2,
+ midgard_int_reserved = 3
+} midgard_int_mod;
+
+#define MIDGARD_FLOAT_MOD_ABS (1 << 0)
+#define MIDGARD_FLOAT_MOD_NEG (1 << 1)
+
typedef struct
__attribute__((__packed__))
{
- bool abs : 1;
- bool negate : 1;
+ /* Either midgard_int_mod or from midgard_float_mod_*, depending on the
+ * type of op */
+ unsigned mod : 2;
/* replicate lower half if dest = half, or low/high half selection if
* dest = full
diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
index 539f8ca12bb..c4802d16762 100644
--- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c
+++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
@@ -254,8 +254,7 @@ vector_alu_modifiers(nir_alu_src *src)
if (!src) return blank_alu_src;
midgard_vector_alu_src alu_src = {
- .abs = src->abs,
- .negate = src->negate,
+ .mod = (src->abs << 0) | (src->negate << 1),
.rep_low = 0,
.rep_high = 0,
.half = 0, /* TODO */
@@ -1474,10 +1473,10 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
emit_mir_instruction(ctx, ins);
}
- /* vadd.u2f hr2, abs(hr2), #0 */
+ /* vadd.u2f hr2, zext(hr2), #0 */
midgard_vector_alu_src alu_src = blank_alu_src;
- alu_src.abs = true;
+ alu_src.mod = midgard_int_zero_extend;
alu_src.half = true;
midgard_instruction u2f = {
@@ -1502,7 +1501,7 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
/* vmul.fmul.sat r1, hr2, #0.00392151 */
- alu_src.abs = false;
+ alu_src.mod = 0;
midgard_instruction fmul = {
.type = TAG_ALU_4,
@@ -2183,9 +2182,11 @@ vector_to_scalar_source(unsigned u)
midgard_vector_alu_src v;
memcpy(&v, &u, sizeof(v));
+ /* TODO: Integers */
+
midgard_scalar_alu_src s = {
- .abs = v.abs,
- .negate = v.negate,
+ .abs = v.mod & MIDGARD_FLOAT_MOD_ABS,
+ .negate = v.mod & MIDGARD_FLOAT_MOD_NEG,
.full = !v.half,
.component = (v.swizzle & 3) << 1
};
@@ -2975,7 +2976,7 @@ embedded_to_inline_constant(compiler_context *ctx)
/* We don't know how to handle these with a constant */
- if (src->abs || src->negate || src->half || src->rep_low || src->rep_high) {
+ if (src->mod || src->half || src->rep_low || src->rep_high) {
DBG("Bailing inline constant...\n");
continue;
}