diff options
author | Jeff Law <law@redhat.com> | 2015-01-22 14:24:28 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2015-01-22 14:24:28 -0700 |
commit | 5e7821eb98292742a6aa4e1495ad1ccf9832d749 (patch) | |
tree | 5cc13a22d537751d7a1a6c2797a54801459e8957 /gcc/config/m68k | |
parent | 33eaef4bf7f7b0650236c6ce2f5512344b3acbbf (diff) | |
download | gcc-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
Diffstat (limited to 'gcc/config/m68k')
-rwxr-xr-x | gcc/config/m68k/.m68k.md.swp | bin | 0 -> 16384 bytes | |||
-rw-r--r-- | gcc/config/m68k/m68k.md | 21 | ||||
-rw-r--r-- | gcc/config/m68k/predicates.md | 13 |
3 files changed, 29 insertions, 5 deletions
diff --git a/gcc/config/m68k/.m68k.md.swp b/gcc/config/m68k/.m68k.md.swp Binary files differnew file mode 100755 index 0000000..36d7681 --- /dev/null +++ b/gcc/config/m68k/.m68k.md.swp 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)); +}) |