aboutsummaryrefslogtreecommitdiffstats
path: root/cfrontend/C2C.ml
diff options
context:
space:
mode:
Diffstat (limited to 'cfrontend/C2C.ml')
-rw-r--r--cfrontend/C2C.ml126
1 files changed, 114 insertions, 12 deletions
diff --git a/cfrontend/C2C.ml b/cfrontend/C2C.ml
index ef621a7c..0ccf569b 100644
--- a/cfrontend/C2C.ml
+++ b/cfrontend/C2C.ml
@@ -147,8 +147,8 @@ let builtins_generic = {
(TVoid [],
[TPtr(TVoid [], []);
TPtr(TVoid [AConst], []);
- TInt(Cutil.size_t_ikind, []);
- TInt(Cutil.size_t_ikind, [])],
+ TInt(IUInt, []);
+ TInt(IUInt, [])],
false);
(* Annotations *)
"__builtin_annot",
@@ -198,7 +198,60 @@ let builtins_generic = {
"__compcert_va_float64",
(TFloat(FDouble, []),
[TPtr(TVoid [], [])],
- false)
+ false);
+ (* Helper functions for int64 arithmetic *)
+ "__i64_dtos",
+ (TInt(ILongLong, []),
+ [TFloat(FDouble, [])],
+ false);
+ "__i64_dtou",
+ (TInt(IULongLong, []),
+ [TFloat(FDouble, [])],
+ false);
+ "__i64_stod",
+ (TFloat(FDouble, []),
+ [TInt(ILongLong, [])],
+ false);
+ "__i64_utod",
+ (TFloat(FDouble, []),
+ [TInt(IULongLong, [])],
+ false);
+ "__i64_stof",
+ (TFloat(FFloat, []),
+ [TInt(ILongLong, [])],
+ false);
+ "__i64_utof",
+ (TFloat(FFloat, []),
+ [TInt(IULongLong, [])],
+ false);
+ "__i64_sdiv",
+ (TInt(ILongLong, []),
+ [TInt(ILongLong, []); TInt(ILongLong, [])],
+ false);
+ "__i64_udiv",
+ (TInt(IULongLong, []),
+ [TInt(IULongLong, []); TInt(IULongLong, [])],
+ false);
+ "__i64_smod",
+ (TInt(ILongLong, []),
+ [TInt(ILongLong, []); TInt(ILongLong, [])],
+ false);
+ "__i64_umod",
+ (TInt(IULongLong, []),
+ [TInt(IULongLong, []); TInt(IULongLong, [])],
+ false);
+ "__i64_shl",
+ (TInt(ILongLong, []),
+ [TInt(ILongLong, []); TInt(IInt, [])],
+ false);
+ "__i64_shr",
+ (TInt(IULongLong, []),
+ [TInt(IULongLong, []); TInt(IInt, [])],
+ false);
+ "__i64_sar",
+ (TInt(ILongLong, []),
+ [TInt(ILongLong, []); TInt(IInt, [])],
+ false)
]
}
@@ -211,7 +264,8 @@ let builtins =
(** ** Functions used to handle string literals *)
let stringNum = ref 0 (* number of next global for string literals *)
-let stringTable = Hashtbl.create 47
+let stringTable : (string, AST.ident) Hashtbl.t = Hashtbl.create 47
+let wstringTable : (int64 list, AST.ident) Hashtbl.t = Hashtbl.create 47
let name_for_string_literal env s =
try
@@ -231,7 +285,8 @@ let name_for_string_literal env s =
id
let typeStringLiteral s =
- Tarray(Tint(I8, Unsigned, noattr), Z.of_uint (String.length s + 1), noattr)
+ let sg = if Machine.((!config).char_signed) then Signed else Unsigned in
+ Tarray(Tint(I8, sg, noattr), Z.of_uint (String.length s + 1), noattr)
let global_for_string s id =
let init = ref [] in
@@ -242,10 +297,57 @@ let global_for_string s id =
(id, Gvar {gvar_info = typeStringLiteral s; gvar_init = !init;
gvar_readonly = true; gvar_volatile = false})
+let name_for_wide_string_literal env s =
+ try
+ Hashtbl.find wstringTable s
+ with Not_found ->
+ incr stringNum;
+ let name = Printf.sprintf "__stringlit_%d" !stringNum in
+ let id = intern_string name in
+ Hashtbl.add decl_atom id
+ { a_storage = C.Storage_static;
+ a_alignment = Some Machine.((!config).sizeof_wchar);
+ a_sections = [Sections.for_stringlit()];
+ a_access = Sections.Access_default;
+ a_inline = false;
+ a_loc = Cutil.no_loc };
+ Hashtbl.add wstringTable s id;
+ id
+
+let typeWideStringLiteral s =
+ let sz =
+ match Machine.((!config).sizeof_wchar) with
+ | 2 -> I16
+ | 4 -> I32
+ | _ -> assert false in
+ let sg =
+ if Machine.((!config).wchar_signed) then Signed else Unsigned in
+ Tarray(Tint(sz, sg, noattr), Z.of_uint (List.length s + 1), noattr)
+
+let global_for_wide_string s id =
+ let init = ref [] in
+ let init_of_char =
+ match Machine.((!config).sizeof_wchar) with
+ | 2 -> (fun z -> AST.Init_int16 z)
+ | 4 -> (fun z -> AST.Init_int32 z)
+ | _ -> assert false in
+ let add_char c =
+ init := init_of_char(Z.of_uint64 c) :: !init in
+ List.iter add_char s;
+ add_char 0L;
+ (id, Gvar {gvar_info = typeWideStringLiteral s; gvar_init = List.rev !init;
+ gvar_readonly = true; gvar_volatile = false})
+
let globals_for_strings globs =
- Hashtbl.fold
- (fun s id l -> global_for_string s id :: l)
- stringTable globs
+ let globs1 =
+ Hashtbl.fold
+ (fun s id l -> global_for_wide_string s id :: l)
+ wstringTable globs in
+ let globs2 =
+ Hashtbl.fold
+ (fun s id l -> global_for_string s id :: l)
+ stringTable globs1 in
+ globs2
(** ** Handling of inlined memcpy functions *)
@@ -509,7 +611,8 @@ let rec convertExpr env e =
let ty = typeStringLiteral s in
Evalof(Evar(name_for_string_literal env s, ty), ty)
| C.EConst(C.CWStr s) ->
- unsupported "wide string literal"; ezero
+ let ty = typeWideStringLiteral s in
+ Evalof(Evar(name_for_wide_string_literal env s, ty), ty)
| C.EConst(C.CEnum(id, i)) ->
Ctyping.econst_int (convertInt i) Signed
| C.ESizeof ty1 ->
@@ -789,8 +892,6 @@ let rec convertStmt ploc env s =
Scontinue
| C.Sswitch(e, s1) ->
let (init, cases) = groupSwitch (flattenSwitch s1) in
- if cases = [] then
- unsupported "ill-formed 'switch' statement";
if init.sdesc <> C.Sskip then
warning "ignored code at beginning of 'switch'";
let te = convertExpr env e in
@@ -869,7 +970,7 @@ let convertFundef loc env fd =
a_alignment = None;
a_sections = Sections.for_function env id' fd.fd_ret;
a_access = Sections.Access_default;
- a_inline = fd.fd_inline;
+ a_inline = fd.fd_inline && not fd.fd_vararg; (* PR#15 *)
a_loc = loc };
(id', Gfun(Internal {fn_return = ret;
fn_callconv = convertCallconv fd.fd_vararg fd.fd_attrib;
@@ -1089,6 +1190,7 @@ let convertProgram p =
stringNum := 0;
Hashtbl.clear decl_atom;
Hashtbl.clear stringTable;
+ Hashtbl.clear wstringTable;
let p = cleanupGlobals (Builtins.declarations() @ p) in
try
let env = translEnv Env.empty p in