AInstEmitSystem.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using ChocolArm64.Decoder;
  2. using ChocolArm64.State;
  3. using ChocolArm64.Translation;
  4. using System;
  5. using System.Reflection;
  6. using System.Reflection.Emit;
  7. namespace ChocolArm64.Instruction
  8. {
  9. static partial class AInstEmit
  10. {
  11. public static void Hint(AILEmitterCtx Context)
  12. {
  13. //Execute as no-op.
  14. }
  15. public static void Mrs(AILEmitterCtx Context)
  16. {
  17. AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;
  18. Context.EmitLdarg(ATranslatedSub.StateArgIdx);
  19. string PropName;
  20. switch (GetPackedId(Op))
  21. {
  22. case 0b11_011_0000_0000_001: PropName = nameof(AThreadState.CtrEl0); break;
  23. case 0b11_011_0000_0000_111: PropName = nameof(AThreadState.DczidEl0); break;
  24. case 0b11_011_0100_0100_000: PropName = nameof(AThreadState.Fpcr); break;
  25. case 0b11_011_0100_0100_001: PropName = nameof(AThreadState.Fpsr); break;
  26. case 0b11_011_1101_0000_010: PropName = nameof(AThreadState.TpidrEl0); break;
  27. case 0b11_011_1101_0000_011: PropName = nameof(AThreadState.Tpidr); break;
  28. case 0b11_011_1110_0000_001: PropName = nameof(AThreadState.CntpctEl0); break;
  29. default: throw new NotImplementedException($"Unknown MRS at {Op.Position:x16}");
  30. }
  31. Context.EmitCallPropGet(typeof(AThreadState), PropName);
  32. PropertyInfo PropInfo = typeof(AThreadState).GetProperty(PropName);
  33. if (PropInfo.PropertyType != typeof(long) &&
  34. PropInfo.PropertyType != typeof(ulong))
  35. {
  36. Context.Emit(OpCodes.Conv_U8);
  37. }
  38. Context.EmitStintzr(Op.Rt);
  39. }
  40. public static void Msr(AILEmitterCtx Context)
  41. {
  42. AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;
  43. Context.EmitLdarg(ATranslatedSub.StateArgIdx);
  44. Context.EmitLdintzr(Op.Rt);
  45. string PropName;
  46. switch (GetPackedId(Op))
  47. {
  48. case 0b11_011_0100_0100_000: PropName = nameof(AThreadState.Fpcr); break;
  49. case 0b11_011_0100_0100_001: PropName = nameof(AThreadState.Fpsr); break;
  50. case 0b11_011_1101_0000_010: PropName = nameof(AThreadState.TpidrEl0); break;
  51. default: throw new NotImplementedException($"Unknown MSR at {Op.Position:x16}");
  52. }
  53. PropertyInfo PropInfo = typeof(AThreadState).GetProperty(PropName);
  54. if (PropInfo.PropertyType != typeof(long) &&
  55. PropInfo.PropertyType != typeof(ulong))
  56. {
  57. Context.Emit(OpCodes.Conv_U4);
  58. }
  59. Context.EmitCallPropSet(typeof(AThreadState), PropName);
  60. }
  61. public static void Nop(AILEmitterCtx Context)
  62. {
  63. //Do nothing.
  64. }
  65. public static void Sys(AILEmitterCtx Context)
  66. {
  67. //This instruction is used to do some operations on the CPU like cache invalidation,
  68. //address translation and the like.
  69. //We treat it as no-op here since we don't have any cache being emulated anyway.
  70. AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;
  71. switch (GetPackedId(Op))
  72. {
  73. case 0b11_011_0111_0100_001:
  74. {
  75. //DC ZVA
  76. for (int Offs = 0; Offs < (4 << AThreadState.DczSizeLog2); Offs += 8)
  77. {
  78. Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
  79. Context.EmitLdint(Op.Rt);
  80. Context.EmitLdc_I(Offs);
  81. Context.Emit(OpCodes.Add);
  82. Context.EmitLdc_I8(0);
  83. AInstEmitMemoryHelper.EmitWriteCall(Context, 3);
  84. }
  85. break;
  86. }
  87. }
  88. }
  89. private static int GetPackedId(AOpCodeSystem Op)
  90. {
  91. int Id;
  92. Id = Op.Op2 << 0;
  93. Id |= Op.CRm << 3;
  94. Id |= Op.CRn << 7;
  95. Id |= Op.Op1 << 11;
  96. Id |= Op.Op0 << 14;
  97. return Id;
  98. }
  99. }
  100. }