[comp.compilers] Borland Turbo C 2.0 for Atari 68000 machines: ODD behavior

carter@cs.wisc.edu (Gregory Carter) (04/06/91)

I recently had a problem with a compiler for my MEGA STE 4/50.  I was
wondering if any of you can report the same problems with Borland's
compiler?

When I attempt to move 0x03 into the address 0x00ff8e20 I get the
following:

 (unsigned int)(*((unsigned int *)0x00ff8e20L)) = 0x03;
 which translates to:
                       MOVE.W #$0003, $00ff8e20

 Ok, I expect that, thats no problem....BUT when I do this:

 (unsigned int)(*((unsigned int *)0xffff8e20L)) = 0x03;
 which translates to:
                       MOVE.W #$0003, $8e20

This is obviously not correct.

I thought about the compiler cutting 8 bits off the top half of the
address since the 68000 doesn't use this space anyway.  But, this isn't
what I expected.  Anyone know why they (BORLAND) decided to do address
coloring in this fashion?

Its a curiosity right now, but when I was going through my profs unclear,
nonportable, nonfunctional class examples, IT TICKED ME OFF. Made life
generally !pleasant.

Any help greatly appreciated.

Greg Carter
[Looks like a bug to me. -John]
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.

ckp@grebyn.com (Checkpoint Technologies) (04/08/91)

In article <1991Apr6.091013.26131@daffy.cs.wisc.edu> carter@cs.wisc.edu (Gregory Carter) writes:
> (unsigned int)(*((unsigned int *)0x00ff8e20L)) = 0x03;
>                       MOVE.W #$0003, $00ff8e20
>...
> (unsigned int)(*((unsigned int *)0xffff8e20L)) = 0x03;
>                       MOVE.W #$0003, $8e20
>
>This is obviously not correct.

This may not be obvious, but it *is* correct.  The compiler is doing you a
favor.

The 68K has "absolute short" and "absolute long" addressing.  Absolute
long means that a whole 32 bit absoluet address follows.

Absolute short means that only a 16 bit word follows, and it should be
*sign extended* to 32 bits before being used.

The value $8E20, when sign extended into a full 32 bit address becomes
$FFFF8E20.  This is just what you asked for, and the compiler found a
briefer way to code it.
-- 
ckp@grebyn.com
[brychcy@informatik.tu-muenchen.dbp.de (Till Brychcy) also pointed this out.
-John]
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.

albaugh@dms.UUCP (Mike Albaugh) (04/09/91)

	I was originally going to say the same thing, but stopped when I
actually read the question:

>From article <1991Apr8.133307.27870@grebyn.com>, by ckp@grebyn.com (Checkpoint Technologies):
> In article <1991Apr6.091013.26131@daffy.cs.wisc.edu> carter@cs.wisc.edu (Gregory Carter) writes:
>> (unsigned int)(*((unsigned int *)0xffff8e20L)) = 0x03;
>>                       MOVE.W #$0003, $8e20
>>
>>This is obviously not correct.
> 
> This may not be obvious, but it *is* correct.  The compiler is doing you a
> favor.
> [...]
> The value $8E20, when sign extended into a full 32 bit address becomes
> $FFFF8E20.  This is just what you asked for, and the compiler found a
> briefer way to code it.

	Such favors I don't need. Assuming that Greg correctly transcribed
the assembly output (rather than making a mistake dissasembling actual
machine code) the "correct" outcome from the above requires an assembler
that has some non-intuitive way of marking "I want a 32-bit address here"
and _defaults_ to using short addressess. This is definitely not the
way any of the five 68000 assemblers I have used work, and seems to me to
violate the "principle of least surprise". Now, if the assembler had
taken
	MOVE.W #$0003, $0ffff8e20

and generated a 16-bit address (as all the ones I've used do) I would
accept it as a "favor". But If I have to code

	MOVE.W	#$0003, $8e20.YES_I_REALLY_MEAN_IT

to access the equally legitimate address $00008e20, I don't consider that
a "favor". My personal suspicion is that either Greg (or one of his
software tools) mis-disassembled some machine code, or the compiler
was intended to emit a variety of 68000 assembly syntaces, and the
marker for "use short address" was accidentally omitted in his "flavor".
The second scenario also postulates an intended assembler that is _not_
smart enough to figure it out for itself, so I am dubious...

					Mike

Mike Albaugh (albaugh@dms.UUCP || {...decwrl!pyramid!}weitek!dms!albaugh)
[I've sent followups to comp.sys.m68k, since this seems to be more related
to details of 68K assembler syntax than any compiler issue. -John]
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.

pardo@june.cs.washington.edu (David Keppel) (04/13/91)

carter@cs.wisc.edu (Gregory Carter) writes:
> (unsigned int)(*((unsigned int *)0xffff8e20L)) = 0x03;
>translates to:
>                       MOVE.W #$0003, $8e20
>This is obviously not correct.

I'll agree that it isn't what I *expected* but it is *correct*.
Here are some other correct implementations:

 * Compiler refuses to compile the program
 * Program aborts when executed
 * Program runs `rogue'
 * Program assigs 3 to memory location 0xffff8e20

Remember, dereferencing a hard-coded address (in C) has
implementation-defined effect.

In the meanwhile, I agree that the one it chose is non-intuitive.

Followups to `comp.lang.c' and `comp.sys.m68k'.

	;-D on  ( Paid-up in tuition )  Pardo
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.