This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好!
由最近的讨论(e2e.ti.com/.../713771)触发、我想知道为什么没有 F32TOI32R 指令(以及内在函数 long __f32toi32r (double src))?
这将消除 F32TOI32指令具有的零附近的非线性:正浮点数和负浮点数都向零舍入(截断)。
类似于 float f;long l;l =(int32_t)(f >= 0.0? F + 0.5:f - 0.5)执行它、有 F32TOI16R 指令执行它、但仅适用于16位值。
是否有下一版本的想法?
请参阅 SPRU514P、表7-7。 FPU 的 C/C++编译器内在函数。
此致、
弗兰克
您好!
而不是(f >= 0.0? f + 0.5:f - 0.5)您应该使用无分支((f + 0x0.Cp24f)- 0x0.Cp24f)。 它会增加2^23、然后减去2^23。 它将遵循当前的 FP 舍入模式。 由于它舍入到最接近的偶数、因此它将舍入到您的表达式类似、但所有这些都在中间值中舍入到偶数、即+-0.5至0.0、+-1.5至+-2.0、+-2.5至+-2.0、+-3.5至+-4.0等。
抱歉、+2^23 -2^23诀窍仅对正数有效。 对于负值、必须先减2^23、然后再加。 仍然需要分支。
此致、
Edward
爱德华
我收到了一封邮件、其中包含您的第一次答复、但以后没有添加更正的邮件。 可能是要检查的论坛管理员。
我测试了您的建议并获得了以下结果。 在我的应用程序中、没有必要保留"round x.5 to evole"规则、因此我认为这是一个很好的解决方案。
我不知道"0x0.Cp24f"语法、也没有找到它的文档。 是通用 C 语言还是特定于 TI 的语法? 在哪里可以阅读更多信息?
谢谢、此致、
弗兰克
静态内联
int32_t f32toi32r (float32_t f)
{
返回(int32_t)(((f + 0x0.Cp24f)- 0x0.Cp24f);
}
float fr 和 f32toi32r 结果 ir:
法国
-4.0 -3.875 -3.75 -3.625 -3.5 -3.375 -3.25 -3.125
-3.0 -2.875 -2.75 -2.625 -2.5 -2.375 -2.25 -2.125
-2.0 -1.875 -1.75 -1.625 -1.5 -1.375 -1.25 -1.125
-1.0 -0.875 -0.75 -0.625 -0.5-0.375 -0.125
0.0 0.125 0.25 0.375 0.5 0.625 0.75 0.875
1.0 1.125 1.25 1.375 1.5 1.625 1.75 1.875
2.0 2.125 2.25 2.375 2.5 2.625 2.75 2.875
3.0 3.125 3.25 3.375 3.5 3.625 3.75 3.875
红外
-4-4-4-4-4-4-4-3-3-3
-3-3-3-2 -2
-2 -2 -2 -2 -2 -2 -2 -2 -1 -1 -1
-1 -1 -1 -1 0 0 0 0 0
0 0 0 0 0 1 1 1
1 1 1 1 2 2 2 2
2 2 2 2 2 3 3 3
3 3 3 3 4 4 4 4
法国
-3.9375 -3.8125 -3.6875 -3.5625 -3.4375 -3.3125 -3.1875 -3.0625
-2.9375 -2.8125 -2.6875 -2.5625 -2.4375 -2.3125 -2.1875 -2.0625
-1.9375-1.8125 -1.6875 -1.5625 -1.4375 -1.3125 -1.1875 -1.0625
-0.9375 -0.8125 -0.6875 -0.5625 -0.4375 -0.3125 -0.1875 -0.0625
0.0625 0.1875 0.3125 0.4375 0.5625 0.6875 0.8125 0.9375
1.0625 1.1875 1.3125 1.4375 1.5625 1.6875 1.8125 1.9375
2.0625 2.1875 2.3125 2.4375 2.5625 2.6875 2.8125 2.9375
3.0625 3.1875 3.3125 3.4375 3.5625 3.6875 3.8125 3.9375
红外
-4-4-4-4-4-3-3-3
-3-3-3-2 -2
-2 -2 -2 -2 -2 -2 -1 -1 -1 -1
-1 -1 -1 -1 0 0 0 0 0
0 0 0 0 1 1 1 1
1 1 1 1 2 2 2 2
2 2 2 2 3 3 3 3
3 3 3 3 4 4 4 4
非线性、其中 ir =(int32_t) fr;
红外
-3-3-3 -3-3.
-2 -2 -2 -2 -2 -2 -2 2 -2 2 2 2 2 2 -2-2
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2.
3 3 3 3 3 3 3 3 3.
爱德华
再次感谢您的信息。
我没有在 SPRUEO2B (FPU)、SPRU514P (C28x 编译器)、SPRU430F (中的 C28x CPU)或 SPRU513P (C28汇编工具)中找到_u32_bits_as_F32、__F32_bits_as_u32内在函数。 TI 的任何人都可以在此处提供帮助吗? 还是这个"Herrschaftswissen"(德语)?
不幸的是、这些内在函数不适用于 CLA 编译器。
下面是测试多个版本的代码段。 它包含一个汇编器编码函数、该函数按照建议使用 NEGF 指令。 它似乎符合我们的要求、但我不确定是否满足所有条件(流水线等)。 它也似乎是最快的方式-呼叫/返回的4 + 4个周期开销(尽管该呼叫可能会妨碍其他操作)。 & 0x80000000方法在内存方面表现良好、在表达式中表现不佳、原因是 ACC <> RnH 传输的4周期流水线延迟。
谢谢、此致
弗兰克
静态内联
float32_t fsignt (float32_t f)
{
返回__u32_bits_as_F32 (__f32_bits_as_u32 (f)& 0x80000000)| 0x3F800000);
}
volatile float32_t f1、f2、f3;
extern float32_t fsignf (float32_t f);
/* r0h = r0h < 0.0? -1.0:1.0 */
asm (" .global _fsignf ");
asm ("_fsignf: movizf32 r1h、#1.0 ");
asm (" cmpf32 r0h、#0.0 ");
asm (" negf32 r0h、r1h、lt ");
asm (" lretr ");
无效
main (空)
{
F1 = 2.0;
F2 = fsign(F1);
F1 =-2.0;
F3 = F1 * fsign( F1 + f2);
F3 = fsignf (F1);
F3 = F1 >= 0.0? 1.0:-1.0;
F3 = fsignf (-f1);
}
使用
"c:/ti/ccsv7/tools/compiler/ti-cgt-c2000_16.9.1.LTS/bin/cl2000 "-v28 -ml -mt --vcu_support=vcu2 -cla_support=cla1 -float_support=fpu32 -tmu_support=tmu0 -O2 -g -define=CPU1
编译为:
015155: 761F0487 MOVW DP、#0x487
88 f1 = 2.0;
015157: E8020000 MOVIZ R0、#0x4000
015159: E2030016 MOV32 @0x16、R0H
61 {
01515b: 0616 MOVL ACC、@0x16
90 f1 =-2.0;
01515c: E8060000 MOVIZ R0、#0xc000
89 f2 = fsign(F1);
01515e: 18A88000 和 @AH、#0x8000
015160: 9000 ANDB AL、#0x0
015161: 1AA83F80 或 @AH、#0x3f80
015163: 1E14 MOVL @0x14、ACC
90 f1 =-2.0;
015164: E2030016 MOV32 @0x16、R0H
61 {
015166: E2A0016 MOV32 R0H、@0x16、UNCF
015168: E2A0114 MOV32 R1H、@0x14、UNCF
01516a: E7100040 ADDF32 R0H、R0H、R1H
01516c: 7700 NOP
01516d: 7700 NOP
01516e: 7700 NOP
91 f3 = f1 * fsign( f1 + f2);
01516f: BFA90F12 MOV32 @ACC、R0H
015171: 18A88000 和 @AH、#0x8000
015173: 9000 ANDB AL、#0x0
015174: 1AA83F80 或 @AH、#0x3f80
015176: BDA90F12 MOV32 R0H、@Ω 附件
015178: 7700 NOP
015179: 7700 NOP
01517a: 7700 NOP
01517b: E2A0116 MOV32 R1H、@0x16、UNCF
01517d: E7000008 MPYF32 R0H、R1H、R0H
01517f: 7700 NOP
015180: E2030018 MOV32 @0x18、R0H
92f3 = fsignf (f1);
015182: E2A0016 MOV32 R0H、@0x16、UNCF
015184: 7641514B LCR fsignf
015186: 761F0487 MOVW DP、#0x487
015188: E2030018 MOV32 @0x18、R0H
93 f3 = f1 >= 0.0? 1.0:-1.0;
01518a: E2A0016 MOV32 R0H、@0x16、UNCF
01518c: E5A0 CMP32 R0H、#0.0
01518d: AD14 MOVST0 NF、ZF
01518e: 6304 SB C$L1、GEQ
01518f: E805FC00 MOVIZ R0、#bbbf80
015191: 6F03 SB C$L2、UNC
015192: E801FC00 MOVIZ R0、#0x3f80
015194: E2030018 MOV32 @0x18、R0H
94 f3 = fsignf (-f1);
015196: E2A0016 MOV32 R0H、@0x16、UNCF
015198: E6AF0000 NEGF32 R0H、R0H、UNCF
01519a: 7641514B LCR fsignf
01519c: 761F0487 MOVW DP、#0x487
01519e: E2030018 MOV32 @0x18、R0H
Richard、
我想我可以总结如下:对于16位整数、但对于32位整数、F32TOI32R 应该执行 F32TOI16R 所做的操作。
我再次运行了测试程序并包含了__f32toi16r 内在函数。 正如与 Edward 讨论的那样,x.5案例的处理是不同的:F32TOI16R 和 Edwards 加/减1.5*2^23舍入到下一个偶数,分支(int32_t)(fr[i]< 0.0? FR[i]- 0.5:fr[i]+ 0.5);)和我的 f + halffsign(f)方法没有。
在我的控制应用中、数学家和其他应用中可能需要的东西并不重要。 由于始终存在一些噪声、因此将 x.5舍入到中并不重要。 我只想有一个"直道楼梯"、楼梯间距均匀(F32TOI32在零点处没有缺失的楼梯)。
谢谢、此致、
弗兰克