/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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
 *
 *      http://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 ART_COMPILER_DEX_QUICK_RESOURCE_MASK_H_
#define ART_COMPILER_DEX_QUICK_RESOURCE_MASK_H_

#include <stdint.h>

#include "base/logging.h"
#include "dex/reg_storage.h"

namespace art {

class ArenaAllocator;

/**
 * @brief Resource mask for LIR insn uses or defs.
 * @detail Def/Use mask used for checking dependencies between LIR insns in local
 * optimizations such as load hoisting.
 */
class ResourceMask {
 private:
  constexpr ResourceMask(uint64_t mask1, uint64_t mask2)
      : masks_{ mask1, mask2 } {  // NOLINT
  }

 public:
  /*
   * Def/Use encoding in 128-bit use_mask/def_mask.  Low positions used for target-specific
   * registers (and typically use the register number as the position).  High positions
   * reserved for common and abstract resources.
   */
  enum ResourceBit {
    kMustNotAlias = 127,
    kHeapRef = 126,         // Default memory reference type.
    kLiteral = 125,         // Literal pool memory reference.
    kDalvikReg = 124,       // Dalvik v_reg memory reference.
    kFPStatus = 123,
    kCCode = 122,
    kLowestCommonResource = kCCode,
    kHighestCommonResource = kMustNotAlias
  };

  // Default-constructible.
  constexpr ResourceMask()
    : masks_ { 0u, 0u } {
  }

  // Copy-constructible and copyable.
  ResourceMask(const ResourceMask& other) = default;
  ResourceMask& operator=(const ResourceMask& other) = default;

  static constexpr ResourceMask RawMask(uint64_t mask1, uint64_t mask2) {
    return ResourceMask(mask1, mask2);
  }

  static constexpr ResourceMask Bit(size_t bit) {
    return ResourceMask(bit >= 64u ? 0u : UINT64_C(1) << bit,
                        bit >= 64u ? UINT64_C(1) << (bit - 64u) : 0u);
  }

  // Two consecutive bits. The start_bit must be even.
  static constexpr ResourceMask TwoBits(size_t start_bit) {
    return
        DCHECK_CONSTEXPR((start_bit & 1u) == 0u, << start_bit << " isn't even", Bit(0))
        ResourceMask(start_bit >= 64u ? 0u : UINT64_C(3) << start_bit,
                     start_bit >= 64u ? UINT64_C(3) << (start_bit - 64u) : 0u);
  }

  static constexpr ResourceMask NoBits() {
    return ResourceMask(UINT64_C(0), UINT64_C(0));
  }

  static constexpr ResourceMask AllBits() {
    return ResourceMask(~UINT64_C(0), ~UINT64_C(0));
  }

  constexpr ResourceMask Union(const ResourceMask& other) const {
    return ResourceMask(masks_[0] | other.masks_[0], masks_[1] | other.masks_[1]);
  }

  constexpr ResourceMask Intersection(const ResourceMask& other) const {
    return ResourceMask(masks_[0] & other.masks_[0], masks_[1] & other.masks_[1]);
  }

  constexpr ResourceMask Without(const ResourceMask& other) const {
    return ResourceMask(masks_[0] & ~other.masks_[0], masks_[1] & ~other.masks_[1]);
  }

  constexpr bool Equals(const ResourceMask& other) const {
    return masks_[0] == other.masks_[0] && masks_[1] == other.masks_[1];
  }

  constexpr bool Intersects(const ResourceMask& other) const {
    return (masks_[0] & other.masks_[0]) != 0u || (masks_[1] & other.masks_[1]) != 0u;
  }

  void SetBit(size_t bit) {
    DCHECK_LE(bit, kHighestCommonResource);
    masks_[bit / 64u] |= UINT64_C(1) << (bit & 63u);
  }

  constexpr bool HasBit(size_t bit) const {
    return (masks_[bit / 64u] & (UINT64_C(1) << (bit & 63u))) != 0u;
  }

  ResourceMask& SetBits(const ResourceMask& other) {
    masks_[0] |= other.masks_[0];
    masks_[1] |= other.masks_[1];
    return *this;
  }

  ResourceMask& ClearBits(const ResourceMask& other) {
    masks_[0] &= ~other.masks_[0];
    masks_[1] &= ~other.masks_[1];
    return *this;
  }

 private:
  uint64_t masks_[2];

  friend class ResourceMaskCache;
};

constexpr ResourceMask kEncodeNone = ResourceMask::NoBits();
constexpr ResourceMask kEncodeAll = ResourceMask::AllBits();
constexpr ResourceMask kEncodeHeapRef = ResourceMask::Bit(ResourceMask::kHeapRef);
constexpr ResourceMask kEncodeLiteral = ResourceMask::Bit(ResourceMask::kLiteral);
constexpr ResourceMask kEncodeDalvikReg = ResourceMask::Bit(ResourceMask::kDalvikReg);
constexpr ResourceMask kEncodeMem = kEncodeLiteral.Union(kEncodeDalvikReg).Union(
    kEncodeHeapRef).Union(ResourceMask::Bit(ResourceMask::kMustNotAlias));

class ResourceMaskCache {
 public:
  explicit ResourceMaskCache(ArenaAllocator* allocator)
      : allocator_(allocator) {
  }

  const ResourceMask* GetMask(const ResourceMask& mask);

 private:
  ArenaAllocator* allocator_;
};

}  // namespace art

#endif  // ART_COMPILER_DEX_QUICK_RESOURCE_MASK_H_
