2
0
Эх сурвалжийг харах

* a_call_ref functionality cannot be implemented efficiently at code generator level, because references need specific preparations at earlier points. Moved this support to tcgcallnode and its x86 descendants, and got rid of all ifdef's around.
+ x86 targets now directly call procedure variables located in references.
- a_call_ref method removed from tcg and thlcgobj.

git-svn-id: trunk@26666 -

sergei 11 жил өмнө
parent
commit
9c1f917e3a

+ 0 - 11
compiler/arm/cgcpu.pas

@@ -47,7 +47,6 @@ unit cgcpu;
 
 
         procedure a_call_name(list : TAsmList;const s : string; weak: boolean);override;
         procedure a_call_name(list : TAsmList;const s : string; weak: boolean);override;
         procedure a_call_reg(list : TAsmList;reg: tregister);override;
         procedure a_call_reg(list : TAsmList;reg: tregister);override;
-        procedure a_call_ref(list : TAsmList;ref: treference);override;
 
 
         { move instructions }
         { move instructions }
         procedure a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);override;
         procedure a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);override;
@@ -681,16 +680,6 @@ unit cgcpu;
       end;
       end;
 
 
 
 
-    procedure tbasecgarm.a_call_ref(list : TAsmList;ref: treference);
-      begin
-        a_reg_alloc(list,NR_R12);
-        a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,NR_R12);
-        a_call_reg(list,NR_R12);
-        a_reg_dealloc(list,NR_R12);
-        include(current_procinfo.flags,pi_do_call);
-      end;
-
-
      procedure tcgarm.a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister);
      procedure tcgarm.a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister);
        begin
        begin
           a_op_const_reg_reg(list,op,size,a,reg,reg);
           a_op_const_reg_reg(list,op,size,a,reg,reg);

+ 0 - 14
compiler/avr/cgcpu.pas

@@ -54,7 +54,6 @@ unit cgcpu;
 
 
         procedure a_call_name(list : TAsmList;const s : string; weak: boolean);override;
         procedure a_call_name(list : TAsmList;const s : string; weak: boolean);override;
         procedure a_call_reg(list : TAsmList;reg: tregister);override;
         procedure a_call_reg(list : TAsmList;reg: tregister);override;
-        procedure a_call_ref(list : TAsmList;ref: treference);override;
 
 
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override;
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override;
         procedure a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src, dst : TRegister); override;
         procedure a_op_reg_reg(list: TAsmList; Op: TOpCG; size: TCGSize; src, dst : TRegister); override;
@@ -406,19 +405,6 @@ unit cgcpu;
       end;
       end;
 
 
 
 
-    procedure tcgavr.a_call_ref(list : TAsmList;ref: treference);
-      begin
-        a_reg_alloc(list,NR_ZLO);
-        a_reg_alloc(list,NR_ZHI);
-        a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,NR_ZLO);
-        list.concat(taicpu.op_none(A_ICALL));
-        a_reg_dealloc(list,NR_ZLO);
-        a_reg_dealloc(list,NR_ZHI);
-
-        include(current_procinfo.flags,pi_do_call);
-      end;
-
-
      procedure tcgavr.a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister);
      procedure tcgavr.a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister);
        begin
        begin
          if not(size in [OS_S8,OS_8,OS_S16,OS_16,OS_S32,OS_32]) then
          if not(size in [OS_S8,OS_8,OS_S16,OS_16,OS_S32,OS_32]) then

+ 0 - 11
compiler/cgobj.pas

@@ -227,7 +227,6 @@ unit cgobj;
           }
           }
           procedure a_call_name(list : TAsmList;const s : string; weak: boolean);virtual; abstract;
           procedure a_call_name(list : TAsmList;const s : string; weak: boolean);virtual; abstract;
           procedure a_call_reg(list : TAsmList;reg : tregister);virtual; abstract;
           procedure a_call_reg(list : TAsmList;reg : tregister);virtual; abstract;
