aoptcpu.pas 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. {
  2. Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
  3. Development Team
  4. This unit implements the LoongArch64 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. interface
  20. {$I fpcdefs.inc}
  21. {$ifdef EXTDEBUG}
  22. {$define DEBUG_AOPTCPU}
  23. {$endif EXTDEBUG}
  24. uses
  25. cpubase,
  26. globals, globtype,
  27. cgbase, cutils,
  28. aoptobj, aoptcpub, aopt,
  29. aasmtai, aasmcpu;
  30. type
  31. TCpuAsmOptimizer = class(TAsmOptimizer)
  32. function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
  33. function RegLoadedWithNewValue(reg: tregister; hp: tai): boolean; override;
  34. function GetNextInstructionUsingReg(Current: tai; Out Next: tai; reg: TRegister): Boolean;
  35. function OptPass1Mov(var p: tai): Boolean;
  36. end;
  37. implementation
  38. function TCpuAsmOptimizer.RegLoadedWithNewValue(reg: tregister; hp: tai): boolean;
  39. var
  40. p: taicpu;
  41. begin
  42. result:=false;
  43. if not ((assigned(hp)) and (hp.typ = ait_instruction)) then
  44. exit;
  45. p := taicpu(hp);
  46. if p.ops=0 then
  47. exit;
  48. case p.oper[0]^.typ of
  49. top_reg:
  50. result:=(SuperRegistersEqual(p.oper[0]^.reg,reg)) and
  51. (p.spilling_get_operation_type(0)<>operand_read);
  52. else
  53. ;
  54. end;
  55. end;
  56. function TCpuAsmOptimizer.GetNextInstructionUsingReg(Current: tai; out Next: tai; reg: TRegister): Boolean;
  57. begin
  58. Next:=Current;
  59. repeat
  60. Result:=GetNextInstruction(Next,Next);
  61. until not (Result) or
  62. not(cs_opt_level3 in current_settings.optimizerswitches) or
  63. (Next.typ<>ait_instruction) or
  64. RegInInstruction(reg,Next) or
  65. is_calljmp(taicpu(Next).opcode);
  66. end;
  67. function MatchInstruction(const instr: tai; const op: TAsmOp; const AConditions: TAsmConds = []): boolean;
  68. begin
  69. result :=
  70. (instr.typ = ait_instruction) and
  71. (taicpu(instr).opcode = op) and
  72. ((AConditions=[]) or (taicpu(instr).condition in AConditions));
  73. end;
  74. function MatchOperand(const oper1: TOper; const oper2: TOper): boolean; inline;
  75. begin
  76. result := oper1.typ = oper2.typ;
  77. if result then
  78. case oper1.typ of
  79. top_const:
  80. Result:=oper1.val = oper2.val;
  81. top_reg:
  82. Result:=oper1.reg = oper2.reg;
  83. {top_ref:
  84. Result:=RefsEqual(oper1.ref^, oper2.ref^);}
  85. else Result:=false;
  86. end
  87. end;
  88. function MatchOperand(const oper: TOper; const reg: TRegister): boolean; inline;
  89. begin
  90. result := (oper.typ = top_reg) and (oper.reg = reg);
  91. end;
  92. function TCpuAsmOptimizer.OptPass1Mov(var p: tai): Boolean;
  93. var
  94. hp1: tai;
  95. alloc, dealloc: tai_regalloc;
  96. begin
  97. {
  98. change
  99. mov reg0,reg1
  100. mov reg1,reg0
  101. into
  102. mov reg0,reg1
  103. }
  104. Result := False;
  105. while GetNextInstruction(p, hp1) and
  106. MatchInstruction(hp1, A_MOVE, [taicpu(p).condition]) and
  107. MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[1]^) and
  108. MatchOperand(taicpu(p).oper[1]^, taicpu(hp1).oper[0]^) do
  109. begin
  110. asml.Remove(hp1);
  111. hp1.free;
  112. Result:=true;
  113. end;
  114. end;
  115. function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
  116. begin
  117. result := false;
  118. if p.typ=ait_instruction then
  119. begin
  120. case taicpu(p).opcode of
  121. A_MOVE:
  122. Result:=OptPass1Mov(p);
  123. else
  124. ;
  125. end;
  126. end;
  127. end;
  128. begin
  129. casmoptimizer := TCpuAsmOptimizer;
  130. end.