mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 16:59:45 +01:00 
			
		
		
		
	* call firstpass before allocation and codegeneration is started
* move leftover code from pass_2.generatecode() to psub
This commit is contained in:
		
							parent
							
								
									1953a4a4f2
								
							
						
					
					
						commit
						9e66b09843
					
				@ -37,10 +37,6 @@ uses
 | 
				
			|||||||
       allow_multi_pass2 : boolean;
 | 
					       allow_multi_pass2 : boolean;
 | 
				
			||||||
       flowcontrol : tflowcontrol;
 | 
					       flowcontrol : tflowcontrol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{ produces assembler for the expression in variable p }
 | 
					 | 
				
			||||||
{ and produces an assembler node at the end        }
 | 
					 | 
				
			||||||
procedure generatecode(var p : tnode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{ produces the actual code }
 | 
					{ produces the actual code }
 | 
				
			||||||
function do_secondpass(var p : tnode) : boolean;
 | 
					function do_secondpass(var p : tnode) : boolean;
 | 
				
			||||||
procedure secondpass(var p : tnode);
 | 
					procedure secondpass(var p : tnode);
 | 
				
			||||||
@ -210,78 +206,15 @@ implementation
 | 
				
			|||||||
         do_secondpass:=codegenerror;
 | 
					         do_secondpass:=codegenerror;
 | 
				
			||||||
      end;
 | 
					      end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    procedure clearrefs(p : tnamedindexitem;arg:pointer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      begin
 | 
					 | 
				
			||||||
         if (tsym(p).typ=varsym) then
 | 
					 | 
				
			||||||
           if tvarsym(p).refs>1 then
 | 
					 | 
				
			||||||
             tvarsym(p).refs:=1;
 | 
					 | 
				
			||||||
      end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    procedure generatecode(var p : tnode);
 | 
					 | 
				
			||||||
      begin
 | 
					 | 
				
			||||||
         flowcontrol:=[];
 | 
					 | 
				
			||||||
         { when size optimization only count occurrence }
 | 
					 | 
				
			||||||
         if cs_littlesize in aktglobalswitches then
 | 
					 | 
				
			||||||
           cg.t_times:=1
 | 
					 | 
				
			||||||
         else
 | 
					 | 
				
			||||||
           { reference for repetition is 100 }
 | 
					 | 
				
			||||||
           cg.t_times:=100;
 | 
					 | 
				
			||||||
         { clear register count }
 | 
					 | 
				
			||||||
         symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}clearrefs,nil);
 | 
					 | 
				
			||||||
         symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}clearrefs,nil);
 | 
					 | 
				
			||||||
         { firstpass everything }
 | 
					 | 
				
			||||||
         do_firstpass(p);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
         { after pass 1, we should have all necessary information to set the temp. start location }
 | 
					 | 
				
			||||||
         current_procinfo.set_first_temp_offset;
 | 
					 | 
				
			||||||
         { only do secondpass if there are no errors }
 | 
					 | 
				
			||||||
         if ErrorCount=0 then
 | 
					 | 
				
			||||||
           begin
 | 
					 | 
				
			||||||
              { caller paraloc info is also necessary in the stackframe_entry }
 | 
					 | 
				
			||||||
              { code of the ppc (and possibly other processors)               }
 | 
					 | 
				
			||||||
              if not current_procinfo.procdef.has_paraloc_info then
 | 
					 | 
				
			||||||
                begin
 | 
					 | 
				
			||||||
                  paramanager.create_paraloc_info(current_procinfo.procdef,callerside);
 | 
					 | 
				
			||||||
                  current_procinfo.procdef.has_paraloc_info:=true;
 | 
					 | 
				
			||||||
                end;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              { process register variable stuff (JM) }
 | 
					 | 
				
			||||||
{              assign_regvars(p);}
 | 
					 | 
				
			||||||
{              load_regvars(current_procinfo.aktentrycode,p);}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              { for the i386 it must be done in genexitcode because it has  }
 | 
					 | 
				
			||||||
              { to add 'fstp' instructions when using fpu regvars and those }
 | 
					 | 
				
			||||||
              { must come after the "exitlabel" (JM)                        }
 | 
					 | 
				
			||||||
{$ifndef i386}
 | 
					 | 
				
			||||||
{              cleanup_regvars(current_procinfo.aktexitcode);}
 | 
					 | 
				
			||||||
{$endif i386}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{              current_procinfo.allocate_framepointer_reg;}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              do_secondpass(p);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{$ifdef EXTDEBUG}
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
              for sr:=first_int_imreg to last_int_imreg do
 | 
					 | 
				
			||||||
                if not(sr in rg.unusedregsint) then
 | 
					 | 
				
			||||||
                  Comment(V_Warning,'Register '+std_regname(newreg(R_INTREGISTER,sr,R_SUBNONE))+' not released');
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
{$endif EXTDEBUG}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
{$ifdef i386}
 | 
					 | 
				
			||||||
              if assigned(current_procinfo.procdef) then
 | 
					 | 
				
			||||||
                current_procinfo.procdef.fpu_used:=p.registersfpu;
 | 
					 | 
				
			||||||
{$endif i386}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
           end;
 | 
					 | 
				
			||||||
         current_procinfo.aktproccode.concatlist(exprasmlist);
 | 
					 | 
				
			||||||
      end;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