-          procedure a_call_ref(list : TAsmList;ref : treference);virtual;
           { same as a_call_name, might be overridden on certain architectures to emit
           { same as a_call_name, might be overridden on certain architectures to emit
             static calls without usage of a got trampoline }
             static calls without usage of a got trampoline }
           procedure a_call_name_static(list : TAsmList;const s : string);virtual;
           procedure a_call_name_static(list : TAsmList;const s : string);virtual;
@@ -2413,16 +2412,6 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcg.a_call_ref(list : TAsmList;ref: treference);
-      var
-        tempreg : TRegister;
-      begin
-        tempreg := getintregister(list, OS_ADDR);
-        a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,tempreg);
-        a_call_reg(list,tempreg);
-      end;
-
-
    function tcg.g_indirect_sym_load(list:TAsmList;const symname: string; const flags: tindsymflags): tregister;
    function tcg.g_indirect_sym_load(list:TAsmList;const symname: string; const flags: tindsymflags): tregister;
       var
       var
         l: tasmsymbol;
         l: tasmsymbol;

+ 0 - 6
compiler/hlcg2ll.pas

@@ -151,7 +151,6 @@ unit hlcg2ll;
 
 
           function a_call_name(list : TAsmList;pd : tprocdef;const s : TSymStr; forceresdef: tdef; weak: boolean): tcgpara;override;
           function a_call_name(list : TAsmList;pd : tprocdef;const s : TSymStr; forceresdef: tdef; weak: boolean): tcgpara;override;
           procedure a_call_reg(list : TAsmList;pd : tabstractprocdef;reg : tregister);override;
           procedure a_call_reg(list : TAsmList;pd : tabstractprocdef;reg : tregister);override;
-          procedure a_call_ref(list : TAsmList;pd : tabstractprocdef;const ref : treference);override;
           { same as a_call_name, might be overridden on certain architectures to emit
           { same as a_call_name, might be overridden on certain architectures to emit
             static calls without usage of a got trampoline }
             static calls without usage of a got trampoline }
           function a_call_name_static(list : TAsmList;pd : tprocdef;const s : TSymStr; forceresdef: tdef): tcgpara;override;
           function a_call_name_static(list : TAsmList;pd : tprocdef;const s : TSymStr; forceresdef: tdef): tcgpara;override;
@@ -462,11 +461,6 @@ implementation
       cg.a_call_reg(list,reg);
       cg.a_call_reg(list,reg);
     end;
     end;
 
 
-  procedure thlcg2ll.a_call_ref(list: TAsmList; pd: tabstractprocdef; const ref: treference);
-    begin
-      cg.a_call_ref(list,ref);
-    end;
-
   function thlcg2ll.a_call_name_static(list: TAsmList; pd: tprocdef; const s: TSymStr; forceresdef: tdef): tcgpara;
   function thlcg2ll.a_call_name_static(list: TAsmList; pd: tprocdef; const s: TSymStr; forceresdef: tdef): tcgpara;
     begin
     begin
       cg.a_call_name_static(list,s);
       cg.a_call_name_static(list,s);

+ 0 - 17
compiler/hlcgobj.pas

@@ -194,7 +194,6 @@ unit hlcgobj;
           }
           }
           function a_call_name(list : TAsmList;pd : tprocdef;const s : TSymStr; forceresdef: tdef; weak: boolean): tcgpara;virtual;abstract;
           function a_call_name(list : TAsmList;pd : tprocdef;const s : TSymStr; forceresdef: tdef; weak: boolean): tcgpara;virtual;abstract;
           procedure a_call_reg(list : TAsmList;pd : tabstractprocdef;reg : tregister);virtual;abstract;
           procedure a_call_reg(list : TAsmList;pd : tabstractprocdef;reg : tregister);virtual;abstract;
-          procedure a_call_ref(list : TAsmList;pd : tabstractprocdef;const ref : treference);virtual;
           { same as a_call_name, might be overridden on certain architectures to emit
           { same as a_call_name, might be overridden on certain architectures to emit
             static calls without usage of a got trampoline }
             static calls without usage of a got trampoline }
           function a_call_name_static(list : TAsmList;pd : tprocdef;const s : TSymStr; forceresdef: tdef): tcgpara;virtual;
           function a_call_name_static(list : TAsmList;pd : tprocdef;const s : TSymStr; forceresdef: tdef): tcgpara;virtual;
