diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 34696c61235..405b081e432 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2003-02-19 Kazu Hirata + + * config/h8300/h8300-protos.h: Update the prototype for + split_adds_subs. Remove the prototypes for + const_int_le_2_operand and const_int_le_6_operand. + * config/h8300/h8300.c (split_adds_sub): Don't output inc/dec. + (const_int_le_2_operand): Remove. + (const_int_le_6_operand): Likewise. + * config/h8300/h8300.h (PREDICATE_CODES): Remove the entries + for const_int_le_2_operand and const_int_le_6_operand. + * config/h8300/h8300.md: Update all uses of split_adds_subs. + (a peephole2): New. + Tue Feb 18 23:50:59 CET 2003 Jan Hubicka * cgraph.c (NPREDECESORC, SET_NPREDECESORS): Kill. diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h index b65f3f4ab8b..6c2fe68a422 100644 --- a/gcc/config/h8300/h8300-protos.h +++ b/gcc/config/h8300/h8300-protos.h @@ -47,7 +47,7 @@ extern int h8300_shift_needs_scratch_p PARAMS ((int, enum machine_mode)); extern int expand_a_rotate PARAMS ((enum rtx_code, rtx[])); extern int fix_bit_operand PARAMS ((rtx *, int, enum rtx_code)); extern int h8300_adjust_insn_length PARAMS ((rtx, int)); -extern void split_adds_subs PARAMS ((enum machine_mode, rtx[], int)); +extern void split_adds_subs PARAMS ((enum machine_mode, rtx[])); extern int general_operand_src PARAMS ((rtx, enum machine_mode)); extern int general_operand_dst PARAMS ((rtx, enum machine_mode)); @@ -60,8 +60,6 @@ extern int jump_address_operand PARAMS ((rtx, enum machine_mode)); extern int bit_operand PARAMS ((rtx, enum machine_mode)); extern int bit_memory_operand PARAMS ((rtx, enum machine_mode)); extern int stack_pointer_operand PARAMS ((rtx, enum machine_mode)); -extern int const_int_le_2_operand PARAMS ((rtx, enum machine_mode)); -extern int const_int_le_6_operand PARAMS ((rtx, enum machine_mode)); extern int const_int_gt_2_operand PARAMS ((rtx, enum machine_mode)); extern int const_int_ge_8_operand PARAMS ((rtx, enum machine_mode)); extern int const_int_qi_operand PARAMS ((rtx, enum machine_mode)); diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index e8de91dd08e..173946cbc72 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -865,17 +865,15 @@ two_insn_adds_subs_operand (op, mode) instead of adds/subs. */ void -split_adds_subs (mode, operands, use_incdec_p) +split_adds_subs (mode, operands) enum machine_mode mode; rtx *operands; - int use_incdec_p; { HOST_WIDE_INT val = INTVAL (operands[1]); rtx reg = operands[0]; HOST_WIDE_INT sign = 1; HOST_WIDE_INT amount; - rtx (*gen_last) (rtx, rtx, rtx); - rtx (*gen_normal) (rtx, rtx, rtx); + rtx (*gen_add) (rtx, rtx, rtx); /* Force VAL to be positive so that we do not have to consider the sign. */ @@ -888,13 +886,11 @@ split_adds_subs (mode, operands, use_incdec_p) switch (mode) { case HImode: - gen_normal = gen_addhi3; - gen_last = gen_addhi3_incdec; + gen_add = gen_addhi3; break; case SImode: - gen_normal = gen_addsi3; - gen_last = gen_addsi3_incdec; + gen_add = gen_addsi3; break; default: @@ -907,13 +903,7 @@ split_adds_subs (mode, operands, use_incdec_p) amount /= 2) { for (; val >= amount; val -= amount) - { - /* If requested, generate the last insn using inc/dec. */ - if (use_incdec_p && amount <= 2 && val == amount) - emit_insn (gen_last (reg, reg, GEN_INT (sign * amount))); - else - emit_insn (gen_normal (reg, reg, GEN_INT (sign * amount))); - } + emit_insn (gen_add (reg, reg, GEN_INT (sign * amount))); } return; @@ -1835,30 +1825,6 @@ stack_pointer_operand (x, mode) return x == stack_pointer_rtx; } -/* Return nonzero if X is a constant whose absolute value is no - greater than 2. */ - -int -const_int_le_2_operand (x, mode) - rtx x; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (x) == CONST_INT - && abs (INTVAL (x)) <= 2); -} - -/* Return nonzero if X is a constant whose absolute value is no - greater than 6. */ - -int -const_int_le_6_operand (x, mode) - rtx x; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - return (GET_CODE (x) == CONST_INT - && abs (INTVAL (x)) <= 6); -} - /* Return nonzero if X is a constant whose absolute value is greater than 2. */ diff --git a/gcc/config/h8300/h8300.h b/gcc/config/h8300/h8300.h index 333101059a7..0c408145191 100644 --- a/gcc/config/h8300/h8300.h +++ b/gcc/config/h8300/h8300.h @@ -1284,8 +1284,6 @@ struct cum_arg {"bit_operand", {REG, SUBREG, MEM}}, \ {"bit_memory_operand", {MEM}}, \ {"stack_pointer_operand", {REG}}, \ - {"const_int_le_2_operand", {CONST_INT}}, \ - {"const_int_le_6_operand", {CONST_INT}}, \ {"const_int_gt_2_operand", {CONST_INT}}, \ {"const_int_ge_8_operand", {CONST_INT}}, \ {"const_int_qi_operand", {CONST_INT}}, \ diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index 011a949dc81..817b52d6f64 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -798,7 +798,7 @@ (match_operand 1 "const_int_gt_2_operand" "")))] "TARGET_H8300 && flow2_completed" [(const_int 0)] - "split_adds_subs (HImode, operands, 0); DONE;") + "split_adds_subs (HImode, operands); DONE;") (define_peephole2 [(match_scratch:HI 2 "r") @@ -845,7 +845,7 @@ (match_operand:HI 1 "two_insn_adds_subs_operand" "")))] "" [(const_int 0)] - "split_adds_subs (HImode, operands, 0); DONE;") + "split_adds_subs (HImode, operands); DONE;") (define_expand "addsi3" [(set (match_operand:SI 0 "register_operand" "") @@ -894,7 +894,7 @@ (match_operand:SI 1 "two_insn_adds_subs_operand" "")))] "TARGET_H8300H || TARGET_H8300S" [(const_int 0)] - "split_adds_subs (SImode, operands, 0); DONE;") + "split_adds_subs (SImode, operands); DONE;") ;; ---------------------------------------------------------------------- ;; SUBTRACT INSTRUCTIONS @@ -3447,34 +3447,39 @@ "") ;; (compare (reg:SI) (const_int)) takes 6 bytes, so we try to achieve -;; the equivalent with shorter sequences. Here is the summary. +;; the equivalent with shorter sequences. Here is the summary. Cases +;; are grouped for each define_peephole2. ;; -;; reg const_int use insn -;; live -2 eq/ne copy and inc.l -;; live -1 eq/ne copy and inc.l -;; live 1 eq/ne copy and dec.l -;; live 2 eq/ne copy and dec.l -;; dead -6 eq/ne adds and inc.l -;; dead -5 eq/ne adds and inc.l -;; dead -4 eq/ne adds and test -;; dead -3 eq/ne adds and inc.l -;; dead -2 eq/ne inc.l -;; dead -1 eq/ne inc.l -;; dead 1 eq/ne dec.l -;; dead 2 eq/ne dec.l -;; dead 0x000000?? except 1 and 2 eq/ne xor.b and test -;; dead 0x0000??00 eq/ne xor.b and test -;; dead 0x0000ffff eq/ne not.w and test -;; dead 0xffff0000 eq/ne not.w and test -;; dead 1 geu/ltu and.b and test -;; dead 3 geu/ltu and.b and test -;; dead 7 geu/ltu and.b and test -;; dead 15 geu/ltu and.b and test -;; dead 31 geu/ltu and.b and test -;; dead 63 geu/ltu and.b and test -;; dead 127 geu/ltu and.b and test -;; dead 255 geu/ltu and.b and test -;; dead 65535 geu/ltu mov.w +;; reg const_int use insn +;; -------------------------------------------------------- +;; live -2 eq/ne copy and inc.l +;; live -1 eq/ne copy and inc.l +;; live 1 eq/ne copy and dec.l +;; live 2 eq/ne copy and dec.l +;; +;; dead -2 eq/ne inc.l +;; dead -1 eq/ne inc.l +;; dead 1 eq/ne dec.l +;; dead 2 eq/ne dec.l +;; +;; dead 0x000000?? except 1 and 2 eq/ne xor.b and test +;; dead 0x0000??00 eq/ne xor.b and test +;; dead 0x0000ffff eq/ne not.w and test +;; dead 0xffff0000 eq/ne not.w and test +;; +;; dead 0xffffff?? except -1 and -2 eq/ne xor.b and not.l +;; dead 0xffff??ff eq/ne xor.b and not.l +;; +;; dead 1 geu/ltu and.b and test +;; dead 3 geu/ltu and.b and test +;; dead 7 geu/ltu and.b and test +;; dead 15 geu/ltu and.b and test +;; dead 31 geu/ltu and.b and test +;; dead 63 geu/ltu and.b and test +;; dead 127 geu/ltu and.b and test +;; dead 255 geu/ltu and.b and test +;; +;; dead 65535 geu/ltu mov.w ;; For a small constant, it is cheaper to actually do the subtraction ;; and then test the register. @@ -3482,7 +3487,7 @@ (define_peephole2 [(set (cc0) (compare (match_operand:HI 0 "register_operand" "") - (match_operand:HI 1 "const_int_le_2_operand" ""))) + (match_operand:HI 1 "incdec_operand" ""))) (set (pc) (if_then_else (match_operator 3 "eqne_operator" [(cc0) (const_int 0)]) @@ -3490,21 +3495,24 @@ (pc)))] "(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0])" - [(set (cc0) + [(set (match_dup 0) + (unspec:HI [(match_dup 0) + (match_dup 4)] + UNSPEC_INCDEC)) + (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] - "operands[1] = GEN_INT (- INTVAL (operands[1])); - split_adds_subs (HImode, operands, 1);") + "operands[4] = GEN_INT (- INTVAL (operands[1]));") ;; The SImode version of the previous pattern. (define_peephole2 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "const_int_le_6_operand" ""))) + (match_operand:SI 1 "incdec_operand" ""))) (set (pc) (if_then_else (match_operator 3 "eqne_operator" [(cc0) (const_int 0)]) @@ -3512,14 +3520,17 @@ (pc)))] "(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0])" - [(set (cc0) + [(set (match_dup 0) + (unspec:SI [(match_dup 0) + (match_dup 4)] + UNSPEC_INCDEC)) + (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] - "operands[1] = GEN_INT (- INTVAL (operands[1])); - split_adds_subs (SImode, operands, 1);") + "operands[4] = GEN_INT (- INTVAL (operands[1]));") ;; For certain (in)equaltity comparisions against a constant, we can ;; XOR the register with the constant, and test the register against @@ -3553,6 +3564,34 @@ (pc)))] "") +(define_peephole2 + [(set (cc0) + (compare (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "const_int_operand" ""))) + (set (pc) + (if_then_else (match_operator 3 "eqne_operator" + [(cc0) (const_int 0)]) + (label_ref (match_operand 2 "" "")) + (pc)))] + "(TARGET_H8300H || TARGET_H8300S) + && peep2_reg_dead_p (1, operands[0]) + && ((INTVAL (operands[1]) | 0x00ff) == -1 + || (INTVAL (operands[1]) | 0xff00) == -1) + && INTVAL (operands[1]) != -1 + && INTVAL (operands[1]) != -2" + [(set (match_dup 0) + (xor:SI (match_dup 0) + (match_dup 4))) + (set (match_dup 0) + (not:SI (match_dup 0))) + (set (cc0) + (match_dup 0)) + (set (pc) + (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) + (label_ref (match_dup 2)) + (pc)))] + "operands[4] = GEN_INT (INTVAL (operands[1]) ^ -1);") + ;; Transform A <= 1 to (A & 0xfffffffe) == 0. (define_peephole2 @@ -3653,16 +3692,19 @@ && !peep2_reg_dead_p (1, operands[0]) && !rtx_equal_p (PATTERN (insn), PATTERN (next_nonnote_insn (next_nonnote_insn (insn))))" - [(set (cc0) + [(set (match_dup 4) (match_dup 0)) + (set (match_dup 4) + (unspec:SI [(match_dup 4) + (match_dup 5)] + UNSPEC_INCDEC)) + (set (cc0) + (match_dup 4)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] - "emit_move_insn (operands[4], operands[0]); - operands[0] = operands[4]; - operands[1] = GEN_INT (- INTVAL (operands[1])); - split_adds_subs (SImode, operands, 1);") + "operands[5] = GEN_INT (- INTVAL (operands[1]));") ;; Narrow the mode of testing if possible.