Added RV32F extension, fixed RV32M bugs
This commit is contained in:
parent
bc7450dad2
commit
48ad30dcae
10
.cproject
10
.cproject
|
@ -13,7 +13,7 @@
|
||||||
</extensions>
|
</extensions>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
<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="">
|
<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">
|
<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"/>
|
<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"/>
|
||||||
|
@ -46,6 +46,13 @@
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||||
<storageModule buildDir="build/${ConfigName}" moduleId="de.marw.cdt.cmake.core.settings">
|
<storageModule buildDir="build/${ConfigName}" moduleId="de.marw.cdt.cmake.core.settings">
|
||||||
<options/>
|
<options/>
|
||||||
|
<linux command="cmake" generator="UnixMakefiles" use-default="true">
|
||||||
|
<defs>
|
||||||
|
<def name="CMAKE_VERBOSE_MAKEFILE" type="BOOL" val="OFF"/>
|
||||||
|
</defs>
|
||||||
|
</linux>
|
||||||
|
<win32 command="cmake" generator="MinGWMakefiles" use-default="true">
|
||||||
|
</win32>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
</cconfiguration>
|
</cconfiguration>
|
||||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.1745230171">
|
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.1745230171">
|
||||||
|
@ -177,4 +184,5 @@
|
||||||
</configuration>
|
</configuration>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||||
</cproject>
|
</cproject>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.exe.debug.1751741082/LLVM_HOME/delimiter=\:
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.exe.debug.1751741082/LLVM_HOME/operation=replace
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.exe.debug.1751741082/LLVM_HOME/value=/usr/lib/llvm-4.0
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.exe.debug.1751741082/append=true
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.exe.debug.1751741082/appendContributed=true
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171/LLVM_HOME/delimiter=\:
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171/LLVM_HOME/operation=append
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171/LLVM_HOME/value=/usr/lib/llvm-6.0
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171/append=true
|
||||||
|
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171/appendContributed=true
|
2
dbt-core
2
dbt-core
|
@ -1 +1 @@
|
||||||
Subproject commit bc05d40184ccb8871afa61620fe2c67ce2951fa4
|
Subproject commit d9512853b22e869938013c8dc0c6678a92d52c0e
|
|
@ -2,7 +2,7 @@
|
||||||
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
|
||||||
<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/dbt-riscv/riscv" type="2"/> </resources>}"/>
|
<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <resources> <item path="/dbt-riscv/riscv" type="2"/> </resources>}"/>
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LAUNCH_CONFIGURATION_BUILD_SCOPE" value="${none}"/>
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LAUNCH_CONFIGURATION_BUILD_SCOPE" value="${none}"/>
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="/usr/lib/jvm/java-8-oracle/bin/java"/>
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="/usr/bin/java"/>
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-jar ${env_var:HOME}/git/JIT-ISS-CoreDsl/com.minres.coredsl.standalone/target/com.minres.coredsl.standalone-1.0.0-SNAPSHOT.jar -i=${project_loc:dbt-riscv}/riscv/incl/iss/arch -s=${project_loc:dbt-riscv}/riscv/src/iss -v=${project_loc:dbt-riscv}/riscv/src/internal -t=${project_loc:dbt-riscv}/riscv/gen_input/templates ${project_loc:dbt-riscv}/riscv/gen_input/minres_rv.core_desc"/>
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="-Xmx1G -jar ${env_var:HOME}/git/JIT-ISS-CoreDsl/com.minres.coredsl.standalone/target/com.minres.coredsl.standalone-1.0.0-SNAPSHOT.jar -i=${project_loc:DBT-RISE-RISCV}/riscv/incl/iss/arch -s=${project_loc:DBT-RISE-RISCV}/riscv/src/iss -v=${project_loc:DBT-RISE-RISCV}/riscv/src/internal -t=${project_loc:DBT-RISE-RISCV}/riscv/gen_input/templates ${project_loc:DBT-RISE-RISCV}/riscv/gen_input/minres_rv.core_desc"/>
|
||||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/dbt-riscv}/riscv/gen_input"/>
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/DBT-RISE-RISCV}/riscv/gen_input"/>
|
||||||
</launchConfiguration>
|
</launchConfiguration>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import "RV32IBase.core_desc"
|
import "RV32IBase.core_desc"
|
||||||
|
|
||||||
InsructionSet RV32CI {
|
InsructionSet RV32IC {
|
||||||
constants {
|
constants {
|
||||||
XLEN
|
XLEN
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,64 @@ InsructionSet RV32CI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InsructionSet RV32CF extends RV32CI {
|
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 {
|
||||||
|
val upper[FLEN] <= (-1<<31);
|
||||||
|
F[rd_idx] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
val upper[FLEN] <= (-1<<31);
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InsructionSet RV32DC extends RV32IC{
|
||||||
constants {
|
constants {
|
||||||
XLEN, FLEN
|
XLEN, FLEN
|
||||||
}
|
}
|
||||||
|
@ -212,31 +269,19 @@ InsructionSet RV32CF extends RV32CI {
|
||||||
C.FLD { //(RV32/64)
|
C.FLD { //(RV32/64)
|
||||||
encoding: b001 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00;
|
encoding: b001 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rd[2:0] | b00;
|
||||||
}
|
}
|
||||||
C.FLW {//(RV32)
|
|
||||||
encoding: b011 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rd[2:0] | b00;
|
|
||||||
}
|
|
||||||
C.FSD { //(RV32/64)
|
C.FSD { //(RV32/64)
|
||||||
encoding: b101 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00;
|
encoding: b101 | uimm[5:3] | rs1[2:0] | uimm[7:6] | rs2[2:0] | b00;
|
||||||
}
|
}
|
||||||
C.FSW {//(RV32)
|
|
||||||
encoding: b111 | uimm[5:3] | rs1[2:0] | uimm[2:2] | uimm[6:6] | rs2[2:0] | b00;
|
|
||||||
}
|
|
||||||
C.FLDSP {//(RV32/64)
|
C.FLDSP {//(RV32/64)
|
||||||
encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10;
|
encoding:b001 | uimm[5:5] | rd[4:0] | uimm[4:3] | uimm[8:6] | b10;
|
||||||
}
|
}
|
||||||
C.FLWSP {//RV32
|
|
||||||
encoding:b011 | uimm[5:5] | rd[4:0] | uimm[4:2] | uimm[7:6] | b10;
|
|
||||||
}
|
|
||||||
C.FSDSP {//(RV32/64)
|
C.FSDSP {//(RV32/64)
|
||||||
encoding:b101 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10;
|
encoding:b101 | uimm[5:3] | uimm[8:6] | rs2[4:0] | b10;
|
||||||
}
|
}
|
||||||
C.FSWSP {//(RV32)
|
|
||||||
encoding:b111 | uimm[5:2] | uimm[7:6] | rs2[4:0] | b10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InsructionSet RV64CI extends RV32CI {
|
InsructionSet RV64IC extends RV32IC {
|
||||||
constants {
|
constants {
|
||||||
XLEN
|
XLEN
|
||||||
}
|
}
|
||||||
|
@ -284,7 +329,7 @@ InsructionSet RV64CI extends RV32CI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InsructionSet RV128CI extends RV64CI {
|
InsructionSet RV128IC extends RV64IC {
|
||||||
constants {
|
constants {
|
||||||
XLEN
|
XLEN
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,104 +2,293 @@ import "RV32IBase.core_desc"
|
||||||
|
|
||||||
InsructionSet RV32F extends RV32IBase{
|
InsructionSet RV32F extends RV32IBase{
|
||||||
constants {
|
constants {
|
||||||
FLEN, fcsr
|
FLEN, FFLAG_MASK
|
||||||
}
|
}
|
||||||
registers {
|
registers {
|
||||||
[31:0] F[FLEN]
|
[31:0] F[FLEN], FCSR[32]
|
||||||
}
|
}
|
||||||
instructions{
|
instructions{
|
||||||
FLW {
|
FLW {
|
||||||
encoding: imm[11:0]s | rs1[4:0] | b010 | rd[4:0] | b0000111;
|
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 offs[XLEN] <= X[rs1]+imm;
|
||||||
F[rd]<=MEM[offs];
|
val res[32] <= MEM[offs]{32};
|
||||||
|
if(FLEN==32)
|
||||||
|
F[rd] <= res;
|
||||||
|
else {
|
||||||
|
val upper[FLEN] <= (-1<<31);
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FSW {
|
FSW {
|
||||||
encoding: imm[11:5]s | rs2[4:0] | rs1[4:0] | b010 | imm[4:0]s | b0100111;
|
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;
|
val offs[XLEN] <= X[rs1]+imm;
|
||||||
MEM[offs]<=F[rs2];
|
MEM[offs]{32}<=F[rs2]{32};
|
||||||
}
|
}
|
||||||
FMADD.S {
|
FMADD.S {
|
||||||
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011;
|
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000011;
|
||||||
F[rd]f<= F[rs1]f * F[rs2]f * F[rs3]f;
|
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 {
|
||||||
|
val upper[FLEN] <= (-1<<31);
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
}
|
}
|
||||||
FMSUB.S {
|
FMSUB.S {
|
||||||
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111;
|
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1000111;
|
||||||
F[rd]f<=F[rs1]f * F[rs2]f -F[rs3]f;
|
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 {
|
||||||
|
val upper[FLEN] <= (-1<<31);
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
}
|
}
|
||||||
FNMSUB.S {
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011;
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
F[rd]f<=-F[rs1]f * F[rs2]f- F[rs3]f;
|
|
||||||
}
|
}
|
||||||
FNMADD.S {
|
FNMADD.S {
|
||||||
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111;
|
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001111;
|
||||||
F[rd]f<=-F[rs1]f*F[rs2]f+F[rs3]f;
|
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 {
|
||||||
|
val upper[FLEN] <= (-1<<31);
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
val upper[FLEN] <= (-1<<31);
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
}
|
}
|
||||||
FADD.S {
|
FADD.S {
|
||||||
encoding: b0000000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
encoding: b0000000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
||||||
F[rd]f <= F[rs1]f + F[rs2]f;
|
args_disass:"x%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 {
|
||||||
|
val upper[FLEN] <= (-1<<31);
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
}
|
}
|
||||||
FSUB.S {
|
FSUB.S {
|
||||||
encoding: b0000100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
encoding: b0000100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
||||||
F[rd]f <= F[rs1]f - F[rs2]f;
|
args_disass:"x%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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
}
|
}
|
||||||
FMUL.S {
|
FMUL.S {
|
||||||
encoding: b0001000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
encoding: b0001000 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
||||||
F[rd]f <= F[rs1]f * F[rs2];
|
args_disass:"x%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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
}
|
}
|
||||||
FDIV.S {
|
FDIV.S {
|
||||||
encoding: b0001100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
encoding: b0001100 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
||||||
F[rd]f <= F[rs1]f / F[rs2]f;
|
args_disass:"x%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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
}
|
}
|
||||||
FSQRT.S {
|
FSQRT.S {
|
||||||
encoding: b0101100 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
encoding: b0101100 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
||||||
F[rd]f<=sqrt(F[rs1]f);
|
args_disass:"x%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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
}
|
}
|
||||||
FSGNJ.S {
|
FSGNJ.S {
|
||||||
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
|
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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FSGNJN.S {
|
FSGNJN.S {
|
||||||
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
|
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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FSGNJX.S {
|
FSGNJX.S {
|
||||||
encoding: b0010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
|
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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FMIN.S {
|
FMIN.S {
|
||||||
encoding: b0010100 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
|
encoding: b0010100 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
|
||||||
F[rd]f<= choose(F[rs1]f<F[rs2]f, F[rs1]f, F[rs2]f);
|
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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
}
|
}
|
||||||
FMAX.S {
|
FMAX.S {
|
||||||
encoding: b0010100 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
|
encoding: b0010100 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
|
||||||
F[rd]f<= choose(F[rs1]f>F[rs2]f, F[rs1]f, F[rs2]f);
|
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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
}
|
}
|
||||||
FCVT.W.S {
|
FCVT.W.S {
|
||||||
encoding: b1100000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
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 {
|
FCVT.WU.S {
|
||||||
encoding: b1100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
encoding: b1100000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
||||||
}
|
args_disass:"x%rd$d, f%rs1$d";
|
||||||
FMV.X.W {
|
X[rd]<= zext(fdispatch_fcvt_s(F[rs1]{32}, zext(1, 32), rm{8}), XLEN);
|
||||||
encoding: b1110000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011;
|
val flags[32] <= fdispatch_fget_flags();
|
||||||
|
FCSR <= (FCSR & ~FFLAG_MASK) + flags{5};
|
||||||
}
|
}
|
||||||
FEQ.S {
|
FEQ.S {
|
||||||
encoding: b1010000 | rs2[4:0] | rs1[4:0] | b010 | rd[4:0] | b1010011;
|
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 {
|
FLT.S {
|
||||||
encoding: b1010000 | rs2[4:0] | rs1[4:0] | b001 | rd[4:0] | b1010011;
|
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 {
|
FLE.S {
|
||||||
encoding: b1010000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b1010011;
|
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 {
|
FCLASS.S {
|
||||||
encoding: b1110000 | b00000 | rs1[4:0] | b001 | rd[4:0] | b1010011;
|
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 {
|
FCVT.S.W {
|
||||||
encoding: b1101000 | b00000 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
FCVT.S.WU {
|
FCVT.S.WU {
|
||||||
encoding: b1101000 | b00001 | rs1[4:0] | rm[2:0] | rd[4:0] | b1010011;
|
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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 {
|
FMV.W.X {
|
||||||
encoding: b1111000 | b00000 | rs1[4:0] | b000 | rd[4:0] | b1010011;
|
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 {
|
||||||
|
val upper[FLEN] <= -1<<31;
|
||||||
|
F[rd] <= upper*2 | X[rs1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -41,9 +41,17 @@ InsructionSet RV32M extends RV32IBase {
|
||||||
encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0110011;
|
encoding: b0000001 | rs2[4:0] | rs1[4:0] | b100 | rd[4:0] | b0110011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
||||||
if(rd != 0){
|
if(rd != 0){
|
||||||
if(X[rs2]!=0)
|
if(X[rs2]!=0){
|
||||||
X[rd] <= sext(X[rs1], 32) / sext(X[rs2], 32);
|
val M1[XLEN] <= -1;
|
||||||
|
val MMIN[XLEN] <= -1<<(XLEN-1);
|
||||||
|
if(X[rs1]s==MMIN's)
|
||||||
|
if(X[rs2]s==M1's)
|
||||||
|
X[rd]<=MMIN;
|
||||||
else
|
else
|
||||||
|
X[rd] <= X[rs1]s / X[rs2]s;
|
||||||
|
else
|
||||||
|
X[rd] <= X[rs1]s / X[rs2]s;
|
||||||
|
}else
|
||||||
X[rd] <= -1;
|
X[rd] <= -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,9 +69,17 @@ InsructionSet RV32M extends RV32IBase {
|
||||||
encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011;
|
encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011;
|
||||||
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
||||||
if(rd != 0){
|
if(rd != 0){
|
||||||
if(X[rs2]!=0)
|
if(X[rs2]!=0) {
|
||||||
|
val M1[XLEN] <= -1;
|
||||||
|
val MMIN[XLEN] <= -1<<(XLEN-1);
|
||||||
|
if(X[rs1]s==MMIN's)
|
||||||
|
if(X[rs2]s==M1's)
|
||||||
|
X[rd] <= 0;
|
||||||
|
else
|
||||||
X[rd] <= sext(X[rs1], 32) % sext(X[rs2], 32);
|
X[rd] <= sext(X[rs1], 32) % sext(X[rs2], 32);
|
||||||
else
|
else
|
||||||
|
X[rd] <= sext(X[rs1], 32) % sext(X[rs2], 32);
|
||||||
|
} else
|
||||||
X[rd] <= X[rs1];
|
X[rd] <= X[rs1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,13 @@ import "RV32IBase.core_desc"
|
||||||
import "RV32M.core_desc"
|
import "RV32M.core_desc"
|
||||||
import "RV32A.core_desc"
|
import "RV32A.core_desc"
|
||||||
import "RV32C.core_desc"
|
import "RV32C.core_desc"
|
||||||
|
import "RV32F.core_desc"
|
||||||
import "RV64IBase.core_desc"
|
import "RV64IBase.core_desc"
|
||||||
//import "RV64M.core_desc"
|
//import "RV64M.core_desc"
|
||||||
import "RV64A.core_desc"
|
import "RV64A.core_desc"
|
||||||
|
|
||||||
|
|
||||||
Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32CI {
|
Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32IC {
|
||||||
template:"vm_riscv.in.cpp";
|
template:"vm_riscv.in.cpp";
|
||||||
constants {
|
constants {
|
||||||
XLEN:=32;
|
XLEN:=32;
|
||||||
|
@ -25,6 +26,25 @@ Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32CI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Core RV32GC provides RV32IBase, RV32M, RV32A, RV32IC, RV32F, RV32FC {
|
||||||
|
constants {
|
||||||
|
XLEN:=32;
|
||||||
|
FLEN:=32;
|
||||||
|
XLEN2:=64;
|
||||||
|
XLEN_BIT_MASK:=0x1f;
|
||||||
|
PCLEN:=32;
|
||||||
|
fence:=0;
|
||||||
|
fencei:=1;
|
||||||
|
fencevmal:=2;
|
||||||
|
fencevmau:=3;
|
||||||
|
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||||
|
MISA_VAL:=0b01000000000101000001000100000001;
|
||||||
|
PGSIZE := 4096; //1 << 12;
|
||||||
|
PGMASK := 4095; //PGSIZE-1
|
||||||
|
FFLAG_MASK:=0x1f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Core RV64IA provides RV64IBase, RV64A, RV32A {
|
Core RV64IA provides RV64IBase, RV64A, RV32A {
|
||||||
template:"vm_riscv.in.cpp";
|
template:"vm_riscv.in.cpp";
|
||||||
|
|
|
@ -100,6 +100,8 @@ struct traits<${coreDef.name.toLowerCase()}> {
|
||||||
|
|
||||||
enum mem_type_e {${allSpaces.collect{s -> s.name}.join(', ')}};
|
enum mem_type_e {${allSpaces.collect{s -> s.name}.join(', ')}};
|
||||||
|
|
||||||
|
constexpr static bool has_fp_regs = ${allRegs.find {it.name=='FCSR'}!= null ?'true':'false'};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ${coreDef.name.toLowerCase()}: public arch_if {
|
struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||||
|
@ -112,8 +114,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||||
${coreDef.name.toLowerCase()}();
|
${coreDef.name.toLowerCase()}();
|
||||||
~${coreDef.name.toLowerCase()}();
|
~${coreDef.name.toLowerCase()}();
|
||||||
|
|
||||||
const std::string core_type_name() const override {return traits<${coreDef.name.toLowerCase()}>::core_type;}
|
|
||||||
|
|
||||||
void reset(uint64_t address=0) override;
|
void reset(uint64_t address=0) override;
|
||||||
|
|
||||||
uint8_t* get_regs_base_ptr() override;
|
uint8_t* get_regs_base_ptr() override;
|
||||||
|
@ -159,8 +159,15 @@ protected:
|
||||||
|
|
||||||
std::array<address_type, 4> addr_mode;
|
std::array<address_type, 4> addr_mode;
|
||||||
|
|
||||||
uint64_t cycles = 0;
|
<%
|
||||||
|
def fcsr = allRegs.find {it.name=='FCSR'}
|
||||||
|
if(fcsr != null) {%>
|
||||||
|
uint${generator.getSize(fcsr)}_t get_fcsr(){return reg.FCSR;}
|
||||||
|
void set_fcsr(uint${generator.getSize(fcsr)}_t val){reg.FCSR = val;}
|
||||||
|
<%} else { %>
|
||||||
|
uint32_t get_fcsr(){return 0;}
|
||||||
|
void set_fcsr(uint32_t val){}
|
||||||
|
<%}%>
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ uint8_t* ${coreDef.name.toLowerCase()}::get_regs_base_ptr(){
|
||||||
return reinterpret_cast<uint8_t*>(®);
|
return reinterpret_cast<uint8_t*>(®);
|
||||||
}
|
}
|
||||||
|
|
||||||
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::v2p(const iss::addr_t& pc) {
|
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &pc) {
|
||||||
return phys_addr_t(pc); // change logical address to physical address
|
return phys_addr_t(pc); // change logical address to physical address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,12 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
|
namespace vm {
|
||||||
|
namespace fp_impl{
|
||||||
|
void add_fp_functions_2_module(llvm::Module *mod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace ${coreDef.name.toLowerCase()} {
|
namespace ${coreDef.name.toLowerCase()} {
|
||||||
using namespace iss::arch;
|
using namespace iss::arch;
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
@ -81,6 +87,11 @@ protected:
|
||||||
return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits()));
|
return llvm::ConstantInt::get(getContext(), llvm::APInt(32, type->getType()->getScalarSizeInBits()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setup_module(llvm::Module* m) override {
|
||||||
|
super::setup_module(m);
|
||||||
|
vm::fp_impl::add_fp_functions_2_module(m);
|
||||||
|
}
|
||||||
|
|
||||||
inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,
|
inline llvm::Value *gen_choose(llvm::Value *cond, llvm::Value *trueVal, llvm::Value *falseVal,
|
||||||
unsigned size) const {
|
unsigned size) const {
|
||||||
return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
|
return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
|
||||||
|
@ -106,6 +117,10 @@ protected:
|
||||||
return this->builder.CreateLoad(get_reg_ptr(i), false);
|
return this->builder.CreateLoad(get_reg_ptr(i), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
llvm::Value* gen_fdispatch(std::string fname, const std::vector<llvm::Value*>& args);
|
||||||
|
|
||||||
|
llvm::Value* gen_dispatch(std::string name, llvm::Value*, llvm::Value*, llvm::Value*);
|
||||||
|
|
||||||
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
||||||
llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
|
llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
|
||||||
this->get_type(traits<ARCH>::XLEN));
|
this->get_type(traits<ARCH>::XLEN));
|
||||||
|
@ -310,7 +325,16 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(llvm::BasicBl
|
||||||
bb, this->trap_blk, 1);
|
bb, this->trap_blk, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ${coreDef.name.toLowerCase()}
|
template<typename ARCH>
|
||||||
|
inline llvm::Value* vm_impl<ARCH>::gen_fdispatch(std::string fname, const std::vector<llvm::Value*>& args) {
|
||||||
|
return this->builder.CreateCall(this->mod->getFunction(fname), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ARCH>
|
||||||
|
inline llvm::Value* vm_impl<ARCH>::gen_dispatch(std::string name, llvm::Value* val1, llvm::Value* val2, llvm::Value* val3) {
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace rv32imacf
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) {
|
std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) {
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include <util/sparse_array.h>
|
#include <util/sparse_array.h>
|
||||||
#include <util/bit_field.h>
|
#include <util/bit_field.h>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace arch {
|
namespace arch {
|
||||||
|
@ -537,6 +538,8 @@ private:
|
||||||
iss::status write_ip(unsigned addr, reg_t val);
|
iss::status write_ip(unsigned addr, reg_t val);
|
||||||
iss::status read_satp(unsigned addr, reg_t &val);
|
iss::status read_satp(unsigned addr, reg_t &val);
|
||||||
iss::status write_satp(unsigned addr, reg_t val);
|
iss::status write_satp(unsigned addr, reg_t val);
|
||||||
|
iss::status read_fcsr(unsigned addr, reg_t& val);
|
||||||
|
iss::status write_fcsr(unsigned addr, reg_t val);
|
||||||
protected:
|
protected:
|
||||||
void check_interrupt();
|
void check_interrupt();
|
||||||
};
|
};
|
||||||
|
@ -579,6 +582,13 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
|
||||||
csr_wr_cb[uie] = &riscv_hart_msu_vp<BASE>::write_ie;
|
csr_wr_cb[uie] = &riscv_hart_msu_vp<BASE>::write_ie;
|
||||||
csr_rd_cb[satp] = &riscv_hart_msu_vp<BASE>::read_satp;
|
csr_rd_cb[satp] = &riscv_hart_msu_vp<BASE>::read_satp;
|
||||||
csr_wr_cb[satp] = &riscv_hart_msu_vp<BASE>::write_satp;
|
csr_wr_cb[satp] = &riscv_hart_msu_vp<BASE>::write_satp;
|
||||||
|
csr_rd_cb[fcsr] = &riscv_hart_msu_vp<BASE>::read_fcsr;
|
||||||
|
csr_wr_cb[fcsr] = &riscv_hart_msu_vp<BASE>::write_fcsr;
|
||||||
|
csr_rd_cb[fflags] = &riscv_hart_msu_vp<BASE>::read_fcsr;
|
||||||
|
csr_wr_cb[fflags] = &riscv_hart_msu_vp<BASE>::write_fcsr;
|
||||||
|
csr_rd_cb[frm] = &riscv_hart_msu_vp<BASE>::read_fcsr;
|
||||||
|
csr_wr_cb[frm] = &riscv_hart_msu_vp<BASE>::write_fcsr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE> std::pair<uint64_t,bool> riscv_hart_msu_vp<BASE>::load_file(std::string name, int type) {
|
template <typename BASE> std::pair<uint64_t,bool> riscv_hart_msu_vp<BASE>::load_file(std::string name, int type) {
|
||||||
|
@ -940,6 +950,39 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_satp(unsigne
|
||||||
update_vm_info();
|
update_vm_info();
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
template<typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_fcsr(unsigned addr, reg_t& val) {
|
||||||
|
switch(addr){
|
||||||
|
case 1: //fflags, 4:0
|
||||||
|
val = bit_sub<0, 5>(this->get_fcsr());
|
||||||
|
break;
|
||||||
|
case 2: // frm, 7:5
|
||||||
|
val = bit_sub<5, 3>(this->get_fcsr());
|
||||||
|
break;
|
||||||
|
case 3: // fcsr
|
||||||
|
val=this->get_fcsr();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return iss::Err;
|
||||||
|
}
|
||||||
|
return iss::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_fcsr(unsigned addr, reg_t val) {
|
||||||
|
switch(addr){
|
||||||
|
case 1: //fflags, 4:0
|
||||||
|
this->set_fcsr( (this->get_fcsr() & 0xffffffe0) | (val&0x1f));
|
||||||
|
break;
|
||||||
|
case 2: // frm, 7:5
|
||||||
|
this->set_fcsr( (this->get_fcsr() & 0xffffff1f) | ((val&0x7)<<5));
|
||||||
|
break;
|
||||||
|
case 3: // fcsr
|
||||||
|
this->set_fcsr(val&0xff);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return iss::Err;
|
||||||
|
}
|
||||||
|
return iss::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename BASE>
|
template <typename BASE>
|
||||||
iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
|
iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
|
||||||
|
@ -1299,4 +1342,5 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::wait_until(uint64_t flags
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* _RISCV_CORE_H_ */
|
#endif /* _RISCV_CORE_H_ */
|
||||||
|
|
|
@ -0,0 +1,278 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2017, MINRES Technologies GmbH
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _RV32GC_H_
|
||||||
|
#define _RV32GC_H_
|
||||||
|
|
||||||
|
#include <iss/arch_if.h>
|
||||||
|
#include <iss/vm_if.h>
|
||||||
|
#include <iss/arch/traits.h>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace iss {
|
||||||
|
namespace arch {
|
||||||
|
|
||||||
|
struct rv32gc;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct traits<rv32gc> {
|
||||||
|
|
||||||
|
constexpr static char const* const core_type = "RV32GC";
|
||||||
|
|
||||||
|
enum constants {XLEN=32, FLEN=32, XLEN2=64, XLEN_BIT_MASK=31, PCLEN=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=1075056897, PGSIZE=4096, PGMASK=4095, FFLAG_MASK=31};
|
||||||
|
|
||||||
|
enum reg_e {
|
||||||
|
X0,
|
||||||
|
X1,
|
||||||
|
X2,
|
||||||
|
X3,
|
||||||
|
X4,
|
||||||
|
X5,
|
||||||
|
X6,
|
||||||
|
X7,
|
||||||
|
X8,
|
||||||
|
X9,
|
||||||
|
X10,
|
||||||
|
X11,
|
||||||
|
X12,
|
||||||
|
X13,
|
||||||
|
X14,
|
||||||
|
X15,
|
||||||
|
X16,
|
||||||
|
X17,
|
||||||
|
X18,
|
||||||
|
X19,
|
||||||
|
X20,
|
||||||
|
X21,
|
||||||
|
X22,
|
||||||
|
X23,
|
||||||
|
X24,
|
||||||
|
X25,
|
||||||
|
X26,
|
||||||
|
X27,
|
||||||
|
X28,
|
||||||
|
X29,
|
||||||
|
X30,
|
||||||
|
X31,
|
||||||
|
PC,
|
||||||
|
F0,
|
||||||
|
F1,
|
||||||
|
F2,
|
||||||
|
F3,
|
||||||
|
F4,
|
||||||
|
F5,
|
||||||
|
F6,
|
||||||
|
F7,
|
||||||
|
F8,
|
||||||
|
F9,
|
||||||
|
F10,
|
||||||
|
F11,
|
||||||
|
F12,
|
||||||
|
F13,
|
||||||
|
F14,
|
||||||
|
F15,
|
||||||
|
F16,
|
||||||
|
F17,
|
||||||
|
F18,
|
||||||
|
F19,
|
||||||
|
F20,
|
||||||
|
F21,
|
||||||
|
F22,
|
||||||
|
F23,
|
||||||
|
F24,
|
||||||
|
F25,
|
||||||
|
F26,
|
||||||
|
F27,
|
||||||
|
F28,
|
||||||
|
F29,
|
||||||
|
F30,
|
||||||
|
F31,
|
||||||
|
FCSR,
|
||||||
|
NUM_REGS,
|
||||||
|
NEXT_PC=NUM_REGS,
|
||||||
|
TRAP_STATE,
|
||||||
|
PENDING_TRAP,
|
||||||
|
MACHINE_STATE,
|
||||||
|
ICOUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
using reg_t = uint32_t;
|
||||||
|
|
||||||
|
using addr_t = uint32_t;
|
||||||
|
|
||||||
|
using code_word_t = uint32_t; //TODO: check removal
|
||||||
|
|
||||||
|
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
|
||||||
|
|
||||||
|
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||||
|
|
||||||
|
constexpr static unsigned reg_bit_width(unsigned r) {
|
||||||
|
constexpr std::array<const uint32_t, 71> RV32GC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}};
|
||||||
|
return RV32GC_reg_size[r];
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static unsigned reg_byte_offset(unsigned r) {
|
||||||
|
constexpr std::array<const uint32_t, 72> RV32GC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256,260,264,268,272,276,280,288}};
|
||||||
|
return RV32GC_reg_byte_offset[r];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
||||||
|
|
||||||
|
enum sreg_flag_e {FLAGS};
|
||||||
|
|
||||||
|
enum mem_type_e {MEM, CSR, FENCE, RES};
|
||||||
|
|
||||||
|
constexpr static bool has_fp_regs = true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rv32gc: public arch_if {
|
||||||
|
|
||||||
|
using virt_addr_t = typename traits<rv32gc>::virt_addr_t;
|
||||||
|
using phys_addr_t = typename traits<rv32gc>::phys_addr_t;
|
||||||
|
using reg_t = typename traits<rv32gc>::reg_t;
|
||||||
|
using addr_t = typename traits<rv32gc>::addr_t;
|
||||||
|
|
||||||
|
rv32gc();
|
||||||
|
~rv32gc();
|
||||||
|
|
||||||
|
void reset(uint64_t address=0) override;
|
||||||
|
|
||||||
|
uint8_t* get_regs_base_ptr() override;
|
||||||
|
/// deprecated
|
||||||
|
void get_reg(short idx, std::vector<uint8_t>& value) override {}
|
||||||
|
void set_reg(short idx, const std::vector<uint8_t>& value) override {}
|
||||||
|
/// deprecated
|
||||||
|
bool get_flag(int flag) override {return false;}
|
||||||
|
void set_flag(int, bool value) override {};
|
||||||
|
/// deprecated
|
||||||
|
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
|
||||||
|
|
||||||
|
uint64_t get_icount() { return reg.icount;}
|
||||||
|
|
||||||
|
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||||
|
if(addr.space != traits<rv32gc>::MEM ||
|
||||||
|
addr.type == iss::address_type::PHYSICAL ||
|
||||||
|
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL){
|
||||||
|
return phys_addr_t(addr.access, addr.space, addr.val&traits<rv32gc>::addr_mask);
|
||||||
|
} else
|
||||||
|
return virt2phys(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
|
||||||
|
|
||||||
|
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct RV32GC_regs {
|
||||||
|
uint32_t X0 = 0;
|
||||||
|
uint32_t X1 = 0;
|
||||||
|
uint32_t X2 = 0;
|
||||||
|
uint32_t X3 = 0;
|
||||||
|
uint32_t X4 = 0;
|
||||||
|
uint32_t X5 = 0;
|
||||||
|
uint32_t X6 = 0;
|
||||||
|
uint32_t X7 = 0;
|
||||||
|
uint32_t X8 = 0;
|
||||||
|
uint32_t X9 = 0;
|
||||||
|
uint32_t X10 = 0;
|
||||||
|
uint32_t X11 = 0;
|
||||||
|
uint32_t X12 = 0;
|
||||||
|
uint32_t X13 = 0;
|
||||||
|
uint32_t X14 = 0;
|
||||||
|
uint32_t X15 = 0;
|
||||||
|
uint32_t X16 = 0;
|
||||||
|
uint32_t X17 = 0;
|
||||||
|
uint32_t X18 = 0;
|
||||||
|
uint32_t X19 = 0;
|
||||||
|
uint32_t X20 = 0;
|
||||||
|
uint32_t X21 = 0;
|
||||||
|
uint32_t X22 = 0;
|
||||||
|
uint32_t X23 = 0;
|
||||||
|
uint32_t X24 = 0;
|
||||||
|
uint32_t X25 = 0;
|
||||||
|
uint32_t X26 = 0;
|
||||||
|
uint32_t X27 = 0;
|
||||||
|
uint32_t X28 = 0;
|
||||||
|
uint32_t X29 = 0;
|
||||||
|
uint32_t X30 = 0;
|
||||||
|
uint32_t X31 = 0;
|
||||||
|
uint32_t PC = 0;
|
||||||
|
uint32_t F0 = 0;
|
||||||
|
uint32_t F1 = 0;
|
||||||
|
uint32_t F2 = 0;
|
||||||
|
uint32_t F3 = 0;
|
||||||
|
uint32_t F4 = 0;
|
||||||
|
uint32_t F5 = 0;
|
||||||
|
uint32_t F6 = 0;
|
||||||
|
uint32_t F7 = 0;
|
||||||
|
uint32_t F8 = 0;
|
||||||
|
uint32_t F9 = 0;
|
||||||
|
uint32_t F10 = 0;
|
||||||
|
uint32_t F11 = 0;
|
||||||
|
uint32_t F12 = 0;
|
||||||
|
uint32_t F13 = 0;
|
||||||
|
uint32_t F14 = 0;
|
||||||
|
uint32_t F15 = 0;
|
||||||
|
uint32_t F16 = 0;
|
||||||
|
uint32_t F17 = 0;
|
||||||
|
uint32_t F18 = 0;
|
||||||
|
uint32_t F19 = 0;
|
||||||
|
uint32_t F20 = 0;
|
||||||
|
uint32_t F21 = 0;
|
||||||
|
uint32_t F22 = 0;
|
||||||
|
uint32_t F23 = 0;
|
||||||
|
uint32_t F24 = 0;
|
||||||
|
uint32_t F25 = 0;
|
||||||
|
uint32_t F26 = 0;
|
||||||
|
uint32_t F27 = 0;
|
||||||
|
uint32_t F28 = 0;
|
||||||
|
uint32_t F29 = 0;
|
||||||
|
uint32_t F30 = 0;
|
||||||
|
uint32_t F31 = 0;
|
||||||
|
uint32_t FCSR = 0;
|
||||||
|
uint32_t NEXT_PC = 0;
|
||||||
|
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0;
|
||||||
|
uint64_t icount = 0;
|
||||||
|
} reg;
|
||||||
|
|
||||||
|
std::array<address_type, 4> addr_mode;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t get_fcsr(){return reg.FCSR;}
|
||||||
|
void set_fcsr(uint32_t val){reg.FCSR = val;}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* _RV32GC_H_ */
|
|
@ -118,6 +118,8 @@ struct traits<rv32imac> {
|
||||||
|
|
||||||
enum mem_type_e {MEM, CSR, FENCE, RES};
|
enum mem_type_e {MEM, CSR, FENCE, RES};
|
||||||
|
|
||||||
|
constexpr static bool has_fp_regs = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rv32imac: public arch_if {
|
struct rv32imac: public arch_if {
|
||||||
|
@ -199,6 +201,10 @@ protected:
|
||||||
|
|
||||||
std::array<address_type, 4> addr_mode;
|
std::array<address_type, 4> addr_mode;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t get_fcsr(){return 0;}
|
||||||
|
void set_fcsr(uint32_t val){}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,8 @@ struct traits<rv64ia> {
|
||||||
|
|
||||||
enum mem_type_e {MEM, CSR, FENCE, RES};
|
enum mem_type_e {MEM, CSR, FENCE, RES};
|
||||||
|
|
||||||
|
constexpr static bool has_fp_regs = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rv64ia: public arch_if {
|
struct rv64ia: public arch_if {
|
||||||
|
@ -199,6 +201,10 @@ protected:
|
||||||
|
|
||||||
std::array<address_type, 4> addr_mode;
|
std::array<address_type, 4> addr_mode;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t get_fcsr(){return 0;}
|
||||||
|
void set_fcsr(uint32_t val){}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,290 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2017, MINRES Technologies GmbH
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// Contributors:
|
||||||
|
// eyck@minres.com - initial API and implementation
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <iss/iss.h>
|
||||||
|
#include <iss/vm_base.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <softfloat.h>
|
||||||
|
#include "internals.h"
|
||||||
|
#include "specialize.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace iss {
|
||||||
|
namespace vm {
|
||||||
|
namespace fp_impl {
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define INT_TYPE(L) Type::getIntNTy(mod->getContext(), L)
|
||||||
|
#define FLOAT_TYPE Type::getFloatTy(mod->getContext())
|
||||||
|
#define DOUBLE_TYPE Type::getDoubleTy(mod->getContext())
|
||||||
|
#define VOID_TYPE Type::getVoidTy(mod->getContext())
|
||||||
|
#define THIS_PTR_TYPE Type::getIntNPtrTy(mod->getContext(), 8)
|
||||||
|
#define FDECLL(NAME, RET, ...) \
|
||||||
|
Function *NAME##_func = CurrentModule->getFunction(#NAME); \
|
||||||
|
if (!NAME##_func) { \
|
||||||
|
std::vector<Type *> NAME##_args{__VA_ARGS__}; \
|
||||||
|
FunctionType *NAME##_type = FunctionType::get(RET, NAME##_args, false); \
|
||||||
|
NAME##_func = Function::Create(NAME##_type, GlobalValue::ExternalLinkage, #NAME, CurrentModule); \
|
||||||
|
NAME##_func->setCallingConv(CallingConv::C); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FDECL(NAME, RET, ...) \
|
||||||
|
std::vector<Type *> NAME##_args{__VA_ARGS__}; \
|
||||||
|
FunctionType *NAME##_type = llvm::FunctionType::get(RET, NAME##_args, false); \
|
||||||
|
mod->getOrInsertFunction(#NAME, NAME##_type);
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
void add_fp_functions_2_module(Module *mod) {
|
||||||
|
FDECL(fget_flags, INT_TYPE(32));
|
||||||
|
FDECL(fadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
|
||||||
|
FDECL(fsub_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
|
||||||
|
FDECL(fmul_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
|
||||||
|
FDECL(fdiv_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
|
||||||
|
FDECL(fsqrt_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
|
||||||
|
FDECL(fcmp_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32));
|
||||||
|
FDECL(fcvt_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
|
||||||
|
FDECL(fmadd_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(8));
|
||||||
|
FDECL(fsel_s, INT_TYPE(32), INT_TYPE(32), INT_TYPE(32), INT_TYPE(32));
|
||||||
|
FDECL(fclass_s, INT_TYPE(32), INT_TYPE(32));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using this_t = uint8_t *;
|
||||||
|
const uint8_t rmm_map[] = {
|
||||||
|
softfloat_round_near_even /*RNE*/,
|
||||||
|
softfloat_round_minMag/*RTZ*/,
|
||||||
|
softfloat_round_min/*RDN*/,
|
||||||
|
softfloat_round_max/*RUP?*/,
|
||||||
|
softfloat_round_near_maxMag /*RMM*/,
|
||||||
|
softfloat_round_max/*RTZ*/,
|
||||||
|
softfloat_round_max/*RTZ*/,
|
||||||
|
softfloat_round_max/*RTZ*/,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint32_t quiet_nan32=0x7fC00000;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
uint32_t fget_flags(){
|
||||||
|
return softfloat_exceptionFlags&0x1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fadd_s(uint32_t v1, uint32_t v2, uint8_t mode) {
|
||||||
|
float32_t v1f{v1},v2f{v2};
|
||||||
|
softfloat_roundingMode=rmm_map[mode&0x7];
|
||||||
|
softfloat_exceptionFlags=0;
|
||||||
|
float32_t r =f32_add(v1f, v2f);
|
||||||
|
return r.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fsub_s(uint32_t v1, uint32_t v2, uint8_t mode) {
|
||||||
|
float32_t v1f{v1},v2f{v2};
|
||||||
|
softfloat_roundingMode=rmm_map[mode&0x7];
|
||||||
|
softfloat_exceptionFlags=0;
|
||||||
|
float32_t r=f32_sub(v1f, v2f);
|
||||||
|
return r.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fmul_s(uint32_t v1, uint32_t v2, uint8_t mode) {
|
||||||
|
float32_t v1f{v1},v2f{v2};
|
||||||
|
softfloat_roundingMode=rmm_map[mode&0x7];
|
||||||
|
softfloat_exceptionFlags=0;
|
||||||
|
float32_t r=f32_mul(v1f, v2f);
|
||||||
|
return r.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fdiv_s(uint32_t v1, uint32_t v2, uint8_t mode) {
|
||||||
|
float32_t v1f{v1},v2f{v2};
|
||||||
|
softfloat_roundingMode=rmm_map[mode&0x7];
|
||||||
|
softfloat_exceptionFlags=0;
|
||||||
|
float32_t r=f32_div(v1f, v2f);
|
||||||
|
return r.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fsqrt_s(uint32_t v1, uint8_t mode) {
|
||||||
|
float32_t v1f{v1};
|
||||||
|
softfloat_roundingMode=rmm_map[mode&0x7];
|
||||||
|
softfloat_exceptionFlags=0;
|
||||||
|
float32_t r=f32_sqrt(v1f);
|
||||||
|
return r.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fcmp_s(uint32_t v1, uint32_t v2, uint32_t op) {
|
||||||
|
float32_t v1f{v1},v2f{v2};
|
||||||
|
softfloat_exceptionFlags=0;
|
||||||
|
bool nan = (v1&defaultNaNF32UI)==quiet_nan32 || (v2&defaultNaNF32UI)==quiet_nan32;
|
||||||
|
bool snan = softfloat_isSigNaNF32UI(v1) || softfloat_isSigNaNF32UI(v2);
|
||||||
|
switch(op){
|
||||||
|
case 0:
|
||||||
|
if(nan | snan){
|
||||||
|
if(snan) softfloat_raiseFlags(softfloat_flag_invalid);
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
return f32_eq(v1f,v2f )?1:0;
|
||||||
|
case 1:
|
||||||
|
if(nan | snan){
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid);
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
return f32_le(v1f,v2f )?1:0;
|
||||||
|
case 2:
|
||||||
|
if(nan | snan){
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid);
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
return f32_lt(v1f,v2f )?1:0;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fcvt_s(uint32_t v1, uint32_t op, uint8_t mode) {
|
||||||
|
float32_t v1f{v1};
|
||||||
|
softfloat_exceptionFlags=0;
|
||||||
|
float32_t r;
|
||||||
|
int32_t res;
|
||||||
|
switch(op){
|
||||||
|
case 0: //w->s, fp to int32
|
||||||
|
res = f32_to_i32(v1f,rmm_map[mode&0x7],true);
|
||||||
|
return (uint32_t)res;
|
||||||
|
case 1: //wu->s
|
||||||
|
return f32_to_ui32(v1f,rmm_map[mode&0x7],true);
|
||||||
|
case 2: //s->w
|
||||||
|
r=i32_to_f32(v1);
|
||||||
|
return r.v;
|
||||||
|
case 3: //s->wu
|
||||||
|
r=ui32_to_f32(v1);
|
||||||
|
return r.v;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fmadd_s(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mode) {
|
||||||
|
// op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)}
|
||||||
|
softfloat_roundingMode=rmm_map[mode&0x7];
|
||||||
|
softfloat_exceptionFlags=0;
|
||||||
|
float32_t res = softfloat_mulAddF32(v1, v2, v3, op&0x1);
|
||||||
|
if(op>1) res.v ^= 0x80000000UL;
|
||||||
|
return res.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fsel_s(uint32_t v1, uint32_t v2, uint32_t op) {
|
||||||
|
softfloat_exceptionFlags = 0;
|
||||||
|
bool v1_nan = (v1 & defaultNaNF32UI) == quiet_nan32;
|
||||||
|
bool v2_nan = (v2 & defaultNaNF32UI) == quiet_nan32;
|
||||||
|
bool v1_snan = softfloat_isSigNaNF32UI(v1);
|
||||||
|
bool v2_snan = softfloat_isSigNaNF32UI(v2);
|
||||||
|
if (v1_snan || v2_snan) softfloat_raiseFlags(softfloat_flag_invalid);
|
||||||
|
if (v1_nan || v1_snan)
|
||||||
|
return (v2_nan || v2_snan) ? defaultNaNF32UI : v2;
|
||||||
|
else
|
||||||
|
if (v2_nan || v2_snan)
|
||||||
|
return v1;
|
||||||
|
else {
|
||||||
|
if ((v1 & 0x7fffffff) == 0 && (v2 & 0x7fffffff) == 0) {
|
||||||
|
return op == 0 ? ((v1 & 0x80000000) ? v1 : v2) : ((v1 & 0x80000000) ? v2 : v1);
|
||||||
|
} else {
|
||||||
|
float32_t v1f{ v1 }, v2f{ v2 };
|
||||||
|
return op == 0 ? (f32_lt(v1f, v2f) ? v1 : v2) : (f32_lt(v1f, v2f) ? v2 : v1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fclass_s( uint32_t v1 ){
|
||||||
|
|
||||||
|
float32_t a{v1};
|
||||||
|
union ui32_f32 uA;
|
||||||
|
uint_fast32_t uiA;
|
||||||
|
|
||||||
|
uA.f = a;
|
||||||
|
uiA = uA.ui;
|
||||||
|
|
||||||
|
uint_fast16_t infOrNaN = expF32UI( uiA ) == 0xFF;
|
||||||
|
uint_fast16_t subnormalOrZero = expF32UI( uiA ) == 0;
|
||||||
|
bool sign = signF32UI( uiA );
|
||||||
|
bool fracZero = fracF32UI( uiA ) == 0;
|
||||||
|
bool isNaN = isNaNF32UI( uiA );
|
||||||
|
bool isSNaN = softfloat_isSigNaNF32UI( uiA );
|
||||||
|
|
||||||
|
return
|
||||||
|
( sign && infOrNaN && fracZero ) << 0 |
|
||||||
|
( sign && !infOrNaN && !subnormalOrZero ) << 1 |
|
||||||
|
( sign && subnormalOrZero && !fracZero ) << 2 |
|
||||||
|
( sign && subnormalOrZero && fracZero ) << 3 |
|
||||||
|
( !sign && infOrNaN && fracZero ) << 7 |
|
||||||
|
( !sign && !infOrNaN && !subnormalOrZero ) << 6 |
|
||||||
|
( !sign && subnormalOrZero && !fracZero ) << 5 |
|
||||||
|
( !sign && subnormalOrZero && fracZero ) << 4 |
|
||||||
|
( isNaN && isSNaN ) << 8 |
|
||||||
|
( isNaN && !isSNaN ) << 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t fclass_d(uint64_t v1 ){
|
||||||
|
|
||||||
|
float64_t a{v1};
|
||||||
|
union ui64_f64 uA;
|
||||||
|
uint_fast64_t uiA;
|
||||||
|
|
||||||
|
uA.f = a;
|
||||||
|
uiA = uA.ui;
|
||||||
|
|
||||||
|
uint_fast16_t infOrNaN = expF64UI( uiA ) == 0x7FF;
|
||||||
|
uint_fast16_t subnormalOrZero = expF64UI( uiA ) == 0;
|
||||||
|
bool sign = signF64UI( uiA );
|
||||||
|
bool fracZero = fracF64UI( uiA ) == 0;
|
||||||
|
bool isNaN = isNaNF64UI( uiA );
|
||||||
|
bool isSNaN = softfloat_isSigNaNF64UI( uiA );
|
||||||
|
|
||||||
|
return
|
||||||
|
( sign && infOrNaN && fracZero ) << 0 |
|
||||||
|
( sign && !infOrNaN && !subnormalOrZero ) << 1 |
|
||||||
|
( sign && subnormalOrZero && !fracZero ) << 2 |
|
||||||
|
( sign && subnormalOrZero && fracZero ) << 3 |
|
||||||
|
( !sign && infOrNaN && fracZero ) << 7 |
|
||||||
|
( !sign && !infOrNaN && !subnormalOrZero ) << 6 |
|
||||||
|
( !sign && subnormalOrZero && !fracZero ) << 5 |
|
||||||
|
( !sign && subnormalOrZero && fracZero ) << 4 |
|
||||||
|
( isNaN && isSNaN ) << 8 |
|
||||||
|
( isNaN && !isSNaN ) << 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,74 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2017, MINRES Technologies GmbH
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "util/ities.h"
|
||||||
|
#include <util/logging.h>
|
||||||
|
|
||||||
|
#include <elfio/elfio.hpp>
|
||||||
|
#include <iss/arch/rv32gc.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
#include <ihex.h>
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#include <fstream>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace iss::arch;
|
||||||
|
|
||||||
|
rv32gc::rv32gc() {
|
||||||
|
reg.icount=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rv32gc::~rv32gc(){
|
||||||
|
}
|
||||||
|
|
||||||
|
void rv32gc::reset(uint64_t address) {
|
||||||
|
for(size_t i=0; i<traits<rv32gc>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<rv32gc>::reg_t),0));
|
||||||
|
reg.PC=address;
|
||||||
|
reg.NEXT_PC=reg.PC;
|
||||||
|
reg.trap_state=0;
|
||||||
|
reg.machine_state=0x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* rv32gc::get_regs_base_ptr(){
|
||||||
|
return reinterpret_cast<uint8_t*>(®);
|
||||||
|
}
|
||||||
|
|
||||||
|
rv32gc::phys_addr_t rv32gc::virt2phys(const iss::addr_t &pc) {
|
||||||
|
return phys_addr_t(pc); // change logical address to physical address
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
#include <iss/arch/riscv_hart_msu_vp.h>
|
#include <iss/arch/riscv_hart_msu_vp.h>
|
||||||
#include <iss/arch/rv32imac.h>
|
#include <iss/arch/rv32imac.h>
|
||||||
|
#include <iss/arch/rv32gc.h>
|
||||||
#include <iss/arch/rv64ia.h>
|
#include <iss/arch/rv64ia.h>
|
||||||
#include <iss/jit/MCJIThelper.h>
|
#include <iss/jit/MCJIThelper.h>
|
||||||
#include <iss/log_categories.h>
|
#include <iss/log_categories.h>
|
||||||
|
@ -103,15 +104,19 @@ int main(int argc, char *argv[]) {
|
||||||
// instantiate the simulator
|
// instantiate the simulator
|
||||||
std::unique_ptr<iss::vm_if> vm{nullptr};
|
std::unique_ptr<iss::vm_if> vm{nullptr};
|
||||||
std::string isa_opt(clim["isa"].as<std::string>());
|
std::string isa_opt(clim["isa"].as<std::string>());
|
||||||
iss::plugin::instruction_count ic_plugin("riscv/gen_input/src-gen/rv32imac_cyles.txt");
|
// iss::plugin::instruction_count ic_plugin("riscv/gen_input/src-gen/rv32imac_cyles.txt");
|
||||||
iss::plugin::cycle_estimate ce_plugin("riscv/gen_input/src-gen/rv32imac_cyles.txt");
|
// iss::plugin::cycle_estimate ce_plugin("riscv/gen_input/src-gen/rv32imac_cyles.txt");
|
||||||
if (isa_opt.substr(0, 4)=="rv64") {
|
if (isa_opt.substr(0, 4)=="rv64") {
|
||||||
iss::arch::rv64ia* cpu = new iss::arch::riscv_hart_msu_vp<iss::arch::rv64ia>();
|
iss::arch::rv64ia* cpu = new iss::arch::riscv_hart_msu_vp<iss::arch::rv64ia>();
|
||||||
vm = iss::create(cpu, clim["gdb-port"].as<unsigned>());
|
vm = iss::create(cpu, clim["gdb-port"].as<unsigned>());
|
||||||
} else if (isa_opt.substr(0, 4)=="rv32") {
|
} else if (isa_opt.substr(0, 5)=="rv32i") {
|
||||||
iss::arch::rv32imac* cpu = new iss::arch::riscv_hart_msu_vp<iss::arch::rv32imac>();
|
iss::arch::rv32imac* cpu = new iss::arch::riscv_hart_msu_vp<iss::arch::rv32imac>();
|
||||||
vm = iss::create(cpu, clim["gdb-port"].as<unsigned>());
|
vm = iss::create(cpu, clim["gdb-port"].as<unsigned>());
|
||||||
//vm->register_plugin(ce_plugin);
|
//vm->register_plugin(ce_plugin);
|
||||||
|
} else if (isa_opt.substr(0, 5)=="rv32g") {
|
||||||
|
iss::arch::rv32gc* cpu = new iss::arch::riscv_hart_msu_vp<iss::arch::rv32gc>();
|
||||||
|
vm = iss::create(cpu, clim["gdb-port"].as<unsigned>());
|
||||||
|
//vm->register_plugin(ce_plugin);
|
||||||
} else {
|
} else {
|
||||||
LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;
|
LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;
|
||||||
return 127;
|
return 127;
|
||||||
|
|
Loading…
Reference in New Issue