1321369Sdim//===- llvm/MC/LaneBitmask.h ------------------------------------*- C++ -*-===// 2311116Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6311116Sdim// 7311116Sdim//===----------------------------------------------------------------------===// 8311116Sdim/// 9311116Sdim/// \file 10311116Sdim/// A common definition of LaneBitmask for use in TableGen and CodeGen. 11311116Sdim/// 12311116Sdim/// A lane mask is a bitmask representing the covering of a register with 13311116Sdim/// sub-registers. 14311116Sdim/// 15311116Sdim/// This is typically used to track liveness at sub-register granularity. 16311116Sdim/// Lane masks for sub-register indices are similar to register units for 17311116Sdim/// physical registers. The individual bits in a lane mask can't be assigned 18311116Sdim/// any specific meaning. They can be used to check if two sub-register 19311116Sdim/// indices overlap. 20311116Sdim/// 21311116Sdim/// Iff the target has a register such that: 22311116Sdim/// 23311116Sdim/// getSubReg(Reg, A) overlaps getSubReg(Reg, B) 24311116Sdim/// 25311116Sdim/// then: 26311116Sdim/// 27311116Sdim/// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0 28311116Sdim 29311116Sdim#ifndef LLVM_MC_LANEBITMASK_H 30311116Sdim#define LLVM_MC_LANEBITMASK_H 31311116Sdim 32321369Sdim#include "llvm/Support/Compiler.h" 33311116Sdim#include "llvm/Support/Format.h" 34311116Sdim#include "llvm/Support/Printable.h" 35311116Sdim#include "llvm/Support/raw_ostream.h" 36311116Sdim 37311116Sdimnamespace llvm { 38321369Sdim 39311116Sdim struct LaneBitmask { 40311116Sdim // When changing the underlying type, change the format string as well. 41321369Sdim using Type = unsigned; 42311116Sdim enum : unsigned { BitWidth = 8*sizeof(Type) }; 43311116Sdim constexpr static const char *const FormatStr = "%08X"; 44311116Sdim 45311116Sdim constexpr LaneBitmask() = default; 46311116Sdim explicit constexpr LaneBitmask(Type V) : Mask(V) {} 47311116Sdim 48311116Sdim constexpr bool operator== (LaneBitmask M) const { return Mask == M.Mask; } 49311116Sdim constexpr bool operator!= (LaneBitmask M) const { return Mask != M.Mask; } 50311116Sdim constexpr bool operator< (LaneBitmask M) const { return Mask < M.Mask; } 51311116Sdim constexpr bool none() const { return Mask == 0; } 52311116Sdim constexpr bool any() const { return Mask != 0; } 53311116Sdim constexpr bool all() const { return ~Mask == 0; } 54311116Sdim 55311116Sdim constexpr LaneBitmask operator~() const { 56311116Sdim return LaneBitmask(~Mask); 57311116Sdim } 58311116Sdim constexpr LaneBitmask operator|(LaneBitmask M) const { 59311116Sdim return LaneBitmask(Mask | M.Mask); 60311116Sdim } 61311116Sdim constexpr LaneBitmask operator&(LaneBitmask M) const { 62311116Sdim return LaneBitmask(Mask & M.Mask); 63311116Sdim } 64311116Sdim LaneBitmask &operator|=(LaneBitmask M) { 65311116Sdim Mask |= M.Mask; 66311116Sdim return *this; 67311116Sdim } 68311116Sdim LaneBitmask &operator&=(LaneBitmask M) { 69311116Sdim Mask &= M.Mask; 70311116Sdim return *this; 71311116Sdim } 72311116Sdim 73311116Sdim constexpr Type getAsInteger() const { return Mask; } 74311116Sdim 75327952Sdim unsigned getNumLanes() const { 76327952Sdim return countPopulation(Mask); 77327952Sdim } 78327952Sdim unsigned getHighestLane() const { 79327952Sdim return Log2_32(Mask); 80327952Sdim } 81327952Sdim 82327952Sdim static constexpr LaneBitmask getNone() { return LaneBitmask(0); } 83327952Sdim static constexpr LaneBitmask getAll() { return ~LaneBitmask(0); } 84327952Sdim static constexpr LaneBitmask getLane(unsigned Lane) { 85321369Sdim return LaneBitmask(Type(1) << Lane); 86321369Sdim } 87311116Sdim 88311116Sdim private: 89311116Sdim Type Mask = 0; 90311116Sdim }; 91311116Sdim 92311116Sdim /// Create Printable object to print LaneBitmasks on a \ref raw_ostream. 93327952Sdim inline Printable PrintLaneMask(LaneBitmask LaneMask) { 94311116Sdim return Printable([LaneMask](raw_ostream &OS) { 95311116Sdim OS << format(LaneBitmask::FormatStr, LaneMask.getAsInteger()); 96311116Sdim }); 97311116Sdim } 98311116Sdim 99321369Sdim} // end namespace llvm 100321369Sdim 101311116Sdim#endif // LLVM_MC_LANEBITMASK_H 102