[3.0.1 PATCH] S/390 code cleanup

Ulrich Weigand weigand@immd1.informatik.uni-erlangen.de
Fri Aug 10 14:25:00 GMT 2001


Hello,

this rather large patch doesn't modifiy the behaviour of the
s390 backend (regression tested), but just cleans up the code 
to get it in line with the the coding conventions.  It is not really 
crucial, but I'd still like to get it into the branch as well.

OK to apply to the branch?



2001-08-10  Ulrich Weigand  <uweigand@de.ibm.com>

	* s390-protos.h, s390.c, s390.h, s390.md: Clean up code:
	add missing comments and prototypes, fix warnings,
	remove obsolete code.


diff -r -c -p gcc-3.0.1/gcc/config/s390/s390-protos.h gcc-3.0.1-s390/gcc/config/s390/s390-protos.h
*** gcc-3.0.1/gcc/config/s390/s390-protos.h	Fri Aug 10 13:09:47 2001
--- gcc-3.0.1-s390/gcc/config/s390/s390-protos.h	Fri Aug 10 21:40:46 2001
*************** along with GNU CC; see the file COPYING.
*** 19,85 ****
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! /* Declare functions in s390.c and linux.c */
  
! #ifdef RTX_CODE
! 
! #ifdef TREE_CODE
! extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx, int));
! extern void s390_va_start PARAMS ((int, tree, rtx));
! 
! #endif /* TREE_CODE */
  
  extern int fp_operand PARAMS ((rtx, enum machine_mode));
  extern int s_operand PARAMS ((rtx, enum machine_mode));
! extern int r_or_im8_operand PARAMS ((rtx, enum machine_mode));
! extern int r_or_s_operand PARAMS ((rtx, enum machine_mode)); 
  extern int r_or_s_or_im8_operand PARAMS ((rtx, enum machine_mode));
  extern int r_or_x_or_im16_operand PARAMS ((rtx, enum machine_mode));
  extern int bras_sym_operand PARAMS ((rtx, enum machine_mode));
! extern int dead_p PARAMS ((rtx, rtx));
! extern void print_operand PARAMS ((FILE *, rtx, char));
! extern void print_operand_address PARAMS ((FILE *, rtx));
  extern int legitimate_pic_operand_p PARAMS ((rtx));
  extern int legitimate_constant_p PARAMS ((rtx));
  
- extern int unsigned_comparison_operator PARAMS ((rtx));
- extern int unsigned_jump_follows_p PARAMS ((rtx));
- 
- extern void update_cc PARAMS ((rtx, rtx));
- 
- extern void s390_initialize_trampoline PARAMS ((rtx, rtx, rtx));
  extern void s390_output_symbolic_const PARAMS ((FILE *, rtx));
  extern int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
- 
  extern int s390_stop_dump_lit_p PARAMS ((rtx));
  extern void s390_dump_literal_pool PARAMS ((rtx, rtx));
! extern void s390_expand_eh_epilogue PARAMS ((rtx, rtx, rtx));
! extern void s390_asm_output_external_libcall PARAMS ((FILE *, rtx));
! 
  #endif /* RTX_CODE */
  
  #ifdef TREE_CODE
! extern void s390_function_arg_advance PARAMS ((CUMULATIVE_ARGS *,
! 					       enum machine_mode,
! 					       tree, int));
! extern struct rtx_def *s390_function_arg PARAMS ((CUMULATIVE_ARGS *,
! 					     enum machine_mode, tree, int));
! extern int s390_function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *,
! 					       enum machine_mode, tree, int));
  extern int s390_function_arg_pass_by_reference PARAMS ((enum machine_mode, tree));
! extern void setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
! 					    enum machine_mode, tree,
! 					    int *, int));
! extern struct rtx_def *s390_va_arg PARAMS ((tree, tree));
! extern union tree_node *s390_build_va_list PARAMS ((void));
! extern void s390_asm_output_pool_prologue PARAMS ((FILE *, char *, tree, int));
! extern void encode_section_info PARAMS ((tree));
! 
  #endif /* TREE_CODE */
  
- 
- extern void s390_trampoline_template PARAMS ((FILE *));
- extern int s390_function_prologue PARAMS ((FILE *, int));
- extern int s390_function_epilogue PARAMS ((FILE *, int));
- extern void s390_final_chunkify PARAMS ((int));
- extern int s390_arg_frame_offset PARAMS ((void));
--- 19,74 ----
  the Free Software Foundation, 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */
  
! /* Declare functions in s390.c.  */
  
! extern void optimization_options PARAMS ((int, int));
! extern int s390_arg_frame_offset PARAMS ((void));
! extern int s390_function_prologue PARAMS ((FILE *, int));
! extern int s390_function_epilogue PARAMS ((FILE *, int));
  
+ #ifdef RTX_CODE
+ extern int const0_operand PARAMS ((rtx, enum machine_mode));
+ extern int const1_operand PARAMS ((rtx, enum machine_mode));
+ extern int larl_operand PARAMS ((rtx, enum machine_mode));
  extern int fp_operand PARAMS ((rtx, enum machine_mode));
  extern int s_operand PARAMS ((rtx, enum machine_mode));
! extern int r_or_s_operand PARAMS ((rtx, enum machine_mode));
  extern int r_or_s_or_im8_operand PARAMS ((rtx, enum machine_mode));
  extern int r_or_x_or_im16_operand PARAMS ((rtx, enum machine_mode));
+ extern int r_or_im8_operand PARAMS ((rtx, enum machine_mode));
+ extern int tmxx_operand PARAMS ((rtx, enum machine_mode));
  extern int bras_sym_operand PARAMS ((rtx, enum machine_mode));
! extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
! extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
! 
! extern int s390_match_ccmode PARAMS ((rtx, enum machine_mode));
! extern int symbolic_reference_mentioned_p PARAMS ((rtx));
  extern int legitimate_pic_operand_p PARAMS ((rtx));
  extern int legitimate_constant_p PARAMS ((rtx));
+ extern int legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
+ extern rtx legitimize_pic_address PARAMS ((rtx, rtx));
+ extern rtx legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
+ extern void emit_pic_move PARAMS ((rtx *, enum machine_mode));
  
  extern void s390_output_symbolic_const PARAMS ((FILE *, rtx));
+ extern void print_operand_address PARAMS ((FILE *, rtx));
+ extern void print_operand PARAMS ((FILE *, rtx, int));
  extern int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
  extern int s390_stop_dump_lit_p PARAMS ((rtx));
  extern void s390_dump_literal_pool PARAMS ((rtx, rtx));
! extern void s390_trampoline_template PARAMS ((FILE *));
! extern void s390_initialize_trampoline PARAMS ((rtx, rtx, rtx));
  #endif /* RTX_CODE */
  
  #ifdef TREE_CODE
! extern void s390_asm_output_pool_prologue PARAMS ((FILE *, const char *, tree, int));
  extern int s390_function_arg_pass_by_reference PARAMS ((enum machine_mode, tree));
! extern void s390_function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
! extern tree s390_build_va_list PARAMS ((void));
! #ifdef RTX_CODE
! extern rtx s390_function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
! extern void s390_va_start PARAMS ((int, tree, rtx));
! extern rtx s390_va_arg PARAMS ((tree, tree));
! #endif /* RTX_CODE */
  #endif /* TREE_CODE */
  
diff -r -c -p gcc-3.0.1/gcc/config/s390/s390.c gcc-3.0.1-s390/gcc/config/s390/s390.c
*** gcc-3.0.1/gcc/config/s390/s390.c	Fri Aug 10 13:10:01 2001
--- gcc-3.0.1-s390/gcc/config/s390/s390.c	Fri Aug 10 21:40:46 2001
*************** Boston, MA 02111-1307, USA.  */
*** 23,30 ****
  #include "config.h"
  #include "system.h"
  #include "rtl.h"
- #include "expr.h"
  #include "tree.h"
  #include "regs.h"
  #include "hard-reg-set.h"
  #include "real.h"
--- 23,30 ----
  #include "config.h"
  #include "system.h"
  #include "rtl.h"
  #include "tree.h"
