diff options
author | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2011-04-16 08:20:45 +0000 |
---|---|---|
committer | xleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e> | 2011-04-16 08:20:45 +0000 |
commit | abb6fbfe333173acfeeb9304f9c529778e58ff1c (patch) | |
tree | d30ab1346fd80d006943e0d9c81264bac17f161c | |
parent | 12696ae9f6c34aaffc668711d96beda51a783832 (diff) |
Preliminary support for 'aligned' and 'section' attributes, gcc-style. New-style handling of sections for IA32 and ARM. Work in progress, to be tested.
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1635 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
-rw-r--r-- | arm/PrintAsm.ml | 48 | ||||
-rw-r--r-- | cfrontend/C2C.ml | 37 | ||||
-rw-r--r-- | common/Sections.ml | 53 | ||||
-rw-r--r-- | common/Sections.mli | 4 | ||||
-rw-r--r-- | ia32/PrintAsm.ml | 70 | ||||
-rw-r--r-- | powerpc/PrintAsm.ml | 14 |
6 files changed, 155 insertions, 71 deletions
diff --git a/arm/PrintAsm.ml b/arm/PrintAsm.ml index 883ee72..f6bff26 100644 --- a/arm/PrintAsm.ml +++ b/arm/PrintAsm.ml @@ -15,6 +15,7 @@ open Printf open Datatypes open Camlcoq +open Sections open AST open Asm @@ -98,6 +99,24 @@ let condition_name = function | CRgt -> "gt" | CRle -> "le" +(* Names of sections *) + +let name_of_section_ELF = function + | Section_text -> ".text" + | Section_data i -> if i then ".data" else ".bss" + | Section_small_data i -> if i then ".sdata" else ".sbss" + | Section_const -> ".rodata" + | Section_small_const -> ".sdata2" + | Section_string -> ".rodata" + | Section_literal -> ".section .rodata.cst8,\"aM\",%progbits,8" + | Section_jumptable -> ".text" + | Section_user(s, wr, ex) -> + sprintf ".section %s,\"a%s%s\",%progbits" + s (if wr then "w" else "") (if ex then "x" else "") + +let section oc sec = + fprintf oc " %s\n" (name_of_section sec) + (* Record current code position and latest position at which to emit float and symbol constants. *) @@ -525,14 +544,16 @@ let print_function oc name code = Hashtbl.clear current_function_labels; reset_constants(); currpos := 0; - fprintf oc " .text\n"; + let (text, _, _) = sections_for_function name in + section oc text; fprintf oc " .align 2\n"; if not (C2C.atom_is_static name) then fprintf oc " .global %a\n" print_symb name; - fprintf oc " .type %a, %%function\n" print_symb name; fprintf oc "%a:\n" print_symb name; print_instructions oc (labels_of_code Labelset.empty code) code; - emit_constants oc + emit_constants oc; + fprintf oc " .type %a, %%function\n" print_symb name; + fprintf oc " .size %a, . - %a\n" symbol name symbol name (* Generation of stub code for external functions. Compcert passes the first two float arguments in F0 and F1, @@ -566,7 +587,7 @@ let print_external_function oc name sg = move_args tys int_regs float_regs end in - fprintf oc " .text\n"; + section oc Section_text; fprintf oc " .align 2\n"; fprintf oc ".L%s$stub:\n" name; move_args sg.sig_args [IR0;IR1;IR2;IR3] [FR0;FR1]; @@ -616,15 +637,24 @@ let print_var oc (Coq_pair(name, v)) = match v.gvar_init with | [] -> () | _ -> - if v.gvar_readonly - then fprintf oc " .const\n" - else fprintf oc " .data\n"; - fprintf oc " .align 2\n"; + let init = + match v.gvar_init with [Init_space _] -> false | _ -> true in + let sec = + Sections.section_for_variable name init + and align = + match C2C.atom_alignof name with + | Some a -> log2 a + | None -> 3 (* 8-alignment is a safe default *) + in + section oc sec; + fprintf oc " .align %d\n" align; if not (C2C.atom_is_static name) then fprintf oc " .global %a\n" print_symb name; fprintf oc " .type %a, %%object\n" print_symb name; fprintf oc "%a:\n" print_symb name; - print_init_data oc name v.gvar_init + print_init_data oc name v.gvar_init; + fprintf oc " .type %a, @object\n" print_symb name; + fprintf oc " .size %a, . - %a\n" print_symb name print_symb name let print_program oc p = extfuns := IdentSet.empty; diff --git a/cfrontend/C2C.ml b/cfrontend/C2C.ml index 966bb76..1a6539a 100644 --- a/cfrontend/C2C.ml +++ b/cfrontend/C2C.ml @@ -719,7 +719,7 @@ let convertFundef env fd = a_env = env; a_type = Cutil.fundef_typ fd; a_fundef = Some fd }; - Sections.define_function id'; + Sections.define_function env id' fd.fd_ret; Datatypes.Coq_pair(id', Internal {fn_return = ret; fn_params = params; fn_vars = vars; fn_body = body'}) @@ -776,21 +776,6 @@ let convertInitializer env ty i = (** Global variable *) -let rec type_is_readonly env t = - let a = Cutil.attributes_of_type env t in - if List.mem C.AVolatile a then false else - if List.mem C.AConst a then true else - match Cutil.unroll env t with - | C.TArray(t', _, _) -> type_is_readonly env t' - | _ -> false - -let rec type_is_volatile env t = - let a = Cutil.attributes_of_type env t in - if List.mem C.AConst a then true else - match Cutil.unroll env t with - | C.TArray(t', _, _) -> type_is_volatile env t' - | _ -> false - let convertGlobvar env (sto, id, ty, optinit) = let id' = intern_string id.name in let ty' = convertTyp env ty in @@ -805,13 +790,14 @@ let convertGlobvar env (sto, id, ty, optinit) = a_env = env; a_type = ty; a_fundef = None }; - Sections.define_variable id' - (match Cutil.sizeof env ty with Some sz -> sz | None -> max_int) - (type_is_readonly env ty); + Sections.define_variable env id' ty; + let a = Cutil.attributes_of_type env ty in + let volatile = List.mem C.AVolatile a in + let readonly = List.mem C.AConst a && not volatile in Datatypes.Coq_pair(id', {gvar_info = ty'; gvar_init = init'; - gvar_readonly = type_is_readonly env ty; - gvar_volatile = type_is_volatile env ty}) + gvar_readonly = readonly; + gvar_volatile = volatile}) (** Convert a list of global declarations. Result is a pair [(funs, vars)] where [funs] are @@ -937,6 +923,7 @@ let atom_is_extern a = with Not_found -> false +(* let atom_is_readonly a = try let i = Hashtbl.find decl_atom a in type_is_readonly i.a_env i.a_type @@ -948,10 +935,16 @@ let atom_sizeof a = let i = Hashtbl.find decl_atom a in Cutil.sizeof i.a_env i.a_type with Not_found -> None +*) let atom_alignof a = try - let i = Hashtbl.find decl_atom a in Cutil.alignof i.a_env i.a_type + let i = Hashtbl.find decl_atom a in + match Cutil.find_custom_attributes + ["aligned"; "__aligned__"] + (Cutil.attributes_of_type i.a_env i.a_type) with + | [[C.AInt n]] -> Some(Int64.to_int n) + | _ -> Cutil.alignof i.a_env i.a_type with Not_found -> None diff --git a/common/Sections.ml b/common/Sections.ml index 9124f85..f37144a 100644 --- a/common/Sections.ml +++ b/common/Sections.ml @@ -14,6 +14,7 @@ (* *********************************************************************) open Camlcoq +open Cparser module StringMap = Map.Make(String) @@ -165,19 +166,50 @@ let default_use_section id name = assert ok end -let define_function id = - default_use_section id "CODE" +(* Associate an undeclared section to a global symbol, GCC-style *) + +let use_gcc_section id name readonly exec = + Hashtbl.add section_table_at_def id !current_section_table; + let sn = Section_user(name, not readonly, exec) in + let si = { sec_name_init = sn; sec_name_uninit = sn; + sec_writable = not readonly; sec_executable = exec; + sec_near_access = false } in + Hashtbl.add use_section_table id si + +(* Record sections for a variable definition *) + +let define_variable env id ty = + let attr = Cutil.attributes_of_type env ty in + let readonly = List.mem C.AConst attr && not(List.mem C.AVolatile attr) in + (* Check for a GCC-style "section" attribute *) + match Cutil.find_custom_attributes ["section"; "__section__"] attr with + | [[C.AString name]] -> + (* Use gcc-style section *) + use_gcc_section id name readonly false + | _ -> + (* Use default section appropriate for size and const-ness *) + let size = match Cutil.sizeof env ty with Some sz -> sz | None -> max_int in + default_use_section id + (if readonly + then if size <= !Clflags.option_small_const then "SCONST" else "CONST" + else if size <= !Clflags.option_small_data then "SDATA" else "DATA") + +(* Record sections for a function definition *) + +let define_function env id ty_res = + let attr = Cutil.attributes_of_type env ty_res in + match Cutil.find_custom_attributes ["section"; "__section__"] attr with + | [[C.AString name]] -> + use_gcc_section id name true true + | _ -> + default_use_section id "CODE" + +(* Record sections for a string literal *) let define_stringlit id = default_use_section id "STRING" -let define_variable id size readonly = - default_use_section id - (if readonly - then if size <= !Clflags.option_small_const then "SCONST" else "CONST" - else if size <= !Clflags.option_small_data then "SDATA" else "DATA") - -(* Determine section to use for a variable definition *) +(* Determine section to use for a variable *) let section_for_variable a initialized = try @@ -186,8 +218,7 @@ let section_for_variable a initialized = with Not_found -> Section_data initialized -(* Determine (text, literal, jumptable) sections to use - for a function definition *) +(* Determine (text, literal, jumptable) sections to use for a function *) let sections_for_function a = let s_text = diff --git a/common/Sections.mli b/common/Sections.mli index 090d4bb..c6a7c96 100644 --- a/common/Sections.mli +++ b/common/Sections.mli @@ -34,8 +34,8 @@ val define_section: -> ?writable:bool -> ?executable:bool -> ?near:bool -> unit -> unit val use_section_for: AST.ident -> string -> bool -val define_function: AST.ident -> unit -val define_variable: AST.ident -> int -> bool -> unit +val define_function: Cparser.Env.t -> AST.ident -> Cparser.C.typ -> unit +val define_variable: Cparser.Env.t -> AST.ident -> Cparser.C.typ -> unit val define_stringlit: AST.ident -> unit val section_for_variable: AST.ident -> bool -> section_name diff --git a/ia32/PrintAsm.ml b/ia32/PrintAsm.ml index e4de2a3..33aae6a 100644 --- a/ia32/PrintAsm.ml +++ b/ia32/PrintAsm.ml @@ -15,6 +15,7 @@ open Printf open Datatypes open Camlcoq +open Sections open AST open Asm @@ -132,26 +133,46 @@ let section oc name = (* Names of sections *) -let (text, data, const_data, float_literal, jumptable_literal) = +let name_of_section_ELF = function + | Section_text -> ".text" + | Section_data i | Section_small_data i -> if i then ".data" else ".bss" + | Section_const | Section_small_const -> ".rodata" + | Section_string -> ".rodata" + | Section_literal -> ".section .rodata.cst8,\"aM\",@progbits,8" + | Section_jumptable -> ".text" + | Section_user(s, wr, ex) -> + sprintf ".section %s,\"a%s%s\",@progbits" + s (if wr then "w" else "") (if ex then "x" else "") + +let name_of_section_MacOS = function + | Section_text -> ".text" + | Section_data _ | Section_small_data _ -> ".data" + | Section_const | Section_small_const -> ".const" + | Section_string -> ".const" + | Section_literal -> ".literal8" + | Section_jumptable -> ".const" + | Section_user(s, wr, ex) -> + sprintf ".section %s, %s, %s" + (if wr then "__DATA" else "__TEXT") s + (if ex then "regular, pure_instructions" else "regular") + +let name_of_section_Cygwin = function + | Section_text -> ".text" + | Section_data _ | Section_small_data _ -> ".data" + | Section_const | Section_small_const -> ".section .rdata,\"dr\"" + | Section_string -> ".section .rdata,\"dr\"" + | Section_literal -> ".section .rdata,\"dr\"" + | Section_jumptable -> ".text" + | Section_user _ -> assert false + +let name_of_section = match target with - | ELF -> - (".text", - ".data", - ".section .rodata", - ".section .rodata.cst8,\"a\",@progbits", - ".text") - | MacOS -> - (".text", - ".data", - ".const", - ".const_data", - ".text") - | Cygwin -> - (".text", - ".data", - ".section .rdata,\"dr\"", - ".section .rdata,\"dr\"", - ".text") + | ELF -> name_of_section_ELF + | MacOS -> name_of_section_MacOS + | Cygwin -> name_of_section_Cygwin + +let section oc sec = + fprintf oc " %s\n" (name_of_section sec) (* SP adjustment to allocate or free a stack frame *) @@ -587,6 +608,7 @@ let print_function oc name code = Hashtbl.clear current_function_labels; float_literals := []; jumptables := []; + let (text, lit, jmptbl) = sections_for_function name in section oc text; print_align oc 16; if not (C2C.atom_is_static name) then @@ -598,13 +620,13 @@ let print_function oc name code = fprintf oc " .size %a, . - %a\n" symbol name symbol name end; if !float_literals <> [] then begin - section oc float_literal; + section oc lit; print_align oc 8; List.iter (print_literal oc) !float_literals; float_literals := [] end; if !jumptables <> [] then begin - section oc jumptable_literal; + section oc jmptbl; print_align oc 4; List.iter (print_jumptable oc) !jumptables; jumptables := [] @@ -645,8 +667,10 @@ let print_var oc (Coq_pair(name, v)) = match v.gvar_init with | [] -> () | _ -> + let init = + match v.gvar_init with [Init_space _] -> false | _ -> true in let sec = - if v.gvar_readonly then const_data else data + Sections.section_for_variable name init and align = match C2C.atom_alignof name with | Some a -> a @@ -668,7 +692,7 @@ let print_program oc p = List.iter (print_var oc) p.prog_vars; List.iter (print_fundef oc) p.prog_funct; if !need_masks then begin - section oc float_literal; + section oc Section_const; (* not Section_literal because not 8-bytes *) print_align oc 16; fprintf oc "%a: .quad 0x8000000000000000, 0\n" raw_symbol "__negd_mask"; diff --git a/powerpc/PrintAsm.ml b/powerpc/PrintAsm.ml index c0f9294..71d73c0 100644 --- a/powerpc/PrintAsm.ml +++ b/powerpc/PrintAsm.ml @@ -192,9 +192,12 @@ let name_of_section_MacOS = function | Section_const -> ".const" | Section_small_const -> ".const" | Section_string -> ".const" - | Section_literal -> ".const_data" - | Section_jumptable -> ".text" - | Section_user _ -> assert false + | Section_literal -> ".literal8" + | Section_jumptable -> ".const" + | Section_user(s, wr, ex) -> + sprintf ".section %s, %s, %s" + (if wr then "__DATA" else "__TEXT") s + (if ex then "regular, pure_instructions" else "regular") let name_of_section_Linux = function | Section_text -> ".text" @@ -479,7 +482,10 @@ let print_instruction oc labels = function fprintf oc " bt %a, %a\n" crbit bit label (transl_label lbl) | Pbtbl(r, tbl) -> let lbl = new_label() in - fprintf oc "%s begin pseudoinstr btbl(%a, %a)\n" comment ireg r label lbl; + fprintf oc "%s begin pseudoinstr btbl(%a)\n comment ireg r; + fprintf oc "%s jumptable [ " comment; + List.iter (fun l -> fprintf oc "%a " (transl_label l)) tbl; + fprintf oc "]\n"; fprintf oc " addis %a, %a, %a\n" ireg GPR12 ireg r label_high lbl; fprintf oc " lwz %a, %a(%a)\n" ireg GPR12 label_low lbl ireg GPR12; fprintf oc " mtctr %a\n" ireg GPR12; |