ILBlock.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. using System.Collections.Generic;
  2. namespace ChocolArm64.Translation
  3. {
  4. class ILBlock : IILEmit
  5. {
  6. public long IntInputs { get; private set; }
  7. public long IntOutputs { get; private set; }
  8. private long _intAwOutputs;
  9. public long VecInputs { get; private set; }
  10. public long VecOutputs { get; private set; }
  11. private long _vecAwOutputs;
  12. public bool HasStateStore { get; private set; }
  13. private List<IILEmit> _emitters;
  14. public int Count => _emitters.Count;
  15. public ILBlock Next { get; set; }
  16. public ILBlock Branch { get; set; }
  17. public ILBlock()
  18. {
  19. _emitters = new List<IILEmit>();
  20. }
  21. public void Add(IILEmit emitter)
  22. {
  23. if (emitter is ILBarrier)
  24. {
  25. //Those barriers are used to separate the groups of CIL
  26. //opcodes emitted by each ARM instruction.
  27. //We can only consider the new outputs for doing input elimination
  28. //after all the CIL opcodes used by the instruction being emitted.
  29. _intAwOutputs = IntOutputs;
  30. _vecAwOutputs = VecOutputs;
  31. }
  32. else if (emitter is ILOpCodeLoad ld && ILMethodBuilder.IsRegIndex(ld.Index))
  33. {
  34. switch (ld.VarType)
  35. {
  36. case VarType.Flag: IntInputs |= ((1L << ld.Index) << 32) & ~_intAwOutputs; break;
  37. case VarType.Int: IntInputs |= (1L << ld.Index) & ~_intAwOutputs; break;
  38. case VarType.Vector: VecInputs |= (1L << ld.Index) & ~_vecAwOutputs; break;
  39. }
  40. }
  41. else if (emitter is ILOpCodeStore st && ILMethodBuilder.IsRegIndex(st.Index))
  42. {
  43. switch (st.VarType)
  44. {
  45. case VarType.Flag: IntOutputs |= (1L << st.Index) << 32; break;
  46. case VarType.Int: IntOutputs |= 1L << st.Index; break;
  47. case VarType.Vector: VecOutputs |= 1L << st.Index; break;
  48. }
  49. }
  50. else if (emitter is ILOpCodeStoreState)
  51. {
  52. HasStateStore = true;
  53. }
  54. _emitters.Add(emitter);
  55. }
  56. public void Emit(ILMethodBuilder context)
  57. {
  58. foreach (IILEmit ilEmitter in _emitters)
  59. {
  60. ilEmitter.Emit(context);
  61. }
  62. }
  63. }
  64. }