// 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_OPCODE_H_
#define MPACT_SIM_DECODER_OPCODE_H_

#include <stdbool.h>

#include <functional>
#include <string>
#include <utility>
#include <variant>
#include <vector>

#include "absl/container/btree_set.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/decoder/format_name.h"
#include "mpact/sim/decoder/resource.h"
#include "mpact/sim/decoder/template_expression.h"

namespace mpact {
namespace sim {
namespace machine_description {
namespace instruction_set {

// An instance of the Opcode class represents an individual instruction opcode
// in the instruction set. The Opcode name has to be unique within the
// instruction set. In addition to having a name, the opcode also has an
// optional predicate operand name, a (possibly empty) list of source operand
// names, and a (possibly empty) list of destination operand names.
//
// Opcodes are created using the OpcodeFactory factory class. Each opcode is
// assigned a unique (within the OpcodeFactory) value that is used to define
// the value of the corresponding class enum entry in the generated code. This
// value is unrelated to any value of the "opcode" field in the instruction
// encoding.
class DestinationOperand {
 public:
  // Operand latency is defined by the expression.
  DestinationOperand(std::string name, bool is_array, bool is_reloc,
                     TemplateExpression *expression)
      : name_(std::move(name)),
        pascal_case_name_(ToPascalCase(name_)),
        expression_(expression),
        is_array_(is_array),
        is_reloc_(is_reloc) {}
  // Operand latency is a constant.
  DestinationOperand(std::string name, bool is_array, bool is_reloc,
                     int latency)
      : name_(std::move(name)),
        pascal_case_name_(ToPascalCase(name_)),
        expression_(new TemplateConstant(latency)),
        is_array_(is_array),
        is_reloc_(is_reloc) {}
  // This constructor is used when the destination operand latency is specified
  // as '*' - meaning that it will be computed at the time of decode.
  DestinationOperand(std::string name, bool is_array, bool is_reloc)
      : name_(std::move(name)),
        pascal_case_name_(ToPascalCase(name_)),
        expression_(nullptr),
        is_array_(is_array),
        is_reloc_(is_reloc) {}
  ~DestinationOperand() {
    delete expression_;
    expression_ = nullptr;
  }

  const std::string &name() const { return name_; }
  const std::string &pascal_case_name() const { return pascal_case_name_; }
  TemplateExpression *expression() const { return expression_; }
  bool is_array() const { return is_array_; }
  bool is_reloc() const { return is_reloc_; }
  bool HasLatency() const { return expression_ != nullptr; }
  absl::StatusOr<int> GetLatency() const {
    if (expression_ == nullptr) return -1;
    auto res = expression_->GetValue();
    if (!res.ok()) {
      return absl::InternalError(absl::StrCat(
          "Template expression evaluation error", res.status().message()));
    }
    auto variant_value = res.value();
    auto *value_ptr = std::get_if<int>(&variant_value);
    if (value_ptr == nullptr) {
      return absl::InternalError("Template expression type error");
    }
    return *value_ptr;
  }

 private:
  std::string name_;
  std::string pascal_case_name_;
  TemplateExpression *expression_;
  bool is_array_ = false;
  bool is_reloc_ = false;
};

struct SourceOperand {
  std::string name;
  bool is_array;
  bool is_reloc;
  SourceOperand(std::string name_, bool is_array_, bool is_reloc_)
      : name(std::move(name_)), is_array(is_array_), is_reloc(is_reloc_) {}
};

// This struct is used to specify the location of an operand within an
// instruction. It specifies which instruction (or child instruction) number. In
// this case, 0 is the top level instruction, 1 is the first child instruction
// etc. The type is 'p' for predicate operand, 's' for source operand, 't' for
// source array operand, 'd' for destination operand, and 'e' for destination
// array operand. The instance number specifies the entry index in the
// source or destination operand vector.
struct OperandLocator {
  static constexpr char kPredicate = 'p';
  static constexpr char kSource = 's';
  static constexpr char kSourceArray = 't';
  static constexpr char kDestination = 'd';
  static constexpr char kDestinationArray = 'e';
  int op_spec_number;
  char type;
  bool is_reloc;
  int instance;
  OperandLocator(int op_spec_number_, char type_, bool is_reloc_, int instance_)
      : op_spec_number(op_spec_number_),
        type(type_),
        is_reloc(is_reloc_),
        instance(instance_) {}
};

struct FormatInfo {
  FormatInfo() = default;
  // Use default copy constructor.
  FormatInfo(const FormatInfo &) = default;
  std::string op_name;
  bool is_formatted = true;
  bool is_optional = false;
  std::string number_format;
  bool use_address = false;
  std::string operation;
  bool do_left_shift = false;
  int shift_amount = 0;
};

struct DisasmFormat {
  DisasmFormat() = default;
  // Copy constructor.
  DisasmFormat(const DisasmFormat &df) {
    width = df.width;
    for (auto const &frag : df.format_fragment_vec) {
      format_fragment_vec.push_back(frag);
    }
    for (auto const *info : df.format_info_vec) {
      format_info_vec.push_back(new FormatInfo(*info));
    }
  }
  // Destructor.
  ~DisasmFormat() {
    for (auto *info : format_info_vec) {
      delete info;
    }
    format_info_vec.clear();
  }
  int width = 0;
  int num_optional = 0;
  std::vector<std::string> format_fragment_vec;
  std::vector<FormatInfo *> format_info_vec;
};

struct ResourceReference {
  Resource *resource;
  bool is_array;
  DestinationOperand *dest_op;
  TemplateExpression *begin_expression;
  TemplateExpression *end_expression;
  ResourceReference(Resource *resource_, bool is_array_,
                    DestinationOperand *dest_op_,
                    TemplateExpression *begin_expr_,
                    TemplateExpression *end_expr_)
      : resource(resource_),
        is_array(is_array_),
        dest_op(dest_op_),
        begin_expression(begin_expr_),
        end_expression(end_expr_) {}
  ResourceReference(const ResourceReference &rhs) {
    resource = rhs.resource;
    is_array = rhs.is_array;
    dest_op = rhs.dest_op;
    begin_expression = rhs.begin_expression->DeepCopy();
    end_expression = rhs.end_expression->DeepCopy();
  }
  ~ResourceReference() {
    resource = nullptr;
    dest_op = nullptr;
    delete begin_expression;
    begin_expression = nullptr;
    delete end_expression;
    end_expression = nullptr;
  }
};

using OpLocatorMap = absl::flat_hash_map<std::string, OperandLocator>;

class Opcode {
  friend class OpcodeFactory;

 public:
  // Constructor is private (defined below), only used by OpcodeFactory.
  virtual ~Opcode();

  // Each opcode specifies an optional predicate operand name, an optional list
  // of source operand names, and an optional list of destination operand names.
  // These methods append the source and destination operand names to the
  // opcode. These names are used to create interface methods that are called
  // to get the Predicate, Source and Destination operand interfaces (defined
  // in .../sim/generic/operand_interfaces.h. The implementation of these
  // methods will be left to the user of this generator tool.
  void AppendSourceOp(absl::string_view op_name, bool is_array, bool is_reloc);
  void AppendDestOp(absl::string_view op_name, bool is_array, bool is_reloc,
                    TemplateExpression *expression);
  void AppendDestOp(absl::string_view op_name, bool is_array, bool is_reloc);
  DestinationOperand *GetDestOp(absl::string_view op_name);
  // Append child opcode specification.
  void AppendChild(Opcode *op) { child_ = op; }
  // Checks destination latencies with the given function. Returns true if all
  // comply.
  bool ValidateDestLatencies(const std::function<bool(int)> &validator) const;
  int instruction_size() const { return instruction_size_; }
  void set_instruction_size(int val) { instruction_size_ = val; }
  Opcode *child() const { return child_; }
  Opcode *parent() const { return parent_; }
  const std::string &name() const { return name_; }
  const std::string &pascal_name() const { return pascal_name_; }
  // Each opcode is assigned a unique value that is used in the slot class
  // enum definition.
  int value() const { return value_; }
  // Predicate, source and destination operand names.
  const std::string &predicate_op_name() const { return predicate_op_name_; }
  void set_predicate_op_name(absl::string_view op_name) {
    predicate_op_name_ = op_name;
  }
  const std::vector<SourceOperand> &source_op_vec() const {
    return source_op_vec_;
  }
  const std::vector<DestinationOperand *> &dest_op_vec() const {
    return dest_op_vec_;
  }

  OpLocatorMap &op_locator_map() { return op_locator_map_; }  // not const.
  const OpLocatorMap &op_locator_map() const { return op_locator_map_; }

 private:
  Opcode(absl::string_view name, int value);
  int instruction_size_;
  Opcode *child_ = nullptr;
  Opcode *parent_ = nullptr;
  std::string predicate_op_name_;
  std::vector<SourceOperand> source_op_vec_;
  std::vector<DestinationOperand *> dest_op_vec_;
  absl::flat_hash_map<std::string, DestinationOperand *> dest_op_map_;
  std::string name_;
  std::string pascal_name_;
  std::string semfunc_code_string_;
  int value_;
  OpLocatorMap op_locator_map_;
};

class OpcodeFactory {
 public:
  OpcodeFactory() = default;
  ~OpcodeFactory() = default;

  // If the opcode doesn't yet exist, create a new opcode and return the
  // pointer, otherwise return an error code.
  absl::StatusOr<Opcode *> CreateOpcode(absl::string_view name);
  Opcode *CreateDefaultOpcode();
  Opcode *CreateChildOpcode(Opcode *opcode) const;
  // Duplicate the opcode, but evaluate the destination latency expressions
  // with the template argument expression vector.
  absl::StatusOr<Opcode *> CreateDerivedOpcode(const Opcode *opcode,
                                               TemplateInstantiationArgs *args);
  const std::vector<Opcode *> &opcode_vec() const { return opcode_vec_; }

 private:
  absl::btree_set<std::string> opcode_names_;
  std::vector<Opcode *> opcode_vec_;
  int opcode_value_ = 1;
};

}  // namespace instruction_set
}  // namespace machine_description
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_DECODER_OPCODE_H_
