panfrost/midgard: Document sign-extension/zero-extension bits (vector)
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Mon, 22 Apr 2019 03:08:25 +0000 (03:08 +0000)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Wed, 24 Apr 2019 02:22:32 +0000 (02:22 +0000)
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 <alyssa@rosenzweig.io>
src/gallium/drivers/panfrost/midgard/disassemble.c
src/gallium/drivers/panfrost/midgard/midgard.h
src/gallium/drivers/panfrost/midgard/midgard_compile.c

index 21a01aa9b0eecd0fdd693100739c9a7becce80b8..be0d250f7e552a8b99ce0eda1728fd61cfe08b2a 100644 (file)
@@ -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");
index 6176dfbb1c96cdd5951693a599d5fc6c2e4ffbe4..f426b9712b109baca68ec18ccb1ee1d7bb4fff24 100644 (file)
@@ -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
index 539f8ca12bbf6f66740d4c19e30866f0355bbefe..c4802d16762d74fb99f7a31ca2ad7685e8ddfdd2 100644 (file)
@@ -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;
                         }