* smartlinking fixes for binary writer

* release alignreg code and moved instruction writing align to cpuasm,
    but it doesn't use the specified register yet
This commit is contained in:
peter 2000-01-12 10:38:16 +00:00
parent 6f3e82438e
commit 96ed273164
7 changed files with 234 additions and 159 deletions

View File

@ -87,10 +87,11 @@ unit aasm;
{ asm symbol functions }
type
TAsmsymtype=(AS_EXTERNAL,AS_LOCAL,AS_GLOBAL);
TAsmsymtype=(AS_NONE,AS_EXTERNAL,AS_LOCAL,AS_GLOBAL);
pasmsymbol = ^tasmsymbol;
tasmsymbol = object(tnamedindexobject)
orgtyp,
typ : TAsmsymtype;
proclocal : boolean;
{ this need to be incremented with every symbol loading into the
@ -107,6 +108,7 @@ unit aasm;
constructor init(const s:string;_typ:TAsmsymtype);
procedure reset;
function is_used:boolean;
procedure settyp(t:tasmsymtype);
procedure setaddress(sec:tsection;offset,len:longint);
procedure GenerateAltSymbol;
end;
@ -191,19 +193,16 @@ unit aasm;
{ alignment for operator }
{$ifndef alignreg}
pai_align = ^tai_align;
tai_align = object(tai)
{$else alignreg}
pai_align_abstract = ^tai_align_abstract;
tai_align_abstract = object(tai)
{$endif alignreg}
buf : array[0..63] of char; { buf used for fill }
aligntype : byte; { 1 = no align, 2 = word align, 4 = dword align }
fillsize : byte; { real size to fill }
fillop : byte; { value to fill with - optional }
use_op : boolean;
constructor init(b:byte);
constructor init_op(b: byte; _op: byte);
function getfillbuf:pchar;
end;
{ Insert a section/segment directive }
@ -706,12 +705,7 @@ uses
TAI_ALIGN
****************************************************************************}
{$ifndef alignreg}
constructor tai_align.init(b: byte);
{$else alignreg}
constructor tai_align_abstract.init(b: byte);
{$endif alignreg}
begin
inherited init;
typ:=ait_align;
@ -725,12 +719,7 @@ uses
end;
{$ifndef alignreg}
constructor tai_align.init_op(b: byte; _op: byte);
{$else alignreg}
constructor tai_align_abstract.init_op(b: byte; _op: byte);
{$endif alignreg}
begin
inherited init;
typ:=ait_align;
@ -741,6 +730,13 @@ uses
fillsize:=0;
fillop:=_op;
use_op:=true;
fillchar(buf,sizeof(buf),_op)
end;
function tai_align_abstract.getfillbuf:pchar;
begin
getfillbuf:=@buf;
end;
{****************************************************************************
@ -831,6 +827,10 @@ uses
procedure tasmsymbol.reset;
begin
{ save the original typ if not done yet }
if orgtyp=AS_NONE then
orgtyp:=typ;
{ reset section info }
section:=sec_none;
address:=0;
size:=0;
@ -846,11 +846,21 @@ uses
is_used:=(refs>0);
end;
procedure tasmsymbol.settyp(t:tasmsymtype);
begin
typ:=t;
orgtyp:=t;
end;
procedure tasmsymbol.setaddress(sec:tsection;offset,len:longint);
begin
section:=sec;
address:=offset;
size:=len;
{ when the typ was reset to External, set it back to the original
type it got when defined }
if (typ=AS_EXTERNAL) and (orgtyp<>AS_NONE) then
typ:=orgtyp;
end;
@ -917,7 +927,7 @@ uses
hp:=pasmsymbol(asmsymbollist^.search(s));
if assigned(hp) then
begin
hp^.typ:=_typ;
hp^.settyp(_typ);
newasmsymboltyp:=hp;
exit;
end;
@ -1028,7 +1038,12 @@ uses
end.
{
$Log$
Revision 1.70 2000-01-07 01:14:18 peter
Revision 1.71 2000-01-12 10:38:16 peter
* smartlinking fixes for binary writer
* release alignreg code and moved instruction writing align to cpuasm,
but it doesn't use the specified register yet
Revision 1.70 2000/01/07 01:14:18 peter
* updated copyright to 2000
Revision 1.69 1999/12/22 01:01:46 peter

View File

@ -305,7 +305,7 @@ unit ag386bin;
hp:=newasmsymbol('Ltext'+ToStr(IncludeCount));
if currpass=1 then
begin
hp^.typ:=AS_LOCAL;
hp^.settyp(AS_LOCAL);
hp^.setaddress(objectalloc^.currsec,objectalloc^.sectionsize,0);
end
else
@ -364,7 +364,6 @@ unit ag386bin;
function ti386binasmlist.TreePass0(hp:pai):pai;
var
lastsec : tsection;
l : longint;
begin
while assigned(hp) do
@ -421,10 +420,7 @@ unit ag386bin;
ait_const_symbol :
objectalloc^.sectionalloc(4);
ait_section:
begin
objectalloc^.setsection(pai_section(hp)^.sec);
lastsec:=pai_section(hp)^.sec;
end;
objectalloc^.setsection(pai_section(hp)^.sec);
ait_symbol :
pai_symbol(hp)^.sym^.setaddress(objectalloc^.currsec,objectalloc^.sectionsize,0);
ait_label :
@ -439,10 +435,7 @@ unit ag386bin;
end;
ait_cut :
if SmartAsm then
begin
objectalloc^.resetsections;
objectalloc^.setsection(lastsec);
end;
break;
end;
hp:=pai(hp^.next);
end;
@ -486,7 +479,7 @@ unit ag386bin;
begin
if pai_datablock(hp)^.is_global then
begin
pai_datablock(hp)^.sym^.typ:=AS_EXTERNAL;
pai_datablock(hp)^.sym^.settyp(AS_EXTERNAL);
pai_datablock(hp)^.sym^.setaddress(sec_none,pai_datablock(hp)^.size,pai_datablock(hp)^.size);
end
else
@ -496,7 +489,7 @@ unit ag386bin;
objectalloc^.sectionalign(4)
else if l>1 then
objectalloc^.sectionalign(2);
pai_datablock(hp)^.sym^.typ:=AS_LOCAL;
pai_datablock(hp)^.sym^.settyp(AS_LOCAL);
pai_datablock(hp)^.sym^.setaddress(objectalloc^.currsec,objectalloc^.sectionsize,
pai_datablock(hp)^.size);
objectalloc^.sectionalloc(pai_datablock(hp)^.size);
@ -506,9 +499,9 @@ unit ag386bin;
{$endif}
begin
if pai_datablock(hp)^.is_global then
pai_datablock(hp)^.sym^.typ:=AS_GLOBAL
pai_datablock(hp)^.sym^.settyp(AS_GLOBAL)
else
pai_datablock(hp)^.sym^.typ:=AS_LOCAL;
pai_datablock(hp)^.sym^.settyp(AS_LOCAL);
l:=pai_datablock(hp)^.size;
if l>2 then
objectalloc^.sectionalign(4)
@ -565,17 +558,17 @@ unit ag386bin;
ait_symbol :
begin
if pai_symbol(hp)^.is_global then
pai_symbol(hp)^.sym^.typ:=AS_GLOBAL
pai_symbol(hp)^.sym^.settyp(AS_GLOBAL)
else
pai_symbol(hp)^.sym^.typ:=AS_LOCAL;
pai_symbol(hp)^.sym^.settyp(AS_LOCAL);
pai_symbol(hp)^.sym^.setaddress(objectalloc^.currsec,objectalloc^.sectionsize,0);
end;
ait_label :
begin
if pai_label(hp)^.is_global then
pai_label(hp)^.l^.typ:=AS_GLOBAL
pai_label(hp)^.l^.settyp(AS_GLOBAL)
else
pai_label(hp)^.l^.typ:=AS_LOCAL;
pai_label(hp)^.l^.settyp(AS_LOCAL);
pai_label(hp)^.l^.setaddress(objectalloc^.currsec,objectalloc^.sectionsize,0);
end;
ait_string :
@ -595,18 +588,8 @@ unit ag386bin;
function ti386binasmlist.TreePass2(hp:pai):pai;
const
alignarray:array[0..5] of string[8]=(
#$8D#$B4#$26#$00#$00#$00#$00,
#$8D#$B6#$00#$00#$00#$00,
#$8D#$74#$26#$00,
#$8D#$76#$00,
#$89#$F6,
#$90
);
var
l,j : longint;
alignoparray:array[0..63] of byte;
l : longint;
{$ifdef I386}
co : comp;
{$endif I386}
@ -619,7 +602,7 @@ unit ag386bin;
if cs_debuginfo in aktmoduleswitches then
begin
if (objectoutput^.currsec<>sec_none) and
not(hp^.typ in [
not(hp^.typ in [
ait_label,
ait_regalloc,ait_tempalloc,
ait_stabn,ait_stabs,ait_section,
@ -629,25 +612,7 @@ unit ag386bin;
{$endif GDB}
case hp^.typ of
ait_align :
begin
if not pai_align(hp)^.use_op then
begin
l:=pai_align(hp)^.fillsize;
while (l>0) do
begin
for j:=0to 5 do
if (l>=length(alignarray[j])) then
break;
objectoutput^.writebytes(alignarray[j][1],length(alignarray[j]));
dec(l,length(alignarray[j]));
end;
end
else
begin
fillchar(alignoparray,pai_align(hp)^.fillsize,pai_align(hp)^.fillop);
objectoutput^.writebytes(alignoparray,pai_align(hp)^.fillsize);
end;
end;
objectoutput^.writebytes(pai_align(hp)^.getfillbuf^,pai_align(hp)^.fillsize);
ait_section :
begin
objectoutput^.defaultsection(pai_section(hp)^.sec);
@ -741,11 +706,32 @@ unit ag386bin;
var
hp : pai;
begin
objectalloc^.setsection(sec_code);
{ reset the asmsymbol list }
ResetAsmsymbolList;
objectoutput^.defaultsection(sec_code);
{$ifdef MULTIPASS}
{ Pass 0 }
currpass:=0;
objectalloc^.setsection(sec_code);
{ start with list 1 }
currlistidx:=1;
currlist:=list[currlistidx];
hp:=pai(currlist^.first);
while assigned(hp) do
begin
hp:=TreePass0(hp);
MaybeNextList(hp);
end;
{ leave if errors have occured }
if errorcount>0 then
exit;
{$endif}
{ Pass 1 }
currpass:=1;
objectalloc^.resetsections;
objectalloc^.setsection(sec_code);
{$ifdef GDB}
StartFileLineInfo;
{$endif GDB}
@ -786,17 +772,33 @@ unit ag386bin;
procedure ti386binasmlist.writetreesmart;
var
hp : pai;
startsec : tsection;
begin
objectalloc^.setsection(sec_code);
objectoutput^.defaultsection(sec_code);
startsec:=sec_code;
{ start with list 1 }
currlistidx:=1;
currlist:=list[currlistidx];
hp:=pai(currlist^.first);
while assigned(hp) do
begin
{ reset the asmsymbol list }
ResetAsmsymbolList;
{$ifdef MULTIPASS}
{ Pass 0 }
currpass:=0;
objectalloc^.resetsections;
objectalloc^.setsection(startsec);
TreePass0(hp);
{$endif}
{ leave if errors have occured }
if errorcount>0 then
exit;
{ Pass 1 }
currpass:=1;
objectalloc^.resetsections;
objectalloc^.setsection(startsec);
{$ifdef GDB}
StartFileLineInfo;
{$endif GDB}
@ -811,37 +813,36 @@ unit ag386bin;
{ Pass 2 }
currpass:=2;
objectoutput^.defaultsection(startsec);
{$ifdef GDB}
StartFileLineInfo;
{$endif GDB}
hp:=TreePass2(hp);
if not MaybeNextList(hp) then
break;
{ leave if errors have occured }
if errorcount>0 then
exit;
{ write the current objectfile }
{ end of lists? }
if not MaybeNextList(hp) then
break;
{ if not end then write the current objectfile }
objectoutput^.donewriting;
{ save section for next loop }
startsec:=objectalloc^.currsec;
{ we will start a new objectfile so reset everything }
if (hp^.typ=ait_cut) then
objectoutput^.initwriting(pai_cut(hp)^.place)
else
objectoutput^.initwriting(cut_normal);
objectalloc^.resetsections;
ResetAsmsymbolList;
{ avoid empty files }
while assigned(hp^.next) and
(pai(hp^.next)^.typ in [ait_marker,ait_comment,ait_section,ait_cut]) do
begin
if pai(hp^.next)^.typ=ait_section then
begin
objectalloc^.setsection(pai_section(hp^.next)^.sec);
objectoutput^.defaultsection(pai_section(hp^.next)^.sec);
end;
startsec:=pai_section(hp^.next)^.sec;
hp:=pai(hp^.next);
end;
@ -862,13 +863,6 @@ unit ag386bin;
end;
begin
{$ifdef MULTIPASS}
{ Process the codesegment twice so the short jmp instructions can
be optimized }
currpass:=0;
TreePass0(pai(codesegment^.first));
{$endif}
objectalloc^.resetsections;
objectalloc^.setsection(sec_code);
@ -932,7 +926,12 @@ unit ag386bin;
end.
{
$Log$
Revision 1.33 2000-01-07 01:14:18 peter
Revision 1.34 2000-01-12 10:38:17 peter
* smartlinking fixes for binary writer
* release alignreg code and moved instruction writing align to cpuasm,
but it doesn't use the specified register yet
Revision 1.33 2000/01/07 01:14:18 peter
* updated copyright to 2000
Revision 1.32 1999/12/24 15:22:52 peter

View File

@ -3313,7 +3313,7 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
exprasmlist^.insert(new(pai_align,init_op(16,$90)))
else
if not(cs_littlesize in aktglobalswitches) then
exprasmlist^.insert(new(pai_align,init_op(16,$90)));
exprasmlist^.insert(new(pai_align,init(16)));
end;
exprasmlist:=oldexprasmlist;
end;
@ -3660,7 +3660,12 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
end.
{
$Log$
Revision 1.68 2000-01-09 12:35:02 jonas
Revision 1.69 2000-01-12 10:38:17 peter
* smartlinking fixes for binary writer
* release alignreg code and moved instruction writing align to cpuasm,
but it doesn't use the specified register yet
Revision 1.68 2000/01/09 12:35:02 jonas
* changed edi allocation to use getexplicitregister32/ungetregister
(adapted tgeni386 a bit for this) and enabled it by default
* fixed very big and stupid bug of mine in cg386mat that broke the

View File

@ -53,15 +53,14 @@ type
constructor dealloc(r : tregister);
end;
{$ifdef alignreg}
{ alignment for operator }
pai_align = ^tai_align;
tai_align = object(tai_align_abstract)
reg : tregister;
constructor init(b:byte);
constructor init_op(b: byte; _op: byte);
end;
{$endif alignreg}
{ alignment for operator }
pai_align = ^tai_align;
tai_align = object(tai_align_abstract)
reg : tregister;
constructor init(b:byte);
constructor init_op(b: byte; _op: byte);
function getfillbuf:pchar;
end;
paicpu = ^taicpu;
taicpu = object(tai)
@ -166,27 +165,53 @@ uses
end;
{$ifdef alignreg}
{****************************************************************************
TAI_ALIGN
****************************************************************************}
constructor tai_align.init(b: byte);
begin
inherited init(b);
reg := R_ECX;
end;
constructor tai_align.init(b: byte);
begin
inherited init(b);
reg := R_ECX;
end;
constructor tai_align.init_op(b: byte; _op: byte);
constructor tai_align.init_op(b: byte; _op: byte);
begin
inherited init_op(b,_op);
reg := R_NO;
end;
begin
inherited init_op(b,_op);
reg := R_ECX;
end;
{$endif alignreg}
function tai_align.getfillbuf:pchar;
const
alignarray:array[0..5] of string[8]=(
#$8D#$B4#$26#$00#$00#$00#$00,
#$8D#$B6#$00#$00#$00#$00,
#$8D#$74#$26#$00,
#$8D#$76#$00,
#$89#$F6,
#$90
);
var
bufptr : pchar;
j : longint;
begin
if not use_op then
begin
bufptr:=@buf;
while (fillsize>0) do
begin
for j:=0to 5 do
if (fillsize>=length(alignarray[j])) then
break;
move(alignarray[j][1],bufptr^,length(alignarray[j]));
inc(bufptr,length(alignarray[j]));
dec(fillsize,length(alignarray[j]));
end;
end;
getfillbuf:=pchar(@buf);
end;
{*****************************************************************************
@ -206,6 +231,7 @@ uses
end;
end;
procedure taicpu.loadsymbol(opidx:longint;s:pasmsymbol;sofs:longint);
begin
if opidx>=ops then
@ -223,6 +249,7 @@ uses
inc(s^.refs);
end;
procedure taicpu.loadref(opidx:longint;p:preference);
begin
if opidx>=ops then
@ -253,6 +280,7 @@ uses
end;
end;
procedure taicpu.loadreg(opidx:longint;r:tregister);
begin
if opidx>=ops then
@ -299,9 +327,11 @@ uses
insentry:=nil;
LastInsOffset:=-1;
InsOffset:=0;
InsSize:=0;
{$endif}
end;
constructor taicpu.op_none(op : tasmop;_size : topsize);
begin
inherited init;
@ -395,6 +425,7 @@ uses
loadref(1,_op2);
end;
constructor taicpu.op_ref_reg(op : tasmop;_size : topsize;_op1 : preference;_op2 : tregister);
begin
inherited init;
@ -435,7 +466,7 @@ uses
loadreg(2,_op3);
end;
constructor taicpu.op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister;_op3 : preference);
constructor taicpu.op_reg_reg_ref(op : tasmop;_size : topsize;_op1,_op2 : tregister;_op3 : preference);
begin
inherited init;
init(op,_size);
@ -445,7 +476,8 @@ uses
loadref(2,_op3);
end;
constructor taicpu.op_const_ref_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : preference;_op3 : tregister);
constructor taicpu.op_const_ref_reg(op : tasmop;_size : topsize;_op1 : longint;_op2 : preference;_op3 : tregister);
begin
inherited init;
init(op,_size);
@ -455,7 +487,8 @@ uses
loadreg(2,_op3);
end;
constructor taicpu.op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : preference);
constructor taicpu.op_const_reg_ref(op : tasmop;_size : topsize;_op1 : longint;_op2 : tregister;_op3 : preference);
begin
inherited init;
init(op,_size);
@ -513,6 +546,7 @@ uses
loadref(1,_op2);
end;
destructor taicpu.done;
var
i : longint;
@ -528,6 +562,7 @@ uses
inherited done;
end;
function taicpu.getcopy:plinkedlist_item;
var
i : longint;
@ -622,26 +657,26 @@ uses
end;
procedure taicpu.SwapOperands;
var
p : TOper;
begin
{ Fix the operands which are in AT&T style and we need them in Intel style }
case ops of
2 : begin
{ 0,1 -> 1,0 }
p:=oper[0];
oper[0]:=oper[1];
oper[1]:=p;
procedure taicpu.SwapOperands;
var
p : TOper;
begin
{ Fix the operands which are in AT&T style and we need them in Intel style }
case ops of
2 : begin
{ 0,1 -> 1,0 }
p:=oper[0];
oper[0]:=oper[1];
oper[1]:=p;
end;
3 : begin
{ 0,1,2 -> 2,1,0 }
p:=oper[0];
oper[0]:=oper[2];
oper[2]:=p;
end;
end;
3 : begin
{ 0,1,2 -> 2,1,0 }
p:=oper[0];
oper[0]:=oper[2];
oper[2]:=p;
end;
end;
end;
end;
{*****************************************************************************
@ -831,7 +866,7 @@ begin
((InsEntry^.flags and IF_PASS2)<>0) then
begin
InsEntry:=nil;
InsSize:=-1;
InsSize:=0;
end;
LastInsOffset:=-1;
end;
@ -1565,7 +1600,12 @@ end;
end.
{
$Log$
Revision 1.9 2000-01-07 01:14:23 peter
Revision 1.10 2000-01-12 10:38:18 peter
* smartlinking fixes for binary writer
* release alignreg code and moved instruction writing align to cpuasm,
but it doesn't use the specified register yet
Revision 1.9 2000/01/07 01:14:23 peter
* updated copyright to 2000
Revision 1.8 2000/01/07 00:07:24 peter

View File

@ -430,13 +430,14 @@ var
cnt : longint;
begin
MakeStaticLibrary:=false;
{ remove the library, to be sure that it is rewritten }
RemoveFile(current_module^.staticlibfilename^);
{ Call AR }
smartpath:=current_module^.outputpath^+FixPath(FixFileName(current_module^.modulename^)+target_info.smartext,false);
SplitBinCmd(target_ar.arcmd,binstr,cmdstr);
Replace(cmdstr,'$LIB',current_module^.staticlibfilename^);
Replace(cmdstr,'$FILES',FixFileName(smartpath+current_module^.asmprefix^+'*'+target_info.objext));
success:=DoExec(FindUtil(binstr),cmdstr,false,true);
{ Clean up }
if not(cs_asm_leave in aktglobalswitches) then
if not(cs_link_extern in aktglobalswitches) then
@ -521,7 +522,12 @@ end;
end.
{
$Log$
Revision 1.80 2000-01-11 09:52:06 peter
Revision 1.81 2000-01-12 10:38:18 peter
* smartlinking fixes for binary writer
* release alignreg code and moved instruction writing align to cpuasm,
but it doesn't use the specified register yet
Revision 1.80 2000/01/11 09:52:06 peter
* fixed placing of .sl directories
* use -b again for base-file selection
* fixed group writing for linux with smartlinking

View File

@ -775,22 +775,24 @@ unit og386cff;
{ fix all section }
mempos:=0;
for sec:=low(tsection) to high(tsection) do
if s[sec]>0 then
begin
if not assigned(sects[sec]) then
begin
if (s[sec]>0) and (not assigned(sects[sec])) then
createsection(sec);
sects[sec]^.size:=s[sec];
sects[sec]^.mempos:=mempos;
{ calculate the alignment }
align:=sects[sec]^.align;
sects[sec]^.fillsize:=align-(sects[sec]^.size and (align-1));
if sects[sec]^.fillsize=align then
sects[sec]^.fillsize:=0;
{ next section position, not for win32 which uses
relative addresses }
if not win32 then
inc(mempos,sects[sec]^.size+sects[sec]^.fillsize);
end;
if assigned(sects[sec]) then
begin
sects[sec]^.size:=s[sec];
sects[sec]^.mempos:=mempos;
{ calculate the alignment }
align:=sects[sec]^.align;
sects[sec]^.fillsize:=align-(sects[sec]^.size and (align-1));
if sects[sec]^.fillsize=align then
sects[sec]^.fillsize:=0;
{ next section position, not for win32 which uses
relative addresses }
if not win32 then
inc(mempos,sects[sec]^.size+sects[sec]^.fillsize);
end;
end;
end;
@ -982,7 +984,12 @@ unit og386cff;
end.
{
$Log$
Revision 1.17 2000-01-07 01:14:27 peter
Revision 1.18 2000-01-12 10:38:18 peter
* smartlinking fixes for binary writer
* release alignreg code and moved instruction writing align to cpuasm,
but it doesn't use the specified register yet
Revision 1.17 2000/01/07 01:14:27 peter
* updated copyright to 2000
Revision 1.16 1999/12/20 22:29:26 pierre

View File

@ -484,9 +484,7 @@ implementation
{$ifdef BrowserLog}
,browlog
{$endif BrowserLog}
{$ifdef alignreg}
,cpuasm
{$endif alignreg}
;
var
@ -2771,7 +2769,12 @@ implementation
end.
{
$Log$
Revision 1.74 2000-01-09 00:37:56 pierre
Revision 1.75 2000-01-12 10:38:18 peter
* smartlinking fixes for binary writer
* release alignreg code and moved instruction writing align to cpuasm,
but it doesn't use the specified register yet
Revision 1.74 2000/01/09 00:37:56 pierre
* avoid testing object types that are simple aliases for unused privates
Revision 1.73 2000/01/07 01:14:41 peter