Commit Graph

312 Commits

Author SHA1 Message Date
Stephen Heumann
5685009791 Update release notes to cover recent changes. 2018-03-17 22:54:53 -05:00
Stephen Heumann
324c979f3b Correctly handle tentative struct/union and array definitions that are not completed.
In the case of structs or unions, an error is now produced. This addresses one of the problems mentioned in issue #53.

In the case of arrays, tentative definitions like "int i[];" are now permitted at file scope. If not completed by a subsequent definition, this winds up producing an array with one element, initialized to 0. See the discussion and example in C99/C11 section 6.9.2 (or C90 section 6.7.2 and example in TC1).
2018-03-06 22:53:52 -06:00
Stephen Heumann
c55acd1150 Give an error if the element type of an array type is an incomplete or function type. 2018-03-06 22:46:23 -06:00
Stephen Heumann
96f04b168e Do not enter forward-declared struct parameters in the global symbol table.
Memory for them is still allocated from the global pool, to ensure they remain available for as long as the function prototype that references them.

This addresses one of the problems mentioned in issue #53.
2018-03-06 19:46:51 -06:00
Stephen Heumann
78db036a85
Merge pull request #55 from ksherlock/debugger_struct_2
more nested struct type tweaks
2018-03-06 15:52:02 -06:00
Kelvin Sherlock
ae55b80f2f Previous embedded struct debugger fix didn't account for pointers to structs (ExpandPointerType).
This always pre-increments symLength then compensate by subtracting 12 in GetTypeDisp.
2018-03-05 23:15:14 -05:00
Stephen Heumann
cbdb773101 Add snprintf() and vsnprintf() prototypes in <stdio.h>. 2018-03-05 19:01:42 -06:00
Stephen Heumann
ef30698ac8 Update <ctype.h> header to include isblank(), as both a macro and function.
In order to work right, this needs either GNO's ORCALib (which already included isblank()) or a copy of ORCA's ORCALib with the corresponding patch applied.
2018-03-05 18:59:25 -06:00
Stephen Heumann
28fa8b1853 Merge branch 'stack-repair-opt' 2018-03-04 16:09:08 -06:00
Stephen Heumann
0884c019d2 Generate correct debugger symbol tables for nested struct types.
Previously, when a struct type first appeared in a symbol table nested within another struct type, subsequent references to that type would use the wrong offset and be corrupted. This occurred because the symbol table length had not yet been updated to reflect the size of the entry for the outer structure at the time the inner one was processed.

Fixes #54.
2018-02-28 23:31:10 -06:00
Stephen Heumann
83df2fd9e1 Revert definition of FILE structure in <stdio.h> to match the implementation in ORCALib.
It had been changed to reflect changes in the ORCALib code that added a second putback buffer element, but those changes were problematic and have been reverted for now. (It's also not clear if ORCALib binaries with the larger putback buffer were ever distributed--at the least, they aren't on Opus ][ or in any of the ORCA/C 2.2.0 beta releases.)
2018-02-28 22:57:41 -06:00
Stephen Heumann
5b26b8cc5b Expand all tabs in assembly files to spaces.
This allows the code to be displayed properly on GitHub and in modern text editors, which typically do not support the irregularly-spaced tab stops used for ORCA/M code. It also avoids any possibility of problems building the code if the SysTabs file is missing or has been customized with non-standard tab stops.
2018-02-10 21:55:24 -06:00
Stephen Heumann
bd110d7e21
Merge pull request #51 from ksherlock/debugger_forward_struct_decl
Fix debugger symbol tables with forward declared structs
2018-02-10 21:17:03 -06:00
Kelvin Sherlock
c11218359f forward-declared structs have no field list and generate an invalid debugger symbol table. Generate a valid struct entry by re-using the default error struct ({ field: int }) 2018-02-09 22:14:36 -05:00
Stephen Heumann
bdd60d9d08 When using varargs stack repair, only disable native-code peephole opt in functions containing varargs calls.
There is no need to reduce the optimization in other functions, which will not contain any varargs stack repair code.
2018-01-13 21:37:28 -06:00
Stephen Heumann
4a7644e0b5 Don't allocate stack space for varargs stack repair unless it's needed.
If there are no varargs calls (and nothing else that saves stack positions), then space doesn't need to be allocated for the saved stack position. This can also lead to more efficient prolog/epilog code for small functions.
2018-01-13 20:02:43 -06:00
Stephen Heumann
f24f37aa9f Generate more efficient stack repair code (2).
Previously, the stack repair code always generated code to save and restore a register, but this can be omitted except in cases where a 32-bit value or pointer is returned.
2018-01-12 22:32:12 -06:00
Stephen Heumann
b697094c58 Generate more efficient stack repair code (1).
Previously, when stack repair code was generated, it always included instructions to save and restore a previously-saved stack position, but this was only actually used for function calls nested within the arguments to other function calls using stack repair code. Now that code is only generated in cases where it is needed, and the stack repair code for other calls is simplified to omit it.