@@ -975,22 +974,6 @@ implementation
          end;
          end;
     end;
     end;
 
 
-  procedure thlcgobj.a_call_ref(list: TAsmList; pd: tabstractprocdef; const ref: treference);
-    var
-      reg: tregister;
-      size: tdef;
-    begin
-      { the loaded data is always a pointer to a procdef. A procvardef is
-        implicitly a pointer already, but a procdef isn't -> create one }
-      if pd.typ=procvardef then
-        size:=pd
-      else
-        size:=getpointerdef(pd);
-      reg:=getaddressregister(list,size);
-      a_load_ref_reg(list,size,size,ref,reg);
-      a_call_reg(list,pd,reg);
-    end;
-
   function thlcgobj.a_call_name_static(list: TAsmList; pd: tprocdef; const s: TSymStr; forceresdef: tdef): tcgpara;
   function thlcgobj.a_call_name_static(list: TAsmList; pd: tprocdef; const s: TSymStr; forceresdef: tdef): tcgpara;
     begin
     begin
       result:=a_call_name(list,pd,s,forceresdef,false);
       result:=a_call_name(list,pd,s,forceresdef,false);

+ 2 - 19
compiler/i8086/cgcpu.pas

@@ -49,8 +49,6 @@ unit cgcpu;
         procedure a_call_name_static_far(list : TAsmList;const s : string);
         procedure a_call_name_static_far(list : TAsmList;const s : string);
         procedure a_call_reg(list : TAsmList;reg : tregister);override;
         procedure a_call_reg(list : TAsmList;reg : tregister);override;
         procedure a_call_reg_far(list : TAsmList;reg : tregister);
         procedure a_call_reg_far(list : TAsmList;reg : tregister);
-        procedure a_call_ref(list : TAsmList;ref : treference);override;
-        procedure a_call_ref_far(list : TAsmList;ref : treference);
 
 
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override;
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override;
         procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; const ref: TReference); override;
         procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; const ref: TReference); override;
@@ -254,27 +252,12 @@ unit cgcpu;
         a_load_reg_ref(list,OS_32,OS_32,reg,href);
         a_load_reg_ref(list,OS_32,OS_32,reg,href);
         cg.getcpuregister(list,NR_BX);
         cg.getcpuregister(list,NR_BX);
         cg.getcpuregister(list,NR_SI);
         cg.getcpuregister(list,NR_SI);
-        a_call_ref_far(list,href);
+        href.refaddr:=addr_far_ref;
+        list.concat(taicpu.op_ref(A_CALL,S_NO,href));
         tg.ungettemp(list,href);
         tg.ungettemp(list,href);
       end;
       end;
 
 
 
 
-    procedure tcg8086.a_call_ref(list: TAsmList; ref: treference);
-      begin
-        if current_settings.x86memorymodel in x86_far_code_models then
-          a_call_ref_far(list,ref)
-        else
-          a_call_ref_near(list,ref);
-      end;
-
-
-    procedure tcg8086.a_call_ref_far(list: TAsmList; ref: treference);
-      begin
-        ref.refaddr:=addr_far_ref;
-        list.concat(taicpu.op_ref(A_CALL,S_NO,ref));
-      end;
-
-
     procedure tcg8086.a_op_const_reg(list: TAsmList; Op: TOpCG; size: TCGSize;
     procedure tcg8086.a_op_const_reg(list: TAsmList; Op: TOpCG; size: TCGSize;
       a: tcgint; reg: TRegister);
       a: tcgint; reg: TRegister);
       var
       var

+ 32 - 3
compiler/i8086/n8086cal.pas

@@ -28,13 +28,15 @@ interface
 { $define AnsiStrRef}
 { $define AnsiStrRef}
 
 
     uses
     uses
-      nx86cal;
+      nx86cal,cgutils;
 
 
     type
     type
        ti8086callnode = class(tx86callnode)
        ti8086callnode = class(tx86callnode)
        protected
        protected
           procedure pop_parasize(pop_size:longint);override;
           procedure pop_parasize(pop_size:longint);override;
           procedure extra_interrupt_code;override;
           procedure extra_interrupt_code;override;
