diff options
author | DJ Delorie <dj@redhat.com> | 2006-01-12 22:34:40 -0500 |
---|---|---|
committer | DJ Delorie <dj@gcc.gnu.org> | 2006-01-12 22:34:40 -0500 |
commit | 23fed240a465b1e66ad1af308fe485f42c156cb9 (patch) | |
tree | 9e1c2623ec284bf054eb8d2b3113f0d0a8aa724d /gcc | |
parent | dadb213fd1d7a25235ac92656e451b0fe189ecc5 (diff) | |
download | gcc-23fed240a465b1e66ad1af308fe485f42c156cb9.zip gcc-23fed240a465b1e66ad1af308fe485f42c156cb9.tar.gz gcc-23fed240a465b1e66ad1af308fe485f42c156cb9.tar.bz2 |
shift.md: Rewrite...
* config/m32c/shift.md: Rewrite: Allow arbitrary operands for
shift counts, separate SI shifts for m32c vs m16c, pass shift type
so that constant shifts can be split.
* config/m32c/m32c.c (m32c_const_ok_for_constraint_p): Add In6.
(m32c_valid_pointer_mode): Make static.
(shift_gen_func_for): New.
(m32c_prepare_shift): Use it. Split large const shifts into
multiple shifts.
* config/m32c/predicates.md (shiftcount_operand): Allow more
general operands.
(longshiftcount_operand): New.
* doc/md.texi (Machine Constraints): Document In6.
From-SVN: r109661
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/config/m32c/m32c.c | 62 | ||||
-rw-r--r-- | gcc/config/m32c/predicates.md | 6 | ||||
-rw-r--r-- | gcc/config/m32c/shift.md | 137 | ||||
-rw-r--r-- | gcc/doc/md.texi | 4 |
5 files changed, 163 insertions, 61 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a87c296..4da37fd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2006-01-12 DJ Delorie <dj@redhat.com> + + * config/m32c/shift.md: Rewrite: Allow arbitrary operands for + shift counts, separate SI shifts for m32c vs m16c, pass shift type + so that constant shifts can be split. + * config/m32c/m32c.c (m32c_const_ok_for_constraint_p): Add In6. + (m32c_valid_pointer_mode): Make static. + (shift_gen_func_for): New. + (m32c_prepare_shift): Use it. Split large const shifts into + multiple shifts. + * config/m32c/predicates.md (shiftcount_operand): Allow more + general operands. + (longshiftcount_operand): New. + * doc/md.texi (Machine Constraints): Document In6. + 2006-01-13 Ben Elliston <bje@au.ibm.com> * doc/tm.texi (Data Output): Add REAL_VALUE_TO_TARGET_DECIMAL32, diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index 8712131..24b7fff 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -901,6 +901,10 @@ m32c_const_ok_for_constraint_p (HOST_WIDE_INT value, { return (-16 <= value && value && value <= 16); } + if (memcmp (str, "In6", 3) == 0) + { + return (-32 <= value && value && value <= 32); + } if (memcmp (str, "IM2", 3) == 0) { return (-65536 <= value && value && value <= -1); @@ -1505,7 +1509,7 @@ m32c_function_arg_regno_p (int r) for some opcodes in R8C/M16C and for reset vectors and such. */ #undef TARGET_VALID_POINTER_MODE #define TARGET_VALID_POINTER_MODE m32c_valid_pointer_mode -bool +static bool m32c_valid_pointer_mode (enum machine_mode mode) { if (mode == HImode @@ -2834,27 +2838,63 @@ m32c_split_move (rtx * operands, enum machine_mode mode, int split_all) return rv; } +typedef rtx (*shift_gen_func)(rtx, rtx, rtx); + +static shift_gen_func +shift_gen_func_for (int mode, int code) +{ +#define GFF(m,c,f) if (mode == m && code == c) return f + GFF(QImode, ASHIFT, gen_ashlqi3_i); + GFF(QImode, ASHIFTRT, gen_ashrqi3_i); + GFF(QImode, LSHIFTRT, gen_lshrqi3_i); + GFF(HImode, ASHIFT, gen_ashlhi3_i); + GFF(HImode, ASHIFTRT, gen_ashrhi3_i); + GFF(HImode, LSHIFTRT, gen_lshrhi3_i); + GFF(PSImode, ASHIFT, gen_ashlpsi3_i); + GFF(PSImode, ASHIFTRT, gen_ashrpsi3_i); + GFF(PSImode, LSHIFTRT, gen_lshrpsi3_i); + GFF(SImode, ASHIFT, TARGET_A16 ? gen_ashlsi3_16 : gen_ashlsi3_24); + GFF(SImode, ASHIFTRT, TARGET_A16 ? gen_ashrsi3_16 : gen_ashrsi3_24); + GFF(SImode, LSHIFTRT, TARGET_A16 ? gen_lshrsi3_16 : gen_lshrsi3_24); +#undef GFF +} + /* The m32c only has one shift, but it takes a signed count. GCC doesn't want this, so we fake it by negating any shift count when we're pretending to shift the other way. */ int -m32c_prepare_shift (rtx * operands, int scale, int bits) +m32c_prepare_shift (rtx * operands, int scale, int shift_code) { + enum machine_mode mode = GET_MODE (operands[0]); + shift_gen_func func = shift_gen_func_for (mode, shift_code); rtx temp; - if (GET_CODE (operands[2]) == CONST_INT - && INTVAL (operands[2]) <= (1 << (bits - 1)) - && INTVAL (operands[2]) >= -(1 << (bits - 1))) + + if (GET_CODE (operands[2]) == CONST_INT) { - operands[2] = GEN_INT (scale * INTVAL (operands[2])); - return 0; + int maxc = TARGET_A24 && (mode == PSImode || mode == SImode) ? 32 : 8; + int count = INTVAL (operands[2]) * scale; + + while (count > maxc) + { + temp = gen_reg_rtx (mode); + emit_insn (func (temp, operands[1], GEN_INT (maxc))); + operands[1] = temp; + count -= maxc; + } + while (count < -maxc) + { + temp = gen_reg_rtx (mode); + emit_insn (func (temp, operands[1], GEN_INT (-maxc))); + operands[1] = temp; + count += maxc; + } + emit_insn (func (operands[0], operands[1], GEN_INT (count))); + return 1; } if (scale < 0) { temp = gen_reg_rtx (QImode); - if (GET_CODE (operands[2]) == CONST_INT) - temp = GEN_INT (-INTVAL (operands[2])); - else - emit_move_insn (temp, gen_rtx_NEG (QImode, operands[2])); + emit_move_insn (temp, gen_rtx_NEG (QImode, operands[2])); } else temp = operands[2]; diff --git a/gcc/config/m32c/predicates.md b/gcc/config/m32c/predicates.md index 0c80e1a..c3b44b8 100644 --- a/gcc/config/m32c/predicates.md +++ b/gcc/config/m32c/predicates.md @@ -145,9 +145,13 @@ ; TRUE if we can shift by this amount. Constant shift counts have a ; limited range. (define_predicate "shiftcount_operand" - (ior (match_operand 0 "m32c_pseudo" "") + (ior (match_operand 0 "mra_operand" "") (and (match_operand 2 "const_int_operand" "") (match_test "-8 <= INTVAL (op) && INTVAL (op) && INTVAL (op) <= 8")))) +(define_predicate "longshiftcount_operand" + (ior (match_operand 0 "mra_operand" "") + (and (match_operand 2 "const_int_operand" "") + (match_test "-32 <= INTVAL (op) && INTVAL (op) && INTVAL (op) <= 32")))) ; TRUE for r0..r3, a0..a1, or sp. (define_predicate "mra_or_sp_operand" diff --git a/gcc/config/m32c/shift.md b/gcc/config/m32c/shift.md index 95b298c..3e07b25 100644 --- a/gcc/config/m32c/shift.md +++ b/gcc/config/m32c/shift.md @@ -33,34 +33,34 @@ (define_insn "ashlqi3_i" [(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm") (ashift:QI (match_operand:QI 1 "mra_operand" "0,0") - (match_operand:QI 2 "mrai_operand" "In4,R1w"))) + (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))) (clobber (match_scratch:HI 3 "=X,R1w"))] "" "@ sha.b\t%2,%0 - mov.b\tr1l,r1h\n\tsha.b\tr1h,%0" + mov.b\t%2,r1h\n\tsha.b\tr1h,%0" ) (define_insn "ashrqi3_i" [(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm") (ashiftrt:QI (match_operand:QI 1 "mra_operand" "0,0") - (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w")))) + (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd")))) (clobber (match_scratch:HI 3 "=X,R1w"))] "" "@ sha.b\t%2,%0 - mov.b\tr1l,r1h\n\tsha.b\tr1h,%0" + mov.b\t%2,r1h\n\tsha.b\tr1h,%0" ) -(define_insn "lshlqi3_i" +(define_insn "lshrqi3_i" [(set (match_operand:QI 0 "mra_operand" "=RqiSd*Rmm,RqiSd*Rmm") (lshiftrt:QI (match_operand:QI 1 "mra_operand" "0,0") - (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w")))) + (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd")))) (clobber (match_scratch:HI 3 "=X,R1w"))] "" "@ shl.b\t%2,%0 - mov.b\tr1l,r1h\n\tshl.b\tr1h,%0" + mov.b\t%2,r1h\n\tshl.b\tr1h,%0" ) @@ -70,7 +70,7 @@ (match_operand:QI 2 "general_operand" ""))) (clobber (match_scratch:HI 3 ""))])] "" - "if (m32c_prepare_shift (operands, 1, 4)) + "if (m32c_prepare_shift (operands, 1, ASHIFT)) DONE;" ) @@ -80,7 +80,7 @@ (neg:QI (match_operand:QI 2 "general_operand" "")))) (clobber (match_scratch:HI 3 ""))])] "" - "if (m32c_prepare_shift (operands, -1, 4)) + "if (m32c_prepare_shift (operands, -1, ASHIFTRT)) DONE;" ) @@ -90,7 +90,7 @@ (neg:QI (match_operand:QI 2 "general_operand" "")))) (clobber (match_scratch:HI 3 ""))])] "" - "if (m32c_prepare_shift (operands, -1, 4)) + "if (m32c_prepare_shift (operands, -1, LSHIFTRT)) DONE;" ) @@ -99,34 +99,34 @@ (define_insn "ashlhi3_i" [(set (match_operand:HI 0 "mra_operand" "=SdRhi*Rmm,SdRhi*Rmm") (ashift:HI (match_operand:HI 1 "mra_operand" "0,0") - (match_operand:QI 2 "mrai_operand" "In4,R1w"))) + (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))) (clobber (match_scratch:HI 3 "=X,R1w"))] "" "@ sha.w\t%2,%0 - mov.b\tr1l,r1h\n\tsha.w\tr1h,%0" + mov.b\t%2,r1h\n\tsha.w\tr1h,%0" ) (define_insn "ashrhi3_i" [(set (match_operand:HI 0 "mra_operand" "=SdRhi*Rmm,SdRhi*Rmm") (ashiftrt:HI (match_operand:HI 1 "mra_operand" "0,0") - (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w")))) + (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd")))) (clobber (match_scratch:HI 3 "=X,R1w"))] "" "@ sha.w\t%2,%0 - mov.b\tr1l,r1h\n\tsha.w\tr1h,%0" + mov.b\t%2,r1h\n\tsha.w\tr1h,%0" ) -(define_insn "lshlhi3_i" +(define_insn "lshrhi3_i" [(set (match_operand:HI 0 "mra_operand" "=RhiSd*Rmm,RhiSd*Rmm") (lshiftrt:HI (match_operand:HI 1 "mra_operand" "0,0") - (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w")))) + (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd")))) (clobber (match_scratch:HI 3 "=X,R1w"))] "" "@ shl.w\t%2,%0 - mov.b\tr1l,r1h\n\tshl.w\tr1h,%0" + mov.b\t%2,r1h\n\tshl.w\tr1h,%0" ) @@ -136,7 +136,7 @@ (match_operand:QI 2 "general_operand" ""))) (clobber (match_scratch:HI 3 ""))])] "" - "if (m32c_prepare_shift (operands, 1, 4)) + "if (m32c_prepare_shift (operands, 1, ASHIFT)) DONE;" ) @@ -146,7 +146,7 @@ (neg:QI (match_operand:QI 2 "general_operand" "")))) (clobber (match_scratch:HI 3 ""))])] "" - "if (m32c_prepare_shift (operands, -1, 4)) + "if (m32c_prepare_shift (operands, -1, ASHIFTRT)) DONE;" ) @@ -156,7 +156,7 @@ (neg:QI (match_operand:QI 2 "general_operand" "")))) (clobber (match_scratch:HI 3 ""))])] "" - "if (m32c_prepare_shift (operands, -1, 4)) + "if (m32c_prepare_shift (operands, -1, LSHIFTRT)) DONE;" ) @@ -169,34 +169,34 @@ (define_insn "ashlpsi3_i" [(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd*Rmm,R02RaaSd*Rmm") (ashift:PSI (match_operand:PSI 1 "mra_operand" "0,0") - (match_operand:QI 2 "mrai_operand" "In4,R1w"))) + (match_operand:QI 2 "mrai_operand" "In4,RqiSd"))) (clobber (match_scratch:HI 3 "=X,R1w"))] "TARGET_A24" "@ sha.l\t%2,%0 - mov.b\tr1l,r1h\n\tsha.l\tr1h,%0" + mov.b\t%2,r1h\n\tsha.l\tr1h,%0" ) (define_insn "ashrpsi3_i" [(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd*Rmm,R02RaaSd*Rmm") (ashiftrt:PSI (match_operand:PSI 1 "mra_operand" "0,0") - (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w")))) + (neg:QI (match_operand:QI 2 "mrai_operand" "In4,RqiSd")))) (clobber (match_scratch:HI 3 "=X,R1w"))] "TARGET_A24" "@ sha.l\t%2,%0 - mov.b\tr1l,r1h\n\tsha.l\tr1h,%0" + mov.b\t%2,r1h\n\tsha.l\tr1h,%0" ) -(define_insn "lshlpsi3_i" +(define_insn "lshrpsi3_i" [(set (match_operand:PSI 0 "mra_operand" "=R02RaaSd,??Rmm") (lshiftrt:PSI (match_operand:PSI 1 "mra_operand" "0,0") - (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,R1w")))) + (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd")))) (clobber (match_scratch:HI 3 "=X,R1w"))] "TARGET_A24" "@ shl.l\t%2,%0 - mov.b\tr1l,r1h\n\tshl.l\tr1h,%0" + mov.b\t%2,r1h\n\tshl.l\tr1h,%0" ) @@ -206,7 +206,7 @@ (match_operand:QI 2 "mrai_operand" ""))) (clobber (match_scratch:HI 3 ""))])] "TARGET_A24" - "if (m32c_prepare_shift (operands, 1, 4)) + "if (m32c_prepare_shift (operands, 1, ASHIFT)) DONE;" ) @@ -216,7 +216,7 @@ (neg:QI (match_operand:QI 2 "mrai_operand" "")))) (clobber (match_scratch:HI 3 ""))])] "TARGET_A24" - "if (m32c_prepare_shift (operands, -1, 4)) + "if (m32c_prepare_shift (operands, -1, ASHIFTRT)) DONE;" ) @@ -226,55 +226,98 @@ (neg:QI (match_operand:QI 2 "mrai_operand" "")))) (clobber (match_scratch:HI 3 ""))])] "TARGET_A24" - "if (m32c_prepare_shift (operands, -1, 4)) + "if (m32c_prepare_shift (operands, -1, LSHIFTRT)) DONE;" ) ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +; The m16c has a maximum shift count of -16..16, even when in a +; register. It's optimal to use multiple shifts of -8..8 rather than +; loading larger constants into R1H multiple time. The m32c can shift +; -32..32 either via immediates or in registers. Hence, separate +; patterns. -(define_insn "ashlsi3_i" +(define_insn "ashlsi3_16" [(set (match_operand:SI 0 "r0123_operand" "=R03,R03") (ashift:SI (match_operand:SI 1 "r0123_operand" "0,0") - (match_operand:QI 2 "mrai_operand" "In4,R1w"))) + (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd"))) (clobber (match_scratch:HI 3 "=X,R1w"))] - "" + "TARGET_A16" "@ sha.l\t%2,%0 - mov.b\tr1l,r1h\n\tsha.l\tr1h,%0" + mov.b\t%2,r1h\n\tsha.l\tr1h,%0" + [(set_attr "flags" "sz,sz")] ) -(define_insn "ashrsi3_i" +(define_insn "ashrsi3_16" [(set (match_operand:SI 0 "r0123_operand" "=R03,R03") (ashiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0") - (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w")))) + (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd")))) (clobber (match_scratch:HI 3 "=X,R1w"))] - "" + "TARGET_A16" "@ sha.l\t%2,%0 - mov.b\tr1l,r1h\n\tsha.l\tr1h,%0" + mov.b\t%2,r1h\n\tsha.l\tr1h,%0" ) -(define_insn "lshlsi3_i" +(define_insn "lshrsi3_16" [(set (match_operand:SI 0 "r0123_operand" "=R03,R03") (lshiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0") - (neg:QI (match_operand:QI 2 "mrai_operand" "In4,R1w")))) + (neg:QI (match_operand:QI 2 "shiftcount_operand" "In4,RqiSd")))) (clobber (match_scratch:HI 3 "=X,R1w"))] - "" + "TARGET_A16" "@ shl.l\t%2,%0 - mov.b\tr1l,r1h\n\tshl.l\tr1h,%0" + mov.b\t%2,r1h\n\tshl.l\tr1h,%0" + ) + + + +(define_insn "ashlsi3_24" + [(set (match_operand:SI 0 "r0123_operand" "=R03,R03") + (ashift:SI (match_operand:SI 1 "r0123_operand" "0,0") + (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd"))) + (clobber (match_scratch:HI 3 "=X,R1w"))] + "TARGET_A24" + "@ + sha.l\t%2,%0 + mov.b\t%2,r1h\n\tsha.l\tr1h,%0" ) +(define_insn "ashrsi3_24" + [(set (match_operand:SI 0 "r0123_operand" "=R03,R03") + (ashiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0") + (neg:QI (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd")))) + (clobber (match_scratch:HI 3 "=X,R1w"))] + "TARGET_A24" + "@ + sha.l\t%2,%0 + mov.b\t%2,r1h\n\tsha.l\tr1h,%0" + ) + +(define_insn "lshrsi3_24" + [(set (match_operand:SI 0 "r0123_operand" "=R03,R03") + (lshiftrt:SI (match_operand:SI 1 "r0123_operand" "0,0") + (neg:QI (match_operand:QI 2 "longshiftcount_operand" "In6,RqiSd")))) + (clobber (match_scratch:HI 3 "=X,R1w"))] + "TARGET_A24" + "@ + shl.l\t%2,%0 + mov.b\t%2,r1h\n\tshl.l\tr1h,%0" + ) + + + (define_expand "ashlsi3" [(parallel [(set (match_operand:SI 0 "r0123_operand" "") - (ashift:SI (match_operand:SI 1 "r0123_operand" "") - (match_operand:QI 2 "mrai_operand" ""))) + (ashift:SI (match_operand:SI 1 "r0123_operand" "") + (match_operand:QI 2 "mrai_operand" ""))) (clobber (match_scratch:HI 3 ""))])] "" - "if (m32c_prepare_shift (operands, 1, 4)) + "if (m32c_prepare_shift (operands, 1, ASHIFT)) DONE;" ) @@ -284,7 +327,7 @@ (neg:QI (match_operand:QI 2 "mrai_operand" "")))) (clobber (match_scratch:HI 3 ""))])] "" - "if (m32c_prepare_shift (operands, -1, 4)) + "if (m32c_prepare_shift (operands, -1, ASHIFTRT)) DONE;" ) @@ -294,6 +337,6 @@ (neg:QI (match_operand:QI 2 "mrai_operand" "")))) (clobber (match_scratch:HI 3 ""))])] "" - "if (m32c_prepare_shift (operands, -1, 5)) + "if (m32c_prepare_shift (operands, -1, LSHIFTRT)) DONE;" ) diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi index cce838d..90efcc3 100644 --- a/gcc/doc/md.texi +++ b/gcc/doc/md.texi @@ -2323,8 +2323,8 @@ Used to match function return values. @item In5 -16 @dots{} -1 or 1 @dots{} 16 -@item In4 --8 @dots{} -1 or 1 @dots{} 8 +@item In6 +-32 @dots{} -1 or 1 @dots{} 32 @item IM2 -65536 @dots{} -1 |