Sat 17 Feb 2007 11:34:26 AM UTC, comment #4:
In atmega256 is solved one more general issue.
As Bjorn Haase wrote:
Two other general issues are fixed with gcc part of the present patch family:
1.) citing from the gcc info pages:
`-fdelete-null-pointer-checks'
Use global dataflow analysis to identify and eliminate useless
checks for null pointers. The compiler assumes that dereferencing
a null pointer would have halted the program. If a pointer is
checked after it has already been dereferenced, it cannot be null.
In some environments, this assumption is not true, and programs can
safely dereference null pointers. Use
`-fno-delete-null-pointer-checks' to disable this optimization for
programs which depend on that behavior.
The AVR HW does not implement null-pointer-checks and this option now is
allways used for the avr target.
2.) make main a normal function
.....
I split "mega256-wo-main-as-normal.diff" patch in "mega256.diff" and "null-pointer-checks.diff".
(file #11992, file #11993)
|
Tue 13 Feb 2007 10:28:18 PM UTC, comment #2:
In oficial GCC 4.x main() do not converted to a normal function. 'atmega256' patch does it.
For fast correction of a bug it is necessary to restore special handling of main() funcion in 'patch-zz-atmega256x' patch.
These changes should be reverted:
- if (main_p)
- {
- fprintf (file, ("\t"
- AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
- AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
- AS2 (out,__SP_H__,r29) CR_TAB
- AS2 (out,__SP_L__,r28) "\n"),
- avr_init_stack, size, avr_init_stack, size);
-
- prologue_size += 4;
- }
- else if (minimize && (frame_pointer_needed || live_seq > 6))
+ if (minimize && (frame_pointer_needed || live_seq > 6))
and:
- if (main_p)
- {
- /* Return value from main() is already in the correct registers
- (r25:r24) as the exit() argument. */
- if (AVR_MEGA)
- {
- fputs ("\t" AS1 (jmp,exit) "\n", file);
- epilogue_size += 2;
- }
- else
- {
- fputs ("\t" AS1 (rjmp,exit) "\n", file);
- ++epilogue_size;
- }
- }
- else if (minimize && (frame_pointer_needed || live_seq > 4))
+ if (minimize && (frame_pointer_needed || live_seq > 4))
|
Tue 13 Feb 2007 04:51:48 PM UTC, comment #1:
Call main() as a normal function have some drawback:
1. Loss of two bytes of RAM for storing 'main' return address in stack.
2. Increase code size, if 'main' function has local variables.
Now stack frames for 'main' function is setup by a following code:
REG_Y (frame pointer) = RAM_END - frame_size
SP = REG_Y
Size = 4 instruction.
If 'main' will be usual function, that in prologue will be a following code:
PUSH REG_Y
REG_Y = SP
REG_Y = REG_Y - frame_size
SP = REG_Y
Size - 7/8 instruction and loss of two bytes more of RAM. And 7/8 more instructions in an epilogue of function.
3. If in 'main' function 'call-saved' registers (r2..r17) will be used, then they will be saved in a stack.
|
Tue 13 Feb 2007 12:29:02 PM UTC, original submission:
Now with GCC 4.x, main() is treated as a normal function. As
such, it must no longer be jumped to, but needs to be called
(with XCALL), and the value returned needs to be passed to
exit(). As the user can override exit() and thus implement
an exit() function that erroneously returns, we should
probably also supply an infinite loop in gcrt1.S that the
code falls into in case exit() ever returns -- much better
than having the program counter run into the wild.
|