Explorar o código

+ added support for 'external far' variables for i8086

git-svn-id: trunk@37532 -
nickysn %!s(int64=7) %!d(string=hai) anos
pai
achega
303309b28f
Modificáronse 4 ficheiros con 66 adicións e 53 borrados
  1. 52 52
      compiler/i8086/n8086ld.pas
  2. 8 0
      compiler/pdecvar.pas
  3. 3 1
      compiler/symconst.pas
  4. 3 0
      compiler/systems.pas

+ 52 - 52
compiler/i8086/n8086ld.pas

@@ -187,70 +187,70 @@ implementation
         segreg: TRegister;
         newsize: TCgSize;
       begin
-        if current_settings.x86memorymodel=mm_huge then
-          begin
-            case symtableentry.typ of
-              staticvarsym:
+        case symtableentry.typ of
+          staticvarsym:
+            begin
+              gvs:=tstaticvarsym(symtableentry);
+              if (vo_is_dll_var in gvs.varoptions) then
+              { DLL variable }
+                begin
+                  inherited pass_generate_code;
+                  exit;
+                end
+              { Thread variable }
+              else if (vo_is_thread_var in gvs.varoptions) then
                 begin
-                  gvs:=tstaticvarsym(symtableentry);
-                  if (vo_is_dll_var in gvs.varoptions) then
-                  { DLL variable }
+                  { this will be handled in ti8086loadnode.generate_threadvar_access }
+                  inherited pass_generate_code;
+                  exit;
+                end
+              { Normal (or external) variable }
+              else
+                begin
+                  if (current_settings.x86memorymodel<>mm_huge) and not (vo_is_far in gvs.varoptions) then
                     begin
                       inherited pass_generate_code;
                       exit;
-                    end
-                  { Thread variable }
-                  else if (vo_is_thread_var in gvs.varoptions) then
+                    end;
+                  if not (vo_is_external in gvs.varoptions) and gvs.Owner.iscurrentunit then
                     begin
-                      { this will be handled in ti8086loadnode.generate_threadvar_access }
                       inherited pass_generate_code;
                       exit;
-                    end
-                  { Normal (or external) variable }
-                  else
+                    end;
+
+                  { we don't know the size of all arrays }
+                  newsize:=def_cgsize(resultdef);
+                  { alignment is overridden per case below }
+                  location_reset_ref(location,LOC_REFERENCE,newsize,resultdef.alignment,[]);
+
+                  if gvs.localloc.loc=LOC_INVALID then
                     begin
-                      if not (vo_is_external in gvs.varoptions) and gvs.Owner.iscurrentunit then
-                        begin
-                          inherited pass_generate_code;
-                          exit;
-                        end;
-
-                      { we don't know the size of all arrays }
-                      newsize:=def_cgsize(resultdef);
-                      { alignment is overridden per case below }
-                      location_reset_ref(location,LOC_REFERENCE,newsize,resultdef.alignment,[]);
-
-                      if gvs.localloc.loc=LOC_INVALID then
-                        begin
-                          if not(vo_is_weak_external in gvs.varoptions) then
-                            refsym:=current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA)
-                          else
-                            refsym:=current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA);
-
-                          segreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
-
-                          reference_reset_symbol(segref,refsym,0,0,[]);
-                          segref.refaddr:=addr_seg;
-                          cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,segref,segreg);
-
-                          reference_reset_symbol(location.reference,refsym,0,location.reference.alignment,[]);
-                          location.reference.segment:=segreg;
-                        end
+                      if not(vo_is_weak_external in gvs.varoptions) then
+                        refsym:=current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA)
                       else
-                        location:=gvs.localloc;
-                    end;
+                        refsym:=current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA);
+
+                      segreg:=cg.getintregister(current_asmdata.CurrAsmList,OS_16);
 
-                  { make const a LOC_CREFERENCE }
-                  if (gvs.varspez=vs_const) and
-                     (location.loc=LOC_REFERENCE) then
-                    location.loc:=LOC_CREFERENCE;
+                      reference_reset_symbol(segref,refsym,0,0,[]);
+                      segref.refaddr:=addr_seg;
+                      cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_16,OS_16,segref,segreg);
+
+                      reference_reset_symbol(location.reference,refsym,0,location.reference.alignment,[]);
+                      location.reference.segment:=segreg;
+                    end
+                  else
+                    location:=gvs.localloc;
                 end;
-              else
-                inherited pass_generate_code;
+
+              { make const a LOC_CREFERENCE }
+              if (gvs.varspez=vs_const) and
+                 (location.loc=LOC_REFERENCE) then
+                location.loc:=LOC_CREFERENCE;
             end;
-          end
-        else
-          inherited pass_generate_code;
+          else
+            inherited pass_generate_code;
+        end;
       end;
 
 

+ 8 - 0
compiler/pdecvar.pas

@@ -871,6 +871,7 @@ implementation
     procedure read_public_and_external(vs: tabstractvarsym);
     var
       is_dll,
+      is_far,
       is_cdecl,
       is_external_var,
       is_weak_external,
@@ -887,6 +888,7 @@ implementation
         end;
       { defaults }
       is_dll:=false;
+      is_far:=false;
       is_cdecl:=false;
       is_external_var:=false;
       is_public_var:=false;
@@ -922,6 +924,10 @@ implementation
          try_to_consume(_EXTERNAL) then
         begin
           is_external_var:=true;
+          { far? }
+          if (target_info.system in systems_allow_external_far_var) and
+             try_to_consume(_FAR) then
+            is_far:=true;
           if (idtoken<>_NAME) and (token<>_SEMICOLON) then
             begin
               is_dll:=true;
@@ -988,6 +994,8 @@ implementation
           if vo_is_typed_const in vs.varoptions then
             Message(parser_e_initialized_not_for_external);
           include(vs.varoptions,vo_is_external);
+          if is_far then
+            include(vs.varoptions,vo_is_far);
           if (is_weak_external) then
             begin
               if not(target_info.system in systems_weak_linking) then

+ 3 - 1
compiler/symconst.pas

@@ -586,7 +586,9 @@ type
     vo_force_finalize,
     { this is an internal variable that is used for Default() intrinsic in code
       sections }
-    vo_is_default_var
+    vo_is_default_var,
+    { i8086 'external far' (can only be used in combination with vo_is_external) }
+    vo_is_far
   );
   tvaroptions=set of tvaroption;
 

+ 3 - 0
compiler/systems.pas

@@ -285,6 +285,9 @@ interface
 {$endif not DISABLE_TLS_DIRECTORY}
        ;
 
+       { systems that allow external far variables }
+       systems_allow_external_far_var = [system_i8086_msdos,system_i8086_win16,system_i8086_embedded];
+
        { all symbian systems }
        systems_symbian = [system_i386_symbian,system_arm_symbian];