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.

[参考译文] 编译器/LINUXSDK-OMAPL138:编译器数据类型问题与生成的代码有关

Guru**** 2609895 points


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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/631075/compiler-linuxsdk-omapl138-compiler-data-type-problem-with-generated-code

部件号:LINUXSDK-OMAPL138
主题:OMAPL138中讨论的其它部件

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

我在6.1 1.0.0022万 L138上使用CCS版本OMAP.OMAP与编译器7.4 v.17。 编译器输出格式设置为传统COFF。 SYS/BIOS版本UIA 2.0 v.4.54 和6.41 2.39 工具版本3.30 .6.67_core。

我最近生成了一些代码,这些代码导致了不良行为。 我已将生成的代码缩小到以下代码片段:

#include <ti/SysBIOS/BIOS.h>
#include <xDC/runtime
/Log.h>
#include <xdc/runtime/Diags.h>
#include <xdc/cfg/globL.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>

/---------------
int main (void)
{
typedef long int40_T;//长32位?
typedef int Int32_T;//int 32位
typedef Short Int16_T;//短16位

int40_T Q1;
int40_T累加器;
Int32_T I;
Int32_T inCnt;
Int16_T tempArray[119]={-71,-75,-74,-68,-58, -42,-23,1,27,53, 791.03122135亿,141, 139,
12.8108万,79,42,-1, -48,-96,-143,-185,-220, -244,-255,-252,-232,
-196,-144,-77,1,88, 1782.6835042亿,473, 5025.03472406亿,305,
169,-2,-202,-429,-676, -935,-1199,-1460,-1707,-1934, -2132,-2293,
-2413,-2487,30165,-2487,-2413, -2293,-2132,-1934,-1707,-1460, -1199,
-935,-676,-429,-202,-2, 1693.05406472亿,503, 5024.7342035亿,268,
178,88,1,-77,-144, -196,-232,-252,-255,-244, -220,-185,-143,-96,
-48,-1,42,7.9108万, 1281.39141135亿,122, 103,79,53,27,1, -23,-42,
-58,-68,-74,-75,-71 };

log_print0 (Diags_User1,"Begin");
(i = 118;i < 480;I++)
{
蓄能器= 0L;
对于(inCnt = 0;inCnt < 119;inCnt++)
{
Q1 =-117 * tempArray[inCnt];
如果(蓄能器< 0L)&&(Q1 <-5497558138888L -蓄能器))
{
log_print3 (Diags_User1,"saturate:Q1:%d,ACC:%d,条件:%d",
Q1,蓄能器(-5497558138888L -蓄能器);
蓄能器=-5497558138888L;
Log_Print1 (Diags_User1,"ACC:%d",收集器);
}
否则,如果((收集器> 0L)&&(Q1 > 5497558138887L -收集器))
{
收集器= 54.9755万813887L;
}81.3887万}
否则
{
累加器+= Q1;
}
}
}
log_print0 (Diags_User1,"Done");

// bios_start();/*不返回*/
while (true){}
return(0);
} 

生成的代码工具允许我选择TI的C6000 DSP处理器,并假定数据类型“长”为40位。 根据 TMS320C6000优化编译器v 7.4 用户指南,spru187u,在表6-1中,COFF输出格式的“长,带符号的长”数据类型确实是40位。 如果我在目标(OMAP L138E)上运行上述代码片段,我会意外地碰到“饱和”记录器线路。 打印的变量看起来就像"condition"参数只是在做(0 -累加器),就像它将-5497558138888L处理为32位数(将为零)一样。 这解释了为什么条件语句"(Q1 <-5497558138888L -累加器)在我不期望的情况下评估为真。 第二个饱和日志行确认在分配到40位Long_min后累加器确实为零。

如果我将所有常量long声明更改为long long (例如:-5497558138888LL),并将int40_T typedef更改为long long类型,我将永远不会像我预期的那样达到饱和状态,因为每个地方都使用64位。

在生成代码工具中,我选择了"自定义我的处理器",在这里我可以输入我喜欢的数据类型位宽度。 我将长数据类型更改为使用32位而不是40位,然后重新生成了代码。 现在我无法编译该代码,因为使用TI编译器<limits.h>生成的代码中有#define保护。

#if ( ULong_MAX !=(0xFFFFFFFFFFU))||( LONG_MAX !=(0x7FFFFFFF))
#error Code was generated for compiler with different sized ulong/long。
#endif 

生成的代码尝试使用32位长的长型(0xFFFFFFFFFFU),但TI定义的<limits.h>文件定义的长度为40位,Ulong_MAX =1099511627775U 。 因此编译器确实认为数据类型long应该是40位,但实际上它似乎处理的长度是32位? 我是否缺少某些内容?

