+2016-02-26 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/69946
+ * config/rs6000/rs6000.c (rs6000_insn_for_shift_mask): Print rlwinm
+ shift amount using %h. Add comment.
+
2016-02-26 Richard Biener <rguenther@suse.de>
Jeff Law <law@redhat.com>
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
operands[3] = GEN_INT (31 - nb);
operands[4] = GEN_INT (31 - ne);
+ /* This insn can also be a 64-bit rotate with mask that really makes
+ it just a shift right (with mask); the %h below are to adjust for
+ that situation (shift count is >= 32 in that case). */
if (dot)
- return "rlw%I2nm. %0,%1,%2,%3,%4";
- return "rlw%I2nm %0,%1,%2,%3,%4";
+ return "rlw%I2nm. %0,%1,%h2,%3,%4";
+ return "rlw%I2nm %0,%1,%h2,%3,%4";
}
gcc_unreachable ();
+2016-02-26 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/69946
+ * gcc.target/powerpc/pr69946.c: New file.
+
2016-02-26 Richard Biener <rguenther@suse.de>
Jeff Law <law@redhat.com>
--- /dev/null
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc_elfv2 } } */
+/* { dg-options "-O2" } */
+
+/* This generates a rotate:DI by 44, with mask 0xf00, which is implemented
+ using a rlwinm instruction. We used to write 44 for the shift count
+ there; it should be 12. */
+
+struct A
+{
+ int a : 4;
+ int : 2;
+ int b : 2;
+ int : 2;
+ int c : 2;
+ int d : 1;
+ int e;
+};
+struct B
+{
+ int a : 4;
+} *a;
+void bar (struct A);
+
+void
+foo (void)
+{
+ struct B b = a[0];
+ struct A c;
+ c.a = b.a;
+ c.b = 1;
+ c.c = 1;
+ c.d = 0;
+ bar (c);
+}
+
+/* { dg-final { scan-assembler-not {(?n)rlwinm.*,44,20,23} } } */
+/* { dg-final { scan-assembler-times {(?n)rlwinm.*,12,20,23} 1 } } */