From f3afe24594bad11d7e0fd28902d1ce1e6e22e3a2 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sat, 2 Apr 2016 00:02:03 -0400
Subject: [PATCH] shader_jit_x64: Execute certain asserts at runtime.

- This is because we compile the full shader code space, and therefore its common to compile malformed instructions.
---
 src/video_core/shader/shader_jit_x64.cpp | 18 +++++++++++++-----
 src/video_core/shader/shader_jit_x64.h   |  6 ++++++
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp
index cbdc1e40fd..dda9bcef71 100644
--- a/src/video_core/shader/shader_jit_x64.cpp
+++ b/src/video_core/shader/shader_jit_x64.cpp
@@ -146,6 +146,16 @@ static Instruction GetVertexShaderInstruction(size_t offset) {
     return { g_state.vs.program_code[offset] };
 }
 
+static void LogCritical(const char* msg) {
+    LOG_CRITICAL(HW_GPU, msg);
+}
+
+void JitCompiler::RuntimeAssert(bool condition, const char* msg) {
+    if (!condition) {
+        ABI_CallFunctionP(reinterpret_cast<const void*>(LogCritical), const_cast<char*>(msg));
+    }
+}
+
 /**
  * Loads and swizzles a source register into the specified XMM register.
  * @param instr VS instruction, used for determining how to load the source register
@@ -667,8 +677,7 @@ void JitCompiler::Compile_MAD(Instruction instr) {
 }
 
 void JitCompiler::Compile_IF(Instruction instr) {
-    ASSERT_MSG(instr.flow_control.dest_offset > last_program_counter, "Backwards if-statements (%d -> %d) not supported",
-        last_program_counter, instr.flow_control.dest_offset.Value());
+    RuntimeAssert(instr.flow_control.dest_offset > last_program_counter, "Backwards if-statements not supported");
 
     // Evaluate the "IF" condition
     if (instr.opcode.Value() == OpCode::Id::IFU) {
@@ -699,9 +708,8 @@ void JitCompiler::Compile_IF(Instruction instr) {
 }
 
 void JitCompiler::Compile_LOOP(Instruction instr) {
-    ASSERT_MSG(instr.flow_control.dest_offset > last_program_counter, "Backwards loops (%d -> %d) not supported",
-        last_program_counter, instr.flow_control.dest_offset.Value());
-    ASSERT_MSG(!looping, "Nested loops not supported");
+    RuntimeAssert(instr.flow_control.dest_offset > last_program_counter, "Backwards loops not supported");
+    RuntimeAssert(!looping, "Nested loops not supported");
 
     looping = true;
 
diff --git a/src/video_core/shader/shader_jit_x64.h b/src/video_core/shader/shader_jit_x64.h
index 1501d13bf9..159b902b25 100644
--- a/src/video_core/shader/shader_jit_x64.h
+++ b/src/video_core/shader/shader_jit_x64.h
@@ -90,6 +90,12 @@ private:
 
     BitSet32 PersistentCallerSavedRegs();
 
+    /**
+     * Assertion evaluated at compile-time, but only triggered if executed at runtime.
+     * @param msg Message to be logged if the assertion fails.
+     */
+    void RuntimeAssert(bool condition, const char* msg);
+
     /**
      * Analyzes the entire shader program for `CALL` instructions before emitting any code,
      * identifying the locations where a return needs to be inserted.