Copyright for 2003.
[gcc.git] / gcc / config / s390 / s390.md
index 905092befa5ed4ca5bec863d7df8e24fd33a12ca..402f2fdb2a3026fb455d8d8a8904404c1774e9dd 100644 (file)
@@ -1,9 +1,9 @@
 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
-;;  Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+;;  Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 ;;  Contributed by Hartmut Penner (hpenner@de.ibm.com) and
 ;;                 Ulrich Weigand (uweigand@de.ibm.com).
 ;; This file is part of GNU CC.
-
 ;; GNU CC is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
 ;; the Free Software Foundation; either version 2, or (at your option)
 ;;   s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
 ;;
 
+;; Processor type.  This attribute must exactly match the processor_type
+;; enumeration in s390.h.
+
+(define_attr "cpu" "g5,g6,z900"
+  (const (symbol_ref "s390_cpu")))
 
 ;; Define an insn type attribute.  This is used in function unit delay
 ;; computations.
 
-(define_attr "type" "none,integer,load,lr,la,lm,stm,cs,vs,store,imul,lmul,fmul,idiv,ldiv,fdiv,branch,jsr,other,o2,o3"
-  (const_string "integer"))
+(define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
+                    cs,vs,store,imul,idiv,
+                    branch,jsr,fsimpd,fsimps,
+                    floadd,floads,fstored, fstores,
+                    fmuld,fmuls,fdivd,fdivs,
+                    ftoi,itof,fsqrtd,fsqrts,
+                     other,o2,o3"
+  (const_string "integer")) 
 
-;; Insn are devide in two classes:
-;;   mem: Insn accessing memory
-;;   reg: Insn operands all in registers
+;; Operand type. Used to default length attribute values
+
+(define_attr "op_type"
+  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE"
+  (const_string "RX"))
 
-(define_attr "atype" "reg,mem"
-  (const_string "reg"))
+;; Insn are devide in two classes:
+;;   agen: Insn using agen
+;;   reg: Insn not using agen
+
+(define_attr "atype" "agen,reg"
+(cond [ (eq_attr "op_type" "E")    (const_string "reg")
+         (eq_attr "op_type" "RR")  (const_string "reg")
+         (eq_attr "op_type" "RX")  (const_string "agen")
+         (eq_attr "op_type" "RI")  (const_string "reg")
+         (eq_attr "op_type" "RRE") (const_string "reg")
+         (eq_attr "op_type" "RS")  (const_string "agen")
+         (eq_attr "op_type" "RSI") (const_string "agen")
+         (eq_attr "op_type" "S")   (const_string "agen")
+         (eq_attr "op_type" "SI")  (const_string "agen")
+         (eq_attr "op_type" "SS")  (const_string "agen")
+         (eq_attr "op_type" "SSE") (const_string "agen")
+         (eq_attr "op_type" "RXE") (const_string "agen")
+         (eq_attr "op_type" "RSE") (const_string "agen")
+         (eq_attr "op_type" "RIL") (const_string "agen")]
+  (const_string "reg")))
 
 ;; Generic pipeline function unit.  
 
 (define_function_unit "integer" 1 0
   (eq_attr "type" "integer") 1 1)
 
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "fsimpd") 1 1)
+
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "fsimps") 1 1)
+
 (define_function_unit "integer" 1 0
   (eq_attr "type" "load") 1 1)
 
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "floadd") 1 1)
+
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "floads") 1 1)
+
 (define_function_unit "integer" 1 0
   (eq_attr "type" "la") 1 1)
 
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "larl") 1 1)
+
 (define_function_unit "integer" 1 0
   (eq_attr "type" "lr") 1 1)
 
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "branch") 1 1)
+
 (define_function_unit "integer" 1 0
   (eq_attr "type" "store") 1 1)
 
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "fstored") 1 1)
+
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "fstores") 1 1)
+
 (define_function_unit "integer" 1 0
   (eq_attr "type" "lm") 2 2)
 
   (eq_attr "type" "imul") 7 7)
 
 (define_function_unit "integer" 1 0
-  (eq_attr "type" "fmul") 6 6)
+  (eq_attr "type" "fmuld") 6 6)
+
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "fmuls") 6 6)
 
 (define_function_unit "integer" 1 0
   (eq_attr "type" "idiv") 33 33)
 
 (define_function_unit "integer" 1 0
-  (eq_attr "type" "fdiv") 33 33)
+  (eq_attr "type" "fdivd") 33 33)
+
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "fdivs") 33 33)
+
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "fsqrtd") 30 30)
+
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "fsqrts") 30 30)
+
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "ftoi") 2 2)
+
+(define_function_unit "integer" 1 0
+  (eq_attr "type" "itof") 2 2)
 
 (define_function_unit "integer" 1 0
   (eq_attr "type" "o2") 2 2)
 (define_function_unit "integer" 1 0
   (eq_attr "type" "other") 5 5)
 
-;; Operand type. Used to default length attribute values
+;; Pipeline description for z900
 
-(define_attr "op_type"
-  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE"
-  (const_string "RX"))
+(include "2064.md")
 
 ;; Length in bytes.
 
          (eq_attr "op_type" "RRE") (const_int 4)
          (eq_attr "op_type" "RS")  (const_int 4)
          (eq_attr "op_type" "RSI") (const_int 4)
-         (eq_attr "op_type" "RX")  (const_int 4)
          (eq_attr "op_type" "S")   (const_int 4)
          (eq_attr "op_type" "SI")  (const_int 4)
          (eq_attr "op_type" "SS")  (const_int 6)
   DONE;
 }")
 
-;(define_expand "cmphi"
-;  [(set (reg:CC 33)
-;        (compare:CC (match_operand:HI 0 "register_operand" "")
-;                    (match_operand:HI 1 "general_operand" "")))]
-;  ""
-;  "
-;{
-;  s390_compare_op0 = operands[0];
-;  s390_compare_op1 = operands[1];
-;  DONE;
-;}")
-
-;(define_expand "cmpqi"
-;  [(set (reg:CC 33)
-;        (compare:CC (match_operand:QI 0 "register_operand" "")
-;                    (match_operand:QI 1 "general_operand" "")))]
-;  ""
-;  "
-;{
-;  s390_compare_op0 = operands[0];
-;  s390_compare_op1 = operands[1];
-;  DONE;
-;}")
-
 (define_expand "cmpdf"
   [(set (reg:CC 33)
         (compare:CC (match_operand:DF 0 "register_operand" "")
 }")
 
 
-; DI instructions
+; Test-under-Mask (zero_extract) instructions
 
-(define_insn "*cmpdi_tm2"
+(define_insn "*tmdi_ext"
   [(set (reg 33)
         (compare (zero_extract:DI (match_operand:DI 0 "register_operand" "d")
                                  (match_operand:DI 1 "const_int_operand" "n")
 }"
   [(set_attr "op_type" "RI")])
 
-(define_insn "*cmpdi_tm_reg"
+(define_insn "*tmsi_ext"
   [(set (reg 33)
-        (compare (and:DI (match_operand:DI 0 "register_operand" "%d")
-                         (match_operand:DI 1 "immediate_operand" "n"))
+        (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
+                                 (match_operand:SI 1 "const_int_operand" "n")
+                                  (match_operand:SI 2 "const_int_operand" "n"))
                  (const_int 0)))]
-  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
-   && s390_single_hi (operands[1], DImode, 0) >= 0"
+  "s390_match_ccmode(insn, CCTmode)
+   && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 
+   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
+   && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
+      == INTVAL (operands[2]) >> 4"
   "*
 {
-  int part = s390_single_hi (operands[1], DImode, 0);
-  operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
+  int part = INTVAL (operands[2]) >> 4;
+  int block = (1 << INTVAL (operands[1])) - 1;
+  int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15);
+
+  operands[2] = GEN_INT (block << shift);
 
   switch (part)
     {
-      case 0: return \"tmhh\\t%0,%x1\";
-      case 1: return \"tmhl\\t%0,%x1\";
-      case 2: return \"tmlh\\t%0,%x1\";
-      case 3: return \"tmll\\t%0,%x1\";
+      case 0: return \"tmh\\t%0,%x2\";
+      case 1: return \"tml\\t%0,%x2\";
       default: abort ();
     }
 }"
   [(set_attr "op_type" "RI")])
 
-(define_insn "*cmpdi_tm_mem"
+(define_insn "*tmqi_ext"
   [(set (reg 33)
-        (compare (and:DI (match_operand:DI 0 "s_operand" "%Qo")
-                         (match_operand:DI 1 "immediate_operand" "n"))
+        (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q")
+                                 (match_operand:SI 1 "const_int_operand" "n")
+                                  (match_operand:SI 2 "const_int_operand" "n"))
                  (const_int 0)))]
-  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
+  "s390_match_ccmode(insn, CCTmode)
+   && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 
+   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8"
+  "*
+{
+  int block = (1 << INTVAL (operands[1])) - 1;
+  int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]);
+
+  operands[2] = GEN_INT (block << shift);
+  return \"tm\\t%0,%b2\";
+}"
+  [(set_attr "op_type" "SI")])
+
+; Test-under-Mask instructions
+
+(define_insn "*tmdi_mem"
+  [(set (reg 33)
+        (compare (and:DI (match_operand:DI 0 "memory_operand" "Q")
+                         (match_operand:DI 1 "immediate_operand" "n"))
+                 (match_operand:DI 2 "immediate_operand" "n")))]
+  "TARGET_64BIT
+   && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
    && s390_single_qi (operands[1], DImode, 0) >= 0"
   "*
 {
                             plus_constant (XEXP (operands[0], 0), part));
   return \"tm\\t%0,%b1\";
 }"
-  [(set_attr "op_type" "SI")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "SI")])
 
-(define_insn "*ltgr"
+(define_insn "*tmsi_mem"
   [(set (reg 33)
-        (compare (match_operand:DI 0 "register_operand" "d")
-                 (match_operand:DI 1 "const0_operand" "")))
-   (set (match_operand:DI 2 "register_operand" "=d")
-        (match_dup 0))]
-  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
-  "ltgr\\t%2,%0"
-  [(set_attr "op_type" "RRE")])
+        (compare (and:SI (match_operand:SI 0 "memory_operand" "Q")
+                         (match_operand:SI 1 "immediate_operand" "n"))
+                 (match_operand:SI 2 "immediate_operand" "n")))]
+  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
+   && s390_single_qi (operands[1], SImode, 0) >= 0"
+  "*
+{
+  int part = s390_single_qi (operands[1], SImode, 0);
+  operands[1] = GEN_INT (s390_extract_qi (operands[1], SImode, part));
 
-(define_insn "*cmpdi_ccs_0_64"
-  [(set (reg 33)
-        (compare (match_operand:DI 0 "register_operand" "d")
-                 (match_operand:DI 1 "const0_operand" "")))]
-  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
-  "ltgr\\t%0,%0"
-  [(set_attr "op_type" "RRE")])
+  operands[0] = gen_rtx_MEM (QImode, 
+                            plus_constant (XEXP (operands[0], 0), part));
+  return \"tm\\t%0,%b1\";
+}"
+  [(set_attr "op_type" "SI")])
 
-(define_insn "*cmpdi_ccs_0_31"
+(define_insn "*tmhi_mem"
   [(set (reg 33)
-        (compare (match_operand:DI 0 "register_operand" "d")
-                 (match_operand:DI 1 "const0_operand" "")))]
-  "s390_match_ccmode(insn, CCSmode)"
-  "srda\\t%0,0"
-  [(set_attr "op_type" "RS")])
+        (compare (and:SI (subreg:SI (match_operand:HI 0 "memory_operand" "Q") 0)
+                         (match_operand:SI 1 "immediate_operand" "n"))
+                 (match_operand:SI 2 "immediate_operand" "n")))]
+  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
+   && s390_single_qi (operands[1], HImode, 0) >= 0"
+  "*
+{
+  int part = s390_single_qi (operands[1], HImode, 0);
+  operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part));
 
-(define_insn "*cmpdi_ccs"
-  [(set (reg 33)
-        (compare (match_operand:DI 0 "register_operand" "d,d,d")
-                 (match_operand:DI 1 "general_operand" "d,K,m")))]
-  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
-  "@
-   cgr\\t%0,%1
-   cghi\\t%0,%c1
-   cg\\t%0,%1"
-  [(set_attr "op_type" "RRE,RI,RXE")
-   (set_attr "atype"    "reg,reg,mem")])
-   
-(define_insn "*cmpdi_ccu"
-  [(set (reg 33)
-        (compare (match_operand:DI 0 "register_operand" "d,d")
-                 (match_operand:DI 1 "general_operand" "d,m")))]
-  "s390_match_ccmode(insn, CCUmode) && TARGET_64BIT"
-  "@
-   clgr\\t%0,%1
-   clg\\t%0,%1"
-  [(set_attr "op_type" "RRE,RXE")
-   (set_attr "atype"   "reg,mem")])
+  operands[0] = gen_rtx_MEM (QImode, 
+                            plus_constant (XEXP (operands[0], 0), part));
+  return \"tm\\t%0,%b1\";
+}"
+  [(set_attr "op_type" "SI")])
 
-(define_insn "*cmpdi_ccu_mem"
+(define_insn "*tmqi_mem"
   [(set (reg 33)
-        (compare (match_operand:DI 0 "s_operand" "oQ")
-                 (match_operand:DI 1 "s_imm_operand" "oQ")))]
-  "s390_match_ccmode(insn, CCUmode)"
-  "clc\\t%O0(8,%R0),%1"
-  [(set_attr "op_type" "SS")
-   (set_attr "atype"   "mem")])
-
-; SI instructions
+        (compare (and:SI (subreg:SI (match_operand:QI 0 "memory_operand" "Q") 0)
+                         (match_operand:SI 1 "immediate_operand" "n"))
+                 (match_operand:SI 2 "immediate_operand" "n")))]
+  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))"
+  "tm\\t%0,%b1"
+  [(set_attr "op_type" "SI")])
 
-(define_insn "*cmpsi_tm2"
+(define_insn "*tmdi_reg"
   [(set (reg 33)
-        (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
-                                 (match_operand:SI 1 "const_int_operand" "n")
-                                  (match_operand:SI 2 "const_int_operand" "n"))
-                 (const_int 0)))]
-  "s390_match_ccmode(insn, CCTmode)
-   && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 
-   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
-   && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
-      == INTVAL (operands[2]) >> 4"
+        (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d")
+                         (match_operand:DI 1 "immediate_operand" "n"))
+                 (match_operand:DI 2 "immediate_operand" "n")))]
+  "TARGET_64BIT
+   && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
+   && s390_single_hi (operands[1], DImode, 0) >= 0"
   "*
 {
-  int part = INTVAL (operands[2]) >> 4;
-  int block = (1 << INTVAL (operands[1])) - 1;
-  int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15);
-
-  operands[2] = GEN_INT (block << shift);
+  int part = s390_single_hi (operands[1], DImode, 0);
+  operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
 
   switch (part)
     {
-      case 0: return \"tmh\\t%0,%x2\";
-      case 1: return \"tml\\t%0,%x2\";
+      case 0: return \"tmhh\\t%0,%x1\";
+      case 1: return \"tmhl\\t%0,%x1\";
+      case 2: return \"tmlh\\t%0,%x1\";
+      case 3: return \"tmll\\t%0,%x1\";
       default: abort ();
     }
 }"
   [(set_attr "op_type" "RI")])
 
-(define_insn "*cmpsi_tm_reg"
+(define_insn "*tmsi_reg"
   [(set (reg 33)
-        (compare (and:SI (match_operand:SI 0 "register_operand" "%d")
+        (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d")
                          (match_operand:SI 1 "immediate_operand" "n"))
-                 (const_int 0)))]
-  "s390_match_ccmode(insn, CCTmode)
+                 (match_operand:SI 2 "immediate_operand" "n")))]
+  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
    && s390_single_hi (operands[1], SImode, 0) >= 0"
   "*
 {
 }"
   [(set_attr "op_type" "RI")])
 
-(define_insn "*cmpsi_tm_mem"
+(define_insn "*tmhi_full"
   [(set (reg 33)
-        (compare (and:SI (match_operand:SI 0 "s_operand" "%Qo")
-                         (match_operand:SI 1 "immediate_operand" "n"))
-                 (const_int 0)))]
-  "s390_match_ccmode(insn, CCTmode)
-   && s390_single_qi (operands[1], SImode, 0) >= 0"
-  "*
-{
-  int part = s390_single_qi (operands[1], SImode, 0);
-  operands[1] = GEN_INT (s390_extract_qi (operands[1], SImode, part));
+        (compare (match_operand:HI 0 "register_operand" "d")
+                 (match_operand:HI 1 "immediate_operand" "n")))]
+  "s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1], 1))"
+  "tml\\t%0,65535"
+  [(set_attr "op_type" "RX")])
+
+(define_insn "*tmqi_full"
+  [(set (reg 33)
+        (compare (match_operand:QI 0 "register_operand" "d")
+                 (match_operand:QI 1 "immediate_operand" "n")))]
+  "s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1], 1))"
+  "tml\\t%0,255"
+  [(set_attr "op_type" "RI")])
 
-  operands[0] = gen_rtx_MEM (QImode, 
-                            plus_constant (XEXP (operands[0], 0), part));
-  return \"tm\\t%0,%b1\";
-}"
-  [(set_attr "op_type" "SI")
-   (set_attr "atype"   "mem")])
 
-(define_insn "*ltr"
+; Load-and-Test instructions
+
+(define_insn "*tstdi_sign"
   [(set (reg 33)
-        (compare (match_operand:SI 0 "register_operand" "d")
-                 (match_operand:SI 1 "const0_operand" "")))
-   (set (match_operand:SI 2 "register_operand" "=d")
+        (compare (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 0 "register_operand" "d") 0)
+                                        (const_int 32)) (const_int 32))
+                 (match_operand:DI 1 "const0_operand" "")))
+   (set (match_operand:DI 2 "register_operand" "=d")
+        (sign_extend:DI (match_dup 0)))]
+  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
+  "ltgfr\\t%2,%0"
+  [(set_attr "op_type" "RRE")])
+
+(define_insn "*tstdi"
+  [(set (reg 33)
+        (compare (match_operand:DI 0 "register_operand" "d")
+                 (match_operand:DI 1 "const0_operand" "")))
+   (set (match_operand:DI 2 "register_operand" "=d")
         (match_dup 0))]
-  "s390_match_ccmode(insn, CCSmode)"
-  "ltr\\t%2,%0"
-  [(set_attr "op_type" "RR")])
+  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
+  "ltgr\\t%2,%0"
+  [(set_attr "op_type" "RRE")])
+
+(define_insn "*tstdi_cconly"
+  [(set (reg 33)
+        (compare (match_operand:DI 0 "register_operand" "d")
+                 (match_operand:DI 1 "const0_operand" "")))]
+  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
+  "ltgr\\t%0,%0"
+  [(set_attr "op_type" "RRE")])
 
-(define_insn "*icm15"
+(define_insn "*tstdi_cconly_31"
   [(set (reg 33)
-        (compare (match_operand:SI 0 "s_operand" "Qo")
+        (compare (match_operand:DI 0 "register_operand" "d")
+                 (match_operand:DI 1 "const0_operand" "")))]
+  "s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT"
+  "srda\\t%0,0"
+  [(set_attr "op_type" "RS")
+   (set_attr "atype"   "reg")])
+
+
+(define_insn "*tstsi"
+  [(set (reg 33)
+        (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q")
                  (match_operand:SI 1 "const0_operand" "")))
-   (set (match_operand:SI 2 "register_operand" "=d")
+   (set (match_operand:SI 2 "register_operand" "=d,d")
         (match_dup 0))]
   "s390_match_ccmode(insn, CCSmode)"
-  "icm\\t%2,15,%0"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+  "@
+   ltr\\t%2,%0
+   icm\\t%2,15,%0"
+  [(set_attr "op_type" "RR,RS")])
 
-(define_insn "*icm15_cconly"
+(define_insn "*tstsi_cconly"
   [(set (reg 33)
-        (compare (match_operand:SI 0 "s_operand" "Qo")
+        (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q")
                  (match_operand:SI 1 "const0_operand" "")))
-   (clobber (match_scratch:SI 2 "=d"))]
+   (clobber (match_scratch:SI 2 "=X,d"))]
   "s390_match_ccmode(insn, CCSmode)"
-  "icm\\t%2,15,%0"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+  "@
+   ltr\\t%0,%0
+   icm\\t%2,15,%0"
+  [(set_attr "op_type" "RR,RS")])
 
-(define_insn "*cmpsi_ccs_0"
+(define_insn "*tstsi_cconly2"
   [(set (reg 33)
         (compare (match_operand:SI 0 "register_operand" "d")
                  (match_operand:SI 1 "const0_operand" "")))]
   "ltr\\t%0,%0"
   [(set_attr "op_type" "RR")])
 
-(define_insn "*cmpsidi_ccs"
+(define_insn "*tsthiCCT"
   [(set (reg 33)
-        (compare (match_operand:SI 0 "register_operand" "d")
-                 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))))]
-  "s390_match_ccmode(insn, CCSmode)"
-  "ch\\t%0,%1"
-  [(set_attr "op_type" "RR")
-   (set_attr "atype"   "mem")])
-
-(define_insn "*cmpsi_ccs"
-  [(set (reg 33)
-        (compare (match_operand:SI 0 "register_operand" "d,d,d")
-                 (match_operand:SI 1 "general_operand" "d,K,m")))]
-  "s390_match_ccmode(insn, CCSmode)"
-  "@
-   cr\\t%0,%1
-   chi\\t%0,%c1
-   c\\t%0,%1"
-  [(set_attr "op_type" "RR,RI,RX")
-   (set_attr "atype"   "reg,reg,mem")])
-   
-(define_insn "*cmpsi_ccu"
-  [(set (reg 33)
-        (compare (match_operand:SI 0 "register_operand" "d,d")
-                 (match_operand:SI 1 "general_operand" "d,m")))]
-  "s390_match_ccmode(insn, CCUmode)"
+        (compare (match_operand:HI 0 "nonimmediate_operand" "?Q,d")
+                 (match_operand:HI 1 "const0_operand" "")))
+   (set (match_operand:HI 2 "register_operand" "=d,0")
+        (match_dup 0))]
+  "s390_match_ccmode(insn, CCTmode)"
   "@
-   clr\\t%0,%1
-   cl\\t%0,%1"
-  [(set_attr "op_type" "RR,RX")
-   (set_attr "atype"   "reg,mem")])
-
-(define_insn "*cmpsi_ccu_mem"
-  [(set (reg 33)
-        (compare (match_operand:SI 0 "s_operand" "oQ")
-                 (match_operand:SI 1 "s_imm_operand" "oQ")))]
-  "s390_match_ccmode(insn, CCUmode)"
-  "clc\\t%O0(4,%R0),%1"
-   [(set_attr "op_type" "SS")
-    (set_attr "atype"   "mem")])
-
+   icm\\t%2,3,%0
+   tml\\t%0,65535"
+  [(set_attr "op_type" "RS,RI")])
 
-; HI instructions
-
-(define_insn "*cmphi_tm_sub"
+(define_insn "*tsthiCCT_cconly"
   [(set (reg 33)
-        (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Qo") 0)
-                         (match_operand:SI 1 "immediate_operand" "n"))
-                 (const_int 0)))]
-  "s390_match_ccmode(insn, CCTmode)
-   && s390_single_qi (operands[1], HImode, 0) >= 0"
-  "*
-{
-  int part = s390_single_qi (operands[1], HImode, 0);
-  operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part));
-
-  operands[0] = gen_rtx_MEM (QImode, 
-                            plus_constant (XEXP (operands[0], 0), part));
-  return \"tm\\t%0,%b1\";
-}"
-  [(set_attr "op_type" "SI")
-   (set_attr "atype"   "mem")])
+        (compare (match_operand:HI 0 "nonimmediate_operand" "?Q,d")
+                 (match_operand:HI 1 "const0_operand" "")))
+   (clobber (match_scratch:HI 2 "=d,X"))]
+  "s390_match_ccmode(insn, CCTmode)"
+  "@
+   icm\\t%2,3,%0
+   tml\\t%0,65535"
+  [(set_attr "op_type" "RS,RI")])
 