+ #include "expr.h"
  #include "regs.h"
  #include "hard-reg-set.h"
  #include "real.h"
*************** int  s390_function_count = 0;
*** 51,67 ****
  /* Save information from a "cmpxx" operation until the branch or scc is
     emitted.  */
  rtx s390_compare_op0, s390_compare_op1;
   
! /* Return TRUE or FALSE depending on whether every SET in INSN that
!    set the CC register has source and destination with matching CC modes, 
!    and that the CC mode is at least as constrained as REQ_MODE.  */
   
  static int
  s390_match_ccmode_set (set, req_mode)
       rtx set;
!      int req_mode;
  {
!   int set_mode;
  
    if (GET_CODE (set) != SET)
      abort ();
--- 51,105 ----
  /* Save information from a "cmpxx" operation until the branch or scc is
     emitted.  */
  rtx s390_compare_op0, s390_compare_op1;
+ 
+ /* Structure used to hold the components of a S/390 memory
+    address.  A legitimate address on S/390 is of the general
+    form
+           base + index + displacement
+    where any of the components is optional.
+ 
+    base and index are registers of the class ADDR_REGS,
+    displacement is an unsigned 12-bit immediate constant.  */
+ 
+ struct s390_address
+ {
+   rtx base;
+   rtx indx;
+   rtx disp;
+ };
+ 
+ static int s390_match_ccmode_set PARAMS ((rtx, enum machine_mode));
+ static int base_n_index_p PARAMS ((rtx));
+ static int check_mode PARAMS ((rtx, enum machine_mode *));
+ static int s390_decompose_address PARAMS ((rtx, struct s390_address *, int));
+ static void output_branch_condition PARAMS ((FILE *, rtx));
+ static void output_inverse_branch_condition PARAMS ((FILE *, rtx));
+ static int reg_used_in_mem_p PARAMS ((int, rtx));
+ static int addr_generation_dependency_p PARAMS ((rtx, rtx));
+ static int other_chunk PARAMS ((int *, int, int));
+ static int far_away PARAMS ((int, int));
+ static rtx check_and_change_labels PARAMS ((rtx, int *));
+ static void s390_final_chunkify PARAMS ((int));
+ static int save_fprs_p PARAMS ((void));
+ static int cur_is_leaf_function PARAMS ((void));
+ static int save_fprs PARAMS ((FILE *, long, int));
+ static int restore_fprs PARAMS ((FILE *, long, int));
+ static void s390_output_constant_pool PARAMS ((FILE *));
+ static rtx s390_force_const_mem_late PARAMS ((rtx));
+ static rtx s390_force_const_mem_symbol PARAMS ((const char *, int, int));
+ static int s390_function_arg_size PARAMS ((enum machine_mode, tree));
+ 
   
! /* Return true if SET either doesn't set the CC register, or else
!    the source and destination have matching CC modes and that 
!    CC mode is at least as constrained as REQ_MODE.  */
   
  static int
  s390_match_ccmode_set (set, req_mode)
       rtx set;
!      enum machine_mode req_mode;
  {
!   enum machine_mode set_mode;
  
    if (GET_CODE (set) != SET)
      abort ();
*************** s390_match_ccmode_set (set, req_mode)
*** 95,104 ****
    return (GET_MODE (SET_SRC (set)) == set_mode);
  }
  
  int
  s390_match_ccmode (insn, req_mode)
       rtx insn;
!      int req_mode;
  {
    int i;
  
--- 133,146 ----
    return (GET_MODE (SET_SRC (set)) == set_mode);
  }
  
+ /* Return true if every SET in INSN that sets the CC register 
+    has source and destination with matching CC modes and that 
+    CC mode is at least as constrained as REQ_MODE.  */
+  
  int
  s390_match_ccmode (insn, req_mode)
       rtx insn;
!      enum machine_mode req_mode;
  {
    int i;
  
*************** s390_match_ccmode (insn, req_mode)
*** 117,126 ****
    return 1;
  }
  
  
  void
  optimization_options (level, size)
!      int level;
       int size ATTRIBUTE_UNUSED;
  {
  #ifdef HAVE_decrement_and_branch_on_count
--- 159,175 ----
    return 1;
  }
  
+ /* Change optimizations to be performed, depending on the 
+    optimization level.
+ 
+    LEVEL is the optimization level specified; 2 if `-O2' is
+    specified, 1 if `-O' is specified, and 0 if neither is specified.
+ 
+    SIZE is non-zero if `-Os' is specified and zero otherwise. */
  
  void
  optimization_options (level, size)
!      int level ATTRIBUTE_UNUSED;
       int size ATTRIBUTE_UNUSED;
  {
  #ifdef HAVE_decrement_and_branch_on_count
*************** enum reg_class regclass_map[FIRST_PSEUDO
*** 146,152 ****
  };
  
  
! /* Match exactly zero.  */
   
  int
  const0_operand (op, mode)
--- 195,203 ----
  };
  
  
! /* Return true if OP a (const_int 0) operand.
!    OP is the current operation.
!    MODE is the current operation mode.  */
   
  int
  const0_operand (op, mode)
*************** const0_operand (op, mode)
*** 156,162 ****
    return op == CONST0_RTX (mode);
  }
  
! /* Match exactly one.  */
   
  int
  const1_operand (op, mode)
--- 207,215 ----
    return op == CONST0_RTX (mode);
  }
  
! /* Return true if OP a (const_int 1) operand.
!    OP is the current operation.
!    MODE is the current operation mode.  */
   
  int
  const1_operand (op, mode)
*************** const1_operand (op, mode)
*** 165,176 ****
  {
    return op == CONST1_RTX (mode);
  }
-  
  
! /* Return 1 if OP needs base and index register.  */
  
  static int 
! base_n_index_p (rtx op)
  {
    if ((GET_CODE (op) == PLUS) &&
        (GET_CODE (XEXP (op, 0)) == PLUS ||
--- 218,229 ----
  {
    return op == CONST1_RTX (mode);
  }
  
! /* Return true if OP needs base and index register.  */
  
  static int 
! base_n_index_p (op)
!      register rtx op;
  {
    if ((GET_CODE (op) == PLUS) &&
        (GET_CODE (XEXP (op, 0)) == PLUS ||
*************** base_n_index_p (rtx op)
*** 180,186 ****
    return 0;
  }
  
! /* Check mode and mode of op, set it to mode of op, if VOIDmode.  */ 
  
  static int
  check_mode (op, mode)
--- 233,240 ----
    return 0;
  }
  
! /* Return true if the mode of operand OP matches MODE.
!    If MODE is set to VOIDmode, set it to the mode of OP.  */ 
  
  static int
  check_mode (op, mode)
*************** check_mode (op, mode)
*** 197,204 ****
    return 1;
  }
  
! 
! /* Return 1 if OP a valid operand for the LARL instruction.
     OP is the current operation.
     MODE is the current operation mode.  */
  
--- 251,257 ----
    return 1;
  }
  
! /* Return true if OP a valid operand for the LARL instruction.
     OP is the current operation.
     MODE is the current operation mode.  */
  
*************** larl_operand (op, mode)
*** 207,215 ****
       register rtx op;
       enum machine_mode mode;
  {
-   rtx sym;
-   register enum rtx_code code = GET_CODE (op);
- 
    if (! check_mode (op, &mode))
      return 0;
  
--- 260,265 ----
*************** larl_operand (op, mode)
*** 254,260 ****
    return 0;
  }
  
! /* Return 1 if OP is a valid FP-Register.
     OP is the current operation.
     MODE is the current operation mode.  */
  
--- 304,310 ----
    return 0;
  }
  
! /* Return true if OP is a valid FP-Register.
     OP is the current operation.
     MODE is the current operation mode.  */
  
*************** fp_operand (op, mode)
*** 272,278 ****
      return 0;
  }
  
! /* Return 1 if OP is a valid S operand for an RS, SI or SS type instruction.  */
  
  int
  s_operand (op, mode)
--- 322,330 ----
      return 0;
  }
  
! /* Return true if OP is a valid S operand for an RS, SI or SS type instruction.
!    OP is the current operation.
!    MODE is the current operation mode.  */
  
  int
  s_operand (op, mode)
