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.cpp1170
1 files changed, 550 insertions, 620 deletions
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index 731b42d3a..e2d3cc414 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -21,32 +21,31 @@
// global.
//
-#include <algorithm>
-#include "wasm.h"
-#include "pass.h"
-#include "emscripten-optimizer/istring.h"
-#include "support/name.h"
-#include "wasm-builder.h"
#include "abi/js.h"
+#include "asmjs/shared-constants.h"
+#include "emscripten-optimizer/istring.h"
#include "ir/flat.h"
#include "ir/iteration.h"
#include "ir/memory-utils.h"
#include "ir/module-utils.h"
#include "ir/names.h"
-#include "asmjs/shared-constants.h"
+#include "pass.h"
+#include "support/name.h"
+#include "wasm-builder.h"
+#include "wasm.h"
+#include <algorithm>
namespace wasm {
-static Name makeHighName(Name n) {
- return std::string(n.c_str()) + "$hi";
-}
+static Name makeHighName(Name n) { return std::string(n.c_str()) + "$hi"; }
struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
struct TempVar {
- TempVar(Index idx, Type ty, I64ToI32Lowering& pass) :
- idx(idx), pass(pass), moved(false), ty(ty) {}
+ TempVar(Index idx, Type ty, I64ToI32Lowering& pass)
+ : idx(idx), pass(pass), moved(false), ty(ty) {}
- TempVar(TempVar&& other) : idx(other), pass(other.pass), moved(false), ty(other.ty) {
+ TempVar(TempVar&& other)
+ : idx(other), pass(other.pass), moved(false), ty(other.ty) {
assert(!other.moved);
other.moved = true;
}
@@ -54,7 +53,8 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
TempVar& operator=(TempVar&& rhs) {
assert(!rhs.moved);
// free overwritten idx
- if (!moved) freeIdx();
+ if (!moved)
+ freeIdx();
idx = rhs.idx;
rhs.moved = true;
moved = false;
@@ -62,7 +62,8 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
~TempVar() {
- if (!moved) freeIdx();
+ if (!moved)
+ freeIdx();
}
bool operator==(const TempVar& rhs) {
@@ -81,8 +82,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
private:
void freeIdx() {
- auto &freeList = pass.freeTemps[(int) ty];
- assert(std::find(freeList.begin(), freeList.end(), idx) == freeList.end());
+ auto& freeList = pass.freeTemps[(int)ty];
+ assert(std::find(freeList.begin(), freeList.end(), idx) ==
+ freeList.end());
freeList.push_back(idx);
}
@@ -96,19 +98,22 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
// TODO: allow module-level transformations in parallel passes
bool isFunctionParallel() override { return false; }
- Pass* create() override {
- return new I64ToI32Lowering;
- }
+ Pass* create() override { return new I64ToI32Lowering; }
void doWalkModule(Module* module) {
- if (!builder) builder = make_unique<Builder>(*module);
+ if (!builder)
+ builder = make_unique<Builder>(*module);
// add new globals for high bits
for (size_t i = 0, globals = module->globals.size(); i < globals; ++i) {
auto* curr = module->globals[i].get();
- if (curr->type != i64) continue;
+ if (curr->type != i64)
+ continue;
originallyI64Globals.insert(curr->name);
curr->type = i32;
- auto* high = builder->makeGlobal(makeHighName(curr->name), i32, builder->makeConst(Literal(int32_t(0))), Builder::Mutable);
+ auto* high = builder->makeGlobal(makeHighName(curr->name),
+ i32,
+ builder->makeConst(Literal(int32_t(0))),
+ Builder::Mutable);
module->addGlobal(high);
if (curr->imported()) {
Fatal() << "TODO: imported i64 globals";
@@ -157,7 +162,8 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
void doWalkFunction(Function* func) {
Flat::verifyFlatness(func);
// create builder here if this is first entry to module for this object
- if (!builder) builder = make_unique<Builder>(*getModule());
+ if (!builder)
+ builder = make_unique<Builder>(*getModule());
indexMap.clear();
highBitVars.clear();
freeTemps.clear();
@@ -174,9 +180,10 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
Name lowName = oldFunc->getLocalName(i);
Name highName = makeHighName(lowName);
Type paramType = oldFunc->getLocalType(i);
- auto builderFunc = (i < oldFunc->getVarIndexBase()) ?
- Builder::addParam :
- static_cast<Index (*)(Function*, Name, Type)>(Builder::addVar);
+ auto builderFunc =
+ (i < oldFunc->getVarIndexBase())
+ ? Builder::addParam
+ : static_cast<Index (*)(Function*, Name, Type)>(Builder::addVar);
if (paramType == i64) {
builderFunc(func, lowName, i32);
builderFunc(func, highName, i32);
@@ -201,14 +208,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
if (hasOutParam(func->body)) {
TempVar highBits = fetchOutParam(func->body);
TempVar lowBits = getTemp();
- SetLocal* setLow = builder->makeSetLocal(
- lowBits,
- func->body
- );
+ SetLocal* setLow = builder->makeSetLocal(lowBits, func->body);
SetGlobal* setHigh = builder->makeSetGlobal(
- INT64_TO_32_HIGH_BITS,
- builder->makeGetLocal(highBits, i32)
- );
+ INT64_TO_32_HIGH_BITS, builder->makeGetLocal(highBits, i32));
GetLocal* getLow = builder->makeGetLocal(lowBits, i32);
func->body = builder->blockify(setLow, setHigh, getLow);
}
@@ -223,7 +225,8 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
template<typename T>
using BuilderFunc = std::function<T*(std::vector<Expression*>&, Type)>;
- // Fixes up a call. If we performed fixups, returns the call; otherwise returns nullptr;
+ // Fixes up a call. If we performed fixups, returns the call; otherwise
+ // returns nullptr;
template<typename T>
T* visitGenericCall(T* curr, BuilderFunc<T> callBuilder) {
bool fixed = false;
@@ -233,7 +236,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
if (hasOutParam(e)) {
TempVar argHighBits = fetchOutParam(e);
args.push_back(builder->makeGetLocal(argHighBits, i32));
- fixed = true;
+ fixed = true;
}
}
if (curr->type != i64) {
@@ -244,14 +247,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
TempVar lowBits = getTemp();
TempVar highBits = getTemp();
auto* call = callBuilder(args, i32);
- SetLocal* doCall = builder->makeSetLocal(
- lowBits,
- call
- );
+ SetLocal* doCall = builder->makeSetLocal(lowBits, call);
SetLocal* setHigh = builder->makeSetLocal(
- highBits,
- builder->makeGetGlobal(INT64_TO_32_HIGH_BITS, i32)
- );
+ highBits, builder->makeGetGlobal(INT64_TO_32_HIGH_BITS, i32));
GetLocal* getLow = builder->makeGetLocal(lowBits, i32);
Block* result = builder->blockify(doCall, setHigh, getLow);
setOutParam(result, std::move(highBits));
@@ -260,11 +258,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitCall(Call* curr) {
auto* fixedCall = visitGenericCall<Call>(
- curr,
- [&](std::vector<Expression*>& args, Type ty) {
+ curr, [&](std::vector<Expression*>& args, Type ty) {
return builder->makeCall(curr->target, args, ty);
- }
- );
+ });
// If this was to an import, we need to call the legal version. This assumes
// that legalize-js-interface has been run before.
if (fixedCall && getModule()->getFunction(fixedCall->target)->imported()) {
@@ -275,16 +271,10 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
void visitCallIndirect(CallIndirect* curr) {
visitGenericCall<CallIndirect>(
- curr,
- [&](std::vector<Expression*>& args, Type ty) {
+ curr, [&](std::vector<Expression*>& args, Type ty) {
return builder->makeCallIndirect(
- curr->fullType,
- curr->target,
- args,
- ty
- );
- }
- );
+ curr->fullType, curr->target, args, ty);
+ });
}
void visitGetLocal(GetLocal* curr) {
@@ -297,13 +287,8 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
curr->type = i32;
TempVar highBits = getTemp();
- SetLocal *setHighBits = builder->makeSetLocal(
- highBits,
- builder->makeGetLocal(
- mappedIndex + 1,
- i32
- )
- );
+ SetLocal* setHighBits = builder->makeSetLocal(
+ highBits, builder->makeGetLocal(mappedIndex + 1, i32));
Block* result = builder->blockify(setHighBits, curr);
replaceCurrent(result);
setOutParam(result, std::move(highBits));
@@ -315,9 +300,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
curr->type = i32;
SetLocal* setLow = builder->makeSetLocal(tmp, curr);
SetLocal* setHigh = builder->makeSetLocal(
- curr->index + 1,
- builder->makeGetLocal(highBits, i32)
- );
+ curr->index + 1, builder->makeGetLocal(highBits, i32));
GetLocal* getLow = builder->makeGetLocal(tmp, i32);
Block* result = builder->blockify(setLow, setHigh, getLow);
replaceCurrent(result);
@@ -337,44 +320,40 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
return;
}
TempVar highBits = fetchOutParam(curr->value);
- auto* setHigh = builder->makeSetLocal(
- mappedIndex + 1,
- builder->makeGetLocal(highBits, i32)
- );
+ auto* setHigh = builder->makeSetLocal(mappedIndex + 1,
+ builder->makeGetLocal(highBits, i32));
Block* result = builder->blockify(curr, setHigh);
replaceCurrent(result);
}
void visitGetGlobal(GetGlobal* curr) {
- if (!getFunction()) return; // if in a global init, skip - we already handled that.
- if (!originallyI64Globals.count(curr->name)) return;
+ if (!getFunction())
+ return; // if in a global init, skip - we already handled that.
+ if (!originallyI64Globals.count(curr->name))
+ return;
curr->type = i32;
TempVar highBits = getTemp();
- SetLocal *setHighBits = builder->makeSetLocal(
- highBits,
- builder->makeGetGlobal(
- makeHighName(curr->name),
- i32
- )
- );
+ SetLocal* setHighBits = builder->makeSetLocal(
+ highBits, builder->makeGetGlobal(makeHighName(curr->name), i32));
Block* result = builder->blockify(setHighBits, curr);
replaceCurrent(result);
setOutParam(result, std::move(highBits));
}
void visitSetGlobal(SetGlobal* curr) {
- if (!originallyI64Globals.count(curr->name)) return;
- if (handleUnreachable(curr)) return;
+ if (!originallyI64Globals.count(curr->name))
+ return;
+ if (handleUnreachable(curr))
+ return;
TempVar highBits = fetchOutParam(curr->value);
auto* setHigh = builder->makeSetGlobal(
- makeHighName(curr->name),
- builder->makeGetLocal(highBits, i32)
- );
+ makeHighName(curr->name), builder->makeGetLocal(highBits, i32));
replaceCurrent(builder->makeSequence(curr, setHigh));
}
void visitLoad(Load* curr) {
- if (curr->type != i64) return;
+ if (curr->type != i64)
+ return;
assert(!curr->isAtomic && "atomic load not implemented");
TempVar lowBits = getTemp();
TempVar highBits = getTemp();
@@ -384,46 +363,37 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
if (curr->bytes == 8) {
loadHigh = builder->makeSetLocal(
highBits,
- builder->makeLoad(
- 4,
- curr->signed_,
- curr->offset + 4,
- 1,
- builder->makeGetLocal(ptrTemp, i32),
- i32
- )
- );
+ builder->makeLoad(4,
+ curr->signed_,
+ curr->offset + 4,
+ 1,
+ builder->makeGetLocal(ptrTemp, i32),
+ i32));
} else if (curr->signed_) {
loadHigh = builder->makeSetLocal(
highBits,
- builder->makeBinary(
- ShrSInt32,
- builder->makeGetLocal(lowBits, i32),
- builder->makeConst(Literal(int32_t(31)))
- )
- );
+ builder->makeBinary(ShrSInt32,
+ builder->makeGetLocal(lowBits, i32),
+ builder->makeConst(Literal(int32_t(31)))));
} else {
- loadHigh = builder->makeSetLocal(
- highBits,
- builder->makeConst(Literal(int32_t(0)))
- );
+ loadHigh = builder->makeSetLocal(highBits,
+ builder->makeConst(Literal(int32_t(0))));
}
curr->type = i32;
curr->bytes = std::min(curr->bytes, uint8_t(4));
curr->align = std::min(uint32_t(curr->align), uint32_t(4));
curr->ptr = builder->makeGetLocal(ptrTemp, i32);
- Block* result = builder->blockify(
- setPtr,
- builder->makeSetLocal(lowBits, curr),
- loadHigh,
- builder->makeGetLocal(lowBits, i32)
- );
+ Block* result = builder->blockify(setPtr,
+ builder->makeSetLocal(lowBits, curr),
+ loadHigh,
+ builder->makeGetLocal(lowBits, i32));
replaceCurrent(result);
setOutParam(result, std::move(highBits));
}
void visitStore(Store* curr) {
- if (!hasOutParam(curr->value)) return;
+ if (!hasOutParam(curr->value))
+ return;
assert(curr->offset + 4 > curr->offset);
assert(!curr->isAtomic && "atomic store not implemented");
TempVar highBits = fetchOutParam(curr->value);
@@ -436,14 +406,13 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
SetLocal* setPtr = builder->makeSetLocal(ptrTemp, curr->ptr);
curr->ptr = builder->makeGetLocal(ptrTemp, i32);
curr->finalize();
- Store* storeHigh = builder->makeStore(
- 4,
- curr->offset + 4,
- 1,
- builder->makeGetLocal(ptrTemp, i32),
- builder->makeGetLocal(highBits, i32),
- i32
- );
+ Store* storeHigh =
+ builder->makeStore(4,
+ curr->offset + 4,
+ 1,
+ builder->makeGetLocal(ptrTemp, i32),
+ builder->makeGetLocal(highBits, i32),
+ i32);
replaceCurrent(builder->blockify(setPtr, curr, storeHigh));
}
}
@@ -457,18 +426,17 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitConst(Const* curr) {
- if (!getFunction()) return; // if in a global init, skip - we already handled that.
- if (curr->type != i64) return;
+ if (!getFunction())
+ return; // if in a global init, skip - we already handled that.
+ if (curr->type != i64)
+ return;
TempVar highBits = getTemp();
- Const* lowVal = builder->makeConst(
- Literal(int32_t(curr->value.geti64() & 0xffffffff))
- );
- SetLocal* setHigh = builder->makeSetLocal(
- highBits,
- builder->makeConst(
- Literal(int32_t(uint64_t(curr->value.geti64()) >> 32))
- )
- );
+ Const* lowVal =
+ builder->makeConst(Literal(int32_t(curr->value.geti64() & 0xffffffff)));
+ SetLocal* setHigh =
+ builder->makeSetLocal(highBits,
+ builder->makeConst(Literal(
+ int32_t(uint64_t(curr->value.geti64()) >> 32))));
Block* result = builder->blockify(setHigh, lowVal);
setOutParam(result, std::move(highBits));
replaceCurrent(result);
@@ -480,11 +448,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
auto* result = builder->makeUnary(
EqZInt32,
builder->makeBinary(
- OrInt32,
- curr->value,
- builder->makeGetLocal(highBits, i32)
- )
- );
+ OrInt32, curr->value, builder->makeGetLocal(highBits, i32)));
replaceCurrent(result);
}
@@ -493,8 +457,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
TempVar highBits = getTemp();
Block* result = builder->blockify(
builder->makeSetLocal(highBits, builder->makeConst(Literal(int32_t(0)))),
- curr->value
- );
+ curr->value);
setOutParam(result, std::move(highBits));
replaceCurrent(result);
}
@@ -506,18 +469,12 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
SetLocal* setLow = builder->makeSetLocal(lowBits, curr->value);
SetLocal* setHigh = builder->makeSetLocal(
highBits,
- builder->makeBinary(
- ShrSInt32,
- builder->makeGetLocal(lowBits, i32),
- builder->makeConst(Literal(int32_t(31)))
- )
- );
+ builder->makeBinary(ShrSInt32,
+ builder->makeGetLocal(lowBits, i32),
+ builder->makeConst(Literal(int32_t(31)))));
- Block* result = builder->blockify(
- setLow,
- setHigh,
- builder->makeGetLocal(lowBits, i32)
- );
+ Block* result =
+ builder->blockify(setLow, setHigh, builder->makeGetLocal(lowBits, i32));
setOutParam(result, std::move(highBits));
replaceCurrent(result);
@@ -533,14 +490,16 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
// Assume that the wasm file assumes the address 0 is invalid and roundtrip
// our f64 through memory at address 0
TempVar highBits = getTemp();
- Block *result = builder->blockify(
- builder->makeCall(ABI::wasm2js::SCRATCH_STORE_F64, { curr->value }, none),
+ Block* result = builder->blockify(
+ builder->makeCall(ABI::wasm2js::SCRATCH_STORE_F64, {curr->value}, none),
builder->makeSetLocal(
highBits,
- builder->makeCall(ABI::wasm2js::SCRATCH_LOAD_I32, { builder->makeConst(Literal(int32_t(1))) }, i32)
- ),
- builder->makeCall(ABI::wasm2js::SCRATCH_LOAD_I32, { builder->makeConst(Literal(int32_t(0))) }, i32)
- );
+ builder->makeCall(ABI::wasm2js::SCRATCH_LOAD_I32,
+ {builder->makeConst(Literal(int32_t(1)))},
+ i32)),
+ builder->makeCall(ABI::wasm2js::SCRATCH_LOAD_I32,
+ {builder->makeConst(Literal(int32_t(0)))},
+ i32));
setOutParam(result, std::move(highBits));
replaceCurrent(result);
MemoryUtils::ensureExists(getModule()->memory);
@@ -551,17 +510,21 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
// Assume that the wasm file assumes the address 0 is invalid and roundtrip
// our i64 through memory at address 0
TempVar highBits = fetchOutParam(curr->value);
- Block *result = builder->blockify(
- builder->makeCall(ABI::wasm2js::SCRATCH_STORE_I32, { builder->makeConst(Literal(int32_t(0))), curr->value }, none),
- builder->makeCall(ABI::wasm2js::SCRATCH_STORE_I32, { builder->makeConst(Literal(int32_t(1))), builder->makeGetLocal(highBits, i32) }, none),
- builder->makeCall(ABI::wasm2js::SCRATCH_LOAD_F64, {}, f64)
- );
+ Block* result = builder->blockify(
+ builder->makeCall(ABI::wasm2js::SCRATCH_STORE_I32,
+ {builder->makeConst(Literal(int32_t(0))), curr->value},
+ none),
+ builder->makeCall(ABI::wasm2js::SCRATCH_STORE_I32,
+ {builder->makeConst(Literal(int32_t(1))),
+ builder->makeGetLocal(highBits, i32)},
+ none),
+ builder->makeCall(ABI::wasm2js::SCRATCH_LOAD_F64, {}, f64));
replaceCurrent(result);
MemoryUtils::ensureExists(getModule()->memory);
ABI::wasm2js::ensureScratchMemoryHelpers(getModule());
}
- void lowerTruncFloatToInt(Unary *curr) {
+ void lowerTruncFloatToInt(Unary* curr) {
// hiBits = if abs(f) >= 1.0 {
// if f > 0.0 {
// (unsigned) min(
@@ -584,9 +547,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
switch (curr->op) {
case TruncSFloat32ToInt64:
case TruncUFloat32ToInt64: {
- litZero = Literal((float) 0);
- litOne = Literal((float) 1);
- u32Max = Literal(((float) UINT_MAX) + 1);
+ litZero = Literal((float)0);
+ litOne = Literal((float)1);
+ u32Max = Literal(((float)UINT_MAX) + 1);
trunc = TruncUFloat32ToInt32;
convert = ConvertUInt32ToFloat32;
localType = f32;
@@ -602,9 +565,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
case TruncSFloat64ToInt64:
case TruncUFloat64ToInt64: {
- litZero = Literal((double) 0);
- litOne = Literal((double) 1);
- u32Max = Literal(((double) UINT_MAX) + 1);
+ litZero = Literal((double)0);
+ litOne = Literal((double)1);
+ u32Max = Literal(((double)UINT_MAX) + 1);
trunc = TruncUFloat64ToInt32;
convert = ConvertUInt32ToFloat64;
localType = f64;
@@ -618,74 +581,63 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
sub = SubFloat64;
break;
}
- default: abort();
+ default:
+ abort();
}
TempVar f = getTemp(localType);
TempVar highBits = getTemp();
- Expression *gtZeroBranch = builder->makeBinary(
- min,
- builder->makeUnary(
- floor,
- builder->makeBinary(
- div,
- builder->makeGetLocal(f, localType),
- builder->makeConst(u32Max)
- )
- ),
- builder->makeBinary(sub, builder->makeConst(u32Max), builder->makeConst(litOne))
- );
- Expression *ltZeroBranch = builder->makeUnary(
- ceil,
+ Expression* gtZeroBranch = builder->makeBinary(
+ min,
+ builder->makeUnary(
+ floor,
+ builder->makeBinary(div,
+ builder->makeGetLocal(f, localType),
+ builder->makeConst(u32Max))),
+ builder->makeBinary(
+ sub, builder->makeConst(u32Max), builder->makeConst(litOne)));
+ Expression* ltZeroBranch = builder->makeUnary(
+ ceil,
+ builder->makeBinary(
+ div,
builder->makeBinary(
- div,
- builder->makeBinary(
- sub,
- builder->makeGetLocal(f, localType),
- builder->makeUnary(convert,
- builder->makeUnary(trunc, builder->makeGetLocal(f, localType))
- )
- ),
- builder->makeConst(u32Max)
- )
- );
-
- If *highBitsCalc = builder->makeIf(
+ sub,
+ builder->makeGetLocal(f, localType),
+ builder->makeUnary(
+ convert,
+ builder->makeUnary(trunc, builder->makeGetLocal(f, localType)))),
+ builder->makeConst(u32Max)));
+
+ If* highBitsCalc = builder->makeIf(
builder->makeBinary(
- gt,
- builder-> makeGetLocal(f, localType),
- builder->makeConst(litZero)
- ),
+ gt, builder->makeGetLocal(f, localType), builder->makeConst(litZero)),
builder->makeUnary(trunc, gtZeroBranch),
- builder->makeUnary(trunc, ltZeroBranch)
- );
- If *highBitsVal = builder->makeIf(
+ builder->makeUnary(trunc, ltZeroBranch));
+ If* highBitsVal = builder->makeIf(
builder->makeBinary(
ge,
builder->makeUnary(abs, builder->makeGetLocal(f, localType)),
- builder->makeConst(litOne)
- ),
+ builder->makeConst(litOne)),
highBitsCalc,
- builder->makeConst(Literal(int32_t(0)))
- );
- Block *result = builder->blockify(
+ builder->makeConst(Literal(int32_t(0))));
+ Block* result = builder->blockify(
builder->makeSetLocal(f, curr->value),
builder->makeSetLocal(highBits, highBitsVal),
- builder->makeUnary(trunc, builder->makeGetLocal(f, localType))
- );
+ builder->makeUnary(trunc, builder->makeGetLocal(f, localType)));
setOutParam(result, std::move(highBits));
replaceCurrent(result);
}
- void lowerConvertIntToFloat(Unary *curr) {
+ void lowerConvertIntToFloat(Unary* curr) {
// Here the same strategy as `emcc` is taken which takes the two halves of
// the 64-bit integer and creates a mathematical expression using float
// arithmetic to reassemble the final floating point value.
//
// For example for i64 -> f32 we generate:
//
- // ((double) (unsigned) lowBits) + ((double) U32_MAX) * ((double) (int) highBits)
+ // ((double) (unsigned) lowBits) +
+ // ((double) U32_MAX) * ((double) (int) highBits)
//
// Mostly just shuffling things around here with coercions and whatnot!
// Note though that all arithmetic is done with f64 to have as much
@@ -704,31 +656,23 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
case ConvertUInt64ToFloat64:
convertHigh = ConvertUInt32ToFloat64;
break;
- default: abort();
+ default:
+ abort();
}
- Expression *result = builder->blockify(
+ Expression* result = builder->blockify(
builder->makeSetLocal(lowBits, curr->value),
- builder->makeSetLocal(
- highResult,
- builder->makeConst(Literal(int32_t(0)))
- ),
+ builder->makeSetLocal(highResult,
+ builder->makeConst(Literal(int32_t(0)))),
builder->makeBinary(
AddFloat64,
- builder->makeUnary(
- ConvertUInt32ToFloat64,
- builder->makeGetLocal(lowBits, i32)
- ),
+ builder->makeUnary(ConvertUInt32ToFloat64,
+ builder->makeGetLocal(lowBits, i32)),
builder->makeBinary(
MulFloat64,
builder->makeConst(Literal((double)UINT_MAX + 1)),
- builder->makeUnary(
- convertHigh,
- builder->makeGetLocal(highBits, i32)
- )
- )
- )
- );
+ builder->makeUnary(convertHigh,
+ builder->makeGetLocal(highBits, i32)))));
switch (curr->op) {
case ConvertSInt64ToFloat32:
@@ -736,52 +680,43 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
result = builder->makeUnary(DemoteFloat64, result);
break;
}
- default: break;
+ default:
+ break;
}
replaceCurrent(result);
}
void lowerCountZeros(Unary* curr) {
- auto lower = [&](Block* result, UnaryOp op32, TempVar&& first, TempVar&& second) {
+ auto lower = [&](Block* result,
+ UnaryOp op32,
+ TempVar&& first,
+ TempVar&& second) {
TempVar highResult = getTemp();
TempVar firstResult = getTemp();
SetLocal* setFirst = builder->makeSetLocal(
firstResult,
- builder->makeUnary(op32, builder->makeGetLocal(first, i32))
- );
+ builder->makeUnary(op32, builder->makeGetLocal(first, i32)));
- Binary* check = builder->makeBinary(
- EqInt32,
- builder->makeGetLocal(firstResult, i32),
- builder->makeConst(Literal(int32_t(32)))
- );
+ Binary* check =
+ builder->makeBinary(EqInt32,
+ builder->makeGetLocal(firstResult, i32),
+ builder->makeConst(Literal(int32_t(32))));
If* conditional = builder->makeIf(
check,
builder->makeBinary(
AddInt32,
builder->makeUnary(op32, builder->makeGetLocal(second, i32)),
- builder->makeConst(Literal(int32_t(32)))
- ),
- builder->makeGetLocal(firstResult, i32)
- );
+ builder->makeConst(Literal(int32_t(32)))),
+ builder->makeGetLocal(firstResult, i32));
SetLocal* setHigh = builder->makeSetLocal(
- highResult,
- builder->makeConst(Literal(int32_t(0)))
- );
+ highResult, builder->makeConst(Literal(int32_t(0))));
setOutParam(result, std::move(highResult));
- replaceCurrent(
- builder->blockify(
- result,
- setFirst,
- setHigh,
- conditional
- )
- );
+ replaceCurrent(builder->blockify(result, setFirst, setHigh, conditional));
};
TempVar highBits = fetchOutParam(curr->value);
@@ -820,32 +755,54 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
case ConvertSInt64ToFloat64:
case ConvertUInt64ToFloat32:
case ConvertUInt64ToFloat64:
- case ReinterpretInt64: return true;
- default: return false;
+ case ReinterpretInt64:
+ return true;
+ default:
+ return false;
}
}
void visitUnary(Unary* curr) {
- if (!unaryNeedsLowering(curr->op)) return;
- if (handleUnreachable(curr)) return;
+ if (!unaryNeedsLowering(curr->op))
+ return;
+ if (handleUnreachable(curr))
+ return;
assert(hasOutParam(curr->value) || curr->type == i64 || curr->type == f64);
switch (curr->op) {
case ClzInt64:
- case CtzInt64: lowerCountZeros(curr); break;
- case EqZInt64: lowerEqZInt64(curr); break;
- case ExtendSInt32: lowerExtendSInt32(curr); break;
- case ExtendUInt32: lowerExtendUInt32(curr); break;
- case WrapInt64: lowerWrapInt64(curr); break;
- case ReinterpretFloat64: lowerReinterpretFloat64(curr); break;
- case ReinterpretInt64: lowerReinterpretInt64(curr); break;
+ case CtzInt64:
+ lowerCountZeros(curr);
+ break;
+ case EqZInt64:
+ lowerEqZInt64(curr);
+ break;
+ case ExtendSInt32:
+ lowerExtendSInt32(curr);
+ break;
+ case ExtendUInt32:
+ lowerExtendUInt32(curr);
+ break;
+ case WrapInt64:
+ lowerWrapInt64(curr);
+ break;
+ case ReinterpretFloat64:
+ lowerReinterpretFloat64(curr);
+ break;
+ case ReinterpretInt64:
+ lowerReinterpretInt64(curr);
+ break;
case TruncSFloat32ToInt64:
case TruncUFloat32ToInt64:
case TruncSFloat64ToInt64:
- case TruncUFloat64ToInt64: lowerTruncFloatToInt(curr); break;
+ case TruncUFloat64ToInt64:
+ lowerTruncFloatToInt(curr);
+ break;
case ConvertSInt64ToFloat32:
case ConvertSInt64ToFloat64:
case ConvertUInt64ToFloat32:
- case ConvertUInt64ToFloat64: lowerConvertIntToFloat(curr); break;
+ case ConvertUInt64ToFloat64:
+ lowerConvertIntToFloat(curr);
+ break;
case PopcntInt64:
std::cerr << "i64.popcnt should already be removed" << std::endl;
WASM_UNREACHABLE();
@@ -855,117 +812,104 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
}
- Block* lowerAdd(Block* result, TempVar&& leftLow, TempVar&& leftHigh,
- TempVar&& rightLow, TempVar&& rightHigh) {
+ Block* lowerAdd(Block* result,
+ TempVar&& leftLow,
+ TempVar&& leftHigh,
+ TempVar&& rightLow,
+ TempVar&& rightHigh) {
TempVar lowResult = getTemp();
TempVar highResult = getTemp();
SetLocal* addLow = builder->makeSetLocal(
lowResult,
- builder->makeBinary(
- AddInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(rightLow, i32)
- )
- );
+ builder->makeBinary(AddInt32,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(rightLow, i32)));
SetLocal* addHigh = builder->makeSetLocal(
highResult,
- builder->makeBinary(
- AddInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(rightHigh, i32)
- )
- );
+ builder->makeBinary(AddInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(rightHigh, i32)));
SetLocal* carryBit = builder->makeSetLocal(
highResult,
- builder->makeBinary(
- AddInt32,
- builder->makeGetLocal(highResult, i32),
- builder->makeConst(Literal(int32_t(1)))
- )
- );
- If* checkOverflow = builder->makeIf(
- builder->makeBinary(
- LtUInt32,
- builder->makeGetLocal(lowResult, i32),
- builder->makeGetLocal(rightLow, i32)
- ),
- carryBit
- );
+ builder->makeBinary(AddInt32,
+ builder->makeGetLocal(highResult, i32),
+ builder->makeConst(Literal(int32_t(1)))));
+ If* checkOverflow =
+ builder->makeIf(builder->makeBinary(LtUInt32,
+ builder->makeGetLocal(lowResult, i32),
+ builder->makeGetLocal(rightLow, i32)),
+ carryBit);
GetLocal* getLow = builder->makeGetLocal(lowResult, i32);
result = builder->blockify(result, addLow, addHigh, checkOverflow, getLow);
setOutParam(result, std::move(highResult));
return result;
}
- Block* lowerSub(Block* result, TempVar&& leftLow, TempVar&& leftHigh,
- TempVar&& rightLow, TempVar&& rightHigh) {
+ Block* lowerSub(Block* result,
+ TempVar&& leftLow,
+ TempVar&& leftHigh,
+ TempVar&& rightLow,
+ TempVar&& rightHigh) {
TempVar lowResult = getTemp();
TempVar highResult = getTemp();
TempVar borrow = getTemp();
SetLocal* subLow = builder->makeSetLocal(
lowResult,
- builder->makeBinary(
- SubInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(rightLow, i32)
- )
- );
+ builder->makeBinary(SubInt32,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(rightLow, i32)));
SetLocal* borrowBit = builder->makeSetLocal(
borrow,
- builder->makeBinary(
- LtUInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(rightLow, i32)
- )
- );
+ builder->makeBinary(LtUInt32,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(rightLow, i32)));
SetLocal* subHigh1 = builder->makeSetLocal(
highResult,
- builder->makeBinary(
- AddInt32,
- builder->makeGetLocal(borrow, i32),
- builder->makeGetLocal(rightHigh, i32)
- )
- );
+ builder->makeBinary(AddInt32,
+ builder->makeGetLocal(borrow, i32),
+ builder->makeGetLocal(rightHigh, i32)));
SetLocal* subHigh2 = builder->makeSetLocal(
highResult,
- builder->makeBinary(
- SubInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(highResult, i32)
- )
- );
+ builder->makeBinary(SubInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(highResult, i32)));
GetLocal* getLow = builder->makeGetLocal(lowResult, i32);
- result = builder->blockify(result, subLow, borrowBit, subHigh1, subHigh2, getLow);
+ result =
+ builder->blockify(result, subLow, borrowBit, subHigh1, subHigh2, getLow);
setOutParam(result, std::move(highResult));
return result;
}
- Block* lowerBitwise(BinaryOp op, Block* result, TempVar&& leftLow,
- TempVar&& leftHigh, TempVar&& rightLow,
+ Block* lowerBitwise(BinaryOp op,
+ Block* result,
+ TempVar&& leftLow,
+ TempVar&& leftHigh,
+ TempVar&& rightLow,
TempVar&& rightHigh) {
BinaryOp op32;
switch (op) {
- case AndInt64: op32 = AndInt32; break;
- case OrInt64: op32 = OrInt32; break;
- case XorInt64: op32 = XorInt32; break;
- default: abort();
+ case AndInt64:
+ op32 = AndInt32;
+ break;
+ case OrInt64:
+ op32 = OrInt32;
+ break;
+ case XorInt64:
+ op32 = XorInt32;
+ break;
+ default:
+ abort();
}
result = builder->blockify(
result,
builder->makeSetLocal(
rightHigh,
- builder->makeBinary(
- op32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(rightHigh, i32)
- )
- ),
- builder->makeBinary(
- op32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(rightLow, i32)
- )
- );
+ builder->makeBinary(op32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(rightHigh, i32))),
+ builder->makeBinary(op32,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(rightLow, i32)));
setOutParam(result, std::move(rightHigh));
return result;
}
@@ -974,14 +918,10 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
return builder->blockify(
builder->makeSetLocal(
highBits,
- builder->makeBinary(
- ShlInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(shift, i32)
- )
- ),
- builder->makeConst(Literal(int32_t(0)))
- );
+ builder->makeBinary(ShlInt32,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(shift, i32))),
+ builder->makeConst(Literal(int32_t(0))));
}
// a >> b where `b` >= 32
@@ -994,58 +934,43 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
return builder->blockify(
builder->makeSetLocal(
highBits,
- builder->makeBinary(
- ShrSInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeConst(Literal(int32_t(31)))
- )
- ),
- builder->makeBinary(
- ShrSInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(shift, i32)
- )
- );
+ builder->makeBinary(ShrSInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeConst(Literal(int32_t(31))))),
+ builder->makeBinary(ShrSInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(shift, i32)));
}
Block* makeLargeShrU(Index highBits, Index leftHigh, Index shift) {
return builder->blockify(
builder->makeSetLocal(highBits, builder->makeConst(Literal(int32_t(0)))),
- builder->makeBinary(
- ShrUInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(shift, i32)
- )
- );
+ builder->makeBinary(ShrUInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(shift, i32)));
}
- Block* makeSmallShl(Index highBits, Index leftLow, Index leftHigh,
- Index shift, Binary* shiftMask, Binary* widthLessShift) {
+ Block* makeSmallShl(Index highBits,
+ Index leftLow,
+ Index leftHigh,
+ Index shift,
+ Binary* shiftMask,
+ Binary* widthLessShift) {
Binary* shiftedInBits = builder->makeBinary(
AndInt32,
shiftMask,
builder->makeBinary(
- ShrUInt32,
- builder->makeGetLocal(leftLow, i32),
- widthLessShift
- )
- );
- Binary* shiftHigh = builder->makeBinary(
- ShlInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(shift, i32)
- );
+ ShrUInt32, builder->makeGetLocal(leftLow, i32), widthLessShift));
+ Binary* shiftHigh =
+ builder->makeBinary(ShlInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(shift, i32));
return builder->blockify(
builder->makeSetLocal(
- highBits,
- builder->makeBinary(OrInt32, shiftedInBits, shiftHigh)
- ),
- builder->makeBinary(
- ShlInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(shift, i32)
- )
- );
+ highBits, builder->makeBinary(OrInt32, shiftedInBits, shiftHigh)),
+ builder->makeBinary(ShlInt32,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(shift, i32)));
}
// a >> b where `b` < 32
@@ -1054,66 +979,58 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
//
// hi = leftHigh >> b
// lo = (leftLow >>> b) | (leftHigh << (32 - b))
- Block* makeSmallShrS(Index highBits, Index leftLow, Index leftHigh,
- Index shift, Binary* shiftMask, Binary* widthLessShift) {
+ Block* makeSmallShrS(Index highBits,
+ Index leftLow,
+ Index leftHigh,
+ Index shift,
+ Binary* shiftMask,
+ Binary* widthLessShift) {
Binary* shiftedInBits = builder->makeBinary(
ShlInt32,
builder->makeBinary(
- AndInt32,
- shiftMask,
- builder->makeGetLocal(leftHigh, i32)
- ),
- widthLessShift
- );
- Binary* shiftLow = builder->makeBinary(
- ShrUInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(shift, i32)
- );
+ AndInt32, shiftMask, builder->makeGetLocal(leftHigh, i32)),
+ widthLessShift);
+ Binary* shiftLow = builder->makeBinary(ShrUInt32,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(shift, i32));
return builder->blockify(
builder->makeSetLocal(
highBits,
- builder->makeBinary(
- ShrSInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(shift, i32)
- )
- ),
- builder->makeBinary(OrInt32, shiftedInBits, shiftLow)
- );
+ builder->makeBinary(ShrSInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(shift, i32))),
+ builder->makeBinary(OrInt32, shiftedInBits, shiftLow));
}
- Block* makeSmallShrU(Index highBits, Index leftLow, Index leftHigh,
- Index shift, Binary* shiftMask, Binary* widthLessShift) {
+ Block* makeSmallShrU(Index highBits,
+ Index leftLow,
+ Index leftHigh,
+ Index shift,
+ Binary* shiftMask,
+ Binary* widthLessShift) {
Binary* shiftedInBits = builder->makeBinary(
ShlInt32,
builder->makeBinary(
- AndInt32,
- shiftMask,
- builder->makeGetLocal(leftHigh, i32)
- ),
- widthLessShift
- );
- Binary* shiftLow = builder->makeBinary(
- ShrUInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(shift, i32)
- );
+ AndInt32, shiftMask, builder->makeGetLocal(leftHigh, i32)),
+ widthLessShift);
+ Binary* shiftLow = builder->makeBinary(ShrUInt32,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(shift, i32));
return builder->blockify(
builder->makeSetLocal(
highBits,
- builder->makeBinary(
- ShrUInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(shift, i32)
- )
- ),
- builder->makeBinary(OrInt32, shiftedInBits, shiftLow)
- );
+ builder->makeBinary(ShrUInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(shift, i32))),
+ builder->makeBinary(OrInt32, shiftedInBits, shiftLow));
}
- Block* lowerShift(BinaryOp op, Block* result, TempVar&& leftLow,
- TempVar&& leftHigh, TempVar&& rightLow, TempVar&& rightHigh) {
+ Block* lowerShift(BinaryOp op,
+ Block* result,
+ TempVar&& leftLow,
+ TempVar&& leftHigh,
+ TempVar&& rightLow,
+ TempVar&& rightHigh) {
assert(op == ShlInt64 || op == ShrUInt64 || op == ShrSInt64);
// shift left lowered as:
// if 32 <= rightLow % 64:
@@ -1125,191 +1042,192 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
TempVar shift = getTemp();
SetLocal* setShift = builder->makeSetLocal(
shift,
- builder->makeBinary(
- AndInt32,
- builder->makeGetLocal(rightLow, i32),
- builder->makeConst(Literal(int32_t(32 - 1)))
- )
- );
+ builder->makeBinary(AndInt32,
+ builder->makeGetLocal(rightLow, i32),
+ builder->makeConst(Literal(int32_t(32 - 1)))));
Binary* isLargeShift = builder->makeBinary(
LeUInt32,
builder->makeConst(Literal(int32_t(32))),
- builder->makeBinary(
- AndInt32,
- builder->makeGetLocal(rightLow, i32),
- builder->makeConst(Literal(int32_t(64 - 1)))
- )
- );
+ builder->makeBinary(AndInt32,
+ builder->makeGetLocal(rightLow, i32),
+ builder->makeConst(Literal(int32_t(64 - 1)))));
Block* largeShiftBlock;
switch (op) {
case ShlInt64:
- largeShiftBlock = makeLargeShl(rightHigh, leftLow, shift); break;
+ largeShiftBlock = makeLargeShl(rightHigh, leftLow, shift);
+ break;
case ShrSInt64:
- largeShiftBlock = makeLargeShrS(rightHigh, leftHigh, shift); break;
+ largeShiftBlock = makeLargeShrS(rightHigh, leftHigh, shift);
+ break;
case ShrUInt64:
- largeShiftBlock = makeLargeShrU(rightHigh, leftHigh, shift); break;
- default: abort();
+ largeShiftBlock = makeLargeShrU(rightHigh, leftHigh, shift);
+ break;
+ default:
+ abort();
}
Binary* shiftMask = builder->makeBinary(
SubInt32,
- builder->makeBinary(
- ShlInt32,
- builder->makeConst(Literal(int32_t(1))),
- builder->makeGetLocal(shift, i32)
- ),
- builder->makeConst(Literal(int32_t(1)))
- );
- Binary* widthLessShift = builder->makeBinary(
- SubInt32,
- builder->makeConst(Literal(int32_t(32))),
- builder->makeGetLocal(shift, i32)
- );
+ builder->makeBinary(ShlInt32,
+ builder->makeConst(Literal(int32_t(1))),
+ builder->makeGetLocal(shift, i32)),
+ builder->makeConst(Literal(int32_t(1))));
+ Binary* widthLessShift =
+ builder->makeBinary(SubInt32,
+ builder->makeConst(Literal(int32_t(32))),
+ builder->makeGetLocal(shift, i32));
Block* smallShiftBlock;
- switch(op) {
+ switch (op) {
case ShlInt64: {
- smallShiftBlock = makeSmallShl(rightHigh, leftLow, leftHigh,
- shift, shiftMask, widthLessShift);
+ smallShiftBlock = makeSmallShl(
+ rightHigh, leftLow, leftHigh, shift, shiftMask, widthLessShift);
break;
}
case ShrSInt64: {
- smallShiftBlock = makeSmallShrS(rightHigh, leftLow, leftHigh,
- shift, shiftMask, widthLessShift);
+ smallShiftBlock = makeSmallShrS(
+ rightHigh, leftLow, leftHigh, shift, shiftMask, widthLessShift);
break;
}
case ShrUInt64: {
- smallShiftBlock = makeSmallShrU(rightHigh, leftLow, leftHigh,
- shift, shiftMask, widthLessShift);
+ smallShiftBlock = makeSmallShrU(
+ rightHigh, leftLow, leftHigh, shift, shiftMask, widthLessShift);
break;
}
- default: abort();
+ default:
+ abort();
}
- If* ifLargeShift = builder->makeIf(
- isLargeShift,
- largeShiftBlock,
- smallShiftBlock
- );
+ If* ifLargeShift =
+ builder->makeIf(isLargeShift, largeShiftBlock, smallShiftBlock);
result = builder->blockify(result, setShift, ifLargeShift);
setOutParam(result, std::move(rightHigh));
return result;
}
- Block* lowerEq(Block* result, TempVar&& leftLow, TempVar&& leftHigh,
- TempVar&& rightLow, TempVar&& rightHigh) {
+ Block* lowerEq(Block* result,
+ TempVar&& leftLow,
+ TempVar&& leftHigh,
+ TempVar&& rightLow,
+ TempVar&& rightHigh) {
return builder->blockify(
result,
builder->makeBinary(
AndInt32,
- builder->makeBinary(
- EqInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(rightLow, i32)
- ),
- builder->makeBinary(
- EqInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(rightHigh, i32)
- )
- )
- );
+ builder->makeBinary(EqInt32,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(rightLow, i32)),
+ builder->makeBinary(EqInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(rightHigh, i32))));
}
- Block* lowerNe(Block* result, TempVar&& leftLow, TempVar&& leftHigh,
- TempVar&& rightLow, TempVar&& rightHigh) {
+ Block* lowerNe(Block* result,
+ TempVar&& leftLow,
+ TempVar&& leftHigh,
+ TempVar&& rightLow,
+ TempVar&& rightHigh) {
return builder->blockify(
result,
builder->makeBinary(
OrInt32,
- builder->makeBinary(
- NeInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(rightLow, i32)
- ),
- builder->makeBinary(
- NeInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(rightHigh, i32)
- )
- )
- );
+ builder->makeBinary(NeInt32,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(rightLow, i32)),
+ builder->makeBinary(NeInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(rightHigh, i32))));
}
- Block* lowerUComp(BinaryOp op, Block* result, TempVar&& leftLow,
- TempVar&& leftHigh, TempVar&& rightLow,
+ Block* lowerUComp(BinaryOp op,
+ Block* result,
+ TempVar&& leftLow,
+ TempVar&& leftHigh,
+ TempVar&& rightLow,
TempVar&& rightHigh) {
BinaryOp highOp, lowOp;
switch (op) {
- case LtUInt64: highOp = LtUInt32; lowOp = LtUInt32; break;
- case LeUInt64: highOp = LtUInt32; lowOp = LeUInt32; break;
- case GtUInt64: highOp = GtUInt32; lowOp = GtUInt32; break;
- case GeUInt64: highOp = GtUInt32; lowOp = GeUInt32; break;
- default: abort();
+ case LtUInt64:
+ highOp = LtUInt32;
+ lowOp = LtUInt32;
+ break;
+ case LeUInt64:
+ highOp = LtUInt32;
+ lowOp = LeUInt32;
+ break;
+ case GtUInt64:
+ highOp = GtUInt32;
+ lowOp = GtUInt32;
+ break;
+ case GeUInt64:
+ highOp = GtUInt32;
+ lowOp = GeUInt32;
+ break;
+ default:
+ abort();
}
- Binary* compHigh = builder->makeBinary(
- highOp,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(rightHigh, i32)
- );
- Binary* eqHigh = builder->makeBinary(
- EqInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(rightHigh, i32)
- );
- Binary* compLow = builder->makeBinary(
- lowOp,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(rightLow, i32)
- );
+ Binary* compHigh =
+ builder->makeBinary(highOp,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(rightHigh, i32));
+ Binary* eqHigh = builder->makeBinary(EqInt32,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(rightHigh, i32));
+ Binary* compLow = builder->makeBinary(lowOp,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(rightLow, i32));
return builder->blockify(
result,
builder->makeBinary(
- OrInt32,
- compHigh,
- builder->makeBinary(AndInt32, eqHigh, compLow)
- )
- );
+ OrInt32, compHigh, builder->makeBinary(AndInt32, eqHigh, compLow)));
}
- Block* lowerSComp(BinaryOp op, Block* result, TempVar&& leftLow,
- TempVar&& leftHigh, TempVar&& rightLow,
- TempVar&& rightHigh) {
+ Block* lowerSComp(BinaryOp op,
+ Block* result,
+ TempVar&& leftLow,
+ TempVar&& leftHigh,
+ TempVar&& rightLow,
+ TempVar&& rightHigh) {
BinaryOp highOp1, highOp2, lowOp;
switch (op) {
- case LtSInt64: highOp1 = LtSInt32; highOp2 = LeSInt32; lowOp = GeUInt32; break;
- case LeSInt64: highOp1 = LtSInt32; highOp2 = LeSInt32; lowOp = GtUInt32; break;
- case GtSInt64: highOp1 = GtSInt32; highOp2 = GeSInt32; lowOp = LeUInt32; break;
- case GeSInt64: highOp1 = GtSInt32; highOp2 = GeSInt32; lowOp = LtUInt32; break;
- default: abort();
+ case LtSInt64:
+ highOp1 = LtSInt32;
+ highOp2 = LeSInt32;
+ lowOp = GeUInt32;
+ break;
+ case LeSInt64:
+ highOp1 = LtSInt32;
+ highOp2 = LeSInt32;
+ lowOp = GtUInt32;
+ break;
+ case GtSInt64:
+ highOp1 = GtSInt32;
+ highOp2 = GeSInt32;
+ lowOp = LeUInt32;
+ break;
+ case GeSInt64:
+ highOp1 = GtSInt32;
+ highOp2 = GeSInt32;
+ lowOp = LtUInt32;
+ break;
+ default:
+ abort();
}
- Binary* compHigh1 = builder->makeBinary(
- highOp1,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(rightHigh, i32)
- );
- Binary* compHigh2 = builder->makeBinary(
- highOp2,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(rightHigh, i32)
- );
- Binary* compLow = builder->makeBinary(
- lowOp,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(rightLow, i32)
- );
- If* lowIf = builder->makeIf(
- compLow,
- builder->makeConst(Literal(int32_t(0))),
- builder->makeConst(Literal(int32_t(1)))
- );
+ Binary* compHigh1 =
+ builder->makeBinary(highOp1,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(rightHigh, i32));
+ Binary* compHigh2 =
+ builder->makeBinary(highOp2,
+ builder->makeGetLocal(leftHigh, i32),
+ builder->makeGetLocal(rightHigh, i32));
+ Binary* compLow = builder->makeBinary(lowOp,
+ builder->makeGetLocal(leftLow, i32),
+ builder->makeGetLocal(rightLow, i32));
+ If* lowIf = builder->makeIf(compLow,
+ builder->makeConst(Literal(int32_t(0))),
+ builder->makeConst(Literal(int32_t(1))));
If* highIf2 = builder->makeIf(
- compHigh2,
- lowIf,
- builder->makeConst(Literal(int32_t(0)))
- );
+ compHigh2, lowIf, builder->makeConst(Literal(int32_t(0))));
If* highIf1 = builder->makeIf(
- compHigh1,
- builder->makeConst(Literal(int32_t(1))),
- highIf2
- );
+ compHigh1, builder->makeConst(Literal(int32_t(1))), highIf2);
return builder->blockify(result, highIf1);
}
@@ -1339,14 +1257,18 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
case GtSInt64:
case GtUInt64:
case GeSInt64:
- case GeUInt64: return true;
- default: return false;
+ case GeUInt64:
+ return true;
+ default:
+ return false;
}
}
void visitBinary(Binary* curr) {
- if (handleUnreachable(curr)) return;
- if (!binaryNeedsLowering(curr->op)) return;
+ if (handleUnreachable(curr))
+ return;
+ if (!binaryNeedsLowering(curr->op))
+ return;
// left and right reachable, lower normally
TempVar leftLow = getTemp();
TempVar leftHigh = fetchOutParam(curr->left);
@@ -1357,15 +1279,19 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
Block* result = builder->blockify(setLeft, setRight);
switch (curr->op) {
case AddInt64: {
- replaceCurrent(
- lowerAdd(result, std::move(leftLow), std::move(leftHigh),
- std::move(rightLow), std::move(rightHigh)));
+ replaceCurrent(lowerAdd(result,
+ std::move(leftLow),
+ std::move(leftHigh),
+ std::move(rightLow),
+ std::move(rightHigh)));
break;
}
case SubInt64: {
- replaceCurrent(
- lowerSub(result, std::move(leftLow), std::move(leftHigh),
- std::move(rightLow), std::move(rightHigh)));
+ replaceCurrent(lowerSub(result,
+ std::move(leftLow),
+ std::move(leftHigh),
+ std::move(rightLow),
+ std::move(rightHigh)));
break;
}
case MulInt64:
@@ -1375,59 +1301,69 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
case RemUInt64:
case RotLInt64:
case RotRInt64:
- std::cerr << "should have been removed by now " << curr->op << std::endl;
+ std::cerr << "should have been removed by now " << curr->op
+ << std::endl;
WASM_UNREACHABLE();
case AndInt64:
case OrInt64:
case XorInt64: {
- replaceCurrent(
- lowerBitwise(curr->op, result, std::move(leftLow),
- std::move(leftHigh), std::move(rightLow),
- std::move(rightHigh))
- );
+ replaceCurrent(lowerBitwise(curr->op,
+ result,
+ std::move(leftLow),
+ std::move(leftHigh),
+ std::move(rightLow),
+ std::move(rightHigh)));
break;
}
case ShlInt64:
case ShrSInt64:
case ShrUInt64: {
- replaceCurrent(
- lowerShift(curr->op, result, std::move(leftLow), std::move(leftHigh),
- std::move(rightLow), std::move(rightHigh))
- );
+ replaceCurrent(lowerShift(curr->op,
+ result,
+ std::move(leftLow),
+ std::move(leftHigh),
+ std::move(rightLow),
+ std::move(rightHigh)));
break;
}
case EqInt64: {
- replaceCurrent(
- lowerEq(result, std::move(leftLow), std::move(leftHigh),
- std::move(rightLow), std::move(rightHigh))
- );
+ replaceCurrent(lowerEq(result,
+ std::move(leftLow),
+ std::move(leftHigh),
+ std::move(rightLow),
+ std::move(rightHigh)));
break;
}
case NeInt64: {
- replaceCurrent(
- lowerNe(result, std::move(leftLow), std::move(leftHigh),
- std::move(rightLow), std::move(rightHigh))
- );
+ replaceCurrent(lowerNe(result,
+ std::move(leftLow),
+ std::move(leftHigh),
+ std::move(rightLow),
+ std::move(rightHigh)));
break;
}
case LtSInt64:
case LeSInt64:
case GtSInt64:
case GeSInt64:
- replaceCurrent(
- lowerSComp(curr->op, result, std::move(leftLow), std::move(leftHigh),
- std::move(rightLow), std::move(rightHigh))
- );
- break;
+ replaceCurrent(lowerSComp(curr->op,
+ result,
+ std::move(leftLow),
+ std::move(leftHigh),
+ std::move(rightLow),
+ std::move(rightHigh)));
+ break;
case LtUInt64:
case LeUInt64:
case GtUInt64:
case GeUInt64: {
- replaceCurrent(
- lowerUComp(curr->op, result, std::move(leftLow), std::move(leftHigh),
- std::move(rightLow), std::move(rightHigh))
- );
+ replaceCurrent(lowerUComp(curr->op,
+ result,
+ std::move(leftLow),
+ std::move(leftHigh),
+ std::move(rightLow),
+ std::move(rightHigh)));
break;
}
default: {
@@ -1438,7 +1374,8 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
}
void visitSelect(Select* curr) {
- if (handleUnreachable(curr)) return;
+ if (handleUnreachable(curr))
+ return;
if (!hasOutParam(curr->ifTrue)) {
assert(!hasOutParam(curr->ifFalse));
return;
@@ -1452,40 +1389,33 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
builder->makeSetLocal(
lowBits,
builder->makeSelect(
- builder->makeGetLocal(cond, i32),
- curr->ifTrue,
- curr->ifFalse
- )
- ),
+ builder->makeGetLocal(cond, i32), curr->ifTrue, curr->ifFalse)),
builder->makeSetLocal(
highBits,
builder->makeSelect(
builder->makeGetLocal(cond, i32),
builder->makeGetLocal(fetchOutParam(curr->ifTrue), i32),
- builder->makeGetLocal(fetchOutParam(curr->ifFalse), i32)
- )
- ),
- builder->makeGetLocal(lowBits, i32)
- );
+ builder->makeGetLocal(fetchOutParam(curr->ifFalse), i32))),
+ builder->makeGetLocal(lowBits, i32));
setOutParam(result, std::move(highBits));
replaceCurrent(result);
}
void visitDrop(Drop* curr) {
- if (!hasOutParam(curr->value)) return;
+ if (!hasOutParam(curr->value))
+ return;
// free temp var
fetchOutParam(curr->value);
}
void visitReturn(Return* curr) {
- if (!hasOutParam(curr->value)) return;
+ if (!hasOutParam(curr->value))
+ return;
TempVar lowBits = getTemp();
TempVar highBits = fetchOutParam(curr->value);
SetLocal* setLow = builder->makeSetLocal(lowBits, curr->value);
SetGlobal* setHigh = builder->makeSetGlobal(
- INT64_TO_32_HIGH_BITS,
- builder->makeGetLocal(highBits, i32)
- );
+ INT64_TO_32_HIGH_BITS, builder->makeGetLocal(highBits, i32));
curr->value = builder->makeGetLocal(lowBits, i32);
Block* result = builder->blockify(setLow, setHigh, curr);
replaceCurrent(result);
@@ -1502,7 +1432,7 @@ private:
TempVar getTemp(Type ty = i32) {
Index ret;
- auto &freeList = freeTemps[(int) ty];
+ auto& freeList = freeTemps[(int)ty];
if (freeList.size() > 0) {
ret = freeList.back();
freeList.pop_back();
@@ -1538,7 +1468,8 @@ private:
// unconditionally before themselves, so it is not valid for an if,
// in particular.
bool handleUnreachable(Expression* curr) {
- if (curr->type != unreachable) return false;
+ if (curr->type != unreachable)
+ return false;
std::vector<Expression*> children;
bool hasUnreachable = false;
for (auto* child : ChildIterator(curr)) {
@@ -1549,7 +1480,8 @@ private:
}
children.push_back(child);
}
- if (!hasUnreachable) return false;
+ if (!hasUnreachable)
+ return false;
// This has an unreachable child, so we can replace it with
// the children.
auto* block = builder->makeBlock(children);
@@ -1559,8 +1491,6 @@ private:
}
};
-Pass *createI64ToI32LoweringPass() {
- return new I64ToI32Lowering();
-}
+Pass* createI64ToI32LoweringPass() { return new I64ToI32Lowering(); }
-}
+} // namespace wasm