summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorkaizhangNV <149626564+kaizhangNV@users.noreply.github.com>2024-12-17 19:06:30 -0600
committerGitHub <noreply@github.com>2024-12-17 17:06:30 -0800
commit6f57e47a9e1675b011f023277b47cfc768d30da8 (patch)
treeed9d531c1e1e4f55650314956c485d5107130a21 /source
parent49e912a9d0d6ca5f762ec11cd8cb918f182eb76e (diff)
Implement bitcast for 64-bit date type (#5895)
Close #5470 * implement bitcast for 64-bit date type * Move 'ensurePrelude' to base class to remove duplication * Assert on 'double' type for Metal target, as Metal doesn't have 'double' support
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-c-like.cpp11
-rw-r--r--source/slang/slang-emit-c-like.h5
-rw-r--r--source/slang/slang-emit-glsl.cpp26
-rw-r--r--source/slang/slang-emit-hlsl.cpp37
-rw-r--r--source/slang/slang-emit-metal.cpp16
-rw-r--r--source/slang/slang-emit-metal.h4
-rw-r--r--source/slang/slang-emit-wgsl.cpp12
-rw-r--r--source/slang/slang-emit-wgsl.h4
8 files changed, 73 insertions, 42 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index f38adc67e..b70069d42 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -5137,4 +5137,15 @@ void CLikeSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
executeEmitActions(actions);
}
+void CLikeSourceEmitter::ensurePrelude(const char* preludeText)
+{
+ IRStringLit* stringLit;
+ if (!m_builtinPreludes.tryGetValue(preludeText, stringLit))
+ {
+ IRBuilder builder(m_irModule);
+ stringLit = builder.getStringValue(UnownedStringSlice(preludeText));
+ m_builtinPreludes[preludeText] = stringLit;
+ }
+ m_requiredPreludes.add(stringLit);
+}
} // namespace Slang
diff --git a/source/slang/slang-emit-c-like.h b/source/slang/slang-emit-c-like.h
index 7f6f32923..dd8e27674 100644
--- a/source/slang/slang-emit-c-like.h
+++ b/source/slang/slang-emit-c-like.h
@@ -678,6 +678,9 @@ protected:
String _emitLiteralOneWithType(int bitWidth);
+
+ virtual void ensurePrelude(const char* preludeText);
+
CodeGenContext* m_codeGenContext = nullptr;
IRModule* m_irModule = nullptr;
@@ -723,6 +726,8 @@ protected:
{
String requireComputeDerivatives;
} m_requiredAfter;
+
+ Dictionary<const char*, IRStringLit*> m_builtinPreludes;
};
} // namespace Slang
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 2c2447c53..d6f3795e3 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -2030,6 +2030,32 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
emitType(inst->getDataType());
}
break;
+ case BaseType::Int64:
+ if (fromType == BaseType::Double)
+ {
+ m_writer->emit("int64_t(doubleBitsToInt64(");
+ emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
+ m_writer->emit("))");
+ return true;
+ }
+ else
+ {
+ emitType(inst->getDataType());
+ }
+ break;
+ case BaseType::UInt64:
+ if (fromType == BaseType::Double)
+ {
+ m_writer->emit("uint64_t(doubleBitsToUint64(");
+ emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
+ m_writer->emit("))");
+ return true;
+ }
+ else
+ {
+ emitType(inst->getDataType());
+ }
+ break;
case BaseType::Half:
switch (fromType)
{
diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp
index 824680b72..c43f075b2 100644
--- a/source/slang/slang-emit-hlsl.cpp
+++ b/source/slang/slang-emit-hlsl.cpp
@@ -11,6 +11,23 @@
namespace Slang
{
+static const char* kHLSLBuiltInPrelude64BitCast = R"(
+uint64_t _slang_asuint64(double x)
+{
+ uint32_t low;
+ uint32_t high;
+ asuint(x, low, high);
+ return ((uint64_t)high << 32) | low;
+}
+
+double _slang_asdouble(uint64_t x)
+{
+ uint32_t low = x & 0xFFFFFFFF;
+ uint32_t high = x >> 32;
+ return asdouble(low, high);
+}
+)";
+
void HLSLSourceEmitter::_emitHLSLDecorationSingleString(
const char* name,
IRFunc* entryPoint,
@@ -822,17 +839,12 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
//
// There is no current function (it seems)
// for bit-casting an `int16_t` to a `half`.
- //
- // TODO: There is an `asdouble` function
- // for converting two 32-bit integer values into
- // one `double`. We could use that for
- // bit casts of 64-bit values with a bit of
- // extra work, but doing so might be best
- // handled in an IR pass that legalizes
- // bit-casts.
- //
m_writer->emit("asfloat");
break;
+ case BaseType::Double:
+ ensurePrelude(kHLSLBuiltInPrelude64BitCast);
+ m_writer->emit("_slang_asdouble");
+ break;
}
m_writer->emit("(");
int closeCount = 1;
@@ -844,6 +856,8 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
diagnoseUnhandledInst(inst);
break;
+ case BaseType::Int64:
+ case BaseType::UInt64:
case BaseType::UInt:
case BaseType::Int:
case BaseType::Bool:
@@ -860,6 +874,11 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
m_writer->emit("asuint16(");
closeCount++;
break;
+ case BaseType::Double:
+ ensurePrelude(kHLSLBuiltInPrelude64BitCast);
+ m_writer->emit("_slang_asuint64(");
+ closeCount++;
+ break;
}
emitOperand(inst->getOperand(0), getInfo(EmitOp::General));
diff --git a/source/slang/slang-emit-metal.cpp b/source/slang/slang-emit-metal.cpp
index 45a9e60ad..282d8f95c 100644
--- a/source/slang/slang-emit-metal.cpp
+++ b/source/slang/slang-emit-metal.cpp
@@ -263,18 +263,6 @@ void MetalSourceEmitter::emitEntryPointAttributesImpl(
}
}
-void MetalSourceEmitter::ensurePrelude(const char* preludeText)
-{
- IRStringLit* stringLit;
- if (!m_builtinPreludes.tryGetValue(preludeText, stringLit))
- {
- IRBuilder builder(m_irModule);
- stringLit = builder.getStringValue(UnownedStringSlice(preludeText));
- m_builtinPreludes[preludeText] = stringLit;
- }
- m_requiredPreludes.add(stringLit);
-}
-
void MetalSourceEmitter::emitMemoryOrderOperand(IRInst* inst)
{
auto memoryOrder = (IRMemoryOrder)getIntVal(inst);
@@ -1065,7 +1053,6 @@ void MetalSourceEmitter::emitSimpleTypeImpl(IRType* type)
case kIROp_UInt8Type:
case kIROp_UIntType:
case kIROp_FloatType:
- case kIROp_DoubleType:
case kIROp_HalfType:
{
m_writer->emit(getDefaultBuiltinTypeName(type->getOp()));
@@ -1093,6 +1080,9 @@ void MetalSourceEmitter::emitSimpleTypeImpl(IRType* type)
m_writer->emit(getName(type));
return;
+ case kIROp_DoubleType:
+ SLANG_UNEXPECTED("'double' type emitted");
+ return;
case kIROp_VectorType:
{
auto vecType = (IRVectorType*)type;
diff --git a/source/slang/slang-emit-metal.h b/source/slang/slang-emit-metal.h
index 17562b1c4..b67a5b801 100644
--- a/source/slang/slang-emit-metal.h
+++ b/source/slang/slang-emit-metal.h
@@ -22,13 +22,9 @@ public:
virtual RefObject* getExtensionTracker() SLANG_OVERRIDE { return m_extensionTracker; }
- Dictionary<const char*, IRStringLit*> m_builtinPreludes;
-
protected:
RefPtr<MetalExtensionTracker> m_extensionTracker;
- void ensurePrelude(const char* preludeText);
-
void emitMemoryOrderOperand(IRInst* inst);
virtual void emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type)
SLANG_OVERRIDE;
diff --git a/source/slang/slang-emit-wgsl.cpp b/source/slang/slang-emit-wgsl.cpp
index 0e45fd4cf..da5e38327 100644
--- a/source/slang/slang-emit-wgsl.cpp
+++ b/source/slang/slang-emit-wgsl.cpp
@@ -49,18 +49,6 @@ fn _slang_getNan() -> f32
}
)";
-void WGSLSourceEmitter::ensurePrelude(const char* preludeText)
-{
- IRStringLit* stringLit;
- if (!m_builtinPreludes.tryGetValue(preludeText, stringLit))
- {
- IRBuilder builder(m_irModule);
- stringLit = builder.getStringValue(UnownedStringSlice(preludeText));
- m_builtinPreludes[preludeText] = stringLit;
- }
- m_requiredPreludes.add(stringLit);
-}
-
void WGSLSourceEmitter::emitSwitchCaseSelectorsImpl(
const SwitchRegion::Case* const currentCase,
const bool isDefault)
diff --git a/source/slang/slang-emit-wgsl.h b/source/slang/slang-emit-wgsl.h
index 28311aa27..390ee876d 100644
--- a/source/slang/slang-emit-wgsl.h
+++ b/source/slang/slang-emit-wgsl.h
@@ -57,10 +57,6 @@ public:
void emit(const AddressSpace addressSpace);
virtual bool shouldFoldInstIntoUseSites(IRInst* inst) SLANG_OVERRIDE;
- Dictionary<const char*, IRStringLit*> m_builtinPreludes;
-
-protected:
- void ensurePrelude(const char* preludeText);
private:
bool maybeEmitSystemSemantic(IRInst* inst);