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.

[参考译文] 编译器/TMS320F2.8377万D:编译器未发出MOV32 Rah,RBH {,CNDF}或MOV32 Rah,mem32 {,CNDF}指令

Guru**** 2585275 points


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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/601812/compiler-tms320f28377d-compiler-not-emitting-mov32-rah-rbh-cndf-or-mov32-rah-mem32-cndf-instructions

部件号:TMS320F2.8377万D

工具/软件:TI C/C++编译器

我尝试用C语言而不是汇编程序编写快速代码,并且在我期望的时候偶然发现编译器没有发出MOV32 Rah,RBH {, CNDF}或MOV32 Rah, mem32 {, CNDF}指令。

给定文件test.c:

#include <mathing.h>

双倍测试双倍(双A,双b){
返回fabs (a)> fabs (b)? a:b;
}

静态内嵌双精度QUICK_two_sum (双精度A,双精度b,双精度*ERR){
双s = a + b;
*错误= b -(s - a);
退货;
}

void c_dd_add_dd_d (const double *a,double b,double * restrictd c){
双s1,s2;

如果(fabs (a[0])> fabs (b)){
S1 = A[0];
S2 = b;
}其他{
S1 = b;
S2 = A[0];
}

S1 = quick_two_sum (s1,s2,&s2);
S2 += A[1];
S1 = quick_two_sum (s1,s2,&s2);

C[0]= s1;
C[1]=s2;
}

和命令:

c:/ti/ccsv6/tools/compiler/ti-CGT-C2000_C2000_STS/bin/cl2000"<xmt-block0>2000 17.32000 17.3 -v28 -ml -mt --CLA_support=cla1 --float_support=fpu32 --tmu_support=tmu0 --vcu_support=vcu2 -o4 -opt_for c2000_support=class1 -compiler -fp_per-fm_guide=-fu/fm_support=fm=t_support-fm=t_sym_tools/cru_cru_cruel_crue_d=-cruel_cruel_cruel_f_d=-cruile.d=-f_cru_f_f_f_f_f_dip-f_f_-f_-fp=-cruilt -cruildip_f_f_f_f_-f_-f_fuilt 17.3  

我以以下装配体结束(为简洁而剪裁):

测试双精度:
;***4 --------------------------- 返回(ABS (a)> ABS (b))? a:b;
ADDB SP,#2;[CPU_U]
MOV32 R2H,R1H;[CPU_]|4|
MOV32 R3H,R0H;[CPU_]|4|
SubB SP,#2;[CPU]|4|
ABSF32 R2H,R2H;[CPU_]|4|
ABSF32 R3H,R3H;[CPU_]|4|
CMPF32 R3H,R2H;[CPU_]|4|
MOVST0 ZF,NF;[CPU_]|4|
MOV32 R1H,R0H,GT;[CPU_]|4|
MOV32 R0H,R1H;[CPU_]|4|
LRTR;[CPU_]

