Skip to content

Commit

Permalink
Feature: add partial support for Risc-V Zfa extension
Browse files Browse the repository at this point in the history
  • Loading branch information
uxmal committed Jan 10, 2024
1 parent 2e6fadd commit 7e783de
Show file tree
Hide file tree
Showing 10 changed files with 440 additions and 63 deletions.
46 changes: 41 additions & 5 deletions src/Arch/RiscV/InstructionSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class InstructionSet
private Func<Mnemonic, Mutator<RiscVDisassembler>[], Decoder> float32Support;
private Func<Mnemonic, Mutator<RiscVDisassembler>[], Decoder> float64Support;
private Func<Mnemonic, Mutator<RiscVDisassembler>[], Decoder> float128Support;
private Func<Decoder, Decoder> zfaSupport;
private Dictionary<string, object> options;

public static InstructionSet Create(Dictionary<string, object> options)
Expand Down Expand Up @@ -82,6 +83,17 @@ private InstructionSet(Dictionary<string, object> options)
float64Support = MakeInvalid;
float32Support = MakeInvalid;
}

if (!options.TryGetValue("Zfa", out var oZfa) ||
!bool.TryParse(oZfa.ToString()!, out var isZfa) ||
isZfa)
{
zfaSupport = d => d;
}
else
{
zfaSupport = d => invalid;
}
}

private static Decoder MakeInvalid(Mnemonic mnemonic, params Mutator<RiscVDisassembler>[] mutators)
Expand Down Expand Up @@ -109,6 +121,11 @@ private Decoder FpInstr128(Mnemonic mnemonic, params Mutator<RiscVDisassembler>[
return float128Support(mnemonic, mutators);
}

private Decoder Zfa(Decoder decoder)
{
return zfaSupport(decoder);
}

private static Decoder Instr(Mnemonic mnemonic, InstrClass iclass, params Mutator<RiscVDisassembler>[] mutators)
{
return new InstrDecoder<RiscVDisassembler, Mnemonic, RiscVInstruction>(iclass, mnemonic, mutators);
Expand Down Expand Up @@ -337,13 +354,24 @@ public Decoder[] CreateRootDecoders()

( 0x14, Sparse(12, 3, "fmin/fmax.s", invalid,
(0x0, FpInstr32(Mnemonic.fmin_s, Fd,F1, F2)),
(0x1, FpInstr32(Mnemonic.fmax_s, Fd,F1, F2)))),
(0x1, FpInstr32(Mnemonic.fmax_s, Fd,F1, F2)),
(0x2, FpInstr32(Mnemonic.fminm_s, Fd,F1, F2)),
(0x3, FpInstr32(Mnemonic.fmaxm_s, Fd,F1, F2)))),
( 0x15, Sparse(12, 3, "fmin/fmax.d", invalid,
(0x0, FpInstr64(Mnemonic.fmin_d, Fd,F1, F2)),
(0x1, FpInstr64(Mnemonic.fmax_d, Fd,F1, F2)))),
(0x1, FpInstr64(Mnemonic.fmax_d, Fd,F1, F2)),
(0x2, FpInstr64(Mnemonic.fminm_d, Fd,F1, F2)),
(0x3, FpInstr64(Mnemonic.fmaxm_d, Fd,F1, F2)))),
( 0x16, Sparse(12, 3, "fmin/fmax.h", invalid,
(0x0, FpInstr32(Mnemonic.fmin_h, Fd,F1, F2)),
(0x1, FpInstr32(Mnemonic.fmax_h, Fd,F1, F2)),
(0x2, FpInstr32(Mnemonic.fminm_h, Fd,F1, F2)),
(0x3, FpInstr32(Mnemonic.fmaxm_h, Fd,F1, F2)))),
( 0x17, Sparse(12, 3, "fmin/fmax.q", invalid,
(0x0, FpInstr128(Mnemonic.fmin_q, Fd,F1, F2)),
(0x1, FpInstr128(Mnemonic.fmax_q, Fd,F1, F2)))),
(0x1, FpInstr128(Mnemonic.fmax_q, Fd,F1, F2)),
(0x2, FpInstr128(Mnemonic.fminm_q, Fd,F1, F2)),
(0x3, FpInstr128(Mnemonic.fmaxm_q, Fd,F1, F2)))),

