aoptx86.pas 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. {
  2. Copyright (c) 1998-2002 by Florian Klaempfl and Jonas Maebe
  3. This unit contains the peephole optimizer.
  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 aoptx86;
  18. {$i fpcdefs.inc}
  19. { $define DEBUG_AOPTCPU}
  20. interface
  21. uses
  22. globtype,
  23. cpubase,
  24. aasmtai,
  25. cgbase,cgutils;
  26. function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
  27. function MatchInstruction(const instr: tai; const op1,op2: TAsmOp; const opsize: topsizes): boolean;
  28. function MatchInstruction(const instr: tai; const op1,op2,op3: TAsmOp; const opsize: topsizes): boolean;
  29. function MatchOperand(const oper: TOper; const reg: TRegister): boolean; inline;
  30. function MatchOperand(const oper: TOper; const a: tcgint): boolean; inline;
  31. function MatchOperand(const oper1: TOper; const oper2: TOper): boolean;
  32. function RefsEqual(const r1, r2: treference): boolean;
  33. function MatchReference(const ref : treference;base,index : TRegister) : Boolean;
  34. function MatchOpType(const instr : tai;ot0,ot1 : toptype) : Boolean;
  35. implementation
  36. uses
  37. verbose,
  38. aasmcpu;
  39. function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
  40. begin
  41. result :=
  42. (instr.typ = ait_instruction) and
  43. (taicpu(instr).opcode = op) and
  44. ((opsize = []) or (taicpu(instr).opsize in opsize));
  45. end;
  46. function MatchInstruction(const instr: tai; const op1,op2: TAsmOp; const opsize: topsizes): boolean;
  47. begin
  48. result :=
  49. (instr.typ = ait_instruction) and
  50. ((taicpu(instr).opcode = op1) or
  51. (taicpu(instr).opcode = op2)
  52. ) and
  53. ((opsize = []) or (taicpu(instr).opsize in opsize));
  54. end;
  55. function MatchInstruction(const instr: tai; const op1,op2,op3: TAsmOp; const opsize: topsizes): boolean;
  56. begin
  57. result :=
  58. (instr.typ = ait_instruction) and
  59. ((taicpu(instr).opcode = op1) or
  60. (taicpu(instr).opcode = op2) or
  61. (taicpu(instr).opcode = op3)
  62. ) and
  63. ((opsize = []) or (taicpu(instr).opsize in opsize));
  64. end;
  65. function MatchOperand(const oper: TOper; const reg: TRegister): boolean; inline;
  66. begin
  67. result := (oper.typ = top_reg) and (oper.reg = reg);
  68. end;
  69. function MatchOperand(const oper: TOper; const a: tcgint): boolean; inline;
  70. begin
  71. result := (oper.typ = top_const) and (oper.val = a);
  72. end;
  73. function MatchOperand(const oper1: TOper; const oper2: TOper): boolean;
  74. begin
  75. result := oper1.typ = oper2.typ;
  76. if result then
  77. case oper1.typ of
  78. top_const:
  79. Result:=oper1.val = oper2.val;
  80. top_reg:
  81. Result:=oper1.reg = oper2.reg;
  82. top_ref:
  83. Result:=RefsEqual(oper1.ref^, oper2.ref^);
  84. else
  85. internalerror(2013102801);
  86. end
  87. end;
  88. function RefsEqual(const r1, r2: treference): boolean;
  89. begin
  90. RefsEqual :=
  91. (r1.offset = r2.offset) and
  92. (r1.segment = r2.segment) and (r1.base = r2.base) and
  93. (r1.index = r2.index) and (r1.scalefactor = r2.scalefactor) and
  94. (r1.symbol=r2.symbol) and (r1.refaddr = r2.refaddr) and
  95. (r1.relsymbol = r2.relsymbol);
  96. end;
  97. function MatchReference(const ref : treference;base,index : TRegister) : Boolean;
  98. begin
  99. Result:=(ref.offset=0) and
  100. (ref.scalefactor in [0,1]) and
  101. (ref.segment=NR_NO) and
  102. (ref.symbol=nil) and
  103. (ref.relsymbol=nil) and
  104. ((base=NR_INVALID) or
  105. (ref.base=base)) and
  106. ((index=NR_INVALID) or
  107. (ref.index=index));
  108. end;
  109. function MatchOpType(const instr : tai;ot0,ot1 : toptype) : Boolean;
  110. begin
  111. Result:=(taicpu(instr).ops=2) and
  112. (taicpu(instr).oper[0]^.typ=ot0) and
  113. (taicpu(instr).oper[1]^.typ=ot1);
  114. end;
  115. end.