This optimization affects all (non-nested) function calls when not using optimize bit 3, and varargs function calls when not using optimize bit 6.
2018-01-12 22:28:47 -06:00
Stephen Heumann
44714767e5 Don't optimize out certain volatile stores.
This could occur due to the new native-code peephole optimizations for stz instructions, which can collapse consecutive identical ones down to one instruction. This is OK most of the time, but not when dealing with volatile variables, so disable it in that case.

The following test case shows the issue (look at the generated code):

#pragma optimize -1
volatile int a;
int main(void) {
        a = 0;
        a = 0;
}
2018-01-07 21:50:32 -06:00
Stephen Heumann
38345e4ca2 Update ORCA/C version number to 2.2.0 B2. 2017-12-13 23:05:20 -06:00
Stephen Heumann
13434dd520 Update release notes. 2017-12-13 22:20:59 -06:00
Stephen Heumann
5312843b93 Don't invalidly eliminate certain stores of 0 to global/static variables.
This could happen in native-code peephole optimization if two stz instructions targeting different global/static locations occurred consecutively.

This was a regression introduced by commit a3170ea7.

The following program demonstrates the problem:

#pragma optimize 1+2+8+64
int i,j=1;
int main (void) {
    i = 0;
    j = 0;
    return j; /* should return 0 */
}
2017-12-13 20:03:48 -06:00
Stephen Heumann
4e7a7e67e7 Fix problems with loop invariant removal optimization.
These mainly related to situations where the optimization of multiple natural loops (including those created by continue statements) could interact to generate invalid results. Invalid optimizations could also be performed in certain other cases where there were multiple goto statements targeting a single label and at least one of them formed a loop.

These issues are addressed by appropriately adjusting the control flow and updating various data structures after each loop is processed during loop invariant removal.

This fixes #18 (compca18.c).
2017-12-12 13:50:17 -06:00
Stephen Heumann
89f4257742
Merge pull request #46 from ksherlock/profile_flag_exit
generate function exit cop with profiling / #pragma debug 4.
2017-12-07 20:31:45 -06:00
Stephen Heumann
5152790b00 Don't inappropriately re-expand a macro's name when it appears within the macro.
This should implement the C standard rules about making macro name tokens ineligible for replacement, except that it does not currently handle cases of nested replacements (such as a cycle of mutually-referential macros).

This fixes #12. There are still a couple other bugs with macro expansion in obscure cases, but I'll consider them separate issues.
2017-12-05 23:28:57 -06:00
Kelvin Sherlock
dbfa542fba generate function exit cop with profiling / pragma debug 4. Expected by prizm. 2017-12-05 21:31:36 -05:00
Stephen Heumann
bfb929f4a7 Remove the setbuf macro in favor of just calling the library function.
The macro was slightly broken in that its 'buf' argument might be evaluated twice. This could be a problem if it was, e.g., a call to an allocation function.
2017-11-12 23:57:28 -06:00
Stephen Heumann
dedd50c81e Include prototypes for standard library functions that are also defined as macros.
This is needed to ensure correct behavior in cases where the macro is bypassed to access the library function, e.g. by enclosing the function name in parentheses or by taking its address.
2017-11-12 23:27:15 -06:00
Stephen Heumann
10c9e70f85 Update release notes. 2017-11-12 21:43:39 -06:00
Stephen Heumann
14cb6c6b8f Merge commit '3c09d1c4ff3ae3afc9afe0f44d58c5502ea953ed' 2017-11-12 20:08:26 -06:00
Stephen Heumann
ba09d5ee6d Fix issues with addressing/pointer arithmetic using unsigned indexes that generate a displacement of 32K to 64K.
These cases should now always work when using an expression of type unsigned as the index. They will work in some cases but not others when using an int as the index: making those cases work consistently would require more extensive changes and/or a speed hit, so I haven't done it for now.

Note that this now uses an "unsigned multiply" operation for all 16-bit index computations. This should actually work even when the index is a negative signed value, because it will wind up producing (the low-order 16 bits of) the right answer. The signed multiply, on the other hand, generally does not produce the low-order 16 bits of the right answer in cases where it overflows.

The following program is an example that was miscompiled (both with and without optimization):

int c[20000] = {3};

int main(void) {
    int *p;
    unsigned i = 17000;

    p = c + 17000u;
    return *(p-i); /* should return 3 */
}
2017-11-12 17:21:05 -06:00
Stephen Heumann
df42ce257f Fix issue where certain address computations could be improperly restricted to a 32K or 64K range (even when using the large memory model).
This could occur with computations where multiple variables were added to a pointer.

The following program is an example that was miscompiled:

#pragma optimize 1
#pragma memorymodel 1

char c[80000];

