Browse Source

* fixed passing of fpu paras on the stack
* fixed number of fpu parameters passed in registers
* skip corresponding integer registers when using an fpu register for a
parameter under the AIX abi

Jonas Maebe 21 years ago
parent
commit
fab51678da
2 changed files with 74 additions and 20 deletions
  1. 38 12
      compiler/powerpc/cgcpu.pas
  2. 36 8
      compiler/powerpc/cpupara.pas

+ 38 - 12
compiler/powerpc/cgcpu.pas

@@ -1030,12 +1030,12 @@ const
          href,href2 : treference;
          href,href2 : treference;
          usesfpr,usesgpr,gotgot : boolean;
          usesfpr,usesgpr,gotgot : boolean;
          parastart : aint;
          parastart : aint;
-//         r,r2,rsp:Tregister;
          l : tasmlabel;
          l : tasmlabel;
          regcounter2, firstfpureg: Tsuperregister;
          regcounter2, firstfpureg: Tsuperregister;
          hp: tparaitem;
          hp: tparaitem;
          cond : tasmcond;
          cond : tasmcond;
          instr : taicpu;
          instr : taicpu;
+         size: tcgsize;
 
 
       begin
       begin
         { CR and LR only have to be saved in case they are modified by the current }
         { CR and LR only have to be saved in case they are modified by the current }
@@ -1215,23 +1215,43 @@ const
                               { we can't use functions here which allocate registers (FK)
                               { we can't use functions here which allocate registers (FK)
                                cg.a_load_ref_ref(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,href);
                                cg.a_load_ref_ref(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,href);
                               }
                               }
-                              cg.a_load_ref_reg(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,NR_R0);
-                              cg.a_load_reg_ref(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,NR_R0,href);
+                              case hp.paraloc[calleeside].size of
+                                OS_F32:
+                                  size := OS_32;
+                                OS_64,OS_S64:
+                                  size := OS_F64;
+                                else
+                                  size := hp.paraloc[calleeside].size;
+                              end;
+                              case size of
+                                OS_8,OS_S8,OS_16,OS_S16,OS_32,OS_S32:
+                                  begin
+                                    cg.a_load_ref_reg(list,size,size,href2,NR_R0);
+                                    cg.a_load_reg_ref(list,size,size,NR_R0,href);
+                                  end;
+                                OS_F64:
+                                  begin
+                                    cg.a_loadfpu_ref_reg(list,size,href2,NR_F0);
+                                    cg.a_loadfpu_reg_ref(list,size,NR_F0,href);
+                                  end;
+                                else
+                                  internalerror(2004070910);
+                              end;
                             end;
                             end;
                           LOC_CREGISTER:
                           LOC_CREGISTER:
                             begin
                             begin
                               reference_reset_base(href2,NR_R12,hp.paraloc[callerside].reference.offset);
                               reference_reset_base(href2,NR_R12,hp.paraloc[callerside].reference.offset);
                               cg.a_load_ref_reg(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,tvarsym(hp.parasym).localloc.register);
                               cg.a_load_ref_reg(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,tvarsym(hp.parasym).localloc.register);
                             end;
                             end;
+                          LOC_CFPUREGISTER:
+                            begin
+                              reference_reset_base(href2,NR_R12,hp.paraloc[callerside].reference.offset);
+                              cg.a_loadfpu_ref_reg(list,hp.paraloc[calleeside].size,href2,tvarsym(hp.parasym).localloc.register);
+                            end;
+                          else
+                            internalerror(2004070911);
                         end;
                         end;
-                      end
-{$ifdef dummy}
-                    else if (hp.calleeparaloc.loc in [LOC_REGISTER,LOC_CREGISTER]) then
-                      begin
-                        rg.getexplicitregisterint(list,hp.calleeparaloc.register);
-                      end
-{$endif dummy}
-                      ;
+                      end;
                     hp := tparaitem(hp.next);
                     hp := tparaitem(hp.next);
                   end;
                   end;
               end;
               end;
