From: krebbel Date: Tue, 11 Dec 2012 08:37:00 +0000 (+0000) Subject: 2012-12-11 Andreas Krebbel X-Git-Tag: upstream/4.9.2~8618 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e6e458703682c39a4f4c065e120e432bc8789e83;p=platform%2Fupstream%2Flinaro-gcc.git 2012-12-11 Andreas Krebbel * 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 --- 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 + + * 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 * 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)])]