mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-30 10:41:15 +02:00
+ handling of local variables in direct reader implemented
This commit is contained in:
parent
98dd65b0f3
commit
39f35373a8
@ -31,7 +31,8 @@ unit agppcgas;
|
||||
|
||||
uses
|
||||
aasmtai,
|
||||
aggas;
|
||||
aggas,
|
||||
cpubase;
|
||||
|
||||
type
|
||||
PPPCGNUAssembler=^TPPCGNUAssembler;
|
||||
@ -39,13 +40,29 @@ unit agppcgas;
|
||||
procedure WriteInstruction(hp : tai);override;
|
||||
end;
|
||||
|
||||
const
|
||||
gas_reg2str : treg2strtable = ('',
|
||||
'r0','r1','r2','r3','r4','r5','r6','r7','r8','r9','r10','r11','r12','r13','r14','r15','r16',
|
||||
'r17','r18','r19','r20','r21','r22','r23','r24','r25','r26','r27','r28','r29','r30','r31',
|
||||
'f0','f1','f2','f3','f4','f5','f6','f7', 'f8','f9','f10','f11','f12',
|
||||
'f13','f14','f15','f16','f17', 'f18','f19','f20','f21','f22', 'f23','f24',
|
||||
'f25','f26','f27','f28','f29','f30','f31',
|
||||
'v0','v1','v2','v3','v4','v5','v6','v7','v8','v9','v10','v11','v12',
|
||||
'v13','v14','v15','v16','v17','v18','v19','v20','v21','v22', 'v23','v24',
|
||||
'v25','v26','v27','v28','v29','v30','v31',
|
||||
'cR','cr0','cr1','cr2','cr3','cr4','cr5','cr6','cr7',
|
||||
'xer','lr','ctr','fpscr'
|
||||
);
|
||||
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
cutils,globals,verbose,
|
||||
systems,
|
||||
assemble,
|
||||
aasmcpu,cpubase;
|
||||
aasmcpu;
|
||||
|
||||
const
|
||||
as_ppc_gas_info : tasminfo =
|
||||
@ -113,19 +130,6 @@ unit agppcgas;
|
||||
'clrslwi.', 'blr', 'bctr', 'blrl', 'bctrl', 'crset', 'crclr', 'crmove',
|
||||
'crnot', 'mt', 'mf','nop', 'li', 'lis', 'la', 'mr','mr.','not', 'mtcr');
|
||||
|
||||
reg2str : reg2strtable = ('',
|
||||
'r0','r1','r2','r3','r4','r5','r6','r7','r8','r9','r10','r11','r12','r13','r14','r15','r16',
|
||||
'r17','r18','r19','r20','r21','r22','r23','r24','r25','r26','r27','r28','r29','r30','r31',
|
||||
'f0','f1','f2','f3','f4','f5','f6','f7', 'f8','f9','f10','f11','f12',
|
||||
'f13','f14','f15','f16','f17', 'f18','f19','f20','f21','f22', 'f23','f24',
|
||||
'f25','f26','f27','f28','f29','f30','f31',
|
||||
'v0','v1','v2','v3','v4','v5','v6','v7','v8','v9','v10','v11','v12',
|
||||
'v13','v14','v15','v16','v17','v18','v19','v20','v21','v22', 'v23','v24',
|
||||
'v25','v26','v27','v28','v29','v30','v31',
|
||||
'cR','cr0','cr1','cr2','cr3','cr4','cr5','cr6','cr7',
|
||||
'xer','lr','ctr','fpscr'
|
||||
);
|
||||
|
||||
symaddr2str: array[trefsymaddr] of string[2] = ('','@ha','@l');
|
||||
|
||||
function getreferencestring(var ref : treference) : string;
|
||||
@ -167,10 +171,10 @@ unit agppcgas;
|
||||
else
|
||||
s:=s+'0';
|
||||
end;
|
||||
s:=s+'('+reg2str[base]+')'
|
||||
s:=s+'('+gas_reg2str[base]+')'
|
||||
end
|
||||
else if (index<>R_NO) and (base<>R_NO) and (offset=0) then
|
||||
s:=s+reg2str[base]+','+reg2str[index]
|
||||
s:=s+gas_reg2str[base]+','+gas_reg2str[index]
|
||||
else if ((index<>R_NO) or (base<>R_NO)) then
|
||||
{$ifndef testing}
|
||||
internalerror(19992);
|
||||
@ -190,7 +194,7 @@ unit agppcgas;
|
||||
begin
|
||||
case o.typ of
|
||||
top_reg :
|
||||
getopstr_jmp:=reg2str[o.reg];
|
||||
getopstr_jmp:=gas_reg2str[o.reg];
|
||||
{ no top_ref jumping for powerpc }
|
||||
top_const :
|
||||
getopstr_jmp:=tostr(o.val);
|
||||
@ -222,7 +226,7 @@ unit agppcgas;
|
||||
begin
|
||||
case o.typ of
|
||||
top_reg:
|
||||
getopstr:=reg2str[o.reg];
|
||||
getopstr:=gas_reg2str[o.reg];
|
||||
{ no top_ref jumping for powerpc }
|
||||
top_const:
|
||||
getopstr:=tostr(longint(o.val));
|
||||
@ -289,7 +293,7 @@ unit agppcgas;
|
||||
branchmode(op)+#9;
|
||||
case c.cond of
|
||||
C_LT..C_NU:
|
||||
cond2str := tempstr+reg2str[c.cr];
|
||||
cond2str := tempstr+gas_reg2str[c.cr];
|
||||
C_T..C_DZF:
|
||||
cond2str := tempstr+tostr(c.crbit);
|
||||
end;
|
||||
@ -351,7 +355,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.12 2002-08-18 10:34:30 florian
|
||||
Revision 1.13 2002-08-18 21:36:42 florian
|
||||
+ handling of local variables in direct reader implemented
|
||||
|
||||
Revision 1.12 2002/08/18 10:34:30 florian
|
||||
* more ppc assembling fixes
|
||||
|
||||
Revision 1.11 2002/08/17 18:23:53 florian
|
||||
|
@ -124,7 +124,7 @@ uses
|
||||
treg64 = tregister64;
|
||||
|
||||
{# Type definition for the array of string of register nnames }
|
||||
reg2strtable = array[tregister] of string[5];
|
||||
treg2strtable = array[tregister] of string[5];
|
||||
|
||||
Const
|
||||
{# First register in the tregister enumeration }
|
||||
@ -153,7 +153,7 @@ uses
|
||||
VX = 6;
|
||||
OX = 7;}
|
||||
|
||||
mot_reg2str : reg2strtable = ('',
|
||||
mot_reg2str : treg2strtable = ('',
|
||||
'r0','r1','r2','r3','r4','r5','r6','r7','r8','r9','r10','r11','r12','r13',
|
||||
'r14','r15','r16','r17','r18','r19','r20','r21','r22','r23','r24','r25',
|
||||
'r26','r27','r28','r29','r30','r31',
|
||||
@ -167,7 +167,7 @@ uses
|
||||
'XER','LR','CTR','FPSCR'
|
||||
);
|
||||
|
||||
std_reg2str : reg2strtable = ('',
|
||||
std_reg2str : treg2strtable = ('',
|
||||
'r0','r1','r2','r3','r4','r5','r6','r7','r8','r9','r10','r11','r12','r13',
|
||||
'r14','r15','r16','r17','r18','r19','r20','r21','r22','r23','r24','r25',
|
||||
'r26','r27','r28','r29','r30','r31',
|
||||
@ -383,7 +383,7 @@ uses
|
||||
case longint of
|
||||
1 : (value : AWord);
|
||||
{ can't do this, this layout depends on the host cpu. Use }
|
||||
{ lo(valueqword)/hi(valueqword) instead (JM) }
|
||||
{ lo(valueqword)/hi(valueqword) instead (JM) }
|
||||
{ 2 : (valuelow, valuehigh:AWord); }
|
||||
{ overlay a complete 64 Bit value }
|
||||
3 : (valueqword : qword);
|
||||
@ -709,7 +709,10 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.28 2002-08-14 18:41:47 jonas
|
||||
Revision 1.29 2002-08-18 21:36:42 florian
|
||||
+ handling of local variables in direct reader implemented
|
||||
|
||||
Revision 1.28 2002/08/14 18:41:47 jonas
|
||||
- remove valuelow/valuehigh fields from tlocation, because they depend
|
||||
on the endianess of the host operating system -> difficult to get
|
||||
right. Use lo/hi(location.valueqword) instead (remember to use
|
||||
|
@ -53,7 +53,8 @@ interface
|
||||
{ codegen }
|
||||
cgbase,
|
||||
{ constants }
|
||||
agppcgas
|
||||
agppcgas,
|
||||
cpubase
|
||||
;
|
||||
|
||||
function assemble : tnode;
|
||||
@ -134,8 +135,7 @@ interface
|
||||
end
|
||||
else
|
||||
Message(asmr_w_using_defined_as_local);
|
||||
end;
|
||||
{$ifdef dummy}
|
||||
end
|
||||
else
|
||||
{ access to local variables }
|
||||
if assigned(aktprocdef) then
|
||||
@ -145,14 +145,14 @@ interface
|
||||
|
||||
{ is the last written character an special }
|
||||
{ char ? }
|
||||
{ !!!
|
||||
if (s[length(s)]='%') and
|
||||
ret_in_acc(aktprocdef.rettype.def) and
|
||||
((pos('AX',upper(hs))>0) or
|
||||
(pos('AL',upper(hs))>0)) then
|
||||
tfuncretsym(aktprocdef.funcretsym).funcretstate:=vs_assigned;
|
||||
if (s[length(s)]<>'%') and
|
||||
(s[length(s)]<>'$') and
|
||||
((s[length(s)]<>'0') or (hs[1]<>'x')) then
|
||||
}
|
||||
if ((s[length(s)]<>'0') or (hs[1]<>'x')) then
|
||||
begin
|
||||
if assigned(aktprocdef.localst) and
|
||||
(lexlevel >= normal_function_level) then
|
||||
@ -161,32 +161,27 @@ interface
|
||||
sym:=nil;
|
||||
if assigned(sym) then
|
||||
begin
|
||||
if (sym.typ = labelsym) then
|
||||
if (sym.typ=labelsym) then
|
||||
Begin
|
||||
hs:=tlabelsym(sym).lab.name;
|
||||
end
|
||||
else if sym.typ=varsym then
|
||||
begin
|
||||
{variables set are after a comma }
|
||||
{like in movl %eax,I }
|
||||
if pos(',',s) > 0 then
|
||||
tvarsym(sym).varstate:=vs_used
|
||||
else
|
||||
if (pos('MOV',upper(s)) > 0) and (tvarsym(sym).varstate=vs_declared) then
|
||||
Message1(sym_n_uninitialized_local_variable,hs);
|
||||
if (vo_is_external in tvarsym(sym).varoptions) then
|
||||
hs:=tvarsym(sym).mangledname
|
||||
else
|
||||
hs:='-'+tostr(tvarsym(sym).address)+
|
||||
'('+gas_reg2str[procinfo^.framepointer]+')';
|
||||
if (vo_is_external in tvarsym(sym).varoptions) then
|
||||
hs:=tvarsym(sym).mangledname
|
||||
else
|
||||
begin
|
||||
if (tvarsym(sym).reg<>R_NO) then
|
||||
hs:=gas_reg2str[procinfo.framepointer]
|
||||
else
|
||||
hs:=tostr(tvarsym(sym).address)+
|
||||
'('+gas_reg2str[procinfo.framepointer]+')';
|
||||
end;
|
||||
end
|
||||
else
|
||||
{ call to local function }
|
||||
if (sym.typ=procsym) and ((pos('CALL',upper(s))>0) or
|
||||
(pos('LEA',upper(s))>0)) then
|
||||
begin
|
||||
hs:=tprocsym(sym).defs^.def.mangledname;
|
||||
end;
|
||||
if (sym.typ=procsym) and (pos('BL',upper(s))>0) then
|
||||
hs:=tprocsym(sym).defs^.def.mangledname;
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -201,83 +196,85 @@ interface
|
||||
l:=tvarsym(sym).address;
|
||||
{ set offset }
|
||||
inc(l,aktprocdef.parast.address_fixup);
|
||||
hs:=tostr(l)+'('+gas_reg2str[procinfo^.framepointer]+')';
|
||||
hs:=tostr(l)+'('+gas_reg2str[procinfo.framepointer]+')';
|
||||
if pos(',',s) > 0 then
|
||||
tvarsym(sym).varstate:=vs_used;
|
||||
end;
|
||||
end
|
||||
{ I added that but it creates a problem in line.ppi
|
||||
because there is a local label wbuffer and
|
||||
a static variable WBUFFER ...
|
||||
what would you decide, florian ?}
|
||||
else
|
||||
begin
|
||||
searchsym(upper(hs),sym,srsymtable);
|
||||
if assigned(sym) and (sym.owner.symtabletype in [globalsymtable,staticsymtable]) then
|
||||
begin
|
||||
case sym.typ of
|
||||
varsym :
|
||||
begin
|
||||
Message2(asmr_h_direct_global_to_mangled,hs,tvarsym(sym).mangledname);
|
||||
hs:=tvarsym(sym).mangledname;
|
||||
inc(tvarsym(sym).refs);
|
||||
end;
|
||||
typedconstsym :
|
||||
begin
|
||||
Message2(asmr_h_direct_global_to_mangled,hs,ttypedconstsym(sym).mangledname);
|
||||
hs:=ttypedconstsym(sym).mangledname;
|
||||
end;
|
||||
procsym :
|
||||
begin
|
||||
{ procs can be called or the address can be loaded }
|
||||
if ((pos('CALL',upper(s))>0) or (pos('LEA',upper(s))>0)) then
|
||||
begin
|
||||
if assigned(tprocsym(sym).defs^.def) then
|
||||
Message1(asmr_w_direct_global_is_overloaded_func,hs);
|
||||
Message2(asmr_h_direct_global_to_mangled,hs,tprocsym(sym).defs^.def.mangledname);
|
||||
hs:=tprocsym(sym).defs^.def.mangledname;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
Message(asmr_e_wrong_sym_type);
|
||||
end;
|
||||
end
|
||||
else if upper(hs)='__SELF' then
|
||||
begin
|
||||
if assigned(procinfo^._class) then
|
||||
hs:=tostr(procinfo^.selfpointer_offset)+
|
||||
'('+gas_reg2str[procinfo^.framepointer]+')'
|
||||
else
|
||||
Message(asmr_e_cannot_use_SELF_outside_a_method);
|
||||
end
|
||||
else if upper(hs)='__RESULT' then
|
||||
begin
|
||||
if (not is_void(aktprocdef.rettype.def)) then
|
||||
hs:=retstr
|
||||
else
|
||||
Message(asmr_e_void_function);
|
||||
end
|
||||
{ implement old stack/frame pointer access for nested procedures }
|
||||
{!!!!
|
||||
else if upper(hs)='__OLDSP' then
|
||||
begin
|
||||
{ complicate to check there }
|
||||
{ we do it: }
|
||||
if lexlevel>normal_function_level then
|
||||
hs:=tostr(procinfo^.framepointer_offset)+
|
||||
'('+gas_reg2str[procinfo^.framepointer]+')'
|
||||
else
|
||||
Message(asmr_e_cannot_use_OLDEBP_outside_nested_procedure);
|
||||
end;
|
||||
}
|
||||
end;
|
||||
{$ifdef dummy}
|
||||
{ I added that but it creates a problem in line.ppi
|
||||
because there is a local label wbuffer and
|
||||
a static variable WBUFFER ...
|
||||
what would you decide, florian ?}
|
||||
else
|
||||
begin
|
||||
searchsym(upper(hs),sym,srsymtable);
|
||||
if assigned(sym) and (sym.owner.symtabletype in [globalsymtable,staticsymtable]) then
|
||||
begin
|
||||
case sym.typ of
|
||||
varsym :
|
||||
begin
|
||||
Message2(asmr_h_direct_global_to_mangled,hs,tvarsym(sym).mangledname);
|
||||
hs:=tvarsym(sym).mangledname;
|
||||
inc(tvarsym(sym).refs);
|
||||
end;
|
||||
typedconstsym :
|
||||
begin
|
||||
Message2(asmr_h_direct_global_to_mangled,hs,ttypedconstsym(sym).mangledname);
|
||||
hs:=ttypedconstsym(sym).mangledname;
|
||||
end;
|
||||
procsym :
|
||||
begin
|
||||
{ procs can be called or the address can be loaded }
|
||||
if ((pos('CALL',upper(s))>0) or (pos('LEA',upper(s))>0)) then
|
||||
begin
|
||||
if assigned(tprocsym(sym).defs^.def) then
|
||||
Message1(asmr_w_direct_global_is_overloaded_func,hs);
|
||||
Message2(asmr_h_direct_global_to_mangled,hs,tprocsym(sym).defs^.def.mangledname);
|
||||
hs:=tprocsym(sym).defs^.def.mangledname;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
Message(asmr_e_wrong_sym_type);
|
||||
end;
|
||||
end
|
||||
else if upper(hs)='__SELF' then
|
||||
begin
|
||||
if assigned(procinfo^._class) then
|
||||
hs:=tostr(procinfo^.selfpointer_offset)+
|
||||
'('+gas_reg2str[procinfo^.framepointer]+')'
|
||||
else
|
||||
Message(asmr_e_cannot_use_SELF_outside_a_method);
|
||||
end
|
||||
else if upper(hs)='__RESULT' then
|
||||
begin
|
||||
if (not is_void(aktprocdef.rettype.def)) then
|
||||
hs:=retstr
|
||||
else
|
||||
Message(asmr_e_void_function);
|
||||
end
|
||||
{ implement old stack/frame pointer access for nested procedures }
|
||||
{!!!!
|
||||
else if upper(hs)='__OLDSP' then
|
||||
begin
|
||||
{ complicate to check there }
|
||||
{ we do it: }
|
||||
if lexlevel>normal_function_level then
|
||||
hs:=tostr(procinfo^.framepointer_offset)+
|
||||
'('+gas_reg2str[procinfo^.framepointer]+')'
|
||||
else
|
||||
Message(asmr_e_cannot_use_OLDEBP_outside_nested_procedure);
|
||||
end;
|
||||
}
|
||||
end;
|
||||
end;
|
||||
{$endif dummy}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{$endif dummy}
|
||||
s:=s+hs;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
'{',';',#10,#13:
|
||||
begin
|
||||
if pos(retstr,s) > 0 then
|
||||
@ -317,7 +314,10 @@ initialization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.1 2002-08-10 14:52:52 carl
|
||||
Revision 1.2 2002-08-18 21:36:42 florian
|
||||
+ handling of local variables in direct reader implemented
|
||||
|
||||
Revision 1.1 2002/08/10 14:52:52 carl
|
||||
+ moved target_cpu_string to cpuinfo
|
||||
* renamed asmmode enum.
|
||||
* assembler reader has now less ifdef's
|
||||
|
Loading…
Reference in New Issue
Block a user