diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a4131703fc2..3bef7cd98ca 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2002-02-26 Kazu Hirata + + * config/h8300/h8300-protos.h: Update the prototype for + compute_logical_op_length. Add the prototype for + compute_logical_op_cc. + * config/h8300/h8300.c (compute_logical_op_length): Figure out + code from operands. + (compute_logical_op_cc): New. + * config/h8300/h8300.md: Combine all the logical op patterns + in HImode and SImode. Use compute_logical_op_cc. + 2002-02-26 Kelley Cook * config/i386/i386.c (print_operand): Don't append ATT-style diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h index cebcb5b4f25..e930d5ec0dd 100644 --- a/gcc/config/h8300/h8300-protos.h +++ b/gcc/config/h8300/h8300-protos.h @@ -35,9 +35,10 @@ extern void print_operand PARAMS ((FILE *, rtx, int)); extern void final_prescan_insn PARAMS ((rtx, rtx *, int)); extern int do_movsi PARAMS ((rtx[])); extern void notice_update_cc PARAMS ((rtx, rtx)); -extern const char *output_logical_op PARAMS ((enum machine_mode, int, rtx *)); +extern const char *output_logical_op PARAMS ((enum machine_mode, rtx *)); extern unsigned int compute_logical_op_length PARAMS ((enum machine_mode, - enum rtx_code, rtx *)); + rtx *)); +extern int compute_logical_op_cc PARAMS ((enum machine_mode, rtx *)); extern int expand_a_shift PARAMS ((enum machine_mode, int, rtx[])); extern int expand_a_rotate PARAMS ((enum rtx_code, rtx[])); extern int fix_bit_operand PARAMS ((rtx *, int, enum rtx_code)); diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c index d09068cfd8b..1e997c885d7 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -1487,11 +1487,12 @@ bit_operator (x, mode) } const char * -output_logical_op (mode, code, operands) +output_logical_op (mode, operands) enum machine_mode mode; - int code; rtx *operands; { + /* Figure out the logical op that we need to perform. */ + enum rtx_code code = GET_CODE (operands[3]); /* Pretend that every byte is affected if both operands are registers. */ unsigned HOST_WIDE_INT intval = (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT) @@ -1629,11 +1630,12 @@ output_logical_op (mode, code, operands) } unsigned int -compute_logical_op_length (mode, code, operands) +compute_logical_op_length (mode, operands) enum machine_mode mode; - enum rtx_code code; rtx *operands; { + /* Figure out the logical op that we need to perform. */ + enum rtx_code code = GET_CODE (operands[3]); /* Pretend that every byte is affected if both operands are registers. */ unsigned HOST_WIDE_INT intval = (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT) @@ -1738,6 +1740,55 @@ compute_logical_op_length (mode, code, operands) } return length; } + +int +compute_logical_op_cc (mode, operands) + enum machine_mode mode; + rtx *operands; +{ + /* Figure out the logical op that we need to perform. */ + enum rtx_code code = GET_CODE (operands[3]); + /* Pretend that every byte is affected if both operands are registers. */ + unsigned HOST_WIDE_INT intval = + (unsigned HOST_WIDE_INT) ((GET_CODE (operands[2]) == CONST_INT) + ? INTVAL (operands[2]) : 0x55555555); + /* The determinant of the algorithm. If we perform an AND, 0 + affects a bit. Otherwise, 1 affects a bit. */ + unsigned HOST_WIDE_INT det = (code != AND) ? intval : ~intval; + /* Condition code. */ + enum attr_cc cc = CC_CLOBBER; + + switch (mode) + { + case HImode: + /* First, see if we can finish with one insn. */ + if ((TARGET_H8300H || TARGET_H8300S) + && ((det & 0x00ff) != 0) + && ((det & 0xff00) != 0)) + { + cc = CC_SET_ZNV; + } + break; + case SImode: + /* First, see if we can finish with one insn. + + If code is either AND or XOR, we exclude two special cases, + 0xffffff00 and 0xffff00ff, because insns like sub.w or not.w + can do a better job. */ + if ((TARGET_H8300H || TARGET_H8300S) + && ((det & 0x0000ffff) != 0) + && ((det & 0xffff0000) != 0) + && (code == IOR || det != 0xffffff00) + && (code == IOR || det != 0xffff00ff)) + { + cc = CC_SET_ZNV; + } + break; + default: + abort (); + } + return cc; +} /* Shifts. diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index a711d2985d8..b17d5557944 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -1033,26 +1033,6 @@ "" "") -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (and:HI (match_operand:HI 1 "register_operand" "%0") - (match_operand:HI 2 "nonmemory_operand" "rn")))] - "TARGET_H8300" - "* return output_logical_op (HImode, AND, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (HImode, AND, operands)")) - (set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (and:HI (match_operand:HI 1 "register_operand" "%0,0") - (match_operand:HI 2 "nonmemory_operand" "r,n")))] - "TARGET_H8300H || TARGET_H8300S" - "* return output_logical_op (HImode, AND, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (HImode, AND, operands)")) - (set_attr "cc" "set_znv,clobber")]) - (define_insn "*andorhi3" [(set (match_operand:HI 0 "register_operand" "=r") (ior:HI (and:HI (match_operand:HI 2 "register_operand" "r") @@ -1079,26 +1059,6 @@ "" "") -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (and:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "nonmemory_operand" "rn")))] - "TARGET_H8300" - "* return output_logical_op (SImode, AND, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (SImode, AND, operands)")) - (set_attr "cc" "clobber")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (and:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "r,n")))] - "TARGET_H8300H || TARGET_H8300S" - "* return output_logical_op (SImode, AND, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (SImode, AND, operands)")) - (set_attr "cc" "set_znv,clobber")]) - ;; ---------------------------------------------------------------------- ;; OR INSTRUCTIONS ;; ---------------------------------------------------------------------- @@ -1145,26 +1105,6 @@ "" "") -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=r,r") - (ior:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "J,rn")))] - "TARGET_H8300" - "* return output_logical_op (HImode, IOR, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (HImode, IOR, operands)")) - (set_attr "cc" "clobber,clobber")]) - -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=r,r,r") - (ior:HI (match_operand:HI 1 "general_operand" "%0,0,0") - (match_operand:HI 2 "general_operand" "J,r,n")))] - "TARGET_H8300H || TARGET_H8300S" - "* return output_logical_op (HImode, IOR, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (HImode, IOR, operands)")) - (set_attr "cc" "clobber,set_znv,clobber")]) - (define_expand "iorsi3" [(set (match_operand:SI 0 "register_operand" "") (ior:SI (match_operand:SI 1 "register_operand" "") @@ -1172,26 +1112,6 @@ "" "") -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (ior:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "J,rn")))] - "TARGET_H8300" - "* return output_logical_op (SImode, IOR, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (SImode, IOR, operands)")) - (set_attr "cc" "clobber,clobber")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (ior:SI (match_operand:SI 1 "register_operand" "%0,0,0") - (match_operand:SI 2 "nonmemory_operand" "J,r,n")))] - "TARGET_H8300H || TARGET_H8300S" - "* return output_logical_op (SImode, IOR, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (SImode, IOR, operands)")) - (set_attr "cc" "clobber,set_znv,clobber")]) - ;; ---------------------------------------------------------------------- ;; XOR INSTRUCTIONS ;; ---------------------------------------------------------------------- @@ -1238,26 +1158,6 @@ "" "") -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (xor:HI (match_operand:HI 1 "register_operand" "%0,0") - (match_operand:HI 2 "nonmemory_operand" "J,rn")))] - "TARGET_H8300" - "* return output_logical_op (HImode, XOR, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (HImode, XOR, operands)")) - (set_attr "cc" "clobber,clobber")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r,r,r") - (xor:HI (match_operand:HI 1 "register_operand" "%0,0,0") - (match_operand:HI 2 "nonmemory_operand" "J,r,n")))] - "TARGET_H8300H || TARGET_H8300S" - "* return output_logical_op (HImode, XOR, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (HImode, XOR, operands)")) - (set_attr "cc" "clobber,set_znv,clobber")]) - (define_expand "xorsi3" [(set (match_operand:SI 0 "register_operand" "") (xor:SI (match_operand:SI 1 "register_operand" "") @@ -1265,25 +1165,33 @@ "" "") -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (xor:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "J,rn")))] - "TARGET_H8300" - "* return output_logical_op (SImode, XOR, operands);" - [(set (attr "length") - (symbol_ref "compute_logical_op_length (SImode, XOR, operands)")) - (set_attr "cc" "clobber,clobber")]) +;; ---------------------------------------------------------------------- +;; {AND,IOR,XOR}{HI3,SI3} PATTERNS +;; ---------------------------------------------------------------------- (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (xor:SI (match_operand:SI 1 "register_operand" "%0,0,0") - (match_operand:SI 2 "nonmemory_operand" "J,r,n")))] - "TARGET_H8300H || TARGET_H8300S" - "* return output_logical_op (SImode, XOR, operands);" + [(set (match_operand:HI 0 "register_operand" "=r") + (match_operator:HI 3 "bit_operator" + [(match_operand:HI 1 "register_operand" "%0") + (match_operand:HI 2 "nonmemory_operand" "rn")]))] + "" + "* return output_logical_op (HImode, operands);" [(set (attr "length") - (symbol_ref "compute_logical_op_length (SImode, XOR, operands)")) - (set_attr "cc" "clobber,set_znv,clobber")]) + (symbol_ref "compute_logical_op_length (HImode, operands)")) + (set (attr "cc") + (symbol_ref "compute_logical_op_cc (HImode, operands)"))]) + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (match_operator:SI 3 "bit_operator" + [(match_operand:SI 1 "register_operand" "%0") + (match_operand:SI 2 "nonmemory_operand" "rn")]))] + "" + "* return output_logical_op (SImode, operands);" + [(set (attr "length") + (symbol_ref "compute_logical_op_length (SImode, operands)")) + (set (attr "cc") + (symbol_ref "compute_logical_op_cc (SImode, operands)"))]) ;; ---------------------------------------------------------------------- ;; NEGATION INSTRUCTIONS