pass_1.pas 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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 firstblock(var p : ptree);
  94. var
  95. hp : ptree;
  96. count : longint;
  97. begin
  98. count:=0;
  99. hp:=p^.left;
  100. while assigned(hp) do
  101. begin
  102. if cs_regalloc in aktglobalswitches then
  103. begin
  104. { Codeumstellungen }
  105. { Funktionsresultate an exit anh„ngen }
  106. { this is wrong for string or other complex
  107. result types !!! }
  108. if ret_in_acc(procinfo.retdef) and
  109. assigned(hp^.left) and
  110. (hp^.left^.right^.treetype=exitn) and
  111. (hp^.right^.treetype=assignn) and
  112. (hp^.right^.left^.treetype=funcretn) then
  113. begin
  114. if assigned(hp^.left^.right^.left) then
  115. CGMessage(cg_n_inefficient_code)
  116. else
  117. begin
  118. hp^.left^.right^.left:=getcopy(hp^.right^.right);
  119. disposetree(hp^.right);
  120. hp^.right:=nil;
  121. end;
  122. end
  123. { warning if unreachable code occurs and elimate this }
  124. else if (hp^.right^.treetype in
  125. [exitn,breakn,continuen,goton]) and
  126. assigned(hp^.left) and
  127. (hp^.left^.treetype<>labeln) then
  128. begin
  129. { use correct line number }
  130. aktfilepos:=hp^.left^.fileinfo;
  131. disposetree(hp^.left);
  132. hp^.left:=nil;
  133. CGMessage(cg_w_unreachable_code);
  134. { old lines }
  135. aktfilepos:=hp^.right^.fileinfo;
  136. end;
  137. end;
  138. if assigned(hp^.right) then
  139. begin
  140. cleartempgen;
  141. firstpass(hp^.right);
  142. if (not (cs_extsyntax in aktmoduleswitches)) and
  143. assigned(hp^.right^.resulttype) and
  144. (hp^.right^.resulttype<>pdef(voiddef)) then
  145. CGMessage(cg_e_illegal_expression);
  146. if codegenerror then
  147. exit;
  148. hp^.registers32:=hp^.right^.registers32;
  149. hp^.registersfpu:=hp^.right^.registersfpu;
  150. {$ifdef SUPPORT_MMX}
  151. hp^.registersmmx:=hp^.right^.registersmmx;
  152. {$endif SUPPORT_MMX}
  153. end
  154. else
  155. hp^.registers32:=0;
  156. if hp^.registers32>p^.registers32 then
  157. p^.registers32:=hp^.registers32;
  158. if hp^.registersfpu>p^.registersfpu then
  159. p^.registersfpu:=hp^.registersfpu;
  160. {$ifdef SUPPORT_MMX}
  161. if hp^.registersmmx>p^.registersmmx then
  162. p^.registersmmx:=hp^.registersmmx;
  163. {$endif}
  164. inc(count);
  165. hp:=hp^.left;
  166. end;
  167. end;
  168. procedure firstasm(var p : ptree);
  169. begin
  170. procinfo.flags:=procinfo.flags or pi_uses_asm;
  171. end;
  172. {$endif dummy}
  173. procedure firstpass(p : pnode);
  174. var
  175. oldcodegenerror : boolean;
  176. oldlocalswitches : tlocalswitches;
  177. oldpos : tfileposinfo;
  178. {$ifdef extdebug}
  179. str1,str2 : string;
  180. oldp : ptree;
  181. not_first : boolean;
  182. {$endif extdebug}
  183. begin
  184. {$ifdef extdebug}
  185. inc(total_of_firstpass);
  186. if (p^.firstpasscount>0) and only_one_pass then
  187. exit;
  188. {$endif extdebug}
  189. oldcodegenerror:=codegenerror;
  190. oldpos:=aktfilepos;
  191. oldlocalswitches:=aktlocalswitches;
  192. {$ifdef extdebug}
  193. if p^.firstpasscount>0 then
  194. begin
  195. move(p^,str1[1],sizeof(ttree));
  196. {$ifndef TP}
  197. {$ifopt H+}
  198. SetLength(str1,sizeof(ttree));
  199. {$else}
  200. str1[0]:=char(sizeof(ttree));
  201. {$endif}
  202. {$else}
  203. str1[0]:=char(sizeof(ttree));
  204. {$endif}
  205. new(oldp);
  206. oldp^:=p^;
  207. not_first:=true;
  208. inc(firstpass_several);
  209. end
  210. else
  211. not_first:=false;
  212. {$endif extdebug}
  213. if not p^.error then
  214. begin
  215. codegenerror:=false;
  216. aktfilepos:=p^.fileinfo;
  217. aktlocalswitches:=p^.localswitches;
  218. p^.pass_1;
  219. aktlocalswitches:=oldlocalswitches;
  220. aktfilepos:=oldpos;
  221. p^.error:=codegenerror;
  222. codegenerror:=codegenerror or oldcodegenerror;
  223. end
  224. else
  225. codegenerror:=true;
  226. {$ifdef extdebug}
  227. if not_first then
  228. begin
  229. { dirty trick to compare two ttree's (PM) }
  230. move(p^,str2[1],sizeof(ttree));
  231. {$ifndef TP}
  232. {$ifopt H+}
  233. SetLength(str2,sizeof(ttree));
  234. {$else}
  235. str2[0]:=char(sizeof(ttree));
  236. {$endif}
  237. {$else}
  238. str2[0]:=char(sizeof(ttree));
  239. {$endif}
  240. if str1<>str2 then
  241. begin
  242. comment(v_debug,'tree changed after first counting pass '
  243. +tostr(longint(p^.treetype)));
  244. compare_trees(oldp,p);
  245. end;
  246. dispose(oldp);
  247. end;
  248. if count_ref then
  249. inc(p^.firstpasscount);
  250. {$endif extdebug}
  251. end;
  252. function do_firstpass(var p : ptree) : boolean;
  253. begin
  254. codegenerror:=false;
  255. do_firstpass:=codegenerror;
  256. end;
  257. function do_firstpassnode(var p : pnode) : boolean;
  258. begin
  259. codegenerror:=false;
  260. firstpass(p);
  261. do_firstpassnode:=codegenerror;
  262. end;
  263. end.
  264. {
  265. $Log$
  266. Revision 1.1 1998-12-26 15:20:31 florian
  267. + more changes for the new version
  268. }