Commit Graph

465 Commits

Author SHA1 Message Date
Stephen Heumann b16210a50b Record volatile and restrict qualifiers in types.
These are needed to correctly distinguish pointer types in _Generic. They should also be used for type compatibility checks in other contexts, but currently are not.

This also fixes a couple small problems related to type qualifiers:
*restrict was not allowed to appear after * in type-names
*volatile status was not properly recorded in sym files

Here is an example of using _Generic to distinguish pointer types based on the qualifiers of the pointed-to type:

#include <stdio.h>

#define f(e) _Generic((e),\
        int * restrict *: 1,\
        int * volatile const *: 2,\
        int **: 3,\
        default: 0)

#define g(e) _Generic((e),\
        int *: 1,\
        const int *: 2,\
        volatile int *: 3,\
        default: 0)

int main(void) {
        int * restrict * p1;
        int * volatile const * p2;
        int * const * p3;

        // should print "1 2 0 1"
        printf("%i %i %i %i\n", f(p1), f(p2), f(p3), f((int * restrict *)0));

        int *q1;
        const int *q2;
        volatile int *q3;
        const volatile int *q4;

        // should print "1 2 3 0"
        printf("%i %i %i %i\n", g(q1), g(q2), g(q3), g(q4));
}

Here is an example of a problem resulting from volatile not being recorded in sym files (if a sym file was present, the read of x was lifted out of the loop):

#pragma optimize -1
static volatile int x;
#include <stdio.h>
int main(void) {
        int y;
        for (unsigned i = 0; i < 100; i++) {
                y = x*2 + 7;
        }
}
2021-08-30 18:19:58 -05:00
Stephen Heumann 586e3f9146 Document that toint() is a non-standard extension. 2021-08-26 22:27:08 -05:00
Stephen Heumann 08dbe1eea3 Include the function name in assertion failure messages.
This is required by C99 and later, enabled by the availability of __func__.

This requires an updated assertion-printing function in ORCALib. Unfortunately, GNO has the assertion-printing function in its libc rather than in ORCALib, because it calls the GNO implementation of stdio. Therefore, we continue to use the old form under GNO for now, to maintain compatibility with its existing libc.
2021-08-24 18:35:01 -05:00
Stephen Heumann aa5b239824 Make CLOCKS_PER_SEC and CLK_TCK work in 50Hz video mode.
Previously, they were hard-coded as 60, but the clock tick frequency actually depends on the video mode. They now call a new library function that can detect the video mode and return the proper value.

This also makes CLOCKS_PER_SEC have the type clock_t, as C99 and later require.
2021-08-23 21:58:19 -05:00
Stephen Heumann 2b9d332580 Give an appropriate error for an illegal operator in a constant expression.
This was being reported as an "illegal type cast".
2021-08-22 20:33:34 -05:00
Stephen Heumann e4515e580a Omit all non-standard stuff from <ctype.h> if __KeepNamespacePure__ is defined.
This affects the toint function and the _tolower and _toupper macros. Several other non-standard functions and macros were already being omitted.
2021-08-22 17:35:16 -05:00
Stephen Heumann bb51e77193 Make MB_CUR_MAX have type size_t, as C99 and later require. 2021-08-22 17:35:16 -05:00
Stephen Heumann d5f1987dc4 Small updates to release notes. 2021-08-22 17:35:16 -05:00
Stephen Heumann 5faf219eff Update comments about pragma flags. 2021-08-22 17:35:16 -05:00
Stephen Heumann 6ead1d4caf Add a set of new tests for C95/C99/C11 features that we now support.
These are currently only run by the new DOIT3 test-running script.

Note that these tests are designed to be applicable to most implementations of C95/C99/C11, not just ORCA/C. They do make certain assumptions not guaranteed by the standards (e.g. power of 2 types and some properties of IEEE-like FP), but in general those assumptions should be true for most 'normal' systems.
2021-08-22 17:32:56 -05:00
Stephen Heumann 40f560039d Consistently use upper-case filenames for existing test cases. 2021-07-09 19:43:57 -05:00
Stephen Heumann fbdbad1f45 Report an error for certain large unsigned enumeration constants.
Enumeration constants must have values representable as an int (i.e. 16-bit signed values, in ORCA/C), but errors were not being reported if code tried to use the values 0xFFFF8000 to 0xFFFFFFFF. This problem could also affect certain larger values of type unsigned long long. The issue stemmed from not properly accounting for whether the constant expression had a signed or unsigned type.

This sample code demonstrated the problem:

enum E {
        a = 0xFFFFFFFF,
        b = 0xFFFF8000,
        y = 0x7FFFFFFFFFFFFFFFull,
        z = 0x8000000000000000
};
2021-07-07 20:06:05 -05:00
Stephen Heumann ae45bd4538 Update release notes. 2021-07-06 18:41:40 -05:00
Stephen Heumann debd0ccffc Always allow the middle expression of a ? : expression to use the comma operator.
This should be allowed, but it previously could lead to spurious errors in contexts like argument lists, where a comma would normally be expected to end the expression.

The following example program demonstrated the problem:

#include <stdlib.h>
int main(void) {
        return abs(1 ? 2,-3 : 4);
}
2021-03-16 18:20:42 -05:00
Stephen Heumann 03f267ac02 Write out long long constants when using #pragma expand. 2021-03-11 23:20:14 -06:00
Stephen Heumann dae27757d3 As of C11, errno must be a macro, so make it one. 2021-03-11 21:16:41 -06:00
Stephen Heumann 9cd2807bc8 Do not leave behind detritus from the spinner when using #pragma expand.
This could happen with the following example (under ORCA/Shell with output to the screen only):

#include <stdio.h>
#pragma expand 1

int main(void) {
}
2021-03-11 19:01:38 -06:00
Stephen Heumann c95d8d9f9b Optimize away unneeded floating-point conversions after loads. 2021-03-10 18:48:58 -06:00
Stephen Heumann 031af54112 Save the original value when doing postfix ++/-- on fp types.
The old code would add 1 and then subtract 1, which does not necessarily give the original value (e.g. if it is much less than 1).
2021-03-09 19:29:55 -06:00
Stephen Heumann db7a0a995d Update release notes with discussion of new floating-point features. 2021-03-09 18:01:30 -06:00
Stephen Heumann 4381b97f86 Report an error if a type name is missing in a _Generic expression. 2021-03-09 17:45:49 -06:00
Stephen Heumann 8fd091e119 Implement the signbit() macro.
This uses a new helper function.
2021-03-09 00:24:08 -06:00
Stephen Heumann a3006e46b1 Add more floating-point classification macros. 2021-03-09 00:08:04 -06:00
Stephen Heumann 17a7fc5487 Add fpclassify() macro and some other stuff from C99 to <math.h>.
fpclassify() is a type-generic macro that is implemented via new internal library routines.
2021-03-08 23:42:44 -06:00
Stephen Heumann cad042b95b Add new <float.h> macros from C99 and C11. 2021-03-08 19:16:28 -06:00
Stephen Heumann 0ba8e4adb0 Update the limit values in <float.h>.
The correct values for LDBL_MAX and LDBL_MIN can now be provided, because we support long double constants. The other values are also updated to have more precision, so that they evaluate to bit-correct values in the long double format.
2021-03-08 18:32:33 -06:00
Stephen Heumann 57d11a573d Document _Generic expressions in the release notes. 2021-03-08 00:29:55 -06:00
Stephen Heumann f2414cd815 Create a new function that checks for compatible types strictly according to the C standards.
For now, this is only used for _Generic expressions. Eventually, it should probably replace the current CompTypes, but CompTypes currently performs somewhat looser checks that are suitable for some situations, so adjustments would be needed at some call sites.
2021-03-07 23:39:30 -06:00
Stephen Heumann 2de8ac993e Fix to make _Generic handle struct types properly.
Also, use an existing error message instead of creating a new equivalent one.
2021-03-07 23:35:12 -06:00
Stephen Heumann bccd86a627 Implement _Generic expressions (from C11).
Note that this code relies on CompTypes for type compatibility testing, and it has slightly non-standard behavior in some cases.
2021-03-07 21:59:37 -06:00
Stephen Heumann 2b7e72ac49 Document <fenv.h> and standard pragmas in the release notes. 2021-03-07 15:11:49 -06:00
Stephen Heumann 979852be3c Use the right types for constants cast to character types.
These were previously treated as having type int. This resulted in incorrect results from sizeof, and would also be a problem for _Generic if it was implemented.

