113 lines
3.6 KiB
C#
113 lines
3.6 KiB
C#
using StgSharp.Math;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using static StgSharp.Optimization.CpuInfo;
|
|
|
|
namespace StgSharp.Optimization
|
|
{
|
|
public static unsafe partial class SSE
|
|
{
|
|
public static m128 sqrtssM128Cache = new m128();
|
|
public static m128* sqrtssM128CachePointer;
|
|
|
|
private static IntPtr sqrtssCodePointer;
|
|
|
|
private static sqrtssDelegate sqrtssDele;
|
|
|
|
private static byte[] sqrtssCodeBytes
|
|
= new byte[]
|
|
{
|
|
0x48,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // mov rax, [pointer location]
|
|
0x48,0x8b,0x00, // mov rax, [rax]
|
|
0xf3,0x0f,0x6f,0x00, // movqdu xmm0,xmmword ptr [rax]
|
|
0xf3,0x0f,0x51,0xc0, // sqrtss xmm0,xmm0
|
|
0xf3,0x0f,0x7f,0x00 // movdqu xmmword ptr [rax],xmm0
|
|
};
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
private static extern IntPtr VirtualAlloc(
|
|
IntPtr lpAddress,
|
|
UIntPtr dwSize,
|
|
AllocationType flAllocationType,
|
|
MemoryProtection flProtect
|
|
);
|
|
|
|
[DllImport("kernel32")]
|
|
private static extern bool VirtualFree(
|
|
IntPtr lpAddress,
|
|
UInt32 dwSize,
|
|
UInt32 dwFreeType
|
|
);
|
|
|
|
[Flags()]
|
|
protected enum AllocationType : uint
|
|
{
|
|
COMMIT = 0x1000,
|
|
RESERVE = 0x2000,
|
|
RESET = 0x80000,
|
|
LARGE_PAGES = 0x20000000,
|
|
PHYSICAL = 0x400000,
|
|
TOP_DOWN = 0x100000,
|
|
WRITE_WATCH = 0x200000
|
|
}
|
|
|
|
[Flags()]
|
|
protected enum MemoryProtection : uint
|
|
{
|
|
EXECUTE = 0x10,
|
|
EXECUTE_READ = 0x20,
|
|
EXECUTE_READWRITE = 0x40,
|
|
EXECUTE_WRITECOPY = 0x80,
|
|
NOACCESS = 0x01,
|
|
READONLY = 0x02,
|
|
READWRITE = 0x04,
|
|
WRITECOPY = 0x08,
|
|
GUARD_Modifierflag = 0x100,
|
|
NOCACHE_Modifierflag = 0x200,
|
|
WRITECOMBINE_Modifierflag = 0x400
|
|
}
|
|
|
|
private unsafe static void InitSqrtss()
|
|
{
|
|
byte[] sqrtssM128PointerBytes = BitConverter.GetBytes((ulong)sqrtssM128CachePointer);
|
|
for (int i = 0; i < sqrtssM128PointerBytes.Length; i++)
|
|
{
|
|
sqrtssCodeBytes[2+i] = sqrtssCodeBytes[7-i];
|
|
}
|
|
|
|
if (IntPtr.Size!=8)
|
|
{
|
|
throw new Exception("This SSE class support 64bits OS only presently!");
|
|
}
|
|
|
|
sqrtssCodePointer = VirtualAlloc(
|
|
IntPtr.Zero,
|
|
new UIntPtr((uint)sqrtssCodeBytes.Length),
|
|
AllocationType.COMMIT | AllocationType.RESERVE,
|
|
MemoryProtection.EXECUTE_READWRITE
|
|
);
|
|
|
|
Marshal.Copy(sqrtssCodeBytes, 0, sqrtssCodePointer, sqrtssCodeBytes.Length);
|
|
sqrtssDele = (sqrtssDelegate)Marshal.GetDelegateForFunctionPointer(sqrtssCodePointer,typeof(sqrtssDelegate));
|
|
}
|
|
|
|
public static float Sqrtss(float a)
|
|
{
|
|
fixed (m128* p = &sqrtssM128Cache)
|
|
{
|
|
sqrtssM128Cache.float0 = a;
|
|
sqrtssDele(sqrtssM128Cache);
|
|
return sqrtssM128Cache.float0;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
[UnmanagedFunctionPointerAttribute(CallingConvention.ThisCall)]
|
|
internal delegate void sqrtssDelegate(m128 a);
|
|
}
|