SPRADD8 November 2024 F29H850TU , F29H859TU-Q1
Saturation type code commonly occurs in real-time applications. shows a summary of two different ways saturation is implemented in C.
The code block below shows the if..else based approach to implementing saturation. The C29 (11 cycles, independent of input) outperforms the Cortex-M7 (14-27 cycles, dependent on input). On the C29, the if() is implemented through a conditional branch instruction (BC), and for the remaining two paths (the elseif and else), a compare (CMPF) followed by a conditional instruction (XCP) is used, thus avoiding branches.
volatile float in;
volatile float out;
const float max =1.0f;
const float min = -1.0f;
if(in > max)
out = max;
else if(in < min)
out = min;
else
out = in;
C29 Implementation
LD.32 M1,@in
||ONEF M0
CMPF TDM0,M.GT,M1,M0
ONEF M1
|| BC @($LBB0_2),TDM0.NZ
LD.32 M1,@in
|| NEGONEF M2
CMPF TDM0,M.LT,M1,M2
XCP #0x1,TDM0.Z
|| LD.32 M1,@in
SELECT TDM0,M1,M2,M1
$LBB0_2:
ST.32 @out,M1
M7 Implementation
MOVW R0,#in2
MOVT R0,#in2
MOVS R1,#+1
MOVT R1,#+16256
VLDR S0,[R0, #0]
VMOV S1,R1
VCMP.F32 S0,S1
FMSTAT
BLT.N saturation_0
MOV R2,#+1065353216
STR R2,[R0, #+4]
B saturation_2
saturation_0:
VMOV.F32 S0,#-1.0
VLDR S1,[R0, #0]
VCMP.F32 S1,S0
FMSTAT
BPL.N saturation1_1
VSTR S0,[R0, #+4]
B saturation_2
saturation_1:
LDR R1,[R0, #+0]
STR R1,[R0, #+4]
saturation_2:
The code block below shows the ternary operator '?' based approach to implementing saturation. The C29 (three cycles, independent of input) outperforms the Cortex-M7 (18-22 cycles, dependent on input), through the MINMAXF instruction without any branches.
volatile float in;
volatile float out;
const float max =1.0f;
const float min = -1.0f;
float temp = in;
temp = (temp > max)? max: ((temp < min)? min: temp);
out = temp;
C29 Implementation
ONEF M0 || LD.32 M1,@in || NEGONEF M2 MINMAXF M1,M0,M2 ST.32 @out,M1
M7 Implementation
MOVW R0,#in2
MOVS R1,#+1
MOVT R0,#in2
MOVT R1,#+16256
VMOV S2,R1
VLDR S0,[R0, #0]
VCMP.F32 S0,S2
VMOV.F32 S1,S0
FMSTAT
IT GE
VMOVGE.F32 S1,#1.0
BGE.N saturation_0
VMOV.F32 S2,#-1.0
VCMP.F32 S0,S2
FMSTAT
IT MI
VMOVMI.F32 S1,S2
saturation_0:
VSTR S1,[R0, #+8]
The C29 compiler is enhanced to generate equal performance regardless of the if..else or the ternary operator based approaches.
|| denotes instructions occurring in parallel with the above instructions.