Commit Graph

70 Commits

Author SHA1 Message Date
Stephen Heumann
785a6997de Record source file changes within a function as part of debug info.
This affects functions whose body spans multiple files due to includes, or is treated as doing so due to #line directives. ORCA/C will now generate a COP 6 instruction to record each source file change, allowing debuggers to properly track the flow of execution across files.
2022-02-05 18:32:11 -06:00
Stephen Heumann
5ac79ff36c Stop capitalizing file names in debug information.
This does not seem to be necessary for any of the debuggers (at least in their latest versions), and it obviously causes problems with case-sensitive filesystems.
2022-02-04 22:15:02 -06:00
Stephen Heumann
242bef1f6e Correct a comment. 2022-01-17 18:27:10 -06:00
Stephen Heumann
7584f8185c Add ability to force stack repair and checking off for certain calls.
This can be used on library calls generated by the compiler for internal purposes.
2021-10-19 22:10:04 -05:00
Stephen Heumann
5871820e0c Support UTF-8/16/32 string literals and character constants (C11).
These have u8, u, or U prefixes, respectively. The types char16_t and char32_t (defined in <uchar.h>) are used for UTF-16 and UTF-32 code points.
2021-10-11 20:54:37 -05:00
Stephen Heumann
650ff4697f Update release notes to include a bug fix in ORCALib.
Also, update a comment to reflect the actual behavior.
2021-09-17 19:28:21 -05:00
Stephen Heumann
d72c0fb9a5 Fix bug in some cases where a byte value is loaded and then stored as a word.
It could wind up storing garbage in the upper 8 bits of the destination, because it was not doing a proper 8-bit to 16-bit conversion.

This is an old bug, but the change in commit 95f5182442 caused it to be triggered in more cases, e.g. in the C7.5.1.1.CC test case.

Here is a case that could exhibit the bug even before that:

#pragma optimize 1
#include <stdio.h>
int main(void) {
        int k[1];
        int i = 0;
        unsigned char uch = 'm';
        k[i] = uch;
        printf("%i\n", k[0]);
}
2021-09-03 18:10:27 -05:00
Stephen Heumann
acddd93ffb Avoid a precision reduction in some cases where it is not needed. 2021-03-06 23:14:29 -06:00
Stephen Heumann
fc515108f4 Make floating-point casts reduce the range and precision of numbers.
The C standards generally allow floating-point operations to be done with extra range and precision, but they require that explicit casts convert to the actual type specified. ORCA/C was not previously doing that.

This patch relies on some new library routines (currently in ORCALib) to do this precision reduction.

This fixes #64.
2021-03-06 22:28:39 -06:00
Stephen Heumann
c0727315e0 Recognize byte swapping and generate an xba instruction for it.
Specifically, this recognizes the pattern "(exp << 8) | (exp >> 8)", where exp has an unsigned 16-bit type and does not have side effects.
2021-03-05 22:00:13 -06:00
Stephen Heumann
95f5182442 Change copies to stores when the value is unused.
This was already done by the optimizer, but it is simple enough to just do it all the time. This avoids most performance regressions from the previous commit, and also generates more efficient code for long long stores (in the common cases where the value of an assignment expression is not used in any larger expression).
2021-03-05 19:44:38 -06:00
Stephen Heumann
4a7e994da8 Eliminate extra precision when doing floating-point assignments.
The value of an assignment expression should be exactly what gets written to the destination, without any extra range or precision. Since floating-point expressions generally do have extra precision, we need to load the actual stored value to get rid of it.
2021-03-05 19:21:54 -06:00
Stephen Heumann
4ad7a65de6 Process floating-point values within the compiler using the extended type.
This means that floating-point constants can now have the range and precision of the extended type (aka long double), and floating-point constant expressions evaluated within the compiler also have that same range and precision (matching expressions evaluated at run time). This new behavior is intended to match the behavior specified in the C99 and later standards for FLT_EVAL_METHOD 2.

This fixes the previous problem where long double constants and constant expressions of type long double were not represented and evaluated with the full range and precision that they should be. It also gives extra range and precision to constants and constant expressions of type double or float. This may have pluses and minuses, but at any rate it is consistent with the existing behavior for expressions evaluated at run time, and with one of the possible models of floating point evaluation specified in the C standards.
2021-03-04 23:58:08 -06:00
Stephen Heumann
36d31ab37c Optimize quad == 0 comparisons. 2021-02-25 21:40:32 -06:00
Stephen Heumann
5c92a8a0d3 Do unsigned quad inequalities without loading operands on stack. 2021-02-25 20:18:59 -06:00
Stephen Heumann
c5c401d229 Do quad equality comparisons without loading operands on stack. 2021-02-25 20:03:13 -06:00
Stephen Heumann
f1c19d2940 Do unary quad ops without loading operand on stack. 2021-02-25 19:28:36 -06:00
Stephen Heumann
0b56689626 Do quad add/subtract without loading operands on stack.
As with the previous support for bitwise ops, this applies if the operands are simple quad loads.
2021-02-25 18:26:26 -06:00
Stephen Heumann
043124db93 Implement support for doing quad ops without loading operands on stack.
This works when both operands are simple loads, such that they can be broken up into operations on their subwords in a standard format.

