This adds support for the branch indirect instruction.

gcc/ChangeLog:

2017-03-24  Andreas Krebbel  <kreb...@linux.vnet.ibm.com>

        * config/s390/s390.md ("indirect_jump"): Turn insn definition into
        expander.
        ("*indirect_jump", "*indirect2_jump"): New pattern definitions.
---
 gcc/ChangeLog           |  6 ++++++
 gcc/config/s390/s390.md | 48 +++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a48b743..b3f3d95 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@
 2017-03-24  Andreas Krebbel  <kreb...@linux.vnet.ibm.com>
 
+       * config/s390/s390.md ("indirect_jump"): Turn insn definition into
+       expander.
+       ("*indirect_jump", "*indirect2_jump"): New pattern definitions.
+
+2017-03-24  Andreas Krebbel  <kreb...@linux.vnet.ibm.com>
+
        * config/s390/s390.c (s390_expand_vec_init): Use vllezl
        instruction if possible.
        * config/s390/vector.md (vec_halfnumelts): New mode
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 53c8fed..32753ef 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -9509,20 +9509,46 @@
 ; indirect-jump instruction pattern(s).
 ;
 
-(define_insn "indirect_jump"
- [(set (pc) (match_operand 0 "address_operand" "ZR"))]
+(define_expand "indirect_jump"
+  [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
   ""
 {
-  if (get_attr_op_type (insn) == OP_TYPE_RR)
-    return "br\t%0";
+  if (address_operand (operands[0], GET_MODE (operands[0])))
+    ;
+  else if (TARGET_ARCH12
+          && GET_MODE (operands[0]) == Pmode
+          && memory_operand (operands[0], Pmode))
+    ;
   else
-    return "b\t%a0";
-}
-  [(set (attr "op_type")
-        (if_then_else (match_operand 0 "register_operand" "")
-                      (const_string "RR") (const_string "RX")))
-   (set_attr "type"  "branch")
-   (set_attr "atype" "agen")])
+    operands[0] = force_reg (Pmode, operands[0]);
+})
+
+(define_insn "*indirect_jump"
+  [(set (pc)
+       (match_operand 0 "address_operand" "a,ZR"))]
+ ""
+ "@
+  br\t%0
+  b\t%a0"
+ [(set_attr "op_type" "RR,RX")
+  (set_attr "type"  "branch")
+  (set_attr "atype" "agen")
+  (set_attr "cpu_facility" "*")])
+
+; FIXME: LRA does not appear to be able to deal with MEMs being
+; checked against address constraints like ZR above.  So make this a
+; separate pattern for now.
+(define_insn "*indirect2_jump"
+  [(set (pc)
+       (match_operand 0 "nonimmediate_operand" "a,T"))]
+ ""
+ "@
+  br\t%0
+  bi\t%0"
+ [(set_attr "op_type" "RR,RXY")
+  (set_attr "type"  "branch")
+  (set_attr "atype" "agen")
+  (set_attr "cpu_facility" "*,arch12")])
 
 ;
 ; casesi instruction pattern(s).
-- 
2.9.1

Reply via email to