Pārlūkot izejas kodu

+ added support for units with code larger than 64kb in the far code i8086
memory models. Enabled by the new directive {$hugecode on}. The directive is
ignored in the near code memory models. When enabled, it forces each procedure
to be in a separate segment and disables mixing near and far procedures (so
'near' and {$F-} are ignored in this mode). Note that {$hugecode on} does not
count as a different memory model, because you can freely link modules (units)
compiled with {$hugecode on} and {$hugecode off}.

git-svn-id: trunk@27615 -

nickysn 11 gadi atpakaļ
vecāks
revīzija
597f110eb9

+ 3 - 1
compiler/globtype.pas

@@ -164,7 +164,9 @@ interface
          { browser switches are back }
          { browser switches are back }
          cs_browser,cs_local_browser,
          cs_browser,cs_local_browser,
          { target specific }
          { target specific }
-         cs_executable_stack
+         cs_executable_stack,
+         { i8086 specific }
+         cs_huge_code
        );
        );
        tmoduleswitches = set of tmoduleswitch;
        tmoduleswitches = set of tmoduleswitch;
 
 

+ 4 - 2
compiler/i8086/symcpu.pas

@@ -222,7 +222,8 @@ implementation
     begin
     begin
       inherited create(level);
       inherited create(level);
       if (current_settings.x86memorymodel in x86_far_code_models) and
       if (current_settings.x86memorymodel in x86_far_code_models) and
-         (cs_force_far_calls in current_settings.localswitches) then
+         ((cs_huge_code in current_settings.moduleswitches) or
+          (cs_force_far_calls in current_settings.localswitches)) then
         procoptions:=procoptions+[po_far];
         procoptions:=procoptions+[po_far];
     end;
     end;
 
 
@@ -247,7 +248,8 @@ implementation
 
 
   procedure tcpuprocdef.declared_near;
   procedure tcpuprocdef.declared_near;
     begin
     begin
-      if current_settings.x86memorymodel in x86_far_code_models then
+      if (current_settings.x86memorymodel in x86_far_code_models) and
+         not (cs_huge_code in current_settings.moduleswitches) then
         exclude(procoptions,po_far)
         exclude(procoptions,po_far)
       else
       else
         inherited declared_near;
         inherited declared_near;

+ 15 - 0
compiler/scandir.pas

@@ -1516,6 +1516,20 @@ unit scandir;
       begin
       begin
       end;
       end;
 
 
+    procedure dir_hugecode;
+      begin
+        if (target_info.system<>system_i8086_msdos)
+{$ifdef i8086}
+           or (current_settings.x86memorymodel in x86_near_code_models)
+{$endif i8086}
+            then
+          begin
+            Message1(scan_n_ignored_switch,pattern);
+            exit;
+          end;
+        do_moduleswitch(cs_huge_code);
+      end;
+
     procedure dir_weakpackageunit;
     procedure dir_weakpackageunit;
       begin
       begin
       end;
       end;
@@ -1618,6 +1632,7 @@ unit scandir;
         AddDirective('HINT',directive_all, @dir_hint);
         AddDirective('HINT',directive_all, @dir_hint);
         AddDirective('HINTS',directive_all, @dir_hints);
         AddDirective('HINTS',directive_all, @dir_hints);
         AddDirective('HPPEMIT',directive_all, @dir_hppemit);
         AddDirective('HPPEMIT',directive_all, @dir_hppemit);
+        AddDirective('HUGECODE',directive_all, @dir_hugecode);
         AddDirective('IEEEERRORS',directive_all,@dir_ieeeerrors);
         AddDirective('IEEEERRORS',directive_all,@dir_ieeeerrors);
         AddDirective('IOCHECKS',directive_all, @dir_iochecks);
         AddDirective('IOCHECKS',directive_all, @dir_iochecks);
         AddDirective('IMAGEBASE',directive_all, @dir_imagebase);
         AddDirective('IMAGEBASE',directive_all, @dir_imagebase);

+ 11 - 6
compiler/x86/agx86nsm.pas

@@ -37,7 +37,7 @@ interface
       TX86NasmAssembler = class(texternalassembler)
       TX86NasmAssembler = class(texternalassembler)
       private
       private
         using_relative : boolean;
         using_relative : boolean;
-        function CodeSectionName: string;
+        function CodeSectionName(const aname:string): string;
         procedure WriteReference(var ref : treference);
         procedure WriteReference(var ref : treference);
         procedure WriteOper(const o:toper;s : topsize; opcode: tasmop;ops:longint;dest : boolean);
         procedure WriteOper(const o:toper;s : topsize; opcode: tasmop;ops:longint;dest : boolean);
         procedure WriteOper_jmp(const o:toper; ai : taicpu);
         procedure WriteOper_jmp(const o:toper; ai : taicpu);
@@ -312,11 +312,16 @@ interface
  ****************************************************************************}
  ****************************************************************************}
 
 
 
 
-    function TX86NasmAssembler.CodeSectionName: string;
+    function TX86NasmAssembler.CodeSectionName(const aname:string): string;
       begin
       begin
 {$ifdef i8086}
 {$ifdef i8086}
         if current_settings.x86memorymodel in x86_far_code_models then
         if current_settings.x86memorymodel in x86_far_code_models then
-          result:=current_module.modulename^ + '_TEXT'
+          begin
+            if cs_huge_code in current_settings.moduleswitches then
+              result:=aname + '_TEXT use16 class=code'
+            else
+              result:=current_module.modulename^ + '_TEXT';
+          end
         else
         else
 {$endif}
 {$endif}
           result:='.text';
           result:='.text';
@@ -581,7 +586,7 @@ interface
           (target_info.system in (systems_windows+systems_wince)) then
           (target_info.system in (systems_windows+systems_wince)) then
           AsmWrite('.tls'#9'bss')
           AsmWrite('.tls'#9'bss')
         else if secnames[atype]='.text' then
         else if secnames[atype]='.text' then
-          AsmWrite(CodeSectionName)
+          AsmWrite(CodeSectionName(aname))
         else
         else
           AsmWrite(secnames[atype]);
           AsmWrite(secnames[atype]);
         if create_smartlink_sections and
         if create_smartlink_sections and
@@ -1211,7 +1216,7 @@ interface
           internalerror(2013050101);
           internalerror(2013050101);
       end;
       end;
 
 
-      AsmWriteLn('SECTION ' + CodeSectionName + ' use16 class=code');
+      AsmWriteLn('SECTION ' + CodeSectionName(current_module.modulename^) + ' use16 class=code');
       { NASM complains if you put a missing section in the GROUP directive, so }
       { NASM complains if you put a missing section in the GROUP directive, so }
       { we add empty declarations to make sure they exist, even if empty }
       { we add empty declarations to make sure they exist, even if empty }
       AsmWriteLn('SECTION .rodata');
       AsmWriteLn('SECTION .rodata');
@@ -1231,7 +1236,7 @@ interface
           AsmWriteLn('SECTION .debug_line   use32 class=DWARF');
           AsmWriteLn('SECTION .debug_line   use32 class=DWARF');
           AsmWriteLn('SECTION .debug_abbrev use32 class=DWARF');
           AsmWriteLn('SECTION .debug_abbrev use32 class=DWARF');
         end;
         end;
-      AsmWriteLn('SECTION ' + CodeSectionName);
+      AsmWriteLn('SECTION ' + CodeSectionName(current_module.modulename^));
 {$else i8086}
 {$else i8086}
 {$ifdef i386}
 {$ifdef i386}
       AsmWriteLn('BITS 32');
       AsmWriteLn('BITS 32');