ILOpCodeConst.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  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. public long Value => _value.I8;
  17. private enum ConstType
  18. {
  19. Int32,
  20. Int64,
  21. Single,
  22. Double
  23. }
  24. private ConstType _type;
  25. private ILOpCodeConst(ConstType type)
  26. {
  27. _type = type;
  28. }
  29. public ILOpCodeConst(int value) : this(ConstType.Int32)
  30. {
  31. _value = new ImmVal { I4 = value };
  32. }
  33. public ILOpCodeConst(long value) : this(ConstType.Int64)
  34. {
  35. _value = new ImmVal { I8 = value };
  36. }
  37. public ILOpCodeConst(float value) : this(ConstType.Single)
  38. {
  39. _value = new ImmVal { R4 = value };
  40. }
  41. public ILOpCodeConst(double value) : this(ConstType.Double)
  42. {
  43. _value = new ImmVal { R8 = value };
  44. }
  45. public void Emit(ILMethodBuilder context)
  46. {
  47. switch (_type)
  48. {
  49. case ConstType.Int32: context.Generator.EmitLdc_I4(_value.I4); break;
  50. case ConstType.Int64: context.Generator.Emit(OpCodes.Ldc_I8, _value.I8); break;
  51. case ConstType.Single: context.Generator.Emit(OpCodes.Ldc_R4, _value.R4); break;
  52. case ConstType.Double: context.Generator.Emit(OpCodes.Ldc_R8, _value.R8); break;
  53. }
  54. }
  55. }
  56. }