AILOpCodeStore.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using ChocolArm64.State;
  2. using System;
  3. using System.Reflection.Emit;
  4. namespace ChocolArm64.Translation
  5. {
  6. struct AILOpCodeStore : IAILEmit
  7. {
  8. public AIoType IoType { get; private set; }
  9. public Type OperType { get; private set; }
  10. public int Index { get; private set; }
  11. public AILOpCodeStore(int Index, AIoType IoType) : this(Index, IoType, null) { }
  12. public AILOpCodeStore(int Index, AIoType IoType, Type OperType)
  13. {
  14. this.IoType = IoType;
  15. this.Index = Index;
  16. this.OperType = OperType;
  17. }
  18. public void Emit(AILEmitter Context)
  19. {
  20. switch (IoType & AIoType.Mask)
  21. {
  22. case AIoType.Arg: EmitStarg(Context, Index); break;
  23. case AIoType.Fields: EmitStfld(Context, Index); break;
  24. case AIoType.Flag: EmitStloc(Context, Index, ARegisterType.Flag); break;
  25. case AIoType.Int: EmitStloc(Context, Index, ARegisterType.Int); break;
  26. case AIoType.Vector: EmitStloc(Context, Index, ARegisterType.Vector); break;
  27. }
  28. }
  29. private void EmitStarg(AILEmitter Context, int Index)
  30. {
  31. Context.Generator.EmitStarg(Index);
  32. }
  33. private void EmitStfld(AILEmitter Context, int Index)
  34. {
  35. long IntOutputs = Context.LocalAlloc.GetIntOutputs(Context.GetILBlock(Index));
  36. long VecOutputs = Context.LocalAlloc.GetVecOutputs(Context.GetILBlock(Index));
  37. StoreLocals(Context, IntOutputs, ARegisterType.Int);
  38. StoreLocals(Context, VecOutputs, ARegisterType.Vector);
  39. }
  40. private void StoreLocals(AILEmitter Context, long Outputs, ARegisterType BaseType)
  41. {
  42. for (int Bit = 0; Bit < 64; Bit++)
  43. {
  44. long Mask = 1L << Bit;
  45. if ((Outputs & Mask) != 0)
  46. {
  47. ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType);
  48. Context.Generator.EmitLdarg(ATranslatedSub.RegistersArgIdx);
  49. Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg));
  50. AILConv.EmitConv(
  51. Context,
  52. Context.GetLocalType(Reg),
  53. Context.GetFieldType(Reg.Type));
  54. Context.Generator.Emit(OpCodes.Stfld, Reg.GetField());
  55. }
  56. }
  57. }
  58. private void EmitStloc(AILEmitter Context, int Index, ARegisterType Type)
  59. {
  60. ARegister Reg = new ARegister(Index, Type);
  61. AILConv.EmitConv(Context, OperType, Context.GetLocalType(Reg));
  62. Context.Generator.EmitStloc(Context.GetLocalIndex(Reg));
  63. }
  64. }
  65. }