Browse Source

+ tcg8086.g_copyvaluepara_openarray: support source to be in a different segment

git-svn-id: trunk@27393 -
nickysn 11 years ago
parent
commit
0a9f738167
1 changed files with 19 additions and 2 deletions
  1. 19 2
      compiler/i8086/cgcpu.pas

+ 19 - 2
compiler/i8086/cgcpu.pas

@@ -121,7 +121,8 @@ unit cgcpu;
        paramgr,procinfo,fmodule,
        paramgr,procinfo,fmodule,
        rgcpu,rgx86,cpuinfo,
        rgcpu,rgx86,cpuinfo,
        symtype,symsym,
        symtype,symsym,
-       tgobj;
+       tgobj,
+       hlcgobj;
 
 
     function use_push(const cgpara:tcgpara):boolean;
     function use_push(const cgpara:tcgpara):boolean;
       begin
       begin
@@ -1819,6 +1820,7 @@ unit cgcpu;
       var
       var
         power  : longint;
         power  : longint;
         opsize : topsize;
         opsize : topsize;
+        saved_ds: Boolean;
       begin
       begin
         { get stack space }
         { get stack space }
         getcpuregister(list,NR_DI);
         getcpuregister(list,NR_DI);
@@ -1867,7 +1869,20 @@ unit cgcpu;
 
 
         { Allocate SI and load it with source }
         { Allocate SI and load it with source }
         getcpuregister(list,NR_SI);
         getcpuregister(list,NR_SI);
-        a_loadaddr_ref_reg(list,ref,NR_SI);
+        if (ref.segment=NR_NO) or
+           (is_segment_reg(ref.segment) and segment_regs_equal(ref.segment,NR_DS)) then
+          begin
+            a_loadaddr_ref_reg(list,ref,NR_SI);
+            saved_ds:=false;
+          end
+        else
+          begin
+            hlcg.a_loadaddr_ref_reg(list,voidnearpointertype,voidnearpointertype,ref,NR_SI);
+            list.concat(taicpu.op_reg(A_PUSH,S_W,NR_DS));
+            saved_ds:=true;
+            list.concat(taicpu.op_reg(A_PUSH,S_W,ref.segment));
+            list.concat(taicpu.op_reg(A_POP,S_W,NR_DS));
+          end;
 
 
         { calculate size }
         { calculate size }
         opsize:=S_B;
         opsize:=S_B;
@@ -1907,6 +1922,8 @@ unit cgcpu;
         ungetcpuregister(list,NR_DI);
         ungetcpuregister(list,NR_DI);
         ungetcpuregister(list,NR_CX);
         ungetcpuregister(list,NR_CX);
         ungetcpuregister(list,NR_SI);
         ungetcpuregister(list,NR_SI);
+        if saved_ds then
+          list.concat(taicpu.op_reg(A_POP,S_W,NR_DS));
 
 
         { patch the new address, but don't use a_load_reg_reg, that will add a move instruction
         { patch the new address, but don't use a_load_reg_reg, that will add a move instruction
           that can confuse the reg allocator }
           that can confuse the reg allocator }