On Sun, Jul 10, 2011 at 7:32 AM, Uros Bizjak <ubiz...@gmail.com> wrote: > On Sat, Jul 9, 2011 at 11:28 PM, H.J. Lu <hongjiu...@intel.com> wrote: > >> X32 psABI requires promoting pointers to Pmode when passing/returning >> in registers. OK for trunk? >> >> Thanks. >> >> H.J. >> -- >> 2011-07-09 H.J. Lu <hongjiu...@intel.com> >> >> * config/i386/i386.c (ix86_promote_function_mode): New. >> (TARGET_PROMOTE_FUNCTION_MODE): Likewise. >> >> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c >> index 04cb07d..c852719 100644 >> --- a/gcc/config/i386/i386.c >> +++ b/gcc/config/i386/i386.c >> @@ -7052,6 +7061,23 @@ ix86_function_value (const_tree valtype, const_tree >> fntype_or_decl, >> return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode); >> } >> >> +/* Pointer function arguments and return values are promoted to >> + Pmode. */ >> + >> +static enum machine_mode >> +ix86_promote_function_mode (const_tree type, enum machine_mode mode, >> + int *punsignedp, const_tree fntype, >> + int for_return) >> +{ >> + if (for_return != 1 && type != NULL_TREE && POINTER_TYPE_P (type)) >> + { >> + *punsignedp = POINTERS_EXTEND_UNSIGNED; >> + return Pmode; >> + } >> + return default_promote_function_mode (type, mode, punsignedp, fntype, >> + for_return); >> +} > > Please rewrite the condition to: > > if (for_return == 1) > /* Do not promote function return values. */ > ; > else if (type != NULL_TREE && ...) > > Also, please add some comments. > > Your comment also says that pointer return arguments are promoted to > Pmode. The documentation says that: > > FOR_RETURN allows to distinguish the promotion of arguments and > return values. If it is `1', a return value is being promoted and > `TARGET_FUNCTION_VALUE' must perform the same promotions done here. > If it is `2', the returned mode should be that of the register in > which an incoming parameter is copied, or the outgoing result is > computed; then the hook should return the same mode as > `promote_mode', though the signedness may be different. > > You bypass promotions when FOR_RETURN is 1. > > Uros. >
Here is the updated patch. OK for trunk? Thanks. -- H.J. -- 2011-07-10 H.J. Lu <hongjiu...@intel.com> * config/i386/i386.c (ix86_promote_function_mode): New. (TARGET_PROMOTE_FUNCTION_MODE): Likewise. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 04cb07d..1b02312 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2973,6 +2973,9 @@ ix86_option_override_internal (bool main_args_p) SUBSUBTARGET_OVERRIDE_OPTIONS; #endif + if (TARGET_X32) + ix86_isa_flags |= OPTION_MASK_ISA_64BIT; + /* -fPIC is the default for x86_64. */ if (TARGET_MACHO && TARGET_64BIT) @@ -7052,6 +7061,27 @@ ix86_function_value (const_tree valtype, const_tree fntype_or_decl, return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode); } +/* Pointer function arguments and return values are promoted to Pmode. + If FOR_RETURN is 1, this function must behave in the same way with + regard to function returns as TARGET_FUNCTION_VALUE. */ + +static enum machine_mode +ix86_promote_function_mode (const_tree type, enum machine_mode mode, + int *punsignedp, const_tree fntype, + int for_return) +{ + if (for_return == 1) + /* Do not promote function return values. */ + ; + else if (type != NULL_TREE && POINTER_TYPE_P (type)) + { + *punsignedp = POINTERS_EXTEND_UNSIGNED; + return Pmode; + } + return default_promote_function_mode (type, mode, punsignedp, fntype, + for_return); +} + rtx ix86_libcall_value (enum machine_mode mode) { @@ -34810,6 +35157,9 @@ ix86_autovectorize_vector_sizes (void) #undef TARGET_FUNCTION_VALUE_REGNO_P #define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p +#undef TARGET_PROMOTE_FUNCTION_MODE +#define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode + #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD ix86_secondary_reload