2005-04-17 02:20:36 +04:00
/*
* 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>
2013-12-04 17:56:03 +04:00
# include <asm/asm-eva.h>
2005-04-17 02:20:36 +04:00
# ifndef CAT
# ifdef __STDC__
2007-10-12 02:46:15 +04:00
# define __CAT(str1, str2) str1##str2
2005-04-17 02:20:36 +04:00
# else
2007-10-12 02:46:15 +04:00
# define __CAT(str1, str2) str1 /**/ str2
2005-04-17 02:20:36 +04:00
# endif
2007-10-12 02:46:15 +04:00
# define CAT(str1, str2) __CAT(str1, str2)
2005-04-17 02:20:36 +04:00
# endif
/*
* PIC specific declarations
* Not used for the kernel but here seems to be the right place .
*/
# ifdef __PIC__
2013-01-22 15:59:30 +04:00
# define CPRESTORE(register) \
2005-04-17 02:20:36 +04:00
. cprestore register
2013-01-22 15:59:30 +04:00
# define CPADD(register) \
2005-04-17 02:20:36 +04:00
. cpadd register
2013-01-22 15:59:30 +04:00
# define CPLOAD(register) \
. cpload register
2005-04-17 02:20:36 +04:00
# else
# define CPRESTORE(register)
# define CPADD(register)
# define CPLOAD(register)
# endif
/*
* LEAF - declare leaf routine
*/
2013-01-22 15:59:30 +04:00
# define LEAF(symbol) \
. globl symbol ; \
. align 2 ; \
. type symbol , @ function ; \
. ent symbol , 0 ; \
2007-10-12 02:46:15 +04:00
symbol : . frame sp , 0 , ra
2005-04-17 02:20:36 +04:00
/*
* NESTED - declare nested routine entry point
*/
2013-01-22 15:59:30 +04:00
# define NESTED(symbol, framesize, rpc) \
. globl symbol ; \
. align 2 ; \
. type symbol , @ function ; \
. ent symbol , 0 ; \
2005-04-17 02:20:36 +04:00
symbol : . frame sp , framesize , rpc
/*
* END - mark end of function
*/
2013-01-22 15:59:30 +04:00
# define END(function) \
. end function ; \
2007-10-12 02:46:15 +04:00
. size function , . - function
2005-04-17 02:20:36 +04:00
/*
* EXPORT - export definition of symbol
*/
# define EXPORT(symbol) \
2013-01-22 15:59:30 +04:00
. globl symbol ; \
2005-04-17 02:20:36 +04:00
symbol :
/*
* FEXPORT - export definition of a function symbol
*/
# define FEXPORT(symbol) \
. globl symbol ; \
2007-10-12 02:46:15 +04:00
. type symbol , @ function ; \
2005-04-17 02:20:36 +04:00
symbol :
/*
* ABS - export absolute symbol
*/
2013-01-22 15:59:30 +04:00
# define ABS(symbol,value) \
. globl symbol ; \
2005-04-17 02:20:36 +04:00
symbol = value
2013-01-22 15:59:30 +04:00
# define PANIC(msg) \
2005-04-17 02:20:36 +04:00
. set push ; \
2013-01-22 15:59:30 +04:00
. set reorder ; \
PTR_LA a0 , 8f ; \
jal panic ; \
9 : b 9 b ; \
2005-04-17 02:20:36 +04:00
. set pop ; \
TEXT ( msg )
/*
* Print formatted string
*/
2005-06-01 16:18:30 +04:00
# ifdef CONFIG_PRINTK
2013-01-22 15:59:30 +04:00
# define PRINT(string) \
2005-04-17 02:20:36 +04:00
. set push ; \
2013-01-22 15:59:30 +04:00
. set reorder ; \
PTR_LA a0 , 8f ; \
jal printk ; \
2005-04-17 02:20:36 +04:00
. set pop ; \
TEXT ( string )
2005-06-01 16:18:30 +04:00
# else
# define PRINT(string)
# endif
2005-04-17 02:20:36 +04:00
2013-01-22 15:59:30 +04:00
# define TEXT(msg) \
2005-04-17 02:20:36 +04:00
. pushsection . data ; \
2013-01-22 15:59:30 +04:00
8 : . asciiz msg ; \
2005-04-17 02:20:36 +04:00
. popsection ;
/*
* Build text tables
*/
2013-01-22 15:59:30 +04:00
# define TTABLE(string) \
2005-04-17 02:20:36 +04:00
. pushsection . text ; \
2013-01-22 15:59:30 +04:00
. word 1f ; \
2005-04-17 02:20:36 +04:00
. popsection \
. pushsection . data ; \
2013-01-22 15:59:30 +04:00
1 : . asciiz string ; \
2005-04-17 02:20:36 +04:00
. 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
2013-01-22 15:59:30 +04:00
# define PREF(hint,addr) \
2005-04-17 02:20:36 +04:00
. set push ; \
2014-03-30 15:20:10 +04:00
. set arch = r5000 ; \
2007-10-12 02:46:15 +04:00
pref hint , addr ; \
2005-04-17 02:20:36 +04:00
. set pop
2013-12-03 14:48:15 +04:00
# define PREFE(hint, addr) \
. set push ; \
. set mips0 ; \
. set eva ; \
prefe hint , addr ; \
. set pop
2013-01-22 15:59:30 +04:00
# define PREFX(hint,addr) \
2005-04-17 02:20:36 +04:00
. set push ; \
2014-03-30 15:20:10 +04:00
. set arch = r5000 ; \
2007-10-12 02:46:15 +04:00
prefx hint , addr ; \
2005-04-17 02:20:36 +04:00
. set pop
# else /* !CONFIG_CPU_HAS_PREFETCH */
2007-10-12 02:46:15 +04:00
# define PREF(hint, addr)
2013-12-03 14:48:15 +04:00
# define PREFE(hint, addr)
2007-10-12 02:46:15 +04:00
# define PREFX(hint, addr)
2005-04-17 02:20:36 +04:00
# endif /* !CONFIG_CPU_HAS_PREFETCH */
/*
* MIPS ISA IV / V movn / movz instructions and equivalents for older CPUs .
*/
# if (_MIPS_ISA == _MIPS_ISA_MIPS1)
2013-01-22 15:59:30 +04:00
# define MOVN(rd, rs, rt) \
2005-04-17 02:20:36 +04:00
. set push ; \
. set reorder ; \
2013-01-22 15:59:30 +04:00
beqz rt , 9f ; \
move rd , rs ; \
2005-04-17 02:20:36 +04:00
. set pop ; \
9 :
2013-01-22 15:59:30 +04:00
# define MOVZ(rd, rs, rt) \
2005-04-17 02:20:36 +04:00
. set push ; \
. set reorder ; \
2013-01-22 15:59:30 +04:00
bnez rt , 9f ; \
move rd , rs ; \
2005-04-17 02:20:36 +04:00
. set pop ; \
9 :
# endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
# if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
2013-01-22 15:59:30 +04:00
# define MOVN(rd, rs, rt) \
2005-04-17 02:20:36 +04:00
. set push ; \
. set noreorder ; \
2013-01-22 15:59:30 +04:00
bnezl rt , 9f ; \
move rd , rs ; \
2005-04-17 02:20:36 +04:00
. set pop ; \
9 :
2013-01-22 15:59:30 +04:00
# define MOVZ(rd, rs, rt) \
2005-04-17 02:20:36 +04:00
. set push ; \
. set noreorder ; \
2013-01-22 15:59:30 +04:00
beqzl rt , 9f ; \
move rd , rs ; \
2005-04-17 02:20:36 +04:00
. 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 )
2013-01-22 15:59:30 +04:00
# define MOVN(rd, rs, rt) \
2007-10-12 02:46:15 +04:00
movn rd , rs , rt
2013-01-22 15:59:30 +04:00
# define MOVZ(rd, rs, rt) \
2007-10-12 02:46:15 +04:00
movz rd , rs , rt
2005-04-17 02:20:36 +04:00
# 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
2013-03-25 22:40:49 +04:00
# define LONG_SP swp
2005-04-17 02:20:36 +04:00
# 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
2013-03-25 22:40:49 +04:00
# define LONG_SP sdp
2005-04-17 02:20:36 +04:00
# 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
2006-10-24 05:29:01 +04:00
# define PTR_LI li
2005-04-17 02:20:36 +04:00
# 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
2006-10-24 05:29:01 +04:00
# define PTR_LI dli
2005-04-17 02:20:36 +04:00
# 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 64 bit 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
2007-10-12 02:46:15 +04:00
# define SSNOP sll zero, zero, 1
2005-04-17 02:20:36 +04:00
2007-11-25 13:47:56 +03:00
# 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
2005-04-17 02:20:36 +04:00
# endif /* __ASM_ASM_H */