+ 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
uses
aasmbase,aasmtai,aasmcpu,assemble,
globals,aasmbase,aasmtai,aasmcpu,assemble,
cpubase;
const
@ -52,6 +52,10 @@ interface
procedure WriteAsmList;override;
Function DoAssemble:boolean;override;
procedure WriteExternals;
{$ifdef GDB}
procedure WriteFileLineInfo(var fileinfo : tfileposinfo);
procedure WriteFileEndInfo;
{$endif}
procedure WriteAsmFileHeader;
private
procedure GenProcedureHeader(var hp:tai);
@ -64,7 +68,7 @@ interface
{$ifdef delphi}
sysutils,
{$endif}
cutils,globtype,globals,systems,cclasses,
cutils,globtype,systems,cclasses,
verbose,finput,fmodule,script,cpuinfo
;
@ -77,6 +81,18 @@ interface
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;
{Returns wheater a replacement has occured.}
@ -499,10 +515,21 @@ function getreferencestring(var ref : treference) : string;
begin
GetAdjacentTaiSymbol:= false;
if assigned(hp.next) and (tai(hp.next).typ=ait_symbol) then
begin
hp:=tai(hp.next);
GetAdjacentTaiSymbol:= true;
while assigned(hp.next) do
case tai(hp.next).typ of
ait_symbol:
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;
@ -533,7 +560,16 @@ function getreferencestring(var ref : treference) : string;
AsmWriteLn(#9'csect'#9'.'+s+'[PR]'); //starts the section
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: }
hp:= first;
repeat
@ -606,6 +642,84 @@ function getreferencestring(var ref : treference) : string;
PadTabs:=s+#9;
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);
var
@ -628,19 +742,29 @@ function getreferencestring(var ref : treference) : string;
begin
if not assigned(p) then
exit;
InlineLevel:=0;
{ lineinfo is only needed for codesegment (PFV) }
do_line:=((cs_asm_source in aktglobalswitches) or
(cs_lineinfo in aktmoduleswitches))
and (p=codesegment);
InlineLevel:=0;
DoNotSplitLine:=false;
hp:=tai(p.first);
while assigned(hp) do
begin
if do_line and not(hp.typ in SkipLineInfo) and
if not(hp.typ in SkipLineInfo) and
not DoNotSplitLine then
begin
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 }
if lastfileinfo.fileindex<>hp1.fileinfo.fileindex then
begin
@ -682,7 +806,10 @@ function getreferencestring(var ref : treference) : string;
lastfileinfo:=hp1.fileinfo;
lastinfile:=infile;
end;
end;
DoNotSplitLine:=false;
case hp.typ of
ait_comment:
begin
@ -700,9 +827,10 @@ function getreferencestring(var ref : treference) : string;
if tai_section(hp).sec<>sec_none then
begin
AsmLn;
AsmWriteLn(#9+target_asm.secnames[tai_section(hp).sec]){+#9#9+
'SEGMENT'#9'PARA PUBLIC USE32 '''+
target_asm.secnames[tai_section(hp).sec]+'''');}
AsmWriteLn(#9+target_asm.secnames[tai_section(hp).sec]);
{$ifdef GDB}
lastfileinfo.line:=-1;
{$endif GDB}
end;
LasTSec:=tai_section(hp).sec;
end;
@ -721,9 +849,9 @@ function getreferencestring(var ref : treference) : string;
replaced:= ReplaceForbiddenChars(s);
if tai_datablock(hp).is_global 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
AsmWriteLn(#9'export'#9+s);
AsmWriteLn(#9'export'#9+s+'[RW]');
if not macos_direct_globals then
@ -924,7 +1052,7 @@ function getreferencestring(var ref : treference) : string;
replaced:= ReplaceForbiddenChars(s);
if tai_symbol(hp).is_global 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
AsmWriteLn(#9'export'#9+s+'[RW]');
@ -943,16 +1071,30 @@ function getreferencestring(var ref : treference) : string;
end;
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:
AsmWriteLn(GetInstruction(hp));
{$ifdef GDB}
ait_stabn,
ait_stabs,
ait_force_line,
ait_stab_function_name : ;
ait_stabn: ;
ait_stabs: ;
ait_force_line :
stabslastfileinfo.line:=0;
ait_stab_function_name: ;
{$endif GDB}
ait_cut : begin
ait_cut :
begin
{ only reset buffer if nothing has changed }
if AsmSize=AsmStartSize then
AsmClear
@ -986,14 +1128,14 @@ ait_stab_function_name : ;
target_asm.secnames[lasTSec]+'''');
}
AsmStartSize:=AsmSize;
end;
ait_marker :
begin
if tai_marker(hp).kind=InlineStart then
inc(InlineLevel)
else if tai_marker(hp).kind=InlineEnd then
dec(InlineLevel);
end;
end;
ait_marker :
begin
if tai_marker(hp).kind=InlineStart then
inc(InlineLevel)
else if tai_marker(hp).kind=InlineEnd then
dec(InlineLevel);
end;
else
internalerror(2002110303);
end;
@ -1039,13 +1181,11 @@ ait_stab_function_name : ;
else
begin
if ReplaceForbiddenChars(s) then
currentasmlist.AsmWriteLn(#9'import'#9+s+' <= '''+p.name+'''')
currentasmlist.AsmWriteLn(#9'import'#9+s+'[RW] <= '''+p.name+'''')
else
begin
currentasmlist.AsmWriteLn(#9'import'#9+s+'[RW]');
currentasmlist.AsmWriteLn(#9'toc');
currentasmlist.AsmWriteLn(#9'tc'#9+s+'[TC],'+s+'[RW]');
end;
currentasmlist.AsmWriteLn(#9'import'#9+s+'[RW]');
currentasmlist.AsmWriteLn(#9'toc');
currentasmlist.AsmWriteLn(#9'tc'#9+s+'[TC],'+s+'[RW]');
end;
end;
end;
@ -1101,12 +1241,37 @@ ait_stab_function_name : ;
end;
procedure TPPCMPWAssembler.WriteAsmList;
{$ifdef GDB}
var
fileinfo : tfileposinfo;
{$endif GDB}
begin
{$ifdef EXTDEBUG}
if assigned(current_module.mainsource) then
comment(v_info,'Start writing MPW-styled assembler output for '+current_module.mainsource^);
{$endif}
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;
WriteExternals;
@ -1120,6 +1285,9 @@ ait_stab_function_name : ;
WriteTree(rttilist);
WriteTree(resourcestringlist);
WriteTree(bsssegment);
{$ifdef GDB}
WriteFileEndInfo;
{$ENDIF}
AsmWriteLn(#9'end');
AsmLn;
@ -1159,7 +1327,12 @@ initialization
end.
{
$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
* fixed handling of function pointers