diff options
author | Micael Karlberg <[email protected]> | 2011-05-27 14:38:08 +0200 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2011-05-27 14:38:08 +0200 |
commit | 1c01cf2fb625e105dd2355279635edbb3dbb3063 (patch) | |
tree | 5dbd5a391b86d99c00a01c456f817f30209f1962 /lib/hipe | |
parent | 77fe4062599e4ffe897c21d22ad493cfec4b475c (diff) | |
parent | 4a5a75811e2cd590b5c94f71864a5245fd511ccf (diff) | |
download | otp-1c01cf2fb625e105dd2355279635edbb3dbb3063.tar.gz otp-1c01cf2fb625e105dd2355279635edbb3dbb3063.tar.bz2 otp-1c01cf2fb625e105dd2355279635edbb3dbb3063.zip |
Merge branch 'maint-r14' of super:otp into maint-r14
Diffstat (limited to 'lib/hipe')
-rw-r--r-- | lib/hipe/cerl/erl_bif_types.erl | 69 | ||||
-rw-r--r-- | lib/hipe/cerl/erl_types.erl | 151 | ||||
-rw-r--r-- | lib/hipe/doc/src/notes.xml | 35 | ||||
-rw-r--r-- | lib/hipe/main/hipe_main.erl | 6 | ||||
-rw-r--r-- | lib/hipe/ppc/hipe_ppc.erl | 172 | ||||
-rw-r--r-- | lib/hipe/ppc/hipe_ppc_assemble.erl | 76 | ||||
-rw-r--r-- | lib/hipe/ppc/hipe_ppc_frame.erl | 30 | ||||
-rw-r--r-- | lib/hipe/ppc/hipe_rtl_to_ppc.erl | 260 | ||||
-rw-r--r-- | lib/hipe/rtl/hipe_rtl_arch.erl | 57 | ||||
-rw-r--r-- | lib/hipe/rtl/hipe_tagscheme.erl | 2 | ||||
-rw-r--r-- | lib/hipe/vsn.mk | 2 |
11 files changed, 574 insertions, 286 deletions
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index 30b911c41b..0b47c7b6e1 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -45,6 +45,7 @@ t_atom_vals/1, t_binary/0, t_bitstr/0, + t_bitstrlist/0, t_boolean/0, t_byte/0, t_char/0, @@ -153,7 +154,7 @@ type(binary, bin_to_list, Arity, Xs) when 1 =< Arity, Arity =< 3 -> fun(_) -> t_list(t_integer()) end); type(binary, compile_pattern, 1, Xs) -> strict(arg_types(binary, compile_pattern, 1), Xs, - fun(_) -> t_tuple([t_atom(bm),t_binary()]) end); + fun(_) -> t_binary_compiled_pattern() end); type(binary, copy, Arity, Xs) when Arity =:= 1; Arity =:= 2 -> strict(arg_types(binary, copy, Arity), Xs, fun(_) -> t_binary() end); @@ -3552,7 +3553,7 @@ arg_types(erlang, list_to_binary, 1) -> arg_types(erlang, list_to_bitstr, 1) -> % XXX: TAKE OUT arg_types(erlang, list_to_bitstring, 1); arg_types(erlang, list_to_bitstring, 1) -> - [t_iolist()]; + [t_bitstrlist()]; arg_types(erlang, list_to_existing_atom, 1) -> [t_string()]; arg_types(erlang, list_to_float, 1) -> @@ -4468,27 +4469,6 @@ t_endian() -> t_sup(t_atom('big'), t_atom('little')). %% ===================================================================== -%% Types for the binary module -%% ===================================================================== - -t_binary_part() -> - t_tuple([t_non_neg_integer(), t_integer()]). - -t_binary_canonical_part() -> - t_tuple([t_non_neg_integer(), t_non_neg_integer()]). - -t_binary_pattern() -> - t_sup([t_binary(), - t_list(t_binary()), - t_binary_compiled_pattern()]). - -t_binary_compiled_pattern() -> - t_tuple([t_atom('cp'), t_binary()]). - -t_binary_options() -> - t_list(t_tuple([t_atom('scope'), t_binary_part()])). - -%% ===================================================================== %% HTTP types documented in R12B-4 %% ===================================================================== @@ -4543,7 +4523,28 @@ t_HttpFieldAtom() -> 'Keep-Alive', 'Proxy-Connection']). t_HttpString() -> - t_sup(t_string(),t_binary()). + t_sup(t_string(), t_binary()). + +%% ===================================================================== +%% These are used for the built-in functions of 'binary' +%% ===================================================================== + +t_binary_part() -> + t_tuple([t_non_neg_integer(), t_integer()]). + +t_binary_canonical_part() -> + t_tuple([t_non_neg_integer(), t_non_neg_integer()]). + +t_binary_pattern() -> + t_sup([t_binary(), + t_list(t_binary()), + t_binary_compiled_pattern()]). + +t_binary_compiled_pattern() -> + t_tuple([t_sup(t_atom('bm'), t_atom('ac')), t_binary()]). + +t_binary_options() -> + t_list(t_tuple([t_atom('scope'), t_binary_part()])). %% ===================================================================== %% These are used for the built-in functions of 'code' @@ -4564,11 +4565,6 @@ t_code_load_error_rsn() -> % also used in erlang:load_module/2 t_atom('on_load'), t_atom('sticky_directory')]). % only for the 'code' functions -t_code_loaded_fname_or_status() -> - t_sup([t_string(), % filename - t_atom('preloaded'), - t_atom('cover_compiled')]). - %% ===================================================================== %% These are used for the built-in functions of 'erlang' %% ===================================================================== @@ -4733,7 +4729,6 @@ t_scheduler_bind_type_results() -> t_atom('thread_no_node_processor_spread'), t_atom('unbound')]). - t_system_monitor_settings() -> t_sup([t_atom('undefined'), t_tuple([t_pid(), t_system_monitor_options()])]). @@ -4813,13 +4808,6 @@ t_ets_info_items() -> t_atom('type')]). %% ===================================================================== -%% These are used for the built-in functions of 'prim_file' -%% ===================================================================== - -t_prim_file_name() -> - t_sup(t_unicode_string(), t_binary()). - -%% ===================================================================== %% These are used for the built-in functions of 'gen_tcp' %% ===================================================================== @@ -5013,6 +5001,13 @@ t_re_CapturedData() -> t_sup([t_tuple([t_integer(), t_integer()]), t_string(), t_binary()]). %% ===================================================================== +%% These are used for the built-in functions of 'prim_file' +%% ===================================================================== + +t_prim_file_name() -> + t_sup(t_unicode_string(), t_binary()). + +%% ===================================================================== %% These are used for the built-in functions of 'unicode' %% ===================================================================== diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index 080d6936b2..1748c1cc16 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -2,7 +2,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2010. All Rights Reserved. +%% Copyright Ericsson AB 2003-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -59,6 +59,7 @@ t_bitstr_concat/2, t_bitstr_match/2, t_bitstr_unit/1, + t_bitstrlist/0, t_boolean/0, t_byte/0, t_char/0, @@ -1457,11 +1458,11 @@ t_is_tuple(_) -> false. %% Non-primitive types, including some handy syntactic sugar types %% --spec t_unicode_string() -> erl_type(). +-spec t_bitstrlist() -> erl_type(). + +t_bitstrlist() -> + t_iolist(1, t_bitstr()). -t_unicode_string() -> - t_list(t_unicode_char()). - -spec t_charlist() -> erl_type(). t_charlist() -> @@ -1551,15 +1552,16 @@ t_iodata() -> -spec t_iolist() -> erl_type(). t_iolist() -> - t_iolist(1). + t_iolist(1, t_binary()). --spec t_iolist(non_neg_integer()) -> erl_type(). +%% Added a second argument which currently is t_binary() | t_bitstr() +-spec t_iolist(non_neg_integer(), erl_type()) -> erl_type(). -t_iolist(N) when N > 0 -> - t_maybe_improper_list(t_sup([t_iolist(N-1), t_binary(), t_byte()]), - t_sup(t_binary(), t_nil())); -t_iolist(0) -> - t_maybe_improper_list(t_any(), t_sup(t_binary(), t_nil())). +t_iolist(N, T) when N > 0 -> + t_maybe_improper_list(t_sup([t_iolist(N-1, T), T, t_byte()]), + t_sup(T, t_nil())); +t_iolist(0, T) -> + t_maybe_improper_list(t_any(), t_sup(T, t_nil())). -spec t_parameterized_module() -> erl_type(). @@ -1581,6 +1583,11 @@ t_unicode_binary() -> t_unicode_char() -> t_integer(). % representing a valid unicode codepoint +-spec t_unicode_string() -> erl_type(). + +t_unicode_string() -> + t_list(t_unicode_char()). + %%----------------------------------------------------------------------------- %% Some built-in opaque types %% @@ -3220,16 +3227,16 @@ t_to_string(?atom(Set), _RecDict) -> _ -> set_to_string(Set) end; -t_to_string(?bitstr(8, 0), _RecDict) -> - "binary()"; t_to_string(?bitstr(0, 0), _RecDict) -> "<<>>"; +t_to_string(?bitstr(8, 0), _RecDict) -> + "binary()"; t_to_string(?bitstr(0, B), _RecDict) -> - io_lib:format("<<_:~w>>", [B]); + lists:flatten(io_lib:format("<<_:~w>>", [B])); t_to_string(?bitstr(U, 0), _RecDict) -> - io_lib:format("<<_:_*~w>>", [U]); + lists:flatten(io_lib:format("<<_:_*~w>>", [U])); t_to_string(?bitstr(U, B), _RecDict) -> - io_lib:format("<<_:~w,_:_*~w>>", [B, U]); + lists:flatten(io_lib:format("<<_:~w,_:_*~w>>", [B, U])); t_to_string(?function(?any, ?any), _RecDict) -> "fun()"; t_to_string(?function(?any, Range), RecDict) -> @@ -3238,16 +3245,18 @@ t_to_string(?function(?product(ArgList), Range), RecDict) -> "fun((" ++ comma_sequence(ArgList, RecDict) ++ ") -> " ++ t_to_string(Range, RecDict) ++ ")"; t_to_string(?identifier(Set), _RecDict) -> - if Set =:= ?any -> "identifier()"; - true -> sequence([io_lib:format("~w()", [T]) - || T <- set_to_list(Set)], [], " | ") + case Set of + ?any -> "identifier()"; + _ -> + string:join([io_lib:format("~w()", [T]) || T <- set_to_list(Set)], " | ") end; t_to_string(?opaque(Set), _RecDict) -> - sequence([case is_opaque_builtin(Mod, Name) of - true -> io_lib:format("~w()", [Name]); - false -> io_lib:format("~w:~w()", [Mod, Name]) - end - || #opaque{mod = Mod, name = Name} <- set_to_list(Set)], [], " | "); + string:join([case is_opaque_builtin(Mod, Name) of + true -> io_lib:format("~w()", [Name]); + false -> io_lib:format("~w:~w()", [Mod, Name]) + end + || #opaque{mod = Mod, name = Name} <- set_to_list(Set)], + " | "); t_to_string(?matchstate(Pres, Slots), RecDict) -> io_lib:format("ms(~s,~s)", [t_to_string(Pres, RecDict), t_to_string(Slots,RecDict)]); @@ -3321,14 +3330,15 @@ t_to_string(?number(?any, ?unknown_qual), _RecDict) -> "number()"; t_to_string(?product(List), RecDict) -> "<" ++ comma_sequence(List, RecDict) ++ ">"; t_to_string(?remote(Set), RecDict) -> - sequence([case Args =:= [] of - true -> io_lib:format("~w:~w()", [Mod, Name]); - false -> - ArgString = comma_sequence(Args, RecDict), - io_lib:format("~w:~w(~s)", [Mod, Name, ArgString]) - end - || #remote{mod = Mod, name = Name, args = Args} <- set_to_list(Set)], - [], " | "); + string:join([case Args =:= [] of + true -> io_lib:format("~w:~w()", [Mod, Name]); + false -> + ArgString = comma_sequence(Args, RecDict), + io_lib:format("~w:~w(~s)", [Mod, Name, ArgString]) + end + || #remote{mod = Mod, name = Name, args = Args} <- + set_to_list(Set)], + " | "); t_to_string(?tuple(?any, ?any, ?any), _RecDict) -> "tuple()"; t_to_string(?tuple(Elements, _Arity, ?any), RecDict) -> "{" ++ comma_sequence(Elements, RecDict) ++ "}"; @@ -3350,7 +3360,7 @@ t_to_string(?var(Id), _RecDict) when is_integer(Id) -> record_to_string(Tag, [_|Fields], FieldNames, RecDict) -> FieldStrings = record_fields_to_string(Fields, FieldNames, RecDict, []), - "#" ++ atom_to_list(Tag) ++ "{" ++ sequence(FieldStrings, [], ",") ++ "}". + "#" ++ atom_to_list(Tag) ++ "{" ++ string:join(FieldStrings, ",") ++ "}". record_fields_to_string([F|Fs], [{FName, _DefType}|FDefs], RecDict, Acc) -> NewAcc = @@ -3376,7 +3386,7 @@ record_field_diffs_to_string(?tuple([_|Fs], Arity, Tag), RecDict) -> {ok, FieldNames} = lookup_record(TagAtom, Arity-1, RecDict), %% io:format("RecCElems = ~p\nRecTypes = ~p\n", [Fs, FieldNames]), FieldDiffs = field_diffs(Fs, FieldNames, RecDict, []), - sequence(FieldDiffs, [], " and "). + string:join(FieldDiffs, " and "). field_diffs([F|Fs], [{FName, DefType}|FDefs], RecDict, Acc) -> NewAcc = @@ -3395,21 +3405,11 @@ comma_sequence(Types, RecDict) -> true -> "_"; false -> t_to_string(T, RecDict) end || T <- Types], - sequence(List, ","). + string:join(List, ","). union_sequence(Types, RecDict) -> List = [t_to_string(T, RecDict) || T <- Types], - sequence(List, " | "). - -sequence(List, Delimiter) -> - sequence(List, [], Delimiter). - -sequence([], [], _Delimiter) -> - []; -sequence([T], Acc, _Delimiter) -> - lists:flatten(lists:reverse([T|Acc])); -sequence([T|Ts], Acc, Delimiter) -> - sequence(Ts, [T ++ Delimiter|Acc], Delimiter). + string:join(List, " | "). %%============================================================================= %% @@ -3490,10 +3490,8 @@ t_from_form({type, _L, binary, []}, _TypeNames, _InOpaque, _RecDict, t_from_form({type, _L, binary, [Base, Unit]} = Type, _TypeNames, _InOpaque, _RecDict, _VarDict) -> case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of - {{integer, _, BaseVal}, - {integer, _, UnitVal}} - when BaseVal >= 0, UnitVal >= 0 -> - {t_bitstr(UnitVal, BaseVal), []}; + {{integer, _, B}, {integer, _, U}} when B >= 0, U >= 0 -> + {t_bitstr(U, B), []}; _ -> throw({error, io_lib:format("Unable to evaluate type ~w\n", [Type])}) end; t_from_form({type, _L, bitstring, []}, _TypeNames, _InOpaque, _RecDict, @@ -3839,26 +3837,40 @@ t_form_to_string({integer, _L, Int}) -> integer_to_list(Int); t_form_to_string({op, _L, _Op, _Arg} = Op) -> case erl_eval:partial_eval(Op) of {integer, _, _} = Int -> t_form_to_string(Int); - _ -> io_lib:format("Bad formed type ~w",[Op]) + _ -> io_lib:format("Badly formed type ~w", [Op]) end; t_form_to_string({op, _L, _Op, _Arg1, _Arg2} = Op) -> case erl_eval:partial_eval(Op) of {integer, _, _} = Int -> t_form_to_string(Int); - _ -> io_lib:format("Bad formed type ~w",[Op]) + _ -> io_lib:format("Badly formed type ~w", [Op]) end; t_form_to_string({ann_type, _L, [Var, Type]}) -> t_form_to_string(Var) ++ "::" ++ t_form_to_string(Type); t_form_to_string({paren_type, _L, [Type]}) -> io_lib:format("(~s)", [t_form_to_string(Type)]); t_form_to_string({remote_type, _L, [{atom, _, Mod}, {atom, _, Name}, Args]}) -> - ArgString = "(" ++ sequence(t_form_to_string_list(Args), ",") ++ ")", + ArgString = "(" ++ string:join(t_form_to_string_list(Args), ",") ++ ")", io_lib:format("~w:~w", [Mod, Name]) ++ ArgString; t_form_to_string({type, _L, arity, []}) -> "arity()"; +t_form_to_string({type, _L, binary, []}) -> "binary()"; +t_form_to_string({type, _L, binary, [Base, Unit]} = Type) -> + case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of + {{integer, _, B}, {integer, _, U}} -> + %% the following mirrors the clauses of t_to_string/2 + case {U, B} of + {0, 0} -> "<<>>"; + {8, 0} -> "binary()"; + {0, B} -> lists:flatten(io_lib:format("<<_:~w>>", [B])); + {U, 0} -> lists:flatten(io_lib:format("<<_:_*~w>>", [U])); + {U, B} -> lists:flatten(io_lib:format("<<_:~w,_:_*~w>>", [B, U])) + end; + _ -> io_lib:format("Badly formed bitstr type ~w", [Type]) + end; t_form_to_string({type, _L, 'fun', []}) -> "fun()"; t_form_to_string({type, _L, 'fun', [{type, _, any, []}, Range]}) -> "fun(...) -> " ++ t_form_to_string(Range); t_form_to_string({type, _L, 'fun', [{type, _, product, Domain}, Range]}) -> - "fun((" ++ sequence(t_form_to_string_list(Domain), ",") ++ ") -> " + "fun((" ++ string:join(t_form_to_string_list(Domain), ",") ++ ") -> " ++ t_form_to_string(Range) ++ ")"; t_form_to_string({type, _L, iodata, []}) -> "iodata()"; t_form_to_string({type, _L, iolist, []}) -> "iolist()"; @@ -3871,7 +3883,7 @@ t_form_to_string({type, _L, nonempty_list, [Type]}) -> "[" ++ t_form_to_string(Type) ++ ",...]"; t_form_to_string({type, _L, nonempty_string, []}) -> "nonempty_string()"; t_form_to_string({type, _L, product, Elements}) -> - "<" ++ sequence(t_form_to_string_list(Elements), ",") ++ ">"; + "<" ++ string:join(t_form_to_string_list(Elements), ",") ++ ">"; t_form_to_string({type, _L, range, [From, To]} = Type) -> case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of {{integer, _, FromVal}, {integer, _, ToVal}} -> @@ -3881,7 +3893,7 @@ t_form_to_string({type, _L, range, [From, To]} = Type) -> t_form_to_string({type, _L, record, [{atom, _, Name}]}) -> io_lib:format("#~w{}", [Name]); t_form_to_string({type, _L, record, [{atom, _, Name}|Fields]}) -> - FieldString = sequence(t_form_to_string_list(Fields), ","), + FieldString = string:join(t_form_to_string_list(Fields), ","), io_lib:format("#~w{~s}", [Name, FieldString]); t_form_to_string({type, _L, field_type, [{atom, _, Name}, Type]}) -> io_lib:format("~w::~s", [Name, t_form_to_string(Type)]); @@ -3889,27 +3901,16 @@ t_form_to_string({type, _L, term, []}) -> "term()"; t_form_to_string({type, _L, timeout, []}) -> "timeout()"; t_form_to_string({type, _L, tuple, any}) -> "tuple()"; t_form_to_string({type, _L, tuple, Args}) -> - "{" ++ sequence(t_form_to_string_list(Args), ",") ++ "}"; + "{" ++ string:join(t_form_to_string_list(Args), ",") ++ "}"; t_form_to_string({type, _L, union, Args}) -> - sequence(t_form_to_string_list(Args), " | "); + string:join(t_form_to_string_list(Args), " | "); t_form_to_string({type, _L, Name, []} = T) -> try t_to_string(t_from_form(T)) catch throw:{error, _} -> atom_to_list(Name) ++ "()" end; -t_form_to_string({type, _L, binary, [X,Y]} = Type) -> - case {erl_eval:partial_eval(X), erl_eval:partial_eval(Y)} of - {{integer, _, XVal}, {integer, _, YVal}} -> - case YVal of - 0 -> - case XVal of - 0 -> "<<>>"; - _ -> io_lib:format("<<_:~w>>", [XVal]) - end - end; - _ -> io_lib:format("Bad formed type ~w",[Type]) - end; t_form_to_string({type, _L, Name, List}) -> - io_lib:format("~w(~s)", [Name, sequence(t_form_to_string_list(List), ",")]). + io_lib:format("~w(~s)", + [Name, string:join(t_form_to_string_list(List), ",")]). t_form_to_string_list(List) -> t_form_to_string_list(List, []). @@ -3917,8 +3918,8 @@ t_form_to_string_list(List) -> t_form_to_string_list([H|T], Acc) -> t_form_to_string_list(T, [t_form_to_string(H)|Acc]); t_form_to_string_list([], Acc) -> - lists:reverse(Acc). - + lists:reverse(Acc). + %%============================================================================= %% %% Utilities @@ -4057,7 +4058,7 @@ set_to_string(Set) -> true -> io_lib:write_string(atom_to_list(X), $'); % stupid emacs ' false -> io_lib:format("~w", [X]) end || X <- set_to_list(Set)], - sequence(L, [], " | "). + string:join(L, " | "). set_min([H|_]) -> H. diff --git a/lib/hipe/doc/src/notes.xml b/lib/hipe/doc/src/notes.xml index 434bfac64c..4eb188f76f 100644 --- a/lib/hipe/doc/src/notes.xml +++ b/lib/hipe/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2006</year><year>2010</year> + <year>2006</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -30,6 +30,39 @@ </header> <p>This document describes the changes made to HiPE.</p> +<section><title>Hipe 3.8</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + Fix hipe bug causing minor heap corruption related to + binary matching. The bug has not been confirmed as the + cause of any actual fault symptom.</p> + <p> + Own Id: OTP-9182</p> + </item> + <item> + <p> + Enable HiPE by default when compiling for PPC64</p> + <p> + Own Id: OTP-9198</p> + </item> + <item> + <p> + Fix handling of <<_:N,_:_*M>> type + expressions Fix the argument of + erlang:list_to_bitstring/1 Remove unneeded function + 'sequence/2' Same functionality provided by + string:join/2.</p> + <p> + Own Id: OTP-9277</p> + </item> + </list> + </section> + +</section> + <section><title>Hipe 3.7.9</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/lib/hipe/main/hipe_main.erl b/lib/hipe/main/hipe_main.erl index e81642fb33..99028cc3c1 100644 --- a/lib/hipe/main/hipe_main.erl +++ b/lib/hipe/main/hipe_main.erl @@ -2,7 +2,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2010. All Rights Reserved. +%% Copyright Ericsson AB 2001-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -313,7 +313,7 @@ icode_ssa_struct_reuse(IcodeSSA, Options) -> icode_ssa_type_info(IcodeSSA, MFA, Options, Servers) -> ?option_time(hipe_icode_type:cfg(IcodeSSA, MFA, Options, Servers), - "Icode SSA type info", Options). + io_lib:format("Icode SSA type info for ~p", [MFA]), Options). icode_range_analysis(IcodeSSA, MFA, Options, Servers) -> case proplists:get_bool(icode_range, Options) of @@ -527,6 +527,8 @@ rtl_to_native(MFA, LinearRTL, Options, DebugState) -> hipe_sparc_main:rtl_to_sparc(MFA, LinearRTL, Options); powerpc -> hipe_ppc_main:rtl_to_ppc(MFA, LinearRTL, Options); + ppc64 -> + hipe_ppc_main:rtl_to_ppc(MFA, LinearRTL, Options); arm -> hipe_arm_main:rtl_to_arm(MFA, LinearRTL, Options); x86 -> diff --git a/lib/hipe/ppc/hipe_ppc.erl b/lib/hipe/ppc/hipe_ppc.erl index 047e86c45b..4014fc1561 100644 --- a/lib/hipe/ppc/hipe_ppc.erl +++ b/lib/hipe/ppc/hipe_ppc.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% @@ -58,6 +58,10 @@ mk_blr/0, mk_cmp/3, + cmpop_word/0, + cmpiop_word/0, + cmplop_word/0, + cmpliop_word/0, mk_comment/1, @@ -73,6 +77,8 @@ mk_loadx/4, mk_load/6, ldop_to_ldxop/1, + ldop_word/0, + ldop_wordx/0, mk_mfspr/2, @@ -110,6 +116,8 @@ mk_storex/4, mk_store/6, stop_to_stxop/1, + stop_word/0, + stop_wordx/0, mk_unary/3, @@ -189,6 +197,31 @@ mk_blr() -> #blr{}. mk_cmp(CmpOp, Src1, Src2) -> #cmp{cmpop=CmpOp, src1=Src1, src2=Src2}. +cmpop_word() -> + case get(hipe_target_arch) of + powerpc -> 'cmp'; + ppc64 -> 'cmpd' + end. + +cmpiop_word() -> + case get(hipe_target_arch) of + powerpc -> 'cmpi'; + ppc64 -> 'cmpdi' + end. + +cmplop_word() -> + case get(hipe_target_arch) of + powerpc -> 'cmpl'; + ppc64 -> 'cmpld' + end. + +cmpliop_word() -> + case get(hipe_target_arch) of + powerpc -> 'cmpli'; + ppc64 -> 'cmpldi' + end. + + mk_comment(Term) -> #comment{term=Term}. mk_label(Label) -> #label{label=Label}. @@ -198,9 +231,50 @@ label_label(#label{label=Label}) -> Label. %%% Load an integer constant into a register. mk_li(Dst, Value) -> mk_li(Dst, Value, []). -mk_li(Dst, Value, Tail) -> +mk_li(Dst, Value, Tail) -> % Dst can be R0 R0 = mk_temp(0, 'untagged'), - mk_addi(Dst, R0, Value, Tail). + %% Check if immediate can fit in the 32 bits, this is obviously a + %% sufficient check for PPC32 + if Value >= -16#80000000, + Value =< 16#7FFFFFFF -> + mk_li32(Dst, R0, Value, Tail); + true -> + Highest = (Value bsr 48), % Value@highest + Higher = (Value bsr 32) band 16#FFFF, % Value@higher + High = (Value bsr 16) band 16#FFFF, % Value@h + Low = Value band 16#FFFF, % Value@l + LdLo = + case Low of + 0 -> Tail; + _ -> [mk_alu('ori', Dst, Dst, mk_uimm16(Low)) | Tail] + end, + Ld32bits = + case High of + 0 -> LdLo; + _ -> [mk_alu('oris', Dst, Dst, mk_uimm16(High)) | LdLo] + end, + [mk_alu('addis', Dst, R0, mk_simm16(Highest)), + mk_alu('ori', Dst, Dst, mk_uimm16(Higher)), + mk_alu('sldi', Dst, Dst, mk_uimm16(32)) | + Ld32bits] + end. + +mk_li32(Dst, R0, Value, Tail) -> + case at_ha(Value) of + 0 -> + %% Value[31:16] are the sign-extension of Value[15]. + %% Use a single addi to load and sign-extend 16 bits. + [mk_alu('addi', Dst, R0, mk_simm16(at_l(Value))) | Tail]; + _ -> + %% Use addis to load the high 16 bits, followed by an + %% optional ori to load non sign-extended low 16 bits. + High = simm16sext((Value bsr 16) band 16#FFFF), + [mk_alu('addis', Dst, R0, mk_simm16(High)) | + case (Value band 16#FFFF) of + 0 -> Tail; + Low -> [mk_alu('ori', Dst, Dst, mk_uimm16(Low)) | Tail] + end] + end. mk_addi(Dst, R0, Value, Tail) -> Low = at_l(Value), @@ -232,27 +306,6 @@ simm16sext(Value) -> true -> Value end. -mk_li_new(Dst, Value, Tail) -> % Dst may be R0 - R0 = mk_temp(0, 'untagged'), - case at_ha(Value) of - 0 -> - %% Value[31:16] are the sign-extension of Value[15]. - %% Use a single addi to load and sign-extend 16 bits. - [mk_alu('addi', Dst, R0, mk_simm16(at_l(Value))) | - Tail]; - _ -> - %% Use addis to load the high 16 bits, followed by an - %% optional ori to load non sign-extended low 16 bits. - High = simm16sext((Value bsr 16) band 16#FFFF), - [mk_alu('addis', Dst, R0, mk_simm16(High)) | - case (Value band 16#FFFF) of - 0 -> Tail; - Low -> - [mk_alu('ori', Dst, Dst, mk_uimm16(Low)) | - Tail] - end] - end. - mk_load(LDop, Dst, Disp, Base) -> #load{ldop=LDop, dst=Dst, disp=Disp, base=Base}. @@ -260,8 +313,15 @@ mk_loadx(LdxOp, Dst, Base1, Base2) -> #loadx{ldxop=LdxOp, dst=Dst, base1=Base1, base2=Base2}. mk_load(LdOp, Dst, Offset, Base, Scratch, Rest) when is_integer(Offset) -> - if Offset >= -32768, Offset =< 32767 -> - [mk_load(LdOp, Dst, Offset, Base) | Rest]; + RequireAlignment = + case LdOp of + 'ld' -> true; + 'ldx' -> true; + _ -> false + end, + if Offset >= -32768, Offset =< 32767, + not RequireAlignment orelse Offset band 3 =:= 0 -> + [mk_load(LdOp, Dst, Offset, Base) | Rest]; true -> LdxOp = ldop_to_ldxop(LdOp), Index = @@ -272,8 +332,8 @@ mk_load(LdOp, Dst, Offset, Base, Scratch, Rest) when is_integer(Offset) -> true -> mk_scratch(Scratch) end end, - mk_li_new(Index, Offset, - [mk_loadx(LdxOp, Dst, Base, Index) | Rest]) + mk_li(Index, Offset, + [mk_loadx(LdxOp, Dst, Base, Index) | Rest]) end. ldop_to_ldxop(LdOp) -> @@ -281,7 +341,21 @@ ldop_to_ldxop(LdOp) -> 'lbz' -> 'lbzx'; 'lha' -> 'lhax'; 'lhz' -> 'lhzx'; - 'lwz' -> 'lwzx' + 'lwa' -> 'lwax'; + 'lwz' -> 'lwzx'; + 'ld' -> 'ldx' + end. + +ldop_word() -> + case get(hipe_target_arch) of + powerpc -> 'lwz'; + ppc64 -> 'ld' + end. + +ldop_wordx() -> + case get(hipe_target_arch) of + powerpc -> 'lwzx'; + ppc64 -> 'ldx' end. mk_scratch(Scratch) -> @@ -354,20 +428,40 @@ mk_storex(StxOp, Src, Base1, Base2) -> #storex{stxop=StxOp, src=Src, base1=Base1, base2=Base2}. mk_store(StOp, Src, Offset, Base, Scratch, Rest)when is_integer(Offset) -> - if Offset >= -32768, Offset =< 32767 -> + RequireAlignment = + case StOp of + 'std' -> true; + 'stdx' -> true; + _ -> false + end, + if Offset >= -32768, Offset =< 32767, + not RequireAlignment orelse Offset band 3 =:= 0 -> [mk_store(StOp, Src, Offset, Base) | Rest]; true -> StxOp = stop_to_stxop(StOp), Index = mk_scratch(Scratch), - mk_li_new(Index, Offset, - [mk_storex(StxOp, Src, Base, Index) | Rest]) + mk_li(Index, Offset, + [mk_storex(StxOp, Src, Base, Index) | Rest]) end. stop_to_stxop(StOp) -> case StOp of 'stb' -> 'stbx'; 'sth' -> 'sthx'; - 'stw' -> 'stwx' + 'stw' -> 'stwx'; + 'std' -> 'stdx' + end. + +stop_word() -> + case get(hipe_target_arch) of + powerpc -> 'stw'; + ppc64 -> 'std' + end. + +stop_wordx() -> + case get(hipe_target_arch) of + powerpc -> 'stwx'; + ppc64 -> 'stdx' end. mk_unary(UnOp, Dst, Src) -> #unary{unop=UnOp, dst=Dst, src=Src}. @@ -379,7 +473,7 @@ mk_fload(Dst, Offset, Base, Scratch) when is_integer(Offset) -> [mk_lfd(Dst, Offset, Base)]; true -> Index = mk_scratch(Scratch), - mk_li_new(Index, Offset, [mk_lfdx(Dst, Base, Index)]) + mk_li(Index, Offset, [mk_lfdx(Dst, Base, Index)]) end. mk_stfd(Src, Disp, Base) -> #stfd{src=Src, disp=Disp, base=Base}. @@ -389,7 +483,7 @@ mk_fstore(Src, Offset, Base, Scratch) when is_integer(Offset) -> [mk_stfd(Src, Offset, Base)]; true -> Index = mk_scratch(Scratch), - mk_li_new(Index, Offset, [mk_stfdx(Src, Base, Index)]) + mk_li(Index, Offset, [mk_stfdx(Src, Base, Index)]) end. mk_fp_binary(FpBinOp, Dst, Src1, Src2) -> diff --git a/lib/hipe/ppc/hipe_ppc_assemble.erl b/lib/hipe/ppc/hipe_ppc_assemble.erl index 6f06f8b841..b2fd50517b 100644 --- a/lib/hipe/ppc/hipe_ppc_assemble.erl +++ b/lib/hipe/ppc/hipe_ppc_assemble.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% @@ -39,7 +39,7 @@ assemble(CompiledCode, Closures, Exports, Options) -> || {MFA, Defun} <- CompiledCode], %% {ConstAlign,ConstSize,ConstMap,RefsFromConsts} = - hipe_pack_constants:pack_constants(Code, 4), + hipe_pack_constants:pack_constants(Code, hipe_rtl_arch:word_size()), %% {CodeSize,CodeBinary,AccRefs,LabelMap,ExportMap} = encode(translate(Code, ConstMap), Options), @@ -159,6 +159,13 @@ do_alu(I) -> 'srwi.' -> {'rlwinm.', do_srwi_opnds(NewDst, NewSrc1, NewSrc2)}; 'srawi' -> {'srawi', {NewDst,NewSrc1,do_srawi_src2(NewSrc2)}}; 'srawi.' -> {'srawi.', {NewDst,NewSrc1,do_srawi_src2(NewSrc2)}}; + %ppc64 extension + 'sldi' -> {'rldicr', do_sldi_opnds(NewDst, NewSrc1, NewSrc2)}; + 'sldi.' -> {'rldicr.', do_sldi_opnds(NewDst, NewSrc1, NewSrc2)}; + 'srdi' -> {'rldicl', do_srdi_opnds(NewDst, NewSrc1, NewSrc2)}; + 'srdi.' -> {'rldicl.', do_srdi_opnds(NewDst, NewSrc1, NewSrc2)}; + 'sradi' -> {'sradi', {NewDst,NewSrc1,do_sradi_src2(NewSrc2)}}; + 'sradi.' -> {'sradi.', {NewDst,NewSrc1,do_sradi_src2(NewSrc2)}}; _ -> {AluOp, {NewDst,NewSrc1,NewSrc2}} end, [{NewI, NewOpnds, I}]. @@ -171,6 +178,15 @@ do_srwi_opnds(Dst, Src1, {uimm,N}) when is_integer(N), 0 =< N, N < 32 -> do_srawi_src2({uimm,N}) when is_integer(N), 0 =< N, N < 32 -> {sh,N}. +%% ppc64 extension +do_sldi_opnds(Dst, Src1, {uimm,N}) when is_integer(N), 0 =< N, N < 64 -> + {Dst, Src1, {sh6,N}, {me6,63-N}}. + +do_srdi_opnds(Dst, Src1, {uimm,N}) when is_integer(N), 0 =< N, N < 64 -> + {Dst, Src1, {sh6,64-N}, {mb6,N}}. + +do_sradi_src2({uimm,N}) when is_integer(N), 0 =< N, N < 64 -> {sh6,N}. + do_b_fun(I) -> #b_fun{'fun'=Fun,linkage=Linkage} = I, [{'.reloc', {b_fun,Fun,Linkage}, #comment{term='fun'}}, @@ -205,7 +221,18 @@ do_cmp(I) -> #cmp{cmpop=CmpOp,src1=Src1,src2=Src2} = I, NewSrc1 = do_reg(Src1), NewSrc2 = do_reg_or_imm(Src2), - [{CmpOp, {{crf,0},0,NewSrc1,NewSrc2}, I}]. + {RealOp,L} = + case CmpOp of + 'cmpd' -> {'cmp',1}; + 'cmpdi' -> {'cmpi',1}; + 'cmpld' -> {'cmpl',1}; + 'cmpldi' -> {'cmpli',1}; + 'cmp' -> {CmpOp,0}; + 'cmpi' -> {CmpOp,0}; + 'cmpl' -> {CmpOp,0}; + 'cmpli' -> {CmpOp,0} + end, + [{RealOp, {{crf,0},L,NewSrc1,NewSrc2}, I}]. do_label(I) -> #label{label=Label} = I, @@ -214,7 +241,12 @@ do_label(I) -> do_load(I) -> #load{ldop=LdOp,dst=Dst,disp=Disp,base=Base} = I, NewDst = do_reg(Dst), - NewDisp = do_disp(Disp), + NewDisp = + case LdOp of + 'ld' -> do_disp_ds(Disp); + 'ldu' -> do_disp_ds(Disp); + _ -> do_disp(Disp) + end, NewBase = do_reg(Base), [{LdOp, {NewDst,NewDisp,NewBase}, I}]. @@ -265,14 +297,30 @@ do_pseudo_li(I, MFA, ConstMap) -> end, NewDst = do_reg(Dst), Simm0 = {simm,0}, - [{'.reloc', RelocData, #comment{term=reloc}}, - {addi, {NewDst,{r,0},Simm0}, I}, - {addis, {NewDst,NewDst,Simm0}, I}]. + Uimm0 = {uimm,0}, + case get(hipe_target_arch) of + powerpc -> + [{'.reloc', RelocData, #comment{term=reloc}}, + {addi, {NewDst,{r,0},Simm0}, I}, + {addis, {NewDst,NewDst,Simm0}, I}]; + ppc64 -> + [{'.reloc', RelocData, #comment{term=reloc}}, + {addis, {NewDst,{r,0},Simm0}, I}, % @highest + {ori, {NewDst,NewDst,Uimm0}, I}, % @higher + {rldicr, {NewDst,NewDst,{sh6,32},{me6,31}}, I}, + {oris, {NewDst,NewDst,Uimm0}, I}, % @h + {ori, {NewDst,NewDst,Uimm0}, I}] % @l + end. do_store(I) -> #store{stop=StOp,src=Src,disp=Disp,base=Base} = I, NewSrc = do_reg(Src), - NewDisp = do_disp(Disp), + NewDisp = + case StOp of + 'std' -> do_disp_ds(Disp); + 'stdu' -> do_disp_ds(Disp); + _ -> do_disp(Disp) + end, NewBase = do_reg(Base), [{StOp, {NewSrc,NewDisp,NewBase}, I}]. @@ -344,6 +392,10 @@ do_reg_or_imm(Src) -> do_disp(Disp) when is_integer(Disp), -32768 =< Disp, Disp =< 32767 -> {d, Disp band 16#ffff}. +do_disp_ds(Disp) when is_integer(Disp), + -32768 =< Disp, Disp =< 32767, Disp band 3 =:= 0 -> + {ds, (Disp band 16#ffff) bsr 2}. + do_spr(SPR) -> SPR_NR = case SPR of diff --git a/lib/hipe/ppc/hipe_ppc_frame.erl b/lib/hipe/ppc/hipe_ppc_frame.erl index 158009872f..8a4d1906c0 100644 --- a/lib/hipe/ppc/hipe_ppc_frame.erl +++ b/lib/hipe/ppc/hipe_ppc_frame.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% @@ -103,12 +103,12 @@ do_pseudo_move(I, Context, FPoff) -> case temp_is_pseudo(Dst) of true -> Offset = pseudo_offset(Dst, FPoff, Context), - mk_store('stw', Src, Offset, mk_sp(), []); + mk_store(hipe_ppc:stop_word(), Src, Offset, mk_sp(), []); _ -> case temp_is_pseudo(Src) of true -> Offset = pseudo_offset(Src, FPoff, Context), - mk_load('lwz', Dst, Offset, mk_sp(), []); + mk_load(hipe_ppc:ldop_word(), Dst, Offset, mk_sp(), []); _ -> [hipe_ppc:mk_alu('or', Dst, Src, Src)] end @@ -152,7 +152,7 @@ restore_lr(FPoff, Context, Rest) -> false -> Rest; true -> Temp = mk_temp1(), - mk_load('lwz', Temp, FPoff - word_size(), mk_sp(), + mk_load(hipe_ppc:ldop_word(), Temp, FPoff - word_size(), mk_sp(), [hipe_ppc:mk_mtspr('lr', Temp) | Rest]) end. @@ -324,8 +324,8 @@ simple_moves([{SrcOff,DstOff,Type}|Moves], FPoff, TempReg, Rest) -> LoadOff = FPoff+SrcOff, StoreOff = FPoff+DstOff, simple_moves(Moves, FPoff, TempReg, - mk_load('lwz', Temp, LoadOff, SP, - mk_store('stw', Temp, StoreOff, SP, + mk_load(hipe_ppc:ldop_word(), Temp, LoadOff, SP, + mk_store(hipe_ppc:stop_word(), Temp, StoreOff, SP, Rest))); simple_moves([], _, _, Rest) -> Rest. @@ -343,7 +343,8 @@ store_moves([{Src,DstOff}|Moves], FPoff, TempReg, Rest) -> {Temp, hipe_ppc:mk_li(Temp, Src)} end, store_moves(Moves, FPoff, TempReg, - FixSrc ++ mk_store('stw', NewSrc, StoreOff, SP, Rest)); + FixSrc ++ mk_store(hipe_ppc:stop_word(), NewSrc, + StoreOff, SP, Rest)); store_moves([], _, _, Rest) -> Rest. @@ -400,7 +401,7 @@ mk_temp_map(Formals, ClobbersLR, Temps) -> enter_vars([V|Vs], PrevOff, Map) -> Off = case hipe_ppc:temp_type(V) of - 'double' -> PrevOff - 2*word_size(); + 'double' -> PrevOff - 8; _ -> PrevOff - word_size() end, enter_vars(Vs, Off, tmap_bind(Map, V, Off)); @@ -454,7 +455,8 @@ do_prologue(CFG, Context) -> AllocFrameCodeTail = case ClobbersLR of false -> GotoOldStartCode; - true -> mk_store('stw', Temp1, FrameSize-word_size(), SP, GotoOldStartCode) + true -> mk_store(hipe_ppc:stop_word(), Temp1, + FrameSize-word_size(), SP, GotoOldStartCode) end, %% Arity = context_arity(Context), @@ -484,7 +486,7 @@ do_prologue(CFG, Context) -> true -> [hipe_ppc:mk_mfspr(Temp1, 'lr') | NewStartCodeTail2] end, NewStartCode0 = - [hipe_ppc:mk_load('lwz', Temp1, ?P_NSP_LIMIT, P) | + [hipe_ppc:mk_load(hipe_ppc:ldop_word(), Temp1, ?P_NSP_LIMIT, P) | hipe_ppc:mk_addi(Temp2, SP, -MaxStack, [hipe_ppc:mk_cmp('cmpl', Temp2, Temp1) | NewStartCodeTail1])], diff --git a/lib/hipe/ppc/hipe_rtl_to_ppc.erl b/lib/hipe/ppc/hipe_rtl_to_ppc.erl index 458af250de..7dfa56df29 100644 --- a/lib/hipe/ppc/hipe_rtl_to_ppc.erl +++ b/lib/hipe/ppc/hipe_rtl_to_ppc.erl @@ -1,20 +1,20 @@ %%% -*- erlang-indent-level: 2 -*- %%% %%% %CopyrightBegin% -%%% -%%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%%% +%%% +%%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%%% %%% The contents of this file are subject to the Erlang Public License, %%% Version 1.1, (the "License"); you may not use this file except in %%% compliance with the License. You should have received a copy of the %%% Erlang Public License along with this software. If not, it can be %%% retrieved online at http://www.erlang.org/. -%%% +%%% %%% Software distributed under the License is distributed on an "AS IS" %%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %%% the License for the specific language governing rights and limitations %%% under the License. -%%% +%%% %%% %CopyrightEnd% %%% %%% The PowerPC instruction set is quite irregular. @@ -110,20 +110,27 @@ conv_fconv(I, Map, Data) -> mk_fconv(Dst, Src) -> CSP = hipe_ppc:mk_temp(1, 'untagged'), - R0 = hipe_ppc:mk_temp(0, 'untagged'), - RTmp1 = hipe_ppc:mk_new_temp('untagged'), - RTmp2 = hipe_ppc:mk_new_temp('untagged'), - RTmp3 = hipe_ppc:mk_new_temp('untagged'), - FTmp1 = hipe_ppc:mk_new_temp('double'), - FTmp2 = hipe_ppc:mk_new_temp('double'), - [hipe_ppc:mk_pseudo_li(RTmp1, {fconv_constant,c_const}), - hipe_ppc:mk_lfd(FTmp1, 0, RTmp1), - hipe_ppc:mk_alu('xoris', RTmp2, Src, hipe_ppc:mk_uimm16(16#8000)), - hipe_ppc:mk_store('stw', RTmp2, 28, CSP), - hipe_ppc:mk_alu('addis', RTmp3, R0, hipe_ppc:mk_simm16(16#4330)), - hipe_ppc:mk_store('stw', RTmp3, 24, CSP), - hipe_ppc:mk_lfd(FTmp2, 24, CSP), - hipe_ppc:mk_fp_binary('fsub', Dst, FTmp2, FTmp1)]. + case get(hipe_target_arch) of + powerpc -> + R0 = hipe_ppc:mk_temp(0, 'untagged'), + RTmp1 = hipe_ppc:mk_new_temp('untagged'), + RTmp2 = hipe_ppc:mk_new_temp('untagged'), + RTmp3 = hipe_ppc:mk_new_temp('untagged'), + FTmp1 = hipe_ppc:mk_new_temp('double'), + FTmp2 = hipe_ppc:mk_new_temp('double'), + [hipe_ppc:mk_pseudo_li(RTmp1, {fconv_constant,c_const}), + hipe_ppc:mk_lfd(FTmp1, 0, RTmp1), + hipe_ppc:mk_alu('xoris', RTmp2, Src, hipe_ppc:mk_uimm16(16#8000)), + hipe_ppc:mk_store('stw', RTmp2, 28, CSP), + hipe_ppc:mk_alu('addis', RTmp3, R0, hipe_ppc:mk_simm16(16#4330)), + hipe_ppc:mk_store('stw', RTmp3, 24, CSP), + hipe_ppc:mk_lfd(FTmp2, 24, CSP), + hipe_ppc:mk_fp_binary('fsub', Dst, FTmp2, FTmp1)]; + ppc64 -> + [hipe_ppc:mk_store('std', Src, 24, CSP), + hipe_ppc:mk_lfd(Dst, 24, CSP), + hipe_ppc:mk_fp_unary('fcfid', Dst, Dst)] + end. conv_fmove(I, Map, Data) -> %% Dst := Src, where both Dst and Src are FP regs @@ -280,10 +287,14 @@ mk_alu_ri(Dst, Src1, RtlAluOp, Src2) -> 'mul' -> % 'mulli' has a 16-bit simm operand mk_alu_ri_simm16(Dst, Src1, RtlAluOp, 'mulli', Src2); 'and' -> % 'andi.' has a 16-bit uimm operand - case rlwinm_mask(Src2) of - {MB,ME} -> - [hipe_ppc:mk_unary({'rlwinm',0,MB,ME}, Dst, Src1)]; - _ -> + if Src2 band (bnot 16#ffffffff) =:= 0 -> + case rlwinm_mask(Src2) of + {MB,ME} -> + [hipe_ppc:mk_unary({'rlwinm',0,MB,ME}, Dst, Src1)]; + _ -> + mk_alu_ri_bitop(Dst, Src1, RtlAluOp, 'andi.', Src2) + end; + true -> mk_alu_ri_bitop(Dst, Src1, RtlAluOp, 'andi.', Src2) end; 'or' -> % 'ori' has a 16-bit uimm operand @@ -360,17 +371,33 @@ mk_alu_ri_bitop(Dst, Src1, RtlAluOp, AluOp, Src2) -> end. mk_alu_ri_shift(Dst, Src1, RtlAluOp, Src2) -> - if Src2 < 32, Src2 >= 0 -> - AluOp = - case RtlAluOp of - 'sll' -> 'slwi'; % alias for rlwinm - 'srl' -> 'srwi'; % alias for rlwinm - 'sra' -> 'srawi' - end, - [hipe_ppc:mk_alu(AluOp, Dst, Src1, - hipe_ppc:mk_uimm16(Src2))]; - true -> - mk_alu_ri_rr(Dst, Src1, RtlAluOp, Src2) + case get(hipe_target_arch) of + ppc64 -> + if Src2 < 64, Src2 >= 0 -> + AluOp = + case RtlAluOp of + 'sll' -> 'sldi'; % alias for rldimi %%% buggy + 'srl' -> 'srdi'; % alias for rldimi %%% buggy + 'sra' -> 'sradi' %%% buggy + end, + [hipe_ppc:mk_alu(AluOp, Dst, Src1, + hipe_ppc:mk_uimm16(Src2))]; + true -> + mk_alu_ri_rr(Dst, Src1, RtlAluOp, Src2) + end; + powerpc -> + if Src2 < 32, Src2 >= 0 -> + AluOp = + case RtlAluOp of + 'sll' -> 'slwi'; % alias for rlwinm + 'srl' -> 'srwi'; % alias for rlwinm + 'sra' -> 'srawi' + end, + [hipe_ppc:mk_alu(AluOp, Dst, Src1, + hipe_ppc:mk_uimm16(Src2))]; + true -> + mk_alu_ri_rr(Dst, Src1, RtlAluOp, Src2) + end end. mk_alu_ri_rr(Dst, Src1, RtlAluOp, Src2) -> @@ -384,15 +411,21 @@ mk_alu_rr(Dst, Src1, RtlAluOp, Src2) -> [hipe_ppc:mk_alu('subf', Dst, Src2, Src1)]; _ -> AluOp = - case RtlAluOp of - 'add' -> 'add'; - 'mul' -> 'mullw'; - 'or' -> 'or'; - 'and' -> 'and'; - 'xor' -> 'xor'; - 'sll' -> 'slw'; - 'srl' -> 'srw'; - 'sra' -> 'sraw' + case {get(hipe_target_arch), RtlAluOp} of + {_, 'add'} -> 'add'; + {_, 'or'} -> 'or'; + {_, 'and'} -> 'and'; + {_, 'xor'} -> 'xor'; + + {powerpc, 'mul'} -> 'mullw'; + {powerpc, 'sll'} -> 'slw'; + {powerpc, 'srl'} -> 'srw'; + {powerpc, 'sra'} -> 'sraw'; + + {ppc64, 'mul'} -> 'mulld'; + {ppc64, 'sll'} -> 'sld'; + {ppc64, 'srl'} -> 'srd'; + {ppc64, 'sra'} -> 'srad' end, [hipe_ppc:mk_alu(AluOp, Dst, Src1, Src2)] end. @@ -431,16 +464,22 @@ conv_alub(I, Map, Data) -> {I1 ++ I2, Map2, Data}. conv_alub_op(RtlAluOp) -> - case RtlAluOp of - 'add' -> 'add'; - 'sub' -> 'subf'; % XXX: must swap operands - 'mul' -> 'mullw'; - 'or' -> 'or'; - 'and' -> 'and'; - 'xor' -> 'xor'; - 'sll' -> 'slw'; - 'srl' -> 'srw'; - 'sra' -> 'sraw' + case {get(hipe_target_arch), RtlAluOp} of + {_, 'add'} -> 'add'; + {_, 'sub'} -> 'subf'; % XXX: must swap operands + {_, 'or'} -> 'or'; + {_, 'and'} -> 'and'; + {_, 'xor'} -> 'xor'; + + {powerpc, 'mul'} -> 'mullw'; + {powerpc, 'sll'} -> 'slw'; + {powerpc, 'srl'} -> 'srw'; + {powerpc, 'sra'} -> 'sraw'; + + {ppc64, 'mul'} -> 'mulld'; + {ppc64, 'sll'} -> 'sld'; + {ppc64, 'srl'} -> 'srd'; + {ppc64, 'sra'} -> 'srad' end. aluop_commutes(AluOp) -> @@ -454,7 +493,11 @@ aluop_commutes(AluOp) -> 'xor' -> true; 'slw' -> false; 'srw' -> false; - 'sraw' -> false + 'sraw' -> false; + 'mulld' -> true; % ppc64 + 'sld' -> false; % ppc64 + 'srd' -> false; % ppc64 + 'srad' -> false % ppc64 end. conv_alub_cond(Cond) -> % only signed @@ -528,17 +571,24 @@ mk_alub_ri_Rc(Dst, Src1, AluOp, Src2) -> mk_alub_ri_Rc_addi(Dst, Src1, Src2, 'addic.', 'add.'); 'addc' -> % 'addic' has a 16-bit simm operand mk_alub_ri_Rc_addi(Dst, Src1, Src2, 'addic', 'addc'); - 'mullw' -> % there is no 'mulli.' + 'mullw' -> % there is no 'mulli.' mk_alub_ri_Rc_rr(Dst, Src1, 'mullw.', Src2); + 'mulld' -> % there is no 'mulli.' + mk_alub_ri_Rc_rr(Dst, Src1, 'mulld.', Src2); 'or' -> % there is no 'ori.' mk_alub_ri_Rc_rr(Dst, Src1, 'or.', Src2); 'xor' -> % there is no 'xori.' mk_alub_ri_Rc_rr(Dst, Src1, 'xor.', Src2); 'and' -> % 'andi.' has a 16-bit uimm operand - case rlwinm_mask(Src2) of - {MB,ME} -> - [hipe_ppc:mk_unary({'rlwinm.',0,MB,ME}, Dst, Src1)]; - _ -> + if + Src2 band (bnot 16#ffffffff) =:= 0 -> + case rlwinm_mask(Src2) of + {MB,ME} -> + [hipe_ppc:mk_unary({'rlwinm.',0,MB,ME}, Dst, Src1)]; + _ -> + mk_alub_ri_Rc_andi(Dst, Src1, Src2) + end; + true -> mk_alub_ri_Rc_andi(Dst, Src1, Src2) end; _ -> % shift ops have 5-bit uimm operands @@ -562,13 +612,16 @@ mk_alub_ri_Rc_andi(Dst, Src1, Src2) -> end. mk_alub_ri_Rc_shift(Dst, Src1, AluOp, Src2) -> - if Src2 < 32, Src2 >= 0 -> - AluOpIDot = - case AluOp of - 'slw' -> 'slwi.'; % alias for rlwinm. - 'srw' -> 'srwi.'; % alias for rlwinm. - 'sraw' -> 'srawi.' - end, + {AluOpIDot, MaxIShift} = + case AluOp of + 'slw' -> {'slwi.', 32}; % alias for rlwinm. + 'srw' -> {'srwi.', 32}; % alias for rlwinm. + 'sraw' -> {'srawi.', 32}; + 'sld' -> {'sldi.', 64}; + 'srd' -> {'srdi.', 64}; + 'srad' -> {'sradi.', 64} + end, + if Src2 < MaxIShift, Src2 >= 0 -> [hipe_ppc:mk_alu(AluOpIDot, Dst, Src1, hipe_ppc:mk_uimm16(Src2))]; true -> @@ -576,7 +629,10 @@ mk_alub_ri_Rc_shift(Dst, Src1, AluOp, Src2) -> case AluOp of 'slw' -> 'slw.'; 'srw' -> 'srw.'; - 'sraw' -> 'sraw.' + 'sraw' -> 'sraw.'; + 'sld' -> 'sld.'; + 'srd' -> 'srd.'; + 'srad' -> 'srad.' end, mk_alub_ri_Rc_rr(Dst, Src1, AluOpDot, Src2) end. @@ -598,8 +654,9 @@ mk_alub_rr_OE(Dst, Src1, AluOp, Src2) -> case AluOp of 'subf' -> 'subfo.'; 'add' -> 'addo.'; - 'mullw' -> 'mullwo.' - %% fail for addc, or, and, xor, slw, srw, sraw + 'mullw' -> 'mullwo.'; + 'mulld' -> 'mulldo.' + %% fail for addc, or, and, xor, slw, srw, sraw end, [hipe_ppc:mk_alu(AluOpODot, Dst, Src1, Src2)]. @@ -610,12 +667,16 @@ mk_alub_rr_Rc(Dst, Src1, AluOp, Src2) -> 'add' -> 'add.'; 'addc' -> 'addc'; % only interested in CA, no Rc needed 'mullw' -> 'mullw.'; + 'mulld' -> 'mulld.'; 'or' -> 'or.'; 'and' -> 'and.'; 'xor' -> 'xor.'; 'slw' -> 'slw.'; + 'sld' -> 'sld.'; 'srw' -> 'srw.'; - 'sraw' -> 'sraw.' + 'srd' -> 'srd.'; + 'sraw' -> 'sraw.'; + 'srad' -> 'srad.' end, [hipe_ppc:mk_alu(AluOpDot, Dst, Src1, Src2)]. @@ -682,17 +743,17 @@ mk_branch_ri(Src1, BCond, Sign, Src2, TrueLab, FalseLab, Pred) -> case Sign of 'signed' -> if is_integer(Src2), -32768 =< Src2, Src2 < 32768 -> - {[], hipe_ppc:mk_simm16(Src2), 'cmpi'}; + {[], hipe_ppc:mk_simm16(Src2), hipe_ppc:cmpiop_word()}; true -> Tmp = new_untagged_temp(), - {mk_li(Tmp, Src2), Tmp, 'cmp'} + {mk_li(Tmp, Src2), Tmp, hipe_ppc:cmpop_word()} end; 'unsigned' -> if is_integer(Src2), 0 =< Src2, Src2 < 65536 -> - {[], hipe_ppc:mk_uimm16(Src2), 'cmpli'}; + {[], hipe_ppc:mk_uimm16(Src2), hipe_ppc:cmpliop_word()}; true -> Tmp = new_untagged_temp(), - {mk_li(Tmp, Src2), Tmp, 'cmpl'} + {mk_li(Tmp, Src2), Tmp, hipe_ppc:cmplop_word()} end end, FixSrc2 ++ @@ -701,8 +762,8 @@ mk_branch_ri(Src1, BCond, Sign, Src2, TrueLab, FalseLab, Pred) -> mk_branch_rr(Src1, BCond, Sign, Src2, TrueLab, FalseLab, Pred) -> CmpOp = case Sign of - 'signed' -> 'cmp'; - 'unsigned' -> 'cmpl' + 'signed' -> hipe_ppc:cmpop_word(); + 'unsigned' -> hipe_ppc:cmplop_word() end, mk_cmp_bc(CmpOp, Src1, Src2, BCond, TrueLab, FalseLab, Pred). @@ -841,7 +902,7 @@ mk_store_args([Arg|Args], PrevOffset, Tail) -> Tmp = new_tagged_temp(), {Tmp, mk_li(Tmp, Arg)} end, - Store = hipe_ppc:mk_store('stw', Src, Offset, mk_sp()), + Store = hipe_ppc:mk_store(hipe_ppc:stop_word(), Src, Offset, mk_sp()), mk_store_args(Args, Offset, FixSrc ++ [Store | Tail]); mk_store_args([], _, Tail) -> Tail. @@ -883,25 +944,19 @@ conv_load(I, Map, Data) -> {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)]; - _ -> [] + {LdOp, Rest} = + case {LoadSize, LoadSign} of + {byte, signed} -> {'lbz', [hipe_ppc:mk_unary('extsb', Dst, Dst)]}; + {byte, unsigned} -> {'lbz', []}; + {int16, signed} -> {'lha', []}; + {int16, unsigned} -> {'lhz', []}; + {int32, signed} -> + case get(hipe_target_arch) of + powerpc -> {'lwz', []}; + ppc64 -> {'lwa', []} end; - _ -> [] - end, - LdOp = - case LoadSize of - byte -> 'lbz'; - int32 -> 'lwz'; - word -> 'lwz'; - int16 -> - case LoadSign of - signed -> 'lha'; - unsigned -> 'lhz' - end + {int32, unsigned} -> {'lwz', []}; + {word, _} -> {hipe_ppc:ldop_word(), []} end, case hipe_ppc:is_temp(Base1) of true -> @@ -980,7 +1035,7 @@ mk_store(Src, Base1, Base2, StoreSize) -> byte -> 'stb'; int16 -> 'sth'; int32 -> 'stw'; - word -> 'stw' + word -> hipe_ppc:stop_word() end, case hipe_ppc:is_temp(Src) of true -> @@ -1022,10 +1077,16 @@ conv_switch(I, Map, Data) -> JTabR = new_untagged_temp(), OffsetR = new_untagged_temp(), DestR = new_untagged_temp(), + ShiftInstruction = + case get(hipe_target_arch) of + powerpc -> 'slwi'; + ppc64 -> 'sldi' + end, 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_alu(ShiftInstruction, OffsetR, IndexR, + hipe_ppc:mk_uimm16(log2_word_size())), + hipe_ppc:mk_loadx(hipe_ppc:ldop_wordx(), DestR, JTabR, OffsetR), hipe_ppc:mk_mtspr('ctr', DestR), hipe_ppc:mk_bctr(Labels)], {I2, Map1, NewData}. @@ -1247,3 +1308,6 @@ vmap_bind(Map, Key, Val) -> word_size() -> hipe_rtl_arch:word_size(). + +log2_word_size() -> + hipe_rtl_arch:log2_word_size(). diff --git a/lib/hipe/rtl/hipe_rtl_arch.erl b/lib/hipe/rtl/hipe_rtl_arch.erl index 2afdf4eb6b..22cda57a3a 100644 --- a/lib/hipe/rtl/hipe_rtl_arch.erl +++ b/lib/hipe/rtl/hipe_rtl_arch.erl @@ -1,20 +1,20 @@ %% -*- erlang-indent-level: 2 -*- %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2001-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2001-2011. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -86,6 +86,8 @@ first_virtual_reg() -> hipe_sparc_registers:first_virtual(); powerpc -> hipe_ppc_registers:first_virtual(); + ppc64 -> + hipe_ppc_registers:first_virtual(); arm -> hipe_arm_registers:first_virtual(); x86 -> @@ -100,6 +102,8 @@ heap_pointer() -> % {GetHPInsn, HPReg, PutHPInsn} heap_pointer_from_reg(hipe_sparc_registers:heap_pointer()); powerpc -> heap_pointer_from_reg(hipe_ppc_registers:heap_pointer()); + ppc64 -> + heap_pointer_from_reg(hipe_ppc_registers:heap_pointer()); arm -> heap_pointer_from_reg(hipe_arm_registers:heap_pointer()); x86 -> @@ -143,6 +147,8 @@ heap_limit() -> % {GetHLIMITInsn, HLIMITReg} heap_limit_from_pcb(); powerpc -> heap_limit_from_pcb(); + ppc64 -> + heap_limit_from_pcb(); arm -> heap_limit_from_pcb(); x86 -> @@ -165,6 +171,8 @@ fcalls() -> % {GetFCallsInsn, FCallsReg, PutFCallsInsn} fcalls_from_pcb(); powerpc -> fcalls_from_pcb(); + ppc64 -> + fcalls_from_pcb(); arm -> fcalls_from_pcb(); x86 -> @@ -188,6 +196,8 @@ reg_name(Reg) -> hipe_sparc_registers:reg_name_gpr(Reg); powerpc -> hipe_ppc_registers:reg_name_gpr(Reg); + ppc64 -> + hipe_ppc_registers:reg_name_gpr(Reg); arm -> hipe_arm_registers:reg_name_gpr(Reg); x86 -> @@ -215,6 +225,8 @@ is_precolored_regnum(RegNum) -> hipe_sparc_registers:is_precoloured_gpr(RegNum); powerpc -> hipe_ppc_registers:is_precoloured_gpr(RegNum); + ppc64 -> + hipe_ppc_registers:is_precoloured_gpr(RegNum); arm -> hipe_arm_registers:is_precoloured_gpr(RegNum); x86 -> @@ -243,6 +255,9 @@ live_at_return() -> powerpc -> ordsets:from_list([hipe_rtl:mk_reg(R) || {R,_} <- hipe_ppc_registers:live_at_return()]); + ppc64 -> + ordsets:from_list([hipe_rtl:mk_reg(R) + || {R,_} <- hipe_ppc_registers:live_at_return()]); arm -> ordsets:from_list([hipe_rtl:mk_reg(R) || {R,_} <- hipe_arm_registers:live_at_return()]); @@ -262,6 +277,7 @@ word_size() -> case get(hipe_target_arch) of ultrasparc -> 4; powerpc -> 4; + ppc64 -> 8; arm -> 4; x86 -> 4; amd64 -> 8 @@ -284,6 +300,7 @@ log2_word_size() -> case get(hipe_target_arch) of ultrasparc -> 2; powerpc -> 2; + ppc64 -> 3; arm -> 2; x86 -> 2; amd64 -> 3 @@ -297,6 +314,7 @@ endianess() -> case get(hipe_target_arch) of ultrasparc -> big; powerpc -> big; + ppc64 -> big; x86 -> little; amd64 -> little; arm -> ?ARM_ENDIANESS @@ -313,6 +331,8 @@ load_big_2(Dst, Base, Offset, Signedness) -> case get(hipe_target_arch) of powerpc -> load_2_directly(Dst, Base, Offset, Signedness); + ppc64 -> + load_2_directly(Dst, Base, Offset, Signedness); %% Note: x86 could use a "load;xchgb" or "load;rol $8,<16-bit reg>" %% sequence here. This has been implemented, but unfortunately didn't %% make consistent improvements to our benchmarks. @@ -333,6 +353,13 @@ load_little_2(Dst, Base, Offset, Signedness) -> unsigned -> []; signed -> [hipe_rtl:mk_call([Dst], 'extsh', [Dst], [], [], not_remote)] end]; + ppc64 -> + [hipe_rtl:mk_call([Dst], 'lhbrx', [Base,Offset], [], [], not_remote), + hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(2)) | + case Signedness of + unsigned -> []; + signed -> [hipe_rtl:mk_call([Dst], 'extsh', [Dst], [], [], not_remote)] + end]; _ -> load_little_2_in_pieces(Dst, Base, Offset, Signedness) end. @@ -365,6 +392,8 @@ load_big_4(Dst, Base, Offset, Signedness) -> case get(hipe_target_arch) of powerpc -> load_4_directly(Dst, Base, Offset, Signedness); + ppc64 -> + load_4_directly(Dst, Base, Offset, Signedness); %% Note: x86 could use a "load;bswap" sequence here. %% This has been implemented, but unfortunately didn't %% make any noticeable improvements in our benchmarks. @@ -386,6 +415,13 @@ load_little_4(Dst, Base, Offset, Signedness) -> powerpc -> [hipe_rtl:mk_call([Dst], 'lwbrx', [Base,Offset], [], [], not_remote), hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(4))]; + ppc64 -> + [hipe_rtl:mk_call([Dst], 'lwbrx', [Base,Offset], [], [], not_remote), + hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(4)) | + case Signedness of + unsigned -> []; + signed -> [hipe_rtl:mk_call([Dst], 'extsw', [Dst], [], [], not_remote)] + end]; arm -> %% When loading 4 bytes into a 32-bit register, the %% signedness of the high-order byte doesn't matter. @@ -396,7 +432,7 @@ load_little_4(Dst, Base, Offset, Signedness) -> end. load_4_directly(Dst, Base, Offset, Signedness) -> - [hipe_rtl:mk_load(Dst, Base, Offset, word, Signedness), + [hipe_rtl:mk_load(Dst, Base, Offset, int32, Signedness), hipe_rtl:mk_alu(Offset, Offset, add, hipe_rtl:mk_imm(4))]. load_big_4_in_pieces(Dst, Base, Offset, Signedness) -> @@ -440,6 +476,8 @@ store_4(Base, Offset, Src) -> store_4_directly(Base, Offset, Src); powerpc -> store_4_directly(Base, Offset, Src); + ppc64 -> + store_4_directly(Base, Offset, Src); arm -> store_big_4_in_pieces(Base, Offset, Src); ultrasparc -> @@ -525,6 +563,7 @@ fwait() -> amd64 -> [hipe_rtl:mk_call([], 'fwait', [], [], [], not_remote)]; arm -> []; powerpc -> []; + ppc64 -> []; ultrasparc -> [] end. @@ -549,6 +588,8 @@ handle_fp_exception() -> []; powerpc -> []; + ppc64 -> + []; ultrasparc -> [] end. @@ -577,6 +618,8 @@ proc_pointer() -> % must not be exported hipe_rtl:mk_reg_gcsafe(hipe_sparc_registers:proc_pointer()); powerpc -> hipe_rtl:mk_reg_gcsafe(hipe_ppc_registers:proc_pointer()); + ppc64 -> + hipe_rtl:mk_reg_gcsafe(hipe_ppc_registers:proc_pointer()); arm -> hipe_rtl:mk_reg_gcsafe(hipe_arm_registers:proc_pointer()); x86 -> @@ -601,6 +644,8 @@ nr_of_return_regs() -> %% hipe_sparc_registers:nr_rets(); powerpc -> 1; + ppc64 -> + 1; %% hipe_ppc_registers:nr_rets(); arm -> 1; diff --git a/lib/hipe/rtl/hipe_tagscheme.erl b/lib/hipe/rtl/hipe_tagscheme.erl index 5859c345d0..0cc6c2deec 100644 --- a/lib/hipe/rtl/hipe_tagscheme.erl +++ b/lib/hipe/rtl/hipe_tagscheme.erl @@ -1045,7 +1045,7 @@ convert_matchstate(Ms) -> build_sub_binary(Ms, ByteSize, ByteOffset, BitSize, BitOffset, hipe_rtl:mk_imm(0), Orig), size_from_header(SizeInWords, Header), - hipe_rtl:mk_alu(Hole, SizeInWords, sub, hipe_rtl:mk_imm(?SUB_BIN_WORDSIZE-1)), + hipe_rtl:mk_alu(Hole, SizeInWords, sub, hipe_rtl:mk_imm(?SUB_BIN_WORDSIZE)), mk_var_header(BigIntHeader, Hole, ?TAG_HEADER_POS_BIG), hipe_rtl:mk_store(Ms, hipe_rtl:mk_imm(?SUB_BIN_WORDSIZE*WordSize-?TAG_PRIMARY_BOXED), BigIntHeader)]. diff --git a/lib/hipe/vsn.mk b/lib/hipe/vsn.mk index 6ba9009a24..58ebe68401 100644 --- a/lib/hipe/vsn.mk +++ b/lib/hipe/vsn.mk @@ -1 +1 @@ -HIPE_VSN = 3.7.9 +HIPE_VSN = 3.8 |