]> gcc.gnu.org Git - gcc.git/commitdiff
builtins.c: (expand_builtin_memcmp, expand_builtin_strncmp): s/cmpstrsi/cmpstrnsi
authorAdrian Straetling <straetling@de.ibm.com>
Tue, 12 Jul 2005 09:20:21 +0000 (09:20 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Tue, 12 Jul 2005 09:20:21 +0000 (09:20 +0000)
2005-07-12  Adrian Straetling  <straetling@de.ibm.com>

* builtins.c: (expand_builtin_memcmp, expand_builtin_strncmp):
s/cmpstrsi/cmpstrnsi
(expand_builtin_strcmp): Rewrite to support both 'cmpstrsi' and
'cmpstrnsi'.
* optabs.c: (prepare_cmp_insn): Add availability of 'cmpstrn'.
(init_optabs): Initialize cmpstrn_optab.
* optabs.h: (enum insn_code cmpstrn_optab): Declare.
* genopinit.c: (optabs[]): Add 'cmpstrn' to initialisation.
* expr.c: (enum insn_code cmpstrn_optab): Declare.
* config/i386/i386.md: s/cmpstr/cmpstrn
* config/c4x/c4x.md: s/cmpstr/cmpstrn
* doc/md.texi: Update documentation.

From-SVN: r101916

gcc/ChangeLog
gcc/builtins.c
gcc/config/c4x/c4x.md
gcc/config/i386/i386.md
gcc/doc/md.texi
gcc/expr.c
gcc/genopinit.c
gcc/optabs.c
gcc/optabs.h

index f44b1f4e2b7fc46d7d3fb05a37574a1aa65eefc9..0ab6fdebde26fbae7af1b7de9a6461f79a6951c6 100644 (file)
@@ -1,3 +1,18 @@
+2005-07-12  Adrian Straetling  <straetling@de.ibm.com>
+
+       * builtins.c: (expand_builtin_memcmp, expand_builtin_strncmp):
+       s/cmpstrsi/cmpstrnsi
+       (expand_builtin_strcmp): Rewrite to support both 'cmpstrsi' and
+       'cmpstrnsi'.
+       * optabs.c: (prepare_cmp_insn): Add availability of 'cmpstrn'.
+       (init_optabs): Initialize cmpstrn_optab.
+       * optabs.h: (enum insn_code cmpstrn_optab): Declare.
+       * genopinit.c: (optabs[]): Add 'cmpstrn' to initialisation.
+       * expr.c: (enum insn_code cmpstrn_optab): Declare.
+       * config/i386/i386.md: s/cmpstr/cmpstrn
+       * config/c4x/c4x.md: s/cmpstr/cmpstrn
+       * doc/md.texi: Update documentation.
+
 2005-07-11  Richard Henderson  <rth@redhat.com>
 
        * config/alpha/alpha.c (alpha_gimplify_va_arg_1): Use
index f308f530c354336575955dbb6353f7355bdcf11e..b032fc4378489cc3b7d858abbccc0b3ce5fdc547 100644 (file)
@@ -3449,7 +3449,7 @@ expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
        return expand_expr (result, target, mode, EXPAND_NORMAL);
     }
 
-#if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
+#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
   {
     tree arg1 = TREE_VALUE (arglist);
     tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
@@ -3469,9 +3469,9 @@ expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
     else
 #endif
-#ifdef HAVE_cmpstrsi
-    if (HAVE_cmpstrsi)
-      insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
+#ifdef HAVE_cmpstrnsi
+    if (HAVE_cmpstrnsi)
+      insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
     else
 #endif
       return 0;
@@ -3504,10 +3504,10 @@ expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
                           GEN_INT (MIN (arg1_align, arg2_align)));
     else
 #endif
-#ifdef HAVE_cmpstrsi
-    if (HAVE_cmpstrsi)
-      insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
-                          GEN_INT (MIN (arg1_align, arg2_align)));
+#ifdef HAVE_cmpstrnsi
+    if (HAVE_cmpstrnsi)
+      insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
+                           GEN_INT (MIN (arg1_align, arg2_align)));
     else
 #endif
       gcc_unreachable ();
@@ -3558,103 +3558,134 @@ expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
        return expand_expr (result, target, mode, EXPAND_NORMAL);
     }
 
-#ifdef HAVE_cmpstrsi
-  if (HAVE_cmpstrsi)
-  {
-    tree arg1 = TREE_VALUE (arglist);
-    tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
-    tree len, len1, len2;
-    rtx arg1_rtx, arg2_rtx, arg3_rtx;
-    rtx result, insn;
-    tree fndecl, fn;
-
-    int arg1_align
-      = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
-    int arg2_align
-      = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
-    enum machine_mode insn_mode
-      = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
+#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
+  if (cmpstr_optab[SImode] != CODE_FOR_nothing
+      || cmpstrn_optab[SImode] != CODE_FOR_nothing)
+    {
+      rtx arg1_rtx, arg2_rtx;
+      rtx result, insn = NULL_RTX;
+      tree fndecl, fn;
+      
+      tree arg1 = TREE_VALUE (arglist);
+      tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
+      int arg1_align
+       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
+      int arg2_align
+       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
+
+      /* If we don't have POINTER_TYPE, call the function.  */
+      if (arg1_align == 0 || arg2_align == 0)
+       return 0;
 
-    len1 = c_strlen (arg1, 1);
-    len2 = c_strlen (arg2, 1);
+      /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
+      arg1 = builtin_save_expr (arg1);
+      arg2 = builtin_save_expr (arg2);
 
-    if (len1)
-      len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
-    if (len2)
-      len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
+      arg1_rtx = get_memory_rtx (arg1);
+      arg2_rtx = get_memory_rtx (arg2);
 
-    /* If we don't have a constant length for the first, use the length
-       of the second, if we know it.  We don't require a constant for
-       this case; some cost analysis could be done if both are available
-       but neither is constant.  For now, assume they're equally cheap,
-       unless one has side effects.  If both strings have constant lengths,
-       use the smaller.  */
-
-    if (!len1)
-      len = len2;
-    else if (!len2)
-      len = len1;
-    else if (TREE_SIDE_EFFECTS (len1))
-      len = len2;
-    else if (TREE_SIDE_EFFECTS (len2))
-      len = len1;
-    else if (TREE_CODE (len1) != INTEGER_CST)
-      len = len2;
-    else if (TREE_CODE (len2) != INTEGER_CST)
-      len = len1;
-    else if (tree_int_cst_lt (len1, len2))
-      len = len1;
-    else
-      len = len2;
+#ifdef HAVE_cmpstrsi
+      /* Try to call cmpstrsi.  */
+      if (HAVE_cmpstrsi)
+       {
+         enum machine_mode insn_mode 
+           = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
+
+         /* Make a place to write the result of the instruction.  */
+         result = target;
+         if (! (result != 0
+                && REG_P (result) && GET_MODE (result) == insn_mode
+                && REGNO (result) >= FIRST_PSEUDO_REGISTER))
+           result = gen_reg_rtx (insn_mode);
+
+         insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
+                              GEN_INT (MIN (arg1_align, arg2_align)));
+       }
+#endif
+#if HAVE_cmpstrnsi 
+      /* Try to determine at least one length and call cmpstrnsi.  */
+      if (!insn && HAVE_cmpstrnsi) 
+       {
+         tree len;
+         rtx arg3_rtx;
+
+         enum machine_mode insn_mode 
+           = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
+         tree len1 = c_strlen (arg1, 1);
+         tree len2 = c_strlen (arg2, 1);
+
+         if (len1)
+           len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
+         if (len2)
+           len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
+
+         /* If we don't have a constant length for the first, use the length
+            of the second, if we know it.  We don't require a constant for
+            this case; some cost analysis could be done if both are available
+            but neither is constant.  For now, assume they're equally cheap,
+            unless one has side effects.  If both strings have constant lengths,
+            use the smaller.  */
+
+         if (!len1)
+           len = len2;
+         else if (!len2)
+           len = len1;
+         else if (TREE_SIDE_EFFECTS (len1))
+           len = len2;
+         else if (TREE_SIDE_EFFECTS (len2))
+           len = len1;
+         else if (TREE_CODE (len1) != INTEGER_CST)
+           len = len2;
+         else if (TREE_CODE (len2) != INTEGER_CST)
+           len = len1;
+         else if (tree_int_cst_lt (len1, len2))
+           len = len1;
+         else
+           len = len2;
 
-    /* If both arguments have side effects, we cannot optimize.  */
-    if (!len || TREE_SIDE_EFFECTS (len))
-      return 0;
+         /* If both arguments have side effects, we cannot optimize.  */
+         if (!len || TREE_SIDE_EFFECTS (len))
+           return 0;
 
-    /* If we don't have POINTER_TYPE, call the function.  */
-    if (arg1_align == 0 || arg2_align == 0)
-      return 0;
+         /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
+         arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
 
-    /* Make a place to write the result of the instruction.  */
-    result = target;
-    if (! (result != 0
-          && REG_P (result) && GET_MODE (result) == insn_mode
-          && REGNO (result) >= FIRST_PSEUDO_REGISTER))
-      result = gen_reg_rtx (insn_mode);
+         /* Make a place to write the result of the instruction.  */
+         result = target;
+         if (! (result != 0
+                && REG_P (result) && GET_MODE (result) == insn_mode
+                && REGNO (result) >= FIRST_PSEUDO_REGISTER))
+           result = gen_reg_rtx (insn_mode);
 
-    /* Stabilize the arguments in case gen_cmpstrsi fails.  */
-    arg1 = builtin_save_expr (arg1);
-    arg2 = builtin_save_expr (arg2);
+         insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
+                               GEN_INT (MIN (arg1_align, arg2_align)));
+       }
+#endif
 
-    arg1_rtx = get_memory_rtx (arg1);
-    arg2_rtx = get_memory_rtx (arg2);
-    arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
-    insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
-                        GEN_INT (MIN (arg1_align, arg2_align)));
-    if (insn)
-      {
-       emit_insn (insn);
+      if (insn)
+       {
+         emit_insn (insn);
 
-       /* Return the value in the proper mode for this function.  */
-       mode = TYPE_MODE (TREE_TYPE (exp));
-       if (GET_MODE (result) == mode)
-         return result;
-       if (target == 0)
-         return convert_to_mode (mode, result, 0);
-       convert_move (target, result, 0);
-       return target;
-      }
+         /* Return the value in the proper mode for this function.  */
+         mode = TYPE_MODE (TREE_TYPE (exp));
+         if (GET_MODE (result) == mode)
+           return result;
+         if (target == 0)
+           return convert_to_mode (mode, result, 0);
+         convert_move (target, result, 0);
+         return target;
+       }
 
-    /* Expand the library call ourselves using a stabilized argument
-       list to avoid re-evaluating the function's arguments twice.  */
-    arglist = build_tree_list (NULL_TREE, arg2);
-    arglist = tree_cons (NULL_TREE, arg1, arglist);
-    fndecl = get_callee_fndecl (exp);
-    fn = build_function_call_expr (fndecl, arglist);
-    if (TREE_CODE (fn) == CALL_EXPR)
-      CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
-    return expand_call (fn, target, target == const0_rtx);
-  }
+      /* Expand the library call ourselves using a stabilized argument
+        list to avoid re-evaluating the function's arguments twice.  */
+      arglist = build_tree_list (NULL_TREE, arg2);
+      arglist = tree_cons (NULL_TREE, arg1, arglist);
+      fndecl = get_callee_fndecl (exp);
+      fn = build_function_call_expr (fndecl, arglist);
+      if (TREE_CODE (fn) == CALL_EXPR)
+       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
+      return expand_call (fn, target, target == const0_rtx);
+    }
 #endif
   return 0;
 }
@@ -3679,10 +3710,10 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
     }
 
   /* If c_strlen can determine an expression for one of the string
-     lengths, and it doesn't have side effects, then emit cmpstrsi
+     lengths, and it doesn't have side effects, then emit cmpstrnsi
      using length MIN(strlen(string)+1, arg3).  */
-#ifdef HAVE_cmpstrsi
-  if (HAVE_cmpstrsi)
+#ifdef HAVE_cmpstrnsi
+  if (HAVE_cmpstrnsi)
   {
     tree arg1 = TREE_VALUE (arglist);
     tree arg2 = TREE_VALUE (TREE_CHAIN (arglist));
@@ -3697,7 +3728,7 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
     int arg2_align
       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
     enum machine_mode insn_mode
-      = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
+      = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
 
     len1 = c_strlen (arg1, 1);
     len2 = c_strlen (arg2, 1);
@@ -3750,7 +3781,7 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
           && REGNO (result) >= FIRST_PSEUDO_REGISTER))
       result = gen_reg_rtx (insn_mode);
 
-    /* Stabilize the arguments in case gen_cmpstrsi fails.  */
+    /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
     arg1 = builtin_save_expr (arg1);
     arg2 = builtin_save_expr (arg2);
     len = builtin_save_expr (len);
@@ -3758,8 +3789,8 @@ expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
     arg1_rtx = get_memory_rtx (arg1);
     arg2_rtx = get_memory_rtx (arg2);
     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
-    insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
-                        GEN_INT (MIN (arg1_align, arg2_align)));
+    insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
+                         GEN_INT (MIN (arg1_align, arg2_align)));
     if (insn)
       {
        emit_insn (insn);
index f37a49bc36fcdeefe1571b18393e2dfaa1bb99f2..5054383e5204a57505c81393517b9246d21771df 100644 (file)
  }")
 
 
-(define_insn "*cmpstrqi"
+(define_insn "*cmpstrnqi"
   [(set (match_operand:QI 0 "ext_reg_operand" "=d")
         (compare:QI (mem:BLK (match_operand:QI 1 "addr_reg_operand" "+a"))
                     (mem:BLK (match_operand:QI 2 "addr_reg_operand" "+a"))))
     return \"\";
  }")
 
-(define_expand "cmpstrqi"
+(define_expand "cmpstrnqi"
   [(parallel [(set (match_operand:QI 0 "reg_operand" "")
                    (compare:QI (match_operand:BLK 1 "general_operand" "")
                                (match_operand:BLK 2 "general_operand" "")))
index c0823b608d8a9c7b6d19b89bd94edf8c15a1578e..d3a085b9f97da4e72faf00d39a4f719d164af908 100644 (file)
    (set_attr "memory" "store")
    (set_attr "mode" "QI")])
 
-(define_expand "cmpstrsi"
+(define_expand "cmpstrnsi"
   [(set (match_operand:SI 0 "register_operand" "")
        (compare:SI (match_operand:BLK 1 "general_operand" "")
                    (match_operand:BLK 2 "general_operand" "")))
          emit_move_insn (operands[0], const0_rtx);
          DONE;
        }
-      emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
-                                   operands[1], operands[2]));
+      emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
+                                    operands[1], operands[2]));
     }
   else
     {
        emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
       else
        emit_insn (gen_cmpsi_1 (countreg, countreg));
-      emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
-                                operands[1], operands[2]));
+      emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
+                                 operands[1], operands[2]));
     }
 
   outlow = gen_lowpart (QImode, out);
 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
 
