AInstEmitMemoryHelper.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using ChocolArm64.Memory;
  2. using ChocolArm64.Translation;
  3. using System;
  4. using System.Reflection.Emit;
  5. namespace ChocolArm64.Instruction
  6. {
  7. static class AInstEmitMemoryHelper
  8. {
  9. private enum Extension
  10. {
  11. Zx,
  12. Sx32,
  13. Sx64
  14. }
  15. public static void EmitReadZxCall(AILEmitterCtx Context, int Size)
  16. {
  17. EmitReadCall(Context, Extension.Zx, Size);
  18. }
  19. public static void EmitReadSx32Call(AILEmitterCtx Context, int Size)
  20. {
  21. EmitReadCall(Context, Extension.Sx32, Size);
  22. }
  23. public static void EmitReadSx64Call(AILEmitterCtx Context, int Size)
  24. {
  25. EmitReadCall(Context, Extension.Sx64, Size);
  26. }
  27. private static void EmitReadCall(AILEmitterCtx Context, Extension Ext, int Size)
  28. {
  29. if (Size < 0 || Size > 4)
  30. {
  31. throw new ArgumentOutOfRangeException(nameof(Size));
  32. }
  33. string Name = null;
  34. switch (Size)
  35. {
  36. case 0: Name = nameof(AMemory.ReadByte); break;
  37. case 1: Name = nameof(AMemory.ReadUInt16); break;
  38. case 2: Name = nameof(AMemory.ReadUInt32); break;
  39. case 3: Name = nameof(AMemory.ReadUInt64); break;
  40. case 4: Name = nameof(AMemory.ReadVector128); break;
  41. }
  42. Context.EmitCall(typeof(AMemory), Name);
  43. if (Ext == Extension.Sx32 ||
  44. Ext == Extension.Sx64)
  45. {
  46. switch (Size)
  47. {
  48. case 0: Context.Emit(OpCodes.Conv_I1); break;
  49. case 1: Context.Emit(OpCodes.Conv_I2); break;
  50. case 2: Context.Emit(OpCodes.Conv_I4); break;
  51. }
  52. }
  53. if (Size < 3)
  54. {
  55. Context.Emit(Ext == Extension.Sx64
  56. ? OpCodes.Conv_I8
  57. : OpCodes.Conv_U8);
  58. }
  59. }
  60. public static void EmitWriteCall(AILEmitterCtx Context, int Size)
  61. {
  62. if (Size < 0 || Size > 4)
  63. {
  64. throw new ArgumentOutOfRangeException(nameof(Size));
  65. }
  66. if (Size < 3)
  67. {
  68. Context.Emit(OpCodes.Conv_I4);
  69. }
  70. string Name = null;
  71. switch (Size)
  72. {
  73. case 0: Name = nameof(AMemory.WriteByte); break;
  74. case 1: Name = nameof(AMemory.WriteUInt16); break;
  75. case 2: Name = nameof(AMemory.WriteUInt32); break;
  76. case 3: Name = nameof(AMemory.WriteUInt64); break;
  77. case 4: Name = nameof(AMemory.WriteVector128); break;
  78. }
  79. Context.EmitCall(typeof(AMemory), Name);
  80. }
  81. }
  82. }