diff options
-rwxr-xr-x | check.py | 2 | ||||
-rw-r--r-- | src/passes/Print.cpp | 2 | ||||
-rw-r--r-- | src/wasm-binary.h | 8 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 4 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 6 | ||||
-rw-r--r-- | src/wasm.h | 29 | ||||
m--------- | test/spec | 0 |
7 files changed, 48 insertions, 3 deletions
@@ -354,7 +354,7 @@ for t in tests: print '\n[ checking binaryen-shell spec testcases... ]\n' if len(requested) == 0: - BLACKLIST = ['i32.wast', 'i64.wast'] + BLACKLIST = [] spec_tests = [os.path.join('spec', t) for t in sorted(os.listdir(os.path.join('test', 'spec'))) if t not in BLACKLIST] else: spec_tests = requested[:] diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 91c4040f6..b69f7a977 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -284,6 +284,8 @@ struct PrintSExpression : public WasmVisitor<PrintSExpression, void> { case Shl: o << "shl"; break; case ShrU: o << "shr_u"; break; case ShrS: o << "shr_s"; break; + case RotL: o << "rotl"; break; + case RotR: o << "rotr"; break; case Div: o << "div"; break; case CopySign: o << "copysign"; break; case Min: o << "min"; break; diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 47da374c1..715c06287 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -287,6 +287,10 @@ enum ASTNodes { F64ConvertF32 = 0xb2, F64ReinterpretI64 = 0xb3, I64ReinterpretF64 = 0xb5, + I32RotR = 0xb6, + I32RotL = 0xb7, + I64RotR = 0xb8, + I64RotL = 0xb9, I32ReinterpretF32 = 0xfe, // XXX not in v8 spec doc I32LoadMem8S = 0x20, @@ -883,6 +887,8 @@ public: case Shl: INT_TYPED_CODE(Shl);; case ShrU: INT_TYPED_CODE(ShrU); case ShrS: INT_TYPED_CODE(ShrS); + case RotL: INT_TYPED_CODE(RotL); + case RotR: INT_TYPED_CODE(RotR); case Div: FLOAT_TYPED_CODE(Div); case CopySign: FLOAT_TYPED_CODE(CopySign); case Min: FLOAT_TYPED_CODE(Min); @@ -1593,6 +1599,8 @@ public: INT_TYPED_CODE(Shl); INT_TYPED_CODE(ShrU); INT_TYPED_CODE(ShrS); + INT_TYPED_CODE(RotL); + INT_TYPED_CODE(RotR); FLOAT_TYPED_CODE(Div); FLOAT_TYPED_CODE(CopySign); FLOAT_TYPED_CODE(Min); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 2edaad846..f6a3e1027 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -464,6 +464,8 @@ private: case Shl: return left.shl(right.and_(Literal(int32_t(31)))); case ShrU: return left.shrU(right.and_(Literal(int32_t(31)))); case ShrS: return left.shrS(right.and_(Literal(int32_t(31)))); + case RotL: return left.rotL(right); + case RotR: return left.rotR(right); case Eq: return left.eq(right); case Ne: return left.ne(right); case LtS: return left.ltS(right); @@ -505,6 +507,8 @@ private: case Shl: return left.shl(right.and_(Literal(int64_t(63)))); case ShrU: return left.shrU(right.and_(Literal(int64_t(63)))); case ShrS: return left.shrS(right.and_(Literal(int64_t(63)))); + case RotL: return left.rotL(right); + case RotR: return left.rotR(right); case Eq: return left.eq(right); case Ne: return left.ne(right); case LtS: return left.ltS(right); diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 1cd614c1d..cfabbf52d 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -430,7 +430,8 @@ public: WasmType type = stringToWasmType(str, false, true); // Local copy to index into op without bounds checking. constexpr size_t maxNameSize = 15; - char op[maxNameSize + 1] = { '\0' }; + char op[maxNameSize + 1]; + memset(op, 0, maxNameSize + 1); // ensure the whole string is cleared. strncpy(op, dot + 1, maxNameSize); switch (op[0]) { case 'a': { @@ -523,6 +524,9 @@ public: if (op[2] == 'm') return makeBinary(s, op[4] == 'u' ? BinaryOp::RemU : BinaryOp::RemS, type); if (op[2] == 'i') return makeUnary(s, isWasmTypeFloat(type) ? UnaryOp::ReinterpretInt : UnaryOp::ReinterpretFloat, type); } + if (op[1] == 'o' && op[2] == 't') { + return makeBinary(s, op[3] == 'l' ? BinaryOp::RotL : BinaryOp::RotR, type); + } abort_on(op); } case 's': { diff --git a/src/wasm.h b/src/wasm.h index ce6b9d294..26b5e18e1 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -45,6 +45,7 @@ #include <cassert> #include <cmath> +#include <climits> #include <cstddef> #include <cstdint> #include <cstring> @@ -503,6 +504,32 @@ public: default: WASM_UNREACHABLE(); } } + template <typename T> + static T rol(T val, T count) { + T mask = sizeof(T) * CHAR_BIT - 1; + count &= mask; + return (val << count) | (val >> (-count & mask)); + } + Literal rotL(const Literal& other) const { + switch (type) { + case WasmType::i32: return Literal(rol(uint32_t(i32), uint32_t(other.i32))); + case WasmType::i64: return Literal(rol(uint64_t(i64), uint64_t(other.i64))); + default: WASM_UNREACHABLE(); + } + } + template <typename T> + static T ror (T val, T count) { + T mask = sizeof(T) * CHAR_BIT - 1; + count &= mask; + return (val >> count) | (val << (-count & mask)); + } + Literal rotR(const Literal& other) const { + switch (type) { + case WasmType::i32: return Literal(ror(uint32_t(i32), uint32_t(other.i32))); + case WasmType::i64: return Literal(ror(uint64_t(i64), uint64_t(other.i64))); + default: WASM_UNREACHABLE(); + } + } Literal eq(const Literal& other) const { switch (type) { @@ -676,7 +703,7 @@ enum UnaryOp { enum BinaryOp { Add, Sub, Mul, // int or float - DivS, DivU, RemS, RemU, And, Or, Xor, Shl, ShrU, ShrS, // int + DivS, DivU, RemS, RemU, And, Or, Xor, Shl, ShrU, ShrS, RotL, RotR, // int Div, CopySign, Min, Max, // float // relational ops Eq, Ne, // int or float diff --git a/test/spec b/test/spec -Subproject 3fdec99e94434b58d7477834c2be6b81c1aea91 +Subproject 6e6134562e70299bea9e85fc845e5ce210e96db |