diff options
Diffstat (limited to 'interpreter/riscv64/interpreter.cc')
-rw-r--r-- | interpreter/riscv64/interpreter.cc | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/interpreter/riscv64/interpreter.cc b/interpreter/riscv64/interpreter.cc index f4e82fea..a8fcbf61 100644 --- a/interpreter/riscv64/interpreter.cc +++ b/interpreter/riscv64/interpreter.cc @@ -28,10 +28,11 @@ #include "berberis/decoder/riscv64/semantics_player.h" #include "berberis/guest_state/guest_addr.h" #include "berberis/guest_state/guest_state_riscv64.h" -#include "berberis/intrinsics/riscv64/guest_fpstate.h" +#include "berberis/intrinsics/riscv64_to_x86_64/intrinsics_float.h" #include "berberis/kernel_api/run_guest_syscall.h" #include "atomics.h" +#include "fp_regs.h" namespace berberis { @@ -42,6 +43,8 @@ class Interpreter { using Decoder = Decoder<SemanticsPlayer<Interpreter>>; using Register = uint64_t; using FpRegister = uint64_t; + using Float32 = intrinsics::Float32; + using Float64 = intrinsics::Float64; explicit Interpreter(ThreadState* state) : state_(state), branch_taken_(false) {} @@ -352,6 +355,38 @@ class Interpreter { return RunGuestSyscall(syscall_nr, arg0, arg1, arg2, arg3, arg4, arg5); } + FpRegister OpFp(Decoder::OpFpOpcode opcode, + Decoder::FloatSize float_size, + uint8_t rm, + FpRegister arg1, + FpRegister arg2) { + switch (float_size) { + case Decoder::FloatSize::kFloat: + return NanBoxFloatToFPReg(OpFp<Float32>( + opcode, rm, NanUnboxFPRegToFloat<Float32>(arg1), NanUnboxFPRegToFloat<Float32>(arg2))); + case Decoder::FloatSize::kDouble: + return NanBoxFloatToFPReg(OpFp<Float64>( + opcode, rm, NanUnboxFPRegToFloat<Float64>(arg1), NanUnboxFPRegToFloat<Float64>(arg2))); + default: + Unimplemented(); + return {}; + } + } + + // TODO(b/278812060): switch to intrinsics when they would become available and stop using + // ExecuteFloatOperation directly. + template <typename FloatType> + FloatType OpFp(Decoder::OpFpOpcode opcode, uint8_t rm, FloatType arg1, FloatType arg2) { + switch (opcode) { + case Decoder::OpFpOpcode::kFAdd: + return intrinsics::ExecuteFloatOperation<FloatType>( + rm, state_->cpu.frm, [](auto x, auto y) { return x + y; }, arg1, arg2); + default: + Unimplemented(); + return {}; + } + } + Register ShiftImm(Decoder::ShiftImmOpcode opcode, Register arg, uint16_t imm) { switch (opcode) { case Decoder::ShiftImmOpcode::kSlli: |