diff options
-rw-r--r-- | aarch64/TargetPrinter.ml | 4 | ||||
-rw-r--r-- | arm/TargetPrinter.ml | 4 | ||||
-rw-r--r-- | backend/JsonAST.ml | 2 | ||||
-rw-r--r-- | backend/PrintAsm.ml | 2 | ||||
-rw-r--r-- | backend/PrintAsmaux.ml | 1 | ||||
-rw-r--r-- | cfrontend/C2C.ml | 36 | ||||
-rw-r--r-- | common/Sections.ml | 21 | ||||
-rw-r--r-- | common/Sections.mli | 5 | ||||
-rw-r--r-- | cparser/C.mli | 3 | ||||
-rw-r--r-- | cparser/Cabs.v | 2 | ||||
-rw-r--r-- | cparser/Ceval.ml | 4 | ||||
-rw-r--r-- | cparser/Cleanup.ml | 8 | ||||
-rw-r--r-- | cparser/Cprint.ml | 3 | ||||
-rw-r--r-- | cparser/Elab.ml | 36 | ||||
-rw-r--r-- | cparser/Lexer.mll | 2 | ||||
-rw-r--r-- | cparser/Parser.vy | 4 | ||||
-rw-r--r-- | cparser/Rename.ml | 7 | ||||
-rw-r--r-- | cparser/deLexer.ml | 1 | ||||
-rw-r--r-- | cparser/pre_parser.mly | 3 | ||||
-rw-r--r-- | mppa_k1c/TargetPrinter.ml | 24 | ||||
-rw-r--r-- | powerpc/TargetPrinter.ml | 8 | ||||
-rw-r--r-- | riscV/TargetPrinter.ml | 4 | ||||
-rw-r--r-- | runtime/include/ccomp_k1c_fixes.h | 2 | ||||
-rw-r--r-- | test/monniaux/thread_local/thread_local.c | 13 | ||||
-rw-r--r-- | test/monniaux/thread_local/thread_local2.c | 18 | ||||
-rwxr-xr-x | test/mppa/hardcheck.sh | 2 | ||||
-rwxr-xr-x | test/mppa/hardtest.sh | 2 | ||||
-rw-r--r-- | x86/TargetPrinter.ml | 12 |
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" |