Selaa lähdekoodia

* removed a_call_ref

peter 22 vuotta sitten
vanhempi
commit
a561878746
1 muutettua tiedostoa jossa 82 lisäystä ja 150 poistoa
  1. 82 150
      compiler/ncgcal.pas

+ 82 - 150
compiler/ncgcal.pas

@@ -2,7 +2,7 @@
     $Id$
     Copyright (c) 1998-2002 by Florian Klaempfl
 
-    Generate i386 assembler for in call nodes
+    Generate assembler for call nodes
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -134,8 +134,8 @@ implementation
              if paramanager.push_addr_param(vs_value,left.resulttype.def,calloption) then
                begin
                  inc(pushedparasize,POINTER_SIZE);
-                 cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
                  location_release(exprasmlist,left.location);
+                 cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
                end
              else
                push_value_para(exprasmlist,left,vs_value,calloption,alignment,tempparaloc);
@@ -153,8 +153,8 @@ implementation
                     internalerror(200305071);
 
                   inc(pushedparasize,POINTER_SIZE);
-                  cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
                   location_release(exprasmlist,left.location);
+                  cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
                end
              else
                begin
@@ -180,64 +180,52 @@ implementation
               if (left.nodetype=addrn) and
                  (not(nf_procvarload in left.flags)) then
                 begin
-                  cg.a_param_loc(exprasmlist,left.location,tempparaloc);
                   location_release(exprasmlist,left.location);
+                  cg.a_param_loc(exprasmlist,left.location,tempparaloc);
                 end
               else
                 begin
                    if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
                      internalerror(200304235);
 
-                   cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
                    location_release(exprasmlist,left.location);
+                   cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
                 end;
            end
+         { Normal parameter }
          else
-              { don't push a node that already generated a pointer type
-                by address for implicit hidden parameters }
-              if (not(
-                      paraitem.is_hidden and
-                      (left.resulttype.def.deftype in [pointerdef,classrefdef])
-                     ) and
-                  paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,calloption)) then
-                begin
-                   { Check for passing a constant to var,out parameter }
-                   if (paraitem.paratyp in [vs_var,vs_out]) and
-                      (left.location.loc<>LOC_REFERENCE) then
-                    begin
-                      { passing self to a var parameter is allowed in
-                        TP and delphi }
-                      if not((left.location.loc=LOC_CREFERENCE) and
-                             is_self_node(left)) then
-                       internalerror(200106041);
-                    end;
-                   if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
-                    begin
-                      { allow passing nil to a procvardef (methodpointer) }
-                      if (left.nodetype=typeconvn) and
-                         (left.resulttype.def.deftype=procvardef) and
-                         (ttypeconvnode(left).left.nodetype=niln) then
-                       begin
-                         tg.GetTemp(exprasmlist,tcgsize2size[left.location.size],tt_normal,href);
-                         if not (left.location.size in [OS_64,OS_S64]) then
-                           cg.a_load_loc_ref(exprasmlist,left.location.size,left.location,href)
-                         else
-                           cg64.a_load64_loc_ref(exprasmlist,left.location,href);
-                         location_reset(left.location,LOC_REFERENCE,left.location.size);
-                         left.location.reference:=href;
-                       end
-                      else
-                       internalerror(200204011);
-                    end;
-
-                   inc(pushedparasize,POINTER_SIZE);
-                   cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
-                   location_release(exprasmlist,left.location);
-                end
-              else
-                begin
-                  push_value_para(exprasmlist,left,paraitem.paratyp,calloption,alignment,tempparaloc);
-                end;
+           begin
+             { don't push a node that already generated a pointer type
+               by address for implicit hidden parameters }
+             if (not(
+                     paraitem.is_hidden and
+                     (left.resulttype.def.deftype in [pointerdef,classrefdef])
+                    ) and
+                 paramanager.push_addr_param(paraitem.paratyp,paraitem.paratype.def,calloption)) then
+               begin
+                  { Check for passing a constant to var,out parameter }
+                  if (paraitem.paratyp in [vs_var,vs_out]) and
+                     (left.location.loc<>LOC_REFERENCE) then
+                   begin
+                     { passing self to a var parameter is allowed in
+                       TP and delphi }
+                     if not((left.location.loc=LOC_CREFERENCE) and
+                            is_self_node(left)) then
+                      internalerror(200106041);
+                   end;
+                  { Move to memory }
+                  if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
+                    location_force_mem(exprasmlist,left.location);
+                  { Push address }
+                  inc(pushedparasize,POINTER_SIZE);
+                  location_release(exprasmlist,left.location);
+                  cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
+               end
+             else
+               begin
+                 push_value_para(exprasmlist,left,paraitem.paratyp,calloption,alignment,tempparaloc);
+               end;
+           end;
          truelabel:=otlabel;
          falselabel:=oflabel;
 
