fix(asm): complete RISC-V compressed loads/stores and word arithmetic
Assisted-by: DeepSeek V4 Pro
This commit is contained in:
+52
-22
@@ -466,45 +466,75 @@ func rvcSLLI(rd, shamt uint32) uint16 {
|
||||
return uint16(((shamt>>5)&1)<<12 | (rd << 7) | (shamt&0x1F)<<2 | 0x2)
|
||||
}
|
||||
|
||||
// rvcLSP encodes a CI-type stack-relative load: C.LDSP (funct3=3) or
|
||||
// C.FLDSP (funct3=1). offset is the full byte offset; the immediate bits
|
||||
// are interleaved per the RISC-V spec: [5:3|8:6].
|
||||
func rvcLSP(funct3, rd uint32, offset uint32) uint16 {
|
||||
// Bit interleave offset bits [5,4,3,8,7,6] → packed value.
|
||||
// encodeRVCPattern extracts the bits listed in pattern (MSB first) from imm
|
||||
// into a packed value, matching cmd/internal/obj/riscv's encodeBitPattern.
|
||||
func encodeRVCPattern(imm uint32, pattern []int) uint32 {
|
||||
packed := uint32(0)
|
||||
for i, b := range []int{5, 4, 3, 8, 7, 6} {
|
||||
for _, bit := range pattern {
|
||||
packed = packed<<1 | (imm>>bit)&1
|
||||
}
|
||||
return packed
|
||||
}
|
||||
|
||||
// rvcLSP encodes a stack-relative compressed load (op=10 quadrant): C.LWSP
|
||||
// (funct3=2, 4-byte scale), C.LDSP (funct3=3) or C.FLDSP (funct3=1, 8-byte
|
||||
// scale). offset is the full byte offset.
|
||||
func rvcLSP(funct3, rd uint32, offset uint32) uint16 {
|
||||
pattern := []int{5, 4, 3, 8, 7, 6}
|
||||
if funct3 == 0x2 {
|
||||
pattern = []int{5, 4, 3, 2, 7, 6}
|
||||
}
|
||||
packed := uint32(0)
|
||||
for i, b := range pattern {
|
||||
packed |= ((offset >> b) & 1) << (5 - i)
|
||||
}
|
||||
return uint16((funct3 << 13) | ((packed>>5)&1)<<12 | (rd << 7) | (packed&0x1F)<<2 | 0x2)
|
||||
}
|
||||
|
||||
// rvcSSP encodes a CSS-type stack-relative store: C.SDSP (funct3=7) or
|
||||
// C.FSDSP (funct3=5). offset is the full byte offset; the immediate bits
|
||||
// are interleaved per the RISC-V spec: [5:3|8:6].
|
||||
// rvcSSP encodes a stack-relative compressed store (op=10 quadrant): C.SWSP
|
||||
// (funct3=6, 4-byte scale), C.SDSP (funct3=7) or C.FSDSP (funct3=5, 8-byte
|
||||
// scale). offset is the full byte offset.
|
||||
func rvcSSP(funct3, rs2 uint32, offset uint32) uint16 {
|
||||
// Bit interleave offset bits [5,4,3,8,7,6] → packed value.
|
||||
pattern := []int{5, 4, 3, 8, 7, 6}
|
||||
if funct3 == 0x6 {
|
||||
pattern = []int{5, 4, 3, 2, 7, 6}
|
||||
}
|
||||
packed := uint32(0)
|
||||
for i, b := range []int{5, 4, 3, 8, 7, 6} {
|
||||
for i, b := range pattern {
|
||||
packed |= ((offset >> b) & 1) << (5 - i)
|
||||
}
|
||||
return uint16((funct3 << 13) | (packed << 7) | (rs2 << 2) | 0x2)
|
||||
}
|
||||
|
||||
// rvcCSS encodes a CSS-type (stack store) compressed instruction.
|
||||
func rvcCSS(funct3, rs2 uint32, imm uint32) uint16 {
|
||||
return uint16((funct3 << 13) | (imm << 7) | (rs2 << 2) | 0x2)
|
||||
}
|
||||
|
||||
// rvcCL encodes a CL-type (load) compressed instruction.
|
||||
// imm layout: [5:3] in bits [12:10], [2|6] in bits [6:5].
|
||||
// rvcCL encodes a register-relative compressed load (op=00 quadrant): C.LW
|
||||
// (funct3=2), C.LD (funct3=3) or C.FLD (funct3=1). imm is the full byte
|
||||
// offset; the immediate bits are extracted per the RISC-V CL format.
|
||||
func rvcCL(funct3, rd, rs1 uint32, imm uint32) uint16 {
|
||||
bits := uint16((funct3 << 13) | ((imm>>3)&0x7)<<10 | (rs1 << 7) | ((imm & 0x7) << 5) | (rd << 2) | 0x0)
|
||||
return bits
|
||||
pattern := []int{5, 4, 3, 7, 6}
|
||||
if funct3 == 0x2 {
|
||||
pattern = []int{5, 4, 3, 2, 6}
|
||||
}
|
||||
packed := encodeRVCPattern(imm, pattern)
|
||||
return uint16((funct3 << 13) | ((packed>>2)&0x7)<<10 | (rs1 << 7) | ((packed & 0x3) << 5) | (rd << 2))
|
||||
}
|
||||
|
||||
// rvcCS encodes a CS-type (store) compressed instruction.
|
||||
// rvcCS encodes a register-relative compressed store (op=00 quadrant): C.SW
|
||||
// (funct3=6), C.SD (funct3=7) or C.FSD (funct3=5). imm is the full byte
|
||||
// offset; the immediate bits are extracted per the RISC-V CS format.
|
||||
func rvcCS(funct3, rs2, rs1 uint32, imm uint32) uint16 {
|
||||
return uint16((funct3 << 13) | ((imm>>3)&0x7)<<10 | (rs1 << 7) | ((imm & 0x7) << 5) | (rs2 << 2) | 0x0)
|
||||
pattern := []int{5, 3, 7, 6}
|
||||
if funct3 == 0x6 {
|
||||
pattern = []int{5, 3, 2, 6}
|
||||
}
|
||||
packed := encodeRVCPattern(imm, pattern)
|
||||
return uint16((funct3 << 13) | ((packed>>2)&0x7)<<10 | (rs1 << 7) | ((packed & 0x3) << 5) | (rs2 << 2))
|
||||
}
|
||||
|
||||
// rvcCIW encodes a CIW-type compressed immediate wide instruction: C.ADDI4SPN
|
||||
// (funct3=0). imm is the raw byte offset.
|
||||
func rvcCIW(funct3, rd uint32, imm uint32) uint16 {
|
||||
packed := encodeRVCPattern(imm, []int{5, 4, 9, 8, 7, 6, 2, 3})
|
||||
return uint16((funct3 << 13) | (packed << 5) | (rd << 2))
|
||||
}
|
||||
|
||||
// rvcCJ encodes a CJ-type (jump) compressed instruction.
|
||||
|
||||
Reference in New Issue
Block a user