Port-atari archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

gcc4 problem on netbsd-4



[start a new thread]

I wrote in article <081229084450.M0108632%mirage.ceres.dti.ne.jp@localhost>:

> Okay, then we have to fix gcc4 issue on netbsd-4 before tracking
> wdc/dma issue on the HEAD. Maybe our sources might have some problem,
> rather than gcc4.
> 
> gcc4 is so aggressive on optimization and strictly requires C99
> that variables lacking volatile or statements which are invalid
> or undefined in C99 scope could be removed during optimization.
> 
> The major changes between netbsd-4 and HEAD are:
> (a) MI softintr(9) and yamt-splraiseipl merge
> (b) MI todr(9) and timecounter(9)
> (c) bus_space_handle_t type change (char * -> u_long)
> (d) caddr_t purge
> 
> I'll check sources around (a) and (b) again.

I have not confirmed, but it looks atari/dev/clock.c:delay()
in netbsd-4 may have a problem:

---
        /*
         * Calculate ((n * TIMER_FREQ) / 1e6) using explicit assembler code so
         * we can take advantage of the intermediate 64-bit quantity to prevent
         * loss of significance.
         */
        n -= 5;
        if(n < 0)
                return;
        {
            u_int       temp;
                
            __asm volatile ("mulul %2,%1:%0" : "=d" (n), "=d" (temp)
                                               : "d" (TIMB_FREQ), "d" (n));
            __asm volatile ("divul %1,%2:%0" : "=d" (n)
                                               : "d"(1000000),"d"(temp),"0"(n));
        }
---

In this code block, variable "temp" might be passed to
__asm statements without initialization, so
it could cause unexpected too long delays.

We could just add "u_int temp = 0;" to initialize it,
but in -current that code block has been replaced with
(more human readable) C code.

Could you try this one?
http://www.ceres.dti.ne.jp/~tsutsui/netbsd/netbsd-ATARITT-4.0_STABLE-20081231.gz
http://www.ceres.dti.ne.jp/~tsutsui/netbsd/netbsd-FALCON-4.0_STABLE-20081231.gz

Index: dev/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/dev/clock.c,v
retrieving revision 1.37
diff -u -r1.37 clock.c
--- dev/clock.c 24 Dec 2005 20:06:58 -0000      1.37
+++ dev/clock.c 31 Dec 2008 17:20:18 -0000
@@ -333,10 +333,9 @@
  * Note: timer had better have been programmed before this is first used!
  */
 void
-delay(n)
-int    n;
+delay(unsigned int n)
 {
-       int     ticks, otick;
+       int     ticks, otick, remaining;
 
        /*
         * Read the counter first, so that the rest of the setup overhead is
@@ -344,28 +343,25 @@
         */
        otick = MFP->mf_tbdr;
 
-       /*
-        * Calculate ((n * TIMER_FREQ) / 1e6) using explicit assembler code so
-        * we can take advantage of the intermediate 64-bit quantity to prevent
-        * loss of significance.
-        */
-       n -= 5;
-       if(n < 0)
-               return;
-       {
-           u_int       temp;
-               
-           __asm volatile ("mulul %2,%1:%0" : "=d" (n), "=d" (temp)
-                                              : "d" (TIMB_FREQ), "d" (n));
-           __asm volatile ("divul %1,%2:%0" : "=d" (n)
-                                              : "d"(1000000),"d"(temp),"0"(n));
+       if (n <= UINT_MAX / TIMB_FREQ) {
+               /*
+                * For unsigned arithmetic, division can be replaced with
+                * multiplication with the inverse and a shift.
+                */
+               remaining = n * TIMB_FREQ / 1000000;
+       } else {
+               /* This is a very long delay.
+                * Being slow here doesn't matter.
+                */
+               remaining = (unsigned long long) n * TIMB_FREQ / 1000000;
        }
 
-       while(n > 0) {
+       while(remaining > 0) {
                ticks = MFP->mf_tbdr;
                if(ticks > otick)
-                       n -= TIMB_LIMIT - (ticks - otick);
-               else n -= otick - ticks;
+                       remaining -= TIMB_LIMIT - (ticks - otick);
+               else
+                       remaining -= otick - ticks;
                otick = ticks;
        }
 }
Index: include/param.h
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/include/param.h,v
retrieving revision 1.30
diff -u -r1.30 param.h
--- include/param.h     11 Dec 2005 12:16:59 -0000      1.30
+++ include/param.h     31 Dec 2008 17:20:18 -0000
@@ -112,7 +112,7 @@
 
 #include <machine/intr.h>
 
-void delay __P((int));
+void delay __P((unsigned int));
 
 #define        DELAY(n)        delay(n)
 #endif /* _KERNEL */

---


Home | Main Index | Thread Index | Old Index