Skip to content

Commit 2f1a6c4

Browse files
authored
Add SIMD prerequisites (AssemblyScript#469)
1 parent 7ce3296 commit 2f1a6c4

File tree

201 files changed

+1485
-1432
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

201 files changed

+1485
-1432
lines changed

cli/asc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@
162162
" sign-extension Enables sign-extension operations",
163163
" mutable-global Enables mutable global imports and exports",
164164
" bulk-memory Enables bulk memory operations",
165+
" simd Enables SIMD types and operations.",
165166
""
166167
],
167168
"type": "s"

src/builtins.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3513,7 +3513,7 @@ export function compileIterateRoots(compiler: Compiler): void {
35133513
? module.createI64(i64_low(value), i64_high(value))
35143514
: module.createI32(i64_low(value))
35153515
],
3516-
"iv"
3516+
"i_"
35173517
)
35183518
);
35193519
} else {
@@ -3526,7 +3526,7 @@ export function compileIterateRoots(compiler: Compiler): void {
35263526
compiler.options.nativeSizeType
35273527
)
35283528
],
3529-
"iv"
3529+
"i_"
35303530
)
35313531
);
35323532
}
@@ -3610,7 +3610,7 @@ export function ensureGCHook(
36103610
[
36113611
module.createGetLocal(0, nativeSizeType)
36123612
],
3613-
nativeSizeType == NativeType.I64 ? "Iv" : "iv"
3613+
nativeSizeType == NativeType.I64 ? "I_" : "i_"
36143614
)
36153615
);
36163616

src/compiler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,9 @@ export const enum Feature {
235235
/** Mutable global imports and exports. */
236236
MUTABLE_GLOBAL = 1 << 1, // see: https://github.com/WebAssembly/mutable-global
237237
/** Bulk memory operations. */
238-
BULK_MEMORY = 1 << 2 // see: https://github.com/WebAssembly/bulk-memory-operations
238+
BULK_MEMORY = 1 << 2, // see: https://github.com/WebAssembly/bulk-memory-operations
239+
/** SIMD types and operations. */
240+
SIMD = 1 << 3 // see: https://github.com/WebAssembly/simd
239241
}
240242

241243
/** Indicates the desired kind of a conversion. */

