英文:
Branch riscv instruction offset calculation on my emulator
问题
我写了一个riscv64模拟器,但在分支指令的偏移计算上遇到了问题(特别是bge指令)。
对我来说,计算满足条件时要添加到pc的偏移量的公式是:PC = PC + IMM;
立即数从指令中提取出来:
这是我的C代码:
void BNE(unsigned long instr) {
unsigned long IMM1 = instr >> 7 & 0b11111;
unsigned long IMM2 = instr >> 25 & 0b1111111;
unsigned long first = IMM1 & 0b1; // 11 eme bits IMM\[11\]
unsigned long second = IMM1 >> 1 & 0b1111; // IMM\[4:1\]
unsigned long third = IMM2 & 0b111111; //imm\[10:5\]
unsigned long fourth = IMM2 >> 6 & 0b1; // IMM\[12\]
// after extract assemble :
unsigned long imm = second | third << 5 | first << 7 | fourth << 9; // \<- I think here is the problem
}
当程序获取这个简单的程序代码时:
// 我简化了代码:
00000000000100e8 \<init\>:
10130: fd843783 ld a5,-40(s0)
1018c: fae7d2e3 bge a5,a4,10130 \<init+0x48\> # 注意我的代码中条件总是满足的
我得到:0x7a2。
pc地址是:0x1018c
当我将0x1018c加到0x7a2时,我得到:0x1092E
有一个问题,但我不知道问题出在哪里。我认为在imm
变量的提取中可能存在问题。
我尝试修改imm
变量的位移和掩码,但没有运气。
我尝试过这些:
unsigned long imm = second | third << 4 | first << 5 | fourth << 6; // 输出错误的数据
unsigned long imm = second | third << 6 | first << 11 | fourth << 12; // 输出与imm相同的数据
unsigned long imm = second | third << 5 | first << 7 | fourth << 9; // 实际版本
unsigned long imm = second | third << 6 | first << 7 | fourth << 8; // 输出与imm相同的数据
英文:
I have wrote a riscv64 emulator but I have an issue on offset calculation for branch instructions (especially for bge).
For me , the formula to calculate offset to add to pc when condition is meet is : PC = PC+IMM;
Immediate is extract from instruction :
there is my C code :
void BNE(unsigned long instr) {
unsigned long IMM1 = instr >>7 & 0b11111;
unsigned long IMM2 = instr >> 25 & 0b1111111;
unsigned long first = IMM1 & 0b1; // 11 eme bits IMM\[11\]
unsigned long second = IMM1 >> 1 & 0b1111; // IMM\[4:1\]
unsigned long third = IMM2 & 0b111111; //imm\[10:5\]
unsigned long fourth = IMM2 >> 6 & 0b1; // IMM\[12\]
// after extract assemble :
unsigned long imm = second | third << 5 | first <<7 | fourth << 9; // \<- I think here is the problem
}
When the program get this simply program code :
// I have simplified the code :
00000000000100e8 \<init\>:
10130: fd843783 ld a5,-40(s0)
1018c: fae7d2e3 bge a5,a4,10130 \<init+0x48\> # note that the condition is always met on my code
I got : 0x7a2.
The pc adress is : 0x1018c
When I add 0x1018c to 0x7a2 , I got :0x1092E
There is an issue but I don't know where. I think the extract on imm variable have some issue.
I have tried to modify the imm variable bits shift and mask. But I don't have any luck.
I have try this :
unsigned long imm = second | third << 4 | first << 5 | fourth << 6; // output wrong data
unsigned long imm = second | third << 6 | first << 11 | fourth << 12; // output the same data as imm
unsigned long imm = second | third << 5 | first << 7 | fourth << 9; // actual version
unsigned long imm = second | third << 6 | first << 7 | fourth <<8; // output the same data as imm
答案1
得分: 0
你已经很接近了,但有几个要点:
- 你的变量
second
包含了位 4 到 1,但你却将它们应用到位 3 到 0,因为你没有将其左移 1 位(或者可以使用额外的>> 1
,注意IMM1 & 0b11110
也可以工作)。 - 你的变量
fourth
包含了位 12,但那是符号位,必须进行符号扩展以用作立即数的 32 位使用。
除此之外,只需按照以下模式检查你的移位操作:[m:n]
必须左移 n
位。所以,假设每个字段都是右对齐的某个变量:
[4:1]
<< 1[11]
<< 11[10:5]
<< 5[12]
<< 12 —— 但要进行符号扩展 —— 因此在 32 位机器上,[12]
<< 31,然后视为有符号数 >> 19,或者使用[12] ? 0xFFFFF000 : 0
或[12] ? -4096 : 0
。
这样,你将获得一个 SB 类型的立即数,它从指令中的混淆的 12 位扩展到 32 位,适合加到 PC 上。
在 bge
指令中编码的立即数值为 0xfae7d2e3,这是 -92(0xFFFFFFA4)。
英文:
You're close, but a few points:
- Your variable,
second
, has bits 4:1 but you're applying them to 3:0 by failing to shift by 1 bit (or by doing that extra >> 1, note thatIMM1 & 0b11110
would work). - Your variable,
fourth
, has bit 12, though that is the sign bit and must be sign extended out to 32 bits for use as the immediate.
Otherwise, just recheck your shifts by the following pattern: [m:n]
must << n
. So, assuming each field is right justified in some variable:
[4:1]
<< 1[11]
<< 11[10:5]
<< 5[12]
<< 12 — but with sign extension — so on 32-bit machine,[12]
<< 31, then taken as signed >> 19, or else use[12] ? 0xFFFFF000 : 0
or[12] ? -4096 : 0
.
With that you'll have an SB-Type immediate of 32 bits expanded from the mangled 12 bits in the instruction and suitable for adding to the PC.
The immediate value encoded in that bge
instruction, 0xfae7d2e3, is -92 (0xFFFFFFA4).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论