diff --git a/src/PseudoOps.txt b/src/PseudoOps.txt index 2ee5e98b..9df2d996 100644 --- a/src/PseudoOps.txt +++ b/src/PseudoOps.txt @@ -252,6 +252,8 @@ fcvt.d.wu f1, t1 ; fcvt.d.wu RG1, RG2, dyn ;#Convert double from fcvt.d.w f1, t1 ; fcvt.d.w RG1, RG2, dyn ;#Convert double from signed integer: Assigns the value of t1 to f1 fcvt.w.d t1, f1 ; fcvt.w.d RG1, RG2, dyn ;#Convert signed integer from double: Assigns the value of f1 (rounded) to t1 fcvt.wu.d t1, f1 ; fcvt.wu.d RG1, RG2, dyn ;#Convert unsigned integer from double: Assigns the value of f1 (rounded) to t1 +fcvt.s.d f1, f2 ; fcvt.s.d RG1, RG2, dyn ;#Convert double to float: Assigned the value of f2 to f1 +fcvt.d.s f1, f2 ; fcvt.d.s RG1, RG2 , dyn ;#Convert float to double: Assigned the value of f2 to f1 ### TODO: maybe it makes sense to rename the instructions and flip these pseudo-instructions fmv.x.w t1, f1 ; fmv.x.s RG1, RG2 ;#Move float (New mnemonic): move bits representing a float to an integer register diff --git a/src/rars/riscv/instructions/FCVTDS.java b/src/rars/riscv/instructions/FCVTDS.java new file mode 100644 index 00000000..7385235e --- /dev/null +++ b/src/rars/riscv/instructions/FCVTDS.java @@ -0,0 +1,28 @@ +package rars.riscv.instructions; + +import jsoftfloat.Environment; +import jsoftfloat.types.Float32; +import jsoftfloat.types.Float64; +import rars.ProgramStatement; +import rars.SimulationException; +import rars.riscv.BasicInstruction; +import rars.riscv.BasicInstructionFormat; +import rars.riscv.hardware.FloatingPointRegisterFile; + +public class FCVTDS extends BasicInstruction { + public FCVTDS() { + super("fcvt.d.s t1, f1, dyn", "Convert a float to a double: Assigned the value of f2 to f1", + BasicInstructionFormat.R4_FORMAT,"0100001 00000 sssss ttt fffff 1010011"); + } + + public void simulate(ProgramStatement statement) throws SimulationException { + int[] operands = statement.getOperands(); + Environment e = new Environment(); + e.mode = Floating.getRoundingMode(operands[3],statement); + Float32 in = new Float32(FloatingPointRegisterFile.getValue(operands[1])); + Float64 out = new Float64(0); + out = FCVTSD.convert(in,out,e); + Floating.setfflags(e); + FloatingPointRegisterFile.updateRegisterLong(operands[0],out.bits); + } +} \ No newline at end of file diff --git a/src/rars/riscv/instructions/FCVTSD.java b/src/rars/riscv/instructions/FCVTSD.java new file mode 100644 index 00000000..45ba4902 --- /dev/null +++ b/src/rars/riscv/instructions/FCVTSD.java @@ -0,0 +1,42 @@ +package rars.riscv.instructions; + +import jsoftfloat.Environment; +import jsoftfloat.types.Float32; +import jsoftfloat.types.Float64; +import rars.ProgramStatement; +import rars.SimulationException; +import rars.riscv.BasicInstruction; +import rars.riscv.BasicInstructionFormat; +import rars.riscv.hardware.FloatingPointRegisterFile; + +public class FCVTSD extends BasicInstruction { + public FCVTSD() { + super("fcvt.s.d t1, f1, dyn", "Convert a double to a float: Assigned the value of f2 to f1", + BasicInstructionFormat.R4_FORMAT,"0100000 00001 sssss ttt fffff 1010011"); + } + + public void simulate(ProgramStatement statement) throws SimulationException { + int[] operands = statement.getOperands(); + Environment e = new Environment(); + e.mode = Floating.getRoundingMode(operands[3],statement); + Float64 in = new Float64(FloatingPointRegisterFile.getValueLong(operands[1])); + Float32 out = new Float32(0); + out = convert(in,out,e); + Floating.setfflags(e); + FloatingPointRegisterFile.updateRegister(operands[0],out.bits); + } + // Kindof a long type, but removes duplicate code and would make it easy for quads to be implemented. + public static ,D extends jsoftfloat.types.Floating> + S convert(D toconvert, S constructor, Environment e){ + if(toconvert.isInfinite()){ + return toconvert.isSignMinus() ? constructor.NegativeInfinity() : constructor.Infinity(); + } + if(toconvert.isZero()){ + return toconvert.isSignMinus() ? constructor.NegativeZero() : constructor.Zero(); + } + if(toconvert.isNaN()){ + return constructor.NaN(); + } + return constructor.fromExactFloat(toconvert.toExactFloat(),e); + } +} \ No newline at end of file diff --git a/src/rars/riscv/instructions/FMVXS.java b/src/rars/riscv/instructions/FMVXS.java index 9fe2482c..095f34e5 100644 --- a/src/rars/riscv/instructions/FMVXS.java +++ b/src/rars/riscv/instructions/FMVXS.java @@ -41,6 +41,6 @@ public FMVXS() { public void simulate(ProgramStatement statement) { int[] operands = statement.getOperands(); - RegisterFile.updateRegister(operands[0], FloatingPointRegisterFile.getValue(operands[1])); + RegisterFile.updateRegister(operands[0], (int)FloatingPointRegisterFile.getValueLong(operands[1])); } } \ No newline at end of file diff --git a/src/rars/riscv/instructions/FSW.java b/src/rars/riscv/instructions/FSW.java index cf0438bb..ed3e8966 100644 --- a/src/rars/riscv/instructions/FSW.java +++ b/src/rars/riscv/instructions/FSW.java @@ -45,7 +45,7 @@ public FSW() { public void simulate(ProgramStatement statement) throws SimulationException { int[] operands = statement.getOperands(); try { - Globals.memory.setWord(RegisterFile.getValue(operands[2]) + operands[1], FloatingPointRegisterFile.getValue(operands[0])); + Globals.memory.setWord(RegisterFile.getValue(operands[2]) + operands[1], (int)FloatingPointRegisterFile.getValueLong(operands[0])); } catch (AddressErrorException e) { throw new SimulationException(statement, e); }