Sfoglia il codice sorgente

* merged macos entry/exit code generation into the general one.

olle 22 anni fa
parent
commit
c2fe8dbd99

+ 133 - 168
compiler/powerpc/cgcpu.pas

@@ -100,11 +100,9 @@ unit cgcpu;
 
       private
 
-        procedure g_stackframe_entry_sysv(list : taasmoutput;localsize : longint);
-        procedure g_return_from_proc_sysv(list : taasmoutput;parasize : aword);
-        procedure g_stackframe_entry_aix(list : taasmoutput;localsize : longint);
-        procedure g_return_from_proc_aix(list : taasmoutput;parasize : aword);
+        (* NOT IN USE: *)
         procedure g_stackframe_entry_mac(list : taasmoutput;localsize : longint);
+        (* NOT IN USE: *)
         procedure g_return_from_proc_mac(list : taasmoutput;parasize : aword);
 
 
@@ -999,43 +997,6 @@ const
 { *********** entry/exit code and address loading ************ }
 
     procedure tcgppc.g_stackframe_entry(list : taasmoutput;localsize : longint);
-
-      begin
-        case target_info.abi of
-          abi_powerpc_macos:
-            g_stackframe_entry_mac(list,localsize);
-          abi_powerpc_sysv:
-            g_stackframe_entry_sysv(list,localsize);
-          abi_powerpc_aix:
-            g_stackframe_entry_aix(list,localsize);
-          else
-            internalerror(2204001);
-        end;
-      end;
-
-    procedure tcgppc.g_return_from_proc(list : taasmoutput;parasize : aword);
-
-      begin
-        case target_info.abi of
-          abi_powerpc_macos:
-            g_return_from_proc_mac(list,parasize);
-          abi_powerpc_sysv:
-            g_return_from_proc_sysv(list,parasize);
-          abi_powerpc_aix:
-            g_return_from_proc_aix(list,parasize);
-          else
-            internalerror(2204001);
-        end;
-      end;
-
-
-    procedure tcgppc.g_stackframe_entry_aix(list : taasmoutput;localsize : longint);
-      begin
-         g_stackframe_entry_sysv(list,localsize);
-      end;
-
-
-    procedure tcgppc.g_stackframe_entry_sysv(list : taasmoutput;localsize : longint);
      { generated the entry code of a procedure/function. Note: localsize is the }
      { sum of the size necessary for local variables and the maximum possible   }
      { combined size of ALL the parameters of a procedure called by the current }
@@ -1102,12 +1063,32 @@ const
                r.enum:=R_INTREGISTER;
                r.number:=NR_R0;
                list.concat(taicpu.op_reg(A_MFLR,r));
