pass_1.pas 6.3 KB

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