RISC-V分支偏移机器指令编码

RISC-V branch offset machine instruction encoding

0001100 01010 11100 100 10001 1100011 的解码 RISC-V 汇编指令是什么?从 specification 我知道,操作码是 BLT 指令和 rs1 = x28, rs2 = x10.

但是编码后的偏移量是多少? imm[12|10:5] 是 0001100 = 12 而 imm[4:1|11] 是 10001 = -8,对吗?跳到哪里去?

.word 0x18ae48e3

blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello
hello:
blt x28,x19,hello
blt x28,x19,hello
blt x28,x19,hello



00000000 <hello-0x38>:
   0:   18ae48e3            blt x28,x10,990 <hello+0x958>
   4:   033e4a63            blt x28,x19,38 <hello>
   8:   033e4863            blt x28,x19,38 <hello>
   c:   033e4663            blt x28,x19,38 <hello>
  10:   033e4463            blt x28,x19,38 <hello>
  14:   033e4263            blt x28,x19,38 <hello>
  18:   033e4063            blt x28,x19,38 <hello>
  1c:   013e4e63            blt x28,x19,38 <hello>
  20:   013e4c63            blt x28,x19,38 <hello>
  24:   013e4a63            blt x28,x19,38 <hello>
  28:   013e4863            blt x28,x19,38 <hello>
  2c:   013e4663            blt x28,x19,38 <hello>
  30:   013e4463            blt x28,x19,38 <hello>
  34:   013e4263            blt x28,x19,38 <hello>

00000038 <hello>:
  38:   013e4063            blt x28,x19,38 <hello>
  3c:   ff3e4ee3            blt x28,x19,38 <hello>
  40:   ff3e4ce3            blt x28,x19,38 <hello>

00000001001111100100001001100011
00000001001111100100000001100011
11111111001111100100111011100011


0 000000 1001111100100 0010 0 1100011
0 000000 1001111100100 0000 0 1100011
1 111111 1001111100100 1110 1 1100011 

您确实看到如何从记录的说明中提取这些数字是吗?

0 0 000000 0010 0
0 0 000000 0000 0
1 1 111111 1110 0

0 0000 0000 0100 = 0x0004 
0 0000 0000 0000 = 0x0000 (<-- hello label here)
1 1111 1111 1100 = 0x1FFC

好吧,这里没有魔法,有时会有偏移,通常会有偏移。通常下一条指令的地址是应用立即数的地方。例如,对于 ARM,前面两条指令的地址就是应用偏移量的位置。

from your instruction
0001100 01010 11100 100 10001 1100011
0 001100 01010 11100 100 1000 1 1100011
010011001000 (add implied zero for bit 0)
0 1001 1001 0000 = 0x990

The RISC-V Instruction Set Manual 列出第 19 章中的完整指令集。 opcode(7 个最低有效位)告诉我们,我们处理的是一条 B 类指令。 funct3 位 ([14:12]) 指定 BLT 指令。

BLT指令编码如下:

这给了我们:

imm[12|10:5] rs2 rs1 funct3 imm[4:1|11] opcode
instruction 0001100 01010 11100 100 10001 1100011
value 0xc 0xa (x10) 0x1c (x28) 0x4 0x11 0x63

立即数是指令位 [31|7|30:25|11:8]: 0|1|001100|1000 = 0x4c8 的串联。 请注意,立即数缺少索引 0.

处的位

The RISC-V Instruction Set Manual 状态 2.3 立即编码变体:

There are a further two variants of the instruction formats (B/J) based on the handling of immediates, as shown in Figure 2.3. The only difference between the S and B formats is that the 12-bit immediate field is used to encode branch offsets in multiples of 2 in the B format. Instead of shifting all bits in the instruction-encoded immediate left by one in hardware as is conventionally done, the middle bits (imm[10:1]) and sign bit stay in fixed positions, while the lowest bit in S format (inst[7]) encodes a high-order bit in B format.

这是因为RISC-V有16位指令对齐约束(1.2指令长度编码):

The base RISC-V ISA has fixed-length 32-bit instructions that must be naturally aligned on 32-bit boundaries. However, the standard RISC-V encoding scheme is designed to support ISA extensions with variable-length instructions, where each instruction can be any number of 16-bit instruction parcels in length and parcels are naturally aligned on 16-bit boundaries. The standard compressed ISA extension described in Chapter 12 reduces code size by providing compressed 16-bit instructions and relaxes the alignment constraints to allow all instructions (16 bit and 32 bit) to be aligned on any 16-bit boundary to improve code density.

因此我们需要在偏移量中添加一个尾随 0,这样我们就可以得到:0|1|001100|1000|0 = 0x990.

解码指令为:blt x28, x10, 0x990