_c_dd_add_dd_d:
;***16--------------- 3美元=* a;
;***16--------------- 如果( abs(U3美元)> abs(b))转到G3;
ADDB SP,#2;[CPU_U]
MOVL ACC,*+XAR4[0];[CPU_]|16|
MOV32 R2H,ACC;[CPU_]|16|
NOP;[CPU_]
NOP;[CPU_]
MOV32 R1H,R0H;[CPU_]|16|
ABSF32 R1H,R1H;[CPU_]|16|
ABSF32 R2H,R2H;[CPU_]|16|
CMPF32 R2H,R1H;[CPU_]|16|
MOVST0 ZF,NF;[CPU_]|16|
b $C$L1,GT;[CPU_]|16|
;发生分支;[]|16|
;***20--------------- S1 = b;
;***21 --------------------------- S2 = 3元;
;***21 --------------------------- 转到G4;
MOV32 R1H,R0H;[CPU_]|20|
MOV32 R0H,ACC;[CPU_]|21|
b $C$L2,UNC;[CPU_]|21|
;出现分支;[]|21|
$C$L1:
;***--------------- G3:
;***17--------------- S1 = 3元;
;*** 18--------------- S2 = b;
MOV32 R1H,ACC;[CPU_]|17|
NOP;[CPU_]
NOP;[CPU_]
NOP;[CPU_]
NOP;[CPU_]
$C$L2:
;***--------------- G4:
;***8 --------------------------- S = s1+s2;//[2]
;***9 --------------------------- S2 = s2-(s-1)+a[1];//[2]
;***8 --------------------------- S = s+s2;//[2]
;***9 --------------------------- s2 -= s-s;//[2]
;***28------------------ *c = s;
;***29------------------ C[1]=s2;
;***--------------- 返回;
ADDF32 R2H,R0H,R1H;[CPU_]|8|
NOP;[CPU_]
SUBF32 R1H,R2H,R1H;[CPU_]|9|
NOP;[CPU_]
SUBF32 R0H,R0H,R1H;[CPU_]|9|
MOV32 R3H,*+XAR4[2];[CPU_]|9|
ADDF32 R0H,R0H,R3H;[CPU_]|9|
NOP;[CPU_]
ADDF32 R1H,R0H,R2H;[CPU_]|8|
NOP;[CPU_]
SUBF32 R2H,R1H,R2H;[CPU_]|9|
SubB SP,#2;[CPU_U]
SUBF32 R0H,R0H,R2H;[CPU_]|9|
MOV32 *+XAR5[0],R1H;[CPU_]|28|
MOV32 *+XAR5[2],R0H;[CPU_]|29|
LRTR;[CPU_]

在 _test_double中,将浮点状态标志冗余移动到整数状态标志,因为后续移动使用ZF和NF标志。

在_c_dd_add_dd_d中,使用了一个代价高昂的分支,而不是条件移动。

在_c_dd_add_dd_d中 ,使用ACC避免推入和弹出浮点寄存器的成本很高。  

我在这里错过了什么吗? 在这种情况下,是否有理由不使用条件移动?

当ACC产生周期罚分时,为什么要将其用作临时寄存器(我处于优化级别4,优化速度5)。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我不认识。 可能不可能有从ACC到RxH的条件移动;汇编程序拒绝此类指令。 我需要询问一下这个问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    查看编译器的汇编输出,我想知道为什么编译器首先通过ACC移动浮点值,而不是直接加载到浮点寄存器。 这样就不需要从ACC到RxH的条件性移动。

    另外,您能否澄清MOV32 Rah,RBH {, CNDF}和MOV32 Rah, mem32 {, CNDF}是否在条件评估中使用浮点状态位或整数状态位? test_double函数的编译器的汇编输出表明它是整数状态位,而参考手册却指出它是浮点状态位。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    请忍受,我不是C28x指令集专家,所以我不得不在这里查找一些答案。

    是的,条件FPU指令(如MOV32)使用CNDF标志,这些标志与C28x CPU中使用的cond标志完全不同。 可能不幸的是,其中一些标志的名称重叠,如NEQ,EQ等

    至于编译器生成错误代码的原因,答案是它很复杂。 编译器使用启发式集合进行优化,这些集合并不总是给出最佳答案,在这种情况下,编译器无法向前看足够远,知道它应该完全使用FPU指令进行此计算。 这不是一个错误,只是编译器不能很好地全面了解代码。 此功能无疑有很大的改进空间,因此我将提交增强请求(CodeGen-2341)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您为我了解这一情况。 我一直在查看生成的装配体,以了解其他一些示例。 我已经看到编译器为浮点寄存器而不是分支生成条件移动,因此编译器有时会正确获取。 在这些情况下,总是有一个冗余的MOVST0指令。

    此示例函数是一组基本操作的一部分,这些基本操作广泛用于构造更复杂的操作。 因此,它们都是内嵌的,以避免成本高昂的函数调用。 如果可以,我会将这些函数下放到汇编中,但不能将汇编函数内联到C/C++或使用内联汇编修改C/C++变量。

    请提供链接以跟踪增强请求。 SDOWP数据库表示无法找到记录。

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

    请提供链接以跟踪增强请求。 SDOWP数据库表示无法找到记录。[/QUOT]

    增强请求已更新。  请使用我签名中下面的SDOWP链接重试。

    谢谢,此致,

    -George