asm.h revision 1.20 1 /* $NetBSD: asm.h,v 1.20 2006/07/01 20:34:49 ross Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifndef _PPC_ASM_H_
35 #define _PPC_ASM_H_
36
37 #ifdef PIC
38 #define PIC_PROLOGUE XXX
39 #define PIC_EPILOGUE XXX
40 #define PIC_PLT(x) x@plt
41 #ifdef __STDC__
42 #define PIC_GOT(x) XXX
43 #define PIC_GOTOFF(x) XXX
44 #else /* not __STDC__ */
45 #define PIC_GOT(x) XXX
46 #define PIC_GOTOFF(x) XXX
47 #endif /* __STDC__ */
48 #else
49 #define PIC_PROLOGUE
50 #define PIC_EPILOGUE
51 #define PIC_PLT(x) x
52 #define PIC_GOT(x) x
53 #define PIC_GOTOFF(x) x
54 #endif
55
56 #define _C_LABEL(x) x
57 #define _ASM_LABEL(x) x
58
59 #define _GLOBAL(x) \
60 .data; .align 2; .globl x; x:
61
62 #ifdef GPROF
63 # define _PROF_PROLOGUE mflr 0; stw 0,4(1); bl _mcount
64 #else
65 # define _PROF_PROLOGUE
66 #endif
67
68 #ifdef _LP64
69
70 #define SF_HEADER_SZ 48
71 #define SF_PARAM_SZ 64
72 #define SF_SZ (F_HEADER_SZ + F_PARAM_SZ)
73
74 #define SF_SP 0
75 #define SF_CR 8
76 #define SF_LR 16
77 #define SF_PARAM SF_HEADER_SZ
78
79 #define ENTRY(y) \
80 .globl y; \
81 .section ".opd","aw"; \
82 .align 3; \
83 y: .quad .y,.TOC.@tocbase,0; \
84 .previous; \
85 .size y,24; \
86 .type .y,@function; \
87 .globl .y; \
88 .y:
89 #define CALL(y) \
90 bl y; \
91 nop
92
93 #define ENTRY_NOPROFILE(y) ENTRY(y)
94 #define ASENTRY(y) ENTRY(y)
95 #else
96
97 #define _ENTRY(x) \
98 .text; .align 2; .globl x; .type x,@function; x:
99
100 #define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
101
102 #define ENTRY_NOPROFILE(y) _ENTRY(_C_LABEL(y))
103
104 #define CALL(y) \
105 bl y
106
107 #define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
108 #endif
109
110 #define GLOBAL(y) _GLOBAL(_C_LABEL(y))
111
112 #define ASMSTR .asciz
113
114 #define RCSID(x) .text; .asciz x
115
116 #ifdef __ELF__
117 #define WEAK_ALIAS(alias,sym) \
118 .weak alias; \
119 alias = sym
120 #endif
121 /*
122 * STRONG_ALIAS: create a strong alias.
123 */
124 #define STRONG_ALIAS(alias,sym) \
125 .globl alias; \
126 alias = sym
127
128 #ifdef __STDC__
129 #define WARN_REFERENCES(_sym,_msg) \
130 .section .gnu.warning. ## _sym ; .ascii _msg ; .text
131 #else
132 #define WARN_REFERENCES(_sym,_msg) \
133 .section .gnu.warning./**/_sym ; .ascii _msg ; .text
134 #endif /* __STDC__ */
135
136 #ifdef _KERNEL
137 /*
138 * Get cpu_info pointer for current processor. Always in SPRG0. *ALWAYS*
139 */
140 #define GET_CPUINFO(r) mfsprg r,0
141 /*
142 * IN:
143 * R4[er] = first free byte beyond end/esym.
144 *
145 * OUT:
146 * R1[sp] = new kernel stack
147 * R4[er] = kernelend
148 */
149
150 #define INIT_CPUINFO(er,sp,tmp1,tmp2) \
151 li tmp1,PGOFSET; \
152 add er,er,tmp1; \
153 andc er,er,tmp1; /* page align */ \
154 lis tmp1,_C_LABEL(cpu_info)@ha; \
155 addi tmp1,tmp1,_C_LABEL(cpu_info)@l; \
156 mtsprg0 tmp1; /* save for later use */ \
157 addi er,er,INTSTK; \
158 stptr er,CI_INTSTK(tmp1); \
159 stptr er,CI_IDLE_PCB(tmp1); \
160 addi er,er,USPACE; /* space for idle_u */ \
161 lis tmp2,_C_LABEL(emptyidlespin)@h; \
162 ori tmp2,tmp2,_C_LABEL(emptyidlespin)@l; \
163 stptr tmp2,CI_IDLESPIN(tmp1); \
164 li tmp2,-1; \
165 stint tmp2,CI_INTRDEPTH(tmp1); \
166 li tmp2,0; \
167 stptr tmp2,-CALLFRAMELEN(er); /* terminate idle stack chain */\
168 lis tmp1,_C_LABEL(proc0paddr)@ha; \
169 stptr er,_C_LABEL(proc0paddr)@l(tmp1); \
170 addi er,er,USPACE; /* stackpointer for proc0 */ \
171 addi sp,er,-FRAMELEN; /* stackpointer for proc0 */ \
172 /* er = end of mem reserved for kernel */ \
173 stptru tmp2,-CALLFRAMELEN(sp) /* end of stack chain */
174
175 #endif
176
177 /* Condition Register Bit Fields */
178
179 #if !defined(_NOREGNAMES)
180 #if defined(_KERNEL) || defined(_STANDALONE)
181 #define cr0 0
182 #define cr1 1
183 #define cr2 2
184 #define cr3 3
185 #define cr4 4
186 #define cr5 5
187 #define cr6 6
188 #define cr7 7
189 #endif
190
191 /* General Purpose Registers (GPRs) */
192
193 #if defined(_KERNEL) || defined(_STANDALONE)
194 #define r0 0
195 #define r1 1
196 #define r2 2
197 #define r3 3
198 #define r4 4
199 #define r5 5
200 #define r6 6
201 #define r7 7
202 #define r8 8
203 #define r9 9
204 #define r10 10
205 #define r11 11
206 #define r12 12
207 #define r13 13
208 #define r14 14
209 #define r15 15
210 #define r16 16
211 #define r17 17
212 #define r18 18
213 #define r19 19
214 #define r20 20
215 #define r21 21
216 #define r22 22
217 #define r23 23
218 #define r24 24
219 #define r25 25
220 #define r26 26
221 #define r27 27
222 #define r28 28
223 #define r29 29
224 #define r30 30
225 #define r31 31
226 #endif
227
228 /* Floating Point Registers (FPRs) */
229
230 #if defined(_KERNEL) || defined(_STANDALONE)
231 #define fr0 0
232 #define fr1 1
233 #define fr2 2
234 #define fr3 3
235 #define fr4 4
236 #define fr5 5
237 #define fr6 6
238 #define fr7 7
239 #define fr8 8
240 #define fr9 9
241 #define fr10 10
242 #define fr11 11
243 #define fr12 12
244 #define fr13 13
245 #define fr14 14
246 #define fr15 15
247 #define fr16 16
248 #define fr17 17
249 #define fr18 18
250 #define fr19 19
251 #define fr20 20
252 #define fr21 21
253 #define fr22 22
254 #define fr23 23
255 #define fr24 24
256 #define fr25 25
257 #define fr26 26
258 #define fr27 27
259 #define fr28 28
260 #define fr29 29
261 #define fr30 30
262 #define fr31 31
263 #endif
264 #endif /* !_NOREGNAMES */
265
266 /*
267 * Add some psuedo instructions to made sharing of assembly versions of
268 * ILP32 and LP64 code possible.
269 */
270 #define ldint lwz /* not needed but for completeness */
271 #define ldintu lwzu /* not needed but for completeness */
272 #define stint stw /* not needed but for completeness */
273 #define stintu stwu /* not needed but for completeness */
274
275 #ifndef _LP64
276
277 #define ldlong lwz /* load "C" long */
278 #define ldlongu lwzu /* load "C" long with udpate */
279 #define stlong stw /* load "C" long */
280 #define stlongu stwu /* load "C" long with udpate */
281 #define ldptr lwz /* load "C" pointer */
282 #define ldptru lwzu /* load "C" pointer with udpate */
283 #define stptr stw /* load "C" pointer */
284 #define stptru stwu /* load "C" pointer with udpate */
285 #define ldreg lwz /* load PPC general register */
286 #define ldregu lwzu /* load PPC general register with udpate */
287 #define streg stw /* load PPC general register */
288 #define stregu stwu /* load PPC general register with udpate */
289 #define SZREG 4 /* 4 byte registers */
290
291 #else
292
293 #define ldlong ld /* load "C" long */
294 #define ldlongu ldu /* load "C" long with update */
295 #define stlong std /* store "C" long */
296 #define stlongu stdu /* store "C" long with update */
297 #define ldptr ld /* load "C" pointer */
298 #define ldptru ldu /* load "C" pointer with update */
299 #define stptr std /* store "C" pointer */
300 #define stptru stdu /* store "C" pointer with update */
301 #define ldreg ld /* load PPC general register */
302 #define ldregu ldu /* load PPC general register with update */
303 #define streg std /* store PPC general register */
304 #define stregu stdu /* store PPC general register with update */
305 /* redefined this to force an error on PPC64 to catch their use. */
306 #define lmw lmd /* load multiple PPC general registers */
307 #define stmw stmd /* store multiple PPC general registers */
308 #define SZREG 8 /* 8 byte registers */
309
310 #endif
311
312 #endif /* !_PPC_ASM_H_ */
313