diff options
Diffstat (limited to 'arch/mips/include/asm/asm.h')
| -rw-r--r-- | arch/mips/include/asm/asm.h | 409 | 
1 files changed, 409 insertions, 0 deletions
| diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h new file mode 100644 index 000000000..608cfcfbb --- /dev/null +++ b/arch/mips/include/asm/asm.h @@ -0,0 +1,409 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License.  See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle + * Copyright (C) 1999 by Silicon Graphics, Inc. + * Copyright (C) 2001 MIPS Technologies, Inc. + * Copyright (C) 2002  Maciej W. Rozycki + * + * Some useful macros for MIPS assembler code + * + * Some of the routines below contain useless nops that will be optimized + * away by gas in -O mode. These nops are however required to fill delay + * slots in noreorder mode. + */ +#ifndef __ASM_ASM_H +#define __ASM_ASM_H + +#include <asm/sgidefs.h> + +#ifndef CAT +#ifdef __STDC__ +#define __CAT(str1, str2) str1##str2 +#else +#define __CAT(str1, str2) str1/**/str2 +#endif +#define CAT(str1, str2) __CAT(str1, str2) +#endif + +/* + * PIC specific declarations + * Not used for the kernel but here seems to be the right place. + */ +#ifdef __PIC__ +#define CPRESTORE(register)                             \ +		.cprestore register +#define CPADD(register)                                 \ +		.cpadd	register +#define CPLOAD(register)                                \ +		.cpload	register +#else +#define CPRESTORE(register) +#define CPADD(register) +#define CPLOAD(register) +#endif + +/* + * LEAF - declare leaf routine + */ +#define	LEAF(symbol)                                    \ +		.globl	symbol;                         \ +		.align	2;                              \ +		.type	symbol, @function;              \ +		.ent	symbol, 0;                      \ +symbol:		.frame	sp, 0, ra + +/* + * NESTED - declare nested routine entry point + */ +#define	NESTED(symbol, framesize, rpc)                  \ +		.globl	symbol;                         \ +		.align	2;                              \ +		.type	symbol, @function;              \ +		.ent	symbol, 0;                       \ +symbol:		.frame	sp, framesize, rpc + +/* + * END - mark end of function + */ +#define	END(function)                                   \ +		.end	function;		        \ +		.size	function, .-function + +/* + * EXPORT - export definition of symbol + */ +#define EXPORT(symbol)					\ +		.globl	symbol;                         \ +symbol: + +/* + * FEXPORT - export definition of a function symbol + */ +#define FEXPORT(symbol)					\ +		.globl	symbol;				\ +		.type	symbol, @function;		\ +symbol: + +/* + * ABS - export absolute symbol + */ +#define	ABS(symbol,value)                               \ +		.globl	symbol;                         \ +symbol		=	value + +#define	PANIC(msg)                                      \ +		.set	push;				\ +		.set	reorder;                        \ +		PTR_LA	a0, 8f;                          \ +		jal	panic;                          \ +9:		b	9b;                             \ +		.set	pop;				\ +		TEXT(msg) + +/* + * Print formatted string + */ +#ifdef CONFIG_PRINTK +#define PRINT(string)                                   \ +		.set	push;				\ +		.set	reorder;                        \ +		PTR_LA	a0, 8f;                          \ +		jal	printk;                         \ +		.set	pop;				\ +		TEXT(string) +#else +#define PRINT(string) +#endif + +#define	TEXT(msg)                                       \ +		.pushsection .data;			\ +8:		.asciiz	msg;                            \ +		.popsection; + +/* + * Build text tables + */ +#define TTABLE(string)                                  \ +		.pushsection .text;			\ +		.word	1f;                             \ +		.popsection				\ +		.pushsection .data;			\ +1:		.asciiz	string;                         \ +		.popsection + +/* + * MIPS IV pref instruction. + * Use with .set noreorder only! + * + * MIPS IV implementations are free to treat this as a nop.  The R5000 + * is one of them.  So we should have an option not to use this instruction. + */ +#ifdef CONFIG_CPU_HAS_PREFETCH + +#define PREF(hint,addr)                                 \ +		.set	push;				\ +		.set	mips4;				\ +		pref	hint, addr;			\ +		.set	pop + +#define PREFX(hint,addr)                                \ +		.set	push;				\ +		.set	mips4;				\ +		prefx	hint, addr;			\ +		.set	pop + +#else /* !CONFIG_CPU_HAS_PREFETCH */ + +#define PREF(hint, addr) +#define PREFX(hint, addr) + +#endif /* !CONFIG_CPU_HAS_PREFETCH */ + +/* + * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs. + */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS1) +#define MOVN(rd, rs, rt)                                \ +		.set	push;				\ +		.set	reorder;			\ +		beqz	rt, 9f;                         \ +		move	rd, rs;                         \ +		.set	pop;				\ +9: +#define MOVZ(rd, rs, rt)                                \ +		.set	push;				\ +		.set	reorder;			\ +		bnez	rt, 9f;                         \ +		move	rd, rs;                         \ +		.set	pop;				\ +9: +#endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) +#define MOVN(rd, rs, rt)                                \ +		.set	push;				\ +		.set	noreorder;			\ +		bnezl	rt, 9f;                         \ +		 move	rd, rs;                         \ +		.set	pop;				\ +9: +#define MOVZ(rd, rs, rt)                                \ +		.set	push;				\ +		.set	noreorder;			\ +		beqzl	rt, 9f;                         \ +		 move	rd, rs;                         \ +		.set	pop;				\ +9: +#endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */ +#if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \ +    (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64) +#define MOVN(rd, rs, rt)                                \ +		movn	rd, rs, rt +#define MOVZ(rd, rs, rt)                                \ +		movz	rd, rs, rt +#endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */ + +/* + * Stack alignment + */ +#if (_MIPS_SIM == _MIPS_SIM_ABI32) +#define ALSZ	7 +#define ALMASK	~7 +#endif +#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) +#define ALSZ	15 +#define ALMASK	~15 +#endif + +/* + * Macros to handle different pointer/register sizes for 32/64-bit code + */ + +/* + * Size of a register + */ +#ifdef __mips64 +#define SZREG	8 +#else +#define SZREG	4 +#endif + +/* + * Use the following macros in assemblercode to load/store registers, + * pointers etc. + */ +#if (_MIPS_SIM == _MIPS_SIM_ABI32) +#define REG_S		sw +#define REG_L		lw +#define REG_SUBU	subu +#define REG_ADDU	addu +#endif +#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) +#define REG_S		sd +#define REG_L		ld +#define REG_SUBU	dsubu +#define REG_ADDU	daddu +#endif + +/* + * How to add/sub/load/store/shift C int variables. + */ +#if (_MIPS_SZINT == 32) +#define INT_ADD		add +#define INT_ADDU	addu +#define INT_ADDI	addi +#define INT_ADDIU	addiu +#define INT_SUB		sub +#define INT_SUBU	subu +#define INT_L		lw +#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 +#endif + +#if (_MIPS_SZINT == 64) +#define INT_ADD		dadd +#define INT_ADDU	daddu +#define INT_ADDI	daddi +#define INT_ADDIU	daddiu +#define INT_SUB		dsub +#define INT_SUBU	dsubu +#define INT_L		ld +#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 +#endif + +/* + * How to add/sub/load/store/shift C long variables. + */ +#if (_MIPS_SZLONG == 32) +#define LONG_ADD	add +#define LONG_ADDU	addu +#define LONG_ADDI	addi +#define LONG_ADDIU	addiu +#define LONG_SUB	sub +#define LONG_SUBU	subu +#define LONG_L		lw +#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		.word +#define LONGSIZE	4 +#define LONGMASK	3 +#define LONGLOG		2 +#endif + +#if (_MIPS_SZLONG == 64) +#define LONG_ADD	dadd +#define LONG_ADDU	daddu +#define LONG_ADDI	daddi +#define LONG_ADDIU	daddiu +#define LONG_SUB	dsub +#define LONG_SUBU	dsubu +#define LONG_L		ld +#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		.dword +#define LONGSIZE	8 +#define LONGMASK	7 +#define LONGLOG		3 +#endif + +/* + * How to add/sub/load/store/shift pointers. + */ +#if (_MIPS_SZPTR == 32) +#define PTR_ADD		add +#define PTR_ADDU	addu +#define PTR_ADDI	addi +#define PTR_ADDIU	addiu +#define PTR_SUB		sub +#define PTR_SUBU	subu +#define PTR_L		lw +#define PTR_S		sw +#define PTR_LA		la +#define PTR_LI		li +#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_SCALESHIFT	2 + +#define PTR		.word +#define PTRSIZE		4 +#define PTRLOG		2 +#endif + +#if (_MIPS_SZPTR == 64) +#define PTR_ADD		dadd +#define PTR_ADDU	daddu +#define PTR_ADDI	daddi +#define PTR_ADDIU	daddiu +#define PTR_SUB		dsub +#define PTR_SUBU	dsubu +#define PTR_L		ld +#define PTR_S		sd +#define PTR_LA		dla +#define PTR_LI		dli +#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_SCALESHIFT	3 + +#define PTR		.dword +#define PTRSIZE		8 +#define PTRLOG		3 +#endif + +/* + * Some cp0 registers were extended to 64bit for MIPS III. + */ +#if (_MIPS_SIM == _MIPS_SIM_ABI32) +#define MFC0		mfc0 +#define MTC0		mtc0 +#endif +#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) +#define MFC0		dmfc0 +#define MTC0		dmtc0 +#endif + +#define SSNOP		sll zero, zero, 1 + +#ifdef CONFIG_SGI_IP28 +/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */ +#include <asm/cacheops.h> +#define R10KCBARRIER(addr)  cache   Cache_Barrier, addr; +#else +#define R10KCBARRIER(addr) +#endif + +#endif /* __ASM_ASM_H */ |