builder/llpcBuilderImplArith.cpp
Value* BuilderImplArith::CreateInsertBitField(
    Value*        pBase,                // [in] Base value
    Value*        pInsert,              // [in] Value to insert (same type as base)
    Value*        pOffset,              // Bit number of least-significant end of bitfield
    Value*        pCount,               // Count of bits in bitfield
    const Twine&  instName)             // [in] Name to give instruction(s)
{
    // Make pOffset and pCount vectors of the right integer type if necessary.
    if (auto pVecTy = dyn_cast<VectorType>(pBase->getType()))
    {
        if (isa<VectorType>(pOffset->getType()) == false)
        {
            pOffset = CreateVectorSplat(pVecTy->getNumElements(), pOffset);
        }
        if (isa<VectorType>(pCount->getType()) == false)
        {
            pCount = CreateVectorSplat(pVecTy->getNumElements(), pCount);
        }
    }
    pOffset = CreateZExtOrTrunc(pOffset, pBase->getType());
    pCount = CreateZExtOrTrunc(pCount, pBase->getType());

    Value* pBaseXorInsert = CreateXor(CreateShl(pInsert, pOffset), pBase);
    Constant* pOne = ConstantInt::get(pCount->getType(), 1);
    Value* pMask = CreateShl(CreateSub(CreateShl(pOne, pCount), pOne), pOffset);
    Value* pResult = CreateXor(CreateAnd(pBaseXorInsert, pMask), pBase);
    Value* pIsWholeField = CreateICmpEQ(pCount,
                                        ConstantInt::get(pCount->getType(),
                                                         pCount->getType()->getScalarType()->getPrimitiveSizeInBits()));
    return CreateSelect(pIsWholeField, pInsert, pResult, instName);
}
// =====================================================================================================================
// Create an "insert bitfield" operation for a (vector of) integer type.
// Returns a value where the "pCount" bits starting at bit "pOffset" come from the least significant "pCount"
// bits in "pInsert", and remaining bits come from "pBase". The result is undefined if "pCount"+"pOffset" is
// more than the number of bits (per vector element) in "pBase" and "pInsert".
// If "pBase" and "pInsert" are vectors, "pOffset" and "pCount" can be either scalar or vector of the same
// width. The scalar type of "pOffset" and "pCount" must be integer, but can be different to that of "pBase"
// and "pInsert" (and different to each other too).
Create an "insert bitfield" operation for a (vector of) integer type.
Create an " insert bitfield " operation for a ( vector of ) integer type .
Value* BuilderImplArith::CreateInsertBitField(
    Value*        pBase,                
    Value*        pInsert,              
    Value*        pOffset,              
    Value*        pCount,               
    const Twine&  instName)             
{
    if (auto pVecTy = dyn_cast<VectorType>(pBase->getType()))
    {
        if (isa<VectorType>(pOffset->getType()) == false)
        {
            pOffset = CreateVectorSplat(pVecTy->getNumElements(), pOffset);
        }
        if (isa<VectorType>(pCount->getType()) == false)
        {
            pCount = CreateVectorSplat(pVecTy->getNumElements(), pCount);
        }
    }
    pOffset = CreateZExtOrTrunc(pOffset, pBase->getType());
    pCount = CreateZExtOrTrunc(pCount, pBase->getType());
    Value* pBaseXorInsert = CreateXor(CreateShl(pInsert, pOffset), pBase);
    Constant* pOne = ConstantInt::get(pCount->getType(), 1);
    Value* pMask = CreateShl(CreateSub(CreateShl(pOne, pCount), pOne), pOffset);
    Value* pResult = CreateXor(CreateAnd(pBaseXorInsert, pMask), pBase);
    Value* pIsWholeField = CreateICmpEQ(pCount,
                                        ConstantInt::get(pCount->getType(),
                                                         pCount->getType()->getScalarType()->getPrimitiveSizeInBits()));
    return CreateSelect(pIsWholeField, pInsert, pResult, instName);
}
Value * BuilderImplArith :: CreateInsertBitField ( Value * pBase , Value * pInsert , Value * pOffset , Value * pCount , const Twine & instName ) { if ( auto pVecTy = dyn_cast < VectorType > ( pBase -> getType ( ) ) ) { if ( isa < VectorType > ( pOffset -> getType ( ) ) == false ) { pOffset = CreateVectorSplat ( pVecTy -> getNumElements ( ) , pOffset ) ; } if ( isa < VectorType > ( pCount -> getType ( ) ) == false ) { pCount = CreateVectorSplat ( pVecTy -> getNumElements ( ) , pCount ) ; } } pOffset = CreateZExtOrTrunc ( pOffset , pBase -> getType ( ) ) ; pCount = CreateZExtOrTrunc ( pCount , pBase -> getType ( ) ) ; Value * pBaseXorInsert = CreateXor ( CreateShl ( pInsert , pOffset ) , pBase ) ; Constant * pOne = ConstantInt :: get ( pCount -> getType ( ) , 1 ) ; Value * pMask = CreateShl ( CreateSub ( CreateShl ( pOne , pCount ) , pOne ) , pOffset ) ; Value * pResult = CreateXor ( CreateAnd ( pBaseXorInsert , pMask ) , pBase ) ; Value * pIsWholeField = CreateICmpEQ ( pCount , ConstantInt :: get ( pCount -> getType ( ) , pCount -> getType ( ) -> getScalarType ( ) -> getPrimitiveSizeInBits ( ) ) ) ; return CreateSelect ( pIsWholeField , pInsert , pResult , instName ) ; }
Create an "insert bitfield" operation for a (vector of) integer type.
Create an " insert bitfield " operation for a ( vector of ) integer type .
// [in] Base value // [in] Value to insert (same type as base) // Bit number of least-significant end of bitfield // Count of bits in bitfield // [in] Name to give instruction(s) // Make pOffset and pCount vectors of the right integer type if necessary.