Added RV32F extension, fixed RV32M bugs
This commit is contained in:
parent
bc7450dad2
commit
48ad30dcae
10
.cproject
10
.cproject
|
@ -13,7 +13,7 @@
|
|||
</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"/>
|
||||
|
@ -46,6 +46,13 @@
|
|||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule buildDir="build/${ConfigName}" moduleId="de.marw.cdt.cmake.core.settings">
|
||||
<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>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.1745230171">
|
||||
|
@ -177,4 +184,5 @@
|
|||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
</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">
|
||||
<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_LOCATION" value="/usr/lib/jvm/java-8-oracle/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_WORKING_DIRECTORY" value="${workspace_loc:/dbt-riscv}/riscv/gen_input"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="/usr/bin/java"/>
|
||||
<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-RISE-RISCV}/riscv/gen_input"/>
|
||||
</launchConfiguration>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import "RV32IBase.core_desc"
|
||||
|
||||
InsructionSet RV32CI {
|
||||
InsructionSet RV32IC {
|
||||
constants {
|
||||
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 {
|
||||
XLEN, FLEN
|
||||
}
|
||||
|
@ -212,31 +269,19 @@ InsructionSet RV32CF extends RV32CI {
|
|||
C.FLD { //(RV32/64)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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 {
|
||||
XLEN
|
||||
}
|
||||
|
@ -284,7 +329,7 @@ InsructionSet RV64CI extends RV32CI {
|
|||
}
|
||||
}
|
||||
|
||||
InsructionSet RV128CI extends RV64CI {
|
||||
InsructionSet RV128IC extends RV64IC {
|
||||
constants {
|
||||
XLEN
|
||||
}
|
||||
|
|
|
@ -2,104 +2,293 @@ import "RV32IBase.core_desc"
|
|||
|
||||
InsructionSet RV32F extends RV32IBase{
|
||||
constants {
|
||||
FLEN, fcsr
|
||||
FLEN, FFLAG_MASK
|
||||
}
|
||||
registers {
|
||||
[31:0] F[FLEN]
|
||||
[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;
|
||||
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 {
|
||||
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]<=F[rs2];
|
||||
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;
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
FNMSUB.S {
|
||||
encoding: rs3[4:0] | b00 | rs2[4:0] | rs1[4:0] | rm[2:0] | rd[4:0] | b1001011;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
FMV.X.W {
|
||||
encoding: b1110000 | b00000 | rs1[4:0] | b000 | 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 {
|
||||
val upper[FLEN] <= -1<<31;
|
||||
F[rd] <= upper*2 | res;
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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 {
|
||||
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;
|
||||
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
||||
if(rd != 0){
|
||||
if(X[rs2]!=0)
|
||||
X[rd] <= sext(X[rs1], 32) / sext(X[rs2], 32);
|
||||
else
|
||||
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]<=MMIN;
|
||||
else
|
||||
X[rd] <= X[rs1]s / X[rs2]s;
|
||||
else
|
||||
X[rd] <= X[rs1]s / X[rs2]s;
|
||||
}else
|
||||
X[rd] <= -1;
|
||||
}
|
||||
}
|
||||
|
@ -61,9 +69,17 @@ InsructionSet RV32M extends RV32IBase {
|
|||
encoding: b0000001 | rs2[4:0] | rs1[4:0] | b110 | rd[4:0] | b0110011;
|
||||
args_disass:"x%rd$d, x%rs1$d, x%rs2$d";
|
||||
if(rd != 0){
|
||||
if(X[rs2]!=0)
|
||||
X[rd] <= sext(X[rs1], 32) % sext(X[rs2], 32);
|
||||
else
|
||||
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);
|
||||
else
|
||||
X[rd] <= sext(X[rs1], 32) % sext(X[rs2], 32);
|
||||
} else
|
||||
X[rd] <= X[rs1];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,13 @@ import "RV32IBase.core_desc"
|
|||
import "RV32M.core_desc"
|
||||
import "RV32A.core_desc"
|
||||
import "RV32C.core_desc"
|
||||
import "RV32F.core_desc"
|
||||
import "RV64IBase.core_desc"
|
||||
//import "RV64M.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";
|
||||
constants {
|
||||
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 {
|
||||
template:"vm_riscv.in.cpp";
|
||||
|
|
|
@ -100,6 +100,8 @@ struct traits<${coreDef.name.toLowerCase()}> {
|
|||
|
||||
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 {
|
||||
|
@ -112,8 +114,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
|
|||
${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;
|
||||
|
||||
uint8_t* get_regs_base_ptr() override;
|
||||
|
@ -158,9 +158,16 @@ protected:
|
|||
} reg;
|
||||
|
||||
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*>(®);
|
||||
}
|
||||
|
||||
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::v2p(const iss::addr_t& pc) {
|
||||
return phys_addr_t(pc); //change logical address to physical address
|
||||
${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
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,12 @@
|
|||
#include <array>
|
||||
|
||||
namespace iss {
|
||||
namespace vm {
|
||||
namespace fp_impl{
|
||||
void add_fp_functions_2_module(llvm::Module *mod);
|
||||
}
|
||||
}
|
||||
|
||||
namespace ${coreDef.name.toLowerCase()} {
|
||||
using namespace iss::arch;
|
||||
using namespace llvm;
|
||||
|
@ -81,6 +87,11 @@ protected:
|
|||
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,
|
||||
unsigned size) const {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
llvm::Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
|
||||
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);
|
||||
}
|
||||
|
||||
} // 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 <>
|
||||
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/bit_field.h>
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
|
||||
namespace iss {
|
||||
namespace arch {
|
||||
|
@ -537,6 +538,8 @@ private:
|
|||
iss::status write_ip(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 read_fcsr(unsigned addr, reg_t& val);
|
||||
iss::status write_fcsr(unsigned addr, reg_t val);
|
||||
protected:
|
||||
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_rd_cb[satp] = &riscv_hart_msu_vp<BASE>::read_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) {
|
||||
|
@ -940,6 +950,39 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_satp(unsigne
|
|||
update_vm_info();
|
||||
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>
|
||||
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_ */
|
||||
|
|
|
@ -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};
|
||||
|
||||
constexpr static bool has_fp_regs = false;
|
||||
|
||||
};
|
||||
|
||||
struct rv32imac: public arch_if {
|
||||
|
@ -198,6 +200,10 @@ protected:
|
|||
} reg;
|
||||
|
||||
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};
|
||||
|
||||
constexpr static bool has_fp_regs = false;
|
||||
|
||||
};
|
||||
|
||||
struct rv64ia: public arch_if {
|
||||
|
@ -198,6 +200,10 @@ protected:
|
|||
} reg;
|
||||
|
||||
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 <iss/arch/riscv_hart_msu_vp.h>
|
||||
#include <iss/arch/rv32imac.h>
|
||||
#include <iss/arch/rv32gc.h>
|
||||
#include <iss/arch/rv64ia.h>
|
||||
#include <iss/jit/MCJIThelper.h>
|
||||
#include <iss/log_categories.h>
|
||||
|
@ -103,15 +104,19 @@ int main(int argc, char *argv[]) {
|
|||
// instantiate the simulator
|
||||
std::unique_ptr<iss::vm_if> vm{nullptr};
|
||||
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::cycle_estimate ce_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");
|
||||
if (isa_opt.substr(0, 4)=="rv64") {
|
||||
iss::arch::rv64ia* cpu = new iss::arch::riscv_hart_msu_vp<iss::arch::rv64ia>();
|
||||
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>();
|
||||
vm = iss::create(cpu, clim["gdb-port"].as<unsigned>());
|
||||
//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 {
|
||||
LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as<std::string>() << std::endl;
|
||||
return 127;
|
||||
|
|
Loading…
Reference in New Issue