]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/pa/pa.c
Merge tree-ssa-20020619-branch into mainline.
[thirdparty/gcc.git] / gcc / config / pa / pa.c
index 3d3b1ae0733a116a9c677c448d2e87fd8237f193..0cc1ed7eb99d8a2165c3683ad83345b9789bd6f0 100644 (file)
@@ -131,6 +131,7 @@ static void pa_asm_out_constructor (rtx, int);
 static void pa_asm_out_destructor (rtx, int);
 #endif
 static void pa_init_builtins (void);
+static rtx hppa_builtin_saveregs (void);
 static void copy_fp_args (rtx) ATTRIBUTE_UNUSED;
 static int length_fp_args (rtx) ATTRIBUTE_UNUSED;
 static struct deferred_plabel *get_plabel (const char *)
@@ -148,6 +149,7 @@ static void output_deferred_plabels (void);
 #ifdef HPUX_LONG_DOUBLE_LIBRARY
 static void pa_hpux_init_libfuncs (void);
 #endif
+static rtx pa_struct_value_rtx (tree, int);
 
 /* Save the operands last given to a compare for use when we
    generate a scc or bcc insn.  */
@@ -261,6 +263,19 @@ static size_t n_deferred_plabels = 0;
 #define TARGET_INIT_LIBFUNCS pa_hpux_init_libfuncs
 #endif
 
+#undef TARGET_PROMOTE_FUNCTION_RETURN
+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+#undef TARGET_PROMOTE_PROTOTYPES
+#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
+
+#undef TARGET_STRUCT_VALUE_RTX
+#define TARGET_STRUCT_VALUE_RTX pa_struct_value_rtx
+#undef TARGET_RETURN_IN_MEMORY
+#define TARGET_RETURN_IN_MEMORY pa_return_in_memory
+
+#undef TARGET_EXPAND_BUILTIN_SAVEREGS
+#define TARGET_EXPAND_BUILTIN_SAVEREGS hppa_builtin_saveregs
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 void
@@ -577,9 +592,6 @@ move_src_operand (rtx op, enum machine_mode mode)
   if (register_operand (op, mode))
     return 1;
 
-  if (GET_CODE (op) == CONSTANT_P_RTX)
-    return 1;
-
   if (GET_CODE (op) == CONST_INT)
     return cint_ok_for_move (INTVAL (op));
 
@@ -1085,7 +1097,7 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
   if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
       && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))
