aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2015-07-07 15:38:41 +0200
committerXavier Leroy <xavier.leroy@inria.fr>2015-07-07 15:38:41 +0200
commit4148ee08387bf953bdbe69f7668597ec0bcccc29 (patch)
treea44132c0ead229fdd22eaec196eb7e69428b526c
parent7c361e1bf90166ea65c7a9bcde3fcb53f4ef2e8c (diff)
downloadcompcert-4148ee08387bf953bdbe69f7668597ec0bcccc29.tar.gz
compcert-4148ee08387bf953bdbe69f7668597ec0bcccc29.zip
Set/clear CR6 before calling an unprototyped function.
A function declared without a prototype could be implemented by a vararg function (even though this is undefined behavior in C99). Be nice in this case.
-rw-r--r--powerpc/Asmexpand.ml7
1 files changed, 4 insertions, 3 deletions
diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml
index 3f4dc94b..fd252b98 100644
--- a/powerpc/Asmexpand.ml
+++ b/powerpc/Asmexpand.ml
@@ -427,11 +427,12 @@ let expand_builtin_inline name args res =
(* Calls to variadic functions: condition bit 6 must be set
if at least one argument is a float; clear otherwise.
- Note that variadic functions cannot have arguments of type Tsingle. *)
+ For compatibility with other compilers, do the same if the called
+ function is unprototyped. *)
let set_cr6 sg =
- if sg.sig_cc.cc_vararg then begin
- if List.mem Tfloat sg.sig_args
+ if sg.sig_cc.cc_vararg || sg.sig_cc.cc_unproto then begin
+ if List.exists (function Tfloat | Tsingle -> true | _ -> false) sg.sig_args
then emit (Pcreqv(CRbit_6, CRbit_6, CRbit_6))
else emit (Pcrxor(CRbit_6, CRbit_6, CRbit_6))
end