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.

[参考译文] TMS320F28388D:当处理从超长整型到超长整型的局部变量转换时、反汇编中的 QMPYL 指令运行异常

Guru**** 2589275 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1280414/tms320f28388d-qmpyl-instruction-in-disassembly-is-behaving-abnormally-when-handling-cast-of-a-local-variable-from-long-long-to-long-double

器件型号:TMS320F28388D

您好!  

我们有一个问题,就是当我们把一个值从长的到长的双倍时,它不能正常工作。  

当我们分配带负数的 long 变量时分配给它的值将得到 我们要分配给它的值。  

请注意、优化器设置为: -O4 --opt_for_speed=5 --fp_mode=relaxed  

CCS 版本:10.4.0

编译器版本 TI v20.2.5.LTS

您可以看到这三张图片。  

在第一张图片中,我们明确地将变量 glpVirtualEncoderPointer[0]分配给-2。 根据代码、我们希望 glVEncDelta 也变为2。 请参阅所有相关表达式。 然而我们最终看到的是 glVEncDelta 达到了最大负32位范围。  

在观察反汇编时、我们发现当执行 QMPYL 指令时发生异常、将 ACC 和 XT 寄存器相乘。  

在 QMPYL 之后可在此处看到 R0H 异常0xFFFFFFFF  

glVEncDelta [0]变得异常。  

在故障排除几个小时后、我们发现没有逻辑解释、我们必须在编译器时间寻求帮助。 由于汇编指令不正确、似乎编译器中确实存在问题。 问题是,当我们深入研究时,就像试图把全局变量做很长时间一样,问题就会消失。 因此,似乎某种安排会导致出现这一问题。  

您可以通过远程连接到我们的 PC、查看是否需要我。  

拆卸步骤如下:  

093bfa:0394 SUBL ACC、*+ XAR4[AR0]
093bfb:1E9C MOVL *+XAR4[AR1]、ACC
15687 if (glVEncOn[sAxisNumber]!= 0)
093bfc:0604 MOVL ACC、@0x4
093bfd:FFE100B1 B $C$L2291、EQ
093bff:761F066D MOVW DP、#0x66d
15690超长 llDelta =(超长)(lTemp - glVirtualEncoderPointerPrevValue[sAxisNumber]);
093C01:8A1A MOVL XAR4、@0x1A
093c02:761F066C MOVW DP、#0x66c
093C04:06C4 MOVL ACC、*+ XAR4[0]
093C05:033E SUBL ACC、@0x3E
093c06:761F066C MOVW DP、#0x66c
093C08:1EAC MOVL @XT、ACC
15699 glVEncDelta [sAxisNumber]=(long)((long double) llTemp);
093C09:56630000 QMPYL ACC、XT、@0x0
093C0b:BDA90F12 MOV32 R0H、@Ω ACC
093C0d:7700 NOP
093C0e:7700 NOP
093C0f:7700 NOP
093c10:7700 NOP
093c11:E6858000 I64TOF64 R0、R0
093c13:761F066B MOVW DP、#0x66b
093c15:E6840000 F64TOI32 R0H、R0
15691 glVirtualEncoderPointerPrevValue[sAxisNumber]= lTemp;
093c17:06C4 MOVL ACC、*+ XAR4[0]
15699 glVEncDelta [sAxisNumber]=(long)((long double) llTemp);
093c18:E203003E MOV32 @0x3E、R0H
093c1a:761F066C MOVW DP、#0x66c

而我们使用的代码片段如下所示:  

 

