Commit Graph

906 Commits

Author SHA1 Message Date
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
Stephen Heumann
f5f63563c6 Add tests for designated initializers. 2022-12-04 21:26:40 -06:00
Stephen Heumann
736e7575cf Fix issues with type conversions in static initialization.
*Initialization of floating-point variables from unsigned long expressions with value > LONG_MAX would give the wrong value.
*Initialization of floating-point variables from (unsigned) long long expressions would give the wrong value.
*Initialization of _Bool variables should give 0 or 1, as per the usual rules for conversion to _Bool.
*Initialization of integer variables from floating-point expressions should be allowed, applying the usual conversions.
2022-12-04 16:36:16 -06:00
Stephen Heumann
36c70f9107 Move ResolveForwardReference call to apply to the field being initialized. 2022-12-04 16:23:33 -06:00
Stephen Heumann
20770f388e Move memory allocation code to a new function in MM. 2022-12-03 18:50:26 -06:00
Stephen Heumann
7c0492cfa4 Document designated initializers in the release notes. 2022-12-03 18:04:50 -06:00
Stephen Heumann
945d5ce855 Generate calls to ~ZERO to initialize large numbers of zero bytes.
There is a tradeoff of code size vs. speed, since a sequence of STZ instructions is faster than a call to ~ZERO but could be quite large for a big array or struct. We now use ~ZERO for initializations of over 50 bytes to avoid excessive code bloat; the exact number chosen is somewhat arbitrary.
2022-12-03 15:30:31 -06:00
Stephen Heumann
d56cf7e666 Pass constant data to backend as pointers into buffer.
This avoids needing to generate many intermediate code records representing the data at most 8 bytes at a time, which should reduce memory use and probably improve performance for large initialized arrays or structs.
2022-12-03 00:14:15 -06:00
Stephen Heumann
28e119afb1 Rework static initialization to support new-style initializer records.
Static initialization of arrays/structs/unions now essentially "executes" the initializer records to fill in a buffer (and keep track of relocations), then emits pcode to represent that initialized state. This supports overlapping and out-of-order initializer records, as can be produced by designated initialization.
2022-12-02 21:55:57 -06:00
Stephen Heumann
48efd462ef Allow designated initialization of fields named the same as typedefs.
They are in separate name spaces, so this should be permitted.
2022-12-01 14:09:03 -06:00
Stephen Heumann
8ad58b0de7 Report an error for dual commas at end of struct/union initializer.
This covers things like:

struct {int a,b;} u = {1,2,,};
2022-11-30 19:07:38 -06:00
Stephen Heumann
c1a188aa95 Add some comments in initialization code. 2022-11-30 18:55:43 -06:00
Stephen Heumann
51951721c5 Simplify Fill procedure.
In the current design, it only needs to fill in a certain number of bytes, not a specific type.
2022-11-30 18:37:28 -06:00
Stephen Heumann
94584b0f05 Give error for arrays that are still 0 size after initialization.
This prohibits empty initializers ({}) for arrays of unknown size, consistent with C23 requirements. Previous versions of C did not allow empty initializers at all, but ORCA/C historically did in some cases, so this patch still allows them for structs/unions/arrays of known size.
2022-11-30 17:57:21 -06:00
Stephen Heumann
e7940db4c8 Allow initializers where a string literal begins a longer expression.
This is needed to support cases like:

