diff --git a/GLScreen.cs b/GLScreen.cs
index d757db8fce..3e16f7f1da 100644
--- a/GLScreen.cs
+++ b/GLScreen.cs
@@ -6,6 +6,7 @@ using Gal;
 using OpenTK;
 using OpenTK.Graphics;
 using OpenTK.Graphics.OpenGL;
+using Ryujinx.OsHle;
 using System;
 
 namespace Ryujinx
@@ -60,12 +61,14 @@ namespace Ryujinx
 
             unsafe void UploadBitmap()
             {
-                if (Renderer.FrameBufferPtr == 0)
+                int FbSize = Width * Height * 4;
+
+                if (Renderer.FrameBufferPtr == 0 || Renderer.FrameBufferPtr + FbSize > uint.MaxValue)
                 {
                     return;
                 }
 
-                byte* SrcPtr = (byte*)IntPtr.Add(Ns.Ram, (int)Renderer.FrameBufferPtr);
+                byte* SrcPtr = (byte*)Ns.Ram + (uint)Renderer.FrameBufferPtr;
 
                 for (int Y = 0; Y < Height; Y++)
                 {
@@ -275,7 +278,14 @@ void main(void) {
         {
             unsafe
             {
-                byte* Ptr = (byte*)IntPtr.Add(Ns.Ram, (int)Ns.Os.HidOffset);
+                long HidOffset = Ns.Os.GetVirtHidOffset();
+
+                if (HidOffset == 0 || HidOffset + Horizon.HidSize > uint.MaxValue)
+                {
+                    return;
+                }
+
+                byte* Ptr = (byte*)Ns.Ram + (uint)HidOffset;
 
                 int State = 0;
                 
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
index 38233f6bd0..8d4ade3a17 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
@@ -361,15 +361,7 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
 
-            Context.EmitLdvec(Op.Rn);
-            Context.EmitLdc_I4(Op.Imm - (8 << Op.Size));
-            Context.EmitLdc_I4(Op.Size);
-
-            ASoftFallback.EmitCall(Context,
-                nameof(ASoftFallback.Shl64),
-                nameof(ASoftFallback.Shl128));
-
-            Context.EmitStvec(Op.Rd);
+            EmitVectorImmBinaryZx(Context, OpCodes.Shl, Op.Imm - (8 << Op.Size));
         }
 
         public static void Smax_V(AILEmitterCtx Context) => EmitVectorSmax(Context);
@@ -396,15 +388,7 @@ namespace ChocolArm64.Instruction
         {
             AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
 
-            Context.EmitLdvec(Op.Rn);
-            Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm);
-            Context.EmitLdc_I4(Op.Size);
-
-            ASoftFallback.EmitCall(Context,
-                nameof(ASoftFallback.Sshr64),
-                nameof(ASoftFallback.Sshr128));
-
-            Context.EmitStvec(Op.Rd);
+            EmitVectorImmBinarySx(Context, OpCodes.Shr, (8 << (Op.Size + 1)) - Op.Imm);
         }
 
         public static void St__V(AILEmitterCtx Context) => EmitSimdMultLdSt(Context, IsLoad: false);
@@ -881,6 +865,55 @@ namespace ChocolArm64.Instruction
             }
         }
 
+        private static void EmitVectorImmBinarySx(AILEmitterCtx Context, OpCode ILOp, long Imm)
+        {
+            EmitVectorImmBinarySx(Context, () => Context.Emit(ILOp), Imm);
+        }
+
+        private static void EmitVectorImmBinaryZx(AILEmitterCtx Context, OpCode ILOp, long Imm)
+        {
+            EmitVectorImmBinaryZx(Context, () => Context.Emit(ILOp), Imm);
+        }
+
+        private static void EmitVectorImmBinarySx(AILEmitterCtx Context, Action Emit, long Imm)
+        {
+            EmitVectorImmBinaryOp(Context, Emit, Imm, true);
+        }
+
+        private static void EmitVectorImmBinaryZx(AILEmitterCtx Context, Action Emit, long Imm)
+        {
+            EmitVectorImmBinaryOp(Context, Emit, Imm, false);
+        }
+
+        private static void EmitVectorImmBinaryOp(AILEmitterCtx Context, Action Emit, long Imm, bool Signed)
+        {
+            AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
+
+            int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+
+            for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
+            {
+                Context.EmitLdvec(Op.Rd);
+                Context.EmitLdc_I4(Index);
+                Context.EmitLdc_I4(Op.Size);
+
+                EmitVectorExtract(Context, Op.Rn, Index, Signed);
+
+                Context.EmitLdc_I8(Imm);
+
+                Emit();
+
+                ASoftFallback.EmitCall(Context, nameof(ASoftFallback.InsertVec));
+
+                Context.EmitStvec(Op.Rd);
+            }
+
+            if (Op.RegisterSize == ARegisterSize.SIMD64)
+            {
+                EmitVectorZeroUpper(Context, Op.Rd);
+            }
+        }
+
         private static void EmitVectorCmp(AILEmitterCtx Context, OpCode ILOp)
         {
             AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
@@ -936,7 +969,7 @@ namespace ChocolArm64.Instruction
 
         private static void EmitVectorExtract(AILEmitterCtx Context, int Reg, int Index, bool Signed)
         {
-            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
+            IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;
 
             Context.EmitLdvec(Reg);
             Context.EmitLdc_I4(Index);
diff --git a/Ryujinx/Cpu/Instruction/ASoftFallback.cs b/Ryujinx/Cpu/Instruction/ASoftFallback.cs
index 9101231486..0d52713208 100644
--- a/Ryujinx/Cpu/Instruction/ASoftFallback.cs
+++ b/Ryujinx/Cpu/Instruction/ASoftFallback.cs
@@ -790,32 +790,6 @@ namespace ChocolArm64.Instruction
             return Res;
         }
 
-        public static AVec Shl64(AVec Vector, int Shift, int Size)
-        {
-            return Shl(Vector, Shift, Size, 8);
-        }
-
-        public static AVec Shl128(AVec Vector, int Shift, int Size)
-        {
-            return Shl(Vector, Shift, Size, 16);
-        }
-
-        private static AVec Shl(AVec Vector, int Shift, int Size, int Bytes)
-        {
-            AVec Res = new AVec();
-
-            int Elems = Bytes >> Size;
-
-            for (int Index = 0; Index < Elems; Index++)
-            {
-                ulong Value = ExtractVec(Vector, Index, Size);
-
-                Res = InsertVec(Res, Index, Size, Value << Shift);
-            }
-
-            return Res;
-        }
-
         public static AVec Sshll(AVec Vector, int Shift, int Size)
         {
             return Sshll_(Vector, Shift, Size, false);
@@ -843,32 +817,6 @@ namespace ChocolArm64.Instruction
             return Res;
         }
 
-        public static AVec Sshr64(AVec Vector, int Shift, int Size)
-        {
-            return Sshr(Vector, Shift, Size, 8);
-        }
-
-        public static AVec Sshr128(AVec Vector, int Shift, int Size)
-        {
-            return Sshr(Vector, Shift, Size, 16);
-        }
-
-        private static AVec Sshr(AVec Vector, int Shift, int Size, int Bytes)
-        {
-            AVec Res = new AVec();
-
-            int Elems = Bytes >> Size;
-
-            for (int Index = 0; Index < Elems; Index++)
-            {
-                long Value = ExtractSVec(Vector, Index, Size);
-
-                Res = InsertSVec(Res, Index, Size, Value >> Shift);
-            }
-
-            return Res;
-        }
-
         public static AVec Tbl1_V64(AVec Vector, AVec Tb0)
         {
             return Tbl(Vector, 8, Tb0);
diff --git a/Ryujinx/Cpu/Memory/AMemory.cs b/Ryujinx/Cpu/Memory/AMemory.cs
index af1c75bf0b..8159b341ee 100644
--- a/Ryujinx/Cpu/Memory/AMemory.cs
+++ b/Ryujinx/Cpu/Memory/AMemory.cs
@@ -119,55 +119,22 @@ namespace ChocolArm64.Memory
 
         public byte ReadByte(long Position)
         {
-            return *((byte*)(RamPtr + Manager.GetPhys(Position, AMemoryPerm.Read)));
+            return *((byte*)(RamPtr + (uint)Position));
         }
 
         public ushort ReadUInt16(long Position)
         {
-            long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Read);
-
-            if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 2))
-            {
-                return *((ushort*)(RamPtr + PhysPos));
-            }
-            else
-            {
-                return (ushort)(
-                    ReadByte(Position + 0) << 0 |
-                    ReadByte(Position + 1) << 8);
-            }
+            return *((ushort*)(RamPtr + (uint)Position));
         }
 
         public uint ReadUInt32(long Position)
         {
-            long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Read);
-
-            if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 4))
-            {
-                return *((uint*)(RamPtr + PhysPos));
-            }
-            else
-            {
-                return (uint)(
-                    ReadUInt16(Position + 0) << 0 |
-                    ReadUInt16(Position + 2) << 16);
-            }
+            return *((uint*)(RamPtr + (uint)Position));
         }
 
         public ulong ReadUInt64(long Position)
         {
-            long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Read);
-
-            if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 8))
-            {
-                return *((ulong*)(RamPtr + PhysPos));
-            }
-            else
-            {
-                return
-                    (ulong)ReadUInt32(Position + 0) << 0 |
-                    (ulong)ReadUInt32(Position + 4) << 32;
-            }
+            return *((ulong*)(RamPtr + (uint)Position));
         }
 
         public AVec ReadVector128(long Position)
