diff --git a/src/panfrost/midgard/meson.build b/src/panfrost/midgard/meson.build index c25466161b8..3d78b13d257 100644 --- a/src/panfrost/midgard/meson.build +++ b/src/panfrost/midgard/meson.build @@ -40,7 +40,6 @@ libpanfrost_midgard_files = files( 'midgard_errata_lod.c', 'nir_undef_to_zero.c', 'nir_fuse_io_16.c', - 'disassemble.c', ) midgard_nir_algebraic_c = custom_target( @@ -55,6 +54,23 @@ midgard_nir_algebraic_c = custom_target( depend_files : nir_algebraic_py, ) +libpanfrost_midgard_disasm = static_library( + 'panfrost_midgard_disasm', + ['disassemble.c', 'midgard_ops.c', 'midgard_print_constant.c'], + include_directories : [ + inc_mapi, + inc_mesa, + inc_gallium, + inc_gallium_aux, + inc_include, + inc_src, + inc_panfrost_hw, + ], + c_args : [no_override_init_args], + gnu_symbol_visibility : 'hidden', + build_by_default : false, +) + libpanfrost_midgard = static_library( 'panfrost_midgard', [libpanfrost_midgard_files, midgard_nir_algebraic_c], @@ -70,7 +86,7 @@ libpanfrost_midgard = static_library( dependencies: [ idep_nir ], - link_with: [libpanfrost_util], + link_with: [libpanfrost_util, libpanfrost_midgard_disasm], c_args : [no_override_init_args], gnu_symbol_visibility : 'hidden', build_by_default : false, diff --git a/src/panfrost/midgard/midgard_print.c b/src/panfrost/midgard/midgard_print.c index 3f72864f811..2bbc616ae31 100644 --- a/src/panfrost/midgard/midgard_print.c +++ b/src/panfrost/midgard/midgard_print.c @@ -107,131 +107,6 @@ mir_get_unit(unsigned unit) } } -void -mir_print_constant_component(FILE *fp, const midgard_constants *consts, unsigned c, - midgard_reg_mode reg_mode, bool half, - unsigned mod, midgard_alu_op op) -{ - bool is_sint = false, is_uint = false, is_hex = false; - const char *opname = alu_opcode_props[op].name; - - /* Add a sentinel name to prevent crashing */ - if (!opname) - opname = "unknown"; - - if (opname[0] == 'u') { - /* If the opcode starts with a 'u' we are sure we deal with an - * unsigned int operation - */ - is_uint = true; - } else if (opname[0] == 'i') { - /* Bit ops are easier to follow when the constant is printed in - * hexadecimal. Other operations starting with a 'i' are - * considered to operate on signed integers. That might not - * be true for all of them, but it's good enough for traces. - */ - if (op >= midgard_alu_op_iand && - op <= midgard_alu_op_ibitcount8) - is_hex = true; - else - is_sint = true; - } - - if (half) - reg_mode--; - - switch (reg_mode) { - case midgard_reg_mode_64: - if (is_sint) { - fprintf(fp, "%"PRIi64, consts->i64[c]); - } else if (is_uint) { - fprintf(fp, "%"PRIu64, consts->u64[c]); - } else if (is_hex) { - fprintf(fp, "0x%"PRIX64, consts->u64[c]); - } else { - double v = consts->f64[c]; - - if (mod & MIDGARD_FLOAT_MOD_ABS) v = fabs(v); - if (mod & MIDGARD_FLOAT_MOD_NEG) v = -v; - - printf("%g", v); - } - break; - - case midgard_reg_mode_32: - if (is_sint) { - int64_t v; - - if (half && mod == midgard_int_zero_extend) - v = consts->u32[c]; - else if (half && mod == midgard_int_shift) - v = (uint64_t)consts->u32[c] << 32; - else - v = consts->i32[c]; - - fprintf(fp, "%"PRIi64, v); - } else if (is_uint || is_hex) { - uint64_t v; - - if (half && mod == midgard_int_shift) - v = (uint64_t)consts->u32[c] << 32; - else - v = consts->u32[c]; - - fprintf(fp, is_uint ? "%"PRIu64 : "0x%"PRIX64, v); - } else { - float v = consts->f32[c]; - - if (mod & MIDGARD_FLOAT_MOD_ABS) v = fabsf(v); - if (mod & MIDGARD_FLOAT_MOD_NEG) v = -v; - - fprintf(fp, "%g", v); - } - break; - - case midgard_reg_mode_16: - if (is_sint) { - int32_t v; - - if (half && mod == midgard_int_zero_extend) - v = consts->u16[c]; - else if (half && mod == midgard_int_shift) - v = (uint32_t)consts->u16[c] << 16; - else - v = consts->i16[c]; - - fprintf(fp, "%d", v); - } else if (is_uint || is_hex) { - uint32_t v; - - if (half && mod == midgard_int_shift) - v = (uint32_t)consts->u16[c] << 16; - else - v = consts->u16[c]; - - fprintf(fp, is_uint ? "%u" : "0x%X", v); - } else { - float v = _mesa_half_to_float(consts->f16[c]); - - if (mod & MIDGARD_FLOAT_MOD_ABS) v = fabsf(v); - if (mod & MIDGARD_FLOAT_MOD_NEG) v = -v; - - fprintf(fp, "%g", v); - } - break; - - case midgard_reg_mode_8: - fprintf(fp, "0x%X", consts->u8[c]); - - if (mod) - fprintf(fp, " /* %u */", mod); - - assert(!half); /* No 4-bit */ - - break; - } -} - static void mir_print_embedded_constant(midgard_instruction *ins, unsigned src_idx) { diff --git a/src/panfrost/midgard/midgard_print_constant.c b/src/panfrost/midgard/midgard_print_constant.c new file mode 100644 index 00000000000..6a4d535b4a6 --- /dev/null +++ b/src/panfrost/midgard/midgard_print_constant.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2018-2019 Alyssa Rosenzweig + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include "util/half_float.h" +#include "midgard.h" +#include "helpers.h" +#include "midgard_ops.h" + +void +mir_print_constant_component(FILE *fp, const midgard_constants *consts, unsigned c, + midgard_reg_mode reg_mode, bool half, + unsigned mod, midgard_alu_op op) +{ + bool is_sint = false, is_uint = false, is_hex = false; + const char *opname = alu_opcode_props[op].name; + + /* Add a sentinel name to prevent crashing */ + if (!opname) + opname = "unknown"; + + if (opname[0] == 'u') { + /* If the opcode starts with a 'u' we are sure we deal with an + * unsigned int operation + */ + is_uint = true; + } else if (opname[0] == 'i') { + /* Bit ops are easier to follow when the constant is printed in + * hexadecimal. Other operations starting with a 'i' are + * considered to operate on signed integers. That might not + * be true for all of them, but it's good enough for traces. + */ + if (op >= midgard_alu_op_iand && + op <= midgard_alu_op_ibitcount8) + is_hex = true; + else + is_sint = true; + } + + if (half) + reg_mode--; + + switch (reg_mode) { + case midgard_reg_mode_64: + if (is_sint) { + fprintf(fp, "%"PRIi64, consts->i64[c]); + } else if (is_uint) { + fprintf(fp, "%"PRIu64, consts->u64[c]); + } else if (is_hex) { + fprintf(fp, "0x%"PRIX64, consts->u64[c]); + } else { + double v = consts->f64[c]; + + if (mod & MIDGARD_FLOAT_MOD_ABS) v = fabs(v); + if (mod & MIDGARD_FLOAT_MOD_NEG) v = -v; + + printf("%g", v); + } + break; + + case midgard_reg_mode_32: + if (is_sint) { + int64_t v; + + if (half && mod == midgard_int_zero_extend) + v = consts->u32[c]; + else if (half && mod == midgard_int_shift) + v = (uint64_t)consts->u32[c] << 32; + else + v = consts->i32[c]; + + fprintf(fp, "%"PRIi64, v); + } else if (is_uint || is_hex) { + uint64_t v; + + if (half && mod == midgard_int_shift) + v = (uint64_t)consts->u32[c] << 32; + else + v = consts->u32[c]; + + fprintf(fp, is_uint ? "%"PRIu64 : "0x%"PRIX64, v); + } else { + float v = consts->f32[c]; + + if (mod & MIDGARD_FLOAT_MOD_ABS) v = fabsf(v); + if (mod & MIDGARD_FLOAT_MOD_NEG) v = -v; + + fprintf(fp, "%g", v); + } + break; + + case midgard_reg_mode_16: + if (is_sint) { + int32_t v; + + if (half && mod == midgard_int_zero_extend) + v = consts->u16[c]; + else if (half && mod == midgard_int_shift) + v = (uint32_t)consts->u16[c] << 16; + else + v = consts->i16[c]; + + fprintf(fp, "%d", v); + } else if (is_uint || is_hex) { + uint32_t v; + + if (half && mod == midgard_int_shift) + v = (uint32_t)consts->u16[c] << 16; + else + v = consts->u16[c]; + + fprintf(fp, is_uint ? "%u" : "0x%X", v); + } else { + float v = _mesa_half_to_float(consts->f16[c]); + + if (mod & MIDGARD_FLOAT_MOD_ABS) v = fabsf(v); + if (mod & MIDGARD_FLOAT_MOD_NEG) v = -v; + + fprintf(fp, "%g", v); + } + break; + + case midgard_reg_mode_8: + fprintf(fp, "0x%X", consts->u8[c]); + + if (mod) + fprintf(fp, " /* %u */", mod); + + assert(!half); /* No 4-bit */ + + break; + } +} + +