162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * FP/SIMD state saving and restoring macros
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2012 ARM Ltd.
662306a36Sopenharmony_ci * Author: Catalin Marinas <catalin.marinas@arm.com>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <asm/assembler.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci.macro fpsimd_save state, tmpnr
1262306a36Sopenharmony_ci	stp	q0, q1, [\state, #16 * 0]
1362306a36Sopenharmony_ci	stp	q2, q3, [\state, #16 * 2]
1462306a36Sopenharmony_ci	stp	q4, q5, [\state, #16 * 4]
1562306a36Sopenharmony_ci	stp	q6, q7, [\state, #16 * 6]
1662306a36Sopenharmony_ci	stp	q8, q9, [\state, #16 * 8]
1762306a36Sopenharmony_ci	stp	q10, q11, [\state, #16 * 10]
1862306a36Sopenharmony_ci	stp	q12, q13, [\state, #16 * 12]
1962306a36Sopenharmony_ci	stp	q14, q15, [\state, #16 * 14]
2062306a36Sopenharmony_ci	stp	q16, q17, [\state, #16 * 16]
2162306a36Sopenharmony_ci	stp	q18, q19, [\state, #16 * 18]
2262306a36Sopenharmony_ci	stp	q20, q21, [\state, #16 * 20]
2362306a36Sopenharmony_ci	stp	q22, q23, [\state, #16 * 22]
2462306a36Sopenharmony_ci	stp	q24, q25, [\state, #16 * 24]
2562306a36Sopenharmony_ci	stp	q26, q27, [\state, #16 * 26]
2662306a36Sopenharmony_ci	stp	q28, q29, [\state, #16 * 28]
2762306a36Sopenharmony_ci	stp	q30, q31, [\state, #16 * 30]!
2862306a36Sopenharmony_ci	mrs	x\tmpnr, fpsr
2962306a36Sopenharmony_ci	str	w\tmpnr, [\state, #16 * 2]
3062306a36Sopenharmony_ci	mrs	x\tmpnr, fpcr
3162306a36Sopenharmony_ci	str	w\tmpnr, [\state, #16 * 2 + 4]
3262306a36Sopenharmony_ci.endm
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci.macro fpsimd_restore_fpcr state, tmp
3562306a36Sopenharmony_ci	/*
3662306a36Sopenharmony_ci	 * Writes to fpcr may be self-synchronising, so avoid restoring
3762306a36Sopenharmony_ci	 * the register if it hasn't changed.
3862306a36Sopenharmony_ci	 */
3962306a36Sopenharmony_ci	mrs	\tmp, fpcr
4062306a36Sopenharmony_ci	cmp	\tmp, \state
4162306a36Sopenharmony_ci	b.eq	9999f
4262306a36Sopenharmony_ci	msr	fpcr, \state
4362306a36Sopenharmony_ci9999:
4462306a36Sopenharmony_ci.endm
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* Clobbers \state */
4762306a36Sopenharmony_ci.macro fpsimd_restore state, tmpnr
4862306a36Sopenharmony_ci	ldp	q0, q1, [\state, #16 * 0]
4962306a36Sopenharmony_ci	ldp	q2, q3, [\state, #16 * 2]
5062306a36Sopenharmony_ci	ldp	q4, q5, [\state, #16 * 4]
5162306a36Sopenharmony_ci	ldp	q6, q7, [\state, #16 * 6]
5262306a36Sopenharmony_ci	ldp	q8, q9, [\state, #16 * 8]
5362306a36Sopenharmony_ci	ldp	q10, q11, [\state, #16 * 10]
5462306a36Sopenharmony_ci	ldp	q12, q13, [\state, #16 * 12]
5562306a36Sopenharmony_ci	ldp	q14, q15, [\state, #16 * 14]
5662306a36Sopenharmony_ci	ldp	q16, q17, [\state, #16 * 16]
5762306a36Sopenharmony_ci	ldp	q18, q19, [\state, #16 * 18]
5862306a36Sopenharmony_ci	ldp	q20, q21, [\state, #16 * 20]
5962306a36Sopenharmony_ci	ldp	q22, q23, [\state, #16 * 22]
6062306a36Sopenharmony_ci	ldp	q24, q25, [\state, #16 * 24]
6162306a36Sopenharmony_ci	ldp	q26, q27, [\state, #16 * 26]
6262306a36Sopenharmony_ci	ldp	q28, q29, [\state, #16 * 28]
6362306a36Sopenharmony_ci	ldp	q30, q31, [\state, #16 * 30]!
6462306a36Sopenharmony_ci	ldr	w\tmpnr, [\state, #16 * 2]
6562306a36Sopenharmony_ci	msr	fpsr, x\tmpnr
6662306a36Sopenharmony_ci	ldr	w\tmpnr, [\state, #16 * 2 + 4]
6762306a36Sopenharmony_ci	fpsimd_restore_fpcr x\tmpnr, \state
6862306a36Sopenharmony_ci.endm
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci/* Sanity-check macros to help avoid encoding garbage instructions */
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci.macro _check_general_reg nr
7362306a36Sopenharmony_ci	.if (\nr) < 0 || (\nr) > 30
7462306a36Sopenharmony_ci		.error "Bad register number \nr."
7562306a36Sopenharmony_ci	.endif
7662306a36Sopenharmony_ci.endm
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci.macro _sve_check_zreg znr
7962306a36Sopenharmony_ci	.if (\znr) < 0 || (\znr) > 31
8062306a36Sopenharmony_ci		.error "Bad Scalable Vector Extension vector register number \znr."
8162306a36Sopenharmony_ci	.endif
8262306a36Sopenharmony_ci.endm
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci.macro _sve_check_preg pnr
8562306a36Sopenharmony_ci	.if (\pnr) < 0 || (\pnr) > 15
8662306a36Sopenharmony_ci		.error "Bad Scalable Vector Extension predicate register number \pnr."
8762306a36Sopenharmony_ci	.endif
8862306a36Sopenharmony_ci.endm
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci.macro _check_num n, min, max
9162306a36Sopenharmony_ci	.if (\n) < (\min) || (\n) > (\max)
9262306a36Sopenharmony_ci		.error "Number \n out of range [\min,\max]"
9362306a36Sopenharmony_ci	.endif
9462306a36Sopenharmony_ci.endm
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci.macro _sme_check_wv v
9762306a36Sopenharmony_ci	.if (\v) < 12 || (\v) > 15
9862306a36Sopenharmony_ci		.error "Bad vector select register \v."
9962306a36Sopenharmony_ci	.endif
10062306a36Sopenharmony_ci.endm
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* SVE instruction encodings for non-SVE-capable assemblers */
10362306a36Sopenharmony_ci/* (pre binutils 2.28, all kernel capable clang versions support SVE) */
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/* STR (vector): STR Z\nz, [X\nxbase, #\offset, MUL VL] */
10662306a36Sopenharmony_ci.macro _sve_str_v nz, nxbase, offset=0
10762306a36Sopenharmony_ci	_sve_check_zreg \nz
10862306a36Sopenharmony_ci	_check_general_reg \nxbase
10962306a36Sopenharmony_ci	_check_num (\offset), -0x100, 0xff
11062306a36Sopenharmony_ci	.inst	0xe5804000			\
11162306a36Sopenharmony_ci		| (\nz)				\
11262306a36Sopenharmony_ci		| ((\nxbase) << 5)		\
11362306a36Sopenharmony_ci		| (((\offset) & 7) << 10)	\
11462306a36Sopenharmony_ci		| (((\offset) & 0x1f8) << 13)
11562306a36Sopenharmony_ci.endm
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci/* LDR (vector): LDR Z\nz, [X\nxbase, #\offset, MUL VL] */
11862306a36Sopenharmony_ci.macro _sve_ldr_v nz, nxbase, offset=0
11962306a36Sopenharmony_ci	_sve_check_zreg \nz
12062306a36Sopenharmony_ci	_check_general_reg \nxbase
12162306a36Sopenharmony_ci	_check_num (\offset), -0x100, 0xff
12262306a36Sopenharmony_ci	.inst	0x85804000			\
12362306a36Sopenharmony_ci		| (\nz)				\
12462306a36Sopenharmony_ci		| ((\nxbase) << 5)		\
12562306a36Sopenharmony_ci		| (((\offset) & 7) << 10)	\
12662306a36Sopenharmony_ci		| (((\offset) & 0x1f8) << 13)
12762306a36Sopenharmony_ci.endm
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci/* STR (predicate): STR P\np, [X\nxbase, #\offset, MUL VL] */
13062306a36Sopenharmony_ci.macro _sve_str_p np, nxbase, offset=0
13162306a36Sopenharmony_ci	_sve_check_preg \np
13262306a36Sopenharmony_ci	_check_general_reg \nxbase
13362306a36Sopenharmony_ci	_check_num (\offset), -0x100, 0xff
13462306a36Sopenharmony_ci	.inst	0xe5800000			\
13562306a36Sopenharmony_ci		| (\np)				\
13662306a36Sopenharmony_ci		| ((\nxbase) << 5)		\
13762306a36Sopenharmony_ci		| (((\offset) & 7) << 10)	\
13862306a36Sopenharmony_ci		| (((\offset) & 0x1f8) << 13)
13962306a36Sopenharmony_ci.endm
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci/* LDR (predicate): LDR P\np, [X\nxbase, #\offset, MUL VL] */
14262306a36Sopenharmony_ci.macro _sve_ldr_p np, nxbase, offset=0
14362306a36Sopenharmony_ci	_sve_check_preg \np
14462306a36Sopenharmony_ci	_check_general_reg \nxbase
14562306a36Sopenharmony_ci	_check_num (\offset), -0x100, 0xff
14662306a36Sopenharmony_ci	.inst	0x85800000			\
14762306a36Sopenharmony_ci		| (\np)				\
14862306a36Sopenharmony_ci		| ((\nxbase) << 5)		\
14962306a36Sopenharmony_ci		| (((\offset) & 7) << 10)	\
15062306a36Sopenharmony_ci		| (((\offset) & 0x1f8) << 13)
15162306a36Sopenharmony_ci.endm
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci/* RDVL X\nx, #\imm */
15462306a36Sopenharmony_ci.macro _sve_rdvl nx, imm
15562306a36Sopenharmony_ci	_check_general_reg \nx
15662306a36Sopenharmony_ci	_check_num (\imm), -0x20, 0x1f
15762306a36Sopenharmony_ci	.inst	0x04bf5000			\
15862306a36Sopenharmony_ci		| (\nx)				\
15962306a36Sopenharmony_ci		| (((\imm) & 0x3f) << 5)
16062306a36Sopenharmony_ci.endm
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci/* RDFFR (unpredicated): RDFFR P\np.B */
16362306a36Sopenharmony_ci.macro _sve_rdffr np
16462306a36Sopenharmony_ci	_sve_check_preg \np
16562306a36Sopenharmony_ci	.inst	0x2519f000			\
16662306a36Sopenharmony_ci		| (\np)
16762306a36Sopenharmony_ci.endm
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci/* WRFFR P\np.B */
17062306a36Sopenharmony_ci.macro _sve_wrffr np
17162306a36Sopenharmony_ci	_sve_check_preg \np
17262306a36Sopenharmony_ci	.inst	0x25289000			\
17362306a36Sopenharmony_ci		| ((\np) << 5)
17462306a36Sopenharmony_ci.endm
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci/* PFALSE P\np.B */
17762306a36Sopenharmony_ci.macro _sve_pfalse np
17862306a36Sopenharmony_ci	_sve_check_preg \np
17962306a36Sopenharmony_ci	.inst	0x2518e400			\
18062306a36Sopenharmony_ci		| (\np)
18162306a36Sopenharmony_ci.endm
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci/* SME instruction encodings for non-SME-capable assemblers */
18462306a36Sopenharmony_ci/* (pre binutils 2.38/LLVM 13) */
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci/* RDSVL X\nx, #\imm */
18762306a36Sopenharmony_ci.macro _sme_rdsvl nx, imm
18862306a36Sopenharmony_ci	_check_general_reg \nx
18962306a36Sopenharmony_ci	_check_num (\imm), -0x20, 0x1f
19062306a36Sopenharmony_ci	.inst	0x04bf5800			\
19162306a36Sopenharmony_ci		| (\nx)				\
19262306a36Sopenharmony_ci		| (((\imm) & 0x3f) << 5)
19362306a36Sopenharmony_ci.endm
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci/*
19662306a36Sopenharmony_ci * STR (vector from ZA array):
19762306a36Sopenharmony_ci *	STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
19862306a36Sopenharmony_ci */
19962306a36Sopenharmony_ci.macro _sme_str_zav nw, nxbase, offset=0
20062306a36Sopenharmony_ci	_sme_check_wv \nw
20162306a36Sopenharmony_ci	_check_general_reg \nxbase
20262306a36Sopenharmony_ci	_check_num (\offset), -0x100, 0xff
20362306a36Sopenharmony_ci	.inst	0xe1200000			\
20462306a36Sopenharmony_ci		| (((\nw) & 3) << 13)		\
20562306a36Sopenharmony_ci		| ((\nxbase) << 5)		\
20662306a36Sopenharmony_ci		| ((\offset) & 7)
20762306a36Sopenharmony_ci.endm
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci/*
21062306a36Sopenharmony_ci * LDR (vector to ZA array):
21162306a36Sopenharmony_ci *	LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
21262306a36Sopenharmony_ci */
21362306a36Sopenharmony_ci.macro _sme_ldr_zav nw, nxbase, offset=0
21462306a36Sopenharmony_ci	_sme_check_wv \nw
21562306a36Sopenharmony_ci	_check_general_reg \nxbase
21662306a36Sopenharmony_ci	_check_num (\offset), -0x100, 0xff
21762306a36Sopenharmony_ci	.inst	0xe1000000			\
21862306a36Sopenharmony_ci		| (((\nw) & 3) << 13)		\
21962306a36Sopenharmony_ci		| ((\nxbase) << 5)		\
22062306a36Sopenharmony_ci		| ((\offset) & 7)
22162306a36Sopenharmony_ci.endm
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci/*
22462306a36Sopenharmony_ci * LDR (ZT0)
22562306a36Sopenharmony_ci *
22662306a36Sopenharmony_ci *	LDR ZT0, nx
22762306a36Sopenharmony_ci */
22862306a36Sopenharmony_ci.macro _ldr_zt nx
22962306a36Sopenharmony_ci	_check_general_reg \nx
23062306a36Sopenharmony_ci	.inst	0xe11f8000	\
23162306a36Sopenharmony_ci		 | (\nx << 5)
23262306a36Sopenharmony_ci.endm
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci/*
23562306a36Sopenharmony_ci * STR (ZT0)
23662306a36Sopenharmony_ci *
23762306a36Sopenharmony_ci *	STR ZT0, nx
23862306a36Sopenharmony_ci */
23962306a36Sopenharmony_ci.macro _str_zt nx
24062306a36Sopenharmony_ci	_check_general_reg \nx
24162306a36Sopenharmony_ci	.inst	0xe13f8000		\
24262306a36Sopenharmony_ci		| (\nx << 5)
24362306a36Sopenharmony_ci.endm
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci/*
24662306a36Sopenharmony_ci * Zero the entire ZA array
24762306a36Sopenharmony_ci *	ZERO ZA
24862306a36Sopenharmony_ci */
24962306a36Sopenharmony_ci.macro zero_za
25062306a36Sopenharmony_ci	.inst 0xc00800ff
25162306a36Sopenharmony_ci.endm
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci.macro __for from:req, to:req
25462306a36Sopenharmony_ci	.if (\from) == (\to)
25562306a36Sopenharmony_ci		_for__body %\from
25662306a36Sopenharmony_ci	.else
25762306a36Sopenharmony_ci		__for %\from, %((\from) + ((\to) - (\from)) / 2)
25862306a36Sopenharmony_ci		__for %((\from) + ((\to) - (\from)) / 2 + 1), %\to
25962306a36Sopenharmony_ci	.endif
26062306a36Sopenharmony_ci.endm
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci.macro _for var:req, from:req, to:req, insn:vararg
26362306a36Sopenharmony_ci	.macro _for__body \var:req
26462306a36Sopenharmony_ci		.noaltmacro
26562306a36Sopenharmony_ci		\insn
26662306a36Sopenharmony_ci		.altmacro
26762306a36Sopenharmony_ci	.endm
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	.altmacro
27062306a36Sopenharmony_ci	__for \from, \to
27162306a36Sopenharmony_ci	.noaltmacro
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	.purgem _for__body
27462306a36Sopenharmony_ci.endm
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci/* Update ZCR_EL1.LEN with the new VQ */
27762306a36Sopenharmony_ci.macro sve_load_vq xvqminus1, xtmp, xtmp2
27862306a36Sopenharmony_ci		mrs_s		\xtmp, SYS_ZCR_EL1
27962306a36Sopenharmony_ci		bic		\xtmp2, \xtmp, ZCR_ELx_LEN_MASK
28062306a36Sopenharmony_ci		orr		\xtmp2, \xtmp2, \xvqminus1
28162306a36Sopenharmony_ci		cmp		\xtmp2, \xtmp
28262306a36Sopenharmony_ci		b.eq		921f
28362306a36Sopenharmony_ci		msr_s		SYS_ZCR_EL1, \xtmp2	//self-synchronising
28462306a36Sopenharmony_ci921:
28562306a36Sopenharmony_ci.endm
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci/* Update SMCR_EL1.LEN with the new VQ */
28862306a36Sopenharmony_ci.macro sme_load_vq xvqminus1, xtmp, xtmp2
28962306a36Sopenharmony_ci		mrs_s		\xtmp, SYS_SMCR_EL1
29062306a36Sopenharmony_ci		bic		\xtmp2, \xtmp, SMCR_ELx_LEN_MASK
29162306a36Sopenharmony_ci		orr		\xtmp2, \xtmp2, \xvqminus1
29262306a36Sopenharmony_ci		cmp		\xtmp2, \xtmp
29362306a36Sopenharmony_ci		b.eq		921f
29462306a36Sopenharmony_ci		msr_s		SYS_SMCR_EL1, \xtmp2	//self-synchronising
29562306a36Sopenharmony_ci921:
29662306a36Sopenharmony_ci.endm
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci/* Preserve the first 128-bits of Znz and zero the rest. */
29962306a36Sopenharmony_ci.macro _sve_flush_z nz
30062306a36Sopenharmony_ci	_sve_check_zreg \nz
30162306a36Sopenharmony_ci	mov	v\nz\().16b, v\nz\().16b
30262306a36Sopenharmony_ci.endm
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci.macro sve_flush_z
30562306a36Sopenharmony_ci _for n, 0, 31, _sve_flush_z	\n
30662306a36Sopenharmony_ci.endm
30762306a36Sopenharmony_ci.macro sve_flush_p
30862306a36Sopenharmony_ci _for n, 0, 15, _sve_pfalse	\n
30962306a36Sopenharmony_ci.endm
31062306a36Sopenharmony_ci.macro sve_flush_ffr
31162306a36Sopenharmony_ci		_sve_wrffr	0
31262306a36Sopenharmony_ci.endm
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci.macro sve_save nxbase, xpfpsr, save_ffr, nxtmp
31562306a36Sopenharmony_ci _for n, 0, 31,	_sve_str_v	\n, \nxbase, \n - 34
31662306a36Sopenharmony_ci _for n, 0, 15,	_sve_str_p	\n, \nxbase, \n - 16
31762306a36Sopenharmony_ci		cbz		\save_ffr, 921f
31862306a36Sopenharmony_ci		_sve_rdffr	0
31962306a36Sopenharmony_ci		b		922f
32062306a36Sopenharmony_ci921:
32162306a36Sopenharmony_ci		_sve_pfalse	0			// Zero out FFR
32262306a36Sopenharmony_ci922:
32362306a36Sopenharmony_ci		_sve_str_p	0, \nxbase
32462306a36Sopenharmony_ci		_sve_ldr_p	0, \nxbase, -16
32562306a36Sopenharmony_ci		mrs		x\nxtmp, fpsr
32662306a36Sopenharmony_ci		str		w\nxtmp, [\xpfpsr]
32762306a36Sopenharmony_ci		mrs		x\nxtmp, fpcr
32862306a36Sopenharmony_ci		str		w\nxtmp, [\xpfpsr, #4]
32962306a36Sopenharmony_ci.endm
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci.macro sve_load nxbase, xpfpsr, restore_ffr, nxtmp
33262306a36Sopenharmony_ci _for n, 0, 31,	_sve_ldr_v	\n, \nxbase, \n - 34
33362306a36Sopenharmony_ci		cbz		\restore_ffr, 921f
33462306a36Sopenharmony_ci		_sve_ldr_p	0, \nxbase
33562306a36Sopenharmony_ci		_sve_wrffr	0
33662306a36Sopenharmony_ci921:
33762306a36Sopenharmony_ci _for n, 0, 15,	_sve_ldr_p	\n, \nxbase, \n - 16
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci		ldr		w\nxtmp, [\xpfpsr]
34062306a36Sopenharmony_ci		msr		fpsr, x\nxtmp
34162306a36Sopenharmony_ci		ldr		w\nxtmp, [\xpfpsr, #4]
34262306a36Sopenharmony_ci		msr		fpcr, x\nxtmp
34362306a36Sopenharmony_ci.endm
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci.macro sme_save_za nxbase, xvl, nw
34662306a36Sopenharmony_ci	mov	w\nw, #0
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci423:
34962306a36Sopenharmony_ci	_sme_str_zav \nw, \nxbase
35062306a36Sopenharmony_ci	add	x\nxbase, x\nxbase, \xvl
35162306a36Sopenharmony_ci	add	x\nw, x\nw, #1
35262306a36Sopenharmony_ci	cmp	\xvl, x\nw
35362306a36Sopenharmony_ci	bne	423b
35462306a36Sopenharmony_ci.endm
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci.macro sme_load_za nxbase, xvl, nw
35762306a36Sopenharmony_ci	mov	w\nw, #0
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci423:
36062306a36Sopenharmony_ci	_sme_ldr_zav \nw, \nxbase
36162306a36Sopenharmony_ci	add	x\nxbase, x\nxbase, \xvl
36262306a36Sopenharmony_ci	add	x\nw, x\nw, #1
36362306a36Sopenharmony_ci	cmp	\xvl, x\nw
36462306a36Sopenharmony_ci	bne	423b
36562306a36Sopenharmony_ci.endm
366