Commit Graph

798 Commits

Author SHA1 Message Date
Kelvin Sherlock
6b39cea80d Add missing SysBeep2 constants for System 6.0.1 (Programmer's Reference for System 6.0.1 page 13) 2023-01-27 17:07:33 -06:00
Stephen Heumann
4b9824d5d6 Remove an unused function. 2023-01-22 13:19:06 -06:00
Stephen Heumann
40260bb8a0 Remove an unnecessary instruction from stack check code.
The intention may have been to set the flags based on the return value, but that is not part of the calling convention and nothing should be relying on it.
2023-01-14 19:09:45 -06:00
Stephen Heumann
03fc7a43b9 Give an error for expressions with incomplete struct/union types.
These are erroneous, in situations where the expression is used for its value. For function return types, this violates a constraint (C17 6.5.2.2 p1), so a diagnostic is required. We also now diagnose this issue for identifier expressions or unary * (indirection) expressions. These cases cause undefined behavior per C17 6.3.2.1 p2, so a diagnostic is not required, but it is nice to give one.
2023-01-09 21:58:53 -06:00
Stephen Heumann
61a2cd1e5e Consistently report "compiler error" for unrecognized error codes.
The old approach of calling Error while in the middle of writing error messages did not work reliably.
2023-01-09 18:46:33 -06:00
Stephen Heumann
2958619726 Fix varargs stack repair.
Varargs-only stack repair (i.e. using #pragma optimize bit 3 but not bit 6) was broken by commit 32975b720f. It removed some code that was needed to allocate the direct page location used to hold the stack pointer value in that case. This would lead to invalid code being produced, which could cause a crash when run. The fix is to revert the erroneous parts of commit 32975b720f (which do not affect its core purpose of enabling intermediate code peephole optimization to be used when stack repair code is active).
2023-01-08 15:15:32 -06:00
Stephen Heumann
74b9885572 Fix and simplify handling of pascal qualifiers.
Redeclaration of a pascal function could cause spurious errors when using strict type checking. (This was similar to the issue fixed in commit b5b276d0f4, but this time occurring due to the CompTypes call in NewSymbol.) There may also have been subtle misbehavior in other corner cases.

Now the reversal of parameters for pascal functions is applied only once, in Declarator prior to calling NewSymbol. This ensures that symbols for pascal functions have the correct types whenever they are processed, and also simplifies the previous code, where the parameters could be reversed, un-reversed, and re-reversed in three separate places.
2023-01-07 19:52:11 -06:00
Stephen Heumann
4d1a8caf8a Do not check for functions not returning a value if pc_rev is used.
The pc_rev intermediate code always returns a value, so the check is not needed, and (since the generated code does not jump to a return label) it can yield false positives.
2023-01-06 22:44:40 -06:00
Stephen Heumann
cb6173557e Add tests for <time.h> functions. 2023-01-05 20:46:59 -06:00
Stephen Heumann
34c1564dc4 Do not declare gets() in strict C11/C17 modes.
The declaration is still included in the default compatibility modes, where __KeepNamespacePure__ is not defined.
2023-01-05 17:25:25 -06:00
Stephen Heumann
245dd0a3f4 Add lint check for implicit conversions that change a constant's value.
This occurs when the constant value is out of range of the type being assigned to. This is likely indicative of an error, or of code that assumes types have larger ranges than they do in ORCA/C (e.g. 32-bit int).

This intentionally does not report cases where a value is assigned to a signed type but is within the range of the corresponding unsigned type, or vice versa. These may be done intentionally, e.g. setting an unsigned value to "-1" or setting a signed value using a hex constant with the high bit set. Also, only conversions to 8-bit or 16-bit integer types are currently checked.
2023-01-03 18:57:32 -06:00
Stephen Heumann
9f36e99194 Document __useTimeTool and add a declaration for it. 2023-01-02 18:10:41 -06:00
Stephen Heumann
5476118951 Add documentation and headers for timespec_get.
A macro is used to control whether struct timespec is declared, because GNO might want to declare it in other headers, and this would allow it to avoid duplicate declarations. (This will still require changes in the GNO headers. Currently, they declare struct timespec with different field names, although the layout is the same.)
2023-01-01 21:46:19 -06:00
Stephen Heumann
59664df9d9 Document <time.h> bug fixes. 2023-01-01 21:44:02 -06:00
Stephen Heumann
f7a139b4b5 Document use of Time Tool Set by gmtime and strftime.
Also include some tests for strftime %z and %Z conversions (although just producing no output will satisfy them).
2022-12-28 19:57:19 -06:00
Stephen Heumann
7d3f1c8dd7 Add headers, documentation, and tests for tgamma(). 2022-12-24 20:21:31 -06:00
Stephen Heumann
a87aeef25b Ensure native peephole opt uses a jump table.
In ORCA/Pascal's code generation, a case statement may use a jump table or a sequence of comparisons depending on whether it is considered sparse. This one was just a little too sparse to use a jump table, but changing it to use one makes it considerably faster. To force generation of a jump table, this commit adds several more explicit cases (even though they don't do anything).
2022-12-20 20:31:24 -06:00
Stephen Heumann
cf9f19c93d Optimize LDA+TAY to LDY (when A is unused after).
This pattern comes up in the new return code when returning a local variable.
2022-12-20 20:21:25 -06:00
Stephen Heumann
854a6779a9 Generate even better code for constant returns.
If the return value is just a numeric constant or static address, it can simply be loaded right before the RTL instruction, avoiding any data movement.

This could actually be applied to a somewhat broader class of expressions, but for now it only applies to numeric or address constants, for which it is clearly correct.
2022-12-19 21:18:41 -06:00
Stephen Heumann
e910eda623 Apply return optimization to struct/union return types. 2022-12-19 20:49:25 -06:00
Stephen Heumann
030f3ff9e1 Apply return optimization to enum and pointer return types. 2022-12-19 20:03:13 -06:00
Stephen Heumann
d68e0b268f Generate more efficient code for a single return at end of function.
When a function has a single return statement at the end and meets certain other constraints, we now generate a different intermediate code instruction to evaluate the return value as part of the return operation, rather than assigning it to (effectively) a variable and then reading that value again to return it.

This approach could actually be used for all returns in C code, but for now we only use it for a single return at the end. Directly applying it in other cases could increase the code size by duplicating the function epilogue code.
2022-12-19 18:52:46 -06:00
Stephen Heumann
265a16d2f5 Add headers, documentation, and tests for erf() and erfc(). 2022-12-17 22:26:59 -06:00
Stephen Heumann
53fcb84352 Allocate staticNum prefixes only for scopes that have statics.
This is somewhat faster, and also reduces the theoretical chance of overflowing the available staticNum values for a large source file.
2022-12-13 22:17:25 -06:00
Stephen Heumann
a7551d8c44 Optimize unused variable checks to only run on scopes with variables.
This reduces the overhead of them considerably.
2022-12-13 21:34:24 -06:00
Stephen Heumann
09fbfb1905 Maintain a pool of empty symbol tables that can be reused.
The motivation for this is that allocating and clearing symbol tables is a common operation, especially with C99+, where a construct like "if (...) { ... }" involves three levels of scope with their own symbol tables. In some tests, it could take an appreciable fraction of total execution time (sometimes ~10%).

This patch allows symbol tables that have already been allocated and cleared to be reused for a subsequent scope, as long as they are still empty. It does this by maintaining a pool of empty symbol tables and taking one from there rather than allocating a new one when possible.

We impose a somewhat arbitrary limit of MaxBlock/150000 on the number of symbol tables we keep, to avoid filling up memory with them. It would probably be better to use purgeable handles here, but that would be a little more work, and this should be good enough for now.
2022-12-13 21:14:23 -06:00
Stephen Heumann
705c9d36a2 Count variables referenced in assembly code as used. 2022-12-13 19:04:18 -06:00
Stephen Heumann
4bc486eade Do not require unused static functions to be defined.
This mostly implements the rule in C17 6.9 p3, which requires a definition to be provided only if the function is used in an expression. Per that rule, we should also exclude most sizeof or _Alignof operands, but we don't do that yet.
2022-12-12 22:10:36 -06:00
Stephen Heumann
fe62f70d51 Add lint option to check for unused variables. 2022-12-12 21:47:32 -06:00
Stephen Heumann
44499bdddb Make root files jump to the shutdown code rather than calling it.
This better reflects that the shutdown code will never return.
2022-12-11 22:14:09 -06:00
Stephen Heumann
17936a14ed Rework root file code for CDevs to avoid leaking user IDs.
Formerly, the code would allocate user IDs but never free them. The result was that one user ID was leaked for each time a CDev was opened and closed.

The new root code calls new cleanup code in ORCALib, which detects if the CDev is going away and deallocates its user ID if so.
2022-12-11 22:01:29 -06:00
Stephen Heumann
ecca7a7737 Never make the segment in the root file dynamic.
This would previously happen if a segment directive with "dynamic" appeared before the first function in the program. That would cause the resulting program not to work, because the root segment needs to be a static segment at the start of the program, but if it is dynamic it would come after a jump table and a static segment of library code.

The root segments are also configured to refer to main or the NDA/CDA entry points using LEXPR records, so that they can be in dynamic segments (not that they necessarily should be). That change is intentionally not done for CDEV/XCMD/NBA, because they use code resources, which do not support dynamic segments, so it is better to force a linker error in these cases.
2022-12-11 14:46:38 -06:00
Stephen Heumann
1754607908 Add native peephole opts for stack repair code.
These mainly affect cases of multiple successive or nested function calls.
2022-12-10 21:56:16 -06:00
Stephen Heumann
32975b720f Allow native code peephole opt to be used when stack repair is enabled.
I think the reason this was originally disallowed is that the old code sequence for stack repair code (in ORCA/C 2.1.0) ended with TYA. If this was followed by STA dp or STA abs, the native code peephole optimizer (prior to commit 7364e2d2d3) would have turned the combination into a STY instruction. That is invalid if the value in A is needed. This could come up, e.g., when assigning the return value from a function to two different variables.

This is no longer an issue, because the current code sequence for stack repair code no longer ends in TYA and is not susceptible to the same kind of invalid optimization. So it is no longer necessary to disable the native code peephole optimizer when using stack repair code (either for all calls or just varargs calls).
2022-12-10 20:34:00 -06:00
Stephen Heumann
7364e2d2d3 Fix issue with native code optimization of TYA+STA.
This would be changed to STY, but that is invalid if the A value is needed afterward. This could affect the code for certain division operations (after the optimizations in commit 4470626ade).

Here is an example that would be miscompiled:

#pragma optimize -1
#include <stdio.h>
int main(void) {
        unsigned i = 55555;
        unsigned a,b;
        a = b = i / 10000;
        printf("%u %u\n", a,b);
}

Also, remove MVN from the list of "ASafe" instructions since it really isn't, although I don't think this was affecting anything in practice.
2022-12-10 19:37:48 -06:00
Stephen Heumann
e71fe5d785 Treat unary + as an actual operator, not a no-op.
This is necessary both to detect errors (using unary + on non-arithmetic types) and to correctly perform the integer promotions when unary + is used (which can be detected with sizeof or _Generic).
2022-12-09 19:03:38 -06:00
Stephen Heumann
f027286b6a Do not generate varargs stack repair code if no variable args are passed.
This affects calls to a varargs function that do not actually supply any arguments beyond the fixed portion of the argument list, e.g. printf("foo"). Since these calls do not supply any variable arguments, they clearly do not include any extra variable arguments beyond those used by the function, so the standards-conformance issue that requires varargs stack repair code does not apply.

It is possible that the call may include too few variable arguments, but that is illegal behavior, and it will trash the stack even when varargs stack repair code is present (although in some cases programs may "get away" with it). If stack repair code around these calls is still desired, then general stack repair code can be enabled for all function calls.
2022-12-08 19:27:37 -06:00
Stephen Heumann
6ba6ad549f Change va_start to not depend on the last fixed argument.
This is necessary to work correctly if the last fixed argument is of type double and #pragma extensions bit 1 is clear. It will also be necessary for C23, where va_start does not require the LastFixedParm argument. (For now, however, we stick with the pre-C23 definition of va_start where that argument needs to be supplied, even though it is now ignored.)
2022-12-08 19:15:53 -06:00
Stephen Heumann
fb5a2fcf33 Generate more efficient code for shifts by 13, 14, or 15 bits. 2022-12-07 21:54:53 -06:00
Stephen Heumann
bb1bd176f4 Add a command-line option to select the C standard to use.
This provides a more straightforward way to place the compiler in a "strict conformance" mode. This could essentially be achieved by setting several pragma options, but having a single setting is simpler. "Compatibility modes" for older standards can also be selected, although these actually continue to enable most C17 features (since they are unlikely to cause compatibility problems for older code).
2022-12-07 21:35:15 -06:00
Stephen Heumann
6857913daa Make the object buffer dynamically resizable.
It will now grow as needed to accommodate large segments, subject to the constraints of available memory. In practice, this mostly affects the size of initialized static arrays that can be used.

This also removes any limit apart from memory size on how large the object representation produced by a "compile to memory" can be, and cleans up error reporting regarding size limits.
2022-12-06 21:49:20 -06:00
Stephen Heumann
389f60ed27 Remove segStart variable.
It is the same as objPtr in all meaningful cases, so there is no need for it to be a separate variable.
2022-12-06 19:39:10 -06:00
Stephen Heumann
8aedd42294 Optimize out TDC following TCD.
This can occur if the first code in the function (which could be an initializer) takes the address of a local variable.
2022-12-05 18:02:23 -06:00
Stephen Heumann
a7d9d3039b Initialize arrays from strings with a pc_mov operation.
This is smaller and more efficient than the previous code that called memcpy(). It also avoids a theoretical issue if the user's code included an incompatible definition of memcpy.
2022-12-05 18:00:56 -06:00
Stephen Heumann
0c4660d5fc Generate better code for pc_mov in some cases.
This allows it to use MVN-based copying code in more cases, including when moving to/from local variables on the stack. This is slightly shorter and more efficient than calling a helper function.
2022-12-05 17:58:30 -06:00
Stephen Heumann
8e1db102eb Allow line continuations within // comments.
This is what the standards specify.
2022-12-04 23:16:06 -06:00
Stephen Heumann
facd1bf992 Add parentheses around negative values in float.h. 2022-12-04 22:44:48 -06:00
Stephen Heumann
c06d78bb5e Add __STDC_VERSION__ macro.
With the addition of designated initializers, ORCA/C now supports all the major mandatory language features added between C90 and C17, apart from those made optional by C11. There are still various small areas of nonconformance and a number of missing library functions, but at this point it is reasonable for ORCA/C to report itself as being a C17 implementation.
2022-12-04 22:25:02 -06:00
Stephen Heumann
2550081517 Fix bug with 4-byte comparisons against globals in large memory model.
Long addressing was not being used to access the values, which could lead to mis-evaluation of comparisons against values in global structs, unions, or arrays, depending on the memory layout.

This could sometimes affect the c99desinit.c test, when run with large memory model and at least intermediate code peephole optimization. It could also affect this simpler test (depending on memory layout):

#pragma memorymodel 1
#pragma optimize 1
struct S {
        void *p;
} s =  {&s};
int main(void) {
        return s.p != &s; /* should be 0 */
}
2022-12-04 21:54:29 -06:00
Stephen Heumann
935bb6c04e Merge branch 'designated-initializers'
This implements designated initializers as specified by C99 and later.

It also fixes a few initialization-related bugs.
2022-12-04 21:28:15 -06:00