aboutsummaryrefslogtreecommitdiffstats
path: root/cparser
diff options
context:
space:
mode:
authorxleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-04-17 07:01:18 +0000
committerxleroy <xleroy@fca1b0fc-160b-0410-b1d3-a4f43f01ea2e>2010-04-17 07:01:18 +0000
commit59646439baa1b9cc6209b684e4ccf9aac908fdbc (patch)
tree55f0b7c0f82f9b0e32ba754dc129938ac1242cc9 /cparser
parent9e9853b79e652036c2e5c7af01d8ac9add0b8962 (diff)
downloadcompcert-kvx-59646439baa1b9cc6209b684e4ccf9aac908fdbc.tar.gz
compcert-kvx-59646439baa1b9cc6209b684e4ccf9aac908fdbc.zip
Support __builtin_memcpy; use it for struct assignment
git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@1319 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e
Diffstat (limited to 'cparser')
-rw-r--r--cparser/GCC.ml2
-rw-r--r--cparser/StructAssign.ml54
2 files changed, 26 insertions, 30 deletions
diff --git a/cparser/GCC.ml b/cparser/GCC.ml
index 9f864dcd..17b718b4 100644
--- a/cparser/GCC.ml
+++ b/cparser/GCC.ml
@@ -124,7 +124,7 @@ let builtins = {
"__builtin_inf", (doubleType, [], false);
"__builtin_inff", (floatType, [], false);
"__builtin_infl", (longDoubleType, [], false);
- "__builtin_memcpy", (voidPtrType, [ voidPtrType; voidConstPtrType; uintType ], false);
+ "__builtin_memcpy", (voidPtrType, [ voidPtrType; voidConstPtrType; sizeType ], false);
"__builtin_mempcpy", (voidPtrType, [ voidPtrType; voidConstPtrType; sizeType ], false);
"__builtin_fmod", (doubleType, [ doubleType ], false);
diff --git a/cparser/StructAssign.ml b/cparser/StructAssign.ml
index f5cecfc5..3be917e8 100644
--- a/cparser/StructAssign.ml
+++ b/cparser/StructAssign.ml
@@ -19,13 +19,14 @@
Preserves: simplified code, unblocked code *)
open C
+open Machine
open Cutil
open Env
open Errors
let maxsize = ref 8
-let need_memcpy = ref (None: ident option)
+let memcpy_decl = ref (None : ident option)
let memcpy_type =
TFun(TPtr(TVoid [], []),
@@ -34,14 +35,18 @@ let memcpy_type =
(Env.fresh_ident "", TInt(size_t_ikind, []))],
false, [])
-let memcpy_ident () =
- match !need_memcpy with
- | None ->
- let id = Env.fresh_ident "memcpy" in
- need_memcpy := Some id;
- id
- | Some id ->
- id
+let memcpy_ident env =
+ try fst (Env.lookup_ident env "__builtin_memcpy")
+ with Env.Error _ ->
+ try fst (Env.lookup_ident env "memcpy")
+ with Env.Error _ ->
+ match !memcpy_decl with
+ | Some id -> id
+ | None -> let id = Env.fresh_ident "memcpy" in memcpy_decl := Some id; id
+
+let memcpy_words_ident env =
+ try fst (Env.lookup_ident env "__builtin_memcpy_words")
+ with Env.Error _ -> memcpy_ident env
let transf_assign env loc lhs rhs =
@@ -89,7 +94,15 @@ let transf_assign env loc lhs rhs =
try
transf lhs rhs
with Exit ->
- let memcpy = {edesc = EVar(memcpy_ident()); etyp = memcpy_type} in
+ let by_words =
+ match Cutil.sizeof env lhs.etyp with
+ | Some n -> n mod !config.sizeof_ptr = 0
+ | None -> false in
+ let ident =
+ if by_words
+ then memcpy_word_ident()
+ else memcpy_ident() in
+ let memcpy = {edesc = EVar(ident); etyp = memcpy_type} in
let e_lhs = {edesc = EUnop(Oaddrof, lhs); etyp = TPtr(lhs.etyp, [])} in
let e_rhs = {edesc = EUnop(Oaddrof, rhs); etyp = TPtr(rhs.etyp, [])} in
let e_size = {edesc = ESizeof(lhs.etyp); etyp = TInt(size_t_ikind, [])} in
@@ -131,27 +144,10 @@ let transf_fundef env fd =
{fd with fd_body = transf_stmt env fd.fd_body}
let program p =
- need_memcpy := None;
+ memcpy_decl := None;
let p' = Transform.program ~fundef:transf_fundef p in
- match !need_memcpy with
+ match !memcpy_decl with
| None -> p'
| Some id ->
{gdesc = Gdecl(Storage_extern, id, memcpy_type, None); gloc = no_loc}
:: p'
-
-(* Horrible hack *)
-(***
- let has_memcpy = ref false in
- need_memcpy := None;
- List.iter
- (function {gdesc = Gdecl(_, ({name = "memcpy"} as id), _, _)} ->
- need_memcpy := Some id; has_memcpy := true
- | _ -> ())
- p;
- let p' = Transform.program ~fundef:transf_fundef p in
- match !need_memcpy with
- | Some id when not !has_memcpy ->
- {gdesc = Gdecl(Storage_extern, id, memcpy_type, None); gloc = no_loc}
- :: p'
- | _ -> p'
-***)