hipe_arm_defuse.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 141 行
ERL
141 行
%%% -*- erlang-indent-level: 2 -*-%%% $Id$-module(hipe_arm_defuse).-export([insn_def_all/1, insn_use_all/1]).-export([insn_def_gpr/1, insn_use_gpr/1]).-include("hipe_arm.hrl").%%%%%% Defs and uses for both general-purpose and floating-point registers.%%% This is needed for the frame module, alas.%%%insn_def_all(I) -> insn_def_gpr(I).insn_use_all(I) -> insn_use_gpr(I).%%%%%% Defs and uses for general-purpose (integer) registers only.%%%insn_def_gpr(I) -> case I of #alu{dst=Dst} -> [Dst]; #load{dst=Dst} -> [Dst]; #ldrsb{dst=Dst} -> [Dst]; #move{dst=Dst} -> [Dst]; #pseudo_call{} -> call_clobbered_gpr(); #pseudo_li{dst=Dst} -> [Dst]; #pseudo_move{dst=Dst} -> [Dst]; #pseudo_tailcall_prepare{} -> tailcall_clobbered_gpr(); #smull{dstlo=DstLo,dsthi=DstHi,src1=Src1} -> %% ARM requires DstLo, DstHi, and Src1 to be distinct. %% Add fake DEF of Src1 to prevent regalloc from reusing %% it as DstLo or DstHi. [DstLo, DstHi, Src1]; _ -> [] end.call_clobbered_gpr() -> [hipe_arm:mk_temp(R, T) || {R,T} <- hipe_arm_registers:call_clobbered() ++ all_fp_pseudos()].all_fp_pseudos() -> []. % XXX: for nowtailcall_clobbered_gpr() -> [hipe_arm:mk_temp(R, T) || {R,T} <- hipe_arm_registers:tailcall_clobbered() ++ all_fp_pseudos()].insn_use_gpr(I) -> case I of #alu{src=Src,am1=Am1} -> am1_use(Am1, [Src]); #blx{src=Src} -> [Src]; #cmp{src=Src,am1=Am1} -> am1_use(Am1, [Src]); #load{am2=Am2} -> am2_use(Am2, []); #ldrsb{am3=Am3} -> am3_use(Am3, []); #move{am1=Am1} -> am1_use(Am1, []); #pseudo_blr{} -> LR = hipe_arm:mk_temp(hipe_arm_registers:lr(), 'untagged'), RV = hipe_arm:mk_temp(hipe_arm_registers:return_value(), 'tagged'), [RV, LR]; #pseudo_bx{src=Src} -> io:format("~w: whoa there! insn_use of ~w occurred\n", [?MODULE,I]), [Src]; #pseudo_call{funv=FunV,sdesc=#arm_sdesc{arity=Arity}} -> funv_use(FunV, arity_use_gpr(Arity)); #pseudo_move{src=Src} -> [Src]; #pseudo_switch{jtab=JTabR,index=IndexR} -> addtemp(JTabR, [IndexR]); #pseudo_tailcall{funv=FunV,arity=Arity,stkargs=StkArgs} -> addargs(StkArgs, addtemps(tailcall_clobbered_gpr(), funv_use(FunV, arity_use_gpr(Arity)))); #smull{src1=Src1,src2=Src2} -> addtemp(Src1, [Src2]); #store{src=Src,am2=Am2} -> am2_use(Am2, [Src]); _ -> [] end.addargs([Arg|Args], Set) -> addargs(Args, addarg(Arg, Set));addargs([], Set) -> Set.addarg(Arg, Set) -> case Arg of #arm_temp{} -> addtemp(Arg, Set); _ -> Set end.arity_use_gpr(Arity) -> [hipe_arm:mk_temp(R, 'tagged') || R <- hipe_arm_registers:args(Arity)].funv_use(FunV, Set) -> case FunV of #arm_temp{} -> addtemp(FunV, Set); _ -> Set end.am1_use(Am1, Set) -> case Am1 of #arm_temp{} -> addtemp(Am1, Set); {Src,rrx} -> addtemp(Src, Set); {Src,_,ShiftArg} -> Set1 = addtemp(Src, Set), case ShiftArg of #arm_temp{} -> addtemp(ShiftArg, Set1); _ -> Set1 end; _ -> Set end.am2_use(#am2{src=Src,offset=Am2Offset}, Set) -> Set1 = addtemp(Src, Set), case Am2Offset of #arm_temp{} -> addtemp(Am2Offset, Set1); {Src2,_} -> addtemp(Src2, Set1); {Src2,_,_} -> addtemp(Src2, Set1); _ -> Set1 end.am3_use(#am3{src=Src,offset=Am3Offset}, Set) -> Set1 = addtemp(Src, Set), case Am3Offset of #arm_temp{} -> addtemp(Am3Offset, Set1); _ -> Set1 end.%%%%%% Auxiliary operations on sets of temps%%% These sets are small. No point using gb_trees, right?%%%addtemps([Arg|Args], Set) -> addtemps(Args, addtemp(Arg, Set));addtemps([], Set) -> Set.addtemp(Temp, Set) -> case lists:member(Temp, Set) of false -> [Temp|Set]; _ -> Set end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?