summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/LowerInt64.cpp53
1 files changed, 50 insertions, 3 deletions
diff --git a/src/passes/LowerInt64.cpp b/src/passes/LowerInt64.cpp
index 79b053d44..9e3760613 100644
--- a/src/passes/LowerInt64.cpp
+++ b/src/passes/LowerInt64.cpp
@@ -20,6 +20,8 @@
// This is useful for wasm2asm, as JS has no native 64-bit integer support.
//
+#include <memory>
+
#include <wasm.h>
#include <pass.h>
@@ -29,13 +31,17 @@ cashew::IString GET_HIGH("getHigh");
struct LowerInt64 : public Pass {
MixedArena* allocator;
-
- std::map<Expression*, Expression*> fixes; // fixed nodes, outputs of lowering, mapped to their high bits
+ std::unique_ptr<NameManager> namer;
void prepare(PassRunner* runner, Module *module) override {
allocator = runner->allocator;
+ namer = std::unique_ptr<NameManager>(new NameManager());
+ namer->run(runner, module);
}
+ std::map<Expression*, Expression*> fixes; // fixed nodes, outputs of lowering, mapped to their high bits
+ std::map<Name, Name> locals; // maps locals which were i64->i32 to their high bits
+
void makeGetHigh() {
auto ret = allocator->alloc<CallImport>();
ret->target = GET_HIGH;
@@ -53,7 +59,7 @@ struct LowerInt64 : public Pass {
}
if (curr->type == i64) {
curr->type = i32;
- fixes[curr] = makeGetHigh();
+ fixes[curr] = makeGetHigh(); // called function will setHigh
}
}
@@ -67,8 +73,49 @@ struct LowerInt64 : public Pass {
fixCall(curr);
}
void visitGetLocal(GetLocal *curr) override {
+ if (curr->type == i64) {
+ if (locals.count(curr->name) == 0) {
+ Name highName = namer->getUnique("high");
+ locals[curr->name] = highName;
+ };
+ curr->type = i32;
+ auto high = allocator->alloc<GetLocal>();
+ high->name = locals[curr->name];
+ high->type = i32;
+ fixes[curr] = high;
+ }
}
void visitSetLocal(SetLocal *curr) override {
+ if (curr->type == i64) {
+ Name highName;
+ if (locals.count(curr->name) == 0) {
+ highName = namer->getUnique("high");
+ locals[curr->name] = highName;
+ } else {
+ highName = locals[curr->name];
+ }
+ curr->type = i32;
+ auto high = allocator->alloc<GetLocal>();
+ high->name = highName;
+ high->type = i32;
+ fixes[curr] = high;
+ // Set the high bits
+ auto set = allocator.alloc<SetLocal>();
+ set->name = highName;
+ set->value = fixes[curr->value];
+ set->type = i32;
+ assert(set->value);
+ auto low = allocator->alloc<GetLocal>();
+ low->name = curr->name;
+ low->type = i32;
+ auto ret = allocator.alloc<Block>();
+ ret->list.push_back(curr);
+ ret->list.push_back(set);
+ ret->list.push_back(low); // so the block returns the low bits
+ ret->type = i32;
+ fixes[ret] = high;
+ replaceCurrent(ret);
+ }
}
void visitLoad(Load *curr) override {
}