[gnu.gcc.bug] Optimizing is deleting the extra return register

jkp@SAUNA.HUT.FI (Jyrki Kuoppala) (06/13/89)

I made the following changes to gcc to have it return pointer values
also in a0 in addition to d0.  This is required by some compilers.
Everything works fine when compiling without -O (that is, the movel
d0,a0 instruction is generated), but when -O is used the instruction
isn't there any more.

Isn't the REG_FUNCTION_VALUE_P enough to mark the register so that the
optimizer shouldn't touch it ?  Or can't it be used on multiple
registers ?

I looked at the macro FUNCTION_OUTGOING_VALUE but I don't see a way to
make that macro to generate the extra instruction to copy d0 to a0.

The changes I made:

//Jyrki

*** /usr2/users/jkp/stmt.c	Tue Jun 13 06:41:53 1989
--- stmt.c	Tue Jun 13 04:58:44 1989
***************
*** 4689,4694 ****
--- 4689,4702 ----
        use_variable (outgoing);
      }
  
+   /* If FUNCTION_OUTVALUE_EXTRA is defined, it is executed after the function
+      return value has been but into the appropriate register.
+      This macro can be used to return the value also in some other
+      register than the real one for compatibility with other compilers. */
+ #ifdef FUNCTION_OUTVALUE_EXTRA
+   FUNCTION_OUTVALUE_EXTRA (current_function_decl);
+ #endif
+ 
    /* Output a return insn if we are using one.
       Otherwise, let the rtl chain end here, to drop through
       into the epilogue.  */
*** /usr2/users/jkp/tm-altos3068.h	Tue Jun 13 06:43:13 1989
--- config/tm-altos3068.h	Tue Jun 13 06:10:17 1989
***************
*** 92,94 ****
--- 92,107 ----
       fprintf (FILE, "#0r%.20g", (VALUE))
  
  #define USE_GAS
+ /* The Altos C compiler returns pointer values both in d0 and a0
+    and assumes that pointers are returned in a0.  So, gcc should
+    also return pointers both in d0 and a0 */
+ #define FUNCTION_OUTVALUE_EXTRA(FUNC)	\
+ { rtx read_decl_result;							\
+   if ((TYPE_MODE (TREE_TYPE (DECL_RESULT (FUNC)))) == Pmode) {		\
+        read_decl_result = gen_rtx (REG, Pmode, 8);   			\
+        REG_FUNCTION_VALUE_P (read_decl_result) = 1;			\
+        emit_move_insn (read_decl_result,				\
+ 		       DECL_RTL (DECL_RESULT (FUNC))); } }