Browse Source

* refactored i8086's thlcgcpu.location_force_mem:
o The checks for types that need special handling moved to separate methods,
because they'll probably be used by the other hlcg.a_load*loc* methods as
well.
o Use voidcodepointertype and voidpointertype to avoid the ifs for checking
the memory model.

git-svn-id: trunk@27554 -

nickysn 11 years ago
parent
commit
2e7aab0155
1 changed files with 45 additions and 35 deletions
  1. 45 35
      compiler/i8086/hlcgcpu.pas

+ 45 - 35
compiler/i8086/hlcgcpu.pas

@@ -41,6 +41,25 @@ interface
     { thlcgcpu }
     { thlcgcpu }
 
 
     thlcgcpu = class(thlcgx86)
     thlcgcpu = class(thlcgx86)
+     private
+      { checks whether the type needs special methodptr-like handling, when stored
+        in a LOC_REGISTER location. This applies to the following types:
+          - i8086 method pointers (incl. 6-byte mixed near + far),
+          - 6-byte records (only in the medium and compact memory model are these
+              loaded in a register)
+          - nested proc ptrs
+        When stored in a LOC_REGISTER tlocation, these types use both register
+        and registerhi with the following sizes:
+
+        register   - cgsize = int_cgsize(voidcodepointertype.size)
+        registerhi - cgsize = int_cgsize(voidpointertype.size) }
+      function is_methodptr_like_type(d:tdef): boolean;
+
+      { 4-byte records in registers need special handling as well. A record may
+        be located in registerhi:register if it was converted from a procvar or
+        in GetNextReg(register):register if it was converted from a longint.
+        We can tell between the two by checking whether registerhi has been set. }
+      function is_fourbyterecord(d:tdef): boolean;
      protected
      protected
       procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override;
       procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); override;
      public
      public
@@ -71,6 +90,27 @@ implementation
 
 
   { thlcgcpu }
   { thlcgcpu }
 
 
+  function thlcgcpu.is_methodptr_like_type(d: tdef): boolean;
+    var
+      is_sixbyterecord,is_methodptr,is_nestedprocptr: Boolean;
+    begin
+      is_sixbyterecord:=(d.typ=recorddef) and (d.size=6);
+      is_methodptr:=(d.typ=procvardef)
+        and (po_methodpointer in tprocvardef(d).procoptions)
+        and not(po_addressonly in tprocvardef(d).procoptions);
+      is_nestedprocptr:=(d.typ=procvardef)
+        and is_nested_pd(tprocvardef(d))
+        and not(po_addressonly in tprocvardef(d).procoptions);
+      result:=is_sixbyterecord or is_methodptr or is_nestedprocptr;
+    end;
+
+
+  function thlcgcpu.is_fourbyterecord(d: tdef): boolean;
+    begin
+      result:=(d.typ=recorddef) and (d.size=4);
+    end;
+
+
   procedure thlcgcpu.gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint);
   procedure thlcgcpu.gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint);
     var
     var
       locsize : tcgsize;
       locsize : tcgsize;
@@ -279,50 +319,20 @@ implementation
   procedure thlcgcpu.location_force_mem(list: TAsmList; var l: tlocation; size: tdef);
   procedure thlcgcpu.location_force_mem(list: TAsmList; var l: tlocation; size: tdef);
     var
     var
       r,tmpref: treference;
       r,tmpref: treference;
-      is_sixbyterecord: Boolean;
-      is_fourbyterecord: Boolean;
-      is_methodptr: Boolean;
-      is_nestedprocptr: Boolean;
     begin
     begin
-      is_sixbyterecord:=(size.typ=recorddef) and (size.size=6);
-      is_fourbyterecord:=(size.typ=recorddef) and (size.size=4);
-      is_methodptr:=(size.typ=procvardef)
-        and (po_methodpointer in tprocvardef(size).procoptions)
-        and not(po_addressonly in tprocvardef(size).procoptions);
-      is_nestedprocptr:=(size.typ=procvardef)
-        and is_nested_pd(tprocvardef(size))
-        and not(po_addressonly in tprocvardef(size).procoptions);
-
-      { handle i8086 method pointers (incl. 6-byte mixed near + far),
-        6-byte records and nested proc ptrs }
-      if (is_sixbyterecord or is_methodptr or is_nestedprocptr) and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+      if is_methodptr_like_type(size) and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
         begin
         begin
           tg.gethltemp(list,size,size.size,tt_normal,r);
           tg.gethltemp(list,size,size.size,tt_normal,r);
           tmpref:=r;
           tmpref:=r;
 
 
-          if current_settings.x86memorymodel in x86_far_code_models then
-            begin
-              cg.a_load_reg_ref(list,OS_32,OS_32,l.register,tmpref);
-              inc(tmpref.offset,4);
-            end
-          else
-            begin
-              cg.a_load_reg_ref(list,OS_16,OS_16,l.register,tmpref);
-              inc(tmpref.offset,2);
-            end;
-          if current_settings.x86memorymodel in x86_far_data_models then
-            cg.a_load_reg_ref(list,OS_32,OS_32,l.registerhi,tmpref)
-          else
-            cg.a_load_reg_ref(list,OS_16,OS_16,l.registerhi,tmpref);
+          a_load_reg_ref(list,voidcodepointertype,voidcodepointertype,l.register,tmpref);
+          inc(tmpref.offset,voidcodepointertype.size);
+          a_load_reg_ref(list,voidpointertype,voidpointertype,l.registerhi,tmpref);
 
 
           location_reset_ref(l,LOC_REFERENCE,l.size,0);
           location_reset_ref(l,LOC_REFERENCE,l.size,0);
           l.reference:=r;
           l.reference:=r;
         end
         end
-      { 4-byte records in registers need special handling as well. A record may
-        be located in registerhi:register if it was converted from a procvar or
-        in GetNextReg(register):register if it was converted from a longint.
-        We can tell between the two by checking whether registerhi has been set. }
-      else if is_fourbyterecord and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+      else if is_fourbyterecord(size) and (l.loc in [LOC_REGISTER,LOC_CREGISTER]) then
         begin
         begin
           tg.gethltemp(list,size,size.size,tt_normal,r);
           tg.gethltemp(list,size,size.size,tt_normal,r);
           tmpref:=r;
           tmpref:=r;