* taicpu_abstract.oper[] changed to pointers

This commit is contained in:
peter 2003-10-21 15:15:35 +00:00
parent a57d25b3ed
commit 96f9973b46
10 changed files with 366 additions and 311 deletions

View File

@ -158,7 +158,7 @@ interface
{ local varsym that will be inserted in pass_2 } { local varsym that will be inserted in pass_2 }
top_local : (localsym:pointer;localsymderef:tderef;localsymofs:longint); top_local : (localsym:pointer;localsymderef:tderef;localsymofs:longint);
end; end;
poper=^toper;
{ ait_* types which don't result in executable code or which don't influence } { ait_* types which don't result in executable code or which don't influence }
{ the way the program runs/behaves, but which may be encountered by the } { the way the program runs/behaves, but which may be encountered by the }
@ -440,8 +440,10 @@ interface
condition : TAsmCond; condition : TAsmCond;
{ Number of operands to instruction } { Number of operands to instruction }
ops : byte; ops : byte;
{ Number of allocate oper structures }
opercnt : byte;
{ Operands of instruction } { Operands of instruction }
oper : array[0..max_operands-1] of toper; oper : array[0..max_operands-1] of poper;
{ Actual opcode of instruction } { Actual opcode of instruction }
opcode : tasmop; opcode : tasmop;
{$ifdef x86} {$ifdef x86}
@ -456,6 +458,7 @@ interface
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure derefimpl;override; procedure derefimpl;override;
procedure SetCondition(const c:TAsmCond); procedure SetCondition(const c:TAsmCond);
procedure allocate_oper(opers:longint);
procedure loadconst(opidx:longint;l:aword); procedure loadconst(opidx:longint;l:aword);
procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint); procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
procedure loadlocal(opidx:longint;s:pointer;sofs:longint); procedure loadlocal(opidx:longint;s:pointer;sofs:longint);
@ -1511,19 +1514,24 @@ implementation
destructor taicpu_abstract.Destroy; destructor taicpu_abstract.Destroy;
var var
i : longint; i : integer;
begin begin
for i:=0 to ops-1 do for i:=0 to opercnt-1 do
case oper[i].typ of begin
top_ref: with oper[i]^ do
dispose(oper[i].ref); begin
case typ of
top_ref:
dispose(ref);
{$ifdef ARM} {$ifdef ARM}
top_shifterop: top_shifterop:
dispose(oper[i].shifterop); dispose(shifterop);
{$endif ARM} {$endif ARM}
end; end;
end;
dispose(oper[i]);
end;
inherited destroy; inherited destroy;
end; end;
@ -1532,11 +1540,21 @@ implementation
Loading of operands. Loading of operands.
---------------------------------------------------------------------} ---------------------------------------------------------------------}
procedure taicpu_abstract.allocate_oper(opers:longint);
begin
while (opers>opercnt) do
begin
new(oper[opercnt]);
fillchar(oper[opercnt]^,sizeof(toper),0);
inc(opercnt);
end;
end;
procedure taicpu_abstract.loadconst(opidx:longint;l:aword); procedure taicpu_abstract.loadconst(opidx:longint;l:aword);
begin begin
if opidx>=ops then allocate_oper(opidx+1);
ops:=opidx+1; with oper[opidx]^ do
with oper[opidx] do
begin begin
if typ<>top_const then if typ<>top_const then
clearop(opidx); clearop(opidx);
@ -1550,9 +1568,8 @@ implementation
begin begin
if not assigned(s) then if not assigned(s) then
internalerror(200204251); internalerror(200204251);
if opidx>=ops then allocate_oper(opidx+1);
ops:=opidx+1; with oper[opidx]^ do
with oper[opidx] do
begin begin
if typ<>top_symbol then if typ<>top_symbol then
clearop(opidx); clearop(opidx);
@ -1568,9 +1585,8 @@ implementation
begin begin
if not assigned(s) then if not assigned(s) then
internalerror(200204251); internalerror(200204251);
if opidx>=ops then allocate_oper(opidx+1);
ops:=opidx+1; with oper[opidx]^ do
with oper[opidx] do
begin begin
if typ<>top_local then if typ<>top_local then
clearop(opidx); clearop(opidx);
@ -1583,9 +1599,8 @@ implementation
procedure taicpu_abstract.loadref(opidx:longint;const r:treference); procedure taicpu_abstract.loadref(opidx:longint;const r:treference);
begin begin
if opidx>=ops then allocate_oper(opidx+1);
ops:=opidx+1; with oper[opidx]^ do
with oper[opidx] do
begin begin
if typ<>top_ref then if typ<>top_ref then
begin begin
@ -1610,9 +1625,8 @@ implementation
procedure taicpu_abstract.loadreg(opidx:longint;r:tregister); procedure taicpu_abstract.loadreg(opidx:longint;r:tregister);
begin begin
if opidx>=ops then allocate_oper(opidx+1);
ops:=opidx+1; with oper[opidx]^ do
with oper[opidx] do
begin begin
if typ<>top_reg then if typ<>top_reg then
clearop(opidx); clearop(opidx);
@ -1624,31 +1638,33 @@ implementation
procedure taicpu_abstract.loadoper(opidx:longint;o:toper); procedure taicpu_abstract.loadoper(opidx:longint;o:toper);
begin begin
if opidx>=ops then allocate_oper(opidx+1);
ops:=opidx+1;
clearop(opidx); clearop(opidx);
oper[opidx]:=o; oper[opidx]^:=o;
{ copy also the reference } { copy also the reference }
case oper[opidx].typ of with oper[opidx]^ do
top_ref: begin
begin case typ of
new(oper[opidx].ref); top_ref:
oper[opidx].ref^:=o.ref^; begin
end; new(ref);
ref^:=o.ref^;
end;
{$ifdef ARM} {$ifdef ARM}
top_shifterop: top_shifterop:
begin begin
new(oper[opidx].shifterop); new(shifterop);
oper[opidx].shifterop^:=o.shifterop^; shifterop^:=o.shifterop^;
end; end;
{$endif ARM} {$endif ARM}
end; end;
end;
end; end;
procedure taicpu_abstract.clearop(opidx:longint); procedure taicpu_abstract.clearop(opidx:longint);
begin begin
with oper[opidx] do with oper[opidx]^ do
case typ of case typ of
top_ref: top_ref:
dispose(ref); dispose(ref);
@ -1736,12 +1752,12 @@ implementation
begin begin
spill_registers:=false; spill_registers:=false;
if (ops = 2) and if (ops = 2) and
(oper[1].typ=top_ref) and (oper[1]^.typ=top_ref) and
{ oper[1] can also be ref in case of "lis r3,symbol@ha" or so } { oper[1] can also be ref in case of "lis r3,symbol@ha" or so }
spilling_decode_loadstore(opcode,op,wasload) then spilling_decode_loadstore(opcode,op,wasload) then
begin begin
{ the register that's being stored/loaded } { the register that's being stored/loaded }
supreg:=getsupreg(oper[0].reg); supreg:=getsupreg(oper[0]^.reg);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
begin begin
// Example: // Example:
@ -1762,14 +1778,14 @@ implementation
// st? r21d, 8(r1) // st? r21d, 8(r1)
pos := get_insert_pos(Tai(previous),supreg, pos := get_insert_pos(Tai(previous),supreg,
getsupreg(oper[1].ref^.base), getsupreg(oper[1]^.ref^.base),
getsupreg(oper[1].ref^.index), getsupreg(oper[1]^.ref^.index),
unusedregsint); unusedregsint);
rgget(list,pos,R_SUBWHOLE,helpreg); rgget(list,pos,R_SUBWHOLE,helpreg);
spill_registers := true; spill_registers := true;
if wasload then if wasload then
begin begin
helpins:=spilling_create_loadstore(opcode,helpreg,oper[1].ref^); helpins:=spilling_create_loadstore(opcode,helpreg,oper[1]^.ref^);
loadref(1,spilltemplist[supreg]); loadref(1,spilltemplist[supreg]);
opcode := op; opcode := op;
end end
@ -1790,13 +1806,13 @@ implementation
{ now the registers used in the reference } { now the registers used in the reference }
{ a) base } { a) base }
supreg := getsupreg(oper[1].ref^.base); supreg := getsupreg(oper[1]^.ref^.base);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
begin begin
if wasload then if wasload then
pos:=get_insert_pos(Tai(previous),getsupreg(oper[1].ref^.index),getsupreg(oper[0].reg),0,unusedregsint) pos:=get_insert_pos(Tai(previous),getsupreg(oper[1]^.ref^.index),getsupreg(oper[0]^.reg),0,unusedregsint)
else else
pos:=get_insert_pos(Tai(previous),getsupreg(oper[1].ref^.index),0,0,unusedregsint); pos:=get_insert_pos(Tai(previous),getsupreg(oper[1]^.ref^.index),0,0,unusedregsint);
rgget(list,pos,R_SUBWHOLE,helpreg); rgget(list,pos,R_SUBWHOLE,helpreg);
spill_registers:=true; spill_registers:=true;
helpins:=spilling_create_load(spilltemplist[supreg],helpreg); helpins:=spilling_create_load(spilltemplist[supreg],helpreg);
@ -1804,7 +1820,7 @@ implementation
list.insertafter(helpins,list.first) list.insertafter(helpins,list.first)
else else
list.insertafter(helpins,pos.next); list.insertafter(helpins,pos.next);
oper[1].ref^.base:=helpreg; oper[1]^.ref^.base:=helpreg;
rgunget(list,helpins,helpreg); rgunget(list,helpins,helpreg);
forward_allocation(Tai(helpins.next),unusedregsint); forward_allocation(Tai(helpins.next),unusedregsint);
{ {
@ -1814,13 +1830,13 @@ implementation
end; end;
{ b) index } { b) index }
supreg := getsupreg(oper[1].ref^.index); supreg := getsupreg(oper[1]^.ref^.index);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
begin begin
if wasload then if wasload then
pos:=get_insert_pos(Tai(previous),getsupreg(oper[1].ref^.base),getsupreg(oper[0].reg),0,unusedregsint) pos:=get_insert_pos(Tai(previous),getsupreg(oper[1]^.ref^.base),getsupreg(oper[0]^.reg),0,unusedregsint)
else else
pos:=get_insert_pos(Tai(previous),getsupreg(oper[1].ref^.base),0,0,unusedregsint); pos:=get_insert_pos(Tai(previous),getsupreg(oper[1]^.ref^.base),0,0,unusedregsint);
rgget(list,pos,R_SUBWHOLE,helpreg); rgget(list,pos,R_SUBWHOLE,helpreg);
spill_registers:=true; spill_registers:=true;
helpins:=spilling_create_load(spilltemplist[supreg],helpreg); helpins:=spilling_create_load(spilltemplist[supreg],helpreg);
@ -1828,7 +1844,7 @@ implementation
list.insertafter(helpins,list.first) list.insertafter(helpins,list.first)
else else
list.insertafter(helpins,pos.next); list.insertafter(helpins,pos.next);
oper[1].ref^.index:=helpreg; oper[1]^.ref^.index:=helpreg;
rgunget(list,helpins,helpreg); rgunget(list,helpins,helpreg);
forward_allocation(Tai(helpins.next),unusedregsint); forward_allocation(Tai(helpins.next),unusedregsint);
{ {
@ -1844,16 +1860,16 @@ implementation
{ operand 0 is a register and is the destination, the others are sources } { operand 0 is a register and is the destination, the others are sources }
{ and can be either registers or constants } { and can be either registers or constants }
{ exception: branches (is_jmp isn't always set for them) } { exception: branches (is_jmp isn't always set for them) }
if oper[0].typ <> top_reg then if oper[0]^.typ <> top_reg then
exit; exit;
reg1 := getsupreg(oper[0].reg); reg1 := getsupreg(oper[0]^.reg);
if oper[1].typ = top_reg then if oper[1]^.typ = top_reg then
reg2 := getsupreg(oper[1].reg) reg2 := getsupreg(oper[1]^.reg)
else else
reg2 := 0; reg2 := 0;
if (ops >= 3) and if (ops >= 3) and
(oper[2].typ = top_reg) then (oper[2]^.typ = top_reg) then
reg3 := getsupreg(oper[2].reg) reg3 := getsupreg(oper[2]^.reg)
else else
reg3 := 0; reg3 := 0;
@ -1889,9 +1905,9 @@ implementation
end; end;
for i := 1 to 2 do for i := 1 to 2 do
if (oper[i].typ = top_reg) then if (oper[i]^.typ = top_reg) then
begin begin
supreg:=getsupreg(oper[i].reg); supreg:=getsupreg(oper[i]^.reg);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
begin begin
// Example: // Example:
@ -1936,15 +1952,20 @@ implementation
Function taicpu_abstract.getcopy:TLinkedListItem; Function taicpu_abstract.getcopy:TLinkedListItem;
var var
i : longint; i : longint;
p : TLinkedListItem; p : taicpu_abstract;
begin begin
p:=inherited getcopy; p:=taicpu_abstract(inherited getcopy);
{ make a copy of the references } { make a copy of the references }
for i:=1 to ops do p.opercnt:=0;
if (taicpu_abstract(p).oper[i-1].typ=top_ref) then p.allocate_oper(ops);
for i:=0 to ops-1 do
begin begin
new(taicpu_abstract(p).oper[i-1].ref); p.oper[i]^:=oper[i]^;
taicpu_abstract(p).oper[i-1].ref^:=oper[i-1].ref^; if (oper[i]^.typ=top_ref) then
begin
new(p.oper[i]^.ref);
p.oper[i]^.ref^:=oper[i]^.ref^;
end;
end; end;
getcopy:=p; getcopy:=p;
end; end;
@ -1957,9 +1978,9 @@ implementation
inherited ppuload(t,ppufile); inherited ppuload(t,ppufile);
{ hopefully, we don't get problems with big/litte endian here when cross compiling :/ } { hopefully, we don't get problems with big/litte endian here when cross compiling :/ }
ppufile.getdata(condition,sizeof(tasmcond)); ppufile.getdata(condition,sizeof(tasmcond));
ops:=ppufile.getbyte; allocate_oper(ppufile.getbyte);
for i:=1 to ops do for i:=0 to ops-1 do
ppuloadoper(ppufile,oper[i-1]); ppuloadoper(ppufile,oper[i]^);
opcode:=tasmop(ppufile.getword); opcode:=tasmop(ppufile.getword);
{$ifdef i386} {$ifdef i386}
ppufile.getdata(segprefix,sizeof(Tregister)); ppufile.getdata(segprefix,sizeof(Tregister));
@ -1975,8 +1996,8 @@ implementation
inherited ppuwrite(ppufile); inherited ppuwrite(ppufile);
ppufile.putdata(condition,sizeof(tasmcond)); ppufile.putdata(condition,sizeof(tasmcond));
ppufile.putbyte(ops); ppufile.putbyte(ops);
for i:=1 to ops do for i:=0 to ops-1 do
ppuwriteoper(ppufile,oper[i-1]); ppuwriteoper(ppufile,oper[i]^);
ppufile.putword(word(opcode)); ppufile.putword(word(opcode));
{$ifdef i386} {$ifdef i386}
ppufile.putdata(segprefix,sizeof(Tregister)); ppufile.putdata(segprefix,sizeof(Tregister));
@ -1986,13 +2007,13 @@ implementation
procedure taicpu_abstract.derefimpl; procedure taicpu_abstract.derefimpl;
var
i : integer;
begin
for i:=0 to ops-1 do
ppuderefoper(oper[i]^);
end;
var i:byte;
begin
for i:=1 to ops do
ppuderefoper(oper[i-1]);
end;
{**************************************************************************** {****************************************************************************
tai_align_abstract tai_align_abstract
@ -2101,7 +2122,10 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.44 2003-10-17 14:38:32 peter Revision 1.45 2003-10-21 15:15:35 peter
* taicpu_abstract.oper[] changed to pointers
Revision 1.44 2003/10/17 14:38:32 peter
* 64k registers supported * 64k registers supported
* fixed some memory leaks * fixed some memory leaks

View File

@ -1185,7 +1185,7 @@ Implementation
{ fixup the references } { fixup the references }
for i:=1 to Taicpu(hp).ops do for i:=1 to Taicpu(hp).ops do
begin begin
with Taicpu(hp).oper[i-1] do with Taicpu(hp).oper[i-1]^ do
begin begin
case typ of case typ of
top_ref : top_ref :
@ -1661,7 +1661,10 @@ Implementation
end. end.
{ {
$Log$ $Log$
Revision 1.57 2003-10-03 14:16:48 marco Revision 1.58 2003-10-21 15:15:36 peter
* taicpu_abstract.oper[] changed to pointers
Revision 1.57 2003/10/03 14:16:48 marco
* -XP<prefix> support * -XP<prefix> support
Revision 1.56 2003/09/30 19:54:23 peter Revision 1.56 2003/09/30 19:54:23 peter

View File

@ -604,8 +604,8 @@ implementation
(taicpu(hp).opcode=A_PUSH) or (taicpu(hp).opcode=A_PUSH) or
(taicpu(hp).opcode=A_POP) (taicpu(hp).opcode=A_POP)
) and ) and
(taicpu(hp).oper[0].typ=top_reg) and (taicpu(hp).oper[0]^.typ=top_reg) and
is_segment_reg(taicpu(hp).oper[0].reg) is_segment_reg(taicpu(hp).oper[0]^.reg)
) then ) then
AsmWriteln(#9#9'DB'#9'066h'); AsmWriteln(#9#9'DB'#9'066h');
@ -640,7 +640,7 @@ implementation
if (aktoutputformat = as_i386_wasm) and if (aktoutputformat = as_i386_wasm) and
(taicpu(hp).opsize=S_W) and (taicpu(hp).opsize=S_W) and
(taicpu(hp).opcode=A_PUSH) and (taicpu(hp).opcode=A_PUSH) and
(taicpu(hp).oper[0].typ=top_const) then (taicpu(hp).oper[0]^.typ=top_const) then
begin begin
AsmWriteln(#9#9'DB 66h,68h ; pushw imm16'); AsmWriteln(#9#9'DB 66h,68h ; pushw imm16');
AsmWrite(#9#9'DW'); AsmWrite(#9#9'DW');
@ -652,7 +652,7 @@ implementation
if is_calljmp(taicpu(hp).opcode) then if is_calljmp(taicpu(hp).opcode) then
begin begin
AsmWrite(#9); AsmWrite(#9);
WriteOper_jmp(taicpu(hp).oper[0],taicpu(hp).opsize); WriteOper_jmp(taicpu(hp).oper[0]^,taicpu(hp).opsize);
end end
else else
begin begin
@ -662,7 +662,7 @@ implementation
AsmWrite(#9) AsmWrite(#9)
else else
AsmWrite(','); AsmWrite(',');
WriteOper(taicpu(hp).oper[i],taicpu(hp).opsize,taicpu(hp).opcode,(i=2)); WriteOper(taicpu(hp).oper[i]^,taicpu(hp).opsize,taicpu(hp).opcode,(i=2));
end; end;
end; end;
end; end;
@ -875,7 +875,10 @@ initialization
end. end.
{ {
$Log$ $Log$
Revision 1.42 2003-10-19 01:34:30 florian Revision 1.43 2003-10-21 15:15:36 peter
* taicpu_abstract.oper[] changed to pointers
Revision 1.42 2003/10/19 01:34:30 florian
* some ppc stuff fixed * some ppc stuff fixed
* memory leak fixed * memory leak fixed

View File

@ -647,11 +647,11 @@ interface
(taicpu(hp).opcode=A_FMULP)) (taicpu(hp).opcode=A_FMULP))
and (taicpu(hp).ops=0) then and (taicpu(hp).ops=0) then
begin begin
taicpu(hp).ops:=2; taicpu(hp).allocate_oper(2);
taicpu(hp).oper[0].typ:=top_reg; taicpu(hp).oper[0]^.typ:=top_reg;
taicpu(hp).oper[0].reg:=NR_ST1; taicpu(hp).oper[0]^.reg:=NR_ST1;
taicpu(hp).oper[1].typ:=top_reg; taicpu(hp).oper[1]^.typ:=top_reg;
taicpu(hp).oper[1].reg:=NR_ST; taicpu(hp).oper[1]^.reg:=NR_ST;
end; end;
if taicpu(hp).opcode=A_FWAIT then if taicpu(hp).opcode=A_FWAIT then
AsmWriteln(#9#9'DB'#9'09bh') AsmWriteln(#9#9'DB'#9'09bh')
@ -663,8 +663,8 @@ interface
if (taicpu(hp).opsize=S_W) and if (taicpu(hp).opsize=S_W) and
((taicpu(hp).opcode=A_PUSH) or ((taicpu(hp).opcode=A_PUSH) or
(taicpu(hp).opcode=A_POP)) and (taicpu(hp).opcode=A_POP)) and
(taicpu(hp).oper[0].typ=top_reg) and (taicpu(hp).oper[0]^.typ=top_reg) and
(is_segment_reg(taicpu(hp).oper[0].reg)) then (is_segment_reg(taicpu(hp).oper[0]^.reg)) then
AsmWriteln(#9#9'DB'#9'066h'); AsmWriteln(#9#9'DB'#9'066h');
AsmWrite(#9#9+std_op2str[taicpu(hp).opcode]+cond2str[taicpu(hp).condition]); AsmWrite(#9#9+std_op2str[taicpu(hp).opcode]+cond2str[taicpu(hp).condition]);
if taicpu(hp).ops<>0 then if taicpu(hp).ops<>0 then
@ -672,7 +672,7 @@ interface
if is_calljmp(taicpu(hp).opcode) then if is_calljmp(taicpu(hp).opcode) then
begin begin
AsmWrite(#9); AsmWrite(#9);
WriteOper_jmp(taicpu(hp).oper[0],taicpu(hp).opcode); WriteOper_jmp(taicpu(hp).oper[0]^,taicpu(hp).opcode);
end end
else else
begin begin
@ -682,7 +682,7 @@ interface
AsmWrite(#9) AsmWrite(#9)
else else
AsmWrite(','); AsmWrite(',');
WriteOper(taicpu(hp).oper[i],taicpu(hp).opsize,taicpu(hp).opcode,taicpu(hp).ops,(i=2)); WriteOper(taicpu(hp).oper[i]^,taicpu(hp).opsize,taicpu(hp).opcode,taicpu(hp).ops,(i=2));
end; end;
end; end;
end; end;
@ -900,7 +900,10 @@ initialization
end. end.
{ {
$Log$ $Log$
Revision 1.40 2003-10-01 20:34:49 peter Revision 1.41 2003-10-21 15:15:36 peter
* taicpu_abstract.oper[] changed to pointers
Revision 1.40 2003/10/01 20:34:49 peter
* procinfo unit contains tprocinfo * procinfo unit contains tprocinfo
* cginfo renamed to cgbase * cginfo renamed to cgbase
* moved cgmessage to verbose * moved cgmessage to verbose

View File

@ -208,8 +208,8 @@ interface
{ fixup the references } { fixup the references }
for i:=1 to taicpu(hp2).ops do for i:=1 to taicpu(hp2).ops do
begin begin
ResolveRef(taicpu(hp2).oper[i-1]); ResolveRef(taicpu(hp2).oper[i-1]^);
with taicpu(hp2).oper[i-1] do with taicpu(hp2).oper[i-1]^ do
begin begin
case typ of case typ of
top_ref : top_ref :
@ -255,7 +255,7 @@ interface
{$endif} {$endif}
{ fixup the references } { fixup the references }
for i:=1 to taicpu(hp).ops do for i:=1 to taicpu(hp).ops do
ResolveRef(taicpu(hp).oper[i-1]); ResolveRef(taicpu(hp).oper[i-1]^);
end; end;
end; end;
hp:=tai(hp.next); hp:=tai(hp.next);
@ -372,7 +372,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.44 2003-10-10 17:48:13 peter Revision 1.45 2003-10-21 15:15:36 peter
* taicpu_abstract.oper[] changed to pointers
Revision 1.44 2003/10/10 17:48:13 peter
* old trgobj moved to x86/rgcpu and renamed to trgx86fpu * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
* tregisteralloctor renamed to trgobj * tregisteralloctor renamed to trgobj
* removed rgobj from a lot of units * removed rgobj from a lot of units

View File

@ -2006,7 +2006,7 @@ implementation
if assigned(left) then if assigned(left) then
begin begin
if left.nodetype=callparan then if left.nodetype=callparan then
tcallparanode(left).firstcallparan(false) tcallparanode(left).firstcallparan
else else
firstpass(left); firstpass(left);
left_max; left_max;
@ -2358,7 +2358,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.120 2003-10-08 19:19:45 peter Revision 1.121 2003-10-21 15:15:36 peter
* taicpu_abstract.oper[] changed to pointers
Revision 1.120 2003/10/08 19:19:45 peter
* set_varstate cleanup * set_varstate cleanup
Revision 1.119 2003/10/01 20:34:48 peter Revision 1.119 2003/10/01 20:34:48 peter

View File

@ -854,9 +854,9 @@ implementation
i.moveset:=ms_worklist_moves; i.moveset:=ms_worklist_moves;
i.instruction:=instr; i.instruction:=instr;
worklist_moves.insert(i); worklist_moves.insert(i);
ssupreg:=getsupreg(instr.oper[O_MOV_SOURCE].reg); ssupreg:=getsupreg(instr.oper[O_MOV_SOURCE]^.reg);
add_to_movelist(ssupreg,i); add_to_movelist(ssupreg,i);
dsupreg:=getsupreg(instr.oper[O_MOV_DEST].reg); dsupreg:=getsupreg(instr.oper[O_MOV_DEST]^.reg);
if ssupreg<>dsupreg then if ssupreg<>dsupreg then
{Avoid adding the same move instruction twice to a single register.} {Avoid adding the same move instruction twice to a single register.}
add_to_movelist(dsupreg,i); add_to_movelist(dsupreg,i);
@ -1202,8 +1202,8 @@ implementation
begin begin
m:=Tmoveins(worklist_moves.getfirst); m:=Tmoveins(worklist_moves.getfirst);
x:=get_alias(getsupreg(m.instruction.oper[0].reg)); x:=get_alias(getsupreg(m.instruction.oper[0]^.reg));
y:=get_alias(getsupreg(m.instruction.oper[1].reg)); y:=get_alias(getsupreg(m.instruction.oper[1]^.reg));
if (y<first_imaginary) then if (y<first_imaginary) then
begin begin
u:=y; u:=y;
@ -1259,8 +1259,8 @@ implementation
m:=reginfo[u].movelist^.data[i]; m:=reginfo[u].movelist^.data[i];
if Tmoveins(m).moveset in [ms_worklist_moves,ms_active_moves] then if Tmoveins(m).moveset in [ms_worklist_moves,ms_active_moves] then
begin begin
x:=getsupreg(Tmoveins(m).instruction.oper[0].reg); x:=getsupreg(Tmoveins(m).instruction.oper[0]^.reg);
y:=getsupreg(Tmoveins(m).instruction.oper[1].reg); y:=getsupreg(Tmoveins(m).instruction.oper[1]^.reg);
if get_alias(y)=get_alias(u) then if get_alias(y)=get_alias(u) then
v:=get_alias(x) v:=get_alias(x)
else else
@ -1521,9 +1521,9 @@ implementation
begin begin
m:=Tmoveins(movelist[u]^.data[j]); m:=Tmoveins(movelist[u]^.data[j]);
{Get the other register of the move instruction.} {Get the other register of the move instruction.}
v:=m.instruction.oper[0].reg.number shr 8; v:=m.instruction.oper[0]^.reg.number shr 8;
if v=u then if v=u then
v:=m.instruction.oper[1].reg.number shr 8; v:=m.instruction.oper[1]^.reg.number shr 8;
repeat repeat
repeat repeat
if (u<>v) and (movelist[v]<>nil) then if (u<>v) and (movelist[v]<>nil) then
@ -1752,15 +1752,15 @@ implementation
ait_instruction: ait_instruction:
begin begin
for i:=0 to Taicpu_abstract(p).ops-1 do for i:=0 to Taicpu_abstract(p).ops-1 do
case Taicpu_abstract(p).oper[i].typ of case Taicpu_abstract(p).oper[i]^.typ of
Top_reg: Top_reg:
if (getregtype(Taicpu_abstract(p).oper[i].reg)=regtype) then if (getregtype(Taicpu_abstract(p).oper[i]^.reg)=regtype) then
setsupreg(Taicpu_abstract(p).oper[i].reg,reginfo[getsupreg(Taicpu_abstract(p).oper[i].reg)].colour); setsupreg(Taicpu_abstract(p).oper[i]^.reg,reginfo[getsupreg(Taicpu_abstract(p).oper[i]^.reg)].colour);
Top_ref: Top_ref:
begin begin
if regtype=R_INTREGISTER then if regtype=R_INTREGISTER then
begin begin
r:=Taicpu_abstract(p).oper[i].ref; r:=Taicpu_abstract(p).oper[i]^.ref;
if r^.base<>NR_NO then if r^.base<>NR_NO then
setsupreg(r^.base,reginfo[getsupreg(r^.base)].colour); setsupreg(r^.base,reginfo[getsupreg(r^.base)].colour);
if r^.index<>NR_NO then if r^.index<>NR_NO then
@ -1770,7 +1770,7 @@ implementation
{$ifdef arm} {$ifdef arm}
Top_shifterop: Top_shifterop:
begin begin
so:=Taicpu_abstract(p).oper[i].shifterop; so:=Taicpu_abstract(p).oper[i]^.shifterop;
if so^.rs<>NR_NO then if so^.rs<>NR_NO then
setsupreg(so^.rs,table[getsupreg(so^.rs)]); setsupreg(so^.rs,table[getsupreg(so^.rs)]);
end; end;
@ -1796,7 +1796,10 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.90 2003-10-19 12:36:36 florian Revision 1.91 2003-10-21 15:15:36 peter
* taicpu_abstract.oper[] changed to pointers
Revision 1.90 2003/10/19 12:36:36 florian
* improved speed; reduced memory usage of the interference bitmap * improved speed; reduced memory usage of the interference bitmap
Revision 1.89 2003/10/19 01:34:30 florian Revision 1.89 2003/10/19 01:34:30 florian

View File

@ -213,10 +213,10 @@ interface
procedure ppuderefoper(var o:toper);override; procedure ppuderefoper(var o:toper);override;
private private
{ next fields are filled in pass1, so pass2 is faster } { next fields are filled in pass1, so pass2 is faster }
insentry : PInsEntry; inssize : shortint;
insoffset, insoffset,
inssize : longint;
LastInsOffset : longint; { need to be public to be reset } LastInsOffset : longint; { need to be public to be reset }
insentry : PInsEntry;
function InsEnd:longint; function InsEnd:longint;
procedure create_ot; procedure create_ot;
function Matches(p:PInsEntry):longint; function Matches(p:PInsEntry):longint;
@ -648,59 +648,62 @@ implementation
addsize : boolean; addsize : boolean;
begin begin
s:='['+std_op2str[opcode]; s:='['+std_op2str[opcode];
for i:=1to ops do for i:=0 to ops-1 do
begin begin
if i=1 then with oper[i]^ do
s:=s+' '
else
s:=s+',';
{ type }
addsize:=false;
if (oper[i-1].ot and OT_XMMREG)=OT_XMMREG then
s:=s+'xmmreg'
else
if (oper[i-1].ot and OT_MMXREG)=OT_MMXREG then
s:=s+'mmxreg'
else
if (oper[i-1].ot and OT_FPUREG)=OT_FPUREG then
s:=s+'fpureg'
else
if (oper[i-1].ot and OT_REGISTER)=OT_REGISTER then
begin begin
s:=s+'reg'; if i=0 then
addsize:=true; s:=s+' '
end else
else s:=s+',';
if (oper[i-1].ot and OT_IMMEDIATE)=OT_IMMEDIATE then { type }
begin addsize:=false;
s:=s+'imm'; if (ot and OT_XMMREG)=OT_XMMREG then
addsize:=true; s:=s+'xmmreg'
end else
else if (ot and OT_MMXREG)=OT_MMXREG then
if (oper[i-1].ot and OT_MEMORY)=OT_MEMORY then s:=s+'mmxreg'
begin else
s:=s+'mem'; if (ot and OT_FPUREG)=OT_FPUREG then
addsize:=true; s:=s+'fpureg'
end else
else if (ot and OT_REGISTER)=OT_REGISTER then
s:=s+'???'; begin
{ size } s:=s+'reg';
if addsize then addsize:=true;
begin end
if (oper[i-1].ot and OT_BITS8)<>0 then else
s:=s+'8' if (ot and OT_IMMEDIATE)=OT_IMMEDIATE then
else begin
if (oper[i-1].ot and OT_BITS16)<>0 then s:=s+'imm';
s:=s+'16' addsize:=true;
else end
if (oper[i-1].ot and OT_BITS32)<>0 then else
s:=s+'32' if (ot and OT_MEMORY)=OT_MEMORY then
else begin
s:=s+'??'; s:=s+'mem';
{ signed } addsize:=true;
if (oper[i-1].ot and OT_SIGNED)<>0 then end
s:=s+'s'; else
end; s:=s+'???';
{ size }
if addsize then
begin
if (ot and OT_BITS8)<>0 then
s:=s+'8'
else
if (ot and OT_BITS16)<>0 then
s:=s+'16'
else
if (ot and OT_BITS32)<>0 then
s:=s+'32'
else
s:=s+'??';
{ signed }
if (ot and OT_SIGNED)<>0 then
s:=s+'s';
end;
end;
end; end;
GetString:=s+']'; GetString:=s+']';
end; end;
@ -708,7 +711,7 @@ implementation
procedure taicpu.Swapoperands; procedure taicpu.Swapoperands;
var var
p : TOper; p : POper;
begin begin
{ Fix the operands which are in AT&T style and we need them in Intel style } { Fix the operands which are in AT&T style and we need them in Intel style }
case ops of case ops of
@ -826,16 +829,16 @@ implementation
if ( if (
(ops=2) and (ops=2) and
(oper[0].typ=top_reg) and (oper[0]^.typ=top_reg) and
(oper[1].typ=top_reg) and (oper[1]^.typ=top_reg) and
{ if the first is ST and the second is also a register { if the first is ST and the second is also a register
it is necessarily ST1 .. ST7 } it is necessarily ST1 .. ST7 }
((oper[0].reg=NR_ST) or ((oper[0]^.reg=NR_ST) or
(oper[0].reg=NR_ST0)) (oper[0]^.reg=NR_ST0))
) or ) or
{ ((ops=1) and { ((ops=1) and
(oper[0].typ=top_reg) and (oper[0]^.typ=top_reg) and
(oper[0].reg in [R_ST1..R_ST7])) or} (oper[0]^.reg in [R_ST1..R_ST7])) or}
(ops=0) then (ops=0) then
begin begin
if opcode=A_FSUBR then if opcode=A_FSUBR then
@ -857,9 +860,9 @@ implementation
end; end;
if ( if (
(ops=1) and (ops=1) and
(oper[0].typ=top_reg) and (oper[0]^.typ=top_reg) and
(getregtype(oper[0].reg)=R_FPUREGISTER) and (getregtype(oper[0]^.reg)=R_FPUREGISTER) and
(oper[0].reg<>NR_ST) (oper[0]^.reg<>NR_ST)
) then ) then
begin begin
if opcode=A_FSUBRP then if opcode=A_FSUBRP then
@ -900,7 +903,7 @@ implementation
exit; exit;
{ update oper[].ot field } { update oper[].ot field }
for i:=0 to ops-1 do for i:=0 to ops-1 do
with oper[i] do with oper[i]^ do
begin begin
case typ of case typ of
top_reg : top_reg :
@ -1002,7 +1005,7 @@ implementation
{ Check that no spurious colons or TOs are present } { Check that no spurious colons or TOs are present }
for i:=0 to p^.ops-1 do for i:=0 to p^.ops-1 do
if (oper[i].ot and (not p^.optypes[i]) and (OT_COLON or OT_TO))<>0 then if (oper[i]^.ot and (not p^.optypes[i]) and (OT_COLON or OT_TO))<>0 then
begin begin
Matches:=0; Matches:=0;
exit; exit;
@ -1011,12 +1014,12 @@ implementation
{ Check that the operand flags all match up } { Check that the operand flags all match up }
for i:=0 to p^.ops-1 do for i:=0 to p^.ops-1 do
begin begin
if ((p^.optypes[i] and (not oper[i].ot)) or if ((p^.optypes[i] and (not oper[i]^.ot)) or
((p^.optypes[i] and OT_SIZE_MASK) and ((p^.optypes[i] and OT_SIZE_MASK) and
((p^.optypes[i] xor oper[i].ot) and OT_SIZE_MASK)))<>0 then ((p^.optypes[i] xor oper[i]^.ot) and OT_SIZE_MASK)))<>0 then
begin begin
if ((p^.optypes[i] and (not oper[i].ot) and OT_NON_SIZE) or if ((p^.optypes[i] and (not oper[i]^.ot) and OT_NON_SIZE) or
(oper[i].ot and OT_SIZE_MASK))<>0 then (oper[i]^.ot and OT_SIZE_MASK))<>0 then
begin begin
Matches:=0; Matches:=0;
exit; exit;
@ -1082,10 +1085,10 @@ implementation
for i:=0 to p^.ops-1 do for i:=0 to p^.ops-1 do
begin begin
if ((p^.optypes[i] and OT_SIZE_MASK)=0) and if ((p^.optypes[i] and OT_SIZE_MASK)=0) and
((oper[i].ot and OT_SIZE_MASK and (not siz[i]))<>0) and ((oper[i]^.ot and OT_SIZE_MASK and (not siz[i]))<>0) and
{ Immediates can always include smaller size } { Immediates can always include smaller size }
((oper[i].ot and OT_IMMEDIATE)=0) and ((oper[i]^.ot and OT_IMMEDIATE)=0) and
(((p^.optypes[i] and OT_SIZE_MASK) or siz[i])<(oper[i].ot and OT_SIZE_MASK)) then (((p^.optypes[i] and OT_SIZE_MASK) or siz[i])<(oper[i]^.ot and OT_SIZE_MASK)) then
Matches:=2; Matches:=2;
end; end;
end; end;
@ -1265,15 +1268,15 @@ implementation
function taicpu.needaddrprefix(opidx:byte):boolean; function taicpu.needaddrprefix(opidx:byte):boolean;
begin begin
needaddrprefix:=false; needaddrprefix:=false;
if (OT_MEMORY and (not oper[opidx].ot))=0 then if (OT_MEMORY and (not oper[opidx]^.ot))=0 then
begin begin
if ( if (
(oper[opidx].ref^.index<>NR_NO) and (oper[opidx]^.ref^.index<>NR_NO) and
(getsubreg(oper[opidx].ref^.index)<>R_SUBD) (getsubreg(oper[opidx]^.ref^.index)<>R_SUBD)
) or ) or
( (
(oper[opidx].ref^.base<>NR_NO) and (oper[opidx]^.ref^.base<>NR_NO) and
(getsubreg(oper[opidx].ref^.base)<>R_SUBD) (getsubreg(oper[opidx]^.ref^.base)<>R_SUBD)
) then ) then
needaddrprefix:=true; needaddrprefix:=true;
end; end;
@ -1517,7 +1520,7 @@ implementation
begin begin
if (c>=64) and (c<=191) then if (c>=64) and (c<=191) then
begin begin
if not process_ea(oper[(c shr 3) and 7], ea_data, 0) then if not process_ea(oper[(c shr 3) and 7]^, ea_data, 0) then
Message(asmw_e_invalid_effective_address) Message(asmw_e_invalid_effective_address)
else else
inc(len,ea_data.size); inc(len,ea_data.size);
@ -1583,21 +1586,21 @@ implementation
procedure getvalsym(opidx:longint); procedure getvalsym(opidx:longint);
begin begin
case oper[opidx].typ of case oper[opidx]^.typ of
top_ref : top_ref :
begin begin
currval:=oper[opidx].ref^.offset; currval:=oper[opidx]^.ref^.offset;
currsym:=oper[opidx].ref^.symbol; currsym:=oper[opidx]^.ref^.symbol;
end; end;
top_const : top_const :
begin begin
currval:=longint(oper[opidx].val); currval:=longint(oper[opidx]^.val);
currsym:=nil; currsym:=nil;
end; end;
top_symbol : top_symbol :
begin begin
currval:=oper[opidx].symofs; currval:=oper[opidx]^.symofs;
currsym:=oper[opidx].sym; currsym:=oper[opidx]^.sym;
end; end;
else else
Message(asmw_e_immediate_or_reference_expected); Message(asmw_e_immediate_or_reference_expected);
@ -1645,7 +1648,7 @@ implementation
end; end;
4,6 : 4,6 :
begin begin
case oper[0].reg of case oper[0]^.reg of
NR_CS: NR_CS:
bytes[0]:=$e; bytes[0]:=$e;
NR_NO, NR_NO,
@ -1664,7 +1667,7 @@ implementation
end; end;
5,7 : 5,7 :
begin begin
case oper[0].reg of case oper[0]^.reg of
NR_FS: NR_FS:
bytes[0]:=$a0; bytes[0]:=$a0;
NR_GS: NR_GS:
@ -1678,7 +1681,7 @@ implementation
end; end;
8,9,10 : 8,9,10 :
begin begin
bytes[0]:=ord(codes^)+regval(oper[c-8].reg); bytes[0]:=ord(codes^)+regval(oper[c-8]^.reg);
inc(codes); inc(codes);
sec.writebytes(bytes,1); sec.writebytes(bytes,1);
end; end;
@ -1814,15 +1817,15 @@ implementation
begin begin
if (c<127) then if (c<127) then
begin begin
if (oper[c and 7].typ=top_reg) then if (oper[c and 7]^.typ=top_reg) then
rfield:=regval(oper[c and 7].reg) rfield:=regval(oper[c and 7]^.reg)
else else
rfield:=regval(oper[c and 7].ref^.base); rfield:=regval(oper[c and 7]^.ref^.base);
end end
else else
rfield:=c and 7; rfield:=c and 7;
opidx:=(c shr 3) and 7; opidx:=(c shr 3) and 7;
if not process_ea(oper[opidx], ea_data, rfield) then if not process_ea(oper[opidx]^,ea_data,rfield) then
Message(asmw_e_invalid_effective_address); Message(asmw_e_invalid_effective_address);
pb:=@bytes; pb:=@bytes;
@ -1841,19 +1844,19 @@ implementation
0 : ; 0 : ;
1 : 1 :
begin begin
if (oper[opidx].ot and OT_MEMORY)=OT_MEMORY then if (oper[opidx]^.ot and OT_MEMORY)=OT_MEMORY then
sec.writereloc(oper[opidx].ref^.offset,1,oper[opidx].ref^.symbol,RELOC_ABSOLUTE) sec.writereloc(oper[opidx]^.ref^.offset,1,oper[opidx]^.ref^.symbol,RELOC_ABSOLUTE)
else else
begin begin
bytes[0]:=oper[opidx].ref^.offset; bytes[0]:=oper[opidx]^.ref^.offset;
sec.writebytes(bytes,1); sec.writebytes(bytes,1);
end; end;
inc(s); inc(s);
end; end;
2,4 : 2,4 :
begin begin
sec.writereloc(oper[opidx].ref^.offset,ea_data.bytes, sec.writereloc(oper[opidx]^.ref^.offset,ea_data.bytes,
oper[opidx].ref^.symbol,RELOC_ABSOLUTE); oper[opidx]^.ref^.symbol,RELOC_ABSOLUTE);
inc(s,ea_data.bytes); inc(s,ea_data.bytes);
end; end;
end; end;
@ -1872,8 +1875,8 @@ implementation
{We do not check the number of operands; we assume that nobody constructs {We do not check the number of operands; we assume that nobody constructs
a mov or xchg instruction with less than 2 operands. (DM)} a mov or xchg instruction with less than 2 operands. (DM)}
is_nop:=(opcode=A_NOP) or is_nop:=(opcode=A_NOP) or
(opcode=A_MOV) and (oper[0].typ=top_reg) and (oper[1].typ=top_reg) and (oper[0].reg=oper[1].reg) or (opcode=A_MOV) and (oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg) and (oper[0]^.reg=oper[1]^.reg) or
(opcode=A_XCHG) and (oper[0].typ=top_reg) and (oper[1].typ=top_reg) and (oper[0].reg=oper[1].reg); (opcode=A_XCHG) and (oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg) and (oper[0]^.reg=oper[1]^.reg);
end; end;
function Taicpu.is_move:boolean; function Taicpu.is_move:boolean;
@ -1885,7 +1888,7 @@ implementation
interrest to the register allocation, therefore we only return true interrest to the register allocation, therefore we only return true
for a move between two registers. (DM)} for a move between two registers. (DM)}
is_move:=((opcode=A_MOV) or (opcode=A_MOVZX) or (opcode=A_MOVSX)) and is_move:=((opcode=A_MOV) or (opcode=A_MOVZX) or (opcode=A_MOVSX)) and
((oper[0].typ=top_reg) and (oper[1].typ=top_reg)); ((oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg));
end; end;
@ -1921,10 +1924,10 @@ implementation
case ops of case ops of
1: 1:
begin begin
if (oper[0].typ=top_reg) and if (oper[0]^.typ=top_reg) and
(getregtype(oper[0].reg)=R_INTREGISTER) then (getregtype(oper[0]^.reg)=R_INTREGISTER) then
begin begin
supreg:=getsupreg(oper[0].reg); supreg:=getsupreg(oper[0]^.reg);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
begin begin
{Situation example: {Situation example:
@ -1933,15 +1936,15 @@ implementation
Change into: Change into:
push [ebp-12] ; Replace register by reference } push [ebp-12] ; Replace register by reference }
{ hopsize:=reg2opsize(oper[0].reg);} { hopsize:=reg2opsize(oper[0].reg);}
oper[0].typ:=top_ref; oper[0]^.typ:=top_ref;
new(oper[0].ref); new(oper[0]^.ref);
oper[0].ref^:=spilltemplist[supreg]; oper[0]^.ref^:=spilltemplist[supreg];
{ oper[0].ref^.size:=hopsize;} { oper[0]^.ref^.size:=hopsize;}
end; end;
end; end;
if oper[0].typ=top_ref then if oper[0]^.typ=top_ref then
begin begin
supreg:=getsupreg(oper[0].ref^.base); supreg:=getsupreg(oper[0]^.ref^.base);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
begin begin
{Situation example: {Situation example:
@ -1951,23 +1954,23 @@ implementation
mov r23d,[ebp-12] ; Use a help register mov r23d,[ebp-12] ; Use a help register
push [r23d+4*r22d] ; Replace register by helpregister } push [r23d+4*r22d] ; Replace register by helpregister }
subreg:=getsubreg(oper[0].ref^.base); subreg:=getsubreg(oper[0]^.ref^.base);
if oper[0].ref^.index=NR_NO then if oper[0]^.ref^.index=NR_NO then
pos:=Tai(previous) pos:=Tai(previous)
else else
pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.index),RS_INVALID,RS_INVALID,unusedregsint); pos:=get_insert_pos(Tai(previous),getsupreg(oper[0]^.ref^.index),RS_INVALID,RS_INVALID,unusedregsint);
rgget(list,pos,subreg,helpreg); rgget(list,pos,subreg,helpreg);
spill_registers:=true; spill_registers:=true;
helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[0].ref^.base),spilltemplist[supreg],helpreg); helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[0]^.ref^.base),spilltemplist[supreg],helpreg);
if pos=nil then if pos=nil then
list.insertafter(helpins,list.first) list.insertafter(helpins,list.first)
else else
list.insertafter(helpins,pos.next); list.insertafter(helpins,pos.next);
rgunget(list,helpins,helpreg); rgunget(list,helpins,helpreg);
forward_allocation(Tai(helpins.next),unusedregsint); forward_allocation(Tai(helpins.next),unusedregsint);
oper[0].ref^.base:=helpreg; oper[0]^.ref^.base:=helpreg;
end; end;
supreg:=getsupreg(oper[0].ref^.index); supreg:=getsupreg(oper[0]^.ref^.index);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
begin begin
{Situation example: {Situation example:
@ -1977,21 +1980,21 @@ implementation
mov r23d,[ebp-12] ; Use a help register mov r23d,[ebp-12] ; Use a help register
push [r21d+4*r23d] ; Replace register by helpregister } push [r21d+4*r23d] ; Replace register by helpregister }
subreg:=getsubreg(oper[0].ref^.index); subreg:=getsubreg(oper[0]^.ref^.index);
if oper[0].ref^.base=NR_NO then if oper[0]^.ref^.base=NR_NO then
pos:=Tai(previous) pos:=Tai(previous)
else else
pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.base),RS_INVALID,RS_INVALID,unusedregsint); pos:=get_insert_pos(Tai(previous),getsupreg(oper[0]^.ref^.base),RS_INVALID,RS_INVALID,unusedregsint);
rgget(list,pos,subreg,helpreg); rgget(list,pos,subreg,helpreg);
spill_registers:=true; spill_registers:=true;
helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[0].ref^.index),spilltemplist[supreg],helpreg); helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[0]^.ref^.index),spilltemplist[supreg],helpreg);
if pos=nil then if pos=nil then
list.insertafter(helpins,list.first) list.insertafter(helpins,list.first)
else else
list.insertafter(helpins,pos.next); list.insertafter(helpins,pos.next);
rgunget(list,helpins,helpreg); rgunget(list,helpins,helpreg);
forward_allocation(Tai(helpins.next),unusedregsint); forward_allocation(Tai(helpins.next),unusedregsint);
oper[0].ref^.index:=helpreg; oper[0]^.ref^.index:=helpreg;
end; end;
end; end;
end; end;
@ -2001,9 +2004,9 @@ implementation
required because the reference can be moved from this instruction required because the reference can be moved from this instruction
to a MOV instruction when spilling of the register operand is done } to a MOV instruction when spilling of the register operand is done }
for i:=0 to 1 do for i:=0 to 1 do
if oper[i].typ=top_ref then if oper[i]^.typ=top_ref then
begin begin
supreg:=getsupreg(oper[i].ref^.base); supreg:=getsupreg(oper[i]^.ref^.base);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
begin begin
{Situation example: {Situation example:
@ -2013,24 +2016,24 @@ implementation
mov r23d,[ebp-12] ; Use a help register mov r23d,[ebp-12] ; Use a help register
add r20d,[r23d+4*r22d] ; Replace register by helpregister } add r20d,[r23d+4*r22d] ; Replace register by helpregister }
subreg:=getsubreg(oper[i].ref^.base); subreg:=getsubreg(oper[i]^.ref^.base);
if i=1 then if i=1 then
pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.index),getsupreg(oper[0].reg), pos:=get_insert_pos(Tai(previous),getsupreg(oper[i]^.ref^.index),getsupreg(oper[0]^.reg),
RS_INVALID,unusedregsint) RS_INVALID,unusedregsint)
else else
pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.index),RS_INVALID,RS_INVALID,unusedregsint); pos:=get_insert_pos(Tai(previous),getsupreg(oper[i]^.ref^.index),RS_INVALID,RS_INVALID,unusedregsint);
rgget(list,pos,subreg,helpreg); rgget(list,pos,subreg,helpreg);
spill_registers:=true; spill_registers:=true;
helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[i].ref^.base),spilltemplist[supreg],helpreg); helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[i]^.ref^.base),spilltemplist[supreg],helpreg);
if pos=nil then if pos=nil then
list.insertafter(helpins,list.first) list.insertafter(helpins,list.first)
else else
list.insertafter(helpins,pos.next); list.insertafter(helpins,pos.next);
oper[i].ref^.base:=helpreg; oper[i]^.ref^.base:=helpreg;
rgunget(list,helpins,helpreg); rgunget(list,helpins,helpreg);
forward_allocation(Tai(helpins.next),unusedregsint); forward_allocation(Tai(helpins.next),unusedregsint);
end; end;
supreg:=getsupreg(oper[i].ref^.index); supreg:=getsupreg(oper[i]^.ref^.index);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
begin begin
{Situation example: {Situation example:
@ -2040,31 +2043,31 @@ implementation
mov r23d,[ebp-12] ; Use a help register mov r23d,[ebp-12] ; Use a help register
add r20d,[r21d+4*r23d] ; Replace register by helpregister } add r20d,[r21d+4*r23d] ; Replace register by helpregister }
subreg:=getsubreg(oper[i].ref^.index); subreg:=getsubreg(oper[i]^.ref^.index);
if i=1 then if i=1 then
pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.base),getsupreg(oper[0].reg), pos:=get_insert_pos(Tai(previous),getsupreg(oper[i]^.ref^.base),getsupreg(oper[0]^.reg),
RS_INVALID,unusedregsint) RS_INVALID,unusedregsint)
else else
pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.base),RS_INVALID,RS_INVALID,unusedregsint); pos:=get_insert_pos(Tai(previous),getsupreg(oper[i]^.ref^.base),RS_INVALID,RS_INVALID,unusedregsint);
rgget(list,pos,subreg,helpreg); rgget(list,pos,subreg,helpreg);
spill_registers:=true; spill_registers:=true;
helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[i].ref^.index),spilltemplist[supreg],helpreg); helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[i]^.ref^.index),spilltemplist[supreg],helpreg);
if pos=nil then if pos=nil then
list.insertafter(helpins,list.first) list.insertafter(helpins,list.first)
else else
list.insertafter(helpins,pos.next); list.insertafter(helpins,pos.next);
oper[i].ref^.index:=helpreg; oper[i]^.ref^.index:=helpreg;
rgunget(list,helpins,helpreg); rgunget(list,helpins,helpreg);
forward_allocation(Tai(helpins.next),unusedregsint); forward_allocation(Tai(helpins.next),unusedregsint);
end; end;
end; end;
if (oper[0].typ=top_reg) and if (oper[0]^.typ=top_reg) and
(getregtype(oper[0].reg)=R_INTREGISTER) then (getregtype(oper[0]^.reg)=R_INTREGISTER) then
begin begin
supreg:=getsupreg(oper[0].reg); supreg:=getsupreg(oper[0]^.reg);
subreg:=getsubreg(oper[0].reg); subreg:=getsubreg(oper[0]^.reg);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
if oper[1].typ=top_ref then if oper[1]^.typ=top_ref then
begin begin
{Situation example: {Situation example:
add [r20d],r21d ; r21d must be spilled into [ebp-12] add [r20d],r21d ; r21d must be spilled into [ebp-12]
@ -2073,17 +2076,17 @@ implementation
mov r22d,[ebp-12] ; Use a help register mov r22d,[ebp-12] ; Use a help register
add [r20d],r22d ; Replace register by helpregister } add [r20d],r22d ; Replace register by helpregister }
pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].reg), pos:=get_insert_pos(Tai(previous),getsupreg(oper[0]^.reg),
getsupreg(oper[1].ref^.base),getsupreg(oper[1].ref^.index), getsupreg(oper[1]^.ref^.base),getsupreg(oper[1]^.ref^.index),
unusedregsint); unusedregsint);
rgget(list,pos,subreg,helpreg); rgget(list,pos,subreg,helpreg);
spill_registers:=true; spill_registers:=true;
helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[0].reg),spilltemplist[supreg],helpreg); helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[0]^.reg),spilltemplist[supreg],helpreg);
if pos=nil then if pos=nil then
list.insertafter(helpins,list.first) list.insertafter(helpins,list.first)
else else
list.insertafter(helpins,pos.next); list.insertafter(helpins,pos.next);
oper[0].reg:=helpreg; oper[0]^.reg:=helpreg;
rgunget(list,helpins,helpreg); rgunget(list,helpins,helpreg);
forward_allocation(Tai(helpins.next),unusedregsint); forward_allocation(Tai(helpins.next),unusedregsint);
end end
@ -2095,19 +2098,19 @@ implementation
Change into: Change into:
add r20d,[ebp-12] ; Replace register by reference } add r20d,[ebp-12] ; Replace register by reference }
oper[0].typ:=top_ref; oper[0]^.typ:=top_ref;
new(oper[0].ref); new(oper[0]^.ref);
oper[0].ref^:=spilltemplist[supreg]; oper[0]^.ref^:=spilltemplist[supreg];
end; end;
end; end;
if (oper[1].typ=top_reg) and if (oper[1]^.typ=top_reg) and
(getregtype(oper[1].reg)=R_INTREGISTER) then (getregtype(oper[1]^.reg)=R_INTREGISTER) then
begin begin
supreg:=getsupreg(oper[1].reg); supreg:=getsupreg(oper[1]^.reg);
subreg:=getsubreg(oper[1].reg); subreg:=getsubreg(oper[1]^.reg);
if supregset_in(r,supreg) then if supregset_in(r,supreg) then
begin begin
if oper[0].typ=top_ref then if oper[0]^.typ=top_ref then
begin begin
{Situation example: {Situation example:
add r20d,[r21d] ; r20d must be spilled into [ebp-12] add r20d,[r21d] ; r20d must be spilled into [ebp-12]
@ -2116,8 +2119,8 @@ implementation
mov r22d,[r21d] ; Use a help register mov r22d,[r21d] ; Use a help register
add [ebp-12],r22d ; Replace register by helpregister } add [ebp-12],r22d ; Replace register by helpregister }
pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.base), pos:=get_insert_pos(Tai(previous),getsupreg(oper[0]^.ref^.base),
getsupreg(oper[0].ref^.index),RS_INVALID,unusedregsint); getsupreg(oper[0]^.ref^.index),RS_INVALID,unusedregsint);
rgget(list,pos,subreg,helpreg); rgget(list,pos,subreg,helpreg);
spill_registers:=true; spill_registers:=true;
op:=A_MOV; op:=A_MOV;
@ -2127,19 +2130,19 @@ implementation
{Because 'movzx memory,register' does not exist...} {Because 'movzx memory,register' does not exist...}
op:=opcode; op:=opcode;
opcode:=A_MOV; opcode:=A_MOV;
opsize:=reg2opsize(oper[1].reg); opsize:=reg2opsize(oper[1]^.reg);
end; end;
helpins:=Taicpu.op_ref_reg(op,hopsize,oper[0].ref^,helpreg); helpins:=Taicpu.op_ref_reg(op,hopsize,oper[0]^.ref^,helpreg);
if pos=nil then if pos=nil then
list.insertafter(helpins,list.first) list.insertafter(helpins,list.first)
else else
list.insertafter(helpins,pos.next); list.insertafter(helpins,pos.next);
dispose(oper[0].ref); dispose(oper[0]^.ref);
oper[0].typ:=top_reg; oper[0]^.typ:=top_reg;
oper[0].reg:=helpreg; oper[0]^.reg:=helpreg;
oper[1].typ:=top_ref; oper[1]^.typ:=top_ref;
new(oper[1].ref); new(oper[1]^.ref);
oper[1].ref^:=spilltemplist[supreg]; oper[1]^.ref^:=spilltemplist[supreg];
rgunget(list,helpins,helpreg); rgunget(list,helpins,helpreg);
forward_allocation(Tai(helpins.next),unusedregsint); forward_allocation(Tai(helpins.next),unusedregsint);
end end
@ -2158,32 +2161,32 @@ implementation
op:=opcode; op:=opcode;
hopsize:=opsize; hopsize:=opsize;
opcode:=A_MOV; opcode:=A_MOV;
opsize:=reg2opsize(oper[1].reg); opsize:=reg2opsize(oper[1]^.reg);
pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].reg),RS_INVALID,RS_INVALID,unusedregsint); pos:=get_insert_pos(Tai(previous),getsupreg(oper[0]^.reg),RS_INVALID,RS_INVALID,unusedregsint);
rgget(list,pos,subreg,helpreg); rgget(list,pos,subreg,helpreg);
helpins:=Taicpu.op_reg_reg(op,hopsize,oper[0].reg,helpreg); helpins:=Taicpu.op_reg_reg(op,hopsize,oper[0]^.reg,helpreg);
if pos=nil then if pos=nil then
list.insertafter(helpins,list.first) list.insertafter(helpins,list.first)
else else
list.insertafter(helpins,pos.next); list.insertafter(helpins,pos.next);
oper[0].reg:=helpreg; oper[0]^.reg:=helpreg;
rgunget(list,helpins,helpreg); rgunget(list,helpins,helpreg);
forward_allocation(Tai(helpins.next),unusedregsint); forward_allocation(Tai(helpins.next),unusedregsint);
end; end;
oper[1].typ:=top_ref; oper[1]^.typ:=top_ref;
new(oper[1].ref); new(oper[1]^.ref);
oper[1].ref^:=spilltemplist[supreg]; oper[1]^.ref^:=spilltemplist[supreg];
end; end;
end; end;
end; end;
{ The i386 instruction set never gets boring... { The i386 instruction set never gets boring...
some opcodes do not support a memory location as destination } some opcodes do not support a memory location as destination }
if (oper[1].typ=top_ref) and if (oper[1]^.typ=top_ref) and
( (
(oper[0].typ=top_const) or (oper[0]^.typ=top_const) or
((oper[0].typ=top_reg) and ((oper[0]^.typ=top_reg) and
(getregtype(oper[0].reg)=R_INTREGISTER)) (getregtype(oper[0]^.reg)=R_INTREGISTER))
) then ) then
begin begin
case opcode of case opcode of
@ -2205,16 +2208,16 @@ implementation
rgget(list,Tai(previous),subreg,helpreg); rgget(list,Tai(previous),subreg,helpreg);
spill_registers:=true; spill_registers:=true;
{First help instruction.} {First help instruction.}
helpins:=Taicpu.op_ref_reg(A_MOV,opsize,oper[1].ref^,helpreg); helpins:=Taicpu.op_ref_reg(A_MOV,opsize,oper[1]^.ref^,helpreg);
if previous=nil then if previous=nil then
list.insert(helpins) list.insert(helpins)
else else
list.insertafter(helpins,previous); list.insertafter(helpins,previous);
{Second help instruction.} {Second help instruction.}
helpins:=Taicpu.op_reg_ref(A_MOV,opsize,helpreg,oper[1].ref^); helpins:=Taicpu.op_reg_ref(A_MOV,opsize,helpreg,oper[1]^.ref^);
dispose(oper[1].ref); dispose(oper[1]^.ref);
oper[1].typ:=top_reg; oper[1]^.typ:=top_reg;
oper[1].reg:=helpreg; oper[1]^.reg:=helpreg;
list.insertafter(helpins,self); list.insertafter(helpins,self);
rgunget(list,self,helpreg); rgunget(list,self,helpreg);
end; end;
@ -2223,9 +2226,9 @@ implementation
{ The i386 instruction set never gets boring... { The i386 instruction set never gets boring...
some opcodes do not support a memory location as source } some opcodes do not support a memory location as source }
if (oper[0].typ=top_ref) and if (oper[0]^.typ=top_ref) and
(oper[1].typ=top_reg) and (oper[1]^.typ=top_reg) and
(getregtype(oper[1].reg)=R_INTREGISTER) then (getregtype(oper[1]^.reg)=R_INTREGISTER) then
begin begin
case opcode of case opcode of
A_BT,A_BTS, A_BT,A_BTS,
@ -2245,14 +2248,14 @@ implementation
rgget(list,Tai(previous),subreg,helpreg); rgget(list,Tai(previous),subreg,helpreg);
spill_registers:=true; spill_registers:=true;
{First help instruction.} {First help instruction.}
helpins:=Taicpu.op_ref_reg(A_MOV,opsize,oper[0].ref^,helpreg); helpins:=Taicpu.op_ref_reg(A_MOV,opsize,oper[0]^.ref^,helpreg);
if previous=nil then if previous=nil then
list.insert(helpins) list.insert(helpins)
else else
list.insertafter(helpins,previous); list.insertafter(helpins,previous);
dispose(oper[0].ref); dispose(oper[0]^.ref);
oper[0].typ:=top_reg; oper[0]^.typ:=top_reg;
oper[0].reg:=helpreg; oper[0]^.reg:=helpreg;
rgunget(list,helpins,helpreg); rgunget(list,helpins,helpreg);
end; end;
end; end;
@ -2315,7 +2318,10 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.32 2003-10-17 14:38:32 peter Revision 1.33 2003-10-21 15:15:36 peter
* taicpu_abstract.oper[] changed to pointers
Revision 1.32 2003/10/17 14:38:32 peter
* 64k registers supported * 64k registers supported
* fixed some memory leaks * fixed some memory leaks

