summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2006-01-03 12:49:29 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2006-01-03 12:49:29 +0000
commit21a0f67106d753a8f8f7b8c7aead47a11560cbed (patch)
treea51a06a24f75ec4e4eb1412ba085c063860673c8
parentb896a8b8fe71c5024ab4f59dc3671b9637c87dc3 (diff)
downloadfpc-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.pas4
-rw-r--r--compiler/assemble.pas5
-rw-r--r--compiler/i386/cgcpu.pas2
-rw-r--r--compiler/ncgld.pas21
-rw-r--r--compiler/ncgutil.pas27
-rw-r--r--compiler/ogcoff.pas2
-rw-r--r--compiler/ogelf.pas5
-rw-r--r--compiler/pmodules.pas20
-rw-r--r--compiler/systems.pas9
-rw-r--r--compiler/systems/i_linux.pas6
-rw-r--r--compiler/systems/i_win.pas2
-rw-r--r--compiler/x86/cgx86.pas49
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;