From 0284016ee9ab09fa40f20a2d750ffba21f9bc43a Mon Sep 17 00:00:00 2001 From: florian Date: Wed, 23 Apr 2003 12:35:34 +0000 Subject: [PATCH] * fixed several issues with powerpc + applied a patch from Jonas for nested function calls (PowerPC only) * ... --- compiler/cgbase.pas | 24 +++++- compiler/cginfo.pas | 16 +++- compiler/cgobj.pas | 9 +- compiler/fpcdefs.inc | 10 ++- compiler/m68k/cpubase.pas | 51 ++++------- compiler/ncal.pas | 106 ++++++++++++++++++++++- compiler/ncgutil.pas | 27 +++++- compiler/nutils.pas | 156 ++++++++++++++++++++++++++++++++++ compiler/pmodules.pas | 31 +++++-- compiler/powerpc/agppcgas.pas | 20 +++-- compiler/powerpc/cgcpu.pas | 133 ++++++++++++++++++++++++++++- compiler/powerpc/cpubase.pas | 42 +++------ compiler/powerpc/cpupara.pas | 11 ++- compiler/powerpc/nppcadd.pas | 9 +- compiler/powerpc/nppccal.pas | 38 ++++++--- compiler/powerpc/nppccnv.pas | 9 +- compiler/powerpc/nppcinl.pas | 16 +++- compiler/psub.pas | 9 +- compiler/sparc/cpubase.pas | 43 ++++------ compiler/sparc/cpupara.pas | 11 ++- compiler/symdef.pas | 25 ++++-- 21 files changed, 640 insertions(+), 156 deletions(-) create mode 100644 compiler/nutils.pas diff --git a/compiler/cgbase.pas b/compiler/cgbase.pas index ea11d9d5fa..769a0d4d47 100644 --- a/compiler/cgbase.pas +++ b/compiler/cgbase.pas @@ -72,6 +72,8 @@ unit cgbase; procdef : tprocdef; {# offset from frame pointer to get parent frame pointer reference (used in nested routines only) + On the PowerPC, this is used to store the offset where the + frame pointer from the outer procedure is stored. } framepointer_offset : longint; {# offset from frame pointer to get self reference } @@ -217,6 +219,8 @@ unit cgbase; { save the size of pushed parameter, needed for aligning } pushedparasize : longint; + { procinfo instance which is used in procedures created automatically by the compiler } + voidprocpi : tprocinfo; { message calls with codegenerror support } procedure cgmessage(t : longint); @@ -515,6 +519,14 @@ implementation ResourceStrings:=TResourceStrings.Create; { use the librarydata from current_module } objectlibrary:=current_module.librarydata; + { for the implicitly generated init/final. procedures for global init. variables, + a dummy procinfo is necessary } + voidprocpi:=cprocinfo.create; + with voidprocpi do + begin + framepointer.enum:=R_INTREGISTER; + framepointer.number:=NR_FRAME_POINTER_REG; + end; end; @@ -549,6 +561,7 @@ implementation { resource strings } ResourceStrings.free; objectlibrary:=nil; + // voidprocpi.free; end; @@ -644,7 +657,6 @@ implementation commutativeop := list[op]; end; - {$ifdef fixLeaksOnError} procedure hcodegen_do_stop; var p: pprocinfo; @@ -652,7 +664,8 @@ begin p := pprocinfo(procinfoStack.pop); while p <> nil Do begin - dispose(p,done); + if p<>voidprocpi then + p.free; p := pprocinfo(procinfoStack.pop); end; procinfoStack.done; @@ -668,7 +681,12 @@ begin end. { $Log$ - Revision 1.40 2003-04-22 13:47:08 peter + Revision 1.41 2003-04-23 12:35:34 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.40 2003/04/22 13:47:08 peter * fixed C style array of const * fixed C array passing * fixed left to right with high parameters diff --git a/compiler/cginfo.pas b/compiler/cginfo.pas index 7af8883380..1b40000aa2 100644 --- a/compiler/cginfo.pas +++ b/compiler/cginfo.pas @@ -44,9 +44,14 @@ interface LOC_FPUREGISTER, { FPU stack } LOC_CFPUREGISTER, { if it is a FPU register variable on the fpu stack } LOC_MMXREGISTER, { MMX register } - LOC_CMMXREGISTER, { MMX register variable } + { MMX register variable } + LOC_CMMXREGISTER, LOC_SSEREGISTER, - LOC_CSSEREGISTER + LOC_CSSEREGISTER, + { multimedia register } + LOC_MMREGISTER, + { Constant multimedia reg which shouldn't be modified } + LOC_CMMREGISTER ); {# Generic opcodes, which must be supported by all processors @@ -126,7 +131,12 @@ implementation end. { $Log$ - Revision 1.19 2003-04-22 23:50:22 peter + Revision 1.20 2003-04-23 12:35:34 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.19 2003/04/22 23:50:22 peter * firstpass uses expectloc * checks if there are differences between the expectloc and location.loc from secondpass in EXTDEBUG diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index adb4b41b3a..1be56e6926 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -1808,7 +1808,7 @@ unit cgobj; var r:Tregister; begin - r.enum:=R_INTREGISTER;; + r.enum:=R_INTREGISTER; r.number:=NR_ACCUMULATOR; a_load_ref_reg(list, OS_S32, href, r); end; @@ -1838,7 +1838,12 @@ finalization end. { $Log$ - Revision 1.84 2003-04-22 14:33:38 peter + Revision 1.85 2003-04-23 12:35:34 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.84 2003/04/22 14:33:38 peter * removed some notes/hints Revision 1.83 2003/04/22 13:47:08 peter diff --git a/compiler/fpcdefs.inc b/compiler/fpcdefs.inc index d3063eaf1e..6c088d48c1 100644 --- a/compiler/fpcdefs.inc +++ b/compiler/fpcdefs.inc @@ -52,6 +52,9 @@ {$define cpu64bit} {$undef cpuflags} {$endif alpha} +{$ifdef powerpc} + {$define callparatemp} +{$endif powerpc} { FPU Emulator support } {$ifdef m68k} @@ -60,7 +63,12 @@ { $Log$ - Revision 1.14 2002-12-06 16:56:57 peter + Revision 1.15 2003-04-23 12:35:34 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.14 2002/12/06 16:56:57 peter * only compile cs_fp_emulation support when cpufpuemu is defined * define cpufpuemu for m68k only diff --git a/compiler/m68k/cpubase.pas b/compiler/m68k/cpubase.pas index a0ad1fcc4a..30525ac5f6 100644 --- a/compiler/m68k/cpubase.pas +++ b/compiler/m68k/cpubase.pas @@ -114,7 +114,7 @@ uses R_INTREGISTER,R_FLOATREGISTER); Tnewregister=word; - + Tregister=record enum:Toldregister; number:word; @@ -151,14 +151,14 @@ uses NR_D6 = $0700; NR_D7 = $0800; NR_A0 = $0900; NR_A1 = $0A00; NR_A2 = $0B00; NR_A3 = $0C00; NR_A4 = $0D00; NR_A5 = $0E00; NR_A6 = $0F00; - NR_A7 = $1000; + NR_A7 = $1000; {Super registers.} - RS_D0 = $01; RS_D1 = $02; RS_D2 = $03; - RS_D3 = $04; RS_D4 = $05; RS_D5 = $06; - RS_D6 = $07; RS_D7 = $08; RS_A0 = $09; - RS_A1 = $0A; RS_A2 = $0B; RS_A3 = $0C; - RS_A4 = $0D; RS_A5 = $0E; RS_A6 = $0F; + RS_D0 = $01; RS_D1 = $02; RS_D2 = $03; + RS_D3 = $04; RS_D4 = $05; RS_D5 = $06; + RS_D6 = $07; RS_D7 = $08; RS_A0 = $09; + RS_A1 = $0A; RS_A2 = $0B; RS_A3 = $0C; + RS_A4 = $0D; RS_A5 = $0E; RS_A6 = $0F; RS_A7 = $10; {Sub register numbers:} @@ -288,35 +288,15 @@ uses *****************************************************************************} type - TLoc=( - LOC_INVALID, { added for tracking problems} - LOC_CONSTANT, { constant value } - LOC_JUMP, { boolean results only, jump to false or true label } - LOC_FLAGS, { boolean results only, flags are set } - LOC_CREFERENCE, { in memory constant value reference (cannot change) } - LOC_REFERENCE, { in memory value } - LOC_REGISTER, { in a processor register } - LOC_CREGISTER, { Constant register which shouldn't be modified } - LOC_FPUREGISTER, { FPU stack } - LOC_CFPUREGISTER, { if it is a FPU register variable on the fpu stack } - - { The m68k doesn't know multi media registers but this is for easier porting - because several generic parts of the compiler use it. } - LOC_MMREGISTER, - { The m68k doesn't know multi media registers but this is for easier porting - because several generic parts of the compiler use it. } - LOC_CMMREGISTER - ); - { tparamlocation describes where a parameter for a procedure is stored. References are given from the caller's point of view. The usual TLocation isn't used, because contains a lot of unnessary fields. } tparalocation = packed record size : TCGSize; - loc : TLoc; + loc : TCGLoc; sp_fixup : longint; - case TLoc of + case TCGLoc of LOC_REFERENCE : (reference : tparareference); { segment in reference at the same place as in loc_register } LOC_REGISTER,LOC_CREGISTER : ( @@ -331,9 +311,9 @@ uses end; tlocation = packed record - loc : TLoc; + loc : TCGLoc; size : TCGSize; - case TLoc of + case TCGLoc of LOC_FLAGS : (resflags : tresflags); LOC_CONSTANT : ( case longint of @@ -646,7 +626,7 @@ implementation function flags_to_cond(const f: TResFlags) : TAsmCond; const flags2cond: array[tresflags] of tasmcond = ( - C_EQ,{F_E equal} + C_EQ,{F_E equal} C_NE,{F_NE not equal} C_GT,{F_G gt signed} C_LT,{F_L lt signed} @@ -726,7 +706,12 @@ implementation end. { $Log$ - Revision 1.18 2003-02-19 22:00:16 daniel + Revision 1.19 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.18 2003/02/19 22:00:16 daniel * Code generator converted to new register notation - Horribily outdated todo.txt removed diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 0667e81669..6816409a71 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -29,7 +29,7 @@ interface uses cutils,cclasses, globtype,cpuinfo, - node, + node,nbas, {$ifdef state_tracking} nstate, {$endif state_tracking} @@ -113,6 +113,9 @@ interface function docompare(p: tnode): boolean; override; procedure set_procvar(procvar:tnode); private +{$ifdef callparatemp} + function extract_functioncall_paras: tblocknode; +{$endif callparatemp} AbstractMethodsList : TStringList; end; tcallnodeclass = class of tcallnode; @@ -179,7 +182,8 @@ implementation verbose,globals, symconst,paramgr,defutil,defcmp, htypechk,pass_1,cpubase, - nbas,ncnv,nld,ninl,nadd,ncon,nmem, + ncnv,nld,ninl,nadd,ncon,nmem, + nutils, rgobj,cginfo,cgbase ; @@ -1958,6 +1962,58 @@ type end; +{$ifdef callparatemp} + function tree_contains_function_call(var n: tnode): foreachnoderesult; + begin + result := fen_false; + if n.nodetype = calln then + { stop when we encounter a call node } + result := fen_norecurse_true; + end; + + + function tcallnode.extract_functioncall_paras: tblocknode; + var + curpara: tcallparanode; + newblock: tblocknode; + newstatement: tstatementnode; + temp: ttempcreatenode; + foundcall: boolean; + begin + foundcall := false; + curpara := tcallparanode(left); + if assigned(curpara) then + curpara := tcallparanode(curpara.right); + newblock := nil; + while assigned(curpara) do + begin + if foreachnodestatic(curpara.left,@tree_contains_function_call) then + begin + if (not foundcall) then + begin + foundcall := true; + newblock := internalstatements(newstatement); + end; + temp := ctempcreatenode.create(curpara.left.resulttype,curpara.left.resulttype.def.size,true); + addstatement(newstatement,temp); + resulttypepass(newstatement); + addstatement(newstatement, + cassignmentnode.create(ctemprefnode.create(temp),curpara.left)); + resulttypepass(newstatement); + { after the assignment, turn the temp into a non-persistent one, so } + { that it will be freed once it's used as parameter } + addstatement(newstatement,ctempdeletenode.create_normal_temp(temp)); + resulttypepass(newstatement); + curpara.left := ctemprefnode.create(temp); + { the para's themselves are "resulttypepassed" in in tcallnode.pass_1 } + end; + curpara := tcallparanode(curpara.right); + end; + result := newblock; + end; +{$endif callparatemp} + + function tcallnode.pass_1 : tnode; var inlinecode : tnode; @@ -1965,6 +2021,11 @@ type {$ifdef m68k} regi : tregister; {$endif} +{$ifdef callparatemp} + callparatemps, newblock: tblocknode; + statement: tstatementnode; + paras, oldright, newcall: tnode; +{$endif callparatemp} label errorexit; begin @@ -1972,6 +2033,10 @@ type inlined:=false; inlinecode := nil; +{$ifdef callparatemp} + callparatemps := extract_functioncall_paras; +{$endif callparatemp} + { work trough all parameters to get the register requirements } if assigned(left) then tcallparanode(left).det_registers; @@ -2176,9 +2241,39 @@ type registersmmx:=max(left.registersmmx,registersmmx); {$endif SUPPORT_MMX} end; +{$ifdef callparatemp} + if (callparatemps <> nil) then + begin + { we have to replace the callnode with a blocknode. firstpass will } + { free the original call node. Avoid copying all subnodes though } + paras := left; + oldright := right; + left := nil; + right := nil; + newcall := self.getcopy; + tcallnode(newcall).left := paras; + tcallnode(newcall).right := oldright; + + newblock := internalstatements(statement); + addstatement(statement,callparatemps); + { add the copy of the call node after the callparatemps block } + { and return that. The last statement of a bocknode determines } + { the resulttype & location of the block -> ok. Working with a } + { new block is easier than going to the end of the callparatemps } + { block (JM) } + addstatement(statement,newcall); + result := newblock; + { set to nil so we can free this one in case of an errorexit } + callparatemps := nil; + end; +{$endif callparatemp} errorexit: if inlined then procdefinition.proccalloption:=pocall_inline; +{$ifdef callparatemp} + if assigned(callparatemps) then + callparatemps.free; +{$endif callparatemp} end; {$ifdef state_tracking} @@ -2391,7 +2486,12 @@ begin end. { $Log$ - Revision 1.139 2003-04-22 23:50:22 peter + Revision 1.140 2003-04-23 12:35:34 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.139 2003/04/22 23:50:22 peter * firstpass uses expectloc * checks if there are differences between the expectloc and location.loc from secondpass in EXTDEBUG diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index 26b154d30d..6a698fee47 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -2000,7 +2000,11 @@ implementation procedure genimplicitunitinit(list : TAAsmoutput); + var + oldprocinfo : tprocinfo; begin + oldprocinfo:=procinfo; + procinfo:=voidprocpi; {$ifdef GDB} if (cs_debuginfo in aktmoduleswitches) and target_info.use_function_relative_addresses then @@ -2008,17 +2012,26 @@ implementation {$endif GDB} list.concat(Tai_symbol.Createname_global('INIT$$'+current_module.modulename^,0)); list.concat(Tai_symbol.Createname_global(target_info.cprefix+current_module.modulename^+'_init',0)); +{$ifndef i386} + { on the 386, g_return_from_proc is a simple return, so we don't need a real stack frame } + cg.g_stackframe_entry(list,0); +{$endif i386} { using current_module.globalsymtable is hopefully } { more robust than symtablestack and symtablestack.next } if assigned(current_module.globalsymtable) then tsymtable(current_module.globalsymtable).foreach_static({$ifdef FPCPROCVAR}@{$endif}finalize_data,list); tsymtable(current_module.localsymtable).foreach_static({$ifdef FPCPROCVAR}@{$endif}finalize_data,list); cg.g_return_from_proc(list,0); + procinfo:=oldprocinfo; end; procedure genimplicitunitfinal(list : TAAsmoutput); + var + oldprocinfo : tprocinfo; begin + oldprocinfo:=procinfo; + procinfo:=voidprocpi; {$ifdef GDB} if (cs_debuginfo in aktmoduleswitches) and target_info.use_function_relative_addresses then @@ -2026,20 +2039,28 @@ implementation {$endif GDB} list.concat(Tai_symbol.Createname_global('FINALIZE$$'+current_module.modulename^,0)); list.concat(Tai_symbol.Createname_global(target_info.cprefix+current_module.modulename^+'_finalize',0)); +{$ifndef i386} + { on the 386, g_return_from_proc is a simple return, so we don't need a real stack frame } + cg.g_stackframe_entry(list,0); +{$endif i386} { using current_module.globalsymtable is hopefully } { more robust than symtablestack and symtablestack.next } if assigned(current_module.globalsymtable) then tsymtable(current_module.globalsymtable).foreach_static({$ifdef FPCPROCVAR}@{$endif}finalize_data,list); tsymtable(current_module.localsymtable).foreach_static({$ifdef FPCPROCVAR}@{$endif}finalize_data,list); cg.g_return_from_proc(list,0); + procinfo:=oldprocinfo; end; - - end. { $Log$ - Revision 1.87 2003-04-22 14:33:38 peter + Revision 1.88 2003-04-23 12:35:34 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.87 2003/04/22 14:33:38 peter * removed some notes/hints Revision 1.86 2003/04/22 13:47:08 peter diff --git a/compiler/nutils.pas b/compiler/nutils.pas new file mode 100644 index 0000000000..18a28628c3 --- /dev/null +++ b/compiler/nutils.pas @@ -0,0 +1,156 @@ +{ + $Id$ + Copyright (c) 1998-2002 by Florian Klaempfl + + Type checking and register allocation for inline nodes + + 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 nutils; + +{$i fpcdefs.inc} + +interface + + uses + node; + + type + { resulttype of functions that process on all nodes in a (sub)tree } + foreachnoderesult = ( + { false, continue recursion } + fen_false, + { false, stop recursion } + fen_norecurse_false, + { true, continue recursion } + fen_true, + { true, stop recursion } + fen_norecurse_true + ); + + + foreachnodefunction = function(var n: tnode): foreachnoderesult of object; + staticforeachnodefunction = function(var n: tnode): foreachnoderesult; + + + function foreachnode(var n: tnode; f: foreachnodefunction): boolean; + function foreachnodestatic(var n: tnode; f: staticforeachnodefunction): boolean; + +implementation + + uses nflw,nset,ncal; + + function foreachnode(var n: tnode; f: foreachnodefunction): boolean; + begin + result := false; + if not assigned(n) then + exit; + case f(n) of + fen_norecurse_false: + exit; + fen_norecurse_true: + begin + result := true; + exit; + end; + fen_true: + result := true; + { result is already false + fen_false: + result := false; } + end; + case n.nodetype of + calln: + result := foreachnode(tcallnode(n).methodpointer,f) or result; + procinlinen: + result := foreachnode(tprocinlinenode(n).inlinetree,f) or result; + ifn, whilerepeatn, forn: + begin + { not in one statement, won't work because of b- } + result := foreachnode(tloopnode(n).t1,f) or result; + result := foreachnode(tloopnode(n).t2,f) or result; + end; + raisen: + result := foreachnode(traisenode(n).frametree,f) or result; + casen: + result := foreachnode(tcasenode(n). elseblock,f) or result; + end; + if n.inheritsfrom(tbinarynode) then + begin + result := foreachnode(tbinarynode(n).right,f) or result; + result := foreachnode(tbinarynode(n).left,f) or result; + end + else if n.inheritsfrom(tunarynode) then + result := foreachnode(tunarynode(n).left,f) or result; + end; + + + function foreachnodestatic(var n: tnode; f: staticforeachnodefunction): boolean; + begin + result := false; + if not assigned(n) then + exit; + case f(n) of + fen_norecurse_false: + exit; + fen_norecurse_true: + begin + result := true; + exit; + end; + fen_true: + result := true; + { result is already false + fen_false: + result := false; } + end; + case n.nodetype of + calln: + result := foreachnodestatic(tcallnode(n).methodpointer,f) or result; + procinlinen: + result := foreachnodestatic(tprocinlinenode(n).inlinetree,f) or result; + ifn, whilerepeatn, forn: + begin + { not in one statement, won't work because of b- } + result := foreachnodestatic(tloopnode(n).t1,f) or result; + result := foreachnodestatic(tloopnode(n).t2,f) or result; + end; + raisen: + result := foreachnodestatic(traisenode(n).frametree,f) or result; + casen: + result := foreachnodestatic(tcasenode(n). elseblock,f) or result; + end; + if n.inheritsfrom(tbinarynode) then + begin + result := foreachnodestatic(tbinarynode(n).right,f) or result; + result := foreachnodestatic(tbinarynode(n).left,f) or result; + end + else if n.inheritsfrom(tunarynode) then + result := foreachnodestatic(tunarynode(n).left,f) or result; + end; + + +end. + +{ + $Log$ + Revision 1.1 2003-04-23 12:35:34 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + +} \ No newline at end of file diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 05d3b4f6a0..218d90a198 100644 --- a/compiler/pmodules.pas +++ b/compiler/pmodules.pas @@ -774,7 +774,9 @@ implementation store_crc,store_interface_crc : cardinal; s2 : ^string; {Saves stack space} force_init_final : boolean; + initfinalcode : taasmoutput; begin + initfinalcode:=taasmoutput.create; consume(_UNIT); if compile_level=1 then Status.IsExe:=false; @@ -999,7 +1001,9 @@ implementation { now we can insert a cut } if (cs_create_smart in aktmoduleswitches) then codeSegment.concat(Tai_cut.Create); - genimplicitunitinit(codesegment); + genimplicitunitinit(initfinalcode); + initfinalcode.convert_registers; + codesegment.concatlist(initfinalcode); end; { finalize? } if token=_FINALIZATION then @@ -1021,7 +1025,9 @@ implementation { now we can insert a cut } if (cs_create_smart in aktmoduleswitches) then codeSegment.concat(Tai_cut.Create); - genimplicitunitfinal(codesegment); + genimplicitunitfinal(initfinalcode); + initfinalcode.convert_registers; + codesegment.concatlist(initfinalcode); end; { the last char should always be a point } @@ -1166,7 +1172,10 @@ implementation exit; end; + initfinalcode.free; + Comment(V_Used,'Finished compiling module '+current_module.modulename^); + end; @@ -1175,7 +1184,9 @@ implementation main_file: tinputfile; st : tsymtable; hp : tmodule; + initfinalcode : taasmoutput; begin + initfinalcode:=taasmoutput.create; DLLsource:=islibrary; Status.IsLibrary:=IsLibrary; Status.IsExe:=true; @@ -1318,11 +1329,15 @@ So, all parameters are passerd into registers in sparc architecture.} { Add initialize section } if (cs_create_smart in aktmoduleswitches) then codeSegment.concat(Tai_cut.Create); - genimplicitunitinit(codesegment); + genimplicitunitinit(initfinalcode); + initfinalcode.convert_registers; + codesegment.concatlist(initfinalcode); { Add finalize section } if (cs_create_smart in aktmoduleswitches) then codeSegment.concat(Tai_cut.Create); - genimplicitunitfinal(codesegment); + genimplicitunitfinal(initfinalcode); + initfinalcode.convert_registers; + codesegment.concatlist(initfinalcode); end; { Add symbol to the exports section for win32 so smartlinking a @@ -1448,12 +1463,18 @@ So, all parameters are passerd into registers in sparc architecture.} linker.MakeExecutable; end; end; + initfinalcode.free; end; end. { $Log$ - Revision 1.100 2003-04-12 15:13:03 peter + Revision 1.101 2003-04-23 12:35:34 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.100 2003/04/12 15:13:03 peter * Use the original unitname when defining a unitsym Revision 1.99 2003/03/23 23:21:42 hajny diff --git a/compiler/powerpc/agppcgas.pas b/compiler/powerpc/agppcgas.pas index 2ffbd42a76..8f5ab54f2b 100644 --- a/compiler/powerpc/agppcgas.pas +++ b/compiler/powerpc/agppcgas.pas @@ -174,10 +174,10 @@ unit agppcgas; if (symaddr <> refs_full) then s := s+')'+symaddr2str[symaddr]; - if (index.enum < firstreg) or (index.enum > lastreg) then - internalerror(20030312); - if (base.enum < firstreg) or (base.enum > lastreg) then - internalerror(200303123); + if (index.enum < firstreg) or (index.enum > lastreg) then + internalerror(20030312); + if (base.enum < firstreg) or (base.enum > lastreg) then + internalerror(200303123); if (index.enum=R_NO) and (base.enum<>R_NO) then begin if offset=0 then @@ -192,7 +192,7 @@ unit agppcgas; else if (index.enum<>R_NO) and (base.enum<>R_NO) and (offset=0) then s:=s+gas_reg2str[base.enum]+','+gas_reg2str[index.enum] else if ((index.enum<>R_NO) or (base.enum<>R_NO)) then - internalerror(19992); + internalerror(19992); end; getreferencestring:=s; end; @@ -364,6 +364,9 @@ unit agppcgas; sep:=#9; for i:=0 to taicpu(hp).ops-1 do begin + // debug code + // writeln(s); + // writeln(taicpu(hp).fileinfo.line); s:=s+sep+getopstr(taicpu(hp).oper[i]); sep:=','; end; @@ -377,7 +380,12 @@ begin end. { $Log$ - Revision 1.21 2003-03-12 22:43:38 jonas + Revision 1.22 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.21 2003/03/12 22:43:38 jonas * more powerpc and generic fixes related to the new register allocator Revision 1.20 2003/01/08 18:43:57 daniel diff --git a/compiler/powerpc/cgcpu.pas b/compiler/powerpc/cgcpu.pas index 4174202a7f..ba012ac069 100644 --- a/compiler/powerpc/cgcpu.pas +++ b/compiler/powerpc/cgcpu.pas @@ -76,7 +76,7 @@ unit cgcpu; procedure g_flags2reg(list: taasmoutput; size: TCgSize; const f: TResFlags; reg: TRegister); override; - + procedure g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer);override; procedure g_stackframe_entry(list : taasmoutput;localsize : longint);override; procedure g_return_from_proc(list : taasmoutput;parasize : aword); override; procedure g_restore_frame_pointer(list : taasmoutput);override; @@ -958,7 +958,7 @@ const { following is the entry code as described in "Altivec Programming } { Interface Manual", bar the saving of AltiVec registers } rsp.enum:=R_INTREGISTER; - rsp.number:=NR_STACK_POINTER_REG;; + rsp.number:=NR_STACK_POINTER_REG; a_reg_alloc(list,rsp); r.enum:=R_INTREGISTER; r.number:=NR_R0; @@ -1824,6 +1824,128 @@ const free_scratch_reg(list,dst.base); end; + procedure tcgppc.g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;elesize:integer); + var + lenref : treference; + power,len : longint; +{$ifndef __NOWINPECOFF__} + again,ok : tasmlabel; +{$endif} + r,r2,rsp:Tregister; + begin + {$warning !!!! FIX ME !!!!} +{!!!! + lenref:=ref; + inc(lenref.offset,4); + { get stack space } + r.enum:=R_INTREGISTER; + r.number:=NR_EDI; + rsp.enum:=R_INTREGISTER; + rsp.number:=NR_ESP; + r2.enum:=R_INTREGISTER; + rg.getexplicitregisterint(list,NR_EDI); + list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,r)); + list.concat(Taicpu.op_reg(A_INC,S_L,r)); + if (elesize<>1) then + begin + if ispowerof2(elesize, power) then + list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,r)) + else + list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,r)); + end; +{$ifndef __NOWINPECOFF__} + { windows guards only a few pages for stack growing, } + { so we have to access every page first } + if target_info.system=system_i386_win32 then + begin + objectlibrary.getlabel(again); + objectlibrary.getlabel(ok); + a_label(list,again); + list.concat(Taicpu.op_const_reg(A_CMP,S_L,winstackpagesize,r)); + a_jmp_cond(list,OC_B,ok); + list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,rsp)); + r2.number:=NR_EAX; + list.concat(Taicpu.op_reg(A_PUSH,S_L,r)); + list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize,r)); + a_jmp_always(list,again); + + a_label(list,ok); + list.concat(Taicpu.op_reg_reg(A_SUB,S_L,r,rsp)); + rg.ungetregisterint(list,r); + { now reload EDI } + rg.getexplicitregisterint(list,NR_EDI); + list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,r)); + list.concat(Taicpu.op_reg(A_INC,S_L,r)); + + if (elesize<>1) then + begin + if ispowerof2(elesize, power) then + list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,r)) + else + list.concat(Taicpu.op_const_reg(A_IMUL,S_L,elesize,r)); + end; + end + else +{$endif __NOWINPECOFF__} + list.concat(Taicpu.op_reg_reg(A_SUB,S_L,r,rsp)); + { align stack on 4 bytes } + list.concat(Taicpu.op_const_reg(A_AND,S_L,$fffffff4,rsp)); + { load destination } + a_load_reg_reg(list,OS_INT,OS_INT,rsp,r); + + { don't destroy the registers! } + r2.number:=NR_ECX; + list.concat(Taicpu.op_reg(A_PUSH,S_L,r2)); + r2.number:=NR_ESI; + list.concat(Taicpu.op_reg(A_PUSH,S_L,r2)); + + { load count } + r2.number:=NR_ECX; + a_load_ref_reg(list,OS_INT,lenref,r2); + + { load source } + r2.number:=NR_ESI; + a_load_ref_reg(list,OS_INT,ref,r2); + + { scheduled .... } + r2.number:=NR_ECX; + list.concat(Taicpu.op_reg(A_INC,S_L,r2)); + + { calculate size } + len:=elesize; + opsize:=S_B; + if (len and 3)=0 then + begin + opsize:=S_L; + len:=len shr 2; + end + else + if (len and 1)=0 then + begin + opsize:=S_W; + len:=len shr 1; + end; + + if ispowerof2(len, power) then + list.concat(Taicpu.op_const_reg(A_SHL,S_L,power,r2)) + else + list.concat(Taicpu.op_const_reg(A_IMUL,S_L,len,r2)); + list.concat(Taicpu.op_none(A_REP,S_NO)); + case opsize of + S_B : list.concat(Taicpu.Op_none(A_MOVSB,S_NO)); + S_W : list.concat(Taicpu.Op_none(A_MOVSW,S_NO)); + S_L : list.concat(Taicpu.Op_none(A_MOVSD,S_NO)); + end; + rg.ungetregisterint(list,r); + r2.number:=NR_ESI; + list.concat(Taicpu.op_reg(A_POP,S_L,r2)); + r2.number:=NR_ECX; + list.concat(Taicpu.op_reg(A_POP,S_L,r2)); + + { patch the new address } + a_load_reg_ref(list,OS_INT,rsp,ref); +!!!!} + end; procedure tcgppc.g_overflowcheck(list: taasmoutput; const p: tnode); @@ -2215,7 +2337,12 @@ begin end. { $Log$ - Revision 1.78 2003-04-16 09:26:55 jonas + Revision 1.79 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.78 2003/04/16 09:26:55 jonas * assembler procedures now again get a stackframe if they have local variables. No space is reserved for a function result however. Also, the register parameters aren't automatically saved on the stack diff --git a/compiler/powerpc/cpubase.pas b/compiler/powerpc/cpubase.pas index af564b0c1a..896525d81e 100644 --- a/compiler/powerpc/cpubase.pas +++ b/compiler/powerpc/cpubase.pas @@ -395,33 +395,6 @@ uses *****************************************************************************} type - TLoc=( - { added for tracking problems} - LOC_INVALID, - { ordinal constant } - LOC_CONSTANT, - { in a processor register } - LOC_REGISTER, - { Constant register which shouldn't be modified } - LOC_CREGISTER, - { FPU register} - LOC_FPUREGISTER, - { Constant FPU register which shouldn't be modified } - LOC_CFPUREGISTER, - { multimedia register } - LOC_MMREGISTER, - { Constant multimedia reg which shouldn't be modified } - LOC_CMMREGISTER, - { in memory } - LOC_REFERENCE, - { in memory (constant) } - LOC_CREFERENCE, - { boolean results only, jump to false or true label } - LOC_JUMP, - { boolean results only, flags are set } - LOC_FLAGS - ); - { tparamlocation describes where a parameter for a procedure is stored. References are given from the caller's point of view. The usual TLocation isn't used, because contains a lot of unnessary fields. @@ -431,7 +404,7 @@ uses { The location type where the parameter is passed, usually LOC_REFERENCE,LOC_REGISTER or LOC_FPUREGISTER } - loc : TLoc; + loc : TCGLoc; { The stack pointer must be decreased by this value before the parameter is copied to the given destination. This allows to "encode" pushes with tparalocation. @@ -439,7 +412,7 @@ uses because several generic code accesses it. } sp_fixup : longint; - case TLoc of + case TCGLoc of LOC_REFERENCE : (reference : tparareference); LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER, LOC_REGISTER,LOC_CREGISTER : ( @@ -466,8 +439,8 @@ uses tlocation = packed record size : TCGSize; - loc : tloc; - case tloc of + loc : tcgloc; + case tcgloc of LOC_CREFERENCE,LOC_REFERENCE : (reference : treference); LOC_CONSTANT : ( case longint of @@ -879,7 +852,12 @@ implementation end. { $Log$ - Revision 1.47 2003-04-22 11:27:48 florian + Revision 1.48 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.47 2003/04/22 11:27:48 florian + added first_ and last_imreg Revision 1.46 2003/03/19 14:26:26 jonas diff --git a/compiler/powerpc/cpupara.pas b/compiler/powerpc/cpupara.pas index 2255fa7386..6eec42107b 100644 --- a/compiler/powerpc/cpupara.pas +++ b/compiler/powerpc/cpupara.pas @@ -67,7 +67,7 @@ unit cpupara; end; end; - function getparaloc(p : tdef) : tloc; + function getparaloc(p : tdef) : tcgloc; begin { Later, the LOC_REFERENCE is in most cases changed into LOC_REGISTER @@ -129,7 +129,7 @@ unit cpupara; paradef : tdef; stack_offset : aword; hp : tparaitem; - loc : tloc; + loc : tcgloc; is_64bit: boolean; procedure assignintreg; @@ -301,7 +301,12 @@ begin end. { $Log$ - Revision 1.25 2003-04-17 18:52:35 jonas + Revision 1.26 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.25 2003/04/17 18:52:35 jonas * process para's from first to last instead of the other way round Revision 1.24 2003/04/16 07:55:07 jonas diff --git a/compiler/powerpc/nppcadd.pas b/compiler/powerpc/nppcadd.pas index 1181000799..9329f91bdf 100644 --- a/compiler/powerpc/nppcadd.pas +++ b/compiler/powerpc/nppcadd.pas @@ -73,7 +73,7 @@ interface result := nil; firstpass(left); firstpass(right); - location.loc := LOC_FLAGS; + expectloc := LOC_FLAGS; calcregisters(self,2,0,0); exit; end; @@ -1479,7 +1479,12 @@ begin end. { $Log$ - Revision 1.24 2003-03-11 21:46:24 jonas + Revision 1.25 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.24 2003/03/11 21:46:24 jonas * lots of new regallocator fixes, both in generic and ppc-specific code (ppc compiler still can't compile the linux system unit though) diff --git a/compiler/powerpc/nppccal.pas b/compiler/powerpc/nppccal.pas index 8d226e7478..f0db44e3cc 100644 --- a/compiler/powerpc/nppccal.pas +++ b/compiler/powerpc/nppccal.pas @@ -72,38 +72,43 @@ implementation end; procedure tppccallnode.push_framepointer; - + var + href : treference; + hregister1,hregister2 : tregister; + i : longint; begin - { if lexlevel=(tprocdef(procdefinition).parast.symtablelevel) then begin - reference_reset_base(href,procinfo^.framepointer,procinfo^.framepointer_offset); - cg.a_param_ref(exprasmlist,OS_ADDR,href,paramanager.getframepointerloc(procinfo.procdef)); + { pass the same framepointer as the current procedure got } + hregister2.enum:=R_INTREGISTER; + hregister2.number:=NR_R11; + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,procinfo.framepointer,hregister2); + { it must be adjusted! } end { this is only true if the difference is one !! but it cannot be more !! } else if (lexlevel=(tprocdef(procdefinition).parast.symtablelevel)-1) then begin - cg.a_param_reg(exprasmlist,OS_ADDR,procinfo^.framepointer,paramanager.getframepointerloc(procinfo.procdef)); + // cg.a_param_reg(exprasmlist,OS_ADDR,procinfo.framepointer,paramanager.getframepointerloc(procinfo.procdef)); end else if (lexlevel>(tprocdef(procdefinition).parast.symtablelevel)) then begin - hregister:=rg.getregisterint(exprasmlist); - reference_reset_base(href,procinfo^.framepointer,procinfo^.framepointer_offset); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister); + hregister1:=rg.getregisterint(exprasmlist,OS_ADDR); + reference_reset_base(href,procinfo.framepointer,procinfo.framepointer_offset); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister1); for i:=(tprocdef(procdefinition).parast.symtablelevel) to lexlevel-1 do begin {we should get the correct frame_pointer_offset at each level how can we do this !!! } - reference_reset_base(href,hregister,procinfo^.framepointer_offset); - cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister); + reference_reset_base(href,hregister2,procinfo.framepointer_offset); + cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,hregister1); end; - cg.a_param_reg(exprasmlist,OS_ADDR,hregister,-1); - rg.ungetregisterint(exprasmlist,hregister); + hregister2.enum:=R_11; + cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,hregister1,hregister2); + rg.ungetregisterint(exprasmlist,hregister1); end else internalerror(2002081303); - } end; begin @@ -111,7 +116,12 @@ begin end. { $Log$ - Revision 1.5 2003-04-04 15:38:56 peter + Revision 1.6 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.5 2003/04/04 15:38:56 peter * moved generic code from n386cal to ncgcal, i386 now also uses the generic ncgcal diff --git a/compiler/powerpc/nppccnv.pas b/compiler/powerpc/nppccnv.pas index 4a77b362ab..2b72bf0e9a 100644 --- a/compiler/powerpc/nppccnv.pas +++ b/compiler/powerpc/nppccnv.pas @@ -272,7 +272,7 @@ implementation begin { byte(boolean) or word(wordbool) or longint(longbool) must } { be accepted for var parameters } - if (nf_explizit in flags) and + if (nf_explicit in flags) and (left.resulttype.def.size=resulttype.def.size) and (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then begin @@ -394,7 +394,12 @@ begin end. { $Log$ - Revision 1.30 2003-03-11 21:46:24 jonas + Revision 1.31 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.30 2003/03/11 21:46:24 jonas * lots of new regallocator fixes, both in generic and ppc-specific code (ppc compiler still can't compile the linux system unit though) diff --git a/compiler/powerpc/nppcinl.pas b/compiler/powerpc/nppcinl.pas index f5cececdfc..c04b0d274b 100644 --- a/compiler/powerpc/nppcinl.pas +++ b/compiler/powerpc/nppcinl.pas @@ -64,7 +64,7 @@ implementation function tppcinlinenode.first_abs_real : tnode; begin - location.loc:=LOC_FPUREGISTER; + expectloc:=LOC_FPUREGISTER; registers32:=left.registers32; registersfpu:=max(left.registersfpu,1); {$ifdef SUPPORT_MMX} @@ -75,7 +75,7 @@ implementation function tppcinlinenode.first_sqr_real : tnode; begin - location.loc:=LOC_FPUREGISTER; + expectloc:=LOC_FPUREGISTER; registers32:=left.registers32; registersfpu:=max(left.registersfpu,1); {$ifdef SUPPORT_MMX} @@ -86,7 +86,7 @@ implementation function tppcinlinenode.first_sqrt_real : tnode; begin - location.loc:=LOC_FPUREGISTER; + expectloc:=LOC_FPUREGISTER; registers32:=left.registers32; registersfpu:=max(left.registersfpu,1); {$ifdef SUPPORT_MMX} @@ -126,6 +126,7 @@ implementation procedure tppcinlinenode.second_abs_real; begin + location.loc:=LOC_FPUREGISTER; load_fpu_location; exprasmlist.concat(taicpu.op_reg_reg(A_FABS,location.register, left.location.register)); @@ -133,6 +134,7 @@ implementation procedure tppcinlinenode.second_sqr_real; begin + location.loc:=LOC_FPUREGISTER; load_fpu_location; exprasmlist.concat(taicpu.op_reg_reg_reg(A_FMUL,location.register, left.location.register,left.location.register)); @@ -140,6 +142,7 @@ implementation procedure tppcinlinenode.second_sqrt_real; begin + location.loc:=LOC_FPUREGISTER; load_fpu_location; exprasmlist.concat(taicpu.op_reg_reg(A_FSQRT,location.register, left.location.register)); @@ -150,7 +153,12 @@ begin end. { $Log$ - Revision 1.4 2002-11-25 17:43:28 peter + Revision 1.5 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.4 2002/11/25 17:43:28 peter * splitted defbase in defutil,symutil,defcmp * merged isconvertable and is_equal into compare_defs(_ext) * made operator search faster by walking the list only once diff --git a/compiler/psub.pas b/compiler/psub.pas index f4cfce9db1..9448d692ca 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -329,7 +329,7 @@ implementation {When we are called to compile the body of a unit, aktprocsym should point to the unit initialization. If the unit has no initialization, - aktprocsym=nil. But in that case code=nil. hus we should check for + aktprocsym=nil. But in that case code=nil. Thus we should check for code=nil, when we use aktprocsym.} { set the start offset to the start of the temp area in the stack } @@ -884,7 +884,12 @@ implementation end. { $Log$ - Revision 1.101 2003-04-22 14:33:38 peter + Revision 1.102 2003-04-23 12:35:34 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.101 2003/04/22 14:33:38 peter * removed some notes/hints Revision 1.100 2003/04/22 13:47:08 peter diff --git a/compiler/sparc/cpubase.pas b/compiler/sparc/cpubase.pas index 8dd21360ae..950cf19240 100644 --- a/compiler/sparc/cpubase.pas +++ b/compiler/sparc/cpubase.pas @@ -281,7 +281,7 @@ const {Subregisters; nothing known about.} R_SUBWHOLE=$00; R_SUBL=$00; - + type reg2strtable=ARRAY[TOldRegister] OF STRING[7]; @@ -366,30 +366,14 @@ TYPE Generic Location *****************************************************************************} TYPE - TLoc=( {information about the location of an operand} - LOC_INVALID, { added for tracking problems} - LOC_CONSTANT, { CONSTant value } - LOC_JUMP, { boolean results only, jump to false or true label } - LOC_FLAGS, { boolean results only, flags are set } - LOC_CREFERENCE, { in memory CONSTant value } - LOC_REFERENCE, { in memory value } - LOC_REGISTER, { in a processor register } - LOC_CREGISTER, { Constant register which shouldn't be modified } - LOC_FPUREGISTER, { FPU stack } - LOC_CFPUREGISTER, { if it is a FPU register variable on the fpu stack } - LOC_MMXREGISTER, { MMX register } - LOC_CMMXREGISTER, { MMX register variable } - LOC_MMREGISTER, - LOC_CMMREGISTER - ); {tparamlocation describes where a parameter for a procedure is stored. References are given from the caller's point of view. The usual TLocation isn't used, because contains a lot of unnessary fields.} TParaLocation=PACKED RECORD Size:TCGSize; - Loc:TLoc; + Loc:TCGLoc; sp_fixup:LongInt; - CASE TLoc OF + CASE TCGLoc OF LOC_REFERENCE:(reference:tparareference); { segment in reference at the same place as in loc_register } LOC_REGISTER,LOC_CREGISTER : ( @@ -405,9 +389,9 @@ used, because contains a lot of unnessary fields.} LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister); END; TLocation=PACKED RECORD - loc : TLoc; + loc : TCGLoc; size : TCGSize; - case TLoc of + case TCGLoc of LOC_FLAGS : (resflags : tresflags); LOC_CONSTANT : ( case longint of @@ -455,13 +439,13 @@ const mmregs=[]; usableregsmm=[]; c_countusableregsmm=0; - { no distinction on this platform } + { no distinction on this platform } maxaddrregs = 0; addrregs = []; usableregsaddr = []; c_countusableregsaddr = 0; - - + + firstsaveintreg = RS_O0; lastsaveintreg = RS_I7; firstsavefpureg = R_F0; @@ -591,8 +575,8 @@ const max_operands = 3; maxintregs = maxvarregs; maxfpuregs = maxfpuvarregs; - - + + FUNCTION is_calljmp(o:tasmop):boolean; FUNCTION flags_to_cond(CONST f:TResFlags):TAsmCond; @@ -676,7 +660,12 @@ END. { $Log$ - Revision 1.25 2003-03-10 21:59:54 mazen + Revision 1.26 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.25 2003/03/10 21:59:54 mazen * fixing index overflow in handling new registers arrays. Revision 1.24 2003/02/26 22:06:27 mazen diff --git a/compiler/sparc/cpupara.pas b/compiler/sparc/cpupara.pas index 19583155d9..f4236b91cc 100644 --- a/compiler/sparc/cpupara.pas +++ b/compiler/sparc/cpupara.pas @@ -63,7 +63,7 @@ function TSparcParaManager.GetIntParaLoc(nr:longint):TParaLocation; reference.offset:=-68-nr*4; end; end; -function GetParaLoc(p:TDef):TLoc; +function GetParaLoc(p:TDef):TCGLoc; begin {Later, the LOC_REFERENCE is in most cases changed into LOC_REGISTER if push_addr_param for the def is true} @@ -124,7 +124,7 @@ procedure TSparcParaManager.create_param_loc_info(p:TAbstractProcDef); nextintreg,nextfloatreg:tregister; stack_offset:aword; hp:tparaitem; - loc:tloc; + loc:tcgloc; is_64bit:boolean; begin nextintreg.enum:=R_O0; @@ -281,7 +281,12 @@ begin end. { $Log$ - Revision 1.14 2003-01-08 18:43:58 daniel + Revision 1.15 2003-04-23 12:35:35 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.14 2003/01/08 18:43:58 daniel * Tregister changed into a record Revision 1.13 2003/01/05 21:32:35 mazen diff --git a/compiler/symdef.pas b/compiler/symdef.pas index 6192efec71..f7572e4819 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -687,11 +687,19 @@ interface ordpointertype, pvmttype : ttype; { type of classrefs, used for stabs } + { pointer to the anchestor of all classes } + class_tobject : tobjectdef; + { pointer to the ancestor of all COM interfaces } + interface_iunknown : tobjectdef; + { pointer to the TGUID type + of all interfaces } + rec_tguid : trecorddef; - class_tobject : tobjectdef; { pointer to the anchestor of all classes } - interface_iunknown : tobjectdef; { KAZ: pointer to the ancestor } - rec_tguid : trecorddef; { KAZ: pointer to the TGUID type } - { of all interfaces } + { Pointer to a procdef with no parameters and no return value. + This is used for procedures which are generated automatically + by the compiler. + } + voidprocdef : tprocdef; const {$ifdef i386} @@ -5706,10 +5714,17 @@ implementation (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]); end; +begin + voidprocdef:=tprocdef.create; end. { $Log$ - Revision 1.133 2003-04-10 17:57:53 peter + Revision 1.134 2003-04-23 12:35:34 florian + * fixed several issues with powerpc + + applied a patch from Jonas for nested function calls (PowerPC only) + * ... + + Revision 1.133 2003/04/10 17:57:53 peter * vs_hidden released Revision 1.132 2003/03/18 16:25:50 peter