s390-protos.h (s390_narrow_logical_operator): Add.
authorUlrich Weigand <uweigand@de.ibm.com>
Thu, 7 Oct 2004 20:44:28 +0000 (20:44 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Thu, 7 Oct 2004 20:44:28 +0000 (20:44 +0000)
* config/s390/s390-protos.h (s390_narrow_logical_operator): Add.
* config/s390/s390.c (s390_narrow_logical_operator): New function.
(s390_extra_constraint_str): Add 'A' constraints.
(s390_const_ok_for_constraint_p): Add 'Nx' constraints.
* config/s390/s390.h (EXTRA_MEMORY_CONSTRAINT): Add 'A' constraint.
(CONSTRAINT_LEN): Likewise.
* config/s390/s390.md ("*anddi3"): Add NI alternative and splitter.
("*andsi3_zarch", "*andsi3_esa"): Likewise.
("*andhi3_zarch", "*andhi3_esa"): Likewise.
("*iordi3"): Add OI alternative and splitter.
("*iorsi3_zarch", "*iorsi3_esa"): Likewise.
("*iorhi3_zarch", "*iorhi3_esa"): Likewise.
("*xordi3"): Add XI alternative and splitter.
("*xorsi3", "*xorhi3"): Likewise.

From-SVN: r88705

gcc/ChangeLog
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/s390/s390.md

index 6eb08c7bc0c37db20b5762624b712639adcc64ac..274b882d3711d2a16863c0996cdc79aab4d45460 100644 (file)
@@ -1,3 +1,20 @@
+2004-10-07  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * config/s390/s390-protos.h (s390_narrow_logical_operator): Add.
+       * config/s390/s390.c (s390_narrow_logical_operator): New function.
+       (s390_extra_constraint_str): Add 'A' constraints.
+       (s390_const_ok_for_constraint_p): Add 'Nx' constraints.
+       * config/s390/s390.h (EXTRA_MEMORY_CONSTRAINT): Add 'A' constraint.
+       (CONSTRAINT_LEN): Likewise.
+       * config/s390/s390.md ("*anddi3"): Add NI alternative and splitter.
+       ("*andsi3_zarch", "*andsi3_esa"): Likewise.
+       ("*andhi3_zarch", "*andhi3_esa"): Likewise.
+       ("*iordi3"): Add OI alternative and splitter.
+       ("*iorsi3_zarch", "*iorsi3_esa"): Likewise.
+       ("*iorhi3_zarch", "*iorhi3_esa"): Likewise.
+       ("*xordi3"): Add XI alternative and splitter.
+       ("*xorsi3", "*xorhi3"): Likewise.
+
 2004-10-07  Richard Sandiford  <rsandifo@redhat.com>
 
        * config/mips/mips.c (mips_function_rodata_section): New function.
index b4b695a159f25b2e320e05b9b3e2ba439a16e03a..4e88c1d012379346be001ddc22ea3b43732accd7 100644 (file)
@@ -87,6 +87,7 @@ extern rtx s390_emit_call (rtx, rtx, rtx, rtx);
 extern void s390_expand_logical_operator (enum rtx_code,
                                          enum machine_mode, rtx *);
 extern bool s390_logical_operator_ok_p (rtx *);
+extern void s390_narrow_logical_operator (enum rtx_code, rtx *, rtx *);
 extern bool s390_pool_operand (rtx);
 
 extern bool s390_output_addr_const_extra (FILE*, rtx);
index 45eb905fb666f648cc966c31d6258e0b50f7b63b..08363c8577664a7ac0c56327533ceb5fdcaf772f 100644 (file)
@@ -1166,6 +1166,27 @@ s390_logical_operator_ok_p (rtx *operands)
   return true;
 }
 
