From 042259f23ad6239cd33fc4989f4d0d1dc9d45e76 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Mon, 19 Feb 1996 22:27:14 +0000 Subject: [PATCH] remove operand_subword from easy_fp_const support DImode const in TOC From-SVN: r11309 --- gcc/config/rs6000/rs6000.c | 89 ++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 24 deletions(-) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 0c0eae6c16f..b611ee1288a 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -533,8 +533,6 @@ easy_fp_constant (op, mode) register rtx op; register enum machine_mode mode; { - rtx low, high; - if (GET_CODE (op) != CONST_DOUBLE || GET_MODE (op) != mode || GET_MODE_CLASS (mode) != MODE_FLOAT) @@ -544,14 +542,27 @@ easy_fp_constant (op, mode) if (TARGET_SOFT_FLOAT) return 1; - high = operand_subword (op, 0, 0, mode); - low = operand_subword (op, 1, 0, mode); + if (mode == DFmode) + { + long k[2]; + REAL_VALUE_TYPE rv; + + REAL_VALUE_FROM_CONST_DOUBLE (rv, op); + REAL_VALUE_TO_TARGET_DOUBLE (rv, k); - if (high == 0 || ! input_operand (high, word_mode)) - return 0; + return (((unsigned) (k[0] + 0x8000) < 0x10000 || (k[0] & 0xffff) == 0) + && ((unsigned) (k[1] + 0x8000) < 0x10000 || (k[1] & 0xffff) == 0)); + } + else + { + long l; + REAL_VALUE_TYPE rv; + + REAL_VALUE_FROM_CONST_DOUBLE (rv, op); + REAL_VALUE_TO_TARGET_SINGLE (rv, l); - return (mode == SFmode - || (low != 0 && input_operand (low, word_mode))); + return ((unsigned) (l + 0x8000) < 0x10000 || (l & 0xffff) == 0); + } } /* Return 1 if the operand is in volatile memory. Note that during the @@ -843,9 +854,7 @@ input_operand (op, mode) && small_data_operand (op, Pmode)) return 1; - /* Otherwise, we will be doing this SET with an add, so anything valid - for an add will be valid. */ - return add_operand (op, mode); + return 0; } /* Return 1 for an operand in small memory on V.4/eabi */ @@ -3603,34 +3612,66 @@ output_toc (file, x, labelno) /* Handle FP constants specially. Note that if we have a minimal TOC, things we put here aren't actually in the TOC, so we can allow FP constants. */ - if (GET_CODE (x) == CONST_DOUBLE - && GET_MODE (x) == DFmode + if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) { - REAL_VALUE_TYPE r; - long l[2]; + REAL_VALUE_TYPE rv; + long k[2]; - REAL_VALUE_FROM_CONST_DOUBLE (r, x); - REAL_VALUE_TO_TARGET_DOUBLE (r, l); + REAL_VALUE_FROM_CONST_DOUBLE (rv, x); + REAL_VALUE_TO_TARGET_DOUBLE (rv, k); if (TARGET_MINIMAL_TOC) - fprintf (file, "\t.long %ld\n\t.long %ld\n", l[0], l[1]); + fprintf (file, "\t.long %ld\n\t.long %ld\n", k[0], k[1]); else fprintf (file, "\t.tc FD_%lx_%lx[TC],%ld,%ld\n", - l[0], l[1], l[0], l[1]); + k[0], k[1], k[0], k[1]); return; } else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) { - rtx val = operand_subword (x, 0, 0, SFmode); + REAL_VALUE_TYPE rv; + long l; - if (val == 0 || GET_CODE (val) != CONST_INT) - abort (); + REAL_VALUE_FROM_CONST_DOUBLE (rv, x); + REAL_VALUE_TO_TARGET_SINGLE (rv, l); + + if (TARGET_MINIMAL_TOC) + fprintf (file, "\t.long %d\n", l); + else + fprintf (file, "\t.tc FS_%x[TC],%d\n", l, l); + return; + } + else if (GET_MODE (x) == DImode + && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE) + && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) + { + HOST_WIDE_INT low; + HOST_WIDE_INT high; + + if (GET_CODE (x) == CONST_DOUBLE) + { + low = CONST_DOUBLE_LOW (x); + high = CONST_DOUBLE_HIGH (x); + } + else +#if HOST_BITS_PER_WIDE_INT == 32 + { + low = INTVAL (x); + high = (low < 0) ? ~0 : 0; + } +#else + { + low = INTVAL (x) & 0xffffffff; + high = (HOST_WIDE_INT) INTVAL (x) >> 32; + } +#endif if (TARGET_MINIMAL_TOC) - fprintf (file, "\t.long %d\n", INTVAL (val)); + fprintf (file, "\t.long %ld\n\t.long %ld\n", high, low); else - fprintf (file, "\t.tc FS_%x[TC],%d\n", INTVAL (val), INTVAL (val)); + fprintf (file, "\t.tc ID_%lx_%lx[TC],%ld,%ld\n", + high, low, high, low); return; } -- 2.30.2