aboutsummaryrefslogtreecommitdiff
path: root/interpreter/riscv64/interpreter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'interpreter/riscv64/interpreter.cc')
-rw-r--r--interpreter/riscv64/interpreter.cc37
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: