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