s390.c (legitmate_constant_p): Use LARL on zSeries machines even in 31-bit addressing...
authorUlrich Weigand <uweigand@de.ibm.com>
Thu, 28 Aug 2003 12:28:40 +0000 (12:28 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Thu, 28 Aug 2003 12:28:40 +0000 (12:28 +0000)
* config/s390/s390.c (legitmate_constant_p): Use LARL on
zSeries machines even in 31-bit addressing mode.
(legitimate_reload_constant_p): Likewise.
(legitimize_pic_address): Likewise.
(legitimize_tls_address): Likewise.
(s390_split_branches): Likewise.
(s390_dump_pool): Likewise.
(s390_mainpool_finish): Likewise.
(s390_chunkify_start): Likewise.
(s390_select_rtx_section): Likewise.
* config/s390/s390.md ("doloop_si"): Likewise.
("pool_start_31", "pool_end_31"): Likewise.
("pool_start_64", "pool_end_64"): Likewise.
("main_base_31_small", "main_base_31_large"): Likewise.
("main_base_64"): Likewise.
("reload_base_31", "reload_base_64"): Likewise.
("*movsi_larl"): New insn.
("cjump", "icjump"): Use long branches on zSeries machines.
("jump"): Likewise.
("call"): Use BRASL on zSeries machines.
("call_value", "call_value_tls"): Likewise.
("brasl", "bras", "basr_64", "basr_31", "bas_64", "bas_31"): Remove
and replace by ...
("*bras", "*brasl", "*basr") ... these new insns.
("brasl_r", "bras_r", "basr_64_r", "basr_31_r", "bas_64_r",
"bas_31_r"): Remove and replace by ...
("*bras_r", "*brasl_r", "*basr_r") ... these new insns.
("brasl_tls", "bras_tls", "basr_64_tls", "basr_31_tls",
"bas_64_tls", "bas_31_tls"): Remove and replace by ...
("*bras_tls", "*brasl_tls", "*basr_tls") ... these new insns.
("*return_si", "*return_di"): Remove and replace by ...
("*return"): ... this new insn.
("rotlsi3"): Allow on zSeries machines.

* config/s390/s390.c (legitimize_reload_constant_p): Use
LL/LH type instructions in z/Architecture mode.
* config/s390/s390.md ("*movsi_lli"): Likewise.
("*andsi3_ni", "*andhi3_ni", "*andqi3_ni"): Likewise.
("*iorsi3_ni", "*iorhi3_ni", "*iorqi3_ni"): Likewise.
("*extendqisi2"): Use LB in z/Architecture mode.
("*zero_extendqisi2_64", "*zero_extendqisi2_31"): Use LLGC in
z/Architecture mode.
("zero_extendqihi2", "*zero_extendqihi2_64", "*zero_extendqihi2_31"):
Likewise.

* config/s390/s390.md ("*tmdi_ext"): Allow in both 64-bit
and 31-bit mode.
("ptr_extend"): Allow only in 64-bit mode.

From-SVN: r70882

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/config/s390/s390.md

index 947582e..1ba1a21 100644 (file)
@@ -1,3 +1,54 @@
+2003-08-28  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * config/s390/s390.c (legitmate_constant_p): Use LARL on
+       zSeries machines even in 31-bit addressing mode.
+       (legitimate_reload_constant_p): Likewise.
+       (legitimize_pic_address): Likewise.
+       (legitimize_tls_address): Likewise.
+       (s390_split_branches): Likewise.
+       (s390_dump_pool): Likewise.
+       (s390_mainpool_finish): Likewise.
+       (s390_chunkify_start): Likewise.
+       (s390_select_rtx_section): Likewise.
+       * config/s390/s390.md ("doloop_si"): Likewise.
+       ("pool_start_31", "pool_end_31"): Likewise.
+       ("pool_start_64", "pool_end_64"): Likewise.
+       ("main_base_31_small", "main_base_31_large"): Likewise.
+       ("main_base_64"): Likewise.
+       ("reload_base_31", "reload_base_64"): Likewise.
+       ("*movsi_larl"): New insn.
+       ("cjump", "icjump"): Use long branches on zSeries machines.
+       ("jump"): Likewise.
+       ("call"): Use BRASL on zSeries machines.
+       ("call_value", "call_value_tls"): Likewise.
+       ("brasl", "bras", "basr_64", "basr_31", "bas_64", "bas_31"): Remove 
+       and replace by ...
+       ("*bras", "*brasl", "*basr") ... these new insns.
+       ("brasl_r", "bras_r", "basr_64_r", "basr_31_r", "bas_64_r", 
+       "bas_31_r"): Remove and replace by ...
+       ("*bras_r", "*brasl_r", "*basr_r") ... these new insns.
+       ("brasl_tls", "bras_tls", "basr_64_tls", "basr_31_tls", 
+       "bas_64_tls", "bas_31_tls"): Remove and replace by ...
+       ("*bras_tls", "*brasl_tls", "*basr_tls") ... these new insns.
+       ("*return_si", "*return_di"): Remove and replace by ...
+       ("*return"): ... this new insn.
+       ("rotlsi3"): Allow on zSeries machines.
+
+       * config/s390/s390.c (legitimize_reload_constant_p): Use
+       LL/LH type instructions in z/Architecture mode.
+       * config/s390/s390.md ("*movsi_lli"): Likewise.
+       ("*andsi3_ni", "*andhi3_ni", "*andqi3_ni"): Likewise.
+       ("*iorsi3_ni", "*iorhi3_ni", "*iorqi3_ni"): Likewise.
+       ("*extendqisi2"): Use LB in z/Architecture mode.
+       ("*zero_extendqisi2_64", "*zero_extendqisi2_31"): Use LLGC in 
+       z/Architecture mode.
+       ("zero_extendqihi2", "*zero_extendqihi2_64", "*zero_extendqihi2_31"): 
+       Likewise.
+       
+       * config/s390/s390.md ("*tmdi_ext"): Allow in both 64-bit
+       and 31-bit mode.
+       ("ptr_extend"): Allow only in 64-bit mode.
+
 2003-08-27  Daniel Jacobowitz  <drow@mvista.com>
 
        * gcc.c (STANDARD_EXEC_PREFIX, STANDARD_STARTFILE_PREFIX)
index bd3fc65..4bdb405 100644 (file)
@@ -1631,7 +1631,7 @@ legitimate_constant_p (register rtx op)
     return 1;
 
   /* Accept immediate LARL operands.  */
-  if (TARGET_64BIT && larl_operand (op, VOIDmode))
+  if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
     return 1;
 
   /* Thread-local symbols are never legal constants.  This is
@@ -1730,12 +1730,12 @@ legitimate_reload_constant_p (register rtx op)
     return 1;
 
   /* Accept lliXX operands.  */
-  if (TARGET_64BIT
+  if (TARGET_ZARCH
       && s390_single_hi (op, DImode, 0) >= 0)
   return 1;
 
   /* Accept larl operands.  */
-  if (TARGET_64BIT
+  if (TARGET_CPU_ZARCH
       && larl_operand (op, VOIDmode))
     return 1;
 
@@ -2260,7 +2260,7 @@ legitimize_pic_address (rtx orig, rtx reg)
       || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
     {
       /* This is a local symbol.  */
-      if (TARGET_64BIT && larl_operand (addr, VOIDmode))
+      if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
         {
           /* Access local symbols PC-relative via LARL.
              This is the same as in the non-PIC case, so it is
@@ -2309,7 +2309,7 @@ legitimize_pic_address (rtx orig, rtx reg)
           emit_move_insn (reg, new);
           new = reg;
         }
-      else if (TARGET_64BIT)
+      else if (TARGET_CPU_ZARCH)
         {
           /* If the GOT offset might be >= 4k, we determine the position
              of the GOT entry via a PC-relative LARL (@GOTENT).  */
@@ -2378,7 +2378,7 @@ legitimize_pic_address (rtx orig, rtx reg)
                   /* @PLT is OK as is on 64-bit, must be converted to
                      GOT-relative @PLTOFF on 31-bit.  */
                   case UNSPEC_PLT:
-                    if (!TARGET_64BIT)
+                    if (!TARGET_CPU_ZARCH)
                       {
                         rtx temp = reg? reg : gen_reg_rtx (Pmode);
 
@@ -2418,7 +2418,7 @@ legitimize_pic_address (rtx orig, rtx reg)
                || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
              && GET_CODE (op1) == CONST_INT)
            {
-              if (TARGET_64BIT && larl_operand (op0, VOIDmode))
+              if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
                 {
                   if (INTVAL (op1) & 1)
                     {
@@ -2625,7 +2625,7 @@ legitimize_tls_address (rtx addr, rtx reg)
            temp = gen_reg_rtx (Pmode);
            emit_move_insn (temp, new);
          }
-       else if (TARGET_64BIT)
+       else if (TARGET_CPU_ZARCH)
          {
            /* If the GOT offset might be >= 4k, we determine the position
               of the GOT entry via a PC-relative LARL.  */
@@ -2714,7 +2714,7 @@ legitimize_tls_address (rtx addr, rtx reg)
       switch (XINT (XEXP (addr, 0), 1))
        {
        case UNSPEC_INDNTPOFF:
-         if (TARGET_64BIT)
+         if (TARGET_CPU_ZARCH)
            new = addr;
          else
            abort ();
@@ -3806,12 +3806,12 @@ s390_split_branches (rtx temp_reg, bool *temp_used)
       else
        continue;
 
-      if (get_attr_length (insn) <= (TARGET_64BIT ? 6 : 4))
+      if (get_attr_length (insn) <= (TARGET_CPU_ZARCH ? 6 : 4))
        continue;
 
       *temp_used = 1;
 
-      if (TARGET_64BIT)
+      if (TARGET_CPU_ZARCH)
        {
          tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, *label), insn);
          INSN_ADDRESSES_NEW (tmp, -1);
@@ -4212,7 +4212,7 @@ s390_dump_pool (struct constant_pool *pool, bool remote_label)
 
   /* Pool start insn switches to proper section
      and guarantees necessary alignment.  */
-  if (TARGET_64BIT)
+  if (TARGET_CPU_ZARCH)
     insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn);
   else
     insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn);
@@ -4253,7 +4253,7 @@ s390_dump_pool (struct constant_pool *pool, bool remote_label)
 
   /* Pool end insn switches back to previous section
      and guarantees necessary alignment.  */
-  if (TARGET_64BIT)
+  if (TARGET_CPU_ZARCH)
     insn = emit_insn_after (gen_pool_end_64 (), insn);
   else
     insn = emit_insn_after (gen_pool_end_31 (), insn);
@@ -4380,9 +4380,9 @@ s390_mainpool_finish (struct constant_pool *pool, rtx base_reg)
   /* We need correct insn addresses.  */
   shorten_branches (get_insns ());
 
-  /* In 64-bit, we use a LARL to load the pool register.  The pool is
+  /* On zSeries, we use a LARL to load the pool register.  The pool is
      located in the .rodata section, so we emit it after the function.  */
-  if (TARGET_64BIT)
+  if (TARGET_CPU_ZARCH)
     {
       insn = gen_main_base_64 (base_reg, pool->label);
       insn = emit_insn_after (insn, pool->pool_insn);
@@ -4396,7 +4396,7 @@ s390_mainpool_finish (struct constant_pool *pool, rtx base_reg)
       s390_dump_pool (pool, 0);
     }
 
-  /* In 31-bit, if the total size of the function's code plus literal pool
+  /* On S/390, if the total size of the function's code plus literal pool
      does not exceed 4096 bytes, we use BASR to set up a function base
      pointer, and emit the literal pool at the end of the function.  */
   else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
@@ -4496,7 +4496,7 @@ s390_chunkify_start (rtx base_reg)
   rtx insn;
 
   rtx (*gen_reload_base) (rtx, rtx) =
-    TARGET_64BIT? gen_reload_base_64 : gen_reload_base_31;
+    TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
 
 
   /* We need correct insn addresses.  */
@@ -4562,7 +4562,7 @@ s390_chunkify_start (rtx base_reg)
           || INSN_ADDRESSES (INSN_UID (insn)) == -1)
        continue;
 
-      if (TARGET_64BIT)
+      if (TARGET_CPU_ZARCH)
        {
          if (curr_pool->size < S390_POOL_CHUNK_MAX)
            continue;
@@ -5426,7 +5426,7 @@ s390_load_got (int maybe_dead)
       SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
     }
 
-  if (TARGET_64BIT)
+  if (TARGET_CPU_ZARCH)
     {
       rtx insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
       if (maybe_dead)
@@ -6583,7 +6583,7 @@ s390_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
                         rtx x ATTRIBUTE_UNUSED,
                         unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
 {
-  if (TARGET_64BIT)
+  if (TARGET_CPU_ZARCH)
     readonly_data_section ();
   else
     function_section (current_function_decl);
index 4cda148..01a9904 100644 (file)
         (compare (and:DI (match_operand:DI 0 "memory_operand" "Q,S")
                          (match_operand:DI 1 "immediate_operand" "n,n"))
                  (match_operand:DI 2 "immediate_operand" "n,n")))]
-  "TARGET_64BIT
-   && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
+  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
    && s390_single_qi (operands[1], DImode, 0) >= 0"
 {
   int part = s390_single_qi (operands[1], DImode, 0);
 (define_insn "*movsi_lli"
   [(set (match_operand:SI 0 "register_operand" "=d")
         (match_operand:SI 1 "immediate_operand" "n"))]
-  "TARGET_64BIT && s390_single_hi (operands[1], SImode, 0) >= 0
+  "TARGET_ZARCH && s390_single_hi (operands[1], SImode, 0) >= 0
    && !FP_REG_P (operands[0])"
 {
   int part = s390_single_hi (operands[1], SImode, 0);
   [(set_attr "op_type" "RXY")
    (set_attr "type" "la")])
 
+(define_insn "*movsi_larl"
+  [(set (match_operand:SI 0 "register_operand" "=d")
+        (match_operand:SI 1 "larl_operand" "X"))]
+  "!TARGET_64BIT && TARGET_CPU_ZARCH
+   && !FP_REG_P (operands[0])"
+  "larl\t%0,%1"
+   [(set_attr "op_type" "RIL")
+    (set_attr "type"    "larl")])
+
 (define_insn "*movsi"
   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,T,!*f,!*f,!*f,!R,!T,?Q")
         (match_operand:SI 1 "general_operand" "d,R,T,d,d,*f,R,T,*f,*f,?Q"))]
 (define_insn "*extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=d")
         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
-  "TARGET_64BIT && TARGET_LONG_DISPLACEMENT"
+  "TARGET_LONG_DISPLACEMENT"
   "lb\t%0,%1"
   [(set_attr "op_type" "RXY")])
 
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
         (sign_extend:SI (match_operand:QI 1 "s_operand" "")))]
-  "(!TARGET_64BIT || !TARGET_LONG_DISPLACEMENT) && !reload_completed"
+  "!TARGET_LONG_DISPLACEMENT && !reload_completed"
   [(parallel
     [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_SETHIGH))
      (clobber (reg:CC 33))])
 (define_insn "*zero_extendqisi2_64"
   [(set (match_operand:SI 0 "register_operand" "=d")
         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
-  "TARGET_64BIT"
+  "TARGET_ZARCH"
   "llgc\t%0,%1"
   [(set_attr "op_type" "RXY")])
 
 (define_insn_and_split "*zero_extendqisi2_31"
   [(set (match_operand:SI 0 "register_operand" "=&d")
         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
-  "!TARGET_64BIT"
+  "!TARGET_ZARCH"
   "#"
   "&& reload_completed"
   [(set (match_dup 0) (const_int 0))
 (define_expand "zero_extendqihi2"
   [(set (match_operand:HI 0 "register_operand" "")
         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
-  "TARGET_64BIT"
+  "TARGET_ZARCH"
   "
 {
   operands[1] = gen_lowpart (HImode, operands[1]);
 (define_insn "*zero_extendqihi2_64"
   [(set (match_operand:HI 0 "register_operand" "=d")
         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
-  "TARGET_64BIT"
+  "TARGET_ZARCH"
   "llgc\t%0,%1"
   [(set_attr "op_type" "RXY")])
 
 (define_insn_and_split "*zero_extendqihi2_31"
   [(set (match_operand:HI 0 "register_operand" "=&d")
         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
-  "!TARGET_64BIT"
+  "!TARGET_ZARCH"
   "#"
   "&& reload_completed"
   [(set (match_dup 0) (const_int 0))
         (and:SI (match_operand:SI 1 "nonimmediate_operand" "0")
                 (match_operand:SI 2 "immediate_operand" "n")))
    (clobber (reg:CC 33))]
-  "TARGET_64BIT && s390_single_hi (operands[2], SImode, -1) >= 0"
+  "TARGET_ZARCH && s390_single_hi (operands[2], SImode, -1) >= 0"
 {
   int part = s390_single_hi (operands[2], SImode, -1);
   operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
         (and:HI (match_operand:HI 1 "register_operand" "%0,0")
                 (match_operand:HI 2 "nonmemory_operand" "d,n")))
    (clobber (reg:CC 33))]
-  "TARGET_64BIT"
+  "TARGET_ZARCH"
   "@
    nr\t%0,%2
    nill\t%0,%x2"
         (and:QI (match_operand:QI 1 "register_operand" "%0,0")
                 (match_operand:QI 2 "nonmemory_operand" "d,n")))
    (clobber (reg:CC 33))]
-  "TARGET_64BIT"
+  "TARGET_ZARCH"
   "@
    nr\t%0,%2
    nill\t%0,%b2"
         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0")
                 (match_operand:SI 2 "immediate_operand" "n")))
    (clobber (reg:CC 33))]
-  "TARGET_64BIT && s390_single_hi (operands[2], SImode, 0) >= 0"
+  "TARGET_ZARCH && s390_single_hi (operands[2], SImode, 0) >= 0"
 {
   int part = s390_single_hi (operands[2], SImode, 0);
   operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
         (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
                 (match_operand:HI 2 "nonmemory_operand" "d,n")))
    (clobber (reg:CC 33))]
-  "TARGET_64BIT"
+  "TARGET_ZARCH"
   "@
    or\t%0,%2
    oill\t%0,%x2"
         (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
                 (match_operand:QI 2 "nonmemory_operand" "d,n")))
    (clobber (reg:CC 33))]
-  "TARGET_64BIT"
+  "TARGET_ZARCH"
   "@
    or\t%0,%2
    oill\t%0,%b2"
   [(set (match_operand:SI 0 "register_operand" "=d,d")
        (rotate:SI (match_operand:SI 1 "register_operand" "d,d")
                   (match_operand:SI 2 "nonmemory_operand" "J,a")))]
-  "TARGET_64BIT"
+  "TARGET_CPU_ZARCH"
   "@
    rll\t%0,%1,%c2
    rll\t%0,%1,0(%2)"
 {
   if (get_attr_length (insn) == 4)
     return "j%C1\t%l0";
-  else if (TARGET_64BIT)
+  else if (TARGET_CPU_ZARCH)
     return "jg%C1\t%l0";
   else
     abort ();
    (set (attr "length")
         (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
                 (const_int 4)
-               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+               (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
                  (const_int 6)
                (eq (symbol_ref "flag_pic") (const_int 0))
                  (const_int 6)] (const_int 8)))])
 {
   if (get_attr_length (insn) == 4)
     return "j%D1\t%l0";
-  else if (TARGET_64BIT)
+  else if (TARGET_CPU_ZARCH)
     return "jg%D1\t%l0";
   else
     abort ();
    (set (attr "length")
         (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
                 (const_int 4)
-               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+               (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
                  (const_int 6)
                (eq (symbol_ref "flag_pic") (const_int 0))
                  (const_int 6)] (const_int 8)))])
    (set (attr "length")
         (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
                 (const_int 4)
-               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+               (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
                  (const_int 10)
                (eq (symbol_ref "flag_pic") (const_int 0))
                  (const_int 6)] (const_int 8)))])
 {
   if (get_attr_length (insn) == 4)
     return "j\t%l0";
-  else if (TARGET_64BIT)
+  else if (TARGET_CPU_ZARCH)
     return "jg\t%l0";
   else
     abort ();
    (set (attr "length")
         (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
                 (const_int 4)
-               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+               (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
                  (const_int 6)
                (eq (symbol_ref "flag_pic") (const_int 0))
                  (const_int 6)] (const_int 8)))])
    (use (match_operand 2 "" ""))]
   ""
 {
+  bool plt_call = false;
   rtx insn;
 
   /* Direct function calls need special treatment.  */
         {
           sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
           sym = gen_rtx_CONST (Pmode, sym);
+         plt_call = true;
         }
 
       /* Unless we can use the bras(l) insn, force the
          routine address into a register.  */
-      if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
+      if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
        {
          if (flag_pic)
            sym = legitimize_pic_address (sym, 0);
   /* Emit insn.  */
   insn = emit_call_insn (gen_call_exp (operands[0], operands[1],
                                       gen_rtx_REG (Pmode, RETURN_REGNUM)));
+
+  /* 31-bit PLT stubs use the GOT register implicitly.  */
+  if (!TARGET_64BIT && plt_call)
+    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+  
   DONE;
 })
 
   ""
   "")
 
-(define_insn "brasl"
-  [(call (mem:QI (match_operand:DI 0 "bras_sym_operand" "X"))
-         (match_operand:SI 1 "const_int_operand" "n"))
-   (clobber (match_operand:DI 2 "register_operand" "=r"))]
-  "TARGET_64BIT"
-  "brasl\t%2,%0"
-  [(set_attr "op_type" "RIL")
-   (set_attr "type"    "jsr")])
-
-(define_insn "bras"
-  [(call (mem:QI (match_operand:SI 0 "bras_sym_operand" "X"))
-         (match_operand:SI 1 "const_int_operand" "n"))
-   (clobber (match_operand:SI 2 "register_operand" "=r"))]
-  "TARGET_SMALL_EXEC"
+(define_insn "*bras"
+  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
+         (match_operand 1 "const_int_operand" "n"))
+   (clobber (match_operand 2 "register_operand" "=r"))]
+  "TARGET_SMALL_EXEC && GET_MODE (operands[2]) == Pmode"
   "bras\t%2,%0"
   [(set_attr "op_type" "RI")
    (set_attr "type"    "jsr")])
 
-(define_insn "basr_64"
-  [(call (mem:QI (match_operand:DI 0 "register_operand" "a"))
-         (match_operand:SI 1 "const_int_operand" "n"))
-   (clobber (match_operand:DI 2 "register_operand" "=r"))]
-  "TARGET_64BIT"
-  "basr\t%2,%0"
-  [(set_attr "op_type" "RR")
-   (set_attr "type"    "jsr")
-   (set_attr "atype"   "agen")])
-
-(define_insn "basr_31"
-  [(call (mem:QI (match_operand:SI 0 "register_operand" "a"))
-         (match_operand:SI 1 "const_int_operand" "n"))
-   (clobber (match_operand:SI 2 "register_operand" "=r"))]
-  "!TARGET_64BIT"
-  "basr\t%2,%0"
-  [(set_attr "op_type" "RR")
-   (set_attr "type"    "jsr")
-   (set_attr "atype"    "agen")])
-
-(define_insn "bas_64"
-  [(call (mem:QI (match_operand:QI 0 "address_operand" "U"))
-         (match_operand:SI 1 "const_int_operand" "n"))
-   (clobber (match_operand:DI 2 "register_operand" "=r"))]
-  "TARGET_64BIT"
-  "bas\t%2,%a0"
-  [(set_attr "op_type" "RX")
-   (set_attr "type"    "jsr")])
-
-(define_insn "bas_31"
-  [(call (mem:QI (match_operand:QI 0 "address_operand" "U"))
-         (match_operand:SI 1 "const_int_operand" "n"))
-   (clobber (match_operand:SI 2 "register_operand" "=r"))]
-  "!TARGET_64BIT"
-  "bas\t%2,%a0"
-  [(set_attr "op_type" "RX")
+(define_insn "*brasl"
+  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
+         (match_operand 1 "const_int_operand" "n"))
+   (clobber (match_operand 2 "register_operand" "=r"))]
+  "TARGET_CPU_ZARCH && GET_MODE (operands[2]) == Pmode"
+  "brasl\t%2,%0"
+  [(set_attr "op_type" "RIL")
    (set_attr "type"    "jsr")])
 