-(define_insn "*icm3"
+(define_insn "*tsthi"
   [(set (reg 33)
-        (compare (match_operand:HI 0 "s_operand" "Qo")
+        (compare (match_operand:HI 0 "s_operand" "Q")
                  (match_operand:HI 1 "const0_operand" "")))
    (set (match_operand:HI 2 "register_operand" "=d")
         (match_dup 0))]
   "s390_match_ccmode(insn, CCSmode)"
   "icm\\t%2,3,%0"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
-
-(define_insn "*cmphi_cct_0"
-  [(set (reg 33)
-        (compare (match_operand:HI 0 "register_operand" "d")
-                 (match_operand:HI 1 "const0_operand"   "")))]
-  "s390_match_ccmode(insn, CCTmode)"
-  "tml\\t%0,65535"
-  [(set_attr "op_type" "RX")])
+  [(set_attr "op_type" "RS")])
 
-(define_insn "*cmphi_ccs_0"
+(define_insn "*tsthi_cconly"
   [(set (reg 33)
-        (compare (match_operand:HI 0 "s_operand" "Qo")
+        (compare (match_operand:HI 0 "s_operand" "Q")
                  (match_operand:HI 1 "const0_operand" "")))
    (clobber (match_scratch:HI 2 "=d"))]
   "s390_match_ccmode(insn, CCSmode)"
   "icm\\t%2,3,%0"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RS")])
 
-(define_insn "*cmphi_ccu"
+(define_insn "*tstqiCCT"
   [(set (reg 33)
-        (compare (match_operand:HI 0 "register_operand" "d")
-                 (match_operand:HI 1 "s_imm_operand" "Qo")))]
-  "s390_match_ccmode(insn, CCUmode)"
-  "clm\\t%0,3,%1"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+        (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,d")
+                 (match_operand:QI 1 "const0_operand" "")))
+   (set (match_operand:QI 2 "register_operand" "=d,0")
+        (match_dup 0))]
+  "s390_match_ccmode(insn, CCTmode)"
+  "@
+   icm\\t%2,1,%0
+   tml\\t%0,255"
+  [(set_attr "op_type" "RS,RI")])
 
-(define_insn "*cmphi_ccu_mem"
+(define_insn "*tstqiCCT_cconly"
   [(set (reg 33)
-        (compare (match_operand:HI 0 "s_operand" "oQ")
-                 (match_operand:HI 1 "s_imm_operand" "oQ")))]
-  "s390_match_ccmode(insn, CCUmode)"
-  "clc\\t%O0(2,%R0),%1"
-  [(set_attr "op_type" "SS")
-   (set_attr "atype"   "mem")])
-
+        (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,d")
+                 (match_operand:QI 1 "const0_operand" "")))]
+  "s390_match_ccmode(insn, CCTmode)"
+  "@
+   cli\\t%0,0
+   tml\\t%0,255"
+  [(set_attr "op_type" "SI,RI")])
 
-; QI instructions
+(define_insn "*tstqi"
+  [(set (reg 33)
+        (compare (match_operand:QI 0 "s_operand" "Q")
+                 (match_operand:QI 1 "const0_operand" "")))
+   (set (match_operand:QI 2 "register_operand" "=d")
+        (match_dup 0))]
+  "s390_match_ccmode(insn, CCSmode)"
+  "icm\\t%2,1,%0"
+  [(set_attr "op_type" "RS")])
 
-(define_insn "*cmpqi_tm2"
+(define_insn "*tstqi_cconly"
   [(set (reg 33)
-        (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Qo")
-                                 (match_operand:SI 1 "const_int_operand" "n")
-                                  (match_operand:SI 2 "const_int_operand" "n"))
-                 (const_int 0)))]
-  "s390_match_ccmode(insn, CCTmode)
-   && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 
-   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8"
-  "*
-{
-  int block = (1 << INTVAL (operands[1])) - 1;
-  int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]);
+        (compare (match_operand:QI 0 "s_operand" "Q")
+                 (match_operand:QI 1 "const0_operand" "")))
+   (clobber (match_scratch:QI 2 "=d"))]
+  "s390_match_ccmode(insn, CCSmode)"
+  "icm\\t%2,1,%0"
+  [(set_attr "op_type" "RS")])
 
-  operands[2] = GEN_INT (block << shift);
-  return \"tm\\t%0,%b2\";
-}"
-  [(set_attr "op_type" "SI")
-   (set_attr "atype"   "mem")])
+; Compare (signed) instructions
 
-(define_insn "*cmpqi_tm"
+(define_insn "*cmpdi_ccs_sign"
   [(set (reg 33)
-        (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,Q")
-                         (match_operand:QI 1 "immediate_operand" "n,n"))
-                 (const_int 0)))]
-  "s390_match_ccmode(insn, CCTmode)"
+        (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
+                 (match_operand:DI 0 "register_operand" "d,d")))]
+  "s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT"
   "@
-   tml\\t%0,%b1
-   tm\\t%0,%b1"
-  [(set_attr "op_type" "RI,SI")
-   (set_attr "atype"   "reg,mem")])
+   cgfr\\t%0,%1
+   cgf\\t%0,%1"
+  [(set_attr "op_type" "RRE,RXE")])
 
-(define_insn "*cmpqi_tm_sub"
+(define_insn "*cmpdi_ccs"
   [(set (reg 33)
-        (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Qo") 0)
-                         (match_operand:SI 1 "immediate_operand" "n"))
-                 (const_int 0)))]
-  "s390_match_ccmode(insn, CCTmode)"
-  "tm\\t%0,%b1"
-  [(set_attr "op_type" "SI")
-   (set_attr "atype"   "mem")])
+        (compare (match_operand:DI 0 "register_operand" "d,d,d")
+                 (match_operand:DI 1 "general_operand" "d,K,m")))]
+  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
+  "@
+   cgr\\t%0,%1
+   cghi\\t%0,%c1
+   cg\\t%0,%1"
+  [(set_attr "op_type" "RRE,RI,RXE")])
+   
+(define_insn "*cmpsi_ccs_sign"
+  [(set (reg 33)
+        (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))
+                 (match_operand:SI 0 "register_operand" "d")))]
+  "s390_match_ccmode(insn, CCSRmode)"
+  "ch\\t%0,%1"
+  [(set_attr "op_type" "RX")])
 
-(define_insn "*icm1"
+(define_insn "*cmpsi_ccs"
   [(set (reg 33)
-        (compare (match_operand:QI 0 "s_operand" "Qo")
-                 (match_operand:QI 1 "const0_operand" "")))
-   (set (match_operand:QI 2 "register_operand" "=d")
-        (match_dup 0))]
+        (compare (match_operand:SI 0 "register_operand" "d,d,d")
+                 (match_operand:SI 1 "general_operand" "d,K,m")))]
   "s390_match_ccmode(insn, CCSmode)"
-  "icm\\t%2,1,%0"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+  "@
+   cr\\t%0,%1
+   chi\\t%0,%c1
+   c\\t%0,%1"
+  [(set_attr "op_type" "RR,RI,RX")])
+   
 
-(define_insn "*tm_0"
+; Compare (unsigned) instructions
+
+(define_insn "*cmpdi_ccu_zero"
   [(set (reg 33)
-        (compare (zero_extend:SI (and:QI (match_operand:QI 0 "s_operand" "Qo")
-                                         (match_operand:QI 1 "immediate_operand" "")))
-                 (const_int 0)))]
-  "s390_match_ccmode(insn, CCTmode) &&
-   INTVAL(operands[1]) >= 0 && INTVAL(operands[1]) < 256"
-  "tm\\t%0,%1"
-  [(set_attr "op_type" "RI")
-   (set_attr "atype"   "mem")])
+        (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
+                 (match_operand:DI 0 "register_operand" "d,d")))]
+  "s390_match_ccmode(insn, CCURmode) && TARGET_64BIT"
+  "@
+   clgfr\\t%0,%1
+   clgf\\t%0,%1"
+  [(set_attr "op_type" "RRE,RXE")])
 
-(define_insn "*cmpqi_cct_0"
+(define_insn "*cmpdi_ccu"
   [(set (reg 33)
-        (compare (match_operand:QI 0 "register_operand" "d")
-                 (match_operand:QI 1 "const0_operand"   "")))]
-  "s390_match_ccmode(insn, CCTmode)"
-  "tml\\t%0,255"
-  [(set_attr "op_type" "RI")])
+        (compare (match_operand:DI 0 "register_operand" "d,d")
+                 (match_operand:DI 1 "general_operand" "d,m")))]
+  "s390_match_ccmode(insn, CCUmode) && TARGET_64BIT"
+  "@
+   clgr\\t%0,%1
+   clg\\t%0,%1"
+  [(set_attr "op_type" "RRE,RXE")])
 
-(define_insn "*cmpqi_ccs_0"
+(define_insn "*cmpsi_ccu"
   [(set (reg 33)
-        (compare (match_operand:QI 0 "s_operand" "Qo")
-                 (match_operand:QI 1 "const0_operand" "")))
-   (clobber (match_scratch:QI 2 "=d"))]
-  "s390_match_ccmode(insn, CCSmode)"
-  "icm\\t%2,1,%0"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+        (compare (match_operand:SI 0 "register_operand" "d,d")
+                 (match_operand:SI 1 "general_operand" "d,m")))]
+  "s390_match_ccmode(insn, CCUmode)"
+  "@
+   clr\\t%0,%1
+   cl\\t%0,%1"
+  [(set_attr "op_type" "RR,RX")])
 
-(define_insn "*cmpqi_ccu_0"
+(define_insn "*cmphi_ccu"
   [(set (reg 33)
-        (compare (match_operand:QI 0 "s_operand"      "Qo")
-                 (match_operand:QI 1 "const0_operand" "")))]
+        (compare (match_operand:HI 0 "register_operand" "d")
+                 (match_operand:HI 1 "s_imm_operand" "Q")))]
   "s390_match_ccmode(insn, CCUmode)"
-  "cli\\t%0,0"
-  [(set_attr "op_type" "SI")
-   (set_attr "atype"   "mem")])
+  "clm\\t%0,3,%1"
+  [(set_attr "op_type" "RS")])
 
 (define_insn "*cmpqi_ccu"
   [(set (reg 33)
         (compare (match_operand:QI 0 "register_operand" "d")
-                 (match_operand:QI 1 "s_imm_operand" "Qo")))]
+                 (match_operand:QI 1 "s_imm_operand" "Q")))]
   "s390_match_ccmode(insn, CCUmode)"
   "clm\\t%0,1,%1"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RS")])
+
+(define_insn "*cli"
+  [(set (reg 33)
+        (compare (match_operand:QI 0 "memory_operand" "Q")
+                 (match_operand:QI 1 "immediate_operand" "n")))]
+  "s390_match_ccmode (insn, CCUmode)"
+  "cli\\t%0,%b1"
+  [(set_attr "op_type" "SI")])
+
+(define_insn "*cmpdi_ccu_mem"
+  [(set (reg 33)
+        (compare (match_operand:DI 0 "s_operand" "Q")
+                 (match_operand:DI 1 "s_imm_operand" "Q")))]
+  "s390_match_ccmode(insn, CCUmode)"
+  "clc\\t%O0(8,%R0),%1"
+  [(set_attr "op_type" "SS")])
 
-(define_insn "*cmpqi_ccu_immed"
+(define_insn "*cmpsi_ccu_mem"
   [(set (reg 33)
-        (compare (match_operand:QI 0 "s_operand" "Qo")
-                 (match_operand:QI 1 "const_int_operand" "n")))]
-  "s390_match_ccmode(insn, CCUmode) &&
-   INTVAL(operands[1]) >= 0 && INTVAL(operands[1]) < 256"
-  "cli\\t%0,%1"
-  [(set_attr "op_type" "SI")
-   (set_attr "atype"   "mem")])
+        (compare (match_operand:SI 0 "s_operand" "Q")
+                 (match_operand:SI 1 "s_imm_operand" "Q")))]
+  "s390_match_ccmode(insn, CCUmode)"
+  "clc\\t%O0(4,%R0),%1"
+   [(set_attr "op_type" "SS")])
+
+(define_insn "*cmphi_ccu_mem"
+  [(set (reg 33)
+        (compare (match_operand:HI 0 "s_operand" "Q")
+                 (match_operand:HI 1 "s_imm_operand" "Q")))]
+  "s390_match_ccmode(insn, CCUmode)"
+  "clc\\t%O0(2,%R0),%1"
+  [(set_attr "op_type" "SS")])
 
 (define_insn "*cmpqi_ccu_mem"
   [(set (reg 33)
-        (compare (match_operand:QI 0 "s_operand" "oQ")
-                 (match_operand:QI 1 "s_imm_operand" "oQ")))]
+        (compare (match_operand:QI 0 "s_operand" "Q")
+                 (match_operand:QI 1 "s_imm_operand" "Q")))]
   "s390_match_ccmode(insn, CCUmode)"
   "clc\\t%O0(1,%R0),%1"
-  [(set_attr "op_type" "SS")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "SS")])
 
 
 ; DF instructions
                  (match_operand:DF 1 "const0_operand" "")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "ltdbr\\t%0,%0"
-   [(set_attr "op_type" "RR")])
+   [(set_attr "op_type" "RRE")
+    (set_attr "type"  "fsimpd")])
 
 (define_insn "*cmpdf_ccs_0_ibm"
   [(set (reg 33)
                  (match_operand:DF 1 "const0_operand" "")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "ltdr\\t%0,%0"
-   [(set_attr "op_type" "RR")])
+   [(set_attr "op_type" "RR")
+    (set_attr "type"  "fsimpd")])
 
 (define_insn "*cmpdf_ccs"
   [(set (reg 33)
   "@
    cdbr\\t%0,%1
    cdb\\t%0,%1"
-   [(set_attr "op_type" "RR,RX")
-    (set_attr "atype"   "reg,mem")])  
+   [(set_attr "op_type" "RRE,RXE")
+    (set_attr "type"  "fsimpd")])
 
 (define_insn "*cmpdf_ccs_ibm"
   [(set (reg 33)
    cdr\\t%0,%1
    cd\\t%0,%1"
    [(set_attr "op_type" "RR,RX")
-    (set_attr "atype"   "reg,mem")])  
+    (set_attr "type"  "fsimpd")])
 
 
 ; SF instructions
                  (match_operand:SF 1 "const0_operand" "")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "ltebr\\t%0,%0"
-   [(set_attr "op_type" "RR")])
+   [(set_attr "op_type" "RRE")
+    (set_attr "type"  "fsimps")])
 
 (define_insn "*cmpsf_ccs_0_ibm"
   [(set (reg 33)
                  (match_operand:SF 1 "const0_operand" "")))]
   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "lter\\t%0,%0"
-   [(set_attr "op_type" "RR")])
+   [(set_attr "op_type" "RR")
+    (set_attr "type"  "fsimps")])
 
 (define_insn "*cmpsf_ccs"
   [(set (reg 33)
   "@
    cebr\\t%0,%1
    ceb\\t%0,%1"
-  [(set_attr "op_type" "RR,RX")
-   (set_attr "atype"   "reg,mem")])
+   [(set_attr "op_type" "RRE,RXE")
+    (set_attr "type"  "fsimps")])
 
 (define_insn "*cmpsf_ccs"
   [(set (reg 33)
   "@
    cer\\t%0,%1
    ce\\t%0,%1"
-  [(set_attr "op_type" "RR,RX")
-   (set_attr "atype"   "reg,mem")])
+   [(set_attr "op_type" "RR,RX")
+    (set_attr "type"  "fsimps")])
 
 
 ;;
 ; movti instruction pattern(s).
 ;
 
-(define_insn "*movti_ss"
-  [(set (match_operand:TI 0 "s_operand" "=Qo")
-        (match_operand:TI 1 "s_imm_operand" "Qo"))]
-  ""
-  "mvc\\t%O0(16,%R0),%1"       
-  [(set_attr "op_type" "SS")
-   (set_attr "atype"   "mem")])
-
 (define_insn "movti"
-  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,Q,d,m")
-        (match_operand:TI 1 "general_operand" "Q,d,dKm,d"))]
+  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,Q,d,m,Q")
+        (match_operand:TI 1 "general_operand" "Q,d,dKm,d,Q"))]
   "TARGET_64BIT"
   "@
    lmg\\t%0,%N0,%1
    stmg\\t%1,%N1,%0
    #
-   #"
-  [(set_attr "op_type" "RSE,RSE,NN,NN")
-   (set_attr "atype"   "mem")])
+   #
+   mvc\\t%O0(16,%R0),%1"
+  [(set_attr "op_type" "RSE,RSE,NN,NN,SS")])
 
 (define_split
   [(set (match_operand:TI 0 "nonimmediate_operand" "")
         (match_operand:TI 1 "memory_operand" ""))]
   "TARGET_64BIT && reload_completed
    && !s_operand (operands[1], VOIDmode)"
-  [(set (match_dup 2) (match_dup 3))
-   (set (match_dup 0) (mem:TI (match_dup 2)))]
-  "operands[2] = operand_subword (operands[0], 1, 0, TImode);
-   operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
+  [(set (match_dup 0) (match_dup 1))]
+  "
+{
+  rtx addr = operand_subword (operands[0], 1, 0, TImode);
+  s390_load_address (addr, XEXP (operands[1], 0));
+  operands[1] = replace_equiv_address (operands[1], addr);
+}")
 
 ;
 ; movdi instruction pattern(s).
   if ((reload_in_progress || reload_completed)
       && CONSTANT_P (operands[1]) 
       && (!legitimate_reload_constant_p (operands[1])
-          || fp_operand (operands[0], VOIDmode)))
+          || FP_REG_P (operands[0])))
     operands[1] = force_const_mem (DImode, operands[1]);
 }")
 
   "TARGET_64BIT
    && GET_CODE (operands[1]) == CONST_INT
    && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
-   && !fp_operand (operands[0], VOIDmode)"
+   && !FP_REG_P (operands[0])"
   "lghi\\t%0,%h1"
-  [(set_attr "op_type" "RI")
-   (set_attr "atype"   "reg")])
+  [(set_attr "op_type" "RI")])
 
 (define_insn "*movdi_lli"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (match_operand:DI 1 "immediate_operand" "n"))]
   "TARGET_64BIT && s390_single_hi (operands[1], DImode, 0) >= 0
-   && !fp_operand (operands[0], VOIDmode)"
+   && !FP_REG_P (operands[0])"
   "*
 {
   int part = s390_single_hi (operands[1], DImode, 0);
       default: abort ();
     }
 }"
-  [(set_attr "op_type" "RI")
-   (set_attr "atype"   "reg")])
+  [(set_attr "op_type" "RI")])
 
 (define_insn "*movdi_larl"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (match_operand:DI 1 "larl_operand" "X"))]
   "TARGET_64BIT
-   && !fp_operand (operands[0], VOIDmode)"
+   && !FP_REG_P (operands[0])"
   "larl\\t%0,%1"
    [(set_attr "op_type" "RIL")
-    (set_attr "atype"   "reg")
-    (set_attr "type"    "la")])
-
-(define_insn "*movdi_ss"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
-        (match_operand:DI 1 "s_imm_operand" "Qo"))]
-  ""
-  "mvc\\t%O0(8,%R0),%1"        
-  [(set_attr "op_type" "SS")
-   (set_attr "atype"   "mem")])
+    (set_attr "type"    "larl")])
 
 (define_insn "*movdi_64"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,m,f,f,m")
-        (match_operand:DI 1 "general_operand" "d,m,d,f,m,f"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m,Q")
+        (match_operand:DI 1 "general_operand" "d,m,d,*f,m,*f,Q"))]
   "TARGET_64BIT"
   "@
    lgr\\t%0,%1
    stg\\t%1,%0
    ldr\\t%0,%1
    ld\\t%0,%1
-   std\\t%1,%0"
-  [(set_attr "op_type" "RR,RXE,RXE,RR,RX,RX")
-   (set_attr "atype"   "reg,mem,mem,reg,mem,mem")])
+   std\\t%1,%0
+   mvc\\t%O0(8,%R0),%1"
+  [(set_attr "op_type" "RRE,RXE,RXE,RR,RX,RX,SS")
+   (set_attr "type" "lr,load,store,floadd,floadd,fstored,cs")])
 
 (define_insn "*movdi_31"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,m,f,f,m")
-        (match_operand:DI 1 "general_operand" "Q,d,dKm,d,f,m,f"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,m,!*f,!*f,!m,Q")
+        (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,m,*f,Q"))]
   "!TARGET_64BIT"
   "@
    lm\\t%0,%N0,%1
    #
    ldr\\t%0,%1
    ld\\t%0,%1
-   std\\t%1,%0"
-  [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RX")
-   (set_attr "atype"   "mem,mem,*,*,reg,mem,mem")])
+   std\\t%1,%0
+   mvc\\t%O0(8,%R0),%1"
+  [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RX,SS")
+   (set_attr "type" "lm,stm,*,*,floadd,floadd,fstored,cs")])
 
 (define_split
   [(set (match_operand:DI 0 "nonimmediate_operand" "")
         (match_operand:DI 1 "general_operand" ""))]
   "!TARGET_64BIT && reload_completed
-   && !fp_operand (operands[0], VOIDmode)
-   && !fp_operand (operands[1], VOIDmode)
+   && !FP_REG_P (operands[0])
+   && !FP_REG_P (operands[1])
    && !s_operand (operands[0], VOIDmode)
    && !s_operand (operands[1], VOIDmode)
    && (register_operand (operands[0], VOIDmode)
   [(set (match_operand:DI 0 "register_operand" "")
         (match_operand:DI 1 "memory_operand" ""))]
   "!TARGET_64BIT && reload_completed
-   && !fp_operand (operands[0], VOIDmode)
-   && !fp_operand (operands[1], VOIDmode)
+   && !FP_REG_P (operands[0])
+   && !FP_REG_P (operands[1])
    && !s_operand (operands[1], VOIDmode)"
-  [(set (match_dup 2) (match_dup 3))
-   (set (match_dup 0) (mem:DI (match_dup 2)))]
-  "operands[2] = operand_subword (operands[0], 1, 0, DImode);
-   operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
+  [(set (match_dup 0) (match_dup 1))]
+  "
+{
+  rtx addr = operand_subword (operands[0], 1, 0, DImode);
+  s390_load_address (addr, XEXP (operands[1], 0));
+  operands[1] = replace_equiv_address (operands[1], addr);
+}")
+
+(define_peephole2
+  [(set (match_operand:DI 0 "register_operand" "")
+        (mem:DI (match_operand 1 "address_operand" "")))]
+  "TARGET_64BIT
+   && !FP_REG_P (operands[0])
+   && GET_CODE (operands[1]) == SYMBOL_REF
+   && CONSTANT_POOL_ADDRESS_P (operands[1])
+   && get_pool_mode (operands[1]) == DImode
+   && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
+  [(set (match_dup 0) (match_dup 2))]
+  "operands[2] = get_pool_constant (operands[1]);")
 
 ;
 ; movsi instruction pattern(s).
   if ((reload_in_progress || reload_completed)
       && CONSTANT_P (operands[1]) 
       && (!legitimate_reload_constant_p (operands[1])
-          || fp_operand (operands[0], VOIDmode)))
+          || FP_REG_P (operands[0])))
     operands[1] = force_const_mem (SImode, operands[1]);
 }")
 
         (match_operand:SI 1 "immediate_operand" "K"))]
   "GET_CODE (operands[1]) == CONST_INT
    && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
