/// <summary> /// Creates a unary assembly operator /// </summary> /// <param name="code">The code to execute</param> /// <param name="name">The operator name</param> /// <typeparam name="T">The operand type</typeparam> public static AsmUnaryOp <T> CreateUnaryOp <T>(this AsmCode <T> code, string name = null) where T : unmanaged { var t = typeof(T); var argTypes = new Type[] { t }; var returnType = t; var method = new DynamicMethod(name ?? "anon", returnType, argTypes, t.Module); var g = method.GetILGenerator(); g.Emit(OpCodes.Ldarg_0); g.Emit(OpCodes.Ldc_I8, (long)code.Pointer); g.EmitCalli(OpCodes.Calli, CallingConvention.StdCall, returnType, argTypes); g.Emit(OpCodes.Ret); return((AsmUnaryOp <T>)method.CreateDelegate(typeof(AsmUnaryOp <T>))); }
static AsmCode <T> AddCode <T>() where T : unmanaged { if (typeof(T) == typeof(sbyte)) { return(AsmCode.FromBytes <T>(add8iBytes)); } else if (typeof(T) == typeof(byte)) { return(AsmCode.FromBytes <T>(add8uBytes)); } else if (typeof(T) == typeof(short)) { return(AsmCode.FromBytes <T>(add16iBytes)); } else if (typeof(T) == typeof(ushort)) { return(AsmCode.FromBytes <T>(add16uBytes)); } else if (typeof(T) == typeof(int)) { return(AsmCode.FromBytes <T>(add32iBytes)); } else if (typeof(T) == typeof(uint)) { return(AsmCode.FromBytes <T>(add32uBytes)); } else if (typeof(T) == typeof(long)) { return(AsmCode.FromBytes <T>(add64iBytes)); } else if (typeof(T) == typeof(ulong)) { return(AsmCode.FromBytes <T>(add64uBytes)); } else if (typeof(T) == typeof(float)) { return(AsmCode.FromBytes <T>(add32fBytes)); } else if (typeof(T) == typeof(double)) { return(AsmCode.FromBytes <T>(add64fBytes)); } else { throw unsupported <T>(); } }
public static AsmBinOp <T> CreateBinOpPI <T>(this AsmCode code) where T : unmanaged { if (typeof(T) == typeof(sbyte)) { return(code.CreateBinOpI8().ToGeneric <BinOpI8, T>()); } else if (typeof(T) == typeof(byte)) { return(code.CreateBinOpU8().ToGeneric <BinOpU8, T>()); } else if (typeof(T) == typeof(short)) { return(code.CreateBinOpI16().ToGeneric <BinOpI16, T>()); } else if (typeof(T) == typeof(ushort)) { return(code.CreateBinOpU16().ToGeneric <BinOpU16, T>()); } else if (typeof(T) == typeof(int)) { return(code.CreateBinOpI32().ToGeneric <BinOpI32, T>()); } else if (typeof(T) == typeof(uint)) { return(code.CreateBinOpU32().ToGeneric <BinOpU32, T>()); } else if (typeof(T) == typeof(long)) { return(code.CreateBinOpI64().ToGeneric <BinOpI64, T>()); } else if (typeof(T) == typeof(ulong)) { return(code.CreateBinOpU64().ToGeneric <BinOpU64, T>()); } else if (typeof(T) == typeof(float)) { return(code.CreateBinOpF32().ToGeneric <BinOpF32, T>()); } else if (typeof(T) == typeof(double)) { return(code.CreateBinOpF64().ToGeneric <BinOpF64, T>()); } else { throw unsupported <T>(); } }
static AsmCode <T> SqrtCode <T>() where T : unmanaged { if (typeof(T) == typeof(float)) { return(AsmCode.FromBytes <T>(SqrtF32Bytes)); } else if (typeof(T) == typeof(double)) { return(AsmCode.FromBytes <T>(SqrtF64Bytes)); } else { throw unsupported <T>(); } }
public static AsmCode <T> Add128Code <T>() where T : unmanaged { if (typeof(T) == typeof(sbyte) || typeof(T) == typeof(byte)) { return(AsmCode.FromBytes <T>(vpaddbBytes)); } else if (typeof(T) == typeof(short) || typeof(T) == typeof(ushort)) { return(AsmCode.FromBytes <T>(vpaddwBytes)); } else if (typeof(T) == typeof(int) || typeof(T) == typeof(uint)) { return(AsmCode.FromBytes <T>(vpadddBytes)); } else { throw unsupported <T>(); } }
static AsmRdRand() { var rdrand = new byte[] { 0x0f, 0xc7, 0xf0, // rdrand eax 0x0f, 0x92, 0x01, // setc byte ptr [rcx] 0xc3 // ret }; Marshal.Copy(rdrand, 0, methodPtr <AsmRdRand>(nameof(RandNative)), rdrand.Length); var code = AsmCode.FromBytes <uint>(rdrand); var emitter = code.CreateEmitter(); emitter(); //var il = code.CreateEmitter().Method.GetMethodBody().GetILAsByteArray(); //var emitter = code.CreateEmitter(); //var il = emitter.Method.GetMethodBody().GetILAsByteArray(); //var dst = methodPtr<AsmRdRand>(nameof(Next)); //Marshal.Copy(il, 0, dst, il.Length); }
static QuadOpI32 OpI32(AsmCode code) => code.CreateDelegate <QuadOpI32>();
protected void VerifyOp <T>(AsmCode <T> code, Func <T, T> refop, int n) where T : unmanaged => VerifyOp(code.CreateUnaryOp <T>(), refop, n);
protected void VerifyOp <T>(AsmCode <T> code, Func <T, T, T> refop) where T : unmanaged => VerifyOp(code.CreateBinOp <T>(), refop, SampleSize);
static BinOpF64 CreateBinOpF64(this AsmCode code) => code.CreateDelegate <BinOpF64>();
static BinOpF32 CreateBinOpF32(this AsmCode code) => code.CreateDelegate <BinOpF32>();
static BinOpU16 CreateBinOpU16(this AsmCode code) => code.CreateDelegate <BinOpU16>();
static BinOpU8 CreateBinOpU8(this AsmCode code) => code.CreateDelegate <BinOpU8>();