summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/asm2wasm.h26
-rw-r--r--src/binaryen-c.cpp33
-rw-r--r--src/binaryen-c.h33
-rw-r--r--src/cfg/Relooper.cpp2
-rw-r--r--src/passes/OptimizeInstructions.cpp4
-rw-r--r--src/passes/Print.cpp85
-rw-r--r--src/passes/Vacuum.cpp2
-rw-r--r--src/s2wasm.h22
-rw-r--r--src/wasm-binary.h85
-rw-r--r--src/wasm-interpreter.h44
-rw-r--r--src/wasm-s-parser.h55
-rw-r--r--src/wasm-validator.h36
-rw-r--r--src/wasm.h43
-rw-r--r--test/example/c-api-kitchen-sink.c22
14 files changed, 287 insertions, 205 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h
index 0f4852250..74b1aa8c4 100644
--- a/src/asm2wasm.h
+++ b/src/asm2wasm.h
@@ -1133,11 +1133,12 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
return ret;
}
auto ret = allocator.alloc<Unary>();
- ret->op = Neg;
ret->value = process(ast[2]);
if (asmType == ASM_DOUBLE) {
+ ret->op = NegFloat64;
ret->type = WasmType::f64;
} else if (asmType == ASM_FLOAT) {
+ ret->op = NegFloat32;
ret->type = WasmType::f32;
} else {
abort();
@@ -1188,7 +1189,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
return ret;
} else if (ast[1] == L_NOT) {
auto ret = allocator.alloc<Unary>();
- ret->op = EqZ;
+ ret->op = EqZInt32;
ret->value = process(ast[2]);
ret->type = i32;
return ret;
@@ -1215,7 +1216,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
if (name == Math_clz32 || name == llvm_cttz_i32) {
assert(ast[2]->size() == 1);
auto ret = allocator.alloc<Unary>();
- ret->op = name == Math_clz32 ? Clz : Ctz;
+ ret->op = name == Math_clz32 ? ClzInt32 : CtzInt32;
ret->value = process(ast[2][0]);
ret->type = WasmType::i32;
return ret;
@@ -1283,7 +1284,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
return block;
} else if (value->type == f32 || value->type == f64) {
auto ret = allocator.alloc<Unary>();
- ret->op = Abs;
+ ret->op = value->type == f32 ? AbsFloat32 : AbsFloat64;
ret->value = value;
ret->type = value->type;
return ret;
@@ -1294,15 +1295,18 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
if (name == Math_floor || name == Math_sqrt || name == Math_ceil) {
// overloaded on type: f32 or f64
Expression* value = process(ast[2][0]);
- if (value->type == f32 || value->type == f64) {
- auto ret = allocator.alloc<Unary>();
- ret->op = name == Math_floor ? Floor : name == Math_ceil ? Ceil : Sqrt;
- ret->value = value;
+ auto ret = allocator.alloc<Unary>();
+ ret->value = value;
+ if (value->type == f32) {
+ ret->op = name == Math_floor ? FloorFloat32 : name == Math_ceil ? CeilFloat32 : SqrtFloat32;
+ ret->type = value->type;
+ } else if (value->type == f64) {
+ ret->op = name == Math_floor ? FloorFloat64 : name == Math_ceil ? CeilFloat64 : SqrtFloat64;
ret->type = value->type;
- return ret;
} else {
abort();
}
+ return ret;
}
Expression* ret;
ExpressionList* operands;
@@ -1404,7 +1408,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
Break *breakOut = allocator.alloc<Break>();
breakOut->name = out;
If *condition = allocator.alloc<If>();
- condition->condition = builder.makeUnary(EqZ, process(ast[1]));
+ condition->condition = builder.makeUnary(EqZInt32, process(ast[1]));
condition->ifTrue = breakOut;
auto body = allocator.alloc<Block>();
body->list.push_back(condition);
@@ -1501,7 +1505,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) {
Break *breakOut = allocator.alloc<Break>();
breakOut->name = out;
If *condition = allocator.alloc<If>();
- condition->condition = builder.makeUnary(EqZ, process(fcond));
+ condition->condition = builder.makeUnary(EqZInt32, process(fcond));
condition->ifTrue = breakOut;
auto body = allocator.alloc<Block>();
body->list.push_back(condition);
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp
index 62e35f025..8f94c4ec5 100644
--- a/src/binaryen-c.cpp
+++ b/src/binaryen-c.cpp
@@ -98,17 +98,28 @@ BinaryenLiteral BinaryenLiteralFloat64Bits(int64_t x) { return toBinaryenLiteral
// Expressions
-BinaryenOp BinaryenClz(void) { return Clz; }
-BinaryenOp BinaryenCtz(void) { return Ctz; }
-BinaryenOp BinaryenPopcnt(void) { return Popcnt; }
-BinaryenOp BinaryenNeg(void) { return Neg; }
-BinaryenOp BinaryenAbs(void) { return Abs; }
-BinaryenOp BinaryenCeil(void) { return Ceil; }
-BinaryenOp BinaryenFloor(void) { return Floor; }
-BinaryenOp BinaryenTrunc(void) { return Trunc; }
-BinaryenOp BinaryenNearest(void) { return Nearest; }
-BinaryenOp BinaryenSqrt(void) { return Sqrt; }
-BinaryenOp BinaryenEqZ(void) { return EqZ; }
+BinaryenOp BinaryenClzInt32(void) { return ClzInt32; }
+BinaryenOp BinaryenCtzInt32(void) { return CtzInt32; }
+BinaryenOp BinaryenPopcntInt32(void) { return PopcntInt32; }
+BinaryenOp BinaryenNegFloat32(void) { return NegFloat32; }
+BinaryenOp BinaryenAbsFloat32(void) { return AbsFloat32; }
+BinaryenOp BinaryenCeilFloat32(void) { return CeilFloat32; }
+BinaryenOp BinaryenFloorFloat32(void) { return FloorFloat32; }
+BinaryenOp BinaryenTruncFloat32(void) { return TruncFloat32; }
+BinaryenOp BinaryenNearestFloat32(void) { return NearestFloat32; }
+BinaryenOp BinaryenSqrtFloat32(void) { return SqrtFloat32; }
+BinaryenOp BinaryenEqZInt32(void) { return EqZInt32; }
+BinaryenOp BinaryenClzInt64(void) { return ClzInt64; }
+BinaryenOp BinaryenCtzInt64(void) { return CtzInt64; }
+BinaryenOp BinaryenPopcntInt64(void) { return PopcntInt64; }
+BinaryenOp BinaryenNegFloat64(void) { return NegFloat64; }
+BinaryenOp BinaryenAbsFloat64(void) { return AbsFloat64; }
+BinaryenOp BinaryenCeilFloat64(void) { return CeilFloat64; }
+BinaryenOp BinaryenFloorFloat64(void) { return FloorFloat64; }
+BinaryenOp BinaryenTruncFloat64(void) { return TruncFloat64; }
+BinaryenOp BinaryenNearestFloat64(void) { return NearestFloat64; }
+BinaryenOp BinaryenSqrtFloat64(void) { return SqrtFloat64; }
+BinaryenOp BinaryenEqZInt64(void) { return EqZInt64; }
BinaryenOp BinaryenExtendSInt32(void) { return ExtendSInt32; }
BinaryenOp BinaryenExtentUInt32(void) { return ExtendUInt32; }
BinaryenOp BinaryenWrapInt64(void) { return WrapInt64; }
diff --git a/src/binaryen-c.h b/src/binaryen-c.h
index ae3e0c019..dbaf65b0e 100644
--- a/src/binaryen-c.h
+++ b/src/binaryen-c.h
@@ -114,17 +114,28 @@ struct BinaryenLiteral BinaryenLiteralFloat64Bits(int64_t x);
typedef int32_t BinaryenOp;
-BinaryenOp BinaryenClz(void);
-BinaryenOp BinaryenCtz(void);
-BinaryenOp BinaryenPopcnt(void);
-BinaryenOp BinaryenNeg(void);
-BinaryenOp BinaryenAbs(void);
-BinaryenOp BinaryenCeil(void);
-BinaryenOp BinaryenFloor(void);
-BinaryenOp BinaryenTrunc(void);
-BinaryenOp BinaryenNearest(void);
-BinaryenOp BinaryenSqrt(void);
-BinaryenOp BinaryenEqZ(void);
+BinaryenOp BinaryenClzInt32(void);
+BinaryenOp BinaryenCtzInt32(void);
+BinaryenOp BinaryenPopcntInt32(void);
+BinaryenOp BinaryenNegFloat32(void);
+BinaryenOp BinaryenAbsFloat32(void);
+BinaryenOp BinaryenCeilFloat32(void);
+BinaryenOp BinaryenFloorFloat32(void);
+BinaryenOp BinaryenTruncFloat32(void);
+BinaryenOp BinaryenNearestFloat32(void);
+BinaryenOp BinaryenSqrtFloat32(void);
+BinaryenOp BinaryenEqZInt32(void);
+BinaryenOp BinaryenClzInt64(void);
+BinaryenOp BinaryenCtzInt64(void);
+BinaryenOp BinaryenPopcntInt64(void);
+BinaryenOp BinaryenNegFloat64(void);
+BinaryenOp BinaryenAbsFloat64(void);
+BinaryenOp BinaryenCeilFloat64(void);
+BinaryenOp BinaryenFloorFloat64(void);
+BinaryenOp BinaryenTruncFloat64(void);
+BinaryenOp BinaryenNearestFloat64(void);
+BinaryenOp BinaryenSqrtFloat64(void);
+BinaryenOp BinaryenEqZInt64(void);
BinaryenOp BinaryenExtendSInt32(void);
BinaryenOp BinaryenExtentUInt32(void);
BinaryenOp BinaryenWrapInt64(void);
diff --git a/src/cfg/Relooper.cpp b/src/cfg/Relooper.cpp
index 14941833b..d830caa67 100644
--- a/src/cfg/Relooper.cpp
+++ b/src/cfg/Relooper.cpp
@@ -199,7 +199,7 @@ wasm::Expression* Block::Render(RelooperBuilder& Builder, bool InLoop) {
}
}
} else {
- auto* Now = Builder.makeUnary(wasm::EqZ, Details->Condition);
+ auto* Now = Builder.makeUnary(wasm::EqZInt32, Details->Condition);
if (RemainingConditions) {
RemainingConditions = Builder.makeBinary(wasm::And, RemainingConditions, Now);
} else {
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 368b483ad..3c88c830b 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -32,14 +32,14 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions,
// flip branches to get rid of an i32.eqz
if (curr->ifFalse) {
auto condition = curr->condition->dynCast<Unary>();
- if (condition && condition->op == EqZ && condition->value->type == i32) {
+ if (condition && condition->op == EqZInt32 && condition->value->type == i32) {
curr->condition = condition->value;
std::swap(curr->ifTrue, curr->ifFalse);
}
}
}
void visitUnary(Unary* curr) {
- if (curr->op == EqZ) {
+ if (curr->op == EqZInt32) {
// fold comparisons that flow into an EqZ
auto* child = curr->value->dynCast<Binary>();
if (child && (child->type == i32 || child->type == i64)) {
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 121287846..4559a5ce6 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -283,44 +283,55 @@ struct PrintSExpression : public Visitor<PrintSExpression> {
}
void visitUnary(Unary *curr) {
o << '(';
- prepareColor(o) << printWasmType(curr->isRelational() ? curr->value->type : curr->type) << '.';
+ prepareColor(o);
switch (curr->op) {
- case Clz: o << "clz"; break;
- case Ctz: o << "ctz"; break;
- case Popcnt: o << "popcnt"; break;
- case EqZ: o << "eqz"; break;
- case Neg: o << "neg"; break;
- case Abs: o << "abs"; break;
- case Ceil: o << "ceil"; break;
- case Floor: o << "floor"; break;
- case Trunc: o << "trunc"; break;
- case Nearest: o << "nearest"; break;
- case Sqrt: o << "sqrt"; break;
- case ExtendSInt32: o << "extend_s/i32"; break;
- case ExtendUInt32: o << "extend_u/i32"; break;
- case WrapInt64: o << "wrap/i64"; break;
- case TruncSFloat32ToInt32:
- case TruncSFloat32ToInt64: o << "trunc_s/f32"; break;
- case TruncUFloat32ToInt32:
- case TruncUFloat32ToInt64: o << "trunc_u/f32"; break;
- case TruncSFloat64ToInt32:
- case TruncSFloat64ToInt64: o << "trunc_s/f64"; break;
- case TruncUFloat64ToInt32:
- case TruncUFloat64ToInt64: o << "trunc_u/f64"; break;
- case ReinterpretFloat32: o << "reinterpret/f32"; break;
- case ReinterpretFloat64: o << "reinterpret/f64"; break;
- case ConvertUInt32ToFloat32:
- case ConvertUInt32ToFloat64: o << "convert_u/i32"; break;
- case ConvertSInt32ToFloat32:
- case ConvertSInt32ToFloat64: o << "convert_s/i32"; break;
- case ConvertUInt64ToFloat32:
- case ConvertUInt64ToFloat64: o << "convert_u/i64"; break;
- case ConvertSInt64ToFloat32:
- case ConvertSInt64ToFloat64: o << "convert_s/i64"; break;
- case PromoteFloat32: o << "promote/f32"; break;
- case DemoteFloat64: o << "demote/f64"; break;
- case ReinterpretInt32: o << "reinterpret/i32"; break;
- case ReinterpretInt64: o << "reinterpret/i64"; break;
+ case ClzInt32: o << "i32.clz"; break;
+ case CtzInt32: o << "i32.ctz"; break;
+ case PopcntInt32: o << "i32.popcnt"; break;
+ case EqZInt32: o << "i32.eqz"; break;
+ case ClzInt64: o << "i64.clz"; break;
+ case CtzInt64: o << "i64.ctz"; break;
+ case PopcntInt64: o << "i64.popcnt"; break;
+ case EqZInt64: o << "i64.eqz"; break;
+ case NegFloat32: o << "f32.neg"; break;
+ case AbsFloat32: o << "f32.abs"; break;
+ case CeilFloat32: o << "f32.ceil"; break;
+ case FloorFloat32: o << "f32.floor"; break;
+ case TruncFloat32: o << "f32.trunc"; break;
+ case NearestFloat32: o << "f32.nearest"; break;
+ case SqrtFloat32: o << "f32.sqrt"; break;
+ case NegFloat64: o << "f64.neg"; break;
+ case AbsFloat64: o << "f64.abs"; break;
+ case CeilFloat64: o << "f64.ceil"; break;
+ case FloorFloat64: o << "f64.floor"; break;
+ case TruncFloat64: o << "f64.trunc"; break;
+ case NearestFloat64: o << "f64.nearest"; break;
+ case SqrtFloat64: o << "f64.sqrt"; break;
+ case ExtendSInt32: o << "i64.extend_s/i32"; break;
+ case ExtendUInt32: o << "i64.extend_u/i32"; break;
+ case WrapInt64: o << "i32.wrap/i64"; break;
+ case TruncSFloat32ToInt32: o << "i32.trunc_s/f32"; break;
+ case TruncSFloat32ToInt64: o << "i64.trunc_s/f32"; break;
+ case TruncUFloat32ToInt32: o << "i32.trunc_u/f32"; break;
+ case TruncUFloat32ToInt64: o << "i64.trunc_u/f32"; break;
+ case TruncSFloat64ToInt32: o << "i32.trunc_s/f64"; break;
+ case TruncSFloat64ToInt64: o << "i64.trunc_s/f64"; break;
+ case TruncUFloat64ToInt32: o << "i32.trunc_u/f64"; break;
+ case TruncUFloat64ToInt64: o << "i64.trunc_u/f64"; break;
+ case ReinterpretFloat32: o << "i32.reinterpret/f32"; break;
+ case ReinterpretFloat64: o << "i64.reinterpret/f64"; break;
+ case ConvertUInt32ToFloat32: o << "f32.convert_u/i32"; break;
+ case ConvertUInt32ToFloat64: o << "f64.convert_u/i32"; break;
+ case ConvertSInt32ToFloat32: o << "f32.convert_s/i32"; break;
+ case ConvertSInt32ToFloat64: o << "f64.convert_s/i32"; break;
+ case ConvertUInt64ToFloat32: o << "f32.convert_u/i64"; break;
+ case ConvertUInt64ToFloat64: o << "f64.convert_u/i64"; break;
+ case ConvertSInt64ToFloat32: o << "f32.convert_s/i64"; break;
+ case ConvertSInt64ToFloat64: o << "f64.convert_s/i64"; break;
+ case PromoteFloat32: o << "f64.promote/f32"; break;
+ case DemoteFloat64: o << "f32.demote/f64"; break;
+ case ReinterpretInt32: o << "f32.reinterpret/i32"; break;
+ case ReinterpretInt64: o << "f64.reinterpret/i64"; break;
default: abort();
}
incIndent();
diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp
index 10d04f160..458ce63ca 100644
--- a/src/passes/Vacuum.cpp
+++ b/src/passes/Vacuum.cpp
@@ -81,7 +81,7 @@ struct Vacuum : public WalkerPass<PostWalker<Vacuum, Visitor<Vacuum>>> {
} else if (curr->ifTrue->is<Nop>()) {
curr->ifTrue = curr->ifFalse;
curr->ifFalse = nullptr;
- curr->condition = Builder(*getModule()).makeUnary(EqZ, curr->condition);
+ curr->condition = Builder(*getModule()).makeUnary(EqZInt32, curr->condition);
}
}
if (!curr->ifFalse) {
diff --git a/src/s2wasm.h b/src/s2wasm.h
index bef31486a..68a7c5b62 100644
--- a/src/s2wasm.h
+++ b/src/s2wasm.h
@@ -745,7 +745,7 @@ class S2WasmBuilder {
case 'a': {
if (match("add")) makeBinary(BinaryOp::Add, type);
else if (match("and")) makeBinary(BinaryOp::And, type);
- else if (match("abs")) makeUnary(UnaryOp::Abs, type);
+ else if (match("abs")) makeUnary(type == f32 ? UnaryOp::AbsFloat32 : UnaryOp::AbsFloat64, type);
else abort_on("type.a");
break;
}
@@ -768,10 +768,10 @@ class S2WasmBuilder {
else if (match("convert_u/i32")) makeUnary(type == f32 ? UnaryOp::ConvertUInt32ToFloat32 : UnaryOp::ConvertUInt32ToFloat64, type);
else if (match("convert_s/i64")) makeUnary(type == f32 ? UnaryOp::ConvertSInt64ToFloat32 : UnaryOp::ConvertSInt64ToFloat64, type);
else if (match("convert_u/i64")) makeUnary(type == f32 ? UnaryOp::ConvertUInt64ToFloat32 : UnaryOp::ConvertUInt64ToFloat64, type);
- else if (match("clz")) makeUnary(UnaryOp::Clz, type);
- else if (match("ctz")) makeUnary(UnaryOp::Ctz, type);
+ else if (match("clz")) makeUnary(type == i32 ? UnaryOp::ClzInt32 : UnaryOp::ClzInt64, type);
+ else if (match("ctz")) makeUnary(type == i32 ? UnaryOp::CtzInt32 : UnaryOp::CtzInt64, type);
else if (match("copysign")) makeBinary(BinaryOp::CopySign, type);
- else if (match("ceil")) makeUnary(UnaryOp::Ceil, type);
+ else if (match("ceil")) makeUnary(type == f32 ? UnaryOp::CeilFloat32 : UnaryOp::CeilFloat64, type);
else abort_on("type.c");
break;
}
@@ -784,7 +784,7 @@ class S2WasmBuilder {
break;
}
case 'e': {
- if (match("eqz")) makeUnary(UnaryOp::EqZ, i32);
+ if (match("eqz")) makeUnary(type == i32 ? UnaryOp::EqZInt32 : UnaryOp::EqZInt64, type);
else if (match("eq")) makeBinary(BinaryOp::Eq, i32);
else if (match("extend_s/i32")) makeUnary(UnaryOp::ExtendSInt32, type);
else if (match("extend_u/i32")) makeUnary(UnaryOp::ExtendUInt32, type);
@@ -792,7 +792,7 @@ class S2WasmBuilder {
break;
}
case 'f': {
- if (match("floor")) makeUnary(UnaryOp::Floor, type);
+ if (match("floor")) makeUnary(type == f32 ? UnaryOp::FloorFloat32 : UnaryOp::FloorFloat64, type);
else abort_on("type.e");
break;
}
@@ -825,8 +825,8 @@ class S2WasmBuilder {
break;
}
case 'n': {
- if (match("neg")) makeUnary(UnaryOp::Neg, type);
- else if (match("nearest")) makeUnary(UnaryOp::Nearest, type);
+ if (match("neg")) makeUnary(type == f32 ? UnaryOp::NegFloat32 : UnaryOp::NegFloat64, type);
+ else if (match("nearest")) makeUnary(type == f32 ? UnaryOp::NearestFloat32 : UnaryOp::NearestFloat64, type);
else if (match("ne")) makeBinary(BinaryOp::Ne, i32);
else abort_on("type.n");
break;
@@ -838,7 +838,7 @@ class S2WasmBuilder {
}
case 'p': {
if (match("promote/f32")) makeUnary(UnaryOp::PromoteFloat32, type);
- else if (match("popcnt")) makeUnary(UnaryOp::Popcnt, type);
+ else if (match("popcnt")) makeUnary(type == i32 ? UnaryOp::PopcntInt32 : UnaryOp::PopcntInt64, type);
else abort_on("type.p");
break;
}
@@ -861,7 +861,7 @@ class S2WasmBuilder {
else if (match("sub")) makeBinary(BinaryOp::Sub, type);
else if (match("store")) makeStore(type);
else if (match("select")) makeSelect(type);
- else if (match("sqrt")) makeUnary(UnaryOp::Sqrt, type);
+ else if (match("sqrt")) makeUnary(type == f32 ? UnaryOp::SqrtFloat32 : UnaryOp::SqrtFloat64, type);
else abort_on("type.s");
break;
}
@@ -870,7 +870,7 @@ class S2WasmBuilder {
else if (match("trunc_u/f32")) makeUnary(type == i32 ? UnaryOp::TruncUFloat32ToInt32 : UnaryOp::TruncUFloat32ToInt64, type);
else if (match("trunc_s/f64")) makeUnary(type == i32 ? UnaryOp::TruncSFloat64ToInt32 : UnaryOp::TruncSFloat64ToInt64, type);
else if (match("trunc_u/f64")) makeUnary(type == i32 ? UnaryOp::TruncUFloat64ToInt32 : UnaryOp::TruncUFloat64ToInt64, type);
- else if (match("trunc")) makeUnary(UnaryOp::Trunc, type);
+ else if (match("trunc")) makeUnary(type == f32 ? UnaryOp::TruncFloat32 : UnaryOp::TruncFloat64, type);
else abort_on("type.t");
break;
}
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 9674d12c1..a2ea93605 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -1011,17 +1011,28 @@ public:
if (debug) std::cerr << "zz node: Unary" << std::endl;
recurse(curr->value);
switch (curr->op) {
- case Clz: o << int8_t(curr->type == i32 ? BinaryConsts::I32Clz : BinaryConsts::I64Clz); break;
- case Ctz: o << int8_t(curr->type == i32 ? BinaryConsts::I32Ctz : BinaryConsts::I64Ctz); break;
- case Popcnt: o << int8_t(curr->type == i32 ? BinaryConsts::I32Popcnt : BinaryConsts::I64Popcnt); break;
- case EqZ: o << int8_t(curr->type == i32 ? BinaryConsts::I32EqZ : BinaryConsts::I64EqZ); break;
- case Neg: o << int8_t(curr->type == f64 ? BinaryConsts::F64Neg : BinaryConsts::F32Neg); break; // TODO: wasm.h needs separate opcodes for all these
- case Abs: o << int8_t(curr->type == f32 ? BinaryConsts::F32Abs : BinaryConsts::F64Abs); break;
- case Ceil: o << int8_t(curr->type == f32 ? BinaryConsts::F32Ceil : BinaryConsts::F64Ceil); break;
- case Floor: o << int8_t(curr->type == f32 ? BinaryConsts::F32Floor : BinaryConsts::F64Floor); break;
- case Trunc: o << int8_t(curr->type == f32 ? BinaryConsts::F32Trunc : BinaryConsts::F64Trunc); break;
- case Nearest: o << int8_t(curr->type == f32 ? BinaryConsts::F32NearestInt : BinaryConsts::F64NearestInt); break;
- case Sqrt: o << int8_t(curr->type == f32 ? BinaryConsts::F32Sqrt : BinaryConsts::F64Sqrt); break;
+ case ClzInt32: o << int8_t(BinaryConsts::I32Clz); break;
+ case CtzInt32: o << int8_t(BinaryConsts::I32Ctz); break;
+ case PopcntInt32: o << int8_t(BinaryConsts::I32Popcnt); break;
+ case EqZInt32: o << int8_t(BinaryConsts::I32EqZ); break;
+ case ClzInt64: o << int8_t(BinaryConsts::I64Clz); break;
+ case CtzInt64: o << int8_t(BinaryConsts::I64Ctz); break;
+ case PopcntInt64: o << int8_t(BinaryConsts::I64Popcnt); break;
+ case EqZInt64: o << int8_t(BinaryConsts::I64EqZ); break;
+ case NegFloat32: o << int8_t(BinaryConsts::F32Neg); break;
+ case AbsFloat32: o << int8_t(BinaryConsts::F32Abs); break;
+ case CeilFloat32: o << int8_t(BinaryConsts::F32Ceil); break;
+ case FloorFloat32: o << int8_t(BinaryConsts::F32Floor); break;
+ case TruncFloat32: o << int8_t(BinaryConsts::F32Trunc); break;
+ case NearestFloat32: o << int8_t(BinaryConsts::F32NearestInt); break;
+ case SqrtFloat32: o << int8_t(BinaryConsts::F32Sqrt); break;
+ case NegFloat64: o << int8_t(BinaryConsts::F64Neg); break;
+ case AbsFloat64: o << int8_t(BinaryConsts::F64Abs); break;
+ case CeilFloat64: o << int8_t(BinaryConsts::F64Ceil); break;
+ case FloorFloat64: o << int8_t(BinaryConsts::F64Floor); break;
+ case TruncFloat64: o << int8_t(BinaryConsts::F64Trunc); break;
+ case NearestFloat64: o << int8_t(BinaryConsts::F64NearestInt); break;
+ case SqrtFloat64: o << int8_t(BinaryConsts::F64Sqrt); break;
case ExtendSInt32: o << int8_t(BinaryConsts::I64STruncI32); break;
case ExtendUInt32: o << int8_t(BinaryConsts::I64UTruncI32); break;
case WrapInt64: o << int8_t(BinaryConsts::I32ConvertI64); break;
@@ -1896,26 +1907,26 @@ public:
bool maybeVisitUnary(Expression*& out, uint8_t code) {
Unary* curr;
switch (code) {
- case BinaryConsts::I32Clz: curr = allocator.alloc<Unary>(); curr->op = Clz; curr->type = i32; break;
- case BinaryConsts::I64Clz: curr = allocator.alloc<Unary>(); curr->op = Clz; curr->type = i64; break;
- case BinaryConsts::I32Ctz: curr = allocator.alloc<Unary>(); curr->op = Ctz; curr->type = i32; break;
- case BinaryConsts::I64Ctz: curr = allocator.alloc<Unary>(); curr->op = Ctz; curr->type = i64; break;
- case BinaryConsts::I32Popcnt: curr = allocator.alloc<Unary>(); curr->op = Popcnt; curr->type = i32; break;
- case BinaryConsts::I64Popcnt: curr = allocator.alloc<Unary>(); curr->op = Popcnt; curr->type = i64; break;
- case BinaryConsts::I32EqZ: curr = allocator.alloc<Unary>(); curr->op = EqZ; curr->type = i32; break;
- case BinaryConsts::I64EqZ: curr = allocator.alloc<Unary>(); curr->op = EqZ; curr->type = i64; break;
- case BinaryConsts::F32Neg: curr = allocator.alloc<Unary>(); curr->op = Neg; curr->type = f32; break;
- case BinaryConsts::F64Neg: curr = allocator.alloc<Unary>(); curr->op = Neg; curr->type = f64; break;
- case BinaryConsts::F32Abs: curr = allocator.alloc<Unary>(); curr->op = Abs; curr->type = f32; break;
- case BinaryConsts::F64Abs: curr = allocator.alloc<Unary>(); curr->op = Abs; curr->type = f64; break;
- case BinaryConsts::F32Ceil: curr = allocator.alloc<Unary>(); curr->op = Ceil; curr->type = f32; break;
- case BinaryConsts::F64Ceil: curr = allocator.alloc<Unary>(); curr->op = Ceil; curr->type = f64; break;
- case BinaryConsts::F32Floor: curr = allocator.alloc<Unary>(); curr->op = Floor; curr->type = f32; break;
- case BinaryConsts::F64Floor: curr = allocator.alloc<Unary>(); curr->op = Floor; curr->type = f64; break;
- case BinaryConsts::F32NearestInt: curr = allocator.alloc<Unary>(); curr->op = Nearest; curr->type = f32; break;
- case BinaryConsts::F64NearestInt: curr = allocator.alloc<Unary>(); curr->op = Nearest; curr->type = f64; break;
- case BinaryConsts::F32Sqrt: curr = allocator.alloc<Unary>(); curr->op = Sqrt; curr->type = f32; break;
- case BinaryConsts::F64Sqrt: curr = allocator.alloc<Unary>(); curr->op = Sqrt; curr->type = f64; break;
+ case BinaryConsts::I32Clz: curr = allocator.alloc<Unary>(); curr->op = ClzInt32; curr->type = i32; break;
+ case BinaryConsts::I64Clz: curr = allocator.alloc<Unary>(); curr->op = ClzInt64; curr->type = i64; break;
+ case BinaryConsts::I32Ctz: curr = allocator.alloc<Unary>(); curr->op = CtzInt32; curr->type = i32; break;
+ case BinaryConsts::I64Ctz: curr = allocator.alloc<Unary>(); curr->op = CtzInt64; curr->type = i64; break;
+ case BinaryConsts::I32Popcnt: curr = allocator.alloc<Unary>(); curr->op = PopcntInt32; curr->type = i32; break;
+ case BinaryConsts::I64Popcnt: curr = allocator.alloc<Unary>(); curr->op = PopcntInt64; curr->type = i64; break;
+ case BinaryConsts::I32EqZ: curr = allocator.alloc<Unary>(); curr->op = EqZInt32; curr->type = i32; break;
+ case BinaryConsts::I64EqZ: curr = allocator.alloc<Unary>(); curr->op = EqZInt64; curr->type = i32; break;
+ case BinaryConsts::F32Neg: curr = allocator.alloc<Unary>(); curr->op = NegFloat32; curr->type = f32; break;
+ case BinaryConsts::F64Neg: curr = allocator.alloc<Unary>(); curr->op = NegFloat64; curr->type = f64; break;
+ case BinaryConsts::F32Abs: curr = allocator.alloc<Unary>(); curr->op = AbsFloat32; curr->type = f32; break;
+ case BinaryConsts::F64Abs: curr = allocator.alloc<Unary>(); curr->op = AbsFloat64; curr->type = f64; break;
+ case BinaryConsts::F32Ceil: curr = allocator.alloc<Unary>(); curr->op = CeilFloat32; curr->type = f32; break;
+ case BinaryConsts::F64Ceil: curr = allocator.alloc<Unary>(); curr->op = CeilFloat64; curr->type = f64; break;
+ case BinaryConsts::F32Floor: curr = allocator.alloc<Unary>(); curr->op = FloorFloat32; curr->type = f32; break;
+ case BinaryConsts::F64Floor: curr = allocator.alloc<Unary>(); curr->op = FloorFloat64; curr->type = f64; break;
+ case BinaryConsts::F32NearestInt: curr = allocator.alloc<Unary>(); curr->op = NearestFloat32; curr->type = f32; break;
+ case BinaryConsts::F64NearestInt: curr = allocator.alloc<Unary>(); curr->op = NearestFloat64; curr->type = f64; break;
+ case BinaryConsts::F32Sqrt: curr = allocator.alloc<Unary>(); curr->op = SqrtFloat32; curr->type = f32; break;
+ case BinaryConsts::F64Sqrt: curr = allocator.alloc<Unary>(); curr->op = SqrtFloat64; curr->type = f64; break;
case BinaryConsts::F32UConvertI32: curr = allocator.alloc<Unary>(); curr->op = ConvertUInt32ToFloat32; curr->type = f32; break;
case BinaryConsts::F64UConvertI32: curr = allocator.alloc<Unary>(); curr->op = ConvertUInt32ToFloat64; curr->type = f64; break;
case BinaryConsts::F32SConvertI32: curr = allocator.alloc<Unary>(); curr->op = ConvertSInt32ToFloat32; curr->type = f32; break;
@@ -1930,16 +1941,16 @@ public:
case BinaryConsts::I32ConvertI64: curr = allocator.alloc<Unary>(); curr->op = WrapInt64; curr->type = i32; break;
case BinaryConsts::I32UTruncF32: curr = allocator.alloc<Unary>(); curr->op = TruncUFloat32ToInt32; curr->type = i32; break;
- case BinaryConsts::I32UTruncF64: curr = allocator.alloc<Unary>(); curr->op = TruncUFloat64ToInt64; curr->type = i32; break;
+ case BinaryConsts::I32UTruncF64: curr = allocator.alloc<Unary>(); curr->op = TruncUFloat64ToInt32; curr->type = i32; break;
case BinaryConsts::I32STruncF32: curr = allocator.alloc<Unary>(); curr->op = TruncSFloat32ToInt32; curr->type = i32; break;
- case BinaryConsts::I32STruncF64: curr = allocator.alloc<Unary>(); curr->op = TruncSFloat64ToInt64; curr->type = i32; break;
- case BinaryConsts::I64UTruncF32: curr = allocator.alloc<Unary>(); curr->op = TruncUFloat32ToInt32; curr->type = i64; break;
+ case BinaryConsts::I32STruncF64: curr = allocator.alloc<Unary>(); curr->op = TruncSFloat64ToInt32; curr->type = i32; break;
+ case BinaryConsts::I64UTruncF32: curr = allocator.alloc<Unary>(); curr->op = TruncUFloat32ToInt64; curr->type = i64; break;
case BinaryConsts::I64UTruncF64: curr = allocator.alloc<Unary>(); curr->op = TruncUFloat64ToInt64; curr->type = i64; break;
- case BinaryConsts::I64STruncF32: curr = allocator.alloc<Unary>(); curr->op = TruncSFloat32ToInt32; curr->type = i64; break;
+ case BinaryConsts::I64STruncF32: curr = allocator.alloc<Unary>(); curr->op = TruncSFloat32ToInt64; curr->type = i64; break;
case BinaryConsts::I64STruncF64: curr = allocator.alloc<Unary>(); curr->op = TruncSFloat64ToInt64; curr->type = i64; break;
- case BinaryConsts::F32Trunc: curr = allocator.alloc<Unary>(); curr->op = Trunc; curr->type = f32; break;
- case BinaryConsts::F64Trunc: curr = allocator.alloc<Unary>(); curr->op = Trunc; curr->type = f64; break;
+ case BinaryConsts::F32Trunc: curr = allocator.alloc<Unary>(); curr->op = TruncFloat32; curr->type = f32; break;
+ case BinaryConsts::F64Trunc: curr = allocator.alloc<Unary>(); curr->op = TruncFloat64; curr->type = f64; break;
case BinaryConsts::F32ConvertF64: curr = allocator.alloc<Unary>(); curr->op = DemoteFloat64; curr->type = f32; break;
case BinaryConsts::F64ConvertF32: curr = allocator.alloc<Unary>(); curr->op = PromoteFloat32; curr->type = f64; break;
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index c40132b18..21ccd7a47 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -402,10 +402,10 @@ private:
NOTE_EVAL1(value);
if (value.type == i32) {
switch (curr->op) {
- case Clz: return value.countLeadingZeroes();
- case Ctz: return value.countTrailingZeroes();
- case Popcnt: return value.popCount();
- case EqZ: return Literal(int32_t(value == Literal(int32_t(0))));
+ case ClzInt32: return value.countLeadingZeroes();
+ case CtzInt32: return value.countTrailingZeroes();
+ case PopcntInt32: return value.popCount();
+ case EqZInt32: return Literal(int32_t(value == Literal(int32_t(0))));
case ReinterpretInt32: return value.castToF32();
case ExtendSInt32: return value.extendToSI64();
case ExtendUInt32: return value.extendToUI64();
@@ -418,10 +418,10 @@ private:
}
if (value.type == i64) {
switch (curr->op) {
- case Clz: return value.countLeadingZeroes();
- case Ctz: return value.countTrailingZeroes();
- case Popcnt: return value.popCount();
- case EqZ: return Literal(int32_t(value == Literal(int64_t(0))));
+ case ClzInt64: return value.countLeadingZeroes();
+ case CtzInt64: return value.countTrailingZeroes();
+ case PopcntInt64: return value.popCount();
+ case EqZInt64: return Literal(int32_t(value == Literal(int64_t(0))));
case WrapInt64: return value.truncateToI32();
case ReinterpretInt64: return value.castToF64();
case ConvertUInt64ToFloat32: return value.convertUToF32();
@@ -433,13 +433,13 @@ private:
}
if (value.type == f32) {
switch (curr->op) {
- case Neg: return value.neg();
- case Abs: return value.abs();
- case Ceil: return value.ceil();
- case Floor: return value.floor();
- case Trunc: return value.trunc();
- case Nearest: return value.nearbyint();
- case Sqrt: return value.sqrt();
+ case NegFloat32: return value.neg();
+ case AbsFloat32: return value.abs();
+ case CeilFloat32: return value.ceil();
+ case FloorFloat32: return value.floor();
+ case TruncFloat32: return value.trunc();
+ case NearestFloat32: return value.nearbyint();
+ case SqrtFloat32: return value.sqrt();
case TruncSFloat32ToInt32:
case TruncSFloat32ToInt64: return truncSFloat(curr, value);
case TruncUFloat32ToInt32:
@@ -451,13 +451,13 @@ private:
}
if (value.type == f64) {
switch (curr->op) {
- case Neg: return value.neg();
- case Abs: return value.abs();
- case Ceil: return value.ceil();
- case Floor: return value.floor();
- case Trunc: return value.trunc();
- case Nearest: return value.nearbyint();
- case Sqrt: return value.sqrt();
+ case NegFloat64: return value.neg();
+ case AbsFloat64: return value.abs();
+ case CeilFloat64: return value.ceil();
+ case FloorFloat64: return value.floor();
+ case TruncFloat64: return value.trunc();
+ case NearestFloat64: return value.nearbyint();
+ case SqrtFloat64: return value.sqrt();
case TruncSFloat64ToInt32:
case TruncSFloat64ToInt64: return truncSFloat(curr, value);
case TruncUFloat64ToInt32:
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index 74c2200a9..0ffbfe989 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -529,14 +529,14 @@ public:
strncpy(op, dot + 1, maxNameSize);
switch (op[0]) {
case 'a': {
- if (op[1] == 'b') return makeUnary(s, UnaryOp::Abs, type);
+ if (op[1] == 'b') return makeUnary(s, type == f32 ? UnaryOp::AbsFloat32 : UnaryOp::AbsFloat64, type);
if (op[1] == 'd') return makeBinary(s, BinaryOp::Add, type);
if (op[1] == 'n') return makeBinary(s, BinaryOp::And, type);
abort_on(op);
}
case 'c': {
- if (op[1] == 'e') return makeUnary(s, UnaryOp::Ceil, type);
- if (op[1] == 'l') return makeUnary(s, UnaryOp::Clz, type);
+ if (op[1] == 'e') return makeUnary(s, type == f32 ? UnaryOp::CeilFloat32 : UnaryOp::CeilFloat64, type);
+ if (op[1] == 'l') return makeUnary(s, type == i32 ? UnaryOp::ClzInt32 : UnaryOp::ClzInt64, type);
if (op[1] == 'o') {
if (op[2] == 'p') return makeBinary(s, BinaryOp::CopySign, type);
if (op[2] == 'n') {
@@ -547,7 +547,7 @@ public:
if (op[3] == 's') return makeConst(s, type);
}
}
- if (op[1] == 't') return makeUnary(s, UnaryOp::Ctz, type);
+ if (op[1] == 't') return makeUnary(s, type == i32 ? UnaryOp::CtzInt32 : UnaryOp::CtzInt64, type);
abort_on(op);
}
case 'd': {
@@ -561,13 +561,13 @@ public:
case 'e': {
if (op[1] == 'q') {
if (op[2] == 0) return makeBinary(s, BinaryOp::Eq, type);
- if (op[2] == 'z') return makeUnary(s, UnaryOp::EqZ, type);
+ if (op[2] == 'z') return makeUnary(s, type == i32 ? UnaryOp::EqZInt32 : UnaryOp::EqZInt64, type);
}
if (op[1] == 'x') return makeUnary(s, op[7] == 'u' ? UnaryOp::ExtendUInt32 : UnaryOp::ExtendSInt32, type);
abort_on(op);
}
case 'f': {
- if (op[1] == 'l') return makeUnary(s, UnaryOp::Floor, type);
+ if (op[1] == 'l') return makeUnary(s, type == f32 ? UnaryOp::FloorFloat32 : UnaryOp::FloorFloat64, type);
abort_on(op);
}
case 'g': {
@@ -602,8 +602,8 @@ public:
case 'n': {
if (op[1] == 'e') {
if (op[2] == 0) return makeBinary(s, BinaryOp::Ne, type);
- if (op[2] == 'a') return makeUnary(s, UnaryOp::Nearest, type);
- if (op[2] == 'g') return makeUnary(s, UnaryOp::Neg, type);
+ if (op[2] == 'a') return makeUnary(s, type == f32 ? UnaryOp::NearestFloat32 : UnaryOp::NearestFloat64, type);
+ if (op[2] == 'g') return makeUnary(s, type == f32 ? UnaryOp::NegFloat32 : UnaryOp::NegFloat64, type);
}
abort_on(op);
}
@@ -613,7 +613,7 @@ public:
}
case 'p': {
if (op[1] == 'r') return makeUnary(s, UnaryOp::PromoteFloat32, type);
- if (op[1] == 'o') return makeUnary(s, UnaryOp::Popcnt, type);
+ if (op[1] == 'o') return makeUnary(s, type == i32 ? UnaryOp::PopcntInt32 : UnaryOp::PopcntInt64, type);
abort_on(op);
}
case 'r': {
@@ -632,7 +632,7 @@ public:
return makeBinary(s, op[4] == 'u' ? BinaryOp::ShrU : BinaryOp::ShrS, type);
}
if (op[1] == 'u') return makeBinary(s, BinaryOp::Sub, type);
- if (op[1] == 'q') return makeUnary(s, UnaryOp::Sqrt, type);
+ if (op[1] == 'q') return makeUnary(s, type == f32 ? UnaryOp::SqrtFloat32 : UnaryOp::SqrtFloat64, type);
if (op[1] == 't') return makeStore(s, type);
abort_on(op);
}
@@ -640,7 +640,7 @@ public:
if (op[1] == 'r') {
if (op[6] == 's') return makeUnary(s, op[9] == '3' ? (type == i32 ? UnaryOp::TruncSFloat32ToInt32 : UnaryOp::TruncSFloat32ToInt64) : (type == i32 ? UnaryOp::TruncSFloat64ToInt32 : UnaryOp::TruncSFloat64ToInt64), type);
if (op[6] == 'u') return makeUnary(s, op[9] == '3' ? (type == i32 ? UnaryOp::TruncUFloat32ToInt32 : UnaryOp::TruncUFloat32ToInt64) : (type == i32 ? UnaryOp::TruncUFloat64ToInt32 : UnaryOp::TruncUFloat64ToInt64), type);
- if (op[2] == 'u') return makeUnary(s, UnaryOp::Trunc, type);
+ if (op[2] == 'u') return makeUnary(s, type == f32 ? UnaryOp::TruncFloat32 : UnaryOp::TruncFloat64, type);
}
abort_on(op);
}
@@ -743,17 +743,28 @@ private:
// type is the reported type, e.g. i64.ctz reports i64 (but has a return type of i32, in this case)
// verify the reported type is correct
switch (op) {
- case EqZ:
- case Neg:
- case Abs:
- case Ceil:
- case Floor:
- case Trunc:
- case Nearest:
- case Sqrt:
- case Clz:
- case Ctz:
- case Popcnt: {
+ case EqZInt32:
+ case NegFloat32:
+ case AbsFloat32:
+ case CeilFloat32:
+ case FloorFloat32:
+ case TruncFloat32:
+ case NearestFloat32:
+ case SqrtFloat32:
+ case ClzInt32:
+ case CtzInt32:
+ case PopcntInt32:
+ case EqZInt64:
+ case NegFloat64:
+ case AbsFloat64:
+ case CeilFloat64:
+ case FloorFloat64:
+ case TruncFloat64:
+ case NearestFloat64:
+ case SqrtFloat64:
+ case ClzInt64:
+ case CtzInt64:
+ case PopcntInt64: {
if (ret->value->type != unreachable && type != ret->value->type) throw ParseException(std::string("bad type for ") + getExpressionName(ret) + ": " + printWasmType(type) + " vs value type " + printWasmType(ret->value->type), s.line, s.col);
break;
}
diff --git a/src/wasm-validator.h b/src/wasm-validator.h
index 3d8596ad2..8e94fd368 100644
--- a/src/wasm-validator.h
+++ b/src/wasm-validator.h
@@ -139,7 +139,8 @@ public:
void visitUnary(Unary *curr) {
shouldBeUnequal(curr->value->type, none, curr, "unaries must not receive a none as their input");
switch (curr->op) {
- case EqZ: {
+ case EqZInt32:
+ case EqZInt64: {
shouldBeEqual(curr->type, i32, curr, "eqz must return i32");
break;
}
@@ -147,22 +148,33 @@ public:
}
if (curr->value->type == unreachable) return;
switch (curr->op) {
- case Clz:
- case Ctz:
- case Popcnt:
- case Neg:
- case Abs:
- case Ceil:
- case Floor:
- case Trunc:
- case Nearest:
- case Sqrt: {
+ case ClzInt32:
+ case CtzInt32:
+ case PopcntInt32:
+ case NegFloat32:
+ case AbsFloat32:
+ case CeilFloat32:
+ case FloorFloat32:
+ case TruncFloat32:
+ case NearestFloat32:
+ case SqrtFloat32:
+ case ClzInt64:
+ case CtzInt64:
+ case PopcntInt64:
+ case NegFloat64:
+ case AbsFloat64:
+ case CeilFloat64:
+ case FloorFloat64:
+ case TruncFloat64:
+ case NearestFloat64:
+ case SqrtFloat64: {
if (curr->value->type != unreachable) {
shouldBeEqual(curr->value->type, curr->type, curr, "non-conversion unaries must return the same type");
}
break;
}
- case EqZ: {
+ case EqZInt32:
+ case EqZInt64: {
shouldBeTrue(curr->value->type == i32 || curr->value->type == i64, curr, "eqz input must be i32 or i64");
break;
}
diff --git a/src/wasm.h b/src/wasm.h
index 68c388df8..6e7ca18ce 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -775,10 +775,10 @@ private:
// Operators
enum UnaryOp {
- Clz, Ctz, Popcnt, // int
- Neg, Abs, Ceil, Floor, Trunc, Nearest, Sqrt, // float
+ ClzInt32, ClzInt64, CtzInt32, CtzInt64, PopcntInt32, PopcntInt64, // int
+ NegFloat32, NegFloat64, AbsFloat32, AbsFloat64, CeilFloat32, CeilFloat64, FloorFloat32, FloorFloat64, TruncFloat32, TruncFloat64, NearestFloat32, NearestFloat64, SqrtFloat32, SqrtFloat64, // float
// relational
- EqZ,
+ EqZInt32, EqZInt64,
// conversions
ExtendSInt32, ExtendUInt32, // extend i32 to i64
WrapInt64, // i64 to i32
@@ -1116,21 +1116,32 @@ public:
UnaryOp op;
Expression *value;
- bool isRelational() { return op == EqZ; }
+ bool isRelational() { return op == EqZInt32 || op == EqZInt64; }
void finalize() {
switch (op) {
- case Clz:
- case Ctz:
- case Popcnt:
- case Neg:
- case Abs:
- case Ceil:
- case Floor:
- case Trunc:
- case Nearest:
- case Sqrt: type = value->type; break;
- case EqZ: type = i32; break;
+ case ClzInt32:
+ case CtzInt32:
+ case PopcntInt32:
+ case NegFloat32:
+ case AbsFloat32:
+ case CeilFloat32:
+ case FloorFloat32:
+ case TruncFloat32:
+ case NearestFloat32:
+ case SqrtFloat32:
+ case ClzInt64:
+ case CtzInt64:
+ case PopcntInt64:
+ case NegFloat64:
+ case AbsFloat64:
+ case CeilFloat64:
+ case FloorFloat64:
+ case TruncFloat64:
+ case NearestFloat64:
+ case SqrtFloat64: type = value->type; break;
+ case EqZInt32:
+ case EqZInt64: type = i32; break;
case ExtendSInt32: case ExtendUInt32: type = i64; break;
case WrapInt64: type = i32; break;
case PromoteFloat32: type = f64; break;
@@ -1155,7 +1166,7 @@ public:
case ConvertUInt32ToFloat64:
case ConvertSInt64ToFloat64:
case ConvertUInt64ToFloat64: type = f64; break;
- default: WASM_UNREACHABLE();
+ default: std::cerr << "waka " << op << '\n'; WASM_UNREACHABLE();
}
}
};
diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c
index 728215893..dcf1e78ff 100644
--- a/test/example/c-api-kitchen-sink.c
+++ b/test/example/c-api-kitchen-sink.c
@@ -83,17 +83,17 @@ void test_core() {
BinaryenExpressionRef valueList[] = {
// Unary
- makeUnary(module, BinaryenClz(), 1),
- makeUnary(module, BinaryenCtz(), 2),
- makeUnary(module, BinaryenPopcnt(), 1),
- makeUnary(module, BinaryenNeg(), 3),
- makeUnary(module, BinaryenAbs(), 4),
- makeUnary(module, BinaryenCeil(), 3),
- makeUnary(module, BinaryenFloor(), 4),
- makeUnary(module, BinaryenTrunc(), 3),
- makeUnary(module, BinaryenNearest(), 3),
- makeUnary(module, BinaryenSqrt(), 4),
- makeUnary(module, BinaryenEqZ(), 1),
+ makeUnary(module, BinaryenClzInt32(), 1),
+ makeUnary(module, BinaryenCtzInt64(), 2),
+ makeUnary(module, BinaryenPopcntInt32(), 1),
+ makeUnary(module, BinaryenNegFloat32(), 3),
+ makeUnary(module, BinaryenAbsFloat64(), 4),
+ makeUnary(module, BinaryenCeilFloat32(), 3),
+ makeUnary(module, BinaryenFloorFloat64(), 4),
+ makeUnary(module, BinaryenTruncFloat32(), 3),
+ makeUnary(module, BinaryenNearestFloat64(), 3),
+ makeUnary(module, BinaryenSqrtFloat64(), 4),
+ makeUnary(module, BinaryenEqZInt32(), 1),
makeUnary(module, BinaryenExtendSInt32(), 1),
makeUnary(module, BinaryenExtentUInt32(), 1),
makeUnary(module, BinaryenWrapInt64(), 2),