aboutsummaryrefslogtreecommitdiffstats
path: root/powerpc/Asmexpand.ml
diff options
context:
space:
mode:
authorBernhard Schommer <bernhardschommer@gmail.com>2015-09-07 19:35:02 +0200
committerBernhard Schommer <bernhardschommer@gmail.com>2015-09-07 19:35:02 +0200
commit73e20bd6e0586e38fbc7d87d8c306fad7b578418 (patch)
tree3b4ffcfd6ab4df231a2fa66716fa58b4d5ab1b76 /powerpc/Asmexpand.ml
parent76d82e41797ef79531e6bf3d530f380dddd3310e (diff)
downloadcompcert-kvx-73e20bd6e0586e38fbc7d87d8c306fad7b578418.tar.gz
compcert-kvx-73e20bd6e0586e38fbc7d87d8c306fad7b578418.zip
Added builtins for call frame and return address.
This builtins can be used to get the call frame address and the return address. To correctly compute the load address of the return address the allocframe is extended to contain the offset of the return address.
Diffstat (limited to 'powerpc/Asmexpand.ml')
-rw-r--r--powerpc/Asmexpand.ml19
1 files changed, 17 insertions, 2 deletions
diff --git a/powerpc/Asmexpand.ml b/powerpc/Asmexpand.ml
index b3d357ef..929e6325 100644
--- a/powerpc/Asmexpand.ml
+++ b/powerpc/Asmexpand.ml
@@ -276,6 +276,9 @@ let expand_builtin_vstore chunk args =
assert false
(* Handling of varargs *)
+let linkregister_offset = ref Int.zero
+
+let retaddr_offset = ref Int.zero
let current_function_stacksize = ref 0l
@@ -470,6 +473,16 @@ let expand_builtin_inline name args res =
emit (Pmtspr(n, a1))
| "__builtin_set_spr", _, _ ->
raise (Error "the first argument of __builtin_set_spr must be a constant")
+ (* Frame and return address *)
+ | "__builtin_call_frame", _,BR (IR res) ->
+ let sz = !current_function_stacksize
+ and ofs = !linkregister_offset in
+ if sz < 0x8000l then
+ emit (Paddi(res, GPR1, Cint(coqint_of_camlint sz)))
+ else
+ emit (Plwz(res, Cint ofs, GPR1))
+ | "__builtin_return_address",_,BR (IR res) ->
+ emit (Plwz (res, Cint! retaddr_offset,GPR1))
(* Catch-all *)
| _ ->
raise (Error ("unrecognized builtin " ^ name))
@@ -497,7 +510,7 @@ let num_crbit = function
let expand_instruction instr =
match instr with
- | Pallocframe(sz, ofs) ->
+ | Pallocframe(sz, ofs,retofs) ->
let variadic = (!current_function).fn_sig.sig_cc.cc_vararg in
let sz = camlint_of_coqint sz in
assert (ofs = Int.zero);
@@ -516,7 +529,9 @@ let expand_instruction instr =
{sig_args = []; sig_res = None; sig_cc = cc_default}));
emit (Pmtlr GPR0)
end;
- current_function_stacksize := sz
+ current_function_stacksize := sz;
+ linkregister_offset := ofs;
+ retaddr_offset := retofs
| Pbctr sg | Pbctrl sg | Pbl(_, sg) | Pbs(_, sg) ->
set_cr6 sg;
emit instr