[comp.arch] unexpected CPU behavior was 486 bugs -- it's in there!

bruner@sp15.csrd.uiuc.edu (John Bruner) (05/25/90)

In article <2813@medusa.informatik.uni-erlangen.de>, csbrod@medusa (Claus Brod ) writes:
>Motorola's 68000 had a kind of quirk that caused a clr command to
>first read the addressed location and then clear it. This led
>to numerous difficulties when clearing I/O registers. This one,
>however, has always been documented by Motorola, so it's more
>a feature than a bug. Subsequent 680x0s perform a clr operation
>as God intended.

The 68000 was not the only machine to have this particular quirk.  The
CLR instruction on (at least some models of) the PDP-11 also was
implemented by reading memory and then writing zero.  This was a
consequence of implementing CLR as a single-operand instruction in the
same category as, e.g. increment.

In addition to its unexpected effects upon device registers, another
problem with the 11's CLR was that it could not be used to initialize
main memory from an unknown state (e.g., when the machine was rebooted
the first time after being turned on): the reads were likely to
encounter bad parity and cause a trap.  This was a more visible
problem when semiconductor memories replaced core.  (The work-around
was to initialize memory by moving zero.)

alvitar@xavax.com (Phillip Harbison) (05/27/90)

In article <2813@medusa.informatik.uni-erlangen.de>, csbrod@medusa (Claus
Brod) writes:
> Motorola's 68000 had a kind of quirk that caused a clr command to
> first read the addressed location and then clear it. This led
> to numerous difficulties when clearing I/O registers. This one,
> however, has always been documented by Motorola, so it's more
> a feature than a bug. Subsequent 680x0s perform a clr operation
> as God intended.

