Instead of `val` right (left) shifts, we can also do `9 - val` left (right)
rotates and a mask. This saves 3 bytes and 8 cycles for `val == 7` and
1 byte and 4 cycles for `val == 6`.
If lhs and rhs are either both signed char or both unsigned char,
return flags for that type instead of (unsigned) int. The flags
are used only for codegen. Currently, this does nothing, since
codegen treats chars as ints unless CF_FORCECHAR is set, but it
allows more efficient char x char -> int codegen to be added in
the future.
Only the low bytes are compared. Originally, signed 16-bit compares were optimized into signed 8-bit compares. But, the sign bits are in the high bytes; and, they're equal. Therefore, the low bytes always must be compared as unsigned numbers.
Fixes#1348.
The old broken code defers the count until the end of the (parent function's) argument list. But, a nested function call clears the pointer to the deferred type. That leads to an access violation.
The new code defers only until the end of each argument. Fixes#1320.
I placed the Git tag V2.19 in hindsight at 555282497c. But I certainly don't want to rewrite the Git history just for the reported version, so I simply set the reported version at today's HEAD to 2.19.
When there is an integral constant like `3` in an expression, it has
type `int` according to the C spec, even though it can be represented
as an `unsigned char`. Change codegen (`hie_internal` and `typeadjust`)
to treat it as `unsigned char` instead of `int` so that faster,
unsigned operations can be used.
For the test case in #1298, reduces the cycles per iteration from
4311 to 1884. This is a great improvement, but still much worse than
the 1053 cycles/iter from `c4698df~`, so more work remains to be done.
Further partial fix for #1298 and #1308.
In g_typeadjust, before we apply the integral promotions, we check if
both types are unsigned char. If so, we promote to unsigned int, rather
than int, which would be chosen by the standard rules. This is only a
performance optimization and does not affect correctness, as the flags
returned by g_typeadjust are only used for code generation, and not to
determine types of other expressions containing this one. All unsigned
char bit-patterns are valid as both int and unsigned int and represent
the same value, so either signed or unsigned int operations can be used.
This special case part is not duplicated by ArithmeticConvert.
Partial fix for #1308.
This usually allows faster & smaller code.
Note that deferred operations must still be called at sequence points even if the whole expressions containing them had constant values.
Partial fix for ICE in #1211. This may fix enough to allow #1049 to be
fixed.
When merging labels, keep the first label with a ref that has no JumpTo;
this is a data segment label, used by computed gotos.
The real fix is to track and rewrite labels in data, but this is more
involved.
Fixes#1267
Avoid ICE, but treat plain int bit-fields declared via typedef as
signed rather than unsigned. It is more efficient to treat them
as unsigned, but this requires distinguishing int from signed int,
and this is curently not done.
Fix copy & paste bug with warning message.
struct X {
signed int a : 3;
};
struct X g = { 5 };
Before:
s.c(4): Warning: Implicit truncation from 'int' to 'int : 3' in bit-field
initializer changes value from 5 to 5
After:
s.c(4): Warning: Implicit truncation from 'int' to 'int : 3' in bit-field
initializer changes value from 5 to -3
Fixes#1268
Made cc65 replace a bad bit-field type with a good one, and always parse the field width.
Shortenned a parameter name to a spelling that's consistent with other function headers.
Some existing optimizations are impacted and need fixes in order to work correctly again.
Fixed and improved OptPrecalc. Now it respects the C/V/Z/N flags.
Fixed optimizations impacted by added support of tracking processor flags.
Added ZNRegs for tracking what register(s) Z/N flags currently reflect.
Added utility functions to check if the specified processor state is known to be a certain value.
This previously resulted in an ICE:
cc65: Check failed: (Entry->Type->C & T_MASK_SIGN) == T_SIGN_SIGNED,
file 'cc65/symtab.c', line 874
This CHECK is in the code that deals with changing `int` bitfields to
`unsigned int`.
Work around this by treating enum bit-fields as having their signedness
specified, so this type change code does not get called.
Fixes#1244.