summaryrefslogtreecommitdiff
path: root/src/tools/translate-to-fuzz.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/translate-to-fuzz.h')
-rw-r--r--src/tools/translate-to-fuzz.h186
1 files changed, 103 insertions, 83 deletions
diff --git a/src/tools/translate-to-fuzz.h b/src/tools/translate-to-fuzz.h
index a316e6528..39b183d6e 100644
--- a/src/tools/translate-to-fuzz.h
+++ b/src/tools/translate-to-fuzz.h
@@ -101,6 +101,9 @@ private:
// cross-VM comparisons harder)
static const bool DE_NAN = true;
+ // Whether to emit atomics
+ static const bool ATOMICS = true;
+
// after we finish the input, we start going through it again, but xoring
// so it's not identical
int xorFactor = 0;
@@ -377,94 +380,36 @@ private:
nesting++;
Expression* ret;
switch (type) {
- case i32: ret = _makei32(); break;
- case i64: ret = _makei64(); break;
- case f32: ret = _makef32(); break;
- case f64: ret = _makef64(); break;
+ case i32:
+ case i64:
+ case f32:
+ case f64: ret = _makeConcrete(type); break;
case none: ret = _makenone(); break;
case unreachable: ret = _makeunreachable(); break;
default: WASM_UNREACHABLE();
}
+ assert(ret->type == type); // we should create the right type of thing
nesting--;
return ret;
}
- Expression* _makei32() {
- switch (upTo(14)) {
- case 0: return makeBlock(i32);
- case 1: return makeIf(i32);
- case 2: return makeLoop(i32);
- case 3: return makeBreak(i32);
- case 4: return makeCall(i32);
- case 5: return makeCallIndirect(i32);
- case 6: return makeGetLocal(i32);
- case 7: return makeSetLocal(i32);
- case 8: return makeLoad(i32);
- case 9: return makeConst(i32);
- case 10: return makeUnary(i32);
- case 11: return makeBinary(i32);
- case 12: return makeSelect(i32);
- case 13: return makeGetGlobal(i32);
- }
- WASM_UNREACHABLE();
- }
-
- Expression* _makei64() {
- switch (upTo(14)) {
- case 0: return makeBlock(i64);
- case 1: return makeIf(i64);
- case 2: return makeLoop(i64);
- case 3: return makeBreak(i64);
- case 4: return makeCall(i64);
- case 5: return makeCallIndirect(i64);
- case 6: return makeGetLocal(i64);
- case 7: return makeSetLocal(i64);
- case 8: return makeLoad(i64);
- case 9: return makeConst(i64);
- case 10: return makeUnary(i64);
- case 11: return makeBinary(i64);
- case 12: return makeSelect(i64);
- case 13: return makeGetGlobal(i64);
- }
- WASM_UNREACHABLE();
- }
-
- Expression* _makef32() {
- switch (upTo(14)) {
- case 0: return makeBlock(f32);
- case 1: return makeIf(f32);
- case 2: return makeLoop(f32);
- case 3: return makeBreak(f32);
- case 4: return makeCall(f32);
- case 5: return makeCallIndirect(f32);
- case 6: return makeGetLocal(f32);
- case 7: return makeSetLocal(f32);
- case 8: return makeLoad(f32);
- case 9: return makeConst(f32);
- case 10: return makeUnary(f32);
- case 11: return makeBinary(f32);
- case 12: return makeSelect(f32);
- case 13: return makeGetGlobal(f32);
- }
- WASM_UNREACHABLE();
- }
-
- Expression* _makef64() {
- switch (upTo(14)) {
- case 0: return makeBlock(f64);
- case 1: return makeIf(f64);
- case 2: return makeLoop(f64);
- case 3: return makeBreak(f64);
- case 4: return makeCall(f64);
- case 5: return makeCallIndirect(f64);
- case 6: return makeGetLocal(f64);
- case 7: return makeSetLocal(f64);
- case 8: return makeLoad(f64);
- case 9: return makeConst(f64);
- case 10: return makeUnary(f64);
- case 11: return makeBinary(f64);
- case 12: return makeSelect(f64);
- case 13: return makeGetGlobal(f64);
+ Expression* _makeConcrete(WasmType type) {
+ switch (upTo(15)) {
+ case 0: return makeBlock(type);
+ case 1: return makeIf(type);
+ case 2: return makeLoop(type);
+ case 3: return makeBreak(type);
+ case 4: return makeCall(type);
+ case 5: return makeCallIndirect(type);
+ case 6: return makeGetLocal(type);
+ case 7: return makeSetLocal(type);
+ case 8: return makeLoad(type);
+ case 9: return makeConst(type);
+ case 10: return makeUnary(type);
+ case 11: return makeBinary(type);
+ case 12: return makeSelect(type);
+ case 13: return makeGetGlobal(type);
+ case 14: return makeAtomic(type);
}
WASM_UNREACHABLE();
}
@@ -821,7 +766,7 @@ private:
return ret;
}
- Expression* makeLoad(WasmType type) {
+ Load* makeNonAtomicLoad(WasmType type) {
auto offset = logify(get());
auto ptr = makePointer();
switch (type) {
@@ -854,10 +799,22 @@ private:
}
}
- Store* makeStore(WasmType type) {
+ Expression* makeLoad(WasmType type) {
+ auto* ret = makeNonAtomicLoad(type);
+ if (type != i32 && type != i64) return ret;
+ if (!ATOMICS || oneIn(2)) return ret;
+ // make it atomic
+ wasm.memory.shared = true;
+ ret->isAtomic = true;
+ ret->signed_ = false;
+ ret->align = ret->bytes;
+ return ret;
+ }
+
+ Store* makeNonAtomicStore(WasmType type) {
if (type == unreachable) {
// make a normal store, then make it unreachable
- auto* ret = makeStore(getConcreteType());
+ auto* ret = makeNonAtomicStore(getConcreteType());
switch (upTo(3)) {
case 0: ret->ptr = make(unreachable); break;
case 1: ret->value = make(unreachable); break;
@@ -902,6 +859,17 @@ private:
}
}
+ Store* makeStore(WasmType type) {
+ auto* ret = makeNonAtomicStore(type);
+ if (ret->value->type != i32 && ret->value->type != i64) return ret;
+ if (!ATOMICS || oneIn(2)) return ret;
+ // make it atomic
+ wasm.memory.shared = true;
+ ret->isAtomic = true;
+ ret->align = ret->bytes;
+ return ret;
+ }
+
Expression* makeConst(WasmType type) {
Literal value;
switch (upTo(4)) {
@@ -1144,6 +1112,58 @@ private:
return builder.makeUnreachable();
}
+ Expression* makeAtomic(WasmType type) {
+ if (!ATOMICS || (type != i32 && type != i64)) return makeTrivial(type);
+ wasm.memory.shared = true;
+ if (type == i32 && oneIn(2)) {
+ if (oneIn(2)) {
+ auto* ptr = makePointer();
+ auto expectedType = pick(i32, i64);
+ auto* expected = make(expectedType);
+ auto* timeout = make(i64);
+ return builder.makeAtomicWait(ptr, expected, timeout, expectedType);
+ } else {
+ auto* ptr = makePointer();
+ auto* count = make(i32);
+ return builder.makeAtomicWake(ptr, count);
+ }
+ }
+ Index bytes;
+ switch (type) {
+ case i32: {
+ switch (upTo(3)) {
+ case 0: bytes = 1; break;
+ case 1: bytes = pick(1, 2); break;
+ case 2: bytes = pick(1, 2, 4); break;
+ default: WASM_UNREACHABLE();
+ }
+ break;
+ }
+ case i64: {
+ switch (upTo(4)) {
+ case 0: bytes = 1; break;
+ case 1: bytes = pick(1, 2); break;
+ case 2: bytes = pick(1, 2, 4); break;
+ case 3: bytes = pick(1, 2, 4, 8); break;
+ default: WASM_UNREACHABLE();
+ }
+ break;
+ }
+ default: WASM_UNREACHABLE();
+ }
+ auto offset = logify(get());
+ auto* ptr = makePointer();
+ if (oneIn(2)) {
+ auto* value = make(type);
+ return builder.makeAtomicRMW(pick(AtomicRMWOp::Add, AtomicRMWOp::Sub, AtomicRMWOp::And, AtomicRMWOp::Or, AtomicRMWOp::Xor, AtomicRMWOp::Xchg),
+ bytes, offset, ptr, value, type);
+ } else {
+ auto* expected = make(type);
+ auto* replacement = make(type);
+ return builder.makeAtomicCmpxchg(bytes, offset, ptr, expected, replacement, type);
+ }
+ }
+
// special getters
WasmType getType() {