( 0x20, Sparse(20, 5, "fcvt.s", invalid,
(0x1, FpInstr64(Mnemonic.fcvt_s_d, Fd,F1) ),
Expand Down Expand Up @@ -413,8 +441,16 @@ public Decoder[] CreateRootDecoders()
( 0x73, Sparse(20, 5, "fclass.q", invalid,
( 0, FpInstr128(Mnemonic.fclass_q, Rd,F1)))),

( 0x78, FpInstr32(Mnemonic.fmv_w_x, Fd,r1) ),
( 0x79, FpInstr64(Mnemonic.fmv_d_x, Fd,r1) )
( 0x78, Sparse(20, 5, "fmv.w.x", invalid,
(0, FpInstr32(Mnemonic.fmv_w_x, Fd,r1) ),
(1, Zfa(FpInstr32(Mnemonic.fli_s, Fd, fpImm_s))))),
( 0x79, Sparse(20, 5, "fmv.d.x", invalid,
(0, FpInstr64(Mnemonic.fmv_d_x, Fd,r1) ),
(1, Zfa(FpInstr64(Mnemonic.fli_d, Fd, fpImm_d))))),
( 0x7A, Sparse(20, 5, "fli.h", invalid,
(1, Zfa(Nyi("fli.h"))))),
( 0x7B, Sparse(20, 5, "fli.q", invalid,
(1, Zfa(Nyi("fli.q")))))
};

var branches = new Decoder[] // 0b11000
Expand Down
78 changes: 45 additions & 33 deletions src/Arch/RiscV/Mnemonic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,24 @@ public enum Mnemonic
addi,
addiw,
addw,
amoadd_d,
amoadd_w,
amoand_d,
amoand_w,
amomax_d,
amomax_w,
amomaxu_d,
amomaxu_w,
amomin_d,
amomin_w,
amominu_d,
amominu_w,
amoor_d,
amoor_w,
amoswap_d,
amoswap_w,
amoxor_d,
amoxor_w,
and,
andi,
auipc,
Expand Down Expand Up @@ -85,6 +103,8 @@ public enum Mnemonic
csrrsi,
csrrw,
csrrwi,
div,
divu,
divuw,
divw,
ebreak,
Expand All @@ -95,9 +115,9 @@ public enum Mnemonic
fadd_d,
fadd_q,
fadd_s,
fclass_s,
fclass_d,
fclass_q,
fclass_s,
fcvt_d_l,
fcvt_d_lu,
fcvt_d_q,
Expand Down Expand Up @@ -141,6 +161,10 @@ public enum Mnemonic
fle_d,
fle_q,
fle_s,
fli_d,
fli_h,
fli_q,
fli_s,
flq,
flt_d,
flt_q,
Expand All @@ -151,11 +175,21 @@ public enum Mnemonic
fmadd_q,
fmadd_s,
fmax_d,
fmax_h,
fmax_q,
fmax_s,
fmaxm_d,
fmaxm_h,
fmaxm_q,
fmaxm_s,
fmin_d,
fmin_h,
fmin_q,
fmin_s,
fminm_d,
fminm_h,
fminm_q,
fminm_s,
fmsub_d,
fmsub_h,
fmsub_q,
Expand Down Expand Up @@ -206,17 +240,27 @@ public enum Mnemonic
ld,
lh,
lhu,
lr_d,
lr_w,
lui,
lw,
lwu,
mret,
mul,
mulh,
mulhsu,
mulhu,
mulw,
or,
ori,
pause,
rem,
remu,
remuw,
remw,
sb,
sc_d,
sc_w,
sd,
sh,
sll,
Expand All @@ -243,37 +287,5 @@ public enum Mnemonic
wfi,
xor,
xori,

lr_w,
sc_w,
amoswap_w,
amoadd_w,
amoxor_w,
amoand_w,
amoor_w,
amomin_w,
amomax_w,
amominu_w,
amomaxu_w,

lr_d,
sc_d,
amoswap_d,
amoadd_d,
amoxor_d,
amoand_d,
amoor_d,
amomin_d,
amomax_d,
amominu_d,
amomaxu_d,
mulh,
mul,
mulhsu,
mulhu,
div,
divu,
rem,
remu,
}
}
3 changes: 3 additions & 0 deletions src/Arch/RiscV/RiscVArchitecture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public RiscVArchitecture(IServiceProvider services, string archId, Dictionary<st
#nullable enable

public Dictionary<uint, RegisterStorage> Csrs { get; }
public PrimitiveType DoubleWordWidth { get; private set; }
public RegisterStorage[] GpRegs { get; private set; }
public RegisterStorage[] FpRegs { get; private set; }
public RegisterStorage LinkRegister { get; private set; }
Expand Down Expand Up @@ -208,13 +209,15 @@ private void SetOptionDependentProperties()
this.WordWidth = PrimitiveType.Word64;
this.FramePointerType = PrimitiveType.Ptr64;
this.NaturalSignedInteger = PrimitiveType.Int64;
this.DoubleWordWidth = PrimitiveType.Word128;
}
else
{
this.PointerType = PrimitiveType.Ptr32;
this.WordWidth = PrimitiveType.Word32;
this.FramePointerType = PrimitiveType.Ptr32;
this.NaturalSignedInteger = PrimitiveType.Int32;
this.DoubleWordWidth = PrimitiveType.Word64;
}

this.GpRegs = regnames
Expand Down
Loading

0 comments on commit 7e783de

Please sign in to comment.