[net.micro.68k] 68000 inconsistency

breuel@harvard.ARPA (Thomas M. Breuel) (08/06/84)

Consider these two short pieces of 68000 Assembly language:

(1) 1000 MOVE.L #$04001008,A0	(2) 1000 JMP #$04001006,A0
    1006 JMP (A0)		    1006 LEA *-6,A0
    1008 LEA *-8,A0		    ...
    ...

One would expect (at least I did) A0 to contain the same value after
both LEA instructions. Reality on the 68000 (I tried it on a LISA and
a Mac) is different, though. In case (1), A0 contain $04001000, and in
case (2), A0 contains $00001000. I find this behaviour inconsistent.
Apparently, the program counter actually gets set to the 32bit number
in the first case, whereas only 24 bits are used in the second case. 

This feature is particularly noticable on the LISA and the MacIntosh,
on which most addressing is done PC-relative to make code
position-independent: PC-relative instructions use the whole 32 bits
of the program counter, and PC-relative jumps and jsr's preserve the
highest 8 bits, so that any setting of the 8 msb is preserved through
long sections of a program. The LISA/MacIntosh debugger, MWLB, however,
clears those 8 bits. Altogether, this can create pretty obscure bugs.

[The way I discovered this feature was when working on my "Infinite
Improbability Lisp Interpreter" for the MacIntosh: certain functions
called by the evaluator failed mysteriously, but only if they did not
contain debugger trace points. The RTS instruction at the end of these
subroutines restored the program counter to normality... If one of
these functions called the panic routine, though, all of a sudden the
reader and the interpreter would not recognise LISP anymore. Maybe I
should have chosen another name for the thing.]



			Thomas M. Breuel
	...{genrad!wjh12!tardis,allegra!harvard}!gallifrey!tmb

gnu@sun.uucp (John Gilmore) (08/09/84)

Using the high 8 bits of addresses for flags or other data was
traditional wisdom in the '60s on the IBM 360 but eventually it burned
them.  In the '70s when 16MB virtual wasn't enough, they built hardware
that had 31-bit addressing, but it took ANOTHER 10 years (no kidding)
to convert all the software so they could turn the hardware feature
on.

Luckily for most of us we knew when it came out that 24 bits on a 68000
was not enough and avoided playing kludge games.

Don't mess around!  An address is 32 bits, and if you depend on the
hardware to ignore the top N bits you will be burned within two years.

Now, the behaviour decribed (68000 jmp long absolute loses the top 8
bits of the jumped-to address) is certainly a bug if it's true.  But
your code should never notice since it should never use those bits.
The 68010 chip (which when packaged as a 68012 has 31 address bits)
does not have the bug.  I'm sure the 68020, with a 32-bit address bus,
doesn't have the bug either.  I don't have a 68000 around to verify
whether current rev 68000's have it.

doug@oakhill.UUCP (Doug MacGregor) (08/10/84)

The 68000 does not lose the upper 8 bits of the
address. Internally all 32-bits are significant on the 68000 regardless
of whether there are 24, 31, or 32-bits of address visible from outside
the chip. The implementation internally is the same for all cases.
I agree completely with the description given by John Gilmore as to the
motivation for not mucking with the address.
It seems highly likely that the culprit may be a program playing games
with those upper bits, it's not the processor.


Doug MacGregor		{ihnp4,seismo,gatech,ctvax}!ut-sally!oakhill!doug

breuel@harvard.ARPA (Thomas M. Breuel) (08/11/84)

Doug MacGregor (Motorolas) writes: 'The 68000 does not lose the upper 8
bits of the address'.

Well, my 68000 *does* seem to loose the upper 8 bits when loading an
absolute address from memory. Again, consider the following code
fragments (they were run as such under LisaBug, and the register
contents are what LisaBug reported):

----------

1000: 4ef9 ff00 1006	jmp $ff001006
1006: 41fa fffe		lea *,a0

	a0 = $00001006

1000: 227c ff00 1008 	move.l #$ff001008,a1
1006: 4ed1		jmp (a1)
1008: 41fa fffe		lea *,a0

	a0 = $ff001008

----------

Or is there another explanation?

						Thomas.

P.S.: About choice of implementation of type tags: given that the LISP
runs on an MacIntosh with very limited memory resources, given that the
Mac has a "fixed" architecture and is unlikely to profit from
Motorola's corrections to the 68000 (as in the 68010), and given that
the LISP performs very well speedwise, I think the choice of putting
type tags into the "unused" msb of pointers, and not explicitely
stripping them before dereferencing (except for the case of indirect
jumps :-) is justified.  Since all type reconisers and selectors are
defined as macros, this efficiency hack even leaves the program
portable.  Normally, I prefer partitioning to tagging, but in the case
of the MacIntosh there isn't much choice.



			Thomas M. Breuel
	...{genrad!wjh12!tardis,allegra!harvard}!gallifrey!tmb