diff options
author | Kazu Hirata <kazu@cs.umass.edu> | 2003-04-04 22:01:46 +0000 |
---|---|---|
committer | Kazu Hirata <kazu@gcc.gnu.org> | 2003-04-04 22:01:46 +0000 |
commit | 45ca21065864f404f5bb27b7ecf43a40b8efbda0 (patch) | |
tree | 6fe49cbd2890fa089a4111686cf08c87ce19fc69 | |
parent | 7c2aa9d72cc0a0d39c44206f86ffca8f9f2c66bd (diff) | |
download | gcc-45ca21065864f404f5bb27b7ecf43a40b8efbda0.zip gcc-45ca21065864f404f5bb27b7ecf43a40b8efbda0.tar.gz gcc-45ca21065864f404f5bb27b7ecf43a40b8efbda0.tar.bz2 |
h8300-protos.h: Add a prototype for compute_a_shift_cc.
* config/h8300/h8300-protos.h: Add a prototype for
compute_a_shift_cc.
* config/h8300/h8300.c (shift_one): Update the CC status.
(shift_two): Likewise.
(output_a_shift_cc): Set cc_inline and cc_special.
(compute_a_shift_cc): New.
* config/h8300/h8300.md (shift insns): Use compute_a_shift_cc.
From-SVN: r65251
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/h8300/h8300-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.c | 206 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.md | 9 |
4 files changed, 178 insertions, 48 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 923d437..01a858b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2003-04-04 Kazu Hirata <kazu@cs.umass.edu> + + * config/h8300/h8300-protos.h: Add a prototype for + compute_a_shift_cc. + * config/h8300/h8300.c (shift_one): Update the CC status. + (shift_two): Likewise. + (output_a_shift_cc): Set cc_inline and cc_special. + (compute_a_shift_cc): New. + * config/h8300/h8300.md (shift insns): Use compute_a_shift_cc. + 2003-04-04 Richard Henderson <rth@redhat.com> * cse.c (fold_rtx): Fix 03-30 change; do check insn non-null. diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h index 55ef2f5..6cdfbee 100644 --- a/gcc/config/h8300/h8300-protos.h +++ b/gcc/config/h8300/h8300-protos.h @@ -31,6 +31,7 @@ extern unsigned int compute_plussi_length PARAMS ((rtx *)); extern int compute_plussi_cc PARAMS ((rtx *)); extern const char *output_a_shift PARAMS ((rtx *)); extern unsigned int compute_a_shift_length PARAMS ((rtx, rtx *)); +extern int compute_a_shift_cc PARAMS ((rtx, rtx *)); extern const char *emit_a_rotate PARAMS ((enum rtx_code, rtx *)); extern const char *output_simode_bld PARAMS ((int, rtx[])); extern void print_operand_address PARAMS ((FILE *, rtx)); diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index 69f0b53..866e6fd 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -2661,42 +2661,42 @@ static const struct shift_insn shift_one[2][3][3] = { /* SHIFT_ASHIFT */ { - { "shll\t%X0", CC_NO_CARRY }, - { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }, - { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 } + { "shll\t%X0", CC_SET_ZNV }, + { "add.w\t%T0,%T0", CC_SET_ZN }, + { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", CC_CLOBBER } }, /* SHIFT_LSHIFTRT */ { - { "shlr\t%X0", CC_NO_CARRY }, - { "shlr\t%t0\n\trotxr\t%s0", 0 }, - { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 } + { "shlr\t%X0", CC_SET_ZNV }, + { "shlr\t%t0\n\trotxr\t%s0", CC_CLOBBER }, + { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER } }, /* SHIFT_ASHIFTRT */ { - { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }, - { "shar\t%t0\n\trotxr\t%s0", 0 }, - { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 } + { "shar\t%X0", CC_SET_ZNV }, + { "shar\t%t0\n\trotxr\t%s0", CC_CLOBBER }, + { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", CC_CLOBBER } } }, /* H8/300H */ { /* SHIFT_ASHIFT */ { - { "shll.b\t%X0", CC_NO_CARRY }, - { "shll.w\t%T0", CC_NO_CARRY }, - { "shll.l\t%S0", CC_NO_CARRY } + { "shll.b\t%X0", CC_SET_ZNV }, + { "shll.w\t%T0", CC_SET_ZNV }, + { "shll.l\t%S0", CC_SET_ZNV } }, /* SHIFT_LSHIFTRT */ { - { "shlr.b\t%X0", CC_NO_CARRY }, - { "shlr.w\t%T0", CC_NO_CARRY }, - { "shlr.l\t%S0", CC_NO_CARRY } + { "shlr.b\t%X0", CC_SET_ZNV }, + { "shlr.w\t%T0", CC_SET_ZNV }, + { "shlr.l\t%S0", CC_SET_ZNV } }, /* SHIFT_ASHIFTRT */ { - { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }, - { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }, - { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY } + { "shar.b\t%X0", CC_SET_ZNV }, + { "shar.w\t%T0", CC_SET_ZNV }, + { "shar.l\t%S0", CC_SET_ZNV } } } }; @@ -2705,21 +2705,21 @@ static const struct shift_insn shift_two[3][3] = { /* SHIFT_ASHIFT */ { - { "shll.b\t#2,%X0", CC_NO_CARRY }, - { "shll.w\t#2,%T0", CC_NO_CARRY }, - { "shll.l\t#2,%S0", CC_NO_CARRY } + { "shll.b\t#2,%X0", CC_SET_ZNV }, + { "shll.w\t#2,%T0", CC_SET_ZNV }, + { "shll.l\t#2,%S0", CC_SET_ZNV } }, /* SHIFT_LSHIFTRT */ { - { "shlr.b\t#2,%X0", CC_NO_CARRY }, - { "shlr.w\t#2,%T0", CC_NO_CARRY }, - { "shlr.l\t#2,%S0", CC_NO_CARRY } + { "shlr.b\t#2,%X0", CC_SET_ZNV }, + { "shlr.w\t#2,%T0", CC_SET_ZNV }, + { "shlr.l\t#2,%S0", CC_SET_ZNV } }, /* SHIFT_ASHIFTRT */ { - { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }, - { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }, - { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY } + { "shar.b\t#2,%X0", CC_SET_ZNV }, + { "shar.w\t#2,%T0", CC_SET_ZNV }, + { "shar.l\t#2,%S0", CC_SET_ZNV } } }; @@ -2814,8 +2814,11 @@ struct shift_info { or SHIFT_SPECIAL, and REMAINDER is nonzero. */ const char *shift2; - /* Valid CC flags. */ - int cc_valid_p; + /* CC status for SHIFT_INLINE. */ + int cc_inline; + + /* CC status for SHIFT_SPECIAL. */ + int cc_special; }; static void get_shift_alg PARAMS ((enum shift_type, @@ -2885,13 +2888,13 @@ get_shift_alg (shift_type, shift_mode, count, info) /* It is up to the caller to know that looping clobbers cc. */ info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler; info->shift2 = shift_two[shift_type][shift_mode].assembler; - info->cc_valid_p = shift_one[cpu_type][shift_type][shift_mode].cc_valid; + info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid; goto end; case SHIFT_ROT_AND: info->shift1 = rotate_one[cpu_type][shift_type][shift_mode]; info->shift2 = rotate_two[shift_type][shift_mode]; - info->cc_valid_p = 0; + info->cc_inline = CC_CLOBBER; goto end; case SHIFT_SPECIAL: @@ -2899,7 +2902,8 @@ get_shift_alg (shift_type, shift_mode, count, info) info->remainder = 0; info->shift1 = shift_one[cpu_type][shift_type][shift_mode].assembler; info->shift2 = shift_two[shift_type][shift_mode].assembler; - info->cc_valid_p = 0; + info->cc_inline = shift_one[cpu_type][shift_type][shift_mode].cc_valid; + info->cc_special = CC_CLOBBER; break; } @@ -2953,10 +2957,12 @@ get_shift_alg (shift_type, shift_mode, count, info) { info->special = "mov.b\t%t0,%s0\n\tsub.b\t%t0,%t0"; info->shift1 = "shlr.b\t%s0"; + info->cc_inline = CC_SET_ZNV; } else { info->special = "mov.b\t%t0,%s0\n\textu.w\t%T0"; + info->cc_special = CC_SET_ZNV; } goto end; case SHIFT_ASHIFTRT: @@ -2968,6 +2974,7 @@ get_shift_alg (shift_type, shift_mode, count, info) else { info->special = "mov.b\t%t0,%s0\n\texts.w\t%T0"; + info->cc_special = CC_SET_ZNV; } goto end; } @@ -2988,7 +2995,10 @@ get_shift_alg (shift_type, shift_mode, count, info) if (TARGET_H8300) info->special = "mov.b\t%t0,%s0\n\tshll.b\t%s0\n\tsubx.b\t%t0,%t0\n\tshll.b\t%s0\n\tmov.b\t%t0,%s0\n\tbst.b\t#0,%s0"; else if (TARGET_H8300H) - info->special = "shll.b\t%t0\n\tsubx.b\t%s0,%s0\n\tshll.b\t%t0\n\trotxl.b\t%s0\n\texts.w\t%T0"; + { + info->special = "shll.b\t%t0\n\tsubx.b\t%s0,%s0\n\tshll.b\t%t0\n\trotxl.b\t%s0\n\texts.w\t%T0"; + info->cc_special = CC_SET_ZNV; + } else /* TARGET_H8300S */ abort (); goto end; @@ -3065,9 +3075,11 @@ get_shift_alg (shift_type, shift_mode, count, info) { case SHIFT_ASHIFT: info->special = "shlr.w\t%e0\n\tmov.w\t%f0,%e0\n\txor.w\t%f0,%f0\n\trotxr.l\t%S0"; + info->cc_special = CC_SET_ZNV; goto end; case SHIFT_LSHIFTRT: info->special = "shll.w\t%f0\n\tmov.w\t%e0,%f0\n\txor.w\t%e0,%e0\n\trotxl.l\t%S0"; + info->cc_special = CC_SET_ZNV; goto end; case SHIFT_ASHIFTRT: abort (); @@ -3095,6 +3107,7 @@ get_shift_alg (shift_type, shift_mode, count, info) else { info->special = "mov.w\t%e0,%f0\n\textu.l\t%S0"; + info->cc_special = CC_SET_ZNV; } goto end; case SHIFT_ASHIFTRT: @@ -3106,6 +3119,7 @@ get_shift_alg (shift_type, shift_mode, count, info) else { info->special = "mov.w\t%e0,%f0\n\texts.l\t%S0"; + info->cc_special = CC_SET_ZNV; } goto end; } @@ -3119,14 +3133,17 @@ get_shift_alg (shift_type, shift_mode, count, info) case SHIFT_ASHIFT: info->special = "mov.b\t%w0,%z0\n\tsub.b\t%y0,%y0\n\tsub.w\t%f0,%f0"; info->shift1 = "shll.b\t%z0"; + info->cc_inline = CC_SET_ZNV; goto end; case SHIFT_LSHIFTRT: info->special = "mov.b\t%z0,%w0\n\tsub.b\t%x0,%x0\n\tsub.w\t%e0,%e0"; info->shift1 = "shlr.b\t%w0"; + info->cc_inline = CC_SET_ZNV; goto end; case SHIFT_ASHIFTRT: info->special = "mov.b\t%z0,%w0\n\tbld\t#7,%w0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0"; info->shift1 = "shar.b\t%w0"; + info->cc_inline = CC_SET_ZNV; goto end; } } @@ -3142,9 +3159,11 @@ get_shift_alg (shift_type, shift_mode, count, info) goto end; case SHIFT_LSHIFTRT: info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\textu.w\t%f0\n\textu.l\t%S0"; + info->cc_special = CC_SET_ZNV; goto end; case SHIFT_ASHIFTRT: info->special = "mov.w\t%e0,%f0\n\tmov.b\t%t0,%s0\n\texts.w\t%f0\n\texts.l\t%S0"; + info->cc_special = CC_SET_ZNV; goto end; } } @@ -3160,7 +3179,10 @@ get_shift_alg (shift_type, shift_mode, count, info) goto end; case SHIFT_LSHIFTRT: if (TARGET_H8300H) - info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0"; + { + info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0"; + info->cc_special = CC_SET_ZNV; + } else info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t#2,%S0\n\textu.l\t%S0"; goto end; @@ -3180,9 +3202,15 @@ get_shift_alg (shift_type, shift_mode, count, info) goto end; case SHIFT_LSHIFTRT: if (TARGET_H8300H) - info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0"; + { + info->special = "sub.w\t%f0,%f0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\trotl.l\t%S0\n\textu.l\t%S0"; + info->cc_special = CC_SET_ZNV; + } else - info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t%S0\n\textu.l\t%S0"; + { + info->special = "sub.w\t%f0,%f0\n\trotl.l\t#2,%S0\n\trotl.l\t%S0\n\textu.l\t%S0"; + info->cc_special = CC_SET_ZNV; + } goto end; case SHIFT_ASHIFTRT: abort (); @@ -3231,12 +3259,15 @@ get_shift_alg (shift_type, shift_mode, count, info) { case SHIFT_ASHIFT: info->special = "shlr.l\t%S0\n\txor.l\t%S0,%S0\n\trotxr.l\t%S0"; + info->cc_special = CC_SET_ZNV; goto end; case SHIFT_LSHIFTRT: info->special = "shll.l\t%S0\n\txor.l\t%S0,%S0\n\trotxl.l\t%S0"; + info->cc_special = CC_SET_ZNV; goto end; case SHIFT_ASHIFTRT: info->special = "shll\t%e0\n\tsubx\t%w0,%w0\n\texts.w\t%T0\n\texts.l\t%S0"; + info->cc_special = CC_SET_ZNV; goto end; } } @@ -3390,13 +3421,6 @@ output_a_shift (operands) /* Now emit one bit shifts for any residual. */ for (; n > 0; n--) output_asm_insn (info.shift1, operands); - - /* Keep track of CC. */ - if (info.cc_valid_p) - { - cc_status.value1 = operands[0]; - cc_status.flags |= info.cc_valid_p; - } return ""; case SHIFT_ROT_AND: @@ -3431,8 +3455,6 @@ output_a_shift (operands) else abort (); - cc_status.value1 = operands[0]; - cc_status.flags |= CC_NO_CARRY; output_asm_insn (insn_buf, operands); return ""; } @@ -3630,6 +3652,100 @@ compute_a_shift_length (insn, operands) } } } + +int +compute_a_shift_cc (insn, operands) + rtx insn ATTRIBUTE_UNUSED; + rtx *operands; +{ + rtx shift = operands[3]; + enum machine_mode mode = GET_MODE (shift); + enum rtx_code code = GET_CODE (shift); + enum shift_type shift_type; + enum shift_mode shift_mode; + struct shift_info info; + + switch (mode) + { + case QImode: + shift_mode = QIshift; + break; + case HImode: + shift_mode = HIshift; + break; + case SImode: + shift_mode = SIshift; + break; + default: + abort (); + } + + switch (code) + { + case ASHIFTRT: + shift_type = SHIFT_ASHIFTRT; + break; + case LSHIFTRT: + shift_type = SHIFT_LSHIFTRT; + break; + case ASHIFT: + shift_type = SHIFT_ASHIFT; + break; + default: + abort (); + } + + if (GET_CODE (operands[2]) != CONST_INT) + { + /* This case must be taken care of by one of the two splitters + that convert a variable shift into a loop. */ + abort (); + } + else + { + int n = INTVAL (operands[2]); + + /* If the count is negative, make it 0. */ + if (n < 0) + n = 0; + /* If the count is too big, truncate it. + ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to + do the intuitive thing. */ + else if ((unsigned int) n > GET_MODE_BITSIZE (mode)) + n = GET_MODE_BITSIZE (mode); + + get_shift_alg (shift_type, shift_mode, n, &info); + + switch (info.alg) + { + case SHIFT_SPECIAL: + if (info.remainder == 0) + return info.cc_special; + + /* Fall through. */ + + case SHIFT_INLINE: + return info.cc_inline; + + case SHIFT_ROT_AND: + /* This case always ends with an and instruction. */ + return CC_SET_ZNV; + + case SHIFT_LOOP: + /* A loop to shift by a "large" constant value. + If we have shift-by-2 insns, use them. */ + if (info.shift2 != NULL) + { + if (n % 2) + return info.cc_inline; + } + return CC_CLOBBER; + + default: + abort (); + } + } +} /* A rotation by a non-constant will cause a loop to be generated, in which a rotation by one bit is used. A rotation by a constant, diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index b27a077..ce20696 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -2272,7 +2272,8 @@ "* return output_a_shift (operands);" [(set (attr "length") (symbol_ref "compute_a_shift_length (insn, operands)")) - (set_attr "cc" "clobber")]) + (set (attr "cc") + (symbol_ref "compute_a_shift_cc (insn, operands)"))]) ;; HI BIT SHIFTS @@ -2307,7 +2308,8 @@ "* return output_a_shift (operands);" [(set (attr "length") (symbol_ref "compute_a_shift_length (insn, operands)")) - (set_attr "cc" "clobber")]) + (set (attr "cc") + (symbol_ref "compute_a_shift_cc (insn, operands)"))]) ;; SI BIT SHIFTS @@ -2342,7 +2344,8 @@ "* return output_a_shift (operands);" [(set (attr "length") (symbol_ref "compute_a_shift_length (insn, operands)")) - (set_attr "cc" "clobber")]) + (set (attr "cc") + (symbol_ref "compute_a_shift_cc (insn, operands)"))]) ;; Split a variable shift into a loop. If the register containing ;; the shift count dies, then we just use that register. |