ILOpCodeLoadState.cs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. using ChocolArm64.State;
  2. using System.Reflection.Emit;
  3. namespace ChocolArm64.Translation
  4. {
  5. struct ILOpCodeLoadState : IILEmit
  6. {
  7. private ILBlock _block;
  8. private bool _isSubEntry;
  9. public ILOpCodeLoadState(ILBlock block, bool isSubEntry = false)
  10. {
  11. _block = block;
  12. _isSubEntry = isSubEntry;
  13. }
  14. public void Emit(ILMethodBuilder context)
  15. {
  16. long intInputs = context.RegUsage.GetIntInputs(_block);
  17. long vecInputs = context.RegUsage.GetVecInputs(_block);
  18. if (Optimizations.AssumeStrictAbiCompliance && context.IsSubComplete)
  19. {
  20. intInputs = RegisterUsage.ClearCallerSavedIntRegs(intInputs, context.IsAarch64);
  21. vecInputs = RegisterUsage.ClearCallerSavedVecRegs(vecInputs, context.IsAarch64);
  22. }
  23. LoadLocals(context, intInputs, RegisterType.Int);
  24. LoadLocals(context, vecInputs, RegisterType.Vector);
  25. }
  26. private void LoadLocals(ILMethodBuilder context, long inputs, RegisterType baseType)
  27. {
  28. for (int bit = 0; bit < 64; bit++)
  29. {
  30. long mask = 1L << bit;
  31. if ((inputs & mask) != 0)
  32. {
  33. Register reg = ILMethodBuilder.GetRegFromBit(bit, baseType);
  34. context.Generator.EmitLdarg(TranslatedSub.StateArgIdx);
  35. context.Generator.Emit(OpCodes.Ldfld, reg.GetField());
  36. context.Generator.EmitStloc(context.GetLocalIndex(reg));
  37. }
  38. }
  39. }
  40. }
  41. }