diff options
author | Alyssa Rosenzweig <[email protected]> | 2019-05-01 02:00:08 +0000 |
---|---|---|
committer | Alyssa Rosenzweig <[email protected]> | 2019-05-04 19:08:50 +0000 |
commit | f8c7ffa07a2b938f99f656fbc4f7fe1baa9eeafe (patch) | |
tree | d7974f54d52abc73c119f59ab6cdfff2dd05815b /src/gallium | |
parent | b6b534c73366eff8570c15183ed617575295f4b7 (diff) |
panfrost/midgard/disasm: Handle dest_override generalized
Signed-off-by: Alyssa Rosenzweig <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/panfrost/midgard/disassemble.c | 90 |
1 files changed, 68 insertions, 22 deletions
diff --git a/src/gallium/drivers/panfrost/midgard/disassemble.c b/src/gallium/drivers/panfrost/midgard/disassemble.c index 8466a90b8d6..c893bc89a6c 100644 --- a/src/gallium/drivers/panfrost/midgard/disassemble.c +++ b/src/gallium/drivers/panfrost/midgard/disassemble.c @@ -274,6 +274,70 @@ print_immediate(uint16_t imm) printf("#%g", _mesa_half_to_float(imm)); } +static int +bits_for_mode(midgard_reg_mode mode) +{ + switch (mode) { + case midgard_reg_mode_8: + return 8; + case midgard_reg_mode_16: + return 16; + case midgard_reg_mode_32: + return 32; + case midgard_reg_mode_64: + return 64; + default: + return 0; + } +} + +static void +print_dest(unsigned reg, midgard_reg_mode mode, midgard_dest_override override, bool out_high) +{ + bool overriden = override != midgard_dest_override_none; + bool overriden_up = override == midgard_dest_override_upper; + + /* Depending on the mode and override, we determine the type of + * destination addressed. Absent an override, we address just the + * type of the operation itself, directly at the out_reg register + * (scaled if necessary to disambiguate, raised if necessary) */ + + unsigned bits = bits_for_mode(mode); + + if (overriden) + bits /= 2; + + /* Sanity check the override */ + + if (overriden) { + bool modeable = (mode == midgard_reg_mode_32) || (mode == midgard_reg_mode_16); + bool known = override != 0x3; /* Unused value */ + bool uppable = !overriden_up || (mode == midgard_reg_mode_32); + + if (!(modeable && known && uppable)) + printf("/* do%d */ ", override); + } + + switch (mode) { + case midgard_reg_mode_8: + case midgard_reg_mode_16: + reg = reg * 2 + out_high; + break; + + case midgard_reg_mode_32: + if (overriden) { + reg = (reg * 2) + overriden_up; + } + + break; + + default: + break; + } + + print_reg(reg, bits); +} + static void print_vector_field(const char *name, uint16_t *words, uint16_t reg_word, unsigned tabs) @@ -329,29 +393,11 @@ print_vector_field(const char *name, uint16_t *words, uint16_t reg_word, } /* First, print the destination */ - { - int out_reg = reg_info->out_reg; - unsigned bits = 32; - - if (alu_field->dest_override != midgard_dest_override_none) { - printf("/* do%d */ ", alu_field->dest_override); - } - - if (mode == midgard_reg_mode_16) { - bits = 16; - out_reg *= 2; - out_reg += out_high; - } else if (mode == midgard_reg_mode_8) { - bits = 8; - out_reg *= 2; - out_reg += out_high; - } else if (mode == midgard_reg_mode_64) { - bits = 64; - /* TODO */ - } + print_dest(reg_info->out_reg, mode, alu_field->dest_override, out_high); - print_reg(out_reg, bits); - } + /* The semantics here are not totally grokked yet */ + if (alu_field->dest_override == midgard_dest_override_upper) + out_high = true; if (mask != 0xF) { unsigned i; |