1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _ASM_S390_NOSPEC_ASM_H
3#define _ASM_S390_NOSPEC_ASM_H
4
5#include <asm/alternative-asm.h>
6#include <asm/asm-offsets.h>
7#include <asm/dwarf.h>
8
9#ifdef __ASSEMBLY__
10
11#ifdef CC_USING_EXPOLINE
12
13_LC_BR_R1 = __LC_BR_R1
14
15/*
16 * The expoline macros are used to create thunks in the same format
17 * as gcc generates them. The 'comdat' section flag makes sure that
18 * the various thunks are merged into a single copy.
19 */
20	.macro __THUNK_PROLOG_NAME name
21	.pushsection .text.\name,"axG",@progbits,\name,comdat
22	.globl \name
23	.hidden \name
24	.type \name,@function
25\name:
26	CFI_STARTPROC
27	.endm
28
29	.macro __THUNK_EPILOG
30	CFI_ENDPROC
31	.popsection
32	.endm
33
34	.macro __THUNK_PROLOG_BR r1,r2
35	__THUNK_PROLOG_NAME __s390_indirect_jump_r\r2\()use_r\r1
36	.endm
37
38	.macro __THUNK_PROLOG_BC d0,r1,r2
39	__THUNK_PROLOG_NAME __s390_indirect_branch_\d0\()_\r2\()use_\r1
40	.endm
41
42	.macro __THUNK_BR r1,r2
43	jg	__s390_indirect_jump_r\r2\()use_r\r1
44	.endm
45
46	.macro __THUNK_BC d0,r1,r2
47	jg	__s390_indirect_branch_\d0\()_\r2\()use_\r1
48	.endm
49
50	.macro __THUNK_BRASL r1,r2,r3
51	brasl	\r1,__s390_indirect_jump_r\r3\()use_r\r2
52	.endm
53
54	.macro	__DECODE_RR expand,reg,ruse
55	.set __decode_fail,1
56	.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
57	.ifc \reg,%r\r1
58	.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
59	.ifc \ruse,%r\r2
60	\expand \r1,\r2
61	.set __decode_fail,0
62	.endif
63	.endr
64	.endif
65	.endr
66	.if __decode_fail == 1
67	.error "__DECODE_RR failed"
68	.endif
69	.endm
70
71	.macro	__DECODE_RRR expand,rsave,rtarget,ruse
72	.set __decode_fail,1
73	.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
74	.ifc \rsave,%r\r1
75	.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
76	.ifc \rtarget,%r\r2
77	.irp r3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
78	.ifc \ruse,%r\r3
79	\expand \r1,\r2,\r3
80	.set __decode_fail,0
81	.endif
82	.endr
83	.endif
84	.endr
85	.endif
86	.endr
87	.if __decode_fail == 1
88	.error "__DECODE_RRR failed"
89	.endif
90	.endm
91
92	.macro	__DECODE_DRR expand,disp,reg,ruse
93	.set __decode_fail,1
94	.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
95	.ifc \reg,%r\r1
96	.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
97	.ifc \ruse,%r\r2
98	\expand \disp,\r1,\r2
99	.set __decode_fail,0
100	.endif
101	.endr
102	.endif
103	.endr
104	.if __decode_fail == 1
105	.error "__DECODE_DRR failed"
106	.endif
107	.endm
108
109	.macro __THUNK_EX_BR reg,ruse
110	# Be very careful when adding instructions to this macro!
111	# The ALTERNATIVE replacement code has a .+10 which targets
112	# the "br \reg" after the code has been patched.
113#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
114	exrl	0,555f
115	j	.
116#else
117	.ifc \reg,%r1
118	ALTERNATIVE "ex %r0,_LC_BR_R1", ".insn ril,0xc60000000000,0,.+10", 35
119	j	.
120	.else
121	larl	\ruse,555f
122	ex	0,0(\ruse)
123	j	.
124	.endif
125#endif
126555:	br	\reg
127	.endm
128
129	.macro __THUNK_EX_BC disp,reg,ruse
130#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
131	exrl	0,556f
132	j	.
133#else
134	larl	\ruse,556f
135	ex	0,0(\ruse)
136	j	.
137#endif
138556:	b	\disp(\reg)
139	.endm
140
141	.macro GEN_BR_THUNK reg,ruse=%r1
142	__DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse
143	__THUNK_EX_BR \reg,\ruse
144	__THUNK_EPILOG
145	.endm
146
147	.macro GEN_B_THUNK disp,reg,ruse=%r1
148	__DECODE_DRR __THUNK_PROLOG_BC,\disp,\reg,\ruse
149	__THUNK_EX_BC \disp,\reg,\ruse
150	__THUNK_EPILOG
151	.endm
152
153	.macro BR_EX reg,ruse=%r1
154557:	__DECODE_RR __THUNK_BR,\reg,\ruse
155	.pushsection .s390_indirect_branches,"a",@progbits
156	.long	557b-.
157	.popsection
158	.endm
159
160	 .macro B_EX disp,reg,ruse=%r1
161558:	__DECODE_DRR __THUNK_BC,\disp,\reg,\ruse
162	.pushsection .s390_indirect_branches,"a",@progbits
163	.long	558b-.
164	.popsection
165	.endm
166
167	.macro BASR_EX rsave,rtarget,ruse=%r1
168559:	__DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse
169	.pushsection .s390_indirect_branches,"a",@progbits
170	.long	559b-.
171	.popsection
172	.endm
173
174#else
175	.macro GEN_BR_THUNK reg,ruse=%r1
176	.endm
177
178	.macro GEN_B_THUNK disp,reg,ruse=%r1
179	.endm
180
181	 .macro BR_EX reg,ruse=%r1
182	br	\reg
183	.endm
184
185	 .macro B_EX disp,reg,ruse=%r1
186	b	\disp(\reg)
187	.endm
188
189	.macro BASR_EX rsave,rtarget,ruse=%r1
190	basr	\rsave,\rtarget
191	.endm
192#endif /* CC_USING_EXPOLINE */
193
194#endif /* __ASSEMBLY__ */
195
196#endif /* _ASM_S390_NOSPEC_ASM_H */
197