Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d981b7e
Implement v128 initializers / exemplary add
dcodeIO Feb 22, 2019
5689b69
defer to generic v128, implement extract_lane/replace_lane
dcodeIO Feb 23, 2019
c83ce39
reuse write helpers, validate lane index
dcodeIO Feb 23, 2019
62ba17b
add simd shuffle, bitselect and shift bindings
dcodeIO Feb 23, 2019
7c9fcf0
implement v8x16.shuffle
dcodeIO Feb 23, 2019
3c6392e
update actual fixture
dcodeIO Feb 23, 2019
7728857
fix currentType mismatch
dcodeIO Feb 23, 2019
74e5cc2
add zero-cost abstraction experiment
dcodeIO Feb 23, 2019
1884c72
fix non-functional test
dcodeIO Feb 23, 2019
547eb6b
generic shuffle
dcodeIO Feb 25, 2019
dc81231
fix i64x2.add, accept isize/usize
dcodeIO Feb 25, 2019
7893474
load/store, sub, mul, div
dcodeIO Feb 25, 2019
56a221e
fix test
dcodeIO Feb 25, 2019
4bb239f
neg, add/sub_saturate, shl, shr, and, or, xor, not, bitselect, any/al…
dcodeIO Feb 26, 2019
6e96f22
check alignment
dcodeIO Feb 26, 2019
17c48a1
untyped v128 eq/ne for testing
dcodeIO Feb 26, 2019
c127efc
what happens if..
dcodeIO Feb 26, 2019
afcf625
or if..
dcodeIO Feb 26, 2019
0f82469
try this
dcodeIO Feb 26, 2019
aba5c1f
enable others
dcodeIO Feb 26, 2019
b6c8a75
maybe just a fixture even though I can't run it locally
dcodeIO Feb 26, 2019
4e198dd
let's test things
dcodeIO Feb 26, 2019
674e1a2
fixture
dcodeIO Feb 26, 2019
a32366c
design some subtypes
dcodeIO Feb 26, 2019
121df6e
actual test assertions
dcodeIO Feb 27, 2019
74d5b2f
instructions for days
dcodeIO Feb 27, 2019
21590c5
instructions for weeks
dcodeIO Feb 27, 2019
13549b0
definitions for months
dcodeIO Feb 27, 2019
8b5bfd9
universal field alignment, see #518
dcodeIO Feb 27, 2019
ecd538f
where did that come from..
dcodeIO Feb 27, 2019
29218a4
progress
dcodeIO Feb 27, 2019
58e50c5
progress
dcodeIO Feb 27, 2019
ea84dfb
progress
dcodeIO Feb 27, 2019
9f48ebe
definitions for years
dcodeIO Feb 27, 2019
e15b539
Merge branch 'master' into simd-init
dcodeIO Feb 27, 2019
466b7e2
remaining tests
dcodeIO Feb 28, 2019
46c4fcd
revert subtypes
dcodeIO Feb 28, 2019
1a9c4d1
apply new load/store immAlign argument
dcodeIO Feb 28, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ jobs:
script:
- npm run all
env: Runs the tests on node.js stable
- node_js: node
script:
- npm run clean && npm run test:compiler
env:
- ASC_FEATURES="simd"
- NVM_NODEJS_ORG_MIRROR="https://nodejs.org/download/v8-canary/"
2,380 changes: 2,308 additions & 72 deletions src/builtins.ts

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,16 @@ export namespace CommonSymbols {
export const f32 = "f32";
export const f64 = "f64";
export const v128 = "v128";
export const i8x16 = "i8x16";
export const u8x16 = "u8x16";
export const i16x8 = "i16x8";
export const u16x8 = "u16x8";
export const i32x4 = "i32x4";
export const u32x4 = "u32x4";
export const i64x2 = "i64x2";
export const u64x2 = "u64x2";
export const f32x4 = "f32x4";
export const f64x2 = "f64x2";
export const void_ = "void";
export const number = "number";
export const boolean = "boolean";
Expand Down Expand Up @@ -146,6 +156,7 @@ export namespace LibrarySymbols {
export const ASC_FEATURE_SIGN_EXTENSION = "ASC_FEATURE_SIGN_EXTENSION";
export const ASC_FEATURE_BULK_MEMORY = "ASC_FEATURE_BULK_MEMORY";
export const ASC_FEATURE_SIMD = "ASC_FEATURE_SIMD";
export const ASC_FEATURE_THREADS = "ASC_FEATURE_THREADS";
// classes
export const I8 = "I8";
export const I16 = "I16";
Expand Down
12 changes: 12 additions & 0 deletions src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3199,6 +3199,12 @@ export class Compiler extends DiagnosticEmitter {
expr = module.createBinary(BinaryOp.EqF64, leftExpr, rightExpr);
break;
}
case TypeKind.V128: {
expr = module.createUnary(UnaryOp.AllTrueVecI8x16,
module.createBinary(BinaryOp.EqVecI8x16, leftExpr, rightExpr)
);
break;
}
default: {
assert(false);
expr = module.createUnreachable();
Expand Down Expand Up @@ -3287,6 +3293,12 @@ export class Compiler extends DiagnosticEmitter {
expr = module.createBinary(BinaryOp.NeF64, leftExpr, rightExpr);
break;
}
case TypeKind.V128: {
expr = module.createUnary(UnaryOp.AnyTrueVecI8x16,
module.createBinary(BinaryOp.NeVecI8x16, leftExpr, rightExpr)
);
break;
}
default: {
assert(false);
expr = module.createUnreachable();
Expand Down
4 changes: 4 additions & 0 deletions src/diagnosticMessages.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export enum DiagnosticCode {
Optional_properties_are_not_supported = 219,
Expression_must_be_a_compile_time_constant = 220,
Module_cannot_have_multiple_start_functions = 221,
_0_must_be_a_value_between_1_and_2_inclusive = 222,
_0_must_be_a_power_of_two = 223,
Unterminated_string_literal = 1002,
Identifier_expected = 1003,
_0_expected = 1005,
Expand Down Expand Up @@ -165,6 +167,8 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
case 219: return "Optional properties are not supported.";
case 220: return "Expression must be a compile-time constant.";
case 221: return "Module cannot have multiple start functions.";
case 222: return "'{0}' must be a value between '{1}' and '{2}' inclusive.";
case 223: return "'{0}' must be a power of two.";
case 1002: return "Unterminated string literal.";
case 1003: return "Identifier expected.";
case 1005: return "'{0}' expected.";
Expand Down
2 changes: 2 additions & 0 deletions src/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"Optional properties are not supported.": 219,
"Expression must be a compile-time constant.": 220,
"Module cannot have multiple start functions.": 221,
"'{0}' must be a value between '{1}' and '{2}' inclusive.": 222,
"'{0}' must be a power of two.": 223,

"Unterminated string literal.": 1002,
"Identifier expected.": 1003,
Expand Down
9 changes: 9 additions & 0 deletions src/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ export class Flow {
case NativeType.I64: { temps = parentFunction.tempI64s; break; }
case NativeType.F32: { temps = parentFunction.tempF32s; break; }
case NativeType.F64: { temps = parentFunction.tempF64s; break; }
case NativeType.V128: { temps = parentFunction.tempV128s; break; }
default: throw new Error("concrete type expected");
}
var local: Local;
Expand Down Expand Up @@ -270,6 +271,10 @@ export class Flow {
temps = parentFunction.tempF64s || (parentFunction.tempF64s = []);
break;
}
case NativeType.V128: {
temps = parentFunction.tempV128s || (parentFunction.tempV128s = []);
break;
}
default: throw new Error("concrete type expected");
}
assert(local.index >= 0);
Expand Down Expand Up @@ -297,6 +302,10 @@ export class Flow {
temps = parentFunction.tempF64s || (parentFunction.tempF64s = []);
break;
}
case NativeType.V128: {
temps = parentFunction.tempV128s || (parentFunction.tempV128s = []);
break;
}
default: throw new Error("concrete type expected");
}
var local: Local;
Expand Down
205 changes: 146 additions & 59 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export enum UnaryOp {
ExtendI16ToI32 = _BinaryenExtendS16Int32(),
ExtendI8ToI64 = _BinaryenExtendS8Int64(),
ExtendI16ToI64 = _BinaryenExtendS16Int64(),
ExtendI32ToI64 = _BinaryenExtendS32Int64()
ExtendI32ToI64 = _BinaryenExtendS32Int64(),

// see: https://github.com/WebAssembly/nontrapping-float-to-int-conversions
// TruncF32ToI32Sat
Expand All @@ -133,6 +133,41 @@ export enum UnaryOp {
// TruncF32ToU64Sat
// TruncF64ToI64Sat
// TruncF64ToU64Sat

// see: https://github.com/WebAssembly/simd
SplatVecI8x16 = _BinaryenSplatVecI8x16(),
SplatVecI16x8 = _BinaryenSplatVecI16x8(),
SplatVecI32x4 = _BinaryenSplatVecI32x4(),
SplatVecI64x2 = _BinaryenSplatVecI64x2(),
SplatVecF32x4 = _BinaryenSplatVecF32x4(),
SplatVecF64x2 = _BinaryenSplatVecF64x2(),
NotVec128 = _BinaryenNotVec128(),
NegVecI8x16 = _BinaryenNegVecI8x16(),
AnyTrueVecI8x16 = _BinaryenAnyTrueVecI8x16(),
AllTrueVecI8x16 = _BinaryenAllTrueVecI8x16(),
NegVecI16x8 = _BinaryenNegVecI16x8(),
AnyTrueVecI16x8 = _BinaryenAnyTrueVecI16x8(),
AllTrueVecI16x8 = _BinaryenAllTrueVecI16x8(),
NegVecI32x4 = _BinaryenNegVecI32x4(),
AnyTrueVecI32x4 = _BinaryenAnyTrueVecI32x4(),
AllTrueVecI32x4 = _BinaryenAllTrueVecI32x4(),
NegVecI64x2 = _BinaryenNegVecI64x2(),
AnyTrueVecI64x2 = _BinaryenAnyTrueVecI64x2(),
AllTrueVecI64x2 = _BinaryenAllTrueVecI64x2(),
AbsVecF32x4 = _BinaryenAbsVecF32x4(),
NegVecF32x4 = _BinaryenNegVecF32x4(),
SqrtVecF32x4 = _BinaryenSqrtVecF32x4(),
AbsVecF64x2 = _BinaryenAbsVecF64x2(),
NegVecF64x2 = _BinaryenNegVecF64x2(),
SqrtVecF64x2 = _BinaryenSqrtVecF64x2(),
TruncSatSVecF32x4ToVecI32x4 = _BinaryenTruncSatSVecF32x4ToVecI32x4(),
TruncSatUVecF32x4ToVecI32x4 = _BinaryenTruncSatUVecF32x4ToVecI32x4(),
TruncSatSVecF64x2ToVecI64x2 = _BinaryenTruncSatSVecF64x2ToVecI64x2(),
TruncSatUVecF64x2ToVecI64x2 = _BinaryenTruncSatUVecF64x2ToVecI64x2(),
ConvertSVecI32x4ToVecF32x4 = _BinaryenConvertSVecI32x4ToVecF32x4(),
ConvertUVecI32x4ToVecF32x4 = _BinaryenConvertUVecI32x4ToVecF32x4(),
ConvertSVecI64x2ToVecF64x2 = _BinaryenConvertSVecI64x2ToVecF64x2(),
ConvertUVecI64x2ToVecF64x2 = _BinaryenConvertUVecI64x2ToVecF64x2()
}

export enum BinaryOp {
Expand Down Expand Up @@ -211,61 +246,9 @@ export enum BinaryOp {
LtF64 = _BinaryenLtFloat64(),
LeF64 = _BinaryenLeFloat64(),
GtF64 = _BinaryenGtFloat64(),
GeF64 = _BinaryenGeFloat64()
}

export enum HostOp {
CurrentMemory = _BinaryenCurrentMemory(),
GrowMemory = _BinaryenGrowMemory(),

// see: https://github.com/WebAssembly/bulk-memory-operations
// MoveMemory
// SetMemory
}

export enum AtomicRMWOp {
Add = _BinaryenAtomicRMWAdd(),
Sub = _BinaryenAtomicRMWSub(),
And = _BinaryenAtomicRMWAnd(),
Or = _BinaryenAtomicRMWOr(),
Xor = _BinaryenAtomicRMWXor(),
Xchg = _BinaryenAtomicRMWXchg()
}
GeF64 = _BinaryenGeFloat64(),

export enum SIMDOp {
SplatVecI8x16 = _BinaryenSplatVecI8x16(),
SplatVecI16x8 = _BinaryenSplatVecI16x8(),
SplatVecI32x4 = _BinaryenSplatVecI32x4(),
SplatVecI64x2 = _BinaryenSplatVecI64x2(),
SplatVecF32x4 = _BinaryenSplatVecF32x4(),
SplatVecF64x2 = _BinaryenSplatVecF64x2(),
NotVec128 = _BinaryenNotVec128(),
NegVecI8x16 = _BinaryenNegVecI8x16(),
AnyTrueVecI8x16 = _BinaryenAnyTrueVecI8x16(),
AllTrueVecI8x16 = _BinaryenAllTrueVecI8x16(),
NegVecI16x8 = _BinaryenNegVecI16x8(),
AnyTrueVecI16x8 = _BinaryenAnyTrueVecI16x8(),
AllTrueVecI16x8 = _BinaryenAllTrueVecI16x8(),
NegVecI32x4 = _BinaryenNegVecI32x4(),
AnyTrueVecI32x4 = _BinaryenAnyTrueVecI32x4(),
AllTrueVecI32x4 = _BinaryenAllTrueVecI32x4(),
NegVecI64x2 = _BinaryenNegVecI64x2(),
AnyTrueVecI64x2 = _BinaryenAnyTrueVecI64x2(),
AllTrueVecI64x2 = _BinaryenAllTrueVecI64x2(),
AbsVecF32x4 = _BinaryenAbsVecF32x4(),
NegVecF32x4 = _BinaryenNegVecF32x4(),
SqrtVecF32x4 = _BinaryenSqrtVecF32x4(),
AbsVecF64x2 = _BinaryenAbsVecF64x2(),
NegVecF64x2 = _BinaryenNegVecF64x2(),
SqrtVecF64x2 = _BinaryenSqrtVecF64x2(),
TruncSatSVecF32x4ToVecI32x4 = _BinaryenTruncSatSVecF32x4ToVecI32x4(),
TruncSatUVecF32x4ToVecI32x4 = _BinaryenTruncSatUVecF32x4ToVecI32x4(),
TruncSatSVecF64x2ToVecI64x2 = _BinaryenTruncSatSVecF64x2ToVecI64x2(),
TruncSatUVecF64x2ToVecI64x2 = _BinaryenTruncSatUVecF64x2ToVecI64x2(),
ConvertSVecI32x4ToVecF32x4 = _BinaryenConvertSVecI32x4ToVecF32x4(),
ConvertUVecI32x4ToVecF32x4 = _BinaryenConvertUVecI32x4ToVecF32x4(),
ConvertSVecI64x2ToVecF64x2 = _BinaryenConvertSVecI64x2ToVecF64x2(),
ConvertUVecI64x2ToVecF64x2 = _BinaryenConvertUVecI64x2ToVecF64x2(),
// see: https://github.com/WebAssembly/simd
EqVecI8x16 = _BinaryenEqVecI8x16(),
NeVecI8x16 = _BinaryenNeVecI8x16(),
LtSVecI8x16 = _BinaryenLtSVecI8x16(),
Expand Down Expand Up @@ -344,6 +327,59 @@ export enum SIMDOp {
MaxVecF64x2 = _BinaryenMaxVecF64x2()
}

export enum HostOp {
CurrentMemory = _BinaryenCurrentMemory(),
GrowMemory = _BinaryenGrowMemory(),

// see: https://github.com/WebAssembly/bulk-memory-operations
// MoveMemory
// SetMemory
}

export enum AtomicRMWOp {
Add = _BinaryenAtomicRMWAdd(),
Sub = _BinaryenAtomicRMWSub(),
And = _BinaryenAtomicRMWAnd(),
Or = _BinaryenAtomicRMWOr(),
Xor = _BinaryenAtomicRMWXor(),
Xchg = _BinaryenAtomicRMWXchg()
}

export enum SIMDExtractOp {
ExtractLaneSVecI8x16 = _BinaryenExtractLaneSVecI8x16(),
ExtractLaneUVecI8x16 = _BinaryenExtractLaneUVecI8x16(),
ExtractLaneSVecI16x8 = _BinaryenExtractLaneSVecI16x8(),
ExtractLaneUVecI16x8 = _BinaryenExtractLaneUVecI16x8(),
ExtractLaneVecI32x4 = _BinaryenExtractLaneVecI32x4(),
ExtractLaneVecI64x2 = _BinaryenExtractLaneVecI64x2(),
ExtractLaneVecF32x4 = _BinaryenExtractLaneVecF32x4(),
ExtractLaneVecF64x2 = _BinaryenExtractLaneVecF64x2(),
}

export enum SIMDReplaceOp {
ReplaceLaneVecI8x16 = _BinaryenReplaceLaneVecI8x16(),
ReplaceLaneVecI16x8 = _BinaryenReplaceLaneVecI16x8(),
ReplaceLaneVecI32x4 = _BinaryenReplaceLaneVecI32x4(),
ReplaceLaneVecI64x2 = _BinaryenReplaceLaneVecI64x2(),
ReplaceLaneVecF32x4 = _BinaryenReplaceLaneVecF32x4(),
ReplaceLaneVecF64x2 = _BinaryenReplaceLaneVecF64x2()
}

export enum SIMDShiftOp { // FIXME: seems to be missing in binaryen-c.h
ShlVecI8x16,
ShrSVecI8x16,
ShrUVecI8x16,
ShlVecI16x8,
ShrSVecI16x8,
ShrUVecI16x8,
ShlVecI32x4,
ShrSVecI32x4,
ShrUVecI32x4,
ShlVecI64x2,
ShrSVecI64x2,
ShrUVecI64x2
}

export class MemorySegment {

buffer: Uint8Array;
Expand Down Expand Up @@ -510,19 +546,21 @@ export class Module {
signed: bool,
ptr: ExpressionRef,
type: NativeType,
offset: Index = 0
offset: Index = 0,
align: Index = bytes // naturally aligned by default
): ExpressionRef {
return _BinaryenLoad(this.ref, bytes, signed ? 1 : 0, offset, /* always aligned */ bytes, type, ptr);
return _BinaryenLoad(this.ref, bytes, signed ? 1 : 0, offset, align, type, ptr);
}

createStore(
bytes: Index,
ptr: ExpressionRef,
value: ExpressionRef,
type: NativeType,
offset: Index = 0
offset: Index = 0,
align: Index = bytes // naturally aligned by default
): ExpressionRef {
return _BinaryenStore(this.ref, bytes, offset, /* always aligned */ bytes, ptr, value, type);
return _BinaryenStore(this.ref, bytes, offset, align, ptr, value, type);
}

createAtomicLoad(
Expand Down Expand Up @@ -732,6 +770,55 @@ export class Module {
return _BinaryenMemoryFill(this.ref, dest, value, size);
}

// simd

createSIMDExtract(
op: SIMDExtractOp,
vec: ExpressionRef,
idx: u8
): ExpressionRef {
return _BinaryenSIMDExtract(this.ref, op, vec, idx);
}

createSIMDReplace(
op: SIMDReplaceOp,
vec: ExpressionRef,
idx: u8,
value: ExpressionRef
): ExpressionRef {
return _BinaryenSIMDReplace(this.ref, op, vec, idx, value);
}

createSIMDShuffle(
vec1: ExpressionRef,
vec2: ExpressionRef,
mask: Uint8Array
): ExpressionRef {
assert(mask.length == 16);
var cArr = allocU8Array(mask);
try {
return _BinaryenSIMDShuffle(this.ref, vec1, vec2, cArr);
} finally {
memory.free(cArr);
}
}

createSIMDBitselect(
vec1: ExpressionRef,
vec2: ExpressionRef,
cond: ExpressionRef
): ExpressionRef {
return _BinaryenSIMDBitselect(this.ref, vec1, vec2, cond);
}

createSIMDShift(
op: SIMDShiftOp,
vec: ExpressionRef,
shift: ExpressionRef
): ExpressionRef {
return _BinaryenSIMDShift(this.ref, op, vec, shift);
}

// meta

addGlobal(
Expand Down
3 changes: 3 additions & 0 deletions src/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,8 @@ export class Program extends DiagnosticEmitter {
i64_new(options.hasFeature(Feature.BULK_MEMORY) ? 1 : 0, 0));
this.registerConstantInteger(LibrarySymbols.ASC_FEATURE_SIMD, Type.bool,
i64_new(options.hasFeature(Feature.SIMD) ? 1 : 0, 0));
this.registerConstantInteger(LibrarySymbols.ASC_FEATURE_THREADS, Type.bool,
i64_new(options.hasFeature(Feature.THREADS) ? 1 : 0, 0));

// remember deferred elements
var queuedImports = new Array<QueuedImport>();
Expand Down Expand Up @@ -2564,6 +2566,7 @@ export class Function extends TypedElement {
tempI64s: Local[] | null = null;
tempF32s: Local[] | null = null;
tempF64s: Local[] | null = null;
tempV128s: Local[] | null = null;

// used by flows to keep track of break labels
nextBreakId: i32 = 0;
Expand Down
Loading