-   && !fp_operand (operands[0], VOIDmode)"
+   && !FP_REG_P (operands[0])"
   "lhi\\t%0,%h1"
   [(set_attr "op_type" "RI")])
 
   [(set (match_operand:SI 0 "register_operand" "=d")
         (match_operand:SI 1 "immediate_operand" "n"))]
   "TARGET_64BIT && s390_single_hi (operands[1], SImode, 0) >= 0
-   && !fp_operand (operands[0], VOIDmode)"
+   && !FP_REG_P (operands[0])"
   "*
 {
   int part = s390_single_hi (operands[1], SImode, 0);
 }"
   [(set_attr "op_type" "RI")])
 
-(define_insn "*movsi_ss"
-  [(set (match_operand:SI 0 "s_operand" "=Qo")
-        (match_operand:SI 1 "s_imm_operand" "Qo"))]
-  ""
-  "mvc\\t%O0(4,%R0),%1"        
-  [(set_attr "op_type" "SS")
-   (set_attr "atype"   "mem")])
-
 (define_insn "*movsi"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,m,f,f,m")
-        (match_operand:SI 1 "general_operand" "d,m,d,f,m,f"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m,Q")
+        (match_operand:SI 1 "general_operand" "d,m,d,*f,m,*f,Q"))]
   ""
   "@
    lr\\t%0,%1
    st\\t%1,%0
    ler\\t%0,%1
    le\\t%0,%1
-   ste\\t%1,%0"
-  [(set_attr "op_type" "RR,RX,RX,RR,RX,RX")
-   (set_attr "atype"   "reg,mem,mem,reg,mem,mem")])
+   ste\\t%1,%0
+   mvc\\t%O0(4,%R0),%1"
+  [(set_attr "op_type" "RR,RX,RX,RR,RX,RX,SS")
+   (set_attr "type" "lr,load,store,floads,floads,fstores,cs")])
 
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+        (mem:SI (match_operand 1 "address_operand" "")))]
+  "!FP_REG_P (operands[0])
+   && GET_CODE (operands[1]) == SYMBOL_REF
+   && CONSTANT_POOL_ADDRESS_P (operands[1])
+   && get_pool_mode (operands[1]) == SImode
+   && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
+  [(set (match_dup 0) (match_dup 2))]
+  "operands[2] = get_pool_constant (operands[1]);")
 
 ;
 ; movhi instruction pattern(s).
 ;
 
 (define_insn "movhi"
-  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m")
-        (match_operand:HI 1 "general_operand" "d,n,m,d"))]
+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,Q")
+        (match_operand:HI 1 "general_operand" "d,n,m,d,Q"))]
   ""
   "@
    lr\\t%0,%1
    lhi\\t%0,%h1
    lh\\t%0,%1
-   sth\\t%1,%0"
-  [(set_attr "op_type" "RR,RI,RX,RX")
-   (set_attr "atype"   "reg,reg,mem,mem")])
+   sth\\t%1,%0
+   mvc\\t%O0(2,%R0),%1"
+  [(set_attr "op_type" "RR,RI,RX,RX,SS")])
 
+(define_peephole2
+  [(set (match_operand:HI 0 "register_operand" "")
+        (mem:HI (match_operand 1 "address_operand" "")))]
+  "GET_CODE (operands[1]) == SYMBOL_REF
+   && CONSTANT_POOL_ADDRESS_P (operands[1])
+   && get_pool_mode (operands[1]) == HImode
+   && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
+  [(set (match_dup 0) (match_dup 2))]
+  "operands[2] = get_pool_constant (operands[1]);")
 
 ;
 ; movqi instruction pattern(s).
 ;
 
 (define_insn "movqi_64"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q")
-        (match_operand:QI 1 "general_operand" "d,n,m,d,n"))]
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q,Q")
+        (match_operand:QI 1 "general_operand" "d,n,m,d,n,Q"))]
   "TARGET_64BIT"
   "@
    lr\\t%0,%1
    lhi\\t%0,%b1
    llgc\\t%0,%1
    stc\\t%1,%0
-   mvi\\t%0,%b1"
-  [(set_attr "op_type" "RR,RI,RXE,RX,SI")
-   (set_attr "atype"   "reg,reg,mem,mem,mem")])
-
+   mvi\\t%0,%b1
+   mvc\\t%O0(1,%R0),%1"
+  [(set_attr "op_type" "RR,RI,RXE,RX,SI,SS")
+   (set_attr "type" "lr,*,*,store,store,cs")])
 
 (define_insn "movqi"
-  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q")
-        (match_operand:QI 1 "general_operand" "d,n,m,d,n"))]
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q,Q")
+        (match_operand:QI 1 "general_operand" "d,n,m,d,n,Q"))]
   ""
   "@
    lr\\t%0,%1
    lhi\\t%0,%b1
    ic\\t%0,%1
    stc\\t%1,%0
-   mvi\\t%0,%b1"
-  [(set_attr "op_type" "RR,RI,RX,RX,SI")
-   (set_attr "atype"   "reg,reg,mem,mem,mem")])
+   mvi\\t%0,%b1
+   mvc\\t%O0(1,%R0),%1"
+  [(set_attr "op_type" "RR,RI,RX,RX,SI,SS")])
 
+(define_peephole2
+  [(set (match_operand:QI 0 "nonimmediate_operand" "")
+        (mem:QI (match_operand 1 "address_operand" "")))]
+  "GET_CODE (operands[1]) == SYMBOL_REF
+   && CONSTANT_POOL_ADDRESS_P (operands[1])
+   && get_pool_mode (operands[1]) == QImode
+   && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
+  [(set (match_dup 0) (match_dup 2))]
+  "operands[2] = get_pool_constant (operands[1]);")
 
 ;
-; moveqstrictqi instruction pattern(s).
+; movstrictqi instruction pattern(s).
 ;
 
 (define_insn "*movstrictqi"
                          (match_operand:QI 1 "memory_operand" "m"))]
   ""
   "ic\\t%0,%1"
-  [(set_attr "op_type"  "RX")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "RX")])
 
 ;
 ; movstricthi instruction pattern(s).
 
 (define_insn "*movstricthi"
   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
-                         (match_operand:HI 1 "s_imm_operand" "Qo"))
+                         (match_operand:HI 1 "s_imm_operand" "Q"))
    (clobber (reg:CC 33))]
   ""
   "icm\\t%0,3,%1"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RS")])
 
 
 ;
 ; movstrictsi instruction pattern(s).
 ;
 
-(define_insn "movestrictsi"
+(define_insn "movstrictsi"
   [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d"))
                          (match_operand:SI 1 "general_operand" "d,m"))]
   "TARGET_64BIT"
    lr\\t%0,%1
    l\\t%0,%1"
   [(set_attr "op_type" "RR,RS")
-   (set_attr "atype"   "reg,mem")])
+   (set_attr "type" "lr,load")])
 
 
 ;
     operands[1] = force_const_mem (DFmode, operands[1]);
 }")
 
-(define_insn "*movdf_ss"
-  [(set (match_operand:DF 0 "s_operand" "=Qo")
-        (match_operand:DF 1 "s_imm_operand" "Qo"))]
-  ""
-  "mvc\\t%O0(8,%R0),%1"        
-  [(set_attr "op_type" "SS")
-   (set_attr "atype"   "mem")])
-
 (define_insn "*movdf_64"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,d,m")
-        (match_operand:DF 1 "general_operand" "f,m,f,d,m,d"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,d,m,Q")
+        (match_operand:DF 1 "general_operand" "f,m,f,d,m,d,Q"))]
   "TARGET_64BIT"
   "@
    ldr\\t%0,%1
    std\\t%1,%0
    lgr\\t%0,%1
    lg\\t%0,%1
-   stg\\t%1,%0"
-  [(set_attr "op_type" "RR,RX,RX,RR,RXE,RXE")
-   (set_attr "atype"   "reg,mem,mem,reg,mem,mem")])
+   stg\\t%1,%0
+   mvc\\t%O0(8,%R0),%1"
+  [(set_attr "op_type" "RR,RX,RX,RRE,RXE,RXE,SS")
+   (set_attr "type" "floadd,floadd,fstored,lr,load,store,cs")])
 
 (define_insn "*movdf_31"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,Q,d,m")
-        (match_operand:DF 1 "general_operand" "f,m,f,Q,d,dKm,d"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,Q,d,m,Q")
+        (match_operand:DF 1 "general_operand" "f,m,f,Q,d,dKm,d,Q"))]
   "!TARGET_64BIT"
   "@
    ldr\\t%0,%1
    lm\\t%0,%N0,%1
    stm\\t%1,%N1,%0
    #
-   #"
-  [(set_attr "op_type" "RR,RX,RX,RS,RS,NN,NN")
-   (set_attr "atype"   "reg,mem,mem,mem,mem,*,*")])
+   #
+   mvc\\t%O0(8,%R0),%1"
+  [(set_attr "op_type" "RR,RX,RX,RS,RS,NN,NN,SS")
+   (set_attr "type" "floadd,floadd,fstored,lm,stm,*,*,cs")])
 
 (define_split
   [(set (match_operand:DF 0 "nonimmediate_operand" "")
         (match_operand:DF 1 "general_operand" ""))]
   "!TARGET_64BIT && reload_completed
-   && !fp_operand (operands[0], VOIDmode)
-   && !fp_operand (operands[1], VOIDmode)
+   && !FP_REG_P (operands[0])
+   && !FP_REG_P (operands[1])
    && !s_operand (operands[0], VOIDmode)
    && !s_operand (operands[1], VOIDmode)
    && (register_operand (operands[0], VOIDmode)
   [(set (match_operand:DF 0 "register_operand" "")
         (match_operand:DF 1 "memory_operand" ""))]
   "!TARGET_64BIT && reload_completed
-   && !fp_operand (operands[0], VOIDmode)
-   && !fp_operand (operands[1], VOIDmode)
+   && !FP_REG_P (operands[0])
+   && !FP_REG_P (operands[1])
    && !s_operand (operands[1], VOIDmode)"
-  [(set (match_dup 2) (match_dup 3))
-   (set (match_dup 0) (mem:DI (match_dup 2)))]
-  "operands[2] = operand_subword (operands[0], 1, 0, DFmode);
-   operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
+  [(set (match_dup 0) (match_dup 1))]
+  "
+{
+  rtx addr = operand_subword (operands[0], 1, 0, DFmode);
+  s390_load_address (addr, XEXP (operands[1], 0));
+  operands[1] = replace_equiv_address (operands[1], addr);
+}")
 
 ;
 ; movsf instruction pattern(s).
     operands[1] = force_const_mem (SFmode, operands[1]);
 }")
 
-(define_insn "*movsf_ss"
-  [(set (match_operand:SF 0 "s_operand" "=Qo")
-        (match_operand:SF 1 "s_imm_operand" "Qo"))]
-  ""
-  "mvc\\t%O0(4,%R0),%1"        
-  [(set_attr "op_type" "SS")
-   (set_attr "atype"   "mem")])
-
 (define_insn "*movsf"
-  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,d,d,m")
-        (match_operand:SF 1 "general_operand" "f,m,f,d,m,d"))]
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,d,d,m,Q")
+        (match_operand:SF 1 "general_operand" "f,m,f,d,m,d,Q"))]
   ""
   "@
    ler\\t%0,%1
    ste\\t%1,%0
    lr\\t%0,%1
    l\\t%0,%1
-   st\\t%1,%0"
-  [(set_attr "op_type" "RR,RX,RX,RR,RX,RX")
-   (set_attr "atype"   "reg,mem,mem,reg,mem,mem")])
+   st\\t%1,%0
+   mvc\\t%O0(4,%R0),%1"
+  [(set_attr "op_type" "RR,RX,RX,RR,RX,RX,SS")
+   (set_attr "type" "floads,floads,fstores,lr,load,store,cs")])
 
 ;
 ; load_multiple pattern(s).
 (define_insn "*load_multiple_di"
   [(match_parallel 0 "load_multiple_operation"
                   [(set (match_operand:DI 1 "register_operand" "=r")
-                        (match_operand:DI 2 "s_operand" "oQ"))])]
+                        (match_operand:DI 2 "s_operand" "Q"))])]
   ""
   "*
 {
     return \"lmg\\t%1,%0,%2\";
 }"
    [(set_attr "op_type" "RXE")
-    (set_attr "atype"   "mem")
     (set_attr "type"    "lm")])
 
 (define_insn "*load_multiple_si"
   [(match_parallel 0 "load_multiple_operation"
                   [(set (match_operand:SI 1 "register_operand" "=r")
-                        (match_operand:SI 2 "s_operand" "oQ"))])]
+                        (match_operand:SI 2 "s_operand" "Q"))])]
   ""
   "*
 {
     return \"lm\\t%1,%0,%2\";
 }"
    [(set_attr "op_type" "RXE")
-    (set_attr "atype"   "mem")
     (set_attr "type"    "lm")])
 
 ;
 
 (define_insn "*store_multiple_di"
   [(match_parallel 0 "store_multiple_operation"
-                  [(set (match_operand:DI 1 "s_operand" "=oQ")
+                  [(set (match_operand:DI 1 "s_operand" "=Q")
                         (match_operand:DI 2 "register_operand" "r"))])]
   ""
   "*
     return \"stmg\\t%2,%0,%1\";
 }"
    [(set_attr "op_type" "RXE")
-    (set_attr "atype"   "mem")
     (set_attr "type"    "stm")])
 
 
 (define_insn "*store_multiple_si"
   [(match_parallel 0 "store_multiple_operation"
-                  [(set (match_operand:SI 1 "s_operand" "=oQ")
+                  [(set (match_operand:SI 1 "s_operand" "=Q")
                         (match_operand:SI 2 "register_operand" "r"))])]
   ""
   "*
     return \"stm\\t%2,%0,%1\";
 }"
    [(set_attr "op_type" "RXE")
-    (set_attr "atype"   "mem")
     (set_attr "type"    "stm")])
 
 ;;
 ;; String instructions.
-;;
-
-;
-; movstrdi instruction pattern(s).
-;
-
-(define_expand "movstrdi"
-   [(set (match_operand:BLK 0 "general_operand" "")
-         (match_operand:BLK 1 "general_operand" ""))
-    (use (match_operand:DI 2 "general_operand" ""))
-    (match_operand 3 "" "")]
-    "TARGET_64BIT"
-    "
-{
-  rtx addr0, addr1;
-
-  addr0 = force_operand (XEXP (operands[0], 0), NULL_RTX);
-  addr1 = force_operand (XEXP (operands[1], 0), NULL_RTX);
-
-  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 256)
-    {
-      operands[0] = change_address (operands[0], VOIDmode, addr0);
-      operands[1] = change_address (operands[1], VOIDmode, addr1);
-      operands[2] = GEN_INT (INTVAL (operands[2]) - 1);
-
-      emit_insn (gen_movstrdi_short (operands[0], operands[1], operands[2]));
-      DONE;
-    } 
-  else 
-    {
-      if (TARGET_MVCLE) 
-       {
-          /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
-          rtx reg0 = gen_reg_rtx (TImode);
-          rtx reg1 = gen_reg_rtx (TImode);
-          rtx len = operands[2];
-
-          if (! CONSTANT_P (len))
-            len = force_reg (DImode, len);
-
-          /* Load up the address+length pairs.  */
-
-          emit_move_insn (gen_highpart (DImode, reg0), addr0);
-          emit_move_insn (gen_lowpart (DImode, reg0), len);
-
-          emit_move_insn (gen_highpart (DImode, reg1), addr1);
-          emit_move_insn (gen_lowpart (DImode, reg1), len);
-
-          /* MOVE */
-          emit_insn (gen_movstrdi_64 (reg0, reg1, reg0, reg1));
-          DONE;
-        }
-      else
-       {
-          rtx label1 = gen_label_rtx ();
-          rtx label2 = gen_label_rtx ();
-          rtx reg0, reg1, len, blocks;
-               
-          reg0 = gen_reg_rtx (DImode);
-          reg1 = gen_reg_rtx (DImode);
-          len = gen_reg_rtx (DImode);
-          blocks = gen_reg_rtx (DImode);
-
-          emit_move_insn (len, operands[2]);   
-          emit_insn (gen_cmpdi (len, const0_rtx));
-          emit_jump_insn (gen_beq (label1));
-          emit_move_insn (reg0, addr0);
-          emit_move_insn (reg1, addr1);
-          emit_insn (gen_adddi3 (len, len, constm1_rtx));
-          emit_insn (gen_ashrdi3 (blocks, len, GEN_INT (8)));
-          emit_insn (gen_cmpdi (blocks, const0_rtx));
-          emit_jump_insn (gen_beq (label2));
-          emit_insn (gen_movstrdi_long (reg0, reg1, reg0, reg1, blocks, blocks));
-          emit_label (label2); 
-         operands[0] = change_address (operands[0], VOIDmode, reg0);
-         operands[1] = change_address (operands[1], VOIDmode, reg1);
-          emit_insn (gen_movstrdi_short (operands[0], operands[1], len));
-          emit_label (label1); 
-          DONE;           
-       }        
-    }
-}")
-
-;
-; movstrsi instruction pattern(s).
-;
-
-(define_expand "movstrsi"
-   [(set (match_operand:BLK 0 "general_operand" "")
-         (match_operand:BLK 1 "general_operand" ""))
-    (use (match_operand:SI 2 "general_operand" ""))
-    (match_operand 3 "" "")]
-    "!TARGET_64BIT"
-    "
-{
-  rtx addr0 = force_operand (XEXP (operands[0], 0), NULL_RTX);
-  rtx addr1 = force_operand (XEXP (operands[1], 0), NULL_RTX);
-
-  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 256)
-    {
-      operands[0] = change_address (operands[0], VOIDmode, addr0);
-      operands[1] = change_address (operands[1], VOIDmode, addr1);
-      operands[2] = GEN_INT (INTVAL (operands[2]) - 1);
-
-      emit_insn (gen_movstrsi_short (operands[0], operands[1], operands[2]));
-      DONE;
-    } 
-  else 
-    {
-      if (TARGET_MVCLE) 
-       {
-          /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
-          rtx reg0 = gen_reg_rtx (DImode);
-          rtx reg1 = gen_reg_rtx (DImode);
-          rtx len = operands[2];
-
-
-          if (! CONSTANT_P (len))
-            len = force_reg (SImode, len);
-
-          /* Load up the address+length pairs.  */
+;;
 
-          emit_move_insn (gen_highpart (SImode, reg0), addr0);
-          emit_move_insn (gen_lowpart (SImode, reg0), len);
+;
+; movstrM instruction pattern(s).
+;
 
-          emit_move_insn (gen_highpart (SImode, reg1), addr1);
-          emit_move_insn (gen_lowpart (SImode, reg1), len);
+(define_expand "movstrdi"
+  [(set (match_operand:BLK 0 "memory_operand" "")
+        (match_operand:BLK 1 "memory_operand" ""))
+   (use (match_operand:DI 2 "general_operand" ""))
+   (match_operand 3 "" "")]
+  "TARGET_64BIT"
+  "s390_expand_movstr (operands[0], operands[1], operands[2]); DONE;")
 
-          /* MOVE */
-          emit_insn (gen_movstrsi_31 (reg0, reg1, reg0, reg1));
-          DONE;
-        }
-      else
-       {
-          rtx label1 = gen_label_rtx ();
-          rtx label2 = gen_label_rtx ();
-          rtx reg0, reg1, len, blocks;
-               
-          reg0 = gen_reg_rtx (SImode);
-          reg1 = gen_reg_rtx (SImode);
-         len = gen_reg_rtx (SImode); 
-         blocks = gen_reg_rtx (SImode); 
-         
-         emit_move_insn (len, operands[2]);
-          emit_insn (gen_cmpsi (len, const0_rtx));
-          emit_jump_insn (gen_beq (label1));
-          emit_move_insn (reg0, addr0);
-          emit_move_insn (reg1, addr1);
-          emit_insn (gen_addsi3 (len, len, constm1_rtx));
-          emit_insn (gen_ashrsi3 (blocks, len, GEN_INT (8)));
-          emit_insn (gen_cmpsi (blocks, const0_rtx));
-          emit_jump_insn (gen_beq (label2));
-          emit_insn (gen_movstrsi_long (reg0, reg1, reg0, reg1, blocks, blocks));
-          emit_label (label2); 
-         operands[0] = change_address (operands[0], VOIDmode, reg0);
-         operands[1] = change_address (operands[1], VOIDmode, reg1);
-          emit_insn (gen_movstrsi_short (operands[0], operands[1], len));
-          emit_label (label1); 
-          DONE;           
-       }        
-    }
-}")
+(define_expand "movstrsi"
+  [(set (match_operand:BLK 0 "memory_operand" "")
+        (match_operand:BLK 1 "memory_operand" ""))
+   (use (match_operand:SI 2 "general_operand" ""))
+   (match_operand 3 "" "")]
+  ""
+  "s390_expand_movstr (operands[0], operands[1], operands[2]); DONE;")
 
 ; Move a block that is up to 256 bytes in length.
 ; The block length is taken as (operands[2] % 256) + 1.
 
-(define_insn "movstrdi_short"
-  [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ")
-        (match_operand:BLK 1 "s_operand" "oQ,oQ"))
+(define_insn "movstr_short_64"
+  [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
+        (match_operand:BLK 1 "memory_operand" "Q,Q"))
    (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
    (clobber (match_scratch:DI 3 "=X,&a"))]
   "TARGET_64BIT"
     }
 }"
   [(set_attr "op_type" "SS,NN")
-   (set_attr "atype"   "mem,mem")
+   (set_attr "type"    "cs,cs")
+   (set_attr "atype"   "*,agen")
    (set_attr "length"  "*,14")])
 
-(define_insn "movstrsi_short"
-  [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ")
-        (match_operand:BLK 1 "s_operand" "oQ,oQ"))
+(define_insn "movstr_short_31"
+  [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
+        (match_operand:BLK 1 "memory_operand" "Q,Q"))
    (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
    (clobber (match_scratch:SI 3 "=X,&a"))]
   "!TARGET_64BIT"
     }
 }"
   [(set_attr "op_type" "SS,NN")
-   (set_attr "atype"   "mem,mem")
+   (set_attr "type"    "cs,cs")
+   (set_attr "atype"   "*,agen")
    (set_attr "length"  "*,14")])
 
