summaryrefslogtreecommitdiff
path: root/source/slang/slang-emit-hlsl.cpp
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/slang/slang-emit-hlsl.cpp
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/slang/slang-emit-hlsl.cpp')
-rw-r--r--source/slang/slang-emit-hlsl.cpp37
1 files changed, 28 insertions, 9 deletions
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));