• Hexagon_V65_Programmers_Reference_Manual(7)


    6 条件执行

    Hexagon处理器使用基于比较指令的条件执行模型在四个8位断言寄存器(P0-P3)之一中设置断言位。这些断言位可以用于有条件地执行某些指令。

    条件标量运算只检查断言寄存器中的最低有效位,而条件向量运算检查寄存器中的多个位。

    分支指令是断言寄存器的主要使用者。

    6.1 标量断言

    标量断言是8位值,在条件指令中用于表示

    真值:

    • 0xFF表示true
    • 0x00表示错误

    Hexagon处理器提供四个8位断言寄存器P0-P3来保存标量断言(第2.2.5节)。这些寄存器由生成断言的指令,并由断言使用指令检查

    6.1.1生成标量断言

    以下指令生成标量断言:

    • 比较字节、半字、字、双字
    • 比较单精度浮点和双精度浮点
    • 对浮点值进行分类
    • 比较位掩码
    • 边界检查
    • TLB匹配
    • 存储条件

    表6-1列出了标量断言生成指令。
    t6-1-1

    t6-1-2
    注:其中一个比较指令(cmp.eq)包括一个变量,该变量存储通用寄存器而非断言寄存器中的二进制断言值(0或1)

    6.1.2使用标量断言

    某些指令可以基于标量断言的值有条件地执行(或者指定标量断言作为其操作的输入)。

    使用标量断言的条件指令只检查断言值的最低有效位。在最简单的情况下,该位值直接决定是否执行指令:
     1表示指令已执行
     0表示未执行指令

    如果条件指令包含运算符!在其断言表达式中,逻辑位值的求反决定是否执行指令。

    条件指令用带指令前缀的汇编语言表示“if(pred\u expr)”,其中pred\u expr指定断言表达式。例如:
    if (P0) jump target // jump if P0 is true
    if (!P2) R2 = R5 // assign register if !P2 is true
    if (P1) R0 = sub(R2,R3) // conditionally subtract if P1
    if (P2) R0 = memw(R2) // conditionally load word if P2

    以下指令可用作条件指令:

    • 跳转和呼叫(第7.3节)
    • 许多装载和存储说明(第5.9节)
    • 逻辑指令(包括和/或/异或)
    • 移位半字
    • 32位寄存器加减或短立即数
    • 符号和零扩展
    • 32位寄存器传输和64位组合字
    • 立即注册转移
    • 释放帧并返回

    当执行条件加载或存储时,断言表达式为false,则指令被取消(包括可能发生的任何异常)。例如,如果条件加载使用内存权限冲突的地址和断言表达式为false,不会执行加载,也不会引发异常。

    mux指令接受断言作为其基本操作数之一:

    Rd = mux(Ps,Rs,Rt)

    mux根据Ps中的最低有效位选择Rs或Rt。如果最低有效位Ps中的位为1,Rd设置为Rs,否则设置为Rt。

    6.1.3自动并操作断言

    如果数据包中的多个比较指令写入同一断言寄存器,则结果是单个比较结果的逻辑与。例如:
    {
    P0 = cmp(A) // if A && B then jump
    P0 = cmp(B)
    if (P0.new) jump:T taken_path
    }

    要执行相应的OR操作,可以使用以下说明计算现有比较的否定(使用德摩根定律):

    • Pd = !cmp.{eq,gt}(Rs, {#s10,Rt} )
    • Pd = !cmp.gtu(Rs, {#u9,Rt} )
    • Pd = !tstbit(Rs, {#u5,Rt} )
    • Pd = !bitsclr(Rs, {#u6,Rt} )
    • Pd = !bitsset(Rs,Rt)

    Auto和断言有以下限制:

    • 如果数据包包含endloopN,则无法执行auto和with断言寄存器P3。
    • 如果数据包包含从通用寄存器到断言的寄存器传输寄存器,数据包中的任何其他指令都不能写入同一断言寄存器。(因此,到P3:0或C5:4的寄存器传输不能与任何其他寄存器分组。断言编写指令。)
    • 指令spNloop0、decbin、tlbmatch、memw\U locked、memd\U locked、,
      添加:进位、子:进位、sfcmp和dfcmp不能与另一个分组设置相同断言寄存器的指令。

    注:从断言寄存器到断言寄存器的寄存器传输具有与比较指令相同的自动和行为

    6.1.4Dot-New断言

    Hexagon处理器可以在同一条指令中生成和使用标量断言数据包(第3.3节)。此功能在汇编语言中通过附加指定断言寄存器的后缀“.new”。例如:

    if (P0.new) R3 = memw(R4)

    要了解如何使用dot new断言,请考虑以下C语句和编译器从中生成的相应汇编代码:

    C statement
    if (R2 == 4)
    R3 = *R4;
    else
    R5 = 5;

    Assembly code
    {
    P0 = cmp.eq(R2,#4)
    if (P0.new) R3 = memw(R4)
    if (!P0.new) R5 = #5
    }

    以下条件适用于使用dot新断言:
     断言必须由同一数据包中的指令生成。这个汇编程序通常强制执行此限制,但如果处理器执行数据包如果违反此限制,则执行结果未定义。
     单个数据包可以包含新断言和正常断言。这个范式检查断言寄存器中的旧值,而不是新产生的价值。例如
    {
    P0 = cmp.eq(R2,#4)
    if (P0.new) R3 = memw(R4) // use newly-generated P0 value
    if (P0) R5 = #5 // use previous P0 value
    }

    6.1.5 依赖约束

    指令包中的两条指令不应写入同一目标寄存器(第3.3.5节)。此规则的一个例外是,如果这两条指令是有条件的,并且当数据包为时,其中只有一个断言表达式值为true执行。

    例如,只要P2和P3都不计算为,以下数据包就有效执行数据包时为true
    {
    if (P2) R3 = #4 // P2, P3, or both must be false
    if (P3) R3 = #7
    }
    由于断言值在运行时发生变化,程序员负责确保这些数据包在程序执行期间始终有效。如果无效,则处理器执行以下操作:

    • 写入通用寄存器时,会引发错误异常。
    • 写入断言或控制寄存器时,结果未定义。

    6.2向量断言

    断言寄存器也用于条件向量运算。与标量不同

    断言、向量断言包含由向量生成的多个真值

    断言生成操作。

    例如,向量比较指令比较向量的每个元素并赋值

    将结果与断言寄存器进行比较。断言向量中的每一位都包含一个真值

    值,指示向量指令执行的单独比较的结果。

    矢量多路复用指令使用矢量断言有选择地合并两个指令中的元素

    将向量分离为单个目标向量。此操作有助于启用

    具有控制流(即分支)的回路矢量化。

    下面几节介绍了使用断言的向量指令。

    6.2.1矢量比较

    向量比较指令输入两个64位向量,对其执行单独的比较每对向量元素,并生成一个断言值,其中包含真值。
    图6-1显示了向量字节比较的示例
    f6-1
    在图6-1中,比较了两个64位字节向量(包含在Rss和Rtt中)。

    结果作为向量断言分配给目标寄存器Pd。

    在图6-1所示的示例向量断言中,请注意,每隔一个比较结果在断言中为true(即1)。

    图6-2显示了向量半字比较如何生成向量断言。
    f6-2
    在图6-2中,比较了半字的两个64位向量。结果已分配作为目标寄存器Pd的向量断言。

    因为向量半字比较只产生四个真值,所以每个真值是在生成的向量断言中编码为两位

    6.2.2矢量多路复用指令

    矢量多路复用指令用于有条件地从两个矢量中选择元素。

    该指令将两个源向量和一个断言寄存器作为输入。对于中的每个字节

    在向量中,断言寄存器中的对应位用于从

    两个输入向量。组合结果写入目标寄存器。

    图6-3显示了矢量多路复用指令的操作。
    f6-3
    表6-2定义了矢量多路复用指令
    t6-2
    更改多路复用指令中源操作数的顺序可以同时启用要形成的结果。例如:

    R1:0=vmux(P0,R3:2,R5:4)//如果为true,则从R3:2中选择字节

    R1:0=vmux(P0,R5:4,R3:2)//如果为false,则从R3:2中选择字节

    注意:通过复制由字或半字比较生成的断言位矢量多路复用指令可用于选择字或半字。

    6.2.3向量条件支持用于使用条件语句对循环进行向量化。

    考虑以下C语句:
    for (i=0; i<8; i++) {
    if (A[i]) {
    B[i] = C[i];
    }
    }

    假设字节数组,该代码可以矢量化如下

    R1:0 = memd(R_A) // R1:0 holds A[7]-A[0]
    R3 = #0 // clear R3:2
    R2 = #0
    P0 = vcmpb.eq(R1:0,R3:2) // compare bytes in A to zero
    R5:4 = memd(R_B) // R5:4 holds B[7]-B[0]
    R7:6 = memd(R_C) // R7:6 holds C[7]-C[0]
    R3:2 = vmux(P0,R7:6,R5:4) // if (A[i]) B[i]=C[i]
    memd(R_B) = R3:2 // store B[7]-B[0]

    6.3断言运算

    六边形处理器提供了一组操作和移动操作断言寄存器。

    表6-3列出了断言寄存器指令。
    t6-3
    注:这些指令属于指令类CR。

    断言寄存器可以在通用寄存器之间传输单独或作为寄存器四倍(第2.2.5节)

  • 相关阅读:
    2023年行云绽放&傲冠股份厨艺比拼团建活动圆满结束
    ubuntu20安装docker、redis、mysql及部署net6应用
    GO-unioffice实现word编辑
    在T3开发板上实现SylixOS最小系统(一)创建BSP工程
    【CVPR2022 点云3D检测SOTA】SoftGroup for 3D Instance Segmentation on Point Clouds
    信息学奥赛一本通(c++):1839:【05NOIP提高组】谁拿了最多奖学金
    19 04-读取DTC快照信息
    Rust数据类型——初学者指南
    js对象转json文件
    如何修改 node_modules 里的文件
  • 原文地址:https://blog.csdn.net/weixin_38498942/article/details/125909963