diff options
author | Derek Schuff <dschuff@chromium.org> | 2017-09-06 14:13:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-06 14:13:29 -0700 |
commit | d2a401d27ef3592638e0e7689eebed317966334a (patch) | |
tree | 13f627f7cd3aaeb20ac1708ad1bf244bf7ec07c4 /src | |
parent | 192b59a8bc8e5376ca120dc592d5abad7c654230 (diff) | |
download | binaryen-d2a401d27ef3592638e0e7689eebed317966334a.tar.gz binaryen-d2a401d27ef3592638e0e7689eebed317966334a.tar.bz2 binaryen-d2a401d27ef3592638e0e7689eebed317966334a.zip |
Add support for sign-extension operators from threading proposal (#1167)
These are not atomic operations, but are added with the atomic operations to keep from having to define atomic versions of all the sign-extending loads (an atomic zero-extending load + signext operation can be used instead).
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 2 | ||||
-rw-r--r-- | src/passes/Print.cpp | 5 | ||||
-rw-r--r-- | src/wasm-binary.h | 6 | ||||
-rw-r--r-- | src/wasm.h | 4 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 11 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 9 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 13 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 3 |
8 files changed, 49 insertions, 4 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index acbf39447..1f2f07110 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -31,6 +31,8 @@ #include <ast/properties.h> #include <ast/literal-utils.h> +// TODO: Use the new sign-extension opcodes where appropriate. This needs to be conditionalized on the availability of atomics. + namespace wasm { Name I32_EXPR = "i32.expr", diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 3c538a40e..04b649ff6 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -474,6 +474,11 @@ struct PrintSExpression : public Visitor<PrintSExpression> { case DemoteFloat64: o << "f32.demote/f64"; break; case ReinterpretInt32: o << "f32.reinterpret/i32"; break; case ReinterpretInt64: o << "f64.reinterpret/i64"; break; + case ExtendS8Int32: o << "i32.extend8_s"; break; + case ExtendS16Int32: o << "i32.extend16_s"; break; + case ExtendS8Int64: o << "i64.extend8_s"; break; + case ExtendS16Int64: o << "i64.extend16_s"; break; + case ExtendS32Int64: o << "i64.extend32_s"; break; default: abort(); } incIndent(); diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 6df49b162..256cea75c 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -531,6 +531,12 @@ enum ASTNodes { F32ReinterpretI32 = 0xbe, F64ReinterpretI64 = 0xbf, + I32ExtendS8 = 0xc0, + I32ExtendS16 = 0xc1, + I64ExtendS8 = 0xc2, + I64ExtendS16 = 0xc3, + I64ExtendS32 = 0xc4, + AtomicPrefix = 0xfe }; diff --git a/src/wasm.h b/src/wasm.h index 0cd5b05e8..d2bea45a1 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -98,6 +98,10 @@ enum UnaryOp { PromoteFloat32, // f32 to f64 DemoteFloat64, // f64 to f32 ReinterpretInt32, ReinterpretInt64, // reinterpret bits to float + // The following sign-extention operators go along with wasm atomics support. + // Extend signed subword-sized integer. This differs from e.g. ExtendSInt32 + // because the input integer is in an i64 value insetad of an i32 value. + ExtendS8Int32, ExtendS16Int32, ExtendS8Int64, ExtendS16Int64, ExtendS32Int64, }; enum BinaryOp { diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 9c0e5cd37..68fb293e8 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -1048,6 +1048,11 @@ void WasmBinaryWriter::visitUnary(Unary *curr) { case ReinterpretFloat64: o << int8_t(BinaryConsts::I64ReinterpretF64); break; case ReinterpretInt32: o << int8_t(BinaryConsts::F32ReinterpretI32); break; case ReinterpretInt64: o << int8_t(BinaryConsts::F64ReinterpretI64); break; + case ExtendS8Int32: o << int8_t(BinaryConsts::I32ExtendS8); break; + case ExtendS16Int32: o << int8_t(BinaryConsts::I32ExtendS16); break; + case ExtendS8Int64: o << int8_t(BinaryConsts::I64ExtendS8); break; + case ExtendS16Int64: o << int8_t(BinaryConsts::I64ExtendS16); break; + case ExtendS32Int64: o << int8_t(BinaryConsts::I64ExtendS32); break; default: abort(); } if (curr->type == unreachable) { @@ -2678,6 +2683,12 @@ bool WasmBinaryBuilder::maybeVisitUnary(Expression*& out, uint8_t code) { case BinaryConsts::F32ReinterpretI32: curr = allocator.alloc<Unary>(); curr->op = ReinterpretInt32; curr->type = f32; break; case BinaryConsts::F64ReinterpretI64: curr = allocator.alloc<Unary>(); curr->op = ReinterpretInt64; curr->type = f64; break; + case BinaryConsts::I32ExtendS8: curr = allocator.alloc<Unary>(); curr->op = ExtendS8Int32; curr->type = i32; break; + case BinaryConsts::I32ExtendS16: curr = allocator.alloc<Unary>(); curr->op = ExtendS16Int32; curr->type = i32; break; + case BinaryConsts::I64ExtendS8: curr = allocator.alloc<Unary>(); curr->op = ExtendS8Int64; curr->type = i64; break; + case BinaryConsts::I64ExtendS16: curr = allocator.alloc<Unary>(); curr->op = ExtendS16Int64; curr->type = i64; break; + case BinaryConsts::I64ExtendS32: curr = allocator.alloc<Unary>(); curr->op = ExtendS32Int64; curr->type = i64; break; + default: return false; } if (debug) std::cerr << "zz node: Unary" << std::endl; diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index fd7c7e7ae..a95b551ea 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -699,7 +699,12 @@ Expression* SExpressionWasmBuilder::makeExpression(Element& s) { if (op[2] == 0) return makeBinary(s, BINARY_INT_OR_FLOAT(Eq), 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); + if (op[1] == 'x') { + if (op[6] == '8') return makeUnary(s, type == i32 ? UnaryOp::ExtendS8Int32 : UnaryOp::ExtendS8Int64, type); + if (op[6] == '1') return makeUnary(s, type == i32 ? UnaryOp::ExtendS16Int32 : UnaryOp::ExtendS16Int64, type); + if (op[6] == '3') return makeUnary(s, UnaryOp::ExtendS32Int64, type); + return makeUnary(s, op[7] == 'u' ? UnaryOp::ExtendUInt32 : UnaryOp::ExtendSInt32, type); + } abort_on(op); } case 'f': { @@ -920,6 +925,8 @@ Expression* SExpressionWasmBuilder::makeUnary(Element& s, UnaryOp op, WasmType t break; } case ExtendSInt32: case ExtendUInt32: + case ExtendS8Int32: case ExtendS16Int32: + case ExtendS8Int64: case ExtendS16Int64: case ExtendS32Int64: case WrapInt64: case PromoteFloat32: case DemoteFloat64: diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 8e93b1c38..5534eb7b9 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -430,8 +430,17 @@ void WasmValidator::visitUnary(Unary *curr) { shouldBeTrue(curr->value->type == i64, curr, "i64.eqz input must be i64"); break; } - case ExtendSInt32: shouldBeEqual(curr->value->type, i32, curr, "extend type must be correct"); break; - case ExtendUInt32: shouldBeEqual(curr->value->type, i32, curr, "extend type must be correct"); break; + case ExtendSInt32: + case ExtendUInt32: + case ExtendS8Int32: + case ExtendS16Int32: { + shouldBeEqual(curr->value->type, i32, curr, "extend type must be correct"); break; + } + case ExtendS8Int64: + case ExtendS16Int64: + case ExtendS32Int64: { + shouldBeEqual(curr->value->type, i64, curr, "extend type must be correct"); break; + } case WrapInt64: shouldBeEqual(curr->value->type, i64, curr, "wrap type must be correct"); break; case TruncSFloat32ToInt32: shouldBeEqual(curr->value->type, f32, curr, "trunc type must be correct"); break; case TruncSFloat32ToInt64: shouldBeEqual(curr->value->type, f32, curr, "trunc type must be correct"); break; diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index a781e0fa3..6db11cc7d 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -443,7 +443,8 @@ void Unary::finalize() { case SqrtFloat64: type = value->type; break; case EqZInt32: case EqZInt64: type = i32; break; - case ExtendSInt32: case ExtendUInt32: type = i64; break; + case ExtendS8Int32: case ExtendS16Int32: type = i32; break; + case ExtendSInt32: case ExtendUInt32: case ExtendS8Int64: case ExtendS16Int64: case ExtendS32Int64: type = i64; break; case WrapInt64: type = i32; break; case PromoteFloat32: type = f64; break; case DemoteFloat64: type = f32; break; |