int main(void) {
    unsigned i = 30000, j = 40000;
    c[70000] = 3;
    return *(c+i+j); /* should return 3 */
}
2017-11-12 12:29:06 -06:00
Stephen Heumann
103af4c4a4 Generate more efficient code for some indexing operations affected by the previous commit. 2017-11-11 21:55:22 -06:00
Stephen Heumann
3aed2eb8ac Fix problem where array index computations involving a negative variable part of the index could be miscomputed when using the small memory model.
This introduces a function to check whether the index portion of a pc_ixa intermediate code operation (used for array indexing) may be negative. This is also used when generating code for the large memory model, which can allow slightly more efficient code to be generated in some cases.

This fixes #45.
2017-11-11 20:07:46 -06:00
Stephen Heumann
763c5192df When optimizing certain index calculations, properly indicate whether they should be signed or unsigned.
This type information is currently used when generating code for the large memory model, but not for the short memory model (which is a bug in itself, causing issue such as #45).

Because the correct type information was not being provided, the code generator could incorrectly use signed index computations when a 16-bit unsigned index value was used in large-memory-model code. The following program is an example that was being miscompiled:

#pragma optimize 1
#pragma memorymodel 1

char c[0xFFFF];

int main(void) {
    unsigned i = 0xABCD;
    c[0xABCD] = 3;
    return c[i]; /* should return 3 */
}
2017-11-10 22:24:50 -06:00
Stephen Heumann
730544a6ce Fix optimizer bug that could limit certain address calculations to a 32k or 64k range even when using the large memory model.
This optimization could apply when indexing into an array whose elements are a power-of-2 size using a 16-bit index value. It is now only used when addressing arrays on the stack (which are necessarily smaller than 64k).

The following program demonstrates the problem:

#pragma optimize 1
#pragma memorymodel 1

long c[40000];

int main(void) {
    int i = 30000;
    c[30000] = 3;
    return c[i]; /* should return 3 */
}
2017-11-10 22:23:51 -06:00
Stephen Heumann
e780043007 When doing arithmetic/indexing on pointers to one-byte types, don't generate code to multiply by one.
This could already be optimized out by the peephole optimizer, but it's bad enough code that it really shouldn't be generated even when not using that optimization.
2017-10-29 20:25:43 -05:00
Stephen Heumann
8d31481182 Report errors for illegal pointer arithmetic operations.
These include arithmetic on pointers to incomplete types or functions, as well as subtraction of pointers to incompatible types.
2017-10-29 20:21:36 -05:00
Stephen Heumann
dddae89af0 Add prototypes for functions called by macros in <stdio.h>.
This avoids lint errors when using the setbuf() and rewind() macros.

This fixes #42 (libco01.c).
2017-10-28 22:58:26 -05:00
Stephen Heumann
9144002b3b Don't remove bitfield stores during loop invariant removal.
This could generate bad code (e.g. invalidly moving stores ahead of loads, as in #44). It would be possible to do this validly in some cases, but it would take more work to do the necessary checks. For now, we'll just block the optimization for bitfield stores.

In combination with the previous commit, this fixes #44.
2017-10-28 22:41:33 -05:00
Stephen Heumann
ff90151e77 Block invalid movement of bitfield accesses in common subexpression elimination.
This fixes the problem in #44 for the case of using common subexpression elimination only. (Loop invariant removal still causes the problem.)
2017-10-28 22:16:10 -05:00
Stephen Heumann
1e8413138e Avoid lifting indirect loads out of loops where the value may be modified.
The code was not accounting for the possibility that the loaded-from location aliases with the destination of an indirect store in the loop, or for the possibility that it may be written by a function called in the loop. Since we don't have sophisticated alias analysis, we now conservatively assume there may be aliasing in all such cases.

This fixes #20 (compca20.c) and #21 (compca21.c).
2017-10-28 21:59:15 -05:00
Kelvin Sherlock
3c09d1c4ff add allowTokensAfterEndif setting for pragma ignore (from MPW ORCA/C IIgs) [WIP] 2017-10-28 20:19:00 -04:00
Stephen Heumann
780c639112 Add link to binary downloads in the readme shown on GitHub. 2017-10-24 21:10:11 -05:00
Stephen Heumann
34bbcc549b Add readme file documenting how to apply the update. 2017-10-22 17:24:17 -05:00
Stephen Heumann
0fcfcd441a Update cc.notes file to describe new features and bug fixes in ORCA/C 2.2.0 B1. 2017-10-21 21:36:11 -05:00
Stephen Heumann
1d0dcc5cef Add settypes script for setting file types, and update README to refer to it. 2017-10-21 21:17:58 -05:00
Stephen Heumann
0ef7846995 Update ORCA/C version number to 2.2.0 B1. 2017-10-21 20:51:01 -05:00
Stephen Heumann
f3431f8771 Fix types of CHAR_MAX and UCHAR_MAX in <limits.h>.
These should be of type int (not unsigned int), since that is what char and unsigned char now promote to.
2017-10-21 20:47:34 -05:00
Stephen Heumann
8be021eab1 Fix some tool call prototypes in tool headers.
Contrary to the previous comment in window.h, SetContentOrigin2 is in fact documented in TBR2, so a prototype for it was added.
2017-10-21 20:46:21 -05:00