On Sun, 1 Mar 2020 09:23:45 +0900
rgc <[email protected]> wrote:
> 'time sleep 1' takes ages. painfully slow. 'date' after rebooting the
> test kernel is way way off. from the looks of things it never
> advanced.
ppc_mftb() in /sys/arch/powerpc/include/cpu.h is broken with clang.
My one macppc machine, the iMac G3, has hardware trouble, so I turned
it off. My amd64 desktop has ports-clang (from pkg_add clang), which
includes the PowerPC backend, so I can copy ppc_mftb() into a file and
generate PowerPC assembly code.
$ alias pang='/usr/local/bin/clang -target ppc-openbsd'
$ cat exam.c
typedef unsigned long long u_int64_t;
typedef unsigned long u_long;
static __inline u_int64_t
ppc_mftb(void)
{
u_long scratch;
u_int64_t tb;
__asm volatile ("1: mftbu %0; mftb %0+1; mftbu %1;"
" cmpw 0,%0,%1; bne 1b" : "=r"(tb), "=r"(scratch));
return tb;
}
u_int64_t
f(void)
{
u_int64_t tb = ppc_mftb();
return (tb >> 32) | (tb << 32);
}
$ pang -S -O2 exam.c
My function f() swaps the words in the time base, should return the
upper word (mftbu) in %r4 and the lower word in %r3. The generated
code "exam.s" fails to set %r3; the inline __asm turned into,
.Ltmp1:
mfspr 4, 269
mfspr 5, 268
mfspr 5, 269
cmpw 4, 5
bne 0, .Ltmp1
which is wrong because the lower word "mfspr %r5, 268" is lost when
the upper word "mfspr %r5, 269" clobbers %r5. (The code loops until
the upper words in %r4 and %r5 are equal.) If your clang kernel lost
the lower word of the time base, then time might stop.
I suspect that "mftb %0+1" fails because clang doesn't always choose
register %0+1 to hold the lower word of "=r"(tb).
This might work:
static __inline u_int64_t
ppc_mftb(void)
{
u_long high, low, scratch;
__asm volatile ("1: mftbu %0; mftb %1; mftbu %2;"
" cmpw 0,%0,%2; bne 1b" : "=r"(high), "=r"(low), "=r"(scratch));
return ((u_int64_t)high << 32) | low;
}