aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <dave@hiauly1.hia.nrc.ca>2002-11-27 02:34:15 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2002-11-27 02:34:15 +0000
commit44571d6e4642d00a7adeb9564c838ac500eeabbc (patch)
tree5482bdf093f1e92f2e84261741b3eab84f78c930
parent084a11066f6825b040acb692ad1f17981a17f1f6 (diff)
downloadgcc-44571d6e4642d00a7adeb9564c838ac500eeabbc.zip
gcc-44571d6e4642d00a7adeb9564c838ac500eeabbc.tar.gz
gcc-44571d6e4642d00a7adeb9564c838ac500eeabbc.tar.bz2
pa-protos.h (function_value): New prototype.
* 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. From-SVN: r59555
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/pa/pa-protos.h1
-rw-r--r--gcc/config/pa/pa.c61
-rw-r--r--gcc/config/pa/pa.h14
-rw-r--r--gcc/config/pa/pa.md10
5 files changed, 73 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a657229..3067221 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
index 5d1ab11..8ea36f3 100644
--- a/gcc/config/pa/pa-protos.h
+++ b/gcc/config/pa/pa-protos.h
@@ -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,
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 034a647..0d5f111 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -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
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index d01aedf..fbbf18d 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -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. */
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index ac6bdc9..cd28ce8 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -6121,7 +6121,7 @@
}")
(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))
@@ -6138,7 +6138,7 @@
(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))
@@ -6154,7 +6154,7 @@
(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))
@@ -6376,7 +6376,7 @@
}")
(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))
@@ -6392,7 +6392,7 @@
(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))