* i386.md (add?i_3, add?i_5): New.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 11 Sep 2000 23:54:11 +0000 (23:54 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 11 Sep 2000 23:54:11 +0000 (23:54 +0000)
(add?i_4): Rename from add?i_3;  Fix compare pattern.
(sub?i_3, xor?i_3, ior?i_3): New.

* genrecog.c (write_tree): Output code to clear insn_extract cache.
* genattrtab.c (write_attr_case): Gen call to extract_insn_cache
instead of extract_insn and extract_constrain_insn_cache instead of
extract_insn and constrain_operands.
* recog.c (extract_insn_cached, extract_constrain_insn_cached):
New functions.
(extract_insn): Clear which_alternative.
(constrain_operands): Set which_alternative to -1 when failed.
* recog.h (extract_constrain_insn_cached, extract_insn_cached):
Declare.

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

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/genattrtab.c
gcc/genrecog.c
gcc/recog.c
gcc/recog.h

index 57693f6..7643df0 100644 (file)
@@ -1,3 +1,20 @@
+Tue Sep 12 01:51:38 MET DST 2000  Jan Hubicka  <jh@suse.cz>
+
+       * i386.md (add?i_3, add?i_5): New.
+       (add?i_4): Rename from add?i_3;  Fix compare pattern.
+       (sub?i_3, xor?i_3, ior?i_3): New.
+
+       * genrecog.c (write_tree): Output code to clear insn_extract cache.
+       * genattrtab.c (write_attr_case): Gen call to extract_insn_cache
+       instead of extract_insn and extract_constrain_insn_cache instead of
+       extract_insn and constrain_operands.
+       * recog.c (extract_insn_cached, extract_constrain_insn_cached):
+       New functions.
+       (extract_insn): Clear which_alternative.
+       (constrain_operands): Set which_alternative to -1 when failed.
+       * recog.h (extract_constrain_insn_cached, extract_insn_cached):
+       Declare.
+
 2000-09-11  Matthew Hiller  <hiller@redhat.com>
 
        * config/h8300/h8300.md (movstrictqi): Changed constraint modifier
index 51386bc..6e8022f 100644 (file)
    (set_attr "mode" "SI")])
 
 (define_insn "*addsi_3"
+  [(set (reg 17)
+       (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
+                (match_operand:SI 1 "nonimmediate_operand" "%0")))
+   (clobber (match_scratch:SI 0 "=r"))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
+   /* Current assemblers are broken and do not allow @GOTOFF in
+      ought but a memory context. */
+   && ! pic_symbolic_operand (operands[2], VOIDmode)"
+  "*
+{
+  switch (get_attr_type (insn))
+    {
+    case TYPE_INCDEC:
+      if (! rtx_equal_p (operands[0], operands[1]))
+       abort ();
+      if (operands[2] == const1_rtx)
+        return \"inc{l}\\t%0\";
+      else if (operands[2] == constm1_rtx)
+        return \"dec{l}\\t%0\";
+      else
+       abort();
+
+    default:
+      if (! rtx_equal_p (operands[0], operands[1]))
+       abort ();
+      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+        Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
+      if (GET_CODE (operands[2]) == CONST_INT
+          && (INTVAL (operands[2]) == 128
+             || (INTVAL (operands[2]) < 0
+                 && INTVAL (operands[2]) != -128)))
+        {
+          operands[2] = GEN_INT (-INTVAL (operands[2]));
+          return \"sub{l}\\t{%2, %0|%0, %2}\";
+        }
+      return \"add{l}\\t{%2, %0|%0, %2}\";
+    }
+}"
+  [(set (attr "type")
+     (if_then_else (match_operand:SI 2 "incdec_operand" "")
+       (const_string "incdec")
+       (const_string "alu")))
+   (set_attr "mode" "SI")])
+
+(define_insn "*addsi_4"
   [(set (reg:CC 17)
-       (compare:CC (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
-                            (match_operand:SI 2 "general_operand" "rmni,rni"))
-                   (const_int 0)))                     
+       (compare:CC (neg:SI (match_operand:SI 2 "general_operand" "rmni,rni"))
+                   (match_operand:SI 1 "nonimmediate_operand" "%0,0")))
    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
        (plus:SI (match_dup 1) (match_dup 2)))]
   "ix86_binary_operator_ok (PLUS, SImode, operands)
   [(set_attr "type" "alu")
    (set_attr "mode" "SI")])
 
