aoptcpu.pas 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. {
  2. Copyright (c) 1998-2004 by Jonas Maebe
  3. This unit calls the optimization procedures to optimize the assembler
  4. code for sparc
  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. {$ifdef EXTDEBUG}
  21. {$define DEBUG_AOPTCPU}
  22. {$endif EXTDEBUG}
  23. Interface
  24. uses
  25. cpubase, aoptobj, aoptcpub, aopt, aoptx86,
  26. aasmtai;
  27. Type
  28. TCpuAsmOptimizer = class(TX86AsmOptimizer)
  29. function PeepHoleOptPass1Cpu(var p : tai) : boolean; override;
  30. function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
  31. End;
  32. Implementation
  33. uses
  34. globals,
  35. verbose,
  36. cpuinfo,
  37. aasmcpu,
  38. aoptutils;
  39. function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p : tai) : boolean;
  40. var
  41. hp1 : tai;
  42. hp2 : tai;
  43. begin
  44. result:=false;
  45. case p.typ of
  46. ait_instruction:
  47. begin
  48. case taicpu(p).opcode of
  49. A_MOV:
  50. begin
  51. if MatchInstruction(p,A_MOV,[S_W]) and
  52. MatchOpType(taicpu(p),top_ref,top_reg) and
  53. GetNextInstruction(p, hp1) and
  54. MatchInstruction(hp1,A_MOV,[S_W]) and
  55. MatchOpType(taicpu(hp1),top_ref,top_reg) and
  56. GetNextInstruction(hp1, hp2) and
  57. MatchInstruction(hp2,A_MOV,[S_W]) and
  58. MatchOpType(taicpu(hp2),top_reg,top_reg) and
  59. not(OpsEqual(taicpu(p).oper[1]^,taicpu(hp1).oper[1]^)) and
  60. OpsEqual(taicpu(hp1).oper[1]^,taicpu(hp2).oper[0]^) and
  61. (MatchOperand(taicpu(hp2).oper[1]^,NR_ES) or MatchOperand(taicpu(hp2).oper[1]^,NR_DS) or
  62. ((current_settings.cputype>=cpu_386) and
  63. (MatchOperand(taicpu(hp2).oper[1]^,NR_SS) or
  64. MatchOperand(taicpu(hp2).oper[1]^,NR_FS) or
  65. MatchOperand(taicpu(hp2).oper[1]^,NR_GS)))) and
  66. (taicpu(p).oper[0]^.ref^.base=taicpu(hp1).oper[0]^.ref^.base) and
  67. (taicpu(p).oper[0]^.ref^.index=taicpu(hp1).oper[0]^.ref^.index) and
  68. (taicpu(p).oper[0]^.ref^.segment=taicpu(hp1).oper[0]^.ref^.segment) and
  69. (taicpu(p).oper[0]^.ref^.symbol=taicpu(hp1).oper[0]^.ref^.symbol) and
  70. (taicpu(p).oper[0]^.ref^.relsymbol=taicpu(hp1).oper[0]^.ref^.relsymbol) and
  71. (taicpu(p).oper[0]^.ref^.offset+2=taicpu(hp1).oper[0]^.ref^.offset) then
  72. begin
  73. case taicpu(hp2).oper[1]^.reg of
  74. NR_DS:
  75. taicpu(p).opcode:=A_LDS;
  76. NR_ES:
  77. taicpu(p).opcode:=A_LES;
  78. NR_SS:
  79. taicpu(p).opcode:=A_LSS;
  80. NR_FS:
  81. taicpu(p).opcode:=A_LFS;
  82. NR_GS:
  83. taicpu(p).opcode:=A_LGS;
  84. else
  85. internalerror(2015092601);
  86. end;
  87. if assigned(FindRegDealloc(taicpu(hp2).oper[0]^.reg,tai(hp2.Next))) then
  88. begin
  89. asml.remove(hp1);
  90. hp1.free;
  91. DebugMsg('Peephole optimizer MovMovMov2LXX',p);
  92. end
  93. else
  94. begin
  95. taicpu(hp1).loadreg(0,taicpu(hp2).oper[1]^.reg);
  96. DebugMsg('Peephole optimizer MovMovMov2LXXMov',p);
  97. end;
  98. asml.remove(hp2);
  99. hp2.free;
  100. result:=true;
  101. end
  102. else if MatchInstruction(p,A_MOV,[S_W]) and
  103. MatchOpType(taicpu(p),top_reg,top_reg) and
  104. GetNextInstruction(p, hp1) and
  105. MatchInstruction(hp1,A_PUSH,[S_W]) and
  106. MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[0]^) and
  107. assigned(FindRegDealloc(taicpu(hp1).oper[0]^.reg,tai(hp1.Next))) then
  108. begin
  109. DebugMsg('Peephole optimizer MovPush2Push',p);
  110. taicpu(hp1).loadreg(0,taicpu(p).oper[0]^.reg);
  111. { take care of the register (de)allocs following p }
  112. UpdateUsedRegs(tai(p.next));
  113. asml.remove(p);
  114. p.free;
  115. p:=hp1;
  116. result:=true;
  117. end;
  118. end;
  119. A_SUB:
  120. result:=OptPass1Sub(p);
  121. else
  122. ;
  123. end;
  124. end
  125. else
  126. ;
  127. end;
  128. end;
  129. function TCpuAsmOptimizer.PostPeepHoleOptsCpu(var p: tai): boolean;
  130. begin
  131. result := false;
  132. case p.typ of
  133. ait_instruction:
  134. begin
  135. case taicpu(p).opcode of
  136. {A_MOV commented out, because it still breaks some i8086 code :( }
  137. {A_MOV:
  138. Result:=PostPeepholeOptMov(p);}
  139. A_CMP:
  140. Result:=PostPeepholeOptCmp(p);
  141. A_OR,
  142. A_TEST:
  143. Result:=PostPeepholeOptTestOr(p);
  144. A_RET:
  145. Result:=PostPeepholeOptRET(p);
  146. else
  147. ;
  148. end;
  149. { Optimise any reference-type operands (if Result is True, the
  150. instruction will be checked on the next iteration) }
  151. if not Result then
  152. OptimizeRefs(taicpu(p));
  153. end;
  154. else
  155. ;
  156. end;
  157. end;
  158. begin
  159. casmoptimizer:=TCpuAsmOptimizer;
  160. end.