AILOpCodeLoad.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using ChocolArm64.State;
  2. using System;
  3. using System.Reflection.Emit;
  4. namespace ChocolArm64.Translation
  5. {
  6. struct AILOpCodeLoad : IAILEmit
  7. {
  8. public int Index { get; private set; }
  9. public AIoType IoType { get; private set; }
  10. public Type OperType { get; private set; }
  11. public AILOpCodeLoad(int Index, AIoType IoType) : this(Index, IoType, null) { }
  12. public AILOpCodeLoad(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: EmitLdarg(Context, Index); break;
  23. case AIoType.Fields: EmitLdfld(Context, Index); break;
  24. case AIoType.Flag: EmitLdloc(Context, Index, ARegisterType.Flag); break;
  25. case AIoType.Int: EmitLdloc(Context, Index, ARegisterType.Int); break;
  26. case AIoType.Vector: EmitLdloc(Context, Index, ARegisterType.Vector); break;
  27. }
  28. }
  29. private void EmitLdarg(AILEmitter Context, int Index)
  30. {
  31. Context.Generator.EmitLdarg(Index);
  32. }
  33. private void EmitLdfld(AILEmitter Context, int Index)
  34. {
  35. long IntInputs = Context.LocalAlloc.GetIntInputs(Context.GetILBlock(Index));
  36. long VecInputs = Context.LocalAlloc.GetVecInputs(Context.GetILBlock(Index));
  37. LoadLocals(Context, IntInputs, ARegisterType.Int);
  38. LoadLocals(Context, VecInputs, ARegisterType.Vector);
  39. }
  40. private void LoadLocals(AILEmitter Context, long Inputs, ARegisterType BaseType)
  41. {
  42. for (int Bit = 0; Bit < 64; Bit++)
  43. {
  44. long Mask = 1L << Bit;
  45. if ((Inputs & Mask) != 0)
  46. {
  47. ARegister Reg = AILEmitter.GetRegFromBit(Bit, BaseType);
  48. Context.Generator.EmitLdarg(ATranslatedSub.RegistersArgIdx);
  49. Context.Generator.Emit(OpCodes.Ldfld, Reg.GetField());
  50. AILConv.EmitConv(
  51. Context,
  52. Context.GetFieldType(Reg.Type),
  53. Context.GetLocalType(Reg));
  54. Context.Generator.EmitStloc(Context.GetLocalIndex(Reg));
  55. }
  56. }
  57. }
  58. private void EmitLdloc(AILEmitter Context, int Index, ARegisterType Type)
  59. {
  60. ARegister Reg = new ARegister(Index, Type);
  61. Context.Generator.EmitLdloc(Context.GetLocalIndex(Reg));
  62. AILConv.EmitConv(Context, Context.GetLocalType(Reg), OperType);
  63. }
  64. }
  65. }