// 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/shared/register_id.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::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::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::RegisterID register_id_ = debug::RegisterID::kUnknown;

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

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_EXPR_EXPR_VALUE_SOURCE_H_
