All architectures:
- "return" statement at function's end doesn't jump to immediately
following epilog anymore
- zero and non-zero constants are recognized in conditional
expressions of "if", "do/while" and "for" statements, no code
generated to evaluate these constant conditions and related
unnecessary jumps aren't generated anymore either
- in "for (clause-1; expr-2; expr-3) body", "expr-3" and "body" are
now reordered to the more natural code flow "body expr-3", thereby
getting rid of unnecessary jumps
MIPS code generator:
- function prologue/epilogue shortened further
- RA is not explicitly saved/restored in leaf functions
- assignment of 0 (e.g. "int a = 0;") is done from register 0
directly, avoiding a load of a constant
- Update license text (remove irrelevant FreeBSD references)
- Update root readme.txt
- Improve prologue/epilogue generation
Don't generate unnecessary jumps back and forth to/from
"sub sp, size_of_locals".
Instead, with the help of fgetpos()/fsetpos()
initially write ";sub sp, 0" and then, when
the size is finally known, go back and overwrite it with
" sub sp, size_of_locals".
- type specifiers may occur in any order
(e.g. "unsigned short int" and "int short unsigned")
- use .rodata/.rdata section for string literals
- arbitrary length string literals (hooray!)
- better concatenation of adjacent string literals
(now works even across preprocessor directives)
Support .bss section
- -nobss option in smlrc: use .data instead of .bss as before
- take advantage of .bss in smlrc (put a large array into it)
Remove dead/useless code
Remove useless/rarely used features/options:
-use-gp (MIPS)
-flat16/-flat32 (x86)
-seg16t (x86), -seg16 is now the default
-ctor-fxn
Add/change:
- use EXIT_FAILURE=1 instead of -1 in smlrc when aborting
due to an error
- properly sign-/zero-extend returned values, e.g. the following
function must return 255 and not -1:
unsigned char f(void) { return -1; }
- properly decay arrays on the left side of ->, e.g. the following must
compile:
{
struct {char c;} s[1];
s[0].c = 'a'; putchar(s[0].c);
(s+0)->c = 'b'; putchar(s[0].c);
(*s).c = 'c'; putchar(s[0].c);
s->c = 'd'; putchar(s[0].c);
putchar('\n');
}
Also:
- support structure passing/returning by value (x86 only)
Improvements:
- use registers more efficiently
- eliminate some register copies and stack manipulations
- promote left operands to right immediate operands
- improve simple assignments to auto/static vars
- use bltz, blez, bgtz, bgez
- change mul/divu (by powers of 2) to sll/srl/and
- use seb, seh for sign extension instead of sll/sra
- overall generate a bit tighter, faster and more readable asm code
Fixes:
- >>= should be unsigned when the left operand is unsigned int.
The right operand isn't important here.
- very subtle bug in e.g. void f(){int a; &a+1;/*wrong value of &a+1*/}
Other:
- include stdarg.c and skeleton.c in /share/example/Makefile
- move va_list type detection under #ifdef as it's rarely needed anyway
- allow up to 254 characters in a string literal
- generate a warning when an integer is passed instead of a pointer (and
vice versa) as a function parameter (pass -Wall for this)
- when printing an unexpected token, print identifier tokens instead of
'<tokIdent>'
- fix: allow most control characters inside '' and ""
- fix handling of -I<path> and -SI<path>
- switch() now supports Duff's device
- for() now supports declarations in its first clause as in C99/C++
Fixes/workarounds:
- octal escape sequence is to be terminated no later than after three
octal digits:
"\1011" is now parsed equivalently to "A1"
- workaround truncation of immediate operands to 16 bits in MIPS
instructions addi[u], subi[u], slti[u], andi, ori, xori in RetroBSD's as
(disabled since as is being fixed).
Improvements:
- warn on string literal truncation when initializing array of char
- generate trap/break-less form of MIPS div[u]
New:
- experimental support for __interrupt functions (x86/huge only)
Fixed bug in C preprocessor: buffer size reduced to avoid allocation failure.
Added option -v for smlrc.
New example stdarg.c: a demo of function with variable arguments.
The following global/static pointer initialization should now work:
static char* p1 = "abc" + 1;
static char* p2 = "abc" - 1;
static char* p3 = 1 + "abc";
static int a333[3][3][3];
static int* pa333_111 = &a333[1][1][1];
Other seemingly (and in fact actually) functionality preserving changes
are only to reduce code size when self compiling for DOS using -seg16.
Improvements and fixes require space, sigh.
In the following
typedef struct S0 { char ac[4]; } T1;
int v26 = (int)&((T1*)0)->ac[3];
int v27 = &((T1*)0)->ac[3];
v27 should be initialized to 3 just as v26.
Improvements:
- support initialization of multidimensional arrays
- support initialization of structures
- support initialization of structures and arrays inside functions
- support static inside functions
Notes:
- Only fully-bracketed (sic) initialization of arrays is supported.
- && and || have been partially replaced with & and | to slightly reduce
code size when self compiling for DOS using -seg16.