4.5. Assertions¶
The _nassert
intrinsic generates no code and so is not a typical compiler intrinsic. Instead, it tells the compiler that the expression declared with the assert function is true. It can be used to assert that certain conditions are true, which in turn can be used by the compiler during its optimizations.
Warning
Code can fail at runtime if the condition specified in the _nassert
is not true.
Listing 4.12 illustrates an example of using _nassert
. In this case, the programmer is guaranteeing that the loop executes at least once and count
is a multiple of 4. This enables the compiler to avoid generating code to check for count == 0
and peeled iterations during unrolling.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <stdint.h>
int16_t sum(int16_t* input, int16_t count)
{
int16_t sum = 0;
int16_t i = 0;
_nassert(count > 0 && count % 4 == 0);
for (i = 0; i < count; i++)
sum += input[i];
return sum;
}
|
Table 4.6 shows the assembly generated without and with the _nassert
.
Asm generated with _nassert (loop is unrolled 4x) |
Asm generated without _nassert (loop is unrolled 2x) |
---|---|
||sum||:
MOV AH,AL
MOVB AL,#0
ASR AH,2
ADDB AH,#-1
MOVZ AR6,AH
||$C$L1||:
ADD AL,*XAR4++
ADD AL,*XAR4++
ADD AL,*XAR4++
ADD AL,*XAR4++
BANZ ||$C$L1||,AR6--
LRETR
|
||sum||:
MOV AH,AL
MOVB XAR7,#0
BF ||$C$L4||,LEQ
CMPB AH,#2
BF ||$C$L1||,GEQ
MOV PL,#0
BF ||$C$L3||,UNC
||$C$L1||:
AND AH,AH,#0xfffe
MOV PL,AH
MOVL XAR5,XAR4
MOV AH,AL
ASR AH,1
ADDB AH,#-1
MOVZ AR6,AH
||$C$L2||:
MOV AH,AR7
ADD AH,*XAR5++
ADD AH,*XAR5++
MOVZ AR7,AH
BANZ ||$C$L2||,AR6--
||$C$L3||:
TBIT AL,#0
BF ||$C$L4||,NTC
MOVL ACC,XAR4
SETC SXM
ADD ACC,PL
MOVL XAR4,ACC
MOV AL,AR7
ADD AL,*+XAR4[0]
MOVZ AR7,AL
||$C$L4||:
MOV AL,AR7
LRETR
|