FreeBSD/Linux Kernel Cross Reference
sys/mips/include/asm.h
1 /* $NetBSD: asm.h,v 1.29 2000/12/14 21:29:51 jeffs Exp $ */
2
3 /*
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Ralph Campbell.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)machAsmDefs.h 8.1 (Berkeley) 6/10/93
35 * JNPR: asm.h,v 1.10 2007/08/09 11:23:32 katta
36 * $FreeBSD: releng/8.1/sys/mips/include/asm.h 178172 2008-04-13 07:27:37Z imp $
37 */
38
39 /*
40 * machAsmDefs.h --
41 *
42 * Macros used when writing assembler programs.
43 *
44 * Copyright (C) 1989 Digital Equipment Corporation.
45 * Permission to use, copy, modify, and distribute this software and
46 * its documentation for any purpose and without fee is hereby granted,
47 * provided that the above copyright notice appears in all copies.
48 * Digital Equipment Corporation makes no representations about the
49 * suitability of this software for any purpose. It is provided "as is"
50 * without express or implied warranty.
51 *
52 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsmDefs.h,
53 * v 1.2 89/08/15 18:28:24 rab Exp SPRITE (DECWRL)
54 */
55
56 #ifndef _MACHINE_ASM_H_
57 #define _MACHINE_ASM_H_
58
59 #ifndef NO_REG_DEFS
60 #include <machine/regdef.h>
61 #endif
62 #include <machine/endian.h>
63
64 #undef __FBSDID
65 #if !defined(lint) && !defined(STRIP_FBSDID)
66 #define __FBSDID(s) .ident s
67 #else
68 #define __FBSDID(s) /* nothing */
69 #endif
70
71 /*
72 * Define -pg profile entry code.
73 * Must always be noreorder, must never use a macro instruction
74 * Final addiu to t9 must always equal the size of this _KERN_MCOUNT
75 */
76 #define _KERN_MCOUNT \
77 .set push; \
78 .set noreorder; \
79 .set noat; \
80 subu sp,sp,16; \
81 sw t9,12(sp); \
82 move AT,ra; \
83 lui t9,%hi(_mcount); \
84 addiu t9,t9,%lo(_mcount); \
85 jalr t9; \
86 nop; \
87 lw t9,4(sp); \
88 addiu sp,sp,8; \
89 addiu t9,t9,40; \
90 .set pop;
91
92 #ifdef GPROF
93 #define MCOUNT _KERN_MCOUNT
94 #else
95 #define MCOUNT
96 #endif
97
98 #define _C_LABEL(x) x
99
100 /*
101 * Endian-independent assembly-code aliases for unaligned memory accesses.
102 */
103 #if BYTE_ORDER == LITTLE_ENDIAN
104 #define LWLO lwl
105 #define LWHI lwr
106 #define SWLO swl
107 #define SWHI swr
108 #endif
109
110 #if BYTE_ORDER == BIG_ENDIAN
111 #define LWLO lwr
112 #define LWHI lwl
113 #define SWLO swr
114 #define SWHI swl
115 #endif
116
117 #ifdef USE_AENT
118 #define AENT(x) \
119 .aent x, 0
120 #else
121 #define AENT(x)
122 #endif
123
124 /*
125 * WARN_REFERENCES: create a warning if the specified symbol is referenced
126 */
127 #define WARN_REFERENCES(_sym,_msg) \
128 .section .gnu.warning. ## _sym ; .ascii _msg ; .text
129
130 /*
131 * These are temp registers whose names can be used in either the old
132 * or new ABI, although they map to different physical registers. In
133 * the old ABI, they map to t4-t7, and in the new ABI, they map to a4-a7.
134 *
135 * Because they overlap with the last 4 arg regs in the new ABI, ta0-ta3
136 * should be used only when we need more than t0-t3.
137 */
138 #if defined(__mips_n32) || defined(__mips_n64)
139 #define ta0 $8
140 #define ta1 $9
141 #define ta2 $10
142 #define ta3 $11
143 #else
144 #define ta0 $12
145 #define ta1 $13
146 #define ta2 $14
147 #define ta3 $15
148 #endif /* __mips_n32 || __mips_n64 */
149
150 #ifdef __ELF__
151 # define _C_LABEL(x) x
152 #else
153 # define _C_LABEL(x) _ ## x
154 #endif
155
156 /*
157 * WEAK_ALIAS: create a weak alias.
158 */
159 #define WEAK_ALIAS(alias,sym) \
160 .weak alias; \
161 alias = sym
162
163 /*
164 * STRONG_ALIAS: create a strong alias.
165 */
166 #define STRONG_ALIAS(alias,sym) \
167 .globl alias; \
168 alias = sym
169
170 #define GLOBAL(sym) \
171 .globl sym; sym:
172
173 #define ENTRY(sym) \
174 .text; .globl sym; .ent sym; sym:
175
176 #define ASM_ENTRY(sym) \
177 .text; .globl sym; .type sym,@function; sym:
178
179 /*
180 * LEAF
181 * A leaf routine does
182 * - call no other function,
183 * - never use any register that callee-saved (S0-S8), and
184 * - not use any local stack storage.
185 */
186 #define LEAF(x) \
187 .globl _C_LABEL(x); \
188 .ent _C_LABEL(x), 0; \
189 _C_LABEL(x): ; \
190 .frame sp, 0, ra; \
191 MCOUNT
192
193 /*
194 * LEAF_NOPROFILE
195 * No profilable leaf routine.
196 */
197 #define LEAF_NOPROFILE(x) \
198 .globl _C_LABEL(x); \
199 .ent _C_LABEL(x), 0; \
200 _C_LABEL(x): ; \
201 .frame sp, 0, ra
202
203 /*
204 * XLEAF
205 * declare alternate entry to leaf routine
206 */
207 #define XLEAF(x) \
208 .globl _C_LABEL(x); \
209 AENT (_C_LABEL(x)); \
210 _C_LABEL(x):
211
212 /*
213 * NESTED
214 * A function calls other functions and needs
215 * therefore stack space to save/restore registers.
216 */
217 #define NESTED(x, fsize, retpc) \
218 .globl _C_LABEL(x); \
219 .ent _C_LABEL(x), 0; \
220 _C_LABEL(x): ; \
221 .frame sp, fsize, retpc; \
222 MCOUNT
223
224 /*
225 * NESTED_NOPROFILE(x)
226 * No profilable nested routine.
227 */
228 #define NESTED_NOPROFILE(x, fsize, retpc) \
229 .globl _C_LABEL(x); \
230 .ent _C_LABEL(x), 0; \
231 _C_LABEL(x): ; \
232 .frame sp, fsize, retpc
233
234 /*
235 * XNESTED
236 * declare alternate entry point to nested routine.
237 */
238 #define XNESTED(x) \
239 .globl _C_LABEL(x); \
240 AENT (_C_LABEL(x)); \
241 _C_LABEL(x):
242
243 /*
244 * END
245 * Mark end of a procedure.
246 */
247 #define END(x) \
248 .end _C_LABEL(x)
249
250 /*
251 * IMPORT -- import external symbol
252 */
253 #define IMPORT(sym, size) \
254 .extern _C_LABEL(sym),size
255
256 /*
257 * EXPORT -- export definition of symbol
258 */
259 #define EXPORT(x) \
260 .globl _C_LABEL(x); \
261 _C_LABEL(x):
262
263 /*
264 * VECTOR
265 * exception vector entrypoint
266 * XXX: regmask should be used to generate .mask
267 */
268 #define VECTOR(x, regmask) \
269 .ent _C_LABEL(x),0; \
270 EXPORT(x); \
271
272 #define VECTOR_END(x) \
273 EXPORT(x ## End); \
274 END(x)
275
276 #define KSEG0TEXT_START
277 #define KSEG0TEXT_END
278 #define KSEG0TEXT .text
279
280 /*
281 * Macros to panic and printf from assembly language.
282 */
283 #define PANIC(msg) \
284 la a0, 9f; \
285 jal _C_LABEL(panic); \
286 nop; \
287 MSG(msg)
288
289 #define PANIC_KSEG0(msg, reg) PANIC(msg)
290
291 #define PRINTF(msg) \
292 la a0, 9f; \
293 jal _C_LABEL(printf); \
294 nop; \
295 MSG(msg)
296
297 #define MSG(msg) \
298 .rdata; \
299 9: .asciiz msg; \
300 .text
301
302 #define ASMSTR(str) \
303 .asciiz str; \
304 .align 3
305
306 /*
307 * Call ast if required
308 */
309 #define DO_AST \
310 44: \
311 la s0, _C_LABEL(disableintr) ;\
312 jalr s0 ;\
313 nop ;\
314 GET_CPU_PCPU(s1) ;\
315 lw s3, PC_CURPCB(s1) ;\
316 lw s1, PC_CURTHREAD(s1) ;\
317 lw s2, TD_FLAGS(s1) ;\
318 li s0, TDF_ASTPENDING | TDF_NEEDRESCHED;\
319 and s2, s0 ;\
320 la s0, _C_LABEL(enableintr) ;\
321 jalr s0 ;\
322 nop ;\
323 beq s2, zero, 4f ;\
324 nop ;\
325 la s0, _C_LABEL(ast) ;\
326 jalr s0 ;\
327 addu a0, s3, U_PCB_REGS ;\
328 j 44b ;\
329 nop ;\
330 4:
331
332
333 /*
334 * XXX retain dialects XXX
335 */
336 #define ALEAF(x) XLEAF(x)
337 #define NLEAF(x) LEAF_NOPROFILE(x)
338 #define NON_LEAF(x, fsize, retpc) NESTED(x, fsize, retpc)
339 #define NNON_LEAF(x, fsize, retpc) NESTED_NOPROFILE(x, fsize, retpc)
340
341 /*
342 * standard callframe {
343 * register_t cf_args[4]; arg0 - arg3
344 * register_t cf_sp; frame pointer
345 * register_t cf_ra; return address
346 * };
347 */
348 #define CALLFRAME_SIZ (4 * (4 + 2))
349 #define CALLFRAME_SP (4 * 4)
350 #define CALLFRAME_RA (4 * 5)
351 #define START_FRAME CALLFRAME_SIZ
352
353 /*
354 * While it would be nice to be compatible with the SGI
355 * REG_L and REG_S macros, because they do not take parameters, it
356 * is impossible to use them with the _MIPS_SIM_ABIX32 model.
357 *
358 * These macros hide the use of mips3 instructions from the
359 * assembler to prevent the assembler from generating 64-bit style
360 * ABI calls.
361 */
362
363 #if !defined(_MIPS_BSD_API) || _MIPS_BSD_API == _MIPS_BSD_API_LP32
364 #define REG_L lw
365 #define REG_S sw
366 #define REG_LI li
367 #define REG_PROLOGUE .set push
368 #define REG_EPILOGUE .set pop
369 #define SZREG 4
370 #else
371 #define REG_L ld
372 #define REG_S sd
373 #define REG_LI dli
374 #define REG_PROLOGUE .set push ; .set mips3
375 #define REG_EPILOGUE .set pop
376 #define SZREG 8
377 #endif /* _MIPS_BSD_API */
378
379 #define mfc0_macro(data, spr) \
380 __asm __volatile ("mfc0 %0, $%1" \
381 : "=r" (data) /* outputs */ \
382 : "i" (spr)); /* inputs */
383
384 #define mtc0_macro(data, spr) \
385 __asm __volatile ("mtc0 %0, $%1" \
386 : /* outputs */ \
387 : "r" (data), "i" (spr)); /* inputs */
388
389 #define cfc0_macro(data, spr) \
390 __asm __volatile ("cfc0 %0, $%1" \
391 : "=r" (data) /* outputs */ \
392 : "i" (spr)); /* inputs */
393
394 #define ctc0_macro(data, spr) \
395 __asm __volatile ("ctc0 %0, $%1" \
396 : /* outputs */ \
397 : "r" (data), "i" (spr)); /* inputs */
398
399
400 #define lbu_macro(data, addr) \
401 __asm __volatile ("lbu %0, 0x0(%1)" \
402 : "=r" (data) /* outputs */ \
403 : "r" (addr)); /* inputs */
404
405 #define lb_macro(data, addr) \
406 __asm __volatile ("lb %0, 0x0(%1)" \
407 : "=r" (data) /* outputs */ \
408 : "r" (addr)); /* inputs */
409
410 #define lwl_macro(data, addr) \
411 __asm __volatile ("lwl %0, 0x0(%1)" \
412 : "=r" (data) /* outputs */ \
413 : "r" (addr)); /* inputs */
414
415 #define lwr_macro(data, addr) \
416 __asm __volatile ("lwr %0, 0x0(%1)" \
417 : "=r" (data) /* outputs */ \
418 : "r" (addr)); /* inputs */
419
420 #define ldl_macro(data, addr) \
421 __asm __volatile ("ldl %0, 0x0(%1)" \
422 : "=r" (data) /* outputs */ \
423 : "r" (addr)); /* inputs */
424
425 #define ldr_macro(data, addr) \
426 __asm __volatile ("ldr %0, 0x0(%1)" \
427 : "=r" (data) /* outputs */ \
428 : "r" (addr)); /* inputs */
429
430 #define sb_macro(data, addr) \
431 __asm __volatile ("sb %0, 0x0(%1)" \
432 : /* outputs */ \
433 : "r" (data), "r" (addr)); /* inputs */
434
435 #define swl_macro(data, addr) \
436 __asm __volatile ("swl %0, 0x0(%1)" \
437 : /* outputs */ \
438 : "r" (data), "r" (addr)); /* inputs */
439
440 #define swr_macro(data, addr) \
441 __asm __volatile ("swr %0, 0x0(%1)" \
442 : /* outputs */ \
443 : "r" (data), "r" (addr)); /* inputs */
444
445 #define sdl_macro(data, addr) \
446 __asm __volatile ("sdl %0, 0x0(%1)" \
447 : /* outputs */ \
448 : "r" (data), "r" (addr)); /* inputs */
449
450 #define sdr_macro(data, addr) \
451 __asm __volatile ("sdr %0, 0x0(%1)" \
452 : /* outputs */ \
453 : "r" (data), "r" (addr)); /* inputs */
454
455 #define mfgr_macro(data, gr) \
456 __asm __volatile ("move %0, $%1" \
457 : "=r" (data) /* outputs */ \
458 : "i" (gr)); /* inputs */
459
460 #define dmfc0_macro(data, spr) \
461 __asm __volatile ("dmfc0 %0, $%1" \
462 : "=r" (data) /* outputs */ \
463 : "i" (spr)); /* inputs */
464
465 #define dmtc0_macro(data, spr, sel) \
466 __asm __volatile ("dmtc0 %0, $%1, %2" \
467 : /* no outputs */ \
468 : "r" (data), "i" (spr), "i" (sel)); /* inputs */
469
470 /*
471 * The DYNAMIC_STATUS_MASK option adds an additional masking operation
472 * when updating the hardware interrupt mask in the status register.
473 *
474 * This is useful for platforms that need to at run-time mask
475 * interrupts based on motherboard configuration or to handle
476 * slowly clearing interrupts.
477 *
478 * XXX this is only currently implemented for mips3.
479 */
480 #ifdef MIPS_DYNAMIC_STATUS_MASK
481 #define DYNAMIC_STATUS_MASK(sr,scratch) \
482 lw scratch, mips_dynamic_status_mask; \
483 and sr, sr, scratch
484
485 #define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1) \
486 ori sr, (MIPS_INT_MASK | MIPS_SR_INT_IE); \
487 DYNAMIC_STATUS_MASK(sr,scratch1)
488 #else
489 #define DYNAMIC_STATUS_MASK(sr,scratch)
490 #define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1)
491 #endif
492
493 #ifdef SMP
494 /*
495 * FREEBSD_DEVELOPERS_FIXME
496 * In multiprocessor case, store/retrieve the pcpu structure
497 * address for current CPU in scratch register for fast access.
498 */
499 #error "Write GET_CPU_PCPU for SMP"
500 #else
501 #define GET_CPU_PCPU(reg) \
502 lw reg, _C_LABEL(pcpup);
503 #endif
504
505 /*
506 * Description of the setjmp buffer
507 *
508 * word 0 magic number (dependant on creator)
509 * 1 RA
510 * 2 S0
511 * 3 S1
512 * 4 S2
513 * 5 S3
514 * 6 S4
515 * 7 S5
516 * 8 S6
517 * 9 S7
518 * 10 SP
519 * 11 S8
520 * 12 signal mask (dependant on magic)
521 * 13 (con't)
522 * 14 (con't)
523 * 15 (con't)
524 *
525 * The magic number number identifies the jmp_buf and
526 * how the buffer was created as well as providing
527 * a sanity check
528 *
529 */
530
531 #define _JB_MAGIC__SETJMP 0xBADFACED
532 #define _JB_MAGIC_SETJMP 0xFACEDBAD
533
534 /* Valid for all jmp_buf's */
535
536 #define _JB_MAGIC 0
537 #define _JB_REG_RA 1
538 #define _JB_REG_S0 2
539 #define _JB_REG_S1 3
540 #define _JB_REG_S2 4
541 #define _JB_REG_S3 5
542 #define _JB_REG_S4 6
543 #define _JB_REG_S5 7
544 #define _JB_REG_S6 8
545 #define _JB_REG_S7 9
546 #define _JB_REG_SP 10
547 #define _JB_REG_S8 11
548
549 /* Only valid with the _JB_MAGIC_SETJMP magic */
550
551 #define _JB_SIGMASK 12
552
553 #endif /* !_MACHINE_ASM_H_ */
Cache object: 0d42f3aa0381bd52a4d1c6f81a3e3f53
|