{ $Id$ Copyright (c) 1993-98 by Florian Klaempfl Type checking and register allocation for nodes that influence the flow This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. **************************************************************************** } unit tcflw; interface uses tree; procedure first_while_repeat(var p : ptree); procedure firstif(var p : ptree); procedure firstfor(var p : ptree); procedure firstexit(var p : ptree); procedure firstgoto(var p : ptree); procedure firstlabel(var p : ptree); procedure firstraise(var p : ptree); procedure firsttryexcept(var p : ptree); procedure firsttryfinally(var p : ptree); procedure firston(var p : ptree); implementation uses globtype,systems, cobjects,verbose,globals, symtable,aasm,types, hcodegen,htypechk,temp_gen,pass_1 {$ifdef i386} ,i386base ,tgeni386 {$endif} {$ifdef m68k} ,m68k,tgen68k {$endif} ; {***************************************************************************** First_While_RepeatN *****************************************************************************} procedure first_while_repeat(var p : ptree); var old_t_times : longint; begin old_t_times:=t_times; { calc register weight } if not(cs_littlesize in aktglobalswitches ) then t_times:=t_times*8; cleartempgen; must_be_valid:=true; firstpass(p^.left); if codegenerror then exit; if not((p^.left^.resulttype^.deftype=orddef) and (porddef(p^.left^.resulttype)^.typ in [bool8bit,bool16bit,bool32bit])) then begin CGMessage(type_e_mismatch); exit; end; p^.registers32:=p^.left^.registers32; p^.registersfpu:=p^.left^.registersfpu; {$ifdef SUPPORT_MMX} p^.registersmmx:=p^.left^.registersmmx; {$endif SUPPORT_MMX} { loop instruction } if assigned(p^.right) then begin cleartempgen; firstpass(p^.right); if codegenerror then exit; if p^.registers32assignn then CGMessage(cg_e_illegal_expression); cleartempgen; must_be_valid:=false; firstpass(p^.left); must_be_valid:=true; if p^.left^.registers32>p^.registers32 then p^.registers32:=p^.left^.registers32; if p^.left^.registersfpu>p^.registersfpu then p^.registersfpu:=p^.left^.registersfpu; {$ifdef SUPPORT_MMX} if p^.left^.registersmmx>p^.registersmmx then p^.registersmmx:=p^.left^.registersmmx; {$endif SUPPORT_MMX} { process count var } cleartempgen; firstpass(p^.t2); if codegenerror then exit; { Check count var, record fields are also allowed in tp7 } hp:=p^.t2; while (hp^.treetype=subscriptn) do hp:=hp^.left; if (hp^.treetype<>loadn) then CGMessage(cg_e_illegal_count_var) else if (not(is_ordinal(p^.t2^.resulttype))) then CGMessage(type_e_ordinal_expr_expected); if p^.t2^.registers32>p^.registers32 then p^.registers32:=p^.t2^.registers32; if p^.t2^.registersfpu>p^.registersfpu then p^.registersfpu:=p^.t2^.registersfpu; {$ifdef SUPPORT_MMX} if p^.t2^.registersmmx>p^.registersmmx then p^.registersmmx:=p^.t2^.registersmmx; {$endif SUPPORT_MMX} cleartempgen; firstpass(p^.right); if p^.right^.treetype<>ordconstn then begin p^.right:=gentypeconvnode(p^.right,p^.t2^.resulttype); cleartempgen; firstpass(p^.right); end; if p^.right^.registers32>p^.registers32 then p^.registers32:=p^.right^.registers32; if p^.right^.registersfpu>p^.registersfpu then p^.registersfpu:=p^.right^.registersfpu; {$ifdef SUPPORT_MMX} if p^.right^.registersmmx>p^.registersmmx then p^.registersmmx:=p^.right^.registersmmx; {$endif SUPPORT_MMX} t_times:=old_t_times; end; {***************************************************************************** FirstExit *****************************************************************************} procedure firstexit(var p : ptree); begin if assigned(p^.left) then begin firstpass(p^.left); if codegenerror then exit; { Check the 2 types } p^.left:=gentypeconvnode(p^.left,p^.resulttype); firstpass(p^.left); p^.registers32:=p^.left^.registers32; p^.registersfpu:=p^.left^.registersfpu; {$ifdef SUPPORT_MMX} p^.registersmmx:=p^.left^.registersmmx; {$endif SUPPORT_MMX} end; end; {***************************************************************************** FirstGoto *****************************************************************************} procedure firstgoto(var p : ptree); begin p^.resulttype:=voiddef; end; {***************************************************************************** FirstLabel *****************************************************************************} procedure firstlabel(var p : ptree); begin cleartempgen; firstpass(p^.left); p^.registers32:=p^.left^.registers32; p^.registersfpu:=p^.left^.registersfpu; {$ifdef SUPPORT_MMX} p^.registersmmx:=p^.left^.registersmmx; {$endif SUPPORT_MMX} p^.resulttype:=voiddef; end; {***************************************************************************** FirstRaise *****************************************************************************} procedure firstraise(var p : ptree); begin p^.resulttype:=voiddef; { p^.registersfpu:=0; p^.registers32:=0; } if assigned(p^.left) then begin firstpass(p^.left); { this must be a _class_ } if (p^.left^.resulttype^.deftype<>objectdef) or ((pobjectdef(p^.left^.resulttype)^.options and oo_is_class)=0) then CGMessage(type_e_mismatch); p^.registersfpu:=p^.left^.registersfpu; p^.registers32:=p^.left^.registers32; {$ifdef SUPPORT_MMX} p^.registersmmx:=p^.left^.registersmmx; {$endif SUPPORT_MMX} if assigned(p^.right) then begin firstpass(p^.right); p^.right:=gentypeconvnode(p^.right,s32bitdef); firstpass(p^.right); left_right_max(p); end; end; end; {***************************************************************************** FirstTryExcept *****************************************************************************} procedure firsttryexcept(var p : ptree); begin cleartempgen; firstpass(p^.left); { on statements } if assigned(p^.right) then begin cleartempgen; firstpass(p^.right); p^.registers32:=max(p^.registers32,p^.right^.registers32); p^.registersfpu:=max(p^.registersfpu,p^.right^.registersfpu); {$ifdef SUPPORT_MMX} p^.registersmmx:=max(p^.registersmmx,p^.right^.registersmmx); {$endif SUPPORT_MMX} end; { else block } if assigned(p^.t1) then begin firstpass(p^.t1); p^.registers32:=max(p^.registers32,p^.t1^.registers32); p^.registersfpu:=max(p^.registersfpu,p^.t1^.registersfpu); {$ifdef SUPPORT_MMX} p^.registersmmx:=max(p^.registersmmx,p^.t1^.registersmmx); {$endif SUPPORT_MMX} end; end; {***************************************************************************** FirstTryFinally *****************************************************************************} procedure firsttryfinally(var p : ptree); begin p^.resulttype:=voiddef; cleartempgen; must_be_valid:=true; firstpass(p^.left); cleartempgen; must_be_valid:=true; firstpass(p^.right); if codegenerror then exit; left_right_max(p); end; {***************************************************************************** FirstOn *****************************************************************************} procedure firston(var p : ptree); begin { that's really an example procedure for a firstpass :) } cleartempgen; p^.resulttype:=voiddef; p^.registers32:=0; p^.registersfpu:=0; {$ifdef SUPPORT_MMX} p^.registersmmx:=0; {$endif SUPPORT_MMX} if assigned(p^.left) then begin firstpass(p^.left); p^.registers32:=p^.left^.registers32; p^.registersfpu:=p^.left^.registersfpu; {$ifdef SUPPORT_MMX} p^.registersmmx:=p^.left^.registersmmx; {$endif SUPPORT_MMX} end; cleartempgen; if assigned(p^.right) then begin firstpass(p^.right); p^.registers32:=max(p^.registers32,p^.right^.registers32); p^.registersfpu:=max(p^.registersfpu,p^.right^.registersfpu); {$ifdef SUPPORT_MMX} p^.registersmmx:=max(p^.registersmmx,p^.right^.registersmmx); {$endif SUPPORT_MMX} end; end; end. { $Log$ Revision 1.10 1999-05-27 19:45:18 peter * removed oldasm * plabel -> pasmlabel * -a switches to source writing automaticly * assembler readers OOPed * asmsymbol automaticly external * jumptables and other label fixes for asm readers Revision 1.9 1999/05/01 13:24:52 peter * merged nasm compiler * old asm moved to oldasm/ Revision 1.8 1999/03/24 23:17:36 peter * fixed bugs 212,222,225,227,229,231,233 Revision 1.7 1999/03/09 19:24:42 peter * type check the exit() Revision 1.6 1999/02/22 02:15:48 peter * updates for ag386bin Revision 1.5 1999/01/13 12:01:43 peter * fixed crash with counter var Revision 1.4 1998/12/11 00:03:55 peter + globtype,tokens,version unit splitted from globals Revision 1.3 1998/10/19 08:55:10 pierre * wrong stabs info corrected once again !! + variable vmt offset with vmt field only if required implemented now !!! Revision 1.2 1998/10/06 20:49:10 peter * m68k compiler compiles again Revision 1.1 1998/09/23 20:42:24 peter * splitted pass_1 }