+/* Narrow logical operation CODE of memory operand MEMOP with immediate
+   operand IMMOP to switch from SS to SI type instructions.  */
+
+void
+s390_narrow_logical_operator (enum rtx_code code, rtx *memop, rtx *immop)
+{
+  int def = code == AND ? -1 : 0;
+  HOST_WIDE_INT mask;
+  int part;
+
+  gcc_assert (GET_CODE (*memop) == MEM);
+  gcc_assert (!MEM_VOLATILE_P (*memop));
+
+  mask = s390_extract_part (*immop, QImode, def);
+  part = s390_single_part (*immop, GET_MODE (*memop), QImode, def);
+  gcc_assert (part >= 0);
+
+  *memop = adjust_address (*memop, QImode, part);
+  *immop = gen_int_mode (mask, QImode);
+}
+
 
 /* Change optimizations to be performed, depending on the
    optimization level.
@@ -1564,6 +1585,21 @@ s390_extra_constraint_str (rtx op, int c, const char * str)
   if (c != str[0])
     abort ();
 
+  /* Check for offsettable variants of memory constraints.  */
+  if (c == 'A')
+    {
+      /* Only accept non-volatile MEMs.  */
+      if (!MEM_P (op) || MEM_VOLATILE_P (op))
+       return 0;
+
+      if ((reload_completed || reload_in_progress)
+         ? !offsettable_memref_p (op)
+         : !offsettable_nonstrict_memref_p (op))
+       return 0;
+
+      c = str[1];
+    }
+
   switch (c)
     {
     case 'Q':
@@ -1658,7 +1694,7 @@ s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
 {
   enum machine_mode mode, part_mode;
   int def;
-  unsigned char part;
+  int part, part_goal;
 
   if (c != str[0])
     abort ();
@@ -1682,7 +1718,10 @@ s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
       return value == 2147483647;
 
     case 'N':
-      part = str[1] - '0';
+      if (str[1] == 'x')
+       part_goal = -1;
+      else
+       part_goal = str[1] - '0';
 
       switch (str[2])
        {
@@ -1709,7 +1748,10 @@ s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
       if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
        return 0;
 
-      if (s390_single_part (GEN_INT (value), mode, part_mode, def) != part)
+      part = s390_single_part (GEN_INT (value), mode, part_mode, def);
+      if (part < 0)
+       return 0;
+      if (part_goal != -1 && part_goal != part)
        return 0;
 
       break;
index 601314f1843385f426c968bdf4f60628a17a3a1b..cbb28e8fc7d756c8ff3211947d13c4a343beaf8c 100644 (file)
@@ -542,13 +542,14 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
 
 #define EXTRA_CONSTRAINT_STR(OP, C, STR)                                       \
   s390_extra_constraint_str ((OP), (C), (STR))
-#define EXTRA_MEMORY_CONSTRAINT(C, STR)                                \
-  ((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T')
-#define EXTRA_ADDRESS_CONSTRAINT(C, STR)                       \
+#define EXTRA_MEMORY_CONSTRAINT(C, STR)                                        \
+  ((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T' || (C) == 'A')
+#define EXTRA_ADDRESS_CONSTRAINT(C, STR)                               \
   ((C) == 'U' || (C) == 'W' || (C) == 'Y')
 
-#define CONSTRAINT_LEN(C, STR)                                   \
-  ((C) == 'N' ? 5 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
+#define CONSTRAINT_LEN(C, STR)                                         \
+  ((C) == 'N' ? 5 :                                                    \
+   (C) == 'A' ? 2 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
 
 /* Stack layout and calling conventions.  */
 
index feea29836e8118be52eb2097335cdbf0a03129f9..7d59f0c0f7ec2eb7804a6d9d8b0ef2a050e5288c 100644 (file)
 ;;         (-524288..524287) for long displacement
 ;;    M -- Constant integer with a value of 0x7fffffff.
 ;;    N -- Multiple letter constraint followed by 4 parameter letters.
-;;         0..9:  number of the part counting from most to least significant
-;;         H,Q:   mode of the part
-;;         D,S,H: mode of the containing operand
-;;         0,F:   value of the other parts (F - all bits set)
+;;         0..9,x:  number of the part counting from most to least significant
+;;         H,Q:     mode of the part
+;;         D,S,H:   mode of the containing operand
+;;         0,F:     value of the other parts (F - all bits set)
 ;;
 ;;         The constraint matches if the specified part of a constant
-;;         has a value different from its other parts.
+;;         has a value different from its other parts.  If the letter x
+;;         is specified instead of a part number, the constraint matches
+;;         if there is any single part with non-default value.
 ;;    Q -- Memory reference without index register and with short displacement.
 ;;    R -- Memory reference with index register and short displacement.
 ;;    S -- Memory reference without index register but with long displacement.
 ;;    T -- Memory reference with index register and long displacement.
+;;    A -- Multiple letter constraint followed by Q, R, S, or T:
+;;         Offsettable memory reference of type specified by second letter.
 ;;    U -- Pointer with short displacement.
 ;;    W -- Pointer with long displacement.
 ;;    Y -- Shift count operand.
   [(set_attr "op_type"  "RRE,RXY")])
 
 (define_insn "*anddi3"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,Q")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
         (and:DI (match_operand:DI 1 "nonimmediate_operand"
-                                    "%d,o,0,0,0,0,0,0,0")
+                                    "%d,o,0,0,0,0,0,0,0,0")
                 (match_operand:DI 2 "general_operand"
-                                    "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m,Q")))
+                                    "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m,NxQDF,Q")))
    (clobber (reg:CC 33))]
   "TARGET_64BIT && s390_logical_operator_ok_p (operands)"
   "@
    nill\t%0,%j2
    ngr\t%0,%2
    ng\t%0,%2
+   #
    nc\t%O0(8,%R0),%2"
-  [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY,SS")])
+  [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY,SI,SS")])
+
+(define_split
+  [(set (match_operand:DI 0 "s_operand" "")
+        (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
+   (clobber (reg:CC 33))]
+  "reload_completed"
+  [(parallel
+    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
+     (clobber (reg:CC 33))])]
+  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
 
 (define_expand "anddi3"
   [(set (match_operand:DI 0 "nonimmediate_operand" "")
   [(set_attr "op_type"  "RR,RX,RXY")])
 
 (define_insn "*andsi3_zarch"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,Q")
-        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,o,0,0,0,0,0,0")
-                (match_operand:SI 2 "general_operand" "M,M,N0HSF,N1HSF,d,R,T,Q")))
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,AQ,Q")
+        (and:SI (match_operand:SI 1 "nonimmediate_operand"
+                                    "%d,o,0,0,0,0,0,0,0")
+                (match_operand:SI 2 "general_operand"
+                                    "M,M,N0HSF,N1HSF,d,R,T,NxQSF,Q")))
    (clobber (reg:CC 33))]
   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
   "@
    nr\t%0,%2
    n\t%0,%2
    ny\t%0,%2
+   #
    nc\t%O0(4,%R0),%2"
-  [(set_attr "op_type"  "RRE,RXE,RI,RI,RR,RX,RXY,SS")])
+  [(set_attr "op_type"  "RRE,RXE,RI,RI,RR,RX,RXY,SI,SS")])
 
 (define_insn "*andsi3_esa"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,Q")
-        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
-                (match_operand:SI 2 "general_operand" "d,R,Q")))
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
+        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
+                (match_operand:SI 2 "general_operand" "d,R,NxQSF,Q")))
    (clobber (reg:CC 33))]
   "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
   "@
    nr\t%0,%2
    n\t%0,%2
