summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorsceptillion <33798691+sceptillion@users.noreply.github.com>2017-12-20 21:32:43 -0800
committersceptillion <33798691+sceptillion@users.noreply.github.com>2017-12-20 21:32:43 -0800
commitc9378dc2fe8e3097fee0100f2b07c2a1195dc8a0 (patch)
tree2e528788a3943f903a255aee5c9fdbd2849dc150 /gcc
parent58c860d6c48324eba66dd19540db5584d832cf58 (diff)
fix more 64-bit float bugs
Diffstat (limited to 'gcc')
-rwxr-xr-xgcc/emit-rtl.c4
-rwxr-xr-xgcc/real.h11
-rwxr-xr-xgcc/varasm.c24
3 files changed, 26 insertions, 13 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 37c8a5b..7d28df0 100755
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3338,7 +3338,9 @@ init_emit_once (line_numbers)
zero_memory ((char *) &u, sizeof u); /* Zero any holes in a structure. */
u.d = i == 0 ? dconst0 : i == 1 ? dconst1 : dconst2;
- copy_memory ((char *) &u, (char *) &CONST_DOUBLE_LOW (tem), sizeof u);
+ for (int j = 0; j < sizeof (REAL_VALUE_TYPE) / sizeof (HOST_WIDE_INT); j++)
+ XWINT(tem, 2 + j) = u.i[j];
+
CONST_DOUBLE_MEM (tem) = cc0_rtx;
PUT_MODE (tem, mode);
diff --git a/gcc/real.h b/gcc/real.h
index b8f7188..a39cea1 100755
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -351,10 +351,13 @@ union tree_node;
REAL_VALUE_TYPE real_value_from_int_cst (union tree_node *,
union tree_node *);
-#define REAL_VALUE_FROM_CONST_DOUBLE(to, from) \
-do { union real_extract u; \
- memcpy((char *)&u, (char *)&CONST_DOUBLE_LOW(from), sizeof u); \
- to = u.d; } while (0)
+#define REAL_VALUE_FROM_CONST_DOUBLE(to, from) \
+do { \
+ union real_extract u; \
+ for (int i = 0; i < sizeof (REAL_VALUE_TYPE) / sizeof (HOST_WIDE_INT); i++) \
+ u.i[i] = XWINT((from), 2 + i); \
+ to = u.d; \
+} while (0)
/* Return a CONST_DOUBLE with value R and mode M. */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 5020b22..5192b24 100755
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1833,10 +1833,15 @@ immed_real_const_1 (d, mode)
/* Search the chain for an existing CONST_DOUBLE with the right value.
If one is found, return it. */
- for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
- if (! memcmp ((char *) &CONST_DOUBLE_LOW (r), (char *) &u, sizeof u)
- && GET_MODE (r) == mode)
- return r;
+ for (r = const_double_chain; r; r = CONST_DOUBLE_CHAIN (r))
+ {
+ for (int i = 0; i < sizeof (REAL_VALUE_TYPE) / sizeof (HOST_WIDE_INT); i++)
+ if (u.i[i] != XWINT(r, 2 + i))
+ goto not_match;
+ if (GET_MODE(r) == mode)
+ return r;
+ not_match: ;
+ }
/* No; make a new one and add it to the chain.
@@ -1850,7 +1855,8 @@ immed_real_const_1 (d, mode)
rtl_in_saveable_obstack ();
r = rtx_alloc (CONST_DOUBLE);
PUT_MODE (r, mode);
- copy_memory ((char *) &u, (char *) &CONST_DOUBLE_LOW (r), sizeof u);
+ for (int i = 0; i < sizeof (REAL_VALUE_TYPE) / sizeof (HOST_WIDE_INT); i++)
+ XWINT(r, 2 + i) = u.i[i];
pop_obstacks ();
/* Don't touch const_double_chain in nested function; see force_const_mem.
@@ -2967,8 +2973,8 @@ decode_rtx_const (mode, x, value)
if (GET_MODE (x) != VOIDmode)
{
value->mode = GET_MODE (x);
- copy_memory ((char *) &CONST_DOUBLE_LOW (x),
- (char *) &value->un.du, sizeof value->un.du);
+ for (int i = 0; i < sizeof (REAL_VALUE_TYPE) / sizeof (HOST_WIDE_INT); i++)
+ value->un.du.i[i] = XWINT(x, 2 + i);
}
else
{
@@ -3391,8 +3397,10 @@ output_constant_pool (fnname, fndecl)
case MODE_FLOAT:
if (GET_CODE (x) != CONST_DOUBLE)
abort ();
+
+ for (int i = 0; i < sizeof (REAL_VALUE_TYPE) / sizeof (HOST_WIDE_INT); i++)
+ u.i[i] = XWINT(x, 2 + i);
- copy_memory ((char *) &CONST_DOUBLE_LOW (x), (char *) &u, sizeof u);
assemble_real (u.d, pool->mode);
break;