Home | History | Annotate | Download | only in asm-mips
      1 /*
      2  * This file is subject to the terms and conditions of the GNU General Public
      3  * License.  See the file "COPYING" in the main directory of this archive
      4  * for more details.
      5  *
      6  * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
      7  * Copyright (C) 1999 by Silicon Graphics, Inc.
      8  * Copyright (C) 2001 MIPS Technologies, Inc.
      9  * Copyright (C) 2002  Maciej W. Rozycki
     10  *
     11  * Some useful macros for MIPS assembler code
     12  *
     13  * Some of the routines below contain useless nops that will be optimized
     14  * away by gas in -O mode. These nops are however required to fill delay
     15  * slots in noreorder mode.
     16  */
     17 #ifndef __ASM_ASM_H
     18 #define __ASM_ASM_H
     19 
     20 #include <asm/sgidefs.h>
     21 
     22 #ifndef CAT
     23 #ifdef __STDC__
     24 #define __CAT(str1, str2) str1##str2
     25 #else
     26 #define __CAT(str1, str2) str1/**/str2
     27 #endif
     28 #define CAT(str1, str2) __CAT(str1, str2)
     29 #endif
     30 
     31 /*
     32  * PIC specific declarations
     33  * Not used for the kernel but here seems to be the right place.
     34  */
     35 #ifdef __PIC__
     36 #define CPRESTORE(register)                             \
     37 		.cprestore register
     38 #define CPADD(register)                                 \
     39 		.cpadd	register
     40 #define CPLOAD(register)                                \
     41 		.cpload	register
     42 #else
     43 #define CPRESTORE(register)
     44 #define CPADD(register)
     45 #define CPLOAD(register)
     46 #endif
     47 
     48 /*
     49  * LEAF - declare leaf routine
     50  */
     51 #define	LEAF(symbol)                                    \
     52 		.globl	symbol;                         \
     53 		.align	2;                              \
     54 		.type	symbol, @function;              \
     55 		.ent	symbol, 0;                      \
     56 symbol:		.frame	sp, 0, ra
     57 
     58 /*
     59  * NESTED - declare nested routine entry point
     60  */
     61 #define	NESTED(symbol, framesize, rpc)                  \
     62 		.globl	symbol;                         \
     63 		.align	2;                              \
     64 		.type	symbol, @function;              \
     65 		.ent	symbol, 0;                       \
     66 symbol:		.frame	sp, framesize, rpc
     67 
     68 /*
     69  * END - mark end of function
     70  */
     71 #define	END(function)                                   \
     72 		.end	function;		        \
     73 		.size	function, .-function
     74 
     75 /*
     76  * EXPORT - export definition of symbol
     77  */
     78 #define EXPORT(symbol)					\
     79 		.globl	symbol;                         \
     80 symbol:
     81 
     82 /*
     83  * FEXPORT - export definition of a function symbol
     84  */
     85 #define FEXPORT(symbol)					\
     86 		.globl	symbol;				\
     87 		.type	symbol, @function;		\
     88 symbol:
     89 
     90 /*
     91  * ABS - export absolute symbol
     92  */
     93 #define	ABS(symbol,value)                               \
     94 		.globl	symbol;                         \
     95 symbol		=	value
     96 
     97 #define	PANIC(msg)                                      \
     98 		.set	push;				\
     99 		.set	reorder;                        \
    100 		PTR_LA	a0, 8f;                          \
    101 		jal	panic;                          \
    102 9:		b	9b;                             \
    103 		.set	pop;				\
    104 		TEXT(msg)
    105 
    106 /*
    107  * Print formatted string
    108  */
    109 #ifdef CONFIG_PRINTK
    110 #define PRINT(string)                                   \
    111 		.set	push;				\
    112 		.set	reorder;                        \
    113 		PTR_LA	a0, 8f;                          \
    114 		jal	printk;                         \
    115 		.set	pop;				\
    116 		TEXT(string)
    117 #else
    118 #define PRINT(string)
    119 #endif
    120 
    121 #define	TEXT(msg)                                       \
    122 		.pushsection .data;			\
    123 8:		.asciiz	msg;                            \
    124 		.popsection;
    125 
    126 /*
    127  * Build text tables
    128  */
    129 #define TTABLE(string)                                  \
    130 		.pushsection .text;			\
    131 		.word	1f;                             \
    132 		.popsection				\
    133 		.pushsection .data;			\
    134 1:		.asciiz	string;                         \
    135 		.popsection
    136 
    137 /*
    138  * MIPS IV pref instruction.
    139  * Use with .set noreorder only!
    140  *
    141  * MIPS IV implementations are free to treat this as a nop.  The R5000
    142  * is one of them.  So we should have an option not to use this instruction.
    143  */
    144 #ifdef CONFIG_CPU_HAS_PREFETCH
    145 
    146 #define PREF(hint,addr)                                 \
    147 		.set	push;				\
    148 		.set	mips4;				\
    149 		pref	hint, addr;			\
    150 		.set	pop
    151 
    152 #define PREFX(hint,addr)                                \
    153 		.set	push;				\
    154 		.set	mips4;				\
    155 		prefx	hint, addr;			\
    156 		.set	pop
    157 
    158 #else /* !CONFIG_CPU_HAS_PREFETCH */
    159 
    160 #define PREF(hint, addr)
    161 #define PREFX(hint, addr)
    162 
    163 #endif /* !CONFIG_CPU_HAS_PREFETCH */
    164 
    165 /*
    166  * MIPS ISA IV/V movn/movz instructions and equivalents for older CPUs.
    167  */
    168 #if (_MIPS_ISA == _MIPS_ISA_MIPS1)
    169 #define MOVN(rd, rs, rt)                                \
    170 		.set	push;				\
    171 		.set	reorder;			\
    172 		beqz	rt, 9f;                         \
    173 		move	rd, rs;                         \
    174 		.set	pop;				\
    175 9:
    176 #define MOVZ(rd, rs, rt)                                \
    177 		.set	push;				\
    178 		.set	reorder;			\
    179 		bnez	rt, 9f;                         \
    180 		move	rd, rs;                         \
    181 		.set	pop;				\
    182 9:
    183 #endif /* _MIPS_ISA == _MIPS_ISA_MIPS1 */
    184 #if (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3)
    185 #define MOVN(rd, rs, rt)                                \
    186 		.set	push;				\
    187 		.set	noreorder;			\
    188 		bnezl	rt, 9f;                         \
    189 		 move	rd, rs;                         \
    190 		.set	pop;				\
    191 9:
    192 #define MOVZ(rd, rs, rt)                                \
    193 		.set	push;				\
    194 		.set	noreorder;			\
    195 		beqzl	rt, 9f;                         \
    196 		 move	rd, rs;                         \
    197 		.set	pop;				\
    198 9:
    199 #endif /* (_MIPS_ISA == _MIPS_ISA_MIPS2) || (_MIPS_ISA == _MIPS_ISA_MIPS3) */
    200 #if (_MIPS_ISA == _MIPS_ISA_MIPS4 ) || (_MIPS_ISA == _MIPS_ISA_MIPS5) || \
    201     (_MIPS_ISA == _MIPS_ISA_MIPS32) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
    202 #define MOVN(rd, rs, rt)                                \
    203 		movn	rd, rs, rt
    204 #define MOVZ(rd, rs, rt)                                \
    205 		movz	rd, rs, rt
    206 #endif /* MIPS IV, MIPS V, MIPS32 or MIPS64 */
    207 
    208 /*
    209  * Stack alignment
    210  */
    211 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
    212 #define ALSZ	7
    213 #define ALMASK	~7
    214 #endif
    215 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
    216 #define ALSZ	15
    217 #define ALMASK	~15
    218 #endif
    219 
    220 /*
    221  * Macros to handle different pointer/register sizes for 32/64-bit code
    222  */
    223 
    224 /*
    225  * Size of a register
    226  */
    227 #ifdef __mips64
    228 #define SZREG	8
    229 #else
    230 #define SZREG	4
    231 #endif
    232 
    233 /*
    234  * Use the following macros in assemblercode to load/store registers,
    235  * pointers etc.
    236  */
    237 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
    238 #define REG_S		sw
    239 #define REG_L		lw
    240 #define REG_SUBU	subu
    241 #define REG_ADDU	addu
    242 #endif
    243 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
    244 #define REG_S		sd
    245 #define REG_L		ld
    246 #define REG_SUBU	dsubu
    247 #define REG_ADDU	daddu
    248 #endif
    249 
    250 /*
    251  * How to add/sub/load/store/shift C int variables.
    252  */
    253 #if (_MIPS_SZINT == 32)
    254 #define INT_ADD		add
    255 #define INT_ADDU	addu
    256 #define INT_ADDI	addi
    257 #define INT_ADDIU	addiu
    258 #define INT_SUB		sub
    259 #define INT_SUBU	subu
    260 #define INT_L		lw
    261 #define INT_S		sw
    262 #define INT_SLL		sll
    263 #define INT_SLLV	sllv
    264 #define INT_SRL		srl
    265 #define INT_SRLV	srlv
    266 #define INT_SRA		sra
    267 #define INT_SRAV	srav
    268 #endif
    269 
    270 #if (_MIPS_SZINT == 64)
    271 #define INT_ADD		dadd
    272 #define INT_ADDU	daddu
    273 #define INT_ADDI	daddi
    274 #define INT_ADDIU	daddiu
    275 #define INT_SUB		dsub
    276 #define INT_SUBU	dsubu
    277 #define INT_L		ld
    278 #define INT_S		sd
    279 #define INT_SLL		dsll
    280 #define INT_SLLV	dsllv
    281 #define INT_SRL		dsrl
    282 #define INT_SRLV	dsrlv
    283 #define INT_SRA		dsra
    284 #define INT_SRAV	dsrav
    285 #endif
    286 
    287 /*
    288  * How to add/sub/load/store/shift C long variables.
    289  */
    290 #if (_MIPS_SZLONG == 32)
    291 #define LONG_ADD	add
    292 #define LONG_ADDU	addu
    293 #define LONG_ADDI	addi
    294 #define LONG_ADDIU	addiu
    295 #define LONG_SUB	sub
    296 #define LONG_SUBU	subu
    297 #define LONG_L		lw
    298 #define LONG_S		sw
    299 #define LONG_SLL	sll
    300 #define LONG_SLLV	sllv
    301 #define LONG_SRL	srl
    302 #define LONG_SRLV	srlv
    303 #define LONG_SRA	sra
    304 #define LONG_SRAV	srav
    305 
    306 #define LONG		.word
    307 #define LONGSIZE	4
    308 #define LONGMASK	3
    309 #define LONGLOG		2
    310 #endif
    311 
    312 #if (_MIPS_SZLONG == 64)
    313 #define LONG_ADD	dadd
    314 #define LONG_ADDU	daddu
    315 #define LONG_ADDI	daddi
    316 #define LONG_ADDIU	daddiu
    317 #define LONG_SUB	dsub
    318 #define LONG_SUBU	dsubu
    319 #define LONG_L		ld
    320 #define LONG_S		sd
    321 #define LONG_SLL	dsll
    322 #define LONG_SLLV	dsllv
    323 #define LONG_SRL	dsrl
    324 #define LONG_SRLV	dsrlv
    325 #define LONG_SRA	dsra
    326 #define LONG_SRAV	dsrav
    327 
    328 #define LONG		.dword
    329 #define LONGSIZE	8
    330 #define LONGMASK	7
    331 #define LONGLOG		3
    332 #endif
    333 
    334 /*
    335  * How to add/sub/load/store/shift pointers.
    336  */
    337 #if (_MIPS_SZPTR == 32)
    338 #define PTR_ADD		add
    339 #define PTR_ADDU	addu
    340 #define PTR_ADDI	addi
    341 #define PTR_ADDIU	addiu
    342 #define PTR_SUB		sub
    343 #define PTR_SUBU	subu
    344 #define PTR_L		lw
    345 #define PTR_S		sw
    346 #define PTR_LA		la
    347 #define PTR_LI		li
    348 #define PTR_SLL		sll
    349 #define PTR_SLLV	sllv
    350 #define PTR_SRL		srl
    351 #define PTR_SRLV	srlv
    352 #define PTR_SRA		sra
    353 #define PTR_SRAV	srav
    354 
    355 #define PTR_SCALESHIFT	2
    356 
    357 #define PTR		.word
    358 #define PTRSIZE		4
    359 #define PTRLOG		2
    360 #endif
    361 
    362 #if (_MIPS_SZPTR == 64)
    363 #define PTR_ADD		dadd
    364 #define PTR_ADDU	daddu
    365 #define PTR_ADDI	daddi
    366 #define PTR_ADDIU	daddiu
    367 #define PTR_SUB		dsub
    368 #define PTR_SUBU	dsubu
    369 #define PTR_L		ld
    370 #define PTR_S		sd
    371 #define PTR_LA		dla
    372 #define PTR_LI		dli
    373 #define PTR_SLL		dsll
    374 #define PTR_SLLV	dsllv
    375 #define PTR_SRL		dsrl
    376 #define PTR_SRLV	dsrlv
    377 #define PTR_SRA		dsra
    378 #define PTR_SRAV	dsrav
    379 
    380 #define PTR_SCALESHIFT	3
    381 
    382 #define PTR		.dword
    383 #define PTRSIZE		8
    384 #define PTRLOG		3
    385 #endif
    386 
    387 /*
    388  * Some cp0 registers were extended to 64bit for MIPS III.
    389  */
    390 #if (_MIPS_SIM == _MIPS_SIM_ABI32)
    391 #define MFC0		mfc0
    392 #define MTC0		mtc0
    393 #endif
    394 #if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
    395 #define MFC0		dmfc0
    396 #define MTC0		dmtc0
    397 #endif
    398 
    399 #define SSNOP		sll zero, zero, 1
    400 
    401 #ifdef CONFIG_SGI_IP28
    402 /* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
    403 #include <asm/cacheops.h>
    404 #define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
    405 #else
    406 #define R10KCBARRIER(addr)
    407 #endif
    408 
    409 #endif /* __ASM_ASM_H */
    410