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 CONFIG_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 __s390x_indirect_jump_r\r2\()use_r\r1
36 	.endm
37 
38 	.macro __THUNK_BR r1,r2
39 	jg	__s390x_indirect_jump_r\r2\()use_r\r1
40 	.endm
41 
42 	.macro __THUNK_BRASL r1,r2,r3
43 	brasl	\r1,__s390x_indirect_jump_r\r3\()use_r\r2
44 	.endm
45 
46 	.macro	__DECODE_RR expand,reg,ruse
47 	.set __decode_fail,1
48 	.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
49 	.ifc \reg,%r\r1
50 	.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
51 	.ifc \ruse,%r\r2
52 	\expand \r1,\r2
53 	.set __decode_fail,0
54 	.endif
55 	.endr
56 	.endif
57 	.endr
58 	.if __decode_fail == 1
59 	.error "__DECODE_RR failed"
60 	.endif
61 	.endm
62 
63 	.macro	__DECODE_RRR expand,rsave,rtarget,ruse
64 	.set __decode_fail,1
65 	.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
66 	.ifc \rsave,%r\r1
67 	.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
68 	.ifc \rtarget,%r\r2
69 	.irp r3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
70 	.ifc \ruse,%r\r3
71 	\expand \r1,\r2,\r3
72 	.set __decode_fail,0
73 	.endif
74 	.endr
75 	.endif
76 	.endr
77 	.endif
78 	.endr
79 	.if __decode_fail == 1
80 	.error "__DECODE_RRR failed"
81 	.endif
82 	.endm
83 
84 	.macro __THUNK_EX_BR reg,ruse
85 	# Be very careful when adding instructions to this macro!
86 	# The ALTERNATIVE replacement code has a .+10 which targets
87 	# the "br \reg" after the code has been patched.
88 #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
89 	exrl	0,555f
90 	j	.
91 #else
92 	.ifc \reg,%r1
93 	ALTERNATIVE "ex %r0,_LC_BR_R1", ".insn ril,0xc60000000000,0,.+10", 35
94 	j	.
95 	.else
96 	larl	\ruse,555f
97 	ex	0,0(\ruse)
98 	j	.
99 	.endif
100 #endif
101 555:	br	\reg
102 	.endm
103 
104 	.macro GEN_BR_THUNK reg,ruse=%r1
105 	__DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse
106 	__THUNK_EX_BR \reg,\ruse
107 	__THUNK_EPILOG
108 	.endm
109 
110 	.macro BR_EX reg,ruse=%r1
111 557:	__DECODE_RR __THUNK_BR,\reg,\ruse
112 	.pushsection .s390_indirect_branches,"a",@progbits
113 	.long	557b-.
114 	.popsection
115 	.endm
116 
117 	.macro BASR_EX rsave,rtarget,ruse=%r1
118 559:	__DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse
119 	.pushsection .s390_indirect_branches,"a",@progbits
120 	.long	559b-.
121 	.popsection
122 	.endm
123 
124 #else
125 	.macro GEN_BR_THUNK reg,ruse=%r1
126 	.endm
127 
128 	 .macro BR_EX reg,ruse=%r1
129 	br	\reg
130 	.endm
131 
132 	.macro BASR_EX rsave,rtarget,ruse=%r1
133 	basr	\rsave,\rtarget
134 	.endm
135 #endif
136 
137 #endif /* __ASSEMBLY__ */
138 
139 #endif /* _ASM_S390_NOSPEC_ASM_H */
140