@@ -2396,7 +2416,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.174  2004-07-01 18:00:00  jonas
+  Revision 1.175  2004-07-09 21:45:24  jonas
+    * fixed passing of fpu paras on the stack
+    * fixed number of fpu parameters passed in registers
+    * skip corresponding integer registers when using an fpu register for a
+      parameter under the AIX abi
+
+  Revision 1.174  2004/07/01 18:00:00  jonas
     * fixed several errors due to aword -> aint change
     * fixed several errors due to aword -> aint change
 
 
   Revision 1.173  2004/06/20 08:55:32  florian
   Revision 1.173  2004/06/20 08:55:32  florian

+ 36 - 8
compiler/powerpc/cpupara.pas

@@ -269,7 +269,7 @@ unit cpupara;
                var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
                var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
       var
       var
          stack_offset: aword;
          stack_offset: aword;
-         nextintreg,nextfloatreg,nextmmreg : tsuperregister;
+         nextintreg,nextfloatreg,nextmmreg, maxfpureg : tsuperregister;
          paradef : tdef;
          paradef : tdef;
          paraloc : tparalocation;
          paraloc : tparalocation;
          hp : tparaitem;
          hp : tparaitem;
@@ -302,6 +302,13 @@ unit cpupara;
          nextfloatreg := curfloatreg;
          nextfloatreg := curfloatreg;
          nextmmreg := curmmreg;
          nextmmreg := curmmreg;
          stack_offset := cur_stack_offset;
          stack_offset := cur_stack_offset;
+         case target_info.abi of
+           abi_powerpc_aix:
+             maxfpureg := RS_F13;
+           abi_powerpc_sysv:
+             maxfpureg := RS_F8;
+           else internalerror(2004070912);
+         end;
 
 
          hp:=firstpara;
          hp:=firstpara;
          while assigned(hp) do
          while assigned(hp) do
@@ -373,19 +380,34 @@ unit cpupara;
                  LOC_FPUREGISTER:
                  LOC_FPUREGISTER:
                    begin
                    begin
                       paraloc.size:=def_cgsize(paradef);
                       paraloc.size:=def_cgsize(paradef);
-                      if nextfloatreg<=RS_F10 then
+                      if nextfloatreg<=maxfpureg then
                         begin
                         begin
                            paraloc.loc:=LOC_FPUREGISTER;
                            paraloc.loc:=LOC_FPUREGISTER;
                            paraloc.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE);
                            paraloc.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE);
                            inc(nextfloatreg);
                            inc(nextfloatreg);
-                           if target_info.abi=abi_powerpc_aix then
-                             inc(stack_offset,8);
                         end
                         end
                       else
                       else
                          begin
                          begin
-                            {!!!!!!!}
-                            paraloc.size:=def_cgsize(paradef);
-                            internalerror(2002071004);
+                            paraloc.loc:=LOC_REFERENCE;
+                            paraloc.reference.index:=NR_STACK_POINTER_REG;
+                            paraloc.reference.offset:=stack_offset;
+                        end;
+                      if target_info.abi=abi_powerpc_aix then
+                        begin
+                          if paraloc.size = OS_F32 then
+                            begin
+                              inc(stack_offset,4);
+                              if (nextintreg < RS_R11) then
+                                inc(nextintreg);
+                            end
+                          else
+                            begin
+                              inc(stack_offset,8);
+                              if (nextintreg < RS_R10) then
+                                inc(nextintreg,2)
+                              else
+                                nextintreg := RS_R11;
+                            end;
                         end;
                         end;
                    end;
                    end;
                  LOC_REFERENCE:
                  LOC_REFERENCE:
@@ -533,7 +555,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.64  2004-07-01 18:00:37  jonas
+  Revision 1.65  2004-07-09 21:45:24  jonas
+    * fixed passing of fpu paras on the stack
+    * fixed number of fpu parameters passed in registers
+    * skip corresponding integer registers when using an fpu register for a
+      parameter under the AIX abi
+
+  Revision 1.64  2004/07/01 18:00:37  jonas
     * fix for broken TP-style constructor handling in the compiler
     * fix for broken TP-style constructor handling in the compiler
 
 
   Revision 1.63  2004/06/20 08:55:32  florian
   Revision 1.63  2004/06/20 08:55:32  florian