简体   繁体   English

为什么 RISC-V 没有与立即值相等的条件分支?

[英]Why RISC-V don't have conditional branch equal with immediate value?

Following is most common conditional branch code in my RISC-V assembly project.以下是我的 RISC-V 汇编项目中最常见的条件分支代码。

li a0, UART1_BASE;
lw t0, UART_INTR_PEND_OFFSET(a0); // Read UART interrupt pending status

andi t0, t0, 1;
li t1, 1; // IMM LOAD
beq t0, t1, LB_process_tx; // UART Tx interrupt 
// else UART rx interrupt 

The IMM LOAD instruction li t1, 1 could be avoided if branch equal instruction has a immediate variant (like beqi t0, 1, LB_process_tx . I don't find immediate variant for conditional branch. Correct me if I'm wrong.如果分支相等指令具有立即变体(例如beqi t0, 1, LB_process_tx则可以避免 IMM LOAD 指令li t1, 1 。我没有找到条件分支的立即变体。如果我错了,请纠正我。

I am well aware that lot of thoughts have gone in the RISC-V instruction set and hence more interested in knowing is there any other way of doing this conditional branch with lesser instructions .我很清楚 RISC-V 指令集中有很多想法,因此更想知道是否有其他方法可以用较少的指令来执行此条件分支 if not, what might be the reasoning behind not having the immediate variant for conditional branch?如果不是,那么没有条件分支的直接变体的原因可能是什么?

Instruction format-wise, the field for register can be used for imm5 value.指令格式方面,寄存器字段可用于 imm5 值。

There's not so much room in the instruction encoding!指令编码没有那么多空间!

There already is an immediate — the branch target.已经有一个直接的——分支目标。

Conditional branching generally requires many operands: two sources, a condition and a branch target.条件分支通常需要很多操作数:两个源,一个条件和一个分支目标。 Many instruction sets split them into two instructions, compare and branch linked together by condition codes.许多指令集将它们分成两条指令,比较和分支通过条件代码链接在一起。

But RISC V chooses to avoid condition codes, so offers those two register source branches instead.但是 RISC V 选择避免使用条件代码,因此提供了这两个寄存器源分支。

If that code is in a tight loop, you can place the immediate into a register before the loop, and save that instruction inside the loop.如果该代码处于紧密循环中,您可以将立即数放入循环之前的寄存器中,并将该指令保存在循环内。

Even better, you can switch to a bne using the zero register instead of comparing against 1 in that code sequence to eliminate the li .更好的是,您可以使用零寄存器切换到bne ,而不是与该代码序列中的 1 进行比较以消除li

Original:原来的:

andi t0, t0, 1;
li t1, 1; // IMM LOAD
beq t0, t1, LB_process_tx; // UART Tx interrupt 

Since the andi operation in the above constrains the result to 0 or 1, we can use bne to check for zero instead, without needing the li :由于上面的andi操作将结果限制为 0 或 1,我们可以使用bne来检查零,而不需要li

andi t0 t0 1
bne t0, zero, LB_process_tx  # compare for != 0

or, here where the andi result constrains to 0 or 2, we can still use bne :或者,在andi结果限制为 0 或 2 的情况下,我们仍然可以使用bne

andi t0, t0, 2
bne t0, zero, LB_process_rx

Instruction format-wise, the field for register can be used for imm5 value.指令格式方面,寄存器字段可用于 imm5 值。

Yes, that could work.是的,这可以工作。 This would might require an additional opcode (or if restricted to just bne and beq leaving out the other relations, could be squeezed into the func3 of the existing SB format main opcode), and then would also require an additional instruction format.这可能需要一个额外的操作码(或者如果仅限于bnebeq ,而忽略其他关系,可以将其压缩到现有SB格式主操作码的func3中),然后还需要一个额外的指令格式。

The value in code space and other performance improvement is unknown to me, given that the immediate value of 0 (probably the most important immediate) is already accounted for with the zero register, and given that the li instruction can be moved out of tight loops.代码空间和其他性能改进的价值对我来说是未知的,因为 0 的立即数(可能是最重要的立即数)已经用零寄存器考虑了,并且考虑到li指令可以移出紧密循环. However, those other factors (new opcode/instruction format) would complicate especially the low end / embedded processor implementation (known to be very important to the designers) in return for that (small?) improvement.然而,那些其他因素(新的操作码/指令格式)会使特别是低端/嵌入式处理器实现(已知对设计人员非常重要)复杂化,以换取(小?)改进。 The RISC V design allows for extensibility though, so this could still be conceivably implemented. RISC V 设计允许可扩展性,因此这仍然可以实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM