cpuext.pas 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. {
  2. Copyright (c) 2024 by Kirill Kranz
  3. This unit contains the CPU specific part of inserting a NOP on a Read After Write dependency
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit cpuext;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cutils,
  22. globtype, symdef,
  23. procinfo, cpuinfo, cpupara,
  24. psub, aasmdata, cgutils, aasmtai;
  25. procedure resolveReadAfterWrite(list: TAsmList);
  26. implementation
  27. uses
  28. systems, globals, verbose, sysutils, cclasses,
  29. cpubase, cgbase, cgobj,
  30. tgobj, paramgr, symconst, symcpu, aasmcpu;
  31. procedure resolveReadAfterWrite(list: TAsmList);
  32. label skip;
  33. var
  34. p, pp : tai;
  35. l, x : TLinkedListItem;
  36. firstReg : tregister;
  37. begin
  38. l:= list.first;
  39. while assigned(l) do begin
  40. p:= tai(l);
  41. if p.typ = ait_instruction then begin
  42. if (taicpu(p).opcode = A_LB) or (taicpu(p).opcode = A_LBU) or
  43. (taicpu(p).opcode = A_LH) or (taicpu(p).opcode = A_LHU) or
  44. (taicpu(p).opcode = A_LW) or (taicpu(p).opcode = A_LWU) or
  45. (taicpu(p).opcode = A_LWL) or (taicpu(p).opcode = A_LWR) or
  46. (taicpu(p).opcode = A_MFC0) {MFC2} {LWC2} then begin
  47. firstReg:= taicpu(p).oper[0]^.reg;
  48. x:= l.next;
  49. pp:= tai(x);
  50. while pp.typ <> ait_instruction do begin
  51. x:= x.next;
  52. pp:= tai(x);
  53. end;
  54. if pp.typ = ait_instruction then begin
  55. if (taicpu(p).opcode = A_LWL) and (taicpu(pp).opcode = A_LWR) then goto skip;
  56. if (taicpu(p).opcode = A_LWR) and (taicpu(pp).opcode = A_LWL) then goto skip;
  57. if taicpu(pp).ops > 0 then begin
  58. if taicpu(pp).ops = 1 then
  59. if (taicpu(pp).oper[0]^.typ = top_reg) and (firstReg = taicpu(pp).oper[0]^.reg) then
  60. list.insertAfter(taicpu.op_none(A_NOP), l);
  61. if taicpu(pp).ops = 2 then
  62. if ((taicpu(pp).oper[0]^.typ = top_reg) and (firstReg = taicpu(pp).oper[0]^.reg))
  63. or ((taicpu(pp).oper[1]^.typ = top_reg) and (firstReg = taicpu(pp).oper[1]^.reg))
  64. or ((taicpu(pp).oper[1]^.typ = top_ref) and (firstReg = taicpu(pp).oper[1]^.ref^.base))
  65. then
  66. list.insertAfter(taicpu.op_none(A_NOP), l);
  67. if taicpu(pp).ops = 3 then
  68. if ((taicpu(pp).oper[0]^.typ = top_reg) and (firstReg = taicpu(pp).oper[0]^.reg)) or
  69. ((taicpu(pp).oper[1]^.typ = top_reg) and (firstReg = taicpu(pp).oper[1]^.reg)) or
  70. ((taicpu(pp).oper[2]^.typ = top_reg) and (firstReg = taicpu(pp).oper[2]^.reg))
  71. then
  72. list.insertAfter(taicpu.op_none(A_NOP), l);
  73. end;
  74. end;
  75. end;
  76. end;
  77. skip:
  78. l:= l.next;
  79. end;
  80. end;
  81. begin
  82. end.