Note that this creates a token kind of "charconst", but this is not the kind for character constants in the source code. Those have type int, so their kind is intconst. The new kinds of "tokens" are created only through casts of constant expressions.
2021-03-07 13:38:21 -06:00
Stephen Heumann 8f8e7f12e2 Distinguish the different types of floating-point constants.
As with expressions, the type does not actually limit the precision and range of values represented.
2021-03-07 00:48:51 -06:00
Stephen Heumann 41623529d7 Keep track of semantic type of floating-point expressions.
Previously, the type was forced to extended in many circumstances. This was visible in that the results of sizeof were incorrect. It would also affect _Generic, if and when that is implemented.

Note that this does not affect the actual format used for computations and storage of intermediates. That is still the extended format.
2021-03-06 23:54:55 -06:00
Stephen Heumann cf9add4720 Clean up code generated by real negation optimization.
This could read and write a byte beyond the value being modified. This normally would not matter, but theoretically could in some cases involving concurrency.
2021-03-06 23:16:21 -06: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 92048171ef Update definition of FLT_ROUNDS to reflect the dynamic rounding mode. 2021-03-06 16:40:35 -06:00
Stephen Heumann 2630b51b74 Add the <fenv.h> header. 2021-03-06 16:31:52 -06:00
Stephen Heumann f368071146 Do some more checks for invalid sym files. 2021-03-06 15:02:51 -06:00
Stephen Heumann f9f79983f8 Implement the standard pragmas, in particular FENV_ACCESS.
The FENV_ACCESS pragma is now implemented. It causes floating-point operations to be evaluated at run time to the maximum extent possible, so that they can affect and be affected by the floating-point environment. It also disables optimizations that might evaluate floating-point operations at compile time or move them around calls to the <fenv.h> functions.

The FP_CONTRACT and CX_LIMITED_RANGE pragmas are also recognized, but they have no effect. (FP_CONTRACT relates to "contracting" floating-point expressions in a way that ORCA/C does not do, and CX_LIMITED_RANGE relates to complex arithmetic, which ORCA/C does not support.)
2021-03-06 00:57:13 -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 77d66ab699 Support the predefined identifier __func__ (from C99).
This gives the name of the current function, as if the following definition appeared at the beginning of the function body:

static const char __func__[] = "function-name";
2021-03-02 22:28:28 -06:00
Stephen Heumann f19d21365a Recognize more indirect long instructions in the native code optimizer.
These instructions can be generated for indirect accesses to quad values, and the optimization can sometimes make those code sequences more efficient (e.g. avoiding unnecessary reloads of Y).
2021-03-02 19:19:00 -06:00
Stephen Heumann dcbeb3bc61 Optimize unsigned comparisons with 0.
These are either tautological or can be turned into equality/inequality tests, which generate better code.
2021-03-01 22:12:38 -06:00
Stephen Heumann da715ae854 Fix a buggy test case.
It was calling fabs() without having included <math.h>, causing fabs() to be treated as returning an int rather than a floating-point value. This misinterpretation of the return value could cause test failures.
2021-03-01 17:52:59 -06:00
Kelvin Sherlock b39dd0f34c ||, &&, ==, and != ops were clobbering the upper 32-bits
before comparing them.

#if 0xffffffff00000000==0
#error ...
#endif
#if 0xffffffff00000000!=0xffffffff00000000
#error ...
#endif
2021-03-01 18:13:16 -05:00