aoptcpu.pas 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. {
  2. Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
  3. Development Team
  4. This unit implements the ARM optimizer object
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. Unit aoptcpu;
  19. {$i fpcdefs.inc}
  20. Interface
  21. uses cpubase, aopt, aoptcpub;
  22. Type
  23. TCpuAsmOptimizer = class(TAsmOptimizer)
  24. { uses the same constructor as TAopObj }
  25. procedure PeepHoleOptPass2;override;
  26. End;
  27. Implementation
  28. uses
  29. aasmbase,aasmtai,aasmcpu;
  30. function CanBeCond(p : tai) : boolean;
  31. begin
  32. result:=true;
  33. end;
  34. procedure TCpuAsmOptimizer.PeepHoleOptPass2;
  35. var
  36. p,hp1,hp2: tai;
  37. l : longint;
  38. condition : tasmcond;
  39. hp3: tai;
  40. { UsedRegs, TmpUsedRegs: TRegSet; }
  41. begin
  42. exit; { deactived, not working yet FK }
  43. p := BlockStart;
  44. { UsedRegs := []; }
  45. while (p <> BlockEnd) Do
  46. begin
  47. { UpdateUsedRegs(UsedRegs, tai(p.next)); }
  48. case p.Typ Of
  49. Ait_Instruction:
  50. begin
  51. case taicpu(p).opcode Of
  52. A_B:
  53. if taicpu(p).condition<>C_None then
  54. begin
  55. { check for
  56. Bxx xxx
  57. <several instructions>
  58. xxx:
  59. }
  60. l:=0;
  61. GetNextInstruction(p, hp1);
  62. while assigned(hp1) and
  63. (l<=4) and
  64. CanBeCond(hp1) and
  65. { stop on labels }
  66. not(hp1.typ=ait_label) do
  67. begin
  68. inc(l);
  69. GetNextInstruction(hp1,hp1);
  70. end;
  71. if assigned(hp1) then
  72. begin
  73. if FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol),hp1) then
  74. begin
  75. if (l<=4) and (l>0) then
  76. begin
  77. condition:=inverse_cond(taicpu(p).condition);
  78. hp2:=p;
  79. GetNextInstruction(p,hp1);
  80. p:=hp1;
  81. repeat
  82. if hp1.typ=ait_instruction then
  83. taicpu(hp1).condition:=condition;
  84. GetNextInstruction(hp1,hp1);
  85. until not(assigned(hp1)) or
  86. not(CanBeCond(hp1)) or
  87. (hp1.typ=ait_label);
  88. { wait with removing else GetNextInstruction could
  89. ignore the label if it was the only usage in the
  90. jump moved away }
  91. tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol).decrefs;
  92. asml.remove(hp2);
  93. hp2.free;
  94. continue;
  95. end;
  96. end
  97. else
  98. begin
  99. { check further for
  100. Bcc xxx
  101. <several movs 1>
  102. B yyy
  103. xxx:
  104. <several movs 2>
  105. yyy:
  106. }
  107. { hp2 points to jmp yyy }
  108. hp2:=hp1;
  109. { skip hp1 to xxx }
  110. GetNextInstruction(hp1, hp1);
  111. if assigned(hp2) and
  112. assigned(hp1) and
  113. (l<=3) and
  114. (hp2.typ=ait_instruction) and
  115. (taicpu(hp2).is_jmp) and
  116. (taicpu(hp2).condition=C_None) and
  117. { real label and jump, no further references to the
  118. label are allowed }
  119. (tasmlabel(taicpu(p).oper[0]^.ref^.symbol).getrefs=2) and
  120. FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol),hp1) then
  121. begin
  122. l:=0;
  123. { skip hp1 to <several moves 2> }
  124. GetNextInstruction(hp1, hp1);
  125. while assigned(hp1) and
  126. CanBeCond(hp1) do
  127. begin
  128. inc(l);
  129. GetNextInstruction(hp1, hp1);
  130. end;
  131. { hp1 points to yyy: }
  132. if assigned(hp1) and
  133. FindLabel(tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol),hp1) then
  134. begin
  135. condition:=inverse_cond(taicpu(p).condition);
  136. GetNextInstruction(p,hp1);
  137. hp3:=p;
  138. p:=hp1;
  139. repeat
  140. if hp1.typ=ait_instruction then
  141. taicpu(hp1).condition:=condition;
  142. GetNextInstruction(hp1,hp1);
  143. until not(assigned(hp1)) or
  144. not(CanBeCond(hp1));
  145. { hp2 is still at jmp yyy }
  146. GetNextInstruction(hp2,hp1);
  147. { hp2 is now at xxx: }
  148. condition:=inverse_cond(condition);
  149. GetNextInstruction(hp1,hp1);
  150. { hp1 is now at <several movs 2> }
  151. repeat
  152. taicpu(hp1).condition:=condition;
  153. GetNextInstruction(hp1,hp1);
  154. until not(assigned(hp1)) or
  155. not(CanBeCond(hp1)) or
  156. (hp1.typ=ait_label);
  157. {
  158. asml.remove(hp1.next)
  159. hp1.next.free;
  160. asml.remove(hp1);
  161. hp1.free;
  162. }
  163. { remove Bcc }
  164. tasmlabel(taicpu(hp3).oper[0]^.ref^.symbol).decrefs;
  165. asml.remove(hp3);
  166. hp3.free;
  167. { remove jmp }
  168. tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol).decrefs;
  169. asml.remove(hp2);
  170. hp2.free;
  171. continue;
  172. end;
  173. end;
  174. end;
  175. end;
  176. end;
  177. end;
  178. end;
  179. end;
  180. p := tai(p.next)
  181. end;
  182. end;
  183. begin
  184. casmoptimizer:=TCpuAsmOptimizer;
  185. End.