123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- From b302f25e1f472cfe8b8e1867fc7499757c6ec4f0 Mon Sep 17 00:00:00 2001
- From: "yilun.xie" <yilun.xie@starfivetech.com>
- Date: Thu, 18 Nov 2021 15:47:00 +0800
- Subject: [PATCH 21/26] Use li and rori to load constants
- ---
- gcc/config/riscv/riscv.c | 41 ++++++++++++++++++++
- gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c | 35 +++++++++++++++++
- 2 files changed, 76 insertions(+)
- create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c
- diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
- index bf91d8c7371..9e45c1ff9be 100644
- --- a/gcc/config/riscv/riscv.c
- +++ b/gcc/config/riscv/riscv.c
- @@ -439,6 +439,47 @@ riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS],
- }
- }
-
- + if (cost > 2 && TARGET_64BIT && TARGET_ZBB)
- + {
- + int leading_ones = clz_hwi (~value);
- + int trailing_ones = ctz_hwi (~value);
- +
- + /* If all bits are one except a few that are zero, and the zero bits
- + are within a range of 11 bits, and at least one of the upper 32-bits
- + is a zero, then we can generate a constant by loading a small
- + negative constant and rotating. */
- + if (leading_ones < 32
- + && ((64 - leading_ones - trailing_ones) < 12))
- + {
- + codes[0].code = UNKNOWN;
- + /* The sign-bit might be zero, so just rotate to be safe. */
- + codes[0].value = (((unsigned HOST_WIDE_INT) value >> trailing_ones)
- + | (value << (64 - trailing_ones)));
- + codes[1].code = ROTATERT;
- + codes[1].value = 64 - trailing_ones;
- + cost = 2;
- + }
- + /* Handle the case where the 11 bit range of zero bits wraps around. */
- + else
- + {
- + int upper_trailing_ones = ctz_hwi (~value >> 32);
- + int lower_leading_ones = clz_hwi (~value << 32);
- +
- + if (upper_trailing_ones < 32 && lower_leading_ones < 32
- + && ((64 - upper_trailing_ones - lower_leading_ones) < 12))
- + {
- + codes[0].code = UNKNOWN;
- + /* The sign-bit might be zero, so just rotate to be safe. */
- + codes[0].value = ((value << (32 - upper_trailing_ones))
- + | ((unsigned HOST_WIDE_INT) value
- + >> (32 + upper_trailing_ones)));
- + codes[1].code = ROTATERT;
- + codes[1].value = 32 - upper_trailing_ones;
- + cost = 2;
- + }
- + }
- + }
- +
- gcc_assert (cost <= RISCV_MAX_INTEGER_OPS);
- return cost;
- }
- diff --git a/gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c b/gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c
- new file mode 100644
- index 00000000000..ab8138cd874
- --- /dev/null
- +++ b/gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c
- @@ -0,0 +1,35 @@
- +/* { dg-do compile } */
- +/* { dg-options "-march=rv64gc_zbb -mabi=lp64 -O2" } */
- +
- +long
- +li_rori (void)
- +{
- + return 0xffff77ffffffffffL;
- +}
- +
- +long
- +li_rori_2 (void)
- +{
- + return 0x77ffffffffffffffL;
- +}
- +
- +long
- +li_rori_3 (void)
- +{
- + return 0xfffffffeefffffffL;
- +}
- +
- +long
- +li_rori_4 (void)
- +{
- + return 0x5ffffffffffffff5L;
- +}
- +
- +long
- +li_rori_5 (void)
- +{
- + return 0xaffffffffffffffaL;
- +}
- +
- +
- +/* { dg-final { scan-assembler-times "rori\t" 5 } } */
- \ No newline at end of file
- --
- 2.33.1
|