aoptcpu.pas 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. {
  2. $Id$
  3. Copyright (c) 1999 by Jonas Maebe, member of the Free Pascal
  4. Development Team
  5. This unit implements the i386 optimizer object
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. Unit aoptcpu;
  20. Interface
  21. uses cpubase, aoptobj, aoptcpub;
  22. Type
  23. TRegInfoCpu = Object(TRegInfo)
  24. Procedure AddReg(OldReg, NewReg: TRegister); Virtual;
  25. End;
  26. Type
  27. TAOptCpu = Object(TAoptObj)
  28. { uses the same constructor as TAopObj }
  29. Function RegMaxSize(Reg: TRegister): TRegister; Virtual;
  30. Function RegsSameSize(Reg1, Reg2: TRegister): Boolean; Virtual;
  31. Function IsLoadInstr(p: pai): Boolean; Virtual;
  32. Function IsStoreInstr(p: pai): Boolean; Virtual;
  33. Function TCh2Reg(Ch: TChange): TRegister; Virtual;
  34. Function RegReadByInstr(Reg: TRegister; p: Pai); Virtual;
  35. End;
  36. Implementation
  37. {*********************** TAoptCpu **************************}
  38. Function TAOptCpu.RegMaxSize(Reg: TRegister): TRegister;
  39. Begin
  40. RegMaxSize := Reg;
  41. If (Reg >= R_AX)
  42. Then
  43. If (Reg <= R_DI)
  44. Then RegMaxSize := Reg16ToReg32(Reg)
  45. Else
  46. If (Reg <= R_BL)
  47. Then RegMaxSize := Reg8toReg32(Reg)
  48. End;
  49. Function TAOptCpu.RegsSameSize(Reg1, Reg2: TRegister): Boolean;
  50. Begin
  51. If (Reg1 <= R_EDI)
  52. Then RegsSameSize := (Reg2 <= R_EDI)
  53. Else
  54. If (Reg1 <= R_DI)
  55. Then RegsSameSize := (Reg2 in [R_AX..R_DI])
  56. Else
  57. If (Reg1 <= R_BL)
  58. Then RegsSameSize := (Reg2 in [R_AL..R_BL])
  59. Else RegsSameSize := False
  60. End;
  61. Function TAOptCpu.IsLoadInstr(p: pai): Boolean;
  62. Begin
  63. IsLoadInstr :=
  64. (p^.typ = ait_instruction) and
  65. ((PInstr(p)^.OpCode = A_MOV) or
  66. (PInstr(p)^.OpCode = A_MOVZX) or
  67. (PInstr(p)^.OpCode = A_MOVSX)) And
  68. (PInstr(p)^.oper[LoadSrc].typ = top_ref));
  69. End;
  70. Function TAOptCpu.IsStoreInstr(p: pai): Boolean;
  71. Begin
  72. IsLoadInstr :=
  73. (p^.typ = ait_instruction) and
  74. ((PInstr(p)^.OpCode = A_MOV) or
  75. (PInstr(p)^.OpCode = A_MOVZX) or
  76. (PInstr(p)^.OpCode = A_MOVSX)) And
  77. (PInstr(p)^.oper[StoreDst].typ = top_ref));
  78. End;
  79. Function TAOptCpu.TCh2Reg(Ch: TChange): TRegister;
  80. Begin
  81. If (Ch <= C_REDI) Then
  82. TCh2Reg := TRegister(Byte(Ch))
  83. Else
  84. If (Ch <= C_WEDI) Then
  85. TCh2Reg := TRegister(Byte(Ch) - Byte(C_REDI))
  86. Else
  87. If (Ch <= C_RWEDI) Then
  88. TCh2Reg := TRegister(Byte(Ch) - Byte(C_WEDI))
  89. Else InternalError($db)
  90. End;
  91. Function TAOptCpu.RegReadByInstr(Reg: TRegister; p: Pai);
  92. Begin
  93. RegReadByInstr := False;
  94. If (p^.typ = ait_instruction) Then
  95. Case p^.opcode of
  96. A_IMUL:
  97. With PInstr(p)^ Do
  98. RegReadByInstr :=
  99. RegInOp(Reg,op[0]) or
  100. RegInOp(Reg,op[1]) or
  101. ((ops = 1) and
  102. (reg in [R_EAX,R_EDX]))
  103. A_IDIV, A_MUL:
  104. RegReadByInstr :=
  105. RegInOp(Reg,op[0]) or
  106. (Reg = R_EAX) or
  107. ((Reg = R_EDX) and
  108. (p^.opcode = A_IDIV) and
  109. (p^.size = S_L));
  110. Else RegReadByInstr := true !!!!!!!!!!!!!!!
  111. End;
  112. End;
  113. { ********************* TRegInfoCpu *****************}
  114. Procedure TRegInfoCpu.AddReg(OldReg, NewReg: TRegister);
  115. Begin
  116. NewRegsEncountered := NewRegsEncountered + [NewReg];
  117. OldRegsEncountered := OldRegsEncountered + [OldReg];
  118. New2OldReg[NewReg] := OldReg;
  119. Case OldReg Of
  120. R_EAX..R_EDI:
  121. Begin
  122. NewRegsEncountered := NewRegsEncountered + [Reg32toReg16(NewReg)];
  123. OldRegsEncountered := OldRegsEncountered + [Reg32toReg16(OldReg)];
  124. New2OldReg[Reg32toReg16(NewReg)] := Reg32toReg16(OldReg);
  125. If (NewReg in [R_EAX..R_EBX]) And
  126. (OldReg in [R_EAX..R_EBX]) Then
  127. Begin
  128. NewRegsEncountered := NewRegsEncountered + [Reg32toReg8(NewReg)];
  129. OldRegsEncountered := OldRegsEncountered + [Reg32toReg8(OldReg)];
  130. New2OldReg[Reg32toReg8(NewReg)] := Reg32toReg8(OldReg);
  131. End;
  132. End;
  133. R_AX..R_DI:
  134. Begin
  135. NewRegsEncountered := NewRegsEncountered + [Reg16toReg32(NewReg)];
  136. OldRegsEncountered := OldRegsEncountered + [Reg16toReg32(OldReg)];
  137. New2OldReg[Reg16toReg32(NewReg)] := Reg16toReg32(OldReg);
  138. If (NewReg in [R_AX..R_BX]) And
  139. (OldReg in [R_AX..R_BX]) Then
  140. Begin
  141. NewRegsEncountered := NewRegsEncountered + [Reg16toReg8(NewReg)];
  142. OldRegsEncountered := OldRegsEncountered + [Reg16toReg8(OldReg)];
  143. New2OldReg[Reg16toReg8(NewReg)] := Reg16toReg8(OldReg);
  144. End;
  145. End;
  146. R_AL..R_BL:
  147. Begin
  148. NewRegsEncountered := NewRegsEncountered + [Reg8toReg32(NewReg)]
  149. + [Reg8toReg16(NewReg)];
  150. OldRegsEncountered := OldRegsEncountered + [Reg8toReg32(OldReg)]
  151. + [Reg8toReg16(OldReg)];
  152. New2OldReg[Reg8toReg32(NewReg)] := Reg8toReg32(OldReg);
  153. End;
  154. End;
  155. End;
  156. End.
  157. {
  158. $Log$
  159. Revision 1.2 1999-08-09 14:07:26 jonas
  160. commit.msg
  161. Revision 1.1 1999/08/08 13:24:50 jonas
  162. + added copyright header/GNU license info
  163. * made the assembler optimizer almost completely OOP
  164. * some code style clean up and extra comments
  165. * moved from the new/aopt to the /new and /new/i386 dirs
  166. }