+          procedure extra_call_ref_code(var ref: treference);override;
+          procedure do_call_ref(ref: treference);override;
        end;
        end;
 
 
 
 
@@ -43,11 +45,11 @@ implementation
     uses
     uses
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
-      cgbase,cgutils,
+      cgbase,
       cpubase,paramgr,
       cpubase,paramgr,
       aasmtai,aasmdata,aasmcpu,
       aasmtai,aasmdata,aasmcpu,
       ncal,nbas,nmem,nld,ncnv,
       ncal,nbas,nmem,nld,ncnv,
-      cga,cgobj,cpuinfo;
+      cga,cgobj,cgx86,cpuinfo;
 
 
 
 
 {*****************************************************************************
 {*****************************************************************************
@@ -92,6 +94,33 @@ implementation
       end;
       end;
 
 
 
 
+    procedure ti8086callnode.extra_call_ref_code(var ref: treference);
+      begin
+        if ref.base<>NR_NO 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;
+
+
+    procedure ti8086callnode.do_call_ref(ref: treference);
+      begin
+        if current_settings.x86memorymodel in x86_far_code_models then
+          ref.refaddr:=addr_far_ref;
+        current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_CALL,S_NO,ref));
+      end;
+
+
 begin
 begin
    ccallnode:=ti8086callnode;
    ccallnode:=ti8086callnode;
 end.
 end.

+ 58 - 27
compiler/ncgcal.pas

@@ -87,6 +87,14 @@ interface
             LOC_REFERENCE, this method will be called to perform the necessary
             LOC_REFERENCE, this method will be called to perform the necessary
             cleanups. By default it does not do anything }
             cleanups. By default it does not do anything }
           procedure do_release_unused_return_value;virtual;
           procedure do_release_unused_return_value;virtual;
+
+          { Override the following three methods to support calls to address in
+            'ref' without loading it into register (only x86 targets probably).
+            If can_call_ref returns true, it should do required simplification
+            on ref. }
+          function can_call_ref(var ref: treference):boolean;virtual;
+          procedure extra_call_ref_code(var ref: treference);virtual;
+          procedure do_call_ref(ref: treference);virtual;
        public
        public
           procedure pass_generate_code;override;
           procedure pass_generate_code;override;
           destructor destroy;override;
           destructor destroy;override;
@@ -415,6 +423,24 @@ implementation
       end;
       end;
 
 
 
 
+    function tcgcallnode.can_call_ref(var ref: treference): boolean;
+      begin
+        result:=false;
+      end;
+
+
+    procedure tcgcallnode.extra_call_ref_code(var ref: treference);
+      begin
+        { no action by default }
+      end;
+
+
+    procedure tcgcallnode.do_call_ref(ref: treference);
+      begin
+        InternalError(2014012901);
+      end;
+
+
     procedure tcgcallnode.set_result_location(realresdef: tstoreddef);
     procedure tcgcallnode.set_result_location(realresdef: tstoreddef);
       begin
       begin
         if realresdef.is_intregable or
         if realresdef.is_intregable or
@@ -757,6 +783,7 @@ implementation
         pd : tprocdef;
         pd : tprocdef;
         proc_addr_size: TCgSize;
         proc_addr_size: TCgSize;
         proc_addr_voidptrdef: tdef;
         proc_addr_voidptrdef: tdef;
+        callref: boolean;
 {$ifdef vtentry}
 {$ifdef vtentry}
         sym : tasmsymbol;
         sym : tasmsymbol;
 {$endif vtentry}
 {$endif vtentry}
@@ -884,10 +911,14 @@ implementation
                    tobjectdef(tprocdef(procdefinition).struct).register_vmt_call(tprocdef(procdefinition).extnumber);
                    tobjectdef(tprocdef(procdefinition).struct).register_vmt_call(tprocdef(procdefinition).extnumber);
 
 
                  reference_reset_base(href,vmtreg,vmtoffset,proc_addr_voidptrdef.alignment);
                  reference_reset_base(href,vmtreg,vmtoffset,proc_addr_voidptrdef.alignment);
