Procházet zdrojové kódy

* created generic version of thlcgobj.g_reference_loc() and only override
JVM-specific case (needed for future trunk marge to prevent abstract
method warning)

git-svn-id: branches/jvmbackend@20387 -

Jonas Maebe před 13 roky
rodič
revize
3916a32f9e
2 změnil soubory, kde provedl 58 přidání a 33 odebrání
  1. 52 1
      compiler/hlcgobj.pas
  2. 6 32
      compiler/jvm/hlcgcpu.pas

+ 52 - 1
compiler/hlcgobj.pas

@@ -420,6 +420,9 @@ unit hlcgobj;
           The default implementation issues a jump instruction to the external name. }
 //          procedure g_external_wrapper(list : TAsmList; procdef: tprocdef; const externalname: string); virtual;
 
+         protected
+            procedure g_allocload_reg_reg(list: TAsmList; regsize: tdef; const fromreg: tregister; out toreg: tregister; regtyp: tregistertype);
+         public
           { create "safe copy" of a tlocation that can be used later: all
             registers used in the tlocation are copied to new ones, so that
             even if the original ones change, things stay the same (except if
@@ -427,7 +430,7 @@ unit hlcgobj;
             kept). Must only be used on lvalue locations.
             It's intended as some kind of replacement for a_loadaddr_ref_reg()
             for targets without pointers. }
-          procedure g_reference_loc(list: TAsmList; def: tdef; const fromloc: tlocation; out toloc: tlocation); virtual; abstract;
+          procedure g_reference_loc(list: TAsmList; def: tdef; const fromloc: tlocation; out toloc: tlocation); virtual;
 
 
           { routines migrated from ncgutil }
@@ -1859,6 +1862,54 @@ implementation
     begin
     end;
 
+  procedure thlcgobj.g_allocload_reg_reg(list: TAsmList; regsize: tdef; const fromreg: tregister; out toreg: tregister; regtyp: tregistertype);
+    begin
+      case regtyp of
+        R_INTREGISTER:
+          toreg:=getintregister(list,regsize);
+        R_ADDRESSREGISTER:
+          toreg:=getaddressregister(list,regsize);
+        R_FPUREGISTER:
+          toreg:=getfpuregister(list,regsize);
+      end;
+      a_load_reg_reg(list,regsize,regsize,fromreg,toreg);
+    end;
+
+  procedure thlcgobj.g_reference_loc(list: TAsmList; def: tdef; const fromloc: tlocation; out toloc: tlocation);
+
+    begin
+      toloc:=fromloc;
+      case fromloc.loc of
+        { volatile location, can't get a permanent reference }
+        LOC_REGISTER,
+        LOC_FPUREGISTER:
+          internalerror(2012012702);
+        LOC_CONSTANT:
+          { finished }
+          ;
+        LOC_CREGISTER:
+          g_allocload_reg_reg(list,def,fromloc.reference.index,toloc.reference.index,R_INTREGISTER);
+        LOC_CFPUREGISTER:
+          g_allocload_reg_reg(list,def,fromloc.reference.index,toloc.reference.index,R_FPUREGISTER);
+        { although LOC_CREFERENCE cannot be an lvalue, we may want to take a
+          reference to such a location for multiple reading }
+        LOC_CREFERENCE,
+        LOC_REFERENCE:
+          begin
+            if (fromloc.reference.base<>NR_NO) and
+               (fromloc.reference.base<>current_procinfo.framepointer) and
+               (fromloc.reference.base<>NR_STACK_POINTER_REG) then
+              g_allocload_reg_reg(list,voidpointertype,fromloc.reference.base,toloc.reference.base,getregtype(fromloc.reference.base));
+            if (fromloc.reference.index<>NR_NO) and
+               (fromloc.reference.index<>current_procinfo.framepointer) and
+               (fromloc.reference.index<>NR_STACK_POINTER_REG) then
+              g_allocload_reg_reg(list,voidpointertype,fromloc.reference.index,toloc.reference.index,getregtype(fromloc.reference.index));
+          end;
+        else
+          internalerror(2012012701);
+      end;
+    end;
+
   procedure thlcgobj.location_force_reg(list: TAsmList; var l: tlocation; src_size, dst_size: tdef; maybeconst: boolean);
     var
       hregister,

+ 6 - 32
compiler/jvm/hlcgcpu.pas

@@ -588,59 +588,33 @@ implementation
     end;
 
   procedure thlcgjvm.g_reference_loc(list: TAsmList; def: tdef; const fromloc: tlocation; out toloc: tlocation);
-
-    procedure handle_reg_move(regsize: tdef; const fromreg: tregister; out toreg: tregister; regtyp: tregistertype);
-      begin
-        case regtyp of
-          R_INTREGISTER:
-            toreg:=getintregister(list,regsize);
-          R_ADDRESSREGISTER:
-            toreg:=getaddressregister(list,regsize);
-          R_FPUREGISTER:
-            toreg:=getfpuregister(list,regsize);
-        end;
-        a_load_reg_reg(list,regsize,regsize,fromreg,toreg);
-      end;
-
     begin
-      toloc:=fromloc;
       case fromloc.loc of
-        { volatile location, can't get a permanent reference }
-        LOC_REGISTER,
-        LOC_FPUREGISTER:
-          internalerror(2011031406);
-        LOC_CONSTANT:
-          { finished }
-          ;
-        LOC_CREGISTER:
-          handle_reg_move(def,fromloc.reference.index,toloc.reference.index,R_INTREGISTER);
-        LOC_CFPUREGISTER:
-          handle_reg_move(def,fromloc.reference.index,toloc.reference.index,R_FPUREGISTER);
-        { although LOC_CREFERENCE cannot be an lvalue, we may want to take a
-          reference to such a location for multiple reading }
         LOC_CREFERENCE,
         LOC_REFERENCE:
           begin
+            toloc:=fromloc;
             if (fromloc.reference.base<>NR_NO) and
                (fromloc.reference.base<>current_procinfo.framepointer) and
                (fromloc.reference.base<>NR_STACK_POINTER_REG) then
-              handle_reg_move(java_jlobject,fromloc.reference.base,toloc.reference.base,R_ADDRESSREGISTER);
+              g_allocload_reg_reg(list,voidpointertype,fromloc.reference.base,toloc.reference.base,R_ADDRESSREGISTER);
             case fromloc.reference.arrayreftype of
               art_indexreg:
                 begin
                   { all array indices in Java are 32 bit ints }
-                  handle_reg_move(s32inttype,fromloc.reference.index,toloc.reference.index,R_INTREGISTER);
+                  g_allocload_reg_reg(list,s32inttype,fromloc.reference.index,toloc.reference.index,R_INTREGISTER);
                 end;
               art_indexref:
                 begin
+                  { base register of the address of the index -> pointer }
                   if (fromloc.reference.indexbase<>NR_NO) and
                      (fromloc.reference.indexbase<>NR_STACK_POINTER_REG) then
-                    handle_reg_move(s32inttype,fromloc.reference.indexbase,toloc.reference.indexbase,R_ADDRESSREGISTER);
+                    g_allocload_reg_reg(list,voidpointertype,fromloc.reference.indexbase,toloc.reference.indexbase,R_ADDRESSREGISTER);
                 end;
             end;
           end;
         else
-          internalerror(2011031407);
+          inherited;
       end;
     end;