diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 2015-07-07 15:38:41 +0200 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 2015-07-07 15:38:41 +0200 |
commit | 4148ee08387bf953bdbe69f7668597ec0bcccc29 (patch) | |
tree | a44132c0ead229fdd22eaec196eb7e69428b526c /powerpc | |
parent | 7c361e1bf90166ea65c7a9bcde3fcb53f4ef2e8c (diff) | |
download | compcert-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.
Diffstat (limited to 'powerpc')
-rw-r--r-- | powerpc/Asmexpand.ml | 7 |
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 |