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 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Copyright (c) 1992, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * Ralph Campbell.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)machAsmDefs.h 8.1 (Berkeley) 6/10/93
37 * JNPR: asm.h,v 1.10 2007/08/09 11:23:32 katta
38 * $FreeBSD$
39 */
40
41 /*
42 * machAsmDefs.h --
43 *
44 * Macros used when writing assembler programs.
45 *
46 * Copyright (C) 1989 Digital Equipment Corporation.
47 * Permission to use, copy, modify, and distribute this software and
48 * its documentation for any purpose and without fee is hereby granted,
49 * provided that the above copyright notice appears in all copies.
50 * Digital Equipment Corporation makes no representations about the
51 * suitability of this software for any purpose. It is provided "as is"
52 * without express or implied warranty.
53 *
54 * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsmDefs.h,
55 * v 1.2 89/08/15 18:28:24 rab Exp SPRITE (DECWRL)
56 */
57
58 #ifndef _MACHINE_ASM_H_
59 #define _MACHINE_ASM_H_
60
61 #include <machine/abi.h>
62 #include <machine/regdef.h>
63 #include <machine/endian.h>
64 #include <machine/cdefs.h>
65
66 #undef __FBSDID
67 #if !defined(lint) && !defined(STRIP_FBSDID)
68 #define __FBSDID(s) .ident s
69 #else
70 #define __FBSDID(s) /* nothing */
71 #endif
72
73 /*
74 * Define -pg profile entry code.
75 * Must always be noreorder, must never use a macro instruction
76 * Final addiu to t9 must always equal the size of this _KERN_MCOUNT
77 */
78 #define _KERN_MCOUNT \
79 .set push; \
80 .set noreorder; \
81 .set noat; \
82 subu sp,sp,16; \
83 sw t9,12(sp); \
84 move AT,ra; \
85 lui t9,%hi(_mcount); \
86 addiu t9,t9,%lo(_mcount); \
87 jalr t9; \
88 nop; \
89 lw t9,4(sp); \
90 addiu sp,sp,8; \
91 addiu t9,t9,40; \
92 .set pop;
93
94 #ifdef GPROF
95 #define MCOUNT _KERN_MCOUNT
96 #else
97 #define MCOUNT
98 #endif
99
100 #define _C_LABEL(x) x
101
102 #ifdef USE_AENT
103 #define AENT(x) \
104 .aent x, 0
105 #else
106 #define AENT(x)
107 #endif
108
109 /*
110 * WARN_REFERENCES: create a warning if the specified symbol is referenced
111 */
112 #define WARN_REFERENCES(_sym,_msg) \
113 .section .gnu.warning. ## _sym ; .ascii _msg ; .text
114
115 #ifdef __ELF__
116 # define _C_LABEL(x) x
117 #else
118 # define _C_LABEL(x) _ ## x
119 #endif
120
121 /*
122 * WEAK_ALIAS: create a weak alias.
123 */
124 #define WEAK_ALIAS(alias,sym) \
125 .weak alias; \
126 alias = sym
127
128 /*
129 * STRONG_ALIAS: create a strong alias.
130 */
131 #define STRONG_ALIAS(alias,sym) \
132 .globl alias; \
133 alias = sym
134
135 #define GLOBAL(sym) \
136 .globl sym; sym:
137
138 #define ENTRY(sym) \
139 .text; .globl sym; .ent sym; sym:
140
141 #define ASM_ENTRY(sym) \
142 .text; .globl sym; .type sym,@function; sym:
143
144 /*
145 * LEAF
146 * A leaf routine does
147 * - call no other function,
148 * - never use any register that callee-saved (S0-S8), and
149 * - not use any local stack storage.
150 */
151 #define LEAF(x) \
152 .globl _C_LABEL(x); \
153 .ent _C_LABEL(x), 0; \
154 _C_LABEL(x): ; \
155 .frame sp, 0, ra; \
156 MCOUNT
157
158 /*
159 * LEAF_NOPROFILE
160 * No profilable leaf routine.
161 */
162 #define LEAF_NOPROFILE(x) \
163 .globl _C_LABEL(x); \
164 .ent _C_LABEL(x), 0; \
165 _C_LABEL(x): ; \
166 .frame sp, 0, ra
167
168 /*
169 * XLEAF
170 * declare alternate entry to leaf routine
171 */
172 #define XLEAF(x) \
173 .globl _C_LABEL(x); \
174 AENT (_C_LABEL(x)); \
175 _C_LABEL(x):
176
177 /*
178 * NESTED
179 * A function calls other functions and needs
180 * therefore stack space to save/restore registers.
181 */
182 #define NESTED(x, fsize, retpc) \
183 .globl _C_LABEL(x); \
184 .ent _C_LABEL(x), 0; \
185 _C_LABEL(x): ; \
186 .frame sp, fsize, retpc; \
187 MCOUNT
188
189 /*
190 * NESTED_NOPROFILE(x)
191 * No profilable nested routine.
192 */
193 #define NESTED_NOPROFILE(x, fsize, retpc) \
194 .globl _C_LABEL(x); \
195 .ent _C_LABEL(x), 0; \
196 _C_LABEL(x): ; \
197 .frame sp, fsize, retpc
198
199 /*
200 * XNESTED
201 * declare alternate entry point to nested routine.
202 */
203 #define XNESTED(x) \
204 .globl _C_LABEL(x); \
205 AENT (_C_LABEL(x)); \
206 _C_LABEL(x):
207
208 /*
209 * END
210 * Mark end of a procedure.
211 */
212 #define END(x) \
213 .end _C_LABEL(x)
214
215 /*
216 * IMPORT -- import external symbol
217 */
218 #define IMPORT(sym, size) \
219 .extern _C_LABEL(sym),size
220
221 /*
222 * EXPORT -- export definition of symbol
223 */
224 #define EXPORT(x) \
225 .globl _C_LABEL(x); \
226 _C_LABEL(x):
227
228 /*
229 * VECTOR
230 * exception vector entrypoint
231 * XXX: regmask should be used to generate .mask
232 */
233 #define VECTOR(x, regmask) \
234 .ent _C_LABEL(x),0; \
235 EXPORT(x); \
236
237 #define VECTOR_END(x) \
238 EXPORT(x ## End); \
239 END(x)
240
241 /*
242 * Macros to panic and printf from assembly language.
243 */
244 #define PANIC(msg) \
245 PTR_LA a0, 9f; \
246 jal _C_LABEL(panic); \
247 nop; \
248 MSG(msg)
249
250 #define PANIC_KSEG0(msg, reg) PANIC(msg)
251
252 #define PRINTF(msg) \
253 PTR_LA a0, 9f; \
254 jal _C_LABEL(printf); \
255 nop; \
256 MSG(msg)
257
258 #define MSG(msg) \
259 .rdata; \
260 9: .asciiz msg; \
261 .text
262
263 #define ASMSTR(str) \
264 .asciiz str; \
265 .align 3
266
267 #if defined(__mips_o32) || defined(__mips_o64)
268 #define ALSK 7 /* stack alignment */
269 #define ALMASK -7 /* stack alignment */
270 #define SZFPREG 4
271 #define FP_L lwc1
272 #define FP_S swc1
273 #else
274 #define ALSK 15 /* stack alignment */
275 #define ALMASK -15 /* stack alignment */
276 #define SZFPREG 8
277 #define FP_L ldc1
278 #define FP_S sdc1
279 #endif
280
281 /*
282 * Endian-independent assembly-code aliases for unaligned memory accesses.
283 */
284 #if _BYTE_ORDER == _LITTLE_ENDIAN
285 # define LWHI lwr
286 # define LWLO lwl
287 # define SWHI swr
288 # define SWLO swl
289 # if SZREG == 4
290 # define REG_LHI lwr
291 # define REG_LLO lwl
292 # define REG_SHI swr
293 # define REG_SLO swl
294 # else
295 # define REG_LHI ldr
296 # define REG_LLO ldl
297 # define REG_SHI sdr
298 # define REG_SLO sdl
299 # endif
300 #endif
301
302 #if _BYTE_ORDER == _BIG_ENDIAN
303 # define LWHI lwl
304 # define LWLO lwr
305 # define SWHI swl
306 # define SWLO swr
307 # if SZREG == 4
308 # define REG_LHI lwl
309 # define REG_LLO lwr
310 # define REG_SHI swl
311 # define REG_SLO swr
312 # else
313 # define REG_LHI ldl
314 # define REG_LLO ldr
315 # define REG_SHI sdl
316 # define REG_SLO sdr
317 # endif
318 #endif
319
320 /*
321 * While it would be nice to be compatible with the SGI
322 * REG_L and REG_S macros, because they do not take parameters, it
323 * is impossible to use them with the _MIPS_SIM_ABIX32 model.
324 *
325 * These macros hide the use of mips3 instructions from the
326 * assembler to prevent the assembler from generating 64-bit style
327 * ABI calls.
328 */
329 #if _MIPS_SZPTR == 32
330 #define PTR_ADD add
331 #define PTR_ADDI addi
332 #define PTR_ADDU addu
333 #define PTR_ADDIU addiu
334 #define PTR_SUB add
335 #define PTR_SUBI subi
336 #define PTR_SUBU subu
337 #define PTR_SUBIU subu
338 #define PTR_L lw
339 #define PTR_LA la
340 #define PTR_LI li
341 #define PTR_S sw
342 #define PTR_SLL sll
343 #define PTR_SLLV sllv
344 #define PTR_SRL srl
345 #define PTR_SRLV srlv
346 #define PTR_SRA sra
347 #define PTR_SRAV srav
348 #define PTR_LL ll
349 #define PTR_SC sc
350 #define PTR_WORD .word
351 #define PTR_SCALESHIFT 2
352 #else /* _MIPS_SZPTR == 64 */
353 #define PTR_ADD dadd
354 #define PTR_ADDI daddi
355 #define PTR_ADDU daddu
356 #define PTR_ADDIU daddiu
357 #define PTR_SUB dadd
358 #define PTR_SUBI dsubi
359 #define PTR_SUBU dsubu
360 #define PTR_SUBIU dsubu
361 #define PTR_L ld
362 #define PTR_LA dla
363 #define PTR_LI dli
364 #define PTR_S sd
365 #define PTR_SLL dsll
366 #define PTR_SLLV dsllv
367 #define PTR_SRL dsrl
368 #define PTR_SRLV dsrlv
369 #define PTR_SRA dsra
370 #define PTR_SRAV dsrav
371 #define PTR_LL lld
372 #define PTR_SC scd
373 #define PTR_WORD .dword
374 #define PTR_SCALESHIFT 3
375 #endif /* _MIPS_SZPTR == 64 */
376
377 #if _MIPS_SZINT == 32
378 #define INT_ADD add
379 #define INT_ADDI addi
380 #define INT_ADDU addu
381 #define INT_ADDIU addiu
382 #define INT_SUB add
383 #define INT_SUBI subi
384 #define INT_SUBU subu
385 #define INT_SUBIU subu
386 #define INT_L lw
387 #define INT_LA la
388 #define INT_S sw
389 #define INT_SLL sll
390 #define INT_SLLV sllv
391 #define INT_SRL srl
392 #define INT_SRLV srlv
393 #define INT_SRA sra
394 #define INT_SRAV srav
395 #define INT_LL ll
396 #define INT_SC sc
397 #define INT_WORD .word
398 #define INT_SCALESHIFT 2
399 #else
400 #define INT_ADD dadd
401 #define INT_ADDI daddi
402 #define INT_ADDU daddu
403 #define INT_ADDIU daddiu
404 #define INT_SUB dadd
405 #define INT_SUBI dsubi
406 #define INT_SUBU dsubu
407 #define INT_SUBIU dsubu
408 #define INT_L ld
409 #define INT_LA dla
410 #define INT_S sd
411 #define INT_SLL dsll
412 #define INT_SLLV dsllv
413 #define INT_SRL dsrl
414 #define INT_SRLV dsrlv
415 #define INT_SRA dsra
416 #define INT_SRAV dsrav
417 #define INT_LL lld
418 #define INT_SC scd
419 #define INT_WORD .dword
420 #define INT_SCALESHIFT 3
421 #endif
422
423 #if _MIPS_SZLONG == 32
424 #define LONG_ADD add
425 #define LONG_ADDI addi
426 #define LONG_ADDU addu
427 #define LONG_ADDIU addiu
428 #define LONG_SUB add
429 #define LONG_SUBI subi
430 #define LONG_SUBU subu
431 #define LONG_SUBIU subu
432 #define LONG_L lw
433 #define LONG_LA la
434 #define LONG_S sw
435 #define LONG_SLL sll
436 #define LONG_SLLV sllv
437 #define LONG_SRL srl
438 #define LONG_SRLV srlv
439 #define LONG_SRA sra
440 #define LONG_SRAV srav
441 #define LONG_LL ll
442 #define LONG_SC sc
443 #define LONG_WORD .word
444 #define LONG_SCALESHIFT 2
445 #else
446 #define LONG_ADD dadd
447 #define LONG_ADDI daddi
448 #define LONG_ADDU daddu
449 #define LONG_ADDIU daddiu
450 #define LONG_SUB dadd
451 #define LONG_SUBI dsubi
452 #define LONG_SUBU dsubu
453 #define LONG_SUBIU dsubu
454 #define LONG_L ld
455 #define LONG_LA dla
456 #define LONG_S sd
457 #define LONG_SLL dsll
458 #define LONG_SLLV dsllv
459 #define LONG_SRL dsrl
460 #define LONG_SRLV dsrlv
461 #define LONG_SRA dsra
462 #define LONG_SRAV dsrav
463 #define LONG_LL lld
464 #define LONG_SC scd
465 #define LONG_WORD .dword
466 #define LONG_SCALESHIFT 3
467 #endif
468
469 #if SZREG == 4
470 #define REG_L lw
471 #define REG_S sw
472 #define REG_LI li
473 #define REG_ADDU addu
474 #define REG_SLL sll
475 #define REG_SLLV sllv
476 #define REG_SRL srl
477 #define REG_SRLV srlv
478 #define REG_SRA sra
479 #define REG_SRAV srav
480 #define REG_LL ll
481 #define REG_SC sc
482 #define REG_SCALESHIFT 2
483 #else
484 #define REG_L ld
485 #define REG_S sd
486 #define REG_LI dli
487 #define REG_ADDU daddu
488 #define REG_SLL dsll
489 #define REG_SLLV dsllv
490 #define REG_SRL dsrl
491 #define REG_SRLV dsrlv
492 #define REG_SRA dsra
493 #define REG_SRAV dsrav
494 #define REG_LL lld
495 #define REG_SC scd
496 #define REG_SCALESHIFT 3
497 #endif
498
499 #if _MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \
500 _MIPS_ISA == _MIPS_ISA_MIPS32
501 #define MFC0 mfc0
502 #define MTC0 mtc0
503 #endif
504 #if _MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \
505 _MIPS_ISA == _MIPS_ISA_MIPS64
506 #define MFC0 dmfc0
507 #define MTC0 dmtc0
508 #endif
509
510 #if defined(__mips_o32) || defined(__mips_o64)
511
512 #ifdef __ABICALLS__
513 #define CPRESTORE(r) .cprestore r
514 #define CPLOAD(r) .cpload r
515 #else
516 #define CPRESTORE(r) /* not needed */
517 #define CPLOAD(r) /* not needed */
518 #endif
519
520 #define SETUP_GP \
521 .set push; \
522 .set noreorder; \
523 .cpload t9; \
524 .set pop
525 #define SETUP_GPX(r) \
526 .set push; \
527 .set noreorder; \
528 move r,ra; /* save old ra */ \
529 bal 7f; \
530 nop; \
531 7: .cpload ra; \
532 move ra,r; \
533 .set pop
534 #define SETUP_GPX_L(r,lbl) \
535 .set push; \
536 .set noreorder; \
537 move r,ra; /* save old ra */ \
538 bal lbl; \
539 nop; \
540 lbl: .cpload ra; \
541 move ra,r; \
542 .set pop
543 #define SAVE_GP(x) .cprestore x
544
545 #define SETUP_GP64(a,b) /* n32/n64 specific */
546 #define SETUP_GP64_R(a,b) /* n32/n64 specific */
547 #define SETUP_GPX64(a,b) /* n32/n64 specific */
548 #define SETUP_GPX64_L(a,b,c) /* n32/n64 specific */
549 #define RESTORE_GP64 /* n32/n64 specific */
550 #define USE_ALT_CP(a) /* n32/n64 specific */
551 #endif /* __mips_o32 || __mips_o64 */
552
553 #if defined(__mips_o32) || defined(__mips_o64)
554 #define REG_PROLOGUE .set push
555 #define REG_EPILOGUE .set pop
556 #endif
557 #if defined(__mips_n32) || defined(__mips_n64)
558 #define REG_PROLOGUE .set push ; .set mips3
559 #define REG_EPILOGUE .set pop
560 #endif
561
562 #if defined(__mips_n32) || defined(__mips_n64)
563 #define SETUP_GP /* o32 specific */
564 #define SETUP_GPX(r) /* o32 specific */
565 #define SETUP_GPX_L(r,lbl) /* o32 specific */
566 #define SAVE_GP(x) /* o32 specific */
567 #define SETUP_GP64(a,b) .cpsetup $25, a, b
568 #define SETUP_GPX64(a,b) \
569 .set push; \
570 move b,ra; \
571 .set noreorder; \
572 bal 7f; \
573 nop; \
574 7: .set pop; \
575 .cpsetup ra, a, 7b; \
576 move ra,b
577 #define SETUP_GPX64_L(a,b,c) \
578 .set push; \
579 move b,ra; \
580 .set noreorder; \
581 bal c; \
582 nop; \
583 c: .set pop; \
584 .cpsetup ra, a, c; \
585 move ra,b
586 #define RESTORE_GP64 .cpreturn
587 #define USE_ALT_CP(a) .cplocal a
588 #endif /* __mips_n32 || __mips_n64 */
589
590 #define GET_CPU_PCPU(reg) \
591 PTR_L reg, _C_LABEL(pcpup);
592
593 /*
594 * Description of the setjmp buffer
595 *
596 * word 0 magic number (dependant on creator)
597 * 1 RA
598 * 2 S0
599 * 3 S1
600 * 4 S2
601 * 5 S3
602 * 6 S4
603 * 7 S5
604 * 8 S6
605 * 9 S7
606 * 10 SP
607 * 11 S8
608 * 12 GP (dependent on ABI)
609 * 13 signal mask (dependant on magic)
610 * 14 (con't)
611 * 15 (con't)
612 * 16 (con't)
613 *
614 * The magic number number identifies the jmp_buf and
615 * how the buffer was created as well as providing
616 * a sanity check
617 *
618 */
619
620 #define _JB_MAGIC__SETJMP 0xBADFACED
621 #define _JB_MAGIC_SETJMP 0xFACEDBAD
622
623 /* Valid for all jmp_buf's */
624
625 #define _JB_MAGIC 0
626 #define _JB_REG_RA 1
627 #define _JB_REG_S0 2
628 #define _JB_REG_S1 3
629 #define _JB_REG_S2 4
630 #define _JB_REG_S3 5
631 #define _JB_REG_S4 6
632 #define _JB_REG_S5 7
633 #define _JB_REG_S6 8
634 #define _JB_REG_S7 9
635 #define _JB_REG_SP 10
636 #define _JB_REG_S8 11
637 #if defined(__mips_n32) || defined(__mips_n64)
638 #define _JB_REG_GP 12
639 #endif
640
641 /* Only valid with the _JB_MAGIC_SETJMP magic */
642
643 #define _JB_SIGMASK 13
644 #define __JB_SIGMASK_REMAINDER 14 /* sigmask_t is 128-bits */
645
646 #define _JB_FPREG_F20 15
647 #define _JB_FPREG_F21 16
648 #define _JB_FPREG_F22 17
649 #define _JB_FPREG_F23 18
650 #define _JB_FPREG_F24 19
651 #define _JB_FPREG_F25 20
652 #define _JB_FPREG_F26 21
653 #define _JB_FPREG_F27 22
654 #define _JB_FPREG_F28 23
655 #define _JB_FPREG_F29 24
656 #define _JB_FPREG_F30 25
657 #define _JB_FPREG_F31 26
658 #define _JB_FPREG_FCSR 27
659
660 /*
661 * Various macros for dealing with TLB hazards
662 * (a) why so many?
663 * (b) when to use?
664 * (c) why not used everywhere?
665 */
666 /*
667 * Assume that w alaways need nops to escape CP0 hazard
668 * TODO: Make hazard delays configurable. Stuck with 5 cycles on the moment
669 * For more info on CP0 hazards see Chapter 7 (p.99) of "MIPS32 Architecture
670 * For Programmers Volume III: The MIPS32 Privileged Resource Architecture"
671 */
672 #if defined(CPU_NLM)
673 #define HAZARD_DELAY sll $0,3
674 #define ITLBNOPFIX sll $0,3
675 #elif defined(CPU_RMI)
676 #define HAZARD_DELAY
677 #define ITLBNOPFIX
678 #elif defined(CPU_MIPS74K)
679 #define HAZARD_DELAY sll $0,$0,3
680 #define ITLBNOPFIX sll $0,$0,3
681 #else
682 #define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;sll $0,$0,3;
683 #define HAZARD_DELAY nop;nop;nop;nop;sll $0,$0,3;
684 #endif
685
686 #endif /* !_MACHINE_ASM_H_ */
Cache object: 38a07b03d1f0c456539775ec6fc4a25c
|