Add SIMD prerequisites (#469)

This commit is contained in:
Daniel Wirtz
2019-02-07 15:26:26 +01:00
committed by GitHub
parent 7ce3296b5e
commit 2f1a6c44ce
201 changed files with 1485 additions and 1432 deletions

View File

@ -3513,7 +3513,7 @@ export function compileIterateRoots(compiler: Compiler): void {
? module.createI64(i64_low(value), i64_high(value))
: module.createI32(i64_low(value))
],
"iv"
"i_"
)
);
} else {
@ -3526,7 +3526,7 @@ export function compileIterateRoots(compiler: Compiler): void {
compiler.options.nativeSizeType
)
],
"iv"
"i_"
)
);
}
@ -3610,7 +3610,7 @@ export function ensureGCHook(
[
module.createGetLocal(0, nativeSizeType)
],
nativeSizeType == NativeType.I64 ? "Iv" : "iv"
nativeSizeType == NativeType.I64 ? "I_" : "i_"
)
);

View File

@ -235,7 +235,9 @@ export const enum Feature {
/** Mutable global imports and exports. */
MUTABLE_GLOBAL = 1 << 1, // see: https://github.com/WebAssembly/mutable-global
/** Bulk memory operations. */
BULK_MEMORY = 1 << 2 // see: https://github.com/WebAssembly/bulk-memory-operations
BULK_MEMORY = 1 << 2, // see: https://github.com/WebAssembly/bulk-memory-operations
/** SIMD types and operations. */
SIMD = 1 << 3 // see: https://github.com/WebAssembly/simd
}
/** Indicates the desired kind of a conversion. */

View File

