@@ -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 ();
}