Ver Fonte

+ added i8086 specific implementation of thlcgcpu.a_load_loc_ref, which handles
6-byte method pointers and other i8086 types that use loc.registerhi
* changed the i8086 specific code in tcgassignmentnode.pass_generate_code to
use hlcg.a_load_loc_ref

git-svn-id: trunk@27555 -

nickysn há 11 anos atrás
pai
commit
40a6a9c820
2 ficheiros alterados com 32 adições e 30 exclusões
  1. 27 0
      compiler/i8086/hlcgcpu.pas
  2. 5 30
      compiler/ncgld.pas

+ 27 - 0
compiler/i8086/hlcgcpu.pas

@@ -67,6 +67,7 @@ interface
 
       procedure reference_reset_base(var ref: treference; regsize: tdef; reg: tregister; offset, alignment: longint); override;
 
+      procedure a_load_loc_ref(list : TAsmList;fromsize, tosize: tdef; const loc: tlocation; const ref : treference);override;
       procedure a_loadaddr_ref_reg(list : TAsmList;fromsize, tosize : tdef;const ref : treference;r : tregister);override;
 
       procedure g_copyvaluepara_openarray(list: TAsmList; const ref: treference; const lenloc: tlocation; arrdef: tarraydef; destreg: tregister); override;
@@ -255,6 +256,32 @@ implementation
     end;
 
 
+  procedure thlcgcpu.a_load_loc_ref(list: TAsmList; fromsize, tosize: tdef; const loc: tlocation; const ref: treference);
+    var
+      tmpref: treference;
+    begin
+      if is_methodptr_like_type(tosize) and (loc.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+        begin
+          tmpref:=ref;
+          a_load_reg_ref(list,voidcodepointertype,voidcodepointertype,loc.register,tmpref);
+          inc(tmpref.offset,voidcodepointertype.size);
+          a_load_reg_ref(list,voidpointertype,voidpointertype,loc.registerhi,tmpref);
+        end
+      else if is_fourbyterecord(tosize) and (loc.loc in [LOC_REGISTER,LOC_CREGISTER]) then
+        begin
+          tmpref:=ref;
+          cg.a_load_reg_ref(list,OS_16,OS_16,loc.register,tmpref);
+          inc(tmpref.offset,2);
+          if loc.registerhi<>tregister(0) then
+            cg.a_load_reg_ref(list,OS_16,OS_16,loc.registerhi,tmpref)
+          else
+            cg.a_load_reg_ref(list,OS_16,OS_16,GetNextReg(loc.register),tmpref);
+        end
+      else
+        inherited a_load_loc_ref(list, fromsize, tosize, loc, ref);
+    end;
+
+
   procedure thlcgcpu.a_loadaddr_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; r: tregister);
     var
       tmpref,segref: treference;

+ 5 - 30
compiler/ncgld.pas

@@ -885,36 +885,11 @@ implementation
                   else
 {$endif cpu64bitalu}
 {$ifdef i8086}
-                  { i8086 method pointer support (incl. 6-byte method pointers for the medium and compact memory models) }
-                  if (left.resultdef.typ = procvardef) and
-                     ((po_methodpointer in tprocvardef(left.resultdef).procoptions) or is_nested_pd(tprocvardef(left.resultdef))) and
-                     not(po_addressonly in tprocvardef(left.resultdef).procoptions) then
-                    begin
-                      case left.location.loc of
-                        LOC_REFERENCE,LOC_CREFERENCE:
-                          begin
-                            href:=left.location.reference;
-                            { proc address }
-                            if po_far in tprocdef(right.resultdef).procoptions then
-                              begin
-                                cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_32,OS_32,right.location.register,href);
-                                inc(href.offset, 4)
-                              end
-                            else
-                              begin
-                                cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_16,OS_16,right.location.register,href);
-                                inc(href.offset, 2);
-                              end;
-                            { object self }
-                            if current_settings.x86memorymodel in x86_far_data_models then
-                              cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_32,OS_32,right.location.registerhi,href)
-                            else
-                              cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_16,OS_16,right.location.registerhi,href);
-                          end;
-                        else
-                          internalerror(2013072001);
-                      end;
-                    end
+                  { prefer a_load_loc_ref, because it supports i8086-specific types
+                    that use registerhi (like 6-byte method pointers)
+                    (todo: maybe we should add a_load_loc_loc?) }
+                  if left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
+                    hlcg.a_load_loc_ref(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location,left.location.reference)
                   else
 {$endif i8086}
                     hlcg.a_load_reg_loc(current_asmdata.CurrAsmList,right.resultdef,left.resultdef,right.location.register,left.location);