--- gcc/config/m88kv3.h 2018/04/24 17:51:33 1.1 +++ gcc/config/m88kv3.h 2018/04/24 17:54:11 1.1.1.2 @@ -36,12 +36,12 @@ the Free Software Foundation, 675 Mass A From arul@sdsu.edu. */ #undef STARTFILE_SPEC #define STARTFILE_SPEC \ - "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}" + "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}} crtbegin.o%s" /* Profiled libraries live in a different directory but keep the same names other than that. arul@sdsu.edu says -lg is always needed. */ #undef LIB_SPEC -#define LIB_SPEC "%{p:-L/lib/libp}%{pg:%{!p:-L/lib/libp}} -lg -lc" +#define LIB_SPEC "%{p:-L/lib/libp}%{pg:%{!p:-L/lib/libp}} -lg -lc crtend.o%s" /* Hot version of the profiler that uses r10 to pass the address of the counter. the _gcc_mcount routine knows not to screw with @@ -58,3 +58,83 @@ the Free Software Foundation, 675 Mass A too many changes to the m88k.h file. */ #undef USE_LIBG #define USE_LIBG + +/* Define a few machine-specific details of the implementation of + constructors. */ + +/* Although the .init section is used, it is not automatically invoked. */ +#define INVOKE__main + +/* State that atexit exists so __do_global_ctors will register + __do_global_dtors. */ +#define HAVE_ATEXIT + +#if (STACK_BOUNDARY / BITS_PER_UNIT) == 16 && REG_PARM_STACK_SPACE (0) == 32 +#define CTOR_LIST_BEGIN \ + asm (INIT_SECTION_ASM_OP); \ + asm ("\tsubu\t r31,r31,16"); \ + asm ("\tst\t r0,r31,32"); +#define CTOR_LIST_END +#endif + +/* ASM_OUTPUT_CONSTRUCTOR outputs code into the .init section to push the + address of the constructor. This becomes the body of __do_global_ctors + in crtstuff.c. r13 is a temporary register. */ +#undef ASM_OUTPUT_CONSTRUCTOR +#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ + do { \ + init_section (); \ + fprintf (FILE, "\tor.u\t r13,r0,hi16("); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, ")\n\tor\t r13,r13,lo16("); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, ")\n\tsubu\t r31,r31,%d\n\tst\t r13,r31,%d\n", \ + STACK_BOUNDARY / BITS_PER_UNIT, REG_PARM_STACK_SPACE (0)); \ + } while (0) + +#undef DO_GLOBAL_CTORS_BODY +#define DO_GLOBAL_CTORS_BODY \ +do { \ + func_ptr *__CTOR_LIST__ = __builtin_alloca (0), *p; \ + for (p = __CTOR_LIST__; *p; p += 4) \ + (*p) (); \ +} while (0) + +#define DTOR_LIST_BEGIN \ + asm (FINI_SECTION_ASM_OP); \ + func_ptr __DTOR_LIST__[4] = { (func_ptr) (-1), (func_ptr) (-1), \ + (func_ptr) (-1), (func_ptr) (-1) } +#define DTOR_LIST_END \ + asm (FINI_SECTION_ASM_OP); \ + func_ptr __DTOR_END__[4] = { (func_ptr) 0, (func_ptr) 0, \ + (func_ptr) 0, (func_ptr) 0 } + +/* A C statement (sans semicolon) to output an element in the table of + global destructors. The table is constructed in the .fini section + so that an explicit linker script is not required. The complication + is that this section is padded with NOP instructions and to either + 8 or 16 byte alignment depending on the specific system. A clever + way to avoid trouble is to output a block of 16 bytes where the + extra words are known values (-1). */ +#undef ASM_OUTPUT_DESTRUCTOR +#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ + do { \ + register int i; \ + fini_section (); \ + fprintf (FILE, "\t%s\t ", ASM_LONG); \ + assemble_name (FILE,NAME); \ + fprintf (FILE, "\n"); \ + for (i = 1; i < 4; i++) \ + fprintf (FILE, "\t%s\t -1\n", ASM_LONG); \ + } while (0) + +/* Walk the list looking for the terminating zero and ignoring all values of + -1. */ +#undef DO_GLOBAL_DTORS_BODY +#define DO_GLOBAL_DTORS_BODY \ + do { \ + int i; \ + for (i = 0; __DTOR_LIST__[i] != 0; i++) \ + if (((int *)__DTOR_LIST__)[i] != -1) \ + __DTOR_LIST__[i] (); \ + } while (0)