80 lines · c
1//===-- SIDefines.h - SI Helper Functions -----------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7/// \file - utility functions for the SIDefines and its common uses.8//9//===----------------------------------------------------------------------===//10 11#ifndef LLVM_LIB_TARGET_AMDGPU_UTILS_SIDEFINESUTILS_H12#define LLVM_LIB_TARGET_AMDGPU_UTILS_SIDEFINESUTILS_H13 14#include "llvm/MC/MCExpr.h"15#include <utility>16 17namespace llvm {18class MCContext;19namespace AMDGPU {20 21/// Deduce the least significant bit aligned shift and mask values for a binary22/// Complement \p Value (as they're defined in SIDefines.h as C_*) as a returned23/// pair<shift, mask>. That is to say \p Value == ~(mask << shift)24///25/// For example, given C_00B848_FWD_PROGRESS (i.e., 0x7FFFFFFF) from26/// SIDefines.h, this will return the pair as (31,1).27constexpr std::pair<unsigned, unsigned> getShiftMask(unsigned Value) {28 unsigned Shift = 0;29 unsigned Mask = 0;30 31 Mask = ~Value;32 for (; !(Mask & 1); Shift++, Mask >>= 1) {33 }34 35 return std::make_pair(Shift, Mask);36}37 38/// Provided with the MCExpr * \p Val, uint32 \p Mask and \p Shift, will return39/// the masked and left shifted, in said order of operations, MCExpr * created40/// within the MCContext \p Ctx.41///42/// For example, given MCExpr *Val, Mask == 0xf, Shift == 6 the returned MCExpr43/// * will be the equivalent of (Val & 0xf) << 644inline const MCExpr *maskShiftSet(const MCExpr *Val, uint32_t Mask,45 uint32_t Shift, MCContext &Ctx) {46 if (Mask) {47 const MCExpr *MaskExpr = MCConstantExpr::create(Mask, Ctx);48 Val = MCBinaryExpr::createAnd(Val, MaskExpr, Ctx);49 }50 if (Shift) {51 const MCExpr *ShiftExpr = MCConstantExpr::create(Shift, Ctx);52 Val = MCBinaryExpr::createShl(Val, ShiftExpr, Ctx);53 }54 return Val;55}56 57/// Provided with the MCExpr * \p Val, uint32 \p Mask and \p Shift, will return58/// the right shifted and masked, in said order of operations, MCExpr * created59/// within the MCContext \p Ctx.60///61/// For example, given MCExpr *Val, Mask == 0xf, Shift == 6 the returned MCExpr62/// * will be the equivalent of (Val >> 6) & 0xf63inline const MCExpr *maskShiftGet(const MCExpr *Val, uint32_t Mask,64 uint32_t Shift, MCContext &Ctx) {65 if (Shift) {66 const MCExpr *ShiftExpr = MCConstantExpr::create(Shift, Ctx);67 Val = MCBinaryExpr::createLShr(Val, ShiftExpr, Ctx);68 }69 if (Mask) {70 const MCExpr *MaskExpr = MCConstantExpr::create(Mask, Ctx);71 Val = MCBinaryExpr::createAnd(Val, MaskExpr, Ctx);72 }73 return Val;74}75 76} // end namespace AMDGPU77} // end namespace llvm78 79#endif // LLVM_LIB_TARGET_AMDGPU_UTILS_SIDEFINESUTILS_H80