ZHCUBL2K January   2018  – March 2024

 

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

__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;
}