assembly 模拟器上的分支指令偏移量计算

ttisahbt  于 2023-01-09  发布在  其他
关注(0)|答案(1)|浏览(166)

我写了一个riscv 64模拟器,但是在分支指令的偏移量计算上有一个问题(尤其是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

}

当程序得到这个简单的程序代码:

// 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

我得到了:0x 7a 2。
PC地址为:0x1018c
当我添加0x 1018 c到0x 7a 2,我得到:0x 1092 E有一个问题,但我不知道在哪里。我认为imm变量的提取有一些问题。
我试过修改imm变量的位移位和掩码。但是我没有任何运气。
我已经试过了:

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
scyqe7ek

scyqe7ek1#

你很接近了,但还有几点:
1.变量second的位数为4:1,但由于没有移位1位(或者做了额外的〉〉1操作,注意IMM1 & 0b11110也可以),所以将它们应用于3:0。
1.您的变量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

这样,您将拥有一个32位的SB类型立即数,它是从指令中损坏的12位扩展而来的,适合添加到PC中。
bge指令0xfae 7d2 e3中编码的立即数是-92(0xFFFFFFA 4)。

相关问题