-{$ifndef x86}
-                 pvreg:=cg.getintregister(current_asmdata.CurrAsmList,proc_addr_size);
-                 cg.a_load_ref_reg(current_asmdata.CurrAsmList,proc_addr_size,proc_addr_size,href,pvreg);
-{$endif not x86}
+                 pvreg:=NR_NO;
+
+                 callref:=can_call_ref(href);
+                 if not callref then
+                   begin
+                     pvreg:=cg.getintregister(current_asmdata.CurrAsmList,proc_addr_size);
+                     cg.a_load_ref_reg(current_asmdata.CurrAsmList,proc_addr_size,proc_addr_size,href,pvreg);
+                   end;
 
 
                  { Load parameters that are in temporary registers in the
                  { Load parameters that are in temporary registers in the
                    correct parameter register }
                    correct parameter register }
@@ -899,22 +930,9 @@ implementation
                      freeparas;
                      freeparas;
                    end;
                    end;
 
 
-{$ifdef i8086}
-                 if href.base<>NR_NO then
-                   begin
-                     cg.getcpuregister(current_asmdata.CurrAsmList,NR_BX);
-                     cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,href.base,NR_BX);
-                     href.base:=NR_BX;
-                     cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_BX);
-                   end;
-                 if href.index<>NR_NO then
-                   begin
-                     cg.getcpuregister(current_asmdata.CurrAsmList,NR_SI);
-                     cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,href.base,NR_SI);
-                     href.index:=NR_SI;
-                     cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_SI);
-                   end;
-{$endif i8086}
+                 if callref then
+                   extra_call_ref_code(href);
+
                  cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int);
                  cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int);
                  if cg.uses_registers(R_ADDRESSREGISTER) then
                  if cg.uses_registers(R_ADDRESSREGISTER) then
                    cg.alloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address);
                    cg.alloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address);
@@ -925,11 +943,11 @@ implementation
 
 
                  { call method }
                  { call method }
                  extra_call_code;
                  extra_call_code;
-{$ifdef x86}
-                 hlcg.a_call_ref(current_asmdata.CurrAsmList,tabstractprocdef(procdefinition),href);
-{$else x86}
-                 hlcg.a_call_reg(current_asmdata.CurrAsmList,tabstractprocdef(procdefinition),pvreg);
-{$endif x86}
+                 if callref then
+                   do_call_ref(href)
+                 else
+                   hlcg.a_call_reg(current_asmdata.CurrAsmList,tabstractprocdef(procdefinition),pvreg);
+
                  extra_post_call_code;
                  extra_post_call_code;
                end
                end
              else
              else
@@ -977,12 +995,18 @@ implementation
            { now procedure variable case }
            { now procedure variable case }
            begin
            begin
               secondpass(right);
               secondpass(right);
+              callref:=false;
 
 
               pvreg:=cg.getintregister(current_asmdata.CurrAsmList,proc_addr_size);
               pvreg:=cg.getintregister(current_asmdata.CurrAsmList,proc_addr_size);
               { Only load OS_ADDR from the reference (when converting to hlcg:
               { Only load OS_ADDR from the reference (when converting to hlcg:
                 watch out with procedure of object) }
                 watch out with procedure of object) }
               if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
               if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
-                cg.a_load_ref_reg(current_asmdata.CurrAsmList,proc_addr_size,proc_addr_size,right.location.reference,pvreg)
+                begin
+                  href:=right.location.reference;
+                  callref:=can_call_ref(href);
+                  if not callref then
+                    cg.a_load_ref_reg(current_asmdata.CurrAsmList,proc_addr_size,proc_addr_size,right.location.reference,pvreg)
+                end
               else if right.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
               else if right.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
                 begin
                 begin
                   { in case left is a method pointer and we are on a big endian target, then
                   { in case left is a method pointer and we are on a big endian target, then
@@ -1005,6 +1029,9 @@ implementation
                   freeparas;
                   freeparas;
                 end;
                 end;
 
 
+              if callref then
+                extra_call_ref_code(href);
+
               cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int);
               cg.alloccpuregisters(current_asmdata.CurrAsmList,R_INTREGISTER,regs_to_save_int);
               if cg.uses_registers(R_ADDRESSREGISTER) then
               if cg.uses_registers(R_ADDRESSREGISTER) then
                 cg.alloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address);
                 cg.alloccpuregisters(current_asmdata.CurrAsmList,R_ADDRESSREGISTER,regs_to_save_address);
