Browse Source

+ added method is_far to i8086's tcpuprocdef and tcpuprocvardef
+ added helper function to i8086's symcpu is_proc_far that dispatches the call
to the proper is_far method (because we can't make a cpu specific descendant
of tabstractprocdef and add it there)
* all checks for (po_far in procoptions) in the i8086 code generator replaced
with calls to is_proc_far

git-svn-id: trunk@27559 -

nickysn 11 years ago
parent
commit
6fe362a1b0
4 changed files with 43 additions and 13 deletions
  1. 2 2
      compiler/i8086/cgcpu.pas
  2. 6 6
      compiler/i8086/cpupara.pas
  3. 3 3
      compiler/i8086/n8086cnv.pas
  4. 32 2
      compiler/i8086/symcpu.pas

+ 2 - 2
compiler/i8086/cgcpu.pas

@@ -120,7 +120,7 @@ unit cgcpu;
        globals,verbose,systems,cutils,
        paramgr,procinfo,fmodule,
        rgcpu,rgx86,cpuinfo,
-       symtype,symsym,
+       symtype,symsym,symcpu,
        tgobj,
        hlcgobj;
 
@@ -1735,7 +1735,7 @@ unit cgcpu;
         stacksize : longint;
         ret_instr: TAsmOp;
       begin
-        if po_far in current_procinfo.procdef.procoptions then
+        if is_proc_far(current_procinfo.procdef) then
           ret_instr:=A_RETF
         else
           ret_instr:=A_RET;

+ 6 - 6
compiler/i8086/cpupara.pas

@@ -67,7 +67,7 @@ unit cpupara;
     uses
        cutils,
        systems,verbose,
-       symtable,
+       symtable,symcpu,
        defutil;
 
       const
@@ -423,7 +423,7 @@ unit cpupara;
         paraalign:=get_para_align(p.proccalloption);
         { interrupt routines need parameter fixup }
         if po_interrupt in p.procoptions then
-          if po_far in p.procoptions then
+          if is_proc_far(p) then
             dec(parasize,6)
           else
             dec(parasize,4);
@@ -499,7 +499,7 @@ unit cpupara;
                 if side=calleeside then
                   begin
                     inc(paraloc^.reference.offset,target_info.first_parm_offset);
-                    if po_far in p.procoptions then
+                    if is_proc_far(p) then
                       inc(paraloc^.reference.offset,2);
                   end;
                 parasize:=align(parasize+paralen,varalign);
@@ -549,7 +549,7 @@ unit cpupara;
                         else
                           { return addres }
                           inc(paraloc^.reference.offset,2);
-                        if po_far in p.procoptions then
+                        if is_proc_far(p) then
                           inc(paraloc^.reference.offset,2);
                       end;
                     parasize:=align(parasize+l,varalign);
@@ -672,7 +672,7 @@ unit cpupara;
                               if side=calleeside then
                                 begin
                                   inc(paraloc^.reference.offset,target_info.first_parm_offset);
-                                  if po_far in p.procoptions then
+                                  if is_proc_far(p) then
                                     inc(paraloc^.reference.offset,2);
                                 end;
                               parasize:=align(parasize+paralen,varalign);
@@ -717,7 +717,7 @@ unit cpupara;
                                   if side=calleeside then
                                     begin
                                       inc(paraloc^.reference.offset,target_info.first_parm_offset);
-                                      if po_far in p.procoptions then
+                                      if is_proc_far(p) then
                                         inc(paraloc^.reference.offset,2);
                                     end;
                                   parasize:=align(parasize+l,varalign);

+ 3 - 3
compiler/i8086/n8086cnv.pas

@@ -41,7 +41,7 @@ implementation
    uses
       verbose,systems,globals,globtype,
       aasmbase,aasmtai,aasmdata,aasmcpu,
-      symconst,symdef,
+      symconst,symdef,symcpu,
       cgbase,cga,procinfo,pass_1,pass_2,
       ncon,ncal,ncnv,
       cpubase,cpuinfo,
@@ -54,7 +54,7 @@ implementation
         tmpreg: tregister;
         tmpref: treference;
       begin
-        if not (po_far in tabstractprocdef(resultdef).procoptions) then
+        if not is_proc_far(tabstractprocdef(resultdef)) then
           begin
             inherited;
             exit;
@@ -148,7 +148,7 @@ implementation
             location.registerhi:=cg.getaddressregister(current_asmdata.currasmlist);
             cg.a_load_const_reg(current_asmdata.currasmlist,OS_ADDR,0,location.registerhi);
           end;
-        if (resultdef.typ=procvardef) and (po_far in tprocvardef(resultdef).procoptions) then
+        if (resultdef.typ=procvardef) and is_proc_far(tprocvardef(resultdef)) then
           begin
             location.register:=cg.getintregister(current_asmdata.currasmlist,OS_32);
             cg.a_load_const_reg(current_asmdata.currasmlist,OS_32,0,location.register);

+ 32 - 2
compiler/i8086/symcpu.pas

@@ -92,6 +92,7 @@ type
 
   tcpuprocvardef = class(ti86procvardef)
     constructor create(level:byte);override;
+    function is_far:boolean;
   end;
   tcpuprocvardefclass = class of tcpuprocvardef;
 
@@ -100,6 +101,7 @@ type
   tcpuprocdef = class(ti86procdef)
     constructor create(level:byte);override;
     function address_type:tdef;override;
+    function is_far:boolean;
   end;
   tcpuprocdefclass = class of tcpuprocdef;
 
@@ -182,10 +184,25 @@ const
    pbestrealtype : ^tdef = @s80floattype;
 
 
+  function is_proc_far(p: tabstractprocdef): boolean;
+
+
 implementation
 
   uses
-    globals, cpuinfo;
+    globals, cpuinfo, verbose;
+
+
+  function is_proc_far(p: tabstractprocdef): boolean;
+  begin
+    if p is tcpuprocdef then
+      result:=tcpuprocdef(p).is_far
+    else if p is tcpuprocvardef then
+      result:=tcpuprocvardef(p).is_far
+    else
+      internalerror(2014041301);
+  end;
+
 
 {****************************************************************************
                              tcpuprocdef
@@ -202,12 +219,18 @@ implementation
 
   function tcpuprocdef.address_type: tdef;
     begin
-      if po_far in procoptions then
+      if is_far then
         result:=voidfarpointertype
       else
         result:=voidnearpointertype;
     end;
 
+
+  function tcpuprocdef.is_far: boolean;
+    begin
+      result:=po_far in procoptions;
+    end;
+
 {****************************************************************************
                              tcpuprocvardef
 ****************************************************************************}
@@ -220,6 +243,13 @@ implementation
         procoptions:=procoptions+[po_far];
     end;
 
+
+  function tcpuprocvardef.is_far: boolean;
+    begin
+      { procvars are always far in the far code memory models }
+      result:=current_settings.x86memorymodel in x86_far_code_models;
+    end;
+
 {****************************************************************************
                              tcpupointerdef
 ****************************************************************************}