@ -880,6 +880,7 @@ function nativeTypeToType(type: NativeType): string {
case NativeType.I64: return "i64";
case NativeType.F32: return "f32";
case NativeType.F64: return "f64";
case NativeType.V128: return "v128";
case NativeType.Unreachable: throw new Error("unreachable type");
case NativeType.Auto: throw new Error("auto type");
default: throw new Error("unexpected type");

View File

@ -480,6 +480,7 @@ export class TSDBuilder extends ExportsWalker {
case TypeKind.BOOL: return "bool";
case TypeKind.F32: return "f32";
case TypeKind.F64: return "f64";
case TypeKind.V128: return "v128";
case TypeKind.VOID: return "void";
default: {
assert(false);

View File

@ -18,6 +18,7 @@ declare function _BinaryenTypeInt32(): BinaryenType;
declare function _BinaryenTypeInt64(): BinaryenType;
declare function _BinaryenTypeFloat32(): BinaryenType;
declare function _BinaryenTypeFloat64(): BinaryenType;
declare function _BinaryenTypeVec128(): BinaryenType;
declare function _BinaryenTypeUnreachable(): BinaryenType;
declare function _BinaryenTypeAuto(): BinaryenType;

View File

@ -130,6 +130,8 @@ export const FEATURE_SIGN_EXTENSION = Feature.SIGN_EXTENSION;
export const FEATURE_MUTABLE_GLOBAL = Feature.MUTABLE_GLOBAL;
/** Bulk memory operations. */
export const FEATURE_BULK_MEMORY = Feature.BULK_MEMORY;
/** SIMD types and operations. */
export const FEATURE_SIMD = Feature.SIMD;
/** Enables a specific feature. */
export function enableFeature(options: Options, feature: Feature): void {

View File

@ -18,14 +18,15 @@ export type RelooperRef = usize;
export type RelooperBlockRef = usize;
export type Index = u32;
export const enum NativeType {
None = 0, // _BinaryenTypeNone(),
I32 = 1, // _BinaryenTypeInt32(),
I64 = 2, // _BinaryenTypeInt64(),
F32 = 3, // _BinaryenTypeFloat32(),
F64 = 4, // _BinaryenTypeFloat64(),
Unreachable = 5, // _BinaryenTypeUnreachable(),
Auto = -1 // _BinaryenTypeAuto()
export enum NativeType {
None = _BinaryenTypeNone(),
I32 = _BinaryenTypeInt32(),
I64 = _BinaryenTypeInt64(),
F32 = _BinaryenTypeFloat32(),
F64 = _BinaryenTypeFloat64(),
V128 = _BinaryenTypeVec128(),
Unreachable = _BinaryenTypeUnreachable(),
Auto = _BinaryenTypeAuto()
}
export enum ExpressionId {
@ -442,6 +443,15 @@ export class Module {
return _BinaryenConst(this.ref, out);
}
createV128(bytes: Uint8Array): ExpressionRef {
assert(bytes.length == 16);
var out = this.lit;
// FIXME: does this work or do we need to malloc?
for (let i = 0; i < 16; ++i) store<u8>(out + i, bytes[i]);
_BinaryenLiteralVec128(out, out);
return _BinaryenConst(this.ref, out);
}
// expressions
createUnary(

View File

@ -415,6 +415,7 @@ export class Program extends DiagnosticEmitter {
["number", Type.f64],
["boolean", Type.bool]
]);
if (options.hasFeature(Feature.SIMD)) this.typesLookup.set("v128", Type.v128);
// add compiler hints
this.setConstantInteger("ASC_TARGET", Type.i32,
@ -433,6 +434,10 @@ export class Program extends DiagnosticEmitter {
i64_new(options.hasFeature(Feature.MUTABLE_GLOBAL) ? 1 : 0, 0));
this.setConstantInteger("ASC_FEATURE_SIGN_EXTENSION", Type.bool,
i64_new(options.hasFeature(Feature.SIGN_EXTENSION) ? 1 : 0, 0));
this.setConstantInteger("ASC_FEATURE_BULK_MEMORY", Type.bool,
i64_new(options.hasFeature(Feature.BULK_MEMORY) ? 1 : 0, 0));
this.setConstantInteger("ASC_FEATURE_SIMD", Type.bool,
i64_new(options.hasFeature(Feature.SIMD) ? 1 : 0, 0));
// remember deferred elements
var queuedImports = new Array<QueuedImport>();
@ -659,6 +664,7 @@ export class Program extends DiagnosticEmitter {
this.registerBasicClass(TypeKind.BOOL, "Bool");
this.registerBasicClass(TypeKind.F32, "F32");
this.registerBasicClass(TypeKind.F64, "F64");
if (options.hasFeature(Feature.SIMD)) this.registerBasicClass(TypeKind.V128, "V128");
// register 'start'
{

View File

@ -234,6 +234,7 @@ export class Resolver extends DiagnosticEmitter {
case TypeKind.U64: return Type.u64;
case TypeKind.F32: return Type.f32;
case TypeKind.F64: return Type.f64;
case TypeKind.V128: return Type.v128;
case TypeKind.VOID: return Type.void;
default: assert(false);
}

View File

@ -54,6 +54,9 @@ export const enum TypeKind {
/** A 64-bit double. */
F64,
// vectors
V128,
// other
/** No return type. */
@ -82,9 +85,13 @@ export const enum TypeFlags {
/** Is a reference type. */
REFERENCE = 1 << 8,
/** Is a nullable type. */
NULLABLE = 1 << 9
NULLABLE = 1 << 9,
/** Is a vector type. */
VECTOR = 1 << 10
}
const v128_zero = new Uint8Array(16);
/** Represents a resolved type. */
export class Type {
@ -229,6 +236,10 @@ export class Type {
if (target.is(TypeFlags.FLOAT)) {
return this.size <= target.size;
}
} else if (this.is(TypeFlags.VECTOR)) {
if (target.is(TypeFlags.VECTOR)) {
return this.size == target.size;
}
}
}
return false;
@ -272,6 +283,7 @@ export class Type {
case TypeKind.BOOL: return "bool";
case TypeKind.F32: return "f32";
case TypeKind.F64: return "f64";
case TypeKind.V128: return "v128";
default: assert(false);
case TypeKind.VOID: return "void";
}
@ -289,6 +301,7 @@ export class Type {
case TypeKind.USIZE: return this.size == 64 ? NativeType.I64 : NativeType.I32;
case TypeKind.F32: return NativeType.F32;
case TypeKind.F64: return NativeType.F64;
case TypeKind.V128: return NativeType.V128;
case TypeKind.VOID: return NativeType.None;
}
}
@ -304,12 +317,14 @@ export class Type {
case TypeKind.U64: return module.createI64(0);
case TypeKind.F32: return module.createF32(0);
case TypeKind.F64: return module.createF64(0);
case TypeKind.V128: return module.createV128(v128_zero);
}
}
/** Converts this type to its native `1` value. */
toNativeOne(module: Module): ExpressionRef {
switch (this.kind) {
case TypeKind.V128:
case TypeKind.VOID: assert(false);
default: return module.createI32(1);
case TypeKind.ISIZE:
@ -324,6 +339,7 @@ export class Type {
/** Converts this type to its native `-1` value. */
toNativeNegOne(module: Module): ExpressionRef {
switch (this.kind) {
case TypeKind.V128:
case TypeKind.VOID: assert(false);
default: return module.createI32(-1);
case TypeKind.ISIZE:
@ -345,7 +361,8 @@ export class Type {
case TypeKind.USIZE: return this.size == 64 ? "I" : "i";
case TypeKind.F32: return "f";
case TypeKind.F64: return "F";
case TypeKind.VOID: return "v";
case TypeKind.V128: return "v";
case TypeKind.VOID: return "_";
}
}
@ -470,6 +487,12 @@ export class Type {
TypeFlags.VALUE, 64
);
/** A 128-bit vector. */
static readonly v128: Type = new Type(TypeKind.V128,
TypeFlags.VECTOR |
TypeFlags.VALUE, 128
);
/** No return type. */
static readonly void: Type = new Type(TypeKind.VOID, TypeFlags.NONE, 0);
}