From 2feecd05a3ebfcad90a878d59ca7ba7d2a75af60 Mon Sep 17 00:00:00 2001
From: Gabriel A <gab.dark.100@gmail.com>
Date: Thu, 4 Jan 2024 17:58:42 -0300
Subject: [PATCH] Support host tracked on LightningJit

---
 .../Arm32/Target/Arm64/InstEmitMemory.cs      | 21 ++++++++++++++++++-
 .../LightningJit/Arm64/RegisterAllocator.cs   |  2 +-
 .../Arm64/Target/Arm64/InstEmitMemory.cs      | 21 ++++++++++++++++++-
 3 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs
index 534ec80a8..54e156d74 100644
--- a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs
+++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitMemory.cs
@@ -1126,7 +1126,26 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
             Operand destination64 = new(destination.Kind, OperandType.I64, destination.Value);
             Operand basePointer = new(regAlloc.FixedPageTableRegister, RegisterType.Integer, OperandType.I64);
 
-            asm.Add(destination64, basePointer, guestAddress);
+            if (mmType == MemoryManagerType.HostTracked)
+            {
+                int tempRegister = regAlloc.AllocateTempGprRegister();
+
+                Operand pte = new(tempRegister, RegisterType.Integer, OperandType.I64);
+
+                asm.Lsr(pte, guestAddress, new Operand(OperandKind.Constant, OperandType.I32, 12));
+                asm.LdrRr(pte, basePointer, pte, ArmExtensionType.Uxtx, true);
+                asm.Add(destination64, pte, guestAddress);
+
+                regAlloc.FreeTempGprRegister(tempRegister);
+            }
+            else if (mmType == MemoryManagerType.HostMapped || mmType == MemoryManagerType.HostMappedUnsafe)
+            {
+                asm.Add(destination64, basePointer, guestAddress);
+            }
+            else
+            {
+                throw new NotImplementedException(mmType.ToString());
+            }
         }
 
         public static void WriteAddShiftOffset(in Assembler asm, Operand rd, Operand rn, Operand offset, bool add, ArmShiftType shiftType, int shift)
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs
index c9a932093..0a2b4f7aa 100644
--- a/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/RegisterAllocator.cs
@@ -7,7 +7,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64
 {
     class RegisterAllocator
     {
-        public const int MaxTemps = 1;
+        public const int MaxTemps = 2;
         public const int MaxTempsInclFixed = MaxTemps + 2;
 
         private uint _gprMask;
diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs
index fb5cd4781..c9c1c86f2 100644
--- a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs
+++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/InstEmitMemory.cs
@@ -512,7 +512,26 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
         {
             Operand basePointer = new(regAlloc.FixedPageTableRegister, RegisterType.Integer, OperandType.I64);
 
-            asm.Add(destination, basePointer, guestAddress);
+            if (mmType == MemoryManagerType.HostTracked)
+            {
+                int tempRegister = regAlloc.AllocateTempGprRegister();
+
+                Operand pte = new(tempRegister, RegisterType.Integer, OperandType.I64);
+
+                asm.Lsr(pte, guestAddress, new Operand(OperandKind.Constant, OperandType.I32, 12));
+                asm.LdrRr(pte, basePointer, pte, ArmExtensionType.Uxtx, true);
+                asm.Add(destination, pte, guestAddress);
+
+                regAlloc.FreeTempGprRegister(tempRegister);
+            }
+            else if (mmType == MemoryManagerType.HostMapped || mmType == MemoryManagerType.HostMappedUnsafe)
+            {
+                asm.Add(destination, basePointer, guestAddress);
+            }
+            else
+            {
+                throw new NotImplementedException(mmType.ToString());
+            }
         }
 
         private static void WriteAddConstant(ref Assembler asm, Operand rd, Operand rn, int value)