diff options
author | Bernhard Schommer <bernhardschommer@gmail.com> | 2015-09-07 19:35:02 +0200 |
---|---|---|
committer | Bernhard Schommer <bernhardschommer@gmail.com> | 2015-09-07 19:35:02 +0200 |
commit | 73e20bd6e0586e38fbc7d87d8c306fad7b578418 (patch) | |
tree | 3b4ffcfd6ab4df231a2fa66716fa58b4d5ab1b76 /powerpc/Asmexpand.ml | |
parent | 76d82e41797ef79531e6bf3d530f380dddd3310e (diff) | |
download | compcert-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.ml | 19 |
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 |