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.

[参考译文] TMS320F28075:C28x FPU:为什么没有 F32TOI32R 指令?

Guru**** 2033340 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/719504/tms320f28075-c28x-fpu-why-no-f32toi32r-instruction

器件型号:TMS320F28075

您好!

由最近的讨论(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++编译器内在函数。

此致、

弗兰克

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    弗兰克、

    感谢您的建议。 我看到了值。

    FPU 指令集不会很快被改变、所以如果要实现这一点、就必须按内在函数来改变。 我将确保将您的建议传递给编译器组。 如果我了解更多信息、我将在此处发布。

    此致、

    Richard
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    而不是(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.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    再次抱歉。 这次取消修复它。 + 0x0.Cp24f、则- 0x0.Cp24f 正确。 错误0x0.Cp24f 不是2^23、而是1.5 * 2^23。 这是我产生怀疑的地方。
    将此数字(12582912)相加、正或负完全抵消小数部分、从总和中减去小数部分即可得到正确的单精度数取整。

    0x0.Cp24f 语法相对较新、旧编译器不支持它。 它允许以十六进制指定 FP 尾数。

    0x -前缀
    0.C 或0.C000000 -十六进制小数。 将其设为0xC / 0x10 = 12/16 = 0.75

    P24 - 24这里是乘法器2^24。 24为十进制、而不是十六进制。

    0.75 * 2^24 = 12582912

    Edward
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    爱德华

    感谢您的解释。 0x0.Cp24f 语法有点奇怪、因此我终于使用了

    静态内联
    int32_t f32toi32r (float32_t f)

    return (int32_t)(((f + 12582912.0)- 12582912.0);


    起初、我使用 UNION 采用不同的方法、但这有其局限性、详情见下文。 为 CLA 生成了精细代码、但不为 CPU/FPU 生成了精细代码(出于某种原因、没有内联函数)。

    因此、您的解决方案无疑是更好的解决方案。

    再次感谢您、
    弗兰克

    PS:您是否还有一个更好的主意来使用静态内联浮点 fsign(float f){返回 f >=0.0? 1.0:-1.0;}?



    /*定义宏以隐藏 signf()、halfsign()用法*/的奇怪语法
    #define fsign(x) (signf (&(x)).f)
    #define halffsign(x)(halsignf (&(x)).f)/* 0.5 * fsign(x)*/

    /*
    sign(f)=f >=0.0的快速版本? 1.0:-1.0;这不需要
    CLA 中的慢速分支。 不幸的是、参数必须是可寻址的
    变量。
    *

    union fi{
    float32_t f;
    内部32_t 一;
    };


    静态内联
    union fi signf (float32_t * f)

    寄存器 union fi r;

    /*结果= 1.0 | sign_bit (f)*/
    r.i = 0x3F800000 |(*(int32_t *) f)& 0x8000000000);
    返回 r;


    静态内联
    union fi halfsignf (float32_t * f)

    寄存器 union fi r;

    /*结果= 0.5 | sign_bit (f)*/
    r.i = 0x3F000000 |(*(int32_t *) f)& 0x8000000000);
    返回 r;


    静态内联
    int32_t f32toi32r_(float32_t f)

    return (int32_t)(f + halffsign(f));
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    您在 signf()中执行的操作可以在 TI 编译器中进行精简:

    _u32_bits_as_F32 ((_f32_bits_as_u32 (f)& 0x8000000000)| 0x3F800000)

    这些特殊的__u32xx /__f32xx 内在函数有助于分别将 u32视为 float 和 float 处理为 u32,而无需定义任何变量。

    但我不确定、从 FPU 寄存器传输到 ACC、按位和按位或/添加、以及传输回 FPU 寄存器或分支代码的速度有多快? FPU 有条件 NEGF 指令。 因此、如果我们加载一个具有1.0的额外 FPU 寄存器、请将 signf ()参数与零进行比较、并在 LT 上对1.0至-1.0进行求反、我认为这应该更快。 遗憾的是、我不知道如何说服编译器按照我的要求执行它、我看到编译代码中存在分支。

    Edward
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    爱德华

    再次感谢您的信息。

    我没有在 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

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    是的、我看不到 TI PDF 中记录的这些有用的内在函数、我可能在这里找到它们
    e2e.ti.com/.../632168

    有关在 CLA 中使用它们的问题。 是的、遗憾的是、看起来这些都没有实现。

    此致、
    Edward
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    弗兰克、

    您之前发布了以下结果:

    法国
    -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

    我只想双击:这是否正是您对 F32TOI32R 指令的预期行为?

    此致、

    Richard
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    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在零点处没有缺失的楼梯)。

    谢谢、此致、

    弗兰克

    这是文件、我认为您可以构建完整的测试案例 from.e2e.ti.com/.../testfsign.c