// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cstdint>

#include "mpact/sim/generic/type_helpers.h"
#include "riscv/riscv_fp_host.h"
#include "riscv/riscv_fp_info.h"
#include "riscv/riscv_fp_state.h"

// This file implements the x86 versions of the methods/classes that interact
// with the host floating point hw.

namespace mpact {
namespace sim {
namespace riscv {

using ::mpact::sim::generic::operator*;  // NOLINT: is used below (clang error).

// x86 flags.
constexpr uint8_t kPE = 32;  // Inexact result
constexpr uint8_t kUE = 16;  // Underflow
constexpr uint8_t kOE = 8;   // Overflow
constexpr uint8_t kZE = 4;   // Divide by zero
constexpr uint8_t kIE = 1;   // Illegal operation

// RiscV flags.
constexpr uint8_t kNV = static_cast<uint8_t>(FPExceptions::kInvalidOp);
constexpr uint8_t kDZ = static_cast<uint8_t>(FPExceptions::kDivByZero);
constexpr uint8_t kOF = static_cast<uint8_t>(FPExceptions::kOverflow);
constexpr uint8_t kUF = static_cast<uint8_t>(FPExceptions::kUnderflow);
constexpr uint8_t kNX = static_cast<uint8_t>(FPExceptions::kInexact);

// This map converts the x86 fp flags to RiscV fp flags. The x86 layout is:
// PE, UE, OE, ZE, DE, IE, whereas the RiscV layout is
//     IE, ZE, OE, UE, PE  (RiscV terminology: NV, DZ, OF, UF, NX)
// The x86 DE flag bit is not used.
constexpr uint8_t kX86FlagsToRiscvMap[64] = {0,
                                             kNV,
                                             0,
                                             kNV,
                                             kDZ,
                                             kDZ | kNV,
                                             kDZ,
                                             kNV | kDZ,
                                             kOF,
                                             kOF | kNV,
                                             kOF,
                                             kOF | kNV,
                                             kOF | kDZ,
                                             kOF | kDZ | kNV,
                                             kOF | kDZ,
                                             kOF | kDZ | kNV,
                                             kUF,
                                             kUF | kNV,
                                             kUF,
                                             kUF | kNV,
                                             kUF | kDZ,
                                             kUF | kDZ | kNV,
                                             kUF | kDZ,
                                             kUF | kDZ | kNV,
                                             kUF | kOF,
                                             kUF | kOF | kNV,
                                             kUF | kOF,
                                             kUF | kOF | kNV,
                                             kUF | kOF | kDZ,
                                             kUF | kOF | kDZ | kNV,
                                             kUF | kOF | kDZ,
                                             kUF | kOF | kDZ | kNV,
                                             kNX,
                                             kNX | kNV,
                                             kNX,
                                             kNX | kNV,
                                             kNX | kDZ,
                                             kNX | kDZ | kNV,
                                             kNX | kDZ,
                                             kNX | kNV | kDZ,
                                             kNX | kOF,
                                             kNX | kOF | kNV,
                                             kNX | kOF,
                                             kNX | kOF | kNV,
                                             kNX | kOF | kDZ,
                                             kNX | kOF | kDZ | kNV,
                                             kNX | kOF | kDZ,
                                             kNX | kOF | kDZ | kNV,
                                             kNX | kUF,
                                             kNX | kUF | kNV,
                                             kNX | kUF,
                                             kNX | kUF | kNV,
                                             kNX | kUF | kDZ,
                                             kNX | kUF | kDZ | kNV,
                                             kNX | kUF | kDZ,
                                             kNX | kUF | kDZ | kNV,
                                             kNX | kUF | kOF,
                                             kNX | kUF | kOF | kNV,
                                             kNX | kUF | kOF,
                                             kNX | kUF | kOF | kNV,
                                             kNX | kUF | kOF | kDZ,
                                             kNX | kUF | kOF | kDZ | kNV,
                                             kNX | kUF | kOF | kDZ,
                                             kNX | kUF | kOF | kDZ | kNV};

// This map converts RiscV flags to x86 flags.
// The RiscV layout is PE
constexpr uint8_t kRiscVFlagsToX86[32]{
    0,
    kPE,
    kUE,
    kUE | kPE,
    kOE,
    kOE | kPE,
    kOE | kUE,
    kOE | kUE | kPE,
    kZE,
    kZE | kPE,
    kZE | kUE,
    kZE | kUE | kPE,
    kZE | kOE,
    kZE | kOE | kPE,
    kZE | kOE | kUE,
    kZE | kOE | kUE | kPE,
    kIE,
    kIE | kPE,
    kIE | kUE,
    kIE | kUE | kPE,
    kIE | kOE,
    kIE | kOE | kPE,
    kIE | kOE | kUE,
    kIE | kOE | kUE | kPE,
    kIE | kZE,
    kIE | kZE | kPE,
    kIE | kZE | kUE,
    kIE | kZE | kUE | kPE,
    kIE | kZE | kOE,
    kIE | kZE | kOE | kPE,
    kIE | kZE | kOE | kUE,
    kIE | kZE | kOE | kUE | kPE,
};

constexpr uint32_t kX86ToNearest = 0x0000;
constexpr uint32_t kX86ToNegInf = 0x2000;
constexpr uint32_t kX86ToPosInf = 0x4000;
constexpr uint32_t kX86ToZero = 0x6000;

constexpr uint32_t kRiscVToX86RoundingModeMap[8] = {
    kX86ToNearest, kX86ToZero,    kX86ToNegInf,  kX86ToPosInf,
    kX86ToNearest, kX86ToNearest, kX86ToNearest, kX86ToNearest,
};

// Map from x86 rounding mode to RiscV rounding mode.
static constexpr FPRoundingMode kX86ToRiscVRoundingModeMap[] = {
    FPRoundingMode::kRoundToNearest, FPRoundingMode::kRoundDown,
    FPRoundingMode::kRoundUp, FPRoundingMode::kRoundTowardsZero};

static constexpr uint32_t kX86ExceptionFlags = 0x1f80;

// This class provides the translations between RiscV and x86 floating point
// state. It also stores the x86 version of the simulated RISCV state
// between uses in simulated floating point instructions.
class X86FloatingPointInterface : public HostFloatingPointInterface {
 public:
  X86FloatingPointInterface() = default;
  ~X86FloatingPointInterface() override = default;

