diff options
Diffstat (limited to 'ChocolArm64/Memory/AMemory.cs')
| -rw-r--r-- | ChocolArm64/Memory/AMemory.cs | 254 |
1 files changed, 206 insertions, 48 deletions
diff --git a/ChocolArm64/Memory/AMemory.cs b/ChocolArm64/Memory/AMemory.cs index 6625966f..c74e11b2 100644 --- a/ChocolArm64/Memory/AMemory.cs +++ b/ChocolArm64/Memory/AMemory.cs @@ -3,6 +3,8 @@ using ChocolArm64.State; using System; using System.Collections.Generic; using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; namespace ChocolArm64.Memory { @@ -189,33 +191,73 @@ namespace ChocolArm64.Memory return ReadUInt64Unchecked(Position); } - public AVec ReadVector8(long Position) + public Vector128<float> ReadVector8(long Position) { - return new AVec() { B0 = ReadByte(Position) }; + if (Sse2.IsSupported) + { + return Sse.StaticCast<byte, float>(Sse2.SetVector128(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ReadByte(Position))); + } + else + { + throw new PlatformNotSupportedException(); + } } - public AVec ReadVector16(long Position) + public Vector128<float> ReadVector16(long Position) { - return new AVec() { H0 = ReadUInt16(Position) }; + if (Sse2.IsSupported) + { + return Sse.StaticCast<ushort, float>(Sse2.Insert(Sse2.SetZeroVector128<ushort>(), ReadUInt16(Position), 0)); + } + else + { + throw new PlatformNotSupportedException(); + } } - public AVec ReadVector32(long Position) + public Vector128<float> ReadVector32(long Position) { - return new AVec() { W0 = ReadUInt32(Position) }; + EnsureAccessIsValid(Position + 0, AMemoryPerm.Read); + EnsureAccessIsValid(Position + 3, AMemoryPerm.Read); + + if (Sse.IsSupported) + { + return Sse.LoadScalarVector128((float*)(RamPtr + (uint)Position)); + } + else + { + throw new PlatformNotSupportedException(); + } } - public AVec ReadVector64(long Position) + public Vector128<float> ReadVector64(long Position) { - return new AVec() { X0 = ReadUInt64(Position) }; + EnsureAccessIsValid(Position + 0, AMemoryPerm.Read); + EnsureAccessIsValid(Position + 7, AMemoryPerm.Read); + + if (Sse2.IsSupported) + { + return Sse.StaticCast<double, float>(Sse2.LoadScalarVector128((double*)(RamPtr + (uint)Position))); + } + else + { + throw new PlatformNotSupportedException(); + } } - public AVec ReadVector128(long Position) + public Vector128<float> ReadVector128(long Position) { - return new AVec() + EnsureAccessIsValid(Position + 0, AMemoryPerm.Read); + EnsureAccessIsValid(Position + 15, AMemoryPerm.Read); + + if (Sse.IsSupported) + { + return Sse.LoadVector128((float*)(RamPtr + (uint)Position)); + } + else { - X0 = ReadUInt64(Position + 0), - X1 = ReadUInt64(Position + 8) - }; + throw new PlatformNotSupportedException(); + } } public sbyte ReadSByteUnchecked(long Position) @@ -258,33 +300,64 @@ namespace ChocolArm64.Memory return *((ulong*)(RamPtr + (uint)Position)); } - public AVec ReadVector8Unchecked(long Position) + public Vector128<float> ReadVector8Unchecked(long Position) { - return new AVec() { B0 = ReadByteUnchecked(Position) }; + if (Sse2.IsSupported) + { + return Sse.StaticCast<byte, float>(Sse2.SetVector128(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ReadByte(Position))); + } + else + { + throw new PlatformNotSupportedException(); + } } - public AVec ReadVector16Unchecked(long Position) + public Vector128<float> ReadVector16Unchecked(long Position) { - return new AVec() { H0 = ReadUInt16Unchecked(Position) }; + if (Sse2.IsSupported) + { + return Sse.StaticCast<ushort, float>(Sse2.Insert(Sse2.SetZeroVector128<ushort>(), ReadUInt16Unchecked(Position), 0)); + } + else + { + throw new PlatformNotSupportedException(); + } } - public AVec ReadVector32Unchecked(long Position) + public Vector128<float> ReadVector32Unchecked(long Position) { - return new AVec() { W0 = ReadUInt32Unchecked(Position) }; + if (Sse.IsSupported) + { + return Sse.LoadScalarVector128((float*)(RamPtr + (uint)Position)); + } + else + { + throw new PlatformNotSupportedException(); + } } - public AVec ReadVector64Unchecked(long Position) + public Vector128<float> ReadVector64Unchecked(long Position) { - return new AVec() { X0 = ReadUInt64Unchecked(Position) }; + if (Sse2.IsSupported) + { + return Sse.StaticCast<double, float>(Sse2.LoadScalarVector128((double*)(RamPtr + (uint)Position))); + } + else + { + throw new PlatformNotSupportedException(); + } } - public AVec ReadVector128Unchecked(long Position) + public Vector128<float> ReadVector128Unchecked(long Position) { - return new AVec() + if (Sse.IsSupported) { - X0 = ReadUInt64Unchecked(Position + 0), - X1 = ReadUInt64Unchecked(Position + 8) - }; + return Sse.LoadVector128((float*)(RamPtr + (uint)Position)); + } + else + { + throw new PlatformNotSupportedException(); + } } public void WriteSByte(long Position, sbyte Value) @@ -338,30 +411,77 @@ namespace ChocolArm64.Memory WriteUInt64Unchecked(Position, Value); } - public void WriteVector8(long Position, AVec Value) + public void WriteVector8(long Position, Vector128<float> Value) { - WriteByte(Position, Value.B0); + if (Sse41.IsSupported) + { + WriteByte(Position, Sse41.Extract(Sse.StaticCast<float, byte>(Value), 0)); + } + else if (Sse2.IsSupported) + { + WriteByte(Position, (byte)Sse2.Extract(Sse.StaticCast<float, ushort>(Value), 0)); + } + else + { + throw new PlatformNotSupportedException(); + } } - public void WriteVector16(long Position, AVec Value) + public void WriteVector16(long Position, Vector128<float> Value) { - WriteUInt16(Position, Value.H0); + if (Sse2.IsSupported) + { + WriteUInt16(Position, Sse2.Extract(Sse.StaticCast<float, ushort>(Value), 0)); + } + else + { + throw new PlatformNotSupportedException(); + } } - public void WriteVector32(long Position, AVec Value) + public void WriteVector32(long Position, Vector128<float> Value) { - WriteUInt32(Position, Value.W0); + EnsureAccessIsValid(Position + 0, AMemoryPerm.Write); + EnsureAccessIsValid(Position + 3, AMemoryPerm.Write); + + if (Sse.IsSupported) + { + Sse.StoreScalar((float*)(RamPtr + (uint)Position), Value); + } + else + { + throw new PlatformNotSupportedException(); + } } - public void WriteVector64(long Position, AVec Value) + public void WriteVector64(long Position, Vector128<float> Value) { - WriteUInt64(Position, Value.X0); + EnsureAccessIsValid(Position + 0, AMemoryPerm.Write); + EnsureAccessIsValid(Position + 7, AMemoryPerm.Write); + + if (Sse2.IsSupported) + { + Sse2.StoreScalar((double*)(RamPtr + (uint)Position), Sse.StaticCast<float, double>(Value)); + } + else + { + throw new PlatformNotSupportedException(); + } } - public void WriteVector128(long Position, AVec Value) + public void WriteVector128(long Position, Vector128<float> Value) { - WriteUInt64(Position + 0, Value.X0); - WriteUInt64(Position + 8, Value.X1); + EnsureAccessIsValid(Position + 0, AMemoryPerm.Write); + EnsureAccessIsValid(Position + 15, AMemoryPerm.Write); + + if (Sse.IsSupported) + { + Sse.Store((float*)(RamPtr + (uint)Position), Value); + } + else + { + throw new PlatformNotSupportedException(); + } } public void WriteSByteUnchecked(long Position, sbyte Value) @@ -404,30 +524,68 @@ namespace ChocolArm64.Memory *((ulong*)(RamPtr + (uint)Position)) = Value; } - public void WriteVector8Unchecked(long Position, AVec Value) + public void WriteVector8Unchecked(long Position, Vector128<float> Value) { - WriteByteUnchecked(Position, Value.B0); + if (Sse41.IsSupported) + { + WriteByteUnchecked(Position, Sse41.Extract(Sse.StaticCast<float, byte>(Value), 0)); + } + else if (Sse2.IsSupported) + { + WriteByteUnchecked(Position, (byte)Sse2.Extract(Sse.StaticCast<float, ushort>(Value), 0)); + } + else + { + throw new PlatformNotSupportedException(); + } } - public void WriteVector16Unchecked(long Position, AVec Value) + public void WriteVector16Unchecked(long Position, Vector128<float> Value) { - WriteUInt16Unchecked(Position, Value.H0); + if (Sse2.IsSupported) + { + WriteUInt16Unchecked(Position, Sse2.Extract(Sse.StaticCast<float, ushort>(Value), 0)); + } + else + { + throw new PlatformNotSupportedException(); + } } - public void WriteVector32Unchecked(long Position, AVec Value) + public void WriteVector32Unchecked(long Position, Vector128<float> Value) { - WriteUInt32Unchecked(Position, Value.W0); + if (Sse.IsSupported) + { + Sse.StoreScalar((float*)(RamPtr + (uint)Position), Value); + } + else + { + throw new PlatformNotSupportedException(); + } } - public void WriteVector64Unchecked(long Position, AVec Value) + public void WriteVector64Unchecked(long Position, Vector128<float> Value) { - WriteUInt64Unchecked(Position, Value.X0); + if (Sse2.IsSupported) + { + Sse2.StoreScalar((double*)(RamPtr + (uint)Position), Sse.StaticCast<float, double>(Value)); + } + else + { + throw new PlatformNotSupportedException(); + } } - public void WriteVector128Unchecked(long Position, AVec Value) + public void WriteVector128Unchecked(long Position, Vector128<float> Value) { - WriteUInt64Unchecked(Position + 0, Value.X0); - WriteUInt64Unchecked(Position + 8, Value.X1); + if (Sse.IsSupported) + { + Sse.Store((float*)(RamPtr + (uint)Position), Value); + } + else + { + throw new PlatformNotSupportedException(); + } } private void EnsureAccessIsValid(long Position, AMemoryPerm Perm) |
