aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorJohannes Weißl <[email protected]>2013-06-14 15:24:04 +0200
committerJohannes Weißl <[email protected]>2013-06-14 15:25:12 +0200
commit9e45648698862905561baa533831afd4dd23a02a (patch)
treed42c5ddc73fce9ff3b951b48a462cb18f2fe71b0 /erts
parent5adbd7d22bccc57e17ed00cac09fe8a336bb39c7 (diff)
downloadotp-9e45648698862905561baa533831afd4dd23a02a.tar.gz
otp-9e45648698862905561baa533831afd4dd23a02a.tar.bz2
otp-9e45648698862905561baa533831afd4dd23a02a.zip
Fix binary construction on floating point middle-endian machines
This complements 933e701 (OTP-10209). Without this patch the test cases "in_guard/1" and "coerce_to_float/1" in bs_construct_SUITE fail. The added lines in bs_construct_SUITE cover all branches that were not covered before (small and big numbers if BIT_OFFSET(erts_bin_offset) != 0).
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/beam/erl_bits.c26
-rw-r--r--erts/emulator/test/bs_construct_SUITE.erl2
2 files changed, 28 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index 06d53efb5e..43eb691338 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -1022,8 +1022,13 @@ erts_new_bs_put_float(Process *c_p, Eterm arg, Uint num_bits, int flags)
#endif
} else if (is_small(arg)) {
u.f64 = (double) signed_val(arg);
+#ifdef DOUBLE_MIDDLE_ENDIAN
+ a = u.i32[1];
+ b = u.i32[0];
+#else
a = u.i32[0];
b = u.i32[1];
+#endif
} else if (is_big(arg)) {
if (big_to_double(arg, &u.f64) < 0) {
return 0;
@@ -1126,21 +1131,42 @@ erts_new_bs_put_float(Process *c_p, Eterm arg, Uint num_bits, int flags)
byte *bptr;
double f64;
float f32;
+#ifdef DOUBLE_MIDDLE_ENDIAN
+ FloatDef fbuf, ftmp;
+#endif
if (num_bits == 64) {
if (is_float(arg)) {
+#ifdef DOUBLE_MIDDLE_ENDIAN
+ FloatDef *fdp = (FloatDef*)(float_val(arg) + 1);
+ ftmp = *fdp;
+#else
bptr = (byte *) (float_val(arg) + 1);
+#endif
} else if (is_small(arg)) {
f64 = (double) signed_val(arg);
+#ifdef DOUBLE_MIDDLE_ENDIAN
+ ftmp.fd = f64;
+#else
bptr = (byte *) &f64;
+#endif
} else if (is_big(arg)) {
if (big_to_double(arg, &f64) < 0) {
return 0;
}
+#ifdef DOUBLE_MIDDLE_ENDIAN
+ ftmp.fd = f64;
+#else
bptr = (byte *) &f64;
+#endif
} else {
return 0;
}
+#ifdef DOUBLE_MIDDLE_ENDIAN
+ fbuf.fw[0] = ftmp.fw[1];
+ fbuf.fw[1] = ftmp.fw[0];
+ bptr = fbuf.fb;
+#endif
} else if (num_bits == 32) {
if (is_float(arg)) {
FloatDef f;
diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl
index 123952d01d..1a8724d63b 100644
--- a/erts/emulator/test/bs_construct_SUITE.erl
+++ b/erts/emulator/test/bs_construct_SUITE.erl
@@ -438,6 +438,8 @@ in_guard(Config) when is_list(Config) ->
?line 1 = in_guard(<<16#74ad:16>>, 16#e95, 5),
?line 2 = in_guard(<<16#3A,16#F7,"hello">>, 16#3AF7, <<"hello">>),
?line 3 = in_guard(<<16#FBCD:14,3.1415/float,3:2>>, 16#FBCD, 3.1415),
+ ?line 3 = in_guard(<<16#FBCD:14,3/float,3:2>>, 16#FBCD, 3),
+ ?line 3 = in_guard(<<16#FBCD:14,(2 bsl 226)/float,3:2>>, 16#FBCD, 2 bsl 226),
nope = in_guard(<<1>>, 42, b),
nope = in_guard(<<1>>, a, b),
nope = in_guard(<<1,2>>, 1, 1),