Patchwork [AVR] Hookize LIBCALL_VALUE and FUNCTION_VALUE_REGNO_P

login
register
mail settings
Submitter Anatoly Sokolov
Date March 16, 2011, 9:25 p.m.
Message ID <72714667.20110317002538@post.ru>
Download mbox | patch
Permalink /patch/87310/
State New
Headers show

Comments

Anatoly Sokolov - March 16, 2011, 9:25 p.m.
Hello.

  This patch removes obsolete LIBCALL_VALUE and FUNCTION_VALUE_REGNO_P macros 
from AVR back end in the GCC and introduces equivalent TARGET_LIBCALL_VALUE 
and TARGET_FUNCTION_VALUE_REGNO_P target hooks.

        * config/avr/avr.h (RET_REGISTER, LIBCALL_VALUE,
        FUNCTION_VALUE_REGNO_P): Remove.
        * config/avr/avr-protos.h (avr_ret_register, avr_libcall_value):
        Remove.
        * config/avr/avr.c (avr_ret_register): Make static inline.
        (avr_function_value_regno_p): New function.
        (avr_libcall_value): Make static. Add 'func' argument.
        (avr_function_value): Make static. Rename 'func' argument to
        'fn_decl_or_type', forward it to avr_libcall_value. Use
        avr_ret_register function instead of RET_REGISTER macro.
        (TARGET_LIBCALL_VALUE, TARGET_FUNCTION_VALUE_REGNO_P): Define.




Anatoly.
Georg-Johann Lay - March 16, 2011, 9:46 p.m.
Anatoly Sokolov schrieb:

>  /* Returns register number for function return value.*/
>  
> -int
> +static inline int
>  avr_ret_register (void)
>  {
>    return 24;
>  }

I always wondered why that works.

SI is returned in r22..r25 (not in r24..27)
DI is returnet in r18..r25 (not in r24..31)

So according to docs, possible return regs are 18, 22, 24.

http://gcc.gnu.org/onlinedocs/gccint/Scalar-Return.html#index-TARGET_005fFUNCTION_005fVALUE_005fREGNO_005fP-4158

<>
TARGET_FUNCTION_VALUE_REGNO_P

A target hook that return true if regno is the number of a hard register 
in which the values of called function may come back.

A register whose use for returning values is limited to serving as the 
second of a pair (for a value of type double, say) need not be 
recognized by this target hook.
</>

Johann
Richard Henderson - March 17, 2011, 4:25 p.m.
On 03/16/2011 02:46 PM, Georg-Johann Lay wrote:
> Anatoly Sokolov schrieb:
> 
>>  /* Returns register number for function return value.*/
>>  
>> -int
>> +static inline int
>>  avr_ret_register (void)
>>  {
>>    return 24;
>>  }
> 
> I always wondered why that works.
> 
> SI is returned in r22..r25 (not in r24..27)
> DI is returnet in r18..r25 (not in r24..31)
> 
> So according to docs, possible return regs are 18, 22, 24.

It doesn't, quite.  But value_regno_p isn't used for much anymore.

Probably the most important thing remaining is in keep_with_call_p,
where we attempt to prevent the lifetime of a return value from
being extended too much.

Otherwise it's only used in __builtin_apply, which I continue to 
hope we can eliminate.

Anyway, for the benefit of keep_with_call_p, you're best off matching
all register numbers between 18 and 25.  That allows the Right Thing
to happen even if the DImode value is completely decomposed into its
QImode subregs.

Anatoly, I'll go ahead and approve the patch as-is, given that it is
an exact translation of the current state of the backend.  Any logic
fixes to the backend can be done with separate patches.


r~

Patch

Index: gcc/config/avr/avr-protos.h
===================================================================
--- gcc/config/avr/avr-protos.h	(revision 171049)
+++ gcc/config/avr/avr-protos.h	(working copy)
@@ -23,7 +23,6 @@ 
 
 extern int function_arg_regno_p (int r);
 extern void avr_cpu_cpp_builtins (struct cpp_reader * pfile);
