1
%% -*- erlang-indent-level: 2 -*-
2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3
%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved
4
%% Time-stamp: <02/05/13 16:09:13 happi>
5
%% ====================================================================
6
%% Filename : hipe_rtl_guardops.erl
7
%% Module : hipe_rtl_guardops
10
%% History : * 2001-04-10 Erik Johansson (happi@csd.uu.se):
14
%% $Date: 2002/05/13 16:51:08 $
16
%% ====================================================================
19
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
21
-module(hipe_rtl_guardops).
22
-export([gen_guardop/3]).
23
%%-------------------------------------------------------------------------
25
-include("../main/hipe.hrl").
26
-include("hipe_icode2rtl.hrl").
27
-include("hipe_literals.hrl").
29
%%-------------------------------------------------------------------------
32
%% Generate code for guardops. This is mostly a dispatch function
34
gen_guardop(GOp, VarMap, ConstTab) ->
35
Op = hipe_icode:call_fun(GOp),
37
case hipe_icode:call_dst(GOp) of
39
{hipe_rtl:mk_new_var(),VarMap};
41
hipe_rtl_varmap:ivs2rvs(Dsts, VarMap)
43
{Args, VarMap1} = hipe_rtl_varmap:ivs2rvs(hipe_icode:call_args(GOp), VarMap0),
45
hipe_rtl_varmap:icode_label2rtl_label(hipe_icode:call_continuation(GOp), VarMap1),
47
hipe_rtl_varmap:icode_label2rtl_label(hipe_icode:call_fail(GOp), VarMap2),
48
TrueLblName = hipe_rtl:label_name(TrueLbl),
49
FalseLblName = hipe_rtl:label_name(FalseLbl),
51
%% Annot = hipe_icode:info(GOp),
54
{hipe_bs_primop, BsOP} ->
55
case get(hipe_inline_bs) of
58
hipe_rtl_inline_bs_ops:gen_rtl(BsOP,Args, Dst,TrueLblName,
59
FalseLblName, ConstTab);
62
hipe_rtl_bs_ops:gen_rtl(BsOP,Args, Dst,TrueLblName,
63
FalseLblName, ConstTab)
65
{Code, VarMap3, NewTab};
70
gen_guard_add_sub_2(Dst, Args, Op, add, TrueLblName, FalseLblName);
72
gen_guard_add_sub_2(Dst, Args, Op, sub, TrueLblName, FalseLblName);
74
gen_guard_bitop_2(Dst, Args, Op, 'and', TrueLblName, FalseLblName);
76
gen_guard_bitop_2(Dst, Args, Op, 'or', TrueLblName, FalseLblName);
78
gen_guard_bitop_2(Dst, Args, Op, 'xor', TrueLblName, FalseLblName);
80
gen_guard_bnot_2(Dst, Args, Op, TrueLblName, FalseLblName);
84
[Index, Tuple] = Args,
85
gen_guard_element_2(Dst1, Index, Tuple, TrueLblName, FalseLblName);
88
?EXIT({not_allowed_in_guards,Op});
90
?EXIT({not_allowed_in_guards,Op});
92
?EXIT({not_allowed_in_guards,Op});
94
?EXIT({not_allowed_in_guards,Op});
97
%% TODO: Check if the bif is alloed in a guard.
98
%% {Mod,BifName,Arity} = Op,
99
%% Fails = hipe_bif:fails(Arity,BifName),
100
%% if Fails =:= true ->
101
gen_general_guard_op(Dst, Args, Op,
102
TrueLblName, FalseLblName)
104
%% [hipe_rtl:mk_call(Dst, Op, Args, c, TrueLblName,[])]
107
{Code, VarMap3, ConstTab}
111
%% Generate a call to a guard operator (with inlined fail test)
114
gen_general_guard_op(Res, Args, Op, TrueLbl,FalseLbl) ->
115
%% RetLabel = hipe_rtl:mk_new_label(),
116
[hipe_rtl:mk_call(Res, Op, Args, c, TrueLbl,FalseLbl)].
117
%% hipe_rtl:label_name(RetLabel), []),
119
%% test_bif_result(Res, TrueLbl, FalseLbl)].
121
%% Test the result of a bifcall.
122
%% test_bif_result(Result, Continuation, Fail) ->
123
%% [hipe_rtl:mk_branch(Result, eq, hipe_rtl:mk_imm(0), Fail, Continuation, 0.01)].
126
%% ____________________________________________________________________
129
gen_guard_add_sub_2([Res], Args, Op, AluOp,SuccLabel,FailLabel) ->
131
GenCaseLabel = hipe_rtl:mk_new_label(),
132
[hipe_tagscheme:test_two_fixnums(Arg1, Arg2,
133
hipe_rtl:label_name(GenCaseLabel)),
134
hipe_tagscheme:fixnum_addsub(AluOp, Arg1, Arg2, Res, GenCaseLabel)|
135
gen_guardop_general_case(Res, Op, Args, SuccLabel, FailLabel,
138
gen_guardop_general_case(Res, Op, Args, SuccLabel, FailLabel, GenCaseLabel) ->
139
[hipe_rtl:mk_goto(SuccLabel),
141
gen_general_guard_op([Res], Args, Op, SuccLabel, FailLabel)].
144
gen_guard_bitop_2([Res], Args, Op, BitOp, EndLabel, FailLabel) ->
146
OtherLabel = hipe_rtl:mk_new_label(),
147
[hipe_tagscheme:test_two_fixnums(Arg1,Arg2, hipe_rtl:label_name(OtherLabel)),
148
hipe_tagscheme:fixnum_andorxor(BitOp, Arg1, Arg2, Res),
149
gen_guardop_general_case(Res, Op, Args, EndLabel, FailLabel, OtherLabel)].
152
%% Inline guard 'not'.
155
gen_guard_bnot_2([Res], Args, Op, EndLabel, FailLabel) ->
157
FixLabel = hipe_rtl:mk_new_label(),
158
OtherLabel = hipe_rtl:mk_new_label(),
159
[hipe_tagscheme:test_fixnum(Arg, hipe_rtl:label_name(FixLabel),
160
hipe_rtl:label_name(OtherLabel), 0.99),
162
hipe_tagscheme:fixnum_not(Arg, Res),
163
gen_guardop_general_case(Res, Op, Args, EndLabel, FailLabel, OtherLabel)].
168
gen_guard_element_2(Dst1, Index, Tuple, TrueLblName, FailLbl) ->
169
[hipe_tagscheme:element(Dst1, Index, Tuple,
170
hipe_rtl:mk_label(FailLbl), [], []),
171
hipe_rtl:mk_goto(TrueLblName)].