[net.unix-wizards] Words wanted on 68000 invalid operand challenge

ado@elsie.UUCP (Arthur David Olson) (10/09/84)

Recent articles have noted that some 68000 C compilers produce bogus
"Invalid Operand" messages when compiling a program like:

	#define MAXLLEN 80

	struct line {
		char    len;
		char    flags;
		char    l[MAXLLEN];
	};

	_fixlines() {
		register struct line *	lp;
		register char *		p;

		lp->len = p + 1 - lp->l;
	}

I'd appreciate it if some netnik could mail me a description of the class of
C language statements that cause problems so I can set up "lint" to
gripe about them.  This being the goal, it's a help if you can narrow
down the description of the offensive statements as much as possible to keep
lint from nattering needlessly.  Examples of working and failing code are fine.
--
UNIX and lint are AT&T Bell Laboratories and Oscar Madison trademarks
--
	..decvax!seismo!elsie!ado			(301) 496-5688
	DEC, VAX and Elsie are Digital Equipment and Borden trademarks

guy@rlgvax.UUCP (Guy Harris) (10/10/84)

> Recent articles have noted that some 68000 C compilers produce bogus
> "Invalid Operand" messages when compiling a program like:
> 
> I'd appreciate it if some netnik could mail me a description of the class of
> C language statements that cause problems so I can set up "lint" to
> gripe about them.

There are some things "lint" wasn't meant to do, and this is one of them.
The 68000 C compilers that produce crap code on the above examples are
based on the MIT C compiler; a fix to that compiler was posted to the net
a while ago.  It consists of adding one table entry to the code generation
tables, and has fixed our much-modified MIT compiler as well as whatever
compiler the original fixer was using.  The solution to the problem isn't
to twiddle "lint" to catch everything that could possibly cause a compiler
to blow up, it's to GET THE COMPILER FIXED!  I can provide a copy of the
fix to anybody who wants it.

This isn't appropriate for "lint", *even if there currently exist buggy
compilers that that code might cause a problem on*.  It's not "lint"s job
to be aware of every bug in every C compiler out there.

Companies which may use the MIT C compiler include:

	Computer Consoles, Inc. - that's us, but I fixed it in the
	current compiler a couple of weeks ago (current releases
	don't have the fix, the next one will)

	Plexus (somebody claims to have seen this problem on a Plexus)

	UniSoft (I believe they use the MIT compiler, but they may
	already have found the bug)

I don't know whether Microsoft has replaced the MIT compiler with their
own or not.

If any of you out there work for a company using the MIT 68000 C compiler,
test the above fragment and see if it produces code that tries to do a
"movb" into an address register.  If so, you've got the bug - mail me for
a description of the fix.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

guy@rlgvax.UUCP (Guy Harris) (10/11/84)

Here's the fix to the MIT 68000 C compiler to keep it from generating "movb"s
into address registers:

In "table.c", before the table entry that reads something like

	ASSIGN,	INAREG|FOREFF|FORCC,
		EAA,	TSCALAR|TFLOAT,
		EA,	TSCALAR|TFLOAT,
			0,	RLEFT|RRIGHT|RESCC,
			"	moveZB	AR,AL\nT",

put an entry that reads like

	ASSIGN,	INAREG|FOREFF|FORCC,
		EAA,	TCHAR,
		SBREG|STBREG,	TCHAR,
			NAREG|NASR,	RLEFT|RRIGHT|RESCC,
			"	move.l	AR,A1\n	moveZB	A1,AL\nT",

(your mileage and exact entries may differ).  This entry forces a move of
a "char" into a "B register" (which is an address register) to proceed
first by moving the character into a scratch "A register" (data register)
and then move the data register into the address register.

This fix is thanks to somebody at MIT named, I believe, Jonathan something-
or-other, and was posted in response to an article from Steve Kramer mentioning
the bug.  (Apologies to Jonathan X, but I don't have the article any more
and don't remember his name.)

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

rpw3@redwood.UUCP (Rob Warnock) (10/12/84)

Fortune Systems' C compiler is also MIT-derived (circa 1981), but apparently
has been fixed some time in the past, as your example compiled just fine
(edited for brevity and annotated):

	$ cat bugchar.c
	struct line {	char len; char flags; char l[MAXLLEN];};
	_fixlines() {	register struct line *	lp;
			register char *		p;
			lp->len = p + 1 - lp->l;	}

	$ cc -O -S bugchar.c	# Fortune Systems C compiler Release 1.7

	$ cat bugchar.s			# Notes:
	_fixlines:
		jsr	_csav
		link	%a6,#-.F1	| .F1 is count of regs used (in bytes)
		moveml	#.S1,%sp@	| .S1 is mask of regs used
		lea	%a4@(1),%a0	| "p + 1" (note optimization)
		lea	%a5@(2),%a1	| "lp->l"
		subl	%a1,%a0		| " - "
		movw	%a0,%d0		| <-- missing in compilers with bug?
		movb	%d0,%a5@	| "lp->len = ..." (looks o.k. to me)
		moveml	%a6@(-.F1),#.S1
		unlk	%a6
		rts

Rob Warnock

UUCP:	{ihnp4,ucbvax!amd}!fortune!redwood!rpw3
DDD:	(415)572-2607	(*new*)
Envoy:	rob.warnock/kingfisher
USPS:	510 Trinidad Ln, Foster City, CA  94404	(*new*)