+   #
    nc\t%O0(4,%R0),%2"
-  [(set_attr "op_type"  "RR,RX,SS")])
+  [(set_attr "op_type"  "RR,RX,SI,SS")])
+
+(define_split
+  [(set (match_operand:SI 0 "s_operand" "")
+        (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
+   (clobber (reg:CC 33))]
+  "reload_completed"
+  [(parallel
+    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
+     (clobber (reg:CC 33))])]
+  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
 
 (define_expand "andsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "")
 ;
 
 (define_insn "*andhi3_zarch"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,Q")
-        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
-                (match_operand:HI 2 "general_operand" "d,n,Q")))
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
+        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
+                (match_operand:HI 2 "general_operand" "d,n,NxQHF,Q")))
    (clobber (reg:CC 33))]
   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
   "@
    nr\t%0,%2
    nill\t%0,%x2
+   #
    nc\t%O0(2,%R0),%2"
-  [(set_attr "op_type"  "RR,RI,SS")])
+  [(set_attr "op_type"  "RR,RI,SI,SS")])
 
 (define_insn "*andhi3_esa"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,Q")
-        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
-                (match_operand:HI 2 "general_operand" "d,Q")))
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
+        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
+                (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
    (clobber (reg:CC 33))]
   "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
   "@
    nr\t%0,%2