View File

@ -176,8 +176,8 @@ interface
AsmWrite(#9+gas_op2str[op]+cond2str[taicpu(hp).condition]); AsmWrite(#9+gas_op2str[op]+cond2str[taicpu(hp).condition]);
{ suffix needed ? fnstsw,fldcw don't support suffixes { suffix needed ? fnstsw,fldcw don't support suffixes
with binutils 2.9.5 under linux } with binutils 2.9.5 under linux }
{ if (Taicpu(hp).oper[0].typ=top_reg) and { if (Taicpu(hp).oper[0]^.typ=top_reg) and
(Taicpu(hp).oper[0].reg.enum>lastreg) then (Taicpu(hp).oper[0]^.reg.enum>lastreg) then
internalerror(200301081);} internalerror(200301081);}
if (not calljmp) and if (not calljmp) and
@ -185,8 +185,8 @@ interface
(op<>A_FNSTSW) and (op<>A_FSTSW) and (op<>A_FNSTSW) and (op<>A_FSTSW) and
(op<>A_FNSTCW) and (op<>A_FSTCW) and (op<>A_FNSTCW) and (op<>A_FSTCW) and
(op<>A_FLDCW) and not( (op<>A_FLDCW) and not(
(taicpu(hp).oper[0].typ=top_reg) and (taicpu(hp).oper[0]^.typ=top_reg) and
(getregtype(taicpu(hp).oper[0].reg)=R_FPUREGISTER) (getregtype(taicpu(hp).oper[0]^.reg)=R_FPUREGISTER)
) then ) then
AsmWrite(gas_opsize2str[taicpu(hp).opsize]); AsmWrite(gas_opsize2str[taicpu(hp).opsize]);
{ process operands } { process operands }
@ -195,7 +195,7 @@ interface
if calljmp then if calljmp then
begin begin
AsmWrite(#9); AsmWrite(#9);
WriteOper_jmp(taicpu(hp).oper[0]); WriteOper_jmp(taicpu(hp).oper[0]^);
end end
else else
begin begin
@ -205,7 +205,7 @@ interface
AsmWrite(#9) AsmWrite(#9)
else else
AsmWrite(','); AsmWrite(',');
WriteOper(taicpu(hp).oper[i]); WriteOper(taicpu(hp).oper[i]^);
end; end;
end; end;
end; end;
@ -289,7 +289,10 @@ initialization
end. end.
{ {
$Log$ $Log$
Revision 1.8 2003-10-02 21:18:06 peter Revision 1.9 2003-10-21 15:15:36 peter
* taicpu_abstract.oper[] changed to pointers
Revision 1.8 2003/10/02 21:18:06 peter
* remove asw * remove asw
Revision 1.7 2003/10/01 20:34:50 peter Revision 1.7 2003/10/01 20:34:50 peter

View File

@ -661,6 +661,7 @@ begin
ai:=taicpu.op_none(opcode,siz); ai:=taicpu.op_none(opcode,siz);
ai.SetOperandOrder(OpOrder); ai.SetOperandOrder(OpOrder);
ai.Ops:=Ops; ai.Ops:=Ops;
ai.Allocate_oper(Ops);
for i:=1to Ops do for i:=1to Ops do
begin begin
case operands[i].opr.typ of case operands[i].opr.typ of
@ -700,7 +701,7 @@ begin
asize:=OT_BITS80; asize:=OT_BITS80;
end; end;
if asize<>0 then if asize<>0 then
ai.oper[i-1].ot:=(ai.oper[i-1].ot and not OT_SIZE_MASK) or asize; ai.oper[i-1]^.ot:=(ai.oper[i-1]^.ot and not OT_SIZE_MASK) or asize;
end; end;
end; end;
end; end;
@ -732,7 +733,10 @@ end;
end. end.
{ {
$Log$ $Log$
Revision 1.10 2003-10-01 20:34:51 peter Revision 1.11 2003-10-21 15:15:36 peter
* taicpu_abstract.oper[] changed to pointers
Revision 1.10 2003/10/01 20:34:51 peter
* procinfo unit contains tprocinfo * procinfo unit contains tprocinfo
* cginfo renamed to cgbase * cginfo renamed to cgbase
* moved cgmessage to verbose * moved cgmessage to verbose