Browse Source

Adapted descriptions to improved Core DSL and regenerated code

pull/1/head
Eyck Jentzsch 2 years ago
parent
commit
19b660962b
20 changed files with 3765 additions and 3837 deletions
  1. +3
    -4
      .cproject
  2. +1
    -1
      dbt-core
  3. +104
    -104
      riscv/gen_input/RV32A.core_desc
  4. +316
    -345
      riscv/gen_input/RV32C.core_desc
  5. +294
    -294
      riscv/gen_input/RV32D.core_desc
  6. +290
    -290
      riscv/gen_input/RV32F.core_desc
  7. +308
    -307
      riscv/gen_input/RV32IBase.core_desc
  8. +88
    -88
      riscv/gen_input/RV32M.core_desc
  9. +107
    -107
      riscv/gen_input/RV64A.core_desc
  10. +107
    -107
      riscv/gen_input/RV64IBase.core_desc
  11. +37
    -37
      riscv/gen_input/RV64M.core_desc
  12. +6
    -7
      riscv/gen_input/minres_rv.core_desc
  13. +2
    -0
      riscv/gen_input/templates/incl-CORENAME.h.gtl
  14. +2
    -0
      riscv/gen_input/templates/vm-vm_CORENAME.cpp.gtl
  15. +1
    -1
      riscv/incl/iss/arch/rv32gc.h
  16. +1
    -1
      riscv/incl/iss/arch/rv32imac.h
  17. +1
    -1
      riscv/incl/iss/arch/rv64ia.h
  18. +1347
    -1372
      riscv/src/internal/vm_rv32gc.cpp
  19. +449
    -462
      riscv/src/internal/vm_rv32imac.cpp
  20. +301
    -309
      riscv/src/internal/vm_rv64ia.cpp

+ 3
- 4
.cproject View File

@ -10,15 +10,14 @@
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1751741082" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1751741082" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1751741082." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1289745146" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
<targetPlatform binaryParser="org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.exe.debug.1460698591" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
<builder buildPath="/DBT-RISE-RISCV/build/{ConfigName}" id="de.marw.cdt.cmake.core.genmakebuilder.2061143699" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="CMake Builder (GNU Make)" parallelBuildOn="true" parallelizationNumber="optimal" superClass="de.marw.cdt.cmake.core.genmakebuilder"/>
<builder buildPath="/DBT-RISE-RISCV/build/Debug" id="de.marw.cdt.cmake.core.genscriptbuilder.2135578907" keepEnvironmentInBuildfile="false" name="CMake Builder (portable)" parallelBuildOn="false" superClass="de.marw.cdt.cmake.core.genscriptbuilder"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.366643800" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1510612390" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1768317780" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
@ -46,7 +45,7 @@
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule buildDir="build/${ConfigName}" moduleId="de.marw.cdt.cmake.core.settings">
<options clearCache="true"/>
<options/>
<linux command="cmake" generator="UnixMakefiles" use-default="true">
<defs>
<def name="CMAKE_VERBOSE_MAKEFILE" type="BOOL" val="OFF"/>

+ 1
- 1
dbt-core

@ -1 +1 @@
Subproject commit 393c374cac4950e629036dda1615abedf866961f
Subproject commit 23dbab0b768d122c492110d1db34408e9ae787f3

+ 104
- 104
riscv/gen_input/RV32A.core_desc View File

