diff options
Diffstat (limited to 'lib/hipe')
-rw-r--r-- | lib/hipe/rtl/hipe_rtl.erl | 5 | ||||
-rw-r--r-- | lib/hipe/rtl/hipe_rtl_arch.erl | 27 | ||||
-rw-r--r-- | lib/hipe/rtl/hipe_rtl_lcm.erl | 21 |
3 files changed, 41 insertions, 12 deletions
diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl index 29e9c8c8fe..4bf4eb6bd7 100644 --- a/lib/hipe/rtl/hipe_rtl.erl +++ b/lib/hipe/rtl/hipe_rtl.erl @@ -781,8 +781,11 @@ fstore_src_update(F, NewSrc) -> F#fstore{src=NewSrc}. %% fp %% + mk_fp(Dst, Src1, Op, Src2) -> - #fp{dst=Dst, src1=Src1, op=Op, src2=Src2}. + [#fp{dst=Dst, src1=Src1, op=Op, src2=Src2} + | hipe_rtl_arch:mk_fp_check_result(Dst)]. + fp_dst(#fp{dst=Dst}) -> Dst. fp_dst_update(Fp, NewDst) -> Fp#fp{dst=NewDst}. fp_src1(#fp{src1=Src1}) -> Src1. diff --git a/lib/hipe/rtl/hipe_rtl_arch.erl b/lib/hipe/rtl/hipe_rtl_arch.erl index 22cda57a3a..99eb80f3d1 100644 --- a/lib/hipe/rtl/hipe_rtl_arch.erl +++ b/lib/hipe/rtl/hipe_rtl_arch.erl @@ -65,7 +65,8 @@ %% alignment/0, nr_of_return_regs/0, log2_word_size/0, - word_size/0 + word_size/0, + mk_fp_check_result/1 ]). -include("hipe_literals.hrl"). @@ -558,6 +559,12 @@ eval_cond_bits(Cond, N, Z, V, C) -> %%---------------------------------------------------------------------- fwait() -> + case ?ERTS_NO_FPE_SIGNALS of + 1 -> []; + 0 -> fwait_real() + end. + +fwait_real() -> case get(hipe_target_arch) of x86 -> [hipe_rtl:mk_call([], 'fwait', [], [], [], not_remote)]; amd64 -> [hipe_rtl:mk_call([], 'fwait', [], [], [], not_remote)]; @@ -573,6 +580,12 @@ fwait() -> %% Returns RTL code to restore the FPU after a floating-point exception. %% @end handle_fp_exception() -> + case ?ERTS_NO_FPE_SIGNALS of + 1 -> []; + 0 -> handle_real_fp_exception() + end. + +handle_real_fp_exception() -> case get(hipe_target_arch) of x86 -> ContLbl = hipe_rtl:mk_new_label(), @@ -655,3 +668,15 @@ nr_of_return_regs() -> 1 %% hipe_amd64_registers:nr_rets(); end. + + +mk_fp_check_result(Result) -> + case ?ERTS_NO_FPE_SIGNALS of + 0 -> + []; + 1 -> + [hipe_rtl:mk_fstore(proc_pointer(), + hipe_rtl:mk_imm(?P_FLOAT_RESULT), + Result), + hipe_rtl:mk_call([], emulate_fpe, [], [], [], not_remote)] + end. diff --git a/lib/hipe/rtl/hipe_rtl_lcm.erl b/lib/hipe/rtl/hipe_rtl_lcm.erl index 9224623c8b..262aedb409 100644 --- a/lib/hipe/rtl/hipe_rtl_lcm.erl +++ b/lib/hipe/rtl/hipe_rtl_lcm.erl @@ -486,7 +486,7 @@ lcm_precalc(CFG, Options) -> ?option_time(NodeInfo2 = calc_down_exp(CFG, ExprMap, NodeInfo1, Labels), "RTL LCM calc_down_exp", Options), ?option_time(NodeInfo3 = calc_killed_expr(CFG, NodeInfo2, UseMap, AllExpr, - Labels), + IdMap, Labels), "RTL LCM calc_killed_exp", Options), ?option_time(NodeInfo4 = calc_avail(CFG, NodeInfo3), "RTL LCM calc_avail", Options), @@ -815,19 +815,19 @@ exp_kill_expr(Instr, [CheckedExpr|Exprs]) -> %%============================================================================= %% Calculates the killed expression sets for all given labels. -calc_killed_expr(_, NodeInfo, _, _, []) -> +calc_killed_expr(_, NodeInfo, _, _, _, []) -> NodeInfo; -calc_killed_expr(CFG, NodeInfo, UseMap, AllExpr, [Label|Labels]) -> +calc_killed_expr(CFG, NodeInfo, UseMap, AllExpr, IdMap, [Label|Labels]) -> Code = hipe_bb:code(hipe_rtl_cfg:bb(CFG, Label)), - KilledExprs = calc_killed_expr_bb(Code, UseMap, AllExpr, ?SETS:new()), + KilledExprs = calc_killed_expr_bb(Code, UseMap, AllExpr, IdMap, ?SETS:new()), NewNodeInfo = set_killed_expr(NodeInfo, Label, KilledExprs), - calc_killed_expr(CFG, NewNodeInfo, UseMap, AllExpr, Labels). + calc_killed_expr(CFG, NewNodeInfo, UseMap, AllExpr, IdMap, Labels). %%============================================================================= %% Calculates the killed expressions set for one basic block. -calc_killed_expr_bb([], _UseMap, _AllExpr, KilledExprs) -> +calc_killed_expr_bb([], _UseMap, _AllExpr, _IdMap, KilledExprs) -> KilledExprs; -calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) -> +calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, IdMap, KilledExprs) -> %% Calls, gctests and stores potentially clobber everything case Instr of #call{} -> AllExpr; @@ -837,7 +837,8 @@ calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) -> %% Kill all float expressions %% FIXME: Make separate function is_fp_expr ?SETS:from_list - (lists:foldl(fun(Expr, Fexprs) -> + (lists:foldl(fun(ExprId, Fexprs) -> + Expr = expr_id_map_get_expr(IdMap, ExprId), [Define|_] = hipe_rtl:defines(Expr), case hipe_rtl:is_fpreg(Define) of true -> @@ -849,10 +850,10 @@ calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) -> _ -> case hipe_rtl:defines(Instr) of [] -> - calc_killed_expr_bb(Instrs, UseMap, AllExpr, KilledExprs); + calc_killed_expr_bb(Instrs, UseMap, AllExpr, IdMap, KilledExprs); [Define|_] -> NewKilledExprs = use_map_get_expr_uses(UseMap, Define), - calc_killed_expr_bb(Instrs, UseMap, AllExpr, + calc_killed_expr_bb(Instrs, UseMap, AllExpr, IdMap, ?SETS:union(NewKilledExprs, KilledExprs)) end end. |