This is the mail archive of the crossgcc@cygnus.com mailing list for the crossgcc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

egcs-1.1: fix for volatile bug



On Mon, 11 Jan 1999, Mark Powell wrote:
>  The following bug was observed in egcs-1.1b and egcs-1.1.1 configured
>  for m68k-coff.
>  
>  Assignment operations through a pointer variable declared volatile
>  produce multiple accesses. This can cause incorrect behaviour when the
>  destination of the write is a register in a peripheral device and the
>  device expects a series of values to be written to the same address.
>  
>  The bug is triggered when compiling with no optimisation. Optimisation
>  levels of -O1 and above do not exhibit the bug.

For info, the bug is fixed in current snapshots.

The fix was well commented so I was able to narrow it down very quickly.
A patch for egcs-1.1.1 is attached. It should apply to egcs-1.1b
equally well.

Mark

-- 
Mark Powell, Senior Software Engineer, Primagraphics Limited
New Cambridge House, Litlington, nr.Royston, Herts, SG8 0SS, UK
Tel. +44 1763 852222, Fax. 853324, medp@primag.co.uk, http://www.primag.co.uk

*** ../egcs-1.1.1-medp1/gcc/expr.c	Tue Oct 27 00:05:28 1998
--- gcc/expr.c	Tue Dec 29 11:36:18 1998
***************
*** 3457,3466 ****
  
    /* If value was not generated in the target, store it there.
       Convert the value to TARGET's type first if nec.  */
  
    if ((! rtx_equal_p (temp, target)
!        || side_effects_p (temp)
!        || side_effects_p (target))
        && TREE_CODE (exp) != ERROR_MARK)
      {
        target = protect_from_queue (target, 1);
--- 3658,3678 ----
  
    /* If value was not generated in the target, store it there.
       Convert the value to TARGET's type first if nec.  */
+   /* If TEMP and TARGET compare equal according to rtx_equal_p, but
+      one or both of them are volatile memory refs, we have to distinguish
+      two cases:
+      - expand_expr has used TARGET.  In this case, we must not generate
+        another copy.  This can be detected by TARGET being equal according
+        to == .
+      - expand_expr has not used TARGET - that means that the source just
+        happens to have the same RTX form.  Since temp will have been created
+        by expand_expr, it will compare unequal according to == .
+        We must generate a copy in this case, to reach the correct number
+        of volatile memory references.  */
  
    if ((! rtx_equal_p (temp, target)
!        || (temp != target && (side_effects_p (temp)
! 			      || side_effects_p (target))))
        && TREE_CODE (exp) != ERROR_MARK)
      {
        target = protect_from_queue (target, 1);