⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hipe_rtl_to_ppc.erl

📁 OTP是开放电信平台的简称
💻 ERL
📖 第 1 页 / 共 3 页
字号:
conv_enter(I, Map, Data) ->  {Args, Map0} = conv_src_list(hipe_rtl:enter_arglist(I), Map),  {Fun, Map1} = conv_fun(hipe_rtl:enter_fun(I), Map0),  I2 = mk_enter(Fun, Args, hipe_rtl:enter_type(I)),  {I2, Map1, Data}.mk_enter(Fun, Args, Linkage) ->  {FixFunC,FunC} = fix_func(Fun),  Arity = length(Args),  {RegArgs,StkArgs} = split_args(Args),  FixFunC ++    move_actuals(RegArgs,		 [hipe_ppc:mk_pseudo_tailcall_prepare(),		  hipe_ppc:mk_pseudo_tailcall(FunC, Arity, StkArgs, Linkage)]).conv_goto(I, Map, Data) ->  I2 = [hipe_ppc:mk_b_label(hipe_rtl:goto_label(I))],  {I2, Map, Data}.conv_label(I, Map, Data) ->  I2 = [hipe_ppc:mk_label(hipe_rtl:label_name(I))],  {I2, Map, Data}.conv_load(I, Map, Data) ->  {Dst, Map0} = conv_dst(hipe_rtl:load_dst(I), Map),  {Base1, Map1} = conv_src(hipe_rtl:load_src(I), Map0),  {Base2, Map2} = conv_src(hipe_rtl:load_offset(I), Map1),  LoadSize = hipe_rtl:load_size(I),  LoadSign = hipe_rtl:load_sign(I),  I2 = mk_load(Dst, Base1, Base2, LoadSize, LoadSign),  {I2, Map2, Data}.mk_load(Dst, Base1, Base2, LoadSize, LoadSign) ->  Rest =    case LoadSize of      byte ->	case LoadSign of	  signed -> [hipe_ppc:mk_unary('extsb', Dst, Dst)];	  _ -> []	end;      _ -> []    end,  LdOp =    case LoadSize of      byte -> 'lbz';      int32 -> 'lwz';      word -> 'lwz';      int16 ->	case LoadSign of	  signed -> 'lha';	  unsigned -> 'lhz'	end    end,  case hipe_ppc:is_temp(Base1) of    true ->      case hipe_ppc:is_temp(Base2) of	true ->	  mk_load_rr(Dst, Base1, Base2, LdOp, Rest);	_ ->	  mk_load_ri(Dst, Base1, Base2, LdOp, Rest)      end;    _ ->      case hipe_ppc:is_temp(Base2) of	true ->	  mk_load_ri(Dst, Base2, Base1, LdOp, Rest);	_ ->	  mk_load_ii(Dst, Base1, Base2, LdOp, Rest)      end  end.mk_load_ii(Dst, Base1, Base2, LdOp, Rest) ->  io:format("~w: RTL load with two immediates\n", [?MODULE]),  Tmp = new_untagged_temp(),  mk_li(Tmp, Base1,	mk_load_ri(Dst, Tmp, Base2, LdOp, Rest)).   mk_load_ri(Dst, Base, Disp, LdOp, Rest) ->  hipe_ppc:mk_load(LdOp, Dst, Disp, Base, 'new', Rest).mk_load_rr(Dst, Base1, Base2, LdOp, Rest) ->  LdxOp = hipe_ppc:ldop_to_ldxop(LdOp),  [hipe_ppc:mk_loadx(LdxOp, Dst, Base1, Base2) | Rest].conv_load_address(I, Map, Data) ->  {Dst, Map0} = conv_dst(hipe_rtl:load_address_dst(I), Map),  Addr = hipe_rtl:load_address_address(I),  Type = hipe_rtl:load_address_type(I),  Src = {Addr,Type},  I2 = [hipe_ppc:mk_pseudo_li(Dst, Src)],  {I2, Map0, Data}.conv_load_atom(I, Map, Data) ->  {Dst, Map0} = conv_dst(hipe_rtl:load_atom_dst(I), Map),  Src = hipe_rtl:load_atom_atom(I),  I2 = [hipe_ppc:mk_pseudo_li(Dst, Src)],  {I2, Map0, Data}.conv_move(I, Map, Data) ->  {Dst, Map0} = conv_dst(hipe_rtl:move_dst(I), Map),  {Src, Map1} = conv_src(hipe_rtl:move_src(I), Map0),  I2 = mk_move(Dst, Src, []),  {I2, Map1, Data}.mk_move(Dst, Src, Tail) ->  case hipe_ppc:is_temp(Src) of    true -> [hipe_ppc:mk_pseudo_move(Dst, Src) | Tail];    _ -> mk_li(Dst, Src, Tail)  end.conv_return(I, Map, Data) ->  %% TODO: multiple-value returns  {[Arg], Map0} = conv_src_list(hipe_rtl:return_varlist(I), Map),  I2 = mk_move(mk_rv(), Arg,	       [hipe_ppc:mk_blr()]),  {I2, Map0, Data}.conv_store(I, Map, Data) ->  {Base1, Map0} = conv_dst(hipe_rtl:store_base(I), Map),  {Src, Map1} = conv_src(hipe_rtl:store_src(I), Map0),  {Base2, Map2} = conv_src(hipe_rtl:store_offset(I), Map1),  StoreSize = hipe_rtl:store_size(I),  I2 = mk_store(Src, Base1, Base2, StoreSize),  {I2, Map2, Data}.mk_store(Src, Base1, Base2, StoreSize) ->  StOp =    case StoreSize of      byte -> 'stb';      int16 -> 'sth';      int32 -> 'stw';      word -> 'stw'    end,  case hipe_ppc:is_temp(Src) of    true ->      mk_store2(Src, Base1, Base2, StOp);    _ ->      Tmp = new_untagged_temp(),      mk_li(Tmp, Src,	    mk_store2(Tmp, Base1, Base2, StOp))  end.mk_store2(Src, Base1, Base2, StOp) ->  case hipe_ppc:is_temp(Base2) of    true ->      mk_store_rr(Src, Base1, Base2, StOp);    _ ->      mk_store_ri(Src, Base1, Base2, StOp)  end.  mk_store_ri(Src, Base, Disp, StOp) ->  hipe_ppc:mk_store(StOp, Src, Disp, Base, 'new', []).mk_store_rr(Src, Base1, Base2, StOp) ->  StxOp = hipe_ppc:stop_to_stxop(StOp),  [hipe_ppc:mk_storex(StxOp, Src, Base1, Base2)].conv_switch(I, Map, Data) ->  Labels = hipe_rtl:switch_labels(I),  LMap = [{label,L} || L <- Labels],  {NewData, JTabLab} =    case hipe_rtl:switch_sort_order(I) of      [] ->	hipe_consttab:insert_block(Data, word, LMap);      SortOrder ->	hipe_consttab:insert_sorted_block(	  Data, word, LMap, SortOrder)    end,  %% no immediates allowed here  {IndexR, Map1} = conv_dst(hipe_rtl:switch_src(I), Map),  JTabR = new_untagged_temp(),  OffsetR = new_untagged_temp(),  DestR = new_untagged_temp(),  I2 =    [hipe_ppc:mk_pseudo_li(JTabR, {JTabLab,constant}),     hipe_ppc:mk_alu('slwi', OffsetR, IndexR, hipe_ppc:mk_uimm16(2)),     hipe_ppc:mk_loadx('lwzx', DestR, JTabR, OffsetR),     hipe_ppc:mk_mtspr('ctr', DestR),     hipe_ppc:mk_bctr(Labels)],  {I2, Map1, NewData}.%%% Create a conditional branch.%%% If the condition tests CR0[SO], rewrite the path%%% corresponding to SO being set to clear XER[SO].mk_pseudo_bc(BCond, TrueLabel, FalseLabel, Pred) ->  case BCond of    'so' ->      NewTrueLabel = hipe_gensym:get_next_label(ppc),      [hipe_ppc:mk_pseudo_bc(BCond, NewTrueLabel, FalseLabel, Pred),       hipe_ppc:mk_label(NewTrueLabel),       hipe_ppc:mk_mcrxr(),       hipe_ppc:mk_b_label(TrueLabel)];    'ns' ->      NewFalseLabel = hipe_gensym:get_next_label(ppc),      [hipe_ppc:mk_pseudo_bc(BCond, TrueLabel, NewFalseLabel, Pred),       hipe_ppc:mk_label(NewFalseLabel),       hipe_ppc:mk_mcrxr(),       hipe_ppc:mk_b_label(FalseLabel)];    _ ->      [hipe_ppc:mk_pseudo_bc(BCond, TrueLabel, FalseLabel, Pred)]  end.%%% Load an integer constant into a register.mk_li(Dst, Value) -> mk_li(Dst, Value, []).mk_li(Dst, Value, Tail) ->  hipe_ppc:mk_li(Dst, Value, Tail).%%% Check if an RTL ALU or ALUB operator commutes.rtl_aluop_commutes(RtlAluOp) ->  case RtlAluOp of    'add' -> true;    'mul' -> true;    'or'  -> true;    'and' -> true;    'xor' -> true;    _	  -> false  end.%%% Split a list of formal or actual parameters into the%%% part passed in registers and the part passed on the stack.%%% The parameters passed in registers are also tagged with%%% the corresponding registers.split_args(Args) ->  split_args(0, hipe_ppc_registers:nr_args(), Args, []).split_args(I, N, [Arg|Args], RegArgs) when I < N ->  Reg = hipe_ppc_registers:arg(I),  Temp = hipe_ppc:mk_temp(Reg, 'tagged'),  split_args(I+1, N, Args, [{Arg,Temp}|RegArgs]);split_args(_, _, StkArgs, RegArgs) ->  {RegArgs, StkArgs}.%%% Convert a list of actual parameters passed in%%% registers (from split_args/1) to a list of moves.move_actuals([{Src,Dst}|Actuals], Rest) ->  move_actuals(Actuals, mk_move(Dst, Src, Rest));move_actuals([], Rest) ->  Rest.%%% Convert a list of formal parameters passed in%%% registers (from split_args/1) to a list of moves.move_formals([{Dst,Src}|Formals], Rest) ->  move_formals(Formals, [hipe_ppc:mk_pseudo_move(Dst, Src) | Rest]);move_formals([], Rest) ->  Rest.%%% Convert a 'fun' operand (MFA, prim, or temp)conv_fun(Fun, Map) ->  case hipe_rtl:is_var(Fun) of    true ->      conv_dst(Fun, Map);    false ->      case hipe_rtl:is_reg(Fun) of	true ->	  conv_dst(Fun, Map);	false ->	  if is_atom(Fun) ->	      {hipe_ppc:mk_prim(Fun), Map};	     true ->	      {conv_mfa(Fun), Map}	  end      end  end.%%% Convert an MFA operand.conv_mfa({M,F,A}) when is_atom(M), is_atom(F), is_integer(A) ->  hipe_ppc:mk_mfa(M, F, A).%%% Convert an RTL source operand (imm/var/reg).%%% Returns a temp or a naked integer.conv_src(Opnd, Map) ->  case hipe_rtl:is_imm(Opnd) of    true ->      Value = hipe_rtl:imm_value(Opnd),      if is_integer(Value) ->	  {Value, Map}      end;    false ->      conv_dst(Opnd, Map)  end.conv_src_list([O|Os], Map) ->  {V, Map1} = conv_src(O, Map),  {Vs, Map2} = conv_src_list(Os, Map1),  {[V|Vs], Map2};conv_src_list([], Map) ->  {[], Map}.%%% Convert an RTL destination operand (var/reg).conv_fpreg(Opnd, Map) ->  case hipe_rtl:is_fpreg(Opnd) of    true -> conv_dst(Opnd, Map)  end.conv_dst(Opnd, Map) ->  {Name, Type} =    case hipe_rtl:is_var(Opnd) of      true ->	{hipe_rtl:var_index(Opnd), 'tagged'};      false ->	case hipe_rtl:is_fpreg(Opnd) of	  true ->	    {hipe_rtl:fpreg_index(Opnd), 'double'};	  false ->	    {hipe_rtl:reg_index(Opnd), 'untagged'}	end    end,  IsPrecoloured =    case Type of      'double' -> hipe_ppc_registers:is_precoloured_fpr(Name);      _ -> hipe_ppc_registers:is_precoloured_gpr(Name)    end,  case IsPrecoloured of    true ->      {hipe_ppc:mk_temp(Name, Type), Map};    false ->      case vmap_lookup(Map, Opnd) of	{value, NewTemp} ->	  {NewTemp, Map};	_ ->	  NewTemp = hipe_ppc:mk_new_temp(Type),	  {NewTemp, vmap_bind(Map, Opnd, NewTemp)}      end  end.conv_dst_list([O|Os], Map) ->  {Dst, Map1} = conv_dst(O, Map),  {Dsts, Map2} = conv_dst_list(Os, Map1),  {[Dst|Dsts], Map2};conv_dst_list([], Map) ->  {[], Map}.conv_formals(Os, Map) ->  conv_formals(hipe_ppc_registers:nr_args(), Os, Map, []).conv_formals(N, [O|Os], Map, Res) ->  Type =    case hipe_rtl:is_var(O) of      true -> 'tagged';      _ -> 'untagged'    end,  Dst =    if N > 0 -> hipe_ppc:mk_new_temp(Type);	% allocatable       true -> hipe_ppc:mk_new_nonallocatable_temp(Type)    end,  Map1 = vmap_bind(Map, O, Dst),  conv_formals(N-1, Os, Map1, [Dst|Res]);conv_formals(_, [], Map, Res) ->  {lists:reverse(Res), Map}.%%% Create a temp representing the stack pointer register.mk_sp() ->  hipe_ppc:mk_temp(hipe_ppc_registers:stack_pointer(), 'untagged').%%% Create a temp representing the return value register.mk_rv() ->  hipe_ppc:mk_temp(hipe_ppc_registers:return_value(), 'tagged').%%% new_untagged_temp -- conjure up an untagged scratch regnew_untagged_temp() ->  hipe_ppc:mk_new_temp('untagged').%%% new_tagged_temp -- conjure up a tagged scratch regnew_tagged_temp() ->  hipe_ppc:mk_new_temp('tagged').%%% Map from RTL var/reg operands to temps.vmap_empty() ->  gb_trees:empty().vmap_lookup(Map, Key) ->  gb_trees:lookup(Key, Map).vmap_bind(Map, Key, Val) ->  gb_trees:insert(Key, Val, Map).word_size() ->  hipe_rtl_arch:word_size().

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -