Commit Graph

499 Commits

Author SHA1 Message Date
Stephen Heumann
5ed820717e Implement conversions from long long to other types in the optimizer.
The code of PeepHoleOptimization is now big enough that it triggers bogus "Relative address out of range" range errors from the linker. This is a linker bug and should be fixed there.
2021-02-18 23:27:18 -06:00
Stephen Heumann
3e5aa5b7b0 Merge branch 'master' into longlong 2021-02-18 20:31:33 -06:00
Stephen Heumann
0f45e1d0ff Fix optimizer bug affecting casts to char types.
When an expression that the intermediate code peephole optimizer could reduce to a constant was cast to a char type, the resulting value could be outside the range of that type.

The following program illustrates the problem:

#pragma optimize 1
#include <stdio.h>
int main(void) {
        int i = 0;
        i = (unsigned char)(i | -1);
        printf("%i\n", i);
}
2021-02-18 20:31:22 -06:00
Stephen Heumann
d891e672e3 Add various intermediate code peephole optimizations.
These mainly cover 64-bit arithmetic and shifts, but also include a few optimizations for 16-bit and 32-bit shifts.
2021-02-18 19:17:39 -06:00
Stephen Heumann
32f4e70826 Fix a comment. 2021-02-18 12:58:57 -06:00
Stephen Heumann
cf463ff155 Support switch statements using long long expressions. 2021-02-17 19:41:46 -06:00
Stephen Heumann
5268f37261 Merge branch 'master' into longlong 2021-02-17 15:38:06 -06:00
Stephen Heumann
28888cf824 Exclude non-standard functions in <string.h> if __KeepNamespacePure__ is defined. 2021-02-17 15:36:38 -06:00
Stephen Heumann
31adb5f5d6 Update headers to support long long (and intmax_t typedef'd as long long).
This includes:
*Functions operating on long long in <stdlib.h>
*Limits of long long types in <limits.h>
*64-bit types and limits (plus intmax_t and its limits) in <stdint.h>
*New format codes, plus functions operating on intmax_t, in <inttypes.h>

The new stuff is generally conditionalized to only be included if __ORCAC_HAS_LONG_LONG__ is defined, or if the implementation claims to be C99 or later. This allows the headers to remain usable with older versions of ORCA/C, or with any hypothetical "strict C89" mode that might be implemented in the future.
2021-02-17 14:57:18 -06:00
Stephen Heumann
6bb91d20e5 Add the predefined macro __ORCAC_HAS_LONG_LONG__.
This allows headers or other code to test for the presence of this feature.
2021-02-17 14:41:09 -06:00
Stephen Heumann
b4604e079e Do preprocessor arithmetic in intmax_t/uintmax_t (aka long long types).
This is what C99 and later require.
2021-02-17 00:04:20 -06:00
Stephen Heumann
955ee74b25 Evaluate 64-bit comparisons in constant expressions. 2021-02-16 23:11:41 -06:00
Stephen Heumann
e3b24fb50b Add support for real to long long conversions. 2021-02-16 18:47:28 -06:00
Stephen Heumann
e38be489df Implement comparisons for signed long long.
These use a library function to perform the comparison.
2021-02-15 18:10:34 -06:00
Stephen Heumann
d2d871181a Implement comparisons (>, >=, <, <=) for unsigned long long. 2021-02-15 14:43:26 -06:00
Stephen Heumann
2e29390e8e Support 64-bit decimal constants in code. 2021-02-15 12:28:30 -06:00
Stephen Heumann
d66f6b27b7 Evaluate arithmetic and shifts in long long constant expressions.
This winds up calling functions for these operations in ORCALib, so an up-to-date version of that must now be available to build the ORCA/C compiler.
2021-02-14 20:39:35 -06:00
Stephen Heumann
76cc4b9ca7 Update printf/scanf format checker to match recent library changes.
*Recognize the 'll' and 'j' size modifiers as denoting long long times.
*Recognize '%P' as equivalent to '%b'.
*Give a warning for 'L' length modifier in scanf, which is currently not supported (except when assignment is suppressed).
2021-02-14 17:45:39 -06:00
Stephen Heumann
eb49e10ea9 Implement && and || operators for long long types.
This is done by comparing against 0 (similar to how it is done for reals), rather than introducing new intermediate code operations.
2021-02-14 17:37:55 -06:00
Stephen Heumann
c537153ee5 Implement pc_ind (load indirect) for long long. 2021-02-13 21:42:06 -06:00
Stephen Heumann
e8b860f89a Do not corrupt long long expressions that cannot be evaluated at compile time.
The changes to constant expressions were not allowing the unsupported constant expressions to be evaluated at run time when they appear in regular code.
2021-02-13 21:14:26 -06:00
Stephen Heumann
c48811add6 Report errors in a few cases where the codegen finds unexpected types.
This makes it more likely that unsupported ops on long long or any other types added in the future will give an error rather than silently generating bad code.

Also, update a comment.
2021-02-13 18:46:00 -06:00
Stephen Heumann
f41cd241f8 Slightly optimize stack save code for calls to long long functions.
The X register is not used as part of the return value, so it does not have to be preserved.
2021-02-13 17:21:13 -06:00
Stephen Heumann
75234dbf83 Handle long long in pc_equ/pc_neq optimizations. 2021-02-13 17:03:49 -06:00
Stephen Heumann
32ae4c2e17 Allow unsigned constants in "address+constant" constant expressions.
This affected initializers like the following:

static int a[50];
static int *ip = &a[0] + 2U;

Also, introduce some basic range checks for calculations that are obviously outside the 65816's address space.
2021-02-13 15:36:54 -06:00
Stephen Heumann
a3050c76a9 Evaluate some kinds of long long operations in constant expressions.
Other operations on long long (e.g. arithmetic) are still not supported in constant expressions.
2021-02-13 15:07:16 -06:00
Stephen Heumann
8faafcc7c8 Implement 64-bit shifts. 2021-02-12 15:06:15 -06:00
Stephen Heumann
00d72f04d3 Implement basic peephole optimizations for some 64-bit operations.
This currently covers bitwise ops, addition, and subtraction.
2021-02-11 19:47:42 -06:00
Stephen Heumann
cb97623878 Do not copy CGI.Comments into CGI.pas.
This has no functional effect, since it is all comments. It does mean that printed listings of CGI.pas would not contain those comments, but it is easy enough to restore if someone wants such listings.

This change should make compilation slightly faster, and it also avoids issues with filetypes when using certain tools (since they cannot infer the filetype of CGI.Comments from its extension).
2021-02-11 18:53:25 -06:00
Stephen Heumann
a804d1766b Merge branch 'master' into longlong 2021-02-11 15:55:15 -06:00
Stephen Heumann
895d0585a8 Small new optimization: "anything % 1" equals 0. 2021-02-11 15:52:44 -06:00
Stephen Heumann
8078675aae Do not eliminate expressions with side effects in "exp | -1" or "exp & 0".
This was previously happening in intermediate code peephole optimization.

The following example program demonstrates the problem:

#pragma optimize 1
int main(void) {
        int i = 0;
        long j = 0;
        ++i | -1;
        ++i & 0;
        ++j | -1;
        ++j & 0;
        return i+j; /* should be 4 */
}
2021-02-11 14:50:36 -06:00
Stephen Heumann
30f2eda4f3 Generate code for long long to real conversions. 2021-02-11 12:41:58 -06:00
Stephen Heumann
b07c8a1ad8 Merge branch 'master' into longlong 2021-02-10 00:25:45 -06:00
Stephen Heumann
25697b1fba Add prototypes for vscanf, vfscanf, and vsscanf. 2021-02-09 23:24:20 -06:00
Stephen Heumann
52f512370f Update tests to account for recent ORCALib changes.
These involve recent standards-conformance patches for printf and scanf, which changed some (non-standard) behaviors that the test cases were expecting.

I also fixed a couple things that clang flagged as undefined behavior, even though they weren't really causing problems under ORCA/C.
2021-02-09 23:18:36 -06:00
Stephen Heumann
446639badc Don't bogusly push stuff on the stack for conversions to non-long types.
This could happen in some cases when converting between signed and unsigned long long (which should not require any code to be generated).
2021-02-06 12:45:44 -06:00
Stephen Heumann
47fdd9e370 Implement support for functions returning (unsigned) long long.
These use a new calling convention specific to functions returning these types. When such functions are called, the caller must set the X register to the address within bank 0 that the return value is to be saved to. The function is then responsible for saving it there before returning to the caller.

Currently, the calling code always makes space for the return value on the stack and sets X to point to that. (As an optimization, it would be possible to have the return value written directly to a local variable on the direct page, with no change needed to the function being called, but that has not yet been implemented.)
2021-02-05 23:25:46 -06:00
Stephen Heumann
11938d51ff Compute how many bytes of arguments are passed to a function.
This is preparatory to supporting a new calling convention for functions returning long long.
2021-02-05 20:52:03 -06:00
Stephen Heumann
05868667b2 Implement 64-bit division and remainder, signed and unsigned.
These operations rely on new library routines in ORCALib (~CDIV8 and ~UDIV8).
2021-02-05 12:42:48 -06:00
Stephen Heumann
08cf7a0181 Implement 64-bit multiplication support.
Signed multiplication uses the existing ~MUL8 routine in SysLib. Unsigned multiplication will use a new ~UMUL8 library routine.
2021-02-04 22:23:59 -06:00
Stephen Heumann
7f3ba768cd Allow pointer arithmetic using long long values.
This converts them to 32-bit values before doing computations, which is (more than) sufficient for address calculations on the 65816. Trying to compute an address outside the legal range is undefined behavior, and does not necessarily "wrap around" in a predictable way.
2021-02-04 22:05:02 -06:00
Stephen Heumann
8992ddc11f Implement indirect store/copy operations for 64-bit types.
These operations (pc_sto and pc_cpi) are used for access through a pointer, and in some cases also for initialization.
2021-02-04 18:32:06 -06:00
Stephen Heumann
fc3bd32e65 Add long long support for a couple lint checks. 2021-02-04 17:53:37 -06:00
Stephen Heumann
d2fb8cc27e Add long long support for the ! operator. 2021-02-04 17:53:10 -06:00
Stephen Heumann
5e5434987b Give an error when trying to evaluate constant expressions with long long operands. 2021-02-04 14:56:15 -06:00
Stephen Heumann
2408c9602c Make expressionValue a saturating approximation of the true value for long long expressions.
This gives sensible behavior for several things in the parser, e.g. where all negative values or all very large values should be disallowed.
2021-02-04 12:44:44 -06:00
Stephen Heumann
10cf6e446d Enable automatic comparison with 0 for long longs.
This allows them to be used in if statements and as controlling expressions for loops.
2021-02-04 12:39:27 -06:00
Stephen Heumann
a59a2427fd Add some support for ++/-- on long long values.
Some more complex cases require pc_ind, which is not implemented yet.
2021-02-04 12:35:28 -06:00
Stephen Heumann
168a06b7bf Add support for emitting 64-bit constants in statically-initialized data. 2021-02-04 02:17:10 -06:00