196 lines
3.8 KiB
C
196 lines
3.8 KiB
C
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||
|
#ifndef _ASM_S390_NOSPEC_ASM_H
|
||
|
#define _ASM_S390_NOSPEC_ASM_H
|
||
|
|
||
|
#include <asm/alternative-asm.h>
|
||
|
#include <asm/asm-offsets.h>
|
||
|
|
||
|
#ifdef __ASSEMBLY__
|
||
|
|
||
|
#ifdef CONFIG_EXPOLINE
|
||
|
|
||
|
_LC_BR_R1 = __LC_BR_R1
|
||
|
|
||
|
/*
|
||
|
* The expoline macros are used to create thunks in the same format
|
||
|
* as gcc generates them. The 'comdat' section flag makes sure that
|
||
|
* the various thunks are merged into a single copy.
|
||
|
*/
|
||
|
.macro __THUNK_PROLOG_NAME name
|
||
|
.pushsection .text.\name,"axG",@progbits,\name,comdat
|
||
|
.globl \name
|
||
|
.hidden \name
|
||
|
.type \name,@function
|
||
|
\name:
|
||
|
.cfi_startproc
|
||
|
.endm
|
||
|
|
||
|
.macro __THUNK_EPILOG
|
||
|
.cfi_endproc
|
||
|
.popsection
|
||
|
.endm
|
||
|
|
||
|
.macro __THUNK_PROLOG_BR r1,r2
|
||
|
__THUNK_PROLOG_NAME __s390x_indirect_jump_r\r2\()use_r\r1
|
||
|
.endm
|
||
|
|
||
|
.macro __THUNK_PROLOG_BC d0,r1,r2
|
||
|
__THUNK_PROLOG_NAME __s390x_indirect_branch_\d0\()_\r2\()use_\r1
|
||
|
.endm
|
||
|
|
||
|
.macro __THUNK_BR r1,r2
|
||
|
jg __s390x_indirect_jump_r\r2\()use_r\r1
|
||
|
.endm
|
||
|
|
||
|
.macro __THUNK_BC d0,r1,r2
|
||
|
jg __s390x_indirect_branch_\d0\()_\r2\()use_\r1
|
||
|
.endm
|
||
|
|
||
|
.macro __THUNK_BRASL r1,r2,r3
|
||
|
brasl \r1,__s390x_indirect_jump_r\r3\()use_r\r2
|
||
|
.endm
|
||
|
|
||
|
.macro __DECODE_RR expand,reg,ruse
|
||
|
.set __decode_fail,1
|
||
|
.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||
|
.ifc \reg,%r\r1
|
||
|
.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||
|
.ifc \ruse,%r\r2
|
||
|
\expand \r1,\r2
|
||
|
.set __decode_fail,0
|
||
|
.endif
|
||
|
.endr
|
||
|
.endif
|
||
|
.endr
|
||
|
.if __decode_fail == 1
|
||
|
.error "__DECODE_RR failed"
|
||
|
.endif
|
||
|
.endm
|
||
|
|
||
|
.macro __DECODE_RRR expand,rsave,rtarget,ruse
|
||
|
.set __decode_fail,1
|
||
|
.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||
|
.ifc \rsave,%r\r1
|
||
|
.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||
|
.ifc \rtarget,%r\r2
|
||
|
.irp r3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||
|
.ifc \ruse,%r\r3
|
||
|
\expand \r1,\r2,\r3
|
||
|
.set __decode_fail,0
|
||
|
.endif
|
||
|
.endr
|
||
|
.endif
|
||
|
.endr
|
||
|
.endif
|
||
|
.endr
|
||
|
.if __decode_fail == 1
|
||
|
.error "__DECODE_RRR failed"
|
||
|
.endif
|
||
|
.endm
|
||
|
|
||
|
.macro __DECODE_DRR expand,disp,reg,ruse
|
||
|
.set __decode_fail,1
|
||
|
.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||
|
.ifc \reg,%r\r1
|
||
|
.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
||
|
.ifc \ruse,%r\r2
|
||
|
\expand \disp,\r1,\r2
|
||
|
.set __decode_fail,0
|
||
|
.endif
|
||
|
.endr
|
||
|
.endif
|
||
|
.endr
|
||
|
.if __decode_fail == 1
|
||
|
.error "__DECODE_DRR failed"
|
||
|
.endif
|
||
|
.endm
|
||
|
|
||
|
.macro __THUNK_EX_BR reg,ruse
|
||
|
# Be very careful when adding instructions to this macro!
|
||
|
# The ALTERNATIVE replacement code has a .+10 which targets
|
||
|
# the "br \reg" after the code has been patched.
|
||
|
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
|
||
|
exrl 0,555f
|
||
|
j .
|
||
|
#else
|
||
|
.ifc \reg,%r1
|
||
|
ALTERNATIVE "ex %r0,_LC_BR_R1", ".insn ril,0xc60000000000,0,.+10", 35
|
||
|
j .
|
||
|
.else
|
||
|
larl \ruse,555f
|
||
|
ex 0,0(\ruse)
|
||
|
j .
|
||
|
.endif
|
||
|
#endif
|
||
|
555: br \reg
|
||
|
.endm
|
||
|
|
||
|
.macro __THUNK_EX_BC disp,reg,ruse
|
||
|
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
|
||
|
exrl 0,556f
|
||
|
j .
|
||
|
#else
|
||
|
larl \ruse,556f
|
||
|
ex 0,0(\ruse)
|
||
|
j .
|
||
|
#endif
|
||
|
556: b \disp(\reg)
|
||
|
.endm
|
||
|
|
||
|
.macro GEN_BR_THUNK reg,ruse=%r1
|
||
|
__DECODE_RR __THUNK_PROLOG_BR,\reg,\ruse
|
||
|
__THUNK_EX_BR \reg,\ruse
|
||
|
__THUNK_EPILOG
|
||
|
.endm
|
||
|
|
||
|
.macro GEN_B_THUNK disp,reg,ruse=%r1
|
||
|
__DECODE_DRR __THUNK_PROLOG_BC,\disp,\reg,\ruse
|
||
|
__THUNK_EX_BC \disp,\reg,\ruse
|
||
|
__THUNK_EPILOG
|
||
|
.endm
|
||
|
|
||
|
.macro BR_EX reg,ruse=%r1
|
||
|
557: __DECODE_RR __THUNK_BR,\reg,\ruse
|
||
|
.pushsection .s390_indirect_branches,"a",@progbits
|
||
|
.long 557b-.
|
||
|
.popsection
|
||
|
.endm
|
||
|
|
||
|
.macro B_EX disp,reg,ruse=%r1
|
||
|
558: __DECODE_DRR __THUNK_BC,\disp,\reg,\ruse
|
||
|
.pushsection .s390_indirect_branches,"a",@progbits
|
||
|
.long 558b-.
|
||
|
.popsection
|
||
|
.endm
|
||
|
|
||
|
.macro BASR_EX rsave,rtarget,ruse=%r1
|
||
|
559: __DECODE_RRR __THUNK_BRASL,\rsave,\rtarget,\ruse
|
||
|
.pushsection .s390_indirect_branches,"a",@progbits
|
||
|
.long 559b-.
|
||
|
.popsection
|
||
|
.endm
|
||
|
|
||
|
#else
|
||
|
.macro GEN_BR_THUNK reg,ruse=%r1
|
||
|
.endm
|
||
|
|
||
|
.macro GEN_B_THUNK disp,reg,ruse=%r1
|
||
|
.endm
|
||
|
|
||
|
.macro BR_EX reg,ruse=%r1
|
||
|
br \reg
|
||
|
.endm
|
||
|
|
||
|
.macro B_EX disp,reg,ruse=%r1
|
||
|
b \disp(\reg)
|
||
|
.endm
|
||
|
|
||
|
.macro BASR_EX rsave,rtarget,ruse=%r1
|
||
|
basr \rsave,\rtarget
|
||
|
.endm
|
||
|
#endif
|
||
|
|
||
|
#endif /* __ASSEMBLY__ */
|
||
|
|
||
|
#endif /* _ASM_S390_NOSPEC_ASM_H */
|