目录
5.3.4 断言(predicate)生成
5 标量处理单元
5.1 概述
标量处理单元(SPU)负责执行大多数数值计算指令。
SPU由两个独立的子单元(名为SPU0和SPU1)组成。它们各自独立工作,由指令分组中的不同指令激活。
指令包中的每个SPU指令都可以基于16个谓词寄存器中的一个独立的条件寄存器。对于单指令/多数据(SIMD)类型的指令,每个操作都可以单独屏蔽(有关更多详细信息,请参阅 第5.3.4节,断言生成)。
SPU在几个执行阶段中运行,不同的指令可以在多个或少个阶段中执行。指令执行所需的阶段数决定了结果可由另一条指令使用之前的周期惩罚。每个指令所需的延迟在CEVA-BX2体系结构规范第II卷中的指令集中描述。
注意:这些类型的操作的吞吐量仍然是每个周期的单个结果。
5.2 SPU指令
通常,所有SPU指令都可以在两个SPU中以相同的方式执行。一些特定指令只能在SPU0上执行,如CEVA-BX2体系结构规范第二卷中的指令描述中的特定指令所述。
SPU指令可以是标量指令(即更新一个目标操作数),也可以是独立操作两个目标操作数位的SIMD类型指令。SPU支持以下类型的操作:
- 算术的
- 乘法
- 逻辑
- 钻头操作
- 其他
以下部分描述了这些操作。
5.2.1 算术运算
所有单元都支持算术运算,包括SIMD类型的运算。支持以下操作:
- 加法和减法
- 最小值和最大值
- 比较
- 部门
- 绝对和取反
5.2.2 乘法和乘法累加操作
每个SPU支持单个32x32乘法器和四个16x16乘法器,可用于SIMD类型的指令。乘法器能够四舍五入、饱和和后移位,以及支持较大乘积和累加的较长累加器。可以以十字形方式(高位字X低位字)执行操作,以适应复数。
- 乘数支持以下说明:
- 乘法(Multiply)
- 乘积累加
- 乘法-减法
- 乘法加法
此外,CEVA-BX2支持专门为加速特殊算法而定制的特殊乘法指令,例如,用于FFT加速的bfly32、bmac和bmacfirst。
5.2.3 逻辑运算
支持标准的逐位逻辑32位操作(AND、ANDNOT、NAND、NOR、NOT、OR、XNOR和XOR)。
逻辑运算既可以在两个寄存器之间操作,也可以在寄存器和立即数之间操作。对于小于32位的立即数操作数,立即数操作数加零。
使用tst指令也支持测试类型指令,该指令支持根据特定断言寄存器设置和清除断言寄存器。
SIMD支持大多数逻辑类型的操作,包括分别用于每个操作的双断言。
5.2.4 位操作操作
支持以下位操作:
- 寄存器向左或向右移位最多64位,逻辑或算术,包括SIMD类型的操作。移位值不受限制,支持移位操作数类型可以容纳的任何值。
- 移位操作最多剩余七位,然后是加法(shiftadd)
- 插入和提取操作
- 统计寄存器中的设置位数(cntbits)
- 查找寄存器(ffb)中的第一个1或第一个0
- 位字段插入和提取指令(插入、提取)
- 重复位操作(bitdup)
插入操作用放在源操作数LSB中的新位/字段替换(即插入)目标操作数中的指定位/字段。位/字段的宽度和偏移量可以由两个五位立即数指定,或者封装在寄存器中,宽度在高部分,偏移量在低部分。
提取操作需要从寄存器中提取有符号或无符号(基于指令中的符号开关)位/字段。目标操作数是寄存器之一。提取字段的宽度和偏移量可以由两个五位立即数指定,或者封装在寄存器中,宽度在高部分,偏移量在低部分。
位复制操作允许将短类型操作数中的每个单个位复制为两个连续的位,然后将结果写入整数类型操作数。
5.2.5 其他操作
支持以下杂项操作:
- 移动:这些操作清除寄存器,将一个寄存器复制到另一个寄存器,将寄存器复制到其他类型的寄存器,反之亦然。
- 字节置换:这些操作以任何置换方式从目标中的输入操作数中选择并排序字节。
- 断言寄存器操作:这些操作复制到断言寄存器或从断言寄存器复制,并执行断言寄存器之间的逻辑关系。
5.2.6 64位支持
SPU支持使用有限功能集的64位操作。这些操作使用两个连接的32位GRF寄存器。64位操作数支持以下操作:
- Add/subtract
- Multiply-accumulate (the accumulator can be 64 bits)
- Multiply (the result can be 64 bits for 32x16 and 32x32 multiplications)
- Shift
- cmp, min, abs, exp, extract, lim, neg, test and max
5.3 支持的数据类型
SPU支持以下数据类型:
- 8位字符
- 16位短整数
- 32位整数
- 64位长整数
- 32位单精度浮点(符合IEEE-754)
- 16+16和32+32复数
- 16位半精度浮点(符合IEEE-754)
整数数据类型具有有符号和无符号变体。此外,还支持紧凑形式的16位短整数,其中两个短16位值作为两个元素向量存储在单个32位寄存器中,并且可以由专用SIMD指令并行处理。
中列出了数据类型的大小、语法和范围。在CEVA-BX2体系结构规范第II卷的每个指令中具体描述了支持的源和目标类型。
表5-1.SPU数据类型
寄存器类型 | 大小(位) | Value Range | 数据位 | 符号扩展位 | 语法 |
Signed Char | 8 | -2^7 to (2^7-1) | 0–7 | 8–31 | rX.c |
Unsigned Char | 8 | 0 to (2^8-1) | 0–7 | 8–31 | rX.uc |
Signed Short | 16 | -2^15 to(2^15-1) | 0–15 | 16–31 | rX.s |
Unsigned Short | 16 | 0 to(2^16-1) | 0–15 | 16–31 | rX.us |
Dual Signed Short | 2X16 | -2^15 to(2^15-1) | 0–15 and 16- 31 | --- | rX.s2 |
Dual Unsigned Short | 2X16 | 0 to(2^16-1) | 0–15 and 16- 31 | --- | rX.us2 |
Signed Integer | 32 | -2^31 to(2^31-1) | 0–31 | --- | rX.i |
Unsigned Integer | 32 | 0 to(2^32-1) | 0–31 | --- | rX.ui |
Signed Long Long | 64 | -2^63 to(2^63-1) | 0–63 | rX.l Note: Two separate 32-bit registers are assigned to the long long type. | |
Unsigned Long Long | 64 | 0 to(2^64-1) | 0–63 | rX.ula | |
Single-Precision Float | 32 | (-1)^sign x(2^-149 to 2^128) | 0–30 Note: Bits [22:0] for mantissa and [30:23] for exponent | 31 | rX.f |
Half-Precision Float | 16 | (-1)^sign x (2^-24 to(2-2^(-10))x 2^15)) | 0-14 Note: Bits [9:0] for mantissa and [14:10] for exponent. | 15 | rX.hf |
由于GRF寄存器的大小为32位,因此SPU结果始终写入32位(64位操作除外)。这意味着有符号字符和有符号短数据类型被符号扩展到32位,无符号字符和无符号短数据类被零扩展到32比特。这不适用于双短数据类型。
5.3.1 源操作数
所有单个(即不是SIMD)SPU操作都假设源根据源类型进行符号或零扩展到32位。这意味着无论源类型如何,SPU都会执行相同的操作。因此,用户必须确保输入类型的值不超过值位,并且符号位基于输入类型是正确的。使用不符合所使用的特定ISA语法指定的数据类型的类型,如表5-1所述,将导致目标中的未定义值。
5.3.2 目标操作数
单个操作(即,不是SIMD)中的SPU目标将根据目标类型自动进行符号扩展或零扩展。这确保寄存器值符合数据类型定义,并且它可以用作以下指令的源,而不必进行任何转换或修改。
在SIMD操作中,SPU根据目标类型进行符号或零扩展。
5.3.3 SIMD操作
SPU支持SIMD操作,这在双短数据类型(有符号或无符号)上受支持。支持以下操作:
- 算术的
- 逻辑
- 钻头操作
- 其他
每个操作都可以由一个双断言(predicate)进行预测,从而使SIMD指令的每个部分都可以单独进行预测,如例5-1中所示。
例5-1.SIMD类型标量操作
ld (r5.ui).i4+r20, r1.i, r2.i, r3.i, r4.i ... cmp {lt} r2.s2, r1.s2, pr1.b2 ;comparison is done to each part separately nop add r3.s2, r4.s2, r10.s2, ?pr1.b2 ;each part is added separately based on ;the two comparisons of the previous instruction |
5.3.4 断言(predicate)生成
断言生成指令可以更新断言的值,而断言值随后又可以用于断言其他指令。一些断言生成指令仅用于此目的,这意味着断言是它们的唯一目标(例如,cmp指令)。其他指令执行操作,但也会作为副作用更新断言(例如,更新GRF寄存器的最小和最大指令)。有关这些指令的更多详细信息,请参阅CEVA-BX2架构规范第二卷中的描述。
断言由PRDR寄存器中的两个位组成。断言pr0占用位0和16,断言pr1占用位1和17,依此类推。断言生成指令更新这两个位。
有两种类型的断言生成指令:
- 标量断言生成指令:这些指令执行一个条件计算。这些指令的输入操作数是标量。
在这种情况下,目标断言的两个位都用反映条件计算的二进制结果的相同值更新。
- SIMD断言生成指令:它们并行执行两个条件计算。这些指令的输入操作数是s2或us2类型。
每个计算的结果分别存储在断言的每个位中。
大多数断言生成指令都有两个目标断言(更新PRDR寄存器中的四个位,每个断言两个位):
- 使用计算结果更新指令语法中的第一个目标断言,如前一列表中所定义的。
- 用每个断言位的逆值更新第二个断言。这使得后续指令能够在断言化时从计算的正结果和负结果中进行选择。
例如,实现“if-then-else”序列的指令可以使用一个条件计算,使用第一个目标断言来断言属于“if”子句的指令,然后使用第二个(反向)目标断言来断言属于“else”子句的指令。如果只需要一个目标谓语,则用户可以选择pr15作为第二个断言,这相当于不选择第二断言。
断言生成指令本身可以断言。如果设置了断言,则指令会按照前面的描述更新其目标断言。然而,如果没有设置断言,那么在这种情况下,结果上有两个行为变体。语法定义了此断言影响断言生成指令的两种方式:
- 如果断言语法是用前导词指定的?(例如,?pr0.b),这意味着,如果未设置断言,则指令不会更改目标断言。
- 如果断言语法是用前面的&(例如,&pr1.b2)指定的,这意味着,如果未设置断言,则清除目标断言。在这种特定的情况下,由于两个目标断言都被清除,因此第二个断言不是另一个断言的倒数。
prm指令用于通用断言算术,如OR和and。该指令接受三个输入断言,并更新两个目标断言:一个是另一个的倒数,匹配两个断言输出的常规约定。tst指令基于标量操作数中选定位的值设置或清除目标断言。flcopy指令将SASR中所选算术状态标志的状态复制到断言。