0021-Use-li-and-rori-to-load-constants.patch 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. From b302f25e1f472cfe8b8e1867fc7499757c6ec4f0 Mon Sep 17 00:00:00 2001
  2. From: "yilun.xie" <yilun.xie@starfivetech.com>
  3. Date: Thu, 18 Nov 2021 15:47:00 +0800
  4. Subject: [PATCH 21/26] Use li and rori to load constants
  5. ---
  6. gcc/config/riscv/riscv.c | 41 ++++++++++++++++++++
  7. gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c | 35 +++++++++++++++++
  8. 2 files changed, 76 insertions(+)
  9. create mode 100644 gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c
  10. diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
  11. index bf91d8c7371..9e45c1ff9be 100644
  12. --- a/gcc/config/riscv/riscv.c
  13. +++ b/gcc/config/riscv/riscv.c
  14. @@ -439,6 +439,47 @@ riscv_build_integer_1 (struct riscv_integer_op codes[RISCV_MAX_INTEGER_OPS],
  15. }
  16. }
  17. + if (cost > 2 && TARGET_64BIT && TARGET_ZBB)
  18. + {
  19. + int leading_ones = clz_hwi (~value);
  20. + int trailing_ones = ctz_hwi (~value);
  21. +
  22. + /* If all bits are one except a few that are zero, and the zero bits
  23. + are within a range of 11 bits, and at least one of the upper 32-bits
  24. + is a zero, then we can generate a constant by loading a small
  25. + negative constant and rotating. */
  26. + if (leading_ones < 32
  27. + && ((64 - leading_ones - trailing_ones) < 12))
  28. + {
  29. + codes[0].code = UNKNOWN;
  30. + /* The sign-bit might be zero, so just rotate to be safe. */
  31. + codes[0].value = (((unsigned HOST_WIDE_INT) value >> trailing_ones)
  32. + | (value << (64 - trailing_ones)));
  33. + codes[1].code = ROTATERT;
  34. + codes[1].value = 64 - trailing_ones;
  35. + cost = 2;
  36. + }
  37. + /* Handle the case where the 11 bit range of zero bits wraps around. */
  38. + else
  39. + {
  40. + int upper_trailing_ones = ctz_hwi (~value >> 32);
  41. + int lower_leading_ones = clz_hwi (~value << 32);
  42. +
  43. + if (upper_trailing_ones < 32 && lower_leading_ones < 32
  44. + && ((64 - upper_trailing_ones - lower_leading_ones) < 12))
  45. + {
  46. + codes[0].code = UNKNOWN;
  47. + /* The sign-bit might be zero, so just rotate to be safe. */
  48. + codes[0].value = ((value << (32 - upper_trailing_ones))
  49. + | ((unsigned HOST_WIDE_INT) value
  50. + >> (32 + upper_trailing_ones)));
  51. + codes[1].code = ROTATERT;
  52. + codes[1].value = 32 - upper_trailing_ones;
  53. + cost = 2;
  54. + }
  55. + }
  56. + }
  57. +
  58. gcc_assert (cost <= RISCV_MAX_INTEGER_OPS);
  59. return cost;
  60. }
  61. diff --git a/gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c b/gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c
  62. new file mode 100644
  63. index 00000000000..ab8138cd874
  64. --- /dev/null
  65. +++ b/gcc/testsuite/gcc.target/riscv/zbb-li-rotr.c
  66. @@ -0,0 +1,35 @@
  67. +/* { dg-do compile } */
  68. +/* { dg-options "-march=rv64gc_zbb -mabi=lp64 -O2" } */
  69. +
  70. +long
  71. +li_rori (void)
  72. +{
  73. + return 0xffff77ffffffffffL;
  74. +}
  75. +
  76. +long
  77. +li_rori_2 (void)
  78. +{
  79. + return 0x77ffffffffffffffL;
  80. +}
  81. +
  82. +long
  83. +li_rori_3 (void)
  84. +{
  85. + return 0xfffffffeefffffffL;
  86. +}
  87. +
  88. +long
  89. +li_rori_4 (void)
  90. +{
  91. + return 0x5ffffffffffffff5L;
  92. +}
  93. +
  94. +long
  95. +li_rori_5 (void)
  96. +{
  97. + return 0xaffffffffffffffaL;
  98. +}
  99. +
  100. +
  101. +/* { dg-final { scan-assembler-times "rori\t" 5 } } */
  102. \ No newline at end of file
  103. --
  104. 2.33.1