Pārlūkot izejas kodu

* cleaned up segmented thread variables

git-svn-id: trunk@2135 -
florian 19 gadi atpakaļ
vecāks
revīzija
61e3b70cfa

+ 4 - 0
compiler/aggas.pas

@@ -235,6 +235,10 @@ implementation
         else
           secname:=secnames[atype];
 
+        if (atype=sec_threadvar) and
+          (target_info.system=system_i386_win32) then
+          secname:='.tls';
+
         if use_smartlink_section and
            (aname<>'') then
           result:=secname+'.'+aname

+ 2 - 3
compiler/assemble.pas

@@ -1412,9 +1412,8 @@ Implementation
           exclude(to_do,al_exports);
         {$warning TODO internal writer support for dwarf}
         exclude(to_do,al_dwarf);
-{$ifndef segment_threadvars}
-        exclude(to_do,al_threadvars);
-{$endif}
+        if not(tf_section_threadvars in target_info.flags) then
+          exclude(to_do,al_threadvars);
         for i:=low(Tasmlist) to high(Tasmlist) do
           if (i in to_do) and (asmlist[i]<>nil) then
             addlist(asmlist[i]);

+ 0 - 2
compiler/i386/cgcpu.pas

@@ -208,10 +208,8 @@ unit cgcpu;
       begin
         with r do
           begin
-{$ifndef segment_threadvars}
             if (segment<>NR_NO) then
               cgmessage(cg_e_cant_use_far_pointer_there);
-{$endif}
             if use_push(cgpara) then
               begin
                 cgpara.check_simple_location;

+ 14 - 7
compiler/ncgld.pas

@@ -134,9 +134,9 @@ implementation
                       cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,location.reference,hregister);
                       reference_reset_base(location.reference,hregister,0);
                     end
-{$ifndef segment_threadvars}
                   { Thread variable }
