Cc: Marcus Shawcroft <marcus.shawcr...@arm.com>
Cc: Richard Earnshaw <richard.earns...@arm.com>
---
        * config/aarch64/aarch64.c (AA_GI_DUP): New.
        (genimm_aa64::exam_full): Test for equal 32-bit parts.
        (genimm_aa64::generate): Handle AA_GI_DUP.
---
 gcc/config/aarch64/aarch64.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 6b12a07..828526e 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1328,6 +1328,7 @@ STATIC_ASSERT (((int)AND & ~48) != 0);
 
 enum aa_gi_code
 {
+  AA_GI_DUP = -3,
   AA_GI_NIL = -2,
   AA_GI_SET = -1,
 
@@ -1565,6 +1566,17 @@ genimm_aa64::exam_full (unsigned HOST_WIDE_INT val)
       return;
     }
 
+  /* If the two halves of the constant are the same, use an insert.
+     Since we have already excluded one_match and zero_match == 2,
+     this must require three insns to generate.  */
+  if ((val >> 32) == (val & 0xffffffffu))
+    {
+      set0 (val & 0xffff);
+      insN (16, val);
+      opN (AA_GI_DUP, 32);
+      return;
+    }
+
  simple_sequence:
   cost = 0;
   for (int i = 0; i < 64; i += 16)
@@ -1629,6 +1641,11 @@ genimm_aa64::generate (rtx dest, machine_mode mode) const
          else
            x = gen_insv_immdi (dest, GEN_INT ((int)code[i]), x);
          break;
+       case AA_GI_DUP:
+         x = gen_rtx_ASHIFT (mode, dest, x);
+         x = gen_rtx_IOR (mode, x, dest);
+         x = gen_rtx_SET (dest, x);
+         break;
        default:
          gcc_unreachable ();
        }
-- 
2.4.3

Reply via email to