感谢您的抽出时间,

Marshall

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

    源代码有两个问题。  但是,纠正这些问题并不能避免意外饱和。  所以我对编译器提出了一个问题。

    一个问题是这种多重...

    [报价用户="Marshall Schiring"] Q1 =-117 * tempArray[inCnt];[/quot]

    这不是40位乘法。  它是32位乘法。  然后,该乘法的结果被扩展为40位,然后分配给Q1。  要使其成为40位乘法,乘法的一个或两个操作数必须为long类型。  一个简单的方法是将117更改为117升。  L后缀表示其类型为long。  有关此主题的详细信息,请参阅文章 如何在C代码中正确写入多路复用

    另一个问题在打印语句中。  您使用%d打印类型long的值。  如果这些Log_print调用的工作方式与printf相同,则不正确。  您必须改用%ld。

    即使在纠正了这些问题之后,也会出现意外饱和。  所以我在 SDOWP系统中提交了CodeGen-3808来调查这个问题。  在这种特殊情况下,我不太确定这是编译器中的一个问题。  我可能忽略了源代码中的问题。  但是,无论原因是什么,让专家参与将有助于找到它。  欢迎您使用我签名中下面的SDOWP链接进行关注。

    请通过复制粘贴方式显示编译时使用的确切选项。  尽管我找到了一个重现问题的选项集,但我们需要使用您使用的选项测试任何可能的解决方案。

    谢谢,此致,

    -George

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

    谢谢George。

    我的C6000编译器选项:

    -mv6740 --abi=coff-off -g --include_path="C:/ti_ccs6_1/ccsv6/tools/compiler/C6000_Oma.17/include" 7.4 --define=omapl138 --diag_wrap=off --diag_warning=225 --display_error_number --diag_suppress=370 speed=370 -0-op_speed

    我在简化和缩小错误来源的努力中遇到了一些错误,这是对的。 该-117L实际上是另一个Int16_T数组,但用此常量替换更简单,仍然产生相同的问题。 将两个16位数组值相乘将始终是一个32位操作,其符号如您所指出的那样扩展-此处应该没有异常。 我认为Log_print语句没有打印超过32位的选项(如printf)。 我参考 了这里的文档 ,在Log_print6下。 通过使用仿真器,我可以验证存储槽是否正确设置为-5497558138888L,因此print语句具有误导性。 但是,正如您所说,修复这两个问题并不会改变意外行为。

    非常感谢您打开事件报告。 我不是很确定这是编译器的问题,但我很感激得到专家的帮助。 我一直在调查违反C算术规则的情况,在使用40位数据类型时,代码生成工具可能需要考虑这一点。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这里有一个错误。 观察:
    #include <stdio.h>

    内部主(无效)

    typedef long int40_T;//长32位?

    int40_T Q1 = 8307;
    int40_T累加器=-8.7282万;
    IN40_T条件=-5497558138888L -蓄能器;

    printf ("条件:%ld \n",条件);
    printf ("%ld <%ld:%d\n",Q1,条件,(Q1 <(-5497.5581万38138888L -3813.8888万 -收集器)));
    printf ("%ld <%ld:%d\n",Q1,条件,(Q1 <条件));
    printf ("%ld <%ld:%d\n",Q1,条件,(Q1 <-54.9755万726606)72.6606万));
    IF (Q1 <-5497558138888L -蓄能器)

    //为什么要执行此操作?
    ("案例1 -嗯");
    }
    }
    状况:-54.9755万726606</s>72.6606万
    8307 <-54.9755万726606:72.6606万:1.
    8307 <-54.9755万726606:72.6606万:0
    8307 <-54.9755万726606:72.6606万:0
    案例1 -嗯
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这里的问题是常量-5497558138888L。 虽然这看起来像带符号的长常量,但实际上是无符号的长表达式。 在C中,负号不是常量的一部分,而是一元的负表达式。 对于C89,后缀为'L'的整数常量是以下列表中其值适合的第一种类型:"long int","unsigned long int"。 由于54.9755万813888太81.3888万太大,无法容纳"长整型",因此它是"长无符号整型"。 之后出现雪球问题。

    如果要将整数值-54.9755万813888作为81.3888万作为"long int"类型,则应将其写为Long_min,或(-5497558138887L-1)

    我将拒绝此缺陷报告。

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

    感谢随访考古学家。 我感谢您为我跟踪此问题所做的工作。  

    我已经联系了代码生成工具的开发人员,了解他们是否可以实施您的建议之一。