diff mbox series

rs6000: Use rldimi for 64-bit constants with high=low (PR93012)

Message ID b39eb68e8b6c6e88eee572d814718e800e9bd7e1.1581011674.git.segher@kernel.crashing.org
State New
Headers show
Series rs6000: Use rldimi for 64-bit constants with high=low (PR93012) | expand

Commit Message

Segher Boessenkool Feb. 6, 2020, 5:59 p.m. UTC
We currently use an (up to) five instruction sequence to generate such
constants.  After this change we just generate a 32-bit constant and do
a rotate-and-mask-insert instruction, making the sequence only up to
three instructions.

Tested on powerpc64-linux {-m32,-m64}; committing to trunk.


Segher


2020-02-06  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/rs6000.c (rs6000_emit_set_long_const): Handle the case
	where the low and the high 32 bits are equal to each other specially,
	with an rldimi instruction.

gcc/testsuite/
	* gcc.target/powerpc/pr93012.c: New.

---
 gcc/config/rs6000/rs6000.c                 |  9 +++++++++
 gcc/testsuite/gcc.target/powerpc/pr93012.c | 13 +++++++++++++
 2 files changed, 22 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/powerpc/pr93012.c
diff mbox series

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 7457956..f2516a8 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -9257,6 +9257,15 @@  rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c)
 					   gen_lowpart (SImode,
 							copy_rtx (temp))));
     }
+  else if (ud1 == ud3 && ud2 == ud4)
+    {
+      temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode);
+      HOST_WIDE_INT num = (ud2 << 16) | ud1;
+      rs6000_emit_set_long_const (temp, (num ^ 0x80000000) - 0x80000000);
+      rtx one = gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff));
+      rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32));
+      emit_move_insn (dest, gen_rtx_IOR (DImode, one, two));
+    }
   else if ((ud4 == 0xffff && (ud3 & 0x8000))
 	   || (ud4 == 0 && ! (ud3 & 0x8000)))
     {
diff --git a/gcc/testsuite/gcc.target/powerpc/pr93012.c b/gcc/testsuite/gcc.target/powerpc/pr93012.c
new file mode 100644
index 0000000..4f764d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr93012.c
@@ -0,0 +1,13 @@ 
+/* PR target/93012 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O2 -std=c99" } */
+
+unsigned long long msk66() { return 0x6666666666666666ULL; }
+unsigned long long mskih() { return 0xabcd1234abcd1234ULL; }
+unsigned long long mskh0() { return 0x0000123400001234ULL; }
+unsigned long long mskl0() { return 0xabcd0000abcd0000ULL; }
+unsigned long long mskh1() { return 0xffff9234ffff9234ULL; }
+unsigned long long mskl1() { return 0x2bcdffff2bcdffffULL; }
+unsigned long long mskse() { return 0xffff1234ffff1234ULL; }
+
+/* { dg-final { scan-assembler-times {\mrldimi\M} 7 } } */