在ARM上使用double2unsigned(vcvt指令)

时间:2018-06-19 11:48:57

标签: c assembly arm

我有简单的代码。在x86(Visual Studio)上,最后两行代码的分辨率相同。

short res;
double CONST = 32768.0
double d=-0.85;
res = ( unsigned short)( d * CONST );
res = ( short)( d * CONST );

在ARM(GCC)上转换为未签名会得到错误的结果。

short dres;
double CONST = 32768.0
double d=-0.85;
dres = ( unsigned short )( d * CONST );
//007db5c4:   vldr d17, [pc, #76]
//007db5c8:   vldr d16, [r11, #-20]
//007db5cc:   vmul.f64 d7, d17, d16 ;d7=={u8 = {51, 51, 51, 51, 51, 51, 219, 192}, u16 = {13107, 13107, 13107, 49371}, u32 = {858993459, 3235590963}, u64 = 13896757370177139507, f32 = {4.17232506e-08, -6.8499999}, f64 = -27852.799999999999}
//007db5d0:   vcvt.u32.f64 s15, d7 ;s15==0 !!!!!!!!!!!!!!!!!!!!! incorrect
//007db5d4:   vstr s15, [r11, #-48]
//007db5d8:   ldrh r3, [r11, #-48]
//007db5dc:   uxth r3, r3
//007db5e0:   strh r3, [r11, #-6]
dres = ( short )( d * CONST );
//007db5e4:   vldr d17, [pc, #44]
//007db5e8:   vldr d16, [r11, #-20]
//007db5ec:   vmul.f64 d16, d17, d16
//007db5f0:   vcvt.s32.f64 s15, d16 ;s15==-nan(0x7f9334)
//007db5f4:   vmov r3, s15
//007db5f8:   strh r3, [r11, #-6]

这是正确的行为还是错误?

1 个答案:

答案 0 :(得分:2)

这不是编译器错误。

对于16位short,其行为

res = ( unsigned short)( d * CONST );
由于您溢出signed类型的float的值转换为-1的情况下,

未定义 小于unsigned整数类型。这会将整个程序置于未定义状态。