*************** s_operand (op, mode)
*** 293,299 ****
  }
  
  /* Return 1 if OP is a valid R or S operand for an RS, SI or SS type
!    instruction.  */
  
  int
  r_or_s_operand (op, mode)
--- 345,353 ----
  }
  
  /* Return 1 if OP is a valid R or S operand for an RS, SI or SS type
!    instruction.
!    OP is the current operation.
!    MODE is the current operation mode.  */
  
  int
  r_or_s_operand (op, mode)
*************** r_or_s_operand (op, mode)
*** 314,321 ****
    return register_operand (op, mode);
  }
  
! /* Return 1 if OP is a valid R or S or immediate operand for 
!    RS, SI or SS type instruction.  */
  
  int
  r_or_s_or_im8_operand (op, mode)
--- 368,377 ----
    return register_operand (op, mode);
  }
  
! /* Return true if OP is a valid R or S or immediate operand for 
!    RS, SI or SS type instruction.
!    OP is the current operation.
!    MODE is the current operation mode.  */
  
  int
  r_or_s_or_im8_operand (op, mode)
*************** r_or_s_or_im8_operand (op, mode)
*** 336,343 ****
    return register_operand (op, mode) || immediate_operand (op, mode);
  }
  
! /* Return 1 if OP is a valid R or X or 16 bit immediate operand for 
!    RX, RR or RI type instruction.  */
  
  int
  r_or_x_or_im16_operand (op, mode)
--- 392,401 ----
    return register_operand (op, mode) || immediate_operand (op, mode);
  }
  
! /* Return true if OP is a valid R or X or 16 bit immediate operand for 
!    RX, RR or RI type instruction.
!    OP is the current operation.
!    MODE is the current operation mode.  */
  
  int
  r_or_x_or_im16_operand (op, mode)
*************** r_or_x_or_im16_operand (op, mode)
*** 353,360 ****
    return register_operand (op, mode) || memory_operand (op, mode);
  }
  
! /* Return 1 if OP is a valid R or 8 bit immediate operand for 
!    !!!!!!! type instruction.  */
  
  int
  r_or_im8_operand (op, mode)
--- 411,419 ----
    return register_operand (op, mode) || memory_operand (op, mode);
  }
  
! /* Return true if OP is a valid R or 8 bit immediate operand.
!    OP is the current operation.
!    MODE is the current operation mode.  */
  
  int
  r_or_im8_operand (op, mode)
*************** r_or_im8_operand (op, mode)
*** 370,383 ****
    return register_operand (op, mode) || memory_operand (op, mode);
  }
  
! /* Return 1 if OP is a valid operand for the 'test under mask'
     instruction with 16 bit immediate.  
!    The value should only have set bits in one halfword.  */ 
  
  int
  tmxx_operand (op, mode)
       register rtx op;
!      enum machine_mode mode;
  {
    rtx con;
    if (GET_CODE (op) == CONST_INT)
--- 429,444 ----
    return register_operand (op, mode) || memory_operand (op, mode);
  }
  
! /* Return true if OP is a valid operand for the 'test under mask'
     instruction with 16 bit immediate.  
!    The value should only have set bits in one halfword.
!    OP is the current operation.
!    MODE is the current operation mode.  */
  
  int
  tmxx_operand (op, mode)
       register rtx op;
!      enum machine_mode mode ATTRIBUTE_UNUSED;
  {
    rtx con;
    if (GET_CODE (op) == CONST_INT)
*************** tmxx_operand (op, mode)
*** 394,400 ****
  	  c = (unsigned HOST_WIDEST_INT) INTVAL (con);
  	  
  	  return ((c & 0xffff) ? ((c & 0xffffffffffff0000ULL)==0) : 
! 		  (c & 0xffff0000) ? ((c & 0xffffffff0000ffffULL)==0) :
  		  (c & 0xffff00000000ULL) ? ((c & 0xffff0000ffffffffULL)==0) :
  		  (c & 0xffff000000000000ULL) ? ((c & 0xffffffffffffULL)==0) : 1);
  		  
--- 455,461 ----
  	  c = (unsigned HOST_WIDEST_INT) INTVAL (con);
  	  
  	  return ((c & 0xffff) ? ((c & 0xffffffffffff0000ULL)==0) : 
! 		  (c & 0xffff0000U) ? ((c & 0xffffffff0000ffffULL)==0) :
  		  (c & 0xffff00000000ULL) ? ((c & 0xffff0000ffffffffULL)==0) :
  		  (c & 0xffff000000000000ULL) ? ((c & 0xffffffffffffULL)==0) : 1);
  		  
*************** tmxx_operand (op, mode)
*** 403,417 ****
    return 0;
  }
  
! 
! /* Return 1 if valid operand for BRAS
     OP is the current operation.
     MODE is the current operation mode.  */
  
  int
  bras_sym_operand (op, mode)
       register rtx op;
!      enum machine_mode mode;
  {
    register enum rtx_code code = GET_CODE (op);
  
--- 464,477 ----
    return 0;
  }
  
! /* Return true if OP is a valid operand for the BRAS instruction.
     OP is the current operation.
     MODE is the current operation mode.  */
  
  int
  bras_sym_operand (op, mode)
       register rtx op;
!      enum machine_mode mode ATTRIBUTE_UNUSED;
  {
    register enum rtx_code code = GET_CODE (op);
  
*************** bras_sym_operand (op, mode)
*** 428,435 ****
  }
  
  
! /* Return 1 if OP is a load multiple operation.  It is known to be a
!    PARALLEL and the first section will be tested.  */
  
  int
  load_multiple_operation (op, mode)
--- 488,497 ----
  }
  
  
! /* Return true if OP is a load multiple operation.  It is known to be a
!    PARALLEL and the first section will be tested. 
!    OP is the current operation.
!    MODE is the current operation mode.  */
  
  int
  load_multiple_operation (op, mode)
*************** load_multiple_operation (op, mode)
*** 472,478 ****
    return 1;
  }
  
! /* Similar, but tests for store multiple.  */
  
  int
  store_multiple_operation (op, mode)
--- 534,543 ----
    return 1;
  }
  
! /* Return true if OP is a store multiple operation.  It is known to be a
!    PARALLEL and the first section will be tested. 
!    OP is the current operation.
!    MODE is the current operation mode.  */
  
  int
  store_multiple_operation (op, mode)
*************** store_multiple_operation (op, mode)
*** 514,526 ****
  }
  
  
! /* Returns 1 if OP contains a symbol reference */
  
  int
  symbolic_reference_mentioned_p (op)
       rtx op;
  {
!   register char *fmt;
    register int i;
  
    if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
--- 579,591 ----
  }
  
  
! /* Return true if OP contains a symbol reference */
  
  int
  symbolic_reference_mentioned_p (op)
       rtx op;
  {
!   register const char *fmt;
    register int i;
  
    if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
*************** symbolic_reference_mentioned_p (op)
*** 546,552 ****
  }
  
  
! /* Returns 1 if OP is a legitimate general operand when 
     generating PIC code.  It is given that flag_pic is on 
     and that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
  
--- 611,617 ----
  }
  
  
! /* Return true if OP is a legitimate general operand when 
     generating PIC code.  It is given that flag_pic is on 
     and that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
  
*************** legitimate_pic_operand_p (op)
*** 568,574 ****
    return 0;
  }
  
! /* Returns 1 if the constant value OP is a legitimate general operand.
     It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
  
  int
--- 633,639 ----
    return 0;
  }
  
! /* Returns true if the constant value OP is a legitimate general operand.
     It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE.  */
  
  int
*************** legitimate_constant_p (op)
*** 602,623 ****
  }
  
  
- /* Structure used to hold the components of a S/390 memory
-    address.  A legitimate address on S/390 is of the general
-    form  
-           base + index + displacement
-    where any of the components is optional.
- 
-    base and index are registers of the class ADDR_REGS,
-    displacement is an unsigned 12-bit immediate constant.  */
- 
- struct s390_address
- {
-   rtx base;
-   rtx indx;
-   rtx disp;
- };
- 
  /* Decompose a RTL expression ADDR for a memory address into
     its components, returned in OUT.  The boolean STRICT 
     specifies whether strict register checking applies.
--- 667,672 ----
*************** s390_decompose_address (addr, out, stric
*** 746,752 ****
            /* In some cases, we can accept an additional
               small constant offset.  Split these off here.  */
  
