diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/h8300/h8300-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.c | 111 | ||||
-rw-r--r-- | gcc/config/h8300/h8300.md | 36 |
4 files changed, 145 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c3ab8948805..670aafd4375 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2002-02-26 Kazu Hirata <kazu@hxi.com> + + * config/h8300/h8300-protos.h: Add a prototype for + compute_logical_op_length. + * config/h8300/h8300.c (compute_logical_op_length): New. + * config/h8300/h8300.md (anonymous logical patterns): Use + compute_logical_op_length for length. + 2002-02-26 Aldy Hernandez <aldyh@redhat.com> * dwarf2out.c (modified_type_die): Do not call type_main_variant diff --git a/gcc/config/h8300/h8300-protos.h b/gcc/config/h8300/h8300-protos.h index 5d84a979ee0..cebcb5b4f25 100644 --- a/gcc/config/h8300/h8300-protos.h +++ b/gcc/config/h8300/h8300-protos.h @@ -36,6 +36,8 @@ 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 unsigned int compute_logical_op_length PARAMS ((enum machine_mode, + enum rtx_code, 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 63d5ee2530f..d09068cfd8b 100644 --- a/gcc/config/h8300/h8300.c +++ b/gcc/config/h8300/h8300.c @@ -1627,6 +1627,117 @@ output_logical_op (mode, code, operands) } return ""; } + +unsigned int +compute_logical_op_length (mode, code, operands) + enum machine_mode mode; + enum rtx_code code; + rtx *operands; +{ + /* 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; + /* Insn length. */ + unsigned int length = 0; + + switch (mode) + { + case HImode: + /* First, see if we can finish with one insn. */ + if ((TARGET_H8300H || TARGET_H8300S) + && ((det & 0x00ff) != 0) + && ((det & 0xff00) != 0)) + { + if (REG_P (operands[2])) + length += 2; + else + length += 4; + } + else + { + /* Take care of the lower byte. */ + if ((det & 0x00ff) != 0) + length += 2; + + /* Take care of the upper byte. */ + if ((det & 0xff00) != 0) + length += 2; + } + 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)) + { + if (REG_P (operands[2])) + length += 4; + else + length += 6; + } + else + { + /* Take care of the lower and upper words individually. For + each word, we try different methods in the order of + + 1) the special insn (in case of AND or XOR), + 2) the word-wise insn, and + 3) The byte-wise insn. */ + if ((det & 0x0000ffff) == 0x0000ffff + && (TARGET_H8300 ? (code == AND) : (code != IOR))) + { + length += 2; + } + else if ((TARGET_H8300H || TARGET_H8300S) + && ((det & 0x000000ff) != 0) + && ((det & 0x0000ff00) != 0)) + { + length += 4; + } + else + { + if ((det & 0x000000ff) != 0) + length += 2; + + if ((det & 0x0000ff00) != 0) + length += 2; + } + + if ((det & 0xffff0000) == 0xffff0000 + && (TARGET_H8300 ? (code == AND) : (code != IOR))) + { + length += 2; + } + else if (TARGET_H8300H || TARGET_H8300S) + { + if ((det & 0xffff0000) != 0) + length += 4; + } + else + { + if ((det & 0x00ff0000) != 0) + length += 2; + + if ((det & 0xff000000) != 0) + length += 2; + } + } + break; + default: + abort (); + } + return length; +} /* Shifts. diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md index 51541af4330..a711d2985d8 100644 --- a/gcc/config/h8300/h8300.md +++ b/gcc/config/h8300/h8300.md @@ -1039,7 +1039,8 @@ (match_operand:HI 2 "nonmemory_operand" "rn")))] "TARGET_H8300" "* return output_logical_op (HImode, AND, operands);" - [(set_attr "length" "4") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (HImode, AND, operands)")) (set_attr "cc" "clobber")]) (define_insn "" @@ -1048,7 +1049,8 @@ (match_operand:HI 2 "nonmemory_operand" "r,n")))] "TARGET_H8300H || TARGET_H8300S" "* return output_logical_op (HImode, AND, operands);" - [(set_attr "length" "2,4") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (HImode, AND, operands)")) (set_attr "cc" "set_znv,clobber")]) (define_insn "*andorhi3" @@ -1083,7 +1085,8 @@ (match_operand:SI 2 "nonmemory_operand" "rn")))] "TARGET_H8300" "* return output_logical_op (SImode, AND, operands);" - [(set_attr "length" "8") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (SImode, AND, operands)")) (set_attr "cc" "clobber")]) (define_insn "" @@ -1092,7 +1095,8 @@ (match_operand:SI 2 "nonmemory_operand" "r,n")))] "TARGET_H8300H || TARGET_H8300S" "* return output_logical_op (SImode, AND, operands);" - [(set_attr "length" "4,6") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (SImode, AND, operands)")) (set_attr "cc" "set_znv,clobber")]) ;; ---------------------------------------------------------------------- @@ -1147,7 +1151,8 @@ (match_operand:HI 2 "general_operand" "J,rn")))] "TARGET_H8300" "* return output_logical_op (HImode, IOR, operands);" - [(set_attr "length" "2,4") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (HImode, IOR, operands)")) (set_attr "cc" "clobber,clobber")]) (define_insn "" @@ -1156,7 +1161,8 @@ (match_operand:HI 2 "general_operand" "J,r,n")))] "TARGET_H8300H || TARGET_H8300S" "* return output_logical_op (HImode, IOR, operands);" - [(set_attr "length" "2,2,4") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (HImode, IOR, operands)")) (set_attr "cc" "clobber,set_znv,clobber")]) (define_expand "iorsi3" @@ -1172,7 +1178,8 @@ (match_operand:SI 2 "nonmemory_operand" "J,rn")))] "TARGET_H8300" "* return output_logical_op (SImode, IOR, operands);" - [(set_attr "length" "2,8") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (SImode, IOR, operands)")) (set_attr "cc" "clobber,clobber")]) (define_insn "" @@ -1181,7 +1188,8 @@ (match_operand:SI 2 "nonmemory_operand" "J,r,n")))] "TARGET_H8300H || TARGET_H8300S" "* return output_logical_op (SImode, IOR, operands);" - [(set_attr "length" "2,4,6") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (SImode, IOR, operands)")) (set_attr "cc" "clobber,set_znv,clobber")]) ;; ---------------------------------------------------------------------- @@ -1236,7 +1244,8 @@ (match_operand:HI 2 "nonmemory_operand" "J,rn")))] "TARGET_H8300" "* return output_logical_op (HImode, XOR, operands);" - [(set_attr "length" "2,4") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (HImode, XOR, operands)")) (set_attr "cc" "clobber,clobber")]) (define_insn "" @@ -1245,7 +1254,8 @@ (match_operand:HI 2 "nonmemory_operand" "J,r,n")))] "TARGET_H8300H || TARGET_H8300S" "* return output_logical_op (HImode, XOR, operands);" - [(set_attr "length" "2,2,4") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (HImode, XOR, operands)")) (set_attr "cc" "clobber,set_znv,clobber")]) (define_expand "xorsi3" @@ -1261,7 +1271,8 @@ (match_operand:SI 2 "nonmemory_operand" "J,rn")))] "TARGET_H8300" "* return output_logical_op (SImode, XOR, operands);" - [(set_attr "length" "2,8") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (SImode, XOR, operands)")) (set_attr "cc" "clobber,clobber")]) (define_insn "" @@ -1270,7 +1281,8 @@ (match_operand:SI 2 "nonmemory_operand" "J,r,n")))] "TARGET_H8300H || TARGET_H8300S" "* return output_logical_op (SImode, XOR, operands);" - [(set_attr "length" "2,4,6") + [(set (attr "length") + (symbol_ref "compute_logical_op_length (SImode, XOR, operands)")) (set_attr "cc" "clobber,set_znv,clobber")]) ;; ---------------------------------------------------------------------- |