end.
 | 
					end.
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  $Log$
 | 
					  $Log$
 | 
				
			||||||
  Revision 1.72  2003-10-19 01:34:30  florian
 | 
					  Revision 1.73  2003-10-30 16:22:40  peter
 | 
				
			||||||
 | 
					    * call firstpass before allocation and codegeneration is started
 | 
				
			||||||
 | 
					    * move leftover code from pass_2.generatecode() to psub
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Revision 1.72  2003/10/19 01:34:30  florian
 | 
				
			||||||
    * some ppc stuff fixed
 | 
					    * some ppc stuff fixed
 | 
				
			||||||
    * memory leak fixed
 | 
					    * memory leak fixed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -566,6 +566,14 @@ implementation
 | 
				
			|||||||
      end;
 | 
					      end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    procedure clearrefs(p : tnamedindexitem;arg:pointer);
 | 
				
			||||||
 | 
					      begin
 | 
				
			||||||
 | 
					         if (tsym(p).typ=varsym) then
 | 
				
			||||||
 | 
					           if tvarsym(p).refs>1 then
 | 
				
			||||||
 | 
					             tvarsym(p).refs:=1;
 | 
				
			||||||
 | 
					      end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    procedure tcgprocinfo.generate_code;
 | 
					    procedure tcgprocinfo.generate_code;
 | 
				
			||||||
      var
 | 
					      var
 | 
				
			||||||
        oldprocinfo : tprocinfo;
 | 
					        oldprocinfo : tprocinfo;
 | 
				
			||||||
