Browse Source

* fixed the interface wrapper code generation for virtual methods on i8086 in
the medium memory model

git-svn-id: trunk@25817 -

nickysn 11 years ago
parent
commit
ef51c8c5a2
1 changed files with 31 additions and 3 deletions
  1. 31 3
      compiler/i8086/cgcpu.pas

+ 31 - 3
compiler/i8086/cgcpu.pas

@@ -1725,6 +1725,8 @@ unit cgcpu;
                 selfoffsetfromsp:=2*sizeof(aint)
                 selfoffsetfromsp:=2*sizeof(aint)
               else
               else
                 selfoffsetfromsp:=sizeof(aint);
                 selfoffsetfromsp:=sizeof(aint);
+              if current_settings.x86memorymodel in x86_far_code_models then
+                inc(selfoffsetfromsp,2);
               list.concat(taicpu.op_reg_reg(A_mov,S_W,NR_SP,NR_DI));
               list.concat(taicpu.op_reg_reg(A_mov,S_W,NR_SP,NR_DI));
               reference_reset_base(href,NR_DI,selfoffsetfromsp+offs+2,2);
               reference_reset_base(href,NR_DI,selfoffsetfromsp+offs+2,2);
               cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_BX);
               cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_BX);
@@ -1751,6 +1753,12 @@ unit cgcpu;
         begin
         begin
           if (procdef.extnumber=$ffff) then
           if (procdef.extnumber=$ffff) then
             Internalerror(200006139);
             Internalerror(200006139);
+          if current_settings.x86memorymodel in x86_far_code_models then
+            begin
+              { mov vmtseg(%bx),%si ; method seg }
+              reference_reset_base(href,NR_BX,tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber)+2,2);
+              cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_SI);
+            end;
           { mov vmtoffs(%bx),%bx ; method offs }
           { mov vmtoffs(%bx),%bx ; method offs }
           reference_reset_base(href,NR_BX,tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber),2);
           reference_reset_base(href,NR_BX,tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber),2);
           cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_BX);
           cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_BX);
@@ -1790,16 +1798,31 @@ unit cgcpu;
           begin
           begin
             { case 1 & case 2 }
             { case 1 & case 2 }
             list.concat(taicpu.op_reg(A_PUSH,S_W,NR_BX)); { allocate space for address}
             list.concat(taicpu.op_reg(A_PUSH,S_W,NR_BX)); { allocate space for address}
+            if current_settings.x86memorymodel in x86_far_code_models then
+              list.concat(taicpu.op_reg(A_PUSH,S_W,NR_BX));
             list.concat(taicpu.op_reg(A_PUSH,S_W,NR_BX));
             list.concat(taicpu.op_reg(A_PUSH,S_W,NR_BX));
             list.concat(taicpu.op_reg(A_PUSH,S_W,NR_DI));
             list.concat(taicpu.op_reg(A_PUSH,S_W,NR_DI));
-            getselftobx(6);
+            if current_settings.x86memorymodel in x86_far_code_models then
+              list.concat(taicpu.op_reg(A_PUSH,S_W,NR_SI));
+            if current_settings.x86memorymodel in x86_far_code_models then
+              getselftobx(10)
+            else
+              getselftobx(6);
             loadvmttobx;
             loadvmttobx;
             loadmethodoffstobx;
             loadmethodoffstobx;
             { set target address
             { set target address
               "mov %bx,4(%sp)" }
               "mov %bx,4(%sp)" }
-            reference_reset_base(href,NR_DI,4,2);
+            if current_settings.x86memorymodel in x86_far_code_models then
+              reference_reset_base(href,NR_DI,6,2)
+            else
+              reference_reset_base(href,NR_DI,4,2);
             list.concat(taicpu.op_reg_reg(A_MOV,S_W,NR_SP,NR_DI));
             list.concat(taicpu.op_reg_reg(A_MOV,S_W,NR_SP,NR_DI));
             list.concat(taicpu.op_reg_ref(A_MOV,S_W,NR_BX,href));
             list.concat(taicpu.op_reg_ref(A_MOV,S_W,NR_BX,href));
+            if current_settings.x86memorymodel in x86_far_code_models then
+              begin
+                reference_reset_base(href,NR_DI,8,2);
+                list.concat(taicpu.op_reg_ref(A_MOV,S_W,NR_SI,href));
+              end;
 
 
             { load ax? }
             { load ax? }
             if procdef.proccalloption=pocall_register then
             if procdef.proccalloption=pocall_register then
@@ -1807,11 +1830,16 @@ unit cgcpu;
 
 
             { restore register
             { restore register
               pop  %di,bx }
               pop  %di,bx }
+            if current_settings.x86memorymodel in x86_far_code_models then
+              list.concat(taicpu.op_reg(A_POP,S_W,NR_SI));
             list.concat(taicpu.op_reg(A_POP,S_W,NR_DI));
             list.concat(taicpu.op_reg(A_POP,S_W,NR_DI));
             list.concat(taicpu.op_reg(A_POP,S_W,NR_BX));
             list.concat(taicpu.op_reg(A_POP,S_W,NR_BX));
 
 
             { ret  ; jump to the address }
             { ret  ; jump to the address }
-            list.concat(taicpu.op_none(A_RET,S_W));
+            if current_settings.x86memorymodel in x86_far_code_models then
+              list.concat(taicpu.op_none(A_RETF,S_W))
+            else
+              list.concat(taicpu.op_none(A_RET,S_W));
           end
           end
         { case 0 }
         { case 0 }
         else
         else