File Index
Files and directories
Sign in
FILE

asm.h

File preview with syntax highlighting.

linux-6.19.14/arch/x86/include/asm/asm.h C
  1/* SPDX-License-Identifier: GPL-2.0 */
  2#ifndef _ASM_X86_ASM_H
  3#define _ASM_X86_ASM_H
  4
  5#include <linux/annotate.h>
  6
  7#ifdef __ASSEMBLER__
  8# define __ASM_FORM(x, ...)		x,## __VA_ARGS__
  9# define __ASM_FORM_RAW(x, ...)		x,## __VA_ARGS__
 10# define __ASM_FORM_COMMA(x, ...)	x,## __VA_ARGS__,
 11# define __ASM_REGPFX			%
 12#else
 13#include <linux/stringify.h>
 14# define __ASM_FORM(x, ...)		" " __stringify(x,##__VA_ARGS__) " "
 15# define __ASM_FORM_RAW(x, ...)		    __stringify(x,##__VA_ARGS__)
 16# define __ASM_FORM_COMMA(x, ...)	" " __stringify(x,##__VA_ARGS__) ","
 17# define __ASM_REGPFX			%%
 18#endif
 19
 20#define _ASM_BYTES(x, ...)	__ASM_FORM(.byte x,##__VA_ARGS__ ;)
 21
 22#ifndef __x86_64__
 23/* 32 bit */
 24# define __ASM_SEL(a,b)		__ASM_FORM(a)
 25# define __ASM_SEL_RAW(a,b)	__ASM_FORM_RAW(a)
 26#else
 27/* 64 bit */
 28# define __ASM_SEL(a,b)		__ASM_FORM(b)
 29# define __ASM_SEL_RAW(a,b)	__ASM_FORM_RAW(b)
 30#endif
 31
 32#define __ASM_SIZE(inst, ...)	__ASM_SEL(inst##l##__VA_ARGS__, \
 33					  inst##q##__VA_ARGS__)
 34#define __ASM_REG(reg)         __ASM_SEL_RAW(e##reg, r##reg)
 35
 36#define _ASM_PTR	__ASM_SEL(.long, .quad)
 37#define _ASM_ALIGN	__ASM_SEL(.balign 4, .balign 8)
 38
 39#define _ASM_MOV	__ASM_SIZE(mov)
 40#define _ASM_INC	__ASM_SIZE(inc)
 41#define _ASM_DEC	__ASM_SIZE(dec)
 42#define _ASM_ADD	__ASM_SIZE(add)
 43#define _ASM_SUB	__ASM_SIZE(sub)
 44#define _ASM_XADD	__ASM_SIZE(xadd)
 45#define _ASM_MUL	__ASM_SIZE(mul)
 46
 47#define _ASM_AX		__ASM_REG(ax)
 48#define _ASM_BX		__ASM_REG(bx)
 49#define _ASM_CX		__ASM_REG(cx)
 50#define _ASM_DX		__ASM_REG(dx)
 51#define _ASM_SP		__ASM_REG(sp)
 52#define _ASM_BP		__ASM_REG(bp)
 53#define _ASM_SI		__ASM_REG(si)
 54#define _ASM_DI		__ASM_REG(di)
 55
 56/* Adds a (%rip) suffix on 64 bits only; for immediate memory references */
 57#define _ASM_RIP(x)	__ASM_SEL_RAW(x, x (__ASM_REGPFX rip))
 58
 59#ifndef __x86_64__
 60/* 32 bit */
 61
 62#define _ASM_ARG1	_ASM_AX
 63#define _ASM_ARG2	_ASM_DX
 64#define _ASM_ARG3	_ASM_CX
 65
 66#define _ASM_ARG1L	eax
 67#define _ASM_ARG2L	edx
 68#define _ASM_ARG3L	ecx
 69
 70#define _ASM_ARG1W	ax
 71#define _ASM_ARG2W	dx
 72#define _ASM_ARG3W	cx
 73
 74#define _ASM_ARG1B	al
 75#define _ASM_ARG2B	dl
 76#define _ASM_ARG3B	cl
 77
 78#else
 79/* 64 bit */
 80
 81#define _ASM_ARG1	_ASM_DI
 82#define _ASM_ARG2	_ASM_SI
 83#define _ASM_ARG3	_ASM_DX
 84#define _ASM_ARG4	_ASM_CX
 85#define _ASM_ARG5	r8
 86#define _ASM_ARG6	r9
 87
 88#define _ASM_ARG1Q	rdi
 89#define _ASM_ARG2Q	rsi
 90#define _ASM_ARG3Q	rdx
 91#define _ASM_ARG4Q	rcx
 92#define _ASM_ARG5Q	r8
 93#define _ASM_ARG6Q	r9
 94
 95#define _ASM_ARG1L	edi
 96#define _ASM_ARG2L	esi
 97#define _ASM_ARG3L	edx
 98#define _ASM_ARG4L	ecx
 99#define _ASM_ARG5L	r8d
