diff options
author | sceptillion <33798691+sceptillion@users.noreply.github.com> | 2017-12-20 21:32:43 -0800 |
---|---|---|
committer | sceptillion <33798691+sceptillion@users.noreply.github.com> | 2017-12-20 21:32:43 -0800 |
commit | c9378dc2fe8e3097fee0100f2b07c2a1195dc8a0 (patch) | |
tree | 2e528788a3943f903a255aee5c9fdbd2849dc150 /gcc | |
parent | 58c860d6c48324eba66dd19540db5584d832cf58 (diff) |
fix more 64-bit float bugs
Diffstat (limited to 'gcc')
-rwxr-xr-x | gcc/emit-rtl.c | 4 | ||||
-rwxr-xr-x | gcc/real.h | 11 | ||||
-rwxr-xr-x | gcc/varasm.c | 24 |
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); @@ -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; |