+(define_insn "*basr"
+  [(call (mem:QI (match_operand 0 "address_operand" "U"))
+         (match_operand 1 "const_int_operand" "n"))
+   (clobber (match_operand 2 "register_operand" "=r"))]
+  "GET_MODE (operands[2]) == Pmode"
+{
+  if (get_attr_op_type (insn) == OP_TYPE_RR)
+    return "basr\t%2,%0";
+  else
+    return "bas\t%2,%a0";
+}
+  [(set (attr "op_type")
+        (if_then_else (match_operand 0 "register_operand" "")
+                      (const_string "RR") (const_string "RX")))
+   (set_attr "type"  "jsr")
+   (set_attr "atype" "agen")])
 
 ;
 ; call_value instruction pattern(s).
    (use (match_operand 3 "" ""))]
   ""
 {
+  bool plt_call = false;
   rtx insn;
 
   /* Direct function calls need special treatment.  */
         {
           sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
           sym = gen_rtx_CONST (Pmode, sym);
+         plt_call = true;
         }
 
       /* Unless we can use the bras(l) insn, force the
          routine address into a register.  */
-      if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
+      if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
         {
          if (flag_pic)
            sym = legitimize_pic_address (sym, 0);
   insn = emit_call_insn (
            gen_call_value_exp (operands[0], operands[1], operands[2],
                                gen_rtx_REG (Pmode, RETURN_REGNUM)));
+
+  /* 31-bit PLT stubs use the GOT register implicitly.  */
+  if (!TARGET_64BIT && plt_call)
+    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+  
   DONE;
 })
 
   ""
   "")
 
