There are many occurrences of unsigned long in codegen.h's function
arguments. Changing g_getimmed and g_defdata makes `make` succeed
without segfaulting. I don't know if it makes cc65 behave correctly in
all cases, or if there are more unsigned long that need to be changed.
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.
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.
Prior to this PR, `int`, `signed int`, and `unsigned int`
bitfields are all treated as `unsigned int`.
With this PR, `signed int` will be treated as `signed int`,
and the others remain unsigned.
Since `Type` does not distinguish between `int` and `signed int`,
add an extra `int* SignenessSpecified` param to `ParseTypeSpec`
so we can tell these apart for bit-fields and treat plain `int : N`
as `unsigned int : N` since it is more efficient to zero-extend
than sign-extend.
Fixes#1095
Extract functions g_testbitfield and g_extractbitfield from LoadExpr.
This helps prepare for #1192, since g_extractbitfield will get much
longer and call AddCodeLine.
Previously, the following rules were used for binary operators:
* If one of the values is a long, the result is long.
* If one of the values is unsigned, the result is also unsigned.
* Otherwise the result is an int.
C89 specifies the "usual arithmetic conversions" as:
* The integral promotions are performed on both operands.
* Then the following rules are applied:
* If either operand has type unsigned long int, the other operand is
converted to unsigned long int.
* Otherwise, if one operand has type long int and the other has type
unsigned int, if a long int can represent all values of an unsigned int,
the operand of type unsigned int is converted to long int; if a long int
cannot represent all the values of an unsigned int, both operands are
converted to unsigned long int.
* Otherwise, if either operand has type long int, the other operand is
converted to long int.
* Otherwise, if either operand has type unsigned int, the other operand is
converted to unsigned int.
* Otherwise, both operands have type int.
https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.5
As one example, these rules give a different result for an operator
with one long operand and one unsigned int operand. Previously,
the result type was unsigned long. With C89 semantics, it is just long,
since long can represent all unsigned ints.
Integral promotions convert types shorter than int to int (or unsigned int).
Both char and unsigned char are promoted to int since int can represent
all unsigned chars.
https://port70.net/~nsz/c/c89/c89-draft.html#3.2.1.1
Rename promoteint to ArithmeticConvert, since this is more accurate.
Fixes#170
The change allows cc65 to be compiled on 64-bit Windows, without getting warnings. That OS is actually 32 bits with 64-bit pointers. Its pointers are "long long" instead of "long". The change uses type-names that are configured for the actual pointer width.
For example:
int f(int i, int j) { return (char) (i + 1) == j; }
f(0x1234, 0x35) returned 0.
This bug caused zlib/uncompress return Z_DATA_ERROR on correct input.
variables known by the runtime. They aren't currently accessed by the compiler
itself but may be useful for inline assembly.
git-svn-id: svn://svn.cc65.org/cc65/trunk@4891 b7a2c559-68d2-44c3-8de9-860c34a00d81
proper replacements. Some other rearrangements for slightly better code.
git-svn-id: svn://svn.cc65.org/cc65/trunk@4640 b7a2c559-68d2-44c3-8de9-860c34a00d81