1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Some useful macros for LoongArch assembler code
4 *
5 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
6 *
7 * Derived from MIPS:
8 * Copyright (C) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
9 * Copyright (C) 1999 by Silicon Graphics, Inc.
10 * Copyright (C) 2001 MIPS Technologies, Inc.
11 * Copyright (C) 2002  Maciej W. Rozycki
12 */
13#ifndef __ASM_ASM_H
14#define __ASM_ASM_H
15
16/* LoongArch pref instruction. */
17#ifdef CONFIG_CPU_HAS_PREFETCH
18
19#define PREF(hint, addr, offs)				\
20		preld	hint, addr, offs;		\
21
22#define PREFX(hint, addr, index)			\
23		preldx	hint, addr, index;		\
24
25#else /* !CONFIG_CPU_HAS_PREFETCH */
26
27#define PREF(hint, addr, offs)
28#define PREFX(hint, addr, index)
29
30#endif /* !CONFIG_CPU_HAS_PREFETCH */
31
32/*
33 * Stack alignment
34 */
35#define STACK_ALIGN	~(0xf)
36
37/*
38 * Macros to handle different pointer/register sizes for 32/64-bit code
39 */
40
41/*
42 * Size of a register
43 */
44#ifndef __loongarch64
45#define SZREG	4
46#else
47#define SZREG	8
48#endif
49
50/*
51 * Use the following macros in assemblercode to load/store registers,
52 * pointers etc.
53 */
54#if (SZREG == 4)
55#define REG_L		ld.w
56#define REG_S		st.w
57#define REG_ADD		add.w
58#define REG_SUB		sub.w
59#else /* SZREG == 8 */
60#define REG_L		ld.d
61#define REG_S		st.d
62#define REG_ADD		add.d
63#define REG_SUB		sub.d
64#endif
65
66/*
67 * How to add/sub/load/store/shift C int variables.
68 */
69#if (__SIZEOF_INT__ == 4)
70#define INT_ADD		add.w
71#define INT_ADDI	addi.w
72#define INT_SUB		sub.w
73#define INT_L		ld.w
74#define INT_S		st.w
75#define INT_SLL		slli.w
76#define INT_SLLV	sll.w
77#define INT_SRL		srli.w
78#define INT_SRLV	srl.w
79#define INT_SRA		srai.w
80#define INT_SRAV	sra.w
81#endif
82
83#if (__SIZEOF_INT__ == 8)
84#define INT_ADD		add.d
85#define INT_ADDI	addi.d
86#define INT_SUB		sub.d
87#define INT_L		ld.d
88#define INT_S		st.d
89#define INT_SLL		slli.d
90#define INT_SLLV	sll.d
91#define INT_SRL		srli.d
92#define INT_SRLV	srl.d
93#define INT_SRA		srai.d
94#define INT_SRAV	sra.d
95#endif
96
97/*
98 * How to add/sub/load/store/shift C long variables.
99 */
100#if (__SIZEOF_LONG__ == 4)
101#define LONG_ADD	add.w
102#define LONG_ADDI	addi.w
103#define LONG_SUB	sub.w
104#define LONG_L		ld.w
105#define LONG_S		st.w
106#define LONG_SLL	slli.w
107#define LONG_SLLV	sll.w
108#define LONG_SRL	srli.w
109#define LONG_SRLV	srl.w
110#define LONG_SRA	srai.w
111#define LONG_SRAV	sra.w
112
113#ifdef __ASSEMBLY__
114#define LONG		.word
115#endif
116#define LONGSIZE	4
117#define LONGMASK	3
118#define LONGLOG		2
119#endif
120
121#if (__SIZEOF_LONG__ == 8)
122#define LONG_ADD	add.d
123#define LONG_ADDI	addi.d
124#define LONG_SUB	sub.d
125#define LONG_L		ld.d
126#define LONG_S		st.d
127#define LONG_SLL	slli.d
128#define LONG_SLLV	sll.d
129#define LONG_SRL	srli.d
130#define LONG_SRLV	srl.d
131#define LONG_SRA	srai.d
132#define LONG_SRAV	sra.d
133
134#ifdef __ASSEMBLY__
135#define LONG		.dword
136#endif
137#define LONGSIZE	8
138#define LONGMASK	7
139#define LONGLOG		3
140#endif
141
142/*
143 * How to add/sub/load/store/shift pointers.
144 */
145#if (__SIZEOF_POINTER__ == 4)
146#define PTR_ADD		add.w
147#define PTR_ADDI	addi.w
148#define PTR_SUB		sub.w
149#define PTR_L		ld.w
150#define PTR_S		st.w
151#define PTR_LI		li.w
152#define PTR_SLL		slli.w
153#define PTR_SLLV	sll.w
154#define PTR_SRL		srli.w
155#define PTR_SRLV	srl.w
156#define PTR_SRA		srai.w
157#define PTR_SRAV	sra.w
158
159#define PTR_SCALESHIFT	2
160
161#ifdef __ASSEMBLY__
162#define PTR		.word
163#endif
164#define PTRSIZE		4
165#define PTRLOG		2
166#endif
167
168#if (__SIZEOF_POINTER__ == 8)
169#define PTR_ADD		add.d
170#define PTR_ADDI	addi.d
171#define PTR_SUB		sub.d
172#define PTR_L		ld.d
173#define PTR_S		st.d
174#define PTR_LI		li.d
175#define PTR_SLL		slli.d
176#define PTR_SLLV	sll.d
177#define PTR_SRL		srli.d
178#define PTR_SRLV	srl.d
179#define PTR_SRA		srai.d
180#define PTR_SRAV	sra.d
181
182#define PTR_SCALESHIFT	3
183
184#ifdef __ASSEMBLY__
185#define PTR		.dword
186#endif
187#define PTRSIZE		8
188#define PTRLOG		3
189#endif
190
191/* Annotate a function as being unsuitable for kprobes. */
192#ifdef CONFIG_KPROBES
193#define _ASM_NOKPROBE(name)				\
194	.pushsection "_kprobe_blacklist", "aw";		\
195	.quad	name;					\
196	.popsection
197#else
198#define _ASM_NOKPROBE(name)
199#endif
200
201#endif /* __ASM_ASM_H */
202