diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index a52b89f8c8..b6b05b14b0 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -2866,7 +2866,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO emitBitfieldExtractImpl(inst); break; } - case kIROp_BitfieldInsert: + case kIROp_BitfieldInsert: { emitBitfieldInsertImpl(inst); break; @@ -3843,10 +3843,11 @@ void CLikeSourceEmitter::emitFuncDecorationsImpl(IRFunc* func) } } -bool CLikeSourceEmitter::tryGetIntInfo(IRType* elementType, bool &isSigned, int &bitWidth) +bool CLikeSourceEmitter::tryGetIntInfo(IRType* elementType, bool& isSigned, int& bitWidth) { Slang::IROp type = elementType->getOp(); - if (!(type >= kIROp_Int8Type && type <= kIROp_UInt64Type)) return false; + if (!(type >= kIROp_Int8Type && type <= kIROp_UInt64Type)) + return false; isSigned = (type >= kIROp_Int8Type && type <= kIROp_Int64Type); Slang::IROp stype = (isSigned) ? type : Slang::IROp(type - 4); @@ -3854,29 +3855,48 @@ bool CLikeSourceEmitter::tryGetIntInfo(IRType* elementType, bool &isSigned, int return true; } -void CLikeSourceEmitter::emitVecNOrScalar(IRVectorType* vectorType, std::function emitComponentLogic) +void CLikeSourceEmitter::emitVecNOrScalar( + IRVectorType* vectorType, + std::function emitComponentLogic) { if (vectorType) { int N = int(getIntVal(vectorType->getElementCount())); - Slang::IRType *elementType = vectorType->getElementType(); + Slang::IRType* elementType = vectorType->getElementType(); // Special handling required for CUDA target if (isCUDATarget(getTargetReq())) { m_writer->emit("make_"); - switch(elementType->getOp()) + switch (elementType->getOp()) { - case kIROp_Int8Type: m_writer->emit("char"); break; - case kIROp_Int16Type: m_writer->emit("short"); break; - case kIROp_IntType: m_writer->emit("int"); break; - case kIROp_Int64Type: m_writer->emit("longlong"); break; - case kIROp_UInt8Type: m_writer->emit("uchar"); break; - case kIROp_UInt16Type: m_writer->emit("ushort"); break; - case kIROp_UIntType: m_writer->emit("uint"); break; - case kIROp_UInt64Type: m_writer->emit("ulonglong"); break; - default: SLANG_ABORT_COMPILATION("Unhandled type emitting CUDA vector"); + case kIROp_Int8Type: + m_writer->emit("char"); + break; + case kIROp_Int16Type: + m_writer->emit("short"); + break; + case kIROp_IntType: + m_writer->emit("int"); + break; + case kIROp_Int64Type: + m_writer->emit("longlong"); + break; + case kIROp_UInt8Type: + m_writer->emit("uchar"); + break; + case kIROp_UInt16Type: + m_writer->emit("ushort"); + break; + case kIROp_UIntType: + m_writer->emit("uint"); + break; + case kIROp_UInt64Type: + m_writer->emit("ulonglong"); + break; + default: + SLANG_ABORT_COMPILATION("Unhandled type emitting CUDA vector"); } m_writer->emitRawText(std::to_string(N).c_str()); @@ -3892,12 +3912,13 @@ void CLikeSourceEmitter::emitVecNOrScalar(IRVectorType* vectorType, std::functio } // In other languages, we can output the Slang vector type directly - else { + else + { emitType(vectorType); } m_writer->emit("("); - for (int i = 0; i < N; ++i) + for (int i = 0; i < N; ++i) { emitType(elementType); m_writer->emit("("); @@ -3916,7 +3937,7 @@ void CLikeSourceEmitter::emitVecNOrScalar(IRVectorType* vectorType, std::functio } } -void CLikeSourceEmitter::emitBitfieldExtractImpl(IRInst* inst) +void CLikeSourceEmitter::emitBitfieldExtractImpl(IRInst* inst) { // If unsigned, bfue := ((val>>off)&((1u<>off)&((1u<>(nbts-bts)); @@ -3930,26 +3951,38 @@ void CLikeSourceEmitter::emitBitfieldExtractImpl(IRInst* inst) if (vectorType) elementType = vectorType->getElementType(); - bool isSigned; + bool isSigned; int bitWidth; - if (!tryGetIntInfo(elementType, isSigned, bitWidth)) + if (!tryGetIntInfo(elementType, isSigned, bitWidth)) { - SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "non-integer element type given to bitfieldExtract"); + SLANG_DIAGNOSE_UNEXPECTED( + getSink(), + SourceLoc(), + "non-integer element type given to bitfieldExtract"); return; } String one; - switch(bitWidth) + switch (bitWidth) { - case 8: one = "uint8_t(1)"; break; - case 16: one = "uint16_t(1)"; break; - case 32: one = "uint32_t(1)"; break; - case 64: one = "uint64_t(1)"; break; - default: SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unexpected bit width"); + case 8: + one = "uint8_t(1)"; + break; + case 16: + one = "uint16_t(1)"; + break; + case 32: + one = "uint32_t(1)"; + break; + case 64: + one = "uint64_t(1)"; + break; + default: + SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unexpected bit width"); } // Emit open paren and type cast for later sign extension - if (isSigned) + if (isSigned) { m_writer->emit("("); emitType(inst->getDataType()); @@ -3960,50 +3993,55 @@ void CLikeSourceEmitter::emitBitfieldExtractImpl(IRInst* inst) m_writer->emit("(("); emitOperand(val, getInfo(EmitOp::General)); m_writer->emit(">>"); - emitVecNOrScalar(vectorType, [&]() { - emitOperand(off, getInfo(EmitOp::General)); - }); + emitVecNOrScalar(vectorType, [&]() { emitOperand(off, getInfo(EmitOp::General)); }); m_writer->emit(")&("); - emitVecNOrScalar(vectorType, [&]() { - m_writer->emit("((" + one + "<<"); - emitOperand(bts, getInfo(EmitOp::General)); - m_writer->emit(")-" + one + ")"); - }); + emitVecNOrScalar( + vectorType, + [&]() + { + m_writer->emit("((" + one + "<<"); + emitOperand(bts, getInfo(EmitOp::General)); + m_writer->emit(")-" + one + ")"); + }); m_writer->emit("))"); // Emit sign extension logic // (type(bitfield<<(numBits-bts))>>(numBits-bts)) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - if (isSigned) + if (isSigned) { m_writer->emit("<<"); - emitVecNOrScalar(vectorType, [&]() - { - m_writer->emit("("); - m_writer->emit(bitWidth); - m_writer->emit("-"); - emitOperand(bts, getInfo(EmitOp::General)); - m_writer->emit(")"); - }); + emitVecNOrScalar( + vectorType, + [&]() + { + m_writer->emit("("); + m_writer->emit(bitWidth); + m_writer->emit("-"); + emitOperand(bts, getInfo(EmitOp::General)); + m_writer->emit(")"); + }); m_writer->emit(")>>"); - emitVecNOrScalar(vectorType, [&]() - { - m_writer->emit("("); - m_writer->emit(bitWidth); - m_writer->emit("-"); - emitOperand(bts, getInfo(EmitOp::General)); - m_writer->emit(")"); - }); + emitVecNOrScalar( + vectorType, + [&]() + { + m_writer->emit("("); + m_writer->emit(bitWidth); + m_writer->emit("-"); + emitOperand(bts, getInfo(EmitOp::General)); + m_writer->emit(")"); + }); m_writer->emit(")"); } } -void CLikeSourceEmitter::emitBitfieldInsertImpl(IRInst* inst) +void CLikeSourceEmitter::emitBitfieldInsertImpl(IRInst* inst) { // uint clearMask = ~(((1u << bits) - 1u) << offset); // uint clearedBase = base & clearMask; // uint maskedInsert = (insert & ((1u << bits) - 1u)) << offset; - // BitfieldInsert := T(uint(clearedBase) | uint(maskedInsert)); + // BitfieldInsert := T(uint(clearedBase) | uint(maskedInsert)); Slang::IRType* dataType = inst->getDataType(); Slang::IRInst* bse = inst->getOperand(0); Slang::IRInst* ins = inst->getOperand(1); @@ -4019,55 +4057,70 @@ void CLikeSourceEmitter::emitBitfieldInsertImpl(IRInst* inst) int bitWidth; if (!tryGetIntInfo(elementType, isSigned, bitWidth)) { - SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "non-integer element type given to bitfieldInsert"); + SLANG_DIAGNOSE_UNEXPECTED( + getSink(), + SourceLoc(), + "non-integer element type given to bitfieldInsert"); return; } String one; - switch(bitWidth) { - case 8: one = "uint8_t(1)"; break; - case 16: one = "uint16_t(1)"; break; - case 32: one = "uint32_t(1)"; break; - case 64: one = "uint64_t(1)"; break; - default: SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unexpected bit width"); + switch (bitWidth) + { + case 8: + one = "uint8_t(1)"; + break; + case 16: + one = "uint16_t(1)"; + break; + case 32: + one = "uint32_t(1)"; + break; + case 64: + one = "uint64_t(1)"; + break; + default: + SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unexpected bit width"); } m_writer->emit("(("); - + // emit clearedBase := uint(bse & ~(((1u<emit("&"); - emitVecNOrScalar(vectorType, [&]() - { - m_writer->emit("~(((" + one + "<<"); - emitOperand(bts, getInfo(EmitOp::General)); - m_writer->emit(")-" + one + ")<<"); - emitOperand(off, getInfo(EmitOp::General)); - m_writer->emit(")"); - }); - - + emitVecNOrScalar( + vectorType, + [&]() + { + m_writer->emit("~(((" + one + "<<"); + emitOperand(bts, getInfo(EmitOp::General)); + m_writer->emit(")-" + one + ")<<"); + emitOperand(off, getInfo(EmitOp::General)); + m_writer->emit(")"); + }); + // bitwise or clearedBase with maskedInsert m_writer->emit(")|("); // Emit maskedInsert := ((insert & ((1u << bits) - 1u)) << offset); - + // - first emit mask := (insert & ((1u << bits) - 1u)) m_writer->emit("("); emitOperand(ins, getInfo(EmitOp::General)); m_writer->emit("&"); - emitVecNOrScalar(vectorType, [&](){ - m_writer->emit("(" + one + "<<"); - emitOperand(bts, getInfo(EmitOp::General)); - m_writer->emit(")-" + one); - }); + emitVecNOrScalar( + vectorType, + [&]() + { + m_writer->emit("(" + one + "<<"); + emitOperand(bts, getInfo(EmitOp::General)); + m_writer->emit(")-" + one); + }); m_writer->emit(")"); // then emit shift := << offset m_writer->emit("<<"); - emitVecNOrScalar(vectorType, [&](){ - emitOperand(off, getInfo(EmitOp::General)); - }); + emitVecNOrScalar(vectorType, [&]() { emitOperand(off, getInfo(EmitOp::General)); }); m_writer->emit("))"); } diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h index 0e91643590..fc7f9a7f6a 100644 --- a/source/slang/slang-emit-c-like.h +++ b/source/slang/slang-emit-c-like.h @@ -615,7 +615,7 @@ class CLikeSourceEmitter : public SourceEmitterBase SLANG_UNUSED(baseName); } - bool tryGetIntInfo(IRType* elementType, bool &isSigned, int &bitWidth); + bool tryGetIntInfo(IRType* elementType, bool& isSigned, int& bitWidth); void emitVecNOrScalar(IRVectorType* vectorType, std::function func); virtual void emitBitfieldExtractImpl(IRInst* inst); virtual void emitBitfieldInsertImpl(IRInst* inst); diff --git a/source/slang/slang-emit-metal.cpp b/source/slang/slang-emit-metal.cpp index 55477fa5fd..59e894f8a7 100644 --- a/source/slang/slang-emit-metal.cpp +++ b/source/slang/slang-emit-metal.cpp @@ -919,7 +919,8 @@ bool MetalSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inO void MetalSourceEmitter::emitVectorTypeNameImpl(IRType* elementType, IRIntegerValue elementCount) { - // NM: Passing count here, as Metal 64-bit vector type names do not match their scalar equivalents. + // NM: Passing count here, as Metal 64-bit vector type names do not match their scalar + // equivalents. emitSimpleTypeKnowingCount(elementType, elementCount); switch (elementType->getOp()) @@ -1042,10 +1043,10 @@ void MetalSourceEmitter::emitParamTypeImpl(IRType* type, String const& name) void MetalSourceEmitter::emitSimpleTypeKnowingCount(IRType* type, IRIntegerValue elementCount) { - // NM: note, "ulong/ushort" is only type that works for i16/i64 vec, but can't be used for scalars. - // (See metal specification pg 26) + // NM: note, "ulong/ushort" is only type that works for i16/i64 vec, but can't be used for + // scalars. (See metal specification pg 26) - switch (type->getOp()) + switch (type->getOp()) { case kIROp_VoidType: case kIROp_BoolType: @@ -1063,7 +1064,7 @@ void MetalSourceEmitter::emitSimpleTypeKnowingCount(IRType* type, IRIntegerValue case kIROp_Int64Type: m_writer->emit("long"); return; - case kIROp_UInt64Type: + case kIROp_UInt64Type: if (elementCount > 1) m_writer->emit("ulong"); else @@ -1073,7 +1074,7 @@ void MetalSourceEmitter::emitSimpleTypeKnowingCount(IRType* type, IRIntegerValue m_writer->emit("short"); return; case kIROp_UInt16Type: - if (elementCount > 1) + if (elementCount > 1) m_writer->emit("ushort"); else m_writer->emit("uint16_t"); @@ -1082,7 +1083,7 @@ void MetalSourceEmitter::emitSimpleTypeKnowingCount(IRType* type, IRIntegerValue m_writer->emit("long"); return; case kIROp_UIntPtrType: - if (elementCount > 1) + if (elementCount > 1) m_writer->emit("ulong"); else m_writer->emit("uint64_t"); diff --git a/source/slang/slang-emit-metal.h b/source/slang/slang-emit-metal.h index 24805d3d0f..1872a2e353 100644 --- a/source/slang/slang-emit-metal.h +++ b/source/slang/slang-emit-metal.h @@ -55,7 +55,7 @@ class MetalSourceEmitter : public CLikeSourceEmitter IRPackOffsetDecoration* decoration) SLANG_OVERRIDE; void emitSimpleTypeKnowingCount(IRType* type, IRIntegerValue elementCount); - + virtual void emitMeshShaderModifiersImpl(IRInst* varInst) SLANG_OVERRIDE; virtual void emitSimpleTypeImpl(IRType* type) SLANG_OVERRIDE; virtual void emitParamTypeImpl(IRType* type, String const& name) SLANG_OVERRIDE; diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 17f9aec744..ec16a00be9 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -6527,17 +6527,24 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex auto dataType = inst->getDataType(); IRVectorType* vectorType = as(dataType); Slang::IRType* elementType = dataType; - if (vectorType) + if (vectorType) elementType = vectorType->getElementType(); const IntInfo i = getIntTypeInfo(elementType); - // NM: technically, using bitfield intrinsics for anything non-32-bit goes against - // VK specification: VUID-StandaloneSpirv-Base-04781. However, it works on at least - // NVIDIA HW. + // NM: technically, using bitfield intrinsics for anything non-32-bit goes against + // VK specification: VUID-StandaloneSpirv-Base-04781. However, it works on at least + // NVIDIA HW. SpvOp opcode = i.isSigned ? SpvOpBitFieldSExtract : SpvOpBitFieldUExtract; - return emitInst(parent, inst, opcode, inst->getFullType(), kResultID, - inst->getOperand(0), inst->getOperand(1), inst->getOperand(2)); + return emitInst( + parent, + inst, + opcode, + inst->getFullType(), + kResultID, + inst->getOperand(0), + inst->getOperand(1), + inst->getOperand(2)); } SpvInst* emitBitfieldInsert(SpvInstParent* parent, IRInst* inst) @@ -6545,20 +6552,28 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex auto dataType = inst->getDataType(); IRVectorType* vectorType = as(dataType); Slang::IRType* elementType = dataType; - if (vectorType) + if (vectorType) elementType = vectorType->getElementType(); const IntInfo i = getIntTypeInfo(elementType); - if (i.width == 64) + if (i.width == 64) requireSPIRVCapability(SpvCapabilityInt64); if (i.width == 16) requireSPIRVCapability(SpvCapabilityInt16); if (i.width == 8) requireSPIRVCapability(SpvCapabilityInt8); - return emitInst(parent, inst, SpvOpBitFieldInsert, inst->getFullType(), kResultID, - inst->getOperand(0), inst->getOperand(1), inst->getOperand(2), inst->getOperand(3)); + return emitInst( + parent, + inst, + SpvOpBitFieldInsert, + inst->getFullType(), + kResultID, + inst->getOperand(0), + inst->getOperand(1), + inst->getOperand(2), + inst->getOperand(3)); } template diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 630ed7ced0..56acde5f27 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -3894,7 +3894,7 @@ struct IRBuilder IRInst* emitGlobalValueRef(IRInst* globalInst); IRInst* emitBitfieldExtract(IRType* type, IRInst* op0, IRInst* op1, IRInst* op2); - + IRInst* emitBitfieldInsert(IRType* type, IRInst* op0, IRInst* op1, IRInst* op2, IRInst* op3); IRInst* emitPackAnyValue(IRType* type, IRInst* value); diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index 0a31180880..e030f21d4d 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -1938,29 +1938,30 @@ static T* createInst(IRBuilder* builder, IROp op, IRType* type, IRInst* arg1, IR } template -static T* createInst(IRBuilder* builder, IROp op, IRType* type, IRInst* arg1, IRInst* arg2, IRInst* arg3) +static T* createInst( + IRBuilder* builder, + IROp op, + IRType* type, + IRInst* arg1, + IRInst* arg2, + IRInst* arg3) { IRInst* args[] = {arg1, arg2, arg3}; return createInstImpl(builder, op, type, 3, &args[0]); } - + template static T* createInst( IRBuilder* builder, - IROp op, + IROp op, IRType* type, IRInst* arg1, IRInst* arg2, IRInst* arg3, IRInst* arg4) { - IRInst* args[] = { arg1, arg2, arg3, arg4 }; - return createInstImpl( - builder, - op, - type, - 4, - &args[0]); + IRInst* args[] = {arg1, arg2, arg3, arg4}; + return createInstImpl(builder, op, type, 4, &args[0]); } template @@ -3637,7 +3638,7 @@ IRInst* IRBuilder::emitLookupInterfaceMethodInst( IRInst* IRBuilder::emitGetSequentialIDInst(IRInst* rttiObj) { - auto inst = createInst(this, kIROp_GetSequentialID, getUIntType(), rttiObj); + auto inst = createInst(this, kIROp_GetSequentialID, getUIntType(), rttiObj); addInst(inst); return inst; } @@ -3649,7 +3650,12 @@ IRInst* IRBuilder::emitBitfieldExtract(IRType* type, IRInst* value, IRInst* offs return inst; } -IRInst* IRBuilder::emitBitfieldInsert(IRType* type, IRInst* base, IRInst* insert, IRInst* offset, IRInst* bits) +IRInst* IRBuilder::emitBitfieldInsert( + IRType* type, + IRInst* base, + IRInst* insert, + IRInst* offset, + IRInst* bits) { auto inst = createInst(this, kIROp_BitfieldInsert, type, base, insert, offset, bits); addInst(inst);