diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2006-01-03 12:49:29 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2006-01-03 12:49:29 +0000 |
commit | 21a0f67106d753a8f8f7b8c7aead47a11560cbed (patch) | |
tree | a51a06a24f75ec4e4eb1412ba085c063860673c8 | |
parent | b896a8b8fe71c5024ab4f59dc3671b9637c87dc3 (diff) | |
download | fpc-21a0f67106d753a8f8f7b8c7aead47a11560cbed.tar.gz |
* cleaned up segmented thread variables
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@2135 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | compiler/aggas.pas | 4 | ||||
-rw-r--r-- | compiler/assemble.pas | 5 | ||||
-rw-r--r-- | compiler/i386/cgcpu.pas | 2 | ||||
-rw-r--r-- | compiler/ncgld.pas | 21 | ||||
-rw-r--r-- | compiler/ncgutil.pas | 27 | ||||
-rw-r--r-- | compiler/ogcoff.pas | 2 | ||||
-rw-r--r-- | compiler/ogelf.pas | 5 | ||||
-rw-r--r-- | compiler/pmodules.pas | 20 | ||||
-rw-r--r-- | compiler/systems.pas | 9 | ||||
-rw-r--r-- | compiler/systems/i_linux.pas | 6 | ||||
-rw-r--r-- | compiler/systems/i_win.pas | 2 | ||||
-rw-r--r-- | compiler/x86/cgx86.pas | 49 |
12 files changed, 94 insertions, 58 deletions
diff --git a/compiler/aggas.pas b/compiler/aggas.pas index ff80a3a781..2a3f261967 100644 --- a/compiler/aggas.pas +++ b/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 diff --git a/compiler/assemble.pas b/compiler/assemble.pas index 92f47eca39..28132ced43 100644 --- a/compiler/assemble.pas +++ b/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]); diff --git a/compiler/i386/cgcpu.pas b/compiler/i386/cgcpu.pas index 3d7e1bab7d..edd8018e20 100644 --- a/compiler/i386/cgcpu.pas +++ b/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; diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index 4ae6115a03..492914fbda 100644 --- a/compiler/ncgld.pas +++ b/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); diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index facc7a4ad8..c08fb12a3d 100644 --- a/compiler/ncgutil.pas +++ b/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 diff --git a/compiler/ogcoff.pas b/compiler/ogcoff.pas index 877905ad57..e27d820ada 100644 --- a/compiler/ogcoff.pas +++ b/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', diff --git a/compiler/ogelf.pas b/compiler/ogelf.pas index 175cc3f6bd..a2077fccd5 100644 --- a/compiler/ogelf.pas +++ b/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 diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 76f09d12d7..128a340068 100644 --- a/compiler/pmodules.pas +++ b/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; diff --git a/compiler/systems.pas b/compiler/systems.pas index 7f1a2ba4f0..763c484c75 100644 --- a/compiler/systems.pas +++ b/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; diff --git a/compiler/systems/i_linux.pas b/compiler/systems/i_linux.pas index 3feb76d86f..0c32b36f2a 100644 --- a/compiler/systems/i_linux.pas +++ b/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'; diff --git a/compiler/systems/i_win.pas b/compiler/systems/i_win.pas index 929c36156c..88796b36b8 100644 --- a/compiler/systems/i_win.pas +++ b/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'; diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index 2d861b11cc..e891c70e02 100644 --- a/compiler/x86/cgx86.pas +++ b/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; |