-; Move a block that is a multiple of 256 bytes in length
-
-(define_insn "movstrdi_long"
-  [(set (match_operand:DI 4 "register_operand" "=d")
-        (const_int 0))
-   (set (match_operand:DI 0 "register_operand" "=a")
-        (plus:DI (match_operand:DI 2 "register_operand" "0")
-                 (ashift:DI (match_operand:DI 5 "register_operand" "4")
-                            (const_int 8))))
-   (set (match_operand:DI 1 "register_operand" "=a")
-        (plus:DI (match_operand:DI 3 "register_operand" "1")
-                 (ashift:DI (match_dup 5) (const_int 8))))
-   (set (mem:BLK (match_dup 2))
-        (mem:BLK (match_dup 3)))
-   (use (match_dup 5))]
-  "TARGET_64BIT"
-  "*
-{
-  output_asm_insn (\"mvc\\t0(256,%0),0(%1)\", operands);
-  output_asm_insn (\"la\\t%0,256(%0)\", operands);
-  output_asm_insn (\"la\\t%1,256(%1)\", operands);
-  return \"brct\\t%4,.-14\";
-}"
-  [(set_attr "op_type" "NN")
-   (set_attr "atype"   "mem")
-   (set_attr "length"  "18")])
-
-(define_insn "movstrsi_long"
-  [(set (match_operand:SI 4 "register_operand" "=d")
-        (const_int 0))
-   (set (match_operand:SI 0 "register_operand" "=a")
-        (plus:SI (match_operand:SI 2 "register_operand" "0")
-                 (ashift:SI (match_operand:SI 5 "register_operand" "4")
-                            (const_int 8))))
-   (set (match_operand:SI 1 "register_operand" "=a")
-        (plus:SI (match_operand:SI 3 "register_operand" "1")
-                 (ashift:SI (match_dup 5) (const_int 8))))
-   (set (mem:BLK (match_dup 2))
-        (mem:BLK (match_dup 3)))
-   (use (match_dup 5))]
-  "!TARGET_64BIT"
-  "*
-{
-  output_asm_insn (\"mvc\\t0(256,%0),0(%1)\", operands);
-  output_asm_insn (\"la\\t%0,256(%0)\", operands);
-  output_asm_insn (\"la\\t%1,256(%1)\", operands);
-  return \"brct\\t%4,.-14\";
-}"
-  [(set_attr "op_type" "NN")
-   (set_attr "atype"   "mem")
-   (set_attr "length"  "18")])
-
-; Move a block that is larger than 255 bytes in length.
+; Move a block of arbitrary length.
 
-(define_insn "movstrdi_64"
+(define_insn "movstr_long_64"
   [(set (match_operand:TI 0 "register_operand" "=d")
         (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
                             (lshiftrt:TI (match_dup 2) (const_int 64)))
   "TARGET_64BIT"
   "mvcle\\t%0,%1,0\;jo\\t.-4"
   [(set_attr "op_type" "NN")
-   (set_attr "atype"   "mem")
+   (set_attr "type"    "vs")
    (set_attr "length"  "8")])
 
-(define_insn "movstrsi_31"
+(define_insn "movstr_long_31"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
                             (lshiftrt:DI (match_dup 2) (const_int 32)))
    (clobber (reg:CC 33))]
   "!TARGET_64BIT"
   "mvcle\\t%0,%1,0\;jo\\t.-4"
-   [(set_attr "op_type" "NN")
-    (set_attr "atype" "mem")
-    (set_attr "length"  "8")])
+  [(set_attr "op_type" "NN")
+   (set_attr "type"    "vs")
+   (set_attr "length"  "8")])
 
 ;
-; clrstrdi instruction pattern(s).
+; clrstrM instruction pattern(s).
 ;
 
 (define_expand "clrstrdi"
-  [(set (match_operand:BLK 0 "general_operand" "")
+  [(set (match_operand:BLK 0 "memory_operand" "")
         (const_int 0))
    (use (match_operand:DI 1 "general_operand" ""))
    (match_operand 2 "" "")]
   "TARGET_64BIT"
-  "
-{
-   rtx addr = force_operand (XEXP (operands[0], 0), NULL_RTX);
-
-   operands[0] = change_address (operands[0], VOIDmode, addr);
-
-   if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 256)
-     {
-        emit_insn (gen_clrstrsico (operands[0], operands[1]));
-        DONE;
-     }
-   else
-     {
-      rtx reg0 = gen_reg_rtx (TImode);
-      rtx reg1 = gen_reg_rtx (TImode);
-      rtx len = operands[1];
-
-      if (! CONSTANT_P (len))
-          len = force_reg (DImode, len);
-
-      /* Load up the address+length pairs.  */
-
-      emit_move_insn (gen_highpart (DImode, reg0), addr);
-      emit_move_insn (gen_lowpart (DImode, reg0), len);
-
-      emit_move_insn (gen_lowpart (DImode, reg1), const0_rtx);
-      /* Clear! */
-      emit_insn (gen_clrstrsi_64 (reg0, reg1, reg0));
-      DONE;    
-     }
-}")
-
-;
-; clrstrsi instruction pattern(s).
-;
+  "s390_expand_clrstr (operands[0], operands[1]); DONE;")
 
 (define_expand "clrstrsi"
-  [(set (match_operand:BLK 0 "general_operand" "")
+  [(set (match_operand:BLK 0 "memory_operand" "")
         (const_int 0))
    (use (match_operand:SI 1 "general_operand" ""))
    (match_operand 2 "" "")]
-   "!TARGET_64BIT"
-   "
-{
-   rtx addr = force_operand (XEXP (operands[0], 0), NULL_RTX);
-
-   operands[0] = change_address (operands[0], VOIDmode, addr);
-
-   if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 256)
-     {
-        emit_insn (gen_clrstrsico (operands[0], operands[1]));
-        DONE;
-     }
-   else
-     {
-      rtx reg0 = gen_reg_rtx (DImode);
-      rtx reg1 = gen_reg_rtx (DImode);
-      rtx len = operands[1];
-
-      if (! CONSTANT_P (len))
-          len = force_reg (SImode, len);
+  ""
+  "s390_expand_clrstr (operands[0], operands[1]); DONE;")
 
-      /* Load up the address+length pairs.  */
+; Clear a block that is up to 256 bytes in length.
+; The block length is taken as (operands[2] % 256) + 1.
 
-      emit_move_insn (gen_highpart (SImode, reg0), addr);
-      emit_move_insn (gen_lowpart (SImode, reg0), len);
+(define_insn "clrstr_short_64"
+  [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
+        (const_int 0))
+   (use (match_operand:DI 1 "nonmemory_operand" "n,a"))
+   (clobber (match_scratch:DI 2 "=X,&a"))
+   (clobber (reg:CC 33))]
+  "TARGET_64BIT"
+  "*
+{
+  switch (which_alternative)
+    {
+      case 0:
+       return \"xc\\t%O0(%b1+1,%R0),%0\";
 
-      emit_move_insn (gen_lowpart (SImode, reg1), const0_rtx);
-      /* CLear! */
-      emit_insn (gen_clrstrsi_31 (reg0, reg1, reg0));
-      DONE;    
-     }
-}")
+      case 1:
+       output_asm_insn (\"bras\\t%2,.+10\", operands);
+       output_asm_insn (\"xc\\t%O0(1,%R0),%0\", operands);
+       return \"ex\\t%1,0(%2)\";
 
-; Clear memory with length less than 256 bytes 
+      default:
+        abort ();
+    }
+}"
+  [(set_attr "op_type" "SS,NN")
+   (set_attr "type"    "cs,cs")
+   (set_attr "atype"   "*,agen")
+   (set_attr "length"  "*,14")])
 
-(define_insn "clrstrsico"
-  [(set (match_operand:BLK 0 "s_operand" "=Qo")
+(define_insn "clrstr_short_31"
+  [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
         (const_int 0))
-   (use (match_operand 1 "immediate_operand" "I"))
+   (use (match_operand:SI 1 "nonmemory_operand" "n,a"))
+   (clobber (match_scratch:SI 2 "=X,&a"))
    (clobber (reg:CC 33))]
-  ""
-  "xc\\t%O0(%1,%R0),%0"        
-  [(set_attr "op_type" "RS")
-   (set_attr "type"    "cs")
-   (set_attr "atype"   "mem")])
+  "!TARGET_64BIT"
+  "*
+{
+  switch (which_alternative)
+    {
+      case 0:
+       return \"xc\\t%O0(%b1+1,%R0),%0\";
+
+      case 1:
+       output_asm_insn (\"bras\\t%2,.+10\", operands);
+       output_asm_insn (\"xc\\t%O0(1,%R0),%0\", operands);
+       return \"ex\\t%1,0(%2)\";
+
+      default:
+        abort ();
+    }
+}"
+  [(set_attr "op_type" "SS,NN")
+   (set_attr "type"    "cs,cs")
+   (set_attr "atype"   "*,agen")
+   (set_attr "length"  "*,14")])
 
-; Clear memory with length greater 256 bytes or lenght not constant
+; Clear a block of arbitrary length.
 
-(define_insn "clrstrsi_64"
+(define_insn "clrstr_long_64"
   [(set (match_operand:TI 0 "register_operand" "=d")
         (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
                             (lshiftrt:TI (match_dup 2) (const_int 64)))
   "TARGET_64BIT"
   "mvcle\\t%0,%1,0\;jo\\t.-4"
   [(set_attr "op_type" "NN")
-   (set_attr "atype"   "mem")
    (set_attr "type"    "vs")
    (set_attr "length"  "8")])
 
-(define_insn "clrstrsi_31"
+(define_insn "clrstr_long_31"
   [(set (match_operand:DI 0 "register_operand" "=d")
         (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
                             (lshiftrt:DI (match_dup 2) (const_int 32)))
   "!TARGET_64BIT"
   "mvcle\\t%0,%1,0\;jo\\t.-4"
   [(set_attr "op_type" "NN")
-   (set_attr "atype"   "mem")
    (set_attr "type"    "vs")
    (set_attr "length"  "8")])
 
 ;
-; cmpstrdi instruction pattern(s).
+; cmpstrM instruction pattern(s).
 ;
 
 (define_expand "cmpstrdi"
-   [(set (match_operand:DI 0 "register_operand" "")
-         (compare:DI (match_operand:BLK 1 "s_operand" "")
-                  (match_operand:BLK 2 "s_operand" "") ) )
-             (use (match_operand:DI 3  "general_operand" ""))
-             (use (match_operand:DI 4  "" ""))]
-   "TARGET_64BIT"
-   "
-{
-  rtx addr0, addr1;
+  [(set (match_operand:DI 0 "register_operand" "")
+        (compare:DI (match_operand:BLK 1 "memory_operand" "")
+                    (match_operand:BLK 2 "memory_operand" "") ) )
+   (use (match_operand:DI 3 "general_operand" ""))
+   (use (match_operand:DI 4 "" ""))]
+  "TARGET_64BIT"
+  "s390_expand_cmpstr (operands[0], operands[1], 
+                       operands[2], operands[3]); DONE;")
 
-  /* for pre/post increment */
-  operands[1] = protect_from_queue (operands[1], 0);
-  operands[2] = protect_from_queue (operands[2], 0);
-  operands[3] = protect_from_queue (operands[3], 0);
+(define_expand "cmpstrsi"
+  [(set (match_operand:SI 0 "register_operand" "")
+        (compare:SI (match_operand:BLK 1 "memory_operand" "")
+                    (match_operand:BLK 2 "memory_operand" "") ) )
+   (use (match_operand:SI 3 "general_operand" ""))
+   (use (match_operand:SI 4 "" ""))]
+  ""
+  "s390_expand_cmpstr (operands[0], operands[1], 
+                       operands[2], operands[3]); DONE;")
 
-  addr0 = force_operand (XEXP (operands[1], 0), NULL_RTX);
-  addr1 = force_operand (XEXP (operands[2], 0), NULL_RTX);
+; Compare a block that is up to 256 bytes in length.
+; The block length is taken as (operands[2] % 256) + 1.
 
-  if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256) 
+(define_insn "cmpstr_short_64"
+  [(set (reg:CCS 33)
+        (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
+                     (match_operand:BLK 1 "memory_operand" "Q,Q")))
+   (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
+   (clobber (match_scratch:DI 3 "=X,&a"))]
+  "TARGET_64BIT"
+  "*
+{
+  switch (which_alternative)
     {
-      if (INTVAL (operands[3]) == 0) {
-       emit_move_insn (operands[0], operands[3]);
-       DONE;
-      }
-
-      operands[1] = change_address (operands[1], VOIDmode, addr0);
-      operands[2] = change_address (operands[2], VOIDmode, addr1);
-
-      emit_insn (gen_cmpstr_const (operands[1], operands[2], operands[3]));
-      emit_insn (gen_cmpint_di (operands[0]));
-      DONE;
-    }
-  else
-    {  
-      /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
-      rtx reg0 = gen_reg_rtx (TImode);
-      rtx reg1 = gen_reg_rtx (TImode);
-      rtx len = operands[3];
-
-      if (! CONSTANT_P (len))
-          len = force_reg (DImode, len);
-
-      /* Load up the address+length pairs.  */
-      emit_move_insn (gen_highpart (DImode, reg0), addr0); 
-      emit_move_insn (gen_lowpart (DImode, reg0), len);
+      case 0:
+       return \"clc\\t%O0(%b2+1,%R0),%1\";
 
-      emit_move_insn (gen_highpart (DImode, reg1), addr1);
-      emit_move_insn (gen_lowpart (DImode, reg1), len);
+      case 1:
+       output_asm_insn (\"bras\\t%3,.+10\", operands);
+       output_asm_insn (\"clc\\t%O0(1,%R0),%1\", operands);
+       return \"ex\\t%2,0(%3)\";
 
-      /* Compare! */
-      emit_insn (gen_cmpstr_64 (reg0, reg1, reg0, reg1));
-      emit_insn (gen_cmpint_di (operands[0]));
-      DONE;
+      default:
+        abort ();
     }
-}")
-
-;
-; cmpstrsi instruction pattern(s).
-;
+}"
+  [(set_attr "op_type" "SS,NN")
+   (set_attr "type"    "cs,cs")
+   (set_attr "atype"   "*,agen")
+   (set_attr "length"  "*,14")])
 
-(define_expand "cmpstrsi"
-   [(set (match_operand:SI 0 "register_operand" "")
-         (compare:SI (match_operand:BLK 1 "s_operand" "")
-                  (match_operand:BLK 2 "s_operand" "") ) )
-             (use (match_operand:SI 3  "general_operand" ""))
-             (use (match_operand:SI 4  "" ""))]
-   ""
-   "
+(define_insn "cmpstr_short_31"
+  [(set (reg:CCS 33)
+        (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
+                     (match_operand:BLK 1 "memory_operand" "Q,Q")))
+   (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
+   (clobber (match_scratch:SI 3 "=X,&a"))]
+  "!TARGET_64BIT"
+  "*
 {
-  rtx addr0, addr1;
-
-  /* for pre/post increment */
-  operands[1] = protect_from_queue (operands[1], 0);
-  operands[2] = protect_from_queue (operands[2], 0);
-  operands[3] = protect_from_queue (operands[3], 0);
-
-  addr0 = force_operand (XEXP (operands[1], 0), NULL_RTX);
-  addr1 = force_operand (XEXP (operands[2], 0), NULL_RTX);
-
-  if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256) 
+  switch (which_alternative)
     {
-      if (INTVAL (operands[3]) == 0) {
-       emit_move_insn (operands[0], operands[3]);
-       DONE;
-      }
-
-      operands[1] = change_address (operands[1], VOIDmode, addr0);
-      operands[2] = change_address (operands[2], VOIDmode, addr1);
-
-      emit_insn (gen_cmpstr_const (operands[1], operands[2], operands[3]));
-      emit_insn (gen_cmpint_si (operands[0]));
-      DONE;
-    }
-  else
-    {  
-      /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
-      rtx reg0, reg1;
-      rtx len = operands[3];
-
-      if (TARGET_64BIT)
-       {
-         reg0 = gen_reg_rtx (TImode);
-         reg1 = gen_reg_rtx (TImode);
-       }
-      else
-       {
-         reg0 = gen_reg_rtx (DImode);
-         reg1 = gen_reg_rtx (DImode);
-        }  
-
-      if (! CONSTANT_P (len))
-          len = force_reg (Pmode, len);
-
-      /* Load up the address+length pairs.  */
-      emit_move_insn (gen_highpart (Pmode, reg0), addr0); 
-      emit_move_insn (gen_lowpart (Pmode, reg0), len);
-
-      emit_move_insn (gen_highpart (Pmode, reg1), addr1);
-      emit_move_insn (gen_lowpart (Pmode, reg1), len);
+      case 0:
+       return \"clc\\t%O0(%b2+1,%R0),%1\";
 
-      /* Compare! */
-      if (TARGET_64BIT) 
-          emit_insn (gen_cmpstr_64 (reg0, reg1, reg0, reg1));
-      else
-          emit_insn (gen_cmpstr_31 (reg0, reg1, reg0, reg1));
+      case 1:
+       output_asm_insn (\"bras\\t%3,.+10\", operands);
+       output_asm_insn (\"clc\\t%O0(1,%R0),%1\", operands);
+       return \"ex\\t%2,0(%3)\";
 
-      emit_insn (gen_cmpint_si (operands[0]));
-      DONE;
+      default:
+        abort ();
     }
-}")
+}"
+  [(set_attr "op_type" "SS,NN")
+   (set_attr "type"    "cs,cs")
+   (set_attr "atype"   "*,agen")
+   (set_attr "length"  "*,14")])
 
-; Compare a block that is less than 256 bytes in length.
+; Compare a block of arbitrary length.
 
-(define_insn "cmpstr_const"
-  [(set (reg:CCS 33)
-        (compare:CCS (match_operand:BLK 0 "s_operand" "oQ")
-                     (match_operand:BLK 1 "s_operand" "oQ")))
-   (use (match_operand 2 "immediate_operand" "I"))]
-  "(unsigned) INTVAL (operands[2]) < 256"
-  "clc\\t%O0(%c2,%R0),%1"
-  [(set_attr "op_type" "SS")
-   (set_attr "atype"   "mem")
-   (set_attr "type"    "cs")])
-
-; Compare a block that is larger than 255 bytes in length.
-
-(define_insn "cmpstr_64"
+(define_insn "cmpstr_long_64"
   [(clobber (match_operand:TI 0 "register_operand" "=d"))
    (clobber (match_operand:TI 1 "register_operand" "=d"))
    (set (reg:CCS 33)
         (compare:CCS (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
-                     (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0))))]
+                     (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0))))
+   (use (match_dup 2))
+   (use (match_dup 3))]
   "TARGET_64BIT"
   "clcl\\t%0,%1"
   [(set_attr "op_type" "RR")
-   (set_attr "atype"   "mem")
    (set_attr "type"    "vs")])
 
-(define_insn "cmpstr_31"
+(define_insn "cmpstr_long_31"
   [(clobber (match_operand:DI 0 "register_operand" "=d"))
    (clobber (match_operand:DI 1 "register_operand" "=d"))
    (set (reg:CCS 33)
         (compare:CCS (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
-                     (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0))))]
+                     (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0))))
+   (use (match_dup 2))
+   (use (match_dup 3))]
   "!TARGET_64BIT"
   "clcl\\t%0,%1"
   [(set_attr "op_type" "RR")
-   (set_attr "atype"   "mem")
    (set_attr "type"    "vs")])
 
 ; Convert condition code to integer in range (-1, 0, 1)
 }"
   [(set_attr "op_type" "NN")
    (set_attr "length"  "16")
-   (set_attr "atype"   "reg")
    (set_attr "type"    "other")])
 
 (define_insn "cmpint_di"
 }"
   [(set_attr "op_type" "NN")
    (set_attr "length"  "22")
-   (set_attr "atype"   "reg")
    (set_attr "type"    "other")])
 
 
 
 (define_insn "*sethighqisi"
   [(set (match_operand:SI 0 "register_operand" "=d")
-        (unspec:SI [(match_operand:QI 1 "s_operand" "Qo")] 10))
+        (unspec:SI [(match_operand:QI 1 "s_operand" "Q")] 10))
    (clobber (reg:CC 33))]
   ""
   "icm\\t%0,8,%1"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RS")])
 
 (define_insn "*sethighhisi"
   [(set (match_operand:SI 0 "register_operand" "=d")
-        (unspec:SI [(match_operand:HI 1 "s_operand" "Qo")] 10))
+        (unspec:SI [(match_operand:HI 1 "s_operand" "Q")] 10))
    (clobber (reg:CC 33))]
   ""
   "icm\\t%0,12,%1"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RS")])
 
 (define_insn "*sethighqidi_64"
   [(set (match_operand:DI 0 "register_operand" "=d")
-        (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
+        (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
    (clobber (reg:CC 33))]
   "TARGET_64BIT"
   "icmh\\t%0,8,%1"
-  [(set_attr "op_type" "RSE")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RSE")])
 
 (define_insn "*sethighqidi_31"
   [(set (match_operand:DI 0 "register_operand" "=d")
-        (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
+        (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
    (clobber (reg:CC 33))]
   "!TARGET_64BIT"
   "icm\\t%0,8,%1"
-  [(set_attr "op_type" "RS")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RS")])
 
-(define_split
-  [(set (match_operand:SI 0 "register_operand" "")
-        (zero_extract:SI (match_operand:QI 1 "s_operand" "")
-                         (match_operand 2 "const_int_operand" "")
-                         (const_int 0)))]
-  "!TARGET_64BIT && !reload_completed
+(define_insn_and_split "*extractqi"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (zero_extract:SI (match_operand:QI 1 "s_operand" "Q")
+                         (match_operand 2 "const_int_operand" "n")
+                         (const_int 0)))
+   (clobber (reg:CC 33))]
+  "!TARGET_64BIT
    && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 8"
+  "#"
+  "&& reload_completed"
   [(parallel
     [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
      (clobber (reg:CC 33))])
 {
   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
   operands[1] = change_address (operands[1], QImode, 0);
-}")
+}"
+  [(set_attr "type"    "o2")
+   (set_attr "atype"   "agen")])
 
-(define_split
-  [(set (match_operand:SI 0 "register_operand" "")
-        (zero_extract:SI (match_operand:QI 1 "s_operand" "")
-                         (match_operand 2 "const_int_operand" "")
-                         (const_int 0)))]
-  "!TARGET_64BIT && !reload_completed
+(define_insn_and_split "*extracthi"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (zero_extract:SI (match_operand:QI 1 "s_operand" "Q")
+                         (match_operand 2 "const_int_operand" "n")
+                         (const_int 0)))
+   (clobber (reg:CC 33))]
+  "!TARGET_64BIT
    && INTVAL (operands[2]) >= 8 && INTVAL (operands[2]) < 16"
+  "#"
+  "&& reload_completed"
   [(parallel
     [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
      (clobber (reg:CC 33))])
 {
   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
   operands[1] = change_address (operands[1], HImode, 0);
-}")
+}"
+  [(set_attr "type"    "o2")
+   (set_attr "atype"   "agen")])
 
 ;
 ; extendsidi2 instruction pattern(s).
   "@
    lgfr\\t%0,%1
    lgf\\t%0,%1"
-  [(set_attr "op_type" "RRE,RXE")
-   (set_attr "atype"   "reg,mem")])
+  [(set_attr "op_type" "RRE,RXE")])
 
 ;
 ; extendhidi2 instruction pattern(s).
         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
   "TARGET_64BIT"
   "lgh\\t%0,%1"
-  [(set_attr "op_type" "RXE")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RXE")])
 
 ;
 ; extendqidi2 instruction pattern(s).
         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
   ""
   "lh\\t%0,%1"
-  [(set_attr "op_type" "RX")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RX")])
 
 ;
 ; extendqisi2 instruction pattern(s).
   "@
    llgfr\\t%0,%1
    llgf\\t%0,%1"
-  [(set_attr "op_type" "RRE,RXE")
-   (set_attr "atype"   "reg,mem")])
+  [(set_attr "op_type" "RRE,RXE")])
 
 ;
 ; zero_extendhidi2 instruction pattern(s).
         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
   "TARGET_64BIT"
   "llgh\\t%0,%1"
-  [(set_attr "op_type" "RXE")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RXE")])
 
 ;
 ; zero_extendqidi2 instruction pattern(s)
         (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
   "TARGET_64BIT"
   "llgc\\t%0,%1"
-  [(set_attr "op_type" "RXE")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RXE")])
 
 ;
 ; zero_extendhisi2 instruction pattern(s).
         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
   "TARGET_64BIT"
   "llgh\\t%0,%1"
-  [(set_attr "op_type" "RXE")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RXE")])
+
+(define_insn_and_split "*zero_extendhisi2_31"
+  [(set (match_operand:SI 0 "register_operand" "=&d")
+        (zero_extend:SI (match_operand:HI 1 "memory_operand" "Q")))
+   (clobber (reg:CC 33))]
+  "!TARGET_64BIT"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (const_int 0))
+   (parallel
+    [(set (strict_low_part (match_dup 2)) (match_dup 1))
+     (clobber (reg:CC 33))])]
+  "operands[2] = gen_lowpart (HImode, operands[0]);"
+  [(set_attr "type" "o2")
+   (set_attr "atype" "agen")])
  
 ;
 ; zero_extendqisi2 instruction pattern(s).
         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
   "TARGET_64BIT"
   "llgc\\t%0,%1"
-  [(set_attr "op_type" "RXE")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RXE")])
+
+(define_insn_and_split "*zero_extendqisi2_31"
+  [(set (match_operand:SI 0 "register_operand" "=&d")
+        (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+  "!TARGET_64BIT"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (const_int 0))
+   (set (strict_low_part (match_dup 2)) (match_dup 1))]
+  "operands[2] = gen_lowpart (QImode, operands[0]);"
+  [(set_attr "type" "o2")
+   (set_attr "atype" "agen")])
  
 ;
 ; zero_extendqihi2 instruction pattern(s).
 
 (define_insn "*zero_extendqihi2_64"
   [(set (match_operand:HI 0 "register_operand" "=d")
-        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))
-   (clobber (reg:CC 33))]
+        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
   "TARGET_64BIT"
   "llgc\\t%0,%1"
-  [(set_attr "op_type" "RXE")
-   (set_attr "atype"   "mem")])
+  [(set_attr "op_type" "RXE")])
+
+(define_insn_and_split "*zero_extendqihi2_31"
+  [(set (match_operand:HI 0 "register_operand" "=&d")
+        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
+  "!TARGET_64BIT"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (const_int 0))
+   (set (strict_low_part (match_dup 2)) (match_dup 1))]
+  "operands[2] = gen_lowpart (QImode, operands[0]);"
+  [(set_attr "type" "o2")
+   (set_attr "atype" "agen")])
+
 
 ;
 ; fixuns_truncdfdi2 and fix_truncdfsi2 instruction pattern(s).
   "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "cgdbr\\t%0,%h2,%1"
   [(set_attr "op_type" "RRE")
-   (set_attr "type"    "other")])
+   (set_attr "type"    "ftoi")])
 
 ;
 ; fixuns_truncdfsi2 and fix_truncdfsi2 instruction pattern(s).
    return \"l\\t%0,%N4\";
 }"
   [(set_attr "op_type" "NN")
-   (set_attr "type"    "other")
+   (set_attr "type"    "ftoi")
+   (set_attr "atype"   "agen")
    (set_attr "length"  "20")])
 
 ;
   "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "cgebr\\t%0,%h2,%1"
   [(set_attr "op_type" "RRE")
-   (set_attr "type"    "other")])
+   (set_attr "type"    "ftoi")])
 
 ;
 ; fixuns_truncsfsi2 and fix_truncsfsi2 instruction pattern(s).
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "cfebr\\t%0,%h2,%1"
   [(set_attr "op_type" "RRE")
-   (set_attr "type"    "other")])
+   (set_attr "type"    "ftoi")])
 
 ;
 ; floatdidf2 instruction pattern(s).
   "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "cegbr\\t%0,%1"
   [(set_attr "op_type" "RRE")
-   (set_attr "type"    "other" )])
+   (set_attr "type"    "itof" )])
 
 ;
 ; floatsidf2 instruction pattern(s).
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "cdfbr\\t%0,%1"
   [(set_attr "op_type" "RRE")
-   (set_attr "type"   "other" )])
+   (set_attr "type"   "itof" )])
 
 (define_insn "floatsidf2_ibm"
   [(set (match_operand:DF 0 "register_operand" "=f")
 }"
   [(set_attr "op_type" "NN")
    (set_attr "type"    "other" )
+   (set_attr "atype"   "agen")
    (set_attr "length"  "20")])
 
 ;
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "cefbr\\t%0,%1"
   [(set_attr "op_type" "RRE")
-   (set_attr "type"    "other" )])
+   (set_attr "type"    "itof" )])
 
 ;
 ; truncdfsf2 instruction pattern(s).
         (float_truncate:SF (match_operand:DF 1 "general_operand" "f")))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "ledbr\\t%0,%1"
-  [(set_attr "op_type"  "RR")])
+  [(set_attr "op_type"  "RRE")])
 
 (define_insn "truncdfsf2_ibm"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
    lrer\\t%0,%1
    le\\t%0,%1"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"   "floads,floads")])
 
 ;
 ; extendsfdf2 instruction pattern(s).
   "@
    ldebr\\t%0,%1
    ldeb\\t%0,%1"
