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