Przeglądaj źródła

* AIX requires record data that partially fills a register to be
left-aligned. Other targets only require this if the total size of the
parameter was > 8 bytes (this last part used to be ensured by
the ppc64-specific version of a_load_ref_cgpara() that was removed in
r20962)

git-svn-id: trunk@21008 -

Jonas Maebe 13 lat temu
rodzic
commit
d08a17b763
1 zmienionych plików z 15 dodań i 2 usunięć
  1. 15 2
      compiler/powerpc64/cpupara.pas

+ 15 - 2
compiler/powerpc64/cpupara.pas

@@ -299,6 +299,7 @@ var
   paracgsize: tcgsize;
 
   parashift : byte;
+  adjusttail: boolean;
 
 begin
 {$IFDEF extdebug}
@@ -395,8 +396,8 @@ begin
         paraloc^.loc := LOC_VOID;
       end else
         internalerror(2005011310);
+    adjusttail:=paralen>8;
     { can become < 0 for e.g. 3-byte records }
-
     while (paralen > 0) do begin
       paraloc := hp.paraloc[side].add_location;
       { In case of po_delphi_nested_cc, the parent frame pointer
@@ -411,7 +412,19 @@ begin
         { make sure we don't lose whether or not the type is signed }
         if (paracgsize <> OS_NO) and (paradef.typ <> orddef) then
           paracgsize := int_cgsize(paralen);
-        if (paracgsize in [OS_NO,OS_128,OS_S128]) then
+
+        { aix requires that record data (including partial data) stored in
+          parameter registers is left-aligned. Other targets only do this if
+          the total size of the parameter was > 8 bytes. }
+        if (((target_info.system in systems_aix) and
+             (paradef.typ = recorddef)) or
+            adjusttail) and
+           (paralen < sizeof(aint)) then
+          begin
+            paraloc^.shiftval := (sizeof(aint)-paralen)*(-8);
+            paraloc^.size := OS_INT;
+          end
+        else if (paracgsize in [OS_NO,OS_128,OS_S128]) then
           paraloc^.size := OS_INT
         else
           paraloc^.size := paracgsize;