@@ -186,52 +153,22 @@ namespace ChocolArm64.Memory
 
         public void WriteByte(long Position, byte Value)
         {
-            *((byte*)(RamPtr + Manager.GetPhys(Position, AMemoryPerm.Write))) = Value;
+            *((byte*)(RamPtr + (uint)Position)) = Value;
         }
 
         public void WriteUInt16(long Position, ushort Value)
         {
-            long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Write);
-
-            if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 2))
-            {
-                *((ushort*)(RamPtr + PhysPos)) = Value;
-            }
-            else
-            {
-                WriteByte(Position + 0, (byte)(Value >> 0));
-                WriteByte(Position + 1, (byte)(Value >> 8));
-            }
+            *((ushort*)(RamPtr + (uint)Position)) = Value;
         }
 
         public void WriteUInt32(long Position, uint Value)
         {
-            long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Write);
-
-            if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 4))
-            {
-                *((uint*)(RamPtr + PhysPos)) = Value;
-            }
-            else
-            {
-                WriteUInt16(Position + 0, (ushort)(Value >> 0));
-                WriteUInt16(Position + 2, (ushort)(Value >> 16));
-            }
+            *((uint*)(RamPtr + (uint)Position)) = Value;
         }
 
         public void WriteUInt64(long Position, ulong Value)
         {
-            long PhysPos = Manager.GetPhys(Position, AMemoryPerm.Write);
-
-            if (BitConverter.IsLittleEndian && !IsPageCrossed(Position, 8))
-            {
-                *((ulong*)(RamPtr + PhysPos)) = Value;
-            }
-            else
-            {
-                WriteUInt32(Position + 0, (uint)(Value >> 0));
-                WriteUInt32(Position + 4, (uint)(Value >> 32));
-            }
+            *((ulong*)(RamPtr + (uint)Position)) = Value;
         }
 
         public void WriteVector128(long Position, AVec Value)