-(define_insn "brasl_r"
+(define_insn "*bras_r"
   [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X"))
+        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
               (match_operand:SI 2 "const_int_operand" "n")))
-   (clobber (match_operand:DI 3 "register_operand" "=r"))]
-  "TARGET_64BIT"
-  "brasl\t%3,%1"
-  [(set_attr "op_type" "RIL")
-   (set_attr "type"    "jsr")])
-
-(define_insn "bras_r"
-  [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X"))
-              (match_operand:SI 2 "const_int_operand" "n")))
-   (clobber (match_operand:SI 3 "register_operand" "=r"))]
-  "TARGET_SMALL_EXEC"
+   (clobber (match_operand 3 "register_operand" "=r"))]
+  "TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode"
   "bras\t%3,%1"
   [(set_attr "op_type" "RI")
    (set_attr "type"    "jsr")])
 
-(define_insn "basr_r_64"
-  [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:QI (match_operand:DI 1 "register_operand" "a"))
-              (match_operand:SI 2 "const_int_operand" "n")))
-   (clobber (match_operand:DI 3 "register_operand" "=r"))]
-  "TARGET_64BIT"
-  "basr\t%3,%1"
-  [(set_attr "op_type" "RR")
-   (set_attr "type"    "jsr")
-   (set_attr "atype"   "agen")])
-
-(define_insn "basr_r_31"
+(define_insn "*brasl_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")))
-   (clobber (match_operand:SI 3 "register_operand" "=r"))]
-  "!TARGET_64BIT"
-  "basr\t%3,%1"
-  [(set_attr "op_type" "RR")
-   (set_attr "type"    "jsr")
-   (set_attr "atype"   "agen")])
-
-(define_insn "bas_r_64"
-  [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:QI (match_operand:QI 1 "address_operand" "U"))
-              (match_operand:SI 2 "const_int_operand" "n")))
-   (clobber (match_operand:DI 3 "register_operand" "=r"))]
-  "TARGET_64BIT"
-  "bas\t%3,%a1"
-  [(set_attr "op_type" "RX")
+        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+              (match_operand 2 "const_int_operand" "n")))
+   (clobber (match_operand 3 "register_operand" "=r"))]
+  "TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode"
+  "brasl\t%3,%1"
+  [(set_attr "op_type" "RIL")
    (set_attr "type"    "jsr")])
 
