mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 02:31:49 +01:00 
			
		
		
		
	+ no stackframe is generated for i386 if possible
git-svn-id: trunk@2162 -
This commit is contained in:
		
							parent
							
								
									a85bb43749
								
							
						
					
					
						commit
						f7d2c47f73
					
				| @ -240,7 +240,9 @@ than 255 characters. That's why using Ansi Strings} | |||||||
|          pi_needs_got, |          pi_needs_got, | ||||||
|          { references var/proc/type/const in static symtable, |          { references var/proc/type/const in static symtable, | ||||||
|            i.e. not allowed for inlining from other units } |            i.e. not allowed for inlining from other units } | ||||||
|          pi_uses_static_symtable |          pi_uses_static_symtable, | ||||||
|  |          { set if the procedure has to push parameters onto the stack } | ||||||
|  |          pi_has_stackparameter | ||||||
|        ); |        ); | ||||||
|        tprocinfoflags=set of tprocinfoflag; |        tprocinfoflags=set of tprocinfoflag; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -264,7 +264,7 @@ unit cgcpu; | |||||||
|               end |               end | ||||||
|             else |             else | ||||||
|               list.concat(Taicpu.op_none(A_LEAVE,S_NO)); |               list.concat(Taicpu.op_none(A_LEAVE,S_NO)); | ||||||
|             list.concat(tai_regalloc.dealloc(NR_FRAME_POINTER_REG,nil)); |             list.concat(tai_regalloc.dealloc(current_procinfo.framepointer,nil)); | ||||||
|           end; |           end; | ||||||
| 
 | 
 | ||||||
|         { return from proc } |         { return from proc } | ||||||
|  | |||||||
| @ -130,6 +130,9 @@ interface | |||||||
|           procedure printnodedata(var t:text);override; |           procedure printnodedata(var t:text);override; | ||||||
|           function  para_count:longint; |           function  para_count:longint; | ||||||
|           function  get_load_methodpointer:tnode; |           function  get_load_methodpointer:tnode; | ||||||
|  |           { checks if there are any parameters which end up at the stack, i.e. | ||||||
|  |             which have LOC_REFERENCE and set pi_has_stackparameter if this applies } | ||||||
|  |           procedure check_stack_parameters; | ||||||
|        private |        private | ||||||
|           AbstractMethodsList : TStringList; |           AbstractMethodsList : TStringList; | ||||||
|        end; |        end; | ||||||
| @ -2333,6 +2336,22 @@ type | |||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |     procedure tcallnode.check_stack_parameters; | ||||||
|  |       var | ||||||
|  |         hp : tcallparanode; | ||||||
|  |       begin | ||||||
|  |         hp:=tcallparanode(left); | ||||||
|  |         while assigned(hp) do | ||||||
|  |           begin | ||||||
|  |              if assigned(hp.parasym) and | ||||||
|  |                 assigned(hp.parasym.paraloc[callerside].location) and | ||||||
|  |                (hp.parasym.paraloc[callerside].location^.loc=LOC_REFERENCE) then | ||||||
|  |                include(current_procinfo.flags,pi_has_stackparameter); | ||||||
|  |              hp:=tcallparanode(hp.right); | ||||||
|  |           end; | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     function tcallnode.pass_1 : tnode; |     function tcallnode.pass_1 : tnode; | ||||||
|       var |       var | ||||||
|         st : tsymtable; |         st : tsymtable; | ||||||
| @ -2378,7 +2397,16 @@ type | |||||||
| 
 | 
 | ||||||
|          { work trough all parameters to get the register requirements } |          { work trough all parameters to get the register requirements } | ||||||
|          if assigned(left) then |          if assigned(left) then | ||||||
|            tcallparanode(left).det_registers; |            begin | ||||||
|  |              tcallparanode(left).det_registers; | ||||||
|  | 
 | ||||||
|  |              if cs_optimize in aktglobalswitches then | ||||||
|  |                begin | ||||||
|  |                  { check for stacked parameters } | ||||||
|  |                  check_stack_parameters; | ||||||
|  |                end; | ||||||
|  |            end; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|          { order parameters } |          { order parameters } | ||||||
|          order_parameters; |          order_parameters; | ||||||
|  | |||||||
| @ -54,6 +54,8 @@ interface | |||||||
|         procedure add_to_symtablestack; |         procedure add_to_symtablestack; | ||||||
|         procedure remove_from_symtablestack; |         procedure remove_from_symtablestack; | ||||||
|         procedure parse_body; |         procedure parse_body; | ||||||
|  | 
 | ||||||
