// 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.

#ifndef MPACT_RISCV_RISCV_RISCV_FP_STATE_H_
#define MPACT_RISCV_RISCV_RISCV_FP_STATE_H_

#include <cstdint>

#include "riscv/riscv_csr.h"
#include "riscv/riscv_fp_host.h"
#include "riscv/riscv_fp_info.h"

// This file contains code that manages the fp state of the RiscV processor.

namespace mpact {
namespace sim {
namespace riscv {

class RiscVFPState;
class RiscVState;
class HostFloatingPointInterface;

// Floating point CSR.
class RiscVFcsr : public RiscVSimpleCsr<uint32_t> {
 public:
  RiscVFcsr() = delete;
  explicit RiscVFcsr(RiscVFPState *fp_state);
  ~RiscVFcsr() override = default;

  // Overrides.
  uint32_t AsUint32() override;
  uint64_t AsUint64() override;
  void Write(uint32_t value) override;
  void Write(uint64_t value) override;

 private:
  RiscVFPState *fp_state_;
};

// Floating point rounding mode csr.
class RiscVFrm : public RiscVSimpleCsr<uint32_t> {
 public:
  RiscVFrm() = delete;
  explicit RiscVFrm(RiscVFPState *fp_state);
  ~RiscVFrm() override = default;

  // Overrides.
  uint32_t AsUint32() override;
  uint64_t AsUint64() override { return AsUint32(); }
  void Write(uint32_t value) override;
  void Write(uint64_t value) override { Write(static_cast<uint32_t>(value)); }
  uint32_t GetUint32() override;
  uint64_t GetUint64() override { return GetUint32(); }
  void Set(uint32_t value) override;
  void Set(uint64_t value) override { Set(static_cast<uint32_t>(value)); }

 private:
  RiscVFPState *fp_state_;
};

// Floating point status flags csr.
class RiscVFflags : public RiscVSimpleCsr<uint32_t> {
 public:
  RiscVFflags() = delete;
  explicit RiscVFflags(RiscVFPState *fp_state);
  ~RiscVFflags() override = default;

  // Overrides.
  uint32_t AsUint32() override;
  uint64_t AsUint64() override { return AsUint32(); }
  void Write(uint32_t value) override;
  void Write(uint64_t value) override { Write(static_cast<uint32_t>(value)); }
  uint32_t GetUint32() override;
  uint64_t GetUint64() override { return GetUint32(); }
  void Set(uint32_t value) override;
  void Set(uint64_t value) override { Set(static_cast<uint32_t>(value)); }

 private:
  RiscVFPState *fp_state_;
};

class RiscVFPState {
 public:
  RiscVFPState() = delete;
  RiscVFPState(const RiscVFPState &) = delete;
  explicit RiscVFPState(RiscVCsrSet *csr_set, ArchState *rv_state);
  ~RiscVFPState();

  FPRoundingMode GetRoundingMode() const;

  void SetRoundingMode(FPRoundingMode mode);

  bool rounding_mode_valid() const { return rounding_mode_valid_; }

  // FP CSRs.
  RiscVFcsr *fcsr() const { return fcsr_; }
  RiscVFrm *frm() const { return frm_; }
  RiscVFflags *fflags() const { return fflags_; }
  // Parent state.
  ArchState *rv_state() const { return rv_state_; }
  // Host interface.
  HostFloatingPointInterface *host_fp_interface() const {
    return host_fp_interface_;
  }

 private:
  ArchState *rv_state_;
  RiscVFcsr *fcsr_ = nullptr;
  RiscVFrm *frm_ = nullptr;
  RiscVFflags *fflags_ = nullptr;
  HostFloatingPointInterface *host_fp_interface_;

  bool rounding_mode_valid_ = true;
  FPRoundingMode rounding_mode_ = FPRoundingMode::kRoundToNearest;
};

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

#endif  // MPACT_RISCV_RISCV_RISCV_FP_STATE_H_