-               { ... in caller's rframe }
-               reference_reset_base(href,rsp,4);
+               { ... in caller's frame }
+               case target_info.abi of
+                 abi_powerpc_aix:
+                   reference_reset_base(href,rsp,LA_LR_AIX);
+                 abi_powerpc_sysv:
+                   reference_reset_base(href,rsp,LA_LR_SYSV);
+               end;
                list.concat(taicpu.op_reg_ref(A_STW,r,href));
                a_reg_dealloc(list,r);
             end;
 
+        { save the CR if necessary in callers frame. }
+        if not (po_assembler in current_procinfo.procdef.procoptions) then
+          if target_info.abi = abi_powerpc_aix then
+            if false then { Not needed at the moment. }
+              begin
+                r.enum:=R_INTREGISTER;
+                r.number:=NR_R0;
+                a_reg_alloc(list,r);
+                r2.enum:=R_CR;
+                list.concat(taicpu.op_reg_reg(A_MFSPR,r,r2));
+                reference_reset_base(href,rsp,LA_CR_AIX);
+                list.concat(taicpu.op_reg_ref(A_STW,r,href));
+                a_reg_dealloc(list,r);
+              end;
+
         { !!! always allocate space for all registers for now !!! }
         if not (po_assembler in current_procinfo.procdef.procoptions) then
 {        if usesfpr or usesgpr then }
@@ -1281,14 +1262,7 @@ const
           end;
       end;
 
-
-    procedure tcgppc.g_return_from_proc_aix(list : taasmoutput;parasize : aword);
-      begin
-         g_return_from_proc_sysv(list,parasize);
-      end;
-
-
-    procedure tcgppc.g_return_from_proc_sysv(list : taasmoutput;parasize : aword);
+    procedure tcgppc.g_return_from_proc(list : taasmoutput;parasize : aword);
 
       var
          regcounter,firstregfpu,firstreggpr: TRegister;
@@ -1357,7 +1331,7 @@ const
                        a_loadfpu_ref_reg(list,OS_F64,href,regcounter);
                        dec(href.offset,8);
                      end;
-                   inc(href.offset,4);
+                 inc(href.offset,4);
                end
              else
                reference_reset_base(href,r2,-4);
@@ -1401,6 +1375,7 @@ const
           end;
 *)
 
+
         { if we didn't generate the return code, we've to do it now }
         if genret then
           begin
@@ -1410,16 +1385,39 @@ const
              a_op_const_reg(list,OP_ADD,OS_ADDR,tppcprocinfo(current_procinfo).localsize,r);
              { load link register? }
              if not (po_assembler in current_procinfo.procdef.procoptions) then
-               if (pi_do_call in current_procinfo.flags) then
-                 begin
-                    r.enum:=R_INTREGISTER;
-                    r.number:=NR_STACK_POINTER_REG;
-                    reference_reset_base(href,r,4);
-                    r.enum:=R_INTREGISTER;
-                    r.number:=NR_R0;
-                    list.concat(taicpu.op_reg_ref(A_LWZ,r,href));
-                    list.concat(taicpu.op_reg(A_MTLR,r));
-                 end;
+               begin
+                 if (pi_do_call in current_procinfo.flags) then
+                   begin
+                      r.enum:=R_INTREGISTER;
+                      r.number:=NR_STACK_POINTER_REG;
+                      case target_info.abi of
+                        abi_powerpc_aix:
+                          reference_reset_base(href,r,LA_LR_AIX);
+                        abi_powerpc_sysv:
+                          reference_reset_base(href,r,LA_LR_SYSV);
+                      end;
+                      r.enum:=R_INTREGISTER;
+                      r.number:=NR_R0;
+                      list.concat(taicpu.op_reg_ref(A_LWZ,r,href));
+                      list.concat(taicpu.op_reg(A_MTLR,r));
+                   end;
+
+                 { restore the CR if necessary from callers frame}
+                 if target_info.abi = abi_powerpc_aix then
+                   if false then { Not needed at the moment. }
+                     begin
+                      r.enum:=R_INTREGISTER;
+                      r.number:=NR_STACK_POINTER_REG;
+                      reference_reset_base(href,r,LA_CR_AIX);
+                      r.enum:=R_INTREGISTER;
+                      r.number:=NR_R0;
+                      list.concat(taicpu.op_reg_ref(A_LWZ,r,href));
+                      r2.enum:=R_CR;
+                      list.concat(taicpu.op_reg_reg(A_MTSPR,r,r2));
+                      a_reg_dealloc(list,r);
+                     end;
+               end;
+
              list.concat(taicpu.op_none(A_BLR));
           end;
       end;
@@ -1584,6 +1582,8 @@ const
 
 
     procedure tcgppc.g_stackframe_entry_mac(list : taasmoutput;localsize : longint);
+ (* NOT IN USE *)
+
  { generated the entry code of a procedure/function. Note: localsize is the }
  { sum of the size necessary for local variables and the maximum possible   }
  { combined size of ALL the parameters of a procedure called by the current }
@@ -1626,7 +1626,7 @@ const
         a_reg_alloc(list,r);
         r2.enum:=R_CR;
         list.concat(taicpu.op_reg_reg(A_MFSPR,r,r2));
-        reference_reset_base(href,rsp,LA_CR);
+        reference_reset_base(href,rsp,LA_CR_AIX);
         list.concat(taicpu.op_reg_ref(A_STW,r,href));
         a_reg_dealloc(list,r);
 
@@ -1679,6 +1679,7 @@ const
       end;
 
     procedure tcgppc.g_return_from_proc_mac(list : taasmoutput;parasize : aword);
+ (* NOT IN USE *)
 
       var
         regcounter: TRegister;
@@ -1701,7 +1702,7 @@ const
 
         { restore the CR if necessary from callers frame
             ( !!! always done currently ) }
-        reference_reset_base(href,rsp,LA_CR);
+        reference_reset_base(href,rsp,LA_CR_AIX);
         r.enum:=R_INTREGISTER;
         r.number:=NR_R0;
         list.concat(taicpu.op_reg_ref(A_LWZ,r,href));
@@ -1763,37 +1764,32 @@ const
                      reference_reset(tmpref);
                      tmpref.offset := ref2.offset;
                      tmpref.symbol := ref2.symbol;
-                     tmpref.symaddr := refs_full;
                      tmpref.base.number := NR_NO;
                      r2.enum:=R_INTREGISTER;
                      r2.number:=NR_RTOC;
                      list.concat(taicpu.op_reg_reg_ref(A_ADDI,r,r2,tmpref));
-                     if ref2.base.number <> NR_NO then
-                       list.concat(taicpu.op_reg_reg_reg(A_ADD,r,r,ref2.base));
                    end
                  else
                    begin
                      reference_reset(tmpref);
                      tmpref.symbol := ref2.symbol;
                      tmpref.offset := 0;
-                     tmpref.symaddr := refs_full;
                      tmpref.base.enum := R_INTREGISTER;
                      tmpref.base.number := NR_RTOC;
                      list.concat(taicpu.op_reg_ref(A_LWZ,r,tmpref));
 
-                     if ref2.base.number <> NR_NO then
-                       begin
-                         list.concat(taicpu.op_reg_reg_reg(A_ADD,r,r,ref2.base));
-                       end;
                      if ref2.offset <> 0 then
                        begin
                          reference_reset(tmpref);
                          tmpref.offset := ref2.offset;
-                         tmpref.symaddr := refs_full;
                          tmpref.base:= r;
                          list.concat(taicpu.op_reg_ref(A_LA,r,tmpref));
                        end;
                    end;
+
+                 if ref2.base.number <> NR_NO then
+                   list.concat(taicpu.op_reg_reg_reg(A_ADD,r,r,ref2.base));
+
                  //list.concat(tai_comment.create(strpnew('*** a_loadaddr_ref_reg')));
                end
              else
@@ -2430,112 +2426,73 @@ const
 
       var
         tmpreg: tregister;
+        tmpregUsed: Boolean;
         tmpref: treference;
-        r : Tregister;
+        largeOffset: Boolean;
 
       begin
         tmpreg.number := NR_NO;
-        if assigned(ref.symbol) or
-           (cardinal(ref.offset-low(smallint)) >
-            high(smallint)-low(smallint)) then
+
+        if target_info.system = system_powerpc_macos then
           begin
-            if target_info.system = system_powerpc_macos then
-              begin
-                if ref.base.number <> NR_NO then
-                  begin
-                    if macos_direct_globals then
-                      begin
-                        {Generates
-                          add   tempreg, ref.base, RTOC
-                          op    reg, symbolplusoffset, tempreg
-                        which is eqvivalent to the more comprehensive
-                          addi  tempreg, RTOC, symbolplusoffset
-                          add   tempreg, ref.base, tempreg
-                          op    reg, tempreg
-                        but which saves one instruction.}
+            largeOffset:= (cardinal(ref.offset-low(smallint)) >
+                  high(smallint)-low(smallint));
 
 {$ifndef newra}
-                        tmpreg := get_scratch_reg_address(list);
-{$else newra}
-                        tmpreg := rg.getregisterint(list,OS_ADDR);
-{$endif newra}
-                        reference_reset(tmpref);
-                        tmpref.symbol := ref.symbol;
-                        tmpref.offset := ref.offset;
-                        tmpref.symaddr := refs_full;
-                        tmpref.base:= tmpreg;
-
-                        r.enum:=R_INTREGISTER;
-                        r.number:=NR_RTOC;
-                        list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,
-                            ref.base,r));
-                        list.concat(taicpu.op_reg_ref(op,reg,tmpref));
-                      end
-                    else
-                      begin
-{$ifndef newra}
-                        tmpreg := get_scratch_reg_address(list);
+            tmpreg := get_scratch_reg_address(list);
 {$else newra}
-                        tmpreg := rg.getregisterint(list,OS_ADDR);
+            tmpreg := rg.getregisterint(list,OS_ADDR);
 {$endif newra}
-                        reference_reset(tmpref);
-                        tmpref.symbol := ref.symbol;
-                        tmpref.offset := 0;
-                        tmpref.symaddr := refs_full;
-                        tmpref.base.enum:= R_INTREGISTER;
-                        tmpref.base.number:= NR_RTOC;
-                        list.concat(taicpu.op_reg_ref(A_LWZ,tmpreg,tmpref));
-                        list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,
-                            ref.base,tmpreg));
-
-                        reference_reset(tmpref);
-                        tmpref.offset := ref.offset;
-                        tmpref.symaddr := refs_full;
-                        tmpref.base:= tmpreg;
-                        list.concat(taicpu.op_reg_ref(op,reg,tmpref));
+            tmpregUsed:= false;
 
-                      end;
+            if assigned(ref.symbol) then
+              begin //Load symbol's value
+                reference_reset(tmpref);
+                tmpref.symbol := ref.symbol;
+                tmpref.base.enum:= R_INTREGISTER;
+                tmpref.base.number:= NR_RTOC;
+                if macos_direct_globals then
+                  list.concat(taicpu.op_reg_ref(A_LA,tmpreg,tmpref))
+                else
+                  list.concat(taicpu.op_reg_ref(A_LWZ,tmpreg,tmpref));
+                tmpregUsed:= true;
+              end;
 
-                    //list.concat(tai_comment.create(strpnew('**** a_load_store 1')));
-                  end
+            if largeOffset then
+              begin //Add hi part of offset
+                reference_reset(tmpref);
+                tmpref.offset := Hi(ref.offset);
+                if tmpregUsed then
+                  list.concat(taicpu.op_reg_reg_ref(A_ADDIS,tmpreg,
+                    tmpreg,tmpref))
                 else
-                  begin
-                    if macos_direct_globals then
-                      begin
-                        reference_reset(tmpref);
-                        tmpref.symbol := ref.symbol;
-                        tmpref.offset := ref.offset;
-                        tmpref.symaddr := refs_full;
-                        tmpref.base.enum:= R_INTREGISTER;
-                        tmpref.base.number:= NR_RTOC;
-                        list.concat(taicpu.op_reg_ref(op,reg,tmpref));
-                      end
-                    else
-                      begin
-{$ifndef newra}
-                        tmpreg := get_scratch_reg_address(list);
-{$else newra}
-                        tmpreg := rg.getregisterint(list,OS_ADDR);
-{$endif newra}
-                        reference_reset(tmpref);
-                        tmpref.symbol := ref.symbol;
-                        tmpref.offset := 0;
-                        tmpref.symaddr := refs_full;
-                        tmpref.base.enum:= R_INTREGISTER;
-                        tmpref.base.number:= NR_RTOC;
-                        list.concat(taicpu.op_reg_ref(A_LWZ,tmpreg,tmpref));
-
-                        reference_reset(tmpref);
-                        tmpref.offset := ref.offset;
-                        tmpref.symaddr := refs_full;
-                        tmpref.base:= tmpreg;
-                        list.concat(taicpu.op_reg_ref(op,reg,tmpref));
+                  list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,tmpref));
+                tmpregUsed:= true;
+              end;
 
-                      end;
-                    //list.concat(tai_comment.create(strpnew('*** a_load_store 2')));
-                  end;
+            if tmpregUsed then
+              begin
+                //Add content of base register
+                if ref.base.number <> NR_NO then
+                  list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,
+                    ref.base,tmpreg));
+
+                //Make ref ready to be used by op
+                ref.symbol:= nil;
+                ref.base:= tmpreg;
+                if largeOffset then
+                  ref.offset := Lo(ref.offset);
+                list.concat(taicpu.op_reg_ref(op,reg,ref));
+                //list.concat(tai_comment.create(strpnew('*** a_load_store indirect global')));
               end
             else
+              list.concat(taicpu.op_reg_ref(op,reg,ref));
+          end
+        else {if target_info.system <> system_powerpc_macos}
+          begin
+            if assigned(ref.symbol) or
+               (cardinal(ref.offset-low(smallint)) >
+                high(smallint)-low(smallint)) then
               begin
 {$ifndef newra}
                 tmpreg := get_scratch_reg_address(list);
@@ -2555,9 +2512,11 @@ const
                 ref.symaddr := refs_l;
                 list.concat(taicpu.op_reg_ref(op,reg,ref));
               end
-          end
-        else
-          list.concat(taicpu.op_reg_ref(op,reg,ref));
+            else
+              list.concat(taicpu.op_reg_ref(op,reg,ref));
+          end;
+
+
         if (tmpreg.number <> NR_NO) then
 {$ifndef newra}
           free_scratch_reg(list,tmpreg);
@@ -2713,7 +2672,13 @@ begin
 end.
 {
   $Log$
-  Revision 1.116  2003-07-23 11:02:23  jonas
+  Revision 1.118  2003-08-08 15:50:45  olle
+    * merged macos entry/exit code generation into the general one.
+
+  Revision 1.117  2002/10/01 05:24:28  olle
+    * made a_load_store more robust and to accept large offsets and cleaned up code
+
+  Revision 1.116  2003/07/23 11:02:23  jonas
     * don't use rg.getregisterint() anymore in g_stackframe_entry_*, because
       the register colouring has already occurred then, use a hard-coded
       register instead

+ 11 - 6
compiler/powerpc/cpubase.pas

@@ -707,16 +707,18 @@ uses
                             CPU Dependent Constants
 *****************************************************************************}
 
-      LinkageAreaSize = 24;
+      LinkageAreaSizeAIX = 24;
+      LinkageAreaSizeSYSV = 8;
       { offset in the linkage area for the saved stack pointer }
       LA_SP = 0;
       { offset in the linkage area for the saved conditional register}
-      LA_CR = 4;
+      LA_CR_AIX = 4;
       { offset in the linkage area for the saved link register}
-      LA_LR = 8;
+      LA_LR_AIX = 8;
+      LA_LR_SYSV = 4;
       { offset in the linkage area for the saved RTOC register}
-      LA_RTOC = 20;
-      
+      LA_RTOC_AIX = 20;
+
       PARENT_FRAMEPOINTER_OFFSET = 12;
 
 {*****************************************************************************
@@ -886,7 +888,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.62  2003-07-23 11:00:09  jonas
+  Revision 1.63  2003-08-08 15:51:16  olle
+    * merged macos entry/exit code generation into the general one.
+
+  Revision 1.62  2003/07/23 11:00:09  jonas
     * "lastsaveintreg" is RS_R31 instead of RS_R27 with -dnewra, because
       there are no scratch regs anymore
 

+ 11 - 3
compiler/powerpc/cpupi.pas

@@ -49,7 +49,7 @@ unit cpupi;
   implementation
 
     uses
-       globtype,globals,
+       globtype,globals,systems,
        cpubase,
        aasmtai,
        tgobj,
@@ -69,7 +69,12 @@ unit cpupi;
       begin
          if not(po_assembler in procdef.procoptions) then
            begin
-             ofs:=align(maxpushedparasize+LinkageAreaSize,16);
+             case target_info.abi of
+               abi_powerpc_aix:
+                 ofs:=align(maxpushedparasize+LinkageAreaSizeAIX,16);
+               abi_powerpc_sysv:
+                 ofs:=align(maxpushedparasize+LinkageAreaSizeSYSV,16);
+             end;
              inc(procdef.parast.address_fixup,ofs);
              // inc(selfpointer_offset,ofs);
              // inc(vmtpointer_offset,ofs);
@@ -114,7 +119,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.24  2003-07-06 20:25:03  jonas
+  Revision 1.25  2003-08-08 15:52:50  olle
+    * merged macos entry/exit code generation into the general one.
+
+  Revision 1.24  2003/07/06 20:25:03  jonas
     * fixed ppc compiler
 
   Revision 1.23  2003/06/13 21:19:32  peter

+ 5 - 2
compiler/systems.pas

@@ -150,7 +150,7 @@ interface
        );
 
        tabi = (abi_default
-            ,abi_powerpc_sysv,abi_powerpc_aix,abi_powerpc_macos
+            ,abi_powerpc_sysv,abi_powerpc_aix
        );
 
 {*****************************************************************************
@@ -695,7 +695,10 @@ finalization
 end.
 {
   $Log$
-  Revision 1.66  2003-07-21 11:52:57  florian
+  Revision 1.67  2003-08-08 15:49:24  olle
+    * merged macos entry/exit code generation into the general one.
+
+  Revision 1.66  2003/07/21 11:52:57  florian
     * very basic stuff for the arm
 
   Revision 1.65  2003/05/31 16:17:27  marco

+ 9 - 2
compiler/systems/i_macos.pas

@@ -88,7 +88,8 @@ unit i_macos;
             heapsize     : 256*1024;
             stacksize    : 262144;
             DllScanSupported:false;
-            use_function_relative_addresses : true
+            use_function_relative_addresses : true;
+            abi : abi_powerpc_aix;
           );
 
   implementation
@@ -102,7 +103,13 @@ initialization
 end.
 {
   $Log$
-  Revision 1.9  2003-06-18 10:19:07  olle
+  Revision 1.11  2003-08-08 15:54:01  olle
+    * merged macos entry/exit code generation into the general one.
+
+  Revision 1.10  2002/08/18 17:10:15  olle
+    + abi_powerpc_macos added to TSystemInfo
+
+  Revision 1.9  2003/06/18 10:19:07  olle
     * changed .p to .pas to make the compiler compile
 
   Revision 1.8  2003/01/13 22:15:58  florian