Module Name: src
Committed By: matt
Date: Sun Aug 16 02:52:43 UTC 2009
Modified Files:
src/sys/arch/mips/include [matt-nb5-mips64]: asm.h
Log Message:
Completely rework to support multiple ABIs. Includes macros/ops to make
writing ABI independent assembly much easier. Add macros to handle PIC
for N32/N64 as well as O32/O64.
To generate a diff of this commit:
cvs rdiff -u -r1.40 -r1.40.38.1 src/sys/arch/mips/include/asm.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/mips/include/asm.h
diff -u src/sys/arch/mips/include/asm.h:1.40 src/sys/arch/mips/include/asm.h:1.40.38.1
--- src/sys/arch/mips/include/asm.h:1.40 Wed Oct 17 19:55:36 2007
+++ src/sys/arch/mips/include/asm.h Sun Aug 16 02:52:43 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: asm.h,v 1.40 2007/10/17 19:55:36 garbled Exp $ */
+/* $NetBSD: asm.h,v 1.40.38.1 2009/08/16 02:52:43 matt Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -52,7 +52,7 @@
*/
#ifndef _MIPS_ASM_H
-#define _MIPS_ASM_H
+#define _MIPS_ASM_H
#include <machine/cdefs.h> /* for API selection */
#include <mips/regdef.h>
@@ -62,7 +62,7 @@
* Must always be noreorder, must never use a macro instruction
* Final addiu to t9 must always equal the size of this _KERN_MCOUNT
*/
-#define _KERN_MCOUNT \
+#define _KERN_MCOUNT \
.set push; \
.set noreorder; \
.set noat; \
@@ -79,7 +79,7 @@
.set pop;
#ifdef GPROF
-#define MCOUNT _KERN_MCOUNT
+#define MCOUNT _KERN_MCOUNT
#else
#define MCOUNT
#endif
@@ -95,10 +95,10 @@
#endif
#ifdef USE_AENT
-#define AENT(x) \
+#define AENT(x) \
.aent x, 0
#else
-#define AENT(x)
+#define AENT(x)
#endif
/*
@@ -110,7 +110,7 @@
/*
* STRONG_ALIAS: create a strong alias.
*/
-#define STRONG_ALIAS(alias,sym) \
+#define STRONG_ALIAS(alias,sym) \
.globl alias; \
alias = sym
@@ -132,7 +132,7 @@
* - never use any register that callee-saved (S0-S8), and
* - not use any local stack storage.
*/
-#define LEAF(x) \
+#define LEAF(x) \
.globl _C_LABEL(x); \
.ent _C_LABEL(x), 0; \
_C_LABEL(x): ; \
@@ -143,7 +143,7 @@
* LEAF_NOPROFILE
* No profilable leaf routine.
*/
-#define LEAF_NOPROFILE(x) \
+#define LEAF_NOPROFILE(x) \
.globl _C_LABEL(x); \
.ent _C_LABEL(x), 0; \
_C_LABEL(x): ; \
@@ -153,7 +153,7 @@
* STATIC_LEAF
* Declare a local leaf function.
*/
-#define STATIC_LEAF(x) \
+#define STATIC_LEAF(x) \
.ent _C_LABEL(x), 0; \
_C_LABEL(x): ; \
.frame sp, 0, ra; \
@@ -163,7 +163,7 @@
* XLEAF
* declare alternate entry to leaf routine
*/
-#define XLEAF(x) \
+#define XLEAF(x) \
.globl _C_LABEL(x); \
AENT (_C_LABEL(x)); \
_C_LABEL(x):
@@ -172,7 +172,7 @@
* STATIC_XLEAF
* declare alternate entry to a static leaf routine
*/
-#define STATIC_XLEAF(x) \
+#define STATIC_XLEAF(x) \
AENT (_C_LABEL(x)); \
_C_LABEL(x):
@@ -181,7 +181,7 @@
* A function calls other functions and needs
* therefore stack space to save/restore registers.
*/
-#define NESTED(x, fsize, retpc) \
+#define NESTED(x, fsize, retpc) \
.globl _C_LABEL(x); \
.ent _C_LABEL(x), 0; \
_C_LABEL(x): ; \
@@ -192,7 +192,7 @@
* NESTED_NOPROFILE(x)
* No profilable nested routine.
*/
-#define NESTED_NOPROFILE(x, fsize, retpc) \
+#define NESTED_NOPROFILE(x, fsize, retpc) \
.globl _C_LABEL(x); \
.ent _C_LABEL(x), 0; \
_C_LABEL(x): ; \
@@ -202,7 +202,7 @@
* XNESTED
* declare alternate entry point to nested routine.
*/
-#define XNESTED(x) \
+#define XNESTED(x) \
.globl _C_LABEL(x); \
AENT (_C_LABEL(x)); \
_C_LABEL(x):
@@ -211,19 +211,20 @@
* END
* Mark end of a procedure.
*/
-#define END(x) \
- .end _C_LABEL(x)
+#define END(x) \
+ .end _C_LABEL(x); \
+ .size _C_LABEL(x), . - _C_LABEL(x)
/*
* IMPORT -- import external symbol
*/
-#define IMPORT(sym, size) \
+#define IMPORT(sym, size) \
.extern _C_LABEL(sym),size
/*
* EXPORT -- export definition of symbol
*/
-#define EXPORT(x) \
+#define EXPORT(x) \
.globl _C_LABEL(x); \
_C_LABEL(x):
@@ -232,16 +233,16 @@
* exception vector entrypoint
* XXX: regmask should be used to generate .mask
*/
-#define VECTOR(x, regmask) \
+#define VECTOR(x, regmask) \
.ent _C_LABEL(x),0; \
EXPORT(x); \
#ifdef __STDC__
-#define VECTOR_END(x) \
+#define VECTOR_END(x) \
EXPORT(x ## End); \
END(x)
#else
-#define VECTOR_END(x) \
+#define VECTOR_END(x) \
EXPORT(x/**/End); \
END(x)
#endif
@@ -249,7 +250,7 @@
/*
* Macros to panic and printf from assembly language.
*/
-#define PANIC(msg) \
+#define PANIC(msg) \
la a0, 9f; \
jal _C_LABEL(panic); \
nop; \
@@ -266,28 +267,60 @@
9: .asciiz msg; \
.text
-#define ASMSTR(str) \
+#define ASMSTR(str) \
.asciiz str; \
.align 3
+#define RCSID(name) .pushsection ".ident"; .asciz name; .popsection
+
/*
* XXX retain dialects XXX
*/
-#define ALEAF(x) XLEAF(x)
-#define NLEAF(x) LEAF_NOPROFILE(x)
-#define NON_LEAF(x, fsize, retpc) NESTED(x, fsize, retpc)
-#define NNON_LEAF(x, fsize, retpc) NESTED_NOPROFILE(x, fsize, retpc)
+#define ALEAF(x) XLEAF(x)
+#define NLEAF(x) LEAF_NOPROFILE(x)
+#define NON_LEAF(x, fsize, retpc) NESTED(x, fsize, retpc)
+#define NNON_LEAF(x, fsize, retpc) NESTED_NOPROFILE(x, fsize, retpc)
+
+#if defined(__mips_o32)
+#define SZREG 4
+#else
+#define SZREG 8
+#endif
+
+#if defined(__mips_o32) || defined(__mips_o64)
+#define ALSK 7 /* stack alignment */
+#define ALMASK -7 /* stack alignment */
+#define SZFPREG 4
+#define FPLD lwc1
+#define FPST swc1
+#else
+#define ALSK 15 /* stack alignment */
+#define ALMASK -15 /* stack alignment */
+#define SZFPREG 8
+#define FPLD ldc1
+#define FPST sdc1
+#endif
/*
* standard callframe {
- * register_t cf_args[4]; arg0 - arg3
+ * register_t cf_pad[N]; o32 (N=2), n32/n64=(N=1)
+ * register_t cf_args[4]; arg0 - arg3 (only on o32 and o64)
+ * register_t cf_gp; global pointer (only on n32 and n64)
* register_t cf_sp; frame pointer
* register_t cf_ra; return address
* };
*/
-#define CALLFRAME_SIZ (4 * (4 + 2))
-#define CALLFRAME_SP (4 * 4)
-#define CALLFRAME_RA (4 * 5)
+#if defined(__mips_o32)
+#define CALLFRAME_SIZ (SZREG * (4 + 4))
+#elif defined(__mips_o64)
+#define CALLFRAME_SIZ (SZREG * (4 + 4))
+#elif defined(__mips_n32) || defined(__mips_n64)
+#define CALLFRAME_SIZ (SZREG * 4)
+#endif
+#define CALLFRAME_S0 (CALLFRAME_SIZ - 4 * SZREG)
+#define CALLFRAME_GP (CALLFRAME_SIZ - 3 * SZREG)
+#define CALLFRAME_SP (CALLFRAME_SIZ - 2 * SZREG)
+#define CALLFRAME_RA (CALLFRAME_SIZ - 1 * SZREG)
/*
* While it would be nice to be compatible with the SGI
@@ -298,22 +331,269 @@
* assembler to prevent the assembler from generating 64-bit style
* ABI calls.
*/
+#if defined(__mips_o32)
+#define PTR_ADD add
+#define PTR_ADDI addi
+#define PTR_ADDU addu
+#define PTR_ADDIU addiu
+#define PTR_SUB add
+#define PTR_SUBI subi
+#define PTR_SUBU subu
+#define PTR_SUBIU subu
+#define PTR_L lw
+#define PTR_LA la
+#define PTR_S sw
+#define PTR_SLL sll
+#define PTR_SLLV sllv
+#define PTR_SRL srl
+#define PTR_SRLV srlv
+#define PTR_SRA sra
+#define PTR_SRAV srav
+#define PTR_LL ll
+#define PTR_SC sc
+#define PTR_WORD .word
+#define PTR_SCALESHIFT 2
+#endif /* __mips_o32 */
+
+#if defined(__mips_n32)
+#define PTR_ADD add
+#define PTR_ADDI addi
+#define PTR_ADDU add /* no u */
+#define PTR_ADDIU addi /* no u */
+#define PTR_SUB sub
+#define PTR_SUBI subi
+#define PTR_SUBU sub /* no u */
+#define PTR_SUBIU sub /* no u */
+#define PTR_L lw
+#define PTR_LA la
+#define PTR_S sw
+#define PTR_SLL sll
+#define PTR_SLLV sllv
+#define PTR_SRL srl
+#define PTR_SRLV srlv
+#define PTR_SRA sra
+#define PTR_SRAV srav
+#define PTR_LL ll
+#define PTR_SC sc
+#define PTR_WORD .word
+#define PTR_SCALESHIFT 2
+#endif /* __mips_n32 */
+
+#if defined(__mips_n64) || defined(__mips_o64)
+#define PTR_ADD dadd
+#define PTR_ADDI daddi
+#define PTR_ADDU daddu
+#define PTR_ADDIU daddiu
+#define PTR_SUB dadd
+#define PTR_SUBI dsubi
+#define PTR_SUBU dsubu
+#define PTR_SUBIU dsubu
+#define PTR_L ld
+#define PTR_LA dla
+#define PTR_S sd
+#define PTR_SLL dsll
+#define PTR_SLLV dsllv
+#define PTR_SRL dsrl
+#define PTR_SRLV dsrlv
+#define PTR_SRA dsra
+#define PTR_SRAV dsrav
+#define PTR_LL lld
+#define PTR_SC scd
+#define PTR_WORD .dword
+#define PTR_SCALESHIFT 3
+#endif /* __mips_n64 || __mips_o64 */
+
+#if _MIPS_SZINT == 32
+#define INT_ADD add
+#define INT_ADDI addi
+#define INT_ADDU addu
+#define INT_ADDIU addiu
+#define INT_SUB add
+#define INT_SUBI subi
+#define INT_SUBU subu
+#define INT_SUBIU subu
+#define INT_L lw
+#define INT_LA la
+#define INT_S sw
+#define INT_SLL sll
+#define INT_SLLV sllv
+#define INT_SRL srl
+#define INT_SRLV srlv
+#define INT_SRA sra
+#define INT_SRAV srav
+#define INT_LL ll
+#define INT_SC sc
+#else
+#define INT_ADD dadd
+#define INT_ADDI daddi
+#define INT_ADDU daddu
+#define INT_ADDIU daddiu
+#define INT_SUB dadd
+#define INT_SUBI dsubi
+#define INT_SUBU dsubu
+#define INT_SUBIU dsubu
+#define INT_L ld
+#define INT_LA dla
+#define INT_S sd
+#define INT_SLL dsll
+#define INT_SLLV dsllv
+#define INT_SRL dsrl
+#define INT_SRLV dsrlv
+#define INT_SRA dsra
+#define INT_SRAV dsrav
+#define INT_LL lld
+#define INT_SC scd
+#endif
+
+#if _MIPS_SZLONG == 32
+#define LONG_ADD add
+#define LONG_ADDI addi
+#define LONG_ADDU addu
+#define LONG_ADDIU addiu
+#define LONG_SUB add
+#define LONG_SUBI subi
+#define LONG_SUBU subu
+#define LONG_SUBIU subu
+#define LONG_L lw
+#define LONG_LA la
+#define LONG_S sw
+#define LONG_SLL sll
+#define LONG_SLLV sllv
+#define LONG_SRL srl
+#define LONG_SRLV srlv
+#define LONG_SRA sra
+#define LONG_SRAV srav
+#define LONG_LL ll
+#define LONG_SC sc
+#else
+#define LONG_ADD dadd
+#define LONG_ADDI daddi
+#define LONG_ADDU daddu
+#define LONG_ADDIU daddiu
+#define LONG_SUB dadd
+#define LONG_SUBI dsubi
+#define LONG_SUBU dsubu
+#define LONG_SUBIU dsubu
+#define LONG_L ld
+#define LONG_LA dla
+#define LONG_S sd
+#define LONG_SLL dsll
+#define LONG_SLLV dsllv
+#define LONG_SRL dsrl
+#define LONG_SRLV dsrlv
+#define LONG_SRA dsra
+#define LONG_SRAV dsrav
+#define LONG_LL lld
+#define LONG_SC scd
+#endif
+
+#if SZREG == 4
+#define REG_L lw
+#define REG_S sw
+#define REG_LI li
+#define REG_SLL sll
+#define REG_SLLV sllv
+#define REG_SRL srl
+#define REG_SRLV srlv
+#define REG_SRA sra
+#define REG_SRAV srav
+#else
+#define REG_L ld
+#define REG_S sd
+#define REG_LI dli
+#define REG_SLL dsll
+#define REG_SLLV dsllv
+#define REG_SRL dsrl
+#define REG_SRLV dsrlv
+#define REG_SRA dsra
+#define REG_SRAV dsrav
+#endif
-#if !defined(_MIPS_BSD_API) || _MIPS_BSD_API == _MIPS_BSD_API_LP32
-#define REG_L lw
-#define REG_S sw
-#define REG_LI li
#define REG_PROLOGUE .set push
#define REG_EPILOGUE .set pop
-#define SZREG 4
+
+#if _MIPS_ISA == _MIPS_ISA_MIPS1 || _MIPS_ISA == _MIPS_ISA_MIPS2 || \
+ _MIPS_ISA == _MIPS_ISA_MIPS32 || _MIPS_ISA == _MIPS_ISA_MIPS32R2
+#define MFC0 mfc0
+#define MTC0 mtc0
+#endif
+#if _MIPS_ISA == _MIPS_ISA_MIPS3 || _MIPS_ISA == _MIPS_ISA_MIPS4 || \
+ _MIPS_ISA == _MIPS_ISA_MIPS5 || _MIPS_ISA == _MIPS_ISA_MIPS64 || \
+ _MIPS_ISA == _MIPS_ISA_MIPS64R2
+#define MFC0 dmfc0
+#define MTC0 dmtc0
+#endif
+
+#if defined(__mips_o32) || defined(__mips_o64)
+
+#ifdef __ABICALLS__
+#define CPRESTORE(r) .cprestore r
+#define CPLOAD(r) .cpload r
#else
-#define REG_L ld
-#define REG_S sd
-#define REG_LI dli
+#define CPRESTORE(r) /* not needed */
+#define CPLOAD(r) /* not needed */
+#endif
+
+#define SETUP_GP \
+ .set noreorder; \
+ .cpload t9; \
+ .set reorder
+#define SETUP_GPX(r) \
+ .set noreorder; \
+ move r,ra; /* save old ra */ \
+ bal 7f; \
+ nop; \
+ 7: .cpload ra; \
+ move ra,r; \
+ .set reorder
+#define SETUP_GPX_L(r,lbl) \
+ .set noreorder; \
+ move r,ra; /* save old ra */ \
+ bal lbl; \
+ nop; \
+ lbl: .cpload ra; \
+ move ra,r; \
+ .set reorder
+#define SAVE_GP(x) .cprestore x
+
+#define SETUP_GP64(a,b) /* n32/n64 specific */
+#define SETUP_GP64_R(a,b) /* n32/n64 specific */
+#define SETUP_GPX64(a,b) /* n32/n64 specific */
+#define SETUP_GPX64_L(a,b,c) /* n32/n64 specific */
+#define RESTORE_GP64 /* n32/n64 specific */
+#define USE_ALT_CP(a) /* n32/n64 specific */
+#endif /* __mips_o32 || __mips_o64 */
+
+#if defined(__mips_n32) || defined(__mips_n64)
#define REG_PROLOGUE .set push ; .set mips3
#define REG_EPILOGUE .set pop
-#define SZREG 8
-#endif /* _MIPS_BSD_API */
+#endif
+
+#if defined(__mips_n32) || defined(__mips_n64)
+#define SETUP_GP /* o32 specific */
+#define SETUP_GPX(r) /* o32 specific */
+#define SETUP_GPX_L(r,lbl) /* o32 specific */
+#define SAVE_GP(x) /* o32 specific */
+#define SETUP_GP64(a,b) .cpsetup $t9, a, b
+#define SETUP_GPX64(a,b) \
+ move b,ra; \
+ .set noreorder; \
+ bal 7f; \
+ nop; \
+ 7: .set reorder; \
+ .cpsetup ra, a, 7b; \
+ move ra,b
+#define SETUP_GPX64_L(a,b,c) \
+ move b,ra; \
+ .set noreorder; \
+ bal c; \
+ nop; \
+ c: .set reorder; \
+ .cpsetup ra, a, c; \
+ move ra,b
+#define RESTORE_GP64 .cpreturn
+#define USE_ALT_CP(a) .cplocal a
+#endif /* __mips_n32 || __mips_n64 */
/*
* The DYNAMIC_STATUS_MASK option adds an additional masking operation
@@ -326,21 +606,21 @@
* XXX this is only currently implemented for mips3.
*/
#ifdef MIPS_DYNAMIC_STATUS_MASK
-#define DYNAMIC_STATUS_MASK(sr,scratch) \
+#define DYNAMIC_STATUS_MASK(sr,scratch) \
lw scratch, mips_dynamic_status_mask; \
and sr, sr, scratch
-#define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1) \
+#define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1) \
ori sr, (MIPS_INT_MASK | MIPS_SR_INT_IE); \
DYNAMIC_STATUS_MASK(sr,scratch1)
#else
-#define DYNAMIC_STATUS_MASK(sr,scratch)
-#define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1)
+#define DYNAMIC_STATUS_MASK(sr,scratch)
+#define DYNAMIC_STATUS_MASK_TOUSER(sr,scratch1)
#endif
/* See lock_stubs.S. */
#define MIPS_LOCK_RAS_SIZE 128
-#define CPUVAR(off) _C_LABEL(cpu_info_store)+__CONCAT(CPU_INFO_,off)
+#define CPUVAR(off) _C_LABEL(cpu_info_store)+__CONCAT(CPU_INFO_,off)
#endif /* _MIPS_ASM_H */