xref: /kernel/linux/linux-5.10/arch/mips/include/asm/asm.h (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
38c2ecf20Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
48c2ecf20Sopenharmony_ci * for more details.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
78c2ecf20Sopenharmony_ci * Copyright (C) 1999 by Silicon Graphics, Inc.
88c2ecf20Sopenharmony_ci * Copyright (C) 2001 MIPS Technologies, Inc.
98c2ecf20Sopenharmony_ci * Copyright (C) 2002  Maciej W. Rozycki
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * Some useful macros for MIPS assembler code
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * Some of the routines below contain useless nops that will be optimized
148c2ecf20Sopenharmony_ci * away by gas in -O mode. These nops are however required to fill delay
158c2ecf20Sopenharmony_ci * slots in noreorder mode.
168c2ecf20Sopenharmony_ci */
178c2ecf20Sopenharmony_ci#ifndef __ASM_ASM_H
188c2ecf20Sopenharmony_ci#define __ASM_ASM_H
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <asm/sgidefs.h>
218c2ecf20Sopenharmony_ci#include <asm/asm-eva.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#ifndef __VDSO__
248c2ecf20Sopenharmony_ci/*
258c2ecf20Sopenharmony_ci * Emit CFI data in .debug_frame sections, not .eh_frame sections.
268c2ecf20Sopenharmony_ci * We don't do DWARF unwinding at runtime, so only the offline DWARF
278c2ecf20Sopenharmony_ci * information is useful to anyone. Note we should change this if we
288c2ecf20Sopenharmony_ci * ever decide to enable DWARF unwinding at runtime.
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_ci#define CFI_SECTIONS	.cfi_sections .debug_frame
318c2ecf20Sopenharmony_ci#else
328c2ecf20Sopenharmony_ci /*
338c2ecf20Sopenharmony_ci  * For the vDSO, emit both runtime unwind information and debug
348c2ecf20Sopenharmony_ci  * symbols for the .dbg file.
358c2ecf20Sopenharmony_ci  */
368c2ecf20Sopenharmony_ci#define CFI_SECTIONS
378c2ecf20Sopenharmony_ci#endif
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci/*
408c2ecf20Sopenharmony_ci * LEAF - declare leaf routine
418c2ecf20Sopenharmony_ci */
428c2ecf20Sopenharmony_ci#define LEAF(symbol)					\
438c2ecf20Sopenharmony_ci		CFI_SECTIONS;				\
448c2ecf20Sopenharmony_ci		.globl	symbol;				\
458c2ecf20Sopenharmony_ci		.align	2;				\
468c2ecf20Sopenharmony_ci		.type	symbol, @function;		\
478c2ecf20Sopenharmony_ci		.ent	symbol, 0;			\
488c2ecf20Sopenharmony_cisymbol:		.frame	sp, 0, ra;			\
498c2ecf20Sopenharmony_ci		.cfi_startproc;				\
508c2ecf20Sopenharmony_ci		.insn
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/*
538c2ecf20Sopenharmony_ci * NESTED - declare nested routine entry point
548c2ecf20Sopenharmony_ci */
558c2ecf20Sopenharmony_ci#define NESTED(symbol, framesize, rpc)			\
568c2ecf20Sopenharmony_ci		CFI_SECTIONS;				\
578c2ecf20Sopenharmony_ci		.globl	symbol;				\
588c2ecf20Sopenharmony_ci		.align	2;				\
598c2ecf20Sopenharmony_ci		.type	symbol, @function;		\
608c2ecf20Sopenharmony_ci		.ent	symbol, 0;			\
618c2ecf20Sopenharmony_cisymbol:		.frame	sp, framesize, rpc;		\
628c2ecf20Sopenharmony_ci		.cfi_startproc;				\
638c2ecf20Sopenharmony_ci		.insn
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci/*
668c2ecf20Sopenharmony_ci * END - mark end of function
678c2ecf20Sopenharmony_ci */
688c2ecf20Sopenharmony_ci#define END(function)					\
698c2ecf20Sopenharmony_ci		.cfi_endproc;				\
708c2ecf20Sopenharmony_ci		.end	function;			\
718c2ecf20Sopenharmony_ci		.size	function, .-function
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/*
748c2ecf20Sopenharmony_ci * EXPORT - export definition of symbol
758c2ecf20Sopenharmony_ci */
768c2ecf20Sopenharmony_ci#define EXPORT(symbol)					\
778c2ecf20Sopenharmony_ci		.globl	symbol;				\
788c2ecf20Sopenharmony_cisymbol:
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci/*
818c2ecf20Sopenharmony_ci * FEXPORT - export definition of a function symbol
828c2ecf20Sopenharmony_ci */
838c2ecf20Sopenharmony_ci#define FEXPORT(symbol)					\
848c2ecf20Sopenharmony_ci		.globl	symbol;				\
858c2ecf20Sopenharmony_ci		.type	symbol, @function;		\
868c2ecf20Sopenharmony_cisymbol:		.insn
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci/*
898c2ecf20Sopenharmony_ci * ABS - export absolute symbol
908c2ecf20Sopenharmony_ci */
918c2ecf20Sopenharmony_ci#define ABS(symbol,value)				\
928c2ecf20Sopenharmony_ci		.globl	symbol;				\
938c2ecf20Sopenharmony_cisymbol		=	value
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci#define TEXT(msg)					\
968c2ecf20Sopenharmony_ci		.pushsection .data;			\
978c2ecf20Sopenharmony_ci8:		.asciiz msg;				\
988c2ecf20Sopenharmony_ci		.popsection;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci#define ASM_PANIC(msg)					\
1018c2ecf20Sopenharmony_ci		.set	push;				\
1028c2ecf20Sopenharmony_ci		.set	reorder;			\
1038c2ecf20Sopenharmony_ci		PTR_LA	a0, 8f;				\
1048c2ecf20Sopenharmony_ci		jal	panic;				\
1058c2ecf20Sopenharmony_ci9:		b	9b;				\
1068c2ecf20Sopenharmony_ci		.set	pop;				\
1078c2ecf20Sopenharmony_ci		TEXT(msg)
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci/*
1108c2ecf20Sopenharmony_ci * Print formatted string
1118c2ecf20Sopenharmony_ci */
1128c2ecf20Sopenharmony_ci#ifdef CONFIG_PRINTK
1138c2ecf20Sopenharmony_ci#define ASM_PRINT(string)				\
1148c2ecf20Sopenharmony_ci		.set	push;				\
1158c2ecf20Sopenharmony_ci		.set	reorder;			\
1168c2ecf20Sopenharmony_ci		PTR_LA	a0, 8f;				\
1178c2ecf20Sopenharmony_ci		jal	printk;				\
1188c2ecf20Sopenharmony_ci		.set	pop;				\
1198c2ecf20Sopenharmony_ci		TEXT(string)
1208c2ecf20Sopenharmony_ci#else
1218c2ecf20Sopenharmony_ci#define ASM_PRINT(string)
1228c2ecf20Sopenharmony_ci#endif
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci/*
1258c2ecf20Sopenharmony_ci * Stack alignment
1268c2ecf20Sopenharmony_ci */
1278c2ecf20Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_ABI32)
1288c2ecf20Sopenharmony_ci#define ALSZ	7
1298c2ecf20Sopenharmony_ci#define ALMASK	~7
1308c2ecf20Sopenharmony_ci#endif
1318c2ecf20Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
1328c2ecf20Sopenharmony_ci#define ALSZ	15
1338c2ecf20Sopenharmony_ci#define ALMASK	~15
1348c2ecf20Sopenharmony_ci#endif
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/*
1378c2ecf20Sopenharmony_ci * Macros to handle different pointer/register sizes for 32/64-bit code
1388c2ecf20Sopenharmony_ci */
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci/*
1418c2ecf20Sopenharmony_ci * Size of a register
1428c2ecf20Sopenharmony_ci */
1438c2ecf20Sopenharmony_ci#ifdef __mips64
1448c2ecf20Sopenharmony_ci#define SZREG	8
1458c2ecf20Sopenharmony_ci#else
1468c2ecf20Sopenharmony_ci#define SZREG	4
1478c2ecf20Sopenharmony_ci#endif
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci/*
1508c2ecf20Sopenharmony_ci * Use the following macros in assemblercode to load/store registers,
1518c2ecf20Sopenharmony_ci * pointers etc.
1528c2ecf20Sopenharmony_ci */
1538c2ecf20Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_ABI32)
1548c2ecf20Sopenharmony_ci#define REG_S		sw
1558c2ecf20Sopenharmony_ci#define REG_L		lw
1568c2ecf20Sopenharmony_ci#define REG_SUBU	subu
1578c2ecf20Sopenharmony_ci#define REG_ADDU	addu
1588c2ecf20Sopenharmony_ci#endif
1598c2ecf20Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
1608c2ecf20Sopenharmony_ci#define REG_S		sd
1618c2ecf20Sopenharmony_ci#define REG_L		ld
1628c2ecf20Sopenharmony_ci#define REG_SUBU	dsubu
1638c2ecf20Sopenharmony_ci#define REG_ADDU	daddu
1648c2ecf20Sopenharmony_ci#endif
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci/*
1678c2ecf20Sopenharmony_ci * How to add/sub/load/store/shift C int variables.
1688c2ecf20Sopenharmony_ci */
1698c2ecf20Sopenharmony_ci#if (_MIPS_SZINT == 32)
1708c2ecf20Sopenharmony_ci#define INT_ADD		add
1718c2ecf20Sopenharmony_ci#define INT_ADDU	addu
1728c2ecf20Sopenharmony_ci#define INT_ADDI	addi
1738c2ecf20Sopenharmony_ci#define INT_ADDIU	addiu
1748c2ecf20Sopenharmony_ci#define INT_SUB		sub
1758c2ecf20Sopenharmony_ci#define INT_SUBU	subu
1768c2ecf20Sopenharmony_ci#define INT_L		lw
1778c2ecf20Sopenharmony_ci#define INT_S		sw
1788c2ecf20Sopenharmony_ci#define INT_SLL		sll
1798c2ecf20Sopenharmony_ci#define INT_SLLV	sllv
1808c2ecf20Sopenharmony_ci#define INT_SRL		srl
1818c2ecf20Sopenharmony_ci#define INT_SRLV	srlv
1828c2ecf20Sopenharmony_ci#define INT_SRA		sra
1838c2ecf20Sopenharmony_ci#define INT_SRAV	srav
1848c2ecf20Sopenharmony_ci#endif
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci#if (_MIPS_SZINT == 64)
1878c2ecf20Sopenharmony_ci#define INT_ADD		dadd
1888c2ecf20Sopenharmony_ci#define INT_ADDU	daddu
1898c2ecf20Sopenharmony_ci#define INT_ADDI	daddi
1908c2ecf20Sopenharmony_ci#define INT_ADDIU	daddiu
1918c2ecf20Sopenharmony_ci#define INT_SUB		dsub
1928c2ecf20Sopenharmony_ci#define INT_SUBU	dsubu
1938c2ecf20Sopenharmony_ci#define INT_L		ld
1948c2ecf20Sopenharmony_ci#define INT_S		sd
1958c2ecf20Sopenharmony_ci#define INT_SLL		dsll
1968c2ecf20Sopenharmony_ci#define INT_SLLV	dsllv
1978c2ecf20Sopenharmony_ci#define INT_SRL		dsrl
1988c2ecf20Sopenharmony_ci#define INT_SRLV	dsrlv
1998c2ecf20Sopenharmony_ci#define INT_SRA		dsra
2008c2ecf20Sopenharmony_ci#define INT_SRAV	dsrav
2018c2ecf20Sopenharmony_ci#endif
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci/*
2048c2ecf20Sopenharmony_ci * How to add/sub/load/store/shift C long variables.
2058c2ecf20Sopenharmony_ci */
2068c2ecf20Sopenharmony_ci#if (_MIPS_SZLONG == 32)
2078c2ecf20Sopenharmony_ci#define LONG_ADD	add
2088c2ecf20Sopenharmony_ci#define LONG_ADDU	addu
2098c2ecf20Sopenharmony_ci#define LONG_ADDI	addi
2108c2ecf20Sopenharmony_ci#define LONG_ADDIU	addiu
2118c2ecf20Sopenharmony_ci#define LONG_SUB	sub
2128c2ecf20Sopenharmony_ci#define LONG_SUBU	subu
2138c2ecf20Sopenharmony_ci#define LONG_L		lw
2148c2ecf20Sopenharmony_ci#define LONG_S		sw
2158c2ecf20Sopenharmony_ci#define LONG_SP		swp
2168c2ecf20Sopenharmony_ci#define LONG_SLL	sll
2178c2ecf20Sopenharmony_ci#define LONG_SLLV	sllv
2188c2ecf20Sopenharmony_ci#define LONG_SRL	srl
2198c2ecf20Sopenharmony_ci#define LONG_SRLV	srlv
2208c2ecf20Sopenharmony_ci#define LONG_SRA	sra
2218c2ecf20Sopenharmony_ci#define LONG_SRAV	srav
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci#ifdef __ASSEMBLY__
2248c2ecf20Sopenharmony_ci#define LONG		.word
2258c2ecf20Sopenharmony_ci#endif
2268c2ecf20Sopenharmony_ci#define LONGSIZE	4
2278c2ecf20Sopenharmony_ci#define LONGMASK	3
2288c2ecf20Sopenharmony_ci#define LONGLOG		2
2298c2ecf20Sopenharmony_ci#endif
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci#if (_MIPS_SZLONG == 64)
2328c2ecf20Sopenharmony_ci#define LONG_ADD	dadd
2338c2ecf20Sopenharmony_ci#define LONG_ADDU	daddu
2348c2ecf20Sopenharmony_ci#define LONG_ADDI	daddi
2358c2ecf20Sopenharmony_ci#define LONG_ADDIU	daddiu
2368c2ecf20Sopenharmony_ci#define LONG_SUB	dsub
2378c2ecf20Sopenharmony_ci#define LONG_SUBU	dsubu
2388c2ecf20Sopenharmony_ci#define LONG_L		ld
2398c2ecf20Sopenharmony_ci#define LONG_S		sd
2408c2ecf20Sopenharmony_ci#define LONG_SP		sdp
2418c2ecf20Sopenharmony_ci#define LONG_SLL	dsll
2428c2ecf20Sopenharmony_ci#define LONG_SLLV	dsllv
2438c2ecf20Sopenharmony_ci#define LONG_SRL	dsrl
2448c2ecf20Sopenharmony_ci#define LONG_SRLV	dsrlv
2458c2ecf20Sopenharmony_ci#define LONG_SRA	dsra
2468c2ecf20Sopenharmony_ci#define LONG_SRAV	dsrav
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci#ifdef __ASSEMBLY__
2498c2ecf20Sopenharmony_ci#define LONG		.dword
2508c2ecf20Sopenharmony_ci#endif
2518c2ecf20Sopenharmony_ci#define LONGSIZE	8
2528c2ecf20Sopenharmony_ci#define LONGMASK	7
2538c2ecf20Sopenharmony_ci#define LONGLOG		3
2548c2ecf20Sopenharmony_ci#endif
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci/*
2578c2ecf20Sopenharmony_ci * How to add/sub/load/store/shift pointers.
2588c2ecf20Sopenharmony_ci */
2598c2ecf20Sopenharmony_ci#if (_MIPS_SZPTR == 32)
2608c2ecf20Sopenharmony_ci#define PTR_ADD		add
2618c2ecf20Sopenharmony_ci#define PTR_ADDU	addu
2628c2ecf20Sopenharmony_ci#define PTR_ADDI	addi
2638c2ecf20Sopenharmony_ci#define PTR_ADDIU	addiu
2648c2ecf20Sopenharmony_ci#define PTR_SUB		sub
2658c2ecf20Sopenharmony_ci#define PTR_SUBU	subu
2668c2ecf20Sopenharmony_ci#define PTR_L		lw
2678c2ecf20Sopenharmony_ci#define PTR_S		sw
2688c2ecf20Sopenharmony_ci#define PTR_LA		la
2698c2ecf20Sopenharmony_ci#define PTR_LI		li
2708c2ecf20Sopenharmony_ci#define PTR_SLL		sll
2718c2ecf20Sopenharmony_ci#define PTR_SLLV	sllv
2728c2ecf20Sopenharmony_ci#define PTR_SRL		srl
2738c2ecf20Sopenharmony_ci#define PTR_SRLV	srlv
2748c2ecf20Sopenharmony_ci#define PTR_SRA		sra
2758c2ecf20Sopenharmony_ci#define PTR_SRAV	srav
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci#define PTR_SCALESHIFT	2
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci#define PTR		.word
2808c2ecf20Sopenharmony_ci#define PTRSIZE		4
2818c2ecf20Sopenharmony_ci#define PTRLOG		2
2828c2ecf20Sopenharmony_ci#endif
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci#if (_MIPS_SZPTR == 64)
2858c2ecf20Sopenharmony_ci#define PTR_ADD		dadd
2868c2ecf20Sopenharmony_ci#define PTR_ADDU	daddu
2878c2ecf20Sopenharmony_ci#define PTR_ADDI	daddi
2888c2ecf20Sopenharmony_ci#define PTR_ADDIU	daddiu
2898c2ecf20Sopenharmony_ci#define PTR_SUB		dsub
2908c2ecf20Sopenharmony_ci#define PTR_SUBU	dsubu
2918c2ecf20Sopenharmony_ci#define PTR_L		ld
2928c2ecf20Sopenharmony_ci#define PTR_S		sd
2938c2ecf20Sopenharmony_ci#define PTR_LA		dla
2948c2ecf20Sopenharmony_ci#define PTR_LI		dli
2958c2ecf20Sopenharmony_ci#define PTR_SLL		dsll
2968c2ecf20Sopenharmony_ci#define PTR_SLLV	dsllv
2978c2ecf20Sopenharmony_ci#define PTR_SRL		dsrl
2988c2ecf20Sopenharmony_ci#define PTR_SRLV	dsrlv
2998c2ecf20Sopenharmony_ci#define PTR_SRA		dsra
3008c2ecf20Sopenharmony_ci#define PTR_SRAV	dsrav
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ci#define PTR_SCALESHIFT	3
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci#define PTR		.dword
3058c2ecf20Sopenharmony_ci#define PTRSIZE		8
3068c2ecf20Sopenharmony_ci#define PTRLOG		3
3078c2ecf20Sopenharmony_ci#endif
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci/*
3108c2ecf20Sopenharmony_ci * Some cp0 registers were extended to 64bit for MIPS III.
3118c2ecf20Sopenharmony_ci */
3128c2ecf20Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_ABI32)
3138c2ecf20Sopenharmony_ci#define MFC0		mfc0
3148c2ecf20Sopenharmony_ci#define MTC0		mtc0
3158c2ecf20Sopenharmony_ci#endif
3168c2ecf20Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
3178c2ecf20Sopenharmony_ci#define MFC0		dmfc0
3188c2ecf20Sopenharmony_ci#define MTC0		dmtc0
3198c2ecf20Sopenharmony_ci#endif
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci#define SSNOP		sll zero, zero, 1
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci#ifdef CONFIG_SGI_IP28
3248c2ecf20Sopenharmony_ci/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
3258c2ecf20Sopenharmony_ci#include <asm/cacheops.h>
3268c2ecf20Sopenharmony_ci#define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
3278c2ecf20Sopenharmony_ci#else
3288c2ecf20Sopenharmony_ci#define R10KCBARRIER(addr)
3298c2ecf20Sopenharmony_ci#endif
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci#endif /* __ASM_ASM_H */
332