@ -605,168 +613,197 @@ implementation
 | 
				
			|||||||
        { add parast/localst to symtablestack }
 | 
					        { add parast/localst to symtablestack }
 | 
				
			||||||
        add_to_symtablestack;
 | 
					        add_to_symtablestack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { set the start offset to the start of the temp area in the stack }
 | 
					        { when size optimization only count occurrence }
 | 
				
			||||||
        tg:=ttgobj.create;
 | 
					        if cs_littlesize in aktglobalswitches then
 | 
				
			||||||
 | 
					          cg.t_times:=1
 | 
				
			||||||
        { Create register allocator }
 | 
					 | 
				
			||||||
        cg.init_register_allocators;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        current_procinfo.set_first_temp_offset;
 | 
					 | 
				
			||||||
        current_procinfo.generate_parameter_info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        { Allocate space in temp/registers for parast and localst }
 | 
					 | 
				
			||||||
        aktfilepos:=entrypos;
 | 
					 | 
				
			||||||
        gen_alloc_parast(aktproccode,tparasymtable(current_procinfo.procdef.parast));
 | 
					 | 
				
			||||||
        if current_procinfo.procdef.localst.symtabletype=localsymtable then
 | 
					 | 
				
			||||||
          gen_alloc_localst(aktproccode,tlocalsymtable(current_procinfo.procdef.localst));
 | 
					 | 
				
			||||||
        if (cs_asm_source in aktglobalswitches) then
 | 
					 | 
				
			||||||
          aktproccode.concat(Tai_comment.Create(strpnew('Temps start at '+std_regname(current_procinfo.framepointer)+
 | 
					 | 
				
			||||||
              tostr_with_plus(tg.lasttemp))));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        { Generate code to load register parameters in temps and insert local
 | 
					 | 
				
			||||||
          copies for values parameters. This must be done before the code for the
 | 
					 | 
				
			||||||
          body is generated because the localloc is updated.
 | 
					 | 
				
			||||||
          Note: The generated code will be inserted after the code generation of
 | 
					 | 
				
			||||||
          the body is finished, because only then the position is known }
 | 
					 | 
				
			||||||
        aktfilepos:=entrypos;
 | 
					 | 
				
			||||||
        gen_load_para_value(templist);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        { generate code for the body }
 | 
					 | 
				
			||||||
        generatecode(code);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        { The position of the loadpara_asmnode is now known }
 | 
					 | 
				
			||||||
        aktproccode.insertlistafter(loadpara_asmnode.currenttai,templist);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        { first generate entry and initialize code with the correct
 | 
					 | 
				
			||||||
          position and switches }
 | 
					 | 
				
			||||||
        aktfilepos:=entrypos;
 | 
					 | 
				
			||||||
        aktlocalswitches:=entryswitches;
 | 
					 | 
				
			||||||
        gen_entry_code(templist);
 | 
					 | 
				
			||||||
        aktproccode.insertlistafter(entry_asmnode.currenttai,templist);
 | 
					 | 
				
			||||||
        gen_initialize_code(templist,false);
 | 
					 | 
				
			||||||
        aktproccode.insertlistafter(init_asmnode.currenttai,templist);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        { now generate finalize and exit code with the correct position
 | 
					 | 
				
			||||||
          and switches }
 | 
					 | 
				
			||||||
        aktfilepos:=exitpos;
 | 
					 | 
				
			||||||
        aktlocalswitches:=exitswitches;
 | 
					 | 
				
			||||||
        gen_finalize_code(templist,false);
 | 
					 | 
				
			||||||
        { the finalcode must be concated if there was no position available,
 | 
					 | 
				
			||||||
          using insertlistafter will result in an insert at the start
 | 
					 | 
				
			||||||
          when currentai=nil }
 | 
					 | 
				
			||||||
        if assigned(final_asmnode.currenttai) then
 | 
					 | 
				
			||||||
          aktproccode.insertlistafter(final_asmnode.currenttai,templist)
 | 
					 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
          aktproccode.concatlist(templist);
 | 
					          { reference for repetition is 100 }
 | 
				
			||||||
        { insert exit label at the correct position }
 | 
					          cg.t_times:=100;
 | 
				
			||||||
        cg.a_label(templist,current_procinfo.aktexitlabel);
 | 
					
 | 
				
			||||||
        if assigned(exitlabel_asmnode.currenttai) then
 | 
					        { clear register count }
 | 
				
			||||||
          aktproccode.insertlistafter(exitlabel_asmnode.currenttai,templist)
 | 
					        symtablestack.foreach_static({$ifdef FPCPROCVAR}@{$endif}clearrefs,nil);
 | 
				
			||||||
        else
 | 
					        symtablestack.next.foreach_static({$ifdef FPCPROCVAR}@{$endif}clearrefs,nil);
 | 
				
			||||||
          aktproccode.concatlist(templist);
 | 
					
 | 
				
			||||||
        { exit code }
 | 
					        { firstpass everything }
 | 
				
			||||||
        gen_exit_code(templist);
 | 
					        flowcontrol:=[];
 | 
				
			||||||
        aktproccode.concatlist(templist);
 | 
					        do_firstpass(code);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { only do secondpass if there are no errors }
 | 
				
			||||||
 | 
					        if ErrorCount=0 then
 | 
				
			||||||
 | 
					          begin
 | 
				
			||||||
 | 
					            { set the start offset to the start of the temp area in the stack }
 | 
				
			||||||
 | 
					            tg:=ttgobj.create;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { Create register allocator }
 | 
				
			||||||
 | 
					            cg.init_register_allocators;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            current_procinfo.set_first_temp_offset;
 | 
				
			||||||
 | 
					            current_procinfo.generate_parameter_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { Allocate space in temp/registers for parast and localst }
 | 
				
			||||||
 | 
					            aktfilepos:=entrypos;
 | 
				
			||||||
 | 
					            gen_alloc_parast(aktproccode,tparasymtable(current_procinfo.procdef.parast));
 | 
				
			||||||
 | 
					            if current_procinfo.procdef.localst.symtabletype=localsymtable then
 | 
				
			||||||
 | 
					              gen_alloc_localst(aktproccode,tlocalsymtable(current_procinfo.procdef.localst));
 | 
				
			||||||
 | 
					            if (cs_asm_source in aktglobalswitches) then
 | 
				
			||||||
 | 
					              aktproccode.concat(Tai_comment.Create(strpnew('Temps start at '+std_regname(current_procinfo.framepointer)+
 | 
				
			||||||
 | 
					                  tostr_with_plus(tg.lasttemp))));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { Generate code to load register parameters in temps and insert local
 | 
				
			||||||
 | 
					              copies for values parameters. This must be done before the code for the
 | 
				
			||||||
 | 
					              body is generated because the localloc is updated.
 | 
				
			||||||
 | 
					              Note: The generated code will be inserted after the code generation of
 | 
				
			||||||
 | 
					              the body is finished, because only then the position is known }
 | 
				
			||||||
 | 
					            aktfilepos:=entrypos;
 | 
				
			||||||
 | 
					            gen_load_para_value(templist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { caller paraloc info is also necessary in the stackframe_entry
 | 
				
			||||||
 | 
					              code of the ppc (and possibly other processors)               }
 | 
				
			||||||
 | 
					            if not procdef.has_paraloc_info then
 | 
				
			||||||
 | 
					              begin
 | 
				
			||||||
 | 
					                paramanager.create_paraloc_info(procdef,callerside);
 | 
				
			||||||
 | 
					                procdef.has_paraloc_info:=true;
 | 
				
			||||||
 | 
					              end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { generate code for the node tree }
 | 
				
			||||||
 | 
					            do_secondpass(code);
 | 
				
			||||||
 | 
					            current_procinfo.aktproccode.concatlist(exprasmlist);
 | 
				
			||||||
 | 
					{$ifdef i386}
 | 
				
			||||||
 | 
					            procdef.fpu_used:=code.registersfpu;
 | 
				
			||||||
 | 
					{$endif i386}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { The position of the loadpara_asmnode is now known }
 | 
				
			||||||
 | 
					            aktproccode.insertlistafter(loadpara_asmnode.currenttai,templist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { first generate entry and initialize code with the correct
 | 
				
			||||||
 | 
					              position and switches }
 | 
				
			||||||
 | 
					            aktfilepos:=entrypos;
 | 
				
			||||||
 | 
					            aktlocalswitches:=entryswitches;
 | 
				
			||||||
 | 
					            gen_entry_code(templist);
 | 
				
			||||||
 | 
					            aktproccode.insertlistafter(entry_asmnode.currenttai,templist);
 | 
				
			||||||
 | 
					            gen_initialize_code(templist,false);
 | 
				
			||||||
 | 
					            aktproccode.insertlistafter(init_asmnode.currenttai,templist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            { now generate finalize and exit code with the correct position
 | 
				
			||||||
 | 
					              and switches }
 | 
				
			||||||
 | 
					            aktfilepos:=exitpos;
 | 
				
			||||||
 | 
					            aktlocalswitches:=exitswitches;
 | 
				
			||||||
 | 
					            gen_finalize_code(templist,false);
 | 
				
			||||||
 | 
					            { the finalcode must be concated if there was no position available,
 | 
				
			||||||
 | 
					              using insertlistafter will result in an insert at the start
 | 
				
			||||||
 | 
					              when currentai=nil }
 | 
				
			||||||
 | 
					            if assigned(final_asmnode.currenttai) then
 | 
				
			||||||
 | 
					              aktproccode.insertlistafter(final_asmnode.currenttai,templist)
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              aktproccode.concatlist(templist);
 | 
				
			||||||
 | 
					            { insert exit label at the correct position }
 | 
				
			||||||
 | 
					            cg.a_label(templist,current_procinfo.aktexitlabel);
 | 
				
			||||||
 | 
					            if assigned(exitlabel_asmnode.currenttai) then
 | 
				
			||||||
 | 
					              aktproccode.insertlistafter(exitlabel_asmnode.currenttai,templist)
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              aktproccode.concatlist(templist);
 | 
				
			||||||
 | 
					            { exit code }
 | 
				
			||||||
 | 
					            gen_exit_code(templist);
 | 
				
			||||||
 | 
					            aktproccode.concatlist(templist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{$ifdef OLDREGVARS}
 | 
					{$ifdef OLDREGVARS}
 | 
				
			||||||
        { note: this must be done only after as much code as possible has  }
 | 
					            { note: this must be done only after as much code as possible has  }
 | 
				
			||||||
        {   been generated. The result is that when you ungetregister() a  }
 | 
					            {   been generated. The result is that when you ungetregister() a  }
 | 
				
			||||||
        {   regvar, it will actually free the regvar (and alse free the    }
 | 
					            {   regvar, it will actually free the regvar (and alse free the    }
 | 
				
			||||||
        {   the regvars at the same time). Doing this too early will       }
 | 
					            {   the regvars at the same time). Doing this too early will       }
 | 
				
			||||||
        {   confuse the register allocator, as the regvars will still be   }
 | 
					            {   confuse the register allocator, as the regvars will still be   }
 | 
				
			||||||
        {   used. It should be done before loading the result regs (so     }
 | 
					            {   used. It should be done before loading the result regs (so     }
 | 
				
			||||||
        {   they don't conflict with the regvars) and before               }
 | 
					            {   they don't conflict with the regvars) and before               }
 | 
				
			||||||
        {   gen_entry_code (that one has to be able to allocate the        }
 | 
					            {   gen_entry_code (that one has to be able to allocate the        }
 | 
				
			||||||
        {   regvars again) (JM)                                            }
 | 
					            {   regvars again) (JM)                                            }
 | 
				
			||||||
        free_regvars(aktproccode);
 | 
					            free_regvars(aktproccode);
 | 
				
			||||||
{$endif OLDREGVARS}
 | 
					{$endif OLDREGVARS}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { add code that will load the return value, this is not done
 | 
					            { add code that will load the return value, this is not done
 | 
				
			||||||
          for assembler routines when they didn't reference the result
 | 
					              for assembler routines when they didn't reference the result
 | 
				
			||||||
          variable }
 | 
					              variable }
 | 
				
			||||||
        usesacc:=false;
 | 
					            usesacc:=false;
 | 
				
			||||||
        usesfpu:=false;
 | 
					            usesfpu:=false;
 | 
				
			||||||
        usesacchi:=false;
 | 
					            usesacchi:=false;
 | 
				
			||||||
        gen_load_return_value(templist,usesacc,usesacchi,usesfpu);
 | 
					            gen_load_return_value(templist,usesacc,usesacchi,usesfpu);
 | 
				
			||||||
        aktproccode.concatlist(templist);
 | 
					            aktproccode.concatlist(templist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { generate symbol and save end of header position }
 | 
					            { generate symbol and save end of header position }
 | 
				
			||||||
        aktfilepos:=entrypos;
 | 
					            aktfilepos:=entrypos;
 | 
				
			||||||
        gen_proc_symbol(templist);
 | 
					            gen_proc_symbol(templist);
 | 
				
			||||||
        headertai:=tai(templist.last);
 | 
					            headertai:=tai(templist.last);
 | 
				
			||||||
        { insert symbol }
 | 
					            { insert symbol }
 | 
				
			||||||
        aktproccode.insertlist(templist);
 | 
					            aktproccode.insertlist(templist);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { Free space in temp/registers for parast and localst, must be
 | 
					            { Free space in temp/registers for parast and localst, must be
 | 
				
			||||||
          done after gen_entry_code }
 | 
					              done after gen_entry_code }
 | 
				
			||||||
        aktfilepos:=exitpos;
 | 
					            aktfilepos:=exitpos;
 | 
				
			||||||
        if current_procinfo.procdef.localst.symtabletype=localsymtable then
 | 
					            if current_procinfo.procdef.localst.symtabletype=localsymtable then
 | 
				
			||||||
          gen_free_localst(aktproccode,tlocalsymtable(current_procinfo.procdef.localst));
 | 
					              gen_free_localst(aktproccode,tlocalsymtable(current_procinfo.procdef.localst));
 | 
				
			||||||
        gen_free_parast(aktproccode,tparasymtable(current_procinfo.procdef.parast));
 | 
					            gen_free_parast(aktproccode,tparasymtable(current_procinfo.procdef.parast));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { The procedure body is finished, we can now
 | 
					            { The procedure body is finished, we can now
 | 
				
			||||||
          allocate the registers }
 | 
					              allocate the registers }
 | 
				
			||||||
        if not(cs_no_regalloc in aktglobalswitches) then
 | 
					            if not(cs_no_regalloc in aktglobalswitches) then
 | 
				
			||||||
          begin
 | 
					              begin
 | 
				
			||||||
            cg.do_register_allocation(aktproccode,headertai);
 | 
					                cg.do_register_allocation(aktproccode,headertai);
 | 
				
			||||||
(*
 | 
					(*
 | 
				
			||||||
{$ifndef NoOpt}
 | 
					{$ifndef NoOpt}
 | 
				
			||||||
            if (cs_optimize in aktglobalswitches) and
 | 
					                if (cs_optimize in aktglobalswitches) and
 | 
				
			||||||
            { do not optimize pure assembler procedures }
 | 
					                { do not optimize pure assembler procedures }
 | 
				
			||||||
               not(pi_is_assembler in current_procinfo.flags)  then
 | 
					                   not(pi_is_assembler in current_procinfo.flags)  then
 | 
				
			||||||
              optimize(aktproccode);
 | 
					                  optimize(aktproccode);
 | 
				
			||||||
{$endif NoOpt}
 | 
					{$endif NoOpt}
 | 
				
			||||||
*)
 | 
					*)
 | 
				
			||||||
          end;
 | 
					              end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {$warning fixme translate_regvars}
 | 
					            { Add save and restore of used registers }
 | 
				
			||||||
{        translate_regvars(aktproccode,rg.colour);}
 | 
					            aktfilepos:=entrypos;
 | 
				
			||||||
        { Add save and restore of used registers }
 | 
					            gen_save_used_regs(templist);
 | 
				
			||||||
        aktfilepos:=entrypos;
 | 
					            aktproccode.insertlistafter(headertai,templist);
 | 
				
			||||||
        gen_save_used_regs(templist);
 | 
					            aktfilepos:=exitpos;
 | 
				
			||||||
        aktproccode.insertlistafter(headertai,templist);
 | 
					            gen_restore_used_regs(aktproccode,usesacc,usesacchi,usesfpu);
 | 
				
			||||||
        aktfilepos:=exitpos;
 | 
					            { Add stack allocation code after header }
 | 
				
			||||||
        gen_restore_used_regs(aktproccode,usesacc,usesacchi,usesfpu);
 | 
					            aktfilepos:=entrypos;
 | 
				
			||||||
        { Add stack allocation code after header }
 | 
					            gen_stackalloc_code(templist);
 | 
				
			||||||
        aktfilepos:=entrypos;
 | 
					            aktproccode.insertlistafter(headertai,templist);
 | 
				
			||||||
        gen_stackalloc_code(templist);
 | 
					            { Add exit code at the end }
 | 
				
			||||||
        aktproccode.insertlistafter(headertai,templist);
 | 
					            aktfilepos:=exitpos;
 | 
				
			||||||
        { Add exit code at the end }
 | 
					            gen_stackfree_code(templist,usesacc,usesacchi);
 | 
				
			||||||
        aktfilepos:=exitpos;
 | 
					            aktproccode.concatlist(templist);
 | 
				
			||||||
        gen_stackfree_code(templist,usesacc,usesacchi);
 | 
					            { Add end symbol and debug info }
 | 
				
			||||||
        aktproccode.concatlist(templist);
 | 
					            aktfilepos:=exitpos;
 | 
				
			||||||
        { Add end symbol and debug info }
 | 
					            gen_proc_symbol_end(templist);
 | 
				
			||||||
        aktfilepos:=exitpos;
 | 
					            aktproccode.concatlist(templist);
 | 
				
			||||||
        gen_proc_symbol_end(templist);
 | 
					 | 
				
			||||||
        aktproccode.concatlist(templist);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { save local data (casetable) also in the same file }
 | 
					            { save local data (casetable) also in the same file }
 | 
				
			||||||
        if assigned(aktlocaldata) and
 | 
					            if assigned(aktlocaldata) and
 | 
				
			||||||
           (not aktlocaldata.empty) then
 | 
					               (not aktlocaldata.empty) then
 | 
				
			||||||
         begin
 | 
					 | 
				
			||||||
           { because of the limited constant size of the arm, all data access is done pc relative }
 | 
					 | 
				
			||||||
           if target_info.cpu=cpu_arm then
 | 
					 | 
				
			||||||
             aktproccode.concatlist(aktlocaldata)
 | 
					 | 
				
			||||||
           else
 | 
					 | 
				
			||||||
             begin
 | 
					             begin
 | 
				
			||||||
               aktproccode.concat(Tai_section.Create(sec_data));
 | 
					               { because of the limited constant size of the arm, all data access is done pc relative }
 | 
				
			||||||
               aktproccode.concatlist(aktlocaldata);
 | 
					               if target_info.cpu=cpu_arm then
 | 
				
			||||||
               aktproccode.concat(Tai_section.Create(sec_code));
 | 
					                 aktproccode.concatlist(aktlocaldata)
 | 
				
			||||||
             end;
 | 
					               else
 | 
				
			||||||
        end;
 | 
					                 begin
 | 
				
			||||||
 | 
					                   aktproccode.concat(Tai_section.Create(sec_data));
 | 
				
			||||||
 | 
					                   aktproccode.concatlist(aktlocaldata);
 | 
				
			||||||
 | 
					                   aktproccode.concat(Tai_section.Create(sec_code));
 | 
				
			||||||
 | 
					                 end;
 | 
				
			||||||
 | 
					            end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { add the procedure to the codesegment }
 | 
					            { add the procedure to the codesegment }
 | 
				
			||||||
        if (cs_create_smart in aktmoduleswitches) then
 | 
					            if (cs_create_smart in aktmoduleswitches) then
 | 
				
			||||||
          codesegment.concat(Tai_cut.Create);
 | 
					              codesegment.concat(Tai_cut.Create);
 | 
				
			||||||
        codesegment.concatlist(aktproccode);
 | 
					            codesegment.concatlist(aktproccode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { only now we can remove the temps }
 | 
					            { only now we can remove the temps }
 | 
				
			||||||
        tg.resettempgen;
 | 
					            tg.resettempgen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { stop tempgen and ra }
 | 
					            { stop tempgen and ra }
 | 
				
			||||||
        tg.free;
 | 
					            tg.free;
 | 
				
			||||||
        cg.done_register_allocators;
 | 
					            cg.done_register_allocators;
 | 
				
			||||||
        tg:=nil;
 | 
					            tg:=nil;
 | 
				
			||||||
 | 
					          end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        { restore symtablestack }
 | 
					        { restore symtablestack }
 | 
				
			||||||
        remove_from_symtablestack;
 | 
					        remove_from_symtablestack;
 | 
				
			||||||
@ -1266,7 +1303,11 @@ implementation
 | 
				
			|||||||
end.
 | 
					end.
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  $Log$
 | 
					  $Log$
 | 
				
			||||||
  Revision 1.167  2003-10-24 17:40:23  peter
 | 
					  Revision 1.168  2003-10-30 16:22:40  peter
 | 
				
			||||||
 | 
					    * call firstpass before allocation and codegeneration is started
 | 
				
			||||||
 | 
					    * move leftover code from pass_2.generatecode() to psub
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Revision 1.167  2003/10/24 17:40:23  peter
 | 
				
			||||||
    * cleanup of the entry and exit code insertion
 | 
					    * cleanup of the entry and exit code insertion
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Revision 1.166  2003/10/21 15:14:33  peter
 | 
					  Revision 1.166  2003/10/21 15:14:33  peter
 | 
				
			||||||
 | 
				
			|||||||
@ -235,6 +235,7 @@ unit rgobj;
 | 
				
			|||||||
        procedure translate_registers(list:Taasmoutput);
 | 
					        procedure translate_registers(list:Taasmoutput);
 | 
				
			||||||
        {# Adds an interference edge.}
 | 
					        {# Adds an interference edge.}
 | 
				
			||||||
        procedure add_edge(u,v:Tsuperregister);
 | 
					        procedure add_edge(u,v:Tsuperregister);
 | 
				
			||||||
 | 
					        procedure check_unreleasedregs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unusedregs        : Tsuperregisterset;
 | 
					        unusedregs        : Tsuperregisterset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1801,10 +1802,29 @@ implementation
 | 
				
			|||||||
        end;
 | 
					        end;
 | 
				
			||||||
    end;
 | 
					    end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    procedure Trgobj.check_unreleasedregs;
 | 
				
			||||||
 | 
					{$ifdef EXTDEBUG}
 | 
				
			||||||
 | 
					      var
 | 
				
			||||||
 | 
					        sr : tsuperregister;
 | 
				
			||||||
 | 
					{$endif EXTDEBUG}
 | 
				
			||||||
 | 
					      begin
 | 
				
			||||||
 | 
					{$ifdef EXTDEBUG}
 | 
				
			||||||
 | 
					        for sr:=first_imaginary to maxreg-1 do
 | 
				
			||||||
 | 
					          if not(supregset_in(unusedregs,sr)) then
 | 
				
			||||||
 | 
					            Comment(V_Warning,'Register '+std_regname(newreg(R_INTREGISTER,sr,R_SUBNONE))+' not released');
 | 
				
			||||||
 | 
					{$endif EXTDEBUG}
 | 
				
			||||||
 | 
					      end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
end.
 | 
					end.
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  $Log$
 | 
					  $Log$
 | 
				
			||||||
  Revision 1.92  2003-10-29 21:29:14  jonas
 | 
					  Revision 1.93  2003-10-30 16:22:40  peter
 | 
				
			||||||
 | 
					    * call firstpass before allocation and codegeneration is started
 | 
				
			||||||
 | 
					    * move leftover code from pass_2.generatecode() to psub
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Revision 1.92  2003/10/29 21:29:14  jonas
 | 
				
			||||||
    * some ALLOWDUPREG improvements
 | 
					    * some ALLOWDUPREG improvements
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Revision 1.91  2003/10/21 15:15:36  peter
 | 
					  Revision 1.91  2003/10/21 15:15:36  peter
 | 
				
			||||||
 | 
				
			|||||||
@ -310,9 +310,11 @@ unit cgx86;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    begin
 | 
					    begin
 | 
				
			||||||
      { Int }
 | 
					      { Int }
 | 
				
			||||||
 | 
					      rgint.check_unreleasedregs;
 | 
				
			||||||
      rgint.do_register_allocation(list,headertai);
 | 
					      rgint.do_register_allocation(list,headertai);
 | 
				
			||||||
      rgint.translate_registers(list);
 | 
					      rgint.translate_registers(list);
 | 
				
			||||||
      { SSE }
 | 
					      { SSE }
 | 
				
			||||||
 | 
					      rgmm.check_unreleasedregs;
 | 
				
			||||||
      rgmm.do_register_allocation(list,headertai);
 | 
					      rgmm.do_register_allocation(list,headertai);
 | 
				
			||||||
      rgmm.translate_registers(list);
 | 
					      rgmm.translate_registers(list);
 | 
				
			||||||
    end;
 | 
					    end;
 | 
				
			||||||
@ -1735,7 +1737,11 @@ unit cgx86;
 | 
				
			|||||||
end.
 | 
					end.
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  $Log$
 | 
					  $Log$
 | 
				
			||||||
  Revision 1.84  2003-10-29 21:24:14  jonas
 | 
					  Revision 1.85  2003-10-30 16:22:40  peter
 | 
				
			||||||
 | 
					    * call firstpass before allocation and codegeneration is started
 | 
				
			||||||
 | 
					    * move leftover code from pass_2.generatecode() to psub
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Revision 1.84  2003/10/29 21:24:14  jonas
 | 
				
			||||||
    + support for fpu temp parameters
 | 
					    + support for fpu temp parameters
 | 
				
			||||||
    + saving/restoring of fpu register before/after a procedure call
 | 
					    + saving/restoring of fpu register before/after a procedure call
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user