-      && (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == 'o'
+      && (OBJECT_P (XEXP (x, 1))
          || GET_CODE (XEXP (x, 1)) == SUBREG)
       && GET_CODE (XEXP (x, 1)) != CONST)
     {
@@ -1493,7 +1505,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
      We have to do this because the REG_POINTER flag is not correctly
      carried through various optimization passes and CSE may substitute
      a pseudo without the pointer set for one with the pointer set.  As
-     a result, we loose various opportunites to create insns with
+     a result, we loose various opportunities to create insns with
      unscaled indexed addresses.  */
   if (!TARGET_NO_SPACE_REGS
       && !cse_not_expected
@@ -1975,10 +1987,13 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
        {
          rtx insn, temp;
          rtx op1 = operand1;
-         HOST_WIDE_INT value = INTVAL (operand1);
+         HOST_WIDE_INT value = 0;
          HOST_WIDE_INT insv = 0;
          int insert = 0;
 
+         if (GET_CODE (operand1) == CONST_INT)
+           value = INTVAL (operand1);
+
          if (TARGET_64BIT
              && GET_CODE (operand1) == CONST_INT
              && HOST_BITS_PER_WIDE_INT > 32
@@ -2174,7 +2189,7 @@ read_only_operand (rtx operand, enum machine_mode mode ATTRIBUTE_UNUSED)
 
 \f
 /* Return the best assembler insn template
-   for moving operands[1] into operands[0] as a fullword.   */
+   for moving operands[1] into operands[0] as a fullword.  */
 const char *
 singlemove_string (rtx *operands)
 {
@@ -2637,7 +2652,7 @@ find_addr_reg (rtx addr)
    OPERANDS[3] is a register for temporary storage.
    OPERANDS[4] is the size as a CONST_INT
    OPERANDS[5] is the alignment safe to use, as a CONST_INT.
-   OPERANDS[6] is another temporary register.   */
+   OPERANDS[6] is another temporary register.  */
 
 const char *
 output_block_move (rtx *operands, int size_is_constant ATTRIBUTE_UNUSED)
@@ -3124,7 +3139,7 @@ output_ascii (FILE *file, const char *p, int size)
 {
   int i;
   int chars_output;
-  unsigned char partial_output[16];    /* Max space 4 chars can occupy.   */
+  unsigned char partial_output[16];    /* Max space 4 chars can occupy.  */
 
   /* The HP assembler can only take strings of 256 characters at one
      time.  This is a limitation on input line length, *not* the
@@ -5536,8 +5551,8 @@ emit_hpdiv_const (rtx *operands, int unsignedp)
 
       emit_move_insn (gen_rtx_REG (SImode, 26), operands[1]);
       emit
-       (gen_rtx
-        (PARALLEL, VOIDmode,
+       (gen_rtx_PARALLEL
+        (VOIDmode,
          gen_rtvec (6, gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, 29),
                                     gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
                                                     SImode,
@@ -5836,7 +5851,7 @@ function_arg_padding (enum machine_mode mode, tree type)
    to determine if stdargs or varargs is used and fill in an initial
    va_list.  A pointer to this constructor is returned.  */
 
-struct rtx_def *
+static rtx
 hppa_builtin_saveregs (void)
 {
   rtx offset, dest;
@@ -6707,7 +6722,7 @@ output_dbra (rtx *operands, rtx insn, int which_alternative)
   else
     {
       /* Reload loop counter from memory, the store back to memory
-        happens in the branch's delay slot.   */
+        happens in the branch's delay slot.  */
       output_asm_insn ("ldw %0,%4", operands);
       if (get_attr_length (insn) == 12)
        return "addib,%C2 %1,%4,%3\n\tstw %4,%0";
@@ -6810,7 +6825,7 @@ output_movb (rtx *operands, rtx insn, int which_alternative,
   else if (which_alternative == 2)
     {
       /* Reload loop counter from memory, the store back to memory
-        happens in the branch's delay slot.   */
+        happens in the branch's delay slot.  */
       if (get_attr_length (insn) == 8)
        return "{comb|cmpb},%S2 %%r0,%1,%3\n\tstw %1,%0";
       else
@@ -8401,7 +8416,7 @@ pa_reorg (void)
         markers disables output of the branch table to readonly memory,
         and any alignment directives that might be needed.  Possibly,
         the begin_brtab insn should be output before the label for the
-        table.  This doesn matter at the moment since the tables are
+        table.  This doesn't matter at the moment since the tables are
         always output in the text section.  */
       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
        {
@@ -8748,7 +8763,7 @@ insn_refs_are_delayed (rtx insn)
    the mode is SF or DF. Then the value is returned in fr4 (32).
 
    This must perform the same promotions as PROMOTE_MODE, else
-   PROMOTE_FUNCTION_RETURN will not work correctly.
+   TARGET_PROMOTE_FUNCTION_RETURN will not work correctly.
 
    Small structures must be returned in a PARALLEL on PA64 in order
    to match the HP Compiler ABI.  */
@@ -9058,7 +9073,6 @@ pa_select_section (tree exp, int reloc,
       && !reloc)
     readonly_data_section ();
   else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c'
-          && !(TREE_CODE (exp) == STRING_CST && flag_writable_strings)
           && !reloc)
     readonly_data_section ();
   else
@@ -9077,4 +9091,31 @@ pa_globalize_label (FILE *stream, const char *name)
     fputs (",DATA\n", stream);
   }
 }
+
+/* Worker function for TARGET_STRUCT_VALUE_RTX.  */
+
+static rtx
+pa_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
+                    int incoming ATTRIBUTE_UNUSED)
+{
+  return gen_rtx_REG (Pmode, PA_STRUCT_VALUE_REGNUM);
+}
+
+/* Worker function for TARGET_RETURN_IN_MEMORY.  */
+
+bool
+pa_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+{
+  /* SOM ABI says that objects larger than 64 bits are returned in memory.
+     PA64 ABI says that objects larger than 128 bits are returned in memory.
+     Note, int_size_in_bytes can return -1 if the size of the object is
+     variable or larger than the maximum value that can be expressed as
+     a HOST_WIDE_INT.   It can also return zero for an empty type.  The
+     simplest way to handle variable and empty types is to pass them in
+     memory.  This avoids problems in defining the boundaries of argument
+     slots, allocating registers, etc.  */
+  return (int_size_in_bytes (type) > (TARGET_64BIT ? 16 : 8)
+         || int_size_in_bytes (type) <= 0);
+}
+
 #include "gt-pa.h"