  uint32_t GetRiscVFcsr() override {
    auto x86_rm = (x86_status_ >> 13) & 0x3;
    uint32_t rm = *kX86ToRiscVRoundingModeMap[x86_rm];
    uint32_t flags = kX86FlagsToRiscvMap[x86_status_ & 0b11'1111];
    uint32_t value = (rm << 5) | (flags & 0x1f);
    return value;
  }

  void SetRiscVFcsr(uint32_t riscv_fcsr) override {
    uint32_t rm = (riscv_fcsr >> 5) & 0x7;
    uint32_t x86_rm = kRiscVToX86RoundingModeMap[rm];
    uint32_t flags = kRiscVFlagsToX86[riscv_fcsr & 0b1'1111];
    x86_status_ = kX86ExceptionFlags | x86_rm | flags;
  }

  uint32_t x86_status() const { return x86_status_; }
  void set_x86_status(uint32_t x86_status) {
    x86_status_ = kX86ExceptionFlags | x86_status;
  }

 private:
  uint32_t x86_status_ = kX86ExceptionFlags;
};

// Factory function.
HostFloatingPointInterface* GetHostFloatingPointInterface() {
  return new X86FloatingPointInterface();
}

#pragma STDC FENV_ACCESS ON

ScopedFPStatus::ScopedFPStatus(HostFloatingPointInterface* fp_interface)
    : fp_interface_(fp_interface) {
  // The host processor status is saved in cpu_fp_status_.
  uint32_t sim_status = 0;
  asm volatile("stmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               : "=m"(cpu_fp_status_), "+X"(sim_status));
  auto* host_fp_interface =
      static_cast<X86FloatingPointInterface*>(fp_interface_);
  // Get the translated version of the simulated RiscV status.
  sim_status = host_fp_interface->x86_status();
  // Save current "dynamic" rounding mode.
  host_rm_ = sim_status & 0x6000;
  // Set the host status to the translated RiscV status.
  asm volatile("ldmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               :
               : "m"(sim_status));
}

ScopedFPStatus::ScopedFPStatus(HostFloatingPointInterface* fp_interface,
                               uint32_t rm)
    : fp_interface_(fp_interface) {
  // The host processor status is saved in cpu_fp_status_.
  uint32_t sim_status = 0;
  asm volatile("stmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               : "=m"(cpu_fp_status_), "=X"(sim_status));
  auto* host_fp_interface =
      static_cast<X86FloatingPointInterface*>(fp_interface_);
  sim_status = host_fp_interface->x86_status();
  // Save current "dynamic" rounding mode.
  host_rm_ = sim_status & 0x6000;
  if (rm != 0b111) {
    // Override rounding mode with that specified in the instruction.
    uint32_t new_x86_rm = kRiscVToX86RoundingModeMap[rm];
    sim_status = new_x86_rm | (sim_status & 0x1fff);
  }
  // Set the host status to the translated RiscV status.
  asm volatile("ldmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               :
               : "m"(sim_status));
}

ScopedFPStatus::ScopedFPStatus(HostFloatingPointInterface* fp_interface,
                               FPRoundingMode rm)
    : fp_interface_(fp_interface) {
  // The host processor status is saved in cpu_fp_status_.
  uint32_t sim_status = 0;
  asm volatile("stmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               : "=m"(cpu_fp_status_), "=X"(sim_status));
  auto* host_fp_interface =
      static_cast<X86FloatingPointInterface*>(fp_interface);
  sim_status = host_fp_interface->x86_status();
  // Save current "dynamic" rounding mode.
  host_rm_ = sim_status & 0x6000;
  auto rm_value = static_cast<uint32_t>(rm);
  if (rm_value != 0b111) {
    // Override rounding mode with that specified in the instruction.
    uint32_t new_x86_rm = kRiscVToX86RoundingModeMap[rm_value];
    sim_status = new_x86_rm | (sim_status & 0x1fff);
  }
  // Set the host status to the translated RiscV status.
  asm volatile("ldmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               :
               : "m"(sim_status));
}

ScopedFPStatus::~ScopedFPStatus() {
  uint32_t x86_sim_status = 0;
  // Get the current x86 status.
  asm volatile(  // NOLINT(google3-runtime-inline-assembly)
      "stmxcsr %0\n"
      : "=m"(x86_sim_status));
  auto* host_fp_interface =
      static_cast<X86FloatingPointInterface*>(fp_interface_);
  // Save the fp status of the simulated instructions.
  uint32_t sim_status = ((x86_sim_status) & 0x1fff) | host_rm_;
  // Save the new status as the x86 version of the RiscV status.
  host_fp_interface->set_x86_status(x86_sim_status);
  // Restore host cpu status.
  asm volatile("ldmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               :
               : "m"(cpu_fp_status_), "X"(sim_status));
}

ScopedFPRoundingMode::ScopedFPRoundingMode(
    HostFloatingPointInterface* fp_interface) {
  uint32_t sim_status = 0;
  // Get current x86 status and save it in cpu_fp_status_.
  asm volatile("stmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               : "=m"(cpu_fp_status_), "=X"(sim_status));
  auto* host_fp_interface =
      static_cast<X86FloatingPointInterface*>(fp_interface);
  sim_status = host_fp_interface->x86_status();
  asm volatile("ldmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               :
               : "m"(sim_status));
}

ScopedFPRoundingMode::ScopedFPRoundingMode(
    HostFloatingPointInterface* fp_interface, uint32_t rm) {
  uint32_t sim_status = 0;
  // Get current x86 status and save it in cpu_fp_status_.
  asm volatile("stmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               : "=m"(cpu_fp_status_), "=X"(sim_status));
  auto* host_fp_interface =
      static_cast<X86FloatingPointInterface*>(fp_interface);
  sim_status = host_fp_interface->x86_status();
  if (rm != 0b111) {
    // Override rounding mode with that specified in the instruction.
    uint32_t new_x86_rm = kRiscVToX86RoundingModeMap[rm];
    sim_status = new_x86_rm | (sim_status & 0x1fff);
  }
  asm volatile("ldmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               :
               : "m"(sim_status));
}

ScopedFPRoundingMode::ScopedFPRoundingMode(
    HostFloatingPointInterface* fp_interface, FPRoundingMode rm) {
  uint32_t sim_status = 0;
  // Get current x86 status and save it in cpu_fp_status_.
  asm volatile("stmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               : "=m"(cpu_fp_status_), "=X"(sim_status));
  auto* host_fp_interface =
      static_cast<X86FloatingPointInterface*>(fp_interface);
  sim_status = host_fp_interface->x86_status();
  auto rm_value = static_cast<uint32_t>(rm);
  if (rm_value != 0b111) {
    // Override rounding mode with that specified in the instruction.
    uint32_t new_x86_rm = kRiscVToX86RoundingModeMap[rm_value];
    sim_status = new_x86_rm | (sim_status & 0x1fff);
  }
  asm volatile("ldmxcsr %0\n"  // NOLINT(google3-runtime-inline-assembly)
               :
               : "m"(sim_status));
}

ScopedFPRoundingMode::~ScopedFPRoundingMode() {
  // No need to save the state, for RoundingMode we only needed the rounding
  // mode be set. Just restore the previous x86 fp status.
  asm volatile(  // NOLINT(google3-runtime-inline-assembly)
      "ldmxcsr %0\n"
      :
      : "m"(cpu_fp_status_));
}

#pragma STDC FENV_ACCESS OFF

}  // namespace riscv
}  // namespace sim
}  // namespace mpact