+(define_insn "*addsi_5"
+  [(set (reg:CC 17)
+       (compare:CC (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
+                   (match_operand:SI 1 "nonimmediate_operand" "%0")))
+   (clobber (match_scratch:SI 0 "=r"))]
+  "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
+   /* Current assemblers are broken and do not allow @GOTOFF in
+      ought but a memory context. */
+   && ! pic_symbolic_operand (operands[2], VOIDmode)"
+  "add{l}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "SI")])
+
 (define_expand "addhi3"
   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
                   (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
    (set_attr "mode" "HI")])
 
 (define_insn "*addhi_3"
+  [(set (reg 17)
+       (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
+                (match_operand:HI 1 "nonimmediate_operand" "%0")))
+   (clobber (match_scratch:HI 0 "=r"))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  "*
+{
+  switch (get_attr_type (insn))
+    {
+    case TYPE_INCDEC:
+      if (operands[2] == const1_rtx)
+       return \"inc{w}\\t%0\";
+      else if (operands[2] == constm1_rtx
+              || (GET_CODE (operands[2]) == CONST_INT
+                  && INTVAL (operands[2]) == 65535))
+       return \"dec{w}\\t%0\";
+      abort();
+
+    default:
+      /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
+        Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
+      if (GET_CODE (operands[2]) == CONST_INT
+          && (INTVAL (operands[2]) == 128
+             || (INTVAL (operands[2]) < 0
+                 && INTVAL (operands[2]) != -128)))
+       {
+         operands[2] = GEN_INT (-INTVAL (operands[2]));
+         return \"sub{w}\\t{%2, %0|%0, %2}\";
+       }
+      return \"add{w}\\t{%2, %0|%0, %2}\";
+    }
+}"
+  [(set (attr "type")
+     (if_then_else (match_operand:HI 2 "incdec_operand" "")
+       (const_string "incdec")
+       (const_string "alu")))
+   (set_attr "mode" "HI")])
+
+(define_insn "*addhi_4"
   [(set (reg:CC 17)
-       (compare:CC (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
-                            (match_operand:HI 2 "general_operand" "rmni,rni"))
-                   (const_int 0)))                     
+       (compare:CC (neg:HI (match_operand:HI 2 "general_operand" "rmni,rni"))
+                   (match_operand:HI 1 "nonimmediate_operand" "%0,0")))
    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
        (plus:HI (match_dup 1) (match_dup 2)))]
   "ix86_binary_operator_ok (PLUS, HImode, operands)"
   [(set_attr "type" "alu")
    (set_attr "mode" "HI")])
 
+(define_insn "*addhi_5"
+  [(set (reg:CC 17)
+       (compare:CC (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
+                   (match_operand:HI 1 "nonimmediate_operand" "%0")))
+   (clobber (match_scratch:HI 0 "=r"))]
+  "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  "add{w}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "HI")])
+
 (define_expand "addqi3"
   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
                   (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
    (set_attr "mode" "QI")])
 
 (define_insn "*addqi_3"
+  [(set (reg 17)
+       (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
+                (match_operand:QI 1 "nonimmediate_operand" "%0")))
+   (clobber (match_scratch:QI 0 "=r"))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  "*
+{
+  switch (get_attr_type (insn))
+    {
+    case TYPE_INCDEC:
+      if (operands[2] == const1_rtx)
+       return \"inc{b}\\t%0\";
+      else if (operands[2] == constm1_rtx
+              || (GET_CODE (operands[2]) == CONST_INT
+                  && INTVAL (operands[2]) == 255))
+       return \"dec{b}\\t%0\";
+      abort();
+
+    default:
+      /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
+      if (GET_CODE (operands[2]) == CONST_INT
+          && INTVAL (operands[2]) < 0)
+       {
+         operands[2] = GEN_INT (-INTVAL (operands[2]));
+         return \"sub{b}\\t{%2, %0|%0, %2}\";
+       }
+      return \"add{b}\\t{%2, %0|%0, %2}\";
+    }
+}"
+  [(set (attr "type")
+     (if_then_else (match_operand:QI 2 "incdec_operand" "")
+       (const_string "incdec")
+       (const_string "alu")))
+   (set_attr "mode" "QI")])
+
+(define_insn "*addqi_4"
   [(set (reg:CC 17)
-       (compare:CC (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
-                            (match_operand:QI 2 "general_operand" "qmni,qni"))
-                   (const_int 0)))                     
+       (compare:CC (neg:QI (match_operand:QI 2 "general_operand" "qmni,qni"))
+                   (match_operand:QI 1 "nonimmediate_operand" "%0,0")))
    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
        (plus:QI (match_dup 1) (match_dup 2)))]
   "ix86_binary_operator_ok (PLUS, QImode, operands)"
   [(set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
+(define_insn "*addqi_5"
+  [(set (reg:CC 17)
+       (compare:CC (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
+                   (match_operand:QI 1 "nonimmediate_operand" "%0")))
+   (clobber (match_scratch:QI 0 "=r"))]
+  "(GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  "add{b}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
 
 (define_insn "addqi_ext_1"
   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
          (const_int 0)))
    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
        (minus:SI (match_dup 1) (match_dup 2)))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && ix86_binary_operator_ok (MINUS, SImode, operands)"
+  "sub{l}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "SI")])
+
+(define_insn "*subsi_3"
+  [(set (reg 17)
+       (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
+                (match_operand:SI 2 "general_operand" "ri,rm")))
+   (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
+       (minus:SI (match_dup 1) (match_dup 2)))]
   "ix86_match_ccmode (insn, CCmode)
    && ix86_binary_operator_ok (MINUS, SImode, operands)"
   "sub{l}\\t{%2, %0|%0, %2}"
          (const_int 0)))
    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
        (minus:HI (match_dup 1) (match_dup 2)))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && ix86_binary_operator_ok (MINUS, HImode, operands)"
