Commit Graph

431 Commits

Author SHA1 Message Date
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
Stephen Heumann
fa717745ad Update installation instructions. 2021-02-27 19:09:21 -06:00
Stephen Heumann
e226bba4c1 Update release notes. 2021-02-26 19:54:22 -06:00
Stephen Heumann
a44840718e Merge branch 'longlong'
* longlong:
  In PP expressions, make sure identifiers turn into 0LL.
  Optimize quad == 0 comparisons.
  Do unsigned quad inequalities without loading operands on stack.
  Do quad equality comparisons without loading operands on stack.
  Do unary quad ops without loading operand on stack.
  Do quad add/subtract without loading operands on stack.
  Implement support for doing quad ops without loading operands on stack.
  Evaluate constant expressions with long long and floating operands.
  Let functions store a long long return value directly into a variable in the caller.
  Optimize some quad ops to use interleaved loads and stores.
  Basic infrastructure for using different quadword locations in codegen.
  Allow static evaluation of ? : expressions with long long operands.
  Statically evaluate casts to and from long long.
  Implement conversions from long long to other types in the optimizer.
  Add various intermediate code peephole optimizations.
  Fix a comment.
  Support switch statements using long long expressions.
  Update headers to support long long (and intmax_t typedef'd as long long).
  Add the predefined macro __ORCAC_HAS_LONG_LONG__.
  Do preprocessor arithmetic in intmax_t/uintmax_t (aka long long types).
  Evaluate 64-bit comparisons in constant expressions.
  Add support for real to long long conversions.
  Implement comparisons for signed long long.
  Implement comparisons (>, >=, <, <=) for unsigned long long.
  Support 64-bit decimal constants in code.
  Evaluate arithmetic and shifts in long long constant expressions.
  Update printf/scanf format checker to match recent library changes.
  Implement && and || operators for long long types.
  Implement pc_ind (load indirect) for long long.
  Do not corrupt long long expressions that cannot be evaluated at compile time.
  Report errors in a few cases where the codegen finds unexpected types.
  Slightly optimize stack save code for calls to long long functions.
  Handle long long in pc_equ/pc_neq optimizations.
  Allow unsigned constants in "address+constant" constant expressions.
  Evaluate some kinds of long long operations in constant expressions.
  Implement 64-bit shifts.
  Implement basic peephole optimizations for some 64-bit operations.
  Do not copy CGI.Comments into CGI.pas.
  Generate code for long long to real conversions.
  Don't bogusly push stuff on the stack for conversions to non-long types.
  Implement support for functions returning (unsigned) long long.
  Compute how many bytes of arguments are passed to a function.
  Implement 64-bit division and remainder, signed and unsigned.
  Implement 64-bit multiplication support.
  Allow pointer arithmetic using long long values.
  Implement indirect store/copy operations for 64-bit types.
  Add long long support for a couple lint checks.
  Add long long support for the ! operator.
  Give an error when trying to evaluate constant expressions with long long operands.
  Make expressionValue a saturating approximation of the true value for long long expressions.
  Enable automatic comparison with 0 for long longs.
  Add some support for ++/-- on long long values.
  Add support for emitting 64-bit constants in statically-initialized data.
  Add most of the infrastructure to support 64-bit decimal constants.
  Support 64-bit integer constants in hex/octal/binary formats.
  Initial support for constants with long long types.
  Implement equality/inequality comparisons for 64-bit types.
  Implement remaining conversions of integer types to and from long long.
  Update the debugging format for long long values.
  Begin implementing conversions to and from 64-bit types.
  Implement 64-bit addition and subtraction.
  Add support for new pcodes in optimizer.
  Implement unary negation and bitwise complement for 64-bit types.
  Implement bitwise and/or/xor for 64-bit types.
  Handle (unsigned) long long in the front-end code for binary conversions.
  Restore old order of baseTypeEnum values.
  Implement basic load/store ops for long long.
  Initial code to recognize 'long long' as a type.
2021-02-26 19:48:08 -06:00
Stephen Heumann
21f8876f50 In PP expressions, make sure identifiers turn into 0LL. 2021-02-25 21:42:54 -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
4020098dd6 Evaluate constant expressions with long long and floating operands.
Note that we currently defer evaluation of such expressions to run time if the long long value cannot be represented exactly in a double, because statically-evaluated floating point expressions use the double format rather than the extended (long double) format used at run time.
2021-02-21 18:43:53 -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
58f2ebddec Allow static evaluation of ? : expressions with long long operands. 2021-02-19 23:46:57 -06:00
Stephen Heumann
75c7cd95d3 Statically evaluate casts to and from long long. 2021-02-19 21:57:31 -06:00
Stephen Heumann
5ed820717e Implement conversions from long long to other types in the optimizer.
The code of PeepHoleOptimization is now big enough that it triggers bogus "Relative address out of range" range errors from the linker. This is a linker bug and should be fixed there.
2021-02-18 23:27:18 -06:00
Stephen Heumann
3e5aa5b7b0 Merge branch 'master' into longlong 2021-02-18 20:31:33 -06:00
Stephen Heumann
0f45e1d0ff Fix optimizer bug affecting casts to char types.
When an expression that the intermediate code peephole optimizer could reduce to a constant was cast to a char type, the resulting value could be outside the range of that type.

The following program illustrates the problem:

#pragma optimize 1
#include <stdio.h>
int main(void) {
        int i = 0;
        i = (unsigned char)(i | -1);
        printf("%i\n", i);
}
2021-02-18 20:31:22 -06:00
Stephen Heumann
d891e672e3 Add various intermediate code peephole optimizations.
These mainly cover 64-bit arithmetic and shifts, but also include a few optimizations for 16-bit and 32-bit shifts.
2021-02-18 19:17:39 -06:00
Stephen Heumann
32f4e70826 Fix a comment. 2021-02-18 12:58:57 -06:00
Stephen Heumann
cf463ff155 Support switch statements using long long expressions. 2021-02-17 19:41:46 -06:00
Stephen Heumann
5268f37261 Merge branch 'master' into longlong 2021-02-17 15:38:06 -06:00
Stephen Heumann
28888cf824 Exclude non-standard functions in <string.h> if __KeepNamespacePure__ is defined. 2021-02-17 15:36:38 -06:00
Stephen Heumann
31adb5f5d6 Update headers to support long long (and intmax_t typedef'd as long long).
This includes:
*Functions operating on long long in <stdlib.h>
*Limits of long long types in <limits.h>
*64-bit types and limits (plus intmax_t and its limits) in <stdint.h>
*New format codes, plus functions operating on intmax_t, in <inttypes.h>

The new stuff is generally conditionalized to only be included if __ORCAC_HAS_LONG_LONG__ is defined, or if the implementation claims to be C99 or later. This allows the headers to remain usable with older versions of ORCA/C, or with any hypothetical "strict C89" mode that might be implemented in the future.
2021-02-17 14:57:18 -06:00
Stephen Heumann
6bb91d20e5 Add the predefined macro __ORCAC_HAS_LONG_LONG__.
This allows headers or other code to test for the presence of this feature.
2021-02-17 14:41:09 -06:00
Stephen Heumann
b4604e079e Do preprocessor arithmetic in intmax_t/uintmax_t (aka long long types).
This is what C99 and later require.
2021-02-17 00:04:20 -06:00
Stephen Heumann
955ee74b25 Evaluate 64-bit comparisons in constant expressions. 2021-02-16 23:11:41 -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
2e29390e8e Support 64-bit decimal constants in code. 2021-02-15 12:28:30 -06:00
Stephen Heumann
d66f6b27b7 Evaluate arithmetic and shifts in long long constant expressions.
This winds up calling functions for these operations in ORCALib, so an up-to-date version of that must now be available to build the ORCA/C compiler.
2021-02-14 20:39:35 -06:00
Stephen Heumann
76cc4b9ca7 Update printf/scanf format checker to match recent library changes.
*Recognize the 'll' and 'j' size modifiers as denoting long long times.
*Recognize '%P' as equivalent to '%b'.
*Give a warning for 'L' length modifier in scanf, which is currently not supported (except when assignment is suppressed).
2021-02-14 17:45:39 -06:00