// 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_SIM_DECODER_INSTRUCTION_ENCODING_H_
#define MPACT_SIM_DECODER_INSTRUCTION_ENCODING_H_

#include <cstdint>
#include <string>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "mpact/sim/decoder/bin_format_visitor.h"
#include "mpact/sim/decoder/format.h"
#include "mpact/sim/decoder/overlay.h"

namespace mpact {
namespace sim {
namespace decoder {
namespace bin_format {

// Helper struct to group the information of a constraint (either == or !=).
struct Constraint {
  ConstraintType type;
  Field *field = nullptr;
  Overlay *overlay = nullptr;
  Field *rhs_field = nullptr;
  Overlay *rhs_overlay = nullptr;
  bool can_ignore = false;
  uint64_t value;
};

// Class for an individual instruction encoding. The instruction encoding
// captures the constraints on field values in an instruction format that
// determines the encoding of a specific opcode/instruction. It computes the
// constant bit values and masks from these constraints
class InstructionEncoding {
 public:
  // Disable default constructor and assignment operator.
  InstructionEncoding() = delete;
  InstructionEncoding(std::string name, Format *format);
  InstructionEncoding(const InstructionEncoding &encoding);
  InstructionEncoding &operator=(const InstructionEncoding &) = delete;
  ~InstructionEncoding();

  // Add a constraint on a field/overlay (in the format associated with the
  // instruction) needing to be equal to a value.
  absl::Status AddEqualConstraint(std::string field_name, int64_t value);
  // Add a constraint on a field/overlay (in the format associated with the
  // instruction) needing a different comparison (ne, lt, le, etc.).
  absl::Status AddOtherConstraint(ConstraintType type, std::string field_name,
                                  int64_t value);
  // Add a constraint on a field/overlay (in the format associated with the
  // instruction) that compares against another field/overlay.
  absl::Status AddOtherConstraint(ConstraintType type,
                                  const std::string &lhs_name,
                                  const std::string &rhs_name);

  // Get the value of the constant bits in the instruction (as defined by the
  // equal constraints).
  uint64_t GetValue();
  // Get the mask of the instruction word based on the bits that are specified
  // in the equal constraints.
  uint64_t GetMask();
  // Get the mask of the instruction word based on the bits in both equal and
  // not equal constraints.
  uint64_t GetCombinedMask();

  // Accessors.
  const std::string &name() const { return name_; }
  const std::string &format_name() const { return format_name_; }
  // Return the vector of constraints on the values of this encoding. These
  // constraints determine the value that a masked set of bits have to be equal
  // to in order to match this encoding.
  const std::vector<Constraint *> &equal_constraints() const {
    return equal_constraints_;
  }
  // Additionally, overlays may add constant bits to field references. These
  // constraints have to be compared one by one after performing an overlay
  // extraction that adds in the bits as specified in the overlay. Thus, they
  // cannot be used in a simple mask and compare.
  const std::vector<Constraint *> &equal_extracted_constraints() const {
    return equal_extracted_constraints_;
  }
  // The vector of not-equal, greater, less, etc., constraints that have to be
  // satisfied for an instruction to match this encoding.
  const std::vector<Constraint *> &other_constraints() const {
    return other_constraints_;
  }

 private:
  // Internal helper to create and check a constraint.
  absl::StatusOr<Constraint *> CreateConstraint(ConstraintType type,
                                                std::string lhs_name,
                                                std::string rhs_name);

  absl::StatusOr<Constraint *> CreateConstraint(ConstraintType type,
                                                std::string field_name,
                                                int64_t value);
  // Recomputes the masks and values.
  absl::Status ComputeMaskAndValue();

  std::string name_;
  std::string format_name_;
  Format *format_ = nullptr;
  std::vector<Constraint *> equal_constraints_;
  std::vector<Constraint *> equal_extracted_constraints_;
  std::vector<Constraint *> other_constraints_;
  bool mask_set_ = false;
  uint64_t mask_ = 0;
  uint64_t other_mask_ = 0;
  uint64_t extracted_mask_ = 0;
  uint64_t value_ = 0;
};

}  // namespace bin_format
}  // namespace decoder
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_DECODER_INSTRUCTION_ENCODING_H_
