diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/hipe/sparc/hipe_sparc_finalise.erl | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/hipe/sparc/hipe_sparc_finalise.erl')
-rw-r--r-- | lib/hipe/sparc/hipe_sparc_finalise.erl | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/lib/hipe/sparc/hipe_sparc_finalise.erl b/lib/hipe/sparc/hipe_sparc_finalise.erl new file mode 100644 index 0000000000..b44a21f7c0 --- /dev/null +++ b/lib/hipe/sparc/hipe_sparc_finalise.erl @@ -0,0 +1,138 @@ +%% -*- erlang-indent-level: 2 -*- +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% + +-module(hipe_sparc_finalise). +-export([finalise/1]). +-include("hipe_sparc.hrl"). + +finalise(Defun) -> + #defun{code=Code0} = Defun, + Code1 = peep(expand(Code0)), + Defun#defun{code=Code1}. + +expand(Insns) -> + expand_list(Insns, []). + +expand_list([I|Insns], Accum) -> + expand_list(Insns, expand_insn(I, Accum)); +expand_list([], Accum) -> + lists:reverse(Accum). + +expand_insn(I, Accum) -> + case I of + #bp{'cond'='a'} -> + [hipe_sparc:mk_nop(), + I | + Accum]; + #call_rec{} -> + [hipe_sparc:mk_nop(), + I | + Accum]; + #call_tail{} -> + RA = hipe_sparc:mk_ra(), + TempRA = hipe_sparc:mk_temp1(), + [hipe_sparc:mk_mov(TempRA, RA), + I, % becomes a call, which clobbers RA + hipe_sparc:mk_mov(RA, TempRA) | + Accum]; + #jmp{} -> + [hipe_sparc:mk_nop(), + I | + Accum]; + #pseudo_bp{'cond'=Cond,true_label=TrueLab,false_label=FalseLab, pred=Pred} -> + [hipe_sparc:mk_nop(), + hipe_sparc:mk_b_label(FalseLab), + hipe_sparc:mk_nop(), + hipe_sparc:mk_bp(Cond, TrueLab, Pred) | + Accum]; + %% #pseudo_br{} -> expand_pseudo_br(I, Accum); + #pseudo_call{funv=FunV,sdesc=SDesc,contlab=ContLab,linkage=Linkage} -> + [hipe_sparc:mk_nop(), + hipe_sparc:mk_b_label(ContLab), + hipe_sparc:mk_nop(), + case FunV of + #sparc_temp{} -> + hipe_sparc:mk_jmpl(FunV, SDesc); + _ -> + hipe_sparc:mk_call_rec(FunV, SDesc, Linkage) + end | + Accum]; + #pseudo_ret{} -> + RA = hipe_sparc:mk_ra(), + [hipe_sparc:mk_nop(), + hipe_sparc:mk_jmp(RA, hipe_sparc:mk_simm13(8), []) | + Accum]; + #pseudo_tailcall_prepare{} -> + Accum; + _ -> + XXX = + case I of + #alu{} -> true; + #comment{} -> true; + #label{} -> true; + #pseudo_set{} -> true; + #rdy{} -> true; + #sethi{} -> true; + #store{} -> true; + #bp{} -> false; + %% #br{} -> false; + #call_rec{} -> false; + #call_tail{} -> false; + #jmp{} -> false; + #jmpl{} -> false; + #pseudo_bp{} -> false; + %% #pseudo_br{} -> false; + #pseudo_call{} -> false; + #pseudo_call_prepare{} -> false; + #pseudo_move{} -> false; + #pseudo_ret{} -> false; + #pseudo_tailcall{} -> false; + #pseudo_tailcall_prepare{} -> false; + #fp_binary{} -> true; + #fp_unary{} -> true; + #pseudo_fload{} -> true; + #pseudo_fstore{} -> true + end, + case XXX of + true -> []; + false -> exit({?MODULE,expand_insn,I}) + end, + [I|Accum] + end. + +-ifdef(notdef). % XXX: only for sparc64, alas +expand_pseudo_br(I, Accum) -> + #pseudo_br{rcond=RCond,src=Src,true_label=TrueLab,false_label=FalseLab, pred=Pred} = I, + [hipe_sparc:mk_nop(), + hipe_sparc:mk_b_label(FalseLab), + hipe_sparc:mk_nop(), + hipe_sparc:mk_br(RCond, Src, TrueLab, Pred) | + Accum]. +-endif. + +peep(Insns) -> + peep_list(Insns, []). + +peep_list([#bp{'cond'='a',label=Label}, #sethi{uimm22=#sparc_uimm22{value=0},dst=#sparc_temp{reg=0}} | (Insns = [#label{label=Label}|_])], Accum) -> + peep_list(Insns, Accum); +peep_list([I|Insns], Accum) -> + peep_list(Insns, [I|Accum]); +peep_list([], Accum) -> + lists:reverse(Accum). |