-  [(set_attr "op_type"  "RRE,RXE")])
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"   "floads,floads")])
 
 (define_insn "extendsfdf2_ibm"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
   "@
    sdr\\t%0,%0\;ler\\t%0,%1
    sdr\\t%0,%0\;le\\t%0,%1"
-  [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "atype"    "reg,mem")
+  [(set_attr "op_type"  "NN,NN")
+   (set_attr "atype"    "reg,agen")
+   (set_attr "length"   "4,6")
    (set_attr "type"     "o2,o2")]) 
 
 
 ; adddi3 instruction pattern(s).
 ;
 
-(define_insn "addaddr_esame"
-  [(set (match_operand:DI 0 "register_operand" "=a,a")
-        (plus:DI (match_operand:DI 1 "register_operand" "%a,a")
-                 (match_operand:DI 2 "nonmemory_operand" "J,a")))]
-  "TARGET_64BIT && (((REGNO (operands[1]) == STACK_POINTER_REGNUM ) ||
-     (REGNO (operands[1]) == BASE_REGISTER)) && 
-       (GET_CODE (operands[2]) == REG ||
-        CONST_OK_FOR_LETTER_P (INTVAL (operands[2]),'J')))"
+(define_insn "*la_64_cc"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+        (match_operand:QI 1 "address_operand"  "p"))
+   (clobber (reg:CC 33))]
+  "TARGET_64BIT
+   && preferred_la_operand_p (operands[1], 1)"
+  "#"
+  [(set_attr "op_type"  "RX")
+   (set_attr "type"     "la")])
+
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+        (match_operand:QI 1 "address_operand" ""))
+   (clobber (reg:CC 33))]
+  "TARGET_64BIT && reload_completed
+   && preferred_la_operand_p (operands[1], 0)"
+  [(set (match_dup 0) (match_dup 1))])
+
+(define_insn "*adddi3_sign"
+  [(set (match_operand:DI 0 "register_operand" "=d,d")
+        (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
+                 (match_operand:DI 1 "register_operand" "0,0")))
+   (clobber (reg:CC 33))]
+  "TARGET_64BIT"
+  "@
+   agfr\\t%0,%2
+   agf\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*adddi3_zero_cc"
+  [(set (reg 33) 
+        (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
+                          (match_operand:DI 1 "register_operand" "0,0"))
+                 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=d,d")
+        (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
+  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+  "@
+   algfr\\t%0,%2
+   algf\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*adddi3_zero_cconly"
+  [(set (reg 33) 
+        (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
+                          (match_operand:DI 1 "register_operand" "0,0"))
+                 (const_int 0)))
+   (clobber (match_scratch:DI 0 "=d,d"))]
+  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+  "@
+   algfr\\t%0,%2
+   algf\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*adddi3_zero"
+  [(set (match_operand:DI 0 "register_operand" "=d,d")
+        (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
+                 (match_operand:DI 1 "register_operand" "0,0")))
+   (clobber (reg:CC 33))]
+  "TARGET_64BIT"
+  "@
+   algfr\\t%0,%2
+   algf\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*adddi3_imm_cc"
+  [(set (reg 33) 
+        (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "0")
+                          (match_operand:DI 2 "const_int_operand" "K"))
+                 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=d")
+        (plus:DI (match_dup 1) (match_dup 2)))]
+  "TARGET_64BIT         
+   && s390_match_ccmode (insn, CCAmode) 
+   && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
+  "aghi\\t%0,%h2"
+  [(set_attr "op_type"  "RI")])
+
+(define_insn "*adddi3_cc"
+  [(set (reg 33) 
+        (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+                          (match_operand:DI 2 "general_operand" "d,m"))
+                 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=d,d")
+        (plus:DI (match_dup 1) (match_dup 2)))]
+  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+  "@
+   algr\\t%0,%2
+   alg\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*adddi3_cconly"
+  [(set (reg 33) 
+        (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+                          (match_operand:DI 2 "general_operand" "d,m"))
+                 (const_int 0)))
+   (clobber (match_scratch:DI 0 "=d,d"))]
+  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+  "@
+   algr\\t%0,%2
+   alg\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*adddi3_cconly2"
+  [(set (reg 33) 
+        (compare (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+                 (neg:SI (match_operand:DI 2 "general_operand" "d,m"))))
+   (clobber (match_scratch:DI 0 "=d,d"))]
+  "s390_match_ccmode(insn, CCLmode) && TARGET_64BIT"
   "@
-   la\\t%0,%c2(,%1)
-   la\\t%0,0(%1,%2)"
-  [(set_attr "op_type" "RX")
-   (set_attr "atype"   "mem")
-   (set_attr "type"    "la")])
+   algr\\t%0,%2
+   alg\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
 
-(define_insn "adddi3_64"
+(define_insn "*adddi3_64"
   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
-        (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
+        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
                  (match_operand:DI 2 "general_operand" "d,K,m") ) )
    (clobber (reg:CC 33))]
   "TARGET_64BIT"
    agr\\t%0,%2
    aghi\\t%0,%h2
    ag\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RI,RXE")
-   (set_attr "atype"    "reg,reg,mem")])
+  [(set_attr "op_type"  "RRE,RI,RXE")])
 
-(define_insn "adddi3_31"
-  [(set (match_operand:DI 0 "register_operand" "=d,d")
-        (plus:DI (match_operand:DI 1 "register_operand" "0,0")
-                 (match_operand:DI 2 "general_operand" "d,m") ) )
+(define_insn_and_split "*adddi3_31"
+  [(set (match_operand:DI 0 "register_operand" "=&d")
+        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
+                 (match_operand:DI 2 "general_operand" "dm") ) )
    (clobber (reg:CC 33))]
   "!TARGET_64BIT"
-  "*
-{
-   switch (which_alternative)
-     {
-     case 0: /* d <- d */
-       output_asm_insn (\"ar\\t%0,%2\", operands);
-       output_asm_insn (\"alr\\t%N0,%N2\", operands);
-       break;
-
-     case 1: /* d <- m */
-       output_asm_insn (\"a\\t%0,%2\", operands);
-       output_asm_insn (\"al\\t%N0,%N2\", operands);
-       break;
-
-     default:
-       abort ();
-     }
-
-   output_asm_insn (\"brc\\t12,.+8\", operands);
-   return \"ahi\\t%0,1\";
-}"
-  [(set_attr "op_type" "NN,NN")
-   (set_attr "atype"   "reg,mem")
-   (set_attr "type"    "o2,o2")
-   (set_attr "length"  "12,16")])
+  "#"
+  "&& reload_completed"
+  [(parallel
+    [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
+     (clobber (reg:CC 33))])
+   (parallel
+    [(set (reg:CCL1 33)
+          (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
+                        (match_dup 7)))
+     (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
+   (set (pc)
+        (if_then_else (ltu (reg:CCL1 33) (const_int 0))
+                      (pc)
+                      (label_ref (match_dup 9))))
+   (parallel
+    [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
+     (clobber (reg:CC 33))])
+   (match_dup 9)]
+  "operands[3] = operand_subword (operands[0], 0, 1, DImode);
+   operands[4] = operand_subword (operands[1], 0, 1, DImode);
+   operands[5] = operand_subword (operands[2], 0, 1, DImode);
+   operands[6] = operand_subword (operands[0], 1, 1, DImode);
+   operands[7] = operand_subword (operands[1], 1, 1, DImode);
+   operands[8] = operand_subword (operands[2], 1, 1, DImode);
+   operands[9] = gen_label_rtx ();"
+  [(set_attr "op_type"  "NN")
+   (set_attr "type"     "o3")])
 
 (define_expand "adddi3"
-  [(set (match_operand:DI 0 "register_operand" "")
-        (plus:DI (match_operand:DI 1 "register_operand" "")
-                 (match_operand:DI 2 "general_operand" "")))]
+  [(parallel
+    [(set (match_operand:DI 0 "register_operand" "")
+          (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
+                   (match_operand:DI 2 "general_operand" "")))
+     (clobber (reg:CC 33))])]
   ""
-  "
-{
-  if (TARGET_64BIT)
-    emit_insn(gen_adddi3_64 (operands[0],operands[1],operands[2]));
-  else
-    emit_insn(gen_adddi3_31 (operands[0],operands[1],operands[2]));
-  DONE;                
-}")
+  "")
 
 (define_insn "*la_64"
   [(set (match_operand:DI 0 "register_operand" "=d")
   "TARGET_64BIT"
   "la\\t%0,%a1"      
   [(set_attr "op_type" "RX")
-   (set_attr "atype"   "mem")
    (set_attr "type"    "la")])
 
 (define_expand "reload_indi"
 ; addsi3 instruction pattern(s).
 ;
 
-(define_insn "*la_ccclobber"
+(define_insn "*la_31_cc"
   [(set (match_operand:SI 0 "register_operand" "=d")
         (match_operand:QI 1 "address_operand"  "p"))
    (clobber (reg:CC 33))]
-  "legitimate_la_operand_p (operands[1])"
-  "la\\t%0,%a1"
-   [(set_attr "op_type"  "RX")
-    (set_attr "atype"    "mem")
-    (set_attr "type"     "la")])
+  "!TARGET_64BIT
+   && preferred_la_operand_p (operands[1], 1)"
+  "#"
+  [(set_attr "op_type"  "RX")
+   (set_attr "type"     "la")])
+
+(define_split
+  [(set (match_operand:SI 0 "register_operand" "")
+        (match_operand:QI 1 "address_operand" ""))
+   (clobber (reg:CC 33))]
+  "!TARGET_64BIT && reload_completed
+   && preferred_la_operand_p (operands[1], 0)"
+  [(set (match_dup 0) (match_dup 1))])
+
+(define_insn "*addsi3_imm_cc"
+  [(set (reg 33) 
+        (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "0")
+                          (match_operand:SI 2 "const_int_operand" "K"))
+                 (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=d")
+        (plus:SI (match_dup 1) (match_dup 2)))]
+  "s390_match_ccmode (insn, CCAmode)
+   && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
+  "ahi\\t%0,%h2"
+  [(set_attr "op_type"  "RI")])
+
+(define_insn "*addsi3_carry1_cc"
+  [(set (reg 33) 
+        (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+                          (match_operand:SI 2 "general_operand" "d,m"))
+                 (match_dup 1)))
+   (set (match_operand:SI 0 "register_operand" "=d,d")
+        (plus:SI (match_dup 1) (match_dup 2)))]
+  "s390_match_ccmode (insn, CCL1mode)" 
+  "@
+   alr\\t%0,%2
+   al\\t%0,%2"
+  [(set_attr "op_type"  "RR,RX")])
+
+(define_insn "*addsi3_carry1_cconly"
+  [(set (reg 33) 
+        (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+                          (match_operand:SI 2 "general_operand" "d,m"))
+                 (match_dup 1)))
+   (clobber (match_scratch:SI 0 "=d,d"))]
+  "s390_match_ccmode (insn, CCL1mode)" 
+  "@
+   alr\\t%0,%2
+   al\\t%0,%2"
+  [(set_attr "op_type"  "RR,RX")])
+
+(define_insn "*addsi3_carry2_cc"
+  [(set (reg 33) 
+        (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+                          (match_operand:SI 2 "general_operand" "d,m"))
+                 (match_dup 2)))
+   (set (match_operand:SI 0 "register_operand" "=d,d")
+        (plus:SI (match_dup 1) (match_dup 2)))]
+  "s390_match_ccmode (insn, CCL1mode)" 
+  "@
+   alr\\t%0,%2
+   al\\t%0,%2"
+  [(set_attr "op_type"  "RR,RX")])
+
+(define_insn "*addsi3_carry2_cconly"
+  [(set (reg 33) 
+        (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+                          (match_operand:SI 2 "general_operand" "d,m"))
+                 (match_dup 2)))
+   (clobber (match_scratch:SI 0 "=d,d"))]
+  "s390_match_ccmode (insn, CCL1mode)" 
+  "@
+   alr\\t%0,%2
+   al\\t%0,%2"
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*addsi3_cc"
   [(set (reg 33) 
-        (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
-                          (match_operand:SI 2 "nonimmediate_operand" "d,m"))
+        (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+                          (match_operand:SI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (set (match_operand:SI 0 "register_operand" "=d,d")
         (plus:SI (match_dup 1) (match_dup 2)))]
-  "s390_match_ccmode(insn, CCLmode)"
+  "s390_match_ccmode (insn, CCLmode)" 
   "@
    alr\\t%0,%2
    al\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])  
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*addsi3_cconly"
   [(set (reg 33) 
-        (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                           (match_operand:SI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (clobber (match_scratch:SI 0 "=d,d"))]
-  "s390_match_ccmode(insn, CCLmode)"
+  "s390_match_ccmode (insn, CCLmode)" 
   "@
    alr\\t%0,%2
    al\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])  
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*addsi3_cconly2"
   [(set (reg 33) 
-        (compare (match_operand:SI 1 "register_operand" "%0,0")
+        (compare (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                  (neg:SI (match_operand:SI 2 "general_operand" "d,m"))))
    (clobber (match_scratch:SI 0 "=d,d"))]
   "s390_match_ccmode(insn, CCLmode)"
   "@
    alr\\t%0,%2
    al\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])  
+  [(set_attr "op_type"  "RR,RX")])
+
+(define_insn "*addsi3_sign"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (plus:SI (match_operand:SI 1 "register_operand" "0")
+                 (sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))
+   (clobber (reg:CC 33))]
+  ""
+  "ah\\t%0,%2"
+  [(set_attr "op_type"  "RX")])
+
+(define_insn "*addsi3_sub"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (plus:SI (match_operand:SI 1 "register_operand" "0")
+                 (subreg:SI (match_operand:HI 2 "memory_operand" "m") 0)))
+   (clobber (reg:CC 33))]
+  ""
+  "ah\\t%0,%2"
+  [(set_attr "op_type"  "RX")])
 
 (define_insn "addsi3"
   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
-        (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0")
+        (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
                  (match_operand:SI 2 "general_operand" "d,K,m")))
    (clobber (reg:CC 33))]
   ""
    ar\\t%0,%2
    ahi\\t%0,%h2
    a\\t%0,%2"
-  [(set_attr "op_type"  "RR,RI,RX")
-   (set_attr "atype"    "reg,reg,mem")])
+  [(set_attr "op_type"  "RR,RI,RX")])
 
 (define_insn "*la_31"
   [(set (match_operand:SI 0 "register_operand" "=d")
         (match_operand:QI 1 "address_operand" "p"))]
-  "legitimate_la_operand_p (operands[1])"
+  "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
+  "la\\t%0,%a1"
+  [(set_attr "op_type"  "RX")
+   (set_attr "type"     "la")])
+
+(define_insn "*la_31_and"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (and:SI (match_operand:QI 1 "address_operand" "p")
+                (const_int 2147483647)))]
+  "!TARGET_64BIT"
+  "la\\t%0,%a1"
+  [(set_attr "op_type"  "RX")
+   (set_attr "type"     "la")])
+
+(define_insn_and_split "*la_31_and_cc"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (and:SI (match_operand:QI 1 "address_operand" "p")
+                (const_int 2147483647)))
+   (clobber (reg:CC 33))]
+  "!TARGET_64BIT"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) 
+        (and:SI (match_dup 1) (const_int 2147483647)))]
+  ""
+  [(set_attr "op_type"  "RX")
+   (set_attr "type"     "la")])
+
+(define_insn "force_la_31"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (match_operand:QI 1 "address_operand" "p"))
+   (use (const_int 0))]
+  "!TARGET_64BIT"
   "la\\t%0,%a1"
   [(set_attr "op_type"  "RX")
-   (set_attr "atype"    "mem")
    (set_attr "type"     "la")])
 
 (define_expand "reload_insi"
 }")
 
 
