xref: /csrg-svn/old/pcc/ccom.vax/LOG (revision 43111)
1*43111SbosticThere was a bug which caused compiler errors when floating values were
2*43111Sbosticassigned to bit fields.  Some overenthusiastic optimization on my part
3*43111Sbosticled to a float-to-int conversion on the rhs of the assignment being
4*43111Sbosticdropped.  Bit fields are now treated as a special case.  [pcc.vax:
5*43111Sbosticlocal2.c]
6*43111Sbostic
7*43111SbosticAt the instigation of Rob Pike, enums were neutered: they now behave
8*43111Sbosticexactly like ints.  The only traces of Johnson's treatment of enums are
9*43111Sbosticwarnings about clashes between one enum type and another enum type in
10*43111Sbosticcertain expressions.  This fix was trickier than it looked; it would
11*43111Sbostichave been much simpler to drop ALL warnings about enums, as Rob would
12*43111Sbosticrecommend.  [mip: trees.c]
13*43111Sbostic
14*43111SbosticArthur Olsen pointed out a bug with the evaluation of constant
15*43111Sbosticexpressions -- the usual arithmetic conversions are not always
16*43111Sbosticperformed.  Rather than follow Arthur's simple suggestion, I decided to
17*43111Sbosticbe safe and arranged to use the same conversion code on constants that
18*43111Sbosticwe use on variables.  We short-cut the test if the operand(s) are ints,
19*43111Sbosticwhich is the usual case, so the impact on compile time should be
20*43111Sbosticsmall.  [mip: trees.c]
21*43111Sbostic
22*43111SbosticGuy Harris noted that chkpun() considered multiply dimensioned arrays
23*43111Sbosticand multiply indirect pointers to be the same thing, which they are
24*43111Sbosticmost certainly not.  His fix causes an 'illegal pointer combination'
25*43111Sbosticwarning to be emitted for code like:
26*43111Sbostic
27*43111Sbostic	char **cpp, c2a[10][20]; cpp = c2a; cpp[5][3] = 'a';
28*43111Sbostic
29*43111SbosticThe new code is actually simpler than the old...  [mip: trees.c]
30*43111Sbostic
31*43111SbosticAnother irritation of Rob Pike's is fixed -- the old-style assignment
32*43111Sbosticops have been ifdef'ed out.  No more of those obnoxious 'ambiguous
33*43111Sbosticassignment: assignment op taken' messages!  [mip: scan.c]
34*43111Sbostic
35*43111SbosticYet another Rob Pike complaint: you couldn't refer directly to the
36*43111Sbosticmembers of a structure which had been returned by a function.  You may
37*43111Sbosticnow utter things like 'f().a' and get away with them.  The illegal form
38*43111Sbostic'(&f())->a' used to work; since this has the same tree representation
39*43111Sbosticas the legal form, an ugly wart was added to the action for '&' which
40*43111Sbosticspecifically rules this form out.  To be consistent, a similar
41*43111Sbosticexception was made for expressions of the form '(a = b).c'.  [mip:
42*43111Sbosticcgram.y]
43*43111Sbostic
44*43111SbosticMoved configuration flags from Makefile into macdefs.h and converted
45*43111Sbosticsome more trivial routines into macros.  This cleans up the Makefile
46*43111Sbosticconsiderably and consolidates assembler-dependent flags.  [pcc.vax:
47*43111Sbosticmacdefs.h, code.c, order.c, Makefile; mip: onepass.h]
48*43111Sbostic
49*43111SbosticMore efficiency hacks: the compiler now does its best to avoid emitting
50*43111SbosticANY code after an error is detected.  Previously only code generation
51*43111Sbosticthrough the code table was suppressed after an error.  This change can
52*43111Sbosticbuy up to 25% in speed improvements if the dbx stab flag is enabled.
53*43111SbosticThe latest 'ccom' runs twice as fast as the 4.2 BSD compiler in this
54*43111Sbosticsituation...  [pcc.vax:  macdefs.h, local.c, code.c; mip: cgram.y,
55*43111Sbosticscan.c, pftn.c]
56*43111Sbostic
57*43111SbosticFor ANSI compatibility, we now accept void expressions in the colon
58*43111Sbosticpart of a conditional expression.  Both subexpressions under the colon
59*43111Sbosticoperator must be void if one is void.  The overall type of the
60*43111Sbosticconditional expression is void in this case.  [mip: trees.c]
61*43111Sbostic
62*43111SbosticAs long as we're doing away with old-fashioned assignment operators, we
63*43111Sbosticmight as well terminate old-fashioned initializations too.  [mip: cgram.y]
64*43111Sbostic
65*43111SbosticA fix from James Schoner for bitfield assignments was installed.  The
66*43111Sbosticproblem was that the rhs of a bitfield assignment was used as its
67*43111Sbosticvalue, an overlooked aspect of the several earlier bug fixes for
68*43111Sbosticproblems of this variety.  The bug caused
69*43111Sbostic
70*43111Sbostic	struct { unsigned a:4, b:3, c:2; } x;
71*43111Sbostic	int i;
72*43111Sbostic	i = x.b = 255;
73*43111Sbostic
74*43111Sbosticto store 255 in i instead of 7.  [pcc.vax: table.c, local2.c]
75*43111Sbostic
76*43111SbosticScanner code was added to handle the System V/ANSI preprocessor
77*43111Sbosticextensions #ident and #pragma.  Currently #ident is ignored.  #pragma
78*43111Sbosticmay be used as a substitute for lint-style comment directives; e.g. use
79*43111Sbostic'#pragma LINTLIBRARY' for '/* LINTLIBRARY */'.  The #pragma stuff
80*43111Sbosticrequires the hacked-up cpp with ANSI extensions which may eventually be
81*43111Sbosticput into circulation here at Utah.  The #line control from cpp is now
82*43111Sbosticrecognized with the same syntax by ccom.  Unknown control lines elicit
83*43111Sbostica warning.  A small bug is fixed by this new code -- previously #ident
84*43111Sbosticand other unknown controls caused the line control mechanism to get
85*43111Sbosticscrewed up, so that bogus dbx stabs were put in the output.  [mip:
86*43111Sbosticscan.c]
87*43111Sbostic
88*43111SbosticThere seems to be a loophole in initializations -- apparently it is
89*43111Sbosticlegal to initialize a bitfield with a symbolic constant (i.e. the
90*43111Sbosticaddress of something).  No loader that I know of will handle this!  The
91*43111Sbosticcompiler now emits an error when someone tries this trick; it really
92*43111Sbosticcan't do any better.  [mip: pftn.c]
93*43111Sbostic
94*43111SbosticSomeone complained that all illegal characters were being printed as
95*43111Sbosticoctal numbers in the error message.  This was changed so that printable
96*43111Sbosticcharacters are printed normally, and all funny characters are printed
97*43111Sbosticin C 'char' style.  [mip: scan.c]
98*43111Sbostic
99*43111SbosticConversion of unsigned constants to floating point values was broken
100*43111Sbosticbecause the requisite cast in makety() had been commented out!  Argh.
101*43111SbosticUnsigned comparisons of constants were similarly botched.  [mip: trees.c]
102*43111Sbostic
103*43111SbosticRay Butterworth made a sensible suggestion that array definitions which
104*43111Sbosticaren't external and allocate no storage should elicit errors.  I
105*43111Sbosticmodified his suggestion slightly by moving the test into nidcl(), where
106*43111Sbosticwe can be sure that an array isn't being initialized.  I also adopted
107*43111Sbostichis suggestion for a lint warning for arrays with explicit dimensions
108*43111Sbosticthat are lost by the rule that converts array types into pointer types
109*43111Sbosticin formal arguments; the warning is contingent on lint's -h flag.
110*43111Sbostic[mip: pftn.c]
111*43111Sbostic
112*43111SbosticThe structures for fpn and dpn nodes (floating point constants) were
113*43111Sbosticchanged to make them conform in shape to the other nodes.  [mip: ndu.h]
114*43111Sbostic
115*43111SbosticOverenthusiastic SCONV optimization code in optim2() led to functions
116*43111Sbosticnot cooperating with certain casts; e.g.
117*43111Sbostic
118*43111Sbostic	unsigned char x(); ... y((char)x()) ...
119*43111Sbostic
120*43111Sbosticfailed to sign-extend the result of x().  [pcc.vax: local2.c]
121*43111Sbostic
122*43111SbosticA bug in outstruct() caused it to check 'stab[-1].name == NULL' for
123*43111Sbosticunnamed structures.  For some reason this didn't break until my recent
124*43111Sbosticlint fixes tweaked the compiler in some subtle way...  [pcc.vax: stab.c]
125*43111Sbostic
126*43111SbosticThe makefile was changed to pass C options to lint properly and to drop
127*43111Sbosticthe '-a' flag to lint in the 'lintall' entry.  '-a' really ought to
128*43111Sbosticwork but unfortunately the arrangement of 'int'-like types in the
129*43111Sbosticcompiler is extremely confusing and inconsistent, so I eventually gave
130*43111Sbosticup trying to force the issue.  Sam Leffler's 'rel.c' for release
131*43111Sbosticinformation was also added.  [pcc.vax: Makefile, rel.c]
132*43111Sbostic
133*43111SbosticI fixed defid() so that it now insists that all argument type
134*43111Sbosticdeclarations must refer to names in the argument list.  Previously you
135*43111Sbosticcould get away with:
136*43111Sbostic
137*43111Sbostic	int a;
138*43111Sbostic	x()
139*43111Sbostic		int a;
140*43111Sbostic	{ ... }
141*43111Sbostic
142*43111SbosticUse of 'a' in the body of x() would elicit the immortal error message
143*43111Sbostic'warning: bad arg temp'.  [mip: pftn.c]
144*43111Sbostic
145*43111SbosticFor some reason, mainp2() in the two-pass version of the compiler had a
146*43111Sbosticswitch statement with two 'default' cases.  I zapped the obvious one.
147*43111Sbostic[mip: reader.c]
148*43111Sbostic
149*43111SbosticBotched initializations sometimes left the declarations code in a funny
150*43111Sbosticstate, so a fixinit() routine was invented to aid error recovery.  For
151*43111Sbosticexample, the following illegal program forced a core dump:
152*43111Sbostic
153*43111Sbostic	char m[] = ;
154*43111Sbostic	x() {
155*43111Sbostic		y("splat");
156*43111Sbostic	}
157*43111Sbostic
158*43111SbosticThe compiler tried to read "splat" into m[] and died horribly.  [mip:
159*43111Sbosticcgram.y, pftn.c]
160*43111Sbostic
161*43111SbosticThe compiler now warns 'can't take size of function' when asked to do
162*43111Sbosticsomething amazing like '... void f(); ... if (f[10]) ...'.  Previously
163*43111Sbosticit produced a compiler error instead.  [mip: pftn.c]
164*43111Sbostic
165*43111SbosticIf a program tried to access a value below the argument list on the
166*43111Sbosticstack using the clever tactic of manipulating the address of an
167*43111Sbosticargument, it drew a warning 'bad arg temp'.  For the sake of these
168*43111Sbosticclever programs, the warning has been suppressed.  [pcc.vax: local2.c]
169*43111Sbostic
170*43111SbosticThe assembler would sometimes print 'Branch too long: try -J flag' even
171*43111Sbosticwhen you used the -J flag and when there was no reason for it to be
172*43111Sbosticmaking long branches.  This was due to a bug in jxxxfix() which caused
173*43111Sbostictests for explodable branch instructions to terminate early in later
174*43111Sbosticphases of the topological sort, because the loop termination code
175*43111Sbosticdidn't take into account the fact that not all code addresses are
176*43111Sbosticupdated by jxxxbump().  The fix is to match the pointer to the data
177*43111Sbosticstructure for the code in the sorted table rather than check for its
178*43111Sbosticgenerated address.  [as: asjxxx.c]
179*43111Sbostic
180*43111SbosticThe peephole optimizer normally compares instructions for equality
181*43111Sbosticbased on their instruction type and their operands.  Unfortunately
182*43111Sbosticseveral instructions are too complex for c2 to handle and are given an
183*43111Sbosticinstruction type of 0; thus all such instructions compared equal.  The
184*43111Sbosticequop() routine was changed to test the names of these '0' type
185*43111Sbosticinstructions for equality.  [c2: c21.c]
186*43111Sbostic
187*43111SbosticThe compiler sometimes botched computations into stack temporaries by
188*43111Sbostictreating expressions like '-40(fp)[r1]' as permissible temporaries.  I
189*43111Sbosticrewrote the shtemp() routine to make it explicit that the 'stack
190*43111Sbostictemporary' goal in code generation means precisely that the final
191*43111Sbosticexpression must not contain any references to temporary registers (like
192*43111Sbosticr1).  I had to add a couple templates to the code table to push
193*43111Sbosticexceedingly complex OREG expressions onto the stack when this goal is
194*43111Sbosticattempted.  [pcc.vax: local2.c, table.c]
195*43111Sbostic
196*43111SbosticA bug sometimes caused a redeclaration of an array in an inner scope to
197*43111Sbosticaffect the outer array when the outer array was incompletely specified
198*43111Sbostic(by leaving out the most significant dimension).  For example:
199*43111Sbostic
200*43111Sbostic	extern int a[];
201*43111Sbostic	x(){ int a[10]; }
202*43111Sbostic	int a[20];
203*43111Sbostic
204*43111SbosticThis code would elicit the error 'foo.c, line 3: redeclaration of a'.
205*43111SbosticThe routine defid() is used to enter new definitions; for some reason
206*43111Sbosticscope problems are not resolved in defid() until much other code has
207*43111Sbosticbeen executed, including code that deals with filling out array sizes.
208*43111SbosticThe change makes defid() notice inner scopes with auto and register
209*43111Sbosticdeclarations earlier than usual.  [mip: pftn.c]
210*43111Sbostic
211*43111SbosticCase expressions are explicitly restricted to contain only int constants,
212*43111Sbosticchar constants and sizeof expressions (C Reference Manual section 15).
213*43111SbosticPreviously the compiler didn't test for expressions like '(int) &foo[10]'
214*43111Sbosticand thus it would generate some rather bogus code.  Expressions which
215*43111Sbosticresolve to names now elicit the same 'non-constant case expression'
216*43111Sbosticwarning which you receive for variables.  [mip: cgram.y]
217*43111Sbostic
218*43111SbosticThe value of an assignment to an unsigned bitfield was signed through
219*43111Sbostican oversight in the code table.  [pcc.vax: table.c]
220*43111Sbostic
221*43111SbosticFrom Sam Kendall, a fix to prevent structs, unions, floats, doubles
222*43111Sbosticand void from being cast to pointer types.  [mip: trees.c]
223*43111Sbostic
224*43111SbosticSome relict code in moditype() was causing void functions not to be
225*43111Sbosticconverted into pointers in some situations.  [mip: trees.c]
226*43111Sbostic
227*43111SbosticA minor optimization -- when the lhs of a simple assignment op (&=, |=,
228*43111Sbostic^=, +-, -=) is smaller than int size, we can sometimes pun the rhs and
229*43111Sbosticavoid promoting the lhs to int, performing the operation in int width
230*43111Sbosticand converting from int back to the lhs type.  For example:
231*43111Sbostic
232*43111Sbostic	register char *ap, *bp;
233*43111Sbostic	*ap++ |= *bp << 1;
234*43111Sbostic
235*43111SbosticThis used to require 7 instructions, but now needs only 3.  [pcc.vax:
236*43111Sbostictable.c]
237*43111Sbostic
238*43111SbosticAt some point I added code to conval() to balance types before
239*43111Sbosticperforming constant folding...  While hacking on the tahoe compiler, I
240*43111Sbosticdecided that this code was too complex and replaced it with equivalent
241*43111Sbosticcode that's shorter and easier to understand.  [mip: trees.c]
242*43111Sbostic
243*43111SbosticLines containing multiple statements were broken up for the sake of
244*43111Sbostictracing with the source debugger in tcheck() and talloc().  [mip:
245*43111Sbosticcommon.c]
246*43111Sbostic
247*43111SbosticI discovered that the C compiler called urem() in three different
248*43111Sbosticplaces with a constant divisor...  In my subsequent rampage I hacked
249*43111Sbosticthe compiler to generate inline code for all unsigned division and
250*43111Sbosticmodulus operations with constant divisors.  The largest inline
251*43111Sbosticexpansion should use only 5 instructions, with most using just 3 or 4.
252*43111SbosticThe changes touched several files but really weren't very messy.
253*43111Sbostic[mip:  pass1.h, match.c; pcc.vax: local2.c, order.c, table.c]
254*43111Sbostic
255*43111SbosticA lot of new code was added to handle a really simple problem:
256*43111Sbostic
257*43111Sbostic	unsigned char uc = 255;
258*43111Sbostic	if (uc == -1) ...
259*43111Sbostic
260*43111SbosticThis incorrectly tested true, because the compiler generated a test
261*43111Sbosticthat looked only at the low order byte of the constant.  Not only that,
262*43111Sbosticbut the compiler didn't realize that this test could be short-
263*43111Sbosticcircuited, since -1 is equal to 4294967295 unsigned and is hence out of
264*43111Sbosticthe range of an unsigned char.  Rather than add lots of cruft to the
265*43111Sbosticcode table, I shoved it into optim2() -- the compiler now picks up all
266*43111Sbosticthe absurd cases where a constant is out of the range of precision of
267*43111Sbostica variable it's tested against.  To avoid having to write lots of code
268*43111Sbostictemplates to handle unbalanced unsigned/signed expressions, I forced
269*43111Sbostictymatch() to take notice of unbalanced expressions and promote the
270*43111Sbosticsigned operand to unsigned (except with assignment operators, sigh).
271*43111SbosticThis change in turned required tweaks in autoincr() and in the code
272*43111Sbostictable to get code quality back.  I hope I can come up with a better way
273*43111Sbosticto do this...  [mip: trees.c; pcc.vax: local2.c, order.c, table.c]
274*43111Sbostic
275*43111SbosticThe value of TNULL was changed from 'pointer to undef' to 'pointer to
276*43111Sbosticmember of enum' so that 'void *' can be a real type.  TNULL is used to
277*43111Sbostictag unused symbol table slots.  [mip: manifest.h]
278*43111Sbostic
279*43111SbosticA bug in clearst() led to problems with 'schain botch' errors.  When a
280*43111Sbostichash collision occurs, a symbol is (linearly) rehashed; if the symbol
281*43111Sbosticwhich forced the rehash is deleted, the relook() loop in clearst() will
282*43111Sbosticcause another symbol with the same hash code to move up and replace the
283*43111Sbosticdeleted symbol.  Torek's 'schain' hack for speedy identification of
284*43111Sbosticsymbols at the same block level will get screwed up by this operation
285*43111Sbosticsince it relies on a linked list of table entries -- moving an entry
286*43111Sbosticgarbles the list.  How did this code ever work before?  [mip: pftn.c]
287*43111Sbostic
288*43111SbosticChanged putins() in ascode.c in the assembler to permit 0(pc) as a
289*43111Sbosticwrite operand...  Previously the assembler automatically optimized
290*43111Sbosticthis to (pc), which is an illegal operand.  [as.vax: ascode.c]
291*43111Sbostic
292*43111SbosticThe complement of an unsigned char or unsigned short value should have
293*43111Sbosticits high bits set, since the 'usual arithmetic conversions' widen these
294*43111Sbosticsmall integers 'before' the operation.  [pcc.vax: table.c]
295*43111Sbostic
296*43111SbosticA minor code improvement in ccom led to problems in c2 -- c2 was able
297*43111Sbosticto optimize sequences like 'cvtbl -4(fp),r0; bicl2 $-256,r0' but not
298*43111Sbosticthe (shorter and faster) 'cvtbl -4(fp),r0; movzbl r0,r0'.  A change in
299*43111Sbosticbflow() causes redundant conversions to be noted and removed, restoring
300*43111Sbosticcode quality.  [c2: c21.c]
301*43111Sbostic
302*43111SbosticA typo in the 'bitsize' array definition resulted in an unterminated
303*43111Sbosticcomment which screwed up the bit sizes for several types.  I only
304*43111Sbosticnoticed this because I ran the source off with vgrind and the error
305*43111Sbosticwas exposed by comment highlighting...  [c2: c21.c]
306*43111Sbostic
307*43111SbosticAn earlier change to conval() caused LONG and ULONG types to be hacked
308*43111Sbosticinto INT and UNSIGNED; this was fine for the (VAX) compiler, but led
309*43111Sbosticto inconsistencies with lint.  [mip: trees.c]
310*43111Sbostic
311*43111SbosticWhen a syntax error occurs, the parser throws away tokens until it can
312*43111Sbosticenter a known state.  If a string or character constant delimiter is
313*43111Sbostictossed, the parser will try to interpret the contents of the constant
314*43111Sbosticas code and can get very confused.  A hack was added to yylex() to
315*43111Sbosticdetect this situation -- basically, if a delimiter is seen but the
316*43111Sbosticstring or character constant has not been processed by lxstr() at the
317*43111Sbosticnext call to yylex(), yylex() will call lxstr() itself and dispose of
318*43111Sbosticthe rest of the constant.  [mip: scan.c]
319*43111Sbostic
320*43111SbosticFollowing a suggestion by Arthur Olsen, the production for 'switch' was
321*43111Sbosticmodified to complain about constant switch expressions with 'lint -h'.
322*43111Sbostic[mip: cgram.y]
323*43111Sbostic
324*43111SbosticAnother Arthur Olsen bug report pointed out a problem with increment
325*43111Sbosticoperations that don't match a code template...  Two attempts at
326*43111Sbosticrewriting the increment are made: the first tries to turn the lvalue
327*43111Sbosticoperand into an OREG, and the second applies a tree transformation to
328*43111Sbosticconvert 'x++' into '(x += sizeof x) - sizeof x'.  A mistake in the
329*43111Sbosticroutine setincr() caused the lvalue operand in its entirety to be
330*43111Sbosticgenerated into a register instead of just the lvalue operand's address,
331*43111Sbosticproducing something like 'r0 = x, (r0 += sizeof x) - sizeof x' instead
332*43111Sbosticof 'r0 = &x, (*r0 += sizeof x) - sizeof x'.  [pcc.vax: order.c]
333*43111Sbostic
334*43111SbosticBetter code for floating post-increment and -decrement can be generated
335*43111Sbosticwith a simple change to the code table and to zzzcode() so that the
336*43111Sbosticsame hack for ordinary post-increment will work for floating point too.
337*43111Sbostic[pcc.vax: local2.c, table.c]
338*43111Sbostic
339*43111SbosticI added Arthur Olsen's massive lint fixes for typechecking printf().
340*43111SbosticIt sure would be nice if there were a way to specify new printf-like
341*43111Sbosticcommands at execute time, perhaps through lint directives embedded in
342*43111Sbosticinclude files.  [lint: lint.c]
343*43111Sbostic
344*43111SbosticArthur's warning about superfluous backslashes was added to lxstr().
345*43111SbosticRather than adding Arthur's (expensive) code for warning about the
346*43111Sbosticuse of '$', I simply made it illegal (unless 'VMS' is defined).  I
347*43111Sbosticalso took the opportunity to remove '`' gcos BCD constants.  I made
348*43111Sbostica slight alteration to yylex() to cause it to eat unknown characters
349*43111Sbosticrather than punt, since this seemed more useful.  [mip: scan.c]
350*43111Sbostic
351*43111SbosticLint would sometimes print a bogus 'i set but not used' warning in
352*43111Sbosticsituations like this:
353*43111Sbostic
354*43111Sbostic	static int i;
355*43111Sbostic	static int *ip = &i;
356*43111Sbostic
357*43111Sbostic	i = 1;
358*43111Sbostic	return *ip;
359*43111Sbostic
360*43111SbosticIf you moved the initialization out of the declaration, the warning
361*43111Sbosticdisappeared.  I installed Arthur's hack for forcing lint to examine
362*43111Sbosticinitializations.  This causes lint to treat initializations of auto,
363*43111Sbosticregister and static variables as 'uses' and to ignore sizeof
364*43111Sbosticexpressions as 'uses'.  Also, '&i' in a static or external
365*43111Sbosticinitialization is now a 'set' and a 'use' of 'i'.  [lint: lint.c; mip:
366*43111Sbosticcgram.y, pftn.c]
367*43111Sbostic
368*43111SbosticVARARGS0 is now correctly treated differently from plain VARARGS.
369*43111SbosticI don't remember who originally noticed this...  [lint: lint.c,
370*43111Sbosticlpass2.c]
371*43111Sbostic
372*43111SbosticThe register allocation code failed to 'share' register pairs.  I don't
373*43111Sbosticknow why this escaped notice for this long...  I added a bit in the
374*43111Sbostic'busy' array to keep track of pairs and modified the code in usable()
375*43111Sbosticto notice pairs and try to 'share' them.  Some other code which treated
376*43111Sbosticthe values of busy[] elements as arithmetic values had to be changed;
377*43111Sbosticthere is now a macro which performs the proper test.  [mip: allo.c,
378*43111Sbosticmatch.c, pass2.h]
379*43111Sbostic
380*43111SbosticSome extensive code tweaking...  (1) If order() is called on to rewrite
381*43111Sbostica UNARY MUL node and that node has a usable index expression, we now
382*43111Sbostictry to rewrite the base into a register so that oreg2() will produce a
383*43111Sbosticdoubly-indexed OREG.  This is usually an impressive space saving.  (2)
384*43111SbosticInstead of laboriously copying a constant 0.0 in data space to clear a
385*43111Sbosticdouble or a float, we issue the proper 'clrd' or 'clrf'.  This is done
386*43111Sbosticby a trick using an alternate prtdcon() routine; I'm not sure who
387*43111Sbosticinvented it.  I guess I'm still not prepared to hack in support for
388*43111Sbosticfloating literals and immediate constants.  (3) The conversion code now
389*43111Sbostichandles stack pushes directly, which often saves a spill to register.
390*43111SbosticWith very little adjustment, this also buys us optimally small pushes
391*43111Sbosticof constants.  (4) Pointer comparisons are now unsigned; I'm not sure
392*43111Sbosticwhat this really buys us, but I added it anyway.  (5) AND tests against
393*43111Sbosticconstants are 'small' if both the constant and the other operand are
394*43111Sbosticalso 'small'.  (6) base() now recognizes that NAME nodes can be used in
395*43111Sbosticpc relative deferred indexed addressing, which is much more compact
396*43111Sbosticthan the equivalent code to compute the address into a register and
397*43111Sbosticindirect through it.  (7) The optimization code for ANDing with a
398*43111Sbosticconstant now tries to produce a positive mask when small types are used
399*43111Sbosticso that literal operands are possible; a side effect is that the code
400*43111Sbosticis more readable.  (8) UCHAR/USHORT to FLOAT/DOUBLE conversions take an
401*43111Sbosticextra step through INT type to avoid the overhead of an UNSIGNED to
402*43111SbosticFLOAT/DOUBLE conversion.  (9) If a logical operator sits above a pair
403*43111Sbosticof FLOAT to DOUBLE conversions, the conversions are deleted.  (10) Vast
404*43111Sbosticnumbers of redundant or useless templates were deleted from the code
405*43111Sbostictable.  (11) Conversions to FLOAT in double-only arithmetic now go to
406*43111Sbosticthe trouble of clipping off excess precision from INT and DOUBLE
407*43111Sbosticoperands.  (12) DOUBLE to DOUBLE conversions introduced by reclaim()
408*43111Sbosticare now silently deleted in the table.  (13) A few 'movd's were turned
409*43111Sbosticinto 'movq's -- more work needs to be done to make this consistent.
410*43111Sbostic[mip: reader.c; pcc.vax: macdefs.h, local.c, local2.c, table.c]
411*43111Sbostic
412*43111SbosticA bug which caused assignment op expressions with an unsigned char or
413*43111Sbosticunsigned short lhs and a floating rhs to treat the lhs as signed was
414*43111Sbosticfixed.  Some conversion-related stuff which used to be done in the
415*43111Sbostictable is now done in sconv() so that it's easier to handle and so that
416*43111Sbosticzzzcode() and its descendants can more safely perform conversions by
417*43111Sbosticcalling zzzcode(p, 'A').  [pcc.vax: local2.c, table.c]
418*43111Sbostic
419*43111SbosticThe code for setting the type of a floating point constant was bogus.
420*43111SbosticA floating constant was float if it fit in a float without loss of
421*43111Sbosticprecision, otherwise it was double.  This caused silliness like
422*43111Sbosticunexpectedly losing low order bits of integers in mixed floating and
423*43111Sbosticintegral expressions.  The fix was to adopt the ANSI proposal that all
424*43111Sbosticfloating constants are type double unless they bear an 'f' or 'F'
425*43111Sbosticsuffix, in which case they are type float.  (Note that a cast to float
426*43111Sbostichas the same effect as a 'f' suffix and is just as efficient, but I
427*43111Sbosticconceded to the evident popularity of the 'f' suffix...)  [mip: scan.c;
428*43111Sbosticpcc.vax: local.c]
429*43111Sbostic
430*43111SbosticThe ASG OPSIMP templates that produce byte and word instructions for
431*43111Sbosticbyte and word destinations weren't being activated very often because
432*43111Sbosticthe constant operands weren't normalized.  I added code to optim2() to
433*43111Sbosticappropriately reduce the range of constant operands of ASG OPSIMP
434*43111Sbosticoperators and sign-extend.  This blows away many useless conversions to
435*43111Sbosticand from int.  [pcc.vax: local2.c]
436*43111Sbostic
437*43111SbosticThe template for assignment ops with unsigned char/short lhs and
438*43111Sbosticfloating rhs indicated register sharing for the wrong operand...
439*43111Sbostic[pcc.vax: table.c]
440*43111Sbostic
441*43111SbosticThe new template that handled OREG for INTEMP failed to take into
442*43111Sbosticaccount the size variation in OREG objects.  [pcc.vax: table.c]
443*43111Sbostic
444*43111SbosticThe offstar() routine tries to tweak UNARY MUL trees so that they can
445*43111Sbosticbe handled most effectively by VAX addressing modes.  The code for
446*43111Sbosticidentifying index expressions was adjusted so that more indexed
447*43111Sbosticaddressing modes can be produced.  [pcc.vax: order.c]
448*43111Sbostic
449*43111SbosticBogus error messages were being emitted for certain initializations
450*43111Sbosticfollowing an earlier legitimate error.  It turns out that the
451*43111Sbosticoptimization to prevent initialization code from being emitted after
452*43111Sbosticerrors was preventing the initializer offset counter from being
453*43111Sbosticupdated, and when this occurs, the initialization code screws up -- for
454*43111Sbosticexample, string constants appear to be zero length.  The initialization
455*43111Sbosticcode now always updates the offset even if errors have been detected,
456*43111Sbosticalthough code generation is still suppressed.  [pcc.vax: local.c]
457*43111Sbostic
458*43111SbosticAn assignment to a bitfield in an indexed int-width structure led to
459*43111Sbosticcode generation failure due to an indexed OREG child of FLD.  This is
460*43111Sbostictaboo because the VAX field instructions have byte-size side effects,
461*43111Sbosticand code in clocal() arranged for indexed structs to have int width.
462*43111SbosticI changed clocal() to use byte width instead and it appears to work now
463*43111Sbostic(and even uses indexed byte addressing correctly).  [pcc.vax: local.c]
464*43111Sbostic
465*43111SbosticFor some reason the unsigned-to-floating conversion code has always
466*43111Sbosticbeen long and complex when it could be short and simple.  I used the
467*43111Sbosticsimple code in the Tahoe compiler but didn't think to put it in the VAX
468*43111Sbosticcompiler until prodded by Robert Firth...  [pcc.vax: local2.c]
469*43111Sbostic
470*43111SbosticJohn Gilmore noticed that the ! operator didn't work with floating
471*43111Sbosticconstants; this was pretty easy to fix.  [mip: trees.c]
472*43111Sbostic
473*43111SbosticFor some reason, opact() put left and right shifts through tymatch().
474*43111SbosticThe type balancing of tymatch() is wrong for shifts -- the type of the
475*43111Sbosticshift depends only on the left operand, while the right operand is
476*43111Sbosticconverted to int.  We now use the shift special case in buildtree() to
477*43111Sbosticfix the type.  [mip: trees.c]
478*43111Sbostic
479*43111SbosticFollowing ANSI (for once) we eliminate warnings for pointer conversions
480*43111Sbosticinvolving void *.  [mip: trees.c]
481*43111Sbostic
482*43111SbosticThere were at least a couple bugs in c2 with code that converts 'ashl
483*43111Sbostic$2,rA,rB; movab _x[rB],rC' into 'moval _x[rB],rC'; one caused the type
484*43111Sbosticto be wrong ('movab' for 'moval'), one caused neighboring instructions
485*43111Sbosticto get deleted.  [c2.vax: c21.c]
486*43111Sbostic
487*43111SbosticA branch to a redundant test sometimes resulted in c2's deleting the
488*43111Sbosticlabel too, even if the label itself was not redundant.  [c2.vax: c21.c]
489*43111Sbostic
490