// 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_GENERIC_LITERAL_OPERAND_H_
#define MPACT_SIM_GENERIC_LITERAL_OPERAND_H_

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

#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/generic/operand_interface.h"

// Literal operands differ from the immediate operands in that it not only
// represents a constant value in the simulated instruction such as an address
// offset or immediate arithmetic operand, but actually represents an
// "immediate" value that is a compile-time constant. This may seem like a
// small difference, but if an instruction immediate value is 32-bits long, it
// is beyond impractical to switch between 2^32 possible literal operands to
// select from, since each such operand has to be instantiated separately
// in the code, as they are compile time constants. However, for a constant
// true/false predicate this is perfectly reasonable. Even for small sets of
// pre-defined instruction immediate values this can be useful. Using literal
// operands can make a difference in performance when the operand is frequently
// accessed, such as an "always" (true) or "never" (false) predicate for
// simulated instructions.
namespace mpact {
namespace sim {
namespace generic {

// Boolean literal predicate operand.
template <bool literal>
class BoolLiteralPredicateOperand : public PredicateOperandInterface {
 public:
  BoolLiteralPredicateOperand() = default;
  bool Value() override { return literal; }
  std::string AsString() const override { return ""; }
};

// Boolean literal operand.
template <bool literal>
class BoolLiteralOperand : public SourceOperandInterface {
 public:
  BoolLiteralOperand() = default;
  explicit BoolLiteralOperand(const std::vector<int> &shape) : shape_(shape) {}

  // Methods for accessing the literal value. Always returns the same
  // value regardless of the index parameter.
  bool AsBool(int) override { return literal; }
  int8_t AsInt8(int) override { return static_cast<int8_t>(literal); }
  uint8_t AsUint8(int) override { return static_cast<uint8_t>(literal); }
  int16_t AsInt16(int) override { return static_cast<int16_t>(literal); }
  uint16_t AsUint16(int) override { return static_cast<uint16_t>(literal); }
  int32_t AsInt32(int) override { return static_cast<int32_t>(literal); }
  uint32_t AsUint32(int) override { return static_cast<uint32_t>(literal); }
  int64_t AsInt64(int) override { return static_cast<int64_t>(literal); }
  uint64_t AsUint64(int) override { return static_cast<uint64_t>(literal); }

  // Returns empty absl::any, as the literal operand does not have an
  // underlying object that models any processor state.
  std::any GetObject() const override { return std::any(); }

  // Return the shape of the operand (the number of elements in each dimension).
  // For instance {0} indicates a scalar quantity, whereas {128} indicates an
  // 128 element vector quantity.
  std::vector<int> shape() const override { return shape_; }

  std::string AsString() const override { return absl::StrCat(literal); }

 private:
  std::string as_string_;
  std::vector<int> shape_;
};

// Integer valued literal operand.
template <int literal>
class IntLiteralOperand : public SourceOperandInterface {
 public:
  IntLiteralOperand() = default;
  IntLiteralOperand(const std::vector<int> &shape, absl::string_view as_string)
      : shape_(shape), as_string_(as_string) {}
  explicit IntLiteralOperand(const std::vector<int> &shape)
      : IntLiteralOperand(shape, absl::StrCat(literal)) {}

  // Methods for accessing the immediate value. Always returns the same
  // value regardless of the index parameter.
  bool AsBool(int) override { return static_cast<bool>(literal); }
  int8_t AsInt8(int) override { return static_cast<int8_t>(literal); }
  uint8_t AsUint8(int) override { return static_cast<uint8_t>(literal); }
  int16_t AsInt16(int) override { return static_cast<int16_t>(literal); }
  uint16_t AsUint16(int) override { return static_cast<uint16_t>(literal); }
  int32_t AsInt32(int) override { return static_cast<int32_t>(literal); }
  uint32_t AsUint32(int) override { return static_cast<uint32_t>(literal); }
  int64_t AsInt64(int) override { return static_cast<int64_t>(literal); }
  uint64_t AsUint64(int) override { return static_cast<uint64_t>(literal); }

  // Returns empty absl::any, as the literal operand does not have an
  // underlying object that models any processor state.
  std::any GetObject() const override { return std::any(); }

  // Return the shape of the operand (the number of elements in each dimension).
  // For instance {0} indicates a scalar quantity, whereas {128} indicates an
  // 128 element vector quantity.
  std::vector<int> shape() const override { return shape_; }

  std::string AsString() const override { return absl::StrCat(literal); }

 private:
  std::vector<int> shape_;
  std::string as_string_;
};

}  // namespace generic
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_GENERIC_LITERAL_OPERAND_H_
