gcc S/390 backend 3

Hartmut Penner hp@zuck175192.boeblingen.de.ibm.com
Mon Oct 9 23:35:00 GMT 2000


Hi,  
     Part 3 of changed S/390 backend

diff -r -u --new-file egcs-20001002/gcc/config/s390/s390.md
egcs-20001002-s390/gcc/config/s390/s390.md ---
egcs-20001002/gcc/config/s390/s390.md	Thu Jan  1 01:00:00 1970 +++
egcs-20001002-s390/gcc/config/s390/s390.md	Mon Oct  9 13:56:30 2000 @@
-0,0 +1,4852 @@ +;;- Machine description for GNU compiler -- System/390 version.
+;;  Copyright (C) 1989, 1993, 1994, 1995, 1999, 2000 Free Software Foundation, Inc.
+;;  Contributed by Hartmut Penner (hpenner@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)
+;; any later version.
+
+;; GNU CC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU CC; see the file COPYING.  If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
+;;- updates for most instructions.
+
+;;
+;; Special constraints for 390 machine description:
+;;
+;;    a -- Any address register from 1 to 15.
+;;    d -- Any register from 0 to 15.
+;;    I -- An 8-bit constant (0..255).
+;;    J -- A 12-bit constant (0..4095).
+;;    K -- A 16-bit constant (-32768..32767).
+;;    Q -- A memory reference without index-register
+;;
+;; Special formats used for outputting 390 instructions.
+;;
+;;   %b -- Print a constant byte integer.               xy
+;;   %h -- Print a signed 16-bit.                       wxyz
+;;   %N -- Print next register (second word of a DImode reg).
+;;   %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)).
+;;   %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)).
+;;
+;; We have a special constraint for pattern matching.
+;;
+;;   s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
+;;
+;;   r_or_s_operand -- Matches a register or a valid S operand in a RS, SI
+;;                     or SS type instruction or a register
+;;
+
+;; Insn type.  Used to default other attribute values.
+
+(define_attr "type"
+  "load,store,loadm,storem,arith,logic,test,muldiv,fp,branch,jsr,misc,lshift,ashift,nop"
+  (const_string "misc"))
+
+(define_function_unit "memory" 1 0
+  (eq_attr "type" "lshift")
+  5 1 [(eq_attr "type" "loadm")] )
+
+(define_function_unit "memory" 1 0
+  (eq_attr "type" "lshift")
+  5 1 [(eq_attr "type" "storem")] )
+
+(define_function_unit "memory" 1 0
+  (eq_attr "type" "arith")
+  5 1 [(eq_attr "type" "loadm")] )
+
+(define_function_unit "memory" 1 0
+  (eq_attr "type" "arith")
+  5 1 [(eq_attr "type" "storem")] )
+
+(define_function_unit "memory" 1 0
+  (eq_attr "type" "loadm")
+  5 1 [(eq_attr "type" "loadm")] )
+
+(define_function_unit "memory" 1 0
+  (eq_attr "type" "loadm")
+  5 1 [(eq_attr "type" "storem")] )
+
+(define_function_unit "memory" 1 0
+  (eq_attr "type" "load")
+  5 1 [(eq_attr "type" "loadm")] )
+
+(define_function_unit "memory" 1 0
+  (eq_attr "type" "load")
+  5 1 [(eq_attr "type" "storem")] )
+
+(define_function_unit "memory" 1 0
+  (eq_attr "type" "loadm")
+  5 1 [(eq_attr "type" "jsr")] )
+
+
+; Operand type. Used to default length attribute values
+
+(define_attr "op_type"
+  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE"
+  (const_string "RX"))
+
+;; Length in bytes.
+
+(define_attr "length" ""
+(cond [ (eq_attr "op_type" "E")    (const_int 2)
+         (eq_attr "op_type" "RR")  (const_int 2)
+         (eq_attr "op_type" "RX")  (const_int 4)
+         (eq_attr "op_type" "RI")  (const_int 4)
+         (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)
+         (eq_attr "op_type" "SSE") (const_int 6)]
+         (const_int 4)))
+
+;; What insn does to the condition code.
+
+(define_attr "cc"
+  "clobber,sets,sets_ov,none,change0,compare"
+  (cond [(eq_attr "type" "load,store")  (const_string "change0")
+         (eq_attr "type" "arith")       (const_string "clobber")
+         (eq_attr "type" "logic")       (const_string "clobber")
+         (eq_attr "type" "test")        (const_string "compare")
+         (eq_attr "type" "muldiv")      (const_string "clobber")
+         (eq_attr "type" "branch")      (const_string "clobber")
+         (eq_attr "type" "jsr")         (const_string "clobber")
+         (eq_attr "type" "nop")         (const_string "none")
+         (eq_attr "type" "ashift")      (const_string "sets")
+         (eq_attr "type" "lshift")      (const_string "none")
+         (eq_attr "type" "misc")        (const_string "clobber")]
+         (const_string "clobber")))
+
+;; Define attributes for `asm' insns.
+
+(define_asm_attributes [(set_attr "type" "misc")
+                        (set_attr "op_type" "NN")])
+
+;;
+;;- Test instructions.
+;;
+; test operand 0 against zero, and set Condition Code
+;
+
+
+;
+; tstdi instruction pattern(s).
+;
+
+(define_insn "tstdi"
+  [(set (cc0)
+        (match_operand:DI 0 "register_operand" "d"))]
+  ""
+  "*
+{
+   return \"SRDA  %0,0\";
+}"
+   [(set_attr "op_type" "RS")
+    (set_attr "type"    "test")]
+)
+
+;
+; tstsi instruction pattern(s).
+;
+
+(define_insn "tstsi"
+  [(set (cc0)
+        (match_operand:SI 0 "register_operand" "d"))]
+  ""
+  "*
+{
+   return \"LTR   %0,%0\";
+}"
+   [(set_attr "op_type" "RR")
+    (set_attr "type"    "test")]
+)
+
+;
+; tsthi instruction pattern(s).
+;
+
+(define_insn ""
+  [(set (cc0)
+        (match_operand:HI 0 "register_operand" "d"))]
+  "unsigned_jump_follows_p (insn)"
+  "*
+{
+   return \"TML   %0,65535\";
+}"
+   [(set_attr "op_type" "RX")
+    (set_attr "type"    "test")]
+)
+
+
+;
+; tstqi instruction pattern(s).
+;
+
+
+(define_insn "do_tstqi"
+  [(set (cc0)
+        (match_operand:QI 0 "r_or_s_operand" "d,Q"))]
+  "unsigned_jump_follows_p (insn)"
+  "*
+{
+   switch (which_alternative)
+   {
+     case (0): /* d */
+       return \"TML   %0,255\";	
+     case (1): /* d */
+       return \"CLI   %0,0\";	
+   }
+
+}"
+   [(set_attr "op_type" "RI,SI")
+    (set_attr "type"    "test,test")]
+)
+
+;
+; tstdf instruction pattern(s).
+;
+
+(define_insn "tstdf"
+  [(set (cc0)
+        (match_operand:DF 0 "register_operand" "f"))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   if (TARGET_IBM_FLOAT)
+     return \"LTDR  %0,%0\";
+   else
+     return \"LTDBR  %0,%0\";
+}"
+   [(set_attr "op_type" "RR")
+    (set_attr "type"    "test")]
+)
+
+;
+; tstsf instruction pattern(s).
+;
+
+(define_insn "tstsf"
+  [(set (cc0)
+        (match_operand:SF 0 "register_operand" "f"))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   if (TARGET_IBM_FLOAT)
+     return \"LTER  %0,%0\";
+   else
+     return \"LTEBR  %0,%0\";
+}"
+   [(set_attr "op_type" "RR")
+    (set_attr "type"    "test")]
+)
+
+;;
+;;- Compare instructions.
+;;
+;   Compare operand 0 and operand 1 and set CC
+;
+
+;
+; cmpdi instruction pattern(s).
+;
+; Compiler knows what to do
+
+;
+; cmpsi instruction pattern(s).
+;
+; No compare between register and  symbol_ref, because in case
+;
+(define_expand "cmpsi"
+  [(set (cc0)
+        (compare (match_operand:SI 0 "register_operand" "")
+                 (match_operand:SI 1 "general_pmode_operand"  "")))]
+  ""
+  "")
+
+(define_insn "*ucmpsi"
+  [(set (cc0)
+        (compare (match_operand:SI 0 "register_operand" "d,d")
+                 (match_operand:SI 1 "general_pmode_operand" "d,m")))]
+  "unsigned_jump_follows_p (insn)"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  d */
+           return \"CLR   %0,%1\";
+       case (1): /* d  m */
+           return \"CL    %0,%1\";
+   }
+}"
+   [(set_attr "op_type" "RR,RX")
+    (set_attr "type"    "test")]
+)
+
+
+(define_insn "*cmpsi"
+  [(set (cc0)
+        (compare (match_operand:SI 0 "register_operand" "d,d,d,d")
+                 (match_operand:SI 1 "general_pmode_operand"  "d,K,i,m")))]
+  "! unsigned_jump_follows_p (insn)"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  d */
+           return \"CR    %0,%1\";
+       case (1): /* d  K */
+           return \"CHI   %0,%c1\";
+       case (2): /* d  i */
+           return \"C     %0,%g1\";
+       case (3): /* d  m */
+           return \"C     %0,%1\";
+   }
+}"
+   [(set_attr "op_type" "RR,RI,RX,RX")
+    (set_attr "type"    "test")]
+)
+
+
+;
+; cmphi instruction pattern(s).
+;
+
+(define_insn ""
+  [(set (cc0)
+        (compare (match_operand:HI 0 "register_operand" "d")
+                 (match_operand:HI 1 "s_operand"   "Qo")))]
+  "unsigned_jump_follows_p (insn)"
+  "*
+{
+   return \"CLM   %0,3,%1\";
+}"
+   [(set_attr "op_type" "RS")
+    (set_attr "type"    "test")]
+)
+
+;
+; This does not work, because upper part of register is involved
+;
+;(define_insn ""
+;  [(set (cc0)
+;        (compare (match_operand:HI 0 "register_operand" "d,d,d")
+;                 (match_operand:HI 1 "r_or_x_or_im16_operand" "d,m,n")))]
+;  "! unsigned_jump_follows_p (insn)"
+;  "*
+;{
+;  switch (which_alternative) {
+;  case (0): /* d d */
+;    return \"CR    %0,%1\";
+;  case (1): /* d m */
+;    return \"CH    %0,%1\";
+;  case (2): /* d n */
+;    return \"CHI   %0,%1\";
+;  }
+;}"
+;   [(set_attr "op_type" "RR,RX,RI")
+;    (set_attr "type"    "test")]
+;)
+
+
+;
+; cmpqi instruction pattern(s).
+;
+
+(define_insn ""
+  [(set (cc0)
+        (compare (match_operand:QI 0 "register_operand" "d")
+                 (match_operand:QI 1 "s_operand"   "Qo")))]
+  "unsigned_jump_follows_p (insn)"
+  "*
+{
+   return \"CLM   %0,1,%1\";
+}"
+   [(set_attr "op_type" "RS")
+    (set_attr "type"    "test")]
+)
+
+;
+; cmpdf instruction pattern(s).
+;
+
+(define_insn "cmpdf"
+  [(set (cc0)
+        (compare (match_operand:DF 0 "register_operand" "f,f")
+                 (match_operand:DF 1 "nonimmediate_operand"  "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f  f */
+         if (TARGET_IBM_FLOAT)
+           return \"CDR   %0,%1\";
+         else
+           return \"CDBR  %0,%1\";
+       case (1): /* f  m */
+         if (TARGET_IBM_FLOAT)
+           return \"CD    %0,%1\";
+         else
+           return \"CDB   %0,%1\";
+   }
+}"
+   [(set_attr "op_type" "RR,RX")
+    (set_attr "type"    "test")]
+)
+
+;
+; cmpsf instruction pattern(s).
+;
+
+(define_insn "cmpsf"
+  [(set (cc0)
+        (compare (match_operand:SF 0 "register_operand" "f,f")
+                 (match_operand:SF 1 "nonimmediate_operand"  "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f  f */
+         if (TARGET_IBM_FLOAT)
+           return \"CER   %0,%1\";
+         else
+           return \"CEBR  %0,%1\";
+       case (1): /* f  m */
+         if (TARGET_IBM_FLOAT)
+           return \"CE    %0,%1\";
+         else
+           return \"CEB   %0,%1\";
+   }
+}"
+   [(set_attr "op_type" "RR,RX")
+    (set_attr "type"    "test")]
+)
+
+;
+; cmpstrsi instruction pattern(s).
+;
+
+(define_expand "cmpstrsi"
+   [(set (match_operand:SI 0 "register_operand" "")
+         (compare (match_operand:BLK 1 "s_operand" "")
+                  (match_operand:BLK 2 "s_operand" "") ) )
+             (use (match_operand:SI 3  "general_operand" ""))
+             (use (match_operand:SI 4  "" ""))]
+   ""
+   "
+{
+  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) 
+    {
+      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_cmpstrsico (operands[0], operands[1],
+			         operands[2], operands[3]));
+      DONE;
+    }
+  else
+
+    {	
+      /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
+      rtx reg0 = gen_reg_rtx (DImode);
+      rtx reg1 = gen_reg_rtx (DImode);
+      rtx result = operands[0];
+      rtx len = operands[3];
+
+      if (! CONSTANT_P (len))
+          len = force_reg (SImode, len);
+
+      /* Load up the address+length pairs.  */
+      emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
+      emit_move_insn (gen_rtx_SUBREG (SImode, reg0, 0), addr0); 
+      emit_move_insn (gen_rtx_SUBREG (SImode, reg0, 1), len);
+
+      emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
+      emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0), addr1);
+      emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 1), len);
+
+      /* Compare! */
+      emit_insn (gen_cmpstrsi_1 (result, reg0, reg1));
+      DONE;
+    }
+}")
+
+
+; Compare a block that is less than 256 bytes in length.
+;
+
+(define_insn "cmpstrsico_cc"
+  [(set (cc0)
+        (compare (match_operand:BLK 0 "s_operand" "oQ")
+                 (match_operand:BLK 1 "s_operand" "oQ") ) )
+   (use (match_operand:SI 2 "immediate_operand" "I"))]
+  "((unsigned) INTVAL (operands[2]) < 256)"
+  "*
+{
+   return \"CLC   %O0(%c2,%R0),%1\";
+}"
+   [(set_attr "op_type" "SS")
+    (set_attr "type"    "test")]
+)
+
+
+(define_insn "cmpstrsico"
+  [ (parallel
+     [(set (match_operand:SI 0 "register_operand" "=d")
+           (compare (match_operand:BLK 1 "s_operand" "oQ")
+                    (match_operand:BLK 2 "s_operand" "oQ") ) )
+      (use (match_operand:SI 3 "immediate_operand" "I"))
+     ])]
+  "((unsigned) INTVAL (operands[3]) < 256)"
+  "*
+{
+   output_asm_insn (\"CLC   %O1(%c3,%R1),%2\",operands);
+   output_asm_insn (\"LHI   %0,1\",operands);
+   output_asm_insn (\"JH    .+12\",operands);
+   output_asm_insn (\"JL    .+6\",operands);
+   output_asm_insn (\"SR    %0,%0\",operands);
+   return \"LCR   %0,%0\";
+}"
+   [(set_attr "op_type" "NN")
+    (set_attr "length" "20")
+    (set_attr "cc"     "clobber")
+    (set_attr "type"    "test")]
+)
+
+
+; Compare a block that is larger than 255 bytes in length.
+
+
+(define_insn "*cmpstrsi_1_cc"
+  [(set (cc0)
+        (compare
+        (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "d") 0))
+        (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "d") 0))))
+	(clobber (match_dup 0))
+	(clobber (match_dup 1))]
+  ""
+  "CLCL  %0,%1"
+   [(set_attr "op_type" "RR")
+    (set_attr "type"    "test")]
+)
+
+
+(define_insn "cmpstrsi_1"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (compare
+        (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "d") 0))
+        (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "d") 0))))
+	(clobber (match_dup 0))
+	(clobber (match_dup 1))]
+
+  ""
+  "*
+{
+   output_asm_insn (\"CLCL  %1,%2\", operands);
+   output_asm_insn (\"LHI   %0,1\", operands);
+   output_asm_insn (\"JH    .+12\", operands);
+   output_asm_insn (\"JL    .+6\", operands);
+   output_asm_insn (\"SR    %0,%0\", operands);
+   return \"LCR   %0,%0\";
+}"
+   [(set_attr "op_type" "NN")
+    (set_attr "type"    "test")
+    (set_attr "cc" "clobber")
+    (set_attr "length"  "18")]
+)
+
+;;
+;;- Move instructions.
+;;
+
+;
+; load_multiple instruction pattern(s)
+;
+
+(define_insn "load_multiple"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (match_operand:SI 1 "s_operand"        "Q"))
+   (use (match_operand:SI 2 "const_int_operand" "n"))]
+  ""
+  "*
+{
+   operands[2] = gen_rtx (REG, SImode,
+                         REGNO (operands[0]) + INTVAL (operands[2]));
+   return \"LM    %0,%2,%1\";
+}"
+   [(set_attr "op_type" "RS")
+    (set_attr "type"    "load")]
+)
+
+;
+; store_multiple instruction pattern(s)
+;
+
+(define_insn "store_multiple"
+  [(set (match_operand:SI 0 "s_operand"        "=Q")
+        (match_operand:SI 1 "register_operand"  "d"))
+   (use (match_operand:SI 2 "const_int_operand" "n"))]
+  ""
+  "*
+{
+   operands[2] = gen_rtx (REG, SImode,
+                         REGNO (operands[1]) + INTVAL (operands[2]));
+   return \"STM   %1,%2,%0\";
+}"
+   [(set_attr "op_type" "RS")
+    (set_attr "type"    "store")]
+)
+
+;
+; movdi instruction pattern(s).
+;
+
+(define_expand "movdi"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
+        (match_operand:DI 1 "general_operand" ""))]
+    ""
+    "
+{
+  if (CONSTANT_P (operands[1]) ||
+      GET_CODE (operands[1]) == CONST_INT &&
+      ! CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')) 
+    {
+      operands[1] = force_const_mem (DImode, operands[1]);
+    }
+}")
+
+
+(define_insn "do_movdi"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,Q")
+        (match_operand:DI 1 "general_operand"  "d,K,m,d,Q"))]
+  ""
+  "*
+{
+  int reg0,reg1;
+  rtx tmp1,tmp2;	
+
+   switch (which_alternative)
+     {
+     case (0):   /* d <- d */
+       if (REGNO (operands[0]) == REGNO (operands[1])+1)
+         {
+           return \"LR    %N0,%N1\;LR    %0,%1\";
+         }
+       else
+         {
+           return \"LR    %0,%1\;LR    %N0,%N1\";
+         }
+     case (1):  /* d <- K */
+       if (INTVAL (operands[1]) < 0)
+         {
+           return \"LHI   %0,-1\;LHI   %N0,%h1\";
+            }
+       else
+         {
+           return \"LHI   %0,0\;LHI   %N0,%h1\";
+         }
+     case (2): /* d <- m */
+        if (s_operand (operands[1], GET_MODE (operands[1])))
+             return \"LM    %0,%N0,%1\";
+	return \"LA    %N0,%1\;LM    %0,%N0,0(%N0)\";
+     case (3): /* m <- d */
+       if (! s_operand (operands[0], GET_MODE (operands[0])))
+         return \"ST    %1,%0\;ST    %N1,%N0\";
+       else
+         return \"STM   %1,%N1,%0\";
+     case (4): /* m <- m */
+       return \"MVC   %O0(8,%R0),%1\";
+   }
+}"
+   [(set_attr "op_type" "NN,NN,RS,RS,SS")
+    (set_attr "type"    "load,load,load,store,load")
+    (set_attr "length"  "4,8,8,8,*")]
+)
+
+;
+; movsi instruction pattern(s).
+;
+
+; We would not need this insn, if gen_reload would work correctly
+; Right now, gen_movsi_insn is called, with a high integer as second
+; operand, without checking it's vality
+
+(define_expand "movsi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
+       (match_operand:SI 1 "general_operand" ""))]
+    ""
+    "
+{
+  if (GET_CODE (operands[1]) == CONST_INT &&
+      ! CONST_OK_FOR_LETTER_P (INTVAL (operands[1]),'K'))
+    operands[1] = force_const_mem (SImode, operands[1]);   
+  if (GET_CODE (operands[1]) == CONST) 
+    {
+      if (SYMBOL_REF_FLAG (XEXP (XEXP (operands[1], 0), 0)))
+	SYMBOL_REF_FLAG (operands[1]) = 1;
+    }  
+  if (flag_pic) 
+    {
+      if ((GET_CODE (operands[1]) == SYMBOL_REF ||
+	   GET_CODE (operands[1]) == LABEL_REF  ||
+	   GET_CODE (operands[1]) == CONST) && 
+	  ! SYMBOL_REF_FLAG (operands[1])) 
+	{
+	  emit_insn (gen_movsi_loc (operands[0], operands[1]));
+	  DONE;
+	}
+    }
+  if (flag_pic == 1) 
+    {
+      if ((GET_CODE (operands[1]) == SYMBOL_REF ||
+	   GET_CODE (operands[1]) == CONST) && 
+	  SYMBOL_REF_FLAG (operands[1])) {
+	emit_insn (gen_movsi_got (operands[0], operands[1]));
+	DONE;
+      }
+    }			       
+  if (flag_pic == 2) 
+    {
+      if ((GET_CODE (operands[1]) == SYMBOL_REF ||
+	   GET_CODE (operands[1]) == CONST) && 
+	  SYMBOL_REF_FLAG (operands[1])) {
+	emit_insn (gen_movsi_got_big (operands[0], operands[1]));
+	DONE;
+      }
+    }			       
+}")
+
+;
+; Set up a register with a local address
+;
+
+(define_expand "movsi_loc"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(match_operand:SI 1 "general_operand" ""))]
+  "flag_pic"
+  "
+{
+  if (GET_CODE (operands[0]) != REG)
+    { 
+      rtx tmp;
+
+      if (no_new_pseudos)
+	abort ();
+      tmp = gen_reg_rtx (SImode);
+      emit_insn (gen_movsi_loc (tmp, operands[1]));
+      operands[1] = tmp;	
+    }
+  else 
+    {
+      operands[1] = force_const_mem (SImode, operands[1]);
+      emit_insn (gen_movsi_loc_1 (operands[0], operands[1]));
+      emit_insn (gen_movsi_loc_2 (operands[0], operands[0],
+				gen_rtx_REG (Pmode, BASE_REGISTER)));
+      DONE;
+    }
+}")
+
+(define_insn "movsi_loc_1"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] 4))]
+  "flag_pic"
+  "@
+  L\\t%0,%1"
+   [(set_attr "op_type" "RX")
+    (set_attr "type" "loadm")]
+)
+
+(define_insn "movsi_loc_2"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "a")
+		    (match_operand:SI 2 "register_operand" "a")] 5))]
+  "flag_pic"
+  "@
+  LA\\t%0,0(%1,%2)"
+   [(set_attr "op_type" "RX")]
+)
+
+
+;; Set up a register with a value from the GOT table (got < 4k)
+
+(define_expand "movsi_got"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "")
+		    (match_dup 2)] 6))]
+  "flag_pic == 1"
+  "
+{
+  if (GET_CODE (operands[1]) == CONST) 
+    {
+      rtx offset = const0_rtx;
+      rtx tmp;
+    
+      operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
+      tmp = (no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode));
+      emit_insn (gen_movsi_got (tmp, operands[1]));
+      emit_insn (gen_addsi3 (operands[0], tmp, offset));
+      DONE;
+    }
+  operands[2] =	gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
+}")
+
+(define_insn "*movsi_got"
+  [(set (match_operand:SI 0 "general_operand" "=d,m")
+	(unspec:SI [(match_operand:SI 1 "immediate_operand" "i,i")
+		    (match_operand:SI 2 "register_operand" "a,a")] 7))]
+  "flag_pic == 1"
+  "@
+  L\\t%0,%g1
+  MVC\\t%0,%g1"
+  [(set_attr "op_type" "RX,SS")
+  (set_attr "type" "loadm,loadm")]
+)
+
+
+;; Set up a register with a value from the GOT table (GOT > 4k)
+
+(define_expand "movsi_got_big"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(match_operand:SI 1 "general_operand" ""))]
+  "flag_pic == 2"
+  "
+{
+  if (GET_CODE (operands[0]) != REG)
+    { 
+      rtx tmp;
+
+      if (no_new_pseudos)
+	abort ();
+      tmp = gen_reg_rtx (SImode);
+      operands[1] = force_const_mem (SImode, operands[1]);
+      emit_insn (gen_movsi_got_big_1 (tmp, operands[1]));
+      operands[1] = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);	
+      emit_insn (gen_movsi_got_big_2 (tmp,tmp,operands[1]));
+      operands[1] = tmp;
+    }
+  else
+    {
+      if (GET_CODE (operands[1]) == SYMBOL_REF)
+        {
+	  operands[1] = force_const_mem (SImode, operands[1]);
+	  emit_insn (gen_movsi_got_big_1 (operands[0], operands[1]));
+	  operands[1] = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);	
+	  emit_insn (gen_movsi_got_big_2 (operands[0], operands[0],
+				operands[1]));
+	  DONE;
+        }
+      else if (GET_CODE (operands[1]) == CONST)
+        {
+	  rtx offset = const0_rtx;
+	  rtx tmp;
+	  
+	  operands[1] = eliminate_constant_term (XEXP (operands[1], 0), 
+						 &offset);
+	  tmp = (no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode));
+	  emit_insn (gen_movsi_got_big (tmp, operands[1]));
+	  emit_insn (gen_addsi3 (operands[0], tmp, offset));
+
+	}
+      DONE;	
+    }
+}")
+
+(define_insn "movsi_got_big_1"
+  [(set (match_operand:SI 0 "register_operand" "=a")
+	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] 8))]
+  "flag_pic == 2"
+  "@
+   L\\t%0,%1"
+   [(set_attr "op_type" "RX")
+    (set_attr "type" "loadm")]
+)
+
+
+(define_insn "movsi_got_big_2"
+  [(set (match_operand:SI 0 "register_operand" "=a")
+	(unspec:SI [(match_operand:SI 1 "register_operand" "a")
+		    (match_operand:SI 2 "register_operand" "a")] 9))]
+  "flag_pic == 2"
+  "@
+   L\\t%0,0(%1,%2)"
+   [(set_attr "op_type" "RX")
+    (set_attr "type" "loadm")]
+)
+
+
+
+(define_insn "do_movsi"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,m,Q")
+        (match_operand:SI 1 "general_pmode_operand"  "d,K,i,m,d,Q"))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0):   /* d <- d */
+           return \"LR    %0,%1\";
+       case (1):   /* d <- K */
+           if (INTVAL (operands[1]) == 0)
+           {
+               return \"SLR   %0,%0\";
+           }
+           else
+           {
+               return \"LHI   %0,%h1\";
+           }
+       case (2): /* d <- i */
+          return \"L     %0,%g1\";
+       case (3): /* d <- m */
+           return \"L     %0,%1\";
+       case (4): /* m <- d */
+           return \"ST    %1,%0\";
+       case (5): /* m <- m */	
+           return \"MVC   %O0(4,%R0),%1\";	
+   }
+}"
+   [(set_attr "op_type" "RR,RI,RX,RX,RX,SS")
+    (set_attr "type"    "load,load,loadm,loadm,storem,storem")
+    (set_attr "cc"      "*,clobber,*,*,*,*")]
+)
+
+
+;
+; movhi instruction pattern(s).
+;
+
+
+(define_insn "movhi"
+[(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m")
+      (match_operand:HI 1 "r_or_x_or_im16_operand" " d,K,m,d"))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d <- d */
+           return \"LR    %0,%1\";
+       case (1): /* d <- K */
+           return \"LHI   %0,%h1\";
+       case (2): /* d <- m */
+           return \"LH    %0,%1\";
+       case (3): /* m <- d */
+           return \"STH   %1,%0\";
+   }
+}"
+   [(set_attr "op_type" "RR,RI,RX,RX")
+    (set_attr "type"    "load,load,load,store")]
+)
+
+;
+; movqi instruction pattern(s).
+;
+
+(define_insn "movqi"
+[(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m")
+      (match_operand:QI 1 "r_or_x_or_im16_operand" "d,n,m,d"))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0):  /* d <- d */
+           return \"LR    %0,%1\";
+       case (1):  /* d <- n */
+           return \"LHI   %0,%c1\";
+       case (2): /* d <- m */
+           return \"IC    %0,%1\";
+       case (3): /* m <- d */
+           return \"STC   %1,%0\";
+   }
+}"
+   [(set_attr "op_type" "RR,RX,RX,RX")
+    (set_attr "type"    "load,load,load,store")]
+)
+
+;
+; moveqstrictqi instruction pattern(s).
+;
+
+(define_insn "*movstrictqi"
+  [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "=d,m"))
+                         (match_operand:QI 1 "nonimmediate_operand"  "m,d"))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0):  /* d <- m */
+           return \"IC    %0,%1\";
+       case (1):  /* m <- d */
+           return \"STC   %1,%0\";
+   }
+}"
+   [(set_attr "op_type" "RX,RX")
+    (set_attr "type"    "load,store")]
+)
+
+;
+; movstricthi instruction pattern(s).
+;
+
+(define_insn "*movstricthi"
+  [(set (strict_low_part (match_operand:HI 0 "r_or_s_operand" "=d,Q"))
+                         (match_operand:HI 1 "r_or_s_operand"  "Q,d"))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d <- m */
+           return \"ICM   %0,3,%1\";
+       case (1): /* m <- d */
+           return \"STCM  %1,3,%0\";
+   }
+}"
+   [(set_attr "op_type" "RS,RS")
+    (set_attr "type"    "load,store")]
+)
+
+
+;
+; movdf instruction pattern(s).
+;
+
+
+(define_insn "movdf"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,d,m,d")
+        (match_operand:DF 1 "general_operand"  "f,F,m,f,m,d,d"))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+  rtx xoperands[2];
+
+  switch (which_alternative)
+  {
+      case (0):    /* f <- f */
+         return \"LDR   %0,%1\";
+      case (1):  /* f <- 0 */
+         if (operands[1] == const0_rtx)
+         {
+             return \"SDR   %0,%0\";
+         }
+      case (2): /* f <- F,m */
+         return \"LD    %0,%1\";
+      case (3): /* m <- f */
+         return \"STD   %1,%0\";
+      case (4): /* d <- m */
+         if (s_operand (operands[1], DFmode))
+             return \"LM    %0,%N0,%1\";
+         else
+             return \"L     %0,%1\;L     %N0,%N1\";
+      case (5): /* m <- d */
+         if (s_operand (operands[0], DFmode))
+             return \"STM   %1,%N1,%0\";
+         else
+             return \"ST    %1,%0\;ST    %N1,%N0\";
+      case (6): /* d <- d */
+         if (REGNO (operands[0]) == REGNO (operands[1])+1)
+           {
+             return \"LR    %N0,%N1\;LR    %0,%1\";
+           }
+         else
+           {
+             return \"LR    %0,%1\;LR    %N0,%N1\";
+           }
+   }
+}"
+   [(set_attr "op_type" "RR,RR,RX,RX,RS,RS,NN")
+    (set_attr "type"    "load,load,load,store,load,store,load")
+    (set_attr "length"  "*,*,*,*,*,*,4")
+    (set_attr "cc"      "*,clobber,*,*,*,*,*")]
+)
+
+
+(define_insn ""
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=!d,d,m")
+        (match_operand:DF 1 "general_operand"  "!d,m,d"))]
+  "TARGET_SOFT_FLOAT"
+  "*
+{
+  int reg0,reg1;
+
+  switch (which_alternative) {
+  case (0):   /* d <- d */
+    if (REGNO (operands[0]) == REGNO (operands[1])+1)
+      {
+        return \"LR    %N0,%N1\;LR    %0,%1\";
+      }
+    else
+      {
+        return \"LR    %0,%1\;LR    %N0,%N1\";
+      }
+  case (1): /* d <- m */
+    if (GET_CODE (XEXP (operands[1], 0)) == PLUS)
+      {
+        if (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == PLUS)
+          {
+            reg0 = REGNO (XEXP (XEXP (XEXP (operands[1], 0), 0), 0));
+            reg1 = REGNO (XEXP (XEXP (XEXP (operands[1], 0), 0),1));
+          }
+        else
+        {
+          reg0 = REGNO (XEXP (XEXP (operands[1], 0), 0));
+          reg1 = REGNO (XEXP (XEXP (operands[1], 0),1));
+        }
+
+        if ((REGNO (operands[0]) == reg0) ||
+            (REGNO (operands[0]) == reg1))
+          {
+            return \"L     %N0,%N1\;L     %0,%1\";
+          }
+        else
+          {
+            return \"L     %0,%1\;L     %N0,%N1\";
+          }
+      }
+    return \"LM    %0,%N0,%1\";
+  case (2): /* m <- d */
+    if (! s_operand (operands[0], GET_MODE (operands[0])))
+      return \"ST    %1,%0\;ST    %N1,%N0\";
+    else
+      return \"STM   %1,%N1,%0\";
+  }
+}"
+   [(set_attr "op_type" "NN,NN,NN")
+    (set_attr "type"    "load,loadm,storem")
+    (set_attr "length"  "8,8,8")
+    (set_attr "cc"      "*,*,*")]
+)
+
+
+;
+; movsf instruction pattern(s).
+;
+
+(define_insn "movsf"
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,d,m,d")
+        (match_operand:SF 1 "general_operand"  "f,F,m,f,m,d,d"))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+  rtx xoperands[2];
+  switch (which_alternative)
+  {
+      case (0):    /* f <- f */
+         return \"LER   %0,%1\";
+      case (1):  /* f <- 0 */
+         if (operands[1] == const0_rtx)
+         {
+             return \"SER   %0,%0\";
+         }
+      case (2): /* f <- F,m */
+         return \"LE    %0,%1\";
+      case (3): /* m <- f */
+         return \"STE   %1,%0\";
+      case (4): /* d <- m */
+         return \"L     %0,%1\";
+      case (5): /* m <- d */
+         return \"ST    %1,%0\";
+      case (6): /* d <- d */
+        return \"LR    %0,%1\";
+   }
+}"
+   [(set_attr "op_type" "RR,RR,RX,RX,RX,RX,RR")
+    (set_attr "type"    "load,load,load,store,load,store,load")
+    (set_attr "length"  "*,*,*,*,*,*,4")
+    (set_attr "cc"      "*,clobber,*,*,*,*,*")]
+)
+
+(define_insn ""
+  [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
+        (match_operand:SF 1 "general_operand"  "d,m,d"))]
+  "TARGET_SOFT_FLOAT"
+  "*
+{
+  switch (which_alternative) {
+  case (0):   /* d <- d */
+    return \"LR    %0,%1\";
+  case (1): /* d <- m */
+    return \"L     %0,%1\";
+  case (2): /* m <- d */
+      return \"ST    %1,%0\";
+  }
+}"
+   [(set_attr "op_type" "RR,RX,RX")
+    (set_attr "type"    "load,loadm,storem")
+    (set_attr "cc"      "*,*,*")]
+)
+
+
+;
+; 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 "" "")]
+    ""
+    "
+{
+  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);
+
+      emit_insn (gen_movstrsico (operands[0], operands[1], operands[2]));
+      DONE;
+    } 
+  else 
+    {
+      /* 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_rtx_SUBREG (SImode, reg0, 0), addr0);
+      emit_move_insn (gen_rtx_SUBREG (SImode, reg0, 1), len);
+
+      emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0), addr1);
+      emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 1), len);
+
+      /* MOVE */
+      emit_insn (gen_movstrsi_1 (reg0, reg1));
+      DONE;
+    }
+}")
+
+; Move a block that is less than 256 bytes in length.
+
+(define_insn "movstrsico"
+  [(set (match_operand:BLK 0 "s_operand" "=oQ")
+        (match_operand:BLK 1 "s_operand" "oQ"))
+        (use (match_operand 2 "const_int_operand" "I"))]
+  "((unsigned) INTVAL (operands[2]) < 256)"
+  "*
+{
+  return \"MVC   %O0(%c2,%R0),%1\";
+}"
+   [(set_attr "op_type" "SS")
+    (set_attr "type" "loadm")]
+)
+
+; Move a block that is larger than 255 bytes in length.
+
+
+(define_insn "movstrsi_1"
+  [(set (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "d") 0))
+        (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "d") 0)))
+   (clobber (match_dup 0))
+   (clobber (match_dup 1))]
+  ""
+  "MVCLE %0,%1,0\;JO    .-4"
+   [(set_attr "op_type" "NN")
+    (set_attr "cc" "clobber")
+    (set_attr "type" "loadm")
+    (set_attr "length"  "8")]
+)
+
+;
+; clrstrsi instruction pattern(s).
+;
+
+(define_expand "clrstrsi"
+   [(set (match_operand:BLK 0 "general_operand" "")
+         (const_int 0))
+    (use (match_operand:SI 1 "general_operand" ""))
+    (match_operand 2 "" "")]
+    ""
+    "
+{
+   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 mem = operands[0];
+      rtx len = operands[1];
+
+      if (! CONSTANT_P (len))
+          len = force_reg (SImode, len);
+
+      /* Load up the address+length pairs.  */
+
+      emit_move_insn (gen_rtx_SUBREG (SImode, reg0, 0), addr);
+      emit_move_insn (gen_rtx_SUBREG (SImode, reg0, 1), len);
+
+      emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 1), const0_rtx);
+ 
+      /* CLear! */
+      emit_insn (gen_clrstrsi_1 (reg0, reg1));
+      DONE;	
+     }
+}")
+
+(define_insn "clrstrsico"
+      [ (set          (match_operand:BLK 0  "s_operand" "=Qo")
+                      (const_int 0))
+             (use (match_operand:SI 1 "immediate_operand" "I"))]
+   ""
+   "*
+{
+        return \"XC    %O0(%1,%R0),%0\";	
+}"
+   [(set_attr "op_type" "RS")
+    (set_attr "type" "loadm")
+    (set_attr "cc"      "clobber")]
+)
+
+
+(define_insn "clrstrsi_1"
+      [ (set (mem:BLK (subreg:SI 
+	     (match_operand:DI 0 "register_operand" "d") 0))
+                      (const_int 0))
+        (use (match_operand:DI 1 "register_operand" "d"))
+	(clobber (match_dup 0))
+	(clobber (match_dup 1))]
+   ""
+   "MVCLE %0,%1,0\;JO    .-4"
+   [(set_attr "op_type" "NN")
+    (set_attr "type"    "loadm")
+    (set_attr "cc"      "clobber")
+    (set_attr "length"  "8")]
+)
+
+;;
+;;- Conversion instructions.
+;;
+
+;
+; extendsidi2 instruction pattern(s).
+;
+
+(define_expand "extendsidi2"
+  [(set                 (match_operand:DI 0 "register_operand" "=d")
+        (sign_extend:DI (match_operand:SI 1 "general_operand" "")))]
+  ""
+  "
+{
+  if (GET_CODE (operands[1]) != CONST_INT)
+    {
+      emit_insn (gen_rtx (SET, VOIDmode,
+                  operand_subword (operands[0], 0, 1, DImode), operands[1]));
+      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
+                        gen_rtx (ASHIFTRT, DImode, operands[0],
+                                gen_rtx (CONST_INT, SImode, 32))));
+    }
+  else
+    {
+      if (INTVAL (operands[1]) < 0)
+        {
+          emit_insn (gen_rtx (SET, VOIDmode,
+                                  operand_subword (operands[0], 0, 1, DImode),
+                               gen_rtx (CONST_INT, SImode, -1)));
+        }
+      else
+        {
+          emit_insn (gen_rtx (SET, VOIDmode,
+                                operand_subword (operands[0], 0, 1, DImode),
+                               gen_rtx (CONST_INT, SImode, 0)));
+        }
+      emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (SImode, operands[0]),
+                           operands[1]));
+    }
+  DONE;
+}")
+
+;
+; extendhisi2 instruction pattern(s).
+;
+
+(define_insn "extendhisi2"
+  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
+        (sign_extend:SI (match_operand:HI 1 "general_operand"  "0,K,m")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d <- 0 */
+           return \"SLL   %1,16\;SRA   %1,16\";
+       case (1): /* d <- K */
+           return \"LHI   %0,%h1\";
+       case (2): /* d <- m */
+           return \"LH    %0,%1\";
+    }
+}"
+   [(set_attr "op_type" "NN,RX,RX")
+    (set_attr "type"    "ashift,load,load")
+    (set_attr "length"  "8,*,*")]
+)
+
+;
+; extendqisi2 instruction pattern(s).
+;
+
+(define_insn "extendqisi2"
+  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
+        (sign_extend:SI (match_operand:QI 1 "r_or_s_operand"    "0,K,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d <- 0 */
+           return \"SLL   %0,24\;SRA   %0,24\";
+       case (1): /* d <- I */
+           return \"LHI   %0,%h1\";
+       case (2): /* d <- Q */
+           return \"ICM   %0,8,%1\;SRA   %0,24\";
+    }
+}"
+   [(set_attr "op_type" "NN,RX,NN")
+    (set_attr "type"    "ashift,load,ashift")
+    (set_attr "length"  "8,*,8")]
+)
+
+;
+; extendqihi2 instruction pattern(s).
+;
+
+(define_insn "extendqihi2"
+  [(set (match_operand:HI 0 "register_operand" "=d,d,d")
+        (sign_extend:HI (match_operand:QI 1 "r_or_s_operand"  "0,I,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d <- 0 */
+           return \"SLL   %0,24\;SRA   %0,24\";
+       case (1): /* d <- I */
+           return \"LHI   %0,%b1\";
+       case (2): /* d <- Q */
+           return \"ICM   %0,8,%1\;SRA   %0,24\";
+    }
+}"
+   [(set_attr "op_type" "NN,RX,NN")
+    (set_attr "type"    "ashift,load,ashift")
+    (set_attr "length"  "8,*,8")]
+)
+
+;
+; zero_extendsidi2 instruction pattern(s).
+;
+
+(define_expand "zero_extendsidi2"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+        (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
+  ""
+  "
+{
+      emit_insn (gen_rtx (SET, VOIDmode,
+                  operand_subword (operands[0], 1, 1, DImode), operands[1]));
+      emit_insn (gen_rtx (SET, VOIDmode,
+                  operand_subword (operands[0], 0, 1, DImode),
+                  gen_rtx (CONST_INT, SImode, 0)));
+  DONE;
+}")
+
+;
+; zero_extendhisi2 instruction pattern(s).
+;
+
+(define_expand "zero_extendhisi2"
+  [(set              (match_operand:SI 0 "register_operand" "")
+        (zero_extend:SI (match_operand:HI 1 "r_or_s_operand"  "")))]
+  ""
+  "
+{
+  emit_insn (gen_do_zero_extendhisi2 (operands[0], operands[1],
+                              force_const_mem (SImode, const0_rtx)));
+  DONE;
+}")
+
+
+(define_insn "do_zero_extendhisi2"
+  [(set                 (match_operand:SI 0 "register_operand" "=d,d")
+        (zero_extend:SI (match_operand:HI 1 "r_or_s_operand"   "0,Q")))
+   (use (match_operand:SI 2 "memory_operand" "m,m"))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d <- 0 */
+           return \"ICM   %0,12,%2\";
+       case (1): /* d <- Q */
+           return \"ICM   %0,12,%1\;SRL   %0,16\";
+    }
+}"
+   [(set_attr "op_type" "RX,NN")
+    (set_attr "type"    "lshift,load")
+    (set_attr "length"  "*,8")]
+)
+
+;
+; zero_extendqisi2 instruction pattern(s).
+;
+
+(define_insn "do_zero_extendqisi2_mem"
+  [(set (match_operand:SI 0 "register_operand" "=&d")
+        (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))
+   (use (match_operand:SI 2 "memory_operand" "m" ))]
+  ""
+  "*
+{
+   return \"SR    %0,%0\;IC    %0,%1\";
+}"
+   [(set_attr "op_type" "NN")
+    (set_attr "type"    "arith")
+    (set_attr "length"  "6")
+    (set_attr "cc" "clobber")]
+)
+
+(define_insn "do_zero_extendqisi2_reg"
+  [(set                 (match_operand:SI 0 "register_operand" "=d")
+        (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))
+   (use (match_operand:SI 2 "memory_operand" "m" ))]
+  ""
+  "*
+{
+  return \"ICM   %0,14,%2\";
+}"
+   [(set_attr "op_type" "RX")
+    (set_attr "type"    "load")]
+)
+
+(define_expand "zero_extendqisi2"
+  [(set (match_operand:SI 0 "register_operand" "")
+        (zero_extend:SI (match_operand:QI 1 "r_or_s_operand"  "")))]
+  ""
+  "
+{
+  emit_insn (gen_do_zero_extendqisi2_reg (operands[0], operands[1],
+                              force_const_mem (SImode, const0_rtx)));
+  DONE;
+}")
+
+;
+; zero_extendqihi2 instruction pattern(s).
+;
+
+(define_expand "zero_extendqihi2"
+  [(set (match_operand:HI 0 "register_operand" "")
+        (zero_extend:HI (match_operand:QI 1 "general_operand" "")))]
+  ""
+  "
+{
+  emit_insn (gen_do_zero_extendqihi2 (operands[0], operands[1],
+                              force_const_mem (SImode, const0_rtx)));
+  DONE;
+}")
+
+
+(define_insn "do_zero_extendqihi2"
+  [(set (match_operand:HI 0 "register_operand" "=d,d,&d")
+        (zero_extend:HI (match_operand:QI 1 "general_operand"   "0,I,m")))
+   (use (match_operand:SI 2 "memory_operand" "m,m,m"))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d <- 0 */
+           return \"ICM   %0,14,%2\";
+       case (1): /* d <- I */
+           return \"LA    %0,%c1\";
+       case (2): /* d <- Q */
+           return \"SR    %0,%0\;IC    %0,%1\";
+    }
+}"
+   [(set_attr "op_type" "RX,RX,NN")
+    (set_attr "type"    "load,load,load")
+    (set_attr "length"  "*,*,8")]
+)
+
+;
+; truncsihi2 instruction pattern(s).
+;
+
+(define_expand "truncsihi2"
+  [(set (match_operand:HI 0 "register_operand" "")
+        (truncate:HI (match_operand:SI 1 "register_operand" "")))]
+  ""
+  "
+{
+  emit_insn (gen_do_truncsihi2 (operands[0], operands[1],
+                              force_const_mem (SImode, const0_rtx)));
+  DONE;
+}")
+
+
+(define_insn "do_truncsihi2"
+  [(set (match_operand:HI 0 "register_operand" "=d")
+        (truncate:HI (match_operand:SI 1 "register_operand"  "0")))
+        (use (match_operand:SI 2 "memory_operand" "m"))]
+  ""
+  "*
+{
+   return \"ICM   %0,12,%2\";
+}"
+   [(set_attr "op_type" "RX")
+    (set_attr "type"    "load")]
+)
+
+;
+; fixuns_truncdfsi2 instruction pattern(s).
+;
+
+
+(define_expand "fixuns_truncdfsi2"
+  [(set (match_operand:SI 0 "register_operand" "")
+        (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
+  "TARGET_IEEE_FLOAT"
+  "
+{
+  rtx label1 = gen_label_rtx ();
+  rtx label2 = gen_label_rtx ();
+  rtx temp = gen_reg_rtx (DFmode);
+
+  operands[1] = force_reg (DFmode,operands[1]);
+  emit_insn (gen_cmpdf (operands[1], force_const_mem (DFmode,
+	CONST_DOUBLE_FROM_REAL_VALUE (0x80000000, DFmode))));
+  emit_jump_insn (gen_blt (label1));
+  emit_insn ( gen_subdf3 (temp, operands[1], force_const_mem (DFmode,
+	CONST_DOUBLE_FROM_REAL_VALUE (0x100000000, DFmode))));
+  emit_insn (gen_ieee_fix_truncdfsi2 (operands[0], temp, GEN_INT (7)));
+  emit_jump_insn (gen_jump (label2));
+
+  emit_label (label1);
+  emit_insn (gen_ieee_fix_truncdfsi2 (operands[0], operands[1], GEN_INT (5)));
+  emit_label (label2);
+  DONE;
+}")
+
+;
+; fix_truncdfsi2 instruction pattern(s).
+;
+
+
+(define_expand "fix_truncdfsi2"
+  [(set (match_operand:SI 0 "register_operand" "")
+        (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))]
+  "TARGET_HARD_FLOAT"
+  "
+{
+  rtx stack_local;
+  if (TARGET_IBM_FLOAT) {
+    stack_local = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
+    emit_insn (gen_do_fix_truncdfsi2 (operands[0], operands[1],
+                                    force_const_mem (DFmode,
+                                    gen_rtx (CONST_DOUBLE, VOIDmode, cc0_rtx,
+                                        0x08000000, 0x4F000000)),
+                                 force_const_mem (DFmode,
+                                 gen_rtx (CONST_DOUBLE, VOIDmode, cc0_rtx,
+                                         0x0, 0x4E000001)),
+				 stack_local));
+  } else {
+    operands[1] = force_reg (DFmode, operands[1]);
+    emit_insn (gen_ieee_fix_truncdfsi2 (operands[0], operands[1], GEN_INT (5)));
+  }
+  DONE;
+}")
+
+(define_insn "ieee_fix_truncdfsi2"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (fix:SI (match_operand:DF 1 "register_operand"  "f")))
+        (unspec [(match_operand:SI 2 "immediate_operand" "K")] 10)]
+  "TARGET_IEEE_FLOAT"
+  "*
+{
+     return \"CFDBR %0,%h2,%1\";
+}"
+   [(set_attr "op_type" "RR")
+    (set_attr "length"  "4" )
+    (set_attr "type"    "load")]
+)
+
+
+(define_insn "do_fix_truncdfsi2"
+  [(set (match_operand:SI 0 "register_operand" "=d,d")
+        (fix:SI (match_operand:DF 1 "nonimmediate_operand"   "f,m")))
+        (clobber (reg:DF 16))
+        (use (match_operand:DF 2 "memory_operand" "m,m"))
+        (use (match_operand:DF 3 "memory_operand" "m,m"))
+	(use (match_operand:BLK 4 "memory_operand" "m,m"))
+ ]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       rtx xoperands[2];
+
+       case (0): /* d <- f */
+           output_asm_insn (\"LDR   0,%1\", operands);
+           output_asm_insn (\"SD    0,%2\", operands);
+           output_asm_insn (\"AW    0,%3\", operands);
+           output_asm_insn (\"STD   0,%4\", operands);
+
+           xoperands[0] = operands[4];
+           xoperands[1] = gen_rtx (CONST_INT, SImode, 0x80);
+           output_asm_insn (\"XI    %N4,%b1\", xoperands);
+
+           return \"L     %0,%N4\";
+       case (1): /* d <- m */
+           output_asm_insn (\"LD    0,%1\", operands);
+           output_asm_insn (\"SD    0,%2\", operands);
+           output_asm_insn (\"AW    0,%3\", operands);
+           output_asm_insn (\"STD   0,%4\", xoperands);
+
+           xoperands[0] = operands[4];
+           xoperands[1] = gen_rtx (CONST_INT, SImode, 0x80);
+           output_asm_insn (\"XI    %N0,%b1\", xoperands);
+
+           return \"L    %0,%N4\";
+   }
+}"
+   [(set_attr "op_type" "NN,NN")
+    (set_attr "type"    "load,load")
+    (set_attr "length"  "20,24")
+    (set_attr "cc"      "clobber,clobber")]
+)
+
+;
+; fixuns_truncsfsi2 instruction pattern(s).
+;
+
+
+(define_expand "fixuns_truncsfsi2"
+  [(set (match_operand:SI 0 "register_operand" "")
+        (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
+  "TARGET_IEEE_FLOAT"
+  "
+{
+  rtx label1 = gen_label_rtx ();
+  rtx label2 = gen_label_rtx ();
+  rtx temp = gen_reg_rtx (SFmode);
+
+  operands[1] = force_reg (SFmode, operands[1]);
+  emit_insn (gen_cmpsf (operands[1], force_const_mem (SFmode,
+	CONST_DOUBLE_FROM_REAL_VALUE (0x80000000, SFmode))));
+  emit_jump_insn (gen_blt (label1));
+  emit_insn (gen_subsf3 (temp, operands[1], force_const_mem (SFmode,
+	CONST_DOUBLE_FROM_REAL_VALUE (0x100000000, SFmode))));
+  emit_insn (gen_ieee_fix_truncsfsi2 (operands[0], temp, GEN_INT (7)));
+  emit_jump_insn (gen_jump (label2));
+
+  emit_label (label1);
+  emit_insn (gen_ieee_fix_truncsfsi2 (operands[0], operands[1], GEN_INT (5)));
+  emit_label (label2);
+  DONE;
+}")
+
+;
+; fix_truncsfsi2 instruction pattern(s).
+;
+
+
+(define_expand "fix_truncsfsi2"
+  [(set (match_operand:SI 0 "register_operand" "")
+        (fix:SI (match_operand:SF 1 "nonimmediate_operand"   "")))]
+  "TARGET_HARD_FLOAT"
+  "
+{
+  if (TARGET_IBM_FLOAT) {
+  emit_insn (gen_do_fix_truncsfsi2 (operands[0], operands[1],
+                                 force_const_mem (DFmode,
+                                 gen_rtx (CONST_DOUBLE, VOIDmode, cc0_rtx,
+                                         0x08000000, 0x4F000000)),
+                                 force_const_mem (DFmode,
+                                 gen_rtx (CONST_DOUBLE,VOIDmode, cc0_rtx,
+                                         0x0, 0x4E000001))));
+  } else {
+    operands[1] = force_reg (SFmode, operands[1]);
+    emit_insn (gen_ieee_fix_truncsfsi2 (operands[0], operands[1], GEN_INT (5)));
+  }
+  DONE;
+}")
+
+(define_insn "ieee_fix_truncsfsi2"
+  [(set         (match_operand:SI 0 "register_operand" "=d")
+        (fix:SI (match_operand:SF 1 "register_operand"  "f")))
+        (unspec [(match_operand:SI 2 "immediate_operand" "K")] 11)]
+  "TARGET_IEEE_FLOAT"
+  "*
+{
+     return \"CFEBR %0,%h2,%1\";
+}"
+   [(set_attr "op_type" "RR")
+    (set_attr "length"  "4" )
+    (set_attr "type"    "load")]
+)
+
+
+
+(define_insn "do_fix_truncsfsi2"
+  [(set (match_operand:SI 0 "register_operand" "=d,d")
+        (fix:SI (match_operand:SF 1 "nonimmediate_operand"   "f,m")))
+        (clobber (reg:SF 16))
+        (use (match_operand:DF 2 "memory_operand" "m,m"))
+        (use (match_operand:DF 3 "memory_operand" "m,m"))
+ ]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   rtx xoperands[2];
+   switch (which_alternative)
+   {
+       case (0): /* d <- f */
+           output_asm_insn (\"LDR   0,%1\", operands);
+           output_asm_insn (\"SD    0,%2\", operands);
+           output_asm_insn (\"AW    0,%3\", operands);
+           xoperands[0] = gen_rtx (MEM, SImode,
+                            gen_rtx (PLUS, SImode,
+                              gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                              gen_rtx (CONST_INT, SImode, 16)));
+           output_asm_insn (\"STD   0,%0\", xoperands);
+           xoperands[0] = gen_rtx (MEM, SImode,
+                            gen_rtx (PLUS, SImode,
+                              gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                              gen_rtx (CONST_INT, SImode, 16+4)));
+           xoperands[1] = gen_rtx (CONST_INT, SImode, 0x80);
+           output_asm_insn (\"XI    %0,%b1\", xoperands);
+           operands[1] = gen_rtx (MEM, SImode,
+                            gen_rtx (PLUS, SImode,
+                              gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                              gen_rtx (CONST_INT, SImode, 16+4)));
+           return \"L     %0,%1\";
+       case (1): /* d <- m */
+           output_asm_insn (\"LD    0,%1\", operands);
+           output_asm_insn (\"SD    0,%2\", operands);
+           output_asm_insn (\"AW    0,%3\", operands);
+           xoperands[0] = gen_rtx (MEM, SImode,
+                            gen_rtx (PLUS, SImode,
+                              gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                              gen_rtx (CONST_INT, SImode, 16)));
+           output_asm_insn (\"STD   0,%0\", xoperands);
+           xoperands[0] = gen_rtx (MEM, SImode,
+                            gen_rtx (PLUS, SImode,
+                              gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                              gen_rtx (CONST_INT, SImode,16+4)));
+           xoperands[1] = gen_rtx (CONST_INT, SImode, 0x80);
+           output_asm_insn (\"XI    %0,%b1\", xoperands);
+           operands[1] = gen_rtx (MEM, SImode,
+                            gen_rtx (PLUS, SImode,
+                              gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                              gen_rtx (CONST_INT, SImode, 16+4)));
+           return \"L     %0,%1\";
+   }
+}"
+   [(set_attr "op_type" "NN,NN")
+    (set_attr "type"    "load,load")
+    (set_attr "length"  "20,24")
+    (set_attr "cc"      "clobber,clobber")]
+)
+;
+; floatsidf2 instruction pattern(s).
+;
+; like A-41 in POP
+
+
+
+(define_expand "floatsidf2"
+  [(set (match_operand:DF 0 "register_operand" "")
+        (float:DF (match_operand:SI 1 "register_operand"   "")))]
+  "TARGET_HARD_FLOAT"
+  "
+{
+  if (TARGET_IBM_FLOAT) {
+    emit_insn (gen_do_floatsidf2 (operands[0], operands[1],
+                                force_const_mem (SImode,
+                                gen_rtx (CONST_INT, SImode,
+                                        0x4E000000)),
+                                 force_const_mem (DFmode,
+                                 gen_rtx (CONST_DOUBLE, VOIDmode, cc0_rtx,
+                                         0x80000000, 0x4E000000))));
+  DONE;
+  }
+}")
+
+(define_insn "ieee_floatsidf2"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+        (float:DF (match_operand:SI 1 "register_operand"  "d")))]
+  "TARGET_IEEE_FLOAT"
+  "*
+{
+     return \"CDFBR %0,%1\";
+}"
+   [(set_attr "op_type" "RR")
+    (set_attr "length"  "4" )
+    (set_attr "type"    "load")]
+)
+
+
+(define_insn "do_floatsidf2"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+        (float:DF (match_operand:SI 1 "register_operand" "d")))
+   (use (match_operand:SI 2 "memory_operand" "m"))
+   (use (match_operand:DF 3 "memory_operand" "m"))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   rtx xoperands[2];
+   xoperands[0] = operands[1];
+   xoperands[1] = gen_rtx (MEM, SImode,
+                    gen_rtx (PLUS, SImode,
+                      gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                      gen_rtx (CONST_INT, SImode, 16+4)));
+   output_asm_insn (\"ST    %0,%1\", xoperands);
+   xoperands[0] = gen_rtx (CONST_INT, SImode, 0x80);
+   output_asm_insn (\"XI    %1,%b0\", xoperands);
+   xoperands[0] = operands[2];
+   xoperands[1] = gen_rtx (MEM, SImode,
+                    gen_rtx (PLUS, SImode,
+                      gen_rtx (REG, SImode,STACK_POINTER_REGNUM),
+                      gen_rtx (CONST_INT, SImode,16)));
+   output_asm_insn (\"MVC   %O1(4,%R1),%0\", xoperands);
+   xoperands[0] = operands[0];
+   xoperands[1] = gen_rtx (MEM, SImode,
+                    gen_rtx (PLUS, SImode,
+                      gen_rtx (REG, SImode,STACK_POINTER_REGNUM),
+                      gen_rtx (CONST_INT, SImode,16)));
+   output_asm_insn (\"LD    %0,%1\", xoperands);
+
+   return \"SD    %0,%3\";
+
+}"
+   [(set_attr "op_type" "NN")
+    (set_attr "type"    "load")
+    (set_attr "length"  "20")
+    (set_attr "cc"      "clobber")]
+)
+
+
+(define_expand "floatsisf2"
+  [(set (match_operand:SF 0 "register_operand" "")
+        (float:SF (match_operand:SI 1 "register_operand"   "")))]
+  "TARGET_HARD_FLOAT"
+  "
+{
+  if(TARGET_IBM_FLOAT) {
+    emit_insn (gen_do_floatsisf2(operands[0], operands[1],
+                                 force_const_mem (SImode,
+                                 gen_rtx (CONST_INT, SImode,
+                                         0x4E000000)),
+                                 force_const_mem (DFmode,
+                                 gen_rtx (CONST_DOUBLE,VOIDmode,cc0_rtx,
+                                         0x80000000, 0x4E000000))));
+  DONE;
+  }
+}")
+
+(define_insn "ieee_floatsisf2"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+        (float:SF (match_operand:SI 1 "register_operand"  "d")))]
+  "TARGET_IEEE_FLOAT"
+  "*
+{
+     return \"CEFBR %0,%1\";
+}"
+   [(set_attr "op_type" "RR")
+    (set_attr "length"  "4" )
+    (set_attr "type"    "load")]
+)
+
+
+(define_insn "do_floatsisf2"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+        (float:SF (match_operand:SI 1 "register_operand" "d")))
+   (use (match_operand:SI 2 "memory_operand" "m"))
+   (use (match_operand:DF 3 "memory_operand" "m"))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   rtx xoperands[2];
+   xoperands[0] = operands[1];
+   xoperands[1] = gen_rtx (MEM, SImode,
+                    gen_rtx (PLUS, SImode,
+                      gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                      gen_rtx (CONST_INT, SImode,16+4)));
+   output_asm_insn (\"ST    %0,%1\", xoperands);
+   xoperands[0] = gen_rtx (CONST_INT, SImode, 0x80);
+   output_asm_insn (\"XI    %1,%b0\", xoperands);
+   xoperands[0] = operands[2];
+   xoperands[1] = gen_rtx (MEM, SImode,
+                    gen_rtx (PLUS, SImode,
+                      gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                      gen_rtx (CONST_INT, SImode,16)));
+   output_asm_insn (\"MVC   %O1(4,%R1),%0\", xoperands);
+   xoperands[0] = operands[0];
+   xoperands[1] = gen_rtx (MEM, SImode,
+                    gen_rtx (PLUS, SImode,
+                      gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                      gen_rtx (CONST_INT, SImode,16)));
+   output_asm_insn (\"LD    %0,%1\", xoperands);
+   return \"SD    %0,%3\";
+}"
+   [(set_attr "op_type" "NN")
+    (set_attr "type"    "load")
+    (set_attr "length"  "20")
+    (set_attr "cc"      "clobber")]
+)
+
+;
+; truncdfsf2 instruction pattern(s).
+;
+
+(define_expand "truncdfsf2"
+  [(set (match_operand:SF 0 "register_operand" "")
+        (float_truncate:SF (match_operand:DF 1 "general_operand"  "")))]
+  "TARGET_HARD_FLOAT"
+  "
+{
+  if (CONSTANT_P(operands[1]))
+      operands[1] =  force_const_mem (DFmode, operands[1]);
+}")
+
+
+
+
+(define_insn "do_truncdfsf2"
+  [(set (match_operand:SF 0 "register_operand" "=f,f")
+        (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand"  "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f <- f */
+         if (TARGET_IBM_FLOAT)
+           return \"LRER  %0,%1\";
+         else
+           return \"LEDBR %0,%1\";
+       case (1): /* f <- m */
+         if (TARGET_IBM_FLOAT)
+           return \"LE    %0,%1\";
+         else
+           return \"LD    %0,%1\;LEDBR %0,%0\";
+   }
+
+   return \"LRER  %0,%1\";
+}"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "type"     "load,load")]
+)
+
+;
+; extendsfdf2 instruction pattern(s).
+;
+
+(define_insn "extendsfdf2"
+  [(set (match_operand:DF 0 "register_operand" "=f,f")
+        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand"  "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+  rtx xoperands[2];
+  switch (which_alternative)
+    {
+    case (0): /* f <- f */
+      if (TARGET_IBM_FLOAT) {
+	return \"SDR   %0,%0\;LER   %0,%1\";
+      } else {
+        return \"LDEBR %0,%1\";
+      }
+       case (1): /* f <- m */
+         if (TARGET_IBM_FLOAT)
+           return \"SDR   %0,%0\;LE    %0,%1\";
+         else
+           return \"LDEB  %0,%1\";
+   }
+}"
+   [(set_attr "op_type"  "NN,NN")
+    (set_attr "type"     "load,load")
+    (set_attr "length"   "10,6")
+    (set_attr "cc"       "clobber,clobber")]
+)
+
+;;
+;; ARITHMETRIC OPERATIONS
+;;
+;  arithmetric operations set the ConditionCode,
+;  because of unpredictable Bits in Register for Halfword and Byte
+;  the ConditionCode can be set wrong in operations for Halfword and Byte
+;  Therefor the attribute 'cc' is set to 'clobber' in this cases
+
+
+;;
+;;- Add instructions.
+;;
+
+;
+; adddi3 instruction pattern(s).
+;
+
+(define_insn "adddi3"
+  [(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") ) )]
+  ""
+  "*
+{
+  switch (which_alternative)
+    {
+    case (0): /* d  d */
+      output_asm_insn (\"AR    %0,%2\", operands);
+      output_asm_insn (\"ALR   %N0,%N2\", operands);
+      break;
+    case (1): /* d  m */
+      output_asm_insn (\"A     %0,%2\", operands);
+      output_asm_insn (\"AL    %N0,%N2\", operands);
+      break;
+    }
+      output_asm_insn (\"BRC   12,.+8\", operands);
+      return \"AHI   %0,1\";
+
+}"
+   [(set_attr "op_type"  "NN,NN")
+    (set_attr "type"     "arith")
+    (set_attr "length"   "12,16")]
+)
+
+;
+; addsi3 instruction pattern(s).
+;
+; The following insn is used when it is known that operand one is the stack pointer,
+; and operand two is small enough to fit in the displacement field
+; In this case, the result will be a address
+;
+
+(define_insn "addaddr"
+  [(set (match_operand:SI 0 "register_operand" "=d,a")
+        (plus:SI (match_operand:SI 1 "register_operand"  "a,a")
+                 (match_operand:SI 2 "general_operand"   "J,0")))]
+  "(((REGNO (operands[1]) == STACK_POINTER_REGNUM ) || 
+     (REGNO (operands[1]) == BASE_REGISTER)) && 
+	CONST_OK_FOR_LETTER_P (INTVAL (operands[2]),'J'))"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d = a + J */
+           return \"LA    %0,%c2(,%1)\";
+       case (1): /* a = a + a2 */
+           return \"LA    %0,0(%0,%1)\";
+   }
+
+}"
+   [(set_attr "op_type"  "RX")
+    (set_attr "type"     "load")]
+)
+
+
+
+(define_insn "addsi3"
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d")
+        (plus:SI (match_operand:SI 1 "general_operand" "%0,0,0,0")
+                 (match_operand:SI 2 "general_pmode_operand" "d,K,i,m")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d =+ d */
+           return \"AR    %0,%2\";
+       case (1): /* d =+ K */
+           return \"AHI   %0,%h2\";
+       case (2): /* d =+ m */
+           return \"A     %0,%g2\";
+       case (3): /* d =+ m */
+           return \"A     %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RI,RX,RX")]
+)
+
+;(define_expand "addsi3"
+;  [(set (match_operand:SI 0 "nonimmediate_operand" "")
+;        (plus:SI (match_operand:SI 1 "register_operand" "")
+;                 (match_operand:SI 2 "_operand" "")))]
+;  ""
+;  "
+;{
+;  emit_insn (gen_do_addsi3 (operands[0], operands[1], operands[2]));
+;  DONE;		
+;}
+;")
+
+(define_insn "la"
+  [(set (match_operand:SI 0 "register_operand" "=a")
+	(unspec:SI [(match_operand:BLK 1 "memory_operand" "m")] 12))]
+  ""
+  "@
+  LA\\t%0,%1"
+   [(set_attr "op_type"  "RX")
+    (set_attr "type"     "loadm")]
+)
+
+
+(define_insn "do_la"
+  [(set (match_operand:SI 0 "register_operand" "=a")
+        (match_operand:QI 1 "address_operand" "p"))]
+  "GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != CONST"
+  "*
+{
+	rtx reg1=0,reg2=0,disp=0,op0,op1;
+        rtx xoperands[2];
+
+	if (la_address_operand (operands[1], SImode))
+           return \"LA    %0,%1\";
+	else if (GET_CODE (operands[1]) == REG)
+	   return \"LR    %0,%1\";
+	else {
+	  if (GET_CODE (operands[1]) == PLUS) {
+	    op0 = XEXP (operands[1], 0);
+	    op1 = XEXP (operands[1], 1);
+	    if (GET_CODE (op0) == PLUS) {
+              if (GET_CODE (XEXP (op0, 0)) == REG) {
+	        reg1 = XEXP (op0, 0);
+	        if (GET_CODE (XEXP (op0, 1)) == REG) 
+	          reg2 = XEXP (op0, 1);
+	        else
+	          disp = XEXP (op0, 1);
+	        if (GET_CODE (op1) == REG) 
+	          reg2 = op1;
+	        else
+	          disp = op1;
+              } else {
+	        fatal_insn (\"load_address in s390.md failed\", insn);
+              }              
+            } else if (GET_CODE (op0) == REG) {
+	      reg1 = op0; 
+	      if (GET_CODE (op1) == REG) 
+	        reg2 = op1;
+	      else if (GET_CODE (op1) == PLUS) {
+	        if (GET_CODE (XEXP (op1, 0)) == REG) 
+	          reg2 = XEXP (op1, 0);
+		else 
+	          fatal_insn (\"load_address in s390.md failed\", insn);
+	        if (GET_CODE (XEXP (op1, 1)) == CONST_INT) 
+	          disp = XEXP (op1, 1);
+                else
+	          fatal_insn (\"load_address in s390.md failed\", insn);
+              }
+              else		
+	        disp = op1;
+	    } else {
+	      fatal_insn (\"load_address in s390.md failed\", insn);	
+            }   
+	  } else {
+	    fatal_insn (\"load_address in s390.md failed\", insn);
+          }
+        }
+	
+	if (reg2) {
+#if 0
+	  if (REGNO (reg1) == REGNO (reg2))
+	      fatal_insn (\"load_address in s390.md failed\", insn);
+#endif
+
+	  if (REGNO (operands[0]) == REGNO (reg2)) {
+	    xoperands[0] = reg1;
+	    reg1 = reg2;
+	    reg2 = xoperands[0];
+	  }
+	}
+
+        if (REGNO (operands[0]) != REGNO (reg1)) {
+            xoperands[0] = operands[0];
+	    xoperands[1] = reg1;
+            output_asm_insn (\"LR    %0,%1\", xoperands);
+	} 
+
+	if (reg2) {
+          xoperands[0] = operands[0];
+          xoperands[1] = reg2;
+	  if (disp)   
+            output_asm_insn (\"AR    %0,%1\", xoperands);
+          else {
+            operands[1] = reg2;
+            return \"AR    %0,%1\";
+          }  
+        } 
+        if (disp) {
+          operands[1] = disp;
+          return \"AHI   %0,%1\";
+        } 
+}"
+   [(set_attr "op_type"  "RX")
+    (set_attr "type"     "loadm")]
+)
+
+
+;
+; 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")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d =+ d */
+         return \"AR    %0,%2\";
+       case (1): /* d =+ K */
+         return \"AHI   %0,%h2\";
+       case (2): /* d =+ m */
+         return \"AH    %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RI,RX")]
+)
+
+
+;
+; addqi3 instruction pattern(s).
+;
+
+(define_insn "addqi3"
+  [(set (match_operand:QI 0 "register_operand" "=d,d")
+        (plus:QI (match_operand:QI 1 "register_operand"  "%a,a")
+                 (match_operand:QI 2 "general_operand"   "a,n")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d = a + a */
+           return \"LA    %0,0(%1,%2)\";
+       case (1): /* d = a + i */
+           return \"LA    %0,%b2(,%1)\";
+   }
+}"
+   [(set_attr "op_type"  "RX,RX")
+    (set_attr "cc"       "clobber,clobber") ]
+)
+
+
+;
+; adddf3 instruction pattern(s).
+;
+
+(define_insn "adddf3"
+  [(set (match_operand:DF 0 "register_operand" "=f,f")
+        (plus:DF (match_operand:DF 1 "register_operand"  "%0,0")
+                 (match_operand:DF 2 "nonimmediate_operand"   "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f =+ f */
+         if (TARGET_IBM_FLOAT)
+           return \"ADR   %0,%2\";
+         else
+           return \"ADBR  %0,%2\";
+       case (1): /* f =+ m */
+         if (TARGET_IBM_FLOAT)
+           return \"AD    %0,%2\";
+         else
+           return \"ADB   %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")]
+)
+
+;
+; addsf3 instruction pattern(s).
+;
+
+(define_insn "addsf3"
+  [(set (match_operand:SF 0 "register_operand" "=f,f")
+        (plus:SF (match_operand:SF 1 "register_operand"  "%0,0")
+                 (match_operand:SF 2 "nonimmediate_operand"   "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f =+ f */
+         if (TARGET_IBM_FLOAT)
+           return \"AER   %0,%2\";
+         else
+           return \"AEBR  %0,%2\";
+       case (1): /* f =+ m */
+         if (TARGET_IBM_FLOAT)
+           return \"AE    %0,%2\";
+         else
+           return \"AEB   %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")]
+)
+
+;;
+;;- Subtract instructions.
+;;
+
+;
+; subdi3 instruction pattern(s).
+;
+
+(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 "nonimmediate_operand"   "d,m")))]
+  ""
+  "*
+{
+  switch (which_alternative)
+    {
+    case (0): /* d  d */
+      output_asm_insn (\"SR    %0,%2\", operands);
+      output_asm_insn (\"SLR   %N0,%N2\", operands);
+      break;
+    case (1): /* d  m */
+      output_asm_insn (\"S     %0,%2\", operands);
+      output_asm_insn (\"SL    %N0,%N2\", operands);
+      break;
+    }
+      output_asm_insn (\"BRC   11,.+8\", operands);
+      return \"AHI   %0,-1\";
+
+}"
+   [(set_attr "op_type"  "NN,NN")
+    (set_attr "type"     "arith")
+    (set_attr "length"   "12,16")]
+)
+
+;
+; subsi3 instruction pattern(s).
+;
+
+(define_insn "subsi3"
+  [(set (match_operand:SI 0 "register_operand" "=d,d")
+        (minus:SI (match_operand:SI 1 "register_operand"  "0,0")
+                  (match_operand:SI 2 "general_pmode_operand"   "d,m")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d -= d */
+           return \"SR    %0,%2\";
+       case (1): /* d -= m */
+           return \"S     %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "type"     "arith")]
+)
+
+;
+; subhi3 instruction pattern(s).
+;
+
+(define_insn "subhi3"
+  [(set (match_operand:HI 0 "register_operand" "=d,d,d")
+        (minus:HI (match_operand:HI 1 "register_operand"  "0,0,0")
+                  (match_operand:HI 2 "nonimmediate_operand"  "d,K,m")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d -= d */
+           return \"SR    %0,%2\";
+       case (1): /* d -= K */
+           return \"AHI   %0,-%h2\";
+       case (2): /* d -= m */
+           return \"SH    %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RI,RX")
+    (set_attr "type"     "arith")]
+)
+
+;
+; subqi3 instruction pattern(s).
+;
+
+(define_expand "subqi3"
+  [(set (match_operand:QI 0 "register_operand" "")
+        (minus:QI (match_operand:QI 1 "register_operand" "")
+                  (match_operand:QI 2 "general_operand" "")))]
+  ""
+  "
+{
+  if (REG_P (operands[2]))
+    {
+      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
+                        gen_rtx (MINUS, QImode, operands[1], operands[2])));
+    }
+  else
+    {
+      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
+                        gen_rtx (PLUS, QImode, operands[1],
+                                 negate_rtx (QImode, operands[2]))));
+    }
+  DONE;
+}")
+
+(define_insn ""
+  [(set (match_operand:QI 0 "register_operand" "=d")
+        (minus:QI (match_operand:QI 1 "register_operand" "0")
+                  (match_operand:QI 2 "register_operand" "d")))]
+  ""
+  "*
+{
+   return \"SR    %0,%2\";
+}"
+   [(set_attr "op_type"  "RR")
+    (set_attr "type"     "arith")
+    (set_attr "cc"       "clobber")]
+)
+
+;
+; subdf3 instruction pattern(s).
+;
+
+(define_insn "subdf3"
+  [(set (match_operand:DF 0 "register_operand" "=f,f")
+        (minus:DF (match_operand:DF 1 "register_operand"  "0,0")
+                 (match_operand:DF 2 "nonimmediate_operand"   "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f =+ f */
+         if (TARGET_IBM_FLOAT)
+           return \"SDR   %0,%2\";
+         else
+           return \"SDBR  %0,%2\";
+       case (1): /* f =+ m */
+         if (TARGET_IBM_FLOAT)
+           return \"SD    %0,%2\";
+         else
+           return \"SDB   %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")]
+)
+
+;
+; subsf3 instruction pattern(s).
+;
+
+(define_insn "subsf3"
+  [(set (match_operand:SF 0 "register_operand" "=f,f")
+        (minus:SF (match_operand:SF 1 "register_operand"  "0,0")
+                 (match_operand:SF 2 "nonimmediate_operand"   "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f =+ f */
+         if (TARGET_IBM_FLOAT)
+           return \"SER   %0,%2\";
+         else
+           return \"SEBR  %0,%2\";
+       case (1): /* f =+ m */
+         if (TARGET_IBM_FLOAT)
+           return \"SE    %0,%2\";
+         else
+           return \"SEB   %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")]
+)
+
+;;
+;;- Multiply instructions.
+;;
+
+(define_expand "muldi3"
+  [(set (match_operand:DI 0 "register_operand" "")
+        (mult:DI (match_operand:DI 1 "memory_operand"   "")
+                (match_operand:DI 2 "memory_operand"   "") ) )]
+  ""
+  "
+{
+  rtx label1 = gen_label_rtx ();
+  rtx label2 = gen_label_rtx ();
+  rtx op0_0 = operand_subword (operands[0], 0 ,1, DImode);
+  rtx op0_1 = operand_subword (operands[0], 1 ,1, DImode);
+  rtx op1_0 = operand_subword (operands[1], 0 ,1, DImode);
+  rtx op1_1 = operand_subword (operands[1], 1 ,1, DImode);
+  rtx op2_0 = operand_subword (operands[2], 0 ,1, DImode);
+  rtx op2_1 = operand_subword (operands[2], 1 ,1, DImode);
+  rtx temp1 = gen_reg_rtx (SImode); 
+  rtx temp2 = gen_reg_rtx (SImode);
+
+  emit_move_insn (temp1, op1_1);
+  emit_move_insn (temp2, op2_1);
+  emit_move_insn (op0_1, temp1);
+  emit_insn (gen_mulsi_6432 (operands[0], operands[0], temp2));
+
+  emit_insn (gen_tstsi (temp1));
+  emit_jump_insn (gen_bge (label1));
+  emit_insn (gen_addsi3 (op0_0, op0_0, temp2));
+  emit_label (label1);
+  emit_insn (gen_mulsi3 (temp1, temp1, op2_0));
+  emit_insn (gen_addsi3 (op0_0, op0_0, temp1));
+
+  emit_insn (gen_tstsi (temp2));
+  emit_jump_insn (gen_bge (label2));
+  emit_insn (gen_addsi3 (op0_0, op0_0, op1_1));
+  emit_label (label2);
+  emit_insn (gen_mulsi3 (temp2, temp2, op1_0));
+  emit_insn (gen_addsi3 (op0_0, op0_0, temp2));
+
+  DONE;
+
+}")
+
+(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")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d *= d */
+           return \"MSR   %0,%2\";
+       case (1): /* d *= K */
+           return \"MHI   %0,%h2\";
+       case (2): /* d *= m */
+           return \"MS    %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RRE,RI,RX")
+    (set_attr "type"     "muldiv")]
+)
+
+(define_insn "mulsi_6432"
+   [(set          (match_operand:DI 0 "register_operand" "=d,d")
+         (mult:DI (match_operand:DI 1 "register_operand"  "%0,0")
+                  (match_operand:SI 2 "nonimmediate_operand" "d,m")))]
+   ""
+   "*
+ {
+    switch (which_alternative)
+    {
+        case (0): /* d *= d */
+            return \"MR    %0,%2\";
+        case (1): /* d *= m */
+            return \"M     %0,%2\";
+    }
+ }"
+    [(set_attr "op_type"  "RR,RX")
+     (set_attr "type"     "muldiv")]
+ )
+ 
+
+;
+; muldf3 instruction pattern(s).
+;
+
+(define_insn "muldf3"
+  [(set (match_operand:DF 0 "register_operand" "=f,f")
+        (mult:DF (match_operand:DF 1 "register_operand"  "%0,0")
+                 (match_operand:DF 2 "nonimmediate_operand"   "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f *= f */
+         if (TARGET_IBM_FLOAT)
+           return \"MDR   %0,%2\";
+         else
+           return \"MDBR  %0,%2\";
+       case (1): /* f *= m */
+         if (TARGET_IBM_FLOAT)
+           return \"MD    %0,%2\";
+         else
+           return \"MDB   %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "type"     "muldiv")]
+)
+
+;
+; mulsf3 instruction pattern(s).
+;
+
+(define_insn "mulsf3"
+  [(set (match_operand:SF 0 "register_operand" "=f,f")
+        (mult:SF (match_operand:SF 1 "register_operand" "%0,0")
+                 (match_operand:SF 2 "nonimmediate_operand"  "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f *= f */
+         if (TARGET_IBM_FLOAT)
+           return \"MER   %0,%2\";
+         else
+           return \"MEEBR  %0,%2\";
+       case (1): /* f *= m */
+         if (TARGET_IBM_FLOAT)
+           return \"ME    %0,%2\";
+         else
+           return \"MEEB   %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "type"     "muldiv")]
+)
+
+;;
+;;- Divide instructions.
+;;
+
+;
+; divsi3 instruction pattern(s).
+;
+(define_expand "divsi3"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (div:SI (match_operand:SI 1 "register_operand" "d")
+                (match_operand:SI 2 "nonimmediate_operand" "")))]
+  ""
+  "
+{
+  rtx op3;	
+
+  op3 = gen_reg_rtx (DImode);
+  if (CONSTANT_P (operands[2]))
+	operands[2] = force_const_mem (SImode, operands[2]);	
+  else
+	operands[2] = force_reg (SImode, operands[2]);
+  emit_insn (gen_do_divsi3 (op3, operands[1], operands[2]));
+  emit_move_insn (operands[0], gen_rtx (SUBREG, SImode, op3, 1));
+  DONE;
+}")
+
+(define_insn "do_divsi3"
+  [(set         (match_operand:DI 0 "register_operand" "=&d,&d")
+        (div:DI (match_operand:SI 1 "register_operand"  "d,d")
+                (match_operand:SI 2 "nonimmediate_operand" "d,m")))]
+  ""
+  "*
+{
+   output_asm_insn (\"LR    %0,%1\", operands);
+   output_asm_insn (\"SRDA  %0,32\", operands);	
+
+   switch (which_alternative)
+   {
+       case (0): /* d /= d */
+            return \"DR    %0,%2\";
+       case (1): /* d /= m */
+            return \"D     %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "type"     "muldiv")]
+)
+
+;
+; udivsi3 instruction pattern(s).
+;
+
+(define_expand "udivsi3"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (udiv:SI (match_operand:SI 1 "general_operand" "")
+                 (match_operand:SI 2 "general_operand" "")))]
+  ""
+  "
+{
+  rtx dr_0,dr_1,op3;
+
+  op3 = gen_reg_rtx (DImode);
+  dr_0 = gen_rtx (SUBREG, SImode, op3, 0);	
+  dr_1 = gen_rtx (SUBREG, SImode, op3, 1);
+
+  if (CONSTANT_P (operands[2]))
+    {
+      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
+        {
+          rtx label1 = gen_label_rtx ();
+
+          emit_move_insn (dr_0, operands[1]);
+          emit_move_insn (dr_1, const0_rtx);
+          emit_insn (gen_cmpsi (dr_0, operands[2]));
+          emit_jump_insn (gen_bltu (label1));
+          emit_move_insn (dr_1, const1_rtx);
+          emit_label (label1);
+        }
+      else
+        {
+          operands[1] = force_reg (SImode, operands[1]);		
+          operands[2] = force_const_mem (SImode, operands[2]);
+          emit_insn (gen_do_udivsi3 (op3, operands[1], operands[2]));
+        }
+    }
+  else
+    {  
+      rtx label1 = gen_label_rtx ();
+      rtx label2 = gen_label_rtx ();
+      rtx label3 = gen_label_rtx ();
+
+      operands[1] = force_reg (SImode, operands[1]);	
+      operands[2] = force_reg (SImode, operands[2]);	
+	
+      emit_move_insn (dr_1, const0_rtx);
+      emit_insn (gen_cmpsi (operands[2], operands[1]));
+      emit_jump_insn (gen_bgtu (label3));
+      emit_insn (gen_cmpsi (operands[2], const1_rtx));
+      emit_jump_insn (gen_blt (label2));
+      emit_insn (gen_cmpsi (operands[2], const1_rtx));
+      emit_jump_insn (gen_beq (label1));
+      emit_insn (gen_do_udivsi3 (op3, operands[1], operands[2]));
+      emit_jump_insn (gen_jump (label3));
+      emit_label (label1);
+      emit_move_insn (dr_1, operands[1]);
+      emit_jump_insn (gen_jump (label3));
+      emit_label (label2);
+      emit_move_insn (dr_1, const1_rtx);
+      emit_label (label3);
+    }
+  emit_move_insn (operands[0], dr_1);
+
+  DONE;
+}")
+
+
+(define_insn "do_udivsi3"
+  [(set (match_operand:DI 0 "register_operand" "=&d,&d")
+        (udiv:DI (match_operand:SI 1 "register_operand"   "d,d")
+                (match_operand:SI 2 "nonimmediate_operand"   "d,m")))]
+  ""
+  "*
+{
+   output_asm_insn (\"LR    %0,%1\", operands);
+   output_asm_insn (\"SRDL  %0,32\", operands);	
+
+   switch (which_alternative)
+   {
+       case (0): /* d /= d */
+            return \"DR    %0,%2\";
+       case (1): /* d /= m */
+            return \"D     %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "type"     "muldiv")]
+)
+
+
+;
+; divdf3 instruction pattern(s).
+;
+
+(define_insn "divdf3"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f")
+        (div:DF (match_operand:DF 1 "general_operand"  "0,0")
+                (match_operand:DF 2 "nonimmediate_operand"  "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f *= f */
+         if (TARGET_IBM_FLOAT)
+           return \"DDR   %0,%2\";
+         else
+           return \"DDBR  %0,%2\";
+       case (1): /* f *= m */
+         if (TARGET_IBM_FLOAT)
+           return \"DD    %0,%2\";
+         else
+           return \"DDB   %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "type"     "muldiv")]
+)
+
+;
+; divsf3 instruction pattern(s).
+;
+
+(define_insn "divsf3"
+  [(set         (match_operand:SF 0 "nonimmediate_operand" "=f,f")
+        (div:SF (match_operand:SF 1 "nonimmediate_operand"  "0,0")
+                (match_operand:SF 2 "nonimmediate_operand"  "f,m")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* f *= f */
+         if (TARGET_IBM_FLOAT)
+           return \"DER   %0,%2\";
+         else
+           return \"DEBR  %0,%2\";
+       case (1): /* f *= m */
+         if (TARGET_IBM_FLOAT)
+           return \"DE    %0,%2\";
+         else
+           return \"DEB   %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "type"     "muldiv")]
+)
+
+;;
+;;- Modulo instructions.
+;;
+
+;
+; modsi3 instruction pattern(s).
+;
+
+(define_expand "modsi3"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (mod:SI (match_operand:SI 1 "register_operand" "d")
+                (match_operand:SI 2 "nonimmediate_operand" "")))]
+  ""
+  "
+{
+  rtx op3 = gen_reg_rtx (DImode);
+  if (CONSTANT_P (operands[2]))
+	operands[2] = force_const_mem (SImode, operands[2]);	
+  else
+	operands[2] = force_reg (SImode, operands[2]);
+  emit_insn (gen_do_modsi3 (op3, operands[1], operands[2]));
+  emit_insn (gen_rtx (SET, SImode, operands[0],
+                        gen_rtx (SUBREG, SImode, op3, 0)));
+  DONE;
+}")
+
+(define_insn "do_modsi3"
+  [(set (match_operand:DI 0 "register_operand" "=&d,&d")
+        (mod:DI (match_operand:SI 1 "register_operand"  "d,d")
+                (match_operand:SI 2 "nonimmediate_operand"   "d,m")))]
+  ""
+  "*
+{
+   output_asm_insn (\"LR    %0,%1\", operands);
+   output_asm_insn (\"SRDA  %0,32\", operands);	
+
+   switch (which_alternative)
+   {
+       case (0): /* d /= d */
+            return \"DR    %0,%2\";
+       case (1): /* d /= m */
+            return \"D     %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "type"     "muldiv")]
+)
+
+
+;
+; umodsi3 instruction pattern(s).
+;
+
+(define_expand "umodsi3"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
+                 (match_operand:SI 2 "nonimmediate_operand" "")))]
+  ""
+  "
+{
+  rtx dr_0,dr_1,op3;
+
+  op3 = gen_reg_rtx (DImode);
+  dr_0 = gen_rtx (SUBREG, SImode, op3, 0);	
+  dr_1 = gen_rtx (SUBREG, SImode, op3, 1);
+
+  if (CONSTANT_P (operands[2]))
+    {
+      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
+        {
+          rtx label1 = gen_label_rtx ();
+
+	  emit_move_insn (dr_0, operands[1]);
+          emit_insn (gen_cmpsi (dr_0, operands[2]));
+          emit_jump_insn (gen_bltu (label1));
+	  emit_insn (gen_abssi2 (dr_0, operands[2]));
+          emit_insn (gen_addsi3 (dr_0,dr_0, operands[1]));
+          emit_label (label1);
+        }
+      else
+        {
+          operands[1] = force_reg (SImode, operands[1]);		
+          operands[2] = force_const_mem (SImode, operands[2]);
+          emit_insn (gen_do_umodsi3 (op3, operands[1], operands[2]));
+        }
+
+    }
+  else
+    {
+      rtx label1 = gen_label_rtx ();
+      rtx label2 = gen_label_rtx ();
+      rtx label3 = gen_label_rtx ();
+
+      operands[1] = force_reg (SImode, operands[1]);	
+      operands[2] = force_reg (SImode, operands[2]);	
+
+      emit_move_insn(dr_0, operands[1]);	
+      emit_insn (gen_cmpsi (operands[2], dr_0));
+      emit_jump_insn (gen_bgtu (label3));
+      emit_insn (gen_cmpsi (operands[2], const1_rtx));
+      emit_jump_insn (gen_blt (label2));
+         /* due to 'feature' in 2.8.0 (cse.c) not poss. to have two CC0 user */
+      emit_insn (gen_cmpsi (operands[2], const1_rtx));
+      emit_jump_insn (gen_beq (label1));
+      emit_insn (gen_do_umodsi3 (op3, operands[1], operands[2]));
+      emit_jump_insn (gen_jump (label3));
+      emit_label (label1);
+      emit_move_insn (dr_0, const0_rtx);
+      emit_jump_insn (gen_jump (label3));
+      emit_label (label2);
+      emit_insn (gen_rtx (SET, VOIDmode, dr_0,
+                          gen_rtx (MINUS, SImode, dr_0, operands[2])));
+      emit_label (label3);
+
+    }
+  emit_move_insn (operands[0], dr_0);
+
+  DONE;
+}")
+
+
+
+(define_insn "do_umodsi3"
+  [(set (match_operand:DI 0 "register_operand" "=&d,&d")
+        (umod:DI (match_operand:SI 1 "register_operand"   "d,d")
+                (match_operand:SI 2 "nonimmediate_operand"   "d,m")))]
+  ""
+  "*
+{
+   output_asm_insn (\"LR    %0,%1\", operands);
+   output_asm_insn (\"SRDL  %0,32\", operands);	
+
+   switch (which_alternative)
+   {
+       case (0): /* d /= d */
+            return \"DR    %0,%2\";
+       case (1): /* d /= m */
+            return \"D     %0,%2\";
+   }
+}"
+   [(set_attr "op_type"  "NN,NN")
+    (set_attr "length" 	 "12,12") 
+    (set_attr "type"     "muldiv")]
+)
+
+;;
+;;- And instructions.
+;;
+
+;
+; anddi3 instruction pattern(s).
+;
+
+
+;
+; andsi3 instruction pattern(s).
+;
+
+
+(define_expand "andsi3"
+  [(set (match_operand:SI 0 "r_or_s_operand" "")
+        (and:SI (match_operand:SI 1 "r_or_s_operand"  "")
+                (match_operand:SI 2 "r_or_s_operand"  "")))]
+  ""
+  "
+{
+  if (CONSTANT_P (operands[2]))
+      operands[2] =  force_const_mem (SImode, operands[2]);
+}")
+
+
+
+
+(define_insn "do_andsi3"
+  [(set (match_operand:SI 0 "r_or_s_operand" "=d,d,Q")
+        (and:SI (match_operand:SI 1 "r_or_s_operand"  "%0,0,0")
+                (match_operand:SI 2 "r_or_s_operand"  "d,m,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d |= d */
+           return \"NR    %0,%2\";
+       case (1): /* d |= m */
+           return \"N     %0,%2\";
+       case (2): /* m |= m */
+           return \"NC    %O0(4,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX,SS")
+    (set_attr "type"     "logic")]
+)
+
+
+;
+; andhi3 instruction pattern(s).
+;
+
+(define_expand "andhi3"
+  [(set (match_operand:HI 0 "r_or_s_operand" "")
+        (and:HI (match_operand:HI 1 "r_or_s_operand"  "")
+                (match_operand:HI 2 "r_or_s_operand"  "")))]
+  ""
+  "
+{
+  if (CONSTANT_P (operands[2]))
+      operands[2] =  force_const_mem (HImode, operands[2]);
+}")
+
+(define_insn "do_andhi3"
+  [(set (match_operand:HI 0 "r_or_s_operand" "=d,Q")
+        (and:HI (match_operand:HI 1 "r_or_s_operand"  "%0,0")
+                (match_operand:HI 2 "r_or_s_operand"  "d,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d |= d */
+           return \"NR    %0,%2\";
+       case (1): /* m |= m */
+           return \"NC    %O0(2,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,SS")
+    (set_attr "type"     "logic")
+    (set_attr "cc"       "clobber,*")]
+)
+
+;
+; andqi3 instruction pattern(s).
+;
+
+(define_insn "andqi3"
+  [(set (match_operand:QI 0 "r_or_s_operand" "=d,Q,Q")
+        (and:QI (match_operand:QI 1 "r_or_s_operand"  "%0,0,0")
+                (match_operand:QI 2 "r_or_s_or_im8_operand" "d,n,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d |= d */
+           return \"NR    %0,%2\";
+       case (1): /* m |= i */
+           return \"NI    %0,%b2\";
+       case (2): /* m |= m */
+           return \"NC    %O0(1,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,SS,SS")
+    (set_attr "type"     "logic")
+    (set_attr "cc"       "clobber,*,*")]
+)
+
+
+;;
+;;- Bit set (inclusive or) instructions.
+;;
+
+;
+; iordi3 instruction pattern(s).
+;
+
+
+;
+; iorsi3 instruction pattern(s).
+;
+
+(define_expand "iorsi3"
+  [(set (match_operand:SI 0 "r_or_s_operand" "")
+        (ior:SI (match_operand:SI 1 "r_or_s_operand"  "")
+                (match_operand:SI 2 "r_or_s_operand"  "")))]
+  ""
+  "
+{
+  if (CONSTANT_P (operands[2]))
+      operands[2] =  force_const_mem (SImode, operands[2]);
+}")
+
+
+
+(define_insn "do_iorsi3"
+  [(set (match_operand:SI 0 "r_or_s_operand" "=d,d,Q")
+        (ior:SI (match_operand:SI 1 "r_or_s_operand"  "%0,0,0")
+                (match_operand:SI 2 "r_or_s_operand"  "d,m,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d |= d */
+           return \"OR    %0,%2\";
+       case (1): /* d |= m */
+           return \"O     %0,%2\";
+       case (2): /* m |= m */
+           return \"OC    %O0(4,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX,SS")
+    (set_attr "type"     "logic")]
+)
+
+
+;
+; iorhi3 instruction pattern(s).
+;
+
+(define_expand "iorhi3"
+  [(set (match_operand:HI 0 "r_or_s_operand" "")
+        (ior:HI (match_operand:HI 1 "r_or_s_operand"  "")
+                (match_operand:HI 2 "r_or_s_operand"  "")))]
+  ""
+  "
+{
+  if (CONSTANT_P (operands[2]))
+      operands[2] =  force_const_mem (HImode, operands[2]);
+}")
+
+
+(define_insn "do_iorhi3"
+  [(set (match_operand:HI 0 "r_or_s_operand" "=d,Q")
+        (ior:HI (match_operand:HI 1 "r_or_s_operand"  "%0,0")
+                (match_operand:HI 2 "r_or_s_operand"  "d,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d |= d */
+           return \"OR    %0,%2\";
+       case (1): /* m |= m */
+           return \"OC    %O0(2,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,SS")
+    (set_attr "type"     "logic")
+    (set_attr "cc"       "clobber,*")]
+)
+
+;
+; iorqi3 instruction pattern(s).
+;
+
+(define_insn "iorqi3"
+  [(set (match_operand:QI 0 "r_or_s_operand" "=d,Q,Q")
+        (ior:QI (match_operand:QI 1 "r_or_s_operand"  "%0,0,0")
+                (match_operand:QI 2 "r_or_s_or_im8_operand" "d,n,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d |= d */
+           return \"OR    %0,%2\";
+       case (1): /* m |= i */
+           return \"OI    %0,%b2\";
+       case (2): /* m |= m */
+           return \"OC    %O0(1,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,SS,SS")
+    (set_attr "type"     "logic")
+    (set_attr "cc"       "clobber,*,*")]
+)
+
+;;
+;;- Xor instructions.
+;;
+
+;
+; xordi3 instruction pattern(s).
+;
+
+
+;
+; xorsi3 instruction pattern(s).
+;
+
+(define_expand "xorsi3"
+  [(set (match_operand:SI 0 "r_or_s_operand" "")
+        (xor:SI (match_operand:SI 1 "r_or_s_operand"  "")
+                (match_operand:SI 2 "r_or_s_operand"  "")))]
+  ""
+  "
+{
+  if (CONSTANT_P (operands[2]))
+      operands[2] =  force_const_mem (SImode, operands[2]);
+}")
+
+
+
+(define_insn "do_xorsi3"
+  [(set (match_operand:SI 0 "r_or_s_operand" "=d,d,Q")
+        (xor:SI (match_operand:SI 1 "r_or_s_operand"  "%0,0,0")
+                (match_operand:SI 2 "r_or_s_operand"  "d,m,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d |= d */
+           return \"XR    %0,%2\";
+       case (1): /* d |= m */
+           return \"X     %0,%2\";
+       case (2): /* m |= m */
+           return \"XC    %O0(4,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,RX,SS")
+    (set_attr "type"     "logic")]
+)
+
+;
+; xorhi3 instruction pattern(s).
+;
+
+(define_expand "xorhi3"
+  [(set (match_operand:HI 0 "r_or_s_operand" "")
+        (xor:HI (match_operand:HI 1 "r_or_s_operand"  "")
+                (match_operand:HI 2 "r_or_s_operand"  "")))]
+  ""
+  "
+{
+  if (CONSTANT_P (operands[2]))
+      operands[2] =  force_const_mem (HImode, operands[2]);
+}")
+
+
+
+(define_insn "do_xorhi3"
+  [(set (match_operand:HI 0 "r_or_s_operand" "=d,Q")
+        (xor:HI (match_operand:HI 1 "r_or_s_operand"  "%0,0")
+                (match_operand:HI 2 "r_or_s_operand"  "d,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d |= d */
+           return \"XR    %0,%2\";
+       case (1): /* m |= m */
+           return \"XC    %O0(2,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,SS")
+    (set_attr "type"     "logic")
+    (set_attr "cc"       "clobber,*")]
+)
+
+;
+; xorqi3 instruction pattern(s).
+;
+
+(define_insn "xorqi3"
+  [(set (match_operand:QI 0 "r_or_s_operand" "=d,Q,Q")
+        (xor:QI (match_operand:QI 1 "r_or_s_operand"  "0,0,0")
+                (match_operand:QI 2 "r_or_s_or_im8_operand"   "d,n,Q")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d |= d */
+           return \"XR    %0,%2\";
+       case (1): /* m |= i */
+           return \"XI    %0,%b2\";
+       case (2): /* m |= m */
+           return \"XC    %O0(1,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,SS,SS")
+    (set_attr "type"     "logic")
+    (set_attr "cc"       "clobber,*,*")]
+)
+
+
+;;
+;;- Negate instructions.
+;;
+
+;
+; negsi2 instruction pattern(s).
+;
+
+(define_insn "negsi2"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (neg:SI (match_operand:SI 1 "register_operand"  "d")))]
+  ""
+  "*
+{
+   return \"LCR   %0,%1\";
+}"
+   [(set_attr "op_type"  "RR")
+    (set_attr "type"     "logic")]
+)
+
+;
+; negdf2 instruction pattern(s).
+;
+
+(define_insn "negdf2"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+        (neg:DF (match_operand:DF 1 "register_operand"  "f")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+  if (TARGET_IBM_FLOAT)
+    return \"LCDR  %0,%1\";
+  else
+    return \"LCDBR %0,%1\";
+}"
+   [(set_attr "op_type"  "RR")
+    (set_attr "type"     "logic")]
+)
+
+;
+; negsf2 instruction pattern(s).
+;
+
+(define_insn "negsf2"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+        (neg:SF (match_operand:SF 1 "register_operand"  "f")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+  if (TARGET_IBM_FLOAT)
+    return \"LCER  %0,%1\";
+  else
+    return \"LCEBR %0,%1\";
+}"
+   [(set_attr "op_type"  "RR")
+    (set_attr "type"     "logic")]
+)
+
+;;
+;;- Absolute value instructions.
+;;
+
+;
+; abssi2 instruction pattern(s).
+;
+
+(define_insn "abssi2"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (abs:SI (match_operand:SI 1 "register_operand" "d")))]
+  ""
+  "*
+{
+   return \"LPR   %0,%1\";
+}"
+   [(set_attr "op_type"  "RR")
+    (set_attr "type"     "logic")]
+)
+
+;
+; abshi2 instruction pattern(s).
+;
+
+(define_insn "abshi2"
+  [(set (match_operand:HI 0 "register_operand" "=d")
+        (abs:HI (match_operand:HI 1 "register_operand"  "d")))]
+  ""
+  "*
+{
+   return \"SLL   %1,16\;SRA   %1,16\;LPR   %0,%1\";
+}"
+   [(set_attr "op_type"  "RR")
+    (set_attr "type"     "logic")]
+)
+
+;
+; absdf2 instruction pattern(s).
+;
+
+(define_insn "absdf2"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+        (abs:DF (match_operand:DF 1 "register_operand"  "f")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+  if (TARGET_IBM_FLOAT)
+    return \"LPDR  %0,%1\";
+  else
+    return \"LPDBR %0,%1\";
+}"
+   [(set_attr "op_type"  "RR")
+    (set_attr "type"     "logic")]
+)
+
+;
+; abssf2 instruction pattern(s).
+;
+
+(define_insn "abssf2"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+        (abs:SF (match_operand:SF 1 "register_operand"  "f")))]
+  "TARGET_HARD_FLOAT"
+  "*
+{
+  if (TARGET_IBM_FLOAT)
+    return \"LPER  %0,%1\";
+  else
+    return \"LPEBR %0,%1\";
+}"
+   [(set_attr "op_type"  "RR")
+    (set_attr "type"     "logic")]
+)
+
+;;
+;;- One complement instructions.
+;;
+
+;
+; one_cmpldi2 instruction pattern(s).
+;
+
+
+;
+; one_cmplsi2 instruction pattern(s).
+;
+
+(define_expand "one_cmplsi2"
+  [(set (match_operand:SI 0 "r_or_s_operand" "=d")
+        (not:SI (match_operand:SI 1 "r_or_s_operand"  "0")))]
+  ""
+  "
+{
+   emit_insn (gen_do_one_cmplsi2 (operands[0], operands[1],
+             force_const_mem (SImode,constm1_rtx)));
+   DONE;
+}")
+
+
+(define_insn "do_one_cmplsi2"
+  [(set (match_operand:SI 0 "r_or_s_operand" "=d,Q")
+        (not:SI (match_operand:SI 1 "r_or_s_operand"  "0,0")))
+   (use (match_operand:SI 2 "memory_operand" "m,m"))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  d */
+           return \"X     %0,%2\";
+       case (1): /* m  m */
+           return \"XC    %O0(4,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RR,SS")
+    (set_attr "type"     "logic")]
+)
+
+;
+; one_cmplhi2 instruction pattern(s).
+;
+
+(define_expand "one_cmplhi2"
+  [(set (match_operand:HI 0 "r_or_s_operand" "=d")
+        (not:HI (match_operand:HI 1 "r_or_s_operand"  "0")))]
+  ""
+  "
+{
+   emit_insn (gen_do_one_cmplhi2 (operands[0], operands[1],
+             force_const_mem (SImode, constm1_rtx)));
+   DONE;
+}")
+
+
+(define_insn "do_one_cmplhi2"
+  [(set (match_operand:HI 0 "r_or_s_operand" "=d,Q")
+        (not:HI (match_operand:HI 1 "r_or_s_operand"  "0,0")))
+   (use (match_operand:SI 2 "memory_operand" "m,m"))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  d */
+           return \"X     %0,%2\";
+       case (1): /* m  m */
+           return \"XC    %O0(2,%R0),%2\";
+   }
+}"
+   [(set_attr "op_type"  "RX,SS")
+    (set_attr "type"     "logic")
+    (set_attr "cc"       "clobber,*")]
+)
+
+;
+; one_cmplqi2 instruction pattern(s).
+;
+
+(define_insn "one_cmpqi2"
+  [(set (match_operand:QI 0 "memory_operand" "=Q")
+        (not:QI (match_operand:QI 1 "memory_operand"  "0")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* m  m */
+           return \"XI    %0,255\";
+   }
+}"
+   [(set_attr "op_type"  "SI")
+    (set_attr "type"     "logic")]
+)
+
+
+;;
+;;- Arithmetic shift instructions.
+;;
+;;  for left shifts always logical shifts are used (ANSI-C)
+
+;
+; ashldi3 instruction pattern(s).
+;
+
+(define_insn "ashldi3"
+  [(set (match_operand:DI 0 "register_operand" "=d,d")
+        (ashift:DI (match_operand:DI 1 "register_operand"  "0,0")
+                   (match_operand:SI 2 "general_operand"   "J,a")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  J */
+           return \"SLDL  %0,%c2\";
+       case (1): /* d  a */
+           return \"SLDL  %0,0(%2)\";
+   }
+}"
+   [(set_attr "op_type"  "RS")
+    (set_attr "type"     "lshift")]
+)
+
+;
+; ashrdi3 instruction pattern(s).
+;
+
+(define_insn "ashrdi3"
+  [(set (match_operand:DI 0 "register_operand" "=d,d")
+        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
+                     (match_operand:SI 2 "r_or_im8_operand"  "J,a")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  J */
+           return \"SRDA  %0,%c2\";
+       case (1): /* d  a */
+           return \"SRDA  %0,0(%2)\";
+   }
+}"
+   [(set_attr "op_type"  "RS")
+    (set_attr "type"     "ashift")]
+)
+
+;
+; ashlsi3 instruction pattern(s).
+;
+; all 32 bits has to be shifted (testcase co750c)
+
+(define_insn "ashlsi3"
+  [(set (match_operand:SI 0 "register_operand" "=d,d")
+        (ashift:SI (match_operand:SI 1 "register_operand"  "0,0")
+                   (match_operand:SI 2 "r_or_im8_operand"   "J,a")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  J */
+           return \"SLL   %0,%c2\";
+       case (1): /* d  a */
+           return \"SLL   %0,0(%2)\";
+   }
+}"
+   [(set_attr "op_type"  "RS")
+    (set_attr "type"     "lshift")]
+)
+
+;
+; ashrsi3 instruction pattern(s).
+;
+
+(define_insn "ashrsi3"
+  [(set (match_operand:SI 0 "register_operand" "=d,d")
+        (ashiftrt:SI (match_operand:SI 1 "register_operand"  "0,0")
+                     (match_operand:SI 2 "r_or_im8_operand"   "J,a")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  J */
+           return \"SRA   %0,%c2\";
+       case (1): /* d  a */
+           return \"SRA   %0,0(%2)\";
+   }
+}"
+   [(set_attr "op_type"  "RS")
+    (set_attr "type"     "ashift")]
+)
+
+;
+; ashlhi3 instruction pattern(s).
+;
+
+(define_insn "ashlhi3"
+  [(set (match_operand:HI 0 "register_operand" "=d,d")
+        (ashift:HI (match_operand:HI 1 "register_operand"  "0,0")
+                   (match_operand:SI 2 "r_or_im8_operand"   "J,a")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  J */
+               return \"SLL   %0,%c2\";
+       case (1): /* d  a */
+               return \"SLL   %0,0(%2)\";
+   }
+}"
+   [(set_attr "op_type"  "RS,RS")
+    (set_attr "type"     "lshift")]
+)
+
+;
+; ashrhi3 instruction pattern(s).
+;
+
+(define_insn "ashrhi3"
+  [(set (match_operand:HI 0 "register_operand" "=d,d")
+        (ashiftrt:HI (match_operand:HI 1 "register_operand"  "0,0")
+                     (match_operand:SI 2 "r_or_im8_operand"   "J,a")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  J */
+           return \"SLL   %0,16\;SRA   %0,16+%c2\";
+       case (1): /* d  a */
+           return \"SLL   %0,16\;SRA   %0,16(%2)\";
+   }
+}"
+   [(set_attr "op_type"  "NN,NN")
+    (set_attr "type"     "ashift")
+    (set_attr "length"   "8,8")]
+)
+
+;;
+;;- Logical shift instructions.
+;;
+
+;
+; lshrdi3 instruction pattern(s).
+;
+
+(define_insn "lshrdi3"
+  [(set (match_operand:DI 0 "register_operand" "=d,d")
+        (lshiftrt:DI (match_operand:DI 1 "register_operand"  "0,0")
+                     (match_operand:SI 2 "r_or_im8_operand"   "J,a")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  J */
+           return \"SRDL  %0,%c2\";
+       case (1): /* d  a */
+           return \"SRDL  %0,0(%2)\";
+   }
+}"
+   [(set_attr "op_type"  "RS,RS")
+    (set_attr "type"     "lshift")]
+)
+
+
+;
+; lshrsi3 instruction pattern(s).
+;
+
+(define_insn "lshrsi3"
+  [(set (match_operand:SI 0 "register_operand" "=d,d")
+        (lshiftrt:SI (match_operand:SI 1 "register_operand"  "0,0")
+                     (match_operand:SI 2 "r_or_im8_operand"   "J,a")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  J */
+           return \"SRL   %0,%c2\";
+       case (1): /* d  a */
+           return \"SRL   %0,0(%2)\";
+   }
+}"
+   [(set_attr "op_type"  "RS")
+    (set_attr "type"     "lshift")]
+)
+
+;
+; lshrhi3 instruction pattern(s).
+;
+
+(define_insn "lshrhi3"
+  [(set (match_operand:HI 0 "register_operand" "=d,d")
+        (lshiftrt:HI (match_operand:HI 1 "register_operand"  "0,0")
+                     (match_operand:SI 2 "r_or_im8_operand"   "J,a")))]
+  ""
+  "*
+{
+   switch (which_alternative)
+   {
+       case (0): /* d  J */
+           return \"SLL   %0,16\;SRL   %0,16+%c2\";
+       case (1): /* d  a */
+           return \"SLL   %0,16\;SRL   %0,16(%2)\";
+   }
+}"
+   [(set_attr "op_type"  "NN,NN")
+    (set_attr "type"     "lshift")
+    (set_attr "length"   "8,8")]
+)
+
+
+;;
+;;- Conditional jump instructions.
+;;
+
+(define_insn "cjump"
+ [(set (pc)
+       (if_then_else
+       (match_operator 1 "comparison_operator" 
+        [(cc0) (const_int 0)])
+	       (label_ref (match_operand 0 "" ""))
+	       (pc)))]
+  ""
+  "J%C1   %l0"
+   [(set_attr "op_type" "RI")
+    (set_attr "type"    "branch")]
+)
+
+(define_insn "cjump_long"
+ [(set (pc)
+       (if_then_else
+       (match_operator 1 "comparison_operator" 
+        [(cc0) (const_int 0)])
+	       (match_operand 0 "memory_operand" "m")
+	       (pc)))]
+  ""
+  "B%C1   %0"
+   [(set_attr "op_type" "RX")
+    (set_attr "type"    "branch")]
+)
+
+
+;
+; beq instruction pattern(s).
+;
+
+(define_expand "beq"
+  [(set (pc)
+        (if_then_else (eq (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  ""
+  "" )
+
+;
+; bne instruction pattern(s).
+;
+
+(define_expand "bne"
+  [(set (pc)
+        (if_then_else (ne (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  ""
+  "")
+
+;
+; bgt instruction pattern(s).
+;
+(define_expand "bgt"
+  [(set (pc)
+        (if_then_else (gt (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  ""
+  "")
+
+;
+; bgtu instruction pattern(s).
+;
+
+(define_expand "bgtu"
+  [(set (pc)
+        (if_then_else (gtu (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  ""
+  "")
+
+;
+; blt instruction pattern(s).
+;
+
+(define_expand "blt"
+  [(set (pc)
+        (if_then_else (lt (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  ""
+  "")
+
+;
+; bltu instruction pattern(s).
+;
+
+(define_expand "bltu"
+  [(set (pc)
+        (if_then_else (ltu (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  ""
+  "")
+
+;
+; bge instruction pattern(s).
+;
+
+(define_expand "bge"
+  [(set (pc)
+        (if_then_else (ge (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  ""
+  "")
+;
+; bgeu instruction pattern(s).
+;
+
+(define_expand "bgeu"
+  [(set (pc)
+        (if_then_else (geu (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  ""
+  "")
+
+;
+; ble instruction pattern(s).
+;
+
+(define_expand "ble"
+  [(set (pc)
+        (if_then_else (le (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  ""
+  "")
+
+;
+; bleu instruction pattern(s).
+;
+
+(define_insn "bleu"
+  [(set (pc)
+        (if_then_else (leu (cc0)
+                          (const_int 0))
+                      (label_ref (match_operand 0 "" ""))
+                      (pc)))]
+  ""
+  "")
+
+;;
+;;- Negated conditional jump instructions.
+;;
+
+(define_insn "icjump"
+ [(set (pc)
+       (if_then_else
+       (match_operator 1 "comparison_operator" 
+        [(cc0) (const_int 0)])
+               (pc) 
+	       (label_ref (match_operand 0 "" ""))))]
+  ""
+  "J%D1   %l0"
+   [(set_attr "op_type" "RI")
+    (set_attr "type"    "branch")]
+)
+
+(define_insn "icjump_long"
+ [(set (pc)
+       (if_then_else
+       (match_operator 1 "comparison_operator" 
+        [(cc0) (const_int 0)])
+	       (pc)
+	       (match_operand 0 "memory_operand" "m")))]
+  ""
+  "B%D1   %0"
+   [(set_attr "op_type" "RX")
+    (set_attr "type"    "branch")]
+)
+
+;;
+;;- Subtract one and jump if not zero.
+;;
+
+(define_insn ""
+  [(set (pc)
+     (if_then_else
+         (ne (plus:SI (match_operand:SI 0 "register_operand" "+a")
+             (const_int -1))
+         (const_int 0))
+    (label_ref (match_operand 1 "" ""))
+    (pc)))
+   (set (match_dup 0)
+   (plus:SI (match_dup 0)
+            (const_int -1)))]
+  ""
+  "*
+{
+  return \"BRCT  %0,%l1\";
+}"
+   [(set_attr "op_type" "RI")
+    (set_attr "type"    "branch")]
+)
+
+(define_insn ""
+  [(set (pc)
+        (if_then_else
+        (eq (plus:SI (match_operand:SI 0 "register_operand" "+a")
+            (const_int -1))
+        (const_int 0))
+        (pc)
+        (label_ref (match_operand 1 "" ""))))
+   (set (match_dup 0)
+        (plus:SI (match_dup 0)
+                 (const_int -1)))]
+  ""
+  "*
+{
+  return \"BRCT  %0,%l1\";
+}"
+   [(set_attr "op_type" "RI")
+    (set_attr "type"    "branch")]
+)
+
+
+;;
+;;- Unconditional jump instructions.
+;;
+
+;
+; jump instruction pattern(s).
+;
+
+(define_insn "jump"
+  [(set (pc)
+        (label_ref (match_operand 0 "" "")))]
+  ""
+  "*
+{
+  return \"J     %l0\";
+}"
+   [(set_attr "op_type" "RI")
+    (set_attr "type"    "branch")]
+)
+
+
+;
+; indirect-jump instruction pattern(s).
+;
+; only relative jumps allowed, need change here
+
+(define_insn "indirect_jump"
+  [(set (pc) (match_operand:SI 0 "register_operand" "a"))]
+  ""
+  "*
+{
+  return \"BR    %0\";
+}"
+   [(set_attr "op_type" "RX")
+    (set_attr "type"    "branch")]
+)
+
+;
+; issues from s390 backend far jump implementation
+;
+
+(define_insn "jump_long"
+  [(set (pc)
+        (match_operand 0 "memory_operand" "m"))
+	(use (reg:SI 13))]
+  ""
+  "*
+{
+     return \"B     %0\";
+}"
+   [(set_attr "op_type" "RX")
+    (set_attr "type"    "branch")]
+)
+
+
+;
+; tablejump instruction pattern(s).
+;
+
+
+;; Table jump for switch statements:
+(define_insn "tablejump"
+  [(set (pc)
+        (match_operand:SI 0 "register_operand" "a"))
+   (use (label_ref (match_operand 1 "" "")))]
+  ""
+  "*
+{
+  if (flag_pic)
+    return \"AR    %0,13\;BR    %0\";
+  else
+    return \"BR    %0\";
+}"
+)
+
+;;
+;;- Jump to subroutine.
+;;
+;;
+
+
+;
+; untyped call instruction pattern(s).
+;
+
+;; Call subroutine returning any type.
+(define_expand "untyped_call"
+  [(parallel [(call (match_operand 0 "" "")
+                    (const_int 0))
+              (match_operand 1 "" "")
+              (match_operand 2 "" "")])]
+  ""
+  "
+{
+      emit_call_insn (gen_call_value (gen_rtx (REG, SImode, 2),
+                                      operands[0],
+                                      const0_rtx, NULL_RTX));
+
+      emit_move_insn (change_address (operands[1], SImode,
+                                      XEXP (operands[1], 0)),
+                      gen_rtx (REG, SImode, 2));
+
+  emit_insn (gen_blockage ());
+
+  DONE;
+}")
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
+;; all of memory.  This blocks insns from being moved across this point.
+
+(define_insn "blockage"
+  [(unspec_volatile [(const_int 0)] 0)]
+  ""
+  "")
+;
+;call instruction pattern(s).
+;
+
+(define_insn "bras"
+  [(call (mem:QI (match_operand:SI 0 "bras_sym_operand" ""))
+         (match_operand:SI 1 "const_int_operand" "n"))]
+  "TARGET_SMALL_EXEC"
+  "*
+{
+    operands[1] = gen_rtx (REG, SImode, RETURN_REGNUM);
+    return \"BRAS %1,%s0\";
+}"
+   [(set_attr "op_type" "RI")
+    (set_attr "type"    "jsr")]
+)
+
+(define_insn "basr"
+  [(call (mem:QI (match_operand:SI 0 "register_operand" "a"))
+         (match_operand:SI 1 "const_int_operand" "n"))
+         (use (reg:SI 12))
+	 (clobber (reg:SI 14))]
+  ""
+  "*
+{
+    operands[1] = gen_rtx (REG, SImode, RETURN_REGNUM);
+
+    return \"BASR  %1,%0\";
+}"
+   [(set_attr "op_type" "RR")
+    (set_attr "type"    "jsr")]
+)
+
+(define_insn "bas"
+  [(parallel [(call (mem:QI (match_operand:SI 0 "register_operand" "a"))
+         (match_operand:SI 1 "const_int_operand" "n"))
+	 (match_operand:SI 2 "register_operand" "a") 
+         (use (reg:SI 12))
+         (use (reg:SI 13)) 
+	 (clobber (reg:SI 14)) ])]
+  ""
+  "*
+{
+  operands[1] = gen_rtx (REG, SImode, RETURN_REGNUM);
+  operands[2] = gen_rtx (REG, SImode, BASE_REGISTER);
+  return \"BAS   %1,0(%0,%2)\";
+}"
+   [(set_attr "op_type" "RX")
+    (set_attr "type"    "jsr")]
+)
+
+(define_expand "call"
+[(parallel [(call (match_operand:SI 0 "memory_operand" "m")
+            (match_operand 1 "" ""))
+       (use (match_operand 2 "" ""))])]
+    ""
+    "
+{
+  rtx sym;
+  rtx target=gen_reg_rtx (SImode);
+
+  if (flag_pic)
+    current_function_uses_pic_offset_table = 1;
+  if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) {
+    if (TARGET_SMALL_EXEC) {
+      emit_call_insn (gen_bras (XEXP (operands[0], 0), operands[1]));
+    } else {
+    sym = gen_rtx (SYMBOL_REF, SImode, XSTR (XEXP (operands[0], 0), 0)-1);
+    
+    if (flag_pic) 
+      {
+	emit_insn (gen_movsi_loc (target,sym));
+      }
+    else
+      {
+	XEXP (operands[0], 0) = force_const_mem (SImode,sym);
+	emit_insn (gen_movsi (target,
+			     XEXP (operands[0], 0)));
+      }
+    emit_call_insn (gen_basr (target, operands[1]));
+    }
+  } else {                                         /* function pointer call*/
+    emit_call_insn (gen_basr (XEXP (operands[0], 0), operands[1]));
+  }
+  DONE;
+}")
+
+
+;
+; call_value instruction pattern(s).
+;
+
+(define_insn "bras_r"
+  [(set (match_operand 0 "register_operand" "=df")
+        (call (mem:QI (match_operand:SI 1 "bras_sym_operand" ""))
+              (match_operand:SI 2 "const_int_operand" "n")))]
+  "TARGET_SMALL_EXEC"
+  "*
+{
+    operands[0] = gen_rtx (REG, SImode, RETURN_REGNUM);
+    return \"BRAS %0,%s1\";
+}"
+   [(set_attr "op_type" "RI")
+    (set_attr "type"    "jsr")]
+)
+
+(define_insn "basr_r"
+  [(set  (match_operand 0 "register_operand" "=df")
+         (call (mem:QI (match_operand:SI 1 "register_operand" "a"))
+               (match_operand:SI 2 "const_int_operand" "n")))
+         (use (reg:SI 12))
+	 (clobber (reg:SI 14))]
+  ""
+  "*
+{
+    operands[0] = gen_rtx (REG, SImode, RETURN_REGNUM);
+    return \"BASR  %0,%1\";
+}"
+   [(set_attr "op_type" "RR")
+    (set_attr "type"    "jsr")]
+)
+
+
+(define_insn "bas_r"
+  [(parallel [(set  (match_operand 0 "register_operand" "=df")
+   (call (mem:QI (match_operand:SI 1 "register_operand" "a"))
+         (match_operand:SI 2 "const_int_operand" "n")))
+         (use (reg:SI 12))
+         (use (reg:SI 13))  
+	 (clobber (reg:SI 14))])]
+  ""
+  "*
+{
+  operands[0] = gen_rtx (REG, SImode, RETURN_REGNUM);
+  operands[2] = gen_rtx (REG, SImode, BASE_REGISTER);
+
+  return \"BAS   %0,0(%1,%2)\";
+}"
+   [(set_attr "op_type" "RX")
+    (set_attr "type"    "jsr")]
+)
+
+(define_expand "call_value"
+  [(parallel [(set (match_operand 0 "" "")
+           (call (match_operand:SI 1 "memory_operand" "")
+             (match_operand 2 "immediate_operand" "")))
+        (use (match_operand 3 "" ""))])]
+    ""
+    "
+{
+  rtx sym;
+  rtx target=gen_reg_rtx (SImode);
+
+  if (flag_pic)
+    current_function_uses_pic_offset_table = 1;
+  if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) {
+    if (TARGET_SMALL_EXEC) {
+      emit_call_insn (gen_bras_r (operands[0], XEXP (operands[1], 0), operands[2]));
+    } else {
+    sym = gen_rtx (SYMBOL_REF, SImode,XSTR (XEXP (operands[1], 0), 0)-1);
+    if (flag_pic) 
+      {
+	emit_insn (gen_movsi_loc (target, sym));
+      }
+    else
+      {
+	XEXP (operands[1], 0) = force_const_mem (SImode, sym);
+	emit_insn (gen_movsi (target,
+			      XEXP (operands[1], 0)));
+      }
+    emit_call_insn (gen_basr_r (operands[0],
+		    target,
+		    operands[2]));
+    }
+  } else {                                         /* function pointer call*/
+    emit_call_insn (gen_basr_r (operands[0], 
+                    XEXP (operands[1], 0), operands[2]));
+  }
+  DONE;
+}")
+
+;;
+;;- Miscellaneous instructions.
+;;
+
+;
+; allocate stack instruction pattern(s).
+;
+
+(define_expand "allocate_stack"
+  [(set (reg:SI 15)
+        (plus:SI (reg:SI 15) (match_operand:SI 1 "general_operand" "")))
+   (set (match_operand:SI 0 "general_operand" "")
+        (reg:SI 15))]
+ ""
+ "
+{
+    rtx temp = gen_reg_rtx (Pmode);
+	
+    emit_move_insn (temp,
+                    gen_rtx (MEM, SImode,
+                       gen_rtx (PLUS, SImode,
+                           gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                           const0_rtx)));
+    emit_insn (gen_addsi3 (gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                         gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                         negate_rtx (SImode, operands[1])));
+    emit_insn (gen_rtx (SET, SImode,
+                    gen_rtx (MEM, SImode,
+                       gen_rtx (PLUS, SImode,
+                           gen_rtx (REG, SImode, STACK_POINTER_REGNUM),
+                           const0_rtx)), temp));
+    emit_move_insn (operands[0], virtual_stack_dynamic_rtx);	
+    DONE;
+}")
+
+(define_expand "builtin_setjmp_setup"
+  [(unspec [(match_operand 0 "register_operand" "a")] 1)]
+  ""
+  "
+{
+  emit_insn (gen_do_builtin_setjmp_setup (operands[0]));
+  DONE;
+}")
+
+(define_expand "builtin_setjmp_receiver"
+  [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
+  ""
+  "
+{
+  emit_insn (gen_blockage ());
+  DONE;
+}")
+
+
+
+(define_expand "do_builtin_setjmp_setup"
+  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "a")
+		   (const_int 12)))
+      (reg:SI 12))
+   (set (mem:SI (plus:SI (match_dup 0)
+		   (const_int 16)))
+      (reg:SI 13)) ]
+  ""
+  "")
+
+(define_expand "builtin_longjmp"
+  [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
+  ""
+  "
+{
+  /* The elements of the buffer are, in order:  */
+  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
+  rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4));
+  rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
+  rtx gotv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 12));
+  rtx basev = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
+  rtx base = gen_rtx_REG (Pmode, 13);
+  rtx got = gen_rtx_REG (Pmode, 12);
+  rtx jmp = gen_rtx_REG (Pmode, 14);
+
+  emit_move_insn (jmp, lab);
+  emit_move_insn (got, gotv);
+  emit_move_insn (base, basev);
+  emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
+  emit_move_insn (hard_frame_pointer_rtx, fp);
+
+  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
+  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+  emit_insn (gen_rtx_USE (VOIDmode, got));
+  emit_insn (gen_rtx_USE (VOIDmode, base));
+  emit_indirect_jump (jmp);
+  DONE;
+}")
+
+
+;; These patterns say how to save and restore the stack pointer.  We need not
+;; save the stack pointer at function level since we are careful to
+;; preserve the backchain.  At block level, we have to restore the backchain
+;; when we restore the stack pointer.
+;;
+;; For nonlocal gotos, we must save both the stack pointer and its
+;; backchain and restore both.  Note that in the nonlocal case, the
+;; save area is a memory location.
+
+(define_expand "save_stack_function"
+  [(match_operand 0 "general_operand" "")
+   (match_operand 1 "general_operand" "")]
+  ""
+  "DONE;")
+
+(define_expand "restore_stack_function"
+  [(match_operand 0 "general_operand" "")
+   (match_operand 1 "general_operand" "")]
+  ""
+  "DONE;")
+
+(define_expand "restore_stack_block"
+  [(use (match_operand 0 "register_operand" ""))
+   (set (match_dup 2) (match_dup 3))
+   (set (match_dup 0) (match_operand 1 "register_operand" ""))
+   (set (match_dup 3) (match_dup 2))]
+  ""
+  "
+{
+  operands[2] = gen_reg_rtx (Pmode);
+  operands[3] = gen_rtx_MEM (Pmode, operands[0]);
+}")
+
+(define_expand "save_stack_nonlocal"
+  [(match_operand 0 "memory_operand" "")
+   (match_operand 1 "register_operand" "")]
+  ""
+  "
+{
+  rtx temp = gen_reg_rtx (Pmode);
+
+  /* Copy the backchain to the first word, sp to the second.  */
+  emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
+  emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
+		  temp);
+  emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
+		  operands[1]);
+  DONE;
+}")
+
+(define_expand "restore_stack_nonlocal"
+  [(match_operand 0 "register_operand" "")
+   (match_operand 1 "memory_operand" "")]
+  ""
+  "
+{
+  rtx temp = gen_reg_rtx (Pmode);
+
+  /* Restore the backchain from the first word, sp from the second.  */
+  emit_move_insn (temp,
+		  operand_subword (operands[1], 0, 0, DImode));
+  emit_move_insn (operands[0],
+		  operand_subword (operands[1], 1, 0, DImode));
+  emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
+  DONE;
+}")
+
+
+
+(define_expand "eh_epilogue"
+  [(use (match_operand:SI 0 "register_operand" ""))
+   (use (match_operand:SI 1 "register_operand" ""))
+   (use (match_operand:SI 2 "register_operand" ""))]
+ ""
+ "
+{
+  s390_expand_eh_epilogue (operands[0], operands[1], operands[2]);
+  DONE;
+}")
+
+;
+; nop instruction pattern(s).
+;
+
+(define_insn "nop"
+  [(const_int 0)]
+  ""
+  "*
+{
+  return \"LR    0,0\";
+}"
+   [(set_attr "op_type" "RR")
+    (set_attr "type"    "nop")]
+)
+
+
+(define_insn "reload_base"
+   [(parallel [(set (reg:SI 13)
+                    (pc))
+               (use (label_ref (match_operand 0 "" "")))])]
+""
+"*
+{
+   output_asm_insn (\"BASR  13,0\", operands);
+   return \"AHI   13,%Y0\";			
+}"
+     [(set_attr "op_type" "NN")
+      (set_attr "length"  "8")]
+)
+
+(define_insn "ltorg"
+    [(parallel [(set (reg:SI 13)
+                     (pc))
+               (use (match_operand:SI 0 "general_operand" ""))])]
+""
+"*
+{
+   s390_dump_literal_pool (insn, operands[0]);
+   return \"0:\";
+}"
+     [(set_attr "op_type" "NN")
+      (set_attr "length"  "12")]
+)
+
+; L   rx,c(ry) && LTR rx,rx  => ICM rx,15,c(ry)
+(define_peephole
+  [(set (match_operand:SI 0 "register_operand" "d")
+        (match_operand:SI 1 "s_operand"        "Q"))
+   (set (cc0)
+        (match_dup 0))]
+ "! flag_pic"
+ "*
+ {
+    return \"ICM   %0,15,%1\";
+ }
+ ")
+
+; IC  rx,c(ry) && LTR rx,rx  => ICM rx,1,c(ry)
+(define_peephole
+  [(set                 (match_operand:SI 0 "register_operand" "d")
+        (zero_extend:SI (match_operand:QI 1 "general_operand"  "m")))
+   (set (cc0)
+        (match_dup 0))]
+ ""
+ "*
+ {
+    return \"SR  %0,%0; ICM    %0,1,%1\";
+ }
+ ")
+
+; LR rx,ry && LTR rx,rx => LTR rx,ry
+(define_peephole
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (match_operand:SI 1 "register_operand"  "d"))
+   (set (cc0)
+        (match_operand:SI 2 "register_operand" "d"))]
+ "(REGNO (operands[0]) == REGNO (operands[2]))"
+ "*
+ {
+    return \"LTR   %0,%1\";
+ }
+ ")
+
+(define_peephole
+  [(set (match_operand:SI 0 "register_operand" "")
+        (match_operand:SI 1 "register_operand"  ""))
+   (set (match_dup 0)
+        (plus:SI (match_dup 0)
+                 (match_operand:SI 2 "immediate_operand" "") ) )]
+ "(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"
+ "*
+ {
+    return \"LA    %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) ) )]
+ ""
+ "*
+ {
+    return \"ICM   %0,8,%1\;SRL   %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) ) )]
+ ""
+ "*
+ {
+    return \"ICM   %0,8,%1\;SRA   %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) ) )]
+ ""
+ "*
+ {
+    return \"LHI   %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) ) )]
+ ""
+ "*
+ {
+    return \"ICM   %0,12,%1\;SRL   %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) ) )]
+ ""
+ "*
+ {
+    return \"LH    %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) ) )]
+ ""
+ "*
+ {
+    return \"LHI   %0,%h1\";
+ }
+")
+
+(define_peephole
+  [(set (match_operand:SI 0 "memory_operand"   "m")
+        (match_operand:SI 1 "register_operand" "d"))
+   (set (match_dup 1)
+        (match_dup 0) )]
+ ""
+ "*
+ {
+    return \"ST    %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) )]
+ ""
+ "*
+ {
+    return \"ST    %1,%0\";
+ }
+")
+
+(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     %0,%1\", operands);
+    output_asm_insn (\"SRDL  %0,%b2\", operands);
+    if (REG_P (operands[3]))
+    {
+        output_asm_insn (\"DR    %0,%3\", operands);
+    }
+    else
+    {
+        output_asm_insn (\"D     %0,%3\", operands);
+    }
+    return \"ST    %N0,%N1\";
+ }
+")
+
+
+
+(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))]
+ ""
+ "*
+ {
+    output_asm_insn (\"L     %0,%1\", operands);
+    output_asm_insn (\"SRDL  %0,%b2\", operands);
+    if (REG_P (operands[3]))
+    {
+        output_asm_insn (\"DR    %0,%3\", operands);
+    }
+    else
+    {
+        output_asm_insn (\"D     %0,%3\", operands);
+    }
+    return \"ST    %0,%1\";
+ }
+")
diff -r -u --new-file egcs-20001002/gcc/config/s390/t-linux egcs-20001002-s390/gcc/config/s390/t-linux
--- egcs-20001002/gcc/config/s390/t-linux	Thu Jan  1 01:00:00 1970
+++ egcs-20001002-s390/gcc/config/s390/t-linux	Fri Oct  6 12:53:33 2000
@@ -0,0 +1,10 @@
+# The crtbegin and crtend must not depend on a small GOT
+CRTSTUFF_T_CFLAGS = -O2 -fPIC
+
+linux.o: $(srcdir)/config/s390/linux.c $(CONFIG_H) 
+	$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/s390/linux.c
+
+# Compile libgcc2.a with pic.
+TARGET_LIBGCC2_CFLAGS = -fPIC 
+
+
diff -r -u --new-file egcs-20001002/gcc/config/s390/xm-s390.h egcs-20001002-s390/gcc/config/s390/xm-s390.h
--- egcs-20001002/gcc/config/s390/xm-s390.h	Thu Jan  1 01:00:00 1970
+++ egcs-20001002-s390/gcc/config/s390/xm-s390.h	Fri Oct  6 12:53:33 2000
@@ -0,0 +1,49 @@
+/* Configuration for GNU C-compiler for S/390
+   Copyright (C) 1999 Free Software Foundation, Inc.
+   Contributed by Hartmut Penner (hpenner@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)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* #defines that need visibility everywhere.  */
+
+#define FALSE 0
+#define TRUE 1
+
+/* This describes the machine the compiler is hosted on.  */
+
+#define HOST_BITS_PER_CHAR      8
+#define HOST_BITS_PER_SHORT     16
+#define HOST_BITS_PER_INT       32
+#define HOST_BITS_PER_LONG      32
+#define HOST_BITS_PER_LONG_LONG 64
+#define HOST_FLOAT_FORMAT       IEEE_FLOAT_FORMAT
+#define HOST_WORDS_BIG_ENDIAN
+
+/* Target machine dependencies.  tm.h is a symbolic link to the actual
+   target specific file.  */
+
+#include "tm.h"
+
+/* Arguments to use with `exit'.  */
+
+#define SUCCESS_EXIT_CODE       0
+#define FATAL_EXIT_CODE         12
+
+
+
+
    


More information about the Gcc-patches mailing list