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:
Károly Balogh 2020-10-14 01:45:14 +00:00
parent 637976e83f
commit f489858855
4 changed files with 764 additions and 700 deletions

View File

@ -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 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 % If one argument has an explicit argument location, all arguments of a procedure
% must have one. % must have one.
parser_e_illegal_explicit_paraloc=03199_E_Unknown argument location parser_e_illegal_explicit_paraloc=03199_E_Invalid explicit parameter location specified
% The location specified for an argument isn't recognized by the compiler. % 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 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. % 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 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 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 % 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. % 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} % \end{description}
% %

View File

@ -466,6 +466,10 @@ const
parser_w_enumeration_out_of_range=03353; parser_w_enumeration_out_of_range=03353;
parser_e_method_for_type_in_other_unit=03354; parser_e_method_for_type_in_other_unit=03354;
parser_e_generic_constraints_not_allowed_here=03355; 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_mismatch=04000;
type_e_incompatible_types=04001; type_e_incompatible_types=04001;
type_e_not_equal_types=04002; type_e_not_equal_types=04002;
@ -1127,9 +1131,9 @@ const
option_info=11024; option_info=11024;
option_help_pages=11025; option_help_pages=11025;
MsgTxtSize = 85795; MsgTxtSize = 86101;
MsgIdxMax : array[1..20] of longint=( 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 62,20,30,1,1,1,1,1,1,1
); );

File diff suppressed because it is too large Load Diff

View File

@ -663,10 +663,22 @@ unit cpupara;
var var
paraloc : pcgparalocation; paraloc : pcgparalocation;
paracgsize : tcgsize; 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 begin
result:=false; result:=false;
offset:=-1; offset_hi:=-1;
offset_lo:=-1;
case target_info.system of case target_info.system of
system_powerpc_morphos: system_powerpc_morphos:
begin begin
@ -683,30 +695,60 @@ unit cpupara;
paraloc^.size:=OS_ADDR; paraloc^.size:=OS_ADDR;
paraloc^.def:=p.vardef; paraloc^.def:=p.vardef;
{ convert d0-d7/a0-a6 virtual 68k reg patterns into offsets } { convert virtual 68k reg patterns into offsets }
if length(s) = 2 then case length(s) of
begin 2: begin
if (lowercase(s[1]) = 'd') and (s[2] in ['0'..'7']) then { single register }
offset:=(ord(s[2]) - ord('0')) * sizeof(pint) offset_lo:=parse68kregname(1);
else if (lowercase(s[1]) = 'a') and (s[2] in ['0'..'6']) then if offset_lo<0 then
offset:=(ord(s[2]) - ord('0') + 8) * sizeof(pint); message(parser_e_illegal_explicit_paraloc);
if offset < 0 then if tcgsize2size[paracgsize]>4 then
exit; message(parser_e_location_size_too_small);
paraloc^.loc:=LOC_REFERENCE; paraloc^.loc:=LOC_REFERENCE;
paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE); paraloc^.reference.index:=newreg(R_INTREGISTER,RS_R2,R_SUBWHOLE);
paraloc^.reference.offset:=offset; paraloc^.reference.offset:=offset_lo;
end end;
{ 'R12' is special, used internally to support regbase and nobase 5: begin
calling convention } { 64bit register pair, used by AmiSSL 68k for example }
else if lowercase(s)='r12' then offset_hi:=parse68kregname(1);
begin offset_lo:=parse68kregname(4);
paraloc^.loc:=LOC_REGISTER;
paraloc^.register:=NR_R12; if (not (s[3] in [':','-'])) or
end (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 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 } { copy to callee side }
p.paraloc[calleeside].add_location^:=paraloc^; p.paraloc[calleeside].add_location^:=paraloc^;