-;
-; addhi3 instruction pattern(s).
-;
-
-(define_insn "addhi3"
-  [(set (match_operand:HI 0 "register_operand" "=d,d,d")
-        (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
-                 (match_operand:HI 2 "general_operand" "d,K,m")))
-   (clobber (reg:CC 33))]
-  ""
-  "@
-   ar\\t%0,%2
-   ahi\\t%0,%h2
-   ah\\t%0,%2"
-  [(set_attr "op_type"  "RR,RI,RX")
-   (set_attr "atype"    "reg,reg,mem")])
-
-
-;
-; addqi3 instruction pattern(s).
-;
-
-(define_insn "addqi3"
-  [(set (match_operand:QI 0 "register_operand" "=d,d")
-        (plus:QI (match_operand:QI 1 "register_operand" "%0,0")
-                 (match_operand:QI 2 "general_operand" "a,n")))
-   (clobber (reg:CC 33))]
-  ""
-  "@
-   ar\\t%0,%2
-   ahi\\t%0,%h2"
-  [(set_attr "op_type"  "RX,RX")
-   (set_attr "atype"    "reg,mem")])
-
-
 ;
 ; adddf3 instruction pattern(s).
 ;
 (define_expand "adddf3"
   [(parallel
     [(set (match_operand:DF 0 "register_operand" "=f,f")
-          (plus:DF (match_operand:DF 1 "register_operand" "%0,0")
+          (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
                    (match_operand:DF 2 "general_operand" "f,m")))
      (clobber (reg:CC 33))])]
   "TARGET_HARD_FLOAT"
 
 (define_insn "*adddf3"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
-        (plus:DF (match_operand:DF 1 "register_operand" "%0,0")
+        (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
                  (match_operand:DF 2 "general_operand" "f,m")))
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
    adbr\\t%0,%2
    adb\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"     "fsimpd,fsimpd")])
 
 (define_insn "*adddf3_ibm"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
-        (plus:DF (match_operand:DF 1 "register_operand" "%0,0")
+        (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
                  (match_operand:DF 2 "general_operand" "f,m")))
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
    adr\\t%0,%2
    ad\\t%0,%2"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "fsimpd,fsimpd")])
 
 ;
 ; addsf3 instruction pattern(s).
 (define_expand "addsf3"
   [(parallel
     [(set (match_operand:SF 0 "register_operand" "=f,f")
-          (plus:SF (match_operand:SF 1 "register_operand" "%0,0")
+          (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
                    (match_operand:SF 2 "general_operand" "f,m")))
      (clobber (reg:CC 33))])]
   "TARGET_HARD_FLOAT"
 
 (define_insn "*addsf3"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
-        (plus:SF (match_operand:SF 1 "register_operand" "%0,0")
+        (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
                  (match_operand:SF 2 "general_operand" "f,m")))
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
    aebr\\t%0,%2
    aeb\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"     "fsimps,fsimps")])
 
 (define_insn "*addsf3"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
-        (plus:SF (match_operand:SF 1 "register_operand" "%0,0")
+        (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
                  (match_operand:SF 2 "general_operand" "f,m")))
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
    aer\\t%0,%2
    ae\\t%0,%2"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "fsimps,fsimps")])
 
 
 ;;
 ; subdi3 instruction pattern(s).
 ;
 
+(define_insn "*subdi3_sign"
+  [(set (match_operand:DI 0 "register_operand" "=d,d")
+        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                  (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m"))))
+   (clobber (reg:CC 33))]
+  "TARGET_64BIT"
+  "@
+   sgfr\\t%0,%2
+   sgf\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*subdi3_zero_cc"
+  [(set (reg 33) 
+        (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                           (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
+                 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=d,d")
+        (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
+  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+  "@
+   slgfr\\t%0,%2
+   slgf\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*subdi3_zero_cconly"
+  [(set (reg 33) 
+        (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                           (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
+                 (const_int 0)))
+   (clobber (match_scratch:DI 0 "=d,d"))]
+  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+  "@
+   slgfr\\t%0,%2
+   slgf\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*subdi3_zero"
+  [(set (match_operand:DI 0 "register_operand" "=d,d")
+        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                  (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))))
+   (clobber (reg:CC 33))]
+  "TARGET_64BIT"
+  "@
+   slgfr\\t%0,%2
+   slgf\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*subdi3_cc"
+  [(set (reg 33)
+        (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                           (match_operand:DI 2 "general_operand" "d,m"))
+                 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=d,d")
+        (minus:DI (match_dup 1) (match_dup 2)))]
+  "s390_match_ccmode (insn, CCLmode)"
+  "@
+   slgr\\t%0,%2
+   slg\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
+(define_insn "*subdi3_cconly"
+  [(set (reg 33)
+        (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                           (match_operand:DI 2 "general_operand" "d,m"))
+                 (const_int 0)))
+   (clobber (match_scratch:DI 0 "=d,d"))]
+  "s390_match_ccmode (insn, CCLmode)"
+  "@
+   slgr\\t%0,%2
+   slg\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")])
+
 (define_insn "*subdi3_64"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
         (minus:DI (match_operand:DI 1 "register_operand" "0,0")
   "@
    sgr\\t%0,%2
    sg\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RRE")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RRE")])
 
-(define_insn "subdi3"
-  [(set (match_operand:DI 0 "register_operand" "=d,d")
-        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
-                  (match_operand:DI 2 "general_operand" "d,m")))
+(define_insn_and_split "*subdi3_31"
+  [(set (match_operand:DI 0 "register_operand" "=&d")
+        (minus:DI (match_operand:DI 1 "register_operand" "0")
+                  (match_operand:DI 2 "general_operand" "dm") ) )
    (clobber (reg:CC 33))]
+  "!TARGET_64BIT"
+  "#"
+  "&& reload_completed"
+  [(parallel
+    [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
+     (clobber (reg:CC 33))])
+   (parallel
+    [(set (reg:CCL2 33)
+          (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
+                        (match_dup 7)))
+     (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
+   (set (pc)
+        (if_then_else (gtu (reg:CCL2 33) (const_int 0))
+                      (pc)
+                      (label_ref (match_dup 9))))
+   (parallel
+    [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
+     (clobber (reg:CC 33))])
+   (match_dup 9)]
+  "operands[3] = operand_subword (operands[0], 0, 1, DImode);
+   operands[4] = operand_subword (operands[1], 0, 1, DImode);
+   operands[5] = operand_subword (operands[2], 0, 1, DImode);
+   operands[6] = operand_subword (operands[0], 1, 1, DImode);
+   operands[7] = operand_subword (operands[1], 1, 1, DImode);
+   operands[8] = operand_subword (operands[2], 1, 1, DImode);
+   operands[9] = gen_label_rtx ();"
+  [(set_attr "op_type"  "NN")
+   (set_attr "type"     "o3")])
+
+(define_expand "subdi3"
+  [(parallel
+    [(set (match_operand:DI 0 "register_operand" "")
+          (minus:DI (match_operand:DI 1 "register_operand" "")
+                    (match_operand:DI 2 "general_operand" "")))
+     (clobber (reg:CC 33))])]
   ""
-  "*
-{
-   switch (which_alternative)
-     {
-     case 0: /* d <- d */
-       output_asm_insn (\"sr\\t%0,%2\", operands);
-       output_asm_insn (\"slr\\t%N0,%N2\", operands);
-       break;
-     case 1: /* d <- m */
-       output_asm_insn (\"s\\t%0,%2\", operands);
-       output_asm_insn (\"sl\\t%N0,%N2\", operands);
-       break;
-
-     default:
-       abort ();
-     }
-
-   output_asm_insn (\"brc\\t11,.+8\", operands);
-   return \"ahi\\t%0,-1\";
-}"
-  [(set_attr "op_type"  "NN,NN")
-   (set_attr "atype"    "reg,mem")
-   (set_attr "type"     "other,other")
-   (set_attr "length"   "12,16")])
+  "")
 
 ;
 ; subsi3 instruction pattern(s).
 ;
 
+(define_insn "*subsi3_borrow_cc"
+  [(set (reg 33)
+        (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
+                           (match_operand:SI 2 "general_operand" "d,m"))
+                 (match_dup 1)))
+   (set (match_operand:SI 0 "register_operand" "=d,d")
+        (minus:SI (match_dup 1) (match_dup 2)))]
+  "s390_match_ccmode(insn, CCL2mode)"
+  "@
+   slr\\t%0,%2
+   sl\\t%0,%2"
+  [(set_attr "op_type"  "RR,RX")])
+
+(define_insn "*subsi3_borrow_cconly"
+  [(set (reg 33)
+        (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
+                           (match_operand:SI 2 "general_operand" "d,m"))
+                 (match_dup 1)))
+   (clobber (match_scratch:SI 0 "=d,d"))]
+  "s390_match_ccmode(insn, CCL2mode)"
+  "@
+   slr\\t%0,%2
+   sl\\t%0,%2"
+  [(set_attr "op_type"  "RR,RX")])
+
 (define_insn "*subsi3_cc"
   [(set (reg 33)
         (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
   "@
    slr\\t%0,%2
    sl\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*subsi3_cconly"
   [(set (reg 33)
   "@
    slr\\t%0,%2
    sl\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
+
+(define_insn "*subsi3_sign"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (minus:SI (match_operand:SI 1 "register_operand" "0")
+                  (sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))
+   (clobber (reg:CC 33))]
+  ""
+  "sh\\t%0,%2"
+  [(set_attr "op_type"  "RX")])
+
+(define_insn "*subsi3_sub"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (minus:SI (match_operand:SI 1 "register_operand" "0")
+                  (subreg:SI (match_operand:HI 2 "memory_operand" "m") 0)))
+   (clobber (reg:CC 33))]
+  ""
+  "sh\\t%0,%2"
+  [(set_attr "op_type"  "RX")])
 
 (define_insn "subsi3"
   [(set (match_operand:SI 0 "register_operand" "=d,d")
   "@
    sr\\t%0,%2
    s\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
-
-;
-; subhi3 instruction pattern(s).
-;
-
-(define_insn "subhi3"
-  [(set (match_operand:HI 0 "register_operand" "=d,d")
-        (minus:HI (match_operand:HI 1 "register_operand" "0,0")
-                  (match_operand:HI 2 "general_operand" "d,m")))
-   (clobber (reg:CC 33))]
-  ""
-  "@
-   sr\\t%0,%2
-   sh\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
-
-;
-; subqi3 instruction pattern(s).
-;
+  [(set_attr "op_type"  "RR,RX")])
 
-(define_insn "subqi3"
-  [(set (match_operand:QI 0 "register_operand" "=d")
-        (minus:QI (match_operand:QI 1 "register_operand" "0")
-                  (match_operand:QI 2 "register_operand" "d")))
-   (clobber (reg:CC 33))]
-  ""
-  "sr\\t%0,%2"
-   [(set_attr "op_type"  "RR")])
 
 ;
 ; subdf3 instruction pattern(s).
   "@
    sdbr\\t%0,%2
    sdb\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"     "fsimpd,fsimpd")])
 
 (define_insn "*subdf3_ibm"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
    sdr\\t%0,%2
    sd\\t%0,%2"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "fsimpd,fsimpd")])
 
 ;
 ; subsf3 instruction pattern(s).
   "@
    sebr\\t%0,%2
    seb\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"     "fsimps,fsimps")])
 
 (define_insn "*subsf3_ibm"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
    ser\\t%0,%2
    se\\t%0,%2"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "fsimps,fsimps")])
 
 
 ;;
 ; muldi3 instruction pattern(s).
 ;
 
+(define_insn "*muldi3_sign"
+  [(set (match_operand:DI 0 "register_operand" "=d,d")
+        (mult:DI (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m"))
+                 (match_operand:DI 1 "register_operand" "0,0")))]
+  "TARGET_64BIT"
+  "@
+   msgfr\\t%0,%2
+   msgf\\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"     "imul")])
+
+
 (define_insn "muldi3"
   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
-        (mult:DI (match_operand:DI 1 "register_operand" "%0,0,0")
-                 (match_operand:DI 2 "general_operand" "d,K,m")))
-   (clobber (reg:CC 33))]
+        (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
+                 (match_operand:DI 2 "general_operand" "d,K,m")))]
   "TARGET_64BIT"
   "@
    msgr\\t%0,%2
    mghi\\t%0,%h2
    msg\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RI,RX")
-   (set_attr "atype"    "reg,reg,mem")
+  [(set_attr "op_type"  "RRE,RI,RXE")
    (set_attr "type"     "imul")])
 
 ;
 
 (define_insn "mulsi3"
   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
-        (mult:SI  (match_operand:SI 1 "register_operand" "%0,0,0")
-                  (match_operand:SI 2 "general_operand" "d,K,m")))
-   (clobber (reg:CC 33))]
+        (mult:SI  (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+                  (match_operand:SI 2 "general_operand" "d,K,m")))]
   ""
   "@
    msr\\t%0,%2
    mhi\\t%0,%h2
    ms\\t%0,%2"
   [(set_attr "op_type"  "RRE,RI,RX")
-   (set_attr "atype"    "reg,reg,mem")
    (set_attr "type"     "imul")])
 
 ;
 
 (define_expand "mulsidi3"
   [(set (match_operand:DI 0 "register_operand" "")
-       (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))
                 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))))]
   "!TARGET_64BIT"
   "
 {
   rtx insn;
 
-  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
-  emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
+  emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
   insn = emit_insn (gen_mulsi_6432 (operands[0], operands[0], operands[2]));
 
   REG_NOTES (insn) =
          (mult:DI (sign_extend:DI 
                    (truncate:SI (match_operand:DI 1 "register_operand" "0,0")))
                   (sign_extend:DI
-                   (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
-    (clobber (reg:CC 33))]
+                   (match_operand:SI 2 "nonimmediate_operand" "d,m"))))]
    "!TARGET_64BIT"
    "@
     mr\\t%0,%2
     m\\t%0,%2"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")
    (set_attr "type"     "imul")])
  
 ;
 (define_expand "muldf3"
   [(parallel
     [(set (match_operand:DF 0 "register_operand" "=f,f")
-          (mult:DF (match_operand:DF 1 "register_operand" "%0,0")
+          (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
                    (match_operand:DF 2 "general_operand" "f,m")))
      (clobber (reg:CC 33))])]
   "TARGET_HARD_FLOAT"
 
 (define_insn "*muldf3"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
-        (mult:DF (match_operand:DF 1 "register_operand" "%0,0")
+        (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
                  (match_operand:DF 2 "general_operand" "f,m")))
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
    mdbr\\t%0,%2
    mdb\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "type"     "fmul")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"     "fmuld")])
 
 (define_insn "*muldf3_ibm"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
-        (mult:DF (match_operand:DF 1 "register_operand" "%0,0")
+        (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
                  (match_operand:DF 2 "general_operand" "f,m")))
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
    mdr\\t%0,%2
    md\\t%0,%2"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "type"    "fmul")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"    "fmuld")])
 
 ;
 ; mulsf3 instruction pattern(s).
 (define_expand "mulsf3"
   [(parallel
     [(set (match_operand:SF 0 "register_operand" "=f,f")
-          (mult:SF (match_operand:SF 1 "register_operand" "%0,0")
+          (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
                    (match_operand:SF 2 "general_operand" "f,m")))
      (clobber (reg:CC 33))])]
   "TARGET_HARD_FLOAT"
 
 (define_insn "*mulsf3"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
-        (mult:SF (match_operand:SF 1 "register_operand" "%0,0")
+        (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
                  (match_operand:SF 2 "general_operand" "f,m")))
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "@
    meebr\\t%0,%2
    meeb\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "type"     "fmul")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"     "fmuls")])
 
 (define_insn "*mulsf3_ibm"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
-        (mult:SF (match_operand:SF 1 "register_operand" "%0,0")
+        (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
                  (match_operand:SF 2 "general_operand" "f,m")))
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
    mer\\t%0,%2
    me\\t%0,%2"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "type"     "fmul")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "fmuls")])
 
 
 ;;
    dsgr\\t%0,%2
    dsg\\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "type"     "idiv")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "idiv")])
 
 (define_insn "divmodtisi3"
   [(set (match_operand:TI 0 "register_operand" "=d,d")
    dsgfr\\t%0,%2
    dsgf\\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "type"     "idiv")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "idiv")])
 
 ;
 ; udivmoddi4 instruction pattern(s).
    dlgr\\t%0,%2
    dlg\\t%0,%2"
   [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "type"     "idiv")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "idiv")])
 
 ;
 ; divmodsi4 instruction pattern(s).
    dr\\t%0,%2
    d\\t%0,%2"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "type"     "idiv")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "idiv")])
 
 ;
 ; udivsi3 and umodsi3 instruction pattern(s).
   "@
    ddbr\\t%0,%2
    ddb\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "type"     "fdiv")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"     "fdivd")])
 
 (define_insn "*divdf3_ibm"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
    ddr\\t%0,%2
    dd\\t%0,%2"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "type"     "fdiv")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "fdivd")])
 
 ;
 ; divsf3 instruction pattern(s).
   "@
    debr\\t%0,%2
    deb\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "type"     "fdiv")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")
+   (set_attr "type"     "fdivs")])
 
 (define_insn "*divsf3"
   [(set (match_operand:SF 0 "register_operand" "=f,f")
    der\\t%0,%2
    de\\t%0,%2"
   [(set_attr "op_type"  "RR,RX")
-   (set_attr "type"     "fdiv")
-   (set_attr "atype"    "reg,mem")])
+   (set_attr "type"     "fdivs")])
 
 
 ;;
 
 (define_insn "*anddi3_cc"
   [(set (reg 33)
-        (compare (and:DI (match_operand:DI 1 "register_operand" "%0,0")
+        (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:DI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=d,d")
   "@
    ngr\\t%0,%2
    ng\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")])
 
 (define_insn "*anddi3_cconly"
   [(set (reg 33)
-        (compare (and:DI (match_operand:DI 1 "register_operand" "%0,0")
+        (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:DI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (clobber (match_scratch:DI 0 "=d,d"))]
   "@
    ngr\\t%0,%2
    ng\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")])
 
 (define_insn "*anddi3_ni"
   [(set (match_operand:DI 0 "register_operand" "=d")
-        (and:DI (match_operand:DI 1 "register_operand" "%0")
+        (and:DI (match_operand:DI 1 "nonimmediate_operand" "0")
                 (match_operand:DI 2 "immediate_operand" "n")))
    (clobber (reg:CC 33))]
   "TARGET_64BIT && s390_single_hi (operands[2], DImode, -1) >= 0"
       default: abort ();
     }
 }"
-  [(set_attr "op_type"  "RI")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RI")])
 
 (define_insn "anddi3"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
-        (and:DI (match_operand:DI 1 "register_operand" "%0,0")
+        (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
                 (match_operand:DI 2 "general_operand" "d,m")))
    (clobber (reg:CC 33))]
   "TARGET_64BIT"
   "@
    ngr\\t%0,%2
    ng\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")])
 
 (define_insn "*anddi3_ss"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
+  [(set (match_operand:DI 0 "s_operand" "=Q")
         (and:DI (match_dup 0)
-                (match_operand:DI 1 "s_imm_operand" "Qo")))
+                (match_operand:DI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "nc\\t%O0(8,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 (define_insn "*anddi3_ss_inv"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
-        (and:DI (match_operand:DI 1 "s_imm_operand" "Qo")
+  [(set (match_operand:DI 0 "s_operand" "=Q")
+        (and:DI (match_operand:DI 1 "s_imm_operand" "Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "nc\\t%O0(8,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 ;
 ; andsi3 instruction pattern(s).
 
 (define_insn "*andsi3_cc"
   [(set (reg 33)
-        (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:SI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (set (match_operand:SI 0 "register_operand" "=d,d")
   "@
    nr\\t%0,%2
    n\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*andsi3_cconly"
   [(set (reg 33)
-        (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:SI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (clobber (match_scratch:SI 0 "=d,d"))]
   "@
    nr\\t%0,%2
    n\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*andsi3_ni"
   [(set (match_operand:SI 0 "register_operand" "=d")
-        (and:SI (match_operand:SI 1 "register_operand" "%0")
+        (and:SI (match_operand:SI 1 "nonimmediate_operand" "0")
                 (match_operand:SI 2 "immediate_operand" "n")))
    (clobber (reg:CC 33))]
   "TARGET_64BIT && s390_single_hi (operands[2], SImode, -1) >= 0"
       default: abort ();
     }
 }"
-  [(set_attr "op_type"  "RI")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RI")])
 
 (define_insn "andsi3"
   [(set (match_operand:SI 0 "register_operand" "=d,d")
-        (and:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                 (match_operand:SI 2 "general_operand" "d,m")))
    (clobber (reg:CC 33))]
   ""
   "@
    nr\\t%0,%2
    n\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*andsi3_ss"
-  [(set (match_operand:SI 0 "s_operand" "=Qo")
+  [(set (match_operand:SI 0 "s_operand" "=Q")
         (and:SI (match_dup 0)
-                (match_operand:SI 1 "s_imm_operand" "Qo")))
+                (match_operand:SI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "nc\\t%O0(4,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 (define_insn "*andsi3_ss_inv"
-  [(set (match_operand:SI 0 "s_operand" "=Qo")
-        (and:SI (match_operand:SI 1 "s_imm_operand" "Qo")
+  [(set (match_operand:SI 0 "s_operand" "=Q")
+        (and:SI (match_operand:SI 1 "s_imm_operand" "Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "nc\\t%O0(4,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 ;
 ; andhi3 instruction pattern(s).
   "@
    nr\\t%0,%2
    nill\\t%0,%x2"
-  [(set_attr "op_type"  "RR,RI")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RR,RI")])
 
 (define_insn "andhi3"
   [(set (match_operand:HI 0 "register_operand" "=d")
    (clobber (reg:CC 33))]
   ""
   "nr\\t%0,%2"
-  [(set_attr "op_type"  "RR")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RR")])
 
 (define_insn "*andhi3_ss"
-  [(set (match_operand:HI 0 "s_operand" "=Qo")
+  [(set (match_operand:HI 0 "s_operand" "=Q")
         (and:HI (match_dup 0)
-                (match_operand:HI 1 "s_imm_operand" "Qo")))
+                (match_operand:HI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "nc\\t%O0(2,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 (define_insn "*andhi3_ss_inv"
-  [(set (match_operand:HI 0 "s_operand" "=Qo")
-        (and:HI (match_operand:HI 1 "s_imm_operand" "Qo")
+  [(set (match_operand:HI 0 "s_operand" "=Q")
+        (and:HI (match_operand:HI 1 "s_imm_operand" "Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "nc\\t%O0(2,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 ;
 ; andqi3 instruction pattern(s).
   "@
    nr\\t%0,%2
    nill\\t%0,%b2"
-  [(set_attr "op_type"  "RR,RI")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RR,RI")])
 
 (define_insn "andqi3"
   [(set (match_operand:QI 0 "register_operand" "=d")
    (clobber (reg:CC 33))]
   ""
   "nr\\t%0,%2"
-  [(set_attr "op_type"  "RR")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RR")])
 
 (define_insn "*andqi3_ss"
-  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+  [(set (match_operand:QI 0 "s_operand" "=Q,Q")
         (and:QI (match_dup 0)
-                (match_operand:QI 1 "s_imm_operand" "n,Qo")))
+                (match_operand:QI 1 "s_imm_operand" "n,Q")))
    (clobber (reg:CC 33))]
   ""
   "@
    ni\\t%0,%b1
    nc\\t%O0(1,%R0),%1"
-  [(set_attr "op_type"  "SI,SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SI,SS")])
 
 (define_insn "*andqi3_ss_inv"
-  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
-        (and:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
+  [(set (match_operand:QI 0 "s_operand" "=Q,Q")
+        (and:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "@
    ni\\t%0,%b1
    nc\\t%O0(1,%R0),%1"
-  [(set_attr "op_type"  "SI,SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SI,SS")])
 
 
 ;;
 
 (define_insn "*iordi3_cc"
   [(set (reg 33)
-        (compare (ior:DI (match_operand:DI 1 "register_operand" "%0,0")
+        (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:DI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=d,d")
   "@
    ogr\\t%0,%2
    og\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")])
 
 (define_insn "*iordi3_cconly"
   [(set (reg 33)
-        (compare (ior:DI (match_operand:DI 1 "register_operand" "%0,0")
+        (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:DI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (clobber (match_scratch:DI 0 "=d,d"))]
   "@
    ogr\\t%0,%2
    og\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")])
 
 (define_insn "*iordi3_oi"
   [(set (match_operand:DI 0 "register_operand" "=d")
-        (ior:DI (match_operand:DI 1 "register_operand" "%0")
+        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
                 (match_operand:DI 2 "immediate_operand" "n")))
    (clobber (reg:CC 33))]
   "TARGET_64BIT && s390_single_hi (operands[2], DImode, 0) >= 0"
       default: abort ();
     }
 }"
-  [(set_attr "op_type"  "RI")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RI")])
 
 (define_insn "iordi3"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
-        (ior:DI (match_operand:DI 1 "register_operand" "%0,0")
+        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
                 (match_operand:DI 2 "general_operand" "d,m")))
    (clobber (reg:CC 33))]
   "TARGET_64BIT"
   "@
    ogr\\t%0,%2
    og\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")])
 
 (define_insn "*iordi3_ss"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
+  [(set (match_operand:DI 0 "s_operand" "=Q")
         (ior:DI (match_dup 0)
-                (match_operand:DI 1 "s_imm_operand" "Qo")))
+                (match_operand:DI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "oc\\t%O0(8,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 (define_insn "*iordi3_ss_inv"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
-        (ior:DI (match_operand:DI 1 "s_imm_operand" "Qo")
+  [(set (match_operand:DI 0 "s_operand" "=Q")
+        (ior:DI (match_operand:DI 1 "s_imm_operand" "Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "oc\\t%O0(8,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 ;
 ; iorsi3 instruction pattern(s).
 
 (define_insn "*iorsi3_cc"
   [(set (reg 33)
-        (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:SI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (set (match_operand:SI 0 "register_operand" "=d,d")
   "@
    or\\t%0,%2
    o\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*iorsi3_cconly"
   [(set (reg 33)
-        (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:SI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (clobber (match_scratch:SI 0 "=d,d"))]
   "@
    or\\t%0,%2
    o\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*iorsi3_oi"
   [(set (match_operand:SI 0 "register_operand" "=d")
-        (ior:SI (match_operand:SI 1 "register_operand" "%0")
+        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
                 (match_operand:SI 2 "immediate_operand" "n")))
    (clobber (reg:CC 33))]
   "TARGET_64BIT && s390_single_hi (operands[2], SImode, 0) >= 0"
       default: abort ();
     }
 }"
-  [(set_attr "op_type"  "RI")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RI")])
 
 (define_insn "iorsi3"
   [(set (match_operand:SI 0 "register_operand" "=d,d")
-        (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                 (match_operand:SI 2 "general_operand" "d,m")))
    (clobber (reg:CC 33))]
   ""
   "@
    or\\t%0,%2
    o\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*iorsi3_ss"
-  [(set (match_operand:SI 0 "s_operand" "=Qo")
+  [(set (match_operand:SI 0 "s_operand" "=Q")
         (ior:SI (match_dup 0)
-                (match_operand:SI 1 "s_imm_operand" "Qo")))
+                (match_operand:SI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "oc\\t%O0(4,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 (define_insn "*iorsi3_ss_inv"
-  [(set (match_operand:SI 0 "s_operand" "=Qo")
-        (ior:SI (match_operand:SI 1 "s_imm_operand" "Qo")
+  [(set (match_operand:SI 0 "s_operand" "=Q")
+        (ior:SI (match_operand:SI 1 "s_imm_operand" "Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "oc\\t%O0(4,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 ;
 ; iorhi3 instruction pattern(s).
   "@
    or\\t%0,%2
    oill\\t%0,%x2"
-  [(set_attr "op_type"  "RR,RI")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RR,RI")])
 
 (define_insn "iorhi3"
   [(set (match_operand:HI 0 "register_operand" "=d")
    (clobber (reg:CC 33))]
   ""
   "or\\t%0,%2"
-  [(set_attr "op_type"  "RR")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RR")])
 
 (define_insn "*iorhi3_ss"
-  [(set (match_operand:HI 0 "s_operand" "=Qo")
+  [(set (match_operand:HI 0 "s_operand" "=Q")
         (ior:HI (match_dup 0)
-                (match_operand:HI 1 "s_imm_operand" "Qo")))
+                (match_operand:HI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "oc\\t%O0(2,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 (define_insn "*iorhi3_ss_inv"
-  [(set (match_operand:HI 0 "s_operand" "=Qo")
-        (ior:HI (match_operand:HI 1 "s_imm_operand" "Qo")
+  [(set (match_operand:HI 0 "s_operand" "=Q")
+        (ior:HI (match_operand:HI 1 "s_imm_operand" "Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "oc\\t%O0(2,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 ;
 ; iorqi3 instruction pattern(s).
   "@
    or\\t%0,%2
    oill\\t%0,%b2"
-  [(set_attr "op_type"  "RR,RI")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RR,RI")])
 
 (define_insn "iorqi3"
   [(set (match_operand:QI 0 "register_operand" "=d")
    (clobber (reg:CC 33))]
   ""
   "or\\t%0,%2"
-  [(set_attr "op_type"  "RR")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RR")])
 
 (define_insn "*iorqi3_ss"
-  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+  [(set (match_operand:QI 0 "s_operand" "=Q,Q")
         (ior:QI (match_dup 0)
-                (match_operand:QI 1 "s_imm_operand" "n,Qo")))
+                (match_operand:QI 1 "s_imm_operand" "n,Q")))
    (clobber (reg:CC 33))]
   ""
   "@
    oi\\t%0,%b1
    oc\\t%O0(1,%R0),%1"
-  [(set_attr "op_type"  "SI,SS")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "SI,SS")])
 
 (define_insn "*iorqi3_ss_inv"
-  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
-        (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
+  [(set (match_operand:QI 0 "s_operand" "=Q,Q")
+        (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "@
    oi\\t%0,%b1
    oc\\t%O0(1,%R0),%1"
-  [(set_attr "op_type"  "SI,SS")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "SI,SS")])
 
 
 ;;
 
 (define_insn "*xordi3_cc"
   [(set (reg 33)
-        (compare (xor:DI (match_operand:DI 1 "register_operand" "%0,0")
+        (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:DI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (set (match_operand:DI 0 "register_operand" "=d,d")
   "@
    xgr\\t%0,%2
    xg\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")])
 
 (define_insn "*xordi3_cconly"
   [(set (reg 33)
-        (compare (xor:DI (match_operand:DI 1 "register_operand" "%0,0")
+        (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:DI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (clobber (match_scratch:DI 0 "=d,d"))]
   "@
    xgr\\t%0,%2
    xr\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")])
 
 (define_insn "xordi3"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
-        (xor:DI (match_operand:DI 1 "register_operand" "%0,0")
+        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
                 (match_operand:DI 2 "general_operand" "d,m")))
    (clobber (reg:CC 33))]
   "TARGET_64BIT"
   "@
    xgr\\t%0,%2
    xg\\t%0,%2"
-  [(set_attr "op_type"  "RRE,RXE")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RRE,RXE")])
 
 (define_insn "*xordi3_ss"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
+  [(set (match_operand:DI 0 "s_operand" "=Q")
         (xor:DI (match_dup 0)
-                (match_operand:DI 1 "s_imm_operand" "Qo")))
+                (match_operand:DI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "xc\\t%O0(8,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 (define_insn "*xordi3_ss_inv"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
-        (xor:DI (match_operand:DI 1 "s_imm_operand" "Qo")
+  [(set (match_operand:DI 0 "s_operand" "=Q")
+        (xor:DI (match_operand:DI 1 "s_imm_operand" "Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "xc\\t%O0(8,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 ;
 ; xorsi3 instruction pattern(s).
 
 (define_insn "*xorsi3_cc"
   [(set (reg 33)
-        (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:SI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (set (match_operand:SI 0 "register_operand" "=d,d")
   "@
    xr\\t%0,%2
    x\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*xorsi3_cconly"
   [(set (reg 33)
-        (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                          (match_operand:SI 2 "general_operand" "d,m"))
                  (const_int 0)))
    (clobber (match_scratch:SI 0 "=d,d"))]
   "@
    xr\\t%0,%2
    x\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "xorsi3"
   [(set (match_operand:SI 0 "register_operand" "=d,d")
-        (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
+        (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
                 (match_operand:SI 2 "general_operand" "d,m")))
    (clobber (reg:CC 33))]
   ""
   "@
    xr\\t%0,%2
    x\\t%0,%2"
-  [(set_attr "op_type"  "RR,RX")
-   (set_attr "atype"    "reg,mem")])
+  [(set_attr "op_type"  "RR,RX")])
 
 (define_insn "*xorsi3_ss"
-  [(set (match_operand:SI 0 "s_operand" "=Qo")
+  [(set (match_operand:SI 0 "s_operand" "=Q")
         (xor:SI (match_dup 0)
-                (match_operand:SI 1 "s_imm_operand" "Qo")))
+                (match_operand:SI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "xc\\t%O0(4,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 (define_insn "*xorsi3_ss_inv"
-  [(set (match_operand:SI 0 "s_operand" "=Qo")
-        (xor:SI (match_operand:SI 1 "s_imm_operand" "Qo")
+  [(set (match_operand:SI 0 "s_operand" "=Q")
+        (xor:SI (match_operand:SI 1 "s_imm_operand" "Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "xc\\t%O0(4,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 ;
 ; xorhi3 instruction pattern(s).
    (set_attr "atype"    "reg")])
 
 (define_insn "*xorhi3_ss"
-  [(set (match_operand:HI 0 "s_operand" "=Qo")
+  [(set (match_operand:HI 0 "s_operand" "=Q")
         (xor:HI (match_dup 0)
-                (match_operand:HI 1 "s_imm_operand" "Qo")))
+                (match_operand:HI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "xc\\t%O0(2,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 (define_insn "*xorhi3_ss_inv"
-  [(set (match_operand:HI 0 "s_operand" "=Qo")
-        (xor:HI (match_operand:HI 1 "s_imm_operand" "Qo")
+  [(set (match_operand:HI 0 "s_operand" "=Q")
+        (xor:HI (match_operand:HI 1 "s_imm_operand" "Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "xc\\t%O0(2,%R0),%1"
-  [(set_attr "op_type"  "SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SS")])
 
 ;
 ; xorqi3 instruction pattern(s).
    (clobber (reg:CC 33))]
   ""
   "xr\\t%0,%2"
-  [(set_attr "op_type"  "RR")
-   (set_attr "atype"    "reg")])
+  [(set_attr "op_type"  "RR")])
 
 (define_insn "*xorqi3_ss"
-  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+  [(set (match_operand:QI 0 "s_operand" "=Q,Q")
         (xor:QI (match_dup 0)
-                (match_operand:QI 1 "s_imm_operand" "n,Qo")))
+                (match_operand:QI 1 "s_imm_operand" "n,Q")))
    (clobber (reg:CC 33))]
   ""
   "@
    xi\\t%0,%b1
    xc\\t%O0(1,%R0),%1"
-  [(set_attr "op_type"  "SI,SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SI,SS")])
 
 (define_insn "*xorqi3_ss_inv"
-  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
-        (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
+  [(set (match_operand:QI 0 "s_operand" "=Q,Q")
+        (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
                 (match_dup 0)))
    (clobber (reg:CC 33))]
   ""
   "@
    xi\\t%0,%b1
    xc\\t%O0(1,%R0),%1"
-  [(set_attr "op_type"  "SI,SS")
-   (set_attr "atype"    "mem")])
+  [(set_attr "op_type"  "SI,SS")])
 
 
 ;;
   output_asm_insn (\"lcr\\t%N0,%N1\", operands);
   output_asm_insn (\"je\\t%l0\", xop);
   output_asm_insn (\"bctr\\t%0,0\", operands);
-  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
                             CODE_LABEL_NUMBER (xop[0]));
   return \"\";
 }"
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "lcdbr\\t%0,%1"
-  [(set_attr "op_type"  "RR")])
+  [(set_attr "op_type"  "RRE")
+   (set_attr "type"     "fsimpd")])
 
 (define_insn "*negdf2_ibm"
   [(set (match_operand:DF 0 "register_operand" "=f")
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "lcdr\\t%0,%1"
-  [(set_attr "op_type"  "RR")])
+  [(set_attr "op_type"  "RR")
+   (set_attr "type"     "fsimpd")])
 
 ;
 ; negsf2 instruction pattern(s).
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "lcebr\\t%0,%1"
-  [(set_attr "op_type"  "RR")])
+  [(set_attr "op_type"  "RRE")
+   (set_attr "type"     "fsimps")])
 
 (define_insn "*negsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "lcer\\t%0,%1"
-  [(set_attr "op_type"  "RR")])
+  [(set_attr "op_type"  "RR")
+   (set_attr "type"     "fsimps")])
 
 
 ;;
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "lpdbr\\t%0,%1"
-  [(set_attr "op_type"  "RR")])
+  [(set_attr "op_type"  "RRE")
+   (set_attr "type"     "fsimpd")])
 
 (define_insn "*absdf2_ibm"
   [(set (match_operand:DF 0 "register_operand" "=f")
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "lpdr\\t%0,%1"
-  [(set_attr "op_type"  "RR")])
+  [(set_attr "op_type"  "RR")
+   (set_attr "type"     "fsimpd")])
 
 ;
 ; abssf2 instruction pattern(s).
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
   "lpebr\\t%0,%1"
-  [(set_attr "op_type"  "RR")])
+  [(set_attr "op_type"  "RRE")
+   (set_attr "type"     "fsimps")])
 
 (define_insn "*abssf2_ibm"
   [(set (match_operand:SF 0 "register_operand" "=f")
    (clobber (reg:CC 33))]
   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
   "lper\\t%0,%1"
-  [(set_attr "op_type"  "RR")])
+  [(set_attr "op_type"  "RR")
+   (set_attr "type"     "fsimps")])
 
 ;;
 ;;- Square root instructions.
   "@
    sqdbr\\t%0,%1
    sqdb\\t%0,%1"
-  [(set_attr "op_type"  "RRE,RSE")])
+  [(set_attr "op_type"  "RRE,RSE")
+   (set_attr "type"     "fsqrtd")])
 
 ;
 ; sqrtsf2 instruction pattern(s).
   "@
    sqebr\\t%0,%1
    sqeb\\t%0,%1"
-  [(set_attr "op_type"  "RRE,RSE")])
+  [(set_attr "op_type"  "RRE,RSE")
+   (set_attr "type"     "fsqrts")])
 
 ;;
 ;;- One complement instructions.
   "@
    rllg\\t%0,%1,%c2
    rllg\\t%0,%1,0(%2)"
-  [(set_attr "op_type"  "RSE")])
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
 
 ;
 ; rotlsi3 instruction pattern(s).
   "@
    rll\\t%0,%1,%c2
    rll\\t%0,%1,0(%2)"
-  [(set_attr "op_type"  "RSE")])
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
 
 
 ;;
   "@
    sldl\\t%0,%c2
    sldl\\t%0,0(%2)"     
-  [(set_attr "op_type"  "RS")])
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
 
 (define_insn "*ashldi3_64"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
   "@
    sllg\\t%0,%1,%2
    sllg\\t%0,%1,0(%2)"
-  [(set_attr "op_type"  "RSE")])
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
 
 ;
 ; ashrdi3 instruction pattern(s).
   "@
    srda\\t%0,%c2
    srda\\t%0,0(%2)"     
-  [(set_attr "op_type"  "RS")])
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
 
 (define_insn "*ashrdi3_cconly_31"
   [(set (reg 33)
   "@
    srda\\t%0,%c2
    srda\\t%0,0(%2)"     
-  [(set_attr "op_type"  "RS")])
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
 
 (define_insn "*ashrdi3_31"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
   "@
    srda\\t%0,%c2
    srda\\t%0,0(%2)"     
-  [(set_attr "op_type"  "RS")])
-
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
 (define_insn "*ashrdi3_cc_64"
   [(set (reg 33)
         (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
   "@
    srag\\t%0,%1,%c2
    srag\\t%0,%1,0(%2)"
-  [(set_attr "op_type"  "RSE")])
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
 
 (define_insn "*ashrdi3_cconly_64"
   [(set (reg 33)
   "@
    srag\\t%0,%1,%c2
    srag\\t%0,%1,0(%2)"
-  [(set_attr "op_type"  "RSE")])
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
 
 (define_insn "*ashrdi3_64"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
   "@
    srag\\t%0,%1,%c2
    srag\\t%0,%1,0(%2)"
-  [(set_attr "op_type"  "RSE")])
+  [(set_attr "op_type"  "RSE")
+   (set_attr "atype"    "reg")])
+
 
 ;
 ; ashlsi3 instruction pattern(s).
   "@
    sll\\t%0,%c2
    sll\\t%0,0(%2)"
-  [(set_attr "op_type"  "RS")])
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
 
 ;
 ; ashrsi3 instruction pattern(s).
   "@
    sra\\t%0,%c2
    sra\\t%0,0(%2)"
-  [(set_attr "op_type"  "RS")])
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
+
 
 (define_insn "*ashrsi3_cconly"
   [(set (reg 33)
   "@
    sra\\t%0,%c2
    sra\\t%0,0(%2)"
-  [(set_attr "op_type"  "RS")])
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
 
 (define_insn "ashrsi3"
   [(set (match_operand:SI 0 "register_operand" "=d,d")
   "@
    sra\\t%0,%c2
    sra\\t%0,0(%2)"
-  [(set_attr "op_type"  "RS")])
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
 
 
 ;;
   "@
    srdl\\t%0,%c2
    srdl\\t%0,0(%2)"     
-   [(set_attr "op_type"  "RS,RS")])
+   [(set_attr "op_type"  "RS,RS")
+    (set_attr "atype"    "reg")])
 
 (define_insn "*lshrdi3_64"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
   "@
    srlg\\t%0,%1,%c2
    srlg\\t%0,%1,0(%2)"
-  [(set_attr "op_type"  "RS,RS")])
+  [(set_attr "op_type"  "RSE,RSE")
+   (set_attr "atype"    "reg")])
 
 ;
 ; lshrsi3 instruction pattern(s).
   "@
    srl\\t%0,%c2
    srl\\t%0,0(%2)"
-  [(set_attr "op_type"  "RS")])
+  [(set_attr "op_type"  "RS")
+   (set_attr "atype"    "reg")])
 
 
 ;;
   ""
   "*
 {
-  if (get_attr_length (insn) == 4 || !TARGET_64BIT)
-     return \"j%C1\\t%l0\";
+  if (get_attr_length (insn) == 4)
+    return \"j%C1\\t%l0\";
+  else if (TARGET_64BIT)
+    return \"jg%C1\\t%l0\";
   else
-     return \"jg%C1\\t%l0\";
+    abort ();
 }"
   [(set_attr "op_type" "RI")
-   (set (attr "length") (if_then_else
-      (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
-      (const_int 4) (const_int 6)))])
+   (set_attr "type"    "branch")
+   (set (attr "length")
+        (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+                (const_int 4)
+               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+                 (const_int 6)
+               (eq (symbol_ref "flag_pic") (const_int 0))
+                 (const_int 6)] (const_int 8)))])
 
 (define_insn "*cjump_long"
  [(set (pc)
   [(set (attr "op_type") 
         (if_then_else (match_operand 0 "register_operand" "")
                       (const_string "RR") (const_string "RX")))
-   (set_attr "atype" "mem")])
+   (set_attr "type"    "branch")
+   (set_attr "atype" "agen")])
 
 
 ;;
   ""
   "*
 {  
-  if (get_attr_length (insn) == 4 || !TARGET_64BIT)
-     return \"j%D1\\t%l0\";
+  if (get_attr_length (insn) == 4)
+    return \"j%D1\\t%l0\";
+  else if (TARGET_64BIT)
+    return \"jg%D1\\t%l0\";
   else
-     return \"jg%D1\\t%l0\";
+    abort ();
 }"
   [(set_attr "op_type" "RI")
-   (set (attr "length") (if_then_else
-     (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
-     (const_int 4) (const_int 6)))])
+   (set_attr "type"    "branch")
+   (set (attr "length")
+        (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+                (const_int 4)
+               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+                 (const_int 6)
+               (eq (symbol_ref "flag_pic") (const_int 0))
+                 (const_int 6)] (const_int 8)))])
 
 (define_insn "*icjump_long"
  [(set (pc)
   [(set (attr "op_type") 
         (if_then_else (match_operand 0 "register_operand" "")
                       (const_string "RR") (const_string "RX")))
-   (set_attr "atype" "mem")])
+   (set_attr "type"  "branch")
+   (set_attr "atype" "agen")])
+
+;;
+;;- Trap instructions.
+;;
+
+(define_insn "trap"
+  [(trap_if (const_int 1) (const_int 0))]
+  ""
+  "j\\t.+2"
+  [(set_attr "op_type" "RX")
+   (set_attr "type"  "branch")])
+
+(define_expand "conditional_trap"
+  [(set (match_dup 2) (match_dup 3))
+   (trap_if (match_operator 0 "comparison_operator"
+                           [(match_dup 2) (const_int 0)])
+           (match_operand:SI 1 "general_operand" ""))]
+  ""
+  "
+{
+   enum machine_mode ccmode;
+
+   if (operands[1] != const0_rtx) FAIL;        
+
+   ccmode = s390_select_ccmode (GET_CODE (operands[0]), 
+                               s390_compare_op0, s390_compare_op1);    
+   operands[2] = gen_rtx_REG (ccmode, 33);
+   operands[3] = gen_rtx_COMPARE (ccmode, s390_compare_op0, s390_compare_op1);
+}")
 
+(define_insn "*trap"
+  [(trap_if (match_operator 0 "comparison_operator" [(reg 33) (const_int 0)])
+           (const_int 0))]
+  ""
+  "j%C0\\t.+2";
+  [(set_attr "op_type" "RI")
+   (set_attr "type"  "branch")])
 
 ;;
-;;- Subtract one and jump if not zero.
+;;- Loop instructions.
 ;;
+;;  This is all complicated by the fact that since this is a jump insn
+;;  we must handle our own output reloads.
+(define_expand "doloop_end"
+  [(use (match_operand 0 "" ""))        ; loop pseudo
+   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
+   (use (match_operand 2 "" ""))        ; max iterations
+   (use (match_operand 3 "" ""))        ; loop level
+   (use (match_operand 4 "" ""))]       ; label
+  ""
+  "
+{
+  if (GET_MODE (operands[0]) == SImode)
+    emit_jump_insn (gen_doloop_si (operands[4], operands[0], operands[0]));
+  else if (GET_MODE (operands[0]) == DImode && TARGET_64BIT)
+    emit_jump_insn (gen_doloop_di (operands[4], operands[0], operands[0]));
+  else
+    FAIL;
+
+  DONE;
+}")
+
+(define_insn "doloop_si"
+  [(set (pc)
+        (if_then_else
+          (ne (match_operand:SI 1 "register_operand" "d,d")
+              (const_int 1))
+          (label_ref (match_operand 0 "" ""))
+          (pc)))
+   (set (match_operand:SI 2 "register_operand" "=1,?*m*d")
+        (plus:SI (match_dup 1) (const_int -1)))
+   (clobber (match_scratch:SI 3 "=X,&d"))
+   (clobber (reg:CC 33))]
+  ""
+  "*
+{
+  if (which_alternative != 0)
+    return \"#\";
+  else if (get_attr_length (insn) == 4)
+    return \"brct\\t%1,%l0\";
+  else
+    abort ();
+}"
+  [(set_attr "op_type"  "RI")
+   (set_attr "type"  "branch")
+   (set (attr "length")
+        (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+                (const_int 4)
+               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+                 (const_int 10)
+               (eq (symbol_ref "flag_pic") (const_int 0))
+                 (const_int 6)] (const_int 8)))])
+
+(define_insn "*doloop_si_long"
+  [(set (pc)
+        (if_then_else
+          (ne (match_operand:SI 1 "register_operand" "d,d")
+              (const_int 1))
+          (match_operand 0 "address_operand" "p,p")
+          (pc)))
+   (set (match_operand:SI 2 "register_operand" "=1,?*m*d")
+        (plus:SI (match_dup 1) (const_int -1)))
+   (clobber (match_scratch:SI 3 "=X,&d"))
+   (clobber (reg:CC 33))]
+  ""
+  "*
+{
+  if (get_attr_op_type (insn) == OP_TYPE_RR)
+    return \"bctr\\t%1,%0\";
+  else
+    return \"bct\\t%1,%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")])
+
+(define_split
+  [(set (pc)
+        (if_then_else (ne (match_operand:SI 1 "register_operand" "")
+                          (const_int 1))
+                      (match_operand 0 "" "")
+                      (pc)))
+   (set (match_operand:SI 2 "nonimmediate_operand" "")
+        (plus:SI (match_dup 1) (const_int -1)))
+   (clobber (match_scratch:SI 3 ""))
+   (clobber (reg:CC 33))]
+  "reload_completed
+   && (! REG_P (operands[2])
+       || ! rtx_equal_p (operands[1], operands[2]))"
+  [(set (match_dup 3) (match_dup 1))
+   (parallel [(set (reg:CCAN 33)
+                   (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
+                                 (const_int 0)))
+              (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
+   (set (match_dup 2) (match_dup 3))
+   (set (pc) (if_then_else (ne (reg:CCAN 33) (const_int 0))
+                           (match_dup 0)
+                           (pc)))]
+  "")
 
-;(define_expand "decrement_and_branch_on_count"
-;  [(use (match_operand 0 "register_operand" ""))
-;   (use (label_ref (match_operand 1 "" "")))]
-;  ""
-;  "
-;{
-;/*  if (TARGET_64BIT)
-;    emit_jump_insn (gen_brctdi (operands[0], operands[1]));
-;  else */
-;    emit_jump_insn (gen_brctsi (operands[0], operands[1]));
-;  DONE;
-;}")
-;
-;(define_insn "brctsi"
-;  [(set (pc)
-;        (if_then_else
-;           (ne (match_operand:SI 0 "register_operand" "+a")
-;               (const_int 1))
-;           (label_ref (match_operand 1 "" ""))
-;           (pc)))
-;   (set (match_dup 0)
-;        (plus:SI (match_dup 0) (const_int -1)))]
-;  ""
-;  "brct\\t%0,%l1"
-;   [(set_attr "op_type" "RI")
-;    (set_attr "type"    "branch")]
-;)
-;
-;(define_insn "ibrctsi"
-;  [(set (pc)
-;        (if_then_else
-;          (eq (match_operand:SI 0 "register_operand" "+a")
-;              (const_int 1))
-;          (pc)
-;          (label_ref (match_operand 1 "" ""))))
-;   (set (match_dup 0)
-;        (plus:SI (match_dup 0) (const_int -1)))]
-;  ""
-;  "brct\\t%0,%l1"
-;   [(set_attr "op_type" "RI")
-;    (set_attr "type"    "branch")]
-;)
+(define_insn "doloop_di"
+  [(set (pc)
+        (if_then_else
+          (ne (match_operand:DI 1 "register_operand" "d,d")
+              (const_int 1))
+          (label_ref (match_operand 0 "" ""))
+          (pc)))
+   (set (match_operand:DI 2 "register_operand" "=1,?*m*r")
+        (plus:DI (match_dup 1) (const_int -1)))
+   (clobber (match_scratch:DI 3 "=X,&d"))
+   (clobber (reg:CC 33))]
+  "TARGET_64BIT"
+  "*
+{
+  if (which_alternative != 0)
+    return \"#\";
+  else if (get_attr_length (insn) == 4)
+    return \"brctg\\t%1,%l0\";
+  else
+    abort ();
+}"
+  [(set_attr "op_type"  "RI")
+   (set_attr "type"  "branch")
+   (set (attr "length")
+        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+                      (const_int 4) (const_int 12)))])
+
+(define_insn "*doloop_di_long"
+  [(set (pc)
+        (if_then_else
+          (ne (match_operand:DI 1 "register_operand" "d,d")
+              (const_int 1))
+          (match_operand 0 "address_operand" "p,p")
+          (pc)))
+   (set (match_operand:DI 2 "register_operand" "=1,?*m*d")
+        (plus:DI (match_dup 1) (const_int -1)))
+   (clobber (match_scratch:DI 3 "=X,&d"))
+   (clobber (reg:CC 33))]
+  ""
+  "*
+{
+  if (get_attr_op_type (insn) == OP_TYPE_RRE)
+    return \"bctgr\\t%1,%0\";
+  else
+    return \"bctg\\t%1,%a0\";
+}"
+  [(set (attr "op_type") 
+        (if_then_else (match_operand 0 "register_operand" "")
+                      (const_string "RRE") (const_string "RXE")))
+   (set_attr "type"  "branch")
+   (set_attr "atype" "agen")])
 
+(define_split
+  [(set (pc)
+        (if_then_else (ne (match_operand:DI 1 "register_operand" "")
+                          (const_int 1))
+                      (match_operand 0 "" "")
+                      (pc)))
+   (set (match_operand:DI 2 "nonimmediate_operand" "")
+        (plus:DI (match_dup 1) (const_int -1)))
+   (clobber (match_scratch:DI 3 ""))
+   (clobber (reg:CC 33))]
+  "reload_completed
+   && (! REG_P (operands[2])
+       || ! rtx_equal_p (operands[1], operands[2]))"
+  [(set (match_dup 3) (match_dup 1))
+   (parallel [(set (reg:CCAN 33)
+                   (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
+                                 (const_int 0)))
+              (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
+   (set (match_dup 2) (match_dup 3))
+   (set (pc) (if_then_else (ne (reg:CCAN 33) (const_int 0))
+                           (match_dup 0)
+                           (pc)))]
+  "")
 
 ;;
 ;;- Unconditional jump instructions.
   ""
   "*
 {
-  if (get_attr_length (insn) == 4 || !TARGET_64BIT)
-     return \"j\\t%l0\";
+  if (get_attr_length (insn) == 4)
+    return \"j\\t%l0\";
+  else if (TARGET_64BIT)
+    return \"jg\\t%l0\";
   else
-     return \"jg\\t%l0\";
+    abort ();
 }"
   [(set_attr "op_type" "RI")
-   (set (attr "length") (if_then_else
-     (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
-     (const_int 4) (const_int 6)))])
+   (set_attr "type"  "branch")
+   (set (attr "length")
+        (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+                (const_int 4)
+               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+                 (const_int 6)
+               (eq (symbol_ref "flag_pic") (const_int 0))
+                 (const_int 6)] (const_int 8)))])
 
 ;
 ; indirect-jump instruction pattern(s).
   [(set (attr "op_type") 
         (if_then_else (match_operand 0 "register_operand" "")
                       (const_string "RR") (const_string "RX")))
-   (set_attr "atype" "mem")])
+   (set_attr "type"  "branch")
+   (set_attr "atype" "agen")])
 
 ;
 ; casesi instruction pattern(s).
   [(set (attr "op_type") 
         (if_then_else (match_operand 0 "register_operand" "")
                       (const_string "RR") (const_string "RX")))
-   (set_attr "atype" "mem")])
+   (set_attr "type"  "branch")
+   (set_attr "atype" "agen")])
 
 (define_expand "casesi"
   [(match_operand:SI 0 "general_operand" "")
   [(unspec_volatile [(const_int 0)] 0)]
   ""
   ""
-  [(set_attr "type"    "none")])
+  [(set_attr "type"    "none")
+   (set_attr "length"  "0")])
 
 
 
      compiler doesn't know about it, because the PLT glue 
      code uses it.  In 64-bit, this is not necessary.  */
   if (plt_call && !TARGET_64BIT)
-    {
-      current_function_uses_pic_offset_table = 1;
-      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
-    }
+    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
 
   DONE;
 }")
   "basr\\t%2,%0"
   [(set_attr "op_type" "RR")
    (set_attr "type"    "jsr")
-   (set_attr "atype"   "mem")])
+   (set_attr "atype"   "agen")])
 
 (define_insn "basr_31"
   [(call (mem:QI (match_operand:SI 0 "register_operand" "a"))
   "basr\\t%2,%0"
   [(set_attr "op_type" "RR")
    (set_attr "type"    "jsr")
-   (set_attr "atype"    "mem")])
+   (set_attr "atype"    "agen")])
 
 (define_insn "bas_64"
   [(call (mem:QI (match_operand:QI 0 "address_operand" "p"))
   "TARGET_64BIT"
   "bas\\t%2,%a0"
   [(set_attr "op_type" "RX")
-   (set_attr "type"    "jsr")
-   (set_attr "atype"   "mem")])
+   (set_attr "type"    "jsr")])
 
 (define_insn "bas_31"
   [(call (mem:QI (match_operand:QI 0 "address_operand" "p"))
   "!TARGET_64BIT"
   "bas\\t%2,%a0"
   [(set_attr "op_type" "RX")
-   (set_attr "type"    "jsr")
-   (set_attr "atype"   "mem")])
+   (set_attr "type"    "jsr")])
 
 
 ;
      compiler doesn't know about it, because the PLT glue 
      code uses it.  In 64-bit, this is not necessary.  */
   if (plt_call && !TARGET_64BIT)
-    {
-      current_function_uses_pic_offset_table = 1;
-      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
-    }
+    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
 
   DONE;
 }")
   "TARGET_64BIT"
   "basr\\t%3,%1"
   [(set_attr "op_type" "RR")
-   (set_attr "type"    "jsr")])
+   (set_attr "type"    "jsr")
+   (set_attr "atype"   "agen")])
 
 (define_insn "basr_r_31"
   [(set (match_operand 0 "register_operand" "=df")
   "basr\\t%3,%1"
   [(set_attr "op_type" "RR")
    (set_attr "type"    "jsr")
-   (set_attr "atype"   "mem")])
+   (set_attr "atype"   "agen")])
 
 (define_insn "bas_r_64"
   [(set (match_operand 0 "register_operand" "=df")
   "TARGET_64BIT"
   "bas\\t%3,%a1"
   [(set_attr "op_type" "RX")
-   (set_attr "type"    "jsr")
-   (set_attr "atype"   "mem")])
+   (set_attr "type"    "jsr")])
 
 (define_insn "bas_r_31"
   [(set (match_operand 0 "register_operand" "=df")
   "!TARGET_64BIT"
   "bas\\t%3,%a1"
    [(set_attr "op_type" "RX")
-    (set_attr "type"    "jsr")
-    (set_attr "atype"   "mem")])
+    (set_attr "type"    "jsr")])
 
 
 ;;
 ; Special literal pool access instruction pattern(s).
 ;
 
-(define_insn "reload_base"
-  [(parallel [(set (reg 13) (pc))
-              (use (label_ref (match_operand 0 "" "")))])]
+(define_insn "consttable_qi"
+  [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "X")] 200)]
   ""
   "*
 {
-  if (TARGET_64BIT)
-    return \"larl\\t13,%y0\";                  
-  else
-    return \"basr\\t13,0\;ahi\\t13,%Y0\";
+  assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
+  return \"\";
 }"
-  [(set_attr "op_type" "NN")
-   (set_attr "type"    "la")
-   (set_attr "length"  "8")])
+  [(set_attr "op_type"  "NN")
+   (set_attr "length"   "1")])
+
+(define_insn "consttable_hi"
+  [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "X")] 201)]
+  ""
+  "*
+{
+  assemble_integer (operands[0], 2, 2*BITS_PER_UNIT, 1);
+  return \"\";
+}"
+  [(set_attr "op_type"  "NN")
+   (set_attr "length"   "2")])
+
+(define_insn "consttable_si"
+  [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "X")] 202)]
+  ""
+  "*
+{
+  if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[0]))
+    return \".long\\t%0\";
+
+  assemble_integer (operands[0], 4, 4*BITS_PER_UNIT, 1);
+  return \"\";
+}"
+  [(set_attr "op_type"  "NN")
+   (set_attr "length"   "4")])
+
+(define_insn "consttable_di"
+  [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "X")] 203)]
+  ""
+  "*
+{
+  assemble_integer (operands[0], 8, 8*BITS_PER_UNIT, 1);
+  return \"\";
+}"
+  [(set_attr "op_type"  "NN")
+   (set_attr "length"   "8")])
+
+(define_insn "consttable_sf"
+  [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "X")] 204)]
+  ""
+  "*
+{
+  REAL_VALUE_TYPE r;
+
+  if (GET_CODE (operands[0]) != CONST_DOUBLE)
+    abort ();
+
+  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
+  assemble_real (r, SFmode, 4*BITS_PER_UNIT);
+  return \"\";
+}"
+  [(set_attr "op_type"  "NN")
+   (set_attr "length"   "4")])
 
-(define_insn "ltorg"
-  [(parallel [(set (reg 13) (pc))
-              (use (match_operand:SI 0 "const_int_operand" ""))])]
+(define_insn "consttable_df"
+  [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "X")] 205)]
   ""
   "*
 {
-   s390_dump_literal_pool (insn, operands[0]);
-   return \"0:\";
+  REAL_VALUE_TYPE r;
+
+  if (GET_CODE (operands[0]) != CONST_DOUBLE)
+    abort ();
+
+  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
+  assemble_real (r, DFmode, 8*BITS_PER_UNIT);
+  return \"\";
 }"
+  [(set_attr "op_type"  "NN")
+   (set_attr "length"   "8")])
+
+(define_insn "pool_start_31"
+  [(unspec_volatile [(const_int 0)] 206)]
+  "!TARGET_64BIT"
+  ".align\\t4"
+  [(set_attr "op_type"  "NN")
+   (set_attr "length"   "2")])
+
+(define_insn "pool_end_31"
+  [(unspec_volatile [(const_int 0)] 207)]
+  "!TARGET_64BIT"
+  ".align\\t2"
+  [(set_attr "op_type"  "NN")
+   (set_attr "length"   "2")])
+
+(define_insn "pool_start_64"
+  [(unspec_volatile [(const_int 0)] 206)]
+  "TARGET_64BIT"
+  ".section\\t.rodata\;.align\\t8"
+  [(set_attr "op_type"  "NN")
+   (set_attr "length"   "0")])
+
+(define_insn "pool_end_64"
+  [(unspec_volatile [(const_int 0)] 207)]
+  "TARGET_64BIT"
+  ".previous"
+  [(set_attr "op_type"  "NN")
+   (set_attr "length"   "0")])
+
+(define_insn "reload_base_31"
+  [(set (match_operand:SI 0 "register_operand" "=a")
+        (unspec:SI [(label_ref (match_operand 1 "" ""))] 210))]
+  "!TARGET_64BIT"
+  "basr\\t%0,0\;la\\t%0,%1-.(%0)"
+  [(set_attr "op_type" "NN")
+   (set_attr "type"    "la")
+   (set_attr "length"  "6")])
+
+(define_insn "reload_base_64"
+  [(set (match_operand:DI 0 "register_operand" "=a")
+        (unspec:DI [(label_ref (match_operand 1 "" ""))] 210))]
+  "TARGET_64BIT"
+  "larl\\t%0,%1"
+  [(set_attr "op_type" "RIL")
+   (set_attr "type"    "larl")])
+
+(define_insn "reload_anchor"
+  [(set (match_operand:SI 0 "register_operand" "=a")
+        (unspec:SI [(match_operand:SI 1 "register_operand" "a")] 211))]
+  "!TARGET_64BIT"
+  "l\\t%0,0(%1)\;la\\t%0,0(%0,%1)"
+  [(set_attr "op_type" "NN")
+   (set_attr "type"    "la")
+   (set_attr "atype"   "agen")
+   (set_attr "length"  "8")])
+
+(define_insn "pool"
+  [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] 220)]
+  ""
+  "* abort ();"
   [(set_attr "op_type" "NN")
-   (set_attr "type"    "other")
-   (set_attr "length"  "4096")])
+   (set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
 
 ;;
 ;; Insns related to generating the function prologue and epilogue.
   "br\\t%0"
   [(set_attr "op_type" "RR")
    (set_attr "type"    "jsr")          
-   (set_attr "atype"   "mem")])
+   (set_attr "atype"   "agen")])
 
 (define_insn "*return_di"
   [(return)
   "br\\t%0"
   [(set_attr "op_type" "RR")
    (set_attr "type"    "jsr")          
-   (set_attr "atype"   "mem")])
+   (set_attr "atype"   "agen")])
 
-
-(define_insn "lit"
-  [(set (reg 13) (pc))
-   (unspec_volatile [(const_int 0)] 200)]
+(define_insn "literal_pool_31"
+  [(unspec_volatile [(const_int 0)] 300)
+   (set (match_operand:SI 0 "register_operand" "=a") 
+        (label_ref (match_operand 1 "" "")))   
+   (use (label_ref (match_operand 2 "" "")))]
   ""
   "*
 {
-   s390_output_constant_pool (asm_out_file);
-   return \"\";
+   if (s390_nr_constants) {
+     output_asm_insn (\"bras\\t%0,%2\", operands);
+     s390_output_constant_pool (operands[1], operands[2]);
+   }
+   return \"\";        
 }"
   [(set_attr "op_type" "NN")
-   (set_attr "type"    "integer")])
-
-
-;;
-;; Peephole optimization patterns.
-;;
-
-(define_peephole
-  [(set (match_operand:SI 0 "memory_operand" "m")
-        (match_operand:SI 1 "register_operand" "d"))
-   (set (match_dup 1)
-        (match_dup 0))]
- ""
- "st\\t%1,%0")
-
-(define_peephole
-  [(set (match_operand:SI 0 "memory_operand" "m")
-        (match_operand:SI 1 "register_operand" "d"))
-   (set (match_dup 0)
-        (match_dup 1))]
- ""
- "st\\t%1,%0")
-
-(define_peephole
-  [(set (match_operand:SI 0 "register_operand" "")
-        (match_operand:SI 1 "register_operand" ""))
-   (parallel
-    [(set (match_dup 0)
-          (plus:SI (match_dup 0)
-                   (match_operand:SI 2 "immediate_operand" "")))
-     (clobber (reg:CC 33))])]
- "(REGNO (operands[0]) == STACK_POINTER_REGNUM ||
-   REGNO (operands[1]) == STACK_POINTER_REGNUM ||
-   REGNO (operands[0]) == BASE_REGISTER ||
-   REGNO (operands[1]) == BASE_REGISTER) &&
-  INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 4096"
- "la\\t%0,%c2(%1)")
-
-;
-; peepholes for fast char instructions
-;
-
-;(define_peephole
-;  [(set (match_operand:QI 0 "register_operand" "d")
-;        (match_operand:QI 1 "s_operand" "Q"))
-;  (set  (match_operand:SI 2 "register_operand" "0")
-;        (zero_extend:SI (match_dup 0)))]
-; "REGNO(operands[0]) == REGNO(operands[2])"
-; "icm\\t%0,8,%1\;srl\\t%0,24")
-
-;(define_peephole
-;  [(set (match_operand:QI 0 "register_operand" "d")
-;        (match_operand:QI 1 "s_operand" "Q"))
-;   (set (match_operand:SI 2 "register_operand" "0")
-;        (sign_extend:SI (match_dup 0)))]
-; "REGNO(operands[0]) == REGNO(operands[2])"
-; "icm\\t%0,8,%1\;sra\\t%0,24")
-
-(define_peephole
-  [(set (match_operand:QI 0 "register_operand" "d")
-        (match_operand:QI 1 "immediate_operand" "J"))
-   (set (match_operand:SI 2 "register_operand" "0" )
-        (sign_extend:SI (match_dup 0) ) )]
- "REGNO(operands[0]) == REGNO(operands[2])"
- "lhi\\t%0,%h1")
-
-;
-; peepholes for fast short instructions
-;
-
-;(define_peephole
-;  [(set (match_operand:HI 0 "register_operand" "d")
-;        (match_operand:HI 1 "s_operand" "Q"))
-;   (set (match_operand:SI 2 "register_operand" "0" )
-;        (zero_extend:SI (match_dup 0)))]
-; "REGNO(operands[0]) == REGNO(operands[2])"
-; "icm\\t%0,12,%1\;srl\\t%0,16")
-
-(define_peephole
-  [(set (match_operand:HI 0 "register_operand" "d")
-        (match_operand:HI 1 "memory_operand" "m"))
-   (set (match_operand:SI 2 "register_operand" "0" )
-        (sign_extend:SI (match_dup 0)))]
- "REGNO(operands[0]) == REGNO(operands[2])"
- "lh\\t%0,%1")
-
-(define_peephole
-  [(set (match_operand:HI 0 "register_operand" "d")
-        (match_operand:HI 1 "immediate_operand" "K"))
-   (set (match_operand:SI 2 "register_operand" "0" )
-        (sign_extend:SI (match_dup 0) ) )]
- "REGNO(operands[0]) == REGNO(operands[2])"
- "lhi\\t%0,%h1")
-
-;
-; peepholes for divide instructions
-;
-
-(define_peephole
-  [(set (match_operand:DI 0 "register_operand" "d")
-        (match_operand:DI 1 "memory_operand" "m"))
-   (set (match_dup 0)
-        (lshiftrt:DI (match_dup 0)
-        (match_operand:SI 2 "immediate_operand" "J")))
-   (set (match_dup 0)
-        (div:SI (match_dup 0)
-        (match_operand:SI 3 "nonimmediate_operand" "g")))
-   (set (match_dup 1)
-        (match_dup 0))]
-  ""
-  "*
-{
-   output_asm_insn (\"l\\t%0,%1\", operands);
-   output_asm_insn (\"srdl\\t%0,%b2\", operands);
-
-   if (REG_P (operands[3]))
-     output_asm_insn (\"dr\\t%0,%3\", operands);
-   else
-     output_asm_insn (\"d\\t%0,%3\", operands);
-
-   return \"st\\t%N0,%N1\";
-}")
+   (set_attr "type"    "larl")])
 
-(define_peephole
-  [(set (match_operand:DI 0 "register_operand" "d")
-        (match_operand:DI 1 "memory_operand" "m"))
-   (set (match_dup 0)
-        (lshiftrt:DI (match_dup 0)
-        (match_operand:SI 2 "immediate_operand" "J")))
-   (set (match_dup 0)
-        (mod:SI (match_dup 0)
-        (match_operand:SI 3 "nonimmediate_operand" "g")))
-   (set (match_dup 1)
-        (match_dup 0))]
+(define_insn "literal_pool_64"
+  [(unspec_volatile [(const_int 0)] 300)
+   (set (match_operand:DI 0 "register_operand" "=a") 
+        (label_ref (match_operand 1 "" "")))   
+   (use (label_ref (match_operand 2 "" "")))]
   ""
   "*
 {
-   output_asm_insn (\"l\\t%0,%1\", operands);
-   output_asm_insn (\"srdl\\t%0,%b2\", operands);
-
-   if (REG_P (operands[3]))
-     output_asm_insn (\"dr\\t%0,%3\", operands);
-   else
-     output_asm_insn (\"d\\t%0,%3\", operands);
-
-   return \"st\\t%0,%1\";
-}")
-
+   if (s390_nr_constants) {
+     output_asm_insn (\"larl\\t%0,%1\", operands);
+     s390_output_constant_pool (operands[1], operands[2]);
+   }
+   return \"\";        
+}"
+  [(set_attr "op_type" "NN")
+   (set_attr "type"    "larl")])