@ -1,108 +1,108 @@
import "RV32IBase.core_desc"
InsructionSet RV32A extends RV32IBase{
address_spaces {
RES[8]
}
instructions{
LR.W {
encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d";
if(rd!=0){
val offs[XLEN] <= X[rs1];
X[rd]<= sext(MEM[offs]{32}, XLEN);
RES[offs]{32}<=sext(-1, 32);
}
}
SC.W {
encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d";
val offs[XLEN] <= X[rs1];
val res1[32] <= RES[offs]{32};
if(res1!=0)
MEM[offs]{32} <= X[rs2];
if(rd!=0) X[rd]<= choose(res1!=0, 0, 1);
}
AMOSWAP.W{
encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
if(rd!=0) X[rd]<=sext(MEM[offs]{32});
MEM[offs]{32}<=X[rs2];
}
AMOADD.W{
encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<=res1 + X[rs2];
MEM[offs]{32}<=res2;
}
AMOXOR.W{
encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<=res1 ^ X[rs2];
MEM[offs]{32}<=res2;
}
AMOAND.W{
encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN] <=res1 & X[rs2];
MEM[offs]{32}<=res2;
}
AMOOR.W {
encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<=res1 | X[rs2];
MEM[offs]{32}<=res2;
}
AMOMIN.W{
encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<= choose(res1's>X[rs2]s, X[rs2], res1);
MEM[offs]{32}<=res2;
}
AMOMAX.W{
encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<= choose(res1's<X[rs2]s, X[rs2], res1);
MEM[offs]{32}<=res2;
}
AMOMINU.W{
encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= zext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<= choose(res1>X[rs2], X[rs2], res1);
MEM[offs]{32}<=res2;
}
AMOMAXU.W{
encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= zext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<= choose(res1'u<X[rs2]'u, X[rs2], res1);
MEM[offs]{32}<=res2;
}
}
address_spaces {
RES[8]
}
instructions{
LR.W {
encoding: b00010 | aq[0:0] | rl[0:0] | b00000 | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d";
if(rd!=0){
val offs[XLEN] <= X[rs1];
X[rd]<= sext(MEM[offs]{32}, XLEN);
RES[offs]{32}<=sext(-1, 32);
}
}
SC.W {
encoding: b00011 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d";
val offs[XLEN] <= X[rs1];
val res1[32] <= RES[offs]{32};
if(res1!=0)
MEM[offs]{32} <= X[rs2];
if(rd!=0) X[rd]<= choose(res1!=0, 0, 1);
}
AMOSWAP.W{
encoding: b00001 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
if(rd!=0) X[rd]<=sext(MEM[offs]{32});
MEM[offs]{32}<=X[rs2];
}
AMOADD.W{
encoding: b00000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<=res1 + X[rs2];
MEM[offs]{32}<=res2;
}
AMOXOR.W{
encoding: b00100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<=res1 ^ X[rs2];
MEM[offs]{32}<=res2;
}
AMOAND.W{
encoding: b01100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN] <=res1 & X[rs2];
MEM[offs]{32}<=res2;
}
AMOOR.W {
encoding: b01000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<=res1 | X[rs2];
MEM[offs]{32}<=res2;
}
AMOMIN.W{
encoding: b10000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<= choose(res1's>X[rs2]s, X[rs2], res1);
MEM[offs]{32}<=res2;
}
AMOMAX.W{
encoding: b10100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= sext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<= choose(res1's<X[rs2]s, X[rs2], res1);
MEM[offs]{32}<=res2;
}
AMOMINU.W{
encoding: b11000 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= zext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<= choose(res1>X[rs2], X[rs2], res1);
MEM[offs]{32}<=res2;
}
AMOMAXU.W{
encoding: b11100 | aq[0:0] | rl[0:0] | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b0101111;
args_disass: "x%rd$d, x%rs1$d, x%rs2$d (aqu=%aq$d,rel=%rl$d)";
val offs[XLEN]<=X[rs1];
val res1[XLEN] <= zext(MEM[offs]{32});
if(rd!=0) X[rd]<=res1;
val res2[XLEN]<= choose(res1'u<X[rs2]'u, X[rs2], res1);
MEM[offs]{32}<=res2;
}
}
}

+ 316
- 345
riscv/gen_input/RV32C.core_desc View File

@ -1,17 +1,17 @@
import "RV32IBase.core_desc"
InsructionSet RV32IC {
constants {
XLEN
}
address_spaces {
MEM[8]
}
registers {
[31:0] X[XLEN],
PC[XLEN](is_pc)
}
instructions{
constants {
XLEN
}
address_spaces {
MEM[8]
}
registers {
[31:0] X[XLEN],
PC[XLEN](is_pc)
}
instructions{
JALR(no_cont){ // overwriting the implementation if rv32i, alignment does not need to be word
encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b1100111;
args_disass: "x%rd$d, x%rs1$d, 0x%imm$x";
@ -19,366 +19,337 @@ InsructionSet RV32IC {
val ret[XLEN] <= X[rs1]+ imm;
PC<=ret& ~0x1;
}
C.ADDI4SPN { //(RES, imm=0)
encoding: b000 | imm[5:4] | imm[9:6] | imm[2:2] | imm[3:3] | rd[2:0] | b00;
args_disass: "x%rd$d, 0x%imm$05x";
if(imm == 0) raise(0, 2);
val rd_idx[5] <= rd+8;
val x2_idx[5] <= 2;
X[rd_idx] <= X[x2_idx] + imm;
}
C.LW { // (RV32)
encoding: b010 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00;
args_disass: "x(8+%rd$d), x(8+%rs1$d), 0x%uimm$05x";
val rs1_idx[5] <= rs1+8;
val rd_idx[5] <= rd+8;
val offs[XLEN] <= X[rs1_idx]+uimm;
X[rd_idx] <= MEM[offs]{32};
}
C.SW {//(RV32)
encoding: b110 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00;
args_disass: "x(8+%rs1$d), x(8+%rs2$d), 0x%uimm$05x";
val rs1_idx[5] <= rs1+8;
val rs2_idx[5] <= rs2+8;
val offs[XLEN] <= X[rs1_idx]+uimm;
MEM[offs]{32} <= X[rs2_idx];
}
C.ADDI {//(RV32)
encoding:b000 | imm[5:5]s | rs1[4:0] | imm[4:0]s | b01;
args_disass: "x%rs1$d, 0x%imm$05x";
X[rs1] <= X[rs1] + imm;
}
C.NOP {
encoding:b000 | b0 | b00000 | b00000 | b01;
}
C.ADDI4SPN { //(RES, imm=0)
encoding: b000 | imm[5:4] | imm[9:6] | imm[2:2] | imm[3:3] | rd[2:0] | b00;
args_disass: "x%rd$d, 0x%imm$05x";
if(imm == 0) raise(0, 2);
X[rd+8] <= X[2] + imm;
}
C.LW { // (RV32)
encoding: b010 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00;
args_disass: "x(8+%rd$d), x(8+%rs1$d), 0x%uimm$05x";
val offs[XLEN] <= X[rs1+8]+uimm;
X[rd+8] <= MEM[offs]{32};
}
C.SW {//(RV32)
encoding: b110 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00;
args_disass: "x(8+%rs1$d), x(8+%rs2$d), 0x%uimm$05x";
val offs[XLEN] <= X[rs1+8]+uimm;
MEM[offs]{32} <= X[rs2+8];
}
C.ADDI {//(RV32)
encoding:b000 | imm[5:5]s | rs1[4:0] | imm[4:0]s | b01;
args_disass: "x%rs1$d, 0x%imm$05x";
X[rs1] <= X[rs1] + imm;
}
C.NOP {
encoding:b000 | b0 | b00000 | b00000 | b01;
}
// C.JAL will be overwritten by C.ADDIW for RV64/128
C.JAL(no_cont) {//(RV32)
encoding: b001 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01;
args_disass: "0x%imm$05x";
val rd[5] <= 1;
X[rd] <= PC+2;
PC<=PC+imm;
}
C.LI {//(RV32)
encoding:b010 | imm[5:5]s | rd[4:0] | imm[4:0]s | b01;
args_disass: "x%rd$d, 0x%imm$05x";
if(rd == 0) raise(0, 2); //TODO: should it be handled as trap?
X[rd] <= imm;
}
// order matters here as C.ADDI16SP overwrites C.LUI vor rd==2
C.LUI {//(RV32)
encoding:b011 | imm[17:17]s | rd[4:0] | imm[16:12]s | b01;
args_disass: "x%rd$d, 0x%imm$05x";
if(rd == 0) raise(0, 2); //TODO: should it be handled as trap?
if(imm == 0) raise(0, 2); //TODO: should it be handled as trap?
X[rd] <= imm;
}
C.ADDI16SP {//(RV32)
encoding:b011 | imm[9:9]s | b00010 | imm[4:4]s | imm[6:6]s | imm[8:7]s | imm[5:5]s | b01;
args_disass: "0x%imm$05x";
val x2_idx[5] <= 2;
X[x2_idx] <= X[x2_idx]s + imm;
}
C.SRLI {//(RV32 nse)
encoding:b100 | b0 | b00 | rs1[2:0] | shamt[4:0] | b01;
args_disass: "x(8+%rs1$d), %shamt$d";
val rs1_idx[5] <= rs1+8;
X[rs1_idx] <= shrl(X[rs1_idx], shamt);
}
C.SRAI {//(RV32)
encoding:b100 | b0 | b01 | rs1[2:0] | shamt[4:0] | b01;
args_disass: "x(8+%rs1$d), %shamt$d";
val rs1_idx[5] <= rs1+8;
X[rs1_idx] <= shra(X[rs1_idx], shamt);
}
C.ANDI {//(RV32)
encoding:b100 | imm[5:5]s | b10 | rs1[2:0] | imm[4:0]s | b01;
args_disass: "x(8+%rs1$d), 0x%imm$05x";
val rs1_idx[5] <= rs1 + 8;
X[rs1_idx] <= X[rs1_idx] & imm;
}
C.SUB {//(RV32)
encoding:b100 | b0 | b11 | rd[2:0] | b00 | rs2[2:0] | b01;
args_disass: "x(8+%rd$d), x(8+%rs2$d)";
val rd_idx[5] <= rd + 8;
val rs2_idx[5] <= rs2 + 8;
X[rd_idx] <= X[rd_idx] - X[rs2_idx];
}
C.XOR {//(RV32)
encoding:b100 | b0 | b11 | rd[2:0] | b01 | rs2[2:0] | b01;
args_disass: "x(8+%rd$d), x(8+%rs2$d)";
val rd_idx[5] <= rd + 8;
val rs2_idx[5] <= rs2 + 8;
X[rd_idx] <= X[rd_idx] ^ X[rs2_idx];
}
C.OR {//(RV32)
encoding:b100 | b0 | b11 | rd[2:0] | b10 | rs2[2:0] | b01;
args_disass: "x(8+%rd$d), x(8+%rs2$d)";
val rd_idx[5] <= rd + 8;
val rs2_idx[5] <= rs2 + 8;
X[rd_idx] <= X[rd_idx] | X[rs2_idx];
}
C.AND {//(RV32)
encoding:b100 | b0 | b11 | rd[2:0] | b11 | rs2[2:0] | b01;
args_disass: "x(8+%rd$d), x(8+%rs2$d)";
val rd_idx[5] <= rd + 8;
val rs2_idx[5] <= rs2 + 8;
X[rd_idx] <= X[rd_idx] & X[rs2_idx];
}
C.J(no_cont) {//(RV32)
encoding:b101 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01;
args_disass: "0x%imm$05x";
PC<=PC+imm;
}
C.BEQZ(no_cont,cond) {//(RV32)
encoding:b110 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s |imm[2:1]s | imm[5:5]s | b01;
args_disass: "x(8+%rs1$d), 0x%imm$05x";
val rs1_idx[5] <= rs1+8;
PC<=choose(X[rs1_idx]==0, PC+imm, PC+2);
}
C.BNEZ(no_cont,cond) {//(RV32)
encoding:b111 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s | imm[2:1]s | imm[5:5]s | b01;
args_disass: "x(8+%rs1$d), 0x%imm$05x";
C.JAL(no_cont) {//(RV32)
encoding: b001 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01;
args_disass: "0x%imm$05x";
X[1] <= PC+2;
PC<=PC+imm;
}
C.LI {//(RV32)
encoding:b010 | imm[5:5]s | rd[4:0] | imm[4:0]s | b01;
args_disass: "x%rd$d, 0x%imm$05x";
if(rd == 0) raise(0, 2); //TODO: should it be handled as trap?
X[rd] <= imm;
}
// order matters here as C.ADDI16SP overwrites C.LUI vor rd==2
C.LUI {//(RV32)
encoding:b011 | imm[17:17]s | rd[4:0] | imm[16:12]s | b01;
args_disass: "x%rd$d, 0x%imm$05x";
if(rd == 0) raise(0, 2); //TODO: should it be handled as trap?
if(imm == 0) raise(0, 2); //TODO: should it be handled as trap?
X[rd] <= imm;
}
C.ADDI16SP {//(RV32)
encoding:b011 | imm[9:9]s | b00010 | imm[4:4]s | imm[6:6]s | imm[8:7]s | imm[5:5]s | b01;
args_disass: "0x%imm$05x";
X[2] <= X[2]s + imm;
}
C.SRLI {//(RV32 nse)
encoding:b100 | b0 | b00 | rs1[2:0] | shamt[4:0] | b01;
args_disass: "x(8+%rs1$d), %shamt$d";
val rs1_idx[5] <= rs1+8;
X[rs1_idx] <= shrl(X[rs1_idx], shamt);
}
C.SRAI {//(RV32)
encoding:b100 | b0 | b01 | rs1[2:0] | shamt[4:0] | b01;
args_disass: "x(8+%rs1$d), %shamt$d";
val rs1_idx[5] <= rs1+8;
PC<=choose(X[rs1_idx]!=0, PC+imm, PC+2);
}
C.SLLI {//(RV32)
encoding:b000 | b0 | rs1[4:0] | shamt[4:0] | b10;
args_disass: "x%rs1$d, %shamt$d";
if(rs1 == 0) raise(0, 2);
X[rs1] <= shll(X[rs1], shamt);
}
C.LWSP {//
encoding:b010 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10;
args_disass: "x%rd$d, sp, 0x%uimm$05x";
val x2_idx[5] <= 2;
val offs[XLEN] <= X[x2_idx] + uimm;
X[rd] <= MEM[offs]{32};
}
// order matters as C.JR is a special case of C.MV
X[rs1_idx] <= shra(X[rs1_idx], shamt);
}
C.ANDI {//(RV32)
encoding:b100 | imm[5:5]s | b10 | rs1[2:0] | imm[4:0]s | b01;
args_disass: "x(8+%rs1$d), 0x%imm$05x";
val rs1_idx[5] <= rs1 + 8;
X[rs1_idx] <= X[rs1_idx] & imm;
}
C.SUB {//(RV32)
encoding:b100 | b0 | b11 | rd[2:0] | b00 | rs2[2:0] | b01;
args_disass: "x(8+%rd$d), x(8+%rs2$d)";
val rd_idx[5] <= rd + 8;
X[rd_idx] <= X[rd_idx] - X[rs2 + 8];
}
C.XOR {//(RV32)
encoding:b100 | b0 | b11 | rd[2:0] | b01 | rs2[2:0] | b01;
args_disass: "x(8+%rd$d), x(8+%rs2$d)";
val rd_idx[5] <= rd + 8;
X[rd_idx] <= X[rd_idx] ^ X[rs2 + 8];
}
C.OR {//(RV32)
encoding:b100 | b0 | b11 | rd[2:0] | b10 | rs2[2:0] | b01;
args_disass: "x(8+%rd$d), x(8+%rs2$d)";
val rd_idx[5] <= rd + 8;
X[rd_idx] <= X[rd_idx] | X[rs2 + 8];
}
C.AND {//(RV32)
encoding:b100 | b0 | b11 | rd[2:0] | b11 | rs2[2:0] | b01;
args_disass: "x(8+%rd$d), x(8+%rs2$d)";
val rd_idx[5] <= rd + 8;
X[rd_idx] <= X[rd_idx] & X[rs2 + 8];
}
C.J(no_cont) {//(RV32)
encoding:b101 | imm[11:11]s | imm[4:4]s | imm[9:8]s | imm[10:10]s | imm[6:6]s | imm[7:7]s | imm[3:1]s | imm[5:5]s | b01;
args_disass: "0x%imm$05x";
PC<=PC+imm;
}
C.BEQZ(no_cont,cond) {//(RV32)
encoding:b110 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s |imm[2:1]s | imm[5:5]s | b01;
args_disass: "x(8+%rs1$d), 0x%imm$05x";
PC<=choose(X[rs1+8]==0, PC+imm, PC+2);
}
C.BNEZ(no_cont,cond) {//(RV32)
encoding:b111 | imm[8:8]s | imm[4:3]s | rs1[2:0] | imm[7:6]s | imm[2:1]s | imm[5:5]s | b01;
args_disass: "x(8+%rs1$d), 0x%imm$05x";
PC<=choose(X[rs1+8]!=0, PC+imm, PC+2);
}
C.SLLI {//(RV32)
encoding:b000 | b0 | rs1[4:0] | shamt[4:0] | b10;
args_disass: "x%rs1$d, %shamt$d";
if(rs1 == 0) raise(0, 2);
X[rs1] <= shll(X[rs1], shamt);
}
C.LWSP {//
encoding:b010 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10;
args_disass: "x%rd$d, sp, 0x%uimm$05x";
val offs[XLEN] <= X[2] + uimm;
X[rd] <= MEM[offs]{32};
}
// order matters as C.JR is a special case of C.MV
C.MV {//(RV32)
encoding:b100 | b0 | rd[4:0] | rs2[4:0] | b10;
args_disass: "x%rd$d, x%rs2$d";
X[rd] <= X[rs2];
}
C.JR(no_cont) {//(RV32)
encoding:b100 | b0 | rs1[4:0] | b00000 | b10;
args_disass: "x%rs1$d";
PC <= X[rs1];
}
C.JR(no_cont) {//(RV32)
encoding:b100 | b0 | rs1[4:0] | b00000 | b10;
args_disass: "x%rs1$d";
PC <= X[rs1];
}
// order matters as C.EBREAK is a special case of C.JALR which is a special case of C.ADD
C.ADD {//(RV32)
encoding:b100 | b1 | rd[4:0] | rs2[4:0] | b10;
args_disass: "x%rd$d, x%rs2$d";
X[rd] <= X[rd] + X[rs2];
}
C.JALR(no_cont) {//(RV32)
encoding:b100 | b1 | rs1[4:0] | b00000 | b10;
args_disass: "x%rs1$d";
val r_idx[5] <= 1;
X[r_idx] <= PC+2;
PC<=X[rs1];
}
C.EBREAK(no_cont) {//(RV32)
encoding:b100 | b1 | b00000 | b00000 | b10;
raise(0, 3);
}
C.SWSP {//
encoding:b110 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10;
X[rd] <= X[rd] + X[rs2];
}
C.JALR(no_cont) {//(RV32)
encoding:b100 | b1 | rs1[4:0] | b00000 | b10;
args_disass: "x%rs1$d";
X[1] <= PC+2;
PC<=X[rs1];
}
C.EBREAK(no_cont) {//(RV32)
encoding:b100 | b1 | b00000 | b00000 | b10;
raise(0, 3);
}
C.SWSP {//
encoding:b110 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10;
args_disass: "x2+0x%uimm$05x, x%rs2$d";
val x2_idx[5] <= 2;
val offs[XLEN] <= X[x2_idx] + uimm;
val offs[XLEN] <= X[2] + uimm;
MEM[offs]{32} <= X[rs2];
}
DII {
encoding:b000 | b0 | b00000 | b00000 | b00;
raise(0, 2);
}
}
}
DII {
encoding:b000 | b0 | b00000 | b00000 | b00;
raise(0, 2);
}
}
}
InsructionSet RV32FC extends RV32IC{
constants {
XLEN, FLEN
}
address_spaces {
MEM[8]
}
registers {
[31:0] X[XLEN],
[31:0] F[FLEN]
}
instructions{
C.FLW {
encoding: b011 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00;
args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))";
val rs1_idx[5] <= rs1+8;
val rd_idx[5] <= rd+8;
val offs[XLEN] <= X[rs1_idx]+uimm;
val res[32] <= MEM[offs]{32};
if(FLEN==32)
F[rd_idx] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
C.FSW {
encoding: b111 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00;
args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))";
val rs1_idx[5] <= rs1+8;
val rs2_idx[5] <= rs2+8;
val offs[XLEN] <= X[rs1_idx]+uimm;
MEM[offs]{32}<=F[rs2_idx]{32};
}
C.FLWSP {
encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10;
args_disass:"f%rd$d, %uimm%(x2)";
val x2_idx[5] <= 2;
val offs[XLEN] <= X[x2_idx]+uimm;
val res[32] <= MEM[offs]{32};
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
C.FSWSP {
encoding:b111 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10;
args_disass:"f%rs2$d, %uimm%(x2), ";
val x2_idx[5] <= 2;
val offs[XLEN] <= X[x2_idx]+uimm;
MEM[offs]{32}<=F[rs2]{32};
}
}
constants {
XLEN, FLEN
}
address_spaces {
MEM[8]
}
registers {
[31:0] X[XLEN],
[31:0] F[FLEN]
}
instructions{
C.FLW {
encoding: b011 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00;
args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))";
val offs[XLEN] <= X[rs1+8]+uimm;
val res[32] <= MEM[offs]{32};
if(FLEN==32)
F[rd+8] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd+8] <= (upper<<32) | zext(res, FLEN);
}
}
C.FSW {
encoding: b111 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00;
args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))";
val offs[XLEN] <= X[rs1+8]+uimm;
MEM[offs]{32}<=F[rs2+8]{32};
}
C.FLWSP {
encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10;
args_disass:"f%rd$d, %uimm%(x2)";
val offs[XLEN] <= X[2]+uimm;
val res[32] <= MEM[offs]{32};
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
C.FSWSP {
encoding:b111 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10;
args_disass:"f%rs2$d, %uimm%(x2), ";
val offs[XLEN] <= X[2]+uimm;
MEM[offs]{32}<=F[rs2]{32};
}
}
}
InsructionSet RV32DC extends RV32IC{
constants {
XLEN, FLEN
}
address_spaces {
MEM[8]
}
registers {
[31:0] X[XLEN],
[31:0] F[FLEN]
}
instructions{
C.FLD { //(RV32/64)
encoding: b001 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00;
args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))";
val rs1_idx[5] <= rs1+8;
val rd_idx[5] <= rd+8;
val offs[XLEN] <= X[rs1_idx]+uimm;
val res[64] <= MEM[offs]{64};
if(FLEN==64)
F[rd_idx] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd_idx] <= (upper<<64) | res;
}
}
C.FSD { //(RV32/64)
encoding: b101 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00;
args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))";
val rs1_idx[5] <= rs1+8;
val rs2_idx[5] <= rs2+8;
val offs[XLEN] <= X[rs1_idx]+uimm;
MEM[offs]{64}<=F[rs2_idx]{64};
}
C.FLDSP {//(RV32/64)
encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10;
args_disass:"f%rd$d, %uimm%(x2)";
val x2_idx[5] <= 2;
val offs[XLEN] <= X[x2_idx]+uimm;
val res[64] <= MEM[offs]{64};
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | zext(res, FLEN);
}
}
C.FSDSP {//(RV32/64)
encoding:b101 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10;
args_disass:"f%rs2$d, %uimm%(x2), ";
val x2_idx[5] <= 2;
val offs[XLEN] <= X[x2_idx]+uimm;
MEM[offs]{64}<=F[rs2]{64};
}
}
constants {
XLEN, FLEN
}
address_spaces {
MEM[8]
}
registers {
[31:0] X[XLEN],
[31:0] F[FLEN]
}
instructions{
C.FLD { //(RV32/64)
encoding: b001 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00;
args_disass:"f(8+%rd$d), %uimm%(x(8+%rs1$d))";
val offs[XLEN] <= X[rs1+8]+uimm;
val res[64] <= MEM[offs]{64};
if(FLEN==64)
F[rd+8] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd+8] <= (upper<<64) | res;
}
}
C.FSD { //(RV32/64)
encoding: b101 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00;
args_disass:"f(8+%rs2$d), %uimm%(x(8+%rs1$d))";
val offs[XLEN] <= X[rs1+8]+uimm;
MEM[offs]{64}<=F[rs2+8]{64};
}
C.FLDSP {//(RV32/64)
encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10;
args_disass:"f%rd$d, %uimm%(x2)";
val offs[XLEN] <= X[2]+uimm;
val res[64] <= MEM[offs]{64};
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | zext(res, FLEN);
}
}
C.FSDSP {//(RV32/64)
encoding:b101 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10;
args_disass:"f%rs2$d, %uimm%(x2), ";
val offs[XLEN] <= X[2]+uimm;
MEM[offs]{64}<=F[rs2]{64};
}
}
}
InsructionSet RV64IC extends RV32IC {
constants {
XLEN
}
address_spaces {
MEM[8]
}
registers {
[31:0] X[XLEN],
PC[XLEN](is_pc)
}
instructions{
C.LD {//(RV64/128)
encoding:b011 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00;
}
C.SD { //(RV64/128)
encoding:b111 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00;
}
C.SUBW {//(RV64/128, RV32 res)
encoding:b100 | b1 | b11 | rd[2:0] | b00 | rs2[2:0] | b01;
args_disass: "x%rd$d, sp, 0x%imm$05x";
}
C.ADDW {//(RV64/128 RV32 res)
encoding:b100 | b1 | b11 | rd[2:0] | b01 | rs2[2:0] | b01;
args_disass: "x%rd$d, sp, 0x%imm$05x";
}
constants {
XLEN
}
address_spaces {
MEM[8]
}
registers {
[31:0] X[XLEN],
PC[XLEN](is_pc)
}
instructions{
C.LD {//(RV64/128)
encoding:b011 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00;
}
C.SD { //(RV64/128)
encoding:b111 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00;
}
C.SUBW {//(RV64/128, RV32 res)
encoding:b100 | b1 | b11 | rd[2:0] | b00 | rs2[2:0] | b01;
args_disass: "x%rd$d, sp, 0x%imm$05x";
}
C.ADDW {//(RV64/128 RV32 res)
encoding:b100 | b1 | b11 | rd[2:0] | b01 | rs2[2:0] | b01;
args_disass: "x%rd$d, sp, 0x%imm$05x";
}
C.ADDIW {//(RV64/128)
encoding:b001 | imm[5:5] | rs1[4:0] | imm[4:0] | b01;
}
C.SRLI64 {//(RV32/64/128)
encoding:b100 | b0 | b00 | rs1[2:0] | b00000 | b01;
}
C.SRAI64 {//(RV32/64/128)
encoding:b100 | b0 | b01 | rs1[2:0] | b00000 | b01;
}
C.SLLI64 {//(RV128 RV32/64)
encoding:b000 | b0 | rs1[4:0] | b00000 | b10;
}
C.LDSP {//(RV64/128
encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10;
args_disass: "x%rd$d, sp, 0x%imm$05x";
}
C.SDSP {//(RV64/128)
encoding:b111 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10;
}
}
C.SRLI64 {//(RV32/64/128)
encoding:b100 | b0 | b00 | rs1[2:0] | b00000 | b01;
}
C.SRAI64 {//(RV32/64/128)
encoding:b100 | b0 | b01 | rs1[2:0] | b00000 | b01;
}
C.SLLI64 {//(RV128 RV32/64)
encoding:b000 | b0 | rs1[4:0] | b00000 | b10;
}
C.LDSP {//(RV64/128
encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10;
args_disass: "x%rd$d, sp, 0x%imm$05x";
}
C.SDSP {//(RV64/128)
encoding:b111 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10;
}
}
}
InsructionSet RV128IC extends RV64IC {
constants {
XLEN
}
address_spaces {
MEM[8]
}
registers {
[31:0] X[XLEN],
PC[XLEN](is_pc)
}
instructions{
C.LQ { //(RV128)
encoding:b001 | uimm[5:4] | uimm[8:8] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00;
}
C.SQ { //(RV128)
encoding:b101 | uimm[5:4] | uimm[8:8] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00;
}
C.SQSP {//(RV128)
encoding:b101 | uimm[5:4] | uimm[9:6] | rs2[4:0] | b10;
}
}
constants {
XLEN
}
address_spaces {
MEM[8]
}
registers {
[31:0] X[XLEN],
PC[XLEN](is_pc)
}
instructions{
C.LQ { //(RV128)
encoding:b001 | uimm[5:4] | uimm[8:8] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00;
}
C.SQ { //(RV128)
encoding:b101 | uimm[5:4] | uimm[8:8] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00;
}
C.SQSP {//(RV128)
encoding:b101 | uimm[5:4] | uimm[9:6] | rs2[4:0] | b10;
}
}
}

