mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-14 23:41:30 +00:00
Add SIMD prerequisites (#469)
This commit is contained in:
@ -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_"
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
1
src/glue/binaryen.d.ts
vendored
1
src/glue/binaryen.d.ts
vendored
@ -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;
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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(
|
||||
|
@ -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'
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
27
src/types.ts
27
src/types.ts
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user