@@ -483,9 +471,7 @@ implementation
          href,helpref : treference;
          para_alignment,
          pop_size : longint;
-{$ifndef usecallref}
          pvreg,
-{$endif usecallref}
          vmtreg,vmtreg2 : tregister;
          oldaktcallnode : tcallnode;
 
@@ -615,50 +601,37 @@ implementation
          { Align stack if required }
          pop_size:=align_parasize;
 
-         { Push parameters }
+         { Process parameters, register parameters will be loaded
+           in imaginary registers. The actual load to the correct
+           register is done just before the call }
          oldaktcallnode:=aktcallnode;
          aktcallnode:=self;
-
-{$ifndef i386}
-         { process procvar. Done here already, because otherwise it may }
-         { destroy registers containing a parameter for the actual      }
-         { function call (e.g. if it's a function, its result will      }
-         { overwrite r3, which contains the first parameter) (JM)       }
-         if assigned(right) then
-           secondpass(right);
-
-         if (po_virtualmethod in procdefinition.procoptions) and
-            assigned(methodpointer) then
-           begin
-             secondpass(methodpointer);
-             location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false);
-
-             { virtual methods require an index }
-             if tprocdef(procdefinition).extnumber=-1 then
-               internalerror(200304021);
-             { VMT should already be loaded in a register }
-             if methodpointer.location.register=NR_NO then
-               internalerror(200304022);
-
-             { test validity of VMT }
-             if not(is_interface(tprocdef(procdefinition)._class)) and
-                not(is_cppclass(tprocdef(procdefinition)._class)) then
-               cg.g_maybe_testvmt(exprasmlist,methodpointer.location.register,tprocdef(procdefinition)._class);
-           end;
-{$endif not i386}
-
-         { Process parameters }
          if assigned(left) then
-           begin
-             tcallparanode(left).secondcallparan(procdefinition.proccalloption,procdefinition.paraalign);
-
-             pushparas;
-           end;
+           tcallparanode(left).secondcallparan(procdefinition.proccalloption,procdefinition.paraalign);
          aktcallnode:=oldaktcallnode;
 
          { procedure variable or normal function call ? }
          if (right=nil) then
            begin
+             if (po_virtualmethod in procdefinition.procoptions) and
+                assigned(methodpointer) then
+               begin
+                 secondpass(methodpointer);
+                 location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false);
+
+                 { virtual methods require an index }
+                 if tprocdef(procdefinition).extnumber=-1 then
+                   internalerror(200304021);
+                 { VMT should already be loaded in a register }
+                 if methodpointer.location.register=NR_NO then
+                   internalerror(200304022);
+
+                 { test validity of VMT }
+                 if not(is_interface(tprocdef(procdefinition)._class)) and
+                    not(is_cppclass(tprocdef(procdefinition)._class)) then
+                   cg.g_maybe_testvmt(exprasmlist,methodpointer.location.register,tprocdef(procdefinition)._class);
+               end;
+
               { push base pointer ?}
               if (current_procinfo.procdef.parast.symtablelevel>=normal_function_level) and
                  assigned(tprocdef(procdefinition).parast) and
@@ -670,38 +643,25 @@ implementation
               if (po_virtualmethod in procdefinition.procoptions) and
                  assigned(methodpointer) then
                 begin
-{$ifdef i386}
-                   secondpass(methodpointer);
-                   location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false);
                    vmtreg:=methodpointer.location.register;
 
-                   { virtual methods require an index }
-                   if tprocdef(procdefinition).extnumber=-1 then
-                     internalerror(200304021);
-                   { VMT should already be loaded in a register }
-                   if vmtreg=NR_NO then
-                     internalerror(200304022);
-
-                   { test validity of VMT }
-                   if not(is_interface(tprocdef(procdefinition)._class)) and
-                      not(is_cppclass(tprocdef(procdefinition)._class)) then
-                     cg.g_maybe_testvmt(exprasmlist,vmtreg,tprocdef(procdefinition)._class);
-{$else}
-                   vmtreg:=methodpointer.location.register;
-{$endif}
                    { release self }
                    rg.ungetaddressregister(exprasmlist,vmtreg);
                    vmtreg2:=rg.getabtregisterint(exprasmlist,OS_ADDR);
                    rg.ungetregisterint(exprasmlist,vmtreg2);
                    cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,vmtreg,vmtreg2);
 
