From 44571d6e4642d00a7adeb9564c838ac500eeabbc Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Wed, 27 Nov 2002 02:34:15 +0000 Subject: 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 --- gcc/ChangeLog | 11 +++++++++ gcc/config/pa/pa-protos.h | 1 + gcc/config/pa/pa.c | 61 ++++++++++++++++++++++++++++++++++++++++++----- gcc/config/pa/pa.h | 14 +---------- gcc/config/pa/pa.md | 10 ++++---- 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 + * 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 + * 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)) -- cgit v1.1