ILOpCodeConst.cs 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. using System.Reflection.Emit;
  2. using System.Runtime.InteropServices;
  3. namespace ChocolArm64.Translation
  4. {
  5. class ILOpCodeConst : IILEmit
  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 ILOpCodeConst(ConstType type)
  25. {
  26. _type = type;
  27. }
  28. public ILOpCodeConst(int value) : this(ConstType.Int32)
  29. {
  30. _value = new ImmVal { I4 = value };
  31. }
  32. public ILOpCodeConst(long value) : this(ConstType.Int64)
  33. {
  34. _value = new ImmVal { I8 = value };
  35. }
  36. public ILOpCodeConst(float value) : this(ConstType.Single)
  37. {
  38. _value = new ImmVal { R4 = value };
  39. }
  40. public ILOpCodeConst(double value) : this(ConstType.Double)
  41. {
  42. _value = new ImmVal { R8 = value };
  43. }
  44. public void Emit(ILMethodBuilder 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. }