Currently, this is implemented for bitwise binary ops, but it can also be expanded to arithmetic, etc.
2021-02-24 19:44:46 -06:00
Stephen Heumann
b0a61fbadf Let functions store a long long return value directly into a variable in the caller.
This optimization works when the return value is stored directly to a local variable and not used otherwise (typically only recognized when using intermediate code peephole optimization).
2021-02-21 18:37:17 -06:00
Stephen Heumann
daff197811 Optimize some quad ops to use interleaved loads and stores.
This allows them to bypass the intermediate step of loading the value onto the stack. Currently, this only works for simple cases where a value is loaded and immediately stored.
2021-02-20 23:38:42 -06:00
Stephen Heumann
3c0e4baf78 Basic infrastructure for using different quadword locations in codegen.
For the moment, this does not really do anything, but it lays the groundwork for not always having to load quadword values to the stack before operating on or storing them.
2021-02-20 17:07:47 -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
c537153ee5 Implement pc_ind (load indirect) for long long. 2021-02-13 21:42:06 -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
8faafcc7c8 Implement 64-bit shifts. 2021-02-12 15:06:15 -06:00
Stephen Heumann
30f2eda4f3 Generate code for long long to real conversions. 2021-02-11 12:41:58 -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
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
793f0a57cc Initial support for constants with long long types.
Currently, the actual values they can have are still constrained to the 32-bit range. Also, there are some bits of functionality (e.g. for initializers) that are not implemented yet.
2021-02-03 23:11:23 -06:00
Stephen Heumann
6a2ea6ccc4 Implement equality/inequality comparisons for 64-bit types. 2021-02-02 18:18:50 -06:00
Stephen Heumann
1dc0dc7a19 Implement remaining conversions of integer types to and from long long.
The floating-point conversions are not done yet (but do now give an error).
2021-02-01 22:43:35 -06:00
Stephen Heumann
0e59588191 Merge branch 'master' into longlong 2021-01-31 14:32:31 -06:00
Stephen Heumann
393fb8d635 Make floating point to character type conversions yield values within the type's range.
This affects cases where the floating value, truncated to an integer, is outside the range of the destination type. Previously, the result value might appear to be an int value outside the range of the character type.

These situations are undefined behavior under the C standards, so this was not technically a bug, but the new behavior is less surprising. (Note that it still may not raise the "invalid" floating-point exception in some cases where Annex F would call for that.)
2021-01-31 14:04:27 -06:00
Stephen Heumann
130d332284 Fix bugs with several operations on negative values of type signed char.
The basic issue with all of these is that they failed to sign-extend the 8-bit signed char value to the full 16-bit A register. This could make certain operations on negative signed char values appear to yield positive values outside the range of signed char.

The following example code demonstrates the problems:

#include <stdio.h>
signed char f(void) {return -50;}
int main(void) {
        long l = -123;
        int i = -99;
        signed char sc = -47;
        signed char *scp = &sc;
        printf("%i\n", (signed char)l);
        printf("%i\n", (signed char)i);
        printf("%i\n", f());
        printf("%i\n", (*scp)++);
        printf("%i\n", *scp = -32);
}
2021-01-31 11:40:07 -06:00
Stephen Heumann
cb99b3778e Flag that conversions may not set CPU flags usable for a subsequent comparison.
There are several conversions that do not set the necessary flags, so they must be set separately before doing a comparison. Without this fix, comparisons of a value that was just converted might be mis-evaluated.

This led to bugs where the wrong side of an "if" could be followed in some cases, as in the below examples:

#include <stdio.h>
int g(void) {return 50;}
signed char h(void) {return 50;}
long lf(void) {return 50;}
int main(void) {
    signed char sc = 50;
    if ((int)(signed char)g()) puts("OK1");
    if ((int)h()) puts("OK2");
    if ((int)sc) puts("OK3");
    if ((int)lf()) puts("OK4");
}
2021-01-31 08:52:50 -06:00
Stephen Heumann
e8497c7b8f Begin implementing conversions to and from 64-bit types.
Some conversions are implemented, but others are not yet.
2021-01-31 08:37:21 -06:00
Stephen Heumann
807a143e51 Implement 64-bit addition and subtraction. 2021-01-30 23:31:18 -06:00
Stephen Heumann
2e44c36c59 Implement unary negation and bitwise complement for 64-bit types. 2021-01-30 13:49:06 -06:00
Stephen Heumann
abb0fa0fc1 Implement bitwise and/or/xor for 64-bit types.
This introduces three new intermediate codes for these operations.
2021-01-30 00:25:15 -06:00
Stephen Heumann
fa835aca43 Implement basic load/store ops for long long.
The following intermediate codes should now work:
pc_lod
pc_pop
pc_str
pc_cop
pc_sro
pc_cpo
2021-01-29 23:11:08 -06:00
Stephen Heumann
ffe6c4e924 Spellcheck comments throughout the code.
There are no non-comment changes.
2020-01-29 17:09:52 -06:00
Stephen Heumann
8b4213cd5a Fix bug where the condition check of the ?: operator may be mis-evaluated.
This could happen in certain cases where the condition codes might not be set at expected. The following program gives an example:

#pragma optimize 1
#include <stdio.h>
int one(void) {return 1;}
int negative_one(void) {return -1;}
int main(void) {
    puts((one() + negative_one()) ? "A" : "B");
}

This could also occur if the condition used the % operator, particularly after the recent changes to it.

Also, add unsigned multiplication, division, and modulo operations to the list of those that may not set the condition codes based on the result value, both in this and other contexts.

Detected based on several programs from FizzBuzz-C.
2018-09-14 13:25:40 -05:00