From 72b2f3317b4484b25e9a6cc3fd12e7f8c893fb56 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Fri, 20 Dec 2019 00:15:19 +0000 Subject: [PATCH] rs6000: Use rldimi for 64-bit constants with high=low (PR93012) 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. * 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/ChangeLog | 6 ++++++ gcc/config/rs6000/rs6000.c | 9 +++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.target/powerpc/pr93012.c | 13 +++++++++++++ 4 files changed, 32 insertions(+) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr93012.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 302137eb29d..db03bf18242 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-02-06 Segher Boessenkool + + * 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. + 2020-02-06 Mihail Ionescu * config/arm/arm-cpus.in: Set profile M for armv8.1-m.main. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 74579568ee8..f2516a83842 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/ChangeLog b/gcc/testsuite/ChangeLog index 9c208d09c49..fd80c8d0f32 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2020-02-06 Segher Boessenkool + + * gcc.target/powerpc/pr93012.c: New. + 2020-02-06 Richard Sandiford PR target/87763 diff --git a/gcc/testsuite/gcc.target/powerpc/pr93012.c b/gcc/testsuite/gcc.target/powerpc/pr93012.c new file mode 100644 index 00000000000..4f764d0576f --- /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 } } */ -- 2.30.2