summaryrefslogtreecommitdiff
path: root/src/passes/I64ToI32Lowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes/I64ToI32Lowering.cpp')
-rw-r--r--src/passes/I64ToI32Lowering.cpp40
1 files changed, 28 insertions, 12 deletions
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index ae69ec19d..208aac9ea 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -600,16 +600,17 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
// our f64 through memory at address 0
TempVar highBits = getTemp();
Block *result = builder->blockify(
- builder->makeStore(8, 0, 8, builder->makeConst(Literal(int32_t(0))), curr->value, f64),
+ builder->makeStore(8, 0, 8, makeGetTempMemory(), curr->value, f64),
builder->makeSetLocal(
highBits,
- builder->makeLoad(4, true, 4, 4, builder->makeConst(Literal(int32_t(0))), i32)
+ builder->makeLoad(4, true, 4, 4, makeGetTempMemory(), i32)
),
- builder->makeLoad(4, true, 0, 4, builder->makeConst(Literal(int32_t(0))), i32)
+ builder->makeLoad(4, true, 0, 4, makeGetTempMemory(), i32)
);
setOutParam(result, std::move(highBits));
replaceCurrent(result);
- ensureMinimalMemory();
+ MemoryUtils::ensureExists(getModule()->memory);
+ ensureTempMemoryGlobal();
}
void lowerReinterpretInt64(Unary* curr) {
@@ -617,18 +618,33 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
// our i64 through memory at address 0
TempVar highBits = fetchOutParam(curr->value);
Block *result = builder->blockify(
- builder->makeStore(4, 0, 4, builder->makeConst(Literal(int32_t(0))), curr->value, i32),
- builder->makeStore(4, 4, 4, builder->makeConst(Literal(int32_t(0))), builder->makeGetLocal(highBits, i32), i32),
- builder->makeLoad(8, true, 0, 8, builder->makeConst(Literal(int32_t(0))), f64)
+ builder->makeStore(4, 0, 4, makeGetTempMemory(), curr->value, i32),
+ builder->makeStore(4, 4, 4, makeGetTempMemory(), builder->makeGetLocal(highBits, i32), i32),
+ builder->makeLoad(8, true, 0, 8, makeGetTempMemory(), f64)
);
replaceCurrent(result);
- ensureMinimalMemory();
+ MemoryUtils::ensureExists(getModule()->memory);
+ ensureTempMemoryGlobal();
}
- // Ensure memory exists with a minimal size, enough for round-tripping operations on
- // address 0, which we need for reinterpret operations.
- void ensureMinimalMemory() {
- MemoryUtils::ensureExists(getModule()->memory);
+ Name tempMemory = "__tempMemory__";
+
+ void ensureTempMemoryGlobal() {
+ // Ensure the existence of an imported global, __tempMemory__, which points to 8
+ // bytes of scratch memory we can use for roundtrip purposes.
+ if (!getModule()->getGlobalOrNull(tempMemory)) {
+ auto global = make_unique<Global>();
+ global->name = tempMemory;
+ global->type = i32;
+ global->mutable_ = false;
+ global->module = ENV;
+ global->base = tempMemory;
+ getModule()->addGlobal(global.release());
+ }
+ }
+
+ Expression* makeGetTempMemory() {
+ return builder->makeGetGlobal(tempMemory, i32);
}
void lowerTruncFloatToInt(Unary *curr) {