From 422aceb407f63ef23659c890a9536101e4f654f7 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Mon, 22 Apr 2019 03:08:25 +0000 Subject: [PATCH] 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 --- .../drivers/panfrost/midgard/disassemble.c | 43 +++++++++++++++---- .../drivers/panfrost/midgard/midgard.h | 15 ++++++- .../panfrost/midgard/midgard_compile.c | 17 ++++---- 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; } -- 2.30.2