blob: af6c1b34be356f4a93d6a564feb122cdefeca384 [file] [log] [blame]
/*
* Copyright (c) 2021-2023, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <assert_macros.S>
.arch armv8-a+sve
.globl sme_rdsvl_1
.globl sme_try_illegal_instruction
.globl sme_vector_to_ZA
.globl sme_ZA_to_vector
/*
* TODO: Due to the limitation with toolchain, SME intrinsics, still not being
* supported, instructions are manually encoded using the opcodes.
* Further, when the toolchain supports the requirements, these macros could
* be refactored.
*/
/*
* LDR (Loads a vector (an array of elements ) to ZA array ):
* LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
*
* Arguments/Opcode bit field:
* nw : the vector select register W12-W15
* nxbase : 64-bit name of the general-purpose base register.
* offset : vector select and optional memory offset. Default to 0.
*/
.macro _ldr_za nw, nxbase, offset=0
.inst 0xe1000000 \
| (((\nw) & 3) << 13) \
| ((\nxbase) << 5) \
| ((\offset) & 0xf)
.endm
/*
* STR ( It stores an array of elements from ZA array to a vector ).
* STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
*
* Arguments/Opcode bit field:
* nw : the vector select register W12-W15
* nxbase : 64-bit name of the general-purpose base register.
* offset : vector select and optional memory offset. Default to 0.
*/
.macro _str_za nw, nxbase, offset=0
.inst 0xe1200000 \
| (((\nw) & 3) << 13) \
| ((\nxbase) << 5) \
| ((\offset) & 0xf)
.endm
/*
* RDSVL - Read multiple of Streaming SVE vector register size to scalar register
* RDSVL <Xd>, #<imm>
*
* Arguments/Opcode bit field:
* Xd : 64-bit name of the general-purpose base register.
* imm : signed immediate operand (imm6)
*/
.macro _sme_rdsvl xd, imm
.inst 0x04bf5800 \
| (((\imm) & 0x3f) << 5) \
| (\xd)
.endm
/*
* uint64_t sme_rdsvl_1(void);
*
* Run rdsvl instruction with imm #1.
*/
func sme_rdsvl_1
_sme_rdsvl 0, 1
ret
endfunc sme_rdsvl_1
/*
* void sme_try_illegal_instruction(void);
*
* This function tests that illegal instructions are allowed to run when
* FA64 is supported. RDFFR is explicitly stated to be illegal in the SME
* specification section F1.1.2 unless FA64 is supported and enabled.
*/
func sme_try_illegal_instruction
rdffr p0.b
ret
endfunc sme_try_illegal_instruction
/**
* void sme_vector_to_ZA(uint64_t *input_vec)
*
* This function loads an vector of elements to an ZA Array storage
*/
func sme_vector_to_ZA
mov w12, wzr
_ldr_za 12, 0 // ZA.H[W12] loaded from [X0 / input_vector]
ret
endfunc sme_vector_to_ZA
/**
* void sme_ZA_to_vector(uint64_t *out_vec)
*
* This function stores elements from ZA Array storage to an ZA vector
*/
func sme_ZA_to_vector
mov w12, wzr
_str_za 12, 0 // ZA.H[W12] stored to [X0 / out_vector]
ret
endfunc sme_ZA_to_vector