Repository navigation
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The optimized paths contain build failures, unsupported dispatch gaps, arithmetic errors, and potential buffer overflow.
10 open findings
Use wide accumulators for parallel biquad branches · New Remove or implement undeclared float IIR state · New Use size_t for buffer sample counts · New Use 64-bit multiplication for IPC3 volume scaling · New Include math.h for fabsf declarations · New Gate ARM DSP assembly on __ARM_FEATURE_DSP · New Add missing non-ARM DSP primitive fallbacks · New Wrap second delay insertion independently · New Handle INT32_MIN in S16 detector absolute value · New Preserve generic PCM conversion mappings on ARM · New
What changed in this PR
Adds ARM Cortex-M DSP/SIMD implementations for audio processing and fixed-point math, with Kconfig and build-system dispatch.
Changes:
- Adds ARM DSP primitives and optimized FIR/IIR kernels.
- Accelerates volume, EQ, DRC, mixer, DC-block, level-multiplier, and PCM conversion paths.
- Adds ARM-specific configuration and source selection.
| File | Description |
|---|---|
src/math/Kconfig.simd |
Adds ARM filter selection. |
src/math/Kconfig |
Adds ARM IIR/FIR configuration. |
src/math/iir_df2t_arm.c |
Implements ARM DF2T filtering. |
src/math/iir_df1_arm.c |
Implements ARM DF1 filtering. |
src/math/fir_arm.c |
Implements ARM FIR kernels. |
src/math/CMakeLists.txt |
Builds ARM math sources. |
src/include/sof/math/iir_df2t.h |
Dispatches ARM DF2T helpers. |
src/include/sof/math/iir_df2t_arm.h |
Adds ARM DF2T format wrappers. |
src/include/sof/math/iir_df1.h |
Dispatches ARM DF1 helpers. |
src/include/sof/math/iir_df1_arm.h |
Adds ARM DF1 format wrappers. |
src/include/sof/math/fir_generic.h |
Exposes FIR declarations for ARM. |
src/include/sof/common.h |
Adds ARM optimization macros. |
src/include/sof/audio/pcm_converter.h |
Selects ARM PCM conversion. |
src/include/sof/audio/arm_simd.h |
Adds ARM DSP primitives. |
src/audio/volume/volume_arm.c |
Adds ARM volume scaling. |
src/audio/volume/volume_arm_with_peakvol.c |
Adds ARM scaling with metering. |
src/audio/volume/Kconfig.simd |
Configures ARM volume SIMD. |
src/audio/volume/CMakeLists.txt |
Selects ARM volume sources. |
src/audio/pcm_converter/pcm_converter_arm.c |
Adds ARM PCM conversions. |
src/audio/pcm_converter/CMakeLists.txt |
Builds ARM PCM converter. |
src/audio/mixin_mixout/mixin_mixout_generic.c |
Excludes generic ARM path. |
src/audio/mixin_mixout/mixin_mixout_arm.c |
Adds ARM mixin/mixout processing. |
src/audio/mixin_mixout/Kconfig |
Configures ARM mixin/mixout. |
src/audio/mixin_mixout/CMakeLists.txt |
Builds ARM mixin/mixout. |
src/audio/mixer/mixer.h |
Selects ARM mixer implementation. |
src/audio/mixer/mixer_arm.c |
Adds ARM mixer kernels. |
src/audio/mixer/Kconfig |
Configures ARM mixer. |
src/audio/mixer/CMakeLists.txt |
Builds ARM mixer. |
src/audio/level_multiplier/level_multiplier-generic.c |
Excludes generic ARM path. |
src/audio/level_multiplier/level_multiplier-arm.c |
Adds ARM gain scaling. |
src/audio/level_multiplier/CMakeLists.txt |
Builds ARM level multiplier. |
src/audio/Kconfig |
Configures ARM format conversion. |
src/audio/eq_iir/Kconfig.simd |
Configures ARM EQ IIR. |
src/audio/eq_iir/Kconfig |
Includes SIMD configuration. |
src/audio/eq_iir/eq_iir_arm.c |
Adds block-based ARM EQ IIR. |
src/audio/eq_iir/CMakeLists.txt |
Selects ARM EQ IIR. |
src/audio/eq_fir/eq_fir.h |
Enables ARM FIR dispatch. |
src/audio/eq_fir/eq_fir_generic.c |
Retains shared ARM processing. |
src/audio/eq_fir/eq_fir_arm.c |
Adds paired ARM EQ FIR processing. |
src/audio/eq_fir/CMakeLists.txt |
Builds ARM EQ FIR. |
src/audio/drc/Kconfig.simd |
Configures ARM DRC. |
src/audio/drc/drc_math.h |
Adds ARM DRC math helpers. |
src/audio/drc/drc_math_arm.c |
Implements ARM fixed-point DRC math. |
src/audio/drc/drc_generic.c |
Connects shared ARM DRC flow. |
src/audio/drc/drc_arm.c |
Adds ARM compression kernels. |
src/audio/drc/CMakeLists.txt |
Builds ARM DRC sources. |
src/audio/dcblock/Kconfig |
Configures ARM DC blocking. |
src/audio/dcblock/dcblock_generic.c |
Excludes generic ARM path. |
src/audio/dcblock/dcblock_arm.c |
Adds ARM DC-block processing. |
src/audio/dcblock/CMakeLists.txt |
Builds ARM DC-block source. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Define SOF_CONFIG_ARM_SIMD, SOF_USE_ARM_SIMD, SOF_CONFIG_ARM_FPU, and SOF_USE_ARM_FPU macros in common.h mirroring SOF_CONFIG_HIFI and SOF_USE_HIFI to allow compile-time selection of architecture-accelerated ARM Cortex-M DSP SIMD and FPU processing kernels across audio modules and math libraries. Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
…rimitives Add src/include/sof/audio/arm_simd.h providing portable Cortex-M DSP intrinsics and inline assembly primitives: - Branchless saturation: arm_sat_s16, arm_sat_s24, arm_sat_q31 (SSAT) - Saturating arithmetic: arm_qadd16, arm_qsub16, arm_qadd, arm_qsub - 16-bit and 32-bit multipliers: arm_smulbb, arm_smultt, arm_smmulr - Multiply-accumulate: arm_smlal, arm_smlad, arm_smlald, arm_smlawb, arm_smlawt - Halfword packing and extension: arm_pkhbt, arm_sxth - Leading zero count: arm_clz - Generic C fallback implementations when building for non-ARM or host Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement Direct Form 1 (DF1) and Transposed Direct Form 2 (DF2T) biquad filtering kernels optimized for ARM Cortex-M DSP architectures: - Single-cycle 5-term MAC throughput using SMLAL 64-bit accumulators. - Branchless saturation with ARM SSAT (arm_sat_q31). - Specialized 4th order (2 biquads in series) unrolled kernel. - Dispatch headers iir_df1_arm.h and iir_df2t_arm.h for fast inlining. - Add CONFIG_FILTER_ARM_SIMD choice option in math Kconfig and Kconfig.simd. Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
70190e1 to
2d8d2d8
Compare
PR Update & Review Comments ResolutionThe series has been rebased and updated on branch
Verification: |
PR 11301: test resultsRun date: 2026-10-13 15:58 UTC Tested commit: 2d8d2d83f4c9cf457abed5fe6a388fc763cbfba6 |
There was a problem hiding this comment.
🟡 Changes recommended
Unaligned FIR loads, incorrect peak reporting, and unsafe PCM edge-case handling remain unresolved.
5 open findings
Prevent odd-length loop from overrunning PCM input and output · New Avoid unaligned coefficient dereferences in the second filter segment · New Clamp out-of-range floats before converting to int64_t · New Apply attenuation compensation to ARM S24/S32 and float peak meters · New Handle INT32_MIN safely in S32 peak calculations · New
10 resolved since last review
Wrap second delay insertion independently Add missing non-ARM DSP primitive fallbacks Gate ARM DSP assembly on __ARM_FEATURE_DSP Include math.h for fabsf declarations Use 64-bit multiplication for IPC3 volume scaling Use size_t for buffer sample counts Remove or implement undeclared float IIR state Use wide accumulators for parallel biquad branches Preserve generic PCM conversion mappings on ARM Handle INT32_MIN in S16 detector absolute value
🧠 Review effort: Balanced
| for (i = 0; i < n; i += 2) { | ||
| *dst = (*src >> 8) & 0xFFFF; | ||
| dst++; | ||
| *dst = ((*src & 0xFF) << 8) | ((*(src + 1) >> 16) & 0xFF); | ||
| dst++; | ||
| *dst = *(src + 1) & 0xFFFF; | ||
| dst++; | ||
| src += 2; |
There was a problem hiding this comment.
Fixed. Changed the loop condition in pcm_convert_s24_c32_to_s24_c24_link_gtw to i + 1 < n so only complete pairs are processed by the two-sample packer. Moved the single odd trailing sample handler inside each circular-buffer chunk (if (i < n)), and removed the invalid post-loop if (i > n) check.
| uint32_t c01 = *(const uint32_t *)coef; | ||
| uint32_t c23 = *(const uint32_t *)(coef + 2); | ||
| coef += 4; | ||
|
|
||
| int16_t c0 = (int16_t)c01; | ||
| int16_t c1 = (int16_t)(c01 >> 16); | ||
| int16_t c2 = (int16_t)c23; | ||
| int16_t c3 = (int16_t)(c23 >> 16); |
There was a problem hiding this comment.
Fixed. Replaced 32-bit pointer casts and dereferences with direct 16-bit coefficient loads (c0 = coef[0]; c1 = coef[1]; c2 = coef[2]; c3 = coef[3];) in both circular segments of fir_32x16 and fir_32x16_2x, avoiding unaligned memory accesses and strict-aliasing violations.
| n = MIN(n, nmax); | ||
|
|
||
| for (i = 0; i < n; i++) { | ||
| dst[i] = arm_sat_q31((int64_t)(src[i] * scale)); |
There was a problem hiding this comment.
Fixed. Added explicit float range checks against INT32_MAX (val >= 2147483647.0f) and INT32_MIN (val <= -2147483648.0f), mapped NaN to 0, and applied matching protections across float-to-integer converters in pcm_converter_arm.c before integer conversion.
| static void vol_s24_to_s24(struct processing_module *mod, struct cir_buf_source *source, | ||
| struct cir_buf_sink *sink, uint32_t frames, uint32_t attenuation) |
There was a problem hiding this comment.
Fixed. Introduced sat_peak_shift() helper with wide 64-bit shifting and saturation to INT32_MAX. Applied sat_peak_shift(peak, attenuation + PEAK_24S_32C_ADJUST) to S24 peak meters, and sat_peak_shift(peak, attenuation) to S32 and float peak meters across both active volume scaling and passthrough loops.
| peak_l = MAX(abs(x0), peak_l); | ||
| peak_r = MAX(abs(x1), peak_r); | ||
| peak_l = MAX(abs(x2), peak_l); | ||
| peak_r = MAX(abs(x3), peak_r); |
There was a problem hiding this comment.
Fixed. Added sat_abs_s32() helper that maps INT32_MIN to INT32_MAX, and replaced abs() calls with sat_abs_s32() across all S32 peak volume calculations in active and passthrough paths.
Implement unrolled FIR filtering kernels in fir_arm.c optimized for ARM Cortex-M DSP architectures: - Single-cycle SMLAL 64-bit MAC accumulator. - 4-tap unrolled loop for fir_32x16. - Dual-sample parallel filtering kernel fir_32x16_2x. - Guard generic fallback definitions in fir_generic.h. Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Accelerate volume scaling on ARM Cortex-M DSP architectures:
- Add CONFIG_VOLUME_ARM_SIMD choice option in Kconfig.simd.
- Implement volume_arm.c and volume_arm_with_peakvol.c:
* Packed S16 dual halfword unpack/multiply/saturate/pack using
SMULBB, SMULTT, arm_sat_s16, and PKHBT.
* Fast S24 and S32 scaling using SMMULR / arm_smmulr.
* Single-precision floating point processing with hardware FPU.
* Optimized peak volume tracking in volume_arm_with_peakvol.c.
Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement block-accelerated IIR equalizer for ARM Cortex-M architectures:
- Add CONFIG_EQ_IIR_ARM_SIMD Kconfig option.
- Implement eq_iir_arm.c:
* Block vector processing kernel keeping filter delay states
(y_n2, y_n1, x_n2, x_n1) and biquad coefficients in CPU registers
across each 64-sample block.
* Inlines biquad loop eliminating external call dispatches.
* Fast branchless saturation for S16, S24, and S32 formats via SSAT.
Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for Dynamic Range Compressor: - Add CONFIG_DRC_ARM_SIMD choice option in DRC Kconfig.simd. - Implement drc_math_arm.c with Horner's polynomial evaluations for: log10_fixed, drc_lin2db_fixed, drc_log_fixed, drc_asin_fixed, drc_inv_fixed leveraging ARM CLZ (count leading zeros) and branchless saturation. - Implement fast knee_curveK, volume_gain, and envelope tracking. - Implement drc_arm.c with unrolled output compression. - Update drc_generic.c guards for SOF_USE_ARM_SIMD(DRC). Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for FIR Equalizer: - Implement eq_fir_arm.c providing eq_fir_2x_s16, eq_fir_2x_s24, and eq_fir_2x_s32 accelerating 2x parallel filtering. - Route to 2x processing when SOF_USE_ARM_SIMD(FILTER) is enabled. - Branchless saturation with arm_sat_s16 and sat_int24. Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for mixer module: - Add CONFIG_MIXER_ARM_SIMD Kconfig option. - Implement mixer_arm.c: * Packed dual 16-bit saturating addition using arm_qadd16. * 32-bit saturating addition using arm_qadd. * Branchless 24-bit saturation via arm_sat_s24. * Single-precision floating point mixing with FPU vector adds. - Update mixer.h to undefine MIXER_GENERIC when CONFIG_MIXER_ARM_SIMD is set. Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for mixin_mixout module:
- Add CONFIG_MIXIN_MIXOUT_ARM_SIMD choice option in Kconfig.
- Implement mixin_mixout_arm.c:
* Fast channel mixing and gain scaling with saturating adds (arm_qadd16,
arm_qadd, arm_sat_s24).
* 32x32 hardware multiply with 64-bit accumulators.
* Float vector processing using hardware FPU.
- Guard generic fallback implementations in mixin_mixout_generic.c.
Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for DC blocking filter:
- Add CONFIG_DCBLOCK_ARM_SIMD choice option in Kconfig.
- Implement dcblock_arm.c:
* Accelerate single-pole highpass filter using 64-bit MAC and
branchless arm_sat_q31, arm_sat_s16, and arm_sat_s24.
* Hardware FPU accelerated float processing (dcblock_float_arm).
- Guard generic fallback implementations in dcblock_generic.c.
Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for level_multiplier module: - Implement level_multiplier-arm.c: * S16 unpack, multiply, saturate, and pack via SMULBB/SMULTT and PKHBT. * Fast S24 and S32 scaling with arm_smmulr and arm_sat_q31. * Hardware float vector gain scaling. - Guard generic fallback implementations in level_multiplier-generic.c. Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
Implement ARM Cortex-M DSP optimizations for PCM format conversion:
- Add CONFIG_FORMAT_CONVERT_ARM_SIMD Kconfig option in audio Kconfig.
- Define PCM_CONVERTER_ARM_SIMD in pcm_converter.h.
- Implement pcm_converter_arm.c:
* Fast integer format conversions (S16, S24, S32) using SXTH,
PKHBT, SSAT, and sign extension.
* Float-to-integer and integer-to-float conversions with hardware FPU.
* Linear and circular buffer conversion routines with IPC3 and IPC4
dispatch tables (pcm_func_map, pcm_func_vc_map).
Signed-off-by: Liam Girdwood <lgirdwood@gmail.com>
2d8d2d8 to
3636a2e
Compare
|
All latest Copilot code review comments have been examined, resolved, and verified:
Branch |


Description
This series introduces architecture-accelerated DSP and SIMD optimizations for ARM Cortex-M cores (
CONFIG_ARM, ARMv7E-M / Cortex-M7 / Cortex-M4 DSP instruction set).Previously, these optimizations were developed within board-bringup branches (such as
feature/teensy41-sof-portandfeature/rp2350-sof-port) alongside board definitions, static topologies, and USB classes. To facilitate focused review and upstream merging, this series isolates the generic audio processing and math kernels into 13 clean, atomic, module-by-module commits rebased on upstreammain.All board, platform, and application-specific code has been eliminated. The optimizations leverage portable Cortex-M DSP intrinsics and inline assembly primitives (such as single-cycle
SMLAL,SMULBB/SMULTT,SMLAD/SMLALD,SMMULR,PKHBT,QADD16,QADD,CLZ, and branchlessSSAT), with complete generic C fallback implementations provided for host compilation and non-ARM targets.Module-by-Module Summary
include: common: introduce ARM SIMD configuration macrosSOF_CONFIG_ARM_SIMD(component),SOF_USE_ARM_SIMD(component),SOF_CONFIG_ARM_FPU(component), andSOF_USE_ARM_FPU(component)mirroringSOF_CONFIG_HIFI/SOF_USE_HIFIfor compile-time optimization selection.include: audio: add ARM Cortex-M DSP intrinsics and inline assembly primitivessrc/include/sof/audio/arm_simd.hproviding portable Cortex-M DSP intrinsics and inline assembly:arm_sat_s16,arm_sat_s24,arm_sat_q31(SSAT)arm_qadd16,arm_qsub16,arm_qadd,arm_qsubarm_smulbb,arm_smultt,arm_smmulrarm_smlal,arm_smlad,arm_smlald,arm_smlawb,arm_smlawtarm_pkhbt,arm_sxtharm_clzmath: iir: add ARM Cortex-M DSP cascaded DF1 and DF2T biquad filteringiir_df1_arm.c) and Transposed Direct Form 2 (iir_df2t_arm.c) biquads.SMLAL64-bit accumulators.SSAT(arm_sat_q31).iir_df1_arm.handiir_df2t_arm.hfor fast inlining. AddsCONFIG_FILTER_ARM_SIMD.math: fir: add ARM Cortex-M DSP unrolled FIR filteringfir_arm.c.SMLAL64-bit MAC accumulator with 4-tap unrolled loop forfir_32x16.fir_32x16_2x.fir_generic.h.audio: volume: add ARM Cortex-M DSP packed vector volume scalingvolume_arm.candvolume_arm_with_peakvol.c:SMULBB,SMULTT,arm_sat_s16, andPKHBT.SMMULR(arm_smmulr).volume_arm_with_peakvol.c. AddsCONFIG_VOLUME_ARM_SIMD.audio: eq_iir: add ARM Cortex-M DSP block-accelerated processingEQ_IIR_BLOCK_SIZE = 64) keeping filter delay states (y_n2,y_n1,x_n2,x_n1) and coefficients in registers across each block, eliminating ~98% of RAM load/store traffic.SSAT. AddsCONFIG_EQ_IIR_ARM_SIMD.audio: drc: add ARM Cortex-M DSP fast polynomial math and compressiondrc_math_arm.cwith Horner's polynomial evaluations for:log10_fixed,drc_lin2db_fixed,drc_log_fixed,drc_asin_fixed,drc_inv_fixedleveraging ARMCLZand branchless saturation.knee_curveK, volume gain, and envelope tracking.drc_arm.cwith unrolled output compression. AddsCONFIG_DRC_ARM_SIMD.audio: eq_fir: add ARM Cortex-M DSP parallel 2x filteringeq_fir_arm.cprovidingeq_fir_2x_s16,eq_fir_2x_s24, andeq_fir_2x_s32accelerating 2x parallel filtering.SOF_USE_ARM_SIMD(FILTER)is enabled.arm_sat_s16andsat_int24.audio: mixer: add ARM Cortex-M DSP saturating stream summationmixer_arm.c:arm_qadd16.arm_qadd.arm_sat_s24.CONFIG_MIXER_ARM_SIMD.audio: mixin_mixout: add ARM Cortex-M DSP channel mixing and scalingmixin_mixout_arm.c:arm_qadd16,arm_qadd,arm_sat_s24).mixin_mixout_generic.c. AddsCONFIG_MIXIN_MIXOUT_ARM_SIMD.audio: dcblock: add ARM Cortex-M DSP filter accelerationdcblock_arm.c:arm_sat_q31,arm_sat_s16, andarm_sat_s24.dcblock_float_arm).dcblock_generic.c. AddsCONFIG_DCBLOCK_ARM_SIMD.audio: level_multiplier: add ARM Cortex-M DSP gain scalinglevel_multiplier-arm.c:SMULBB/SMULTTandPKHBT.arm_smmulrandarm_sat_q31.level_multiplier-generic.c.audio: pcm_converter: add ARM Cortex-M DSP format conversion routinesCONFIG_FORMAT_CONVERT_ARM_SIMDin audio Kconfig and definesPCM_CONVERTER_ARM_SIMDinpcm_converter.h.pcm_converter_arm.c:SXTH,PKHBT,SSAT, and sign extension.pcm_func_map,pcm_func_vc_map).Verification