|  |         function stack_tainting_parameter : boolean; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -96,7 +98,7 @@ implementation | |||||||
|        scanner,import,gendef, |        scanner,import,gendef, | ||||||
|        pbase,pstatmnt,pdecl,pdecsub,pexports, |        pbase,pstatmnt,pdecl,pdecsub,pexports, | ||||||
|        { codegen } |        { codegen } | ||||||
|        tgobj,cgobj,dbgbase, |        tgobj,cgbase,cgobj,dbgbase, | ||||||
|        ncgutil,regvars |        ncgutil,regvars | ||||||
| {$if defined(arm) or defined(powerpc) or defined(powerpc64)} | {$if defined(arm) or defined(powerpc) or defined(powerpc64)} | ||||||
|        ,aasmcpu |        ,aasmcpu | ||||||
| @ -604,6 +606,29 @@ implementation | |||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |     procedure check_for_stack(p : tnamedindexitem;arg:pointer); | ||||||
|  |       begin | ||||||
|  |          if tsym(p).typ=paravarsym then | ||||||
|  |            begin | ||||||
|  |              { check if there no parameter of the current procedure is stack dependend } | ||||||
|  |              if is_open_array(tparavarsym(p).vartype.def) or | ||||||
|  |                is_array_of_const(tparavarsym(p).vartype.def) then | ||||||
|  |                pboolean(arg)^:=true; | ||||||
|  |              if assigned(p) and | ||||||
|  |                 assigned(tparavarsym(p).paraloc[calleeside].location) and | ||||||
|  |                (tparavarsym(p).paraloc[calleeside].location^.loc=LOC_REFERENCE) then | ||||||
|  |                pboolean(arg)^:=true; | ||||||
|  |            end; | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     function tcgprocinfo.stack_tainting_parameter : boolean; | ||||||
|  |       begin | ||||||
|  |         result:=false; | ||||||
|  |         procdef.parast.foreach_static(@check_for_stack,@result); | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     procedure tcgprocinfo.generate_code; |     procedure tcgprocinfo.generate_code; | ||||||
|       var |       var | ||||||
|         oldprocinfo : tprocinfo; |         oldprocinfo : tprocinfo; | ||||||
| @ -680,6 +705,38 @@ implementation | |||||||
|             { set the start offset to the start of the temp area in the stack } |             { set the start offset to the start of the temp area in the stack } | ||||||
|             tg:=ttgobj.create; |             tg:=ttgobj.create; | ||||||
| 
 | 
 | ||||||
|  | {$ifdef i386} | ||||||
|  |             { try to strip the stack frame } | ||||||
|  |             { set the framepointer to esp if: | ||||||
|  |               - no assembler directive, those are handled elsewhere | ||||||
|  |               - no exceptions are used | ||||||
|  |               - no debug info | ||||||
|  |               - no pushes are used/esp modifications, could be: | ||||||
|  |                 * outgoing parameters on the stack | ||||||
|  |                 * incoming parameters on the stack | ||||||
|  |                 * open arrays | ||||||
|  |               - no inline assembler | ||||||
|  |             } | ||||||
|  |             if (cs_optimize in aktglobalswitches) and | ||||||
|  |                not(po_assembler in procdef.procoptions) and | ||||||
|  |                ((flags*[pi_has_assembler_block,pi_uses_exceptions,pi_is_assembler, | ||||||
|  |                        pi_needs_implicit_finally,pi_has_implicit_finally,pi_has_stackparameter])=[]) then | ||||||
|  |                begin | ||||||
|  |                  { we need the parameter info here to determine if the procedure gets | ||||||
|  |                    parameters on the stack | ||||||
|  | 
 | ||||||
|  |                    calling generate_parameter_info doesn't hurt but it costs time | ||||||
|  |                  } | ||||||
|  |                  generate_parameter_info; | ||||||
|  |                  if not(stack_tainting_parameter) then | ||||||
|  |                    begin | ||||||
|  |                      { Only need to set the framepointer } | ||||||
|  |                      framepointer:=NR_STACK_POINTER_REG; | ||||||
|  |                      tg.direction:=1; | ||||||
|  |                    end; | ||||||
|  |                end; | ||||||
|  | {$endif i386} | ||||||
|  | 
 | ||||||
|             { Create register allocator } |             { Create register allocator } | ||||||
|             cg.init_register_allocators; |             cg.init_register_allocators; | ||||||
| 
 | 
 | ||||||
| @ -713,6 +770,7 @@ implementation | |||||||
|                 procdef.has_paraloc_info:=true; |                 procdef.has_paraloc_info:=true; | ||||||
|               end; |               end; | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|             { generate code for the node tree } |             { generate code for the node tree } | ||||||
|             do_secondpass(code); |             do_secondpass(code); | ||||||
|             aktproccode.concatlist(exprasmlist); |             aktproccode.concatlist(exprasmlist); | ||||||
|  | |||||||
| @ -1839,11 +1839,12 @@ unit cgx86; | |||||||
|         { save old framepointer } |         { save old framepointer } | ||||||
|         if not nostackframe then |         if not nostackframe then | ||||||
|           begin |           begin | ||||||
|  |             list.concat(tai_regalloc.alloc(current_procinfo.framepointer,nil)); | ||||||
|             if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then |             if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then | ||||||
|               CGmessage(cg_d_stackframe_omited) |               CGmessage(cg_d_stackframe_omited) | ||||||
|             else |             else | ||||||
|               begin |               begin | ||||||
|                 list.concat(tai_regalloc.alloc(NR_FRAME_POINTER_REG,nil)); | 
 | ||||||
|                 include(rg[R_INTREGISTER].preserved_by_proc,RS_FRAME_POINTER_REG); |                 include(rg[R_INTREGISTER].preserved_by_proc,RS_FRAME_POINTER_REG); | ||||||
|                 list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],NR_FRAME_POINTER_REG)); |                 list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],NR_FRAME_POINTER_REG)); | ||||||
|                 { Return address and FP are both on stack } |                 { Return address and FP are both on stack } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 florian
						florian