commit 2d77075828c480d5cb0ad3ddb40199ccbbcc27b1
parent bd9c825b331e7f138ed8d7ba1b4878d2b09b8f74
Author: FRIGN <dev@frign.de>
Date: Sat, 18 Jul 2015 23:40:28 +0200
Some grammar and spelling fixes in README
Diffstat:
M | README | | | 119 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
1 file changed, 60 insertions(+), 59 deletions(-)
diff --git a/README b/README
@@ -1,91 +1,92 @@
Introduction
============
-This is the kcc compiler, a one very stupid non retargetable compiler
-for z80. This compiler is intended to be very simple and suitable for
-running in small machines (like MSX for example), and let almost part
-of optimizations to the programmer.
-
-After a lot of years seeing compilers for z80 I notice that it is very
-hard for a C compiler generates a good code for a 8 bit processor like
-z80, with an expensive indirect addressing mode, so the best solution
-is to not try that compiler optimize the code and use C as a macro
+This is the suckless C compiler, a very stupid non-retargetable compiler
+for the Z80. It is intended to be very simple and suitable for running on
+small machines (like MSX for example), and leaves almost all optimizations
+to the programmer.
+
+After a lot of years seeing compilers for the Z80 I noticed that it is very
+hard for a C compiler to generate good programs for 8 Bit processors like
+the Z80, with an expensive indirect addressing mode, so the best solution
+is not to try to make the compiler optimizing, but instead use C as a macro
macro assembler.
-In order to get this target, we need a compiler that does exactly the
-things programmer want to do. For example is a variable is register it MUST be
-register and fails in other case. If a variable is automatic try to
-realize operations directly with the stack (for example use ADD
-A,(IX+4), instead of allocate the variable into register add and store
-again in memory). So if you declare an automatic variable you are a
-big bullshit or you need it for recursion (static variables are your
-friends).
+In order to reach this target, we need a compiler that does exactly the
+things the programmer wants to do. For example, if a variable is a register
+it MUST be a register and should fail in any other case.
+If a variable is automatic operations should be attempted to be realized
+with the stack directly (for example use ADD A,(IX+4) instead of
+allocating the variable into a register add and store it again in memory).
+If you declare an automatic variable you are either doing it wrong or you
+need it for recursion (static variables are you friends).
This is the reason why I began to develop this compiler, and I hope
it will be useful for you.
-Changes from standard C
-=======================
-This compiler is near of being full compatible with C99 standard, but
-it has some differences:
+Derivations from standard C
+===========================
+This compiler is near to being fully compatible with the C99 standard, but
+there are some differences:
- Type qualifiers are accepted but ignored.
-----------------------------------------
-Type qualifers make the type system ugly, and the useless of them
-add innecessary complexity to the compiler (with a bigger compilation
-time):
+Type qualifers make the type system ugly, and their uselessness add
+unnecessary complexity to the compiler (and increased compilation time):
- const: The definition of const is not clear in the standard.
- If a const value is modified then the behaviour is implementation
- defined. It seems that it was defined more in order to can
- allocate variables in ROM than for the error detection. This
+ If a const value is modified the behaviour is implementation
+ defined. It seems it was defined in order to be able to
+ allocate variables in ROM rather than error detection. This
implememtation will not warn about these modifications and
- the code will use them as normal variables (standard specifies
- that a diagnosis message must be printed).
+ the compiler will treat them like normal variables (the standard
+ specifies that a diagnosic message must be printed).
- volatile: The definition of volatile is not concrete, because
- it is defined as 'remove all the optimizations about the
- variable', which of course depend of the kind of optimizations
+ it is defined as 'remove all optimizations applied to the
+ variable', which of course depends on the kind of optimizations
applied to the variable. This qualifier was added to the standard
- to can deal with longjmp (local variables that are not volatile
- have undefined state), and for memory mapped registers or variables
- whose value is modified asynchronous but this can achieved with
- special pragma values.
- In the first case, this is a a non portable code by definition
- (depend of the register mapped), so it is better to deal with
- it using another solution (compiler extensions or directly
- assembler), and in the second case it generated a lot of
- problems with moderm processors out of order and multiprocesor,
- where not hold the value in a register is good enough (it is
- needed a explicit memory barrier).
-
- - restrict: This qualifer can be only applied to pointers, to
+ to be able to deal with longjmp (local variables that are not
+ volatile have undefined state) and for memory mapped registers
+ or variables whose values are modified asynchronously. This can
+ be achieved with special pragma values though.
+ In the first case, this is non-portable code by definition
+ (depending on the register mapped), so it is better to deal with
+ it using another solution (compiler extensions or direct
+ assembler).
+ In the second case, it generates a lot of problems with modern
+ processors and multithreading, where not holding the value in a
+ register is good enough (an explicit memory barrier is needed).
+
+ - restrict: This qualifer can only be applied to pointers to
mark that the pointed object has no other alias. This qualifer
- was introduced to can fix some performance problems in numerical
- algorithm, where FORTRAN can achieve a better performance (and
- in fact even with this specifier FORTRAN has a better performance
- in this field). Ignores it doesn't make the code non standard
- and in almost of the applications the performance will be the same.
+ was introduced to be able to fix some performance problems in
+ numerical algorithms, where FORTRAN could achieve a better
+ performance (and in fact even with this specifier FORTRAN has a
+ better performance in this field). Ignoring it doesn't make the
+ code non-standard and in almost all applications the performance
+ will be the same.
- Function type names
-------------------
-C99 allows to define type names of function types and write something like:
+C99 allows you to define type names of function types and write something
+like:
int f(int (int));
Accepting function types in typenames (or abstract declarators) makes the
-grammar ambiguous because it is impossible difference between:
+grammar ambiguous because it is impossible to differentiate between:
(int (f)) -> function returning int with one parameter of type f
(int (f)) -> integer variable f
Function type names are stupid, because they are used as an alias
-of the function pointer types, but it makes stupid that something
-like sizeof(int (int)) is not allowed (because here should be
-understood as the size of a function), but it is allowed f(int (int))
-because it is understood as a parameter with function pointer type.
-
-This complexity is not needed at all, because function pointers fix
-all these problems without this complexity (and they are the more usual
-way of writing such codes).
+of the function pointer types, but it is stupid that something
+like sizeof(int (int)) is not allowed (because here it should be
+understood as the size of a function), but is f(int (int)) is allowed
+because it is understood as a parameter of function pointer type.
+
+This complexity is not needed at all as function pointers fix all these
+problems without this complexity (and they are the more usual
+way of writing such code).