Browse Source

* ppc64/linux specific compiler patches to improve C parameter passing compatibility
* passes tcalext3 and tcalext4 test programs

git-svn-id: trunk@1984 -

tom_at_work 19 years ago
parent
commit
57b7b72ca4
3 changed files with 37 additions and 18 deletions
  1. 3 6
      compiler/powerpc64/cgcpu.pas
  2. 22 12
      compiler/powerpc64/cpupara.pas
  3. 12 0
      compiler/powerpc64/nppccal.pas

+ 3 - 6
compiler/powerpc64/cgcpu.pas

@@ -373,7 +373,7 @@ begin
               location^.register)
               location^.register)
           else
           else
           {$IFDEF extdebug}
           {$IFDEF extdebug}
-            list.concat(tai_comment.create(strpnew('a_param_ref with OS_NO')));
+            list.concat(tai_comment.create(strpnew('a_param_ref with OS_NO, sizeleft ' + inttostr(sizeleft))));
           {$ENDIF extdebug}
           {$ENDIF extdebug}
 
 
             { load non-integral sized memory location into register. This 
             { load non-integral sized memory location into register. This 
@@ -430,15 +430,12 @@ begin
                 { the block is > 8 bytes, so we have to store any bytes not
                 { the block is > 8 bytes, so we have to store any bytes not
                  a multiple of the register size beginning with the MSB }
                  a multiple of the register size beginning with the MSB }
                 adjusttail := true;
                 adjusttail := true;
-            end; 
-(*          
-            { Comment this in (for gcc compat) and be prepared for a whole bunch of errors :/ }
-            
+            end;           
             if (adjusttail) and (sizeleft < tcgsize2size[OS_INT]) then
             if (adjusttail) and (sizeleft < tcgsize2size[OS_INT]) then
               a_op_const_reg(list, OP_SHL, OS_INT, 
               a_op_const_reg(list, OP_SHL, OS_INT, 
                 (tcgsize2size[OS_INT] - sizeleft) * tcgsize2size[OS_INT], 
                 (tcgsize2size[OS_INT] - sizeleft) * tcgsize2size[OS_INT], 
                 location^.register);
                 location^.register);
-*)
+
         end;
         end;
       LOC_REFERENCE:
       LOC_REFERENCE:
         begin
         begin

+ 22 - 12
compiler/powerpc64/cpupara.pas

@@ -264,6 +264,7 @@ function tppcparamanager.create_paraloc_info_intern(p: tabstractprocdef; side:
   tcallercallee; paras: tparalist;
   tcallercallee; paras: tparalist;
   var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset:
   var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset:
   aword; isVararg : boolean): longint;
   aword; isVararg : boolean): longint;
+
 var
 var
   stack_offset: longint;
   stack_offset: longint;
   paralen: aint;
   paralen: aint;
@@ -275,6 +276,8 @@ var
   loc: tcgloc;
   loc: tcgloc;
   paracgsize: tcgsize;
   paracgsize: tcgsize;
 
 
+  parashift : byte;
+
 begin
 begin
 {$IFDEF extdebug}
 {$IFDEF extdebug}
   if po_explicitparaloc in p.procoptions then
   if po_explicitparaloc in p.procoptions then
@@ -288,13 +291,13 @@ begin
   stack_offset := cur_stack_offset;
   stack_offset := cur_stack_offset;
 
 
   for i := 0 to paras.count - 1 do begin
   for i := 0 to paras.count - 1 do begin
+    parashift := 0;
+
     hp := tparavarsym(paras[i]);
     hp := tparavarsym(paras[i]);
     paradef := hp.vartype.def;
     paradef := hp.vartype.def;
-    { Syscall for Morphos can have already a paraloc set }
+    { Syscall for Morphos can have already a paraloc set; not supported on ppc64 }
     if (vo_has_explicit_paraloc in hp.varoptions) then begin
     if (vo_has_explicit_paraloc in hp.varoptions) then begin
-      if not (vo_is_syscall_lib in hp.varoptions) then
-        internalerror(200412153);
-      continue;
+      internalerror(200412153);
     end;
     end;
     hp.paraloc[side].reset;
     hp.paraloc[side].reset;
     { currently only support C-style array of const }
     { currently only support C-style array of const }
@@ -327,8 +330,8 @@ begin
         { non-composite (not array or record), it must be  }
         { non-composite (not array or record), it must be  }
         { passed according to the rules of that type.       }
         { passed according to the rules of that type.       }
         if (trecorddef(hp.vartype.def).symtable.symindex.count = 1) and
         if (trecorddef(hp.vartype.def).symtable.symindex.count = 1) and
-          (not trecorddef(hp.vartype.def).isunion) and
-          (tabstractvarsym(trecorddef(hp.vartype.def).symtable.symindex.search(1)).vartype.def.deftype = floatdef) then begin
+          (not trecorddef(hp.vartype.def).isunion)  and
+          (tabstractvarsym(trecorddef(hp.vartype.def).symtable.symindex.search(1)).vartype.def.deftype in [orddef, enumdef, floatdef])  then begin
           paradef :=
           paradef :=
             tabstractvarsym(trecorddef(hp.vartype.def).symtable.symindex.search(1)).vartype.def;
             tabstractvarsym(trecorddef(hp.vartype.def).symtable.symindex.search(1)).vartype.def;
           loc := getparaloc(paradef);
           loc := getparaloc(paradef);
@@ -336,6 +339,8 @@ begin
         end else begin
         end else begin
           loc := LOC_REGISTER;
           loc := LOC_REGISTER;
           paracgsize := int_cgsize(paralen);
           paracgsize := int_cgsize(paralen);
+          if (paralen in [3,5,6,7]) then
+            parashift := (tcgsize2size[paracgsize]-paralen) * 8;
         end;
         end;
       end else begin
       end else begin
         loc := getparaloc(paradef);
         loc := getparaloc(paradef);
@@ -369,17 +374,22 @@ begin
       end else
       end else
         internalerror(2005011310);
         internalerror(2005011310);
     { can become < 0 for e.g. 3-byte records }
     { can become < 0 for e.g. 3-byte records }
+
     while (paralen > 0) do begin
     while (paralen > 0) do begin
       paraloc := hp.paraloc[side].add_location;
       paraloc := hp.paraloc[side].add_location;
       if (loc = LOC_REGISTER) and (nextintreg <= RS_R10) then begin
       if (loc = LOC_REGISTER) and (nextintreg <= RS_R10) then begin
         paraloc^.loc := loc;
         paraloc^.loc := loc;
-        { make sure we don't lose whether or not the type is signed }
-        if (paradef.deftype <> orddef) then
-          paracgsize := int_cgsize(paralen);
-        if (paracgsize in [OS_NO]) then
-          paraloc^.size := OS_INT
+        paraloc^.shiftval := parashift;
+
+        if (paracgsize <> OS_NO) then
+          { make sure we don't lose whether or not the type is signed }
+          if (paradef.deftype <> orddef) then
+            paraloc^.size := int_cgsize(paralen)
+          else
+            paraloc^.size := paracgsize
         else
         else
-          paraloc^.size := paracgsize;
+          paraloc^.size := OS_INT;
+
         paraloc^.register := newreg(R_INTREGISTER, nextintreg, R_SUBNONE);
         paraloc^.register := newreg(R_INTREGISTER, nextintreg, R_SUBNONE);
         inc(nextintreg);
         inc(nextintreg);
         dec(paralen, tcgsize2size[paraloc^.size]);
         dec(paralen, tcgsize2size[paraloc^.size]);

+ 12 - 0
compiler/powerpc64/nppccal.pas

@@ -29,7 +29,12 @@ uses
   symdef, node, ncal, ncgcal;
   symdef, node, ncal, ncgcal;
 
 
 type
 type
+
+  tppccallparanode = class(tcgcallparanode)
+  end;
+
   tppccallnode = class(tcgcallnode)
   tppccallnode = class(tcgcallnode)
+    procedure do_syscall; override;
   end;
   end;
 
 
 implementation
 implementation
@@ -44,8 +49,15 @@ uses
   ncgutil, cgutils, cgobj, tgobj, regvars, rgobj, rgcpu,
   ncgutil, cgutils, cgobj, tgobj, regvars, rgobj, rgcpu,
   cgcpu, cpupi, procinfo;
   cgcpu, cpupi, procinfo;
 
 
+procedure tppccallnode.do_syscall;
+begin
+  { no MorphOS style syscalls supported. Only implemented to avoid abstract 
+   method not implemented compiler warning. }
+  internalerror(2005120401);
+end;
 
 
 begin
 begin
+  ccallparanode:=tppccallparanode;
   ccallnode := tppccallnode;
   ccallnode := tppccallnode;
 end.
 end.