+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.
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.
;;
(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)])]