diff options
-rw-r--r-- | src/asm2wasm.h | 26 | ||||
-rw-r--r-- | src/binaryen-c.cpp | 33 | ||||
-rw-r--r-- | src/binaryen-c.h | 33 | ||||
-rw-r--r-- | src/cfg/Relooper.cpp | 2 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 4 | ||||
-rw-r--r-- | src/passes/Print.cpp | 85 | ||||
-rw-r--r-- | src/passes/Vacuum.cpp | 2 | ||||
-rw-r--r-- | src/s2wasm.h | 22 | ||||
-rw-r--r-- | src/wasm-binary.h | 85 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 44 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 55 | ||||
-rw-r--r-- | src/wasm-validator.h | 36 | ||||
-rw-r--r-- | src/wasm.h | 43 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 22 |
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), |