fix(asm): complete RISC-V compressed loads/stores and word arithmetic
Assisted-by: DeepSeek V4 Pro
This commit is contained in:
@@ -749,6 +749,10 @@ func tryCompressRVC(instr *ast.Instr, fi riscvFrameInfo) (uint16, bool) {
|
||||
if rs1 == 2 && rd != 0 && rd != -1 && imm >= 0 && imm < 512 && imm%8 == 0 {
|
||||
return rvcLSP(0x3, uint32(rd), uint32(imm)), true
|
||||
}
|
||||
// Register-relative C.LD: both in prime regs, 8-byte scaled offset.
|
||||
if rs1 != -1 && rd != -1 && isRVCIntReg(rd) && isRVCIntReg(rs1) && imm >= 0 && imm < 256 && imm%8 == 0 {
|
||||
return rvcCL(0x3, rvcReg3(rd), rvcReg3(rs1), uint32(imm)), true
|
||||
}
|
||||
// MOV reg, mem → store, try C.SDSP.
|
||||
if mnem == "MOV" && len(ops) == 2 && !isMemOperand(ops[0]) && isMemOperand(ops[1]) {
|
||||
rs2, rs1, imm := extractSDParams(instr, fi)
|
||||
@@ -763,6 +767,28 @@ func tryCompressRVC(instr *ast.Instr, fi riscvFrameInfo) (uint16, bool) {
|
||||
if rs1 == 2 && rs2 != -1 && imm >= 0 && imm < 512 && imm%8 == 0 {
|
||||
return rvcSSP(0x7, uint32(rs2), uint32(imm)), true
|
||||
}
|
||||
// Register-relative C.SD: base and source in prime regs.
|
||||
if rs1 != -1 && rs2 != -1 && isRVCIntReg(rs1) && isRVCIntReg(rs2) && imm >= 0 && imm < 256 && imm%8 == 0 {
|
||||
return rvcCS(0x7, rvcReg3(rs2), rvcReg3(rs1), uint32(imm)), true
|
||||
}
|
||||
|
||||
case "LW":
|
||||
rd, rs1, imm := extractLDParams(instr, fi)
|
||||
if rs1 == 2 && rd != 0 && rd != -1 && imm >= 0 && imm < 256 && imm%4 == 0 {
|
||||
return rvcLSP(0x2, uint32(rd), uint32(imm)), true
|
||||
}
|
||||
if rs1 != -1 && rd != -1 && isRVCIntReg(rd) && isRVCIntReg(rs1) && imm >= 0 && imm < 128 && imm%4 == 0 {
|
||||
return rvcCL(0x2, rvcReg3(rd), rvcReg3(rs1), uint32(imm)), true
|
||||
}
|
||||
|
||||
case "SW":
|
||||
rs2, rs1, imm := extractSDParams(instr, fi)
|
||||
if rs1 == 2 && rs2 != -1 && imm >= 0 && imm < 256 && imm%4 == 0 {
|
||||
return rvcSSP(0x6, uint32(rs2), uint32(imm)), true
|
||||
}
|
||||
if rs1 != -1 && rs2 != -1 && isRVCIntReg(rs1) && isRVCIntReg(rs2) && imm >= 0 && imm < 128 && imm%4 == 0 {
|
||||
return rvcCS(0x6, rvcReg3(rs2), rvcReg3(rs1), uint32(imm)), true
|
||||
}
|
||||
|
||||
case "ADDI":
|
||||
rd, rs1, imm := extractITypeParams(instr, fi)
|
||||
@@ -777,6 +803,10 @@ func tryCompressRVC(instr *ast.Instr, fi riscvFrameInfo) (uint16, bool) {
|
||||
// C.ADDI: funct3=0x0, rs1/rd, nzimm[5:0]
|
||||
return rvcCI(0x0, uint32(rd), uint32(imm)&0x3F), true
|
||||
}
|
||||
if isRVCIntReg(rd) && rs1 == 2 && imm != 0 && imm >= 0 && imm < 1024 && imm%4 == 0 {
|
||||
// C.ADDI4SPN: ADDI $imm, SP, rd for a prime rd.
|
||||
return rvcCIW(0x0, rvcReg3(rd), uint32(imm)), true
|
||||
}
|
||||
if rs1 == 0 && rd != 0 && imm >= -32 && imm <= 31 {
|
||||
// C.LI: funct3=0x2, rd, imm[5:0]
|
||||
return rvcCI(0x2, uint32(rd), uint32(imm)&0x3F), true
|
||||
@@ -860,12 +890,37 @@ func tryCompressRVC(instr *ast.Instr, fi riscvFrameInfo) (uint16, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
case "ADDW", "SUBW":
|
||||
// C.ADDW (0x27,1) / C.SUBW (0x27,0) — CA-type, prime regs.
|
||||
if len(ops) == 3 {
|
||||
funct2 := uint32(0x0)
|
||||
if mnem == "ADDW" {
|
||||
funct2 = 0x1
|
||||
}
|
||||
rs2 := regFromOperand(ops[0])
|
||||
rs1 := regFromOperand(ops[1])
|
||||
rd := regFromOperand(ops[2])
|
||||
if rd != -1 && rs1 != -1 && rs2 != -1 && isRVCIntReg(rd) {
|
||||
if rd == rs1 && isRVCIntReg(rs2) {
|
||||
return rvcCA(0x27, funct2, rvcReg3(rd), rvcReg3(rs2)), true
|
||||
}
|
||||
// ADDW is commutative; SUBW is not.
|
||||
if mnem == "ADDW" && isRVCIntReg(rs1) && rd == rs2 {
|
||||
return rvcCA(0x27, funct2, rvcReg3(rd), rvcReg3(rs1)), true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case "FLD":
|
||||
// FLD rd, imm(SP) → C.FLDSP (CI-type, funct3=0x1).
|
||||
rd, rs1, imm := extractLDParams(instr, fi)
|
||||
if rs1 == 2 && rd != -1 && imm >= 0 && imm < 512 && imm%8 == 0 {
|
||||
return rvcLSP(0x1, uint32(rd), uint32(imm)), true
|
||||
}
|
||||
// Register-relative C.FLD: rd in F8-F15, base in X8-X15.
|
||||
if rs1 != -1 && rd != -1 && rd >= 8 && rd <= 15 && isRVCIntReg(rs1) && imm >= 0 && imm < 256 && imm%8 == 0 {
|
||||
return rvcCL(0x1, uint32(rd-8), rvcReg3(rs1), uint32(imm)), true
|
||||
}
|
||||
|
||||
case "FSD":
|
||||
// FSD rs2, imm(SP) → C.FSDSP (CSS-type, funct3=0x5).
|
||||
@@ -873,6 +928,10 @@ func tryCompressRVC(instr *ast.Instr, fi riscvFrameInfo) (uint16, bool) {
|
||||
if rs1 == 2 && rs2 != -1 && imm >= 0 && imm < 512 && imm%8 == 0 {
|
||||
return rvcSSP(0x5, uint32(rs2), uint32(imm)), true
|
||||
}
|
||||
// Register-relative C.FSD: source in F8-F15, base in X8-X15.
|
||||
if rs1 != -1 && rs2 != -1 && rs2 >= 8 && rs2 <= 15 && isRVCIntReg(rs1) && imm >= 0 && imm < 256 && imm%8 == 0 {
|
||||
return rvcCS(0x5, uint32(rs2-8), rvcReg3(rs1), uint32(imm)), true
|
||||
}
|
||||
|
||||
case "LUI":
|
||||
// LUI rd, imm → C.LUI when rd≠0, rd≠SP, imm nonzero and fits in 6 bits.
|
||||
|
||||
Reference in New Issue
Block a user