calls.c patch to fix mn102/mn103 bugs

Jeffrey A Law law@hurl.cygnus.com
Tue Feb 16 20:43:00 GMT 1999


The mn102 and mn103 are (as far as I know) the only ports which define
ACCUMULATE_OUTGOING_ARGS but which can not pass all arguments to a library
call in registers.

At one time, this caused the compiler to abort.  So we went into
expand_library_call and added argument slot saving code similar to what is
found in expand_call.  ie, we keep a record of which argument slots have
useful values in them and emit code to save the value in the argument slot
if we are going to clobber it.

It turns out we're not saving these argument slots in one case.  It is possible
for the expansion of an argument expression from tree -> rtl to create a
library call which overwrites values stored into its own argument slot.

Consider:


long a,b,c,d;
int
foo ()
{
  arf (123, ((!a) | b) >> (c < (a - d)), 1);
}

(a - d) on the mn102 will trigger a libcall which will clobber an argument
slot.  However, we've already put ((!a) | b) into that slot -- we clobber
((!a) | b) and end up with incorrect code.

Luckily this problem is easily solved.  In store_expr we need to mark the
slot for the stack argument as in-use before we call expand_expr to expand
the argument.  Thus if expanding the argument requires a libcall the libcall
will know the stack slot for the current argument may already contain a value.


        * calls.c (store_one_arg): Mark any slots used for the argument
        as in-use immediately after we're done saving any slots which
        will be overwritten by this argument. 

Index: gcc/calls.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/calls.c,v
retrieving revision 1.139
diff -c -3 -p -r1.139 calls.c
*** calls.c	1999/01/20 17:50:17	1.139
--- calls.c	1999/02/17 04:33:48
*************** store_one_arg (arg, argblock, may_be_all
*** 3557,3562 ****
--- 3557,3570 ----
  	    }
  	}
      }
+ 
+   /* Now that we have saved any slots that will be overwritten by this
+      store, mark all slots this store will use.  We must do this before
+      we actually expand the argument since the expansion itself may
+      trigger library calls which might need to use the same stack slot.  */
+   if (argblock && ! variable_size && arg->stack)
+     for (i = lower_bound; i < upper_bound; i++)
+       stack_usage_map[i] = 1;
  #endif
  
    /* If this isn't going to be placed on both the stack and in registers,
*************** store_one_arg (arg, argblock, may_be_all
*** 3732,3742 ****
    preserve_temp_slots (NULL_RTX);
    free_temp_slots ();
    pop_temp_slots ();
- 
- #ifdef ACCUMULATE_OUTGOING_ARGS
-   /* Now mark the segment we just used.  */
-   if (argblock && ! variable_size && arg->stack)
-     for (i = lower_bound; i < upper_bound; i++)
-       stack_usage_map[i] = 1;
- #endif
  }
--- 3740,3743 ----


More information about the Gcc-patches mailing list