I never considered this to be a big problem.  As you noted, Motorola
documented this behavior, and anyone who really cared would use the
"move quick" alternative (MOVEQ #0,destination).  Since the constant
value (8 bits signed) was included in the instruction word, I don't
believe there was any advantage to CLR versus MOVEQ.

-- 
Live: Phil Harbison, Xavax, P.O. Box 7413, Huntsville, AL 35807
Uucp: alvitar@xavax.com
Bell: 205-539-1672, 205-880-8951

dswartz@bigbootay.sw.stratus.com (Dan Swartzendruber) (05/28/90)

In article <1990May27.110726.17007@xavax.com> alvitar@xavax.com (Phillip Harbison) writes:
:In article <2813@medusa.informatik.uni-erlangen.de> csbrod@medusa (Claus
>Brod) writes:
:: Motorola's 68000 had a kind of quirk that caused a clr command to
:: first read the addressed location and then clear it. This led
:: to numerous difficulties when clearing I/O registers. This one,
:: however, has always been documented by Motorola, so it's more
:: a feature than a bug. Subsequent 680x0s perform a clr operation
:: as God intended.
:
:I never considered this to be a big problem.  As you noted, Motorola
:documented this behavior, and anyone who really cared would use the
:"move quick" alternative (MOVEQ #0,destination).  Since the constant
:value (8 bits signed) was included in the instruction word, I don't
:believe there was any advantage to CLR versus MOVEQ.
:

Please reread your 680x0 assembler manual.  MOVEQ only works on
data registers.  Either you clear a data register (with MOVEQ)
and move it to the destination, or you move a literal zero there.

The former costs an extra instruction.  The latter isn't much better,
especially when you're clearing a longword, as this embeds a four
byte constant in the instruction.

:-- 
:Live: Phil Harbison, Xavax, P.O. Box 7413, Huntsville, AL 35807
:Uucp: alvitar@xavax.com
:Bell: 205-539-1672, 205-880-8951

--

Dan S.

dolf@idca.tds.PHILIPS.nl (Dolf Grunbauer) (05/28/90)

In article <1990May27.110726.17007@xavax.com> alvitar@xavax.com (Phillip Harbison) writes:
>In article <2813@medusa.informatik.uni-erlangen.de>, csbrod@medusa (Claus
>Brod) writes:
>> Motorola's 68000 had a kind of quirk that caused a clr command to
>> first read the addressed location and then clear it. This led
>> to numerous difficulties when clearing I/O registers. This one,
>> however, has always been documented by Motorola, so it's more
>> a feature than a bug.
>I never considered this to be a big problem.  As you noted, Motorola
>documented this behavior, and anyone who really cared would use the
>"move quick" alternative (MOVEQ #0,destination).  Since the constant
>value (8 bits signed) was included in the instruction word, I don't
>believe there was any advantage to CLR versus MOVEQ.

I think Phillip is missing the point as the MOVEQ allows only a Data
Register (D0 - D7) as destination, not just any memory address.
So I believe the CLR is a big problem as the C compiler I had compiled:
    some_IO_reg = 0;
into
    clr.b some_IO_reg
which is not what I wanted as a read of this volatile I/O register
has some side effects (to be precise: Bus Error as it was a write
only I/O register). There was no way to tell the compiler to use a
    move.b #0,some_IO_reg
Note that this was on a mc68000/68008 before ANSI C (i.e. volatile)
-- 
Dolf Grunbauer      Tel: +31 55 433233 Internet dolf@idca.tds.philips.nl
Philips Information Systems            UUCP     ...!mcsun!philapd!dolf
Dept. BS Software,  P.O. Box 245, 7300 AE Apeldoorn, The Netherlands 
read: error in reading .signature

aglew@dwarfs.csg.uiuc.edu (Andy Glew) (05/28/90)

..> Motorola's 68000 clr instruction quirk that read the addressed
..> location before clearing it - causing problems for active
..> memory mapped I/O locations.

Comment: isn't this the sort of thing that comes with using the same
instructions for I/O access as for memory?  For memory access all we
care about is the data returned or written - for I/O you have to
specify exactly what bus transactions are used.
    It is perfectly reasonable to read before write for a clear
instruction.  Wasteful, but legitimate - it doesn't change the
semantics from the point of view of what is actually written in
memory. And it might be necessary, say, if you are doing a clear-byte
operation, and your bus is word-wide, without partial writes.  In that
case, for memory mapped I/O you might expect the memory controller to
handle the active memory locations specially - but isn't it possible
that a special I/O instruction might make the distinction more easily?

--
Andy Glew, aglew@uiuc.edu

dolf@idca.tds.PHILIPS.nl (Dolf Grunbauer) (05/28/90)

In article <AGLEW.90May27215556@dwarfs.csg.uiuc.edu> aglew@dwarfs.csg.uiuc.edu (Andy Glew) writes:
<..> Motorola's 68000 clr instruction quirk that read the addressed
<..> location before clearing it - causing problems for active
<..> memory mapped I/O locations.
<
<Comment: isn't this the sort of thing that comes with using the same
<instructions for I/O access as for memory?  For memory access all we
<care about is the data returned or written - for I/O you have to
<specify exactly what bus transactions are used.
<[..deleted..]
<case, for memory mapped I/O you might expect the memory controller to
<handle the active memory locations specially - but isn't it possible
<that a special I/O instruction might make the distinction more easily?

Obviously yes, but if you don't want to program in assembler how do you tell
the difference to your (pre-ANSI C) compiler ? 
-- 
Dolf Grunbauer      Tel: +31 55 433233 Internet dolf@idca.tds.philips.nl
Philips Information Systems            UUCP     ...!mcsun!philapd!dolf
Dept. BS Software,  P.O. Box 245, 7300 AE Apeldoorn, The Netherlands 
read: error in reading .signature

roy@phri.nyu.edu (Roy Smith) (05/28/90)

aglew@dwarfs.csg.uiuc.edu (Andy Glew) writes:
>> 68000 clr instruction quirk that read the addressed location before
>> clearing it - causing problems for active memory mapped I/O locations.
> Comment: isn't this the sort of thing that comes with using the same
> instructions for I/O access as for memory?

	No, this is the sort of thing which comes from having write-only
and read-only registers share the same bus address.  Even on machines with
very small I/O address spaces (4k on the pdp-11, I think it was) I never
saw a configuration where you came close to filling the I/O address space.
What harm could it really do to turn a 4-address controller with hairy
twinned control and status registers into an 8-address one on which it was
safe to do read-before-write cycles?
--
Roy Smith, Public Health Research Institute
455 First Avenue, New York, NY 10016
roy@alanine.phri.nyu.edu -OR- {att,cmcl2,rutgers,hombre}!phri!roy
"Arcane?  Did you say arcane?  It wouldn't be Unix if it wasn't arcane!"

news@haddock.ima.isc.com (overhead) (05/30/90)

In article <1990May27.110726.17007@xavax.com> alvitar@xavax.com (Phillip Harbison) writes:
>In article <2813@medusa.informatik.uni-erlangen.de>, csbrod@medusa (Claus
>Brod) writes:
>> Motorola's 68000 had a kind of quirk that caused a clr command to
>> first read the addressed location and then clear it. This led
>
>I never considered this to be a big problem.  As you noted, Motorola
>documented this behavior, and anyone who really cared would use the
>"move quick" alternative (MOVEQ #0,destination).  Since the constant

I remember it being quite an ugly problem because of a C compiler that
used the CLR instead of MOVEQ.  The hardware group in my company had
mapped a read-only and a write-only I/O port to the same address to
save a bit of wire.  Trying to set the write only port to 0 caused a
destructive read of the read-only port.  I only heard about this after
the case because I was still programming in assembler and knew to
avoid the CLR with I/O.

Jim

alix@cerl.uiuc.edu (Chris Alix) (05/30/90)

In article <16744@haddock.ima.isc.com> (Jim McGrath) writes:
>> [Previous Posting about 68000 CLR instruction reading before writing]
>
>I remember it being quite an ugly problem because of a C compiler that
>used the CLR instead of MOVEQ.  The hardware group in my company had
>mapped a read-only and a write-only I/O port to the same address to
>save a bit of wire.  Trying to set the write only port to 0 caused a
>destructive read of the read-only port.  I only heard about this after
>the case because I was still programming in assembler and knew to
>avoid the CLR with I/O.

My (obvious) work-around (temp is unsigned char, ioaddr is an unsigned
char * to the device i/o register):

	temp = 0;
	*ioaddr = temp;

...which my compiler doesn't optimize into a CLR instruction.  the CLR
instruction behavior isn't a "bug" in the sense that Motorola describes it
in the manual, but I'd venture to guess that it wasn't an intentional
part of the original architecture specification.  Given the number of
device driver programmers who have been tripped up by an overzealous
optimizer in the case at hand, combined with the lack of situations in
which I have found the behavior useful, I consider the operation of
CLR a "mistake".

--------------------------------------------------------------------------
Christopher Alix                               E-mail: alix@uiuc.edu
University of Illinois                  PLATO/NovaNET: alix / s / cerl
Computer-Based Education Research Lab           Phone: (217) 333-7439
103 S. Mathews  Urbana, IL  61820                 Fax: (217) 244-0793
--------------------------------------------------------------------------

stevem@sauron.Columbia.NCR.COM (Steve McClure) (05/30/90)

In article <16744@haddock.ima.isc.com> jimm@ima.isc.com (Jim McGrath) writes:
|In article <1990May27.110726.17007@xavax.com> alvitar@xavax.com (Phillip Harbison) writes:
|>In article <2813@medusa.informatik.uni-erlangen.de>, csbrod@medusa (Claus
|>Brod) writes:
|>> Motorola's 68000 had a kind of quirk that caused a clr command to
|>> first read the addressed location and then clear it. This led
|>
|>I never considered this to be a big problem.  As you noted, Motorola
|>documented this behavior, and anyone who really cared would use the
|>"move quick" alternative (MOVEQ #0,destination).  Since the constant
|
|I remember it being quite an ugly problem because of a C compiler that
|used the CLR instead of MOVEQ.  The hardware group in my company had
|mapped a read-only and a write-only I/O port to the same address to
|save a bit of wire.  Trying to set the write only port to 0 caused a
|destructive read of the read-only port.  I only heard about this after
|the case because I was still programming in assembler and knew to
|avoid the CLR with I/O.

C compilers seem to keep doing this.  I instinctively set a variable to 0 and
do the assignment.  You find this situation just about anytime you want to do
hardware level stuff.



-- 
----------------------------------------------------------------------
Steve		email: Steve.McClure@Columbia.NCR.COM	803-791-7054
The above are my opinions, which NCR doesn't really care about anyway!
CAUSER's Amiga BBS! | 803-796-3127 | 8pm-8am 8n1 | 300/1200/2400

dswartz@bigbootay.sw.stratus.com (Dan Swartzendruber) (05/31/90)

I don't quite understand your comment: "...C compilers seem to
keep doing this..."  Please satisfy my naive curiosity.  What is
wrong with "*p = 0;" generating a "clr (a0)" or somesuch.  When
you have an instruction which is defined a zeroing its operand,
this seems a rather obvious use to me!  If the original microcoders
made a silly mistake by sharing the single-operand RMW microcode
for this instruction without documenting it (and BTW, I do have an
OLD manual where the footnote is missing from the clr page.), that
is hardly grounds for slandering C compiler writers who expected the
instruction to work as documented.  Do you feel that it is more
intuitive to declare a variable whose sole purpose is to be zeroed
and then assigned to the destination???


--

Dan S.

jbuck@carson.berkeley.edu (Joe Buck) (05/31/90)

In article <1429@lectroid.sw.stratus.com>,
dswartz@bigbootay.sw.stratus.com (Dan Swartzendruber) writes:
> I don't quite understand your comment: "...C compilers seem to
> keep doing this..."  Please satisfy my naive curiosity.  What is
> wrong with "*p = 0;" generating a "clr (a0)" or somesuch.  When
> you have an instruction which is defined a zeroing its operand,
> this seems a rather obvious use to me!

Nothing is wrong with it.  If p points to a device register, it should
be declared

	volatile int *p;

The C compiler would then be told that the memory p points to is
"unusual" (it can change out from under you, etc) and wouldn't use
a RMW clear instruction in this case.  But there's no reason to forbid
the C compiler from ever generating clears, or in trying to fool
it into generating the right code with temporaries.

One of the main reasons for "volatile" is so you can optimize
device drivers.

This is getting pretty C-specific.  But it shows that compilers
can do the right thing if given enough information.
--
Joe Buck
jbuck@ohm.berkeley.edu	 {uunet,ucbvax}!ohm.berkeley.edu!jbuck	

dswartz@bigbootay.sw.stratus.com (Dan Swartzendruber) (05/31/90)

Keep in mind most of the places that had this problem with
the 68000 had it ~7-10 years ago.  At this point in time,
few if any C compilers had the volatile keyword.

--

Dan S.

philip@Kermit.Stanford.EDU (Philip Machanick) (05/31/90)

In article <1431@lectroid.sw.stratus.com>,
dswartz@bigbootay.sw.stratus.com (Dan Swartzendruber) writes:
> Keep in mind most of the places that had this problem with
> the 68000 had it ~7-10 years ago.  At this point in time,
> few if any C compilers had the volatile keyword.

Yes, like cfront 2.0.

Philip Machanick
philip@pescadero.stanford.edu

boyne@hplvli.HP.COM (Art Boyne) (05/31/90)

csbrod@medusa.informatik.uni-erlangen.de (Claus Brod ) writes:

>Motorola's 68000 had a kind of quirk that caused a clr command to
                  ^^^
Try "has" - the 68000 has never been fixed, and it *still* is a
pain to clear I/O registers to 0 when using a compiler that likes
to optimize "x = 0" to a CLR instruction.

>first read the addressed location and then clear it. This led
>to numerous difficulties when clearing I/O registers. This one,
>however, has always been documented by Motorola, so it's more
>a feature than a bug.

It is documented, true, but a pain nevertheless, and still bites
people using HLL's.  After 7 years programming the 68000, and helping
others do so, believe me, I know!

Art Boyne, boyne@hplvla.hp.com

alvitar@xavax.com (Phillip Harbison) (06/02/90)

In article <16744@haddock.ima.isc.com> jimm@ima.isc.com (Jim McGrath) writes:
> In article <1990May27.110726.17007@xavax.com> alvitar@xavax.com (Phillip
> Harbison) writes:
> > In article <2813@medusa.informatik.uni-erlangen.de>, csbrod@medusa (Claus
> > Brod) writes:
> > > Motorola's 68000 had a kind of quirk that caused a clr command to
> > > first read the addressed location and then clear it. This led
> > I never considered this to be a big problem.  As you noted, Motorola
> > documented this behavior ...
> I remember it being quite an ugly problem because of a C compiler that
> used the CLR instead of MOVEQ.  The hardware group in my company had
> mapped a read-only and a write-only I/O port to the same address to
> save a bit of wire.  Trying to set the write only port to 0 caused a
> destructive read of the read-only port.

My crew wrote about 14,000 lines of C code for a telecommunications
system.  This was an embedded control application where the code
manipulated alot of hardware registers, most of which were write-only. 
I don't recall any problems, but then, the hardware designers were wise
enough to only strobe the registers on a write cycle.  The compilers
used were Green Hills C and the native compiler for 68000 Xenix.  Maybe
we were just lucky. :-)

-- 
Live: Phil Harbison, Xavax, P.O. Box 7413, Huntsville, AL 35807
Uucp: alvitar@xavax.com
Bell: 205-539-1672, 205-880-8951

jack@swlabs.uucp (Jack Bonn) (06/02/90)

In article <1990May28.124724.24879@phri.nyu.edu> roy@phri.nyu.edu (Roy Smith) writes:
>aglew@dwarfs.csg.uiuc.edu (Andy Glew) writes:
>	No, this is the sort of thing which comes from having write-only
>and read-only registers share the same bus address.  Even on machines with
>very small I/O address spaces (4k on the pdp-11, I think it was) I never
>saw a configuration where you came close to filling the I/O address space.

Actually, if a read-only and write-only register share the same address,
the clear instruction works properly (as long as the read-only register
has no side effects).  It is only when the write-only register is at a unique
address that the strange behavior of the CLR instructions becomes apparent.
And even then, sometimes only after some head scratching over an emulator 
trace (tracing before the bus time out).

I agree that cleaner device register definitions like this would be a big 
improvement.  Being able to read what was last written would be a clear win 
in situations where you have to restore a register as part of clean up.

But the worst case I have seen of false "chip shaving" was in a Z80 controller
for a communications device.  It had an 8K ROM segment that was split into
two non-adjacent 4K segments.  The responsible hardware engineer indicated 
that they "saved half a chip" by doing it that way.  Lots of shuffling and 
relinking was the obvious firmware result.
-- 
Jack Bonn, KC1UH, <> Software Labs, Ltd, Box 451, Easton CT  06612
uunet!swlabs!jack (UUCP)        jack%swlabs.uucp@uunet.uu.net (INTERNET)
jack@kc1uh        (TCP/IP)      kc1uh@wb1cqo                  (AX.25)

amull@Morgan.COM (Andrew P. Mullhaupt) (06/08/90)

In article <19200001@hplvli.HP.COM>, boyne@hplvli.HP.COM (Art Boyne) writes:
> csbrod@medusa.informatik.uni-erlangen.de (Claus Brod ) writes:
> 
> >Motorola's 68000 had a kind of quirk that caused a clr command to
>                   ^^^
> Try "has" - the 68000 has never been fixed, and it *still* is a
> pain to clear I/O registers to 0 when using a compiler that likes
> to optimize "x = 0" to a CLR instruction.

This thread started out lamenting the bugs in Intel chips. As an
inveterate Intel chip owner - I've been bit by those bugs, even the
B5 i486. 

What seems interesting to me is the large number of people who 
step forward to rail against the 68000 series chips too. 

I have recently had to go through a rather long list of CPU bugs
and workarounds that came with the latest SunOS fortran compiler;
and it seems that every chip manufacturer which produced processors
for the Sun machines has a bug history. I wonder if Intel is really
much worse than other companies, a claim I would have been more
willing to accept before working through a long list of FPU chips.

It looks like chip bugs are more economic in origin to me than 
the result of ignorant engineering. Any comments?

Later,
Andrew Mullhaupt