-(define_insn "bas_r_31"
+(define_insn "*basr_r"
   [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:QI (match_operand:QI 1 "address_operand" "U"))
-              (match_operand:SI 2 "const_int_operand" "n")))
-   (clobber (match_operand:SI 3 "register_operand" "=r"))]
-  "!TARGET_64BIT"
-  "bas\t%3,%a1"
-   [(set_attr "op_type" "RX")
-    (set_attr "type"    "jsr")])
-
+        (call (mem:QI (match_operand 1 "address_operand" "U"))
+              (match_operand 2 "const_int_operand" "n")))
+   (clobber (match_operand 3 "register_operand" "=r"))]
+  "GET_MODE (operands[3]) == Pmode"
+{
+  if (get_attr_op_type (insn) == OP_TYPE_RR)
+    return "basr\t%3,%1";
+  else
+    return "bas\t%3,%a1";
+}
+  [(set (attr "op_type")
+        (if_then_else (match_operand 1 "register_operand" "")
+                      (const_string "RR") (const_string "RX")))
+   (set_attr "type"  "jsr")
+   (set_attr "atype" "agen")])
 
 ;;
 ;;- Thread-local storage support.
 
   /* Unless we can use the bras(l) insn, force the
      routine address into a register.  */
-  if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
+  if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
     {
       if (flag_pic)
        sym = legitimize_pic_address (sym, 0);
   ""
   "")
 
