aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/x86
diff options
context:
space:
mode:
authorMikael Pettersson <[email protected]>2015-01-08 19:26:38 +0100
committerMikael Pettersson <[email protected]>2015-01-11 13:07:43 +0100
commiteb255403b28bc1330d34d1d64ad8b8b42788c7ae (patch)
tree0aec9325d5407459f93ec9994d0f4509624e65c1 /lib/hipe/x86
parentaee18f309d41691019fc323bd41c5f78be49953b (diff)
downloadotp-eb255403b28bc1330d34d1d64ad8b8b42788c7ae.tar.gz
otp-eb255403b28bc1330d34d1d64ad8b8b42788c7ae.tar.bz2
otp-eb255403b28bc1330d34d1d64ad8b8b42788c7ae.zip
hipe: backends: correct #fconv{} translation
RTL can produce an #fconv{} instruction with an immediate operand, but the backends unconditionally access the operand as a temporary. This results in broken representation in the backends and eventually they crash.
Diffstat (limited to 'lib/hipe/x86')
-rw-r--r--lib/hipe/x86/hipe_rtl_to_x86.erl15
1 files changed, 14 insertions, 1 deletions
diff --git a/lib/hipe/x86/hipe_rtl_to_x86.erl b/lib/hipe/x86/hipe_rtl_to_x86.erl
index d77e4fed3b..36da2f4d44 100644
--- a/lib/hipe/x86/hipe_rtl_to_x86.erl
+++ b/lib/hipe/x86/hipe_rtl_to_x86.erl
@@ -236,7 +236,7 @@ conv_insn(I, Map, Data) ->
#fconv{} ->
{Dst, Map0} = conv_dst(hipe_rtl:fconv_dst(I), Map),
{[], Src, Map1} = conv_src(hipe_rtl:fconv_src(I), Map0),
- I2 = [hipe_x86:mk_fmove(Src, Dst)],
+ I2 = conv_fconv(Dst, Src),
{I2, Map1, Data};
X ->
%% gctest??
@@ -712,6 +712,19 @@ vmap_lookup(Map, Key) ->
vmap_bind(Map, Key, Val) ->
gb_trees:insert(Key, Val, Map).
+%%% Finalise the conversion of an Integer-to-Float operation.
+
+conv_fconv(Dst, Src) ->
+ case hipe_x86:is_imm(Src) of
+ false ->
+ [hipe_x86:mk_fmove(Src, Dst)];
+ true ->
+ %% cvtsi2sd does not allow src to be an immediate
+ Tmp = new_untagged_temp(),
+ [hipe_x86:mk_move(Src, Tmp),
+ hipe_x86:mk_fmove(Tmp, Dst)]
+ end.
+
%%% Finalise the conversion of a 2-address FP operation.
conv_fp_unary(Dst, Src, FpUnOp) ->