ZHCUBL2L January   2018  – March 2025

 

  1.   1
  2.   C7000 主机仿真
  3. 1 关于本文档
    1. 1.1 相关文档
    2. 1.2 免责声明
    3. 1.3 商标
  4. 2 主机仿真入门
    1. 2.1 系统要求
    2. 2.2 安装说明
    3. 2.3 主机仿真库版本
    4. 2.4 差异总结:主机仿真编码与原生 C7000 编码
  5. 3 一般编码要求
    1. 3.1 所需的头文件
    2. 3.2 包依赖项
    3. 3.3 示例程序
  6. 4 内在函数
    1. 4.1 类似 OpenCL 的内在函数
    2. 4.2 流地址生成器内在函数
    3. 4.3 C6000 传统内在函数
    4. 4.4 存储器系统内在函数
  7. 5 TI 向量类型
    1. 5.1 构造函数
    2. 5.2 访问器
    3. 5.3 向量运算符
    4. 5.4 打印调试函数
  8. 6 流引擎和流地址生成器
  9. 7 查询表和直方图接口
    1. 7.1 查询表和直方图数据
  10. 8 C6000 迁移
    1. 8.1 __float2_t 传统数据类型
  11. 9 矩阵乘法加速器 (MMA) 接口
  12. 10编译器错误和警告
    1. 10.1 编译器错误和警告中包含的关键术语
    2. 10.2 主机仿真特定语法
  13. 11修订历史记录
  14.   36

__float2_t 传统数据类型

对于 C7000 编译器,__float2_t 传统类型始终被视为 double。这对于 C7000 编译器有效,因为 double 是 64 位宽,可以容纳两个 32 位浮点元素以用于 SIMD 运算。

如果使用在 Intel x86 架构上执行的主机系统,则情况并非如此。在 Intel x86 计算机上执行双精度型的加载和存储时,会发生自动转换,将 64 位双精度型转换为 80 位“扩展实数”类型。当使用双精度型来存储两个不同的 32 位浮点值时,这会带来问题,因为 80 位“扩展实数”类型会进行规范化,从而改变存储器中的位。如果对表示两个 32 位浮点类型的 double 进行规范化的 80 位类型扩展,则无法再保证数据,并且期望两个浮点值的 SIMD 运算将产生不一致的结果。

为解决此问题,C7000 主机仿真针对 __float2_t 类型包含一个单独的类定义,该定义被视为不透明容器类型。容器类型只能使用特殊的内在函数进行修改、访问和初始化。虽然 __float2_t 类定义包含公共访问器方法,但建议仅使用内在函数来修改 __float2_t 类型,因为 C7000 主机仿真 __float2_t 类型的任何成员都不会在 C7000 编译器中定义。当传统内在函数中需要表示两个 32 位浮点值的单个数据结构时,应使用 __float2_t 类类型。在编写利用 C6000 旧版构造的 C7000 主机仿真代码时,double 类型只能用于表示一个双精度浮点值。

由于 __float2_t 类型有单独的定义,因此必须使用 _ftof2 内在函数来构造 __float2_t 类型。对于 C7000 编译器,此内在函数定义为 _ftod,它根据两个浮点指针参数创建一个 double 类型。__float2_t 的访问器方法以相同的方式定义。

表 8-1 列出了明显定义用于 C7000 主机仿真的内在函数。尽管此表中所列内在函数的定义有所不同,但为 C7000 主机仿真编写的旧代码无需更改即可传输到 C7000 编译器。

表 8-1 主机仿真中具有不同定义的传统内在函数
内在函数名称以前的定义函数
_ftof2_ftod从 2 个浮点值构造 __float2_t 类型
_lltof2_lltod将 long long 值转换为 __float2_t 类型
_f2toll_dtoll将 __float2_t 类型转换为 long long
_hif2_hif从 _float2_t 类型访问高 32 位 float
_lof2_lof从 _float2_t 类型访问低 32 位 float
_fdmv_f2_fdmv使用 PACK 指令从 2 个 float 构造 __float2_type 的替代方法
_fdmvd_f2_fdmvd使用 PACKWDLY4 指令从 2 个 float 构造 __float2_type 的替代方法
_hif2_128_hid128从 __x128_t 类型访问高 __float2_t 类型
_lof2_128_lod128从 __x128_t 类型访问低 __float2_t 类型
_f2to128_dto128根据 2 个 __float2_t 类型构造 _x128_t 类型

以下示例以注释中所示的有效和无效方式构造和设置 __float2_t 变量。

/* __float2_t type examples: Host Emulation Code */

#include <c7x.h>
#include <c6x_migration.h>

int main(){
    // Valid ways to construct a __float2_t
    __float2_t src1 = _ftof2(1.1022, 2.1010);
    __float2_t src2 = _ftof2(-1.1, 4.10101);

    // Invalid way to construct a __float2_t in Host Emulation
    // __float2_t from_double = (double)1.0;

    // Legal to set a __float2_t from other pre-constructed
    // __float2_t types (done using intrinsic)
    src1 = src2;

    // It is illegal to set a __float2_t type via a
    // constructor call. The following will not compile:
    // src1 = __float2_t(1.0, 2.0);

    // Correct way to access lo/hi
    float lo_correct = _lof2(src1);

    // Intrinsic use example
    __float2_t res = _daddsp(src1, src2);

    return 0;
}