This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: HP-UX IA64 Patch to fix earlier patch
- From: Steve Ellcey <sje at cup dot hp dot com>
- To: dave at hiauly1 dot hia dot nrc dot ca
- Cc: gcc at gcc dot gnu dot org, wilson at redhat dot com, law at redhat dot com
- Date: Tue, 19 Nov 2002 13:35:55 -0800 (PST)
- Subject: Re: HP-UX IA64 Patch to fix earlier patch
> I agree with Jim here. Not too long ago, I used this technique to avoid
> defining FUNCTION_ARG_REG_LITTLE_ENDIAN on the hppa64 port. I also
> managed to fix a long standing bug in the 32-bit port passing small
> structs using the same technique. Jim's comment is an over simplification
> of what really happens when a DImode value is used in a PARALLEL on
> big-endian 32-port. You actually get right-justified data in this case.
> See function_arg and function_arg_padding in pa.c.
>
> Dave
Dave,
I am working on using the PARALLEL method for IA64 they way you did on
PA64 so we can get rid of FUNCTION_ARG_REG_LITTLE_ENDIAN and noticed
that on PA64 you use it in function_arg to handle arguments but there is
nothing to handle function return values and I think we need it there
too to handle returns of small structures.
Based on my testing calling a function that returns a structure
containing a single char field currently doesn't work when when the
callee is compiled by the HP compiler and the caller by GNU (or the
other way around).
I tried changing the macro FUNCTION_VALUE to call a function_value
routine and then use gen_rtx_PARALLEL in that routine to handle small
structures but I get errors when compiling after I do this. The same
method in function_value seems to work for IA64 but not for PA64 where I
get a reload error.
Here is a patch (pa-protos.h, pa.h, pa.c) that does not work. It fails
to compile a caller calling a function with a struct value containing a
single char field. Do you have any ideas on what the problem with this
code is or on how to fix it? I have tried some minor variations of this
code but none of them seem to work.
Steve Ellcey
sje@cup.hp.com
*** gcc.orig/gcc/config/pa/pa-protos.h Tue Nov 19 13:22:47 2002
--- gcc/gcc/config/pa/pa-protos.h Tue Nov 19 13:23:53 2002
*************** extern int reloc_needed PARAMS ((tree));
*** 158,163 ****
--- 158,164 ----
#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,
*** gcc.orig/gcc/config/pa/pa.h Tue Nov 19 13:22:51 2002
--- gcc/gcc/config/pa/pa.h Tue Nov 19 13:25:09 2002
*************** extern struct rtx_def *hppa_pic_save_rtx
*** 730,748 ****
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 how to find the value returned by a library function
assuming the value has mode MODE. */
--- 730,736 ----
If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is 0. */
! #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. */
*** gcc.orig/gcc/config/pa/pa.c Tue Nov 19 13:22:53 2002
--- gcc/gcc/config/pa/pa.c Tue Nov 19 13:27:49 2002
*************** insn_refs_are_delayed (insn)
*** 7677,7682 ****
--- 7677,7723 ----
&& 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;
+
+ valmode = TYPE_MODE (valtype);
+
+ if (TREE_CODE (valtype) == REAL_TYPE
+ && TYPE_MODE (valtype) != TFmode
+ && !TARGET_SOFT_FLOAT)
+ return gen_rtx_REG (valmode, 32);
+
+ if (TARGET_64BIT
+ && valtype && AGGREGATE_TYPE_P (valtype)
+ && (int_size_in_bytes (valtype) < UNITS_PER_WORD))
+ {
+ rtx ret_expr = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (word_mode, 28),
+ const0_rtx);
+ return gen_rtx_PARALLEL (BLKmode, gen_rtvec (1, ret_expr));
+ }
+
+ if ((INTEGRAL_TYPE_P (valtype)
+ && TYPE_PRECISION (valtype) < BITS_PER_WORD)
+ || POINTER_TYPE_P (valtype))
+ valmode = word_mode;
+
+ 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.