-(define_insn "brasl_tls"
+(define_insn "*bras_tls"
   [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X"))
-              (match_operand:SI 2 "const_int_operand" "n")))
-   (clobber (match_operand:DI 3 "register_operand" "=r"))
-   (use (match_operand:DI 4 "" ""))]
-  "TARGET_64BIT"
-  "brasl\t%3,%1%J4"
-  [(set_attr "op_type" "RIL")
-   (set_attr "type"    "jsr")])
-
-(define_insn "bras_tls"
-  [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X"))
-              (match_operand:SI 2 "const_int_operand" "n")))
-   (clobber (match_operand:SI 3 "register_operand" "=r"))
-   (use (match_operand:SI 4 "" ""))]
-  "TARGET_SMALL_EXEC"
+        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+              (match_operand 2 "const_int_operand" "n")))
+   (clobber (match_operand 3 "register_operand" "=r"))
+   (use (match_operand 4 "" ""))]
+  "TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode"
   "bras\t%3,%1%J4"
   [(set_attr "op_type" "RI")
    (set_attr "type"    "jsr")])
 
-(define_insn "basr_tls_64"
+(define_insn "*brasl_tls"
   [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:QI (match_operand:DI 1 "register_operand" "a"))
-              (match_operand:SI 2 "const_int_operand" "n")))
-   (clobber (match_operand:DI 3 "register_operand" "=r"))
-   (use (match_operand:DI 4 "" ""))]
-  "TARGET_64BIT"
-  "basr\t%3,%1%J4"
-  [(set_attr "op_type" "RR")
+        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+              (match_operand 2 "const_int_operand" "n")))
+   (clobber (match_operand 3 "register_operand" "=r"))
+   (use (match_operand 4 "" ""))]
+  "TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode"
+  "brasl\t%3,%1%J4"
+  [(set_attr "op_type" "RIL")
    (set_attr "type"    "jsr")])
 
