mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 00:39:34 +02:00
powerpc: added support for 64bit explicit locations in legacy MorphOS syscalls. improved error handling of various corner cases or explicit paraloc handling
git-svn-id: trunk@47104 -
This commit is contained in:
parent
637976e83f
commit
f489858855
@ -1075,8 +1075,9 @@ parser_e_paraloc_only_one_para=03197_E_Each argument must have its own location
|
||||
parser_e_paraloc_all_paras=03198_E_Each argument must have an explicit location
|
||||
% If one argument has an explicit argument location, all arguments of a procedure
|
||||
% must have one.
|
||||
parser_e_illegal_explicit_paraloc=03199_E_Unknown argument location
|
||||
% The location specified for an argument isn't recognized by the compiler.
|
||||
parser_e_illegal_explicit_paraloc=03199_E_Invalid explicit parameter location specified
|
||||
% Syscalls specific: the specified explicit location string for this parameter cannot be parsed, invalid,
|
||||
% or The location specified for an argument isn't recognized by the compiler.
|
||||
parser_e_32bitint_or_pointer_variable_expected=03200_E_32 Bit-Integer or pointer variable expected
|
||||
% The libbase for MorphOS/AmigaOS can be given only as \var{longint}, \var{dword} or any pointer variable.
|
||||
parser_e_goto_outside_proc=03201_E_Goto statements are not allowed between different procedures
|
||||
@ -1612,6 +1613,14 @@ parser_e_method_for_type_in_other_unit=03354_E_Implementing a method for type "$
|
||||
parser_e_generic_constraints_not_allowed_here=03355_E_Generic constraint not allowed here
|
||||
% At the current location specifying a constraint is not allowed. For example
|
||||
% in delphi mode, a constraint might not be specified in the header of the implementation.
|
||||
parser_e_location_size_too_small=03356_E_Explicit location is too small for parameter
|
||||
% AmigaOS/MorphOS syscall specific: for int64/qword parameter only a single register location is specified
|
||||
parser_w_location_size_too_large=03357_W_Explicit location size is larger than required by parameter
|
||||
% AmigaOS/MorphOS syscall specific: for a parameter which is smaller than 64bit, a register pair is specified
|
||||
parser_e_location_regpair_only_data=03358_E_Only data registers are supported for explicit location register pairs
|
||||
% AmigaOS/MorphOS syscall specific: for 64bit register pairs, only data registers are supported
|
||||
parser_e_location_regpair_only_consecutive=03359_E_Only consecutive registers are supported for explicit location register pairs
|
||||
% MorphOS syscall specific: only consecutive (f.e.: d1-d2) registers are supported for 64bit register pairs
|
||||
%
|
||||
% \end{description}
|
||||
%
|
||||
|
@ -466,6 +466,10 @@ const
|
||||
parser_w_enumeration_out_of_range=03353;
|
||||
parser_e_method_for_type_in_other_unit=03354;
|
||||
parser_e_generic_constraints_not_allowed_here=03355;
|
||||
parser_e_location_size_too_small=03356;
|
||||
parser_w_location_size_too_large=03357;
|
||||
parser_e_location_regpair_only_data=03358;
|
||||
parser_e_location_regpair_only_consecutive=03359;
|
||||
type_e_mismatch=04000;
|
||||
type_e_incompatible_types=04001;
|
||||
type_e_not_equal_types=04002;
|
||||
@ -1127,9 +1131,9 @@ const
|
||||
option_info=11024;
|
||||
option_help_pages=11025;
|
||||
|
||||
MsgTxtSize = 85795;
|
||||
MsgTxtSize = 86101;
|
||||
|
||||
MsgIdxMax : array[1..20] of longint=(
|
||||
28,106,356,130,99,63,143,36,223,68,
|
||||
28,106,360,130,99,63,143,36,223,68,
|
||||
62,20,30,1,1,1,1,1,1,1
|
||||
);
|
||||
|
1355
compiler/msgtxt.inc
1355
compiler/msgtxt.inc
File diff suppressed because it is too large
Load Diff
@ -663,10 +663,22 @@ unit cpupara;
|
||||
var
|
||||
paraloc : pcgparalocation;
|
||||
paracgsize : tcgsize;
|
||||
offset : aint;
|
||||
offset_lo: aint;
|
||||
offset_hi: aint;
|
||||
|
||||
function parse68kregname(idx: longint): longint;
|
||||
begin
|
||||
result:=-1;
|
||||
if (lowercase(s[idx]) = 'd') and (s[idx+1] in ['0'..'7']) then
|
||||
result:=(ord(s[idx+1]) - ord('0')) * sizeof(pint)
|
||||
else if (lowercase(s[idx]) = 'a') and (s[idx+1] in ['0'..'6']) then
|
||||
result:=(ord(s[idx+1]) - ord('0') + 8) * sizeof(pint);
|
||||
end;
|
||||
|
||||
begin
|
||||
result:=false;
|
||||
offset:=-1;
|
||||
offset_hi:=-1;
|
||||
offset_lo:=-1;
|
||||
case target_info.system of
|
||||
system_powerpc_morphos:
|
||||
begin
|
||||
@ -683,30 +695,60 @@ unit cpupara;
|
||||
paraloc^.size:=OS_ADDR;
|
||||
paraloc^.def:=p.vardef;
|
||||
|
||||
{ convert d0-d7/a0-a6 virtual 68k reg patterns into offsets }
|
||||
if length(s) = 2 then
|
||||
begin
|
||||
if (lowercase(s[1]) = 'd') and (s[2] in ['0'..'7']) then
|
||||
offset:=(ord(s[2]) - ord('0')) * sizeof(pint)
|
||||
else if (lowercase(s[1]) = 'a') and (s[2] in ['0'..'6']) then
|
||||
offset:=(ord(s[2]) - ord('0') + 8) * sizeof(pint);
|
||||
{ convert virtual 68k reg patterns into offsets }
|
||||
case length(s) of
|
||||
2: begin
|
||||
{ single register }
|
||||
offset_lo:=parse68kregname(1);
|
||||
if offset_lo<0 then
|
||||
message(parser_e_illegal_explicit_paraloc);
|
||||
|
||||
if offset < 0 then
|
||||
exit;
|
||||
if tcgsize2size[paracgsize]>4 then
|
||||
message(parser_e_location_size_too_small);
|
||||
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE);
|
||||
paraloc^.reference.offset:=offset;
|
||||
end
|
||||
{ 'R12' is special, used internally to support regbase and nobase
|
||||
calling convention }
|
||||
else if lowercase(s)='r12' then
|
||||
begin
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
paraloc^.register:=NR_R12;
|
||||
end
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE);
|
||||
paraloc^.reference.offset:=offset_lo;
|
||||
end;
|
||||
5: begin
|
||||
{ 64bit register pair, used by AmiSSL 68k for example }
|
||||
offset_hi:=parse68kregname(1);
|
||||
offset_lo:=parse68kregname(4);
|
||||
|
||||
if (not (s[3] in [':','-'])) or
|
||||
(offset_lo<0) or (offset_hi<0) then
|
||||
message(parser_e_illegal_explicit_paraloc);
|
||||
|
||||
if offset_lo>=(8*sizeof(pint)) then
|
||||
message(parser_e_location_regpair_only_data);
|
||||
|
||||
if (offset_lo-offset_hi)<>4 then
|
||||
message(parser_e_location_regpair_only_consecutive);
|
||||
|
||||
if tcgsize2size[paracgsize]<=4 then
|
||||
message(parser_w_location_size_too_large);
|
||||
|
||||
if tcgsize2size[paracgsize]>8 then
|
||||
message(parser_e_location_size_too_small);
|
||||
|
||||
paraloc^.loc:=LOC_REFERENCE;
|
||||
paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE);
|
||||
paraloc^.reference.offset:=offset_hi;
|
||||
paraloc^.size:=OS_64;
|
||||
end;
|
||||
else
|
||||
exit;
|
||||
begin
|
||||
{ 'R12' is special, used internally to support regbase and nobase
|
||||
calling convention }
|
||||
if lowercase(s)='r12' then
|
||||
begin
|
||||
paraloc^.loc:=LOC_REGISTER;
|
||||
paraloc^.register:=NR_R12;
|
||||
end
|
||||
else
|
||||
exit; { error, cannot parse }
|
||||
end;
|
||||
end;
|
||||
|
||||
{ copy to callee side }
|
||||
p.paraloc[calleeside].add_location^:=paraloc^;
|
||||
|
Loading…
Reference in New Issue
Block a user