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