pass_1.pas 6.5 KB

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