aboutsummaryrefslogtreecommitdiff
path: root/libgloss/m68k/crt0.S
blob: 321b97f036a26eeb909c15ebcfa04adc00e89c92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 * crt0.S -- startup file for m68k-coff
 *
 * Copyright (c) 1995, 1996, 1998 Cygnus Support
 *
 * The authors hereby grant permission to use, copy, modify, distribute,
 * and license this software and its documentation for any purpose, provided
 * that existing copyright notices are retained in all copies and that this
 * notice is included verbatim in any distributions. No written agreement,
 * license, or royalty fee is required for any of the authorized uses.
 * Modifications to this software may be copyrighted by their authors
 * and need not follow the licensing terms described here, provided that
 * the new terms are clearly indicated on the first page of each file where
 * they apply.
 */

#include "asm.h"

	.title "crt0.S for m68k-coff"
#define STACKSIZE	0x4000

/*
 * Define an empty environment.
 */
        .data
        .align 2
SYM (environ):
        .long 0

 	.align	2
	.text

/*
 * These symbols are defined in C code, so they need to always be
 * named with SYM because of the difference between object file formats.
 */

/* These are defined in C code. */
	.extern SYM (main)
	.extern SYM (exit)
	.extern SYM (hardware_init_hook)
	.extern SYM (software_init_hook)
	.extern SYM (atexit)
	.extern SYM(__do_global_dtors)

/* 
 * These values are set in the linker script, so they must be
 * explicitly named here without SYM.
 */
	.extern __stack
	.extern __bss_start
	.extern _end

/*
 * set things up so the application will run. This *must* be called start.
 */
	.global SYM (start)

SYM (start):
	/*
	 * put any hardware init code here
	 */

	/* See if user supplied their own stack (__stack != 0).  If not, then
	 * default to using the value of %sp as set by the ROM monitor.
	 */
	movel	IMM(__stack), a0
	cmpl	IMM(0), a0
	jbeq    1f
	movel	a0, sp
1:
	/* set up initial stack frame */
	link	a6, IMM(-8)

/*
 * zero out the bss section.
 */
	movel	IMM(__bss_start), d1
	movel	IMM(_end), d0
	cmpl	d0, d1
	jbeq	3f
	movl	d1, a0
	subl	d1, d0
	subql	IMM(1), d0
2:
	clrb	(a0)+
#if !defined(__mcoldfire__) && !defined(__mcf5200__)
	dbra	d0, 2b
	clrw	d0
	subql	IMM(1), d0
	jbcc	2b
#else
	subql	IMM(1), d0
	jbpl	2b
#endif
	
3:

/*
 * initialize target specific stuff. Only execute these
 * functions it they exist.
 */
	PICLEA	SYM (hardware_init_hook), a0
	cmpl	IMM(0),a0
	jbeq	4f
	jsr     (a0)
4:

	PICLEA	SYM (software_init_hook), a0
	cmpl	IMM(0),a0
	jbeq	5f
	jsr     (a0)
5:

/*
 * call the main routine from the application to get it going.
 * main (argc, argv, environ)
 * we pass argv as a pointer to NULL.
 */

#ifdef ADD_DTORS
	/* put __do_global_dtors in the atexit list so the destructors get run */
	movel	IMM (SYM(__do_global_dtors)),(sp)
	PICCALL	SYM (atexit)
#endif
	movel	IMM (__FINI_SECTION__),(sp)
	PICCALL	SYM (atexit)

	PICCALL	__INIT_SECTION__

        pea     0
	PICPEA	SYM (environ),a0
        pea     sp@(4)
        pea     0
	PICCALL	SYM (main)
	movel	d0, sp@-

/*
 * drop down into exit incase the user doesn't. This should drop
 * control back to the ROM monitor, if there is one. This calls the
 * exit() from the C library so the C++ tables get cleaned up right.
 */
	PICCALL	SYM (exit)