Subject: GCC can't deal with 68060. How do I turn off caches?
To: None <m68k@NetBSD.ORG>
From: Robert Dick <dickrp@dickrp.remote.princeton.edu>
List: m68k
Date: 01/20/1997 04:12:55
This message is a repeat.  I made a typo when posting the
first time that resulted in a posting without a subject.

----
Most pressing question:  Does anyone know a system-friendly way of disabling
the 68060's caches for a short period of time in NetBSD?

----
Bug 1:
I have known about this first problem for a while and I reported it to
the FSF months ago.  GCC 2.7.2 (and 2.7.2.1) makes assumptions about the
cache on a m68k which are incorrect for the 68060.  This results in
incorrect behavior when nested functions are used.  I ran into this under
ADE's AmigaOS gcc port and had hoped that things were better in NetBSD but
the GCC that comes with 1.2 exhibits this problem, too.  I tried compiling
the ``current'' GCC at ftp.warped.com but it isn't currently in a buildable
state.  It isn't likely that this problem was fixed, though, because I
looked the related trampoline code and it looks the same as in the vanilla
2.7.0 distribution.

This nested function test from the GStep distribution code executes
correctly when single-stepped through using GDB.  It also runs correctly
under AmigaOS when I disable CPU caches.

  int main() {
    int a = 2; void nested(int b) { a += b; }
    void doit(void(*f)(int)) { (*f)(4); } doit(nested);
    if (a != 6) exit(-1); exit(0);
  }

If it is run normally, it results in a segmentation violation or a
completely hung machine. As a consequence, it is not possible to use the
GStep Objective-C class library or nested functions on a 68060.

----
Bug 2:
Like I said, I have known about [bug 1] for a while.  The real reason for
this posting is a more serious problem which appears to be cache-related.  I
explained the first problem primarily to point out that GCC definitely
can't handle a 68060 properly.  I have spent _alot_ of time trying to find
causes for the following odd behavior in my own code and it looks like it's
compiler-related but I can't narrow it down enough to provide a proper bug
report.

I recently ran into a problem with a large project I am working on using G++
2.7.2.1 with the BSD-specific Cygnus template repository patch.
It involves a Boolean expression embedded in a mass of code:
  ...
  (list.exists("Fred") && list.exists("Gene"))
  ...
When the program is run under GDB, this expression evaluates to
1 (as it should). When normally executed, it evaluates to 0.  I tried to
simplify the code while still triggering the incorrect behavior but I have
not been able to do so. Something as simple as evaluating the two cases in
separate expressions causes their evaluations to be correct.  Changes made
to preceding or following statements cause the behavior of the program to be
correct.  Even failing to link in seemingly unrelated object files results
in correct execution. The code executes correctly on another architecture
(686).

Also, this messes up:
  ...
  char dummie[256];
  (list.exists("Fred") && list.exists("Gene"))
  ...

And this messes up:
  ...
  char dummie[512];
  (list.exists("Fred") && list.exists("Gene"))
  ...

But I haven't been able to find any other powers of 2 that
are less than 256 and cause incorrect evaluation.
The List class is a template class with no virtual functions.
The problem is exhibited even when `exists()' ignores its argument
and returns 1 in all cases.

This smells like a cache problem.  I can't include the code
here because there is just too much of it and I can't pull out
the offending code without changing its behavoir.  I may be able
to track this down eventually by poking through the assembly but
if anyone has any ideas, I would be most grateful for them.

----
Is there a NetBSD-friendly way to turn off the bits of the 68060 that GCC
doesn't understand for the duration of a program's run and reactivate them
after the program finishes execution?  I don't want to rebuild the kernel
with all caches disabled because I'll have a 68060 running at the speed of a
68030 although, if that's my only option to get correct execution of GCC
compiled code, I'll do it.  Also, if there are any m68k/GCC wizards reading
this, I would appreciate pointers to possible culprits in GCC.  Even if I
can't fix this (within a reasonable amount of time) I would really like
to know what the possible causes are because at present, my machine isn't
worth much as a research tool; I don't trust the results it yields.

Thanks!

-Robert Dick-
Amiga 3000
Cyberstorm MK-II 68060-50
NetBSD-1.2