* pa-protos.h (function_value): New prototype.
authordanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Nov 2002 02:34:15 +0000 (02:34 +0000)
committerdanglin <danglin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Nov 2002 02:34:15 +0000 (02:34 +0000)
* pa.c (function_value): Use a PARALLEL to return small aggregates on
TARGET_64BIT.
* pa.h (FUNCTION_VALUE): Use function_value.
* pa.md (call_value_internal_symref, call_value_internal_reg_64bit,
call_value_internal_reg, sibcall_value_internal_symref,
sibcall_value_internal_symref_64bit): Remove =rf constraint on return
value.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@59555 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/pa/pa-protos.h
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md

index a657229..3067221 100644 (file)
@@ -1,5 +1,16 @@
 2002-11-26  John David Anglin  <dave@hiauly1.hia.nrc.ca>
 
+       * pa-protos.h (function_value): New prototype.
+       * pa.c (function_value): Use a PARALLEL to return small aggregates on
+       TARGET_64BIT.
+       * pa.h (FUNCTION_VALUE): Use function_value.
+       * pa.md (call_value_internal_symref, call_value_internal_reg_64bit,
+       call_value_internal_reg, sibcall_value_internal_symref,
+       sibcall_value_internal_symref_64bit): Remove =rf constraint on return
+       value.
+
+2002-11-26  John David Anglin  <dave@hiauly1.hia.nrc.ca>
+
        * expr.c (gen_group_rtx, emit_group_move): New functions.
        * expr.h (gen_group_rtx, emit_group_move): Prototype.
        * function.c (expand_function_start): Use gen_group_rtx to create a
index 5d1ab11..8ea36f3 100644 (file)
@@ -158,6 +158,7 @@ extern int reloc_needed PARAMS ((tree));
 #ifdef RTX_CODE
 extern rtx function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode,
                                 tree, int, int));
+extern rtx function_value PARAMS ((tree, tree));
 #endif
 extern int function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *,
                                               enum machine_mode,
index 034a647..0d5f111 100644 (file)
@@ -7677,6 +7677,57 @@ insn_refs_are_delayed (insn)
           && get_attr_type (insn) == TYPE_MILLI));
 }
 
+/* On the HP-PA the value is found in register(s) 28(-29), unless
+   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.
+
+   Small structures must be returned in a PARALLEL on PA64 in order
+   to match the HP Compiler ABI.  */
+
+rtx
+function_value (valtype, func)
+    tree valtype;
+    tree func ATTRIBUTE_UNUSED;
+{
+  enum machine_mode valmode;
+
+  /* Aggregates with a size less than or equal to 128 bits are returned
+     in GR 28(-29).  They are left justified.  The pad bits are undefined.
+     Larger aggregates are returned in memory.  */
+  if (TARGET_64BIT && AGGREGATE_TYPE_P (valtype))
+    {
+      rtx loc[2];
+      int i, offset = 0;
+      int ub = int_size_in_bytes (valtype) <= UNITS_PER_WORD ? 1 : 2;
+
+      for (i = 0; i < ub; i++)
+       {
+         loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
+                                     gen_rtx_REG (DImode, 28 + i),
+                                     GEN_INT (offset));
+         offset += 8;
+       }
+
+      return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (ub, loc));
+    }
+
+  if ((INTEGRAL_TYPE_P (valtype)
+       && TYPE_PRECISION (valtype) < BITS_PER_WORD)
+      || POINTER_TYPE_P (valtype))
+    valmode = word_mode;
+  else
+    valmode = TYPE_MODE (valtype);
+
+  if (TREE_CODE (valtype) == REAL_TYPE
+      && TYPE_MODE (valtype) != TFmode
+      && !TARGET_SOFT_FLOAT)
+    return gen_rtx_REG (valmode, 32);
+
+  return gen_rtx_REG (valmode, 28);
+}
+
 /* Return the location of a parameter that is passed in a register or NULL
    if the parameter has any component that is passed in memory.
 
@@ -7813,12 +7864,10 @@ function_arg (cum, mode, type, named, incoming)
             or returning a DImode REG results in left justified data.  */
          if (mode == BLKmode)
            {
-             rtx loc[1];
-
-             loc[0] = gen_rtx_EXPR_LIST (VOIDmode,
-                                         gen_rtx_REG (DImode, gpr_reg_base),
-                                         const0_rtx);
-             return gen_rtx_PARALLEL (mode, gen_rtvec_v (1, loc));
+             rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
+                                          gen_rtx_REG (DImode, gpr_reg_base),
+                                          const0_rtx);
+             return gen_rtx_PARALLEL (mode, gen_rtvec (1, loc));
            }
        }
       else
index d01aedf..fbbf18d 100644 (file)
@@ -730,19 +730,7 @@ extern struct rtx_def *hppa_pic_save_rtx PARAMS ((void));
    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    otherwise, FUNC is 0.  */
 
-/* On the HP-PA the value is found in register(s) 28(-29), unless
-   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.  */
-#define FUNCTION_VALUE(VALTYPE, FUNC)                                  \
-  gen_rtx_REG (((INTEGRAL_TYPE_P (VALTYPE)                             \
-                && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD)           \
-               || POINTER_TYPE_P (VALTYPE))                            \
-               ? word_mode : TYPE_MODE (VALTYPE),                      \
-              (TREE_CODE (VALTYPE) == REAL_TYPE                        \
-               && TYPE_MODE (VALTYPE) != TFmode                        \
-               && !TARGET_SOFT_FLOAT) ? 32 : 28)
+#define FUNCTION_VALUE(VALTYPE, FUNC) function_value (VALTYPE, FUNC)
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
index ac6bdc9..cd28ce8 100644 (file)
 }")
 
 (define_insn "call_value_internal_symref"
-  [(set (match_operand 0 "" "=rf")
+  [(set (match_operand 0 "" "")
        (call (mem:SI (match_operand 1 "call_operand_address" ""))
              (match_operand 2 "" "i")))
    (clobber (reg:SI 1))
    (set (attr "length") (symbol_ref "attr_length_call (insn, 0)"))])
 
 (define_insn "call_value_internal_reg_64bit"
-  [(set (match_operand 0 "" "=rf")
+  [(set (match_operand 0 "" "")
          (call (mem:SI (match_operand:DI 1 "register_operand" "r"))
               (match_operand 2 "" "i")))
    (clobber (reg:SI 2))
    (set (attr "length") (const_int 12))])
 
 (define_insn "call_value_internal_reg"
-  [(set (match_operand 0 "" "=rf")
+  [(set (match_operand 0 "" "")
        (call (mem:SI (reg:SI 22))
              (match_operand 1 "" "i")))
    (clobber (reg:SI 1))
 }")
 
 (define_insn "sibcall_value_internal_symref"
-  [(set (match_operand 0 "" "=rf")
+  [(set (match_operand 0 "" "")
        (call (mem:SI (match_operand 1 "call_operand_address" ""))
              (match_operand 2 "" "i")))
    (clobber (reg:SI 1))
    (set (attr "length") (symbol_ref "attr_length_call (insn, 1)"))])
 
 (define_insn "sibcall_value_internal_symref_64bit"
-  [(set (match_operand 0 "" "=rf")
+  [(set (match_operand 0 "" "")
        (call (mem:SI (match_operand 1 "call_operand_address" ""))
              (match_operand 2 "" "i")))
    (clobber (reg:SI 1))