src/decompiler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,7 @@ function nativeTypeToType(type: NativeType): string {
880880
case NativeType.I64: return "i64";
881881
case NativeType.F32: return "f32";
882882
case NativeType.F64: return "f64";
883+
case NativeType.V128: return "v128";
883884
case NativeType.Unreachable: throw new Error("unreachable type");
884885
case NativeType.Auto: throw new Error("auto type");
885886
default: throw new Error("unexpected type");

src/definitions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ export class TSDBuilder extends ExportsWalker {
480480
case TypeKind.BOOL: return "bool";
481481
case TypeKind.F32: return "f32";
482482
case TypeKind.F64: return "f64";
483+
case TypeKind.V128: return "v128";
483484
case TypeKind.VOID: return "void";
484485
default: {
485486
assert(false);

src/glue/binaryen.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ declare function _BinaryenTypeInt32(): BinaryenType;
1818
declare function _BinaryenTypeInt64(): BinaryenType;
1919
declare function _BinaryenTypeFloat32(): BinaryenType;
2020
declare function _BinaryenTypeFloat64(): BinaryenType;
21+
declare function _BinaryenTypeVec128(): BinaryenType;
2122
declare function _BinaryenTypeUnreachable(): BinaryenType;
2223
declare function _BinaryenTypeAuto(): BinaryenType;
2324

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ export const FEATURE_SIGN_EXTENSION = Feature.SIGN_EXTENSION;
130130
export const FEATURE_MUTABLE_GLOBAL = Feature.MUTABLE_GLOBAL;
131131
/** Bulk memory operations. */
132132
export const FEATURE_BULK_MEMORY = Feature.BULK_MEMORY;
133+
/** SIMD types and operations. */
134+
export const FEATURE_SIMD = Feature.SIMD;
133135

134136
/** Enables a specific feature. */
135137
export function enableFeature(options: Options, feature: Feature): void {

src/module.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ export type RelooperRef = usize;
1818
export type RelooperBlockRef = usize;
1919
export type Index = u32;
2020

21-
export const enum NativeType {
22-
None = 0, // _BinaryenTypeNone(),
23-
I32 = 1, // _BinaryenTypeInt32(),
24-
I64 = 2, // _BinaryenTypeInt64(),
25-
F32 = 3, // _BinaryenTypeFloat32(),
26-
F64 = 4, // _BinaryenTypeFloat64(),
27-
Unreachable = 5, // _BinaryenTypeUnreachable(),
28-
Auto = -1 // _BinaryenTypeAuto()
21+
export enum NativeType {
22+
None = _BinaryenTypeNone(),
23+
I32 = _BinaryenTypeInt32(),
24+
I64 = _BinaryenTypeInt64(),
25+
F32 = _BinaryenTypeFloat32(),
26+
F64 = _BinaryenTypeFloat64(),
27+
V128 = _BinaryenTypeVec128(),
28+
Unreachable = _BinaryenTypeUnreachable(),
29+
Auto = _BinaryenTypeAuto()
2930
}
3031

3132
export enum ExpressionId {
@@ -442,6 +443,15 @@ export class Module {
442443
return _BinaryenConst(this.ref, out);
443444
}
444445

446+
createV128(bytes: Uint8Array): ExpressionRef {
447+
assert(bytes.length == 16);
448+
var out = this.lit;
449+
// FIXME: does this work or do we need to malloc?
450+
for (let i = 0; i < 16; ++i) store<u8>(out + i, bytes[i]);
451+
_BinaryenLiteralVec128(out, out);
452+
return _BinaryenConst(this.ref, out);
453+
}
454+
445455
// expressions
446456

447457
createUnary(

src/program.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ export class Program extends DiagnosticEmitter {
415415
["number", Type.f64],
416416
["boolean", Type.bool]
417417
]);
418+
if (options.hasFeature(Feature.SIMD)) this.typesLookup.set("v128", Type.v128);
418419

419420
// add compiler hints
420421
this.setConstantInteger("ASC_TARGET", Type.i32,
@@ -433,6 +434,10 @@ export class Program extends DiagnosticEmitter {
433434
i64_new(options.hasFeature(Feature.MUTABLE_GLOBAL) ? 1 : 0, 0));
434435
this.setConstantInteger("ASC_FEATURE_SIGN_EXTENSION", Type.bool,
435436
i64_new(options.hasFeature(Feature.SIGN_EXTENSION) ? 1 : 0, 0));
437+
this.setConstantInteger("ASC_FEATURE_BULK_MEMORY", Type.bool,
438+
i64_new(options.hasFeature(Feature.BULK_MEMORY) ? 1 : 0, 0));
439+
this.setConstantInteger("ASC_FEATURE_SIMD", Type.bool,
440+
i64_new(options.hasFeature(Feature.SIMD) ? 1 : 0, 0));
436441

437442
// remember deferred elements
438443
var queuedImports = new Array<QueuedImport>();
@@ -659,6 +664,7 @@ export class Program extends DiagnosticEmitter {
659664
this.registerBasicClass(TypeKind.BOOL, "Bool");
660665
this.registerBasicClass(TypeKind.F32, "F32");
661666
this.registerBasicClass(TypeKind.F64, "F64");
667+
if (options.hasFeature(Feature.SIMD)) this.registerBasicClass(TypeKind.V128, "V128");
662668

663669
// register 'start'
664670
{

src/resolver.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ export class Resolver extends DiagnosticEmitter {
234234
case TypeKind.U64: return Type.u64;
235235
case TypeKind.F32: return Type.f32;
236236
case TypeKind.F64: return Type.f64;
237+
case TypeKind.V128: return Type.v128;
237238
case TypeKind.VOID: return Type.void;
238239
default: assert(false);
239240
}

src/types.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ export const enum TypeKind {
5454
/** A 64-bit double. */
5555
F64,
5656

57+
// vectors
58+
V128,
59+
5760
// other
5861

5962
/** No return type. */
@@ -82,9 +85,13 @@ export const enum TypeFlags {
8285
/** Is a reference type. */
8386
REFERENCE = 1 << 8,
8487
/** Is a nullable type. */
85-
NULLABLE = 1 << 9
88+
NULLABLE = 1 << 9,
89+
/** Is a vector type. */
90+
VECTOR = 1 << 10
8691
}
8792

93+
const v128_zero = new Uint8Array(16);
94+
8895
/** Represents a resolved type. */
8996
export class Type {
9097

@@ -229,6 +236,10 @@ export class Type {
229236
if (target.is(TypeFlags.FLOAT)) {
230237
return this.size <= target.size;
231238
}
239+
} else if (this.is(TypeFlags.VECTOR)) {
240+
if (target.is(TypeFlags.VECTOR)) {
241+
return this.size == target.size;
242+
}
232243
}
233244
}
234245
return false;
@@ -272,6 +283,7 @@ export class Type {
272283
case TypeKind.BOOL: return "bool";
273284
case TypeKind.F32: return "f32";
274285
case TypeKind.F64: return "f64";
286+
case TypeKind.V128: return "v128";
275287
default: assert(false);
276288
case TypeKind.VOID: return "void";
277289
}
@@ -289,6 +301,7 @@ export class Type {
289301
case TypeKind.USIZE: return this.size == 64 ? NativeType.I64 : NativeType.I32;
290302
case TypeKind.F32: return NativeType.F32;
291303
case TypeKind.F64: return NativeType.F64;
304+
case TypeKind.V128: return NativeType.V128;
292305
case TypeKind.VOID: return NativeType.None;
293306
}
294307
}
@@ -304,12 +317,14 @@ export class Type {
304317
case TypeKind.U64: return module.createI64(0);
305318
case TypeKind.F32: return module.createF32(0);
306319
case TypeKind.F64: return module.createF64(0);
320+
case TypeKind.V128: return module.createV128(v128_zero);
307321
}
308322
}
309323

310324
/** Converts this type to its native `1` value. */
311325
toNativeOne(module: Module): ExpressionRef {
312326
switch (this.kind) {
327+
case TypeKind.V128:
313328
case TypeKind.VOID: assert(false);
314329
default: return module.createI32(1);
315330
case TypeKind.ISIZE:
@@ -324,6 +339,7 @@ export class Type {
324339
/** Converts this type to its native `-1` value. */
325340
toNativeNegOne(module: Module): ExpressionRef {
326341
switch (this.kind) {
342+
case TypeKind.V128:
327343
case TypeKind.VOID: assert(false);
328344
default: return module.createI32(-1);
329345
case TypeKind.ISIZE:
@@ -345,7 +361,8 @@ export class Type {
345361
case TypeKind.USIZE: return this.size == 64 ? "I" : "i";
346362
case TypeKind.F32: return "f";
347363
case TypeKind.F64: return "F";
348-
case TypeKind.VOID: return "v";
364+
case TypeKind.V128: return "v";
365+
case TypeKind.VOID: return "_";
349366
}
350367
}
351368

@@ -470,6 +487,12 @@ export class Type {
470487
TypeFlags.VALUE, 64
471488
);
472489

490+
/** A 128-bit vector. */
491+
static readonly v128: Type = new Type(TypeKind.V128,
492+
TypeFlags.VECTOR |
493+
TypeFlags.VALUE, 128
494+
);
495+
473496
/** No return type. */
474497
static readonly void: Type = new Type(TypeKind.VOID, TypeFlags.NONE, 0);
475498
}

std/assembly/vector.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@sealed
2+
export abstract class V128 {
3+
}

std/portable/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ globalScope.ASC_OPTIMIZE_LEVEL = 3;
1010
globalScope.ASC_SHRINK_LEVEL = 0;
1111
globalScope.ASC_FEATURE_MUTABLE_GLOBAL = false;
1212
globalScope.ASC_FEATURE_SIGN_EXTENSION = false;
13+
globalScope.ASC_FEATURE_BULK_MEMORY = false;
14+
globalScope.ASC_FEATURE_SIMD = false;
1315

1416
var F64 = new Float64Array(1);
1517
var U64 = new Uint32Array(F64.buffer);

tests/compiler/abi.optimized.wat

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(module
22
(type $i (func (result i32)))
3-
(type $iiiiv (func (param i32 i32 i32 i32)))
4-
(type $v (func))
3+
(type $iiii_ (func (param i32 i32 i32 i32)))
4+
(type $_ (func))
55
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
66
(memory $0 1)
77
(data (i32.const 8) "\06\00\00\00a\00b\00i\00.\00t\00s")
@@ -18,7 +18,7 @@
1818
(func $abi/exported (; 1 ;) (type $i) (result i32)
1919
i32.const -128
2020
)
21-
(func $start (; 2 ;) (type $v)
21+
(func $start (; 2 ;) (type $_)
2222
i32.const 1
2323
global.set $abi/condition
2424
i32.const 0
@@ -33,7 +33,7 @@
3333
unreachable
3434
end
3535
)
36-
(func $null (; 3 ;) (type $v)
36+
(func $null (; 3 ;) (type $_)
3737
nop
3838
)
3939
)

tests/compiler/abi.untouched.wat

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(module
22
(type $i (func (result i32)))
3-
(type $iiiiv (func (param i32 i32 i32 i32)))
4-
(type $v (func))
3+
(type $iiii_ (func (param i32 i32 i32 i32)))
4+
(type $_ (func))
55
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
66
(memory $0 1)
77
(data (i32.const 8) "\06\00\00\00a\00b\00i\00.\00t\00s\00")
@@ -36,7 +36,7 @@
3636
i32.const 24
3737
i32.shr_s
3838
)
39-
(func $start (; 5 ;) (type $v)
39+
(func $start (; 5 ;) (type $_)
4040
(local $0 i32)
4141
(local $1 i32)
4242
call $abi/internal
@@ -211,6 +211,6 @@
211211
end
212212
end
213213
)
214-
(func $null (; 6 ;) (type $v)
214+
(func $null (; 6 ;) (type $_)
215215
)
216216
)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
(module
2-
(type $v (func))
2+
(type $_ (func))
33
(memory $0 0)
44
(table $0 1 funcref)
55
(elem (i32.const 0) $start)
66
(export "memory" (memory $0))
77
(export "table" (table $0))
8-
(func $start (; 0 ;) (type $v)
8+
(func $start (; 0 ;) (type $_)
99
nop
1010
)
1111
)

tests/compiler/asc-constants.untouched.wat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(module
2-
(type $v (func))
2+
(type $_ (func))
33
(memory $0 0)
44
(table $0 1 funcref)
55
(elem (i32.const 0) $null)
@@ -15,7 +15,7 @@
1515
(export "memory" (memory $0))
1616
(export "table" (table $0))
1717
(start $start)
18-
(func $start (; 0 ;) (type $v)
18+
(func $start (; 0 ;) (type $_)
1919
i32.const 1
2020
drop
2121
i32.const 0
@@ -33,6 +33,6 @@
3333
i32.const 0
3434
drop
3535
)
36-
(func $null (; 1 ;) (type $v)
36+
(func $null (; 1 ;) (type $_)
3737
)
3838
)

tests/compiler/assert.optimized.wat

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
(module
2-
(type $v (func))
2+
(type $_ (func))
33
(memory $0 1)
44
(data (i32.const 8) "\t\00\00\00a\00s\00s\00e\00r\00t\00.\00t\00s")
55
(data (i32.const 32) "\0c\00\00\00m\00u\00s\00t\00 \00b\00e\00 \00t\00r\00u\00e")
66
(table $0 1 funcref)
77
(elem (i32.const 0) $start)
88
(export "memory" (memory $0))
99
(export "table" (table $0))
10-
(func $start (; 0 ;) (type $v)
10+
(func $start (; 0 ;) (type $_)
1111
nop
1212
)
1313
)

tests/compiler/assert.untouched.wat

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
(module
2-
(type $iiiiv (func (param i32 i32 i32 i32)))
3-
(type $v (func))
2+
(type $iiii_ (func (param i32 i32 i32 i32)))
3+
(type $_ (func))
44
(import "env" "abort" (func $~lib/env/abort (param i32 i32 i32 i32)))
55
(memory $0 1)
66
(data (i32.const 8) "\t\00\00\00a\00s\00s\00e\00r\00t\00.\00t\00s\00")
@@ -11,7 +11,7 @@
1111
(export "memory" (memory $0))
1212
(export "table" (table $0))
1313
(start $start)
14-
(func $start (; 1 ;) (type $v)
14+
(func $start (; 1 ;) (type $_)
1515
(local $0 i32)
1616
i32.const 1
1717
i32.eqz
@@ -107,6 +107,6 @@
107107
unreachable
108108
end
109109
)
110-
(func $null (; 2 ;) (type $v)
110+
(func $null (; 2 ;) (type $_)
111111
)
112112
)

0 commit comments

Comments
 (0)