+   #
    nc\t%O0(2,%R0),%2"
-  [(set_attr "op_type"  "RR,SS")])
+  [(set_attr "op_type"  "RR,SI,SS")])
+
+(define_split
+  [(set (match_operand:HI 0 "s_operand" "")
+        (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
+   (clobber (reg:CC 33))]
+  "reload_completed"
+  [(parallel
+    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
+     (clobber (reg:CC 33))])]
+  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
 
 (define_expand "andhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "")
   [(set_attr "op_type"  "RRE,RXY")])
 
 (define_insn "*iordi3"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,Q")
-        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,0,0,0,0,0")
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q")
+        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,0,0,0,0,0,0")
                 (match_operand:DI 2 "general_operand"
-                                    "N0HD0,N1HD0,N2HD0,N3HD0,d,m,Q")))
+                                    "N0HD0,N1HD0,N2HD0,N3HD0,d,m,NxQD0,Q")))
    (clobber (reg:CC 33))]
   "TARGET_64BIT && s390_logical_operator_ok_p (operands)"
   "@
    oill\t%0,%i2
    ogr\t%0,%2
    og\t%0,%2
+   #
    oc\t%O0(8,%R0),%2"
-  [(set_attr "op_type"  "RI,RI,RI,RI,RRE,RXY,SS")])
+  [(set_attr "op_type"  "RI,RI,RI,RI,RRE,RXY,SI,SS")])
+
+(define_split
+  [(set (match_operand:DI 0 "s_operand" "")
+        (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
+   (clobber (reg:CC 33))]
+  "reload_completed"
+  [(parallel
+    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
+     (clobber (reg:CC 33))])]
+  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
 
 (define_expand "iordi3"
   [(set (match_operand:DI 0 "nonimmediate_operand" "")
   [(set_attr "op_type"  "RR,RX,RXY")])
 
 (define_insn "*iorsi3_zarch"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,Q")
-        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0,0,0")
-                (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,d,R,T,Q")))
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,AQ,Q")
+        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0,0,0,0")
+                (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,d,R,T,NxQS0,Q")))
    (clobber (reg:CC 33))]
   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
   "@
    or\t%0,%2
    o\t%0,%2
    oy\t%0,%2
+   #
    oc\t%O0(4,%R0),%2"
-  [(set_attr "op_type"  "RI,RI,RR,RX,RXY,SS")])
+  [(set_attr "op_type"  "RI,RI,RR,RX,RXY,SI,SS")])
 
 (define_insn "*iorsi3_esa"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,Q")
-        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0")
-                (match_operand:SI 2 "general_operand" "d,R,Q")))
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
+        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0")
+                (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
    (clobber (reg:CC 33))]
   "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
   "@
    or\t%0,%2
    o\t%0,%2
+   #
    oc\t%O0(4,%R0),%2"
-  [(set_attr "op_type"  "RR,RX,SS")])
+  [(set_attr "op_type"  "RR,RX,SI,SS")])
+
+(define_split
+  [(set (match_operand:SI 0 "s_operand" "")
+        (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
+   (clobber (reg:CC 33))]
+  "reload_completed"
+  [(parallel
+    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
+     (clobber (reg:CC 33))])]
+  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
 
 (define_expand "iorsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "")
 ;
 
 (define_insn "*iorhi3_zarch"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,Q")
-        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
-                (match_operand:HI 2 "general_operand" "d,n,Q")))
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
+        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
+                (match_operand:HI 2 "general_operand" "d,n,NxQH0,Q")))
    (clobber (reg:CC 33))]
   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
   "@
    or\t%0,%2
    oill\t%0,%x2