char s[5] = {"abc"[1]};
2022-11-29 21:15:42 -06:00
Stephen Heumann
1f468c437f Set errorFound to true for most errors during initialization. 2022-11-29 13:20:30 -06:00
Stephen Heumann
ac741e26ab Allow nested auto structs/unions to be initialized with an expression of the same type.
When the expression is initially parsed, we do not necessarily know whether it is the initializer for the struct/union or for its first member. That needs to be determined based on the type. To support that, a new function is added to evaluate the expression separately from using it to initialize an object.
2022-11-29 13:19:59 -06:00
Stephen Heumann
c58d84689a Explicitly set disp for every array element.
This is needed to properly deal with arrays of structures with unnamed bit-fields at the end.
2022-11-28 22:11:39 -06:00
Stephen Heumann
4a8b5b25c7 Use a variable to indicate storage duration for initialization. 2022-11-28 21:59:08 -06:00
Stephen Heumann
50e3a8ea30 Avoid dereferencing nil. 2022-11-28 21:44:30 -06:00
Stephen Heumann
bde70e0885 Simplify fill-with-zeros logic.
It now just fills on levels with braces (or at the end of a string).
2022-11-28 21:41:05 -06:00
Stephen Heumann
dc305a86b2 Add flag to suppress printing of put-back tokens with #pragma expand.
This is currently used in a couple places in the designated initializer code (solving the problem with #pragma expand in the last commit). It could probably be used elsewhere too, but for now it is not.
2022-11-28 21:22:56 -06:00
Stephen Heumann
39250629bd Support designated initialization of anonymous member fields.
As noted previously, there is some ambiguity in the standards about how anonymous structs/unions participate in initialization. ORCA/C follows the model that they do participate as structs or unions, and designated initialization of them is implemented accordingly.

This currently has a slight issue in that extra copies of the anonymous member field name will be printed in #pragma expand output.
2022-11-28 20:55:47 -06:00
Stephen Heumann
4621336c3b Give anonymous structs/unions unique internal names.
This will help deal with initialization of them.
2022-11-28 20:47:13 -06:00
Stephen Heumann
a3c4eeb8f6 Rework bit-field initialization.
This generally simplifies things, and always generates individual initializer records for each explicit initialization of a bit-field (which was previously done for automatic initialization, but not static).

This should work correctly for automatic initialization, but needs corresponding code changes in GenSymbols for static initialization.
2022-11-28 18:49:49 -06:00
Stephen Heumann
adfa7c04c1 Support for filling uninitialized data in structs/unions during initialization. 2022-11-28 18:46:40 -06:00
Stephen Heumann
c261e14d56 Basic support for mixing array and struct designators. 2022-11-27 23:54:24 -06:00
Stephen Heumann
250a6361c1 Basic code to handle struct/union designators.
This does not deal with filling yet.
2022-11-27 23:37:22 -06:00
Stephen Heumann
def9e56e8e Fill logic for when to fill uninitialized data with zeros.
This could maybe be simplified to just fill on levels with braces, but I want to consider that after implementing designated initializers for structs and unions.
2022-11-27 17:30:36 -06:00
Stephen Heumann
6260a27b11 Use 16-bit operations to zero out a range of bytes. 2022-11-27 16:49:43 -06:00
Stephen Heumann
58d8edf1ee Handle filling of array elements without explicit initializers.
At this point, designated initializers for arrays are at least largely working.
2022-11-27 16:48:58 -06:00
Stephen Heumann
aa6b82a136 Ensure array designators are processed at the level with braces. 2022-11-26 23:03:20 -06:00
Stephen Heumann
5df94c953e Fix handling of initializer counts in AutoInit.
This was broken by the previous changes to it.
2022-11-26 21:09:53 -06:00
Stephen Heumann
335e8be75e Rename the procedure for initializing one element of an auto variable.
"InitializeOneElement" is more descriptive of what it does now. We also skip passing the variable, which is always the same.
2022-11-26 20:46:24 -06:00
Stephen Heumann
5f8a6baa94 Get rid of an unnecessary field in initializer records.
The "isStructOrUnion" information can now be determined simply by the type in the record.
2022-11-26 20:29:31 -06:00
Stephen Heumann
968844fb38 Make auto initialization use the type and disp in initializer record.
This simplifies the code a good bit, as well as enabling out-of-order initialization using designated initializers.
2022-11-26 20:24:33 -06:00
Stephen Heumann
d1edc8821d Record the type being initialized in auto initializer records. 2022-11-26 19:58:01 -06:00
Stephen Heumann
cd9931a60c Record displacement from start of object in initializer records.
The idea (not yet implemented) is to use this to support out-of-order initialization. For automatic variables, we can just initialize the subobjects in the order that initializers appear. For static variables, we will eventually need to reorder the initializers in order, but this can be done based on their recorded displacements.
2022-11-26 19:27:17 -06:00
Stephen Heumann
8cfc14b50a Rename itype field of initializerRecord to basetype. 2022-11-26 15:45:26 -06:00
Stephen Heumann
b6d3dfb075 Designated initializers for arrays, part 1.
This can parse designated initializers for arrays, but does not create proper initializer records for them.
2022-11-26 15:22:58 -06:00
Stephen Heumann
740468f75c Avoid generating invalid .sym files if header ends with a partial prototyped function decl.
This could happen because the nested calls to DoDeclaration for the parameters would set inhibitHeader to false.
2022-11-26 14:20:58 -06:00
Stephen Heumann
2bf3862e5d Avoid generating invalid .sym files if header ends with a partial declaration.
The part of the declaration within the header could be ignored on subsequent compilations using the .sym file, which could lead to errors or misbehavior.

(This also applies to headers that end in the middle of a _Static_assert(...) or segment directive.)
2022-11-26 00:18:57 -06:00
Stephen Heumann
92a3af1d5f Fix icp/isp tables to account for otherch.
Commit 9cc72c8845 introduced otherch tokens but did not properly update these tables to account for them. This would cause * not to be accepted as the first character in an expression, and might also cause other problems.
2022-11-25 23:25:58 -06:00