162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
362306a36Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
462306a36Sopenharmony_ci * for more details.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
762306a36Sopenharmony_ci * Copyright (C) 1999 by Silicon Graphics, Inc.
862306a36Sopenharmony_ci * Copyright (C) 2001 MIPS Technologies, Inc.
962306a36Sopenharmony_ci * Copyright (C) 2002  Maciej W. Rozycki
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * Some useful macros for MIPS assembler code
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * Some of the routines below contain useless nops that will be optimized
1462306a36Sopenharmony_ci * away by gas in -O mode. These nops are however required to fill delay
1562306a36Sopenharmony_ci * slots in noreorder mode.
1662306a36Sopenharmony_ci */
1762306a36Sopenharmony_ci#ifndef __ASM_ASM_H
1862306a36Sopenharmony_ci#define __ASM_ASM_H
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include <asm/sgidefs.h>
2162306a36Sopenharmony_ci#include <asm/asm-eva.h>
2262306a36Sopenharmony_ci#include <asm/isa-rev.h>
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#ifndef __VDSO__
2562306a36Sopenharmony_ci/*
2662306a36Sopenharmony_ci * Emit CFI data in .debug_frame sections, not .eh_frame sections.
2762306a36Sopenharmony_ci * We don't do DWARF unwinding at runtime, so only the offline DWARF
2862306a36Sopenharmony_ci * information is useful to anyone. Note we should change this if we
2962306a36Sopenharmony_ci * ever decide to enable DWARF unwinding at runtime.
3062306a36Sopenharmony_ci */
3162306a36Sopenharmony_ci#define CFI_SECTIONS	.cfi_sections .debug_frame
3262306a36Sopenharmony_ci#else
3362306a36Sopenharmony_ci /*
3462306a36Sopenharmony_ci  * For the vDSO, emit both runtime unwind information and debug
3562306a36Sopenharmony_ci  * symbols for the .dbg file.
3662306a36Sopenharmony_ci  */
3762306a36Sopenharmony_ci#define CFI_SECTIONS
3862306a36Sopenharmony_ci#endif
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/*
4162306a36Sopenharmony_ci * LEAF - declare leaf routine
4262306a36Sopenharmony_ci */
4362306a36Sopenharmony_ci#define LEAF(symbol)					\
4462306a36Sopenharmony_ci		CFI_SECTIONS;				\
4562306a36Sopenharmony_ci		.globl	symbol;				\
4662306a36Sopenharmony_ci		.align	2;				\
4762306a36Sopenharmony_ci		.type	symbol, @function;		\
4862306a36Sopenharmony_ci		.ent	symbol, 0;			\
4962306a36Sopenharmony_cisymbol:		.frame	sp, 0, ra;			\
5062306a36Sopenharmony_ci		.cfi_startproc;				\
5162306a36Sopenharmony_ci		.insn
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/*
5462306a36Sopenharmony_ci * NESTED - declare nested routine entry point
5562306a36Sopenharmony_ci */
5662306a36Sopenharmony_ci#define NESTED(symbol, framesize, rpc)			\
5762306a36Sopenharmony_ci		CFI_SECTIONS;				\
5862306a36Sopenharmony_ci		.globl	symbol;				\
5962306a36Sopenharmony_ci		.align	2;				\
6062306a36Sopenharmony_ci		.type	symbol, @function;		\
6162306a36Sopenharmony_ci		.ent	symbol, 0;			\
6262306a36Sopenharmony_cisymbol:		.frame	sp, framesize, rpc;		\
6362306a36Sopenharmony_ci		.cfi_startproc;				\
6462306a36Sopenharmony_ci		.insn
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/*
6762306a36Sopenharmony_ci * END - mark end of function
6862306a36Sopenharmony_ci */
6962306a36Sopenharmony_ci#define END(function)					\
7062306a36Sopenharmony_ci		.cfi_endproc;				\
7162306a36Sopenharmony_ci		.end	function;			\
7262306a36Sopenharmony_ci		.size	function, .-function
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci/*
7562306a36Sopenharmony_ci * EXPORT - export definition of symbol
7662306a36Sopenharmony_ci */
7762306a36Sopenharmony_ci#define EXPORT(symbol)					\
7862306a36Sopenharmony_ci		.globl	symbol;				\
7962306a36Sopenharmony_cisymbol:
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci/*
8262306a36Sopenharmony_ci * FEXPORT - export definition of a function symbol
8362306a36Sopenharmony_ci */
8462306a36Sopenharmony_ci#define FEXPORT(symbol)					\
8562306a36Sopenharmony_ci		.globl	symbol;				\
8662306a36Sopenharmony_ci		.type	symbol, @function;		\
8762306a36Sopenharmony_cisymbol:		.insn
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/*
9062306a36Sopenharmony_ci * ABS - export absolute symbol
9162306a36Sopenharmony_ci */
9262306a36Sopenharmony_ci#define ABS(symbol,value)				\
9362306a36Sopenharmony_ci		.globl	symbol;				\
9462306a36Sopenharmony_cisymbol		=	value
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci#define TEXT(msg)					\
9762306a36Sopenharmony_ci		.pushsection .data;			\
9862306a36Sopenharmony_ci8:		.asciiz msg;				\
9962306a36Sopenharmony_ci		.popsection;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci#define ASM_PANIC(msg)					\
10262306a36Sopenharmony_ci		.set	push;				\
10362306a36Sopenharmony_ci		.set	reorder;			\
10462306a36Sopenharmony_ci		PTR_LA	a0, 8f;				\
10562306a36Sopenharmony_ci		jal	panic;				\
10662306a36Sopenharmony_ci9:		b	9b;				\
10762306a36Sopenharmony_ci		.set	pop;				\
10862306a36Sopenharmony_ci		TEXT(msg)
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/*
11162306a36Sopenharmony_ci * Print formatted string
11262306a36Sopenharmony_ci */
11362306a36Sopenharmony_ci#ifdef CONFIG_PRINTK
11462306a36Sopenharmony_ci#define ASM_PRINT(string)				\
11562306a36Sopenharmony_ci		.set	push;				\
11662306a36Sopenharmony_ci		.set	reorder;			\
11762306a36Sopenharmony_ci		PTR_LA	a0, 8f;				\
11862306a36Sopenharmony_ci		jal	_printk;			\
11962306a36Sopenharmony_ci		.set	pop;				\
12062306a36Sopenharmony_ci		TEXT(string)
12162306a36Sopenharmony_ci#else
12262306a36Sopenharmony_ci#define ASM_PRINT(string)
12362306a36Sopenharmony_ci#endif
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci/*
12662306a36Sopenharmony_ci * Stack alignment
12762306a36Sopenharmony_ci */
12862306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_ABI32)
12962306a36Sopenharmony_ci#define ALSZ	7
13062306a36Sopenharmony_ci#define ALMASK	~7
13162306a36Sopenharmony_ci#endif
13262306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
13362306a36Sopenharmony_ci#define ALSZ	15
13462306a36Sopenharmony_ci#define ALMASK	~15
13562306a36Sopenharmony_ci#endif
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci/*
13862306a36Sopenharmony_ci * Macros to handle different pointer/register sizes for 32/64-bit code
13962306a36Sopenharmony_ci */
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci/*
14262306a36Sopenharmony_ci * Size of a register
14362306a36Sopenharmony_ci */
14462306a36Sopenharmony_ci#ifdef __mips64
14562306a36Sopenharmony_ci#define SZREG	8
14662306a36Sopenharmony_ci#else
14762306a36Sopenharmony_ci#define SZREG	4
14862306a36Sopenharmony_ci#endif
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci/*
15162306a36Sopenharmony_ci * Use the following macros in assemblercode to load/store registers,
15262306a36Sopenharmony_ci * pointers etc.
15362306a36Sopenharmony_ci */
15462306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_ABI32)
15562306a36Sopenharmony_ci#define REG_S		sw
15662306a36Sopenharmony_ci#define REG_L		lw
15762306a36Sopenharmony_ci#define REG_SUBU	subu
15862306a36Sopenharmony_ci#define REG_ADDU	addu
15962306a36Sopenharmony_ci#endif
16062306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
16162306a36Sopenharmony_ci#define REG_S		sd
16262306a36Sopenharmony_ci#define REG_L		ld
16362306a36Sopenharmony_ci#define REG_SUBU	dsubu
16462306a36Sopenharmony_ci#define REG_ADDU	daddu
16562306a36Sopenharmony_ci#endif
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci/*
16862306a36Sopenharmony_ci * How to add/sub/load/store/shift C int variables.
16962306a36Sopenharmony_ci */
17062306a36Sopenharmony_ci#if (_MIPS_SZINT == 32)
17162306a36Sopenharmony_ci#define INT_ADD		add
17262306a36Sopenharmony_ci#define INT_ADDU	addu
17362306a36Sopenharmony_ci#define INT_ADDI	addi
17462306a36Sopenharmony_ci#define INT_ADDIU	addiu
17562306a36Sopenharmony_ci#define INT_SUB		sub
17662306a36Sopenharmony_ci#define INT_SUBU	subu
17762306a36Sopenharmony_ci#define INT_L		lw
17862306a36Sopenharmony_ci#define INT_S		sw
17962306a36Sopenharmony_ci#define INT_SLL		sll
18062306a36Sopenharmony_ci#define INT_SLLV	sllv
18162306a36Sopenharmony_ci#define INT_SRL		srl
18262306a36Sopenharmony_ci#define INT_SRLV	srlv
18362306a36Sopenharmony_ci#define INT_SRA		sra
18462306a36Sopenharmony_ci#define INT_SRAV	srav
18562306a36Sopenharmony_ci#endif
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci#if (_MIPS_SZINT == 64)
18862306a36Sopenharmony_ci#define INT_ADD		dadd
18962306a36Sopenharmony_ci#define INT_ADDU	daddu
19062306a36Sopenharmony_ci#define INT_ADDI	daddi
19162306a36Sopenharmony_ci#define INT_ADDIU	daddiu
19262306a36Sopenharmony_ci#define INT_SUB		dsub
19362306a36Sopenharmony_ci#define INT_SUBU	dsubu
19462306a36Sopenharmony_ci#define INT_L		ld
19562306a36Sopenharmony_ci#define INT_S		sd
19662306a36Sopenharmony_ci#define INT_SLL		dsll
19762306a36Sopenharmony_ci#define INT_SLLV	dsllv
19862306a36Sopenharmony_ci#define INT_SRL		dsrl
19962306a36Sopenharmony_ci#define INT_SRLV	dsrlv
20062306a36Sopenharmony_ci#define INT_SRA		dsra
20162306a36Sopenharmony_ci#define INT_SRAV	dsrav
20262306a36Sopenharmony_ci#endif
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci/*
20562306a36Sopenharmony_ci * How to add/sub/load/store/shift C long variables.
20662306a36Sopenharmony_ci */
20762306a36Sopenharmony_ci#if (_MIPS_SZLONG == 32)
20862306a36Sopenharmony_ci#define LONG_ADD	add
20962306a36Sopenharmony_ci#define LONG_ADDU	addu
21062306a36Sopenharmony_ci#define LONG_ADDI	addi
21162306a36Sopenharmony_ci#define LONG_ADDIU	addiu
21262306a36Sopenharmony_ci#define LONG_SUB	sub
21362306a36Sopenharmony_ci#define LONG_SUBU	subu
21462306a36Sopenharmony_ci#define LONG_L		lw
21562306a36Sopenharmony_ci#define LONG_LL		ll
21662306a36Sopenharmony_ci#define LONG_SC		sc
21762306a36Sopenharmony_ci#define LONG_S		sw
21862306a36Sopenharmony_ci#define LONG_SP		swp
21962306a36Sopenharmony_ci#define LONG_SLL	sll
22062306a36Sopenharmony_ci#define LONG_SLLV	sllv
22162306a36Sopenharmony_ci#define LONG_SRL	srl
22262306a36Sopenharmony_ci#define LONG_SRLV	srlv
22362306a36Sopenharmony_ci#define LONG_SRA	sra
22462306a36Sopenharmony_ci#define LONG_SRAV	srav
22562306a36Sopenharmony_ci#define LONG_INS	ins
22662306a36Sopenharmony_ci#define LONG_EXT	ext
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci#ifdef __ASSEMBLY__
22962306a36Sopenharmony_ci#define LONG		.word
23062306a36Sopenharmony_ci#endif
23162306a36Sopenharmony_ci#define LONGSIZE	4
23262306a36Sopenharmony_ci#define LONGMASK	3
23362306a36Sopenharmony_ci#define LONGLOG		2
23462306a36Sopenharmony_ci#endif
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci#if (_MIPS_SZLONG == 64)
23762306a36Sopenharmony_ci#define LONG_ADD	dadd
23862306a36Sopenharmony_ci#define LONG_ADDU	daddu
23962306a36Sopenharmony_ci#define LONG_ADDI	daddi
24062306a36Sopenharmony_ci#define LONG_ADDIU	daddiu
24162306a36Sopenharmony_ci#define LONG_SUB	dsub
24262306a36Sopenharmony_ci#define LONG_SUBU	dsubu
24362306a36Sopenharmony_ci#define LONG_L		ld
24462306a36Sopenharmony_ci#define LONG_LL		lld
24562306a36Sopenharmony_ci#define LONG_SC		scd
24662306a36Sopenharmony_ci#define LONG_S		sd
24762306a36Sopenharmony_ci#define LONG_SP		sdp
24862306a36Sopenharmony_ci#define LONG_SLL	dsll
24962306a36Sopenharmony_ci#define LONG_SLLV	dsllv
25062306a36Sopenharmony_ci#define LONG_SRL	dsrl
25162306a36Sopenharmony_ci#define LONG_SRLV	dsrlv
25262306a36Sopenharmony_ci#define LONG_SRA	dsra
25362306a36Sopenharmony_ci#define LONG_SRAV	dsrav
25462306a36Sopenharmony_ci#define LONG_INS	dins
25562306a36Sopenharmony_ci#define LONG_EXT	dext
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci#ifdef __ASSEMBLY__
25862306a36Sopenharmony_ci#define LONG		.dword
25962306a36Sopenharmony_ci#endif
26062306a36Sopenharmony_ci#define LONGSIZE	8
26162306a36Sopenharmony_ci#define LONGMASK	7
26262306a36Sopenharmony_ci#define LONGLOG		3
26362306a36Sopenharmony_ci#endif
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci/*
26662306a36Sopenharmony_ci * How to add/sub/load/store/shift pointers.
26762306a36Sopenharmony_ci */
26862306a36Sopenharmony_ci#if (_MIPS_SZPTR == 32)
26962306a36Sopenharmony_ci#define PTR_ADD		add
27062306a36Sopenharmony_ci#define PTR_ADDU	addu
27162306a36Sopenharmony_ci#define PTR_ADDI	addi
27262306a36Sopenharmony_ci#define PTR_ADDIU	addiu
27362306a36Sopenharmony_ci#define PTR_SUB		sub
27462306a36Sopenharmony_ci#define PTR_SUBU	subu
27562306a36Sopenharmony_ci#define PTR_L		lw
27662306a36Sopenharmony_ci#define PTR_S		sw
27762306a36Sopenharmony_ci#define PTR_LA		la
27862306a36Sopenharmony_ci#define PTR_LI		li
27962306a36Sopenharmony_ci#define PTR_SLL		sll
28062306a36Sopenharmony_ci#define PTR_SLLV	sllv
28162306a36Sopenharmony_ci#define PTR_SRL		srl
28262306a36Sopenharmony_ci#define PTR_SRLV	srlv
28362306a36Sopenharmony_ci#define PTR_SRA		sra
28462306a36Sopenharmony_ci#define PTR_SRAV	srav
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci#define PTR_SCALESHIFT	2
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci#define PTR_WD		.word
28962306a36Sopenharmony_ci#define PTRSIZE		4
29062306a36Sopenharmony_ci#define PTRLOG		2
29162306a36Sopenharmony_ci#endif
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci#if (_MIPS_SZPTR == 64)
29462306a36Sopenharmony_ci#define PTR_ADD		dadd
29562306a36Sopenharmony_ci#define PTR_ADDU	daddu
29662306a36Sopenharmony_ci#define PTR_ADDI	daddi
29762306a36Sopenharmony_ci#define PTR_ADDIU	daddiu
29862306a36Sopenharmony_ci#define PTR_SUB		dsub
29962306a36Sopenharmony_ci#define PTR_SUBU	dsubu
30062306a36Sopenharmony_ci#define PTR_L		ld
30162306a36Sopenharmony_ci#define PTR_S		sd
30262306a36Sopenharmony_ci#define PTR_LA		dla
30362306a36Sopenharmony_ci#define PTR_LI		dli
30462306a36Sopenharmony_ci#define PTR_SLL		dsll
30562306a36Sopenharmony_ci#define PTR_SLLV	dsllv
30662306a36Sopenharmony_ci#define PTR_SRL		dsrl
30762306a36Sopenharmony_ci#define PTR_SRLV	dsrlv
30862306a36Sopenharmony_ci#define PTR_SRA		dsra
30962306a36Sopenharmony_ci#define PTR_SRAV	dsrav
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci#define PTR_SCALESHIFT	3
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci#define PTR_WD		.dword
31462306a36Sopenharmony_ci#define PTRSIZE		8
31562306a36Sopenharmony_ci#define PTRLOG		3
31662306a36Sopenharmony_ci#endif
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci/*
31962306a36Sopenharmony_ci * Some cp0 registers were extended to 64bit for MIPS III.
32062306a36Sopenharmony_ci */
32162306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_ABI32)
32262306a36Sopenharmony_ci#define MFC0		mfc0
32362306a36Sopenharmony_ci#define MTC0		mtc0
32462306a36Sopenharmony_ci#endif
32562306a36Sopenharmony_ci#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64)
32662306a36Sopenharmony_ci#define MFC0		dmfc0
32762306a36Sopenharmony_ci#define MTC0		dmtc0
32862306a36Sopenharmony_ci#endif
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci#define SSNOP		sll zero, zero, 1
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci/*
33362306a36Sopenharmony_ci * Using a branch-likely instruction to check the result of an sc instruction
33462306a36Sopenharmony_ci * works around a bug present in R10000 CPUs prior to revision 3.0 that could
33562306a36Sopenharmony_ci * cause ll-sc sequences to execute non-atomically.
33662306a36Sopenharmony_ci */
33762306a36Sopenharmony_ci#ifdef CONFIG_WAR_R10000_LLSC
33862306a36Sopenharmony_ci# define SC_BEQZ	beqzl
33962306a36Sopenharmony_ci#elif !defined(CONFIG_CC_HAS_BROKEN_INLINE_COMPAT_BRANCH) && MIPS_ISA_REV >= 6
34062306a36Sopenharmony_ci# define SC_BEQZ	beqzc
34162306a36Sopenharmony_ci#else
34262306a36Sopenharmony_ci# define SC_BEQZ	beqz
34362306a36Sopenharmony_ci#endif
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci#ifdef CONFIG_SGI_IP28
34662306a36Sopenharmony_ci/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
34762306a36Sopenharmony_ci#include <asm/cacheops.h>
34862306a36Sopenharmony_ci#define R10KCBARRIER(addr)  cache   Cache_Barrier, addr;
34962306a36Sopenharmony_ci#else
35062306a36Sopenharmony_ci#define R10KCBARRIER(addr)
35162306a36Sopenharmony_ci#endif
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci#endif /* __ASM_ASM_H */
354