Sound Open Firmware
Loading...
Searching...
No Matches
esp32p4_pie.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2026 Sound Open Firmware (SOF) Project
4 *
5 * Author: Antigravity AI / SOF Team
6 */
7
8#ifndef __SOF_MATH_ESP32P4_PIE_H__
9#define __SOF_MATH_ESP32P4_PIE_H__
10
11#include <stdint.h>
12#include <stdbool.h>
13
14#if defined(CONFIG_SOC_SERIES_ESP32P4) || defined(CONFIG_ESP32P4_PIE_SIMD)
15
16/*
17 * ESP32-P4 Processor Instruction Extensions (PIE / Xespv2p2) 128-bit SIMD.
18 *
19 * To ensure 100% build compatibility with the upstream Zephyr SDK GCC
20 * (which lacks custom -march=xesppie assembler recognition), all PIE
21 * instructions are implemented using native 32-bit machine word directives (.word).
22 *
23 * Register mapping conventions:
24 * q0..q7 : 128-bit vector registers (16x8b, 8x16b, or 4x32b)
25 * QACC : 256-bit accumulator pair (QACC_H / QACC_L)
26 * SAR : 6-bit Shift Amount Register
27 * a0 : Source pointer (incremented by 16 bytes on vld.128.ip)
28 * a2 : Broadcast scalar / control value
29 */
30
31/* Zeroing */
32#define ESP_PIE_ZERO_Q0() __asm__ volatile (".word 0x0040005b") /* esp.zero.q q0 */
33#define ESP_PIE_ZERO_Q1() __asm__ volatile (".word 0x004000db") /* esp.zero.q q1 */
34#define ESP_PIE_ZERO_Q2() __asm__ volatile (".word 0x0040015b") /* esp.zero.q q2 */
35#define ESP_PIE_ZERO_Q3() __asm__ volatile (".word 0x004001db") /* esp.zero.q q3 */
36#define ESP_PIE_ZERO_QACC() __asm__ volatile (".word 0x0000025b") /* esp.zero.qacc */
37
38/* Vector Load 128-bit (16 bytes) with address post-increment (+16) on a0 */
39#define ESP_PIE_VLD_128_IP_Q0_A0() \
40 __asm__ volatile (".word 0x0201223b" : "+r"(src_a0) :: "memory") /* esp.vld.128.ip q0, a0, 16 */
41
42#define ESP_PIE_VLD_128_IP_Q1_A0() \
43 __asm__ volatile (".word 0x0201263b" : "+r"(src_a0) :: "memory") /* esp.vld.128.ip q1, a0, 16 */
44
45#define ESP_PIE_VLD_128_IP_Q2_A0() \
46 __asm__ volatile (".word 0x02012a3b" : "+r"(src_a0) :: "memory") /* esp.vld.128.ip q2, a0, 16 */
47
48/* Vector Store 128-bit (16 bytes) with address post-increment (+16) on a1 */
49#define ESP_PIE_VST_128_IP_Q0_A1() \
50 __asm__ volatile (".word 0x8201a23b" : "+r"(dst_a1) :: "memory") /* esp.vst.128.ip q0, a1, 16 */
51
52#define ESP_PIE_VST_128_IP_Q1_A1() \
53 __asm__ volatile (".word 0x8201a63b" : "+r"(dst_a1) :: "memory") /* esp.vst.128.ip q1, a1, 16 */
54
55/* Broadcast 16-bit scalar from address at a2 to all 8 lanes of q2 */
56#define ESP_PIE_VLDBC_16_IP_Q2_A2() \
57 __asm__ volatile (".word 0x8602283b" : "+r"(bc_a2) :: "memory") /* esp.vldbc.16.ip q2, a2, 0 */
58
59/* Broadcast 32-bit packed stereo [L, R] scalar from address at a2 to all 4 stereo pairs in q2 */
60#define ESP_PIE_VLDBC_32_IP_Q2_A2() \
61 __asm__ volatile (".word 0x0e02283b" : "+r"(bc_a2) :: "memory") /* esp.vldbc.32.ip q2, a2, 0 */
62
63/* Vector Multiplication signed 16-bit: product shifted right by SAR, lower 16 bits retained */
64#define ESP_PIE_VMUL_S16_Q0_Q0_Q2() __asm__ volatile (".word 0x0806bc5f") /* esp.vmul.s16 q0, q0, q2 */
65#define ESP_PIE_VMUL_S16_Q1_Q1_Q2() __asm__ volatile (".word 0x2806bcdf") /* esp.vmul.s16 q1, q1, q2 */
66#define ESP_PIE_VMUL_S16_Q0_Q0_Q1() __asm__ volatile (".word 0x0406bc5f") /* esp.vmul.s16 q0, q0, q1 */
67
68/* Vector Add signed 16-bit elements */
69#define ESP_PIE_VADD_S16_Q0_Q0_Q1() __asm__ volatile (".word 0x0684065f") /* esp.vadd.s16 q0, q0, q1 */
70#define ESP_PIE_VADD_S16_Q0_Q1_Q2() __asm__ volatile (".word 0x2a84065f") /* esp.vadd.s16 q0, q1, q2 */
71
72/* Vector Sub signed 16-bit elements */
73#define ESP_PIE_VSUB_S16_Q0_Q0_Q1() __asm__ volatile (".word 0x068406df") /* esp.vsub.s16 q0, q0, q1 */
74#define ESP_PIE_VSUB_S16_Q0_Q1_Q2() __asm__ volatile (".word 0x2a8406df") /* esp.vsub.s16 q0, q1, q2 */
75
76/* Vector Clamp signed 16-bit elements to signed 16-bit PCM range [-32768, 32767] (imm=15) */
77#define ESP_PIE_VCLAMP_S16_Q0_Q0() __asm__ volatile (".word 0x030c505b") /* esp.vclamp.s16 q0, q0, 15 */
78#define ESP_PIE_VCLAMP_S16_Q0_Q1() __asm__ volatile (".word 0x230c505b") /* esp.vclamp.s16 q0, q1, 15 */
79#define ESP_PIE_VCLAMP_S16_Q1_Q1() __asm__ volatile (".word 0x230c50db") /* esp.vclamp.s16 q1, q1, 15 */
80
81/* Vector Interleave (Zip) and Deinterleave (Unzip) 16-bit elements */
82#define ESP_PIE_VZIP_16_Q0_Q1() __asm__ volatile (".word 0x0682005f") /* esp.vzip.16 q0, q1 */
83#define ESP_PIE_VUNZIP_16_Q0_Q1() __asm__ volatile (".word 0x0686005f") /* esp.vunzip.16 q0, q1 */
84#define ESP_PIE_VZIP_16_Q2_Q3() __asm__ volatile (".word 0x4e82005f") /* esp.vzip.16 q2, q3 */
85#define ESP_PIE_VUNZIP_16_Q2_Q3() __asm__ volatile (".word 0x4e86005f") /* esp.vunzip.16 q2, q3 */
86
87/* Shift Amount Register (SAR) and CFG configuration */
88static inline void esp_pie_set_sar(uint32_t sar)
89{
90 register uint32_t sar_reg asm("a0") = sar;
91 __asm__ volatile (".word 0x90b1005f" : "+r"(sar_reg) : : "memory");
92}
93#define ESP_PIE_SET_SAR(sar) esp_pie_set_sar(sar)
94#define ESP_PIE_SET_SAR_A0() esp_pie_set_sar(15)
95#define ESP_PIE_SET_SAR_A2() __asm__ volatile (".word 0x90b2005f" :: "r"(sar_a2)) /* esp.movx.w.sar a2 */
96#define ESP_PIE_SET_CFG_A0() __asm__ volatile (".word 0x90d1005f" :: "r"(cfg_a0)) /* esp.movx.w.cfg a0 */
97
98/* Vector Right Shift 32-bit elements by SAR */
99#define ESP_PIE_VSR_S32_Q0_Q1() __asm__ volatile (".word 0x8404035b") /* esp.vsr.s32 q0, q1 */
100#define ESP_PIE_VSR_S32_Q0_Q0() __asm__ volatile (".word 0x8004035b") /* esp.vsr.s32 q0, q0 */
101
102/* Vector Unzip & Truncate (Pack 32-bit lanes from q1, q2 into 16-bit lanes in q0) */
103#define ESP_PIE_VUNZIPT_16_Q0_Q1_Q2() __asm__ volatile (".word 0x06c04c5b") /* esp.vunzipt.16 q0, q1, q2 */
104#define ESP_PIE_VUNZIPT_16_Q0_Q0_Q1() __asm__ volatile (".word 0x01c04c5b") /* esp.vunzipt.16 q0, q0, q1 */
105
106#endif /* CONFIG_SOC_SERIES_ESP32P4 || CONFIG_ESP32P4_PIE_SIMD */
107
108#endif /* __SOF_MATH_ESP32P4_PIE_H__ */