aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2015-01-22 14:24:28 -0700
committerJeff Law <law@gcc.gnu.org>2015-01-22 14:24:28 -0700
commit5e7821eb98292742a6aa4e1495ad1ccf9832d749 (patch)
tree5cc13a22d537751d7a1a6c2797a54801459e8957
parent33eaef4bf7f7b0650236c6ce2f5512344b3acbbf (diff)
downloadgcc-5e7821eb98292742a6aa4e1495ad1ccf9832d749.zip
gcc-5e7821eb98292742a6aa4e1495ad1ccf9832d749.tar.gz
gcc-5e7821eb98292742a6aa4e1495ad1ccf9832d749.tar.bz2
re PR target/52076 (bloated code for setting single bits in bitfields on m68k)
PR target/52076 * config/m68k/m68k.md (xorsi3_internal): Twiddle constraints to improve code density for small immediate to memory case. (insv): Better handle bitfield assignments when the field is being set to all ones. * config/m68k/predicates.md (reg_or_pow2_m1_operand): New operand predicate. PR target/52076 * gcc.target/m68k/pr52076-1.c: New test. * gcc.target/m68k/pr52076-2.c: New test. From-SVN: r220015
-rw-r--r--gcc/ChangeLog10
-rwxr-xr-xgcc/config/m68k/.m68k.md.swpbin0 -> 16384 bytes
-rw-r--r--gcc/config/m68k/m68k.md21
-rw-r--r--gcc/config/m68k/predicates.md13
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/m68k/pr52076-1.c20
-rw-r--r--gcc/testsuite/gcc.target/m68k/pr52076-2.c27
7 files changed, 92 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c166933..ae5e9a5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2015-01-22 Jeff Law <law@redhat.com>
+
+ PR target/52076
+ * config/m68k/m68k.md (xorsi3_internal): Twiddle constraints to
+ improve code density for small immediate to memory case.
+ (insv): Better handle bitfield assignments when the field is
+ being set to all ones.
+ * config/m68k/predicates.md (reg_or_pow2_m1_operand): New
+ operand predicate.
+
2015-01-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/config/m68k/.m68k.md.swp b/gcc/config/m68k/.m68k.md.swp
new file mode 100755
index 0000000..36d7681
--- /dev/null
+++ b/gcc/config/m68k/.m68k.md.swp
Binary files differ
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index d34ad1d..6bb296e 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -3838,9 +3838,9 @@
"")
(define_insn "xorsi3_internal"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=do,m")
- (xor:SI (match_operand:SI 1 "general_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "di,dKT")))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,o,m")
+ (xor:SI (match_operand:SI 1 "general_operand" "%0, 0,0")
+ (match_operand:SI 2 "general_operand" "di,dK,dKT")))]
"!TARGET_COLDFIRE"
{
@@ -5583,9 +5583,20 @@
[(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "")
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
- (match_operand:SI 3 "register_operand" ""))]
+ (match_operand:SI 3 "reg_or_pow2_m1_operand" ""))]
"TARGET_68020 && TARGET_BITFIELD"
- "")
+ "
+{
+ /* Special case initializing a field to all ones. */
+ if (GET_CODE (operands[3]) == CONST_INT)
+ {
+ if (exact_log2 (INTVAL (operands[3]) + 1) != INTVAL (operands[1]))
+ operands[3] = force_reg (SImode, operands[3]);
+ else
+ operands[3] = constm1_rtx;
+
+ }
+}")
(define_insn "*insv_bfins_mem"
[(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+o")
diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
index a7b5c42..c652f10 100644
--- a/gcc/config/m68k/predicates.md
+++ b/gcc/config/m68k/predicates.md
@@ -244,3 +244,16 @@
|| reload_in_progress
|| reload_completed));
})
+
+;; Used to detect when an operand is either a register
+;; or a constant that is all ones in its lower bits.
+;; Used by insv pattern to help detect when we're initializing
+;; a bitfield to all ones.
+
+(define_predicate "reg_or_pow2_m1_operand"
+ (match_code "reg,const_int")
+{
+ return (REG_P (op)
+ || (GET_CODE (op) == CONST_INT
+ && exact_log2 (INTVAL (op) + 1) >= 0));
+})
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8bebdac..1fc0241 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-22 Jeff Law <law@redhat.com>
+
+ PR target/52076
+ * gcc.target/m68k/pr52076-1.c: New test.
+ * gcc.target/m68k/pr52076-2.c: New test.
+
2015-01-22 Richard Biener <rguenther@suse.de>
PR middle-end/64728
diff --git a/gcc/testsuite/gcc.target/m68k/pr52076-1.c b/gcc/testsuite/gcc.target/m68k/pr52076-1.c
new file mode 100644
index 0000000..86df0dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/pr52076-1.c
@@ -0,0 +1,20 @@
+/* { dg-do assemble } /*
+/* { dg-options "-Os -fomit-frame-pointer -m68040" } */
+/* { dg-final { object-size text <= 72 } } */
+
+struct kobject {
+ unsigned int b7:1;
+ unsigned int :6;
+ unsigned int b0:1;
+ unsigned char x;
+ unsigned int f;
+};
+
+void ior(struct kobject *kobj) { kobj->f |= 4; }
+void ior_m(struct kobject *kobj) { kobj->f |= -4; }
+
+void xor(struct kobject *kobj) { kobj->f ^= 4; }
+void xor_m(struct kobject *kobj) { kobj->f ^= -4; }
+
+void and(struct kobject *kobj) { kobj->f &= 4; }
+void and_m(struct kobject *kobj) { kobj->f &= -4; }
diff --git a/gcc/testsuite/gcc.target/m68k/pr52076-2.c b/gcc/testsuite/gcc.target/m68k/pr52076-2.c
new file mode 100644
index 0000000..30c6991
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/pr52076-2.c
@@ -0,0 +1,27 @@
+/* { dg-do assemble } /*
+/* { dg-options "-Os -fomit-frame-pointer -m68040" } */
+/* { dg-final { object-size text <= 30 } } */
+
+struct kobject {
+ unsigned int b7:1;
+ unsigned int b56:2;
+ unsigned int b1234:4;
+ unsigned int b0:1;
+ unsigned char x;
+ unsigned int f;
+};
+
+void b7(struct kobject *kobj)
+{
+ kobj->b7 = 1;
+}
+
+void b56(struct kobject *kobj)
+{
+ kobj->b56 = 3;
+}
+
+void b1234(struct kobject *kobj)
+{
+ kobj->b1234 = 15;
+}