2012-12-11 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Dec 2012 08:37:00 +0000 (08:37 +0000)
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 11 Dec 2012 08:37:00 +0000 (08:37 +0000)
* config/s390/predicates.md ("execute_operation"): New predicate.
* config/s390/s390.md ("*execute_rl", "*execute"): Use the new
predicate.

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

gcc/ChangeLog
gcc/config/s390/predicates.md
gcc/config/s390/s390.md

index 9ed5f36..a8bd7c8 100644 (file)
@@ -1,3 +1,9 @@
+2012-12-11  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+       * config/s390/predicates.md ("execute_operation"): New predicate.
+       * config/s390/s390.md ("*execute_rl", "*execute"): Use the new
+       predicate.
+
 2012-12-10  Xinliang David Li  <davidxl@google.com>
 
        * config/i386/i386.c: Enable push/pop in pro/epilogue for mordern CPUs.
index 9d619fb..9ba85bf 100644 (file)
   return true;
 })
 
+;; For an execute pattern the target instruction is embedded into the
+;; RTX but will not get checked for validity by recog automatically.
+;; The execute_operation predicate extracts the target RTX and invokes
+;; recog.
+(define_special_predicate "execute_operation"
+  (match_code "parallel")
+{
+  rtx pattern = op;
+  rtx insn;
+  int icode;
+
+  /* This is redundant but since this predicate is evaluated
+     first when recognizing the insn we can prevent the more
+     expensive code below from being executed for many cases.  */
+  if (GET_CODE (XVECEXP (pattern, 0, 0)) != UNSPEC
+      || XINT (XVECEXP (pattern, 0, 0), 1) != UNSPEC_EXECUTE)
+    return false;
+
+  /* Keep in sync with s390_execute_target.  */
+  if (XVECLEN (pattern, 0) == 2)
+    {
+      pattern = copy_rtx (XVECEXP (pattern, 0, 1));
+    }
+  else
+    {
+      rtvec vec = rtvec_alloc (XVECLEN (pattern, 0) - 1);
+      int i;
+
+      for (i = 0; i < XVECLEN (pattern, 0) - 1; i++)
+       RTVEC_ELT (vec, i) = copy_rtx (XVECEXP (pattern, 0, i + 1));
+
+      pattern = gen_rtx_PARALLEL (VOIDmode, vec);
+    }
+
+  /* Since we do not have the wrapping insn here we have to build one.  */
+  insn = make_insn_raw (pattern);
+  icode = recog_memoized (insn);
+  if (icode < 0)
+    return false;
+
+  extract_insn (insn);
+  constrain_operands (1);
+
+  return which_alternative >= 0;
+})
+
 ;; Return true if OP is a store multiple operation.  It is known to be a
 ;; PARALLEL and the first section will be tested.
 
index 9279a98..bea58cd 100644 (file)
 ;;
 
 (define_insn "*execute_rl"
-  [(match_parallel 0 ""
+  [(match_parallel 0 "execute_operation"
     [(unspec [(match_operand 1    "register_operand" "a")
              (match_operand 2    "" "")
               (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
    (set_attr "type"    "cs")])
 
 (define_insn "*execute"
-  [(match_parallel 0 ""
+  [(match_parallel 0 "execute_operation"
     [(unspec [(match_operand 1 "register_operand" "a")
               (match_operand:BLK 2 "memory_operand" "R")
               (match_operand 3 "" "")] UNSPEC_EXECUTE)])]