diff --git a/Ryujinx/Cpu/Memory/AMemoryMgr.cs b/Ryujinx/Cpu/Memory/AMemoryMgr.cs
index 4d995469fe..0c2c5a50b8 100644
--- a/Ryujinx/Cpu/Memory/AMemoryMgr.cs
+++ b/Ryujinx/Cpu/Memory/AMemoryMgr.cs
@@ -6,8 +6,8 @@ namespace ChocolArm64.Memory
 {
     public class AMemoryMgr
     {
-        public const long AddrSize = 1L << 36;
-        public const long RamSize  = 2L * 1024 * 1024 * 1024;
+        public const long AddrSize = RamSize;
+        public const long RamSize  = 4L * 1024 * 1024 * 1024;
 
         private const int  PTLvl0Bits = 11;
         private const int  PTLvl1Bits = 13;
@@ -117,7 +117,7 @@ namespace ChocolArm64.Memory
 
                 while ((ulong)Size < (ulong)HeapSize)
                 {
-                    Allocator.Free(GetPhys(Position, AMemoryPerm.None));
+                    Allocator.Free(Position);
 
                     Position += PageSize;
                 }
@@ -254,38 +254,6 @@ namespace ChocolArm64.Memory
             return new AMemoryMapInfo(Start, Size, BaseEntry.Type, BaseEntry.Perm);
         }
 
-        [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public long GetPhys(long Position, AMemoryPerm Perm)
-        {
-            if (!HasPTEntry(Position))
-            {
-                if (Position < 0x08000000)
-                {
-                    Console.WriteLine($"HACK: Ignoring bad access at {Position:x16}");
-
-                    return 0;
-                }
-
-                throw new VmmPageFaultException(Position);
-            }
-
-            PTEntry Entry = GetPTEntry(Position);
-
-            long AbsPos = Entry.Position + (Position & PageMask);
-
-            if (Entry.Map == PTMap.Mirror)
-            {
-                return GetPhys(AbsPos, Perm);
-            }
-
-            if (Entry.Map == PTMap.Unmapped)
-            {
-                throw new VmmPageFaultException(Position);
-            }
-
-            return AbsPos;
-        }
-
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         private bool HasPTEntry(long Position)
         {
diff --git a/Ryujinx/OsHle/Handles/HSharedMem.cs b/Ryujinx/OsHle/Handles/HSharedMem.cs
index acc1e7ebd7..2030ff0a44 100644
--- a/Ryujinx/OsHle/Handles/HSharedMem.cs
+++ b/Ryujinx/OsHle/Handles/HSharedMem.cs
@@ -3,6 +3,7 @@ namespace Ryujinx.OsHle.Handles
     class HSharedMem
     {
         public long PhysPos { get; private set; }
+        public long VirtPos { get; set; }
 
         public HSharedMem(long PhysPos)
         {
diff --git a/Ryujinx/OsHle/Handles/HTransferMem.cs b/Ryujinx/OsHle/Handles/HTransferMem.cs
index 962d1b6640..b24e14129d 100644
--- a/Ryujinx/OsHle/Handles/HTransferMem.cs
+++ b/Ryujinx/OsHle/Handles/HTransferMem.cs
@@ -9,15 +9,13 @@ namespace Ryujinx.OsHle.Handles
 
         public long Position { get; private set; }
         public long Size     { get; private set; }
-        public long PhysPos  { get; private set; }
 
-        public HTransferMem(AMemory Memory, AMemoryPerm Perm, long Position, long Size, long PhysPos)
+        public HTransferMem(AMemory Memory, AMemoryPerm Perm, long Position, long Size)
         {
             this.Memory   = Memory;
             this.Perm     = Perm;
             this.Position = Position;
             this.Size     = Size;
-            this.PhysPos  = PhysPos;
         }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Horizon.cs b/Ryujinx/OsHle/Horizon.cs
index bae33f8eb3..04744bdfac 100644
--- a/Ryujinx/OsHle/Horizon.cs
+++ b/Ryujinx/OsHle/Horizon.cs
@@ -159,5 +159,12 @@ namespace Ryujinx.OsHle
 
             Handles.Delete(Handle);
         }
+
+        public long GetVirtHidOffset()
+        {
+            HSharedMem HidSharedMem = Handles.GetData<HSharedMem>(HidHandle);
+
+            return HidSharedMem.VirtPos;
+        }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs b/Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs
index 72a472ae51..13393eafcb 100644
--- a/Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs
+++ b/Ryujinx/OsHle/Objects/ViIHOSBinderDriver.cs
@@ -155,8 +155,7 @@ namespace Ryujinx.OsHle.Objects
 
                 HNvMap NvMap = Context.Ns.Os.Handles.GetData<HNvMap>(Handle);
 
-                Context.Ns.Gpu.Renderer.FrameBufferPtr =
-                    Context.Memory.Manager.GetPhys(NvMap.Address, AMemoryPerm.Read);
+                Context.Ns.Gpu.Renderer.FrameBufferPtr = NvMap.Address;
             }
 
             return MakeReplyParcel(Context, 0);
diff --git a/Ryujinx/OsHle/Svc/SvcMemory.cs b/Ryujinx/OsHle/Svc/SvcMemory.cs
index c1249b403a..70988eb0b4 100644
--- a/Ryujinx/OsHle/Svc/SvcMemory.cs
+++ b/Ryujinx/OsHle/Svc/SvcMemory.cs
@@ -77,6 +77,8 @@ namespace Ryujinx.OsHle.Svc
                 long Src = Position;
                 long Dst = HndData.PhysPos;
 
+                HndData.VirtPos = Src;
+
                 if (Memory.Manager.MapPhys(Src, Dst, Size,
                     (int)MemoryType.SharedMemory, (AMemoryPerm)Perm))
                 {
@@ -113,9 +115,7 @@ namespace Ryujinx.OsHle.Svc
 
             Memory.Manager.Reprotect(Position, Size, (AMemoryPerm)Perm);
 
-            long PhysPos = Memory.Manager.GetPhys(Position, AMemoryPerm.None);
-
-            HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Position, Size, PhysPos);
+            HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Position, Size);
 
             int Handle = Ns.Os.Handles.GenerateId(HndData);