+  "sub{w}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "HI")])
+
+(define_insn "*subhi_3"
+  [(set (reg 17)
+       (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
+                (match_operand:HI 2 "general_operand" "ri,rm")))
+   (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
+       (minus:HI (match_dup 1) (match_dup 2)))]
   "ix86_match_ccmode (insn, CCmode)
    && ix86_binary_operator_ok (MINUS, HImode, operands)"
   "sub{w}\\t{%2, %0|%0, %2}"
          (const_int 0)))
    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
        (minus:HI (match_dup 1) (match_dup 2)))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && ix86_binary_operator_ok (MINUS, QImode, operands)"
+  "sub{b}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
+(define_insn "*subqi_3"
+  [(set (reg 17)
+       (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
+                (match_operand:QI 2 "general_operand" "qi,qm")))
+   (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
+       (minus:HI (match_dup 1) (match_dup 2)))]
   "ix86_match_ccmode (insn, CCmode)
    && ix86_binary_operator_ok (MINUS, QImode, operands)"
   "sub{b}\\t{%2, %0|%0, %2}"
   [(set_attr "type" "alu")
    (set_attr "mode" "SI")])
 
+(define_insn "*iorsi_3"
+  [(set (reg 17)
+       (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
+                        (match_operand:SI 2 "general_operand" "rim"))
+                (const_int 0)))
+   (clobber (match_scratch:SI 0 "=r"))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  "or{l}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "SI")])
+
 (define_expand "iorhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "")
        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
   [(set_attr "type" "alu")
    (set_attr "mode" "HI")])
 
+(define_insn "*iorhi_3"
+  [(set (reg 17)
+       (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
+                        (match_operand:HI 2 "general_operand" "rim"))
+                (const_int 0)))
+   (clobber (match_scratch:HI 0 "=r"))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  "or{w}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "HI")])
+
 (define_expand "iorqi3"
   [(set (match_operand:QI 0 "nonimmediate_operand" "")
        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
   "or{b}\\t{%2, %0|%0, %2}"
   [(set_attr "type" "alu")
    (set_attr "mode" "QI")])
+
+(define_insn "*iorqi_3"
+  [(set (reg 17)
+       (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
+                        (match_operand:QI 2 "general_operand" "qim"))
+                (const_int 0)))
+   (clobber (match_scratch:QI 0 "=r"))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  "or{b}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
 \f
 ;; Logical XOR instructions
 
   [(set_attr "type" "alu")
    (set_attr "mode" "SI")])
 
+(define_insn "*xorsi_3"
+  [(set (reg 17)
+       (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
+                        (match_operand:SI 2 "general_operand" "rim"))
+                (const_int 0)))
+   (clobber (match_scratch:SI 0 "=r"))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  "xor{l}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "SI")])
+
 (define_expand "xorhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "")
        (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
   [(set_attr "type" "alu")
    (set_attr "mode" "HI")])
 
+(define_insn "*xorhi_3"
+  [(set (reg 17)
+       (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
+                        (match_operand:HI 2 "general_operand" "rim"))
+                (const_int 0)))
+   (clobber (match_scratch:HI 0 "=r"))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  "xor{w}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "HI")])
+
 (define_expand "xorqi3"
   [(set (match_operand:QI 0 "nonimmediate_operand" "")
        (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
   [(set_attr "type" "alu")
    (set_attr "mode" "QI")])
 
+(define_insn "*xorqi_cc_2"
+  [(set (reg 17)
+       (compare
+         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
+                 (match_operand:QI 2 "general_operand" "qim"))
+         (const_int 0)))
+   (clobber (match_scratch:QI 0 "=r"))]
+  "ix86_match_ccmode (insn, CCNOmode)
+   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  "xor{b}\\t{%2, %0|%0, %2}"
+  [(set_attr "type" "alu")
+   (set_attr "mode" "QI")])
+
 (define_insn "xorqi_cc_ext_1"
   [(set (reg:CCNO 17)
        (compare:CCNO
index a6a9a90..c8cd193 100644 (file)
@@ -5212,18 +5212,15 @@ write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
   must_extract = must_constrain = address_used = 0;
   walk_attr_value (av->value);
 
-  if (must_extract)
+  if (must_constrain)
     {
       write_indent (indent + 2);
-      printf ("extract_insn (insn);\n");
+      printf ("extract_constrain_insn_cached (insn);\n");
     }
-
-  if (must_constrain)
+  else if (must_extract)
     {
       write_indent (indent + 2);
-      printf ("if (! constrain_operands (reload_completed))\n");
-      write_indent (indent + 2);
-      printf ("  fatal_insn_not_found (insn);\n");
+      printf ("extract_insn_cached (insn);\n");
     }
 
   write_attr_set (attr, indent + 2, av->value, prefix, suffix,
index e506f8d..b512181 100644 (file)
@@ -2189,6 +2189,9 @@ peephole2%s (x0, insn, _pmatch_len)\n\
 
   printf ("  %s tem ATTRIBUTE_UNUSED;\n", IS_SPLIT (type) ? "rtx" : "int");
 
+  if (!subfunction)
+    printf ("  recog_data.insn = NULL_RTX;\n");
+
   if (head->first)
     write_tree (head, "", type, 1);
   else
index 87f8137..f1d5dee 100644 (file)
@@ -2045,6 +2045,31 @@ adj_offsettable_operand (op, offset)
   abort ();
 }
 \f
+/* Like extract_insn, but save insn extracted and don't extract again, when
+   called again for the same insn expecting that recog_data still contain the
+   valid information.  This is used primary by gen_attr infrastructure that
+   often does extract insn again and again.  */
+void
+extract_insn_cached (insn)
+     rtx insn;
+{
+  if (recog_data.insn == insn && INSN_CODE (insn) >= 0)
+    return;
+  extract_insn (insn);
+  recog_data.insn = insn;
+}
+/* Do cached extract_insn, constrain_operand and complain about failures.
+   Used by insn_attrtab.  */
+void
+extract_constrain_insn_cached (insn)
+     rtx insn;
+{
+  extract_insn_cached (insn);
+  if (which_alternative == -1
+      && !constrain_operands (reload_completed))
+    fatal_insn_not_found (insn);
+}
+\f
 /* Analyze INSN and fill in recog_data.  */
 
 void
@@ -2056,9 +2081,11 @@ extract_insn (insn)
   int noperands;
   rtx body = PATTERN (insn);
 
+  recog_data.insn = NULL;
   recog_data.n_operands = 0;
   recog_data.n_alternatives = 0;
   recog_data.n_dups = 0;
+  which_alternative = -1;
 
   switch (GET_CODE (body))
     {
@@ -2592,6 +2619,7 @@ constrain_operands (strict)
       which_alternative++;
     }
 
+  which_alternative = -1;
   /* If we are about to reject this, but we are not to test strictly,
      try a very loose test.  Only return failure if it fails also.  */
   if (strict == 0)
index d4fd4fd..3328af6 100644 (file)
@@ -116,6 +116,8 @@ extern int recog                    PARAMS ((rtx, rtx, int *));
 extern void add_clobbers               PARAMS ((rtx, int));
 extern void insn_extract               PARAMS ((rtx));
 extern void extract_insn               PARAMS ((rtx));
+extern void extract_constrain_insn_cached PARAMS ((rtx));
+extern void extract_insn_cached                PARAMS ((rtx));
 extern void preprocess_constraints     PARAMS ((void));
 extern rtx peep2_next_insn             PARAMS ((int));
 extern int peep2_regno_dead_p          PARAMS ((int, int));
@@ -186,6 +188,9 @@ struct recog_data
 
   /* The number of alternatives in the constraints for the insn.  */
   char n_alternatives;
+
+  /* In case we are caching, hold insn data was generated for.  */
+  rtx insn;
 };
 
 extern struct recog_data recog_data;