OSDN Git Service

* config/h8300/h8300-protos.h: Add a prototype for
authorkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Feb 2002 12:50:52 +0000 (12:50 +0000)
committerkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 26 Feb 2002 12:50:52 +0000 (12:50 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@50055 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/h8300/h8300-protos.h
gcc/config/h8300/h8300.c
gcc/config/h8300/h8300.md

index c3ab894..670aafd 100644 (file)
@@ -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
index 5d84a97..cebcb5b 100644 (file)
@@ -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));
index 63d5ee2..d09068c 100644 (file)
@@ -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;
+}
 \f
 /* Shifts.
 
index 51541af..a711d29 100644 (file)
                (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 ""
                (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"
                (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 ""
                (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")])
 
 ;; ----------------------------------------------------------------------
                (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 ""
                (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"
                (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 ""
                (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")])
 
 ;; ----------------------------------------------------------------------
                (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 ""
                (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"
                (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 ""
                (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")])
 \f
 ;; ----------------------------------------------------------------------