AILOpCodeConst.cs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using System.Reflection.Emit;
  2. using System.Runtime.InteropServices;
  3. namespace ChocolArm64.Translation
  4. {
  5. class AILOpCodeConst : IAILEmit
  6. {
  7. [StructLayout(LayoutKind.Explicit, Size = 8)]
  8. private struct ImmVal
  9. {
  10. [FieldOffset(0)] public int I4;
  11. [FieldOffset(0)] public long I8;
  12. [FieldOffset(0)] public float R4;
  13. [FieldOffset(0)] public double R8;
  14. }
  15. private ImmVal Value;
  16. private enum ConstType
  17. {
  18. Int32,
  19. Int64,
  20. Single,
  21. Double
  22. }
  23. private ConstType Type;
  24. private AILOpCodeConst(ConstType Type)
  25. {
  26. this.Type = Type;
  27. }
  28. public AILOpCodeConst(int Value) : this(ConstType.Int32)
  29. {
  30. this.Value = new ImmVal { I4 = Value };
  31. }
  32. public AILOpCodeConst(long Value) : this(ConstType.Int64)
  33. {
  34. this.Value = new ImmVal { I8 = Value };
  35. }
  36. public AILOpCodeConst(float Value) : this(ConstType.Single)
  37. {
  38. this.Value = new ImmVal { R4 = Value };
  39. }
  40. public AILOpCodeConst(double Value) : this(ConstType.Double)
  41. {
  42. this.Value = new ImmVal { R8 = Value };
  43. }
  44. public void Emit(AILEmitter Context)
  45. {
  46. switch (Type)
  47. {
  48. case ConstType.Int32: Context.Generator.EmitLdc_I4(Value.I4); break;
  49. case ConstType.Int64: Context.Generator.Emit(OpCodes.Ldc_I8, Value.I8); break;
  50. case ConstType.Single: Context.Generator.Emit(OpCodes.Ldc_R4, Value.R4); break;
  51. case ConstType.Double: Context.Generator.Emit(OpCodes.Ldc_R8, Value.R8); break;
  52. }
  53. }
  54. }
  55. }