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.cpp360
1 files changed, 14 insertions, 346 deletions
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index 2f6fdf122..f14f33027 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -118,149 +118,6 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
highBits->mutable_ = true;
module->addGlobal(highBits);
PostWalker<I64ToI32Lowering>::doWalkModule(module);
-
- if (needRotl64) {
- module->addFunction(createRot64(true));
- }
- if (needRotr64) {
- module->addFunction(createRot64(false));
- }
- }
-
- Function* createRot64(bool leftShift) {
- Name name = leftShift ? WASM_ROTL64 : WASM_ROTR64;
-
- // if rotate == 32
- // hi = leftLow
- // lo = leftHigh
- // if rotate > 32
- // rotate = rotate - 32
- // hi = (leftLow << rotate) | (leftHigh >> (32 - rotate))
- // lo = (leftHigh << rotate) | (leftLow >> (32 - rotate))
- // else
- // hi = (leftHigh << rotate) | (leftLow >> (32 - rotate))
- // lo = (leftLow << rotate) | (leftHigh >> (32 - rotate))
- Index lowBits = 0;
- Index highBits = 1;
- Index rotate = 2;
- Index widthLessRotate = 3;
- Binary* is32Rotate = builder->makeBinary(
- EqInt32,
- builder->makeGetLocal(rotate, i32),
- builder->makeConst(Literal(int32_t(32)))
- );
- Binary* isLargeRotate = builder->makeBinary(
- GeUInt32,
- builder->makeGetLocal(rotate, i32),
- builder->makeConst(Literal(int32_t(32)))
- );
- BinaryOp firstOp = leftShift ? ShlInt32 : ShrUInt32;
- BinaryOp secondOp = leftShift ? ShrUInt32 : ShlInt32;
- Block* equalRotateBlock = builder->blockify(
- builder->makeSetGlobal(
- INT64_TO_32_HIGH_BITS,
- builder->makeGetLocal(lowBits, i32)
- ),
- builder->makeGetLocal(highBits, i32)
- );
- Block* largeRotateBlock = builder->blockify(
- builder->makeSetLocal(
- rotate,
- builder->makeBinary(
- SubInt32,
- builder->makeGetLocal(rotate, i32),
- builder->makeConst(Literal(int32_t(32)))
- )
- ),
- builder->makeSetLocal(
- widthLessRotate,
- builder->makeBinary(
- SubInt32,
- builder->makeConst(Literal(int32_t(32))),
- builder->makeGetLocal(rotate, i32)
- )
- ),
- builder->makeSetGlobal(
- INT64_TO_32_HIGH_BITS,
- builder->makeBinary(
- OrInt32,
- builder->makeBinary(
- firstOp,
- builder->makeGetLocal(lowBits, i32),
- builder->makeGetLocal(rotate, i32)
- ),
- builder->makeBinary(
- secondOp,
- builder->makeGetLocal(highBits, i32),
- builder->makeGetLocal(widthLessRotate, i32)
- )
- )
- ),
- builder->makeBinary(
- OrInt32,
- builder->makeBinary(
- firstOp,
- builder->makeGetLocal(highBits, i32),
- builder->makeGetLocal(rotate, i32)
- ),
- builder->makeBinary(
- secondOp,
- builder->makeGetLocal(lowBits, i32),
- builder->makeGetLocal(widthLessRotate, i32)
- )
- )
- );
- Block* smallRotateBlock = builder->blockify(
- builder->makeSetLocal(
- widthLessRotate,
- builder->makeBinary(
- SubInt32,
- builder->makeConst(Literal(int32_t(32))),
- builder->makeGetLocal(rotate, i32)
- )
- ),
- builder->makeSetGlobal(
- INT64_TO_32_HIGH_BITS,
- builder->makeBinary(
- OrInt32,
- builder->makeBinary(
- firstOp,
- builder->makeGetLocal(highBits, i32),
- builder->makeGetLocal(rotate, i32)
- ),
- builder->makeBinary(
- secondOp,
- builder->makeGetLocal(lowBits, i32),
- builder->makeGetLocal(widthLessRotate, i32)
- )
- )
- ),
- builder->makeBinary(
- OrInt32,
- builder->makeBinary(
- firstOp,
- builder->makeGetLocal(lowBits, i32),
- builder->makeGetLocal(rotate, i32)
- ),
- builder->makeBinary(
- secondOp,
- builder->makeGetLocal(highBits, i32),
- builder->makeGetLocal(widthLessRotate, i32)
- )
- )
- );
- If* condition = builder->makeIf(
- is32Rotate,
- equalRotateBlock,
- builder->makeIf(
- isLargeRotate,
- largeRotateBlock,
- smallRotateBlock
- )
- );
- std::vector<Type> params = {i32, i32, i32};
- std::vector<Type> vars = {i32};
- return builder->makeFunction(name, std::move(params), i32, std::move(vars), condition);
}
void visitFunctionType(FunctionType* curr) {
@@ -937,31 +794,6 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
replaceCurrent(result);
}
- void lowerPopcnt64(Unary* curr) {
- TempVar highBits = fetchOutParam(curr->value);
- TempVar lowBits = getTemp();
- TempVar highResult = getTemp();
-
- SetLocal* setLow = builder->makeSetLocal(lowBits, curr->value);
- SetLocal* setHigh = builder->makeSetLocal(
- highResult,
- builder->makeConst(Literal(int32_t(0)))
- );
-
- Block* result = builder->blockify(
- setLow,
- setHigh,
- builder->makeBinary(
- AddInt32,
- builder->makeUnary(PopcntInt32, builder->makeGetLocal(highBits, i32)),
- builder->makeUnary(PopcntInt32, builder->makeGetLocal(lowBits, i32))
- )
- );
-
- setOutParam(result, std::move(highResult));
- replaceCurrent(result);
- }
-
void lowerCountZeros(Unary* curr) {
auto lower = [&](Block* result, UnaryOp op32, TempVar&& first, TempVar&& second) {
TempVar highResult = getTemp();
@@ -1014,7 +846,8 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
lower(result, ClzInt32, std::move(highBits), std::move(lowBits));
break;
case CtzInt64:
- lower(result, CtzInt32, std::move(lowBits), std::move(highBits));
+ std::cerr << "i64.ctz should be removed already" << std::endl;
+ WASM_UNREACHABLE();
break;
default:
abort();
@@ -1055,7 +888,6 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
switch (curr->op) {
case ClzInt64:
case CtzInt64: lowerCountZeros(curr); break;
- case PopcntInt64: lowerPopcnt64(curr); break;
case EqZInt64: lowerEqZInt64(curr); break;
case ExtendSInt32: lowerExtendSInt32(curr); break;
case ExtendUInt32: lowerExtendUInt32(curr); break;
@@ -1070,6 +902,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
case ConvertSInt64ToFloat64:
case ConvertUInt64ToFloat32:
case ConvertUInt64ToFloat64: lowerConvertIntToFloat(curr); break;
+ case PopcntInt64:
+ std::cerr << "i64.popcnt should already be removed" << std::endl;
+ WASM_UNREACHABLE();
default:
std::cerr << "Unhandled unary operator: " << curr->op << std::endl;
abort();
@@ -1161,122 +996,6 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
return result;
}
- Block* lowerMul(Block* result, TempVar&& leftLow, TempVar&& leftHigh,
- TempVar&& rightLow, TempVar&& rightHigh) {
- // high bits = ll*rh + lh*rl + ll1*rl1 + (ll0*rl1)>>16 + (ll1*rl0)>>16
- // low bits = ll*rl
- TempVar leftLow0 = getTemp();
- TempVar leftLow1 = getTemp();
- TempVar rightLow0 = getTemp();
- TempVar rightLow1 = getTemp();
- SetLocal* setLL0 = builder->makeSetLocal(
- leftLow0,
- builder->makeBinary(
- AndInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeConst(Literal(int32_t(0xffff)))
- )
- );
- SetLocal* setLL1 = builder->makeSetLocal(
- leftLow1,
- builder->makeBinary(
- ShrUInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeConst(Literal(int32_t(16)))
- )
- );
- SetLocal* setRL0 = builder->makeSetLocal(
- rightLow0,
- builder->makeBinary(
- AndInt32,
- builder->makeGetLocal(rightLow, i32),
- builder->makeConst(Literal(int32_t(0xffff)))
- )
- );
- SetLocal* setRL1 = builder->makeSetLocal(
- rightLow1,
- builder->makeBinary(
- ShrUInt32,
- builder->makeGetLocal(rightLow, i32),
- builder->makeConst(Literal(int32_t(16)))
- )
- );
- SetLocal* setLLRH = builder->makeSetLocal(
- rightHigh,
- builder->makeBinary(
- MulInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(rightHigh, i32)
- )
- );
- auto addToHighBits = [&](Expression* expr) -> SetLocal* {
- return builder->makeSetLocal(
- rightHigh,
- builder->makeBinary(
- AddInt32,
- builder->makeGetLocal(rightHigh, i32),
- expr
- )
- );
- };
- SetLocal* addLHRL = addToHighBits(
- builder->makeBinary(
- MulInt32,
- builder->makeGetLocal(leftHigh, i32),
- builder->makeGetLocal(rightLow, i32)
- )
- );
- SetLocal* addLL1RL1 = addToHighBits(
- builder->makeBinary(
- MulInt32,
- builder->makeGetLocal(leftLow1, i32),
- builder->makeGetLocal(rightLow1, i32)
- )
- );
- SetLocal* addLL0RL1 = addToHighBits(
- builder->makeBinary(
- ShrUInt32,
- builder->makeBinary(
- MulInt32,
- builder->makeGetLocal(leftLow0, i32),
- builder->makeGetLocal(rightLow1, i32)
- ),
- builder->makeConst(Literal(int32_t(16)))
- )
- );
- SetLocal* addLL1RL0 = addToHighBits(
- builder->makeBinary(
- ShrUInt32,
- builder->makeBinary(
- MulInt32,
- builder->makeGetLocal(leftLow1, i32),
- builder->makeGetLocal(rightLow0, i32)
- ),
- builder->makeConst(Literal(int32_t(16)))
- )
- );
- Binary* getLow = builder->makeBinary(
- MulInt32,
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(rightLow, i32)
- );
- result = builder->blockify(
- result,
- setLL0,
- setLL1,
- setRL0,
- setRL1,
- setLLRH,
- addLHRL,
- addLL1RL1,
- addLL0RL1,
- addLL1RL0,
- getLow
- );
- setOutParam(result, std::move(rightHigh));
- return result;
- }
-
Block* lowerBitwise(BinaryOp op, Block* result, TempVar&& leftLow,
TempVar&& leftHigh, TempVar&& rightLow,
TempVar&& rightHigh) {
@@ -1530,46 +1249,6 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
return result;
}
- Block* lowerRotate(BinaryOp op, Block* result, TempVar&& leftLow,
- TempVar&& leftHigh, TempVar&& rightLow, TempVar&& rightHigh) {
- assert(op == RotLInt64 || op == RotRInt64);
- Name name;
- if (op == RotLInt64) {
- needRotl64 = true;
- name = WASM_ROTL64;
- } else {
- needRotr64 = true;
- name = WASM_ROTR64;
- }
- TempVar lowResult = getTemp();
- result = builder->blockify(
- result,
- builder->makeSetLocal(
- lowResult,
- builder->makeCall(
- name,
- {
- builder->makeGetLocal(leftLow, i32),
- builder->makeGetLocal(leftHigh, i32),
- builder->makeBinary(
- AndInt32,
- builder->makeGetLocal(rightLow, i32),
- builder->makeConst(Literal(int32_t(64 - 1)))
- )
- },
- i32
- )
- ),
- builder->makeSetLocal(
- rightHigh,
- builder->makeGetGlobal(INT64_TO_32_HIGH_BITS, i32)
- ),
- builder->makeGetLocal(lowResult, i32)
- );
- setOutParam(result, std::move(rightHigh));
- return result;
- }
-
Block* lowerEq(Block* result, TempVar&& leftLow, TempVar&& leftHigh,
TempVar&& rightLow, TempVar&& rightHigh) {
return builder->blockify(
@@ -1762,17 +1441,16 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
std::move(rightLow), std::move(rightHigh)));
break;
}
- case MulInt64: {
- replaceCurrent(
- lowerMul(result, std::move(leftLow), std::move(leftHigh),
- std::move(rightLow), std::move(rightHigh))
- );
- break;
- }
+ case MulInt64:
case DivSInt64:
case DivUInt64:
case RemSInt64:
- case RemUInt64: goto err;
+ case RemUInt64:
+ case RotLInt64:
+ case RotRInt64:
+ std::cerr << "should have been removed by now " << curr->op << std::endl;
+ WASM_UNREACHABLE();
+
case AndInt64:
case OrInt64:
case XorInt64: {
@@ -1792,14 +1470,6 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
);
break;
}
- case RotLInt64:
- case RotRInt64: {
- replaceCurrent(
- lowerRotate(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),
@@ -1833,7 +1503,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
);
break;
}
- err: default: {
+ default: {
std::cerr << "Unhandled binary op " << curr->op << std::endl;
abort();
}
@@ -1867,13 +1537,11 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
private:
std::unique_ptr<Builder> builder;
std::unordered_map<Index, Index> indexMap;
+ std::unordered_map<int, std::vector<Index>> freeTemps;
std::unordered_map<Expression*, TempVar> highBitVars;
std::unordered_map<Name, TempVar> labelHighBitVars;
- std::unordered_map<int, std::vector<Index>> freeTemps;
std::unordered_map<Index, Type> tempTypes;
Index nextTemp;
- bool needRotl64 = false;
- bool needRotr64 = false;
TempVar getTemp(Type ty = i32) {
Index ret;