如果(glVEncOn[sAxisNumber]!= 0)
{
lTemp =*(glpVirtualEncoderPointer[sAxisNumber]);
超长整型 llDelta =(超长整型)(lTemp - glVirtualEncoderPointerPrevValue[sAxisNumber]);
glVirtualEncoderPointerPrevValue[sAxisNumber]= lTemp;

//从定义文档("Rational Virtual Encoder Feature Definitions.docx ")中:
//
// 1. temp = Delta * VEncFact + Crip_over // temp 为整数!!
// 2. output_counts = round ((double) temp / VEncFactDen)// output_counts 当然是整数
// 3. carry_over = temp output_counts * VEncFactDen // carry_over 为整数!
long long llTemp = llDelta *(((long long) glVEncFact[sAxisNumber]);//+ gllVEncCarryOver[sAxisNumber];
glVEncDelta [sAxisNumber]=(long)((long double) llTemp);

请告知我们如何处理。 对我们来说,局势非常严峻。 压力非常高的情况。  

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

    对于包含这些行的源文件...

    Unknown 说:
    if (glVEncOn[sAxisNumber]!= 0)
    {
    lTemp =*(glpVirtualEncoderPointer[sAxisNumber]);
    超长整型 llDelta =(超长整型)(lTemp - glVirtualEncoderPointerPrevValue[sAxisNumber]);
    glVirtualEncoderPointerPrevValue[sAxisNumber]= lTemp;

    ... 请按照 如何提交编译器测试用例一文中的说明进行操作

    谢谢。此致、

    -乔治

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

    您好、George、  

    感谢您的答复、附件是这些文件  

    我会私下向您介绍这些细节。  

    此致、

    Cj  

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

    感谢您提供测试用例。  很遗憾,我无法生成此代码...

    [报价 userid="305428" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1280414/tms320f28388d-qmpyl-instruction-in-disassembly-is-behaving-abnormally-when-handling-cast-of-a-local-variable-from-long-long-to-long-double ]093c09:56630000 QMPYL ACC、XT、@0x0
    093C0b:BDA90F12 MOV32 R0H、@Ω ACC
    093C0d:7700 NOP
    093C0e:7700 NOP
    093C0f:7700 NOP
    093c10:7700 NOP
    093c11:E6858000 I64TOF64 R0、R0
    093c13:761F066B MOVW DP、#0x66b
    093c15:E6840000 F64TOI32 R0H、R0

    我使用版本20.2.5.LTS 和相同的构建选项。  但我还添加了选项、 -- src_interlist 。  这会告诉编译器保留生成的汇编文件、并向其中添加注释、以便于理解。  这是我看到的...

            LCR       #||__c28xabi_mpyll||  ; [CPU_ALU] |43961| 
            ; call occurs [#||__c28xabi_mpyll||] ; [] |43961| 
            MOVL      XAR5,ACC              ; [CPU_ALU] |43961| 
    	.dwpsn	file "file.c",line 43962,column 4,is_stmt,isa 0
            MOV32     R0H,XAR5              ; [CPU_FPU] |43962| 
            NOP       ; [CPU_ALU] 
            NOP       ; [CPU_ALU] 
            MOVW      DP,#||llTemp||        ; [CPU_ARAU] 
    	.dwpsn	file "file.c",line 43961,column 4,is_stmt,isa 0
            MOVL      @$BLOCKED(||llTemp||),P ; [CPU_ALU] |43961| 
    	.dwpsn	file "file.c",line 43962,column 4,is_stmt,isa 0
            I64TOF64  R0,R0                 ; [CPU_FPU] |43962| 
    	.dwpsn	file "file.c",line 43961,column 4,is_stmt,isa 0
            MOVL      @$BLOCKED(||llTemp||)+2,ACC ; [CPU_ALU] |43961| 
    	.dwpsn	file "file.c",line 43962,column 4,is_stmt,isa 0
            F64TOI32  R0H,R0                ; [CPU_FPU] |43962| 

    重点关注说明。  忽略 .dwpsn DWARF 指令。  这是一个非常不同的指令序列。  特别是 QMPYL 指令未使用。  每当编译器生成 QMPYL ,指令 IMPYL 附近。  但不在这里。  发生了一些不寻常的事情。

    名为的独立反汇编器 DI2000 相同 二进制 Directory 作为编译器 cl2000 。  请使用它来反汇编链接器创建的最终可执行文件。  从命令提示符下、发出类似于以下内容的命令:

    dis2000 final_executive.out > disassembly_file.txt

    检查拆解情况。  您在地址0x093C09看到什么?  如果它不是 QMPYL 说明、它是如何变为 QMPYL 指令执行时到达该地址?

    谢谢。此致、

    -乔治