blob: 37a6a63ea2dded8c279d34efe0d66fce2937edc2 [file] [log] [blame] [edit]
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* s390x assembly macros
*
* Copyright (c) 2017 Red Hat Inc
* Copyright (c) 2020 IBM Corp.
*
* Authors:
* Pierre Morel <pmorel@linux.ibm.com>
* David Hildenbrand <david@redhat.com>
*/
#include <asm/asm-offsets.h>
.macro SAVE_REGS
/* save grs 0-15 */
stmg %r0, %r15, GEN_LC_SW_INT_GRS
/* save crs 0-15 */
stctg %c0, %c15, GEN_LC_SW_INT_CRS
/* load a cr0 that has the AFP control bit which enables all FPRs */
larl %r1, initial_cr0
lctlg %c0, %c0, 0(%r1)
/* save fprs 0-15 + fpc */
la %r1, GEN_LC_SW_INT_FPRS
.irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
std \i, \i * 8(%r1)
.endr
stfpc GEN_LC_SW_INT_FPC
.endm
.macro RESTORE_REGS
/* restore fprs 0-15 + fpc */
la %r1, GEN_LC_SW_INT_FPRS
.irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
ld \i, \i * 8(%r1)
.endr
lfpc GEN_LC_SW_INT_FPC
/* restore crs 0-15 */
lctlg %c0, %c15, GEN_LC_SW_INT_CRS
/* restore grs 0-15 */
lmg %r0, %r15, GEN_LC_SW_INT_GRS
.endm
/* Save registers on the stack (r15), so we can have stacked interrupts. */
.macro SAVE_REGS_STACK
/* Allocate a stack frame for 15 general registers */
slgfi %r15, 15 * 8
/* Store registers r0 to r14 on the stack */
stmg %r0, %r14, 0(%r15)
/* Allocate a stack frame for 16 floating point registers */
/* The size of a FP register is the size of an double word */
slgfi %r15, 16 * 8
/* Save fp register on stack: offset to SP is multiple of reg number */
.irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
std \i, \i * 8(%r15)
.endr
/* Save fpc, but keep stack aligned on 64bits */
slgfi %r15, 8
efpc %r0
stg %r0, 0(%r15)
.endm
/* Restore the register in reverse order */
.macro RESTORE_REGS_STACK
/* Restore fpc */
lfpc 0(%r15)
algfi %r15, 8
/* Restore fp register from stack: SP still where it was left */
/* and offset to SP is a multiple of reg number */
.irp i, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
ld \i, \i * 8(%r15)
.endr
/* Now that we're done, rewind the stack pointer by 16 double word */
algfi %r15, 16 * 8
/* Load the registers from stack */
lmg %r0, %r14, 0(%r15)
/* Rewind the stack by 15 double word */
algfi %r15, 15 * 8
.endm