-(define_expand "cmpstrqi_nz_1"
+(define_expand "cmpstrnqi_nz_1"
   [(parallel [(set (reg:CC FLAGS_REG)
                   (compare:CC (match_operand 4 "memory_operand" "")
                               (match_operand 5 "memory_operand" "")))
   ""
   "")
 
-(define_insn "*cmpstrqi_nz_1"
+(define_insn "*cmpstrnqi_nz_1"
   [(set (reg:CC FLAGS_REG)
        (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
                    (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
    (set_attr "mode" "QI")
    (set_attr "prefix_rep" "1")])
 
-(define_insn "*cmpstrqi_nz_rex_1"
+(define_insn "*cmpstrnqi_nz_rex_1"
   [(set (reg:CC FLAGS_REG)
        (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
                    (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
 
 ;; The same, but the count is not known to not be zero.
 
-(define_expand "cmpstrqi_1"
+(define_expand "cmpstrnqi_1"
   [(parallel [(set (reg:CC FLAGS_REG)
                (if_then_else:CC (ne (match_operand 2 "register_operand" "")
                                     (const_int 0))
   ""
   "")
 
-(define_insn "*cmpstrqi_1"
+(define_insn "*cmpstrnqi_1"
   [(set (reg:CC FLAGS_REG)
        (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
                             (const_int 0))
    (set_attr "mode" "QI")
    (set_attr "prefix_rep" "1")])
 
-(define_insn "*cmpstrqi_rex_1"
+(define_insn "*cmpstrnqi_rex_1"
   [(set (reg:CC FLAGS_REG)
        (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
                             (const_int 0))
    (set_attr "mode" "QI")
    (set_attr "prefix_rep" "1")])
 
-;; Peephole optimizations to clean up after cmpstr*.  This should be
+;; Peephole optimizations to clean up after cmpstrn*.  This should be
 ;; handled in combine, but it is not currently up to the task.
-;; When used for their truth value, the cmpstr* expanders generate
+;; When used for their truth value, the cmpstrn* expanders generate
 ;; code like this:
 ;;
 ;;   repz cmpsb
 ;;
 ;; The intermediate three instructions are unnecessary.
 
-;; This one handles cmpstr*_nz_1...
+;; This one handles cmpstrn*_nz_1...
 (define_peephole2
   [(parallel[
      (set (reg:CC FLAGS_REG)
      (clobber (match_dup 2))])]
   "")
 
-;; ...and this one handles cmpstr*_1.
+;; ...and this one handles cmpstrn*_1.
 (define_peephole2
   [(parallel[
      (set (reg:CC FLAGS_REG)
index 84be6e4404948d34fc3fcc1c62e0d273d22142eb..5af0d55e10b398c93619e1b407f41d0b8abb2845 100644 (file)
@@ -3269,8 +3269,8 @@ operand.
 
 The use for multiple @code{setmem@var{m}} is as for @code{movmem@var{m}}.
 
-@cindex @code{cmpstr@var{m}} instruction pattern
-@item @samp{cmpstr@var{m}}
+@cindex @code{cmpstrn@var{m}} instruction pattern
+@item @samp{cmpstrn@var{m}}
 String compare instruction, with five operands.  Operand 0 is the output;
 it has mode @var{m}.  The remaining four operands are like the operands
 of @samp{movmem@var{m}}.  The two memory blocks specified are compared
@@ -3281,6 +3281,25 @@ that may access an invalid page or segment and cause a fault.  The
 effect of the instruction is to store a value in operand 0 whose sign
 indicates the result of the comparison.
 
+@cindex @code{cmpstr@var{m}} instruction pattern
+@item @samp{cmpstr@var{m}}
+String compare instruction, without known maximum length.  Operand 0 is the
+output; it has mode @var{m}.  The second and third operand are the blocks of
+memory to be compared; both are @code{mem:BLK} with an address in mode
+@code{Pmode}.
+
+The fourth operand is the known shared alignment of the source and
+destination, in the form of a @code{const_int} rtx.  Thus, if the
+compiler knows that both source and destination are word-aligned,
+it may provide the value 4 for this operand.
+
+The two memory blocks specified are compared byte by byte in lexicographic
+order starting at the beginning of each string.  The instruction is not allowed
+to prefetch more than one byte at a time since either string may end in the
+first byte and reading past that may access an invalid page or segment and
+cause a fault.  The effect of the instruction is to store a value in operand 0
+whose sign indicates the result of the comparison.
+
 @cindex @code{cmpmem@var{m}} instruction pattern
 @item @samp{cmpmem@var{m}}
 Block compare instruction, with five operands like the operands
index d778b59c95d7004e97b880120eb448d03a795512..01f890fa6a51eb9100cb99b593bfe26cd95e482f 100644 (file)
@@ -202,9 +202,10 @@ enum insn_code movmem_optab[NUM_MACHINE_MODES];
 /* This array records the insn_code of insns to perform block sets.  */
 enum insn_code setmem_optab[NUM_MACHINE_MODES];
 
-/* These arrays record the insn_code of two different kinds of insns
+/* These arrays record the insn_code of three different kinds of insns
    to perform block compares.  */
 enum insn_code cmpstr_optab[NUM_MACHINE_MODES];
+enum insn_code cmpstrn_optab[NUM_MACHINE_MODES];
 enum insn_code cmpmem_optab[NUM_MACHINE_MODES];
 
 /* Synchronization primitives.  */
index 409ed08903ba2a16e9bda6bb5291c520da3d092f..8bf574743e96a172b50e0109b14a7e85e2ff872a 100644 (file)
@@ -169,6 +169,7 @@ static const char * const optabs[] =
   "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
   "movmem_optab[$A] = CODE_FOR_$(movmem$a$)",
   "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
+  "cmpstrn_optab[$A] = CODE_FOR_$(cmpstrn$a$)",
   "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)",
   "setmem_optab[$A] = CODE_FOR_$(setmem$a$)",
   "sync_add_optab[$A] = CODE_FOR_$(sync_add$I$a$)",
index 60c491870a88f9866098ee8a7279cdabcf426b43..2f981abf19bf7837a9f1999b5ea03bf796d83d44 100644 (file)
@@ -3425,6 +3425,8 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
          cmp_code = cmpmem_optab[cmp_mode];
          if (cmp_code == CODE_FOR_nothing)
            cmp_code = cmpstr_optab[cmp_mode];
+         if (cmp_code == CODE_FOR_nothing)
+           cmp_code = cmpstrn_optab[cmp_mode];
          if (cmp_code == CODE_FOR_nothing)
            continue;
 
@@ -5090,6 +5092,7 @@ init_optabs (void)
     {
       movmem_optab[i] = CODE_FOR_nothing;
       cmpstr_optab[i] = CODE_FOR_nothing;
+      cmpstrn_optab[i] = CODE_FOR_nothing;
       cmpmem_optab[i] = CODE_FOR_nothing;
       setmem_optab[i] = CODE_FOR_nothing;
 
index bba0a5ce82117cbe255e3e9ac3580a3d60f59798..71f198abf58a5b211a7ca67a6490653f539e22db 100644 (file)
@@ -450,6 +450,7 @@ extern enum insn_code setmem_optab[NUM_MACHINE_MODES];
 /* These arrays record the insn_code of two different kinds of insns
    to perform block compares.  */
 extern enum insn_code cmpstr_optab[NUM_MACHINE_MODES];
+extern enum insn_code cmpstrn_optab[NUM_MACHINE_MODES];
 extern enum insn_code cmpmem_optab[NUM_MACHINE_MODES];
 
 /* Synchronization primitives.  This first set is atomic operation for
This page took 0.100927 seconds and 5 git commands to generate.