aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Monniaux <david.monniaux@univ-grenoble-alpes.fr>2020-04-09 16:27:57 +0200
committerDavid Monniaux <david.monniaux@univ-grenoble-alpes.fr>2020-04-09 16:27:57 +0200
commitf2e6e7ff8aedb94b42da53ddc6bcd1c9ada38b80 (patch)
treed7a43f7d0d1f1a8eaf984817d17eaed8510ddd31
parentdf5dbeebdaed3fd7df3ea9a6bdb9f36e07c288e9 (diff)
parentf38ba5c864ca09b2be8906ae2b0a81e8a57b734b (diff)
downloadcompcert-kvx-f2e6e7ff8aedb94b42da53ddc6bcd1c9ada38b80.tar.gz
compcert-kvx-f2e6e7ff8aedb94b42da53ddc6bcd1c9ada38b80.zip
Merge remote-tracking branch 'origin/mppa-thread' into mppa-work
-rw-r--r--aarch64/TargetPrinter.ml4
-rw-r--r--arm/TargetPrinter.ml4
-rw-r--r--backend/JsonAST.ml2
-rw-r--r--backend/PrintAsm.ml2
-rw-r--r--backend/PrintAsmaux.ml1
-rw-r--r--cfrontend/C2C.ml36
-rw-r--r--common/Sections.ml21
-rw-r--r--common/Sections.mli5
-rw-r--r--cparser/C.mli3
-rw-r--r--cparser/Cabs.v2
-rw-r--r--cparser/Ceval.ml4
-rw-r--r--cparser/Cleanup.ml8
-rw-r--r--cparser/Cprint.ml3
-rw-r--r--cparser/Elab.ml36
-rw-r--r--cparser/Lexer.mll2
-rw-r--r--cparser/Parser.vy4
-rw-r--r--cparser/Rename.ml7
-rw-r--r--cparser/deLexer.ml1
-rw-r--r--cparser/pre_parser.mly3
-rw-r--r--mppa_k1c/TargetPrinter.ml24
-rw-r--r--powerpc/TargetPrinter.ml8
-rw-r--r--riscV/TargetPrinter.ml4
-rw-r--r--runtime/include/ccomp_k1c_fixes.h2
-rw-r--r--test/monniaux/thread_local/thread_local.c13
-rw-r--r--test/monniaux/thread_local/thread_local2.c18
-rwxr-xr-xtest/mppa/hardcheck.sh2
-rwxr-xr-xtest/mppa/hardtest.sh2
-rw-r--r--x86/TargetPrinter.ml12
28 files changed, 183 insertions, 50 deletions
diff --git a/aarch64/TargetPrinter.ml b/aarch64/TargetPrinter.ml
index e54673dd..e7edcf0d 100644
--- a/aarch64/TargetPrinter.ml
+++ b/aarch64/TargetPrinter.ml
@@ -133,7 +133,9 @@ module Target : TARGET =
let name_of_section = function
| Section_text -> ".text"
- | Section_data i | Section_small_data i ->
+ | Section_data(i, true) ->
+ failwith "_Thread_local unsupported on this platform"
+ | Section_data(i, false) | Section_small_data i ->
if i then ".data" else common_section ()
| Section_const i | Section_small_const i ->
if i || (not !Clflags.option_fcommon) then ".section .rodata" else "COMM"
diff --git a/arm/TargetPrinter.ml b/arm/TargetPrinter.ml
index 03e06a65..54af7cd5 100644
--- a/arm/TargetPrinter.ml
+++ b/arm/TargetPrinter.ml
@@ -147,7 +147,9 @@ struct
let name_of_section = function
| Section_text -> ".text"
- | Section_data i | Section_small_data i ->
+ | Section_data(i, true) ->
+ failwith "_Thread_local unsupported on this platform"
+ | Section_data(i, false) | Section_small_data(i) ->
if i then ".data" else common_section ()
| Section_const i | Section_small_const i ->
if i || (not !Clflags.option_fcommon) then ".section .rodata" else "COMM"
diff --git a/backend/JsonAST.ml b/backend/JsonAST.ml
index 8905e252..c73bf30d 100644
--- a/backend/JsonAST.ml
+++ b/backend/JsonAST.ml
@@ -31,7 +31,7 @@ let pp_section pp sec =
pp_jobject_end pp in
match sec with
| Section_text -> pp_simple "Text"
- | Section_data init -> pp_complex "Data" init
+ | Section_data(init, thread_local) -> pp_complex "Data" init (* FIXME *)
| Section_small_data init -> pp_complex "Small Data" init
| Section_const init -> pp_complex "Const" init
| Section_small_const init -> pp_complex "Small Const" init
diff --git a/backend/PrintAsm.ml b/backend/PrintAsm.ml
index 155f5e55..0635e32d 100644
--- a/backend/PrintAsm.ml
+++ b/backend/PrintAsm.ml
@@ -121,7 +121,7 @@ module Printer(Target:TARGET) =
let sec =
match C2C.atom_sections name with
| [s] -> s
- | _ -> Section_data true
+ | _ -> Section_data (true, false)
and align =
match C2C.atom_alignof name with
| Some a -> a
diff --git a/backend/PrintAsmaux.ml b/backend/PrintAsmaux.ml
index d82e6f84..e14da87e 100644
--- a/backend/PrintAsmaux.ml
+++ b/backend/PrintAsmaux.ml
@@ -303,6 +303,7 @@ let print_version_and_options oc comment =
fprintf oc " %s" Commandline.argv.(i)
done;
fprintf oc "\n"
+
(** Get the name of the common section if it is used otherwise the given section
name, with bss as default *)
diff --git a/cfrontend/C2C.ml b/cfrontend/C2C.ml
index bc5173ca..f637b5e4 100644
--- a/cfrontend/C2C.ml
+++ b/cfrontend/C2C.ml
@@ -46,16 +46,29 @@ let decl_atom : (AST.ident, atom_info) Hashtbl.t = Hashtbl.create 103
let atom_is_static a =
try
- (Hashtbl.find decl_atom a).a_storage = C.Storage_static
+ match (Hashtbl.find decl_atom a).a_storage with
+ | C.Storage_static | C.Storage_thread_local_static -> true
+ | _ -> false
with Not_found ->
false
let atom_is_extern a =
try
- (Hashtbl.find decl_atom a).a_storage = C.Storage_extern
+ match (Hashtbl.find decl_atom a).a_storage with
+ | C.Storage_extern| C.Storage_thread_local_extern -> true
+ | _ -> false
with Not_found ->
false
+let atom_is_thread_local a =
+ try
+ match (Hashtbl.find decl_atom a).a_storage with
+ | C.Storage_thread_local_extern| C.Storage_thread_local_static
+ | C.Storage_thread_local -> true
+ | _ -> false
+ with Not_found ->
+ false
+
let atom_alignof a =
try
(Hashtbl.find decl_atom a).a_alignment
@@ -1236,7 +1249,8 @@ let convertFundef loc env fd =
let vars =
List.map
(fun (sto, id, ty, init) ->
- if sto = Storage_extern || sto = Storage_static then
+ if sto = Storage_extern || sto = Storage_thread_local_extern
+ || sto = Storage_static || sto = Storage_thread_local_static then
unsupported "'static' or 'extern' local variable";
if init <> None then
unsupported "initialized local variable";
@@ -1339,15 +1353,21 @@ let convertGlobvar loc env (sto, id, ty, optinit) =
let init' =
match optinit with
| None ->
- if sto = C.Storage_extern then [] else [AST.Init_space sz]
+ if sto = C.Storage_extern || sto = C.Storage_thread_local_extern
+ then [] else [AST.Init_space sz]
| Some i ->
convertInitializer env ty i in
let (section, access) =
- Sections.for_variable env loc id' ty (optinit <> None) in
+ Sections.for_variable env loc id' ty (optinit <> None)
+ (match sto with
+ | Storage_thread_local | Storage_thread_local_extern
+ | Storage_thread_local_static -> true
+ | _ -> false) in
if Z.gt sz (Z.of_uint64 0xFFFF_FFFFL) then
error "'%s' is too big (%s bytes)"
id.name (Z.to_string sz);
- if sto <> C.Storage_extern && Cutil.incomplete_type env ty then
+ if sto <> C.Storage_extern && sto <> C.Storage_thread_local_extern
+ && Cutil.incomplete_type env ty then
error "'%s' has incomplete type" id.name;
Hashtbl.add decl_atom id'
{ a_storage = sto;
@@ -1446,7 +1466,7 @@ let cleanupGlobals p =
if IdentSet.mem fd.fd_name !strong then
error "multiple definitions of %s" fd.fd_name.name;
strong := IdentSet.add fd.fd_name !strong
- | C.Gdecl(Storage_extern, id, ty, init) ->
+ | C.Gdecl((Storage_extern|Storage_thread_local_extern), id, ty, init) ->
extern := IdentSet.add id !extern
| C.Gdecl(sto, id, ty, Some i) ->
if IdentSet.mem id !strong then
@@ -1465,7 +1485,7 @@ let cleanupGlobals p =
match g.gdesc with
| C.Gdecl(sto, id, ty, init) ->
let better_def_exists =
- if sto = Storage_extern then
+ if sto = Storage_extern || sto = Storage_thread_local_extern then
IdentSet.mem id !strong || IdentSet.mem id !weak
else if init = None then
IdentSet.mem id !strong
diff --git a/common/Sections.ml b/common/Sections.ml
index 839128a5..ea0b6dbc 100644
--- a/common/Sections.ml
+++ b/common/Sections.ml
@@ -17,7 +17,8 @@
type section_name =
| Section_text
- | Section_data of bool (* true = init data, false = uninit data *)
+ | Section_data of bool (* true = init data, false = uninit data *)
+ * bool (* thread local? *)
| Section_small_data of bool
| Section_const of bool
| Section_small_const of bool
@@ -47,8 +48,8 @@ type section_info = {
}
let default_section_info = {
- sec_name_init = Section_data true;
- sec_name_uninit = Section_data false;
+ sec_name_init = Section_data (true, false);
+ sec_name_uninit = Section_data (false, false);
sec_writable = true;
sec_executable = false;
sec_access = Access_default
@@ -63,8 +64,13 @@ let builtin_sections = [
sec_writable = false; sec_executable = true;
sec_access = Access_default};
"DATA",
- {sec_name_init = Section_data true;
- sec_name_uninit = Section_data false;
+ {sec_name_init = Section_data (true, false);
+ sec_name_uninit = Section_data (false, false);
+ sec_writable = true; sec_executable = false;
+ sec_access = Access_default};
+ "TDATA",
+ {sec_name_init = Section_data (true, true);
+ sec_name_uninit = Section_data (false, true);
sec_writable = true; sec_executable = false;
sec_access = Access_default};
"SDATA",
@@ -175,7 +181,7 @@ let get_attr_section loc attr =
(* Determine section for a variable definition *)
-let for_variable env loc id ty init =
+let for_variable env loc id ty init thrl =
let attr = Cutil.attributes_of_type env ty in
let readonly = List.mem C.AConst attr && not(List.mem C.AVolatile attr) in
let si =
@@ -194,7 +200,8 @@ let for_variable env loc id ty init =
let name =
if readonly
then if size <= !Clflags.option_small_const then "SCONST" else "CONST"
- else if size <= !Clflags.option_small_data then "SDATA" else "DATA" in
+ else if size <= !Clflags.option_small_data then "SDATA" else
+ if thrl then "TDATA" else "DATA" in
try
Hashtbl.find current_section_table name
with Not_found ->
diff --git a/common/Sections.mli b/common/Sections.mli
index d9fd9239..00c06c20 100644
--- a/common/Sections.mli
+++ b/common/Sections.mli
@@ -18,7 +18,8 @@
type section_name =
| Section_text
- | Section_data of bool (* true = init data, false = uninit data *)
+ | Section_data of bool (* true = init data, false = uninit data *)
+ * bool (* thread local? *)
| Section_small_data of bool
| Section_const of bool
| Section_small_const of bool
@@ -46,7 +47,7 @@ val define_section:
-> ?writable:bool -> ?executable:bool -> ?access:access_mode -> unit -> unit
val use_section_for: AST.ident -> string -> bool
-val for_variable: Env.t -> C.location -> AST.ident -> C.typ -> bool ->
+val for_variable: Env.t -> C.location -> AST.ident -> C.typ -> bool -> bool ->
section_name * access_mode
val for_function: Env.t -> C.location -> AST.ident -> C.attributes -> section_name list
val for_stringlit: unit -> section_name
diff --git a/cparser/C.mli b/cparser/C.mli
index 15717565..3c271f3f 100644
--- a/cparser/C.mli
+++ b/cparser/C.mli
@@ -86,8 +86,11 @@ type attributes = attribute list
type storage =
| Storage_default (* used for toplevel names without explicit storage *)
+ | Storage_thread_local
| Storage_extern
| Storage_static
+ | Storage_thread_local_extern
+ | Storage_thread_local_static
| Storage_auto (* used for block-scoped names without explicit storage *)
| Storage_register
diff --git a/cparser/Cabs.v b/cparser/Cabs.v
index 5f12e8a1..2dae061a 100644
--- a/cparser/Cabs.v
+++ b/cparser/Cabs.v
@@ -54,7 +54,7 @@ Inductive typeSpecifier := (* Merge all specifiers into one type *)
| Tenum : option string -> option (list (string * option expression * loc)) -> list attribute -> typeSpecifier
with storage :=
- AUTO | STATIC | EXTERN | REGISTER | TYPEDEF
+ AUTO | STATIC | EXTERN | REGISTER | TYPEDEF | THREAD_LOCAL
with cvspec :=
| CV_CONST | CV_VOLATILE | CV_RESTRICT
diff --git a/cparser/Ceval.ml b/cparser/Ceval.ml
index ecf83779..7bae2fe2 100644
--- a/cparser/Ceval.ml
+++ b/cparser/Ceval.ml
@@ -354,7 +354,9 @@ and is_constant_lval env e =
begin match Env.find_ident env id with
| Env.II_ident(sto, _) ->
begin match sto with
- | Storage_default | Storage_extern | Storage_static -> true
+ | Storage_default | Storage_extern | Storage_static
+ | Storage_thread_local | Storage_thread_local_extern | Storage_thread_local_static
+ -> true
| Storage_auto | Storage_register -> false
end
| Env.II_enum _ -> false (* should not happen *)
diff --git a/cparser/Cleanup.ml b/cparser/Cleanup.ml
index 63ac8ac1..9f19395a 100644
--- a/cparser/Cleanup.ml
+++ b/cparser/Cleanup.ml
@@ -126,14 +126,14 @@ let add_enum e =
*)
let visible_decl (sto, id, ty, init) =
- sto = Storage_default &&
+ (sto = Storage_default || sto = Storage_thread_local) &&
match ty with TFun _ -> false | _ -> true
let visible_fundef f =
match f.fd_storage with
- | Storage_default -> not f.fd_inline
- | Storage_extern -> true
- | Storage_static -> false
+ | Storage_default | Storage_thread_local -> not f.fd_inline
+ | Storage_extern | Storage_thread_local_extern -> true
+ | Storage_static | Storage_thread_local_static -> false
| Storage_auto | Storage_register -> assert false
let rec add_init_globdecls accu = function
diff --git a/cparser/Cprint.ml b/cparser/Cprint.ml
index 9aeec421..78970990 100644
--- a/cparser/Cprint.ml
+++ b/cparser/Cprint.ml
@@ -361,6 +361,9 @@ let storage pp = function
| Storage_default -> ()
| Storage_extern -> fprintf pp "extern "
| Storage_static -> fprintf pp "static "
+ | Storage_thread_local -> fprintf pp "_Thread_local"
+ | Storage_thread_local_extern -> fprintf pp "extern _Thread_local"
+ | Storage_thread_local_static -> fprintf pp "static _Thread_local"
| Storage_auto -> () (* used only in blocks, where it can be omitted *)
| Storage_register -> fprintf pp "register "
diff --git a/cparser/Elab.ml b/cparser/Elab.ml
index 9e17cb7e..0504ad0b 100644
--- a/cparser/Elab.ml
+++ b/cparser/Elab.ml
@@ -152,6 +152,9 @@ let name_of_storage_class = function
| Storage_default -> "<default>"
| Storage_extern -> "'extern'"
| Storage_static -> "'static'"
+ | Storage_thread_local -> "'_Thread_local'"
+ | Storage_thread_local_extern -> "'_Thread_local extern'"
+ | Storage_thread_local_static -> "'_Thread_local static'"
| Storage_auto -> "'auto'"
| Storage_register -> "'register'"
@@ -177,15 +180,29 @@ let combine_toplevel_definitions loc env s old_sto old_ty sto ty =
| Storage_static,Storage_static
| Storage_extern,Storage_extern
| Storage_default,Storage_default -> sto
- | _,Storage_static ->
+ | Storage_thread_local_static,Storage_thread_local_static
+ | Storage_thread_local_extern,Storage_thread_local_extern
+ | Storage_thread_local,Storage_thread_local -> sto
+ | _,Storage_static | _,Storage_thread_local_static ->
error loc "static declaration of '%s' follows non-static declaration" s;
sto
| Storage_static,_ -> Storage_static (* Static stays static *)
- | Storage_extern,_ -> if is_function_type env new_ty then Storage_extern else sto
+ | Storage_thread_local_static,_ -> Storage_thread_local_static (* Thread-local static stays static *)
+ | (Storage_extern|Storage_thread_local_extern),_ -> if is_function_type env new_ty then Storage_extern else sto
| Storage_default,Storage_extern ->
if is_global_defined s && is_function_type env ty then
warning loc Extern_after_definition "this extern declaration follows a non-extern definition and is ignored";
Storage_extern
+ | Storage_thread_local,Storage_thread_local_extern ->
+ if is_global_defined s && is_function_type env ty then
+ warning loc Extern_after_definition "this extern declaration follows a non-extern definition and is ignored";
+ Storage_extern
+ | Storage_thread_local, Storage_default ->
+ error loc "Non thread-local declaration follows thread-local";
+ sto
+ | Storage_default, (Storage_thread_local|Storage_thread_local_extern) ->
+ error loc "Thread-local declaration follows non thread-local";
+ sto
| _,Storage_extern -> old_sto
(* "auto" and "register" don't appear in toplevel definitions.
Normally this was checked earlier. Generate error message
@@ -639,13 +656,26 @@ let rec elab_specifier ?(only = false) loc env specifier =
restrict := cv = CV_RESTRICT;
attr := add_attributes (elab_cvspec env cv) !attr
| SpecStorage st ->
- if !sto <> Storage_default && st <> TYPEDEF then
+ if !sto <> Storage_default && st <> TYPEDEF && st <> THREAD_LOCAL then
error loc "multiple storage classes in declaration specifier";
begin match st with
| AUTO -> sto := Storage_auto
| STATIC -> sto := Storage_static
| EXTERN -> sto := Storage_extern
| REGISTER -> sto := Storage_register
+ | THREAD_LOCAL ->
+ sto := (match !sto with
+ | Storage_static | Storage_thread_local_static ->
+ Storage_thread_local_static
+ | Storage_extern | Storage_thread_local_extern ->
+ Storage_thread_local_extern
+ | Storage_default | Storage_thread_local ->
+ Storage_thread_local
+ | Storage_auto|Storage_register ->
+ error loc "_Thread_local on auto or register variable";
+ !sto
+ )
+
| TYPEDEF ->
if !typedef then
error loc "multiple uses of 'typedef'";
diff --git a/cparser/Lexer.mll b/cparser/Lexer.mll
index e44a330f..b36b3e81 100644
--- a/cparser/Lexer.mll
+++ b/cparser/Lexer.mll
@@ -72,6 +72,7 @@ let () =
("goto", fun loc -> GOTO loc);
("if", fun loc -> IF loc);
("inline", fun loc -> INLINE loc);
+ ("_Thread_local", fun loc -> THREAD_LOCAL loc);
("_Noreturn", fun loc -> NORETURN loc);
("int", fun loc -> INT loc);
("long", fun loc -> LONG loc);
@@ -542,6 +543,7 @@ and singleline_comment = parse
| Pre_parser.IF loc -> loop (Parser.IF_ loc)
| Pre_parser.INC loc -> loop (Parser.INC loc)
| Pre_parser.INLINE loc -> loop (Parser.INLINE loc)
+ | Pre_parser.THREAD_LOCAL loc -> loop (Parser.THREAD_LOCAL loc)
| Pre_parser.INT loc -> loop (Parser.INT loc)
| Pre_parser.LBRACE loc -> loop (Parser.LBRACE loc)
| Pre_parser.LBRACK loc -> loop (Parser.LBRACK loc)
diff --git a/cparser/Parser.vy b/cparser/Parser.vy
index 03bfa590..4f3b9789 100644
--- a/cparser/Parser.vy
+++ b/cparser/Parser.vy
@@ -32,7 +32,7 @@ Require Cabs.
LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
%token<Cabs.loc> LPAREN RPAREN LBRACK RBRACK LBRACE RBRACE DOT COMMA
- SEMICOLON ELLIPSIS TYPEDEF EXTERN STATIC RESTRICT AUTO REGISTER INLINE
+ SEMICOLON ELLIPSIS TYPEDEF EXTERN STATIC RESTRICT AUTO REGISTER INLINE THREAD_LOCAL
NORETURN CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE CONST VOLATILE VOID
STRUCT UNION ENUM UNDERSCORE_BOOL PACKED ALIGNAS ATTRIBUTE ASM
@@ -397,6 +397,8 @@ storage_class_specifier:
{ (Cabs.AUTO, loc) }
| loc = REGISTER
{ (Cabs.REGISTER, loc) }
+| loc = THREAD_LOCAL
+ { (Cabs.THREAD_LOCAL, loc) }
(* 6.7.2 *)
type_specifier:
diff --git a/cparser/Rename.ml b/cparser/Rename.ml
index 64412194..aeeb9326 100644
--- a/cparser/Rename.ml
+++ b/cparser/Rename.ml
@@ -257,13 +257,16 @@ let rec reserve_public env = function
match dcl.gdesc with
| Gdecl(sto, id, _, _) ->
begin match sto with
- | Storage_default | Storage_extern -> enter_public env id
+ | Storage_default | Storage_thread_local
+ | Storage_extern | Storage_thread_local_extern ->
+ enter_public env id
| Storage_static -> env
| _ -> assert false
end
| Gfundef f ->
begin match f.fd_storage with
- | Storage_default | Storage_extern -> enter_public env f.fd_name
+ | Storage_default | Storage_extern
+ -> enter_public env f.fd_name
| Storage_static -> env
| _ -> assert false
end
diff --git a/cparser/deLexer.ml b/cparser/deLexer.ml
index de0e9b6e..43c1a679 100644
--- a/cparser/deLexer.ml
+++ b/cparser/deLexer.ml
@@ -30,6 +30,7 @@ let delex (symbol : string) : string =
| "BUILTIN_VA_ARG" -> "__builtin_va_arg"
| "CONST" -> "const"
| "INLINE" -> "inline"
+ | "THREAD_LOCAL" -> "_Thread_local"
| "PACKED" -> "__packed__"
| "RESTRICT" -> "restrict"
| "SIGNED" -> "signed"
diff --git a/cparser/pre_parser.mly b/cparser/pre_parser.mly
index 669ecf5e..e21a3519 100644
--- a/cparser/pre_parser.mly
+++ b/cparser/pre_parser.mly
@@ -54,7 +54,7 @@
COLON AND MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN LEFT_ASSIGN
RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN LPAREN RPAREN LBRACK RBRACK
LBRACE RBRACE DOT COMMA SEMICOLON ELLIPSIS TYPEDEF EXTERN STATIC RESTRICT
- AUTO REGISTER INLINE NORETURN CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE
+ AUTO REGISTER INLINE THREAD_LOCAL NORETURN CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE
UNDERSCORE_BOOL CONST VOLATILE VOID STRUCT UNION ENUM CASE DEFAULT IF ELSE
SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN BUILTIN_VA_ARG ALIGNOF
ATTRIBUTE ALIGNAS PACKED ASM BUILTIN_OFFSETOF
@@ -430,6 +430,7 @@ storage_class_specifier_no_typedef:
| STATIC
| AUTO
| REGISTER
+| THREAD_LOCAL
{}
(* [declaration_specifier_no_type] matches declaration specifiers
diff --git a/mppa_k1c/TargetPrinter.ml b/mppa_k1c/TargetPrinter.ml
index 930b1c51..2489b959 100644
--- a/mppa_k1c/TargetPrinter.ml
+++ b/mppa_k1c/TargetPrinter.ml
@@ -157,8 +157,12 @@ module Target (*: TARGET*) =
let name_of_section = function
| Section_text -> ".text"
- | Section_data i | Section_small_data i ->
- if i then ".data" else "COMM"
+ | Section_data(true, true) ->
+ ".section .tdata,\"awT\",@progbits"
+ | Section_data(false, true) ->
+ ".section .tbss,\"awT\",@nobits"
+ | Section_data(i, false) | Section_small_data(i) ->
+ (if i then ".data" else "COMM")
| Section_const i | Section_small_const i ->
if i then ".section .rodata" else "COMM"
| Section_string -> ".section .rodata"
@@ -211,14 +215,20 @@ module Target (*: TARGET*) =
(* Generate code to load the address of id + ofs in register r *)
-(* FIXME DMonniaux ugly ugly hack to get at standard __thread data *)
let loadsymbol oc r id ofs =
if Archi.pic_code () then begin
assert (ofs = Integers.Ptrofs.zero);
- fprintf oc " make %a = %s\n" ireg r (extern_atom id)
- end else begin
- if (extern_atom id) = "_impure_thread_data" then begin
- fprintf oc " addd %a = $r13, @tprel(%a)\n" ireg r symbol_offset (id, ofs)
+ if C2C.atom_is_thread_local id then begin
+ (* fprintf oc " addd %a = $r13, @tprel(%s)\n" ireg r (extern_atom id) *)
+ fprintf oc " addd %a = $r13, @tlsle(%s)\n" ireg r (extern_atom id)
+ end else begin
+ fprintf oc " make %a = %s\n" ireg r (extern_atom id)
+ end
+ end else
+ begin
+ if C2C.atom_is_thread_local id then begin
+ (* fprintf oc " addd %a = $r13, @tprel(%a)\n" ireg r symbol_offset (id, ofs) *)
+ fprintf oc " addd %a = $r13, @tlsle(%a)\n" ireg r symbol_offset (id, ofs)
end else begin
fprintf oc " make %a = %a\n" ireg r symbol_offset (id, ofs)
end
diff --git a/powerpc/TargetPrinter.ml b/powerpc/TargetPrinter.ml
index 0f608d25..3ea03786 100644
--- a/powerpc/TargetPrinter.ml
+++ b/powerpc/TargetPrinter.ml
@@ -117,7 +117,9 @@ module Linux_System : SYSTEM =
let name_of_section = function
| Section_text -> ".text"
- | Section_data i ->
+ | Section_data(i, true) ->
+ failwith "_Thread_local unsupported on this platform"
+ | Section_data(i, false) ->
if i then
".data"
else
@@ -218,7 +220,9 @@ module Diab_System : SYSTEM =
let name_of_section = function
| Section_text -> ".text"
- | Section_data i -> if i then ".data" else common_section ()
+ | Section_data(i, true) ->
+ failwith "_Thread_local unsupported on this platform"
+ | Section_data (i, false) -> if i then ".data" else common_section ()
| Section_small_data i -> if i then ".sdata" else ".sbss"
| Section_const _ -> ".text"
| Section_small_const _ -> ".sdata2"
diff --git a/riscV/TargetPrinter.ml b/riscV/TargetPrinter.ml
index 64bcea4c..1f02ca71 100644
--- a/riscV/TargetPrinter.ml
+++ b/riscV/TargetPrinter.ml
@@ -107,7 +107,9 @@ module Target : TARGET =
let name_of_section = function
| Section_text -> ".text"
- | Section_data i | Section_small_data i ->
+ | Section_data(i, true) ->
+ failwith "_Thread_local unsupported on this platform"
+ | Section_data(i, false) | Section_small_data i ->
if i then ".data" else common_section ()
| Section_const i | Section_small_const i ->
if i || (not !Clflags.option_fcommon) then ".section .rodata" else "COMM"
diff --git a/runtime/include/ccomp_k1c_fixes.h b/runtime/include/ccomp_k1c_fixes.h
index 718ac3e5..69097d06 100644
--- a/runtime/include/ccomp_k1c_fixes.h
+++ b/runtime/include/ccomp_k1c_fixes.h
@@ -6,7 +6,7 @@
#endif
#undef __GNUC__
-#define __thread
+#define __thread _Thread_local
struct __int128_ccomp { long __int128_ccomp_low; long __int128_ccomp_high; };
diff --git a/test/monniaux/thread_local/thread_local.c b/test/monniaux/thread_local/thread_local.c
new file mode 100644
index 00000000..7a50db0a
--- /dev/null
+++ b/test/monniaux/thread_local/thread_local.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+_Thread_local int toto;
+_Thread_local int toto2 = 45;
+
+int foobar(void) {
+ return toto;
+}
+
+int main() {
+ printf("%d %d\n", toto, toto2);
+ return 0;
+}
diff --git a/test/monniaux/thread_local/thread_local2.c b/test/monniaux/thread_local/thread_local2.c
new file mode 100644
index 00000000..ba244ac6
--- /dev/null
+++ b/test/monniaux/thread_local/thread_local2.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <pthread.h>
+
+_Thread_local int toto;
+_Thread_local int toto2 = 45;
+
+void* poulet(void * dummy) {
+ printf("%p %p\n", &toto, &toto2);
+ return NULL;
+}
+
+int main() {
+ pthread_t thr;
+ poulet(NULL);
+ pthread_create(&thr, NULL, poulet, NULL);
+ pthread_join(thr, NULL);
+ return 0;
+}
diff --git a/test/mppa/hardcheck.sh b/test/mppa/hardcheck.sh
index 82b63182..b6538f0e 100755
--- a/test/mppa/hardcheck.sh
+++ b/test/mppa/hardcheck.sh
@@ -3,4 +3,4 @@
source do_test.sh
-do_test hardcheck
+do_test hardcheck 1
diff --git a/test/mppa/hardtest.sh b/test/mppa/hardtest.sh
index 09511da6..6321bc7d 100755
--- a/test/mppa/hardtest.sh
+++ b/test/mppa/hardtest.sh
@@ -3,4 +3,4 @@
source do_test.sh
-do_test hardtest
+do_test hardtest 1
diff --git a/x86/TargetPrinter.ml b/x86/TargetPrinter.ml
index 6159437e..e371380c 100644
--- a/x86/TargetPrinter.ml
+++ b/x86/TargetPrinter.ml
@@ -133,7 +133,9 @@ module ELF_System : SYSTEM =
let name_of_section = function
| Section_text -> ".text"
- | Section_data i | Section_small_data i ->
+ | Section_data(i, true) ->
+ failwith "_Thread_local unsupported on this platform"
+ | Section_data(i, false) | Section_small_data i ->
if i then ".data" else common_section ()
| Section_const i | Section_small_const i ->
if i || (not !Clflags.option_fcommon) then ".section .rodata" else "COMM"
@@ -191,7 +193,9 @@ module MacOS_System : SYSTEM =
let name_of_section = function
| Section_text -> ".text"
- | Section_data i | Section_small_data i ->
+ | Section_data(i, true) ->
+ failwith "_Thread_local unsupported on this platform"
+ | Section_data(i, false) | Section_small_data i ->
if i || (not !Clflags.option_fcommon) then ".data" else "COMM"
| Section_const i | Section_small_const i ->
if i || (not !Clflags.option_fcommon) then ".const" else "COMM"
@@ -268,7 +272,9 @@ module Cygwin_System : SYSTEM =
let name_of_section = function
| Section_text -> ".text"
- | Section_data i | Section_small_data i ->
+ | Section_data(i, true) ->
+ failwith "_Thread_local unsupported on this platform"
+ | Section_data(i, false) | Section_small_data i ->
if i then ".data" else common_section ()
| Section_const i | Section_small_const i ->
if i || (not !Clflags.option_fcommon) then ".section .rdata,\"dr\"" else "COMM"