Browse Source

* 8086: Do not destroy contents of the BX parameter when calling a procvar by ref with a base.

git-svn-id: trunk@46559 -
yury 5 years ago
parent
commit
5ec101d578
2 changed files with 25 additions and 24 deletions
  1. 23 20
      compiler/i8086/n8086cal.pas
  2. 2 4
      compiler/x86/nx86cal.pas

+ 23 - 20
compiler/i8086/n8086cal.pas

@@ -37,8 +37,8 @@ interface
        protected
           procedure pop_parasize(pop_size:longint);override;
           procedure extra_interrupt_code;override;
-          procedure extra_call_ref_code(var ref: treference);override;
           function do_call_ref(ref: treference): tcgpara;override;
+          function can_call_ref(var ref: treference): boolean; override;
         public
           function pass_typecheck: tnode; override;
        end;
@@ -102,25 +102,6 @@ implementation
       end;
 
 
-    procedure ti8086callnode.extra_call_ref_code(var ref: treference);
-      begin
-        if (ref.base<>NR_NO) and (ref.base<>NR_BP) then
-          begin
-            cg.getcpuregister(current_asmdata.CurrAsmList,NR_BX);
-            cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,ref.base,NR_BX);
-            ref.base:=NR_BX;
-            cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_BX);
-          end;
-        if ref.index<>NR_NO then
-          begin
-            cg.getcpuregister(current_asmdata.CurrAsmList,NR_SI);
-            cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,ref.index,NR_SI);
-            ref.index:=NR_SI;
-            cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_SI);
-          end;
-      end;
-
-
     function ti8086callnode.do_call_ref(ref: treference): tcgpara;
       begin
         if is_proc_far(procdefinition) then
@@ -131,6 +112,28 @@ implementation
       end;
 
 
+    function ti8086callnode.can_call_ref(var ref: treference): boolean;
+      var
+        reg,seg: tregister;
+      begin
+        tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,ref);
+        if (procdefinition.proccalloption=pocall_register) and
+           (getsupreg(ref.base)>=first_int_imreg) and
+           (getsupreg(ref.index)>=first_int_imreg) then
+          begin
+            { Precalculate the ref address in case both ref base and index are
+              imm registers and the register calling convention is used.
+              Otherwise register allocation will fail if BX is used for a parameter. }
+            reg:=cg.getaddressregister(current_asmdata.CurrAsmList);
+            current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_LEA,S_W,ref,reg));
+            seg:=ref.segment;
+            reference_reset_base(ref,reg,0,ref.temppos,ref.alignment,[]);
+            ref.segment:=seg;
+          end;
+        result:=true;
+      end;
+
+
     function ti8086callnode.pass_typecheck: tnode;
       begin
         Result:=inherited pass_typecheck;

+ 2 - 4
compiler/x86/nx86cal.pas

@@ -87,11 +87,9 @@ implementation
 
   function tx86callnode.can_call_ref(var ref: treference): boolean;
     const
-{$if defined(i8086)}
-      save_all_regs=[pocall_pascal];
-{$elseif defined(i386)}
+{$if defined(i386)}
       save_all_regs=[pocall_far16,pocall_oldfpccall];
-{$elseif defined(x86_64)}
+{$else}
       save_all_regs=[];
 {$endif}
     begin