虽然我一直用IAR,但近期不得不对ARM的编译能力表示怀疑,在使用CMSIS 2.0的DSP LIB中得到错误的结果,后来跟踪发现是FFT计算中的问题,举个例子:arm_radix4_butterfly_q15函数中有段C代码:
S = pSrc[i2]; // S=0x0000D888
in = ((int16_t) (S & 0xFFFF)) >> 2; // in=0xFFFFF622
S = ((S >> 2) & 0xFFFF0000) | (in & 0xFFFF); // S=0x0000F622
R = __QADD16(T, S);
此段程序的初衷是利用QADD16并行指令加速计算两个16位有符号数的和,高16位和低16位均需要算数右移2位。
IAR汇编代码如下:
LDR.W R12,[R0,R6,LSL #2] ; R12=0x0000D888
AND.W R8, R9, R12, ASR #2
UBFX R12, R12, #2, #16
ORR.W R8, R12, R8 ; R8=0x00003622
QADD16 R12, LR, R8
Keil汇编代码如下:
LDR r8,[r0,r6,LSL #2] ;r8=0x0000D888
SXTH r9,r8
ASR r8,r8,#2
PKHTB r8,r8,r9,ASR #2 ;r8=0x0000F622
QADD16 r9,r10,r8
在S=0x0000D888时,经过上述处理后IAR中的S为0x00003622,Keil中的S为0x0000F622,也就是S的低16bit一个为正,一个为负,结果就差了十万八千里。
KEIL版本为4.14, IAR我尝试了6.10,6.20,均得不到正确结果,其中IAR6.20已经把CMSIS库集成,只需要勾选即可使用,但结果仍然错误。 |