!           int offset = 0;
  
            if (GET_CODE (disp) == CONST
                && GET_CODE (XEXP (disp, 0)) == PLUS
--- 795,801 ----
            /* In some cases, we can accept an additional
               small constant offset.  Split these off here.  */
  
!           unsigned int offset = 0;
  
            if (GET_CODE (disp) == CONST
                && GET_CODE (XEXP (disp, 0)) == PLUS
*************** s390_decompose_address (addr, out, stric
*** 801,812 ****
    return TRUE;
  }
  
! /* Returns nonzero if ADDR is a valid memory address.
     STRICT specifies whether strict register checking applies.  */
  
  int
  legitimate_address_p (mode, addr, strict)
!      enum machine_mode mode;
       register rtx addr;
       int strict;
  {
--- 850,861 ----
    return TRUE;
  }
  
! /* Return nonzero if ADDR is a valid memory address.
     STRICT specifies whether strict register checking applies.  */
  
  int
  legitimate_address_p (mode, addr, strict)
!      enum machine_mode mode ATTRIBUTE_UNUSED;
       register rtx addr;
       int strict;
  {
*************** emit_pic_move (operands, mode)
*** 1118,1135 ****
      operands[1] = legitimize_pic_address (operands[1], temp);
  }
  
! /* Try machine-dependent ways of modifying an illegitimate address
     to be legitimate.  If we find one, return the new, valid address.
-    This macro is used in only one place: `memory_address' in explow.c.
  
     OLDX is the address as it was before break_out_memory_refs was called.
     In some cases it is useful to look at this to decide what needs to be done.
  
!    MODE and WIN are passed so that this macro can use
!    GO_IF_LEGITIMATE_ADDRESS.
! 
!    It is always safe for this macro to do nothing.  It exists to recognize
!    opportunities to optimize the output.
  
     When -fpic is used, special handling is needed for symbolic references.
     See comments by legitimize_pic_address for details.  */
--- 1157,1169 ----
      operands[1] = legitimize_pic_address (operands[1], temp);
  }
  
! /* Try machine-dependent ways of modifying an illegitimate address X
     to be legitimate.  If we find one, return the new, valid address.
  
     OLDX is the address as it was before break_out_memory_refs was called.
     In some cases it is useful to look at this to decide what needs to be done.
  
!    MODE is the mode of the operand pointed to by X.
  
     When -fpic is used, special handling is needed for symbolic references.
     See comments by legitimize_pic_address for details.  */
*************** rtx
*** 1138,1144 ****
  legitimize_address (x, oldx, mode)
       register rtx x;
       register rtx oldx ATTRIBUTE_UNUSED;
!      enum machine_mode mode;
  {
    if (flag_pic && SYMBOLIC_CONST (x))
      return legitimize_pic_address (x, 0);
--- 1172,1178 ----
  legitimize_address (x, oldx, mode)
       register rtx x;
       register rtx oldx ATTRIBUTE_UNUSED;
!      enum machine_mode mode ATTRIBUTE_UNUSED;
  {
    if (flag_pic && SYMBOLIC_CONST (x))
      return legitimize_pic_address (x, 0);
*************** legitimize_address (x, oldx, mode)
*** 1147,1157 ****
  }
  
  
! /* Output branch condition code of RTX code in assembler
     syntax to stdio stream FILE.  */
  
  static void
! output_branch_condition (FILE *file, rtx code)
  {
    switch (GET_CODE (code)) 
      {
--- 1181,1193 ----
  }
  
  
! /* Output branch condition code of CODE in assembler
     syntax to stdio stream FILE.  */
  
  static void
! output_branch_condition (file, code)
!      FILE *file;
!      rtx code;
  {
    switch (GET_CODE (code)) 
      {
*************** output_branch_condition (FILE *file, rtx
*** 1182,1192 ****
      }
  }
  
! /* Output the inverse of the branch condition code of RTX code 
     in assembler syntax to stdio stream FILE.  */
  
  static void
! output_inverse_branch_condition (FILE *file, rtx code)
  {
    switch (GET_CODE (code)) 
      {
--- 1218,1230 ----
      }
  }
  
! /* Output the inverse of the branch condition code of CODE 
     in assembler syntax to stdio stream FILE.  */
  
  static void
! output_inverse_branch_condition (file, code)
!      FILE *file;
!      rtx code;
  {
    switch (GET_CODE (code)) 
      {
*************** output_inverse_branch_condition (FILE *f
*** 1221,1227 ****
     stdio stream FILE.  */
  
  void
! s390_output_symbolic_const (FILE *file, rtx x)
  {
    switch (GET_CODE (x))
      {
--- 1259,1267 ----
     stdio stream FILE.  */
  
  void
! s390_output_symbolic_const (file, x)
!      FILE *file;
!      rtx x;
  {
    switch (GET_CODE (x))
      {
*************** s390_output_symbolic_const (FILE *file, 
*** 1305,1311 ****
     stdio stream FILE.  */
  
  void
! print_operand_address (FILE *file, rtx addr)
  {
    struct s390_address ad;
  
--- 1345,1353 ----
     stdio stream FILE.  */
  
  void
! print_operand_address (file, addr)
!      FILE *file;
!      rtx addr;
  {
    struct s390_address ad;
  
*************** print_operand_address (FILE *file, rtx a
*** 1325,1331 ****
  }
  
  /* Output operand X in assembler syntax to stdio stream FILE.  
!    The following format flags are recognized as CODE:
  
      'C': print opcode suffix for branch condition.
      'D': print opcode suffix for inverse branch condition.
--- 1367,1374 ----
  }
  
  /* Output operand X in assembler syntax to stdio stream FILE.  
!    CODE specified the format flag.  The following format flags 
!    are recognized:
  
      'C': print opcode suffix for branch condition.
      'D': print opcode suffix for inverse branch condition.
*************** print_operand_address (FILE *file, rtx a
*** 1341,1347 ****
      'h': print integer X as if it's a signed word.  */
  
  void
! print_operand (FILE *file, rtx x, char code)
  {
    switch (code)
      {
--- 1384,1393 ----
      'h': print integer X as if it's a signed word.  */
  
  void
! print_operand (file, x, code)
!      FILE *file;
!      rtx x;
!      int code;
  {
    switch (code)
      {
*************** print_operand (FILE *file, rtx x, char c
*** 1454,1460 ****
     a memory address in expression X.  */
  
  static int
! reg_used_in_mem_p (int regno, rtx x)
  {
    enum rtx_code code = GET_CODE (x);
    int i, j;
--- 1500,1508 ----
     a memory address in expression X.  */
  
  static int
! reg_used_in_mem_p (regno, x)
!      int regno;
!      rtx x;
  {
    enum rtx_code code = GET_CODE (x);
    int i, j;
*************** reg_used_in_mem_p (int regno, rtx x)
*** 1486,1492 ****
     used by instruction INSN to address memory.  */
  
  static int 
! addr_generation_dependency_p (rtx dep_rtx, rtx insn)
  {
    rtx target;
  
--- 1534,1542 ----
     used by instruction INSN to address memory.  */
  
  static int 
! addr_generation_dependency_p (dep_rtx, insn)
!      rtx dep_rtx; 
!      rtx insn;
  {
    rtx target;
  
*************** addr_generation_dependency_p (rtx dep_rt
*** 1509,1524 ****
  }
  
  
! /* Data dependencies are all handled without delay. But if an register
!    is changed for a memory access, at least 4 cycle need to be put
!    between the set of the register and the use. Because of that,
!    the delays specified in the .md file needs to check and adjust
!    to the right cost.  */
  
  int
! s390_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
  {
!   rtx dep_rtx, dest, x;
    int i;
  
    /* If the dependence is an anti-dependence, there is no cost.  For an
--- 1559,1581 ----
  }
  
  
! /* Return the modified cost of the dependency of instruction INSN
!    on instruction DEP_INSN through the link LINK.  COST is the 
!    default cost of that dependency.
! 
!    Data dependencies are all handled without delay.  However, if a
!    register is modified and subsequently used as base or index 
!    register of a memory reference, at least 4 cycles need to pass
!    between setting and using the register to avoid pipeline stalls.  */
  
  int
! s390_adjust_cost (insn, link, dep_insn, cost)
!      rtx insn;
!      rtx link;
!      rtx dep_insn;
!      int cost;
  {
!   rtx dep_rtx;
    int i;
  
    /* If the dependence is an anti-dependence, there is no cost.  For an
*************** s390_adjust_cost (rtx insn, rtx link, rt
*** 1588,1606 ****
       - in this case, a branch from one chunk to other chunk needs
         a reload of base register at the code label branched to.  */
  
! rtx s390_pool_start_insn = NULL_RTX;
! 
! /* Count of actual pool in function (-1 -> before function).  */
! 
  int s390_pool_count = -1;
  
  static int pool_stop_uid;
  
  /* Called from the ASM_OUTPUT_POOL_PROLOGUE macro to 
!    prepare for printing a literal pool chunk.  */
   
  void 
! s390_asm_output_pool_prologue (FILE *file, char *fname, tree fndecl, int size)
  {
  
    if (s390_pool_count>0) {
--- 1645,1674 ----
       - in this case, a branch from one chunk to other chunk needs
         a reload of base register at the code label branched to.  */
  
! /* Index of constant pool chunk that is currently being processed.
!    Set to -1 before function output has started.  */
  int s390_pool_count = -1;
  
+ /* First insn using the constant pool chunk that is currently being
+    processed.  */
+ rtx s390_pool_start_insn = NULL_RTX;
+ 
+ /* UID of last insn using the constant pool chunk that is currently 
+    being processed.  */
  static int pool_stop_uid;
  
  /* Called from the ASM_OUTPUT_POOL_PROLOGUE macro to 
!    prepare for printing a literal pool chunk to stdio stream FILE.  
! 
!    FNAME and FNDECL specify the name and type of the current function.
!    SIZE is the size in bytes of the current literal pool.  */
   
  void 
! s390_asm_output_pool_prologue (file, fname, fndecl, size)
!      FILE *file;
!      const char *fname ATTRIBUTE_UNUSED;
!      tree fndecl;
!      int size ATTRIBUTE_UNUSED;
  {
  
    if (s390_pool_count>0) {
*************** s390_asm_output_pool_prologue (FILE *fil
*** 1626,1637 ****
      function_section (fndecl);
  }
  
! /* Return 1 if OTHER_ADDR is in different chunk than MY_ADDR.
     LTORG points to a list of all literal pools inserted
     into the current function.  */
  
  static int
! other_chunk (int *ltorg, int my_addr, int other_addr)
  {
    int ad, i=0, j=0;
  
--- 1694,1708 ----
      function_section (fndecl);
  }
  
! /* Return true if OTHER_ADDR is in different chunk than MY_ADDR.
     LTORG points to a list of all literal pools inserted
     into the current function.  */
  
  static int
! other_chunk (ltorg, my_addr, other_addr)
!      int *ltorg;
!      int my_addr;
!      int other_addr;
  {
    int ad, i=0, j=0;
  
*************** other_chunk (int *ltorg, int my_addr, in
*** 1651,1661 ****
    return 1;
  }
  
! /* Return 1 if OTHER_ADDR is too far away from MY_ADDR
     to use a relative branch instruction.  */
  
  static int 
! far_away (int my_addr, int other_addr)
  {
    /* In 64 bit mode we can jump +- 4GB.  */
    if (TARGET_64BIT)
--- 1722,1734 ----
    return 1;
  }
  
! /* Return true if OTHER_ADDR is too far away from MY_ADDR
     to use a relative branch instruction.  */
  
  static int 
! far_away (my_addr, other_addr)
!      int my_addr;
!      int other_addr;
  {
    /* In 64 bit mode we can jump +- 4GB.  */
    if (TARGET_64BIT)
*************** far_away (int my_addr, int other_addr)
*** 1674,1680 ****
     that have been inserted.  */
  
  static rtx 
! check_and_change_labels (rtx insn, int *ltorg_uids)
  {
    rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
    rtx target, jump;
--- 1747,1755 ----
     that have been inserted.  */
  
  static rtx 
! check_and_change_labels (insn, ltorg_uids)
!      rtx insn;
!      int *ltorg_uids;
  {
    rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
    rtx target, jump;
*************** check_and_change_labels (rtx insn, int *
*** 1811,1829 ****
    return insn;
  }
  
- static int chunk_max=0;
- 
- 
  /* Called from s390_function_prologue to make final adjustments
     before outputting code.  CHUNKIFY specifies whether we need
     to use multiple literal pools (because the total size of the
     literals exceeds 4K).  */
  
! void
! s390_final_chunkify (int chunkify)
  {
    rtx insn, ninsn, tmp;
!   int addr, naddr, uids;
  
    const char *asms;
  
--- 1886,1903 ----
    return insn;
  }
  
  /* Called from s390_function_prologue to make final adjustments
     before outputting code.  CHUNKIFY specifies whether we need
     to use multiple literal pools (because the total size of the
     literals exceeds 4K).  */
  
! static void
! s390_final_chunkify (chunkify)
!      int chunkify;
  {
    rtx insn, ninsn, tmp;
!   int addr, naddr = 0, uids;
!   int chunk_max = 0;
  
    const char *asms;
  
*************** s390_final_chunkify (int chunkify)
*** 1930,1940 ****
    pool_stop_uid = ltorg_uids[0];
  }
  
! /* Return 1 if next literal pool is reached (check for ltorg insn)
!    maybe should use unspec insn.  */
  
  int 
! s390_stop_dump_lit_p (rtx insn)
  {
    rtx body=PATTERN (insn);
    if (GET_CODE (body) == PARALLEL
--- 2004,2014 ----
    pool_stop_uid = ltorg_uids[0];
  }
  
! /* Return true if INSN is a 'ltorg' insn.  */
  
  int 
! s390_stop_dump_lit_p (insn)
!     rtx insn;
  {
    rtx body=PATTERN (insn);
    if (GET_CODE (body) == PARALLEL
*************** s390_stop_dump_lit_p (rtx insn)
*** 1951,1960 ****
  }
  
  /* Output literal pool chunk to be used for insns
!    between ACT_INSN and STOP.  */
  
  void
! s390_dump_literal_pool (rtx act_insn, rtx stop)
  {
    s390_pool_start_insn = act_insn;
    pool_stop_uid = INTVAL (stop);
--- 2025,2036 ----
  }
  
  /* Output literal pool chunk to be used for insns
!    between insn ACT_INSN and the insn with UID STOP.  */
  
  void
! s390_dump_literal_pool (act_insn, stop)
!      rtx act_insn;
!      rtx stop;
  {
    s390_pool_start_insn = act_insn;
    pool_stop_uid = INTVAL (stop);
*************** extern char *dwarf2out_cfi_label PARAMS 
*** 1969,1982 ****
  #endif
  
  /* Flag set in prologue, used in epilog to know
!   if stack is allocated or not.  */
! 
  static int leaf_function_flag;
! rtx s390_got_label;
  rtx s390_profile[10];
  int s390_nr_constants;
  
! /* Returns 1 if floating point registers need to be saved.  */
  
  static int 
  save_fprs_p ()
--- 2045,2061 ----
  #endif
  
  /* Flag set in prologue, used in epilog to know
!    if stack is allocated or not.  */
  static int leaf_function_flag;
! 
! /* Symbol references needed by the profile code;
!    set up by the function prologue routine if necessary.  */
  rtx s390_profile[10];
+ 
+ /* Number of elements of current constant pool.  */
  int s390_nr_constants;
  
! /* Return true if floating point registers need to be saved.  */
  
  static int 
  save_fprs_p ()
*************** save_fprs_p ()
*** 1992,1999 ****
    return 0;
  }
  
! /* Current function is a leaf function, without automatics,
!    alloca or vararg stuff.  */
  
  static int
  cur_is_leaf_function ()
--- 2071,2078 ----
    return 0;
  }
  
! /* Return true if urrent function is a leaf function, 
!    without automatics, alloca or vararg stuff.  */
  
  static int
  cur_is_leaf_function ()
*************** cur_is_leaf_function ()
*** 2008,2015 ****
    return 0;
  }
  
! /* Calculate offset between argument pointer and frame pointer 
!    initialy after prologue.  */
  
  int 
  s390_arg_frame_offset ()
--- 2087,2094 ----
    return 0;
  }
  
! /* Return offset between argument pointer and frame pointer 
!    initially after prologue.  */
  
  int 
  s390_arg_frame_offset ()
*************** s390_arg_frame_offset ()
*** 2028,2034 ****
     pointer register FP.  */
  
  static int 
! save_fprs (FILE *file, long offset, int fp)
  {
    int i;
  
--- 2107,2116 ----
     pointer register FP.  */
  
  static int 
! save_fprs (file, offset, fp)
!      FILE *file;
!      long offset;
!      int fp;
  {
    int i;
  
*************** save_fprs (FILE *file, long offset, int 
*** 2039,2048 ****
      {
        if (regs_ever_live[i] == 1)
  	{
! 	  fprintf (file, "\tstd\t%s,%d(%s)\n", reg_names[i], 
  		   (i-24) * 8 + offset, reg_names[fp]); 
  	}
      }
  }
  
  /* Output code to stdio stream FILE to restore floating point 
--- 2121,2132 ----
      {
        if (regs_ever_live[i] == 1)
  	{
! 	  fprintf (file, "\tstd\t%s,%ld(%s)\n", reg_names[i], 
  		   (i-24) * 8 + offset, reg_names[fp]); 
  	}
      }
+ 
+   return 1;
  }
  
  /* Output code to stdio stream FILE to restore floating point 
*************** save_fprs (FILE *file, long offset, int 
*** 2050,2056 ****
     pointer register FP.  */
  
  static int 
! restore_fprs (FILE *file, long offset, int fp)
  {
    int i;
  
--- 2134,2143 ----
     pointer register FP.  */
  
  static int 
! restore_fprs (file, offset, fp)
!      FILE *file;
!      long offset;
!      int fp;
  {
    int i;
  
*************** restore_fprs (FILE *file, long offset, i
*** 2073,2088 ****
      {
        if (regs_ever_live[i] == 1)
  	{
! 	  fprintf (file, "\tld\t%s,%d(%s)\n", reg_names[i], 
  		   (i-24) * 8 + offset, reg_names[fp]); 
  	}
      }
  }
  
! /* Output constant pool in function prologue (31 bit) or in readonly section.  */ 
  
! static int
! s390_output_constant_pool (FILE* file)
  {
    /* Output constant pool.  */
    if (s390_nr_constants || regs_ever_live[BASE_REGISTER])
--- 2160,2178 ----
      {
        if (regs_ever_live[i] == 1)
  	{
! 	  fprintf (file, "\tld\t%s,%ld(%s)\n", reg_names[i], 
  		   (i-24) * 8 + offset, reg_names[fp]); 
  	}
      }
+ 
+   return 1;
  }
  
! /* Output main constant pool to stdio stream FILE.  */ 
  
! static void
! s390_output_constant_pool (file)
!      FILE *file;
  {
    /* Output constant pool.  */
    if (s390_nr_constants || regs_ever_live[BASE_REGISTER])
*************** s390_output_constant_pool (FILE* file)
*** 2117,2123 ****
     pool reference.  */
  
  static rtx
! s390_force_const_mem_late (rtx cst)
  {
    cst = force_const_mem (Pmode, cst);
  
--- 2207,2214 ----
     pool reference.  */
  
  static rtx
! s390_force_const_mem_late (cst)
!      rtx cst;
  {
    cst = force_const_mem (Pmode, cst);
  
*************** s390_force_const_mem_late (rtx cst)
*** 2136,2142 ****
     generated.  Returns the constant pool reference.  */
  
  static rtx
! s390_force_const_mem_symbol (char *name, int func, int global)
  {
    rtx symbol;
  
--- 2227,2236 ----
     generated.  Returns the constant pool reference.  */
  
  static rtx
! s390_force_const_mem_symbol (name, func, global)
!      const char *name;
!      int func;
!      int global;
  {
    rtx symbol;
  
*************** s390_force_const_mem_symbol (char *name,
*** 2169,2180 ****
     in LSIZE.  */
  
  int
! s390_function_prologue (FILE * file, int lsize)
  {
    extern int profile_label_no;
    int i, j;
    long frame_size;
!   rtx stack_label = 0, got_label = 0, tmp;
    char *l;
    char b64[2] = " ";
    b64[0] = TARGET_64BIT ? 'g' : '\0';
--- 2263,2276 ----
     in LSIZE.  */
  
  int
! s390_function_prologue (file, lsize)
!      FILE *file;
!      int lsize;
  {
    extern int profile_label_no;
    int i, j;
    long frame_size;
!   rtx stack_label = 0, got_label = 0;
    char *l;
    char b64[2] = " ";
    b64[0] = TARGET_64BIT ? 'g' : '\0';
*************** s390_function_prologue (FILE * file, int
*** 2382,2388 ****
        if (save_fprs_p () && frame_size > 4095) 
  	{
  	  int fp = 1;
- 	  int offset = 0;
  	  fprintf (file, "\tlgr\t%s,%s\n", reg_names[fp], 
  		   reg_names[STACK_POINTER_REGNUM]); 
  	  fprintf (file, "\taghi\t%s,-64\n", reg_names[fp]);
--- 2478,2483 ----
*************** s390_function_prologue (FILE * file, int
*** 2414,2420 ****
  	}
        else
  	{
! 	  fprintf (file, "\ta%shi\t%s,-%d\n",b64, 
  		   reg_names[STACK_POINTER_REGNUM], frame_size);
  	}
  #ifdef INCOMING_RETURN_ADDR_RTX
--- 2509,2515 ----
  	}
        else
  	{
! 	  fprintf (file, "\ta%shi\t%s,-%ld\n",b64, 
  		   reg_names[STACK_POINTER_REGNUM], frame_size);
  	}
  #ifdef INCOMING_RETURN_ADDR_RTX
*************** s390_function_prologue (FILE * file, int
*** 2481,2487 ****
     in LSIZE.  */
  
  int
! s390_function_epilogue (FILE * file, int lsize)
  {
  /* Register is call clobbered and not used for eh or return.  */
  #define FREE_REG 4
--- 2576,2584 ----
     in LSIZE.  */
  
  int
! s390_function_epilogue (file, lsize)
!      FILE *file;
!      int lsize;
  {
  /* Register is call clobbered and not used for eh or return.  */
  #define FREE_REG 4
*************** s390_function_epilogue (FILE * file, int
*** 2578,2598 ****
    return 0;
  }
  
- /* This is epilogue code, maybe should use generic in except.c.  */ 
- 
- void
- s390_expand_eh_epilogue (rtx reg1, rtx reg2, rtx reg3)
- {
-   abort ();
- }
- 
  
  /* Return the size in bytes of a function argument of 
     type TYPE and/or mode MODE.  At least one of TYPE or
     MODE must be specified.  */
  
  static int
! s390_function_arg_size (enum machine_mode mode, tree type)
  {
    if (type)
      return int_size_in_bytes (type);
--- 2675,2689 ----
    return 0;
  }
  
  
  /* Return the size in bytes of a function argument of 
     type TYPE and/or mode MODE.  At least one of TYPE or
     MODE must be specified.  */
  
  static int
! s390_function_arg_size (mode, type)
!      enum machine_mode mode;
!      tree type;
  {
    if (type)
      return int_size_in_bytes (type);
*************** s390_function_arg_size (enum machine_mod
*** 2612,2618 ****
     reference.  */
  
  int
! s390_function_arg_pass_by_reference (enum machine_mode mode, tree type)
  {
    int size = s390_function_arg_size (mode, type);
  
--- 2703,2711 ----
     reference.  */
  
  int
! s390_function_arg_pass_by_reference (mode, type)
!      enum machine_mode mode;
!      tree type;
  {
    int size = s390_function_arg_size (mode, type);
  
*************** s390_function_arg_pass_by_reference (enu
*** 2631,2641 ****
  
  /* Update the data in CUM to advance over an argument of mode MODE and
     data type TYPE.  (TYPE is null for libcalls where that information
!    may not be available.).  */
  
  void
! s390_function_arg_advance (CUMULATIVE_ARGS * cum,
! 		      enum machine_mode mode, tree type, int named)
  {
    if (! TARGET_SOFT_FLOAT && (mode == DFmode || mode == SFmode))
      {
--- 2724,2739 ----
  
  /* Update the data in CUM to advance over an argument of mode MODE and
     data type TYPE.  (TYPE is null for libcalls where that information
!    may not be available.).  The boolean NAMED specifies whether the
!    argument is a named argument (as opposed to an unnamed argument
!    matching an ellipsis).  */
  
  void
! s390_function_arg_advance (cum, mode, type, named)
!      CUMULATIVE_ARGS *cum;
!      enum machine_mode mode;
!      tree type;
!      int named ATTRIBUTE_UNUSED;
  {
    if (! TARGET_SOFT_FLOAT && (mode == DFmode || mode == SFmode))
      {
*************** s390_function_arg_advance (CUMULATIVE_AR
*** 2672,2679 ****
     are pushed to the stack.  */
  
  rtx
! s390_function_arg (CUMULATIVE_ARGS * cum,
! 	      enum machine_mode mode, tree type, int named)
  {
    if (s390_function_arg_pass_by_reference (mode, type))
        return 0;
--- 2770,2780 ----
     are pushed to the stack.  */
  
  rtx
! s390_function_arg (cum, mode, type, named)
!      CUMULATIVE_ARGS *cum;
!      enum machine_mode mode;
!      tree type;
!      int named ATTRIBUTE_UNUSED;
  {
    if (s390_function_arg_pass_by_reference (mode, type))
        return 0;
*************** s390_function_arg (CUMULATIVE_ARGS * cum
*** 2698,2716 ****
  }
  
  
! /* Create the va_list datatype.
  
!    On S/390, va_list is a structure of four elements:
  
!       __gpr:  number of general purpose registers used for arguments
!       __fpr:  number of floating point registers used for arguments
!       __overflow_arg_area:  
!               address of area holding arguments that are not 
!               passed in a register
!       __reg_save_area:  
!               address of register save area; the function prologue
!               saves all registers used for argument passing into this
!               area, if the function uses variable arguments.  */
  
  tree
  s390_build_va_list ()
--- 2799,2825 ----
  }
  
  
! /* Create and return the va_list datatype.
  
!    On S/390, va_list is an array type equivalent to
  
!       typedef struct __va_list_tag
!         {
!             long __gpr;
!             long __fpr;
!             void *__overflow_arg_area;
!             void *__reg_save_area;
!             
!         } va_list[1];
! 
!    where __gpr and __fpr hold the number of general purpose
!    or floating point arguments used up to now, respectively,
!    __overflow_arg_area points to the stack location of the 
!    next argument passed on the stack, and __reg_save_area
!    always points to the start of the register area in the
!    call frame of the current function.  The function prologue
!    saves all registers used for argument passing into this
!    area if the function uses variable arguments.  */
  
  tree
  s390_build_va_list ()
*************** s390_build_va_list ()
*** 2749,2767 ****
    return build_array_type (record, build_index_type (size_zero_node));
  }
  
! /* Implement va_start. 
  
     The following global variables are used to initalize
     the va_list structure:
  
       current_function_args_info:
!        holds number of gprs and fprs used for arguments.
       current_function_arg_offset_rtx:
!        holds the offset to the overflow argument area on the stack 
         (relative to the virtual arg pointer).  */
  
  void
! s390_va_start (int stdarg_p, tree valist, rtx nextarg)
  {
    HOST_WIDE_INT n_gpr, n_fpr;
    int off;
--- 2858,2882 ----
    return build_array_type (record, build_index_type (size_zero_node));
  }
  
! /* Implement va_start by filling the va_list structure VALIST.
!    STDARG_P is true if implementing __builtin_stdarg_va_start,
!    false if implementing __builtin_varargs_va_start.  NEXTARG
!    points to the first anonymous stack argument.
  
     The following global variables are used to initalize
     the va_list structure:
  
       current_function_args_info:
!        holds number of gprs and fprs used for named arguments.
       current_function_arg_offset_rtx:
!        holds the offset of the first anonymous stack argument
         (relative to the virtual arg pointer).  */
  
  void
! s390_va_start (stdarg_p, valist, nextarg)
!      int stdarg_p;
!      tree valist;
!      rtx nextarg ATTRIBUTE_UNUSED;
  {
    HOST_WIDE_INT n_gpr, n_fpr;
    int off;
*************** s390_va_start (int stdarg_p, tree valist
*** 2818,2824 ****
    expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
  }
  
! /* Implement va_arg.  
     
     Generates code equivalent to:
     
--- 2933,2941 ----
    expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
  }
  
! /* Implement va_arg by updating the va_list structure 
!    VALIST as required to retrieve an argument of type
!    TYPE, and returning that argument. 
     
     Generates code equivalent to:
     
*************** s390_va_start (int stdarg_p, tree valist
*** 2841,2847 ****
     } */
  
  rtx
! s390_va_arg (tree valist, tree type)
  {
    tree f_gpr, f_fpr, f_ovf, f_sav;
    tree gpr, fpr, ovf, sav, reg, t, u;
--- 2958,2966 ----
     } */
  
  rtx
! s390_va_arg (valist, type)
!      tree valist;
!      tree type;
  {
    tree f_gpr, f_fpr, f_ovf, f_sav;
    tree gpr, fpr, ovf, sav, reg, t, u;
*************** s390_va_arg (tree valist, tree type)
*** 3000,3082 ****
    return addr_rtx;
  }
  
- /* Do what is necessary for `va_start'.  The argument is ignored;
-    we look at the current function to determine if stdarg or varargs
-    is used.  */
- 
- rtx
- s390_builtin_saveregs (arglist)
-      tree arglist ATTRIBUTE_UNUSED;
- {
-   rtx off, block, dest, tmp;
-   tree fntype = TREE_TYPE (current_function_decl);
- 
-   int stdarg = (TYPE_ARG_TYPES (fntype) != 0
- 		&& (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
- 		    != void_type_node));
- 
-   /* Allocate the va_list block.  */
- 
-   block = assign_stack_local (BLKmode, 4 * UNITS_PER_WORD, BITS_PER_WORD);
-   RTX_UNCHANGING_P (block) = 1;
-   RTX_UNCHANGING_P (XEXP (block, 0)) = 1;
- 
-   /* Store the # of named gpr and fpr in 1st and 2nd word of va_list.  */
- 
-   dest = change_address (block, ptr_mode, 
- 			 plus_constant (XEXP (block, 0), 0));
-   emit_move_insn (dest, GEN_INT (current_function_args_info.gprs));
-   dest = change_address (block, ptr_mode, 
- 			 plus_constant (XEXP (block, 0), UNITS_PER_WORD));
-   emit_move_insn (dest, GEN_INT (current_function_args_info.fprs));
- 
-   /* Store the address of the overflow area in 3rd word of va_list.  */
- 
-   if (stdarg)
-     off = current_function_arg_offset_rtx;
-   else
-     {
-       if (GET_CODE (current_function_arg_offset_rtx) != CONST_INT) 
-         {
-           debug_rtx (current_function_arg_offset_rtx);
-           abort ();
-         }
-     
-       if (INTVAL (current_function_arg_offset_rtx) != 0)
-         off = gen_rtx_CONST_INT (Pmode,
-     			      INTVAL (current_function_arg_offset_rtx)-
- 			      UNITS_PER_WORD);
-       else
-         off = current_function_arg_offset_rtx;
-     }
- 
-   dest = change_address (block, ptr_mode,
- 			 plus_constant (XEXP (block, 0),
-                                         2 * UNITS_PER_WORD));
- 
-   tmp = expand_binop (Pmode, add_optab, virtual_incoming_args_rtx,
- 		      off,
- 		      dest, 0, OPTAB_WIDEN);
-   if (tmp != dest)
-     emit_move_insn (dest, tmp);
- 
-   /* Store the address of the register save area in 4th word of va_list.  */
- 
-   dest = change_address (block, ptr_mode,
- 			 plus_constant (XEXP (block, 0),
-                                         3 * UNITS_PER_WORD));
- 
-   tmp = expand_binop (Pmode, add_optab, virtual_incoming_args_rtx,
- 		      GEN_INT (-STACK_POINTER_OFFSET),
- 		      dest, 0, OPTAB_WIDEN);
-   if (tmp != dest)
-     emit_move_insn (dest, tmp);
- 
-   /* Return the address of the va_list block.  */
- 
-   return XEXP (block, 0);
- }
- 
  
  /* Output assembly code for the trampoline template to
     stdio stream FILE.
--- 3119,3124 ----
*************** s390_builtin_saveregs (arglist)
*** 3085,3091 ****
     gpr 0 is used to hold the static chain.  */
  
  void
! s390_trampoline_template (FILE * file)
  {
    if (TARGET_64BIT)
      {
--- 3127,3134 ----
     gpr 0 is used to hold the static chain.  */
  
  void
! s390_trampoline_template (file)
!      FILE *file;
  {
    if (TARGET_64BIT)
      {
diff -r -c -p gcc-3.0.1/gcc/config/s390/s390.h gcc-3.0.1-s390/gcc/config/s390/s390.h
*** gcc-3.0.1/gcc/config/s390/s390.h	Fri Aug 10 13:10:05 2001
--- gcc-3.0.1-s390/gcc/config/s390/s390.h	Fri Aug 10 21:40:46 2001
*************** if (INTEGRAL_MODE_P (MODE) &&	        	 
*** 218,224 ****
  
  /* Standard register usage.  */
   
! #define INT_REGNO_P(N)   ( (N) >= 0 && (N) < 16 )
  #ifdef IEEE_FLOAT
  #define FLOAT_REGNO_P(N) ( (N) >= 16 && (N) < 32 )
  #else
--- 218,224 ----
  
  /* Standard register usage.  */
   
! #define INT_REGNO_P(N)   ( (int)(N) >= 0 && (N) < 16 )
  #ifdef IEEE_FLOAT
  #define FLOAT_REGNO_P(N) ( (N) >= 16 && (N) < 32 )
  #else
*************** CUMULATIVE_ARGS;
*** 814,820 ****
  #define FUNCTION_PROFILER(FILE, LABELNO) 			\
  do {                                     			\
    extern rtx s390_profile[];  					\
!   extern s390_pool_count;     					\
    rtx tmp;                                    			\
    static char label[128];                     			\
    fprintf (FILE, "# function profiler \n");   			\
--- 813,819 ----
  #define FUNCTION_PROFILER(FILE, LABELNO) 			\
  do {                                     			\
    extern rtx s390_profile[];  					\
!   extern int s390_pool_count;     				\
    rtx tmp;                                    			\
    static char label[128];                     			\
    fprintf (FILE, "# function profiler \n");   			\
*************** do {                                    
*** 1537,1543 ****
     After generation of rtl, the compiler makes no further distinction
     between pointers and any other objects of this machine mode.  */
  
! #define Pmode (TARGET_64BIT ? DImode : SImode)
  
  /* A function address in a call instruction is a byte address (for
     indexing purposes) so give the MEM rtx a byte's mode.  */
--- 1536,1542 ----
     After generation of rtl, the compiler makes no further distinction
     between pointers and any other objects of this machine mode.  */
  
! #define Pmode ((enum machine_mode) (TARGET_64BIT ? DImode : SImode))
  
  /* A function address in a call instruction is a byte address (for
     indexing purposes) so give the MEM rtx a byte's mode.  */
*************** do {                                    
*** 1709,1716 ****
     since it hasn't been defined!  */
   
  extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
-  
- extern int s390_match_ccmode PARAMS ((struct rtx_def *, int));
  
  
  /* How to refer to registers in assembler output.  This sequence is
--- 1708,1713 ----
diff -r -c -p gcc-3.0.1/gcc/config/s390/s390.md gcc-3.0.1-s390/gcc/config/s390/s390.md
*** gcc-3.0.1/gcc/config/s390/s390.md	Fri Aug 10 13:10:09 2001
--- gcc-3.0.1-s390/gcc/config/s390/s390.md	Fri Aug 10 21:40:46 2001
***************
*** 796,801 ****
--- 796,804 ----
  
        case 4: /* m <- m */
          return \"mvc\\t%O0(16,%R0),%1\";
+ 
+       default:
+         abort();
      }
  }"
    [(set_attr "op_type" "NN,NN,RS,RS,SS")
***************
*** 873,878 ****
--- 876,884 ----
  
        case 4: /* m <- m */
          return \"mvc\\t%O0(8,%R0),%1\";
+ 
+       default:
+         abort();
       }
  }"
    [(set_attr "op_type" "NN,NN,RS,RS,SS")
***************
*** 1085,1090 ****
--- 1091,1099 ----
  
        case 6: /* m <- m */
          return \"mvc\\t%O0(8,%R0),%1\";
+ 
+       default:
+         abort();
       }
  }"
    [(set_attr "op_type" "RR,RX,RX,RS,RS,NN,SS")
***************
*** 1132,1137 ****
--- 1141,1149 ----
  
        case 3: /* m <- m */
          return \"mvc\\t%O0(8,%R0),%1\";
+ 
+       default:
+         abort();
      }
  }"
    [(set_attr "op_type" "NN,RS,RS,SS")
***************
*** 2440,2446 ****
  
    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 (0x100000000ULL, DFmode))));
--- 2452,2458 ----
  
    operands[1] = force_reg (DFmode,operands[1]);
    emit_insn (gen_cmpdf (operands[1], force_const_mem (DFmode,
! 	CONST_DOUBLE_FROM_REAL_VALUE (0x80000000ULL, DFmode))));
    emit_jump_insn (gen_blt (label1));
    emit_insn (gen_subdf3 (temp, operands[1], force_const_mem (DFmode,
  	CONST_DOUBLE_FROM_REAL_VALUE (0x100000000ULL, DFmode))));
***************
*** 2581,2587 ****
  
    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 (0x100000000ULL, SFmode))));
--- 2593,2599 ----
  
    operands[1] = force_reg (SFmode, operands[1]);
    emit_insn (gen_cmpsf (operands[1], force_const_mem (SFmode,
! 	CONST_DOUBLE_FROM_REAL_VALUE (0x80000000ULL, SFmode))));
    emit_jump_insn (gen_blt (label1));
    emit_insn (gen_subsf3 (temp, operands[1], force_const_mem (SFmode,
  	CONST_DOUBLE_FROM_REAL_VALUE (0x100000000ULL, SFmode))));
***************
*** 2667,2673 ****
        rtx temp  = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
        rtx two31 = force_const_mem (DFmode,
                                     gen_rtx (CONST_DOUBLE, VOIDmode, cc0_rtx,
!                                             0x80000000, 0x4E000000));
  
        emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
        DONE;
--- 2679,2685 ----
        rtx temp  = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
        rtx two31 = force_const_mem (DFmode,
                                     gen_rtx (CONST_DOUBLE, VOIDmode, cc0_rtx,
!                                             0x80000000U, 0x4E000000U));
  
        emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
        DONE;
***************
*** 5655,5672 ****
                   operand_subword (operands[1], 1, 0,
                   TARGET_64BIT ? TImode : DImode));
    emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
-   DONE;
- }")
- 
- 
- (define_expand "eh_epilogue"
-   [(use (match_operand 0 "register_operand" ""))
-    (use (match_operand 1 "register_operand" ""))
-    (use (match_operand 2 "register_operand" ""))]
-  ""
-  "
- {
-   s390_expand_eh_epilogue (operands[0], operands[1], operands[2]);
    DONE;
  }")
  
--- 5687,5692 ----
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de



More information about the Gcc-patches mailing list