+ 294
- 294
riscv/gen_input/RV32D.core_desc View File

@ -1,298 +1,298 @@
import "RV32IBase.core_desc"
InsructionSet RV32D extends RV32IBase{
constants {
FLEN, FFLAG_MASK := 0x1f
}
registers {
[31:0] F[FLEN], FCSR[32]
}
instructions{
FLD {
encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000111;
args_disass:"f%rd$d, %imm%(x%rs1$d)";
val offs[XLEN] <= X[rs1]+imm;
val res[64] <= MEM[offs]{64};
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FSD {
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100111;
args_disass:"f%rs2$d, %imm%(x%rs1$d)";
val offs[XLEN] <= X[rs1]+imm;
MEM[offs]{64}<=F[rs2]{64};
}
FMADD.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(0, 64), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMSUB.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMADD.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMSUB.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FADD.D {
encoding: b0000001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f + F[rs2]f;
val res[64] <= fdispatch_fadd_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSUB.D {
encoding: b0000101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f - F[rs2]f;
val res[64] <= fdispatch_fsub_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMUL.D {
encoding: b0001001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f * F[rs2]f;
val res[64] <= fdispatch_fmul_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FDIV.D {
encoding: b0001101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f / F[rs2]f;
val res[64] <= fdispatch_fdiv_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSQRT.D {
encoding: b0101101 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
//F[rd]f<=sqrt(F[rs1]f);
val res[64] <= fdispatch_fsqrt_d(F[rs1]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSGNJ.D {
encoding: b0010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
val res[64] <= (F[rs1]{64} & 0x7fffffff) | (F[rs2]{64} & 0x80000000);
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FSGNJN.D {
encoding: b0010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
val res[64] <= (F[rs1]{64} & 0x7fffffff) | (~F[rs2]{64} & 0x80000000);
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FSGNJX.D {
encoding: b0010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
val res[64] <= F[rs1]{64} ^ (F[rs2]{64} & 0x80000000);
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FMIN.D {
encoding: b0010101 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
//F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f);
val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMAX.D {
encoding: b0010101 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
//F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f);
val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.S.D {
encoding: b0100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d";
val res[32] <= fdispatch_fconv_d2f(F[rs1], rm{8});
// NaN boxing
val upper[FLEN] <= -1;
F[rd] <= upper<<32 | zext(res, FLEN);
}
FCVT.D.S {
encoding: b0100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d";
val res[64] <= fdispatch_fconv_f2d(F[rs1]{32}, rm{8});
if(FLEN==64){
F[rd] <= res;
} else {
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FEQ.D {
encoding: b1010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FLT.D {
encoding: b1010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(2, 32));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FLE.D {
encoding: b1010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCLASS.D {
encoding: b1110001 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
X[rd]<=fdispatch_fclass_d(F[rs1]{64});
}
FCVT.W.D {
encoding: b1100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
X[rd]<= sext(fdispatch_fcvt_d(F[rs1]{64}, zext(0, 32), rm{8}), XLEN);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.WU.D {
encoding: b1100001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
X[rd]<= zext(fdispatch_fcvt_d(F[rs1]{64}, zext(1, 32), rm{8}), XLEN);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.D.W {
encoding: b1101001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, x%rs1$d";
val res[64] <= fdispatch_fcvt_d(sext(X[rs1],64), zext(2, 32), rm{8});
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FCVT.D.WU {
encoding: b1101001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, x%rs1$d";
val res[64] <=fdispatch_fcvt_d(zext(X[rs1],64), zext(3,32), rm{8});
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
}
constants {
FLEN, FFLAG_MASK := 0x1f
}
registers {
[31:0] F[FLEN], FCSR[32]
}
instructions{
FLD {
encoding: imm[11:0]s | rs1[4:0] | b011 | rd[4:0] | b0000111;
args_disass:"f%rd$d, %imm%(x%rs1$d)";
val offs[XLEN] <= X[rs1]+imm;
val res[64] <= MEM[offs]{64};
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FSD {
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b011 | imm[4:0]s | b0100111;
args_disass:"f%rs2$d, %imm%(x%rs1$d)";
val offs[XLEN] <= X[rs1]+imm;
MEM[offs]{64}<=F[rs2]{64};
}
FMADD.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(0, 64), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMSUB.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMADD.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMSUB.D {
encoding: rs3[4:0] | b01 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f;
val res[64] <= fdispatch_fmadd_d(F[rs1]{64}, F[rs2]{64}, F[rs3]{64}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FADD.D {
encoding: b0000001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f + F[rs2]f;
val res[64] <= fdispatch_fadd_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSUB.D {
encoding: b0000101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f - F[rs2]f;
val res[64] <= fdispatch_fsub_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMUL.D {
encoding: b0001001 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f * F[rs2]f;
val res[64] <= fdispatch_fmul_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FDIV.D {
encoding: b0001101 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f / F[rs2]f;
val res[64] <= fdispatch_fdiv_d(F[rs1]{64}, F[rs2]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSQRT.D {
encoding: b0101101 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
//F[rd]f<=sqrt(F[rs1]f);
val res[64] <= fdispatch_fsqrt_d(F[rs1]{64}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSGNJ.D {
encoding: b0010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
val res[64] <= (F[rs1]{64} & 0x7fffffff) | (F[rs2]{64} & 0x80000000);
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FSGNJN.D {
encoding: b0010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
val res[64] <= (F[rs1]{64} & 0x7fffffff) | (~F[rs2]{64} & 0x80000000);
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FSGNJX.D {
encoding: b0010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
val res[64] <= F[rs1]{64} ^ (F[rs2]{64} & 0x80000000);
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FMIN.D {
encoding: b0010101 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
//F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f);
val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMAX.D {
encoding: b0010101 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
//F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f);
val res[64] <= fdispatch_fsel_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32));
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.S.D {
encoding: b0100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d";
val res[32] <= fdispatch_fconv_d2f(F[rs1], rm{8});
// NaN boxing
val upper[FLEN] <= -1;
F[rd] <= upper<<32 | zext(res, FLEN);
}
FCVT.D.S {
encoding: b0100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d";
val res[64] <= fdispatch_fconv_f2d(F[rs1]{32}, rm{8});
if(FLEN==64){
F[rd] <= res;
} else {
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FEQ.D {
encoding: b1010001 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(0, 32));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FLT.D {
encoding: b1010001 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(2, 32));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FLE.D {
encoding: b1010001 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
X[rd]<=fdispatch_fcmp_d(F[rs1]{64}, F[rs2]{64}, zext(1, 32));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCLASS.D {
encoding: b1110001 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
X[rd]<=fdispatch_fclass_d(F[rs1]{64});
}
FCVT.W.D {
encoding: b1100001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
X[rd]<= sext(fdispatch_fcvt_d(F[rs1]{64}, zext(0, 32), rm{8}), XLEN);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.WU.D {
encoding: b1100001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
X[rd]<= zext(fdispatch_fcvt_d(F[rs1]{64}, zext(1, 32), rm{8}), XLEN);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.D.W {
encoding: b1101001 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, x%rs1$d";
val res[64] <= fdispatch_fcvt_d(sext(X[rs1],64), zext(2, 32), rm{8});
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
FCVT.D.WU {
encoding: b1101001 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, x%rs1$d";
val res[64] <=fdispatch_fcvt_d(zext(X[rs1],64), zext(3,32), rm{8});
if(FLEN==64)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<64) | res;
}
}
}
}

+ 290
- 290
riscv/gen_input/RV32F.core_desc View File

@ -1,294 +1,294 @@
import "RV32IBase.core_desc"
InsructionSet RV32F extends RV32IBase{
constants {
FLEN, FFLAG_MASK := 0x1f
}
registers {
[31:0] F[FLEN], FCSR[32]
}
instructions{
FLW {
encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000111;
args_disass:"f%rd$d, %imm%(x%rs1$d)";
val offs[XLEN] <= X[rs1]+imm;
val res[32] <= MEM[offs]{32};
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FSW {
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100111;
args_disass:"f%rs2$d, %imm%(x%rs1$d)";
val offs[XLEN] <= X[rs1]+imm;
MEM[offs]{32}<=F[rs2]{32};
}
FMADD.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f;
val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(0, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMSUB.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f;
val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMADD.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f;
val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMSUB.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f;
val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FADD.S {
encoding: b0000000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f + F[rs2]f;
val res[32] <= fdispatch_fadd_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSUB.S {
encoding: b0000100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f - F[rs2]f;
val res[32] <= fdispatch_fsub_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMUL.S {
encoding: b0001000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f * F[rs2]f;
val res[32] <= fdispatch_fmul_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FDIV.S {
encoding: b0001100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
// F[rd]f <= F[rs1]f / F[rs2]f;
val res[32] <= fdispatch_fdiv_s(F[rs1]{32}, F[rs2]{32}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSQRT.S {
encoding: b0101100 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d";
//F[rd]f<=sqrt(F[rs1]f);
val res[32] <= fdispatch_fsqrt_s(F[rs1]{32}, choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FSGNJ.S {
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
val res[32] <= (F[rs1]{32} & 0x7fffffff) | (F[rs2]{32} & 0x80000000);
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FSGNJN.S {
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
val res[32] <= (F[rs1]{32} & 0x7fffffff) | (~F[rs2]{32} & 0x80000000);
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FSGNJX.S {
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
val res[32] <= F[rs1]{32} ^ (F[rs2]{32} & 0x80000000);
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FMIN.S {
encoding: b0010100 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
//F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f);
val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMAX.S {
encoding: b0010100 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"f%rd$d, f%rs1$d, f%rs2$d";
//F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f);
val res[32] <= fdispatch_fsel_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.W.S {
encoding: b1100000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
X[rd]<= sext(fdispatch_fcvt_s(F[rs1]{32}, zext(0, 32), rm{8}), XLEN);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCVT.WU.S {
encoding: b1100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
X[rd]<= zext(fdispatch_fcvt_s(F[rs1]{32}, zext(1, 32), rm{8}), XLEN);
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FEQ.S {
encoding: b1010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(0, 32));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FLT.S {
encoding: b1010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(2, 32));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FLE.S {
encoding: b1010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d";
X[rd]<=fdispatch_fcmp_s(F[rs1]{32}, F[rs2]{32}, zext(1, 32));
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FCLASS.S {
encoding: b1110000 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
X[rd]<=fdispatch_fclass_s(F[rs1]{32});
}
FCVT.S.W {
encoding: b1101000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, x%rs1$d";
val res[32] <= fdispatch_fcvt_s(X[rs1]{32}, zext(2, 32), rm{8});
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FCVT.S.WU {
encoding: b1101000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
args_disass:"f%rd$d, x%rs1$d";
val res[32] <=fdispatch_fcvt_s(X[rs1]{32}, zext(3,32), rm{8});
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FMV.X.W {
encoding: b1110000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"x%rd$d, f%rs1$d";
X[rd]<=sext(F[rs1]{32});
}
FMV.W.X {
encoding: b1111000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011;
args_disass:"f%rd$d, x%rs1$d";
if(FLEN==32)
F[rd] <= X[rs1];
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(X[rs1], FLEN);
}
}
}
constants {
FLEN, FFLAG_MASK := 0x1f
}
registers {
[31:0] F[FLEN], FCSR[32]
}
instructions{
FLW {
encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000111;
args_disass:"f%rd$d, %imm%(x%rs1$d)";
val offs[XLEN] <= X[rs1]+imm;
val res[32] <= MEM[offs]{32};
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
}
FSW {
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100111;
args_disass:"f%rs2$d, %imm%(x%rs1$d)";
val offs[XLEN] <= X[rs1]+imm;
MEM[offs]{32}<=F[rs2]{32};
}
FMADD.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<= F[rs1]f * F[rs2]f + F[rs3]f;
val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(0, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FMSUB.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=F[rs1]f * F[rs2]f - F[rs3]f;
val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(1, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMADD.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=-F[rs1]f * F[rs2]f + F[rs3]f;
val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(2, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)
F[rd] <= res;
else { // NaN boxing
val upper[FLEN] <= -1;
F[rd] <= (upper<<32) | zext(res, FLEN);
}
val flags[32] <= fdispatch_fget_flags();
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
}
FNMSUB.S {
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011;
args_disass:"x%rd$d, f%rs1$d, f%rs2$d, f%rs3$d";
//F[rd]f<=-F[rs1]f * F[rs2]f - F[rs3]f;
val res[32] <= fdispatch_fmadd_s(F[rs1]{32}, F[rs2]{32}, F[rs3]{32}, zext(3, 32), choose(rm<7, rm{8}, FCSR{8}));
if(FLEN==32)