diff options
Diffstat (limited to 'cparser')
-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/Machine.ml | 52 | ||||
-rw-r--r-- | cparser/Machine.mli | 5 | ||||
-rw-r--r-- | cparser/Parser.vy | 4 | ||||
-rw-r--r-- | cparser/Rename.ml | 7 | ||||
-rw-r--r-- | cparser/StructPassing.ml | 11 | ||||
-rw-r--r-- | cparser/deLexer.ml | 1 | ||||
-rw-r--r-- | cparser/pre_parser.mly | 3 |
14 files changed, 127 insertions, 14 deletions
diff --git a/cparser/C.mli b/cparser/C.mli index 763a9277..cccf744b 100644 --- a/cparser/C.mli +++ b/cparser/C.mli @@ -87,8 +87,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 accb95a0..ab908be3 100644 --- a/cparser/Cabs.v +++ b/cparser/Cabs.v @@ -55,7 +55,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 14f61e06..b216ebc8 100644 --- a/cparser/Ceval.ml +++ b/cparser/Ceval.ml @@ -355,7 +355,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 62b00e04..74959cbb 100644 --- a/cparser/Cleanup.ml +++ b/cparser/Cleanup.ml @@ -127,14 +127,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 93377989..dddc8f73 100644 --- a/cparser/Cprint.ml +++ b/cparser/Cprint.ml @@ -362,6 +362,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 a5b87e2e..594453b8 100644 --- a/cparser/Elab.ml +++ b/cparser/Elab.ml @@ -153,6 +153,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'" @@ -178,15 +181,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 @@ -654,13 +671,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 42980d30..7a2974eb 100644 --- a/cparser/Lexer.mll +++ b/cparser/Lexer.mll @@ -74,6 +74,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); @@ -545,6 +546,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/Machine.ml b/cparser/Machine.ml index c47ec594..4ce63970 100644 --- a/cparser/Machine.ml +++ b/cparser/Machine.ml @@ -19,6 +19,7 @@ type struct_passing_style = | SP_ref_callee (* by reference, callee takes copy *) | SP_ref_caller (* by reference, caller takes copy *) + | SP_value32_ref_callee (* by value if <= 32 bits, by ref_callee otherwise *) | SP_split_args (* by value, as a sequence of ints *) type struct_return_style = @@ -61,6 +62,7 @@ type t = { supports_unaligned_accesses: bool; struct_passing_style: struct_passing_style; struct_return_style : struct_return_style; + has_non_trapping_loads : bool; } let ilp32ll64 = { @@ -96,6 +98,7 @@ let ilp32ll64 = { supports_unaligned_accesses = false; struct_passing_style = SP_ref_callee; struct_return_style = SR_ref; + has_non_trapping_loads = false; } let i32lpll64 = { @@ -131,6 +134,7 @@ let i32lpll64 = { supports_unaligned_accesses = false; struct_passing_style = SP_ref_callee; struct_return_style = SR_ref; + has_non_trapping_loads = false; } let il32pll64 = { @@ -166,6 +170,7 @@ let il32pll64 = { supports_unaligned_accesses = false; struct_passing_style = SP_ref_callee; struct_return_style = SR_ref; + has_non_trapping_loads = false; } (* Canned configurations for some ABIs *) @@ -238,6 +243,52 @@ let rv64 = struct_passing_style = SP_ref_callee; (* Wrong *) struct_return_style = SR_ref } (* to check *) +let kvxbase = + { name = "kvx"; + char_signed = true; + wchar_signed = true; + sizeof_ptr = 8; + sizeof_short = 2; + sizeof_int = 4; + sizeof_long = 8; + sizeof_longlong = 8; + sizeof_float = 4; + sizeof_double = 8; + sizeof_longdouble = 8; + sizeof_void = None; (* What is this for ? *) + sizeof_fun = None; (* What is this for ? *) + sizeof_wchar = 4; + sizeof_size_t = 8; + sizeof_ptrdiff_t = 8; + sizeof_intreg = 8; (* What is this for ? *) + alignof_ptr = 8; + alignof_short = 2; + alignof_int = 4; + alignof_long = 8; + alignof_longlong = 8; + alignof_float = 4; + alignof_double = 8; + alignof_longdouble = 8; + alignof_void = None; (* what is this for ? *) + alignof_fun = None; (* what is this for ? *) + bigendian = false; + bitfields_msb_first = false; (* TO CHECK *) + supports_unaligned_accesses = true; + struct_passing_style = SP_value32_ref_callee; + struct_return_style = SR_int1to4; + has_non_trapping_loads = false; +} + +let kvxcos = + { kvxbase with has_non_trapping_loads = true; +} + +let kvxmbr = + { kvxbase with has_non_trapping_loads = true; +} + +let kvxelf = kvxmbr + let aarch64 = { i32lpll64 with name = "aarch64"; struct_passing_style = SP_ref_callee; (* Wrong *) @@ -292,6 +343,7 @@ let undef = { supports_unaligned_accesses = false; struct_passing_style = SP_ref_callee; struct_return_style = SR_ref; + has_non_trapping_loads = false; } (* The current configuration. Must be initialized before use. *) diff --git a/cparser/Machine.mli b/cparser/Machine.mli index f9d347b9..9e6063ba 100644 --- a/cparser/Machine.mli +++ b/cparser/Machine.mli @@ -18,6 +18,7 @@ type struct_passing_style = | SP_ref_callee (* by reference, callee takes copy *) | SP_ref_caller (* by reference, caller takes copy *) + | SP_value32_ref_callee (* by value if <= 32 bits, by ref_callee otherwise *) | SP_split_args (* by value, as a sequence of ints *) type struct_return_style = @@ -60,6 +61,7 @@ type t = { supports_unaligned_accesses: bool; struct_passing_style: struct_passing_style; struct_return_style: struct_return_style; + has_non_trapping_loads: bool; } (* The current configuration *) @@ -87,6 +89,9 @@ val arm_littleendian : t val arm_bigendian : t val rv32 : t val rv64 : t +val kvxmbr : t +val kvxcos : t +val kvxelf : t val aarch64 : t val aarch64_apple : t diff --git a/cparser/Parser.vy b/cparser/Parser.vy index f1abe3d9..6c39719c 100644 --- a/cparser/Parser.vy +++ b/cparser/Parser.vy @@ -33,7 +33,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 @@ -403,6 +403,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 96424bf8..e1b3537e 100644 --- a/cparser/Rename.ml +++ b/cparser/Rename.ml @@ -258,13 +258,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/StructPassing.ml b/cparser/StructPassing.ml index f1f481d0..629d7bc3 100644 --- a/cparser/StructPassing.ml +++ b/cparser/StructPassing.ml @@ -69,7 +69,16 @@ let classify_param env ty = match !struct_passing_style with | SP_ref_callee -> Param_unchanged | SP_ref_caller -> Param_ref_caller - | _ -> + | SP_value32_ref_callee -> + (match sizeof env ty, alignof env ty with + | Some sz, Some al -> + if (sz <= 4) then + Param_flattened ((sz+3)/4, sz, al) (* FIXME - why (sz+3)/4 ? *) + else + Param_unchanged + | _, _ -> Param_unchanged (* when parsing prototype with incomplete structure definition *) + ) + | SP_split_args -> match sizeof env ty, alignof env ty with | Some sz, Some al -> Param_flattened ((sz + 3) / 4, sz, al) diff --git a/cparser/deLexer.ml b/cparser/deLexer.ml index e3ab3291..3f84d847 100644 --- a/cparser/deLexer.ml +++ b/cparser/deLexer.ml @@ -31,6 +31,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 cffbd192..f99fef62 100644 --- a/cparser/pre_parser.mly +++ b/cparser/pre_parser.mly @@ -55,7 +55,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 STATIC_ASSERT @@ -432,6 +432,7 @@ storage_class_specifier_no_typedef: | STATIC | AUTO | REGISTER +| THREAD_LOCAL {} (* [declaration_specifier_no_type] matches declaration specifiers |