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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
/* crt0.S -- startup file for frv.
*
* Copyright (c) 2002 Red Hat, Inc
*
* 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 <frv-asm.h>
/* statically store .Lcall's address so we can see if we are running
at the location we were linked for or a different location. */
.data
.type EXT(__start_cmp),@object
.size EXT(__start_cmp),4
.p2align 2
EXT(__start_cmp):
.picptr .Lcall
.globl __start
.weak _start
.text
.type __start,@function
__start:
_start:
call .Lcall /* set up _gp in a pic-friendly manor */
.Lcall: movsg lr, gr4
P(sethi) #gprelhi(.Lcall), gr5
setlo #gprello(.Lcall), gr5
P(sub) gr4, gr5, gr16
sethi #gprelhi(EXT(_stack)), sp /* load up stack pointer */
P(setlo) #gprello(EXT(_stack)), sp
setlos #0, fp /* zero fp to allow unwinders to stop */
P(add) sp, gr16, sp
sethi #gprelhi(EXT(__start_cmp)), gr5
setlo #gprello(EXT(__start_cmp)), gr5
ld @(gr5,gr16), gr6
subcc gr4, gr6, gr8, icc0
beq icc0, 0, .Lfixed
P(st) gr4, @(gr5, gr16) /* update so if we restart no need to fixup */
/* fixup the .ctors list */
sethi #gprelhi(EXT(__CTOR_LIST__)), gr9
P(sethi) #gprelhi(EXT(__CTOR_END__)), gr10
setlo #gprello(EXT(__CTOR_LIST__)), gr9
P(setlo) #gprello(EXT(__CTOR_END__)), gr10
add gr9, gr16, gr9
P(add) gr10, gr16, gr10
addi gr9, 4, gr9
P(subi) gr10, 4, gr10
setlos 4, gr11
call EXT(__frv_fixptrs)
/* fixup the .dtors list */
P(sethi) #gprelhi(EXT(__DTOR_LIST__)), gr9
sethi #gprelhi(EXT(__DTOR_END__)), gr10
P(setlo) #gprello(EXT(__DTOR_LIST__)), gr9
setlo #gprello(EXT(__DTOR_END__)), gr10
P(add) gr9, gr16, gr9
add gr10, gr16, gr10
P(addi) gr9, 4, gr9
subi gr10, 4, gr10
call EXT(__frv_fixptrs)
/* fixup the .dtors list */
P(sethi) #gprelhi(EXT(__ROFIXUP_LIST__)), gr9
sethi #gprelhi(EXT(__ROFIXUP_END__)), gr10
P(setlo) #gprello(EXT(__ROFIXUP_LIST__)), gr9
setlo #gprello(EXT(__ROFIXUP_END__)), gr10
P(add) gr9, gr16, gr9
add gr10, gr16, gr10
call EXT(__frv_fix_usrptrs)
.Lfixed:
/* HSR flags */
#define HSR_ICE 0x80000000 /* Instruction cache enable */
#define HSR_DCE 0x40000000 /* Data cache enable */
#define HSR_CBM 0x08000000 /* Cache copy back mode */
#define HSR_EIMM 0x04000000 /* Enable Instruction MMU */
#define HSR_EDMM 0x02000000 /* Enable Data MMU */
#define HSR_EMEM 0x00800000 /* Enable MMU miss exception mask */
#define HSR_RME 0x00400000 /* Ram mode enable */
#define HSR_SA 0x00001000 /* Start address */
#define HSR_FRN 0x00000800 /* Number of FPRs */
#define HSR_GRN 0x00000400 /* Number of GPRs */
#define HSR_FRHE 0x00000200 /* FR Higher Enable */
#define HSR_FRLE 0x00000100 /* FR Lower Enable */
#define HSR_GRHE 0x00000080 /* GR Higher Enable */
#define HSR_GRLE 0x00000040 /* GR Lower Enable */
#ifndef HSR_CLEAR
#define HSR_CLEAR 0
#endif
#ifndef HSR_SET
#ifndef FRV_NO_CACHE
#define HSR_SET (HSR_ICE|HSR_DCE|HSR_FRHE|HSR_FRLE|HSR_GRHE|HSR_GRLE)
#else
#define HSR_SET (HSR_FRHE|HSR_FRLE|HSR_GRHE|HSR_GRLE)
#endif
#endif
/* PSR flags */
#define PSR_ICE 0x00010000 /* In circuit emulation mode */
#define PSR_NEM 0x00004000 /* Non-exception mode */
#define PSR_CM 0x00002000 /* Conditional mode */
#define PSR_BE 0x00001000 /* Big endian mode */
#define PSR_EF 0x00000100 /* Enable floating point */
#define PSR_EM 0x00000080 /* Enable media instructions */
#define PSR_S 0x00000004 /* Enable supervisor mode */
#define PSR_PS 0x00000002 /* Previous supervisor mode */
#define PSR_ET 0x00000001 /* Enable interrupts */
#ifndef PSR_CLEAR
#if __FRV_FPR__
#define PSR_CLEAR 0
#else
#define PSR_CLEAR (PSR_EF|PSR_EM)
#endif
#endif
#ifndef PSR_SET
#if __FRV_FPR__
#define PSR_SET (PSR_NEM|PSR_CM|PSR_EF|PSR_EM)
#else
#define PSR_SET (PSR_NEM|PSR_CM)
#endif
#endif
/* Enable floating point */
movsg hsr0, gr4
P(sethi) #hi(HSR_SET), gr5
setlo #lo(HSR_SET), gr5
P(sethi) #hi(~HSR_CLEAR), gr6
setlo #lo(~HSR_CLEAR), gr6
or gr4, gr5, gr4
and gr4, gr6, gr4
movgs gr4, hsr0
movsg psr, gr4
P(sethi) #hi(PSR_SET), gr5
setlo #lo(PSR_SET), gr5
P(sethi) #hi(~PSR_CLEAR), gr6
setlo #lo(~PSR_CLEAR), gr6
or gr4, gr5, gr4
and gr4, gr6, gr4
movgs gr4, psr
/* zero the bss area */
P(sethi) #gprelhi(__bss_start), gr8
sethi #gprelhi(__end), gr4
P(setlo) #gprello(__bss_start), gr8
setlo #gprello(__end), gr4
P(add) gr8, gr16, gr8
add gr4, gr16, gr4
P(setlos) #0, gr9
sub gr4, gr8, gr10
call EXT(memset)
P(setlos) #0, gr8 /* zero argc, argv, envp */
setlos #0, gr9
P(setlos) #0, gr10
call EXT(main)
call EXT(exit)
.Lend:
.size __start,(.Lend-__start)
/* Routine to adjust pointers
gr8 = difference to adjust by
gr9 = starting address
gr10 = ending address + 4
gr11 = amount to add to the pointer each iteration. */
.globl EXT(__frv_fixptrs)
.type EXT(__frv_fixptrs),@function
EXT(__frv_fixptrs):
P(sub) gr9, gr11, gr9
sub gr10, gr11, gr10
.Lloop2:
cmp gr10, gr9, icc0
bls icc0, 0, .Lret2
ldu @(gr9,gr11), gr5
add gr8, gr5, gr5
P(st) gr5, @(gr9,gr0)
bra .Lloop2
.Lret2: ret
.Lend2:
.size EXT(__frv_fixptrs),.Lend2-EXT(__frv_fixptrs)
/* Routine to adjust statically initialized pointers
Note since these are pointers to pointers, they
need to be adjusted themsevles.
gr8 = difference to adjust by
gr9 = starting address
gr10 = ending address + 4
gr11 = amount to add to the pointer each iteration. */
.globl EXT(__frv_fix_usrptrs)
.type EXT(__frv_fix_usrptrs),@function
EXT(__frv_fix_usrptrs):
P(sub) gr9, gr11, gr9
sub gr10, gr11, gr10
.Lloop3:
cmp gr10, gr9, icc0
bls icc0, 0, .Lret3
ldu @(gr9,gr11), gr5
ld @(gr5, gr8), gr6
cmp gr6, gr0, icc0 /* skip pointers initialized to 0 */
beq icc0, 0, .Lloop3
add gr8, gr6, gr6
P(st) gr6, @(gr5,gr8)
bra .Lloop3
.Lret3: ret
.Lend3:
.size EXT(__frv_fix_usrptrs),.Lend2-EXT(__frv_fix_usrptrs)
|