diff --git a/.gitattributes b/.gitattributes index 06e2dbfbad..d788d59733 100644 --- a/.gitattributes +++ b/.gitattributes @@ -313,7 +313,6 @@ compiler/powerpc/nppcadd.pas svneol=native#text/plain compiler/powerpc/nppccal.pas svneol=native#text/plain compiler/powerpc/nppccnv.pas svneol=native#text/plain compiler/powerpc/nppcmat.pas svneol=native#text/plain -compiler/powerpc/nppcset.pas svneol=native#text/plain compiler/powerpc/rappc.pas svneol=native#text/plain compiler/powerpc/rappcgas.pas svneol=native#text/plain compiler/powerpc/rgcpu.pas svneol=native#text/plain @@ -349,7 +348,6 @@ compiler/powerpc64/nppccal.pas svneol=native#text/plain compiler/powerpc64/nppccnv.pas svneol=native#text/plain compiler/powerpc64/nppcld.pas svneol=native#text/plain compiler/powerpc64/nppcmat.pas svneol=native#text/plain -compiler/powerpc64/nppcset.pas svneol=native#text/plain compiler/powerpc64/ppcins.dat -text compiler/powerpc64/ppcreg.dat -text compiler/powerpc64/rappc.pas svneol=native#text/plain @@ -381,6 +379,7 @@ compiler/ppcgen/cgppc.pas svneol=native#text/plain compiler/ppcgen/ngppcadd.pas svneol=native#text/plain compiler/ppcgen/ngppccnv.pas svneol=native#text/plain compiler/ppcgen/ngppcinl.pas svneol=native#text/plain +compiler/ppcgen/ngppcset.pas svneol=native#text/plain compiler/ppheap.pas svneol=native#text/plain compiler/ppu.pas svneol=native#text/plain compiler/procinfo.pas svneol=native#text/plain diff --git a/compiler/powerpc/cpunode.pas b/compiler/powerpc/cpunode.pas index 969bc927d3..32955d2783 100644 --- a/compiler/powerpc/cpunode.pas +++ b/compiler/powerpc/cpunode.pas @@ -39,8 +39,8 @@ unit cpunode; // nppccon, // nppcflw, // nppcmem, - nppcset, - nppcinl, + ngppcset, + ngppcinl, // nppcopt, nppcmat, nppccnv diff --git a/compiler/powerpc64/cpunode.pas b/compiler/powerpc64/cpunode.pas index ffa6532916..bbcd9b13b0 100644 --- a/compiler/powerpc64/cpunode.pas +++ b/compiler/powerpc64/cpunode.pas @@ -39,8 +39,8 @@ uses // nppccon, // nppcflw, // nppcmem, - nppcset, - nppcinl, + ngppcset, + ngppcinl, // nppcopt, nppcmat, nppccnv, diff --git a/compiler/powerpc64/nppcset.pas b/compiler/powerpc64/nppcset.pas deleted file mode 100644 index cd70ea1b35..0000000000 --- a/compiler/powerpc64/nppcset.pas +++ /dev/null @@ -1,217 +0,0 @@ -{ - Copyright (c) 1998-2002 by Florian Klaempfl and Carl Eric Codere - - Generate PowerPC assembler for in set/case 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 nppcset; - -{$I fpcdefs.inc} - -interface - -uses - node, nset, ncgset, cpubase, cgbase, cgobj, aasmbase, aasmtai,aasmdata, globtype; - -type - - tppccasenode = class(tcgcasenode) - protected - procedure optimizevalues(var max_linear_list : aint; var max_dist : aword); override; - - function has_jumptable : boolean; override; - procedure genjumptable(hp: pcaselabel; min_, max_ : aint); override; - procedure genlinearlist(hp: pcaselabel); override; - end; - -implementation - -uses - systems, - verbose, globals, - symconst, symdef, defutil, - paramgr, - cpuinfo, - pass_2, cgcpu, - ncon, - tgobj, ncgutil, regvars, rgobj, aasmcpu, - procinfo, cgutils; - -{***************************************************************************** - TCGCASENODE -*****************************************************************************} - -procedure tppccasenode.optimizevalues(var max_linear_list : aint; var max_dist : aword); -begin - max_linear_list := 10; -end; - -function tppccasenode.has_jumptable : boolean; -begin - has_jumptable := true; -end; - -procedure tppccasenode.genjumptable(hp : pcaselabel; min_, max_ : aint); -var - table : tasmlabel; - last : TConstExprInt; - indexreg : tregister; - href : treference; - - procedure genitem(list:TAsmList;t : pcaselabel); - var - i : aint; - begin - if assigned(t^.less) then - genitem(list,t^.less); - { fill possible hole } - i:=last+1; - while i<=t^._low-1 do - begin - list.concat(Tai_const.Create_sym(elselabel)); - inc(i); - end; - i:=t^._low; - while i<=t^._high do - begin - list.concat(Tai_const.Create_sym(blocklabel(t^.blockid))); - inc(i); - end; - last:=t^._high; - if assigned(t^.greater) then - genitem(list,t^.greater); - end; - -begin - { this is exactly the same code as for 32 bit PowerPC processors. It might be useful to change this - later (with e.g. TOC support) into a method which uses relative values in the jumptable to save space - and memory bandwidth. At the moment this is not a good idea, since these methods involve loading of - one or more 64 bit integer adresses which is slow } - if not(jumptable_no_range) then begin - { case expr less than min_ => goto elselabel } - cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,jmp_lt,aint(min_),hregister,elselabel); - { case expr greater than max_ => goto elselabel } - cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,jmp_gt,aint(max_),hregister,elselabel); - end; - current_asmdata.getjumplabel(table); - { allocate base and index registers register } - indexreg:= cg.makeregsize(current_asmdata.CurrAsmList, hregister, OS_INT); - { indexreg := hregister; } - cg.a_load_reg_reg(current_asmdata.CurrAsmList, opsize, OS_INT, hregister, indexreg); - { create reference, indexreg := indexreg * sizeof(OS_ADDR) } - cg.a_op_const_reg(current_asmdata.CurrAsmList, OP_MUL, OS_INT, tcgsize2size[OS_ADDR], indexreg); - reference_reset_symbol(href, table, (-aint(min_)) * tcgsize2size[OS_ADDR]); - href.index := indexreg; - - cg.a_load_ref_reg(current_asmdata.CurrAsmList, OS_INT, OS_INT, href, indexreg); - - current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_MTCTR, indexreg)); - current_asmdata.CurrAsmList.concat(taicpu.op_none(A_BCTR)); - - { generate jump table } - new_section(current_procinfo.aktlocaldata,sec_data,current_procinfo.procdef.mangledname,sizeof(aint)); - current_procinfo.aktlocaldata.concat(Tai_label.Create(table)); - last:=min_; - genitem(current_procinfo.aktlocaldata,hp); -end; - -procedure tppccasenode.genlinearlist(hp: pcaselabel); -var - first, lastrange: boolean; - last: TConstExprInt; - - procedure genitem(t: pcaselabel); - - procedure gensub(value: aint); - var - tmpreg: tregister; - begin - value := -value; - if (value >= low(smallint)) and - (value <= high(smallint)) then - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ADDIC_, hregister, - hregister, value)) - else - begin - tmpreg := cg.getintregister(current_asmdata.CurrAsmList, OS_INT); - cg.a_load_const_reg(current_asmdata.CurrAsmList, OS_INT, value, tmpreg); - current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_ADD_, hregister, - hregister, tmpreg)); - end; - end; - - begin - if assigned(t^.less) then - genitem(t^.less); - { need we to test the first value } - if first and (t^._low > get_min_value(left.resultdef)) then begin - cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, OS_INT, jmp_lt, aword(t^._low), - hregister, elselabel); - end; - if t^._low = t^._high then begin - if t^._low - last = 0 then - cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, opsize, OC_EQ, 0, hregister, - blocklabel(t^.blockid)) - else - gensub(aint(t^._low - last)); - tcgppc(cg).a_jmp_cond(current_asmdata.CurrAsmList, OC_EQ, blocklabel(t^.blockid)); - last := t^._low; - lastrange := false; - end else begin - { it begins with the smallest label, if the value } - { is even smaller then jump immediately to the } - { ELSE-label } - if first then begin - { have we to ajust the first value ? } - if (t^._low > get_min_value(left.resultdef)) then - gensub(aint(t^._low)); - end else begin - { if there is no unused label between the last and the } - { present label then the lower limit can be checked } - { immediately. else check the range in between: } - gensub(aint(t^._low - last)); - if ((t^._low - last) <> 1) or (not lastrange) then - tcgppc(cg).a_jmp_cond(current_asmdata.CurrAsmList, jmp_lt, elselabel); - end; - gensub(aint(t^._high - t^._low)); - tcgppc(cg).a_jmp_cond(current_asmdata.CurrAsmList, jmp_le, blocklabel(t^.blockid)); - last := t^._high; - lastrange := true; - end; - first := false; - if assigned(t^.greater) then - genitem(t^.greater); - end; - -begin - { do we need to generate cmps? } - if (with_sign and (min_label < 0)) or (opsize = OS_32) then - genlinearcmplist(hp) - else begin - last := 0; - lastrange := false; - first := true; - genitem(hp); - cg.a_jmp_always(current_asmdata.CurrAsmList, elselabel); - end; -end; - -begin - ccasenode := tppccasenode; -end. - diff --git a/compiler/powerpc/nppcset.pas b/compiler/ppcgen/ngppcset.pas similarity index 88% rename from compiler/powerpc/nppcset.pas rename to compiler/ppcgen/ngppcset.pas index 44ad6f61a5..6a302cf5c2 100644 --- a/compiler/powerpc/nppcset.pas +++ b/compiler/ppcgen/ngppcset.pas @@ -1,7 +1,7 @@ { Copyright (c) 1998-2002 by Florian Klaempfl and Carl Eric Codere - Generate PowerPC assembler for in set/case nodes + Generate PowerPC32/64 assembler for in set/case 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 @@ -19,7 +19,7 @@ **************************************************************************** } -unit nppcset; +unit ngppcset; {$i fpcdefs.inc} @@ -29,8 +29,9 @@ interface node,nset,ncgset,cpubase,cgbase,cgobj,aasmbase,aasmtai,aasmdata,globtype; type - tppccasenode = class(tcgcasenode) + tgppccasenode = class(tcgcasenode) protected + procedure optimizevalues(var max_linear_list : aint; var max_dist : aword);override; function has_jumptable : boolean;override; procedure genjumptable(hp : pcaselabel;min_,max_ : aint);override; procedure genlinearlist(hp : pcaselabel); override; @@ -56,13 +57,19 @@ implementation *****************************************************************************} - function tppccasenode.has_jumptable : boolean; + procedure tgppccasenode.optimizevalues(var max_linear_list : aint; var max_dist : aword); + begin + max_linear_list := 10; + end; + + + function tgppccasenode.has_jumptable : boolean; begin has_jumptable:=true; end; - procedure tppccasenode.genjumptable(hp : pcaselabel;min_,max_ : aint); + procedure tgppccasenode.genjumptable(hp : pcaselabel;min_,max_ : aint); var table : tasmlabel; last : TConstExprInt; @@ -76,10 +83,18 @@ implementation if assigned(t^.less) then genitem(list,t^.less); { fill possible hole } - for i:=last+1 to t^._low-1 do - list.concat(Tai_const.Create_sym(elselabel)); - for i:=t^._low to t^._high do - list.concat(Tai_const.Create_sym(blocklabel(t^.blockid))); + i:=last+1; + while i<=t^._low-1 do + begin + list.concat(Tai_const.Create_sym(elselabel)); + inc(i); + end; + i:=t^._low; + while i<=t^._high do + begin + list.concat(Tai_const.Create_sym(blocklabel(t^.blockid))); + inc(i); + end; last:=t^._high; if assigned(t^.greater) then genitem(list,t^.greater); @@ -117,7 +132,7 @@ implementation end; - procedure tppccasenode.genlinearlist(hp : pcaselabel); + procedure tgppccasenode.genlinearlist(hp : pcaselabel); var first, lastrange : boolean; @@ -201,7 +216,7 @@ implementation begin { do we need to generate cmps? } if (with_sign and (min_label<0)) or - (opsize = OS_32) then + (opsize = OS_INT) then genlinearcmplist(hp) else begin @@ -215,5 +230,5 @@ implementation begin - ccasenode:=tppccasenode; + ccasenode:=tgppccasenode; end.