diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp
index bee34a7c0c..79434a63cb 100644
--- a/src/video_core/macro/macro_jit_x64.cpp
+++ b/src/video_core/macro/macro_jit_x64.cpp
@@ -273,14 +273,6 @@ void MacroJITx64Impl::Compile_ExtractShiftLeftRegister(Macro::Opcode opcode) {
     Compile_ProcessResult(opcode.result_operation, opcode.dst);
 }
 
-static u32 Read(Engines::Maxwell3D* maxwell3d, u32 method) {
-    return maxwell3d->GetRegisterValue(method);
-}
-
-static void Send(Engines::Maxwell3D* maxwell3d, Macro::MethodAddress method_address, u32 value) {
-    maxwell3d->CallMethodFromMME(method_address.address, value);
-}
-
 void MacroJITx64Impl::Compile_Read(Macro::Opcode opcode) {
     if (optimizer.zero_reg_skip && opcode.src_a == 0) {
         if (opcode.immediate == 0) {
@@ -298,15 +290,27 @@ void MacroJITx64Impl::Compile_Read(Macro::Opcode opcode) {
             sub(result, opcode.immediate * -1);
         }
     }
-    Common::X64::ABI_PushRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0);
-    mov(Common::X64::ABI_PARAM1, qword[STATE]);
-    mov(Common::X64::ABI_PARAM2, RESULT);
-    Common::X64::CallFarFunction(*this, &Read);
-    Common::X64::ABI_PopRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0);
-    mov(RESULT, Common::X64::ABI_RETURN.cvt32());
+
+    // Equivalent to Engines::Maxwell3D::GetRegisterValue:
+    if (optimizer.enable_asserts) {
+        Xbyak::Label pass_range_check;
+        cmp(RESULT, static_cast<u32>(Engines::Maxwell3D::Regs::NUM_REGS));
+        jb(pass_range_check);
+        int3();
+        L(pass_range_check);
+    }
+    mov(rax, qword[STATE]);
+    mov(RESULT,
+        dword[rax + offsetof(Engines::Maxwell3D, regs) +
+              offsetof(Engines::Maxwell3D::Regs, reg_array) + RESULT.cvt64() * sizeof(u32)]);
+
     Compile_ProcessResult(opcode.result_operation, opcode.dst);
 }
 
+static void Send(Engines::Maxwell3D* maxwell3d, Macro::MethodAddress method_address, u32 value) {
+    maxwell3d->CallMethodFromMME(method_address.address, value);
+}
+
 void Tegra::MacroJITx64Impl::Compile_Send(Xbyak::Reg32 value) {
     Common::X64::ABI_PushRegistersAndAdjustStack(*this, PersistentCallerSavedRegs(), 0);
     mov(Common::X64::ABI_PARAM1, qword[STATE]);
@@ -438,6 +442,9 @@ void MacroJITx64Impl::Compile() {
     // one if our register isn't "dirty"
     optimizer.optimize_for_method_move = true;
 
+    // Enable run-time assertions in JITted code
+    optimizer.enable_asserts = false;
+
     // Check to see if we can skip emitting certain instructions
     Optimizer_ScanFlags();
 
diff --git a/src/video_core/macro/macro_jit_x64.h b/src/video_core/macro/macro_jit_x64.h
index 51ec090b85..a180e74283 100644
--- a/src/video_core/macro/macro_jit_x64.h
+++ b/src/video_core/macro/macro_jit_x64.h
@@ -76,6 +76,7 @@ private:
         bool zero_reg_skip{};
         bool skip_dummy_addimmediate{};
         bool optimize_for_method_move{};
+        bool enable_asserts{};
     };
     OptimizerState optimizer{};