aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/rtl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/rtl')
-rw-r--r--lib/hipe/rtl/hipe_icode2rtl.erl4
-rw-r--r--lib/hipe/rtl/hipe_rtl.erl192
-rw-r--r--lib/hipe/rtl/hipe_rtl.hrl3
-rw-r--r--lib/hipe/rtl/hipe_rtl_binary_match.erl18
-rw-r--r--lib/hipe/rtl/hipe_rtl_liveness.erl3
-rw-r--r--lib/hipe/rtl/hipe_tagscheme.erl37
6 files changed, 210 insertions, 47 deletions
diff --git a/lib/hipe/rtl/hipe_icode2rtl.erl b/lib/hipe/rtl/hipe_icode2rtl.erl
index 034153a3cb..483d0b37f7 100644
--- a/lib/hipe/rtl/hipe_icode2rtl.erl
+++ b/lib/hipe/rtl/hipe_icode2rtl.erl
@@ -427,8 +427,6 @@ gen_type_test([X], Type, TrueLbl, FalseLbl, Pred, ConstTab) ->
hipe_rtl:mk_branch(X, eq, TmpF, TrueLbl, FalseLbl, Pred)], ConstTab};
cons ->
{hipe_tagscheme:test_cons(X, TrueLbl, FalseLbl, Pred), ConstTab};
- constant ->
- {hipe_tagscheme:test_constant(X, TrueLbl, FalseLbl, Pred), ConstTab};
fixnum ->
{hipe_tagscheme:test_fixnum(X, TrueLbl, FalseLbl, Pred), ConstTab};
float ->
@@ -439,6 +437,8 @@ gen_type_test([X], Type, TrueLbl, FalseLbl, Pred, ConstTab) ->
{hipe_tagscheme:test_integer(X, TrueLbl, FalseLbl, Pred), ConstTab};
list ->
{hipe_tagscheme:test_list(X, TrueLbl, FalseLbl, Pred), ConstTab};
+ map ->
+ {hipe_tagscheme:test_map(X, TrueLbl, FalseLbl, Pred), ConstTab};
nil ->
{hipe_tagscheme:test_nil(X, TrueLbl, FalseLbl, Pred), ConstTab};
number ->
diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl
index 4bf4eb6bd7..2f62dd79ad 100644
--- a/lib/hipe/rtl/hipe_rtl.erl
+++ b/lib/hipe/rtl/hipe_rtl.erl
@@ -29,7 +29,7 @@
%% <li> {alu, Dst, Src1, Op, Src2} </li>
%% <li> {alub, Dst, Src1, Op, Src2, RelOp, TrueLabel, FalseLabel, P} </li>
%% <li> {branch, Src1, Src2, RelOp, TrueLabel, FalseLabel, P} </li>
-%% <li> {call, DsListt, Fun, ArgList, Type, Continuation, FailContinuation}
+%% <li> {call, DsListt, Fun, ArgList, Type, Continuation, FailContinuation, NormalContinuation}
%% Type is one of {local, remote, primop, closure} </li>
%% <li> {comment, Text} </li>
%% <li> {enter, Fun, ArgList, Type}
@@ -106,7 +106,7 @@
%% rtl_data_update/2,
%% rtl_var_range/1,
%% rtl_var_range_update/2,
- %% rtl_label_range/1,
+ rtl_label_range/1,
%% rtl_label_range_update/2,
rtl_info/1,
rtl_info_update/2]).
@@ -226,6 +226,7 @@
%% goto_label_update/2,
mk_call/6,
+ mk_call/7,
call_fun/1,
call_dstlist/1,
call_dstlist_update/2,
@@ -233,8 +234,10 @@
call_continuation/1,
call_fail/1,
call_type/1,
+ call_normal/1,
+ call_normal_update/2,
%% call_continuation_update/2,
- %% call_fail_update/2,
+ call_fail_update/2,
is_call/1,
mk_enter/3,
@@ -290,10 +293,13 @@
%% fconv_src_update/2,
%% is_fconv/1,
- %% mk_var/1,
+ mk_var/1,
+ mk_var/2,
mk_new_var/0,
is_var/1,
var_index/1,
+ var_liveness/1,
+ var_liveness_update/2,
%% change_vars_to_regs/1,
@@ -350,10 +356,15 @@
%% move_dst_update/2,
fixnumop_dst_update/2,
pp_instr/2,
- %% pp_arg/2,
+ %% Uber hack!
+ pp_var/2,
+ pp_reg/2,
+ pp_arg/2,
phi_arglist_update/2,
phi_redirect_pred/3]).
+-export([subst_uses_llvm/2]).
+
-export_type([alub_cond/0]).
%%
@@ -387,7 +398,7 @@ rtl_data(#rtl{data=Data}) -> Data.
%% rtl_data_update(Rtl, Data) -> Rtl#rtl{data=Data}.
%% rtl_var_range(#rtl{var_range=VarRange}) -> VarRange.
%% rtl_var_range_update(Rtl, VarRange) -> Rtl#rtl{var_range=VarRange}.
-%% rtl_label_range(#rtl{label_range=LabelRange}) -> LabelRange.
+rtl_label_range(#rtl{label_range=LabelRange}) -> LabelRange.
%% rtl_label_range_update(Rtl, LabelRange) -> Rtl#rtl{label_range=LabelRange}.
rtl_info(#rtl{info=Info}) -> Info.
rtl_info_update(Rtl, Info) -> Rtl#rtl{info=Info}.
@@ -402,11 +413,11 @@ rtl_info_update(Rtl, Info) -> Rtl#rtl{info=Info}.
%% move
%%
-mk_move(Dst, Src) -> #move{dst=Dst, src=Src}.
+mk_move(Dst, Src) -> false = is_fpreg(Dst), false = is_fpreg(Src), #move{dst=Dst, src=Src}.
move_dst(#move{dst=Dst}) -> Dst.
-move_dst_update(M, NewDst) -> M#move{dst=NewDst}.
+move_dst_update(M, NewDst) -> false = is_fpreg(NewDst), M#move{dst=NewDst}.
move_src(#move{src=Src}) -> Src.
-move_src_update(M, NewSrc) -> M#move{src=NewSrc}.
+move_src_update(M, NewSrc) -> false = is_fpreg(NewSrc), M#move{src=NewSrc}.
%% is_move(#move{}) -> true;
%% is_move(_) -> false.
@@ -458,7 +469,11 @@ phi_remove_pred(Phi, Pred) ->
case NewArgList of
[Arg] -> %% the phi should be turned into a move instruction
{_Label,Var} = Arg,
- mk_move(phi_dst(Phi), Var);
+ Dst = phi_dst(Phi),
+ case {is_fpreg(Dst), is_fpreg(Var)} of
+ {true, true} -> mk_fmove(Dst, Var);
+ {false, false} -> mk_move(Dst, Var)
+ end;
%% io:format("~nPhi (~w) turned into move (~w) when removing pred ~w~n",[Phi,Move,Pred]),
[_|_] ->
Phi#phi{arglist=NewArgList}
@@ -643,6 +658,17 @@ is_goto(_) -> false.
%% call
%%
+%% LLVM: Call with normal continuation
+mk_call(DstList, Fun, ArgList, Continuation, FailContinuation,
+ NormalContinuation, Type) ->
+ case Type of
+ remote -> ok;
+ not_remote -> ok
+ end,
+ #call{dstlist=DstList, 'fun'=Fun, arglist=ArgList, type=Type,
+ continuation=Continuation, failcontinuation=FailContinuation,
+ normalcontinuation=NormalContinuation}.
+
mk_call(DstList, Fun, ArgList, Continuation, FailContinuation, Type) ->
case Type of
remote -> ok;
@@ -651,6 +677,10 @@ mk_call(DstList, Fun, ArgList, Continuation, FailContinuation, Type) ->
#call{dstlist=DstList, 'fun'=Fun, arglist=ArgList, type=Type,
continuation=Continuation,
failcontinuation=FailContinuation}.
+
+call_normal(#call{normalcontinuation=NormalContinuation}) -> NormalContinuation.
+call_normal_update(C, NewNormalContinuation) ->
+ C#call{normalcontinuation=NewNormalContinuation}.
call_dstlist(#call{dstlist=DstList}) -> DstList.
call_dstlist_update(C, NewDstList) -> C#call{dstlist=NewDstList}.
call_fun(#call{'fun'=Fun}) -> Fun.
@@ -810,11 +840,11 @@ fp_unop_op(#fp_unop{op=Op}) -> Op.
%% fmove
%%
-mk_fmove(X, Y) -> #fmove{dst=X, src=Y}.
+mk_fmove(X, Y) -> true = is_fpreg(X), true = is_fpreg(Y), #fmove{dst=X, src=Y}.
fmove_dst(#fmove{dst=Dst}) -> Dst.
-fmove_dst_update(M, NewDst) -> M#fmove{dst=NewDst}.
+fmove_dst_update(M, NewDst) -> true = is_fpreg(NewDst), M#fmove{dst=NewDst}.
fmove_src(#fmove{src=Src}) -> Src.
-fmove_src_update(M, NewSrc) -> M#fmove{src=NewSrc}.
+fmove_src_update(M, NewSrc) -> true = is_fpreg(NewSrc), M#fmove{src=NewSrc}.
%%
%% fconv
@@ -853,11 +883,14 @@ reg_is_gcsafe(#rtl_reg{is_gc_safe=IsGcSafe}) -> IsGcSafe.
is_reg(#rtl_reg{}) -> true;
is_reg(_) -> false.
--record(rtl_var, {index :: non_neg_integer()}).
+-record(rtl_var, {index :: non_neg_integer(), liveness=live :: dead | live}).
mk_var(Num) when is_integer(Num), Num >= 0 -> #rtl_var{index=Num}.
+mk_var(Num, Liveness) when is_integer(Num), Num>=0 -> #rtl_var{index=Num, liveness=Liveness}.
mk_new_var() -> mk_var(hipe_gensym:get_next_var(rtl)).
var_index(#rtl_var{index=Index}) -> Index.
+var_liveness(#rtl_var{liveness=Liveness}) -> Liveness.
+var_liveness_update(RtlVar, Liveness) -> RtlVar#rtl_var{liveness=Liveness}.
is_var(#rtl_var{}) -> true;
is_var(_) -> false.
@@ -1077,6 +1110,131 @@ subst_uses(Subst, I) ->
switch_src_update(I, subst1(Subst, switch_src(I)))
end.
+subst_uses_llvm(Subst, I) ->
+ case I of
+ #alu{} ->
+ {NewSrc2, Subst1} = subst1_llvm(Subst, alu_src2(I)),
+ {NewSrc1, _ } = subst1_llvm(Subst1, alu_src1(I)),
+ I0 = alu_src1_update(I, NewSrc1),
+ alu_src2_update(I0, NewSrc2);
+ #alub{} ->
+ {NewSrc2, Subst1} = subst1_llvm(Subst, alub_src2(I)),
+ {NewSrc1, _ } = subst1_llvm(Subst1, alub_src1(I)),
+ I0 = alub_src1_update(I, NewSrc1),
+ alub_src2_update(I0, NewSrc2);
+ #branch{} ->
+ {NewSrc2, Subst1} = subst1_llvm(Subst, branch_src2(I)),
+ {NewSrc1, _ } = subst1_llvm(Subst1, branch_src1(I)),
+ I0 = branch_src1_update(I, NewSrc1),
+ branch_src2_update(I0, NewSrc2);
+ #call{} ->
+ case call_is_known(I) of
+ false ->
+ {NewFun, Subst1} = subst1_llvm(Subst, call_fun(I)),
+ {NewArgList, _} = subst_list_llvm(Subst1, call_arglist(I)),
+ I0 = call_fun_update(I, NewFun),
+ call_arglist_update(I0, NewArgList);
+ true ->
+ {NewArgList, _} = subst_list_llvm(Subst, call_arglist(I)),
+ call_arglist_update(I, NewArgList)
+ end;
+ #comment{} ->
+ I;
+ #enter{} ->
+ case enter_is_known(I) of
+ false ->
+ {NewFun, Subst1} = subst1_llvm(Subst, enter_fun(I)),
+ {NewArgList, _} = subst_list_llvm(Subst1, enter_arglist(I)),
+ I0 = enter_fun_update(I, NewFun),
+ enter_arglist_update(I0, NewArgList);
+ true ->
+ {NewArgList, _} = subst_list_llvm(Subst, enter_arglist(I)),
+ enter_arglist_update(I, NewArgList)
+ end;
+ #fconv{} ->
+ {NewSrc, _ } = subst1_llvm(Subst, fconv_src(I)),
+ fconv_src_update(I, NewSrc);
+ #fixnumop{} ->
+ {NewSrc, _ } = subst1_llvm(Subst, fixnumop_src(I)),
+ fixnumop_src_update(I, NewSrc);
+ #fload{} ->
+ {NewSrc, Subst1} = subst1_llvm(Subst, fload_src(I)),
+ {NewOffset, _ } = subst1_llvm(Subst1, fload_offset(I)),
+ I0 = fload_src_update(I, NewSrc),
+ fload_offset_update(I0, NewOffset);
+ #fmove{} ->
+ {NewSrc, _ } = subst1_llvm(Subst, fmove_src(I)),
+ fmove_src_update(I, NewSrc);
+ #fp{} ->
+ {NewSrc2, Subst1} = subst1_llvm(Subst, fp_src2(I)),
+ {NewSrc1, _ } = subst1_llvm(Subst1, fp_src1(I)),
+ I0 = fp_src1_update(I, NewSrc1),
+ fp_src2_update(I0, NewSrc2);
+ #fp_unop{} ->
+ {NewSrc, _ } = subst1_llvm(Subst, fp_unop_src(I)),
+ fp_unop_src_update(I, NewSrc);
+ #fstore{} ->
+ {NewSrc, Subst1} = subst1_llvm(Subst, fstore_src(I)),
+ {NewBase, Subst2} = subst1_llvm(Subst1, fstore_base(I)),
+ {NewOffset, _ } = subst1_llvm(Subst2, fstore_offset(I)),
+ I0 = fstore_src_update(I, NewSrc),
+ I1 = fstore_base_update(I0, NewBase),
+ fstore_offset_update(I1, NewOffset);
+ #goto{} ->
+ I;
+ #goto_index{} ->
+ I;
+ #gctest{} ->
+ {NewWords, _ } = subst1_llvm(Subst, gctest_words(I)),
+ gctest_words_update(I, NewWords);
+ #label{} ->
+ I;
+ #load{} ->
+ {NewSrc, Subst1} = subst1_llvm(Subst, load_src(I)),
+ {NewOffset, _ } = subst1_llvm(Subst1, load_offset(I)),
+ I0 = load_src_update(I, NewSrc),
+ load_offset_update(I0, NewOffset);
+ #load_address{} ->
+ I;
+ #load_atom{} ->
+ I;
+ #load_word_index{} ->
+ I;
+ #move{} ->
+ {NewSrc, _ } = subst1_llvm(Subst, move_src(I)),
+ move_src_update(I, NewSrc);
+ #multimove{} ->
+ {NewSrcList, _} = subst_list_llvm(Subst, multimove_srclist(I)),
+ multimove_srclist_update(I, NewSrcList);
+ #phi{} ->
+ phi_argvar_subst(I, Subst);
+ #return{} ->
+ {NewVarList, _} = subst_list_llvm(Subst, return_varlist(I)),
+ return_varlist_update(I, NewVarList);
+ #store{} ->
+ {NewSrc, Subst1} = subst1_llvm(Subst, store_src(I)),
+ {NewBase, Subst2} = subst1_llvm(Subst1, store_base(I)),
+ {NewOffset, _ } = subst1_llvm(Subst2, store_offset(I)),
+ I0 = store_src_update(I, NewSrc),
+ I1 = store_base_update(I0, NewBase),
+ store_offset_update(I1, NewOffset);
+ #switch{} ->
+ {NewSrc, _ } = subst1_llvm(Subst, switch_src(I)),
+ switch_src_update(I, NewSrc)
+ end.
+
+subst_list_llvm(S,X) -> subst_list_llvm(S, lists:reverse(X), []).
+subst_list_llvm(S, [], Acc) -> {Acc, S};
+subst_list_llvm(S, [X|Xs], Acc) ->
+ {NewX, RestS} = subst1_llvm(S, X),
+ subst_list_llvm(RestS, Xs, [NewX|Acc]).
+
+subst1_llvm(A,B) -> subst1_llvm(A,B,[]).
+
+subst1_llvm([], X, Acc) -> {X, Acc};
+subst1_llvm([{X,Y}|Rs], X, Acc) -> {Y, Acc++Rs};
+subst1_llvm([R|Xs], X, Acc) -> subst1_llvm(Xs,X,[R|Acc]).
+
subst_defines(Subst, I)->
case I of
#alu{} ->
@@ -1614,7 +1772,11 @@ pp_var(Dev, Arg) ->
true ->
pp_hard_reg(Dev, var_index(Arg));
false ->
- io:format(Dev, "v~w", [var_index(Arg)])
+ io:format(Dev, "v~w", [var_index(Arg)]),
+ case var_liveness(Arg) of
+ dead -> io:format(Dev, "(dead)", []);
+ _ -> ok
+ end
end.
pp_arg(Dev, A) ->
diff --git a/lib/hipe/rtl/hipe_rtl.hrl b/lib/hipe/rtl/hipe_rtl.hrl
index 974e40f830..fbdf9ac524 100644
--- a/lib/hipe/rtl/hipe_rtl.hrl
+++ b/lib/hipe/rtl/hipe_rtl.hrl
@@ -28,7 +28,8 @@
-record(alu, {dst, src1, op, src2}).
-record(alub, {dst, src1, op, src2, 'cond', true_label, false_label, p}).
-record(branch, {src1, src2, 'cond', true_label, false_label, p}).
--record(call, {dstlist, 'fun', arglist, type, continuation, failcontinuation}).
+-record(call, {dstlist, 'fun', arglist, type, continuation,
+ failcontinuation, normalcontinuation = []}).
-record(comment, {text}).
-record(enter, {'fun', arglist, type}).
-record(fconv, {dst, src}).
diff --git a/lib/hipe/rtl/hipe_rtl_binary_match.erl b/lib/hipe/rtl/hipe_rtl_binary_match.erl
index 8831199244..af8903904b 100644
--- a/lib/hipe/rtl/hipe_rtl_binary_match.erl
+++ b/lib/hipe/rtl/hipe_rtl_binary_match.erl
@@ -990,19 +990,19 @@ unsigned_bignum(Dst1, Src, TrueLblName) ->
hipe_tagscheme:unsafe_mk_big(Dst1, Src, unsigned),
hipe_rtl:mk_goto(TrueLblName)].
-load_bytes(Dst, Base, Offset, {Signedness, _Endianess},1) ->
+load_bytes(Dst, Base, Offset, {Signedness, _Endianness},1) ->
[hipe_rtl:mk_load(Dst, Base, Offset, byte, Signedness),
hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(1))];
-load_bytes(Dst, Base, Offset, {Signedness, Endianess},2) ->
- case Endianess of
+load_bytes(Dst, Base, Offset, {Signedness, Endianness},2) ->
+ case Endianness of
big ->
hipe_rtl_arch:load_big_2(Dst, Base, Offset, Signedness);
little ->
hipe_rtl_arch:load_little_2(Dst, Base, Offset, Signedness)
end;
-load_bytes(Dst, Base, Offset, {Signedness, Endianess},3) ->
+load_bytes(Dst, Base, Offset, {Signedness, Endianness},3) ->
Tmp1 = hipe_rtl:mk_new_reg(),
- case Endianess of
+ case Endianness of
big ->
[hipe_rtl:mk_load(Dst, Base, Offset, byte, Signedness),
hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(1)),
@@ -1026,18 +1026,18 @@ load_bytes(Dst, Base, Offset, {Signedness, Endianess},3) ->
hipe_rtl:mk_alu(Dst, Dst, 'or', Tmp1),
hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(1))]
end;
-load_bytes(Dst, Base, Offset, {Signedness, Endianess}, 4) ->
- case Endianess of
+load_bytes(Dst, Base, Offset, {Signedness, Endianness}, 4) ->
+ case Endianness of
big ->
hipe_rtl_arch:load_big_4(Dst, Base, Offset, Signedness);
little ->
hipe_rtl_arch:load_little_4(Dst, Base, Offset, Signedness)
end;
-load_bytes(Dst, Base, Offset, {Signedness, Endianess}, X) when X > 1 ->
+load_bytes(Dst, Base, Offset, {Signedness, Endianness}, X) when X > 1 ->
[LoopLbl, EndLbl] = create_lbls(2),
[Tmp1, Limit, TmpOffset] = create_regs(3),
- case Endianess of
+ case Endianness of
big ->
[hipe_rtl:mk_alu(Limit, Offset, add, hipe_rtl:mk_imm(X)),
hipe_rtl:mk_load(Dst, Base, Offset, byte, Signedness),
diff --git a/lib/hipe/rtl/hipe_rtl_liveness.erl b/lib/hipe/rtl/hipe_rtl_liveness.erl
index 3cfada9d6c..0c4b6b2e11 100644
--- a/lib/hipe/rtl/hipe_rtl_liveness.erl
+++ b/lib/hipe/rtl/hipe_rtl_liveness.erl
@@ -34,7 +34,8 @@
-module(hipe_rtl_liveness).
-%% -define(LIVEOUT_NEEDED,true). % needed for liveness.inc below.
+%% -define(DEBUG_LIVENESS,true).
+-define(LIVEOUT_NEEDED,true). % needed for liveness.inc below.
-define(PRETTY_PRINT,false).
-include("hipe_rtl.hrl").
diff --git a/lib/hipe/rtl/hipe_tagscheme.erl b/lib/hipe/rtl/hipe_tagscheme.erl
index f1e8d1ef41..c27c682915 100644
--- a/lib/hipe/rtl/hipe_tagscheme.erl
+++ b/lib/hipe/rtl/hipe_tagscheme.erl
@@ -39,14 +39,13 @@
test_tuple/4, test_atom/4, test_bignum/4, test_pos_bignum/4,
test_any_pid/4, test_any_port/4,
test_ref/4, test_fun/4, test_fun2/5, test_matchstate/4,
- test_binary/4, test_bitstr/4, test_list/4,
- test_integer/4, test_number/4, test_constant/4, test_tuple_N/5]).
+ test_binary/4, test_bitstr/4, test_list/4, test_map/4,
+ test_integer/4, test_number/4, test_tuple_N/5]).
-export([realtag_fixnum/2, tag_fixnum/2, realuntag_fixnum/2, untag_fixnum/2]).
-export([test_two_fixnums/3, test_fixnums/4, unsafe_fixnum_add/3,
unsafe_fixnum_sub/3,
fixnum_gt/5, fixnum_lt/5, fixnum_ge/5, fixnum_le/5, fixnum_val/1,
- fixnum_mul/4,
- fixnum_addsub/5, fixnum_andorxor/4, fixnum_not/2,
+ fixnum_mul/4, fixnum_addsub/5, fixnum_andorxor/4, fixnum_not/2,
fixnum_bsr/3, fixnum_bsl/3]).
-export([unsafe_car/2, unsafe_cdr/2,
unsafe_constant_element/3, unsafe_update_element/3, element/6]).
@@ -113,13 +112,15 @@
-define(TAG_HEADER_EXTERNAL_PID, ((16#C bsl ?TAG_PRIMARY_SIZE) bor ?TAG_PRIMARY_HEADER)).
-define(TAG_HEADER_EXTERNAL_PORT,((16#D bsl ?TAG_PRIMARY_SIZE) bor ?TAG_PRIMARY_HEADER)).
-define(TAG_HEADER_EXTERNAL_REF, ((16#E bsl ?TAG_PRIMARY_SIZE) bor ?TAG_PRIMARY_HEADER)).
+-define(TAG_HEADER_MAP, ((16#F bsl ?TAG_PRIMARY_SIZE) bor ?TAG_PRIMARY_HEADER)).
-define(TAG_HEADER_MASK, 16#3F).
-define(HEADER_ARITY_OFFS, 6).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-mk_header(SZ,TAG) -> (SZ bsl ?HEADER_ARITY_OFFS) + TAG.
+mk_header(SZ, TAG) -> (SZ bsl ?HEADER_ARITY_OFFS) + TAG.
+
mk_arityval(SZ) -> mk_header(SZ, ?TAG_HEADER_ARITYVAL).
size_from_header(Sz, Header) ->
@@ -133,9 +134,9 @@ mk_var_header(Header, Size, Tag) ->
mk_fixnum(X) -> (X bsl ?TAG_IMMED1_SIZE) + ?TAG_IMMED1_SMALL.
-define(NIL, ((-1 bsl ?TAG_IMMED2_SIZE) bor ?TAG_IMMED2_NIL)).
-mk_nil() -> ?NIL.
-%% mk_atom(X) -> (X bsl ?TAG_IMMED2_SIZE) + ?TAG_IMMED2_ATOM.
-mk_non_value() -> ?THE_NON_VALUE.
+mk_nil() -> ?NIL.
+%% mk_atom(X) -> (X bsl ?TAG_IMMED2_SIZE) + ?TAG_IMMED2_ATOM.
+mk_non_value() -> ?THE_NON_VALUE.
-spec is_fixnum(integer()) -> boolean().
is_fixnum(N) when is_integer(N) ->
@@ -253,6 +254,15 @@ test_tuple_N(X, N, TrueLab, FalseLab, Pred) ->
hipe_rtl:mk_branch(Tmp, 'eq', hipe_rtl:mk_imm(mk_arityval(N)),
TrueLab, FalseLab, Pred)].
+test_map(X, TrueLab, FalseLab, Pred) ->
+ Tmp = hipe_rtl:mk_new_reg_gcsafe(),
+ HalfTrueLab = hipe_rtl:mk_new_label(),
+ MapMask = ?TAG_HEADER_MASK,
+ [test_is_boxed(X, hipe_rtl:label_name(HalfTrueLab), FalseLab, Pred),
+ HalfTrueLab,
+ get_header(Tmp, X),
+ mask_and_compare(Tmp, MapMask, ?TAG_HEADER_MAP, TrueLab, FalseLab, Pred)].
+
test_ref(X, TrueLab, FalseLab, Pred) ->
Hdr = hipe_rtl:mk_new_reg_gcsafe(),
Tag = hipe_rtl:mk_new_reg_gcsafe(),
@@ -405,17 +415,6 @@ test_number(X, TrueLab, FalseLab, Pred) ->
hipe_rtl:mk_branch(Tmp, 'eq', hipe_rtl:mk_imm(HeaderFlonum),
TrueLab, FalseLab, Pred)].
-%% CONS, NIL, and TUPLE are not constants, everything else is
-test_constant(X, TrueLab, FalseLab, Pred) ->
- Lab1 = hipe_rtl:mk_new_label(),
- Lab2 = hipe_rtl:mk_new_label(),
- Pred1 = 1-Pred,
- [test_cons(X, FalseLab, hipe_rtl:label_name(Lab1), Pred1),
- Lab1,
- test_nil(X, FalseLab, hipe_rtl:label_name(Lab2), Pred1),
- Lab2,
- test_tuple(X, FalseLab, TrueLab, Pred1)].
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
tag_fixnum(DestVar, SrcReg) ->