From 43d043e941583ccfa974a1dc27ce34d78098deb6 Mon Sep 17 00:00:00 2001 From: ghidorahrex Date: Tue, 30 Jun 2026 14:40:20 -0400 Subject: [PATCH] GP-6876: Corrected operands for RISC-V floating point .w instructions --- .../RISCV/data/languages/riscv.rv32a.sinc | 40 +++++++++---------- .../RISCV/data/languages/riscv.rv32d.sinc | 20 +++++----- .../RISCV/data/languages/riscv.rv32f.sinc | 28 +++++++------ .../RISCV/data/languages/riscv.rv32q.sinc | 7 +++- .../RISCV/data/languages/riscv.rv64d.sinc | 5 ++- .../RISCV/data/languages/riscv.rv64f.sinc | 5 ++- .../RISCV/data/languages/riscv.rv64i.sinc | 8 ++-- .../RISCV/data/languages/riscv.table.sinc | 9 ----- 8 files changed, 61 insertions(+), 61 deletions(-) diff --git a/Ghidra/Processors/RISCV/data/languages/riscv.rv32a.sinc b/Ghidra/Processors/RISCV/data/languages/riscv.rv32a.sinc index 51960421b4..35194bb1c9 100644 --- a/Ghidra/Processors/RISCV/data/languages/riscv.rv32a.sinc +++ b/Ghidra/Processors/RISCV/data/languages/riscv.rv32a.sinc @@ -1,10 +1,10 @@ # RV32A Standard Extension # amoadd.w d,t,0(s) 0000202f fe00707f DWORD|DREF (0, 4) -:amoadd.w^aqrl rd,rs2W,(rs1) is rs1 & rs2W & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0 & aqrl +:amoadd.w^aqrl rd,rs2,(rs1) is rs1 & rs2 & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0 & aqrl { local tmprs1 = rs1; - local tmprs2 = rs2W; + local tmprs2:$(WXLEN) = rs2:$(WXLEN); local tmp:4 = *[ram]:4 tmprs1; assignW(rd, tmp); tmp = tmp + tmprs2; @@ -13,10 +13,10 @@ # amoand.w d,t,0(s) 6000202f fe00707f DWORD|DREF (0, 4) -:amoand.w^aqrl rd,rs2W,(rs1) is rs1 & rs2W & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0xc & aqrl +:amoand.w^aqrl rd,rs2,(rs1) is rs1 & rs2 & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0xc & aqrl { local tmprs1 = rs1; - local tmprs2 = rs2W; + local tmprs2:$(WXLEN) = rs2:$(WXLEN); local tmp:4 = *[ram]:4 tmprs1; assignW(rd, tmp); tmp = tmp & tmprs2; @@ -25,10 +25,10 @@ # amomax.w d,t,0(s) a000202f fe00707f DWORD|DREF (0, 4) -:amomax.w^aqrl rd,rs2W,(rs1) is rs1 & rs2W & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x14 & aqrl +:amomax.w^aqrl rd,rs2,(rs1) is rs1 & rs2 & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x14 & aqrl { local tmprs1 = rs1; - local tmprs2 = rs2W; + local tmprs2:$(WXLEN) = rs2:$(WXLEN); local tmp:4 = *[ram]:4 tmprs1; assignW(rd, tmp); if (tmprs2 s<= tmp) goto inst_next; @@ -37,10 +37,10 @@ # amomaxu.w d,t,0(s) e000202f fe00707f DWORD|DREF (0, 4) -:amomaxu.w^aqrl rd,rs2W,(rs1) is rs1 & rs2W & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x1c & aqrl +:amomaxu.w^aqrl rd,rs2,(rs1) is rs1 & rs2 & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x1c & aqrl { local tmprs1 = rs1; - local tmprs2 = rs2W; + local tmprs2:$(WXLEN) = rs2:$(WXLEN); local tmp:4 = *[ram]:4 tmprs1; assignW(rd, tmp); if (tmprs2 <= tmp) goto inst_next; @@ -49,10 +49,10 @@ # amomin.w d,t,0(s) 8000202f fe00707f DWORD|DREF (0, 4) -:amomin.w^aqrl rd,rs2W,(rs1) is rs1 & rs2W & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x10 & aqrl +:amomin.w^aqrl rd,rs2,(rs1) is rs1 & rs2 & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x10 & aqrl { local tmprs1 = rs1; - local tmprs2 = rs2W; + local tmprs2:$(WXLEN) = rs2:$(WXLEN); local tmp:4 = *[ram]:4 tmprs1; assignW(rd, tmp); if (tmprs2 s>= tmp) goto inst_next; @@ -61,10 +61,10 @@ # amominu.w d,t,0(s) c000202f fe00707f DWORD|DREF (0, 4) -:amominu.w^aqrl rd,rs2W,(rs1) is rs1 & rs2W & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x18 & aqrl +:amominu.w^aqrl rd,rs2,(rs1) is rs1 & rs2 & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x18 & aqrl { local tmprs1 = rs1; - local tmprs2 = rs2W; + local tmprs2:$(WXLEN) = rs2:$(WXLEN); local tmp:4 = *[ram]:4 tmprs1; assignW(rd, tmp); if (tmprs2 >= tmp) goto inst_next; @@ -73,10 +73,10 @@ # amoor.w d,t,0(s) 4000202f fe00707f DWORD|DREF (0, 4) -:amoor.w^aqrl rd,rs2W,(rs1) is rs1 & rs2W & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x8 & aqrl +:amoor.w^aqrl rd,rs2,(rs1) is rs1 & rs2 & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x8 & aqrl { local tmprs1 = rs1; - local tmprs2 = rs2W; + local tmprs2:$(WXLEN) = rs2:$(WXLEN); local tmp:4 = *[ram]:4 tmprs1; assignW(rd, tmp); tmp = tmp | tmprs2; @@ -85,10 +85,10 @@ # amoswap.w d,t,0(s) 0800202f fe00707f DWORD|DREF (0, 4) -:amoswap.w^aqrl rd,rs2W,(rs1) is rs1 & rs2W & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x1 & aqrl +:amoswap.w^aqrl rd,rs2,(rs1) is rs1 & rs2 & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x1 & aqrl { local tmprs1 = rs1; - local tmprs2 = rs2W; + local tmprs2:$(WXLEN) = rs2:$(WXLEN); local tmp:4 = *[ram]:4 tmprs1; assignW(rd, tmp); *[ram]:4 tmprs1 = tmprs2; @@ -96,10 +96,10 @@ # amoxor.w d,t,0(s) 2000202f fe00707f DWORD|DREF (0, 4) -:amoxor.w^aqrl rd,rs2W,(rs1) is rs1 & rs2W & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x4 & aqrl +:amoxor.w^aqrl rd,rs2,(rs1) is rs1 & rs2 & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x4 & aqrl { local tmprs1 = rs1; - local tmprs2 = rs2W; + local tmprs2:$(WXLEN) = rs2:$(WXLEN); local tmp:4 = *[ram]:4 tmprs1; assignW(rd, tmp); tmp = tmp ^ tmprs2; @@ -118,9 +118,9 @@ # sc.w d,t,0(s) 1800202f fe00707f DWORD|DREF (0, 4) -:sc.w^aqrl rd,rs2W,(rs1) is rs1 & rs2W & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x3 & aqrl +:sc.w^aqrl rd,rs2,(rs1) is rs1 & rs2 & rd & op0001=0x3 & op0204=0x3 & op0506=0x1 & funct3=0x2 & op2731=0x3 & aqrl { - local tmprs2 = rs2W; + local tmprs2:$(WXLEN) = rs2:$(WXLEN); local tmprs1 = rs1; rd = 1; if ((RESERVE == 0)||(RESERVE_ADDRESS != tmprs1)||(RESERVE_LENGTH != 4)) goto inst_next; diff --git a/Ghidra/Processors/RISCV/data/languages/riscv.rv32d.sinc b/Ghidra/Processors/RISCV/data/languages/riscv.rv32d.sinc index e8d298bfbe..aa2e72e19d 100644 --- a/Ghidra/Processors/RISCV/data/languages/riscv.rv32d.sinc +++ b/Ghidra/Processors/RISCV/data/languages/riscv.rv32d.sinc @@ -35,18 +35,18 @@ # fcvt.d.w D,s d2000053 fff0707f SIMPLE (0, 0) -:fcvt.d.w frd,rs1W is frd & rs1W & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct3=0x0 & funct7=0x69 & op2024=0x0 +:fcvt.d.w frd,rs1 is frd & rs1 & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct3=0x0 & funct7=0x69 & op2024=0x0 { - local tmp:8 = int2float(rs1W); + local tmp:8 = int2float(rs1:$(WXLEN)); frd = tmp; } # fcvt.d.wu D,s d2100053 fff0707f SIMPLE (0, 0) -:fcvt.d.wu frd,rs1W is frd & rs1W & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct3=0x0 & funct7=0x69 & op2024=0x1 +:fcvt.d.wu frd,rs1 is frd & rs1 & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct3=0x0 & funct7=0x69 & op2024=0x1 { #ATTN unsigned can be an issue here - local u32:$(XLEN2) = zext(rs1W); + local u32:8 = zext(rs1:$(WXLEN)); local tmp:8 = int2float(u32); frd = tmp; } @@ -61,17 +61,19 @@ # fcvt.w.d d,S,m c2000053 fff0007f SIMPLE (0, 0) -:fcvt.w.d rdW,frs1D,FRM is frs1D & FRM & rdW & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x61 & op2024=0x0 +:fcvt.w.d rd,frs1D,FRM is frs1D & FRM & rd & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x61 & op2024=0x0 { - rdW = trunc(frs1D); + local tmp:4 = trunc(frs1D); + rd = sext(tmp); } # fcvt.wu.d d,S,m c2100053 fff0007f SIMPLE (0, 0) -:fcvt.wu.d rdW,frs1D,FRM is frs1D & FRM & rdW & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x61 & op2024=0x1 +:fcvt.wu.d rd,frs1D,FRM is frs1D & FRM & rd & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x61 & op2024=0x1 { - #TODO unsigned - rdW = trunc(frs1D); + local cond = (frs1D s<0); + local tmp:4 = (zext(cond) * 0) + (zext(!cond) * trunc(frs1D)); + rd = sext(tmp); # x[rd] = sext(f32->u32(f[rs1])) } diff --git a/Ghidra/Processors/RISCV/data/languages/riscv.rv32f.sinc b/Ghidra/Processors/RISCV/data/languages/riscv.rv32f.sinc index e830008391..8061d87212 100644 --- a/Ghidra/Processors/RISCV/data/languages/riscv.rv32f.sinc +++ b/Ghidra/Processors/RISCV/data/languages/riscv.rv32f.sinc @@ -27,35 +27,37 @@ # fcvt.s.w D,s,m d0000053 fff0007f SIMPLE (0, 0) -:fcvt.s.w frd,rs1W,FRM is frd & FRM & rs1W & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x68 & op2024=0x0 +:fcvt.s.w frd,rs1,FRM is frd & FRM & rs1 & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x68 & op2024=0x0 { - local tmp:4 = int2float(rs1W); + local tmp:4 = int2float(rs1:$(WXLEN)); fassignS(frd, tmp); } # fcvt.s.wu D,s,m d0100053 fff0007f SIMPLE (0, 0) -:fcvt.s.wu frd,rs1W,FRM is frd & FRM & rs1W & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x68 & op2024=0x1 +:fcvt.s.wu frd,rs1,FRM is frd & FRM & rs1 & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x68 & op2024=0x1 { #ATTN unsigned can be an issue here - local u32:$(XLEN2) = zext(rs1W); + local u32:8 = zext(rs1:$(WXLEN)); local tmp:4 = int2float(u32); fassignS(frd, tmp); } # fcvt.w.s d,S,m c0000053 fff0007f SIMPLE (0, 0) -:fcvt.w.s rdW,frs1S,FRM is frs1S & FRM & rdW & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x60 & op2024=0x0 +:fcvt.w.s rd,frs1S,FRM is frs1S & FRM & rd & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x60 & op2024=0x0 { - rdW = trunc(frs1S); + local tmp:4 = trunc(frs1S); + rd = sext(tmp); } # fcvt.wu.s d,S,m c0100053 fff0007f SIMPLE (0, 0) -:fcvt.wu.s rdW,frs1S,FRM is frs1S & FRM & rdW & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x60 & op2024=0x1 +:fcvt.wu.s rd,frs1S,FRM is frs1S & FRM & rd & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x60 & op2024=0x1 { - #TODO unsigned - rdW = trunc(frs1S); + local cond = (frs1S s<0); + local tmp:4 = (zext(cond) * 0:4) + (zext(!cond) * trunc(frs1S)); + rd = sext(tmp); # x[rd] = sext(f32->u32(f[rs1])) } @@ -153,17 +155,17 @@ # fmv.w.x D,s f0000053 fff0707f SIMPLE (0, 0) -:fmv.w.x frd,rs1W is frd & rs1W & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct3=0x0 & funct7=0x78 & op2024=0x0 +:fmv.w.x frd,rs1 is frd & rs1 & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct3=0x0 & funct7=0x78 & op2024=0x0 { - fassignS(frd, rs1W); + fassignS(frd, rs1:$(WXLEN)); } # fmv.x.w d,S e0000053 fff0707f SIMPLE (0, 0) -:fmv.x.w rdW,frs1S is frs1S & rdW & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct3=0x0 & funct7=0x70 & op2024=0x0 +:fmv.x.w rd,frs1S is frs1S & rd & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct3=0x0 & funct7=0x70 & op2024=0x0 { local tmpreg:4 = &frs1S; local tmp:4 = *[register]:4 tmpreg; - rdW = tmp; + rd = zext(tmp); } diff --git a/Ghidra/Processors/RISCV/data/languages/riscv.rv32q.sinc b/Ghidra/Processors/RISCV/data/languages/riscv.rv32q.sinc index b0339867b1..5d42914bef 100644 --- a/Ghidra/Processors/RISCV/data/languages/riscv.rv32q.sinc +++ b/Ghidra/Processors/RISCV/data/languages/riscv.rv32q.sinc @@ -64,13 +64,16 @@ # fcvt.w.q d,S,m c6000053 fff0007f SIMPLE (0, 0) :fcvt.w.q rd,frs1,FRM is frs1 & FRM & rd & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x63 & op2024=0x0 { - rd = trunc(frs1); + local tmp:4 = trunc(frs1S); + rd = sext(tmp); } # fcvt.wu.q d,S,m c6100053 fff0007f SIMPLE (0, 0) :fcvt.wu.q rd,frs1,FRM is frs1 & FRM & rd & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x63 & op2024=0x1 { - rd = trunc(frs1); + local cond = (frs1S s<0); + local tmp:4 = (zext(cond) * 0) + (zext(!cond) * trunc(frs1S)); + rdL = sext(tmp); } diff --git a/Ghidra/Processors/RISCV/data/languages/riscv.rv64d.sinc b/Ghidra/Processors/RISCV/data/languages/riscv.rv64d.sinc index 0436594765..7029ee677a 100644 --- a/Ghidra/Processors/RISCV/data/languages/riscv.rv64d.sinc +++ b/Ghidra/Processors/RISCV/data/languages/riscv.rv64d.sinc @@ -28,8 +28,9 @@ # fcvt.lu.d d,S,m c2300053 fff0007f SIMPLE (64, 0) :fcvt.lu.d rdL,frs1D,FRM is frs1D & FRM & rdL & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x61 & op2024=0x3 { - #TODO unsigned - rdL = trunc(frs1D); + local cond = (frs1D s<0); + local tmp:8 = (zext(cond) * 0:8) + (zext(!cond) * trunc(frs1D)); + rdL = tmp; } diff --git a/Ghidra/Processors/RISCV/data/languages/riscv.rv64f.sinc b/Ghidra/Processors/RISCV/data/languages/riscv.rv64f.sinc index 9a88490281..55c28ca82c 100644 --- a/Ghidra/Processors/RISCV/data/languages/riscv.rv64f.sinc +++ b/Ghidra/Processors/RISCV/data/languages/riscv.rv64f.sinc @@ -10,8 +10,9 @@ # fcvt.lu.s d,S,m c0300053 fff0007f SIMPLE (64, 0) :fcvt.lu.s rdL,frs1S,FRM is frs1S & FRM & rdL & op0001=0x3 & op0204=0x4 & op0506=0x2 & funct7=0x60 & op2024=0x3 { - #TODO unsigned - rdL = trunc(frs1S); + local cond = (frs1S s<0); + local tmp:8 = (zext(cond) * 0) + (zext(!cond) * trunc(frs1S)); + rdL = tmp; } diff --git a/Ghidra/Processors/RISCV/data/languages/riscv.rv64i.sinc b/Ghidra/Processors/RISCV/data/languages/riscv.rv64i.sinc index c0ad6f0d37..a7d21069a6 100644 --- a/Ghidra/Processors/RISCV/data/languages/riscv.rv64i.sinc +++ b/Ghidra/Processors/RISCV/data/languages/riscv.rv64i.sinc @@ -107,15 +107,15 @@ # subw d,s,t 4000003b fe00707f SIMPLE (64, 0) -:subw rd,rs1W,rs2W is rs1W & rs2W & rd & op0001=0x3 & op0204=0x6 & op0506=0x1 & funct3=0x0 & funct7=0x20 +:subw rd,rs1,rs2 is rs1 & rs2 & rd & op0001=0x3 & op0204=0x6 & op0506=0x1 & funct3=0x0 & funct7=0x20 { - local result = rs1W - rs2W; + local result = rs1:$(WXLEN)- rs2:$(WXLEN); rd = sext(result); } # negw d,t 4000003b fe0ff07f ALIAS (64, 0) -:negw rd,rs2W is rs2W & rd & op0001=0x3 & op0204=0x6 & op0506=0x1 & funct3=0x0 & funct7=0x20 & op1519=0x0 +:negw rd,rs2 is rs2 & rd & op0001=0x3 & op0204=0x6 & op0506=0x1 & funct3=0x0 & funct7=0x20 & op1519=0x0 { - local tmp = -rs2W; + local tmp = -rs2:$(WXLEN); rd = sext(tmp); } diff --git a/Ghidra/Processors/RISCV/data/languages/riscv.table.sinc b/Ghidra/Processors/RISCV/data/languages/riscv.table.sinc index 05d1692c7f..5e7a356de7 100644 --- a/Ghidra/Processors/RISCV/data/languages/riscv.table.sinc +++ b/Ghidra/Processors/RISCV/data/languages/riscv.table.sinc @@ -617,15 +617,6 @@ rs3: zero is zero & op2731=0 { export 0:$(XLEN); } rd: r0711 is r0711 { export r0711; } rd: zero is r0711=0 & zero { local tmp:$(XLEN) = 0; export tmp; } -rs1W: r1519 is r1519 { local tmp:$(WXLEN) = r1519:$(WXLEN); export tmp; } -rs1W: zero is r1519 & zero & op1519=0 { export 0:$(WXLEN); } - -rs2W: r2024 is r2024 { local tmp:$(WXLEN) = r2024:$(WXLEN); export tmp; } -rs2W: zero is r2024 & zero & op2024=0 { export 0:$(WXLEN); } - -rdW: r0711 is r0711 { local tmp:$(WXLEN) = r0711:$(WXLEN); export tmp; } -rdW: zero is r0711=0 & zero { local tmp:$(WXLEN) = 0; export tmp; } - #TODO does this need to be in an if/endif @if ADDRSIZE == "64"