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

#include "riscv/riscv_zvt_instructions.h"

#include <algorithm>
#include <cstdint>
#include <cstring>

#include "absl/base/casts.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/types/span.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/instruction.h"
#include "riscv/riscv_register.h"
#include "riscv/riscv_state.h"
#include "riscv/riscv_vector_state.h"
#include "riscv/riscv_zvt_state.h"

namespace mpact::sim::riscv {

using ::mpact::sim::generic::DataBuffer;
using ::mpact::sim::generic::GetInstructionSource;
using ::mpact::sim::generic::operator*;  // NOLINT
using ::mpact::sim::riscv::RiscVVectorState;
using ::mpact::sim::riscv::RV32VectorDestinationOperand;
using ::mpact::sim::riscv::RV32VectorSourceOperand;

namespace {

// ELEN for the Zve32{x,f} kBase.
constexpr int kElen = 32;

// Decoded kTile subset specifier (TSS). Spec 15.1.1.5.
struct Tss {
  int kTile;       // bits[30:27]
  int pattern;     // bits[26:24]: 0 = row, 1 = col.
  uint32_t index;  // bits[23:0].
};

Tss DecodeTss(uint32_t tss) {
  return Tss{
      .kTile = static_cast<int>((tss >> 27) & 0xF),
      .pattern = static_cast<int>((tss >> 24) & 0x7),
      .index = tss & 0xFFFFFF,
  };
}

constexpr int kTssPatternCol = 1;  // pattern 0 = row (the default branch).

// Reinterprets the low 16 bits of a bf16 value as the high half of an fp32.
float Bf16ToF32(uint16_t bits) {
  uint32_t u = static_cast<uint32_t>(bits) << 16;
  return absl::bit_cast<float>(u);
}

// Reads kTile element (row,col) of `kTile` at width `tile_element_width` as a
// generic 64-bit container, and the inverse. Used by the move/load/store paths
// which carry the element width dynamically.
uint64_t LoadTileBits(RiscVZvtMatrixState* matrix_state, int kTile, int row,
                      int col, int tile_element_width) {
  const int kEffectiveTileEdge = tile_element_width < 64
                                     ? matrix_state->tile_elements()
                                     : matrix_state->tile_elements() / 2;
  if (row < 0 || row >= kEffectiveTileEdge || col < 0 ||
      col >= kEffectiveTileEdge) {
    return 0;
  }
  auto load_elem = [](auto status_or_val) -> uint64_t {
    if (!status_or_val.ok()) {
      LOG(ERROR) << status_or_val.status();
      return 0;
    }
    return static_cast<uint64_t>(*status_or_val);
  };
  switch (tile_element_width) {
    case 8:
      return load_elem(matrix_state->GetElem<uint8_t>(kTile, row, col, 8));
    case 16:
      return load_elem(matrix_state->GetElem<uint16_t>(kTile, row, col, 16));
    case 32:
      return load_elem(matrix_state->GetElem<uint32_t>(kTile, row, col, 32));
    case 64:
      return load_elem(matrix_state->GetElem<uint64_t>(kTile, row, col, 64));
    default:
      LOG(ERROR) << "Invalid tile element width: " << tile_element_width;
      return 0;
  }
}

void StoreTileBits(RiscVZvtMatrixState* matrix_state, int kTile, int row,
                   int col, int tile_element_width, uint64_t value) {
  const int kEffectiveTileEdge = tile_element_width < 64
                                     ? matrix_state->tile_elements()
                                     : matrix_state->tile_elements() / 2;
  if (row < 0 || row >= kEffectiveTileEdge || col < 0 ||
      col >= kEffectiveTileEdge) {
    return;
  }
  absl::Status status;
  switch (tile_element_width) {
    case 8:
      status = matrix_state->SetElem<uint8_t>(kTile, row, col, 8,
                                              static_cast<uint8_t>(value));
      break;
    case 16:
      status = matrix_state->SetElem<uint16_t>(kTile, row, col, 16,
                                               static_cast<uint16_t>(value));
      break;
    case 32:
      status = matrix_state->SetElem<uint32_t>(kTile, row, col, 32,
                                               static_cast<uint32_t>(value));
      break;
    case 64:
      status = matrix_state->SetElem<uint64_t>(kTile, row, col, 64, value);
      break;
    default:
      status = absl::InvalidArgumentError(
          absl::StrCat("Invalid tile element width: ", tile_element_width));
      break;
  }
  if (!status.ok()) {
    LOG(ERROR) << status;
  }
}

// Writes a 32-bit value to the scalar destination operand at `dest_index`.
void WriteScalar(const Instruction* inst, int dest_index, uint32_t value) {
  auto* dest = inst->Destination(dest_index);
  DataBuffer* db = dest->AllocateDataBuffer();
  db->Set<uint32_t>(0, value);
  db->Submit();
}

}  // namespace

void RiscVZvtMsetMtype(const Instruction* inst) {
  auto m_result = GetMatrixState(inst);
  auto* matrix_state = *m_result;
  auto* vector_state = matrix_state->riscv_state()->rv_vector();
  const uint32_t kRs1 = GetInstructionSource<uint32_t>(inst, 0);  // rs1
  const uint32_t kRs2 = GetInstructionSource<uint32_t>(inst, 1);  // rs2

  // Spec 15.1.1.4: vl = 0; mtype = rs1; then vtype = rs2 as if by vsetvl.
  vector_state->set_vector_length(0);
  matrix_state->set_mtype(kRs1);
  vector_state->SetVectorType(kRs2);

  if (matrix_state->mtwiden() == 0) {
    matrix_state->set_mtype(0);
    return;
  }

  const int kSewBits = vector_state->selected_element_width() * 8;
  const int kTwiden = matrix_state->twiden();
  const int kTileElementWidth = kSewBits * kTwiden;
  const int kEffectiveTileElements = kTileElementWidth < 64
                                         ? matrix_state->tile_elements()
                                         : matrix_state->tile_elements() / 2;
  const int kmax = RiscVZvtKmax(kSewBits);
  const int kLmulElements =
      vector_state->max_vector_length();  // LMUL * (VLEN/SEW).

  // If the matrix unit is configured, force vma/vta = 1.
  // TODO: also derive vtype.vlmul per the spec's min() formula; deferred while
  // the v0.3 encoding firms up.
  vector_state->SetVectorType(vector_state->vtype() | (1u << 6) | (1u << 7));

  // kVill if the resulting TILE_ELEMENT_WIDTH is unsupported for the kBase
  // (SEW*TWIDEN > ELEN).
  const bool kVill = kTileElementWidth > kElen;
  if (kVill) {
    vector_state->set_vector_exception();
    matrix_state->set_mtype(0);
    return;
  }

  // kTileK = min(kTileK, KMAX); kTileM = min(kTileM, LMUL*EVE,
  // EFFECTIVE_TILE_EDGE).
  matrix_state->set_tile_k(std::min(matrix_state->tile_k(), kmax));
  matrix_state->set_tile_m(std::min(
      {matrix_state->tile_m(), kLmulElements, kEffectiveTileElements}));
}

void RiscVZvtMsetTn(const Instruction* inst) {
  auto m_result = GetMatrixState(inst);
  auto* matrix_state = *m_result;
  auto* vector_state = matrix_state->riscv_state()->rv_vector();
  const uint32_t kRs1 = GetInstructionSource<uint32_t>(inst, 0);

  uint32_t kTileN;
  if (matrix_state->mtwiden() == 0) {
    // Degenerates to vsetvl using the current vtype: vl = min(rs1, VLMAX).
    kTileN = std::min<uint32_t>(kRs1, vector_state->max_vector_length());
  } else {
    const int kBound = std::min(vector_state->max_vector_length(),
                                matrix_state->effective_tile_edge());
    kTileN = std::min<uint32_t>(kRs1, kBound);
  }
  vector_state->set_vector_length(kTileN);
  WriteScalar(inst, 0, kTileN);
}

void RiscVZvtMsetTm(const Instruction* inst) {
  auto m_result = GetMatrixState(inst);
  auto* matrix_state = *m_result;
  auto* vector_state = matrix_state->riscv_state()->rv_vector();
  const uint32_t kRs1 = GetInstructionSource<uint32_t>(inst, 0);

  uint32_t kTileM;
  if (matrix_state->mtwiden() == 0) {
    kTileM = 0;
  } else {
    const int kBound = std::min(vector_state->max_vector_length(),
                                matrix_state->effective_tile_edge());
    kTileM = std::min<uint32_t>(kRs1, kBound);
  }
  matrix_state->set_tile_m(kTileM);
  WriteScalar(inst, 0, kTileM);
}

void RiscVZvtMsetTk(const Instruction* inst) {
  auto m_result = GetMatrixState(inst);
  auto* matrix_state = *m_result;
  auto* vector_state = matrix_state->riscv_state()->rv_vector();
  const uint32_t kRs1 = GetInstructionSource<uint32_t>(inst, 0);

  uint32_t kTileK;
  if (matrix_state->mtwiden() == 0) {
    kTileK = 0;
  } else {
    const int kSewBits = vector_state->selected_element_width() * 8;
    kTileK = std::min<uint32_t>(kRs1, RiscVZvtKmax(kSewBits));
  }
  matrix_state->set_tile_k(kTileK);
  WriteScalar(inst, 0, kTileK);
}

// ----------------------------------------------------------------------------
// Tile manipulation
// ----------------------------------------------------------------------------

void RiscVZvtVtZero(const Instruction* inst) {
  auto m_result = GetMatrixState(inst);
  auto* matrix_state = *m_result;
  auto* vector_state = matrix_state->riscv_state()->rv_vector();
  const int kTile = GetInstructionSource<uint32_t>(inst, 0);  // mtd
  const int kTileElementWidth = matrix_state->tile_element_width_bits();
  const int kTileM = matrix_state->tile_m();
  const int kEffectiveTileEdge = kTileElementWidth < 64
                                     ? matrix_state->tile_elements()
                                     : matrix_state->tile_elements() / 2;
  const int kTileN =
      std::min(vector_state->vector_length(), kEffectiveTileEdge);
  for (int row = 0; row < kTileM; row++) {
    for (int col = 0; col < kTileN; col++) {
      StoreTileBits(matrix_state, kTile, row, col, kTileElementWidth, 0);
    }
  }
}

void RiscVZvtVtDiscard(const Instruction* /*inst*/) {
  // Architecturally hints the kTile state is dead. No-op in the ISS.
}

// Number of kTile-subset elements processed: min(vl, EFFECTIVE_TILE_EDGE) for
// the given TILE_ELEMENT_WIDTH.
static int TileSubsetCount(RiscVZvtMatrixState* matrix_state,
                           RiscVVectorState* vector_state,
                           int tile_element_width) {
  const int kEffectiveTileEdge = tile_element_width < 64
                                     ? matrix_state->tile_elements()
                                     : matrix_state->tile_elements() / 2;
  return std::min(vector_state->vector_length(), kEffectiveTileEdge);
}

void RiscVZvtVtmvVt(const Instruction* inst) {
  // Tile row/col subset -> vector register group. Move TILE_ELEMENT_WIDTH =
  // SEW.
  auto m_result = GetMatrixState(inst);
  auto* matrix_state = *m_result;
  auto* vector_state = matrix_state->riscv_state()->rv_vector();
  const Tss kTss = DecodeTss(GetInstructionSource<uint32_t>(inst, 0));
  const int kSewBytes = vector_state->selected_element_width();
  const int kTileElementWidth = kSewBytes * 8;
  const int kCount =
      TileSubsetCount(matrix_state, vector_state, kTileElementWidth);
  const int kElementsPerVector =
      vector_state->vector_register_byte_length() / kSewBytes;
  auto* vd = static_cast<RV32VectorDestinationOperand*>(inst->Destination(0));
  const int kNumRegs = (kCount + kElementsPerVector - 1) / kElementsPerVector;
  for (int r = 0; r < kNumRegs; r++) {
    DataBuffer* db = vd->AllocateDataBuffer(r);
    absl::Span<uint8_t> bytes = db->Get<uint8_t>();
    std::memset(bytes.data(), 0, bytes.size());  // tail-agnostic fill.
    for (int kE = 0; kE < kElementsPerVector; kE++) {
      const int kElem = r * kElementsPerVector + kE;
      if (kElem >= kCount) break;
      const uint64_t kVal =
          (kTss.pattern == kTssPatternCol)
              ? LoadTileBits(matrix_state, kTss.kTile, kElem, kTss.index,
                             kTileElementWidth)
              : LoadTileBits(matrix_state, kTss.kTile, kTss.index, kElem,
                             kTileElementWidth);
      std::memcpy(&bytes[kE * kSewBytes], &kVal, kSewBytes);
    }
    db->Submit();
  }
}

void RiscVZvtVtmvTv(const Instruction* inst) {
  // Vector register group -> kTile row/col subset. Move TILE_ELEMENT_WIDTH =
  // SEW.
  auto m_result = GetMatrixState(inst);
  auto* matrix_state = *m_result;
  auto* vector_state = matrix_state->riscv_state()->rv_vector();
  auto* vs = static_cast<RV32VectorSourceOperand*>(inst->Source(0));
  const Tss kTss = DecodeTss(GetInstructionSource<uint32_t>(inst, 1));
  const int kSewBytes = vector_state->selected_element_width();
  const int kTileElementWidth = kSewBytes * 8;
  const int kCount =
      TileSubsetCount(matrix_state, vector_state, kTileElementWidth);
  const int kElementsPerVector =
      vector_state->vector_register_byte_length() / kSewBytes;
  for (int kElem = 0; kElem < kCount; kElem++) {
    const int kReg = kElem / kElementsPerVector;
    const int kE = kElem % kElementsPerVector;
    auto bytes = vs->GetRegister(kReg)->data_buffer()->Get<uint8_t>();
    uint64_t kVal = 0;
    std::memcpy(&kVal, &bytes[kE * kSewBytes], kSewBytes);
    if (kTss.pattern == kTssPatternCol) {
      StoreTileBits(matrix_state, kTss.kTile, kElem, kTss.index,
                    kTileElementWidth, kVal);
    } else {
      StoreTileBits(matrix_state, kTss.kTile, kTss.index, kElem,
                    kTileElementWidth, kVal);
    }
  }
}

void RiscVZvtVtle(int eew_bits, const Instruction* inst) {
  // Memory -> kTile row/col subset. EEW is statically encoded.
  auto m_result = GetMatrixState(inst);
  auto* matrix_state = *m_result;
  auto* state = matrix_state->riscv_state();
  auto* vector_state = state->rv_vector();
  const uint64_t kBase = GetInstructionSource<uint64_t>(inst, 0);       // rs1
  const Tss kTss = DecodeTss(GetInstructionSource<uint32_t>(inst, 1));  // rs2
  const int kElementSize = eew_bits / 8;
  const int kCount = TileSubsetCount(matrix_state, vector_state, eew_bits);
  DataBuffer* db = matrix_state->GetScratchDb(kCount * kElementSize);
  state->memory()->Load(kBase, db, nullptr, nullptr);
  absl::Span<uint8_t> bytes = db->Get<uint8_t>();
  for (int kE = 0; kE < kCount; kE++) {
    uint64_t kVal = 0;
    std::memcpy(&kVal, &bytes[kE * kElementSize], kElementSize);
    if (kTss.pattern == kTssPatternCol) {
      StoreTileBits(matrix_state, kTss.kTile, kE, kTss.index, eew_bits, kVal);
    } else {
      StoreTileBits(matrix_state, kTss.kTile, kTss.index, kE, eew_bits, kVal);
    }
  }
}

void RiscVZvtVtse(int eew_bits, const Instruction* inst) {
  // Tile row/col subset -> memory. EEW is statically encoded.
  auto m_result = GetMatrixState(inst);
  auto* matrix_state = *m_result;
  auto* state = matrix_state->riscv_state();
  auto* vector_state = state->rv_vector();
  const uint64_t kBase = GetInstructionSource<uint64_t>(inst, 0);       // rs1
  const Tss kTss = DecodeTss(GetInstructionSource<uint32_t>(inst, 1));  // rs2
  const int kElementSize = eew_bits / 8;
  const int kCount = TileSubsetCount(matrix_state, vector_state, eew_bits);
  DataBuffer* db = matrix_state->GetScratchDb(kCount * kElementSize);
  absl::Span<uint8_t> bytes = db->Get<uint8_t>();
  for (int kE = 0; kE < kCount; kE++) {
    const uint64_t kVal =
        (kTss.pattern == kTssPatternCol)
            ? LoadTileBits(matrix_state, kTss.kTile, kE, kTss.index, eew_bits)
            : LoadTileBits(matrix_state, kTss.kTile, kTss.index, kE, eew_bits);
    std::memcpy(&bytes[kE * kElementSize], &kVal, kElementSize);
  }
  state->memory()->Store(kBase, db);
}

// ----------------------------------------------------------------------------
// Matrix multiply: C[m,n] += sum_k A[k,m] * B[k,n]
// ----------------------------------------------------------------------------

void RiscVZvtMatmul(RiscVZvtMatmulKind kind, const Instruction* inst) {
  auto m_result = GetMatrixState(inst);
  auto* matrix_state = *m_result;
  auto* vector_state = matrix_state->riscv_state()->rv_vector();
  const int kSewBytes = vector_state->selected_element_width();
  const int kSewBits = kSewBytes * 8;
  const int kElementsPerVector =
      vector_state->vector_register_byte_length() / kSewBytes;  // elems/kReg.
  const int kStride = 8 / RiscVZvtKmax(kSewBits);  // regs between rows.
  const int kTileK =
      matrix_state->tile_k();  // K: the inner dimension of the dot product.
  const int kTileM =
      matrix_state
          ->tile_m();  // M: the number of rows of the accumulator kTile.
  const int kDestTile = GetInstructionSource<uint32_t>(inst, 2);  // mtd
  const int kTileElementWidth =
      matrix_state
          ->tile_element_width_bits();  // == 32 for the supported datatypes.
  const int kEffectiveTileEdge = kTileElementWidth < 64
                                     ? matrix_state->tile_elements()
                                     : matrix_state->tile_elements() / 2;
  // N: the number of columns of the accumulator kTile (derived from vector
  // length).
  const int kTileN =
      std::min(vector_state->vector_length(), kEffectiveTileEdge);

  auto* a = static_cast<RV32VectorSourceOperand*>(inst->Source(0));
  auto* b = static_cast<RV32VectorSourceOperand*>(inst->Source(1));

  absl::Span<uint8_t> a_spans[32] = {};
  absl::Span<uint8_t> b_spans[32] = {};

  const bool kIsFp =
      (kind == RiscVZvtMatmulKind::kFp32 || kind == RiscVZvtMatmulKind::kBf16);

  // Reads element `col` of row `kk` from a vector-group operand.
  auto read_fp = [&](RV32VectorSourceOperand* op, absl::Span<uint8_t>* spans,
                     int kk, int col) -> float {
    const int kReg = kk * kStride + col / kElementsPerVector;
    const int kE = col % kElementsPerVector;
    if (spans[kReg].empty()) {
      spans[kReg] = op->GetRegister(kReg)->data_buffer()->Get<uint8_t>();
    }
    absl::Span<uint8_t> span = spans[kReg];
    if (kind == RiscVZvtMatmulKind::kBf16) {
      uint16_t u;
      std::memcpy(&u, &span[kE * kSewBytes], sizeof(u));
      return Bf16ToF32(u);
    }
    float f;
    std::memcpy(&f, &span[kE * kSewBytes], sizeof(f));
    return f;
  };
  auto read_int = [&](RV32VectorSourceOperand* op, absl::Span<uint8_t>* spans,
                      int kk, int col) -> int32_t {
    const int kReg = kk * kStride + col / kElementsPerVector;
    const int kE = col % kElementsPerVector;
    if (spans[kReg].empty()) {
      spans[kReg] = op->GetRegister(kReg)->data_buffer()->Get<uint8_t>();
    }
    absl::Span<uint8_t> span = spans[kReg];
    if (kind == RiscVZvtMatmulKind::kInt8Signed) {
      return static_cast<int8_t>(span[kE]);
    }
    return static_cast<uint8_t>(span[kE]);
  };

  for (int mm = 0; mm < kTileM; mm++) {
    for (int nn = 0; nn < kTileN; nn++) {
      if (kIsFp) {
        absl::StatusOr<float> acc_res =
            matrix_state->GetElem<float>(kDestTile, mm, nn, kTileElementWidth);
        if (!acc_res.ok()) {
          LOG(ERROR) << acc_res.status();
          return;
        }
        float acc = *acc_res;
        for (int kk = 0; kk < kTileK; kk++) {
          acc += read_fp(a, a_spans, kk, mm) * read_fp(b, b_spans, kk, nn);
        }
        // SetElem cannot fail because GetElem with the same parameters
        // succeeded above.
        matrix_state->SetElem<float>(kDestTile, mm, nn, kTileElementWidth, acc)
            .IgnoreError();
      } else {
        absl::StatusOr<int32_t> acc_res = matrix_state->GetElem<int32_t>(
            kDestTile, mm, nn, kTileElementWidth);
        if (!acc_res.ok()) {
          LOG(ERROR) << acc_res.status();
          return;
        }
        int32_t acc = *acc_res;
        for (int kk = 0; kk < kTileK; kk++) {
          acc += read_int(a, a_spans, kk, mm) * read_int(b, b_spans, kk, nn);
        }
        // SetElem cannot fail because GetElem with the same parameters
        // succeeded above.
        matrix_state
            ->SetElem<int32_t>(kDestTile, mm, nn, kTileElementWidth, acc)
            .IgnoreError();
      }
    }
  }
}

}  // namespace mpact::sim::riscv
