diff mbox

[SPARC] Fix PR target/56890

Message ID 3344061.A5Rjyamnnq@polaris
State New
Headers show

Commit Message

Eric Botcazou April 14, 2013, 8:39 a.m. UTC
To my great surprise, this PR shows that the SPARC back-end allows QImode and 
HImode values to live in FP registers, but can neither load nor move them.
This can result in an unrecognizable move insn between FP registers or an 
illegal fdtox instruction in 64-bit mode as shown by the submitted testcases.

The attached patch changes that and yields no regressions both in 32-bit and 
64-bit modes.  Any objections to applying it to all active branches?


2013-04-14  Eric Botcazou  <ebotcazou@adacore.com>

	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) <MODE_INT>: Set H_MODE bit for sub-word modes.
	<MODE_VECTOR_INT>: Do not set SF_MODE for sub-word modes.
	<MODE_FLOAT>: Likewise.


2013-04-14  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.dg/pr56890-1.c: New test.
	* gcc.dg/pr56890-2.c: Likewise.

Comments

David Miller April 14, 2013, 7:19 p.m. UTC | #1
From: Eric Botcazou <ebotcazou@adacore.com>
Date: Sun, 14 Apr 2013 10:39:59 +0200

> To my great surprise, this PR shows that the SPARC back-end allows QImode and 
> HImode values to live in FP registers, but can neither load nor move them.
> This can result in an unrecognizable move insn between FP registers or an 
> illegal fdtox instruction in 64-bit mode as shown by the submitted testcases.
> 
> The attached patch changes that and yields no regressions both in 32-bit and 
> 64-bit modes.  Any objections to applying it to all active branches?

No objections.

We can actually support this by adding patterns for the partial store
instructions, which can store 8-bit and 16-bit quantities from FP
registers.
Eric Botcazou April 15, 2013, 4:07 p.m. UTC | #2
> No objections.

Thanks.

> We can actually support this by adding patterns for the partial store
> instructions, which can store 8-bit and 16-bit quantities from FP
> registers.

Ah, indeed, with -mvis.  Not clear whether that would really be worthwhile.
David Miller April 15, 2013, 5:09 p.m. UTC | #3
From: Eric Botcazou <ebotcazou@adacore.com>
Date: Mon, 15 Apr 2013 18:07:05 +0200

>> We can actually support this by adding patterns for the partial store
>> instructions, which can store 8-bit and 16-bit quantities from FP
>> registers.
> 
> Ah, indeed, with -mvis.  Not clear whether that would really be worthwhile.

Well, %99 of sparc cpus used with gcc these days are -mvis capable,
and popping the value to the integer register file via the stack
in these situations is needless overhead.
diff mbox

Patch

Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 197926)
+++ config/sparc/sparc.c	(working copy)
@@ -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;