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-exception 6 // 7 /// \file - utility functions for the SIDefines and its common uses. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef LLVM_LIB_TARGET_AMDGPU_UTILS_SIDEFINESUTILS_H 12 #define LLVM_LIB_TARGET_AMDGPU_UTILS_SIDEFINESUTILS_H 13 14 #include "llvm/MC/MCExpr.h" 15 #include <utility> 16 17 namespace llvm { 18 class MCContext; 19 namespace AMDGPU { 20 21 /// Deduce the least significant bit aligned shift and mask values for a binary 22 /// Complement \p Value (as they're defined in SIDefines.h as C_*) as a returned 23 /// pair<shift, mask>. That is to say \p Value == ~(mask << shift) 24 /// 25 /// For example, given C_00B848_FWD_PROGRESS (i.e., 0x7FFFFFFF) from 26 /// SIDefines.h, this will return the pair as (31,1). 27 constexpr 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 return 39 /// the masked and left shifted, in said order of operations, MCExpr * created 40 /// within the MCContext \p Ctx. 41 /// 42 /// For example, given MCExpr *Val, Mask == 0xf, Shift == 6 the returned MCExpr 43 /// * will be the equivalent of (Val & 0xf) << 6 44 inline 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 return 58 /// the right shifted and masked, in said order of operations, MCExpr * created 59 /// within the MCContext \p Ctx. 60 /// 61 /// For example, given MCExpr *Val, Mask == 0xf, Shift == 6 the returned MCExpr 62 /// * will be the equivalent of (Val >> 6) & 0xf 63 inline 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 AMDGPU 77 } // end namespace llvm 78 79 #endif // LLVM_LIB_TARGET_AMDGPU_UTILS_SIDEFINESUTILS_H 80