RISC-V: Branch 指令

亲爱的,帮忙去超市买 1 颗苹果回来,如果他们有鸡蛋的话,买 6 颗。
Simple logic problem that engineers should know.

前面的指令都是执行到就会做对应的事,
只有 Branch 系列指令会先做检查,
然後决定接下来是要执行下一道指令(current_pc + 4),
还是跳到其他位置再继续执行(current_pc + imm*2)。

行为上可以把 BRANCH 指令当作范围较小的 JUMP 指令用,
但为了不让 Branch Prediction 的预测方法受到影响,
规格书建议不要这样做。

和 JUMP 指令同样要注意的是,
如果跳到不合法的位置会触发 instruction-address-misaligned exception。

B-type

指令格式如下:

|31     25|24   20|19   15|14    12|11   7|6       0|
+---------------------------------------------------+
|   imm   |  rs2  |  rs1  | funct3 | imm  | opcode  |
+---------------------------------------------------+

BEQ

pc = current_pc + (rs1 == rs2 ? imm*2 : 4)

|31     25|24   20|19   15|14    12|11   7|6       0|
+---------------------------------------------------+
|   imm   |  rs2  |  rs1  |  000  | imm  | opcode  |
+---------------------------------------------------+

BNE

pc = current_pc + (rs1 != rs2 ? imm*2 : 4)

|31     25|24   20|19   15|14    12|11   7|6       0|
+---------------------------------------------------+
|   imm   |  rs2  |  rs1  |  001  | imm  | opcode  |
+---------------------------------------------------+

BLT

pc = current_pc + (rs1 < rs2 ? imm*2 : 4)

|31     25|24   20|19   15|14    12|11   7|6       0|
+---------------------------------------------------+
|   imm   |  rs2  |  rs1  |  100  | imm  | opcode  |
+---------------------------------------------------+

BGE

pc = current_pc + (rs1 >= rs2 ? imm*2 : 4)

|31     25|24   20|19   15|14    12|11   7|6       0|
+---------------------------------------------------+
|   imm   |  rs2  |  rs1  |  101  | imm  | opcode  |
+---------------------------------------------------+

BLTU

pc = current_pc + ((uint32_t)rs1 < (uint32_t)rs2 ? imm*2 : 4)

|31     25|24   20|19   15|14    12|11   7|6       0|
+---------------------------------------------------+
|   imm   |  rs2  |  rs1  |  110  | imm  | opcode  |
+---------------------------------------------------+

BGEU

pc = current_pc + ((uint32_t)rs1 >= (uint32_t)rs2 ? imm*2 : 4)

|31     25|24   20|19   15|14    12|11   7|6       0|
+---------------------------------------------------+
|   imm   |  rs2  |  rs1  |  111  | imm  | opcode  |
+---------------------------------------------------+

实际程序

github 页面 Tag: ITDay19

吸取昨天的经验,
这次先实作 get_imm_b 减少指令实作的复杂度。

//instructionDecoder.cpp
int32_t INSTRUCTION_DECODER::get_imm_b()
{
	auto value = sc_dt::sc_int<32>();
	value(12, 12) = instruction_value(31, 31);
	value(11, 11) = instruction_value(7, 7);
	value(10, 5) = instruction_value(30, 25);
	value(4, 1) = instruction_value(11, 8);
	value <<= 19;
	value >>= 19;
	return value;
}

指令实作的部分很单纯,就跟上面写的一样,
只要把依照比较结果设定 new_pc 的值就好,
这边只列出 BEQ 指令当作范例。

//executor.cpp
...
		case INSTRUCTION_DECODER_INTERFACE::BRANCH_OP:
			switch (instruction_decoder->get_func3()) {
				case INSTRUCTION_DECODER_INTERFACE::BEQ_FN3:
					BEQ_E();
					break;
...
void EXECUTOR::BEQ_E()
{
	auto offset = instruction_decoder->get_imm_b();
	auto rs1 = instruction_decoder->get_rs1();
	auto rs2 = instruction_decoder->get_rs2();

	new_pc = register_file->get_pc() +
	         (register_file->get_value_integer(rs1) == register_file->get_value_integer(rs1) ?
	          offset : 4);
}
...

<<:  #19 Telegram Bot 起手式

>>:  [Day 18]所以我说那个酱汁呢(前端篇)

Day 12 实作资料库

前言 今天会实作资料库的结构。我们总共需要实作三个 table 的 scheme,分别是 users...

利用十字链结串列概念思考流程 - DAY 24

完整图 步骤 STEP 1. 先把索引列的内容列出来 STEP 2. 从 0->n 开始想他会...

Python 演算法 Day 5 - 理论基础 向量

Chap.I 理论基础 Part 3:Vector 向量 1. Tensor 张量 0 阶张量=纯量...

[拯救上班族的 Chrome 扩充套件] Chrome Extension 是什麽酷东西? 跟着官方做 Hello Extensions

嗨各位,我是 Robin 今天想跟大家分享如同标题, 到底什麽是 Chrome Extension?...

[Golang]同步工具-sync包的Cond-心智图总结

1. sync包的Cond,提供条件变数。 a. 条件变数是基於互斥锁的,它必须有互斥锁的支撑,才能...