ILBlock.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. public long IntAwOutputs { get; private set; }
  9. public long VecInputs { get; private set; }
  10. public long VecOutputs { get; private set; }
  11. public long VecAwOutputs { get; private set; }
  12. public bool HasStateStore { get; private set; }
  13. public List<IILEmit> IlEmitters { get; private set; }
  14. public ILBlock Next { get; set; }
  15. public ILBlock Branch { get; set; }
  16. public ILBlock()
  17. {
  18. IlEmitters = new List<IILEmit>();
  19. }
  20. public void Add(IILEmit ilEmitter)
  21. {
  22. if (ilEmitter is ILBarrier)
  23. {
  24. //Those barriers are used to separate the groups of CIL
  25. //opcodes emitted by each ARM instruction.
  26. //We can only consider the new outputs for doing input elimination
  27. //after all the CIL opcodes used by the instruction being emitted.
  28. IntAwOutputs = IntOutputs;
  29. VecAwOutputs = VecOutputs;
  30. }
  31. else if (ilEmitter is IlOpCodeLoad ld && ILEmitter.IsRegIndex(ld.Index))
  32. {
  33. switch (ld.IoType)
  34. {
  35. case IoType.Flag: IntInputs |= ((1L << ld.Index) << 32) & ~IntAwOutputs; break;
  36. case IoType.Int: IntInputs |= (1L << ld.Index) & ~IntAwOutputs; break;
  37. case IoType.Vector: VecInputs |= (1L << ld.Index) & ~VecAwOutputs; break;
  38. }
  39. }
  40. else if (ilEmitter is IlOpCodeStore st)
  41. {
  42. if (ILEmitter.IsRegIndex(st.Index))
  43. {
  44. switch (st.IoType)
  45. {
  46. case IoType.Flag: IntOutputs |= (1L << st.Index) << 32; break;
  47. case IoType.Int: IntOutputs |= 1L << st.Index; break;
  48. case IoType.Vector: VecOutputs |= 1L << st.Index; break;
  49. }
  50. }
  51. if (st.IoType == IoType.Fields)
  52. {
  53. HasStateStore = true;
  54. }
  55. }
  56. IlEmitters.Add(ilEmitter);
  57. }
  58. public void Emit(ILEmitter context)
  59. {
  60. foreach (IILEmit ilEmitter in IlEmitters)
  61. {
  62. ilEmitter.Emit(context);
  63. }
  64. }
  65. }
  66. }