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
This commit is contained in:
parent
33eaef4bf7
commit
5e7821eb98
7 changed files with 92 additions and 5 deletions
|
@ -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>
|
||||
|
||||
|
|
BIN
gcc/config/m68k/.m68k.md.swp
Executable file
BIN
gcc/config/m68k/.m68k.md.swp
Executable file
Binary file not shown.
|
@ -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")
|
||||
|
|
|
@ -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));
|
||||
})
|
||||
|
|
|
@ -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
|
||||
|
|
20
gcc/testsuite/gcc.target/m68k/pr52076-1.c
Normal file
20
gcc/testsuite/gcc.target/m68k/pr52076-1.c
Normal file
|
@ -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; }
|
27
gcc/testsuite/gcc.target/m68k/pr52076-2.c
Normal file
27
gcc/testsuite/gcc.target/m68k/pr52076-2.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Add table
Reference in a new issue