diff options
Diffstat (limited to 'Ryujinx/Cpu/Translation/AILConv.cs')
| -rw-r--r-- | Ryujinx/Cpu/Translation/AILConv.cs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/Ryujinx/Cpu/Translation/AILConv.cs b/Ryujinx/Cpu/Translation/AILConv.cs new file mode 100644 index 00000000..8969dc4e --- /dev/null +++ b/Ryujinx/Cpu/Translation/AILConv.cs @@ -0,0 +1,113 @@ +using ChocolArm64.State; +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace ChocolArm64.Translation +{ + static class AILConv + { + public static void EmitConv(AILEmitter Context, Type SrcType, Type TgtType) + { + if (SrcType == TgtType) + { + //If both types are equal we don't need to cast anything. + return; + } + + if (SrcType.IsPrimitive) + { + if (TgtType == typeof(byte)) + { + Context.Generator.Emit(OpCodes.Conv_U1); + } + else if (TgtType == typeof(ushort)) + { + Context.Generator.Emit(OpCodes.Conv_U2); + } + else if (TgtType == typeof(uint)) + { + Context.Generator.Emit(OpCodes.Conv_U4); + } + else if (TgtType == typeof(ulong)) + { + Context.Generator.Emit(OpCodes.Conv_U8); + } + else if (TgtType == typeof(float)) + { + Context.Generator.Emit(OpCodes.Conv_R4); + } + else if (TgtType == typeof(double)) + { + Context.Generator.Emit(OpCodes.Conv_R8); + } + else if (TgtType == typeof(AVec)) + { + EmitMakeVec(Context, SrcType); + } + else + { + throw new ArgumentException(nameof(TgtType)); + } + } + else if (SrcType == typeof(AVec)) + { + if (TgtType == typeof(float)) + { + EmitScalarLdfld(Context, nameof(AVec.S0)); + } + else if (TgtType == typeof(double)) + { + EmitScalarLdfld(Context, nameof(AVec.D0)); + } + else if (TgtType == typeof(byte)) + { + EmitScalarLdfld(Context, nameof(AVec.B0)); + } + else if (TgtType == typeof(ushort)) + { + EmitScalarLdfld(Context, nameof(AVec.H0)); + } + else if (TgtType == typeof(uint)) + { + EmitScalarLdfld(Context, nameof(AVec.W0)); + } + else if (TgtType == typeof(ulong)) + { + EmitScalarLdfld(Context, nameof(AVec.X0)); + } + else + { + throw new ArgumentException(nameof(TgtType)); + } + } + else + { + throw new ArgumentException(nameof(SrcType)); + } + } + + private static void EmitScalarLdfld(AILEmitter Context,string FldName) + { + Context.Generator.Emit(OpCodes.Ldfld, typeof(AVec).GetField(FldName)); + } + + private static void EmitMakeVec(AILEmitter Context, Type SrcType) + { + string MthdName = nameof(MakeScalar); + + Type[] MthdTypes = new Type[] { SrcType }; + + MethodInfo MthdInfo = typeof(AILConv).GetMethod(MthdName, MthdTypes); + + Context.Generator.Emit(OpCodes.Call, MthdInfo); + } + + public static AVec MakeScalar(byte Value) => new AVec { B0 = Value }; + public static AVec MakeScalar(ushort Value) => new AVec { H0 = Value }; + public static AVec MakeScalar(uint Value) => new AVec { W0 = Value }; + public static AVec MakeScalar(float Value) => new AVec { S0 = Value }; + public static AVec MakeScalar(ulong Value) => new AVec { X0 = Value }; + public static AVec MakeScalar(double Value) => new AVec { D0 = Value }; + } +}
\ No newline at end of file |
