diff options
author | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-09 03:09:37 +0000 |
---|---|---|
committer | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-09 03:09:37 +0000 |
commit | fedc146b41c867a8a0a2f62d5826b51c1cd6ad3d (patch) | |
tree | 2fb717e64143d3839431bdeadd6264727cee4056 /gcc/config/m32c/bitops.md | |
parent | 8f2de3e5044885a18e7bcec36f14c764b4dfbaa2 (diff) | |
download | ppe42-gcc-fedc146b41c867a8a0a2f62d5826b51c1cd6ad3d.tar.gz ppe42-gcc-fedc146b41c867a8a0a2f62d5826b51c1cd6ad3d.zip |
* config/m32c/addsub.md (addqi3): Disparage a0/a1.
(addpsi3): Expand to include memory operands. Remove
reload-specific splits.
* config/m32c/bitops.md (bset_qi, bset_hi, bclr_qi): New.
(andqi3_16, andhi3_16, iorqi3_16, iorhi3_16): New.
(andqi3_24, andhi3_24, iorqi3_24, iorhi3_24): New.
(andqi3, andhi3, iorqi3, iorhi3): Convert to expanders.
(shift1_qi, shift1_hi, insv): New.
* config/m32c/cond.md (cbranchqi4, cbranchhi4): Remove.
(cbranch<mode>4, stzx_16, stzx_24_<mode>, stzx_reversed,
cmp<mode>, b<code>, s<code>, s<code>_24, movqicc, movhicc,
cond_to_int): New.
* config/m32c/m32c-protos.h: Update as needed.
* config/m32c/m32c.c (m32c_reg_class_from_constraint): Don't
default the Rcr, Rcl, Raw, and Ral constraints. Add Ra0 and Ra1.
Fail for unrecognized R* constraints.
(m32c_cannot_change_mode_class): Be more picky about pseudos.
(m32c_const_ok_for_constraint_p): Add Imb, Imw, and I00.
(m32c_extra_constraint_p2): Allow (mem (plus (plus fb int) int)).
Add Sp constraint.
(m32c_init_libfuncs): New.
(m32c_legitimate_address_p): Add debug wrapper.
(m32c_rtx_costs): New.
(m32c_address_cost): New.
(conversions): Add 'B' prefix.
(m32c_print_operand): 'h' and 'H' pick lower and upper halves of
operands, or word regnames for QI operands. 'B' prints bit
position.
(m32c_expand_setmemhi): New.
(m32c_expand_movmemhi): New.
(m32c_expand_movstr): New.
(m32c_expand_cmpstr): New.
(m32c_prepare_shift): Shift counts are limited to 16 bits at a time.
(m32c_expand_neg_mulpsi3): Handle non-ints.
(m32c_cmp_flg_0): New.
(m32c_expand_movcc): New.
(m32c_expand_insv): New.
(m32c_scc_pattern): New.
* config/m32c/m32c.h (reg classes): Add AO_REGS and A1_REGS. Take
a0/a1 out of SIregs.
(STORE_FLAG_VALUE): New.
* config/m32c/m32c.md: Add unspecs for string moves. Define various mode and
code macros.
(no_insn): New.
* config/m32c/mov.md: Make constraints more liberal.
(zero_extendqihi2): Optimize r0/r1 case.
* config/m32c/muldiv.md (mulpsi3): Check for intvals.
* config/m32c/predicates.md (m32c_any_operand): New.
(m32c_nonimmediate_operand): New.
(m32c_hl_operand): New.
(m32c_r3_operand): New.
(ap_operand): New.
(ma_operand): New.
(memsym_operand): New.
(memimmed_operand): New.
(a_qi_operand): New.
(m32c_eqne_operator): New.
(m32c_1bit8_operand): New.
(m32c_1bit16_operand): New.
(m32c_1mask8_operand): New.
(m32c_1mask16_operand): New.
* config/m32c/blkmov.md: New file.
* config/m32c/t-m32c (MD_FILES): Add blkmov.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111859 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/m32c/bitops.md')
-rw-r--r-- | gcc/config/m32c/bitops.md | 290 |
1 files changed, 266 insertions, 24 deletions
diff --git a/gcc/config/m32c/bitops.md b/gcc/config/m32c/bitops.md index e6c269b175b..e7823b92c72 100644 --- a/gcc/config/m32c/bitops.md +++ b/gcc/config/m32c/bitops.md @@ -22,40 +22,247 @@ ;; Bit-wise operations (and, ior, xor, shift) -(define_insn "andqi3" - [(set (match_operand:QI 0 "mra_operand" "=RhlSd,RhlSd,??Rmm,??Rmm") - (and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0") - (match_operand:QI 2 "mrai_operand" "iRhlSd,?Rmm,iRhlSd,?Rmm")))] +; On the R8C and M16C, "address" for bit instructions is usually (but +; not always!) the *bit* address, not the *byte* address. This +; confuses gcc, so we avoid cases where gcc would produce the wrong +; code. We're left with absolute addresses and registers, and the odd +; case of shifting a bit by a variable. + +; On the M32C, "address" for bit instructions is a regular address, +; and the bit number is stored in a separate field. Thus, we can let +; gcc do more interesting things. However, the M32C cannot set all +; the bits in a 16 bit register, which the R8C/M16C can do. + +; However, it all means that we end up with two sets of patterns, one +; for each chip. + +;;---------------------------------------------------------------------- + +;; First off, all the ways we can set one bit, other than plain IOR. + +(define_insn "bset_qi" + [(set (match_operand:QI 0 "memsym_operand" "+Si") + (ior:QI (subreg:QI (ashift:HI (const_int 1) + (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0)) 0) + (match_operand:QI 2 "" "0")))] + "TARGET_A16" + "bset\t%0[%1]" + [(set_attr "flags" "sz")] + ) + +(define_insn "bset_hi" + [(set (zero_extract:HI (match_operand:QI 0 "memsym_operand" "+Si") + (const_int 1) + (zero_extend:HI (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0))) + (const_int 1))] + "TARGET_A16" + "bset\t%0[%1]" + [(set_attr "flags" "sz")] + ) + +;;---------------------------------------------------------------------- + +;; Now all the ways we can clear one bit, other than plain AND. + +; This is odd because the shift patterns use QI counts, but we can't +; easily put QI in $aN without causing problems elsewhere. +(define_insn "bclr_qi" + [(set (zero_extract:HI (match_operand:QI 0 "memsym_operand" "+Si") + (const_int 1) + (zero_extend:HI (subreg:QI (match_operand:HI 1 "a_qi_operand" "Raa") 0))) + (const_int 0))] + "TARGET_A16" + "bclr\t%0[%1]" + [(set_attr "flags" "sz")] + ) + + +;;---------------------------------------------------------------------- + +;; Now the generic patterns. + +(define_insn "andqi3_16" + [(set (match_operand:QI 0 "mra_operand" "=Sp,Rqi,RhlSd,RhlSd,??Rmm,??Rmm") + (and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") + (match_operand 2 "mrai_operand" "Imb,Imb,iRhlSd,?Rmm,iRhlSd,?Rmm")))] + "TARGET_A16" + "@ + bclr\t%B2,%0 + bclr\t%B2,%h0 + and.b\t%x2,%0 + and.b\t%x2,%0 + and.b\t%x2,%0 + and.b\t%x2,%0" + [(set_attr "flags" "n,n,sz,sz,sz,sz")] + ) + +(define_insn "andhi3_16" + [(set (match_operand:HI 0 "mra_operand" "=Sp,Sp,Rhi,RhiSd,??Rmm,RhiSd,??Rmm") + (and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0") + (match_operand:HI 2 "mrai_operand" "Imb,Imw,Imw,iRhiSd,?Rmm,?Rmm,iRhiSd")))] + "TARGET_A16" + "@ + + bclr\t%B2,%0 + bclr\t%B2-8,1+%0 + bclr\t%B2,%0 + and.w\t%X2,%0 + and.w\t%X2,%0 + and.w\t%X2,%0 + and.w\t%X2,%0" + [(set_attr "flags" "n,n,n,sz,sz,sz,sz")] + ) + + + +(define_insn "iorqi3_16" + [(set (match_operand:QI 0 "mra_operand" "=Sp,Rqi,RqiSd,??Rmm,RqiSd,??Rmm") + (ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") + (match_operand:QI 2 "mrai_operand" "Ilb,Ilb,iRhlSd,iRhlSd,?Rmm,?Rmm")))] + "TARGET_A16" + "@ + bset\t%B2,%0 + bset\t%B2,%h0 + or.b\t%x2,%0 + or.b\t%x2,%0 + or.b\t%x2,%0 + or.b\t%x2,%0" + [(set_attr "flags" "n,n,sz,sz,sz,sz")] + ) + +(define_insn "iorhi3_16" + [(set (match_operand:HI 0 "mra_operand" "=Sp,Sp,Rhi,RhiSd,RhiSd,??Rmm,??Rmm") + (ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0") + (match_operand:HI 2 "mrai_operand" "Imb,Imw,Ilw,iRhiSd,?Rmm,iRhiSd,?Rmm")))] + "TARGET_A16" + "@ + bset %B2,%0 + bset\t%B2-8,1+%0 + bset\t%B2,%0 + or.w\t%X2,%0 + or.w\t%X2,%0 + or.w\t%X2,%0 + or.w\t%X2,%0" + [(set_attr "flags" "n,n,n,sz,sz,sz,sz")] + ) + +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +(define_insn "andqi3_24" + [(set (match_operand:QI 0 "mra_operand" "=Sd,Rqi,RhlSd,RhlSd,??Rmm,??Rmm") + (and:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") + (match_operand 2 "mrai_operand" "Imb,Imb,iRhlSd,?Rmm,iRhlSd,?Rmm")))] + "TARGET_A24" + "@ + bclr\t%B2,%0 + bclr\t%B2,%0 + and.b\t%x2,%0 + and.b\t%x2,%0 + and.b\t%x2,%0 + and.b\t%x2,%0" + [(set_attr "flags" "n,n,sz,sz,sz,sz")] + ) + +(define_insn "andhi3_24" + [(set (match_operand:HI 0 "mra_operand" "=Sd,Sd,Rqi,Rqi,RhiSd,??Rmm,RhiSd,??Rmm") + (and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0,0") + (match_operand:HI 2 "mrai_operand" "Imb,Imw,Imb,Imw,iRhiSd,?Rmm,?Rmm,iRhiSd")))] + "TARGET_A24" + "@ + bclr\t%B2,%0 + bclr\t%B2-8,1+%0 + bclr\t%B2,%h0 + bclr\t%B2-8,%H0 + and.w\t%X2,%0 + and.w\t%X2,%0 + and.w\t%X2,%0 + and.w\t%X2,%0" + [(set_attr "flags" "n,n,n,n,sz,sz,sz,sz")] + ) + + + +(define_insn "iorqi3_24" + [(set (match_operand:QI 0 "mra_operand" "=Sd,Rqi,RqiSd,??Rmm,RqiSd,??Rmm") + (ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0,0,0") + (match_operand:QI 2 "mrai_operand" "Ilb,Ilb,iRhlSd,iRhlSd,?Rmm,?Rmm")))] + "TARGET_A24" + "@ + bset\t%B2,%0 + bset\t%B2,%0 + or.b\t%x2,%0 + or.b\t%x2,%0 + or.b\t%x2,%0 + or.b\t%x2,%0" + [(set_attr "flags" "n,n,sz,sz,sz,sz")] + ) + +(define_insn "iorhi3_24" + [(set (match_operand:HI 0 "mra_operand" "=Sd,Sd,Rqi,Rqi,RhiSd,RhiSd,??Rmm,??Rmm") + (ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0,0,0,0,0") + (match_operand:HI 2 "mrai_operand" "Ilb,Ilw,Ilb,Ilw,iRhiSd,?Rmm,iRhiSd,?Rmm")))] + "TARGET_A24" + "@ + bset\t%B2,%0 + bset\t%B2-8,1+%0 + bset\t%B2,%h0 + bset\t%B2-8,%H0 + or.w\t%X2,%0 + or.w\t%X2,%0 + or.w\t%X2,%0 + or.w\t%X2,%0" + [(set_attr "flags" "n,n,n,n,sz,sz,sz,sz")] + ) + + +; ---------------------------------------------------------------------- + +(define_expand "andqi3" + [(set (match_operand:QI 0 "mra_operand" "") + (and:QI (match_operand:QI 1 "mra_operand" "") + (match_operand:QI 2 "mrai_operand" "")))] "" - "and.b\t%x2,%0" - [(set_attr "flags" "sz,sz,sz,sz")] + "if (TARGET_A16) + emit_insn (gen_andqi3_16 (operands[0], operands[1], operands[2])); + else + emit_insn (gen_andqi3_24 (operands[0], operands[1], operands[2])); + DONE;" ) -(define_insn "andhi3" - [(set (match_operand:HI 0 "mra_operand" "=RhiSd,??Rmm,RhiSd,??Rmm") - (and:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0") - (match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,?Rmm,iRhiSd")))] +(define_expand "andhi3" + [(set (match_operand:HI 0 "mra_operand" "") + (and:HI (match_operand:HI 1 "mra_operand" "") + (match_operand:HI 2 "mrai_operand" "")))] "" - "and.w\t%X2,%0" - [(set_attr "flags" "sz,sz,sz,sz")] + "if (TARGET_A16) + emit_insn (gen_andhi3_16 (operands[0], operands[1], operands[2])); + else + emit_insn (gen_andhi3_24 (operands[0], operands[1], operands[2])); + DONE;" ) -(define_insn "iorqi3" - [(set (match_operand:QI 0 "mra_operand" "=RqiSd,??Rmm,RqiSd,??Rmm") - (ior:QI (match_operand:QI 1 "mra_operand" "%0,0,0,0") - (match_operand:QI 2 "mrai_operand" "iRhlSd,iRhlSd,?Rmm,?Rmm")))] +(define_expand "iorqi3" + [(set (match_operand:QI 0 "mra_operand" "") + (ior:QI (match_operand:QI 1 "mra_operand" "") + (match_operand:QI 2 "mrai_operand" "")))] "" - "or.b\t%x2,%0" - [(set_attr "flags" "sz,sz,sz,sz")] + "if (TARGET_A16) + emit_insn (gen_iorqi3_16 (operands[0], operands[1], operands[2])); + else + emit_insn (gen_iorqi3_24 (operands[0], operands[1], operands[2])); + DONE;" ) -(define_insn "iorhi3" - [(set (match_operand:HI 0 "mra_operand" "=RhiSd,RhiSd,??Rmm,??Rmm") - (ior:HI (match_operand:HI 1 "mra_operand" "%0,0,0,0") - (match_operand:HI 2 "mrai_operand" "iRhiSd,?Rmm,iRhiSd,?Rmm")))] +(define_expand "iorhi3" + [(set (match_operand:HI 0 "mra_operand" "") + (ior:HI (match_operand:HI 1 "mra_operand" "") + (match_operand:HI 2 "mrai_operand" "")))] "" - "or.w\t%X2,%0" - [(set_attr "flags" "sz,sz,sz,sz")] + "if (TARGET_A16) + emit_insn (gen_iorhi3_16 (operands[0], operands[1], operands[2])); + else + emit_insn (gen_iorhi3_24 (operands[0], operands[1], operands[2])); + DONE;" ) (define_insn "xorqi3" @@ -91,3 +298,38 @@ "not.w\t%0" [(set_attr "flags" "sz,sz")] ) + +; Optimizations using bit opcodes + +; We need this because combine only looks at three insns at a time, +; and the bclr_qi pattern uses four - mov, shift, not, and. GCC +; should never expand this pattern, because it only shifts a constant +; by a constant, so gcc should do that itself. +(define_insn "shift1_qi" + [(set (match_operand:QI 0 "mra_operand" "=Rqi") + (ashift:QI (const_int 1) + (match_operand 1 "const_int_operand" "In4")))] + "" + "mov.b\t#1,%0\n\tshl.b\t%1,%0" + ) +(define_insn "shift1_hi" + [(set (match_operand:HI 0 "mra_operand" "=Rhi") + (ashift:HI (const_int 1) + (match_operand 1 "const_int_operand" "In4")))] + "" + "mov.w\t#1,%0\n\tshl.w\t%1,%0" + ) + +; Generic insert-bit expander, needed so that we can use the bit +; opcodes for volatile bitfields. + +(define_expand "insv" + [(set (zero_extract:HI (match_operand:HI 0 "mra_operand" "") + (match_operand 1 "const_int_operand" "") + (match_operand 2 "const_int_operand" "")) + (match_operand:HI 3 "const_int_operand" ""))] + "" + "if (m32c_expand_insv (operands)) + FAIL; + DONE;" + ) |