OSDN Git Service

* config/s390/s390.c (s390_adjust_cost): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / config / s390 / s390.md
index 0cbcc0a..d7f0e07 100644 (file)
           (match_operand:QI 1 "address_operand" ""))
      (clobber (reg:CC 33))])]
   "TARGET_64BIT
-   && strict_memory_address_p (VOIDmode, operands[1])
-   && preferred_la_operand_p (operands[1])"
+   && preferred_la_operand_p (operands[1], const0_rtx)"
   [(set (match_dup 0) (match_dup 1))]
   "")
 
      (clobber (reg:CC 33))])]
   "TARGET_64BIT
    && !reg_overlap_mentioned_p (operands[0], operands[2])
-   && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (DImode, operands[1], operands[2]))
-   && preferred_la_operand_p (gen_rtx_PLUS (DImode, operands[1], operands[2]))"
+   && preferred_la_operand_p (operands[1], operands[2])"
   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
   "")
 
           (match_operand:QI 1 "address_operand" ""))
      (clobber (reg:CC 33))])]
   "!TARGET_64BIT
-   && strict_memory_address_p (VOIDmode, operands[1])
-   && preferred_la_operand_p (operands[1])"
+   && preferred_la_operand_p (operands[1], const0_rtx)"
   [(set (match_dup 0) (match_dup 1))]
   "")
 
      (clobber (reg:CC 33))])]
   "!TARGET_64BIT
    && !reg_overlap_mentioned_p (operands[0], operands[2])
-   && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (SImode, operands[1], operands[2]))
-   && preferred_la_operand_p (gen_rtx_PLUS (SImode, operands[1], operands[2]))"
+   && preferred_la_operand_p (operands[1], operands[2])"
   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
   "")
 
 
    emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
 
-   index = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, base, index));
-   MEM_READONLY_P (index) = 1;
-   MEM_NOTRAP_P (index) = 1;
+   index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
    emit_move_insn (target, index);
 
    if (flag_pic)
 ;
 
 (define_expand "allocate_stack"
-  [(set (reg 15)
-        (plus (reg 15) (match_operand 1 "general_operand" "")))
-   (set (match_operand 0 "general_operand" "")
-        (reg 15))]
+  [(match_operand 0 "general_operand" "")
+   (match_operand 1 "general_operand" "")]
  "TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN"
 {
-    rtx stack = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
-    rtx chain;
-    rtx temp;
-
-    if (TARGET_KERNEL_BACKCHAIN)
-      chain = plus_constant (stack, STACK_POINTER_OFFSET - UNITS_PER_WORD);
-    else
-      chain = stack;
-
-    chain = gen_rtx_MEM (Pmode, chain);
-    temp = gen_reg_rtx (Pmode);
-
-    emit_move_insn (temp, chain);
-
-    if (TARGET_64BIT)
-      emit_insn (gen_adddi3 (stack, stack, negate_rtx (Pmode, operands[1])));
-    else
-      emit_insn (gen_addsi3 (stack, stack, negate_rtx (Pmode, operands[1])));
+  rtx temp = gen_reg_rtx (Pmode);
 
-    emit_move_insn (chain, temp);
+  emit_move_insn (temp, s390_back_chain_rtx ());
+  anti_adjust_stack (operands[1]);
+  emit_move_insn (s390_back_chain_rtx (), temp);
 
-    emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
-    DONE;
+  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
+  DONE;
 })
 
 
   "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))]
-  ""
+  [(match_operand 0 "register_operand" "")
+   (match_operand 1 "register_operand" "")]
+  "TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN"
 {
-  operands[2] = gen_reg_rtx (Pmode);
-  operands[3] = gen_rtx_MEM (Pmode, operands[0]);
+  rtx temp = gen_reg_rtx (Pmode);
+
+  emit_move_insn (temp, s390_back_chain_rtx ());
+  emit_move_insn (operands[0], operands[1]);
+  emit_move_insn (s390_back_chain_rtx (), temp);
+
+  DONE;
 })
 
 (define_expand "save_stack_nonlocal"
    (match_operand 1 "register_operand" "")]
   ""
 {
-  rtx temp = gen_reg_rtx (Pmode);
+  enum machine_mode mode = TARGET_64BIT ? OImode : TImode;
+  rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
+
+  /* Copy the backchain to the first word, sp to the second and the
+     literal pool base to the third.  */
+
+  if (TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN)
+    {
+      rtx temp = force_reg (Pmode, s390_back_chain_rtx ());
+      emit_move_insn (operand_subword (operands[0], 0, 0, mode), temp);
+    }
+
+  emit_move_insn (operand_subword (operands[0], 1, 0, mode), operands[1]);
+  emit_move_insn (operand_subword (operands[0], 2, 0, mode), base);
 
-  /* Copy the backchain to the first word, sp to the second and the literal pool
-     base to the third.  */
-  emit_move_insn (operand_subword (operands[0], 2, 0,
-                  TARGET_64BIT ? OImode : TImode),
-                  gen_rtx_REG (Pmode, BASE_REGNUM));
-  emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
-  emit_move_insn (operand_subword (operands[0], 0, 0,
-                 TARGET_64BIT ? OImode : TImode),
-                 temp);
-  emit_move_insn (operand_subword (operands[0], 1, 0,
-                 TARGET_64BIT ? OImode : TImode),
-                 operands[1]);
   DONE;
 })
 
    (match_operand 1 "memory_operand" "")]
   ""
 {
-  rtx temp = gen_reg_rtx (Pmode);
+  enum machine_mode mode = TARGET_64BIT ? OImode : TImode;
   rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
+  rtx temp = NULL_RTX;
 
   /* Restore the backchain from the first word, sp from the second and the
      literal pool base from the third.  */
-  emit_move_insn (temp,
-                 operand_subword (operands[1], 0, 0,
-                 TARGET_64BIT ? OImode : TImode));
-  emit_move_insn (operands[0],
-                 operand_subword (operands[1], 1, 0,
-                 TARGET_64BIT ? OImode : TImode));
-  emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
-  emit_move_insn (base,
-                  operand_subword (operands[1], 2, 0,
-                  TARGET_64BIT ? OImode : TImode));
-  emit_insn (gen_rtx_USE (VOIDmode, base));
 
+  if (TARGET_BACKCHAIN || TARGET_KERNEL_BACKCHAIN)
+    temp = force_reg (Pmode, operand_subword (operands[1], 0, 0, mode));
+    
+  emit_move_insn (base, operand_subword (operands[1], 2, 0, mode));
+  emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, mode));
+
+  if (temp)
+    emit_move_insn (s390_back_chain_rtx (), temp);
+
+  emit_insn (gen_rtx_USE (VOIDmode, base));
   DONE;
 })
 
         (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
   "GET_MODE (operands[0]) == Pmode"
   "* abort ();"
-  [(set_attr "op_type" "NN")])
+  [(set_attr "op_type" "NN")
+   (set (attr "type") 
+        (if_then_else (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
+                      (const_string "larl") (const_string "la")))])
 
 (define_insn "reload_base_31"
   [(set (match_operand 0 "register_operand" "=a")
                         GEN_INT (0x7fffffff)));
   DONE;
 })
+
+;; Instruction definition to expand eh_return macro to support
+;; swapping in special linkage return addresses.
+
+(define_expand "eh_return"
+  [(use (match_operand 0 "register_operand" ""))]
+  "TARGET_TPF"
+{
+  s390_emit_tpf_eh_return (operands[0]);
+  DONE;
+})
+