Explorar el Código

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 -
Károly Balogh hace 4 años
padre
commit
f489858855
Se han modificado 4 ficheros con 537 adiciones y 471 borrados
  1. 11 2
      compiler/msg/errore.msg
  2. 6 2
      compiler/msgidx.inc
  3. 453 442
      compiler/msgtxt.inc
  4. 67 25
      compiler/powerpc/cpupara.pas

+ 11 - 2
compiler/msg/errore.msg

@@ -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}
 %

+ 6 - 2
compiler/msgidx.inc

@@ -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
   );

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 453 - 442
compiler/msgtxt.inc


+ 67 - 25
compiler/powerpc/cpupara.pas

@@ -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);
-
-                  if offset < 0 then
-                    exit;
-
-                  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
+              { 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 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_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^;

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio