+ line numbers are now emitted in the assembler code

* bug in export and import directive fixed
  * made code more in sync with aggas.pas
This commit is contained in:
olle 2003-04-06 21:01:40 +00:00
parent 03aefe277c
commit 1372a617cb

View File

@ -30,7 +30,7 @@ unit agppcmpw;
interface interface
uses uses
aasmbase,aasmtai,aasmcpu,assemble, globals,aasmbase,aasmtai,aasmcpu,assemble,
cpubase; cpubase;
const const
@ -52,6 +52,10 @@ interface
procedure WriteAsmList;override; procedure WriteAsmList;override;
Function DoAssemble:boolean;override; Function DoAssemble:boolean;override;
procedure WriteExternals; procedure WriteExternals;
{$ifdef GDB}
procedure WriteFileLineInfo(var fileinfo : tfileposinfo);
procedure WriteFileEndInfo;
{$endif}
procedure WriteAsmFileHeader; procedure WriteAsmFileHeader;
private private
procedure GenProcedureHeader(var hp:tai); procedure GenProcedureHeader(var hp:tai);
@ -64,7 +68,7 @@ interface
{$ifdef delphi} {$ifdef delphi}
sysutils, sysutils,
{$endif} {$endif}
cutils,globtype,globals,systems,cclasses, cutils,globtype,systems,cclasses,
verbose,finput,fmodule,script,cpuinfo verbose,finput,fmodule,script,cpuinfo
; ;
@ -77,6 +81,18 @@ interface
const_storage_class = '[RW]'; const_storage_class = '[RW]';
{$ifdef GDB}
var
n_line : byte; { different types of source lines }
linecount,
includecount : longint;
funcname : pchar;
stabslastfileinfo : tfileposinfo;
isInFunction: Boolean;
firstLineInFunction: longint;
{$endif}
function ReplaceForbiddenChars(var s: string):Boolean; function ReplaceForbiddenChars(var s: string):Boolean;
{Returns wheater a replacement has occured.} {Returns wheater a replacement has occured.}
@ -499,10 +515,21 @@ function getreferencestring(var ref : treference) : string;
begin begin
GetAdjacentTaiSymbol:= false; GetAdjacentTaiSymbol:= false;
if assigned(hp.next) and (tai(hp.next).typ=ait_symbol) then while assigned(hp.next) do
begin case tai(hp.next).typ of
hp:=tai(hp.next); ait_symbol:
GetAdjacentTaiSymbol:= true; begin
hp:=tai(hp.next);
GetAdjacentTaiSymbol:= true;
Break;
end;
ait_stab_function_name:
hp:=tai(hp.next);
else
begin
//AsmWriteln(' ;#*#*# ' + tostr(Ord(tai(hp.next).typ)));
Break;
end;
end; end;
end; end;
@ -533,7 +560,16 @@ function getreferencestring(var ref : treference) : string;
AsmWriteLn(#9'csect'#9'.'+s+'[PR]'); //starts the section AsmWriteLn(#9'csect'#9'.'+s+'[PR]'); //starts the section
AsmWriteLn(#9'function'#9'.'+s+'[PR]'); //info for debugger AsmWriteLn(#9'function'#9'.'+s+'[PR]'); //info for debugger
{$ifdef GDB}
if ((cs_debuginfo in aktmoduleswitches) or
(cs_gdb_lineinfo in aktglobalswitches)) then
begin
//info for debuggers:
firstLineInFunction:= stabslastfileinfo.line;
AsmWriteLn(#9'beginf ' + tostr(firstLineInFunction));
isInFunction:= true;
end;
{$endif}
{Write all labels: } {Write all labels: }
hp:= first; hp:= first;
repeat repeat
@ -606,6 +642,84 @@ function getreferencestring(var ref : treference) : string;
PadTabs:=s+#9; PadTabs:=s+#9;
end; end;
{$ifdef GDB}
procedure TPPCMPWAssembler.WriteFileLineInfo(var fileinfo : tfileposinfo);
var
curr_n : byte;
begin
if not ((cs_debuginfo in aktmoduleswitches) or
(cs_gdb_lineinfo in aktglobalswitches)) then
exit;
{ file changed ? (must be before line info) }
if (fileinfo.fileindex<>0) and
(stabslastfileinfo.fileindex<>fileinfo.fileindex) then
begin
infile:=current_module.sourcefiles.get_file(fileinfo.fileindex);
if assigned(infile) then
begin
(*
if includecount=0 then
curr_n:=n_sourcefile
else
curr_n:=n_includefile;
if (infile.path^<>'') then
begin
AsmWriteLn(#9'.stabs "'+lower(BsToSlash(FixPath(infile.path^,false)))+'",'+
tostr(curr_n)+',0,0,'+target_asm.labelprefix+'text'+ToStr(IncludeCount));
end;
AsmWriteLn(#9'.stabs "'+lower(FixFileName(infile.name^))+'",'+
tostr(curr_n)+',0,0,'+target_asm.labelprefix+'text'+ToStr(IncludeCount));
*)
AsmWriteLn(#9'file '''+lower(FixFileName(infile.name^))+'''');
(*
AsmWriteLn(target_asm.labelprefix+'text'+ToStr(IncludeCount)+':');
*)
inc(includecount);
{ force new line info }
stabslastfileinfo.line:=-1;
end;
end;
{ line changed ? }
if (stabslastfileinfo.line<>fileinfo.line) and (fileinfo.line<>0) then
begin
(*
if (n_line=n_textline) and assigned(funcname) and
(target_info.use_function_relative_addresses) then
begin
AsmWriteLn(target_asm.labelprefix+'l'+tostr(linecount)+':');
AsmWrite(#9'.stabn '+tostr(n_line)+',0,'+tostr(fileinfo.line)+','+
target_asm.labelprefix+'l'+tostr(linecount)+' - ');
AsmWritePChar(FuncName);
AsmLn;
inc(linecount);
end
else
AsmWriteLn(#9'.stabd'#9+tostr(n_line)+',0,'+tostr(fileinfo.line));
*)
if isInFunction then
AsmWriteln(#9'line '+ tostr(fileinfo.line - firstLineInFunction - 1));
end;
stabslastfileinfo:=fileinfo;
end;
procedure TPPCMPWAssembler.WriteFileEndInfo;
begin
if not ((cs_debuginfo in aktmoduleswitches) or
(cs_gdb_lineinfo in aktglobalswitches)) then
exit;
AsmLn;
(*
AsmWriteLn(ait_section2str(sec_code));
AsmWriteLn(#9'.stabs "",'+tostr(n_sourcefile)+',0,0,'+target_asm.labelprefix+'etext');
AsmWriteLn(target_asm.labelprefix+'etext:');
*)
end;
{$endif}
procedure TPPCMPWAssembler.WriteTree(p:TAAsmoutput); procedure TPPCMPWAssembler.WriteTree(p:TAAsmoutput);
var var
@ -628,19 +742,29 @@ function getreferencestring(var ref : treference) : string;
begin begin
if not assigned(p) then if not assigned(p) then
exit; exit;
InlineLevel:=0;
{ lineinfo is only needed for codesegment (PFV) } { lineinfo is only needed for codesegment (PFV) }
do_line:=((cs_asm_source in aktglobalswitches) or do_line:=((cs_asm_source in aktglobalswitches) or
(cs_lineinfo in aktmoduleswitches)) (cs_lineinfo in aktmoduleswitches))
and (p=codesegment); and (p=codesegment);
InlineLevel:=0;
DoNotSplitLine:=false; DoNotSplitLine:=false;
hp:=tai(p.first); hp:=tai(p.first);
while assigned(hp) do while assigned(hp) do
begin begin
if do_line and not(hp.typ in SkipLineInfo) and if not(hp.typ in SkipLineInfo) and
not DoNotSplitLine then not DoNotSplitLine then
begin begin
hp1 := hp as tailineinfo; hp1 := hp as tailineinfo;
{$ifdef GDB}
{ write debug info }
if (cs_debuginfo in aktmoduleswitches) or
(cs_gdb_lineinfo in aktglobalswitches) then
WriteFileLineInfo(hp1.fileinfo);
{$endif GDB}
if do_line then
begin
{ load infile } { load infile }
if lastfileinfo.fileindex<>hp1.fileinfo.fileindex then if lastfileinfo.fileindex<>hp1.fileinfo.fileindex then
begin begin
@ -682,7 +806,10 @@ function getreferencestring(var ref : treference) : string;
lastfileinfo:=hp1.fileinfo; lastfileinfo:=hp1.fileinfo;
lastinfile:=infile; lastinfile:=infile;
end; end;
end;
DoNotSplitLine:=false; DoNotSplitLine:=false;
case hp.typ of case hp.typ of
ait_comment: ait_comment:
begin begin
@ -700,9 +827,10 @@ function getreferencestring(var ref : treference) : string;
if tai_section(hp).sec<>sec_none then if tai_section(hp).sec<>sec_none then
begin begin
AsmLn; AsmLn;
AsmWriteLn(#9+target_asm.secnames[tai_section(hp).sec]){+#9#9+ AsmWriteLn(#9+target_asm.secnames[tai_section(hp).sec]);
'SEGMENT'#9'PARA PUBLIC USE32 '''+ {$ifdef GDB}
target_asm.secnames[tai_section(hp).sec]+'''');} lastfileinfo.line:=-1;
{$endif GDB}
end; end;
LasTSec:=tai_section(hp).sec; LasTSec:=tai_section(hp).sec;
end; end;
@ -721,9 +849,9 @@ function getreferencestring(var ref : treference) : string;
replaced:= ReplaceForbiddenChars(s); replaced:= ReplaceForbiddenChars(s);
if tai_datablock(hp).is_global then if tai_datablock(hp).is_global then
if replaced then if replaced then
AsmWriteLn(#9'export'#9+s+' => '''+tai_datablock(hp).sym.name+'''') AsmWriteLn(#9'export'#9+s+'[RW] => '''+tai_datablock(hp).sym.name+'''')
else else
AsmWriteLn(#9'export'#9+s); AsmWriteLn(#9'export'#9+s+'[RW]');
if not macos_direct_globals then if not macos_direct_globals then
@ -924,7 +1052,7 @@ function getreferencestring(var ref : treference) : string;
replaced:= ReplaceForbiddenChars(s); replaced:= ReplaceForbiddenChars(s);
if tai_symbol(hp).is_global then if tai_symbol(hp).is_global then
if replaced then if replaced then
AsmWriteLn(#9'export'#9+s+' => '''+tai_symbol(hp).sym.name+'''') AsmWriteLn(#9'export'#9+s+'[RW] => '''+tai_symbol(hp).sym.name+'''')
else else
AsmWriteLn(#9'export'#9+s+'[RW]'); AsmWriteLn(#9'export'#9+s+'[RW]');
@ -943,16 +1071,30 @@ function getreferencestring(var ref : treference) : string;
end; end;
end; end;
ait_symbol_end: ait_symbol_end:
{$ifdef GDB}
if isInFunction then
if ((cs_debuginfo in aktmoduleswitches) or
(cs_gdb_lineinfo in aktglobalswitches)) then
begin
//info for debuggers:
AsmWriteLn(#9'endf ' + tostr(stabslastfileinfo.line));
isInFunction:= false;
end
{$endif GDB}
; ;
ait_instruction: ait_instruction:
AsmWriteLn(GetInstruction(hp)); AsmWriteLn(GetInstruction(hp));
{$ifdef GDB} {$ifdef GDB}
ait_stabn, ait_stabn: ;
ait_stabs, ait_stabs: ;
ait_force_line,
ait_stab_function_name : ; ait_force_line :
stabslastfileinfo.line:=0;
ait_stab_function_name: ;
{$endif GDB} {$endif GDB}
ait_cut : begin ait_cut :
begin
{ only reset buffer if nothing has changed } { only reset buffer if nothing has changed }
if AsmSize=AsmStartSize then if AsmSize=AsmStartSize then
AsmClear AsmClear
@ -986,14 +1128,14 @@ ait_stab_function_name : ;
target_asm.secnames[lasTSec]+''''); target_asm.secnames[lasTSec]+'''');
} }
AsmStartSize:=AsmSize; AsmStartSize:=AsmSize;
end; end;
ait_marker : ait_marker :
begin begin
if tai_marker(hp).kind=InlineStart then if tai_marker(hp).kind=InlineStart then
inc(InlineLevel) inc(InlineLevel)
else if tai_marker(hp).kind=InlineEnd then else if tai_marker(hp).kind=InlineEnd then
dec(InlineLevel); dec(InlineLevel);
end; end;
else else
internalerror(2002110303); internalerror(2002110303);
end; end;
@ -1039,13 +1181,11 @@ ait_stab_function_name : ;
else else
begin begin
if ReplaceForbiddenChars(s) then if ReplaceForbiddenChars(s) then
currentasmlist.AsmWriteLn(#9'import'#9+s+' <= '''+p.name+'''') currentasmlist.AsmWriteLn(#9'import'#9+s+'[RW] <= '''+p.name+'''')
else else
begin currentasmlist.AsmWriteLn(#9'import'#9+s+'[RW]');
currentasmlist.AsmWriteLn(#9'import'#9+s+'[RW]'); currentasmlist.AsmWriteLn(#9'toc');
currentasmlist.AsmWriteLn(#9'toc'); currentasmlist.AsmWriteLn(#9'tc'#9+s+'[TC],'+s+'[RW]');
currentasmlist.AsmWriteLn(#9'tc'#9+s+'[TC],'+s+'[RW]');
end;
end; end;
end; end;
end; end;
@ -1101,12 +1241,37 @@ ait_stab_function_name : ;
end; end;
procedure TPPCMPWAssembler.WriteAsmList; procedure TPPCMPWAssembler.WriteAsmList;
{$ifdef GDB}
var
fileinfo : tfileposinfo;
{$endif GDB}
begin begin
{$ifdef EXTDEBUG} {$ifdef EXTDEBUG}
if assigned(current_module.mainsource) then if assigned(current_module.mainsource) then
comment(v_info,'Start writing MPW-styled assembler output for '+current_module.mainsource^); comment(v_info,'Start writing MPW-styled assembler output for '+current_module.mainsource^);
{$endif} {$endif}
LasTSec:=sec_none; LasTSec:=sec_none;
{$ifdef GDB}
FillChar(stabslastfileinfo,sizeof(stabslastfileinfo),0);
{$endif GDB}
{$ifdef GDB}
//n_line:=n_bssline;
funcname:=nil;
linecount:=1;
includecount:=0;
fileinfo.fileindex:=1;
fileinfo.line:=1;
isInFunction:= false;
firstLineInFunction:= 0;
{ Write main file }
WriteFileLineInfo(fileinfo);
{$endif GDB}
WriteAsmFileHeader; WriteAsmFileHeader;
WriteExternals; WriteExternals;
@ -1120,6 +1285,9 @@ ait_stab_function_name : ;
WriteTree(rttilist); WriteTree(rttilist);
WriteTree(resourcestringlist); WriteTree(resourcestringlist);
WriteTree(bsssegment); WriteTree(bsssegment);
{$ifdef GDB}
WriteFileEndInfo;
{$ENDIF}
AsmWriteLn(#9'end'); AsmWriteLn(#9'end');
AsmLn; AsmLn;
@ -1159,7 +1327,12 @@ initialization
end. end.
{ {
$Log$ $Log$
Revision 1.18 2003-01-13 17:17:50 olle Revision 1.19 2003-04-06 21:01:40 olle
+ line numbers are now emitted in the assembler code
* bug in export and import directive fixed
* made code more in sync with aggas.pas
Revision 1.18 2003/01/13 17:17:50 olle
* changed global var access, TOC now contain pointers to globals * changed global var access, TOC now contain pointers to globals
* fixed handling of function pointers * fixed handling of function pointers