From 6c06c346d886f47e5a9eb008ede281a200d7cabe Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 16 Sep 2002 18:08:26 +0000 Subject: [PATCH] * fix last optimization in genlinearlist, detected by bug tw1066 * use generic casenode.pass2 routine and override genlinearlist * add jumptable support to generic casenode, by default there is no jumptable support --- compiler/i386/n386set.pas | 536 ++++++++------------------------------ compiler/ncgset.pas | 153 +++++++---- 2 files changed, 213 insertions(+), 476 deletions(-) diff --git a/compiler/i386/n386set.pas b/compiler/i386/n386set.pas index b70a90c016..4ce64252c7 100644 --- a/compiler/i386/n386set.pas +++ b/compiler/i386/n386set.pas @@ -27,7 +27,7 @@ unit n386set; interface uses - node,nset,pass_1; + node,nset,pass_1,ncgset; type @@ -35,10 +35,15 @@ interface procedure pass_2;override; function pass_1 : tnode;override; end; - ti386casenode = class(tcasenode) - procedure pass_2;override; + + ti386casenode = class(tcgcasenode) + procedure optimizevalues(var max_linear_list:longint;var max_dist:cardinal);override; + function has_jumptable : boolean;override; + procedure genjumptable(hp : pcaserecord;min_,max_ : longint);override; + procedure genlinearlist(hp : pcaserecord);override; end; + implementation uses @@ -49,11 +54,7 @@ implementation cginfo,cgbase,pass_2, ncon, cpubase,cpuinfo, - cga,cgobj,tgobj,ncgutil,regvars,rgobj; - - const - bytes2Sxx:array[1..8] of Topsize=(S_B,S_W,S_NO,S_L,S_NO,S_NO,S_NO,S_Q); - + cga,cgx86,cgobj,tgobj,ncgutil,regvars,rgobj; {***************************************************************************** @@ -536,188 +537,106 @@ implementation TI386CASENODE *****************************************************************************} - procedure ti386casenode.pass_2; - var - with_sign : boolean; - opsize : topsize; - jmp_gt,jmp_le,jmp_lee : tasmcond; - hp : tnode; - { register with case expression } - hregister,hregister2 : tregister; - endlabel,elselabel : tasmlabel; - - { true, if we can omit the range check of the jump table } - jumptable_no_range : boolean; - { where to put the jump table } - jumpsegment : TAAsmoutput; - min_label : TConstExprInt; - - procedure gentreejmp(p : pcaserecord); - - var - lesslabel,greaterlabel : tasmlabel; - - begin - cg.a_label(exprasmlist,p^._at); - { calculate labels for left and right } - if (p^.less=nil) then - lesslabel:=elselabel - else - lesslabel:=p^.less^._at; - if (p^.greater=nil) then - greaterlabel:=elselabel - else - greaterlabel:=p^.greater^._at; - { calculate labels for left and right } - { no range label: } - if p^._low=p^._high then - begin - emit_const_reg(A_CMP,opsize,p^._low,hregister); - if greaterlabel=lesslabel then - emitjmp(C_NE,lesslabel) - else - begin - emitjmp(jmp_le,lesslabel); - emitjmp(jmp_gt,greaterlabel); - end; - cg.a_jmp_always(exprasmlist,p^.statement); - end - else - begin - emit_const_reg(A_CMP,opsize,p^._low,hregister); - emitjmp(jmp_le,lesslabel); - emit_const_reg(A_CMP,opsize,p^._high,hregister); - emitjmp(jmp_gt,greaterlabel); - cg.a_jmp_always(exprasmlist,p^.statement); - end; - if assigned(p^.less) then - gentreejmp(p^.less); - if assigned(p^.greater) then - gentreejmp(p^.greater); + procedure ti386casenode.optimizevalues(var max_linear_list:longint;var max_dist:cardinal); + begin + { a jump table crashes the pipeline! } + if aktoptprocessor=Class386 then + inc(max_linear_list,3) + else if aktoptprocessor=ClassP5 then + inc(max_linear_list,6) + else if aktoptprocessor>=ClassP6 then + inc(max_linear_list,9); end; - procedure genlinearcmplist(hp : pcaserecord); - var - first : boolean; - last : TConstExprInt; + function ti386casenode.has_jumptable : boolean; + begin + has_jumptable:=true; + end; + + + procedure ti386casenode.genjumptable(hp : pcaserecord;min_,max_ : longint); + var + table : tasmlabel; + last : TConstExprInt; + indexreg : tregister; + href : treference; + jumpsegment : TAAsmOutput; procedure genitem(t : pcaserecord); - var - l1 : tasmlabel; - + i : longint; begin - if assigned(t^.less) then - genitem(t^.less); - if t^._low=t^._high then - begin - if opsize=S_Q then - begin - objectlibrary.getlabel(l1); - emit_const_reg(A_CMP,S_L,longint(hi(int64(t^._low))),hregister2); - emitjmp(C_NZ,l1); - emit_const_reg(A_CMP,S_L,longint(lo(int64(t^._low))),hregister); - emitjmp(C_Z,t^.statement); - cg.a_label(exprasmlist,l1); - end - else - begin - emit_const_reg(A_CMP,opsize,longint(t^._low),hregister); - emitjmp(C_Z,t^.statement); - last:=t^._low; - end; - 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: } - if first or (t^._low-last>1) then - begin - if opsize=S_Q then - begin - objectlibrary.getlabel(l1); - emit_const_reg(A_CMP,S_L,longint(hi(int64(t^._low))),hregister2); - emitjmp(jmp_le,elselabel); - emitjmp(jmp_gt,l1); - emit_const_reg(A_CMP,S_L,longint(lo(int64(t^._low))),hregister); - { the comparisation of the low dword must be always unsigned! } - emitjmp(C_B,elselabel); - cg.a_label(exprasmlist,l1); - end - else - begin - emit_const_reg(A_CMP,opsize,longint(t^._low),hregister); - emitjmp(jmp_le,elselabel); - end; - end; - - if opsize=S_Q then - begin - objectlibrary.getlabel(l1); - emit_const_reg(A_CMP,S_L,longint(hi(int64(t^._high))),hregister2); - emitjmp(jmp_le,t^.statement); - emitjmp(jmp_gt,l1); - emit_const_reg(A_CMP,S_L,longint(lo(int64(t^._high))),hregister); - { the comparisation of the low dword must be always unsigned! } - emitjmp(C_BE,t^.statement); - cg.a_label(exprasmlist,l1); - end - else - begin - emit_const_reg(A_CMP,opsize,longint(t^._high),hregister); - emitjmp(jmp_lee,t^.statement); - end; - - last:=t^._high; - end; - first:=false; - if assigned(t^.greater) then - genitem(t^.greater); + if assigned(t^.less) then + genitem(t^.less); + { fill possible hole } + for i:=last+1 to t^._low-1 do + jumpSegment.concat(Tai_const_symbol.Create(elselabel)); + for i:=t^._low to t^._high do + jumpSegment.concat(Tai_const_symbol.Create(t^.statement)); + last:=t^._high; + if assigned(t^.greater) then + genitem(t^.greater); end; - begin - last:=0; - first:=true; - genitem(hp); - cg.a_jmp_always(exprasmlist,elselabel); - end; + begin + if (cs_create_smart in aktmoduleswitches) then + jumpsegment:=procinfo.aktlocaldata + else + jumpsegment:=datasegment; + if not(jumptable_no_range) then + begin + { case expr less than min_ => goto elselabel } + cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,longint(min_),hregister,elselabel); + { case expr greater than max_ => goto elselabel } + cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_gt,longint(max_),hregister,elselabel); + end; + objectlibrary.getlabel(table); + { make it a 32bit register } + indexreg:=rg.makeregsize(hregister,OS_INT); + cg.a_load_reg_reg(exprasmlist,opsize,hregister,indexreg); + { create reference } + reference_reset_symbol(href,table,0); + href.offset:=(-longint(min_))*4; + href.index:=indexreg; + href.scalefactor:=4; + emit_ref(A_JMP,S_NO,href); + { generate jump table } + if not(cs_littlesize in aktglobalswitches) then + jumpSegment.concat(Tai_Align.Create_Op(4,0)); + jumpSegment.concat(Tai_label.Create(table)); + last:=min_; + genitem(hp); + end; - procedure genlinearlist(hp : pcaserecord); - var - first : boolean; - last : TConstExprInt; - {helplabel : longint;} + procedure ti386casenode.genlinearlist(hp : pcaserecord); + var + first : boolean; + lastrange : boolean; + last : TConstExprInt; + cond_lt,cond_le : tasmcond; procedure genitem(t : pcaserecord); - - procedure gensub(value:longint); - begin - if value=1 then - emit_reg(A_DEC,opsize,hregister) - else - emit_const_reg(A_SUB,opsize,value,hregister); - 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.resulttype.def)) then begin - emit_const_reg(A_CMP,opsize,longint(t^._low),hregister); - emitjmp(jmp_le,elselabel); + cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,longint(t^._low),hregister,elselabel); end; if t^._low=t^._high then begin if t^._low-last=0 then - emit_reg_reg(A_OR,opsize,hregister,hregister) + cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ,0,hregister,t^.statement) else - gensub(longint(t^._low-last)); + begin + cg.a_op_const_reg(exprasmlist, OP_SUB, longint(t^._low-last), hregister); + emitjmp(C_Z,t^.statement); + end; last:=t^._low; - emitjmp(C_Z,t^.statement); + lastrange:=false; end else begin @@ -728,7 +647,7 @@ implementation begin { have we to ajust the first value ? } if (t^._low>get_min_value(left.resulttype.def)) then - gensub(longint(t^._low)); + cg.a_op_const_reg(exprasmlist, OP_SUB, longint(t^._low), hregister); end else begin @@ -736,15 +655,19 @@ implementation { present label then the lower limit can be checked } { immediately. else check the range in between: } - gensub(longint(t^._low-last)); + cg.a_op_const_reg(exprasmlist, OP_SUB, longint(t^._low-last), hregister); { no jump necessary here if the new range starts at } { at the value following the previous one } - if (t^._low-last) <> 1 then - emitjmp(jmp_le,elselabel); + if ((t^._low-last) <> 1) or + (not lastrange) then + emitjmp(cond_lt,elselabel); end; - emit_const_reg(A_SUB,opsize,longint(t^._high-t^._low),hregister); - emitjmp(jmp_lee,t^.statement); + {we need to use A_SUB, because A_DEC does not set the correct flags, therefor + using a_op_const_reg(OP_SUB) is not possible } + emit_const_reg(A_SUB,TCGSize2OpSize[opsize],longint(t^._high-t^._low),hregister); + emitjmp(cond_le,t^.statement); last:=t^._high; + lastrange:=true; end; first:=false; if assigned(t^.greater) then @@ -752,270 +675,29 @@ implementation end; begin + if with_sign then + begin + cond_lt:=C_L; + cond_le:=C_LE; + end + else + begin + cond_lt:=C_B; + cond_le:=C_BE; + end; { do we need to generate cmps? } if (with_sign and (min_label<0)) then genlinearcmplist(hp) else begin last:=0; + lastrange:=false; first:=true; genitem(hp); cg.a_jmp_always(exprasmlist,elselabel); end; end; - procedure genjumptable(hp : pcaserecord;min_,max_ : longint); - - var - table : tasmlabel; - last : TConstExprInt; - href : treference; - - procedure genitem(t : pcaserecord); - - var - i : longint; - - begin - if assigned(t^.less) then - genitem(t^.less); - { fill possible hole } - for i:=last+1 to t^._low-1 do - jumpSegment.concat(Tai_const_symbol.Create(elselabel)); - for i:=t^._low to t^._high do - jumpSegment.concat(Tai_const_symbol.Create(t^.statement)); - last:=t^._high; - if assigned(t^.greater) then - genitem(t^.greater); - end; - - begin - if not(jumptable_no_range) then - begin - emit_const_reg(A_CMP,opsize,longint(min_),hregister); - { case expr less than min_ => goto elselabel } - emitjmp(jmp_le,elselabel); - emit_const_reg(A_CMP,opsize,longint(max_),hregister); - emitjmp(jmp_gt,elselabel); - end; - objectlibrary.getlabel(table); - { extend with sign } - if opsize=S_W then - begin - if with_sign then - emit_reg_reg(A_MOVSX,S_WL,hregister, - rg.makeregsize(hregister,OS_INT)) - else - emit_reg_reg(A_MOVZX,S_WL,hregister, - rg.makeregsize(hregister,OS_INT)); - hregister:=rg.makeregsize(hregister,OS_INT); - end - else if opsize=S_B then - begin - if with_sign then - emit_reg_reg(A_MOVSX,S_BL,hregister, - rg.makeregsize(hregister,OS_INT)) - else - emit_reg_reg(A_MOVZX,S_BL,hregister, - rg.makeregsize(hregister,OS_INT)); - hregister:=rg.makeregsize(hregister,OS_INT); - end; - reference_reset_symbol(href,table,0); - href.offset:=(-longint(min_))*4; - href.index:=hregister; - href.scalefactor:=4; - emit_ref(A_JMP,S_NO,href); - { !!!!! generate tables - if not(cs_littlesize in aktlocalswitches) then - jumpSegment.concat(Taicpu.Op_const(A_ALIGN,S_NO,4)); - } - jumpSegment.concat(Tai_label.Create(table)); - last:=min_; - genitem(hp); - { !!!!!!! - if not(cs_littlesize in aktlocalswitches) then - emit_const(A_ALIGN,S_NO,4); - } - end; - - var - lv,hv, - max_label: tconstexprint; - labels : longint; - max_linear_list : longint; - otl, ofl: tasmlabel; - isjump : boolean; -{$ifdef Delphi} - dist : cardinal; -{$else Delphi} - dist : dword; -{$endif Delphi} - begin - objectlibrary.getlabel(endlabel); - objectlibrary.getlabel(elselabel); - if (cs_create_smart in aktmoduleswitches) then - jumpsegment:=procinfo.aktlocaldata - else - jumpsegment:=datasegment; - with_sign:=is_signed(left.resulttype.def); - if with_sign then - begin - jmp_gt:=C_G; - jmp_le:=C_L; - jmp_lee:=C_LE; - end - else - begin - jmp_gt:=C_A; - jmp_le:=C_B; - jmp_lee:=C_BE; - end; - rg.cleartempgen; - { save current truelabel and falselabel } - isjump:=false; - if left.location.loc=LOC_JUMP then - begin - otl:=truelabel; - objectlibrary.getlabel(truelabel); - ofl:=falselabel; - objectlibrary.getlabel(falselabel); - isjump:=true; - end; - secondpass(left); - { determines the size of the operand } - opsize:=bytes2Sxx[left.resulttype.def.size]; - { copy the case expression to a register } - location_force_reg(exprasmlist,left.location,def_cgsize(left.resulttype.def),false); - if opsize=S_Q then - begin - hregister:=left.location.registerlow; - hregister2:=left.location.registerhigh; - end - else - hregister:=left.location.register; - if isjump then - begin - truelabel:=otl; - falselabel:=ofl; - end; - - { we need the min_label always to choose between } - { cmps and subs/decs } - min_label:=case_get_min(nodes); - - load_all_regvars(exprasmlist); - { now generate the jumps } - if opsize=S_Q then - genlinearcmplist(nodes) - else - begin - if cs_optimize in aktglobalswitches then - begin - { procedures are empirically passed on } - { consumption can also be calculated } - { but does it pay on the different } - { processors? } - { moreover can the size only be appro- } - { ximated as it is not known if rel8, } - { rel16 or rel32 jumps are used } - max_label:=case_get_max(nodes); - labels:=case_count_labels(nodes); - { can we omit the range check of the jump table ? } - getrange(left.resulttype.def,lv,hv); - jumptable_no_range:=(lv=min_label) and (hv=max_label); - { hack a little bit, because the range can be greater } - { than the positive range of a longint } - - if (min_label<0) and (max_label>0) then - begin -{$ifdef Delphi} - if min_label=longint($80000000) then - dist:=Cardinal(max_label)+Cardinal($80000000) - else - dist:=Cardinal(max_label)+Cardinal(-min_label) -{$else Delphi} - if min_label=$80000000 then - dist:=dword(max_label)+dword($80000000) - else - dist:=dword(max_label)+dword(-min_label) -{$endif Delphi} - end - else - dist:=max_label-min_label; - - { optimize for size ? } - if cs_littlesize in aktglobalswitches then - begin - if (labels<=2) or - ((max_label-min_label)<0) or - ((max_label-min_label)>3*labels) then - { a linear list is always smaller than a jump tree } - genlinearlist(nodes) - else - { if the labels less or more a continuum then } - genjumptable(nodes,min_label,max_label); - end - else - begin - if jumptable_no_range then - max_linear_list:=4 - else - max_linear_list:=2; - { a jump table crashes the pipeline! } - if aktoptprocessor=Class386 then - inc(max_linear_list,3); - if aktoptprocessor=ClassP5 then - inc(max_linear_list,6); - if aktoptprocessor>=ClassP6 then - inc(max_linear_list,9); - - if (labels<=max_linear_list) then - genlinearlist(nodes) - else - begin - if (dist>4*cardinal(labels)) then - begin - if labels>16 then - gentreejmp(nodes) - else - genlinearlist(nodes); - end - else - genjumptable(nodes,min_label,max_label); - end; - end; - end - else - { it's always not bad } - genlinearlist(nodes); - end; - - rg.ungetregister(exprasmlist,hregister); - - { now generate the instructions } - hp:=right; - while assigned(hp) do - begin - rg.cleartempgen; - secondpass(tbinarynode(hp).right); - { don't come back to case line } - aktfilepos:=exprasmList.getlasttaifilepos^; - load_all_regvars(exprasmlist); - cg.a_jmp_always(exprasmlist,endlabel); - hp:=tbinarynode(hp).left; - end; - cg.a_label(exprasmlist,elselabel); - { ...and the else block } - if assigned(elseblock) then - begin - rg.cleartempgen; - secondpass(elseblock); - load_all_regvars(exprasmlist); - end; - cg.a_label(exprasmlist,endlabel); - end; - - begin {$ifndef TEST_GENERIC} cinnode:=ti386innode; @@ -1024,7 +706,13 @@ begin end. { $Log$ - Revision 1.41 2002-09-09 13:57:45 jonas + Revision 1.42 2002-09-16 18:08:26 peter + * fix last optimization in genlinearlist, detected by bug tw1066 + * use generic casenode.pass2 routine and override genlinearlist + * add jumptable support to generic casenode, by default there is + no jumptable support + + Revision 1.41 2002/09/09 13:57:45 jonas * small optimization to case genlist() case statements Revision 1.40 2002/08/17 09:23:46 florian diff --git a/compiler/ncgset.pas b/compiler/ncgset.pas index 7f5f9d2b7f..57991f5643 100644 --- a/compiler/ncgset.pas +++ b/compiler/ncgset.pas @@ -60,8 +60,12 @@ interface protected + procedure optimizevalues(var max_linear_list:longint;var max_dist:cardinal);virtual; + function has_jumptable : boolean;virtual; + procedure genjumptable(hp : pcaserecord;min_,max_ : longint); virtual; procedure genlinearlist(hp : pcaserecord); virtual; procedure genlinearcmplist(hp : pcaserecord); virtual; + procedure gentreejmp(p : pcaserecord); with_sign : boolean; opsize : tcgsize; @@ -72,6 +76,7 @@ interface { true, if we can omit the range check of the jump table } jumptable_no_range : boolean; + { has the implementation jumptable support } min_label : tconstexprint; end; @@ -583,6 +588,25 @@ implementation TCGCASENODE *****************************************************************************} + procedure tcgcasenode.optimizevalues(var max_linear_list:longint;var max_dist:cardinal); + begin + { no changes by default } + end; + + + function tcgcasenode.has_jumptable : boolean; + begin + { No jumptable support in the default implementation } + has_jumptable:=false; + end; + + + procedure tcgcasenode.genjumptable(hp : pcaserecord;min_,max_ : longint); + begin + internalerror(200209161); + end; + + procedure tcgcasenode.genlinearlist(hp : pcaserecord); var @@ -613,9 +637,7 @@ implementation if t^._low=t^._high then begin if t^._low-last=0 then - begin - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ,0,hregister,t^.statement); - end + cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_EQ,0,hregister,t^.statement) else begin gensub(longint(t^._low-last)); @@ -751,51 +773,49 @@ implementation end; - procedure tcgcasenode.pass_2; - - procedure gentreejmp(p : pcaserecord); - - var - lesslabel,greaterlabel : tasmlabel; - - begin - cg.a_label(exprasmlist,p^._at); - { calculate labels for left and right } - if (p^.less=nil) then - lesslabel:=elselabel - else - lesslabel:=p^.less^._at; - if (p^.greater=nil) then - greaterlabel:=elselabel - else - greaterlabel:=p^.greater^._at; - { calculate labels for left and right } - { no range label: } - if p^._low=p^._high then - begin - if greaterlabel=lesslabel then - begin - cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_NE,p^._low,hregister, lesslabel); - end - else - begin - cg.a_cmp_const_reg_label(exprasmlist,OS_INT, jmp_lt,p^._low,hregister, lesslabel); - cg.a_cmp_const_reg_label(exprasmlist,OS_INT, jmp_gt,p^._low,hregister, greaterlabel); - end; - cg.a_jmp_always(exprasmlist,p^.statement); - end - else - begin - cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,p^._low, hregister, lesslabel); - cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_gt,p^._high,hregister, greaterlabel); - cg.a_jmp_always(exprasmlist,p^.statement); - end; - if assigned(p^.less) then - gentreejmp(p^.less); - if assigned(p^.greater) then - gentreejmp(p^.greater); + procedure tcgcasenode.gentreejmp(p : pcaserecord); + var + lesslabel,greaterlabel : tasmlabel; + begin + cg.a_label(exprasmlist,p^._at); + { calculate labels for left and right } + if (p^.less=nil) then + lesslabel:=elselabel + else + lesslabel:=p^.less^._at; + if (p^.greater=nil) then + greaterlabel:=elselabel + else + greaterlabel:=p^.greater^._at; + { calculate labels for left and right } + { no range label: } + if p^._low=p^._high then + begin + if greaterlabel=lesslabel then + begin + cg.a_cmp_const_reg_label(exprasmlist, OS_INT, OC_NE,p^._low,hregister, lesslabel); + end + else + begin + cg.a_cmp_const_reg_label(exprasmlist,OS_INT, jmp_lt,p^._low,hregister, lesslabel); + cg.a_cmp_const_reg_label(exprasmlist,OS_INT, jmp_gt,p^._low,hregister, greaterlabel); + end; + cg.a_jmp_always(exprasmlist,p^.statement); + end + else + begin + cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_lt,p^._low, hregister, lesslabel); + cg.a_cmp_const_reg_label(exprasmlist,OS_INT,jmp_gt,p^._high,hregister, greaterlabel); + cg.a_jmp_always(exprasmlist,p^.statement); + end; + if assigned(p^.less) then + gentreejmp(p^.less); + if assigned(p^.greater) then + gentreejmp(p^.greater); end; + + procedure tcgcasenode.pass_2; var lv,hv, max_label: tconstexprint; @@ -803,6 +823,7 @@ implementation max_linear_list : longint; otl, ofl: tasmlabel; isjump : boolean; + max_dist, dist : cardinal; hp : tnode; begin @@ -890,23 +911,45 @@ implementation { optimize for size ? } if cs_littlesize in aktglobalswitches then begin - { a linear list is always smaller than a jump tree } - genlinearlist(nodes) + if (has_jumptable) and + not((labels<=2) or + ((max_label-min_label)<0) or + ((max_label-min_label)>3*labels)) then + begin + { if the labels less or more a continuum then } + genjumptable(nodes,min_label,max_label); + end + else + begin + { a linear list is always smaller than a jump tree } + genlinearlist(nodes); + end; end else begin + max_dist:=4*cardinal(labels); if jumptable_no_range then max_linear_list:=4 else max_linear_list:=2; + + { allow processor specific values } + optimizevalues(max_linear_list,max_dist); + if (labels<=max_linear_list) then genlinearlist(nodes) else begin - if labels>16 then - gentreejmp(nodes) + if (has_jumptable) and + (dist16 then + gentreejmp(nodes) + else + genlinearlist(nodes); + end; end; end; end @@ -950,7 +993,13 @@ begin end. { $Log$ - Revision 1.18 2002-08-15 15:11:53 carl + Revision 1.19 2002-09-16 18:08:26 peter + * fix last optimization in genlinearlist, detected by bug tw1066 + * use generic casenode.pass2 routine and override genlinearlist + * add jumptable support to generic casenode, by default there is + no jumptable support + + Revision 1.18 2002/08/15 15:11:53 carl * oldset define is now correct for all cpu's except i386 * correct compilation problems because of the above