-                  else if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then
+                  else if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) and
+                    not(tf_section_threadvars in target_info.flags) then
                     begin
                        {
                          Thread var loading is optimized to first check if
@@ -181,7 +181,6 @@ implementation
                        cg.a_label(exprasmlist,endrelocatelab);
                        location.reference.base:=hregister;
                     end
-{$endif}
                   { Nested variable }
                   else if assigned(left) then
                     begin
@@ -233,10 +232,18 @@ implementation
                                     reference_reset_symbol(location.reference,objectlibrary.newasmsymbol(tglobalvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA),0)
                                   else
                                     location:=tglobalvarsym(symtableentry).localloc;
-{$ifdef segment_threadvars}
-                                  if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then
-                                    location.reference.segment:=NR_GS;
-{$endif}
+{$ifdef i386}
+                                  if (tf_section_threadvars in target_info.flags) and
+                                     (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then
+                                    begin
+                                      case target_info.system of
+                                        system_i386_linux:
+                                          location.reference.segment:=NR_GS;
+                                        system_i386_win32:
+                                          location.reference.segment:=NR_FS;
+                                      end;
+                                    end;
+{$endif i386}
                                 end;
                               else
                                 internalerror(200305102);

+ 15 - 12
compiler/ncgutil.pas

@@ -1940,23 +1940,26 @@ implementation
         storefilepos:=aktfilepos;
         aktfilepos:=sym.fileinfo;
         l:=sym.getsize;
-     {$ifndef segment_threadvars}
-        if (vo_is_thread_var in sym.varoptions) then
-          inc(l,sizeof(aint));
-        list:=asmlist[al_globals];
-        sectype:=sec_bss;
-     {$else}
-        if (vo_is_thread_var in sym.varoptions) then
+        if tf_section_threadvars in target_info.flags then
           begin
-            list:=asmlist[al_threadvars];
-            sectype:=sec_threadvar;
+            if (vo_is_thread_var in sym.varoptions) then
+              begin
+                list:=asmlist[al_threadvars];
+                sectype:=sec_threadvar;
+              end
+            else
+              begin
+                list:=asmlist[al_globals];
+                sectype:=sec_bss;
+              end;
           end
         else
           begin
+            if (vo_is_thread_var in sym.varoptions) then
+              inc(l,sizeof(aint));
             list:=asmlist[al_globals];
             sectype:=sec_bss;
           end;
-     {$endif}
         varalign:=var_align(l);
         maybe_new_object_file(list);
         new_section(list,sectype,lower(sym.mangledname),varalign);
@@ -2065,8 +2068,8 @@ implementation
                               staticsymtable :
                                 begin
                                   { PIC, DLL and Threadvar need extra code and are handled in ncgld }
-                                  if not(vo_is_dll_var in varoptions) {$ifndef segment_threadvars} and
-                                     not(vo_is_thread_var in varoptions) {$endif} then
+                                  if not(vo_is_dll_var in varoptions) and ((tf_section_threadvars in target_info.flags) or
+                                     not(vo_is_thread_var in varoptions)) then
                                     reference_reset_symbol(localloc.reference,objectlibrary.newasmsymbol(mangledname,AB_EXTERNAL,AT_DATA),0);
                                 end;
                               else

+ 1 - 1
compiler/ogcoff.pas

@@ -553,7 +553,7 @@ const go32v2stub : array[0..2047] of byte=(
     function TCoffObjectData.sectionname(atype:tasmsectiontype;const aname:string):string;
       const
         secnames : array[tasmsectiontype] of string[16] = ('',
-          '.text','.data','.data','.bss','.threadvar',
+          '.text','.data','.data','.bss','.tls',
           'common',
           '.note',
           '.text',

+ 2 - 3
compiler/ogelf.pas

@@ -320,9 +320,8 @@ implementation
         createsection(sec_code,'',0,[]);
         createsection(sec_data,'',0,[]);
         createsection(sec_bss,'',0,[]);
-{$ifdef segment_threadvars}
-        createsection(sec_threadvar,'',0,[]);
-{$endif}
+        if tf_section_threadvars in target_info.flags then
+          createsection(sec_threadvar,'',0,[]);
         { create stabs sections if debugging }
         if (cs_debuginfo in aktmoduleswitches) then
          begin

+ 9 - 11
compiler/pmodules.pas

@@ -143,7 +143,6 @@ implementation
       end;
 
 
-{$ifndef segment_threadvars}
     procedure InsertThreadvarTablesTable;
       var
         hp : tused_unit;
@@ -219,7 +218,7 @@ implementation
           end;
          ltvTable.Free;
       end;
-{$endif}
+
 
     Procedure InsertResourceInfo;
 
@@ -1189,9 +1188,8 @@ implementation
          gen_pic_helpers(asmlist[al_procedures]);
 
          { generate a list of threadvars }
-{$ifndef segment_threadvars}
-         InsertThreadvars;
-{$endif}
+         if not(tf_section_threadvars in target_info.flags) then
+           InsertThreadvars;
 
          { generate imports }
          if current_module.uses_imports then
@@ -1512,10 +1510,10 @@ implementation
 
          { generate pic helpers to load eip if necessary }
          gen_pic_helpers(asmlist[al_procedures]);
-{$ifndef segment_threadvars}
+
          { generate a list of threadvars }
-         InsertThreadvars;
-{$endif}
+         if not(tf_section_threadvars in target_info.flags) then
+           InsertThreadvars;
 
          { generate imports }
          if current_module.uses_imports then
@@ -1525,9 +1523,9 @@ implementation
            exportlib.generatelib;
 
          { insert Tables and StackLength }
-{$ifndef segment_threadvars}
-         insertThreadVarTablesTable;
-{$endif}
+         if not(tf_section_threadvars in target_info.flags) then
+           insertThreadVarTablesTable;
+
          insertResourceTablesTable;
          insertinitfinaltable;
          insertmemorysizes;

+ 6 - 3
compiler/systems.pas

@@ -248,15 +248,18 @@ interface
 
        tsystemflags = (tf_none,
             tf_under_development,
-            tf_need_export,tf_needs_isconsole,
-            tf_code_small,tf_static_reg_based,
+            tf_need_export,
+            tf_needs_isconsole,
+            tf_code_small,
+            tf_static_reg_based,
             tf_needs_symbol_size,
             tf_smartlink_sections,
             tf_needs_dwarf_cfi,
             tf_use_8_3,
             tf_pic_uses_got,
             tf_library_needs_pic,
-            tf_needs_symbol_type
+            tf_needs_symbol_type,
+            tf_section_threadvars
        );
 
        psysteminfo = ^tsysteminfo;

+ 5 - 1
compiler/systems/i_linux.pas

@@ -46,7 +46,11 @@ unit i_linux;
             system       : system_i386_LINUX;
             name         : 'Linux for i386';
             shortname    : 'Linux';
-            flags        : [tf_needs_symbol_size,tf_pic_uses_got{,tf_smartlink_sections},tf_needs_symbol_type];
+            flags        : [tf_needs_symbol_size,tf_pic_uses_got{,tf_smartlink_sections},
+{$ifdef segment_threadvars}
+                            tf_section_threadvars,
+{$endif segment_threadvars}
+                            tf_needs_symbol_type];
             cpu          : cpu_i386;
             unit_env     : 'LINUXUNITS';
             extradefines : 'UNIX;HASUNIX';

+ 1 - 1
compiler/systems/i_win.pas

@@ -32,7 +32,7 @@ unit i_win;
             system       : system_i386_WIN32;
             name         : 'Win32 for i386';
             shortname    : 'Win32';
-            flags        : [];
+            flags        : [{tf_section_threadvars}];
             cpu          : cpu_i386;
             unit_env     : 'WIN32UNITS';
             extradefines : 'MSWINDOWS';

+ 35 - 14
compiler/x86/cgx86.pas

@@ -766,20 +766,41 @@ unit cgx86;
                 make_simple_ref(list,tmpref);
                 list.concat(Taicpu.op_ref_reg(A_LEA,tcgsize2opsize[OS_ADDR],tmpref,r));
               end;
-            if (segment<>NR_NO) then
-              if segment=NR_GS then
-                begin
-{$ifdef segment_threadvars}
-                  {Convert thread local address to a process global addres
-                   as we cannot handle far pointers.}
-                  reference_reset_symbol(tmpref,objectlibrary.newasmsymbol(
-                    '___fpc_threadvar_offset',AB_EXTERNAL,AT_DATA),0);
-                  tmpref.segment:=NR_GS;
-                  list.concat(Taicpu.op_ref_reg(A_ADD,tcgsize2opsize[OS_ADDR],tmpref,r));
-{$endif}
-                end
-            else
-              cgmessage(cg_e_cant_use_far_pointer_there);
+            if segment<>NR_NO then
+              begin
+                if (tf_section_threadvars in target_info.flags) then
+                  begin
+                    { Convert thread local address to a process global addres
+                      as we cannot handle far pointers.}
+                    case target_info.system of
+                      system_i386_linux:
+                        if segment=NR_GS then
+                          begin
+                            reference_reset_symbol(tmpref,objectlibrary.newasmsymbol(
+                              '___fpc_threadvar_offset',AB_EXTERNAL,AT_DATA),0);
+                            tmpref.segment:=NR_GS;
+                            list.concat(Taicpu.op_ref_reg(A_ADD,tcgsize2opsize[OS_ADDR],tmpref,r));
+                          end
+                        else
+                          cgmessage(cg_e_cant_use_far_pointer_there);
+                      system_i386_win32:
+                        if segment=NR_FS then
+                          begin
+                            allocallcpuregisters(list);
+                            a_call_name(list,'GetTls');
+                            deallocallcpuregisters(list);
+                            list.concat(Taicpu.op_reg_reg(A_ADD,tcgsize2opsize[OS_ADDR],NR_EAX,r));
+                          end
+                        else
+                          cgmessage(cg_e_cant_use_far_pointer_there);
+
+                      else
+                        cgmessage(cg_e_cant_use_far_pointer_there);
+                    end;
+                  end
+                else
+                  cgmessage(cg_e_cant_use_far_pointer_there);
+              end;
           end;
       end;