From 811b72f9c9e0f1ca002e637d836cfc7a84b5927d Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Mon, 15 Apr 2013 08:28:41 +0000 Subject: [PATCH] re PR target/56890 (invalid fdtox instruction in 64-bit mode with -O2) PR target/56890 * config/sparc/sparc.c (enum sparc_mode_class): Add H_MODE value. (S_MODES): Set H_MODE bit. (SF_MODES): Set only S_MODE and SF_MODE bits. (DF_MODES): Set SF_MODES and only D_MODE and DF_MODE bits. (sparc_init_modes) : Set H_MODE bit for sub-word modes. : Do not set SF_MODE for sub-word modes. : Likewise. From-SVN: r197958 --- gcc/ChangeLog | 11 +++++++++++ gcc/config/sparc/sparc.c | 27 +++++++++++++++------------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr56890-1.c | 15 +++++++++++++++ gcc/testsuite/gcc.dg/pr56890-2.c | 19 +++++++++++++++++++ 5 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr56890-1.c create mode 100644 gcc/testsuite/gcc.dg/pr56890-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 26f460878f1..06d603dfb0e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2013-04-15 Eric Botcazou + + PR target/56890 + * config/sparc/sparc.c (enum sparc_mode_class): Add H_MODE value. + (S_MODES): Set H_MODE bit. + (SF_MODES): Set only S_MODE and SF_MODE bits. + (DF_MODES): Set SF_MODES and only D_MODE and DF_MODE bits. + (sparc_init_modes) : Set H_MODE bit for sub-word modes. + : Do not set SF_MODE for sub-word modes. + : Likewise. + 2013-04-15 Joey Ye * config/arm/arm.c (thumb_far_jump_used_p): Fix typo in comments. diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 56b95fe9cff..1dc4e3600a8 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -4467,13 +4467,14 @@ mem_min_alignment (rtx mem, int desired) mapped into one sparc_mode_class mode. */ enum sparc_mode_class { - S_MODE, D_MODE, T_MODE, O_MODE, + H_MODE, S_MODE, D_MODE, T_MODE, O_MODE, SF_MODE, DF_MODE, TF_MODE, OF_MODE, CC_MODE, CCFP_MODE }; /* Modes for single-word and smaller quantities. */ -#define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE)) +#define S_MODES \ + ((1 << (int) H_MODE) | (1 << (int) S_MODE) | (1 << (int) SF_MODE)) /* Modes for double-word and smaller quantities. */ #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE)) @@ -4484,13 +4485,11 @@ enum sparc_mode_class { /* Modes for 8-word and smaller quantities. */ #define O_MODES (T_MODES | (1 << (int) O_MODE) | (1 << (int) OF_MODE)) -/* Modes for single-float quantities. We must allow any single word or - smaller quantity. This is because the fix/float conversion instructions - take integer inputs/outputs from the float registers. */ -#define SF_MODES (S_MODES) +/* Modes for single-float quantities. */ +#define SF_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE)) /* Modes for double-float and smaller quantities. */ -#define DF_MODES (D_MODES) +#define DF_MODES (SF_MODES | (1 << (int) D_MODE) | (1 << DF_MODE)) /* Modes for quad-float and smaller quantities. */ #define TF_MODES (DF_MODES | (1 << (int) TF_MODE)) @@ -4586,7 +4585,9 @@ sparc_init_modes (void) case MODE_INT: case MODE_PARTIAL_INT: case MODE_COMPLEX_INT: - if (GET_MODE_SIZE (i) <= 4) + if (GET_MODE_SIZE (i) < 4) + sparc_mode_class[i] = 1 << (int) H_MODE; + else if (GET_MODE_SIZE (i) == 4) sparc_mode_class[i] = 1 << (int) S_MODE; else if (GET_MODE_SIZE (i) == 8) sparc_mode_class[i] = 1 << (int) D_MODE; @@ -4598,14 +4599,16 @@ sparc_init_modes (void) sparc_mode_class[i] = 0; break; case MODE_VECTOR_INT: - if (GET_MODE_SIZE (i) <= 4) - sparc_mode_class[i] = 1 << (int)SF_MODE; + if (GET_MODE_SIZE (i) == 4) + sparc_mode_class[i] = 1 << (int) SF_MODE; else if (GET_MODE_SIZE (i) == 8) - sparc_mode_class[i] = 1 << (int)DF_MODE; + sparc_mode_class[i] = 1 << (int) DF_MODE; + else + sparc_mode_class[i] = 0; break; case MODE_FLOAT: case MODE_COMPLEX_FLOAT: - if (GET_MODE_SIZE (i) <= 4) + if (GET_MODE_SIZE (i) == 4) sparc_mode_class[i] = 1 << (int) SF_MODE; else if (GET_MODE_SIZE (i) == 8) sparc_mode_class[i] = 1 << (int) DF_MODE; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c8d46d5bd63..98a2decdd05 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-04-15 Eric Botcazou + + * gcc.dg/pr56890-1.c: New test. + * gcc.dg/pr56890-2.c: Likewise. + 2013-04-15 Joey Ye * gcc.target/arm/thumb1-far-jump-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/pr56890-1.c b/gcc/testsuite/gcc.dg/pr56890-1.c new file mode 100644 index 00000000000..93b2134e594 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr56890-1.c @@ -0,0 +1,15 @@ +/* PR target/56890 */ +/* Reported by Rainer Jung */ + +/* { dg-do assemble } */ +/* { dg-options "-O2" } */ + +unsigned int buggy(unsigned int min, unsigned int max) +{ + if (max < 16384) { + unsigned short num16 = 0; + num16 = min + (long) ((double) (max - min + 1.0) * (num16 / (65535 + 1.0))); + return num16; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr56890-2.c b/gcc/testsuite/gcc.dg/pr56890-2.c new file mode 100644 index 00000000000..474327e9d03 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr56890-2.c @@ -0,0 +1,19 @@ +/* PR target/56890 */ +/* Reported by Rainer Jung */ + +/* { dg-do assemble } */ +/* { dg-options "-O" } */ + +unsigned int buggy(unsigned int min, unsigned int max) +{ + unsigned int number; + if (max < 16384) { + unsigned short num16; + num16 = min + (long) ((double) (max - min + 1.0) * (num16 / (65535 + 1.0))); + return num16; + } + else { + (number) = min + (long) ((double) (max - min + 1.0) * (number / (4294967295U + 1.0))); + } + return number; +} -- 2.30.2