@@ -1018,7 +1045,11 @@ implementation
               if (po_interrupt in procdefinition.procoptions) then
               if (po_interrupt in procdefinition.procoptions) then
                 extra_interrupt_code;
                 extra_interrupt_code;
               extra_call_code;
               extra_call_code;
-              hlcg.a_call_reg(current_asmdata.CurrAsmList,tabstractprocdef(procdefinition),pvreg);
+
+              if callref then
+                do_call_ref(href)
+              else
+                hlcg.a_call_reg(current_asmdata.CurrAsmList,procdefinition,pvreg);
               extra_post_call_code;
               extra_post_call_code;
            end;
            end;
 
 

+ 0 - 14
compiler/x86/cgx86.pas

@@ -61,8 +61,6 @@ unit cgx86;
         procedure a_call_name_static_near(list : TAsmList;const s : string);
         procedure a_call_name_static_near(list : TAsmList;const s : string);
         procedure a_call_reg(list : TAsmList;reg : tregister);override;
         procedure a_call_reg(list : TAsmList;reg : tregister);override;
         procedure a_call_reg_near(list : TAsmList;reg : tregister);
         procedure a_call_reg_near(list : TAsmList;reg : tregister);
-        procedure a_call_ref(list : TAsmList;ref : treference);override;
-        procedure a_call_ref_near(list : TAsmList;ref : treference);
 
 
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override;
         procedure a_op_const_reg(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg: TRegister); override;
         procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; const ref: TReference); override;
         procedure a_op_const_ref(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; const ref: TReference); override;
@@ -850,18 +848,6 @@ unit cgx86;
       end;
       end;
 
 
 
 
-    procedure tcgx86.a_call_ref(list : TAsmList;ref : treference);
-      begin
-        a_call_ref_near(list,ref);
-      end;
-
-
-    procedure tcgx86.a_call_ref_near(list: TAsmList; ref: treference);
-      begin
-        list.concat(taicpu.op_ref(A_CALL,S_NO,ref));
-      end;
-
-
 {********************** load instructions ********************}
 {********************** load instructions ********************}
 
 
     procedure tcgx86.a_load_const_reg(list : TAsmList; tosize: TCGSize; a : tcgint; reg : TRegister);
     procedure tcgx86.a_load_const_reg(list : TAsmList; tosize: TCGSize; a : tcgint; reg : TRegister);

+ 16 - 1
compiler/x86/nx86cal.pas

@@ -29,6 +29,7 @@ interface
 
 
     uses
     uses
       symdef,
       symdef,
+      cgutils,
       ncgcal;
       ncgcal;
 
 
     type
     type
@@ -39,6 +40,8 @@ interface
         protected
         protected
          procedure do_release_unused_return_value;override;
          procedure do_release_unused_return_value;override;
          procedure set_result_location(realresdef: tstoreddef);override;
          procedure set_result_location(realresdef: tstoreddef);override;
+         function can_call_ref(var ref: treference):boolean;override;
+         procedure do_call_ref(ref: treference);override;
        end;
        end;
 
 
 
 
@@ -46,7 +49,7 @@ implementation
 
 
     uses
     uses
       cgobj,
       cgobj,
-      cgbase,cgutils,cpubase,cgx86,cga;
+      cgbase,cpubase,cgx86,cga,aasmdata,aasmcpu;
 
 
 
 
 {*****************************************************************************
 {*****************************************************************************
@@ -81,4 +84,16 @@ implementation
     end;
     end;
 
 
 
 
+  function tx86callnode.can_call_ref(var ref: treference): boolean;
+    begin
+      tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,ref);
+      result:=true;
+    end;
+
+
+  procedure tx86callnode.do_call_ref(ref: treference);
+    begin
+      current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_CALL,S_NO,ref));
+    end;
+
 end.
 end.