// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVELOPER_DEBUG_ZXDB_EXPR_EXPR_VALUE_SOURCE_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_EXPR_EXPR_VALUE_SOURCE_H_

#include <stdint.h>

#include "src/developer/debug/ipc/register_desc.h"
#include "src/developer/debug/zxdb/common/int128_t.h"

namespace zxdb {

// Holds the source of a value. This allows taking the address of an object stored in an ExprValue
// ("&foo"), and for updating the contents of variables (currently not supported yet).
class ExprValueSource {
 public:
  // Where this value came from.
  enum class Type {
    // No source, this is the result of some computation.
    kTemporary,

    // The value lived in memory at the specified address.
    kMemory,

    // The value came from the specified CPU register.
    kRegister,

    // The value is known to be constant and can not be changed. The difference between this and
    // "temporary" is really just messaging since neither can be modified.
    kConstant,

    // This value came from more than one place. The optimizer can sometimes split things up,
    // for example, a pair might be put into two CPU registers, one for each value. There can also
    // be composite CPU/memory ones if something is in memory, but a modification to that is
    // only stored in a register.
    //
    // We currently don't support this and this enum indicates that the value can't be modified.
    // But we can message that it could be with additional feature work.
    //
    // TODO(bug 39630) the ExprValueSource should probably have a vector of sub-regions, each with
    // their own ExprValueSource. When we extract structure members, also extract the correct
    // sub-region(s).
    kComposite,
  };

  // Returns a string corresponding to the given type, "register", "temporary", etc.
  static const char* TypeToString(Type t);

  // Indicates an unknown, temporary (the output of "i + 4"), or constant source.
  explicit ExprValueSource(Type type = Type::kTemporary) : type_(type) {}

  // Initializes indicating a memory address and optional bitfield information.
  explicit ExprValueSource(uint64_t address, uint32_t bit_size = 0, uint32_t bit_shift = 0)
      : type_(Type::kMemory), address_(address), bit_size_(bit_size), bit_shift_(bit_shift) {}

  // Initializes indicating a register and optional bitfield information. The register does not have
  // to be a canonical register.
  explicit ExprValueSource(debug_ipc::RegisterID id, uint32_t bit_size = 0, uint32_t bit_shift = 0)
      : type_(Type::kRegister), register_id_(id), bit_size_(bit_size), bit_shift_(bit_shift) {}

  Type type() const { return type_; }

  bool is_bitfield() const { return bit_size_ != 0; }

  // Valid when type_ == kAddress.
  uint64_t address() const { return address_; }

  // Valid when type_ == kRegister.
  debug_ipc::RegisterID register_id() const { return register_id_; }

  // Number of bits used for bitfields. 0 means it is not a bitfield and all bits are used.
  uint32_t bit_size() const { return bit_size_; }

  // Number of bits to shift to the left to get the storage location. This is the offset of the low
  // bit. Note that this is different than the DWARF definition.
  //
  // If a bitfield occupies bits 3-6 (inclusive) of a 32-bit integer:
  //
  //   high                            low
  //    3           2         1          0
  //   10987654 32109876 54321098 76543210
  //                               [--]
  //                                   <--  bit_shift
  //
  // Then the bit_size() will be 4 and the bit_shift() will be 3.
  //
  // The memory layout will be the result of doing the shift and mask and memcpy-ing out which
  // will reorder the bytes in little-endian.
  uint32_t bit_shift() const { return bit_shift_; }

  // Returns a new ExprValueSource pointing to the given offset inside of this one. If this one is
  // not in memory, the returned one will be the same.
  //
  // When computing offsets of bitfields, the shifts are just added to any existing one, but the bit
  // size (if given) will overwrite any existing one.
  ExprValueSource GetOffsetInto(uint32_t offset, uint32_t new_bit_size = 0,
                                uint32_t bit_shift = 0) const {
    if (type_ == Type::kMemory) {
      return ExprValueSource(address_ + offset, new_bit_size == 0 ? bit_size_ : new_bit_size,
                             bit_shift_ + bit_shift);
    }
    return ExprValueSource();
  }

  // Writes the |new_value| over some |existing| value, taking into account the bit size and
  // shift information from this ExprValueSource. The returned value can be used to update the
  // register or memory for a bitfield.
  //
  // This ExprValueSource must be a bitfield (is_bitfield() == true) for this to be called.
  uint128_t SetBits(uint128_t existing, uint128_t new_value) const;

  bool operator==(const ExprValueSource& other) const {
    return type_ == other.type_ && address_ == other.address_ && bit_size_ == other.bit_size_ &&
           bit_shift_ == other.bit_shift_;
  }
  bool operator!=(const ExprValueSource& other) const { return !operator==(other); }

 private:
  Type type_ = Type::kTemporary;
  uint64_t address_ = 0;
  debug_ipc::RegisterID register_id_ = debug_ipc::RegisterID::kUnknown;

  uint32_t bit_size_ = 0;
  uint32_t bit_shift_ = 0;
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_EXPR_EXPR_VALUE_SOURCE_H_