-extern int avr_ret_register (void);
 extern enum reg_class avr_regno_reg_class (int r);
 extern void asm_globalize_label (FILE *file, const char *name);
 extern void avr_asm_declare_function_name (FILE *, const char *, tree);
@@ -85,7 +84,6 @@ 
 
 extern int extra_constraint_Q (rtx x);
 extern int adjust_insn_length (rtx insn, int len);
-extern rtx avr_libcall_value (enum machine_mode mode);
 extern const char *output_reload_inhi (rtx insn, rtx *operands, int *len);
 extern const char *output_reload_insisf (rtx insn, rtx *operands, int *len);
 extern enum reg_class secondary_input_reload_class (enum reg_class,
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c        (revision 171049)
+++ gcc/config/avr/avr.c        (working copy)
@@ -75,6 +75,8 @@ 
 static void avr_asm_function_begin_epilogue (FILE *);
 static bool avr_cannot_modify_jumps_p (void);
 static rtx avr_function_value (const_tree, const_tree, bool);
+static rtx avr_libcall_value (enum machine_mode, const_rtx);
+static bool avr_function_value_regno_p (const unsigned int);
 static void avr_insert_attributes (tree, tree *);
 static void avr_asm_init_sections (void);
 static unsigned int avr_section_type_flags (tree, const char *, int);
@@ -166,8 +168,14 @@ 
 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
+
 #undef TARGET_FUNCTION_VALUE
 #define TARGET_FUNCTION_VALUE avr_function_value
+#undef TARGET_LIBCALL_VALUE
+#define TARGET_LIBCALL_VALUE avr_libcall_value
+#undef TARGET_FUNCTION_VALUE_REGNO_P
+#define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
+
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
@@ -5910,36 +5918,49 @@ 
 
 /* Returns register number for function return value.*/
 
-int
+static inline int
 avr_ret_register (void)
 {
   return 24;
 }
 
+/* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
+
+static bool
+avr_function_value_regno_p (const unsigned int regno)
+{
+  return (regno == avr_ret_register ());
+}
+
 /* Create an RTX representing the place where a
    library function returns a value of mode MODE.  */
 
-rtx
-avr_libcall_value (enum machine_mode mode)
+static rtx
+avr_libcall_value (enum machine_mode mode,
+                  const_rtx func ATTRIBUTE_UNUSED)
 {
   int offs = GET_MODE_SIZE (mode);
   if (offs < 2)
     offs = 2;
-  return gen_rtx_REG (mode, RET_REGISTER + 2 - offs);
+  return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
 }
 
 /* Create an RTX representing the place where a
    function returns a value of data type VALTYPE.  */
 
-rtx
-avr_function_value (const_tree type, 
-                   const_tree func ATTRIBUTE_UNUSED, 
+static rtx
+avr_function_value (const_tree type, const_tree fn_decl_or_type,
                    bool outgoing ATTRIBUTE_UNUSED)
 {
   unsigned int offs;
-  
+  const_rtx func = fn_decl_or_type;
+
+  if (fn_decl_or_type
+      && !DECL_P (fn_decl_or_type))
+  fn_decl_or_type = NULL;
+
   if (TYPE_MODE (type) != BLKmode)
-    return avr_libcall_value (TYPE_MODE (type));
+    return avr_libcall_value (TYPE_MODE (type), func);
   
   offs = int_size_in_bytes (type);
   if (offs < 2)
@@ -5949,7 +5970,7 @@ 
   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
     offs = GET_MODE_SIZE (DImode);
   
-  return gen_rtx_REG (BLKmode, RET_REGISTER + 2 - offs);
+  return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
 }
 
 int
Index: gcc/config/avr/avr.h
===================================================================
--- gcc/config/avr/avr.h        (revision 171049)
+++ gcc/config/avr/avr.h        (working copy)
@@ -380,12 +380,6 @@ 
 
 extern int avr_reg_order[];
 
-#define RET_REGISTER avr_ret_register ()
-
-#define LIBCALL_VALUE(MODE)  avr_libcall_value (MODE)
-
-#define FUNCTION_VALUE_REGNO_P(N) ((int) (N) == RET_REGISTER)
-
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
 #define EPILOGUE_USES(REGNO) avr_epilogue_uses(REGNO)