summaryrefslogtreecommitdiff
path: root/powerpc/eabi/CPragmas.ml
diff options
context:
space:
mode:
Diffstat (limited to 'powerpc/eabi/CPragmas.ml')
-rw-r--r--powerpc/eabi/CPragmas.ml134
1 files changed, 134 insertions, 0 deletions
diff --git a/powerpc/eabi/CPragmas.ml b/powerpc/eabi/CPragmas.ml
new file mode 100644
index 0000000..9d2eb8a
--- /dev/null
+++ b/powerpc/eabi/CPragmas.ml
@@ -0,0 +1,134 @@
+(* *********************************************************************)
+(* *)
+(* The Compcert verified compiler *)
+(* *)
+(* Xavier Leroy, INRIA Paris-Rocquencourt *)
+(* *)
+(* Copyright Institut National de Recherche en Informatique et en *)
+(* Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the GNU General Public License as published by *)
+(* the Free Software Foundation, either version 2 of the License, or *)
+(* (at your option) any later version. This file is also distributed *)
+(* under the terms of the INRIA Non-Commercial License Agreement. *)
+(* *)
+(* *********************************************************************)
+
+(* Platform-dependent handling of pragmas *)
+
+open Printf
+open Cil
+open Camlcoq
+
+type section_info = {
+ sec_name_init: string;
+ sec_name_uninit: string;
+ sec_near_access: bool
+}
+
+let section_table : (string, section_info) Hashtbl.t =
+ Hashtbl.create 17
+
+let use_section_table : (AST.ident, section_info) Hashtbl.t =
+ Hashtbl.create 51
+
+let process_section_pragma classname istring ustring addrmode accmode =
+ let is_near = (addrmode = "near-absolute") || (addrmode = "near-data") in
+ let is_writable = String.contains accmode 'W'
+ and is_executable = String.contains accmode 'X' in
+ let sec_type =
+ match is_writable, is_executable with
+ | true, true -> 'm' (* text+data *)
+ | true, false -> 'd' (* data *)
+ | false, true -> 'c' (* text *)
+ | false, false -> 'r' (* const *)
+ in
+ let info =
+ { sec_name_init = sprintf "%s,,%c" istring sec_type;
+ sec_name_uninit = sprintf "%s,,%c" ustring sec_type;
+ sec_near_access = is_near } in
+ Hashtbl.add section_table classname info
+
+let process_use_section_pragma classname id =
+ try
+ let info = Hashtbl.find section_table classname in
+ Hashtbl.add use_section_table (intern_string id) info
+ with Not_found ->
+ Cil2Csyntax.error (sprintf "unknown section name `%s'" classname)
+
+(* CIL does not parse the "section" and "use_section" pragmas, which
+ have irregular syntax, so we parse them using regexps *)
+
+let re_start_pragma_section = Str.regexp "section\\b"
+
+let re_pragma_section = Str.regexp
+ "section[ \t]+\
+ \\([A-Za-z_][A-Za-z_0-9]*\\)[ \t]+\
+ \"\\([^\"]*\\)\"[ \t]+\
+ \"\\([^\"]*\\)\"[ \t]+\
+ \\([a-z-]+\\)[ \t]+\
+ \\([A-Z]+\\)"
+
+let re_start_pragma_use_section = Str.regexp "use_section\\b"
+
+let re_pragma_use_section = Str.regexp
+ "use_section[ \t]+\
+ \\([A-Za-z_][A-Za-z_0-9]*\\)[ \t]+\
+ \\(.*\\)$"
+
+let re_split_idents = Str.regexp "[ \t,]+"
+
+let process_pragma (Attr(name, _)) =
+ if Str.string_match re_pragma_section name 0 then begin
+ process_section_pragma
+ (Str.matched_group 1 name) (* classname *)
+ (Str.matched_group 2 name) (* istring *)
+ (Str.matched_group 3 name) (* ustring *)
+ (Str.matched_group 4 name) (* addrmode *)
+ (Str.matched_group 5 name); (* accmode *)
+ true
+ end else if Str.string_match re_start_pragma_section name 0 then
+ Cil2Csyntax.error "ill-formed `section' pragma"
+ else if Str.string_match re_pragma_use_section name 0 then begin
+ let classname = Str.matched_group 1 name
+ and idents = Str.matched_group 2 name in
+ let identlist = Str.split re_split_idents idents in
+ if identlist = [] then Cil2Csyntax.warning "vacuous `use_section' pragma";
+ List.iter (process_use_section_pragma classname) identlist;
+ true
+ end else if Str.string_match re_start_pragma_use_section name 0 then
+ Cil2Csyntax.error "ill-formed `use_section' pragma"
+ else
+ false
+
+let initialize () =
+ Cil2Csyntax.process_pragma := process_pragma
+
+(* PowerPC-specific: say if an atom is in a small data area *)
+
+let atom_is_small_data a ofs =
+ match Configuration.system with
+ | "diab" ->
+ begin try
+ let v = Hashtbl.find Cil2Csyntax.varinfo_atom a in
+ let sz = Cil.bitsSizeOf v.vtype / 8 in
+ let ofs = camlint_of_coqint ofs in
+ if ofs >= 0l && ofs < Int32.of_int sz then begin
+ try (Hashtbl.find use_section_table a).sec_near_access
+ with Not_found -> sz <= 8
+ end else
+ false
+ with Not_found ->
+ false
+ end
+ | _ ->
+ false
+
+(* PowerPC-specific: determine section to use for a particular symbol *)
+
+let section_for_atom a init =
+ try
+ let sinfo = Hashtbl.find use_section_table a in
+ Some(if init then sinfo.sec_name_init else sinfo.sec_name_uninit)
+ with Not_found ->
+ None
+