aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>2012-12-11 08:37:00 +0000
committerAndreas Krebbel <krebbel@gcc.gnu.org>2012-12-11 08:37:00 +0000
commit2771c2f9bf60452ae4bf18f8d84b2c5cb7b2b76e (patch)
treecadb0620f280d6c9b908d2db8bd6869fa475d830
parent33e4edab852f968dd90705152d775cf5f7a1827a (diff)
downloadgcc-2771c2f9bf60452ae4bf18f8d84b2c5cb7b2b76e.zip
gcc-2771c2f9bf60452ae4bf18f8d84b2c5cb7b2b76e.tar.gz
gcc-2771c2f9bf60452ae4bf18f8d84b2c5cb7b2b76e.tar.bz2
predicates.md ("execute_operation"): New predicate.
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. From-SVN: r194385
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/s390/predicates.md46
-rw-r--r--gcc/config/s390/s390.md4
3 files changed, 54 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9ed5f36..a8bd7c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index 9d619fb..9ba85bf 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -348,6 +348,52 @@
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.
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 9279a98..bea58cd 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -2493,7 +2493,7 @@
;;
(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)])]
@@ -2504,7 +2504,7 @@
(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)])]