+   #
    oc\t%O0(2,%R0),%2"
-  [(set_attr "op_type"  "RR,RI,SS")])
+  [(set_attr "op_type"  "RR,RI,SI,SS")])
 
 (define_insn "*iorhi3_esa"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,Q")
-        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
-                (match_operand:HI 2 "general_operand" "d,Q")))
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
+        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
+                (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
    (clobber (reg:CC 33))]
   "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
   "@
    or\t%0,%2
+   #
    oc\t%O0(2,%R0),%2"
-  [(set_attr "op_type"  "RR,SS")])
+  [(set_attr "op_type"  "RR,SI,SS")])
+
+(define_split
+  [(set (match_operand:HI 0 "s_operand" "")
+        (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
+   (clobber (reg:CC 33))]
+  "reload_completed"
+  [(parallel
+    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
+     (clobber (reg:CC 33))])]
+  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
 
 (define_expand "iorhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "")
   [(set_attr "op_type"  "RRE,RXY")])
 
 (define_insn "*xordi3"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,Q")
-        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
-                (match_operand:DI 2 "general_operand" "d,m,Q")))
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,AQ,Q")
+        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
+                (match_operand:DI 2 "general_operand" "d,m,NxQD0,Q")))
    (clobber (reg:CC 33))]
   "TARGET_64BIT && s390_logical_operator_ok_p (operands)"
   "@
    xgr\t%0,%2
    xg\t%0,%2
+   #
    xc\t%O0(8,%R0),%2"
-  [(set_attr "op_type"  "RRE,RXY,SS")])
+  [(set_attr "op_type"  "RRE,RXY,SI,SS")])
+
+(define_split
+  [(set (match_operand:DI 0 "s_operand" "")
+        (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
+   (clobber (reg:CC 33))]
+  "reload_completed"
+  [(parallel
+    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
+     (clobber (reg:CC 33))])]
+  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
 
 (define_expand "xordi3"
   [(set (match_operand:DI 0 "nonimmediate_operand" "")
   [(set_attr "op_type"  "RR,RX,RXY")])
 
 (define_insn "*xorsi3"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,Q")
-        (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
-                (match_operand:SI 2 "general_operand" "d,R,T,Q")))
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,AQ,Q")
+        (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0")
+                (match_operand:SI 2 "general_operand" "d,R,T,NxQS0,Q")))
    (clobber (reg:CC 33))]
   "s390_logical_operator_ok_p (operands)"
   "@
    xr\t%0,%2
    x\t%0,%2
    xy\t%0,%2
+   #
    xc\t%O0(4,%R0),%2"
-  [(set_attr "op_type"  "RR,RX,RXY,SS")])
+  [(set_attr "op_type"  "RR,RX,RXY,SI,SS")])
+
+(define_split
+  [(set (match_operand:SI 0 "s_operand" "")
+        (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
+   (clobber (reg:CC 33))]
+  "reload_completed"
+  [(parallel
+    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
+     (clobber (reg:CC 33))])]
+  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
 
 (define_expand "xorsi3"
   [(set (match_operand:SI 0 "nonimmediate_operand" "")
 ;
 
 (define_insn "*xorhi3"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,Q")
-        (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
-                (match_operand:HI 2 "general_operand" "d,Q")))
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
+        (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
+                (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
    (clobber (reg:CC 33))]
   "s390_logical_operator_ok_p (operands)"
   "@
    xr\t%0,%2
+   #
    xc\t%O0(2,%R0),%2"
-  [(set_attr "op_type"  "RR,SS")])
+  [(set_attr "op_type"  "RR,SI,SS")])
+
+(define_split
+  [(set (match_operand:HI 0 "s_operand" "")
+        (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
+   (clobber (reg:CC 33))]
+  "reload_completed"
+  [(parallel
+    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
+     (clobber (reg:CC 33))])]
+  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
 
 (define_expand "xorhi3"
   [(set (match_operand:HI 0 "nonimmediate_operand" "")