diff options
-rw-r--r-- | src/asm2wasm.h | 104 | ||||
-rw-r--r-- | src/ast/ExpressionAnalyzer.cpp | 56 | ||||
-rw-r--r-- | src/ast/ExpressionManipulator.cpp | 6 | ||||
-rw-r--r-- | src/passes/Vacuum.cpp | 2 | ||||
-rw-r--r-- | src/wasm-builder.h | 2 | ||||
-rw-r--r-- | test/threads.asm.js | 144 | ||||
-rw-r--r-- | test/threads.fromasm | 69 | ||||
-rw-r--r-- | test/threads.fromasm.clamp | 69 | ||||
-rw-r--r-- | test/threads.fromasm.clamp.no-opts | 122 | ||||
-rw-r--r-- | test/threads.fromasm.imprecise | 68 | ||||
-rw-r--r-- | test/threads.fromasm.imprecise.no-opts | 122 | ||||
-rw-r--r-- | test/threads.fromasm.no-opts | 122 |
12 files changed, 884 insertions, 2 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index e8349627f..044517d12 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -110,6 +110,16 @@ Name I32_CTTZ("i32_cttz"), MFTCALL("mftCall_"), MAX_("max"), MIN_("min"), + ATOMICS("Atomics"), + ATOMICS_LOAD("load"), + ATOMICS_STORE("store"), + ATOMICS_EXCHANGE("exchange"), + ATOMICS_COMPARE_EXCHANGE("compareExchange"), + ATOMICS_ADD("add"), + ATOMICS_SUB("sub"), + ATOMICS_AND("and"), + ATOMICS_OR("or"), + ATOMICS_XOR("xor"), EMSCRIPTEN_DEBUGINFO("emscripten_debuginfo"); // Utilities @@ -424,6 +434,17 @@ private: IString Math_max; IString Math_min; + // Imported names of Atomics.* + IString Atomics_load; + IString Atomics_store; + IString Atomics_exchange; + IString Atomics_compareExchange; + IString Atomics_add; + IString Atomics_sub; + IString Atomics_and; + IString Atomics_or; + IString Atomics_xor; + IString llvm_cttz_i32; IString tempDoublePtr; // imported name of tempDoublePtr @@ -1014,6 +1035,44 @@ void Asm2WasmBuilder::processAsm(Ref ast) { Math_min = name; return; } + } else if (module[2] == ATOMICS) { + if (imported[2] == ATOMICS_LOAD) { + assert(Atomics_load.isNull()); + Atomics_load = name; + return; + } else if (imported[2] == ATOMICS_STORE) { + assert(Atomics_store.isNull()); + Atomics_store = name; + return; + } else if (imported[2] == ATOMICS_EXCHANGE) { + assert(Atomics_exchange.isNull()); + Atomics_exchange = name; + return; + } else if (imported[2] == ATOMICS_COMPARE_EXCHANGE) { + assert(Atomics_compareExchange.isNull()); + Atomics_compareExchange = name; + return; + } else if (imported[2] == ATOMICS_ADD) { + assert(Atomics_add.isNull()); + Atomics_add = name; + return; + } else if (imported[2] == ATOMICS_SUB) { + assert(Atomics_sub.isNull()); + Atomics_sub = name; + return; + } else if (imported[2] == ATOMICS_AND) { + assert(Atomics_and.isNull()); + Atomics_and = name; + return; + } else if (imported[2] == ATOMICS_OR) { + assert(Atomics_or.isNull()); + Atomics_or = name; + return; + } else if (imported[2] == ATOMICS_XOR) { + assert(Atomics_xor.isNull()); + Atomics_xor = name; + return; + } } std::string fullName = module[1]->getCString(); fullName += '.'; @@ -2057,6 +2116,51 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { ret->type = ret->left->type; return ret; } + if (name == Atomics_load || + name == Atomics_store || + name == Atomics_exchange || + name == Atomics_compareExchange || + name == Atomics_add || + name == Atomics_sub || + name == Atomics_and || + name == Atomics_or || + name == Atomics_xor) { + // atomic operation + Ref target = ast[2][0]; + assert(target->isString()); + IString heap = target->getIString(); + assert(views.find(heap) != views.end()); + View& view = views[heap]; + wasm.memory.shared = true; + if (name == Atomics_load) { + return builder.makeAtomicLoad(view.bytes, view.signed_, 0, processUnshifted(ast[2][1], view.bytes), asmToWasmType(view.type)); + } else if (name == Atomics_store) { + // asm.js stores return the value, wasm does not + auto type = asmToWasmType(view.type); + auto temp = Builder::addVar(function, type); + return builder.makeSequence( + builder.makeAtomicStore(view.bytes, 0, processUnshifted(ast[2][1], view.bytes), + builder.makeTeeLocal(temp, process(ast[2][2])), + type), + builder.makeGetLocal(temp, type) + ); + } else if (name == Atomics_exchange) { + return builder.makeAtomicRMW(AtomicRMWOp::Xchg, view.bytes, 0, processUnshifted(ast[2][1], view.bytes), process(ast[2][2]), asmToWasmType(view.type)); + } else if (name == Atomics_compareExchange) { + return builder.makeAtomicCmpxchg(view.bytes, 0, processUnshifted(ast[2][1], view.bytes), process(ast[2][2]), process(ast[2][3]), asmToWasmType(view.type)); + } else if (name == Atomics_add) { + return builder.makeAtomicRMW(AtomicRMWOp::Add, view.bytes, 0, processUnshifted(ast[2][1], view.bytes), process(ast[2][2]), asmToWasmType(view.type)); + } else if (name == Atomics_sub) { + return builder.makeAtomicRMW(AtomicRMWOp::Sub, view.bytes, 0, processUnshifted(ast[2][1], view.bytes), process(ast[2][2]), asmToWasmType(view.type)); + } else if (name == Atomics_and) { + return builder.makeAtomicRMW(AtomicRMWOp::And, view.bytes, 0, processUnshifted(ast[2][1], view.bytes), process(ast[2][2]), asmToWasmType(view.type)); + } else if (name == Atomics_or) { + return builder.makeAtomicRMW(AtomicRMWOp::Or, view.bytes, 0, processUnshifted(ast[2][1], view.bytes), process(ast[2][2]), asmToWasmType(view.type)); + } else if (name == Atomics_xor) { + return builder.makeAtomicRMW(AtomicRMWOp::Xor, view.bytes, 0, processUnshifted(ast[2][1], view.bytes), process(ast[2][2]), asmToWasmType(view.type)); + } + WASM_UNREACHABLE(); + } bool tableCall = false; if (wasmOnly) { auto num = ast[2]->size(); diff --git a/src/ast/ExpressionAnalyzer.cpp b/src/ast/ExpressionAnalyzer.cpp index 421206706..b8e2ae34c 100644 --- a/src/ast/ExpressionAnalyzer.cpp +++ b/src/ast/ExpressionAnalyzer.cpp @@ -223,6 +223,34 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left, Expression* right, Expr PUSH(Store, value); break; } + case Expression::Id::AtomicCmpxchgId: { + CHECK(AtomicCmpxchg, bytes); + CHECK(AtomicCmpxchg, offset); + PUSH(AtomicCmpxchg, ptr); + PUSH(AtomicCmpxchg, expected); + PUSH(AtomicCmpxchg, replacement); + break; + } + case Expression::Id::AtomicRMWId: { + CHECK(AtomicRMW, op); + CHECK(AtomicRMW, bytes); + CHECK(AtomicRMW, offset); + PUSH(AtomicRMW, ptr); + PUSH(AtomicRMW, value); + break; + } + case Expression::Id::AtomicWaitId: { + CHECK(AtomicWait, expectedType); + PUSH(AtomicWait, ptr); + PUSH(AtomicWait, expected); + PUSH(AtomicWait, timeout); + break; + } + case Expression::Id::AtomicWakeId: { + PUSH(AtomicWake, ptr); + PUSH(AtomicWake, wakeCount); + break; + } case Expression::Id::ConstId: { CHECK(Const, value); break; @@ -440,6 +468,34 @@ uint32_t ExpressionAnalyzer::hash(Expression* curr) { PUSH(Store, value); break; } + case Expression::Id::AtomicCmpxchgId: { + HASH(AtomicCmpxchg, bytes); + HASH(AtomicCmpxchg, offset); + PUSH(AtomicCmpxchg, ptr); + PUSH(AtomicCmpxchg, expected); + PUSH(AtomicCmpxchg, replacement); + break; + } + case Expression::Id::AtomicRMWId: { + HASH(AtomicRMW, op); + HASH(AtomicRMW, bytes); + HASH(AtomicRMW, offset); + PUSH(AtomicRMW, ptr); + PUSH(AtomicRMW, value); + break; + } + case Expression::Id::AtomicWaitId: { + HASH(AtomicWait, expectedType); + PUSH(AtomicWait, ptr); + PUSH(AtomicWait, expected); + PUSH(AtomicWait, timeout); + break; + } + case Expression::Id::AtomicWakeId: { + PUSH(AtomicWake, ptr); + PUSH(AtomicWake, wakeCount); + break; + } case Expression::Id::ConstId: { HASH(Const, value.type); HASH64(Const, value.getBits()); diff --git a/src/ast/ExpressionManipulator.cpp b/src/ast/ExpressionManipulator.cpp index cca799e10..f5b303488 100644 --- a/src/ast/ExpressionManipulator.cpp +++ b/src/ast/ExpressionManipulator.cpp @@ -117,6 +117,12 @@ Expression* flexibleCopy(Expression* original, Module& wasm, CustomCopier custom copy(curr->ptr), copy(curr->expected), copy(curr->replacement), curr->type); } + Expression* visitAtomicWait(AtomicWait* curr) { + return builder.makeAtomicWait(copy(curr->ptr), copy(curr->expected), copy(curr->timeout), curr->type); + } + Expression* visitAtomicWake(AtomicWake* curr) { + return builder.makeAtomicWake(copy(curr->ptr), copy(curr->wakeCount)); + } Expression* visitConst(Const *curr) { return builder.makeConst(curr->value); } diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp index bb6c7c296..30b28a75d 100644 --- a/src/passes/Vacuum.cpp +++ b/src/passes/Vacuum.cpp @@ -162,7 +162,7 @@ struct Vacuum : public WalkerPass<PostWalker<Vacuum>> { } } - default: WASM_UNREACHABLE(); + default: return curr; // assume needed } } } diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 5acac65ee..ad404c337 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -194,7 +194,7 @@ public: return ret; } Load* makeAtomicLoad(unsigned bytes, bool signed_, uint32_t offset, Expression* ptr, WasmType type) { - Load* load = makeLoad(bytes, signed_, offset, getWasmTypeSize(type), ptr, type); + Load* load = makeLoad(bytes, signed_, offset, bytes, ptr, type); load->isAtomic = true; return load; } diff --git a/test/threads.asm.js b/test/threads.asm.js new file mode 100644 index 000000000..1253e8c42 --- /dev/null +++ b/test/threads.asm.js @@ -0,0 +1,144 @@ +Module["asm"] = (function(global, env, buffer) { + 'use asm'; + + + var HEAP8 = new global.Int8Array(buffer); + var HEAP16 = new global.Int16Array(buffer); + var HEAP32 = new global.Int32Array(buffer); + var HEAPU8 = new global.Uint8Array(buffer); + var HEAPU16 = new global.Uint16Array(buffer); + var HEAPU32 = new global.Uint32Array(buffer); + var HEAPF32 = new global.Float32Array(buffer); + var HEAPF64 = new global.Float64Array(buffer); + + var DYNAMICTOP_PTR=env.DYNAMICTOP_PTR|0; + var tempDoublePtr=env.tempDoublePtr|0; + var ABORT=env.ABORT|0; + var STACKTOP=env.STACKTOP|0; + var STACK_MAX=env.STACK_MAX|0; + + var __THREW__ = 0; + var threwValue = 0; + var setjmpId = 0; + var undef = 0; + var nan = global.NaN, inf = global.Infinity; + var tempInt = 0, tempBigInt = 0, tempBigIntS = 0, tempValue = 0, tempDouble = 0.0; + var tempRet0 = 0; + + var __pthread_ptr = 0; + var __pthread_is_main_runtime_thread = 0; + var __pthread_is_main_browser_thread = 0; + + var Math_floor=global.Math.floor; + var Math_abs=global.Math.abs; + var Math_sqrt=global.Math.sqrt; + var Math_pow=global.Math.pow; + var Math_cos=global.Math.cos; + var Math_sin=global.Math.sin; + var Math_tan=global.Math.tan; + var Math_acos=global.Math.acos; + var Math_asin=global.Math.asin; + var Math_atan=global.Math.atan; + var Math_atan2=global.Math.atan2; + var Math_exp=global.Math.exp; + var Math_log=global.Math.log; + var Math_ceil=global.Math.ceil; + var Math_imul=global.Math.imul; + var Math_min=global.Math.min; + var Math_max=global.Math.max; + var Math_clz32=global.Math.clz32; + var Math_fround=global.Math.fround; + var abort=env.abort; + var assert=env.assert; + var enlargeMemory=env.enlargeMemory; + var getTotalMemory=env.getTotalMemory; + var abortOnCannotGrowMemory=env.abortOnCannotGrowMemory; + var abortStackOverflow=env.abortStackOverflow; + var nullFunc_iiii=env.nullFunc_iiii; + var nullFunc_i=env.nullFunc_i; + var nullFunc_vi=env.nullFunc_vi; + var nullFunc_vii=env.nullFunc_vii; + var nullFunc_ii=env.nullFunc_ii; + var nullFunc_viii=env.nullFunc_viii; + var nullFunc_v=env.nullFunc_v; + var nullFunc_iii=env.nullFunc_iii; + var invoke_iiii=env.invoke_iiii; + var invoke_i=env.invoke_i; + var invoke_vi=env.invoke_vi; + var invoke_vii=env.invoke_vii; + var invoke_ii=env.invoke_ii; + var invoke_viii=env.invoke_viii; + var invoke_v=env.invoke_v; + var invoke_iii=env.invoke_iii; + var __spawn_thread=env.__spawn_thread; + var _putenv=env._putenv; + var _emscripten_get_now_is_monotonic=env._emscripten_get_now_is_monotonic; + var _fpathconf=env._fpathconf; + var ___unlock=env.___unlock; + var _emscripten_syscall=env._emscripten_syscall; + var ___assert_fail=env.___assert_fail; + var _utimes=env._utimes; + var ___buildEnvironment=env.___buildEnvironment; + var _emscripten_asm_const_i=env._emscripten_asm_const_i; + var _clock_gettime=env._clock_gettime; + var _emscripten_futex_wait=env._emscripten_futex_wait; + var _tzset=env._tzset; + var ___setErrNo=env.___setErrNo; + var _emscripten_set_current_thread_status_js=env._emscripten_set_current_thread_status_js; + var _pthread_getschedparam=env._pthread_getschedparam; + var _clearenv=env._clearenv; + var _emscripten_futex_wake=env._emscripten_futex_wake; + var _sysconf=env._sysconf; + var _utime=env._utime; + var ___call_main=env.___call_main; + var _emscripten_memcpy_big=env._emscripten_memcpy_big; + var _confstr=env._confstr; + var _getenv=env._getenv; + var ___syscall54=env.___syscall54; + var _emscripten_has_threading_support=env._emscripten_has_threading_support; + var _pthread_create=env._pthread_create; + var _emscripten_get_now=env._emscripten_get_now; + var _chroot=env._chroot; + var ___lock=env.___lock; + var ___syscall6=env.___syscall6; + var _unsetenv=env._unsetenv; + var ___clock_gettime=env.___clock_gettime; + var _gettimeofday=env._gettimeofday; + var _atexit=env._atexit; + var ___syscall140=env.___syscall140; + var _emscripten_set_thread_name_js=env._emscripten_set_thread_name_js; + var _setenv=env._setenv; + var ___syscall146=env.___syscall146; + var _emscripten_conditional_set_current_thread_status_js=env._emscripten_conditional_set_current_thread_status_js; + var Atomics_load=global.Atomics.load; + var Atomics_store=global.Atomics.store; + var Atomics_exchange=global.Atomics.exchange; + var Atomics_compareExchange=global.Atomics.compareExchange; + var Atomics_add=global.Atomics.add; + var Atomics_sub=global.Atomics.sub; + var Atomics_and=global.Atomics.and; + var Atomics_or=global.Atomics.or; + var Atomics_xor=global.Atomics.xor; + var tempFloat = Math_fround(0); + const f0 = Math_fround(0); + + function test() { + var $temp = 0; + $temp = (Atomics_load(HEAP32, 1229)|0); + $temp = (Atomics_load(HEAPU16, 1229)|0); + $temp = (Atomics_store(HEAP32, $temp>>2, 0)|0); + $temp = (Atomics_exchange(HEAP32, $temp>>2, 1)|0); + $temp = (Atomics_compareExchange(HEAP32, $temp>>2, 1, 2)|0); + $temp = (Atomics_add(HEAP32, $temp>>2, 0)|0); + $temp = (Atomics_sub(HEAP32, $temp>>2, 0)|0); + $temp = (Atomics_and(HEAP32, $temp>>2, 0)|0); + $temp = (Atomics_or(HEAP32, $temp>>2, 0)|0); + $temp = (Atomics_xor(HEAP32, $temp>>2, 0)|0); + $temp = (Atomics_xor(HEAPU32, 1024, 0)|0); + $temp = (Atomics_xor(HEAP16, 1024, 0)|0); + $temp = (Atomics_xor(HEAPU8, 1024, 0)|0); + } + + return { test: test }; +}) +; diff --git a/test/threads.fromasm b/test/threads.fromasm new file mode 100644 index 000000000..5114d985a --- /dev/null +++ b/test/threads.fromasm @@ -0,0 +1,69 @@ +(module + (import "env" "memory" (memory $0 256 256 shared)) + (import "env" "table" (table 0 0 anyfunc)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (data (get_global $memoryBase) "threads.asm.js") + (export "test" (func $test)) + (func $test + (local $0 i32) + (drop + (i32.atomic.load + (i32.const 4916) + ) + ) + (drop + (i32.atomic.rmw.xor + (i32.atomic.rmw.or + (i32.atomic.rmw.and + (i32.atomic.rmw.sub + (i32.atomic.rmw.add + (i32.atomic.rmw.cmpxchg + (block (result i32) + (i32.atomic.store + (i32.atomic.load16_u + (i32.const 2458) + ) + (tee_local $0 + (i32.const 0) + ) + ) + (i32.atomic.rmw.xchg + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 1) + (i32.const 2) + ) + (i32.const 0) + ) + (i32.const 0) + ) + (i32.const 0) + ) + (i32.const 0) + ) + (i32.const 0) + ) + ) + (drop + (i32.atomic.rmw.xor + (i32.const 4096) + (i32.const 0) + ) + ) + (drop + (i32.atomic.rmw16_u.xor + (i32.const 2048) + (i32.const 0) + ) + ) + (drop + (i32.atomic.rmw8_u.xor + (i32.const 1024) + (i32.const 0) + ) + ) + ) +) diff --git a/test/threads.fromasm.clamp b/test/threads.fromasm.clamp new file mode 100644 index 000000000..5114d985a --- /dev/null +++ b/test/threads.fromasm.clamp @@ -0,0 +1,69 @@ +(module + (import "env" "memory" (memory $0 256 256 shared)) + (import "env" "table" (table 0 0 anyfunc)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (data (get_global $memoryBase) "threads.asm.js") + (export "test" (func $test)) + (func $test + (local $0 i32) + (drop + (i32.atomic.load + (i32.const 4916) + ) + ) + (drop + (i32.atomic.rmw.xor + (i32.atomic.rmw.or + (i32.atomic.rmw.and + (i32.atomic.rmw.sub + (i32.atomic.rmw.add + (i32.atomic.rmw.cmpxchg + (block (result i32) + (i32.atomic.store + (i32.atomic.load16_u + (i32.const 2458) + ) + (tee_local $0 + (i32.const 0) + ) + ) + (i32.atomic.rmw.xchg + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 1) + (i32.const 2) + ) + (i32.const 0) + ) + (i32.const 0) + ) + (i32.const 0) + ) + (i32.const 0) + ) + (i32.const 0) + ) + ) + (drop + (i32.atomic.rmw.xor + (i32.const 4096) + (i32.const 0) + ) + ) + (drop + (i32.atomic.rmw16_u.xor + (i32.const 2048) + (i32.const 0) + ) + ) + (drop + (i32.atomic.rmw8_u.xor + (i32.const 1024) + (i32.const 0) + ) + ) + ) +) diff --git a/test/threads.fromasm.clamp.no-opts b/test/threads.fromasm.clamp.no-opts new file mode 100644 index 000000000..1c65d0d36 --- /dev/null +++ b/test/threads.fromasm.clamp.no-opts @@ -0,0 +1,122 @@ +(module + (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32)) + (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) + (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) + (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) + (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) + (import "global" "NaN" (global $nan$asm2wasm$import f64)) + (import "global" "Infinity" (global $inf$asm2wasm$import f64)) + (import "env" "memory" (memory $0 256 256 shared)) + (import "env" "table" (table 0 0 anyfunc)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (global $DYNAMICTOP_PTR (mut i32) (get_global $DYNAMICTOP_PTR$asm2wasm$import)) + (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) + (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) + (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) + (global $STACK_MAX (mut i32) (get_global $STACK_MAX$asm2wasm$import)) + (global $__THREW__ (mut i32) (i32.const 0)) + (global $threwValue (mut i32) (i32.const 0)) + (global $setjmpId (mut i32) (i32.const 0)) + (global $undef (mut i32) (i32.const 0)) + (global $nan (mut f64) (get_global $nan$asm2wasm$import)) + (global $inf (mut f64) (get_global $inf$asm2wasm$import)) + (global $tempInt (mut i32) (i32.const 0)) + (global $tempBigInt (mut i32) (i32.const 0)) + (global $tempBigIntS (mut i32) (i32.const 0)) + (global $tempValue (mut i32) (i32.const 0)) + (global $tempDouble (mut f64) (f64.const 0)) + (global $tempRet0 (mut i32) (i32.const 0)) + (global $__pthread_ptr (mut i32) (i32.const 0)) + (global $__pthread_is_main_runtime_thread (mut i32) (i32.const 0)) + (global $__pthread_is_main_browser_thread (mut i32) (i32.const 0)) + (global $tempFloat (mut f32) (f32.const 0)) + (global $f0 (mut f32) (f32.const 0)) + (export "test" (func $test)) + (func $test + (local $$temp i32) + (local $1 i32) + (set_local $$temp + (i32.atomic.load + (i32.const 4916) + ) + ) + (set_local $$temp + (i32.atomic.load16_u + (i32.const 2458) + ) + ) + (set_local $$temp + (block (result i32) + (i32.atomic.store + (get_local $$temp) + (tee_local $1 + (i32.const 0) + ) + ) + (get_local $1) + ) + ) + (set_local $$temp + (i32.atomic.rmw.xchg + (get_local $$temp) + (i32.const 1) + ) + ) + (set_local $$temp + (i32.atomic.rmw.cmpxchg + (get_local $$temp) + (i32.const 1) + (i32.const 2) + ) + ) + (set_local $$temp + (i32.atomic.rmw.add + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.sub + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.and + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.or + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.xor + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.xor + (i32.const 4096) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw16_u.xor + (i32.const 2048) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw8_u.xor + (i32.const 1024) + (i32.const 0) + ) + ) + ) +) diff --git a/test/threads.fromasm.imprecise b/test/threads.fromasm.imprecise new file mode 100644 index 000000000..bad9963c8 --- /dev/null +++ b/test/threads.fromasm.imprecise @@ -0,0 +1,68 @@ +(module + (import "env" "memory" (memory $0 256 256 shared)) + (import "env" "table" (table 0 0 anyfunc)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (export "test" (func $test)) + (func $test + (local $0 i32) + (drop + (i32.atomic.load + (i32.const 4916) + ) + ) + (drop + (i32.atomic.rmw.xor + (i32.atomic.rmw.or + (i32.atomic.rmw.and + (i32.atomic.rmw.sub + (i32.atomic.rmw.add + (i32.atomic.rmw.cmpxchg + (block (result i32) + (i32.atomic.store + (i32.atomic.load16_u + (i32.const 2458) + ) + (tee_local $0 + (i32.const 0) + ) + ) + (i32.atomic.rmw.xchg + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 1) + (i32.const 2) + ) + (i32.const 0) + ) + (i32.const 0) + ) + (i32.const 0) + ) + (i32.const 0) + ) + (i32.const 0) + ) + ) + (drop + (i32.atomic.rmw.xor + (i32.const 4096) + (i32.const 0) + ) + ) + (drop + (i32.atomic.rmw16_u.xor + (i32.const 2048) + (i32.const 0) + ) + ) + (drop + (i32.atomic.rmw8_u.xor + (i32.const 1024) + (i32.const 0) + ) + ) + ) +) diff --git a/test/threads.fromasm.imprecise.no-opts b/test/threads.fromasm.imprecise.no-opts new file mode 100644 index 000000000..1c65d0d36 --- /dev/null +++ b/test/threads.fromasm.imprecise.no-opts @@ -0,0 +1,122 @@ +(module + (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32)) + (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) + (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) + (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) + (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) + (import "global" "NaN" (global $nan$asm2wasm$import f64)) + (import "global" "Infinity" (global $inf$asm2wasm$import f64)) + (import "env" "memory" (memory $0 256 256 shared)) + (import "env" "table" (table 0 0 anyfunc)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (global $DYNAMICTOP_PTR (mut i32) (get_global $DYNAMICTOP_PTR$asm2wasm$import)) + (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) + (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) + (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) + (global $STACK_MAX (mut i32) (get_global $STACK_MAX$asm2wasm$import)) + (global $__THREW__ (mut i32) (i32.const 0)) + (global $threwValue (mut i32) (i32.const 0)) + (global $setjmpId (mut i32) (i32.const 0)) + (global $undef (mut i32) (i32.const 0)) + (global $nan (mut f64) (get_global $nan$asm2wasm$import)) + (global $inf (mut f64) (get_global $inf$asm2wasm$import)) + (global $tempInt (mut i32) (i32.const 0)) + (global $tempBigInt (mut i32) (i32.const 0)) + (global $tempBigIntS (mut i32) (i32.const 0)) + (global $tempValue (mut i32) (i32.const 0)) + (global $tempDouble (mut f64) (f64.const 0)) + (global $tempRet0 (mut i32) (i32.const 0)) + (global $__pthread_ptr (mut i32) (i32.const 0)) + (global $__pthread_is_main_runtime_thread (mut i32) (i32.const 0)) + (global $__pthread_is_main_browser_thread (mut i32) (i32.const 0)) + (global $tempFloat (mut f32) (f32.const 0)) + (global $f0 (mut f32) (f32.const 0)) + (export "test" (func $test)) + (func $test + (local $$temp i32) + (local $1 i32) + (set_local $$temp + (i32.atomic.load + (i32.const 4916) + ) + ) + (set_local $$temp + (i32.atomic.load16_u + (i32.const 2458) + ) + ) + (set_local $$temp + (block (result i32) + (i32.atomic.store + (get_local $$temp) + (tee_local $1 + (i32.const 0) + ) + ) + (get_local $1) + ) + ) + (set_local $$temp + (i32.atomic.rmw.xchg + (get_local $$temp) + (i32.const 1) + ) + ) + (set_local $$temp + (i32.atomic.rmw.cmpxchg + (get_local $$temp) + (i32.const 1) + (i32.const 2) + ) + ) + (set_local $$temp + (i32.atomic.rmw.add + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.sub + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.and + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.or + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.xor + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.xor + (i32.const 4096) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw16_u.xor + (i32.const 2048) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw8_u.xor + (i32.const 1024) + (i32.const 0) + ) + ) + ) +) diff --git a/test/threads.fromasm.no-opts b/test/threads.fromasm.no-opts new file mode 100644 index 000000000..1c65d0d36 --- /dev/null +++ b/test/threads.fromasm.no-opts @@ -0,0 +1,122 @@ +(module + (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32)) + (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) + (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) + (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) + (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) + (import "global" "NaN" (global $nan$asm2wasm$import f64)) + (import "global" "Infinity" (global $inf$asm2wasm$import f64)) + (import "env" "memory" (memory $0 256 256 shared)) + (import "env" "table" (table 0 0 anyfunc)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (global $DYNAMICTOP_PTR (mut i32) (get_global $DYNAMICTOP_PTR$asm2wasm$import)) + (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) + (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) + (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) + (global $STACK_MAX (mut i32) (get_global $STACK_MAX$asm2wasm$import)) + (global $__THREW__ (mut i32) (i32.const 0)) + (global $threwValue (mut i32) (i32.const 0)) + (global $setjmpId (mut i32) (i32.const 0)) + (global $undef (mut i32) (i32.const 0)) + (global $nan (mut f64) (get_global $nan$asm2wasm$import)) + (global $inf (mut f64) (get_global $inf$asm2wasm$import)) + (global $tempInt (mut i32) (i32.const 0)) + (global $tempBigInt (mut i32) (i32.const 0)) + (global $tempBigIntS (mut i32) (i32.const 0)) + (global $tempValue (mut i32) (i32.const 0)) + (global $tempDouble (mut f64) (f64.const 0)) + (global $tempRet0 (mut i32) (i32.const 0)) + (global $__pthread_ptr (mut i32) (i32.const 0)) + (global $__pthread_is_main_runtime_thread (mut i32) (i32.const 0)) + (global $__pthread_is_main_browser_thread (mut i32) (i32.const 0)) + (global $tempFloat (mut f32) (f32.const 0)) + (global $f0 (mut f32) (f32.const 0)) + (export "test" (func $test)) + (func $test + (local $$temp i32) + (local $1 i32) + (set_local $$temp + (i32.atomic.load + (i32.const 4916) + ) + ) + (set_local $$temp + (i32.atomic.load16_u + (i32.const 2458) + ) + ) + (set_local $$temp + (block (result i32) + (i32.atomic.store + (get_local $$temp) + (tee_local $1 + (i32.const 0) + ) + ) + (get_local $1) + ) + ) + (set_local $$temp + (i32.atomic.rmw.xchg + (get_local $$temp) + (i32.const 1) + ) + ) + (set_local $$temp + (i32.atomic.rmw.cmpxchg + (get_local $$temp) + (i32.const 1) + (i32.const 2) + ) + ) + (set_local $$temp + (i32.atomic.rmw.add + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.sub + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.and + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.or + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.xor + (get_local $$temp) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw.xor + (i32.const 4096) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw16_u.xor + (i32.const 2048) + (i32.const 0) + ) + ) + (set_local $$temp + (i32.atomic.rmw8_u.xor + (i32.const 1024) + (i32.const 0) + ) + ) + ) +) |