freedreno/decode: try harder to not crash in disasm
[mesa.git] / src / freedreno / ir3 / disasm-a3xx.c
index 2555c739082fd3613c7c8205009af5719d0872ca..29c78ad5e18c28b9bde573eafd7756fa3c591f38 100644 (file)
@@ -1635,12 +1635,6 @@ static bool print_instr(struct disasm_ctx *ctx, uint32_t *dwords, int n)
                ((opc == OPC_END) || (opc == OPC_CHSH));
 }
 
-int disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned gpu_id)
-{
-       struct shader_stats stats;
-       return disasm_a3xx_stat(dwords, sizedwords, level, out, gpu_id, &stats);
-}
-
 int disasm_a3xx_stat(uint32_t *dwords, int sizedwords, int level, FILE *out,
                unsigned gpu_id, struct shader_stats *stats)
 {
@@ -1680,3 +1674,42 @@ void disasm_a3xx_set_debug(enum debug_t d)
 {
        debug = d;
 }
+
+#include <setjmp.h>
+
+static bool jmp_env_valid;
+static jmp_buf jmp_env;
+
+void
+ir3_assert_handler(const char *expr, const char *file, int line,
+               const char *func)
+{
+       fprintf(stdout, "\n%s:%u: %s: Assertion `%s' failed.\n", file, line, func, expr);
+       if (jmp_env_valid)
+               longjmp(jmp_env, 1);
+       abort();
+}
+
+#define TRY(x) do { \
+               assert(!jmp_env_valid); \
+               if (setjmp(jmp_env) == 0) { \
+                       jmp_env_valid = true; \
+                       x; \
+               } \
+               jmp_env_valid = false; \
+       } while (0)
+
+
+int disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned gpu_id)
+{
+       struct shader_stats stats;
+       return disasm_a3xx_stat(dwords, sizedwords, level, out, gpu_id, &stats);
+}
+
+int try_disasm_a3xx(uint32_t *dwords, int sizedwords, int level, FILE *out, unsigned gpu_id)
+{
+       struct shader_stats stats;
+       int ret;
+       TRY(ret = disasm_a3xx_stat(dwords, sizedwords, level, out, gpu_id, &stats));
+       return ret;
+}