100#define _ASM_ARG6L	r9d
101
102#define _ASM_ARG1W	di
103#define _ASM_ARG2W	si
104#define _ASM_ARG3W	dx
105#define _ASM_ARG4W	cx
106#define _ASM_ARG5W	r8w
107#define _ASM_ARG6W	r9w
108
109#define _ASM_ARG1B	dil
110#define _ASM_ARG2B	sil
111#define _ASM_ARG3B	dl
112#define _ASM_ARG4B	cl
113#define _ASM_ARG5B	r8b
114#define _ASM_ARG6B	r9b
115
116#endif
117
118#ifndef __ASSEMBLER__
119static __always_inline __pure void *rip_rel_ptr(void *p)
120{
121	asm("leaq %c1(%%rip), %0" : "=r"(p) : "i"(p));
122
123	return p;
124}
125#endif
126
127#ifdef __KERNEL__
128
129#ifndef COMPILE_OFFSETS
130#include <asm/asm-offsets.h>
131#endif
132
133# include <asm/extable_fixup_types.h>
134
135/* Exception table entry */
136#ifdef __ASSEMBLER__
137
138# define _ASM_EXTABLE_TYPE(from, to, type)				\
139	.pushsection "__ex_table", "aM", @progbits, EXTABLE_SIZE ;	\
140	.balign 4 ;							\
141	.long (from) - . ;						\
142	.long (to) - . ;						\
143	.long type ;							\
144	.popsection
145
146# ifdef CONFIG_KPROBES
147#  define _ASM_NOKPROBE(entry)					\
148	.pushsection "_kprobe_blacklist","aw" ;			\
149	_ASM_ALIGN ;						\
150	_ASM_PTR (entry);					\
151	.popsection
152# else
153#  define _ASM_NOKPROBE(entry)
154# endif
155
156#else /* ! __ASSEMBLER__ */
157
158# define DEFINE_EXTABLE_TYPE_REG \
159	".macro extable_type_reg type:req reg:req\n"						\
160	".set .Lfound, 0\n"									\
161	".set .Lregnr, 0\n"									\
162	".irp rs,rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15\n"		\
163	".ifc \\reg, %%\\rs\n"									\
164	".set .Lfound, .Lfound+1\n"								\
165	".long \\type + (.Lregnr << 8)\n"							\
166	".endif\n"										\
167	".set .Lregnr, .Lregnr+1\n"								\
168	".endr\n"										\
169	".set .Lregnr, 0\n"									\
170	".irp rs,eax,ecx,edx,ebx,esp,ebp,esi,edi,r8d,r9d,r10d,r11d,r12d,r13d,r14d,r15d\n"	\
171	".ifc \\reg, %%\\rs\n"									\
172	".set .Lfound, .Lfound+1\n"								\
173	".long \\type + (.Lregnr << 8)\n"							\
174	".endif\n"										\
175	".set .Lregnr, .Lregnr+1\n"								\
176	".endr\n"										\
177	".if (.Lfound != 1)\n"									\
178	".error \"extable_type_reg: bad register argument\"\n"					\
179	".endif\n"										\
180	".endm\n"
181
182# define UNDEFINE_EXTABLE_TYPE_REG \
183	".purgem extable_type_reg\n"
184
185# define _ASM_EXTABLE_TYPE(from, to, type)			\
186	" .pushsection __ex_table, \"aM\", @progbits, "		\
187		       __stringify(EXTABLE_SIZE) "\n"		\
188	" .balign 4\n"						\
189	" .long (" #from ") - .\n"				\
190	" .long (" #to ") - .\n"				\
191	" .long " __stringify(type) " \n"			\
192	" .popsection\n"
193
194# define _ASM_EXTABLE_TYPE_REG(from, to, type, reg)				\
195	" .pushsection __ex_table, \"aM\", @progbits, "				\
196		       __stringify(EXTABLE_SIZE) "\n"				\
197	" .balign 4\n"								\
198	" .long (" #from ") - .\n"						\
199	" .long (" #to ") - .\n"						\
200	DEFINE_EXTABLE_TYPE_REG							\
201	"extable_type_reg reg=" __stringify(reg) ", type=" __stringify(type) " \n"\
202	UNDEFINE_EXTABLE_TYPE_REG						\
203	" .popsection\n"
204
205/* For C file, we already have NOKPROBE_SYMBOL macro */
206
207/* Insert a comma if args are non-empty */
208#define COMMA(x...)		__COMMA(x)
209#define __COMMA(...)		, ##__VA_ARGS__
210
211/*
212 * Combine multiple asm inline constraint args into a single arg for passing to
213 * another macro.
214 */
215#define ASM_OUTPUT(x...)	x
216#define ASM_INPUT(x...)		x
217
218/*
219 * This output constraint should be used for any inline asm which has a "call"
220 * instruction.  Otherwise the asm may be inserted before the frame pointer
221 * gets set up by the containing function.  If you forget to do this, objtool
222 * may print a "call without frame pointer save/setup" warning.
223 */
224register unsigned long current_stack_pointer asm(_ASM_SP);
225#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
226#endif /* __ASSEMBLER__ */
227
228#define _ASM_EXTABLE(from, to)					\
229	_ASM_EXTABLE_TYPE(from, to, EX_TYPE_DEFAULT)
230
231#define _ASM_EXTABLE_UA(from, to)				\
232	_ASM_EXTABLE_TYPE(from, to, EX_TYPE_UACCESS)
233
234#define _ASM_EXTABLE_FAULT(from, to)				\
235	_ASM_EXTABLE_TYPE(from, to, EX_TYPE_FAULT)
236
237/*
238 * Both i386 and x86_64 returns 64-bit values in edx:eax for certain
239 * instructions, but GCC's "A" constraint has different meanings.
240 * For i386, "A" means exactly edx:eax, while for x86_64 it
241 * means rax *or* rdx.
242 *
243 * These helpers wrapping these semantic differences save one instruction
244 * clearing the high half of 'low':
245 */
246#ifdef CONFIG_X86_64
247# define EAX_EDX_DECLARE_ARGS(val, low, high)	unsigned long low, high
248# define EAX_EDX_VAL(val, low, high)		((low) | (high) << 32)
249# define EAX_EDX_RET(val, low, high)		"=a" (low), "=d" (high)
250#else
251# define EAX_EDX_DECLARE_ARGS(val, low, high)	u64 val
252# define EAX_EDX_VAL(val, low, high)		(val)
253# define EAX_EDX_RET(val, low, high)		"=A" (val)
254#endif
255
256#endif /* __KERNEL__ */
257#endif /* _ASM_X86_ASM_H */
~/ Read-only file preview.