|
@@ -26,20 +26,24 @@ unit nx86set;
|
|
interface
|
|
interface
|
|
|
|
|
|
uses
|
|
uses
|
|
- node,nset,pass_1,ncgset;
|
|
|
|
|
|
+ globtype,
|
|
|
|
+ node,nset,pass_1,ncgset;
|
|
|
|
|
|
type
|
|
type
|
|
-
|
|
|
|
tx86innode = class(tinnode)
|
|
tx86innode = class(tinnode)
|
|
- procedure pass_generate_code;override;
|
|
|
|
- function pass_1 : tnode;override;
|
|
|
|
|
|
+ procedure pass_generate_code;override;
|
|
|
|
+ function pass_1 : tnode;override;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ tx86casenode = class(tcgcasenode)
|
|
|
|
+ function has_jumptable : boolean;override;
|
|
|
|
+ procedure genjumptable(hp : pcaselabel;min_,max_ : aint);override;
|
|
|
|
+ end;
|
|
|
|
|
|
implementation
|
|
implementation
|
|
|
|
|
|
uses
|
|
uses
|
|
- globtype,systems,constexp,
|
|
|
|
|
|
+ systems,constexp,
|
|
verbose,globals,
|
|
verbose,globals,
|
|
symconst,symdef,defutil,
|
|
symconst,symdef,defutil,
|
|
aasmbase,aasmtai,aasmdata,aasmcpu,
|
|
aasmbase,aasmtai,aasmdata,aasmcpu,
|
|
@@ -47,7 +51,8 @@ implementation
|
|
ncon,
|
|
ncon,
|
|
cpubase,
|
|
cpubase,
|
|
cga,cgobj,cgutils,ncgutil,
|
|
cga,cgobj,cgutils,ncgutil,
|
|
- cgx86;
|
|
|
|
|
|
+ cgx86,
|
|
|
|
+ procinfo;
|
|
|
|
|
|
{*****************************************************************************
|
|
{*****************************************************************************
|
|
TX86INNODE
|
|
TX86INNODE
|
|
@@ -66,6 +71,81 @@ implementation
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ function tx86casenode.has_jumptable : boolean;
|
|
|
|
+ begin
|
|
|
|
+ has_jumptable:=true;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ procedure tx86casenode.genjumptable(hp : pcaselabel;min_,max_ : aint);
|
|
|
|
+ var
|
|
|
|
+ table : tasmlabel;
|
|
|
|
+ last : TConstExprInt;
|
|
|
|
+ indexreg : tregister;
|
|
|
|
+ href : treference;
|
|
|
|
+ jtlist: tasmlist;
|
|
|
|
+ sectype: TAsmSectiontype;
|
|
|
|
+
|
|
|
|
+ procedure genitem(list:TAsmList;t : pcaselabel);
|
|
|
|
+ var
|
|
|
|
+ i : aint;
|
|
|
|
+ begin
|
|
|
|
+ if assigned(t^.less) then
|
|
|
|
+ genitem(list,t^.less);
|
|
|
|
+ { fill possible hole }
|
|
|
|
+ i:=last.svalue+1;
|
|
|
|
+ while i<=t^._low.svalue-1 do
|
|
|
|
+ begin
|
|
|
|
+ list.concat(Tai_const.Create_sym(elselabel));
|
|
|
|
+ inc(i);
|
|
|
|
+ end;
|
|
|
|
+ i:=t^._low.svalue;
|
|
|
|
+ while i<=t^._high.svalue 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
|
|
|
|
+ last:=min_;
|
|
|
|
+ if not(jumptable_no_range) then
|
|
|
|
+ begin
|
|
|
|
+ { a <= x <= b <-> unsigned(x-a) <= (b-a) }
|
|
|
|
+ cg.a_op_const_reg(current_asmdata.CurrAsmList,OP_SUB,opsize,aint(min_),hregister);
|
|
|
|
+ { case expr greater than max_ => goto elselabel }
|
|
|
|
+ cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,OC_A,aint(max_)-aint(min_),hregister,elselabel);
|
|
|
|
+ min_:=0;
|
|
|
|
+ end;
|
|
|
|
+ current_asmdata.getjumplabel(table);
|
|
|
|
+ { make it a 32bit register }
|
|
|
|
+ indexreg:=cg.makeregsize(current_asmdata.CurrAsmList,hregister,OS_INT);
|
|
|
|
+ cg.a_load_reg_reg(current_asmdata.CurrAsmList,opsize,OS_INT,hregister,indexreg);
|
|
|
|
+ { create reference }
|
|
|
|
+ reference_reset_symbol(href,table,0);
|
|
|
|
+ href.offset:=(-aint(min_))*sizeof(aint);
|
|
|
|
+ href.index:=indexreg;
|
|
|
|
+ href.scalefactor:=sizeof(aint);
|
|
|
|
+ emit_ref(A_JMP,S_NO,href);
|
|
|
|
+ { generate jump table }
|
|
|
|
+ if (target_info.system = system_i386_darwin) then
|
|
|
|
+ begin
|
|
|
|
+ jtlist:=current_asmdata.asmlists[al_const];
|
|
|
|
+ sectype:=sec_rodata;
|
|
|
|
+ end
|
|
|
|
+ else
|
|
|
|
+ begin
|
|
|
|
+ jtlist:=current_procinfo.aktlocaldata;
|
|
|
|
+ sectype:=sec_data;
|
|
|
|
+ end;
|
|
|
|
+ new_section(jtlist,sectype,current_procinfo.procdef.mangledname,sizeof(aint));
|
|
|
|
+ jtlist.concat(Tai_label.Create(table));
|
|
|
|
+ genitem(jtlist,hp);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
|
|
procedure tx86innode.pass_generate_code;
|
|
procedure tx86innode.pass_generate_code;
|
|
type
|
|
type
|
|
@@ -468,4 +548,5 @@ implementation
|
|
|
|
|
|
begin
|
|
begin
|
|
cinnode:=tx86innode;
|
|
cinnode:=tx86innode;
|
|
|
|
+ ccasenode:=tx86casenode;
|
|
end.
|
|
end.
|