aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Lång <[email protected]>2015-11-20 14:39:48 +0100
committerMagnus Lång <[email protected]>2015-11-27 18:18:38 +0100
commitbac7c55f9a9250f6edb57170530d567df6c92f29 (patch)
treef44973b5331cb4fd3840ba9d798bd947dc244f6b
parent148153eb16e873181ff6961f854105a240989265 (diff)
downloadotp-bac7c55f9a9250f6edb57170530d567df6c92f29.tar.gz
otp-bac7c55f9a9250f6edb57170530d567df6c92f29.tar.bz2
otp-bac7c55f9a9250f6edb57170530d567df6c92f29.zip
hipe: Allow unsigned args in hipe_rtl_arith
hipe_rtl_arith is only used by hipe_rtl_ssa_const_prop, which applies it to any RTL, including RTL where the intent is to do unsigned math. Since signed and unsigned operations produce the same 2's complement result, this change is harmless. On 32-bit architectures it caused HiPE crashes when compiling code like <<0:((1 bsl 32)-1)>>, because the size of the field is too large to fit in a signed integer.
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith.inc15
-rw-r--r--lib/hipe/rtl/hipe_rtl_arith_32.erl3
2 files changed, 6 insertions, 12 deletions
diff --git a/lib/hipe/rtl/hipe_rtl_arith.inc b/lib/hipe/rtl/hipe_rtl_arith.inc
index 1f455f47ed..1dff56b074 100644
--- a/lib/hipe/rtl/hipe_rtl_arith.inc
+++ b/lib/hipe/rtl/hipe_rtl_arith.inc
@@ -30,13 +30,13 @@
%% Returns a tuple
%% {Res, Sign, Zero, Overflow, Carry}
%% Res will be a number in the range
-%% MAX_SIGNED_INT >= Res >= MIN_SIGNED_INT
+%% MAX_UNSIGNED_INT >= Res >= 0
%% The other four values are flags that are either true or false
%%
eval_alu(Op, Arg1, Arg2)
- when Arg1 =< ?MAX_SIGNED_INT,
+ when Arg1 =< ?MAX_UNSIGNED_INT,
Arg1 >= ?MIN_SIGNED_INT,
- Arg2 =< ?MAX_SIGNED_INT,
+ Arg2 =< ?MAX_UNSIGNED_INT,
Arg2 >= ?MIN_SIGNED_INT ->
Sign1 = sign_bit(Arg1),
@@ -111,7 +111,7 @@ eval_alu(Op, Arg1, Arg2)
Res = N = Z = V = C = 0,
?EXIT({"unknown alu op", Op})
end,
- {two_comp_to_erl(Res), N, Z, V, C};
+ {Res, N, Z, V, C};
eval_alu(Op, Arg1, Arg2) ->
?EXIT({argument_overflow,Op,Arg1,Arg2}).
@@ -162,16 +162,9 @@ eval_cond(Cond, Arg1, Arg2) ->
sign_bit(Val) ->
((Val bsr ?SIGN_BIT) band 1) =:= 1.
-two_comp_to_erl(V) ->
- if V > ?MAX_SIGNED_INT ->
- - ((?MAX_UNSIGNED_INT + 1) - V);
- true -> V
- end.
-
shiftmask(Arg) ->
Setbits = ?BITS - Arg,
(1 bsl Setbits) - 1.
zero(Val) ->
Val =:= 0.
-
diff --git a/lib/hipe/rtl/hipe_rtl_arith_32.erl b/lib/hipe/rtl/hipe_rtl_arith_32.erl
index 572556be1c..d790a8b981 100644
--- a/lib/hipe/rtl/hipe_rtl_arith_32.erl
+++ b/lib/hipe/rtl/hipe_rtl_arith_32.erl
@@ -24,7 +24,8 @@
%% Filename : hipe_rtl_arith_32.erl
%% Module : hipe_rtl_arith_32
%% Purpose : To implement 32-bit RTL-arithmetic
-%% Notes : The arithmetic works on 32-bit signed integers.
+%% Notes : The arithmetic works on 32-bit signed and unsigned
+%% integers.
%% The implementation is taken from the implementation
%% of arithmetic on SPARC.
%% XXX: This code is seldom used, and hence also