Commit 9af145ae by Marek Michalkiewicz Committed by Marek Michalkiewicz

Support for C++ constructors/destructors.

	* config/avr/avr.c (avr_output_function_epilogue): Jump to exit()
	instead of looping if main() returns.
	(asm_file_start): Output global symbols that cause .data and .bss
	initialization code to be linked in, unconditionally for now.
	(avr_asm_out_ctor, avr_asm_out_dtor): New functions.
	* config/avr/avr.h (CTORS_SECTION_ASM_OP, DTORS_SECTION_ASM_OP): New.
	(TARGET_ASM_CONSTRUCTOR, TARGET_ASM_DESTRUCTOR): New.
	(LIBSTDCXX): New.
	* config/avr/libgcc.S (_exit): Split in .fini9 and .fini0 sections.
	(__tablejump__): New.
	(__do_copy_data, __do_clear_bss): New.
	(__do_global_ctors, __do_global_dtors): New.
	* config/avr/t-avr (LIB1ASMFUNCS): Add _copy_data, _clear_bss,
	_ctors, _dtors.

From-SVN: r54156
parent 0d66ad57
2002-06-02 Marek Michalkiewicz <marekm@amelek.gda.pl>
Support for C++ constructors/destructors.
* config/avr/avr.c (avr_output_function_epilogue): Jump to exit()
instead of looping if main() returns.
(asm_file_start): Output global symbols that cause .data and .bss
initialization code to be linked in, unconditionally for now.
(avr_asm_out_ctor, avr_asm_out_dtor): New functions.
* config/avr/avr.h (CTORS_SECTION_ASM_OP, DTORS_SECTION_ASM_OP): New.
(TARGET_ASM_CONSTRUCTOR, TARGET_ASM_DESTRUCTOR): New.
(LIBSTDCXX): New.
* config/avr/libgcc.S (_exit): Split in .fini9 and .fini0 sections.
(__tablejump__): New.
(__do_copy_data, __do_clear_bss): New.
(__do_global_ctors, __do_global_dtors): New.
* config/avr/t-avr (LIB1ASMFUNCS): Add _copy_data, _clear_bss,
_ctors, _dtors.
2002-06-02 Neil Booth <neil@daikokuya.demon.co.uk>
* c4x/c4x.h (TARGET_CPU_CPP_BUILTINS): New.
......
......@@ -67,6 +67,9 @@ static void avr_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static void avr_unique_section PARAMS ((tree, int));
static void avr_encode_section_info PARAMS ((tree, int));
static void avr_asm_out_ctor PARAMS ((rtx, int));
static void avr_asm_out_dtor PARAMS ((rtx, int));
/* Allocate registers from r25 to r8 for parameters for function calls */
#define FIRST_CUM_REG 26
......@@ -757,8 +760,18 @@ avr_output_function_epilogue (file, size)
fprintf (file, "/* epilogue: frame size=%d */\n", size);
if (main_p)
{
fprintf (file, "__stop_progIi__:\n\trjmp __stop_progIi__\n");
++epilogue_size;
/* 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))
{
......@@ -4814,7 +4827,13 @@ asm_file_start (file)
fputs ("__tmp_reg__ = 0\n"
"__zero_reg__ = 1\n"
"_PC_ = 2\n", file);
/* FIXME: output these only if there is anything in the .data / .bss
sections - some code size could be saved by not linking in the
initialization code from libgcc if one or both sections are empty. */
fputs ("\t.global __do_copy_data\n", file);
fputs ("\t.global __do_clear_bss\n", file);
commands_in_file = 0;
commands_in_prologues = 0;
commands_in_epilogues = 0;
......@@ -5531,3 +5550,22 @@ avr_out_sbxx_branch (insn, operands)
return AS1 (rjmp,%3);
return "";
}
static void
avr_asm_out_ctor (symbol, priority)
rtx symbol;
int priority;
{
fputs ("\t.global __do_global_ctors\n", asm_out_file);
default_ctor_section_asm_out_constructor (symbol, priority);
}
static void
avr_asm_out_dtor (symbol, priority)
rtx symbol;
int priority;
{
fputs ("\t.global __do_global_dtors\n", asm_out_file);
default_dtor_section_asm_out_destructor (symbol, priority);
}
......@@ -1728,6 +1728,24 @@ do { \
`-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
used. */
/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
There are no shared libraries on this target, and these sections are
placed in the read-only program memory, so they are not writable. */
#undef CTORS_SECTION_ASM_OP
#define CTORS_SECTION_ASM_OP "\t.section .ctors,\"a\",@progbits"
#undef DTORS_SECTION_ASM_OP
#define DTORS_SECTION_ASM_OP "\t.section .dtors,\"a\",@progbits"
#define TARGET_ASM_CONSTRUCTOR avr_asm_out_ctor
/* If defined, a function that outputs assembler code to arrange to
call the function referenced by SYMBOL at initialization time. */
#define TARGET_ASM_DESTRUCTOR avr_asm_out_dtor
/* This is like `TARGET_ASM_CONSTRUCTOR' but used for termination
functions rather than initialization functions. */
#define EXTRA_SECTIONS in_progmem
/* A list of names for sections other than the standard two, which are
`in_text' and `in_data'. You need not define this macro on a
......@@ -2588,6 +2606,9 @@ extern int avr_case_values_threshold;
If this macro is not defined, a default is provided that loads the
standard C library from the usual place. See `gcc.c'. */
#define LIBSTDCXX "-lgcc"
/* No libstdc++ for now. Empty string doesn't work. */
#define LIBGCC_SPEC \
"%{!mmcu=at90s1*:%{!mmcu=attiny1*:%{!mmcu=attiny28: -lgcc }}}"
/* Another C string constant that tells the GNU CC driver program how
......
......@@ -637,11 +637,19 @@ __epilogue_restores__:
#endif /* defined (L_epilogue) */
#ifdef L_exit
.weak _exit
.section .fini9,"ax",@progbits
.global _exit
.func _exit
_exit:
rjmp _exit
.endfunc
.weak exit
exit:
/* Code from .fini8 ... .fini1 sections inserted by ld script. */
.section .fini0,"ax",@progbits
__stop_program:
rjmp __stop_program
.endfunc
#endif /* defined (L_exit) */
#ifdef L_cleanup
......@@ -658,6 +666,8 @@ _cleanup:
__tablejump2__:
lsl r30
rol r31
.global __tablejump__
__tablejump__:
#if defined (__AVR_ENHANCED__)
lpm __tmp_reg__, Z+
lpm r31, Z
......@@ -665,12 +675,104 @@ __tablejump2__:
ijmp
#else
lpm
adiw r30, 1
push r0
inc r30 ; table is word aligned, no carry to high byte
lpm
push r0
ret
#endif
.endfunc
.endfunc
#endif /* defined (L_tablejump) */
/* __do_copy_data is only necessary if there is anything in .data section.
Does not use RAMPZ - crt*.o provides a replacement for >64K devices. */
#ifdef L_copy_data
.section .init4,"ax",@progbits
.global __do_copy_data
__do_copy_data:
ldi r17, hi8(__data_end)
ldi r26, lo8(__data_start)
ldi r27, hi8(__data_start)
ldi r30, lo8(__data_load_start)
ldi r31, hi8(__data_load_start)
rjmp .do_copy_data_start
.do_copy_data_loop:
#if defined (__AVR_ENHANCED__)
lpm r0, Z+
#else
lpm
adiw r30, 1
#endif
st X+, r0
.do_copy_data_start:
cpi r26, lo8(__data_end)
cpc r27, r17
brne .do_copy_data_loop
#endif /* L_copy_data */
/* __do_clear_bss is only necessary if there is anything in .bss section. */
#ifdef L_clear_bss
.section .init4,"ax",@progbits
.global __do_clear_bss
__do_clear_bss:
ldi r17, hi8(__bss_end)
ldi r26, lo8(__bss_start)
ldi r27, hi8(__bss_start)
rjmp .do_clear_bss_start
.do_clear_bss_loop:
st X+, __zero_reg__
.do_clear_bss_start:
cpi r26, lo8(__bss_end)
cpc r27, r17
brne .do_clear_bss_loop
#endif /* L_clear_bss */
/* __do_global_ctors and __do_global_dtors are only necessary
if there are any constructors/destructors. */
#if defined (__AVR_MEGA__)
#define XCALL call
#else
#define XCALL rcall
#endif
#ifdef L_ctors
.section .init6,"ax",@progbits
.global __do_global_ctors
__do_global_ctors:
ldi r17, hi8(__ctors_start)
ldi r28, lo8(__ctors_end)
ldi r29, hi8(__ctors_end)
rjmp .do_global_ctors_start
.do_global_ctors_loop:
sbiw r28, 2
mov_h r31, r29
mov_l r30, r28
XCALL __tablejump__
.do_global_ctors_start:
cpi r28, lo8(__ctors_start)
cpc r29, r17
brne .do_global_ctors_loop
#endif /* L_ctors */
#ifdef L_dtors
.section .fini6,"ax",@progbits
.global __do_global_dtors
__do_global_dtors:
ldi r17, hi8(__dtors_end)
ldi r28, lo8(__dtors_start)
ldi r29, hi8(__dtors_start)
rjmp .do_global_dtors_start
.do_global_dtors_loop:
mov_h r31, r29
mov_l r30, r28
XCALL __tablejump__
adiw r28, 2
.do_global_dtors_start:
cpi r28, lo8(__dtors_end)
cpc r29, r17
brne .do_global_dtors_loop
#endif /* L_dtors */
......@@ -17,7 +17,11 @@ LIB1ASMFUNCS = \
_epilogue \
_exit \
_cleanup \
_tablejump
_tablejump \
_copy_data \
_clear_bss \
_ctors \
_dtors
# We do not have the DF type.
# Most of the C functions in libgcc2 use almost all registers,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment