// 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/container/btree_map.h"
#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, bool is_duplicate);
  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();
  // Add specialization to this encoding.
  absl::Status AddSpecialization(const std::string& name,
                                 InstructionEncoding* encoding);
  bool HasSpecialization() const { return !specializations_.empty(); }

  // 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_;
  }

  const absl::btree_map<std::string, InstructionEncoding*>& specializations()
      const {
    return specializations_;
  }

  Format* format() const { return format_; }

  void set_is_duplicate(bool is_duplicate) { is_duplicate_ = is_duplicate; }
  bool is_duplicate() const { return is_duplicate_; }

 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;
  absl::btree_map<std::string, InstructionEncoding*> specializations_;
  // True if this encoding is declared as using a duplicate of another opcode
  // name. This is used to suppress warning messages for encodings which
  // purposefully have the same opcode name as another encoding.
  bool is_duplicate_ = false;
};

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

#endif  // MPACT_SIM_DECODER_INSTRUCTION_ENCODING_H_