-(define_insn "basr_tls_31"
-  [(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")))
-   (clobber (match_operand:SI 3 "register_operand" "=r"))
-   (use (match_operand:SI 4 "" ""))]
-  "!TARGET_64BIT"
-  "basr\t%3,%1%J4"
-  [(set_attr "op_type" "RR")
-   (set_attr "type"    "jsr")
-   (set_attr "atype"   "agen")])
-
-(define_insn "bas_tls_64"
+(define_insn "*basr_tls"
   [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:QI (match_operand:QI 1 "address_operand" "U"))
-              (match_operand:SI 2 "const_int_operand" "n")))
-   (clobber (match_operand:DI 3 "register_operand" "=r"))
-   (use (match_operand:DI 4 "" ""))]
-  "TARGET_64BIT"
-  "bas\t%3,%a1%J4"
-  [(set_attr "op_type" "RX")
-   (set_attr "type"    "jsr")
-   (set_attr "atype"   "agen")])
-
-(define_insn "bas_tls_31"
-  [(set (match_operand 0 "register_operand" "=df")
-        (call (mem:QI (match_operand:QI 1 "address_operand" "U"))
-              (match_operand:SI 2 "const_int_operand" "n")))
-   (clobber (match_operand:SI 3 "register_operand" "=r"))
-   (use (match_operand:SI 4 "" ""))]
-  "!TARGET_64BIT"
-  "bas\t%3,%a1%J4"
-   [(set_attr "op_type" "RX")
-    (set_attr "type"    "jsr")
-    (set_attr "atype"   "agen")])
+        (call (mem:QI (match_operand 1 "address_operand" "U"))
+              (match_operand 2 "const_int_operand" "n")))
+   (clobber (match_operand 3 "register_operand" "=r"))
+   (use (match_operand 4 "" ""))]
+  "GET_MODE (operands[3]) == Pmode"
+{
+  if (get_attr_op_type (insn) == OP_TYPE_RR)
+    return "basr\t%3,%1%J4";
+  else
+    return "bas\t%3,%a1%J4";
+}
+  [(set (attr "op_type")
+        (if_then_else (match_operand 1 "register_operand" "")
+                      (const_string "RR") (const_string "RX")))
+   (set_attr "type"  "jsr")
+   (set_attr "atype" "agen")])
 
 ;;
 ;;- Miscellaneous instructions.
 
 (define_insn "pool_start_31"
   [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)]
-  "!TARGET_64BIT"
+  "!TARGET_CPU_ZARCH"
   ".align\t4"
   [(set_attr "op_type"  "NN")
    (set_attr "length"   "2")])
 
 (define_insn "pool_end_31"
   [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)]
-  "!TARGET_64BIT"
+  "!TARGET_CPU_ZARCH"
   ".align\t2"
   [(set_attr "op_type"  "NN")
    (set_attr "length"   "2")])
 
 (define_insn "pool_start_64"
   [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)]
-  "TARGET_64BIT"
+  "TARGET_CPU_ZARCH"
   ".section\t.rodata\;.align\t8"
   [(set_attr "op_type"  "NN")
    (set_attr "length"   "0")])
 
 (define_insn "pool_end_64"
   [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)]
-  "TARGET_64BIT"
+  "TARGET_CPU_ZARCH"
   ".previous"
   [(set_attr "op_type"  "NN")
    (set_attr "length"   "0")])
 
 (define_insn "main_base_31_small"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-        (unspec:SI [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
-  "!TARGET_64BIT"
+  [(set (match_operand 0 "register_operand" "=a")
+        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
+  "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
   "basr\t%0,0"
   [(set_attr "op_type" "RR")
    (set_attr "type"    "la")])
 
 (define_insn "main_base_31_large"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-        (unspec:SI [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
+  [(set (match_operand 0 "register_operand" "=a")
+        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
    (set (pc) (label_ref (match_operand 2 "" "")))]
-  "!TARGET_64BIT"
+  "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
   "bras\t%0,%2"
   [(set_attr "op_type" "RI")])
 
 (define_insn "main_base_64"
-  [(set (match_operand:DI 0 "register_operand" "=a")
-        (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
-  "TARGET_64BIT"
+  [(set (match_operand 0 "register_operand" "=a")
+        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
+  "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
   "larl\t%0,%1"
   [(set_attr "op_type" "RIL")
    (set_attr "type"    "larl")])
   [(set_attr "op_type" "NN")])
 
 (define_insn "reload_base_31"
-  [(set (match_operand:SI 0 "register_operand" "=a")
-        (unspec:SI [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
-  "!TARGET_64BIT"
+  [(set (match_operand 0 "register_operand" "=a")
+        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
+  "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
   "basr\t%0,0\;la\t%0,%1-.(%0)"
   [(set_attr "op_type" "NN")
    (set_attr "type"    "la")
    (set_attr "length"  "6")])
 
 (define_insn "reload_base_64"
-  [(set (match_operand:DI 0 "register_operand" "=a")
-        (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
-  "TARGET_64BIT"
+  [(set (match_operand 0 "register_operand" "=a")
+        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
+  "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
   "larl\t%0,%1"
   [(set_attr "op_type" "RIL")
    (set_attr "type"    "larl")])
   ""
   "s390_emit_epilogue (); DONE;")
 
-
-(define_insn "*return_si"
+(define_insn "*return"
   [(return)
-   (use (match_operand:SI 0 "register_operand" "a"))]
-  "!TARGET_64BIT"
+   (use (match_operand 0 "register_operand" "a"))]
+  "GET_MODE (operands[0]) == Pmode"
   "br\t%0"
   [(set_attr "op_type" "RR")
    (set_attr "type"    "jsr")
    (set_attr "atype"   "agen")])
 
-(define_insn "*return_di"
-  [(return)
-   (use (match_operand:DI 0 "register_operand" "a"))]
-  "TARGET_64BIT"
-  "br\t%0"
-  [(set_attr "op_type" "RR")
-   (set_attr "type"    "jsr")
-   (set_attr "atype"   "agen")])
 
 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
 ;; pointer. This is used for compatability.
 (define_expand "ptr_extend"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (match_operand:SI 1 "register_operand" "r"))]
-   ""
+  "TARGET_64BIT"
 {
   emit_insn (gen_anddi3 (operands[0],
                         gen_lowpart (DImode, operands[1]),