pass_1.pas 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. {
  2. $Id$
  3. Copyright (c) 1996-98 by Florian Klaempfl
  4. This unit implements the first pass of the code generator
  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. {$ifdef tp}
  19. {$F+}
  20. {$endif tp}
  21. unit pass_1;
  22. interface
  23. uses
  24. tree;
  25. procedure firstpass(p : ptree);
  26. procedure firstpassnode(p : pnode);
  27. function do_firstpass(var p : ptree) : boolean;
  28. function do_firstpassnode(var p : pnode) : boolean;
  29. implementation
  30. uses
  31. globtype,systems,
  32. cobjects,verbose,globals,
  33. aasm,symtable,types,
  34. cgbase
  35. { not yet converted:
  36. htypechk,tcadd,tccal,tccnv,tccon,tcflw,
  37. tcinl,tcld,tcmat,tcmem,tcset
  38. }
  39. {$I cpuunit.inc}
  40. ;
  41. {*****************************************************************************
  42. FirstPass
  43. *****************************************************************************}
  44. {$ifdef dummy}
  45. type
  46. firstpassproc = procedure(var p : ptree);
  47. procedure firstnothing(var p : ptree);
  48. begin
  49. p^.resulttype:=voiddef;
  50. end;
  51. procedure firsterror(var p : ptree);
  52. begin
  53. p^.error:=true;
  54. codegenerror:=true;
  55. p^.resulttype:=generrordef;
  56. end;
  57. procedure firststatement(var p : ptree);
  58. begin
  59. { left is the next statement in the list }
  60. p^.resulttype:=voiddef;
  61. { no temps over several statements }
  62. cleartempgen;
  63. { right is the statement itself calln assignn or a complex one }
  64. firstpass(p^.right);
  65. if (not (cs_extsyntax in aktmoduleswitches)) and
  66. assigned(p^.right^.resulttype) and
  67. (p^.right^.resulttype<>pdef(voiddef)) then
  68. CGMessage(cg_e_illegal_expression);
  69. if codegenerror then
  70. exit;
  71. p^.registers32:=p^.right^.registers32;
  72. p^.registersfpu:=p^.right^.registersfpu;
  73. {$ifdef SUPPORT_MMX}
  74. p^.registersmmx:=p^.right^.registersmmx;
  75. {$endif SUPPORT_MMX}
  76. { left is the next in the list }
  77. firstpass(p^.left);
  78. if codegenerror then
  79. exit;
  80. if p^.right^.registers32>p^.registers32 then
  81. p^.registers32:=p^.right^.registers32;
  82. if p^.right^.registersfpu>p^.registersfpu then
  83. p^.registersfpu:=p^.right^.registersfpu;
  84. {$ifdef SUPPORT_MMX}
  85. if p^.right^.registersmmx>p^.registersmmx then
  86. p^.registersmmx:=p^.right^.registersmmx;
  87. {$endif}
  88. end;
  89. procedure firstasm(var p : ptree);
  90. begin
  91. procinfo.flags:=procinfo.flags or pi_uses_asm;
  92. end;
  93. {$endif dummy}
  94. procedure firstpassnode(p : pnode);
  95. var
  96. oldcodegenerror : boolean;
  97. oldlocalswitches : tlocalswitches;
  98. oldpos : tfileposinfo;
  99. {$ifdef extdebug}
  100. str1,str2 : string;
  101. oldp : pnode;
  102. not_first : boolean;
  103. {$endif extdebug}
  104. begin
  105. {$ifdef extdebug}
  106. inc(total_of_firstpass);
  107. if (p^.firstpasscount>0) and only_one_pass then
  108. exit;
  109. {$endif extdebug}
  110. oldcodegenerror:=codegenerror;
  111. oldpos:=aktfilepos;
  112. oldlocalswitches:=aktlocalswitches;
  113. {$ifdef extdebug}
  114. if p^.firstpasscount>0 then
  115. begin
  116. move(p^,str1[1],sizeof(ttree));
  117. {$ifndef TP}
  118. {$ifopt H+}
  119. SetLength(str1,sizeof(ttree));
  120. {$else}
  121. str1[0]:=char(sizeof(ttree));
  122. {$endif}
  123. {$else}
  124. str1[0]:=char(sizeof(ttree));
  125. {$endif}
  126. new(oldp);
  127. oldp^:=p^;
  128. not_first:=true;
  129. inc(firstpass_several);
  130. end
  131. else
  132. not_first:=false;
  133. {$endif extdebug}
  134. if not p^.error then
  135. begin
  136. codegenerror:=false;
  137. aktfilepos:=p^.fileinfo;
  138. aktlocalswitches:=p^.localswitches;
  139. p^.pass_1;
  140. aktlocalswitches:=oldlocalswitches;
  141. aktfilepos:=oldpos;
  142. p^.error:=codegenerror;
  143. codegenerror:=codegenerror or oldcodegenerror;
  144. end
  145. else
  146. codegenerror:=true;
  147. {$ifdef extdebug}
  148. if not_first then
  149. begin
  150. { dirty trick to compare two ttree's (PM) }
  151. move(p^,str2[1],sizeof(ttree));
  152. {$ifndef TP}
  153. {$ifopt H+}
  154. SetLength(str2,sizeof(ttree));
  155. {$else}
  156. str2[0]:=char(sizeof(ttree));
  157. {$endif}
  158. {$else}
  159. str2[0]:=char(sizeof(ttree));
  160. {$endif}
  161. if str1<>str2 then
  162. begin
  163. comment(v_debug,'tree changed after first counting pass '
  164. +tostr(longint(p^.treetype)));
  165. {!!!!!!! compare_trees(oldp,p); }
  166. end;
  167. dispose(oldp);
  168. end;
  169. {!!!!!!!
  170. if count_ref then
  171. inc(p^.firstpasscount);
  172. }
  173. {$endif extdebug}
  174. end;
  175. function do_firstpass(var p : ptree) : boolean;
  176. begin
  177. codegenerror:=false;
  178. do_firstpass:=codegenerror;
  179. end;
  180. procedure firstpass(p : ptree);
  181. begin
  182. codegenerror:=false;
  183. end;
  184. function do_firstpassnode(var p : pnode) : boolean;
  185. begin
  186. codegenerror:=false;
  187. firstpassnode(p);
  188. do_firstpassnode:=codegenerror;
  189. end;
  190. end.
  191. {
  192. $Log$
  193. Revision 1.4 1999-08-01 18:22:36 florian
  194. * made it again compilable
  195. Revision 1.3 1999/01/23 23:29:48 florian
  196. * first running version of the new code generator
  197. * when compiling exceptions under Linux fixed
  198. Revision 1.2 1999/01/13 22:52:37 florian
  199. + YES, finally the new code generator is compilable, but it doesn't run yet :(
  200. Revision 1.1 1998/12/26 15:20:31 florian
  201. + more changes for the new version
  202. }