-{$ifndef usecallref}
+                   { load virtual method (procvar) }
                    pvreg:=rg.getabtregisterint(exprasmlist,OS_ADDR);
                    reference_reset_base(href,vmtreg2,
                       tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber));
                    rg.ungetregisterint(exprasmlist,pvreg);
                    cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,pvreg);
-{$endif usecallref}
+
+                   { Load parameters that are in temporary registers in the
+                     correct parameter register }
+                   if assigned(left) then
+                     pushparas;
 
                    { free the resources allocated for the parameters }
                    freeparas;
@@ -709,16 +669,15 @@ implementation
                    rg.allocexplicitregistersint(exprasmlist,regs_to_alloc);
 
                    { call method }
-{$ifdef usecallref}
-                   reference_reset_base(href,vmtreg2,
-                      tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber));
-                   cg.a_call_ref(exprasmlist,href);
-{$else usecallref}
                    cg.a_call_reg(exprasmlist,pvreg);
-{$endif usecallref}
                 end
               else
                 begin
+                  { Load parameters that are in temporary registers in the
+                    correct parameter register }
+                  if assigned(left) then
+                    pushparas;
+
                   { free the resources allocated for the parameters }
                   freeparas;
 
@@ -733,34 +692,8 @@ implementation
          else
            { now procedure variable case }
            begin
-{$ifdef i386}
               secondpass(right);
-{$endif i386}
-
-{$ifdef usecallref}
-              if right.location.loc in  [LOC_REFERENCE,LOC_CREFERENCE] then
-                begin
-                  helpref:=right.location.reference;
-                  if (helpref.index<>NR_NO) and (helpref.index<>NR_FRAME_POINTER_REG) then
-                    begin
-                      rg.ungetregisterint(exprasmlist,helpref.index);
-                      helpref.index:=rg.getabtregisterint(exprasmlist,OS_ADDR);
-                      cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,
-                                        right.location.reference.index,helpref.index);
-                    end;
-                  if (helpref.base<>NR_NO) and (helpref.base<>NR_FRAME_POINTER_REG) then
-                    begin
-                      rg.ungetregisterint(exprasmlist,helpref.base);
-                      helpref.base:=rg.getabtregisterint(exprasmlist,OS_ADDR);
-                      cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,
-                                        right.location.reference.base,helpref.base);
-                    end;
-                  reference_release(exprasmlist,helpref);
-                end
-              else
-                rg.ungetregisterint(exprasmlist,right.location.register);
-              location_freetemp(exprasmlist,right.location);
-{$else usecallref}
+              location_release(exprasmlist,right.location);
               pvreg:=rg.getabtregisterint(exprasmlist,OS_ADDR);
               rg.ungetregisterint(exprasmlist,pvreg);
               { Only load OS_ADDR from the reference }
@@ -768,9 +701,12 @@ implementation
                 cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,right.location.reference,pvreg)
               else
                 cg.a_load_loc_reg(exprasmlist,OS_ADDR,right.location,pvreg);
-              location_release(exprasmlist,right.location);
               location_freetemp(exprasmlist,right.location);
-{$endif usecallref}
+
+              { Load parameters that are in temporary registers in the
+                correct parameter register }
+              if assigned(left) then
+                pushparas;
 
               { free the resources allocated for the parameters }
               freeparas;
@@ -783,14 +719,7 @@ implementation
                 extra_interrupt_code;
 
               rg.saveotherregvars(exprasmlist,ALL_OTHERREGISTERS);
-{$ifdef usecallref}
-              if right.location.loc in  [LOC_REFERENCE,LOC_CREFERENCE] then
-                cg.a_call_ref(exprasmlist,helpref)
-              else
-                cg.a_call_reg(exprasmlist,right.location.register);
-{$else usecallref}
               cg.a_call_reg(exprasmlist,pvreg);
-{$endif usecallref}
            end;
 
          { Need to remove the parameters from the stack? }
@@ -1233,7 +1162,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.117  2003-09-25 21:28:00  peter
+  Revision 1.118  2003-09-28 13:54:43  peter
+    * removed a_call_ref
+
+  Revision 1.117  2003/09/25 21:28:00  peter
     * parameter fixes
 
   Revision 1.116  2003/09/23 17:56:05  peter