Implement v128 instructions (#508)

This commit is contained in:
Daniel Wirtz 2019-02-28 17:36:22 +01:00 committed by GitHub
parent cdf40578b6
commit e1f1a3b49c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 6647 additions and 286 deletions

View File

@ -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/"

File diff suppressed because it is too large Load Diff

View File

@ -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";
@ -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";

View File

@ -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();
@ -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();

View File

@ -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,
@ -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.";

View File

@ -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,

View File

@ -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;
@ -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);
@ -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;

View File

@ -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
@ -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 {
@ -211,61 +246,9 @@ export enum BinaryOp {
LtF64 = _BinaryenLtFloat64(),
LeF64 = _BinaryenLeFloat64(),
GtF64 = _BinaryenGtFloat64(),
GeF64 = _BinaryenGeFloat64()
}
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()
}
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(),
@ -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;
@ -510,9 +546,10 @@ 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(
@ -520,9 +557,10 @@ export class Module {
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(
@ -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(

View File

@ -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>();
@ -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;

View File

@ -74,7 +74,8 @@ import {
} from "./common";
import {
makeMap
makeMap,
isPowerOf2
} from "./util";
import {
@ -1572,13 +1573,9 @@ export class Resolver extends DiagnosticEmitter {
}
if (!fieldType) break; // did report above
let fieldInstance = new Field(<FieldPrototype>member, instance, fieldType);
switch (fieldType.byteSize) { // align
case 1: break;
case 2: { if (memoryOffset & 1) ++memoryOffset; break; }
case 4: { if (memoryOffset & 3) memoryOffset = (memoryOffset | 3) + 1; break; }
case 8: { if (memoryOffset & 7) memoryOffset = (memoryOffset | 7) + 1; break; }
default: assert(false);
}
assert(isPowerOf2(fieldType.byteSize));
let mask = fieldType.byteSize - 1;
if (memoryOffset & mask) memoryOffset = (memoryOffset | mask) + 1;
fieldInstance.memoryOffset = memoryOffset;
memoryOffset += fieldType.byteSize;
instance.add(member.name, fieldInstance); // reports

View File

@ -55,6 +55,8 @@ export const enum TypeKind {
F64,
// vectors
/** A 128-bit vector. */
V128,
// other

View File

@ -10,3 +10,8 @@ export * from "./collections";
export * from "./path";
export * from "./text";
export * from "./binary";
/** Tests if `x` is a power of two. */
export function isPowerOf2(x: i32): bool {
return x != 0 && (x & (x - 1)) == 0;
}

View File

@ -33,8 +33,8 @@
@builtin export declare function reinterpret<T>(value: void): T;
@builtin export declare function sqrt<T>(value: T): T;
@builtin export declare function trunc<T>(value: T): T;
@builtin export declare function load<T>(offset: usize, constantOffset?: usize): T;
@builtin export declare function store<T>(offset: usize, value: void, constantOffset?: usize): void;
@builtin export declare function load<T>(offset: usize, immOffset?: usize, immAlign?: usize): T;
@builtin export declare function store<T>(offset: usize, value: void, immOffset?: usize, immAlign?: usize): void;
@builtin export declare function sizeof<T>(): usize; // | u32 / u64
@builtin export declare function alignof<T>(): usize; // | u32 / u64
@builtin export declare function offsetof<T>(fieldName?: string): usize; // | u32 / u64
@ -47,15 +47,15 @@
@builtin export declare function instantiate<T>(...args: void[]): T;
export namespace atomic {
@builtin export declare function load<T>(offset: usize, constantOffset?: usize): T;
@builtin export declare function store<T>(offset: usize, value: void, constantOffset?: usize): void;
@builtin export declare function add<T>(ptr: usize, value: T, constantOffset?: usize): T;
@builtin export declare function sub<T>(ptr: usize, value: T, constantOffset?: usize): T;
@builtin export declare function and<T>(ptr: usize, value: T, constantOffset?: usize): T;
@builtin export declare function or<T>(ptr: usize, value: T, constantOffset?: usize): T;
@builtin export declare function xor<T>(ptr: usize, value: T, constantOffset?: usize): T;
@builtin export declare function xchg<T>(ptr: usize, value: T, constantOffset?: usize): T;
@builtin export declare function cmpxchg<T>(ptr: usize, expected:T, replacement: T, constantOffset?: usize): T;
@builtin export declare function load<T>(offset: usize, immOffset?: usize): T;
@builtin export declare function store<T>(offset: usize, value: void, immOffset?: usize): void;
@builtin export declare function add<T>(ptr: usize, value: T, immOffset?: usize): T;
@builtin export declare function sub<T>(ptr: usize, value: T, immOffset?: usize): T;
@builtin export declare function and<T>(ptr: usize, value: T, immOffset?: usize): T;
@builtin export declare function or<T>(ptr: usize, value: T, immOffset?: usize): T;
@builtin export declare function xor<T>(ptr: usize, value: T, immOffset?: usize): T;
@builtin export declare function xchg<T>(ptr: usize, value: T, immOffset?: usize): T;
@builtin export declare function cmpxchg<T>(ptr: usize, expected:T, replacement: T, immOffset?: usize): T;
@builtin export declare function wait<T>(ptr: usize, expected:T, timeout:i64): i32;
@builtin export declare function notify<T>(ptr: usize, count: u32): u32;
}
@ -82,55 +82,55 @@ export namespace i32 {
@builtin export declare function rotl(value: i32, shift: i32): i32;
@builtin export declare function rotr(value: i32, shift: i32): i32;
@builtin export declare function reinterpret_f32(value: f32): i32;
@builtin export declare function load8_s(offset: usize, constantOffset?: usize): i32;
@builtin export declare function load8_u(offset: usize, constantOffset?: usize): i32;
@builtin export declare function load16_s(offset: usize, constantOffset?: usize): i32;
@builtin export declare function load16_u(offset: usize, constantOffset?: usize): i32;
@builtin export declare function load(offset: usize, constantOffset?: usize): i32;
@builtin export declare function store8(offset: usize, value: i32, constantOffset?: usize): void;
@builtin export declare function store16(offset: usize, value: i32, constantOffset?: usize): void;
@builtin export declare function store(offset: usize, value: i32, constantOffset?: usize): void;
@builtin export declare function load8_s(offset: usize, immOffset?: usize, immAlign?: usize): i32;
@builtin export declare function load8_u(offset: usize, immOffset?: usize, immAlign?: usize): i32;
@builtin export declare function load16_s(offset: usize, immOffset?: usize, immAlign?: usize): i32;
@builtin export declare function load16_u(offset: usize, immOffset?: usize, immAlign?: usize): i32;
@builtin export declare function load(offset: usize, immOffset?: usize, immAlign?: usize): i32;
@builtin export declare function store8(offset: usize, value: i32, immOffset?: usize, immAlign?: usize): void;
@builtin export declare function store16(offset: usize, value: i32, immOffset?: usize, immAlign?: usize): void;
@builtin export declare function store(offset: usize, value: i32, immOffset?: usize, immAlign?: usize): void;
export namespace atomic {
@builtin export declare function load8_s(offset: usize, constantOffset?: usize): i32;
@builtin export declare function load8_u(offset: usize, constantOffset?: usize): i32;
@builtin export declare function load16_s(offset: usize, constantOffset?: usize): i32;
@builtin export declare function load16_u(offset: usize, constantOffset?: usize): i32;
@builtin export declare function load(offset: usize, constantOffset?: usize): i32;
@builtin export declare function store8(offset: usize, value: i32, constantOffset?: usize): void;
@builtin export declare function store16(offset: usize, value: i32, constantOffset?: usize): void;
@builtin export declare function store(offset: usize, value: i32, constantOffset?: usize): void;
@builtin export declare function load8_s(offset: usize, immOffset?: usize): i32;
@builtin export declare function load8_u(offset: usize, immOffset?: usize): i32;
@builtin export declare function load16_s(offset: usize, immOffset?: usize): i32;
@builtin export declare function load16_u(offset: usize, immOffset?: usize): i32;
@builtin export declare function load(offset: usize, immOffset?: usize): i32;
@builtin export declare function store8(offset: usize, value: i32, immOffset?: usize): void;
@builtin export declare function store16(offset: usize, value: i32, immOffset?: usize): void;
@builtin export declare function store(offset: usize, value: i32, immOffset?: usize): void;
@builtin export declare function wait(ptr: usize, expected:i32, timeout:i64): i32;
@builtin export declare function notify(ptr: usize, count:u32): u32;
export namespace rmw8_u {
@builtin export declare function add(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function sub(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function and(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function or(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function xor(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function xchg(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function cmpxchg(offset: usize, expected:i32, replacement: i32, constantOffset?: usize): i32;
@builtin export declare function add(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function sub(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function and(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function or(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function xor(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function xchg(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function cmpxchg(offset: usize, expected:i32, replacement: i32, immOffset?: usize): i32;
}
export namespace rmw16_u {
@builtin export declare function add(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function sub(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function and(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function or(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function xor(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function xchg(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function cmpxchg(offset: usize, expected:i32, replacement: i32, constantOffset?: usize): i32;
@builtin export declare function add(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function sub(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function and(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function or(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function xor(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function xchg(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function cmpxchg(offset: usize, expected:i32, replacement: i32, immOffset?: usize): i32;
}
export namespace rmw {
@builtin export declare function add(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function sub(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function and(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function or(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function xor(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function xchg(offset: usize, value: i32, constantOffset?: usize): i32;
@builtin export declare function cmpxchg(offset: usize, expected:i32, replacement: i32, constantOffset?: usize): i32;
@builtin export declare function add(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function sub(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function and(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function or(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function xor(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function xchg(offset: usize, value: i32, immOffset?: usize): i32;
@builtin export declare function cmpxchg(offset: usize, expected:i32, replacement: i32, immOffset?: usize): i32;
}
}
}
@ -141,72 +141,72 @@ export namespace i64 {
@lazy export const MAX_VALUE: i64 = 9223372036854775807;
@builtin export declare function clz(value: i64): i64;
@builtin export declare function ctz(value: i64): i64;
@builtin export declare function load8_s(offset: usize, constantOffset?: usize): i64;
@builtin export declare function load8_u(offset: usize, constantOffset?: usize): u64;
@builtin export declare function load16_s(offset: usize, constantOffset?: usize): i64;
@builtin export declare function load16_u(offset: usize, constantOffset?: usize): u64;
@builtin export declare function load32_s(offset: usize, constantOffset?: usize): i64;
@builtin export declare function load32_u(offset: usize, constantOffset?: usize): u64;
@builtin export declare function load(offset: usize, constantOffset?: usize): i64;
@builtin export declare function load8_s(offset: usize, immOffset?: usize, immAlign?: usize): i64;
@builtin export declare function load8_u(offset: usize, immOffset?: usize, immAlign?: usize): u64;
@builtin export declare function load16_s(offset: usize, immOffset?: usize, immAlign?: usize): i64;
@builtin export declare function load16_u(offset: usize, immOffset?: usize, immAlign?: usize): u64;
@builtin export declare function load32_s(offset: usize, immOffset?: usize, immAlign?: usize): i64;
@builtin export declare function load32_u(offset: usize, immOffset?: usize, immAlign?: usize): u64;
@builtin export declare function load(offset: usize, immOffset?: usize): i64;
@builtin export declare function popcnt(value: i64): i64;
@builtin export declare function rotl(value: i64, shift: i64): i64;
@builtin export declare function rotr(value: i64, shift: i64): i64;
@builtin export declare function reinterpret_f64(value: f64): i64;
@builtin export declare function store8(offset: usize, value: i64, constantOffset?: usize): void;
@builtin export declare function store16(offset: usize, value: i64, constantOffset?: usize): void;
@builtin export declare function store32(offset: usize, value: i64, constantOffset?: usize): void;
@builtin export declare function store(offset: usize, value: i64, constantOffset?: usize): void;
@builtin export declare function store8(offset: usize, value: i64, immOffset?: usize, immAlign?: usize): void;
@builtin export declare function store16(offset: usize, value: i64, immOffset?: usize, immAlign?: usize): void;
@builtin export declare function store32(offset: usize, value: i64, immOffset?: usize, immAlign?: usize): void;
@builtin export declare function store(offset: usize, value: i64, immOffset?: usize, immAlign?: usize): void;
namespace atomic {
@builtin export declare function load8_s(offset: usize, constantOffset?: usize): i64;
@builtin export declare function load8_u(offset: usize, constantOffset?: usize): i64;
@builtin export declare function load16_s(offset: usize, constantOffset?: usize): i64;
@builtin export declare function load16_u(offset: usize, constantOffset?: usize): i64;
@builtin export declare function load(offset: usize, constantOffset?: usize): i64;
@builtin export declare function store8(offset: usize, value: i64, constantOffset?: usize): void;
@builtin export declare function store16(offset: usize, value: i64, constantOffset?: usize): void;
@builtin export declare function store(offset: usize, value: i64, constantOffset?: usize): void;
@builtin export declare function load8_s(offset: usize, immOffset?: usize): i64;
@builtin export declare function load8_u(offset: usize, immOffset?: usize): i64;
@builtin export declare function load16_s(offset: usize, immOffset?: usize): i64;
@builtin export declare function load16_u(offset: usize, immOffset?: usize): i64;
@builtin export declare function load(offset: usize, immOffset?: usize): i64;
@builtin export declare function store8(offset: usize, value: i64, immOffset?: usize): void;
@builtin export declare function store16(offset: usize, value: i64, immOffset?: usize): void;
@builtin export declare function store(offset: usize, value: i64, immOffset?: usize): void;
@builtin export declare function wait(ptr: usize, expected:i64, timeout:i64): i32;
@builtin export declare function notify(ptr: usize, count:u32): u32;
export namespace rmw8_u {
@builtin export declare function add(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function sub(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function and(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function or(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function xor(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function xchg(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function cmpxchg(offset: usize, expected:i64, replacement: i64, constantOffset?: usize): i64;
@builtin export declare function add(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function sub(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function and(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function or(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function xor(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function xchg(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function cmpxchg(offset: usize, expected:i64, replacement: i64, immOffset?: usize): i64;
}
export namespace rmw16_u {
@builtin export declare function add(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function sub(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function and(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function or(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function xor(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function xchg(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function cmpxchg(offset: usize, expected:i64, replacement: i64, constantOffset?: usize): i64;
@builtin export declare function add(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function sub(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function and(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function or(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function xor(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function xchg(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function cmpxchg(offset: usize, expected:i64, replacement: i64, immOffset?: usize): i64;
}
export namespace rmw32_u {
@builtin export declare function add(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function sub(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function and(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function or(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function xor(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function xchg(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function cmpxchg(offset: usize, expected:i64, replacement: i64, constantOffset?: usize): i64;
@builtin export declare function add(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function sub(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function and(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function or(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function xor(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function xchg(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function cmpxchg(offset: usize, expected:i64, replacement: i64, immOffset?: usize): i64;
}
export namespace rmw {
@builtin export declare function add(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function sub(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function and(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function or(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function xor(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function xchg(offset: usize, value: i64, constantOffset?: usize): i64;
@builtin export declare function cmpxchg(offset: usize, expected:i64, replacement: i64, constantOffset?: usize): i64;
@builtin export declare function add(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function sub(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function and(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function or(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function xor(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function xchg(offset: usize, value: i64, immOffset?: usize): i64;
@builtin export declare function cmpxchg(offset: usize, expected:i64, replacement: i64, immOffset?: usize): i64;
}
}
}
@ -271,13 +271,13 @@ export namespace f32 {
@builtin export declare function ceil(value: f32): f32;
@builtin export declare function copysign(x: f32, y: f32): f32;
@builtin export declare function floor(value: f32): f32;
@builtin export declare function load(offset: usize, constantOffset?: usize): f32;
@builtin export declare function load(offset: usize, immOffset?: usize, immAlign?: usize): f32;
@builtin export declare function max(left: f32, right: f32): f32;
@builtin export declare function min(left: f32, right: f32): f32;
@builtin export declare function nearest(value: f32): f32;
@builtin export declare function reinterpret_i32(value: i32): f32;
@builtin export declare function sqrt(value: f32): f32;
@builtin export declare function store(offset: usize, value: f32, constantOffset?: usize): void;
@builtin export declare function store(offset: usize, value: f32, immOffset?: usize, immAlign?: usize): void;
@builtin export declare function trunc(value: f32): f32;
}
@ -293,14 +293,212 @@ export namespace f64 {
@builtin export declare function ceil(value: f64): f64;
@builtin export declare function copysign(x: f64, y: f64): f64;
@builtin export declare function floor(value: f64): f64;
@builtin export declare function load(offset: usize, constantOffset?: usize): f64;
@builtin export declare function load(offset: usize, immOffset?: usize, immAlign?: usize): f64;
@builtin export declare function max(left: f64, right: f64): f64;
@builtin export declare function min(left: f64, right: f64): f64;
@builtin export declare function nearest(value: f64): f64;
@builtin export declare function reinterpret_i64(value: i64): f64;
@builtin export declare function sqrt(value: f64): f64;
@builtin export declare function store(offset: usize, value: f64, constantOffset?: usize): void;
@builtin export declare function store(offset: usize, value: f64, immOffset?: usize, immAlign?: usize): void;
@builtin export declare function trunc(value: f64): f64;
}
@builtin export declare function v128(a: i8, b: i8, c: i8, d: i8, e: i8, f: i8, g: i8, h: i8, i: i8, j: i8, k: i8, l: i8, m: i8, n: i8, o: i8, p: i8): v128;
export namespace v128 {
@builtin export declare function splat<T>(x: T): v128;
@builtin export declare function extract_lane<T>(x: v128, idx: u8): T;
@builtin export declare function replace_lane<T>(x: v128, idx: u8, value: T): v128;
@builtin export declare function shuffle<T>(a: v128, b: v128, ...lanes: u8[]): v128;
@builtin export declare function load(offset: usize, immOffset?: usize, immAlign?: usize): v128;
@builtin export declare function store(offset: usize, value: v128, immOffset?: usize, immAlign?: usize): void;
@builtin export declare function add<T>(a: v128, b: v128): v128;
@builtin export declare function sub<T>(a: v128, b: v128): v128;
@builtin export declare function mul<T>(a: v128, b: v128): v128; // except i64
@builtin export declare function div<T>(a: v128, b: v128): v128; // f32, f64 only
@builtin export declare function neg<T>(a: v128): v128;
@builtin export declare function add_saturate<T>(a: v128, b: v128): v128;
@builtin export declare function sub_saturate<T>(a: v128, b: v128): v128;
@builtin export declare function shl<T>(a: v128, b: i32): v128;
@builtin export declare function shr<T>(a: v128, b: i32): v128;
@builtin export declare function and(a: v128, b: v128): v128;
@builtin export declare function or(a: v128, b: v128): v128;
@builtin export declare function xor(a: v128, b: v128): v128;
@builtin export declare function not(a: v128): v128;
@builtin export declare function bitselect(v1: v128, v2: v128, c: v128): v128;
@builtin export declare function any_true<T>(a: v128): bool;
@builtin export declare function all_true<T>(a: v128): bool;
@builtin export declare function min<T>(a: v128, b: v128): v128; // f32, f64 only
@builtin export declare function max<T>(a: v128, b: v128): v128; // f32, f64 only
@builtin export declare function abs<T>(a: v128): v128; // f32, f64 only
@builtin export declare function sqrt<T>(a: v128): v128; // f32, f64 only
@builtin export declare function eq<T>(a: v128, b: v128): v128;
@builtin export declare function ne<T>(a: v128, b: v128): v128;
@builtin export declare function lt<T>(a: v128, b: v128): v128;
@builtin export declare function le<T>(a: v128, b: v128): v128;
@builtin export declare function gt<T>(a: v128, b: v128): v128;
@builtin export declare function ge<T>(a: v128, b: v128): v128;
@builtin export declare function convert<T>(a: v128): v128;
@builtin export declare function trunc<T>(a: v128): v128;
}
@builtin export declare function i8x16(a: i8, b: i8, c: i8, d: i8, e: i8, f: i8, g: i8, h: i8, i: i8, j: i8, k: i8, l: i8, m: i8, n: i8, o: i8, p: i8): v128;
export namespace i8x16 {
@builtin export declare function splat(x: i8): v128;
@builtin export declare function extract_lane_s(x: v128, idx: u8): i8;
@builtin export declare function extract_lane_u(x: v128, idx: u8): u8;
@builtin export declare function replace_lane(x: v128, idx: u8, value: i8): v128;
@builtin export declare function add(a: v128, b: v128): v128;
@builtin export declare function sub(a: v128, b: v128): v128;
@builtin export declare function mul(a: v128, b: v128): v128;
@builtin export declare function neg(a: v128): v128;
@builtin export declare function add_saturate_s(a: v128, b: v128): v128;
@builtin export declare function add_saturate_u(a: v128, b: v128): v128;
@builtin export declare function sub_saturate_s(a: v128, b: v128): v128;
@builtin export declare function sub_saturate_u(a: v128, b: v128): v128;
@builtin export declare function shl(a: v128, b: i32): v128;
@builtin export declare function shr_s(a: v128, b: i32): v128;
@builtin export declare function shr_u(a: v128, b: i32): v128;
@builtin export declare function any_true(a: v128): bool;
@builtin export declare function all_true(a: v128): bool;
@builtin export declare function eq(a: v128, b: v128): v128;
@builtin export declare function ne(a: v128, b: v128): v128;
@builtin export declare function lt_s(a: v128, b: v128): v128;
@builtin export declare function lt_u(a: v128, b: v128): v128;
@builtin export declare function le_s(a: v128, b: v128): v128;
@builtin export declare function le_u(a: v128, b: v128): v128;
@builtin export declare function gt_s(a: v128, b: v128): v128;
@builtin export declare function gt_u(a: v128, b: v128): v128;
@builtin export declare function ge_s(a: v128, b: v128): v128;
@builtin export declare function ge_u(a: v128, b: v128): v128;
}
@builtin export declare function i16x8(a: i16, b: i16, c: i16, d: i16, e: i16, f: i16, g: i16, h: i16): v128;
export namespace i16x8 {
@builtin export declare function splat(x: i16): v128;
@builtin export declare function extract_lane_s(x: v128, idx: u8): i16;
@builtin export declare function extract_lane_u(x: v128, idx: u8): u16;
@builtin export declare function replace_lane(x: v128, idx: u8, value: i16): v128;
@builtin export declare function add(a: v128, b: v128): v128;
@builtin export declare function sub(a: v128, b: v128): v128;
@builtin export declare function mul(a: v128, b: v128): v128;
@builtin export declare function neg(a: v128): v128;
@builtin export declare function add_saturate_s(a: v128, b: v128): v128;
@builtin export declare function add_saturate_u(a: v128, b: v128): v128;
@builtin export declare function sub_saturate_s(a: v128, b: v128): v128;
@builtin export declare function sub_saturate_u(a: v128, b: v128): v128;
@builtin export declare function shl(a: v128, b: i32): v128;
@builtin export declare function shr_s(a: v128, b: i32): v128;
@builtin export declare function shr_u(a: v128, b: i32): v128;
@builtin export declare function any_true(a: v128): bool;
@builtin export declare function all_true(a: v128): bool;
@builtin export declare function eq(a: v128, b: v128): v128;
@builtin export declare function ne(a: v128, b: v128): v128;
@builtin export declare function lt_s(a: v128, b: v128): v128;
@builtin export declare function lt_u(a: v128, b: v128): v128;
@builtin export declare function le_s(a: v128, b: v128): v128;
@builtin export declare function le_u(a: v128, b: v128): v128;
@builtin export declare function gt_s(a: v128, b: v128): v128;
@builtin export declare function gt_u(a: v128, b: v128): v128;
@builtin export declare function ge_s(a: v128, b: v128): v128;
@builtin export declare function ge_u(a: v128, b: v128): v128;
}
@builtin export declare function i32x4(a: i32, b: i32, c: i32, d: i32): v128;
export namespace i32x4 {
@builtin export declare function splat(x: i32): v128;
@builtin export declare function extract_lane(x: v128, idx: u8): i32;
@builtin export declare function replace_lane(x: v128, idx: u8, value: i32): v128;
@builtin export declare function add(a: v128, b: v128): v128;
@builtin export declare function sub(a: v128, b: v128): v128;
@builtin export declare function mul(a: v128, b: v128): v128;
@builtin export declare function neg(a: v128): v128;
@builtin export declare function shl(a: v128, b: i32): v128;
@builtin export declare function shr_s(a: v128, b: i32): v128;
@builtin export declare function shr_u(a: v128, b: i32): v128;
@builtin export declare function any_true(a: v128): bool;
@builtin export declare function all_true(a: v128): bool;
@builtin export declare function eq(a: v128, b: v128): v128;
@builtin export declare function ne(a: v128, b: v128): v128;
@builtin export declare function lt_s(a: v128, b: v128): v128;
@builtin export declare function lt_u(a: v128, b: v128): v128;
@builtin export declare function le_s(a: v128, b: v128): v128;
@builtin export declare function le_u(a: v128, b: v128): v128;
@builtin export declare function gt_s(a: v128, b: v128): v128;
@builtin export declare function gt_u(a: v128, b: v128): v128;
@builtin export declare function ge_s(a: v128, b: v128): v128;
@builtin export declare function ge_u(a: v128, b: v128): v128;
@builtin export declare function trunc_s_f32x4_sat(a: v128): v128;
@builtin export declare function trunc_u_f32x4_sat(a: v128): v128;
}
@builtin export declare function i64x2(a: i64, b: i64): v128;
export namespace i64x2 {
@builtin export declare function splat(x: i64): v128;
@builtin export declare function extract_lane(x: v128, idx: u8): i64;
@builtin export declare function replace_lane(x: v128, idx: u8, value: i64): v128;
@builtin export declare function add(a: v128, b: v128): v128;
@builtin export declare function sub(a: v128, b: v128): v128;
@builtin export declare function mul(a: v128, b: v128): v128;
@builtin export declare function neg(a: v128): v128;
@builtin export declare function shl(a: v128, b: i32): v128;
@builtin export declare function shr_s(a: v128, b: i32): v128;
@builtin export declare function shr_u(a: v128, b: i32): v128;
@builtin export declare function any_true(a: v128): bool;
@builtin export declare function all_true(a: v128): bool;
@builtin export declare function trunc_s_f64x2_sat(a: v128): v128;
@builtin export declare function trunc_u_f64x2_sat(a: v128): v128;
}
@builtin export declare function f32x4(a: f32, b: f32, c: f32, d: f32): v128;
export namespace f32x4 {
@builtin export declare function splat(x: f32): v128;
@builtin export declare function extract_lane(x: v128, idx: u8): f32;
@builtin export declare function replace_lane(x: v128, idx: u8, value: f32): v128;
@builtin export declare function add(a: v128, b: v128): v128;
@builtin export declare function sub(a: v128, b: v128): v128;
@builtin export declare function mul(a: v128, b: v128): v128;
@builtin export declare function div(a: v128, b: v128): v128;
@builtin export declare function neg(a: v128): v128;
@builtin export declare function min(a: v128, b: v128): v128;
@builtin export declare function max(a: v128, b: v128): v128;
@builtin export declare function abs(a: v128): v128;
@builtin export declare function sqrt(a: v128): v128;
@builtin export declare function eq(a: v128, b: v128): v128;
@builtin export declare function ne(a: v128, b: v128): v128;
@builtin export declare function lt(a: v128, b: v128): v128;
@builtin export declare function le(a: v128, b: v128): v128;
@builtin export declare function gt(a: v128, b: v128): v128;
@builtin export declare function ge(a: v128, b: v128): v128;
@builtin export declare function convert_s_i32x4(a: v128): v128;
@builtin export declare function convert_u_i32x4(a: v128): v128;
}
@builtin export declare function f64x2(a: f64, b: f64): v128;
export namespace f64x2 {
@builtin export declare function splat(x: f64): v128;
@builtin export declare function extract_lane(x: v128, idx: u8): f64;
@builtin export declare function replace_lane(x: v128, idx: u8, value: f64): v128;
@builtin export declare function add(a: v128, b: v128): v128;
@builtin export declare function sub(a: v128, b: v128): v128;
@builtin export declare function mul(a: v128, b: v128): v128;
@builtin export declare function div(a: v128, b: v128): v128;
@builtin export declare function neg(a: v128): v128;
@builtin export declare function min(a: v128, b: v128): v128;
@builtin export declare function max(a: v128, b: v128): v128;
@builtin export declare function abs(a: v128): v128;
@builtin export declare function sqrt(a: v128): v128;
@builtin export declare function eq(a: v128, b: v128): v128;
@builtin export declare function ne(a: v128, b: v128): v128;
@builtin export declare function lt(a: v128, b: v128): v128;
@builtin export declare function le(a: v128, b: v128): v128;
@builtin export declare function gt(a: v128, b: v128): v128;
@builtin export declare function ge(a: v128, b: v128): v128;
@builtin export declare function convert_s_i64x2(a: v128): v128;
@builtin export declare function convert_u_i64x2(a: v128): v128;
}
export namespace v8x16 {
@builtin export declare function shuffle(a: v128, b: v128, l0: u8, l1: u8, l2: u8, l3: u8, l4: u8, l5: u8, l6: u8, l7: u8, l8: u8, l9: u8, l10: u8, l11: u8, l12: u8, l13: u8, l14: u8, l15: u8): v128;
}
@builtin export declare function start(): void;

View File

@ -33,6 +33,8 @@ declare type bool = boolean | number;
declare type f32 = number;
/** A 64-bit float. */
declare type f64 = number;
/** A 128-bit vector. */
declare type v128 = object;
// Compiler hints
@ -50,6 +52,12 @@ declare const ASC_SHRINK_LEVEL: i32;
declare const ASC_FEATURE_MUTABLE_GLOBAL: bool;
/** Whether the sign extension feature is enabled. */
declare const ASC_FEATURE_SIGN_EXTENSION: bool;
/** Whether the bulk memory feature is enabled. */
declare const ASC_FEATURE_BULK_MEMORY: bool;
/** Whether the SIMD feature is enabled. */
declare const ASC_FEATURE_SIMD: bool;
/** Whether the threads feature is enabled. */
declare const ASC_FEATURE_THREADS: bool;
// Builtins
@ -86,9 +94,9 @@ declare function sqrt<T = f32 | f64>(value: T): T;
/** Rounds to the nearest integer towards zero of a 32-bit or 64-bit float. */
declare function trunc<T = f32 | f64>(value: T): T;
/** Loads a value of the specified type from memory. Equivalent to dereferncing a pointer in other languages. */
declare function load<T>(ptr: usize, constantOffset?: usize): T;
declare function load<T>(ptr: usize, immOffset?: usize, immAlign?: usize): T;
/** Stores a value of the specified type to memory. Equivalent to dereferencing a pointer in other languages when assigning a value. */
declare function store<T>(ptr: usize, value: any, constantOffset?: usize): void;
declare function store<T>(ptr: usize, value: any, immOffset?: usize, immAlign?: usize): void;
/** Emits an unreachable operation that results in a runtime error when executed. Both a statement and an expression of any type. */
declare function unreachable(): any; // sic
@ -162,10 +170,6 @@ declare namespace i8 {
export const MIN_VALUE: i8;
/** Largest representable value. */
export const MAX_VALUE: i8;
/** Converts a string to a floating-point number and cast to target integer after. */
export function parseFloat(string: string): i8;
/** Converts A string to an integer. */
export function parseInt(string: string, radix?: i32): i8;
}
/** Converts any other numeric value to a 16-bit signed integer. */
declare function i16(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
@ -174,10 +178,6 @@ declare namespace i16 {
export const MIN_VALUE: i16;
/** Largest representable value. */
export const MAX_VALUE: i16;
/** Converts a string to a floating-point number and cast to target integer after. */
export function parseFloat(string: string): i16;
/** Converts A string to an integer. */
export function parseInt(string: string, radix?: i32): i16;
}
/** Converts any other numeric value to a 32-bit signed integer. */
declare function i32(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i32;
@ -187,25 +187,21 @@ declare namespace i32 {
/** Largest representable value. */
export const MAX_VALUE: i32;
/** Loads an 8-bit signed integer from memory and returns it as a 32-bit integer. */
export function load8_s(offset: usize, constantOffset?: usize): i32;
export function load8_s(offset: usize, immOffset?: usize, immAlign?: usize): i32;
/** Loads an 8-bit unsigned integer from memory and returns it as a 32-bit integer. */
export function load8_u(offset: usize, constantOffset?: usize): i32;
export function load8_u(offset: usize, immOffset?: usize, immAlign?: usize): i32;
/** Loads a 16-bit signed integer from memory and returns it as a 32-bit integer. */
export function load16_s(offset: usize, constantOffset?: usize): i32;
export function load16_s(offset: usize, immOffset?: usize, immAlign?: usize): i32;
/** Loads a 16-bit unsigned integer from memory and returns it as a 32-bit integer. */
export function load16_u(offset: usize, constantOffset?: usize): i32;
export function load16_u(offset: usize, immOffset?: usize, immAlign?: usize): i32;
/** Loads a 32-bit integer from memory. */
export function load(offset: usize, constantOffset?: usize): i32;
export function load(offset: usize, immOffset?: usize, immAlign?: usize): i32;
/** Stores a 32-bit integer to memory as an 8-bit integer. */
export function store8(offset: usize, value: i32, constantOffset?: usize): void;
export function store8(offset: usize, value: i32, immOffset?: usize, immAlign?: usize): void;
/** Stores a 32-bit integer to memory as a 16-bit integer. */
export function store16(offset: usize, value: i32, constantOffset?: usize): void;
export function store16(offset: usize, value: i32, immOffset?: usize, immAlign?: usize): void;
/** Stores a 32-bit integer to memory. */
export function store(offset: usize, value: i32, constantOffset?: usize): void;
/** Converts a string to a floating-point number and cast to target integer after. */
export function parseFloat(string: string): i32;
/** Converts A string to an integer. */
export function parseInt(string: string, radix?: i32): i32;
export function store(offset: usize, value: i32, immOffset?: usize, immAlign?: usize): void;
}
/** Converts any other numeric value to a 64-bit signed integer. */
declare function i64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i64;
@ -215,31 +211,27 @@ declare namespace i64 {
/** Largest representable value. */
export const MAX_VALUE: i64;
/** Loads an 8-bit signed integer from memory and returns it as a 64-bit signed integer. */
export function load8_s(offset: usize, constantOffset?: usize): i64;
export function load8_s(offset: usize, immOffset?: usize, immAlign?: usize): i64;
/** Loads an 8-bit unsigned integer from memory and returns it as a 64-bit unsigned integer. */
export function load8_u(offset: usize, constantOffset?: usize): u64;
export function load8_u(offset: usize, immOffset?: usize, immAlign?: usize): u64;
/** Loads a 16-bit signed integer from memory and returns it as a 64-bit signed integer. */
export function load16_s(offset: usize, constantOffset?: usize): i64;
export function load16_s(offset: usize, immOffset?: usize, immAlign?: usize): i64;
/** Loads a 16-bit unsigned integer from memory and returns it as a 64-bit unsigned integer. */
export function load16_u(offset: usize, constantOffset?: usize): u64;
export function load16_u(offset: usize, immOffset?: usize, immAlign?: usize): u64;
/** Loads a 32-bit signed integer from memory and returns it as a 64-bit signed integer. */
export function load32_s(offset: usize, constantOffset?: usize): i64;
export function load32_s(offset: usize, immOffset?: usize, immAlign?: usize): i64;
/** Loads a 32-bit unsigned integer from memory and returns it as a 64-bit unsigned integer. */
export function load32_u(offset: usize, constantOffset?: usize): u64;
export function load32_u(offset: usize, immOffset?: usize, immAlign?: usize): u64;
/** Loads a 64-bit unsigned integer from memory. */
export function load(offset: usize, constantOffset?: usize): i64;
export function load(offset: usize, immOffset?: usize, immAlign?: usize): i64;
/** Stores a 64-bit integer to memory as an 8-bit integer. */
export function store8(offset: usize, value: i64, constantOffset?: usize): void;
export function store8(offset: usize, value: i64, immOffset?: usize, immAlign?: usize): void;
/** Stores a 64-bit integer to memory as a 16-bit integer. */
export function store16(offset: usize, value: i64, constantOffset?: usize): void;
export function store16(offset: usize, value: i64, immOffset?: usize, immAlign?: usize): void;
/** Stores a 64-bit integer to memory as a 32-bit integer. */
export function store32(offset: usize, value: i64, constantOffset?: usize): void;
export function store32(offset: usize, value: i64, immOffset?: usize, immAlign?: usize): void;
/** Stores a 64-bit integer to memory. */
export function store(offset: usize, value: i64, constantOffset?: usize): void;
/** Converts a string to a floating-point number and cast to target integer after. */
export function parseFloat(string: string): i64;
/** Converts A string to an integer. */
export function parseInt(string: string, radix?: i32): i64;
export function store(offset: usize, value: i64, immOffset?: usize, immAlign?: usize): void;
}
/** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) signed integer. */
declare var isize: typeof i32 | typeof i64;
@ -250,10 +242,6 @@ declare namespace u8 {
export const MIN_VALUE: u8;
/** Largest representable value. */
export const MAX_VALUE: u8;
/** Converts a string to a floating-point number and cast to target integer after. */
export function parseFloat(string: string): u8;
/** Converts A string to an integer. */
export function parseInt(string: string, radix?: i32): u8;
}
/** Converts any other numeric value to a 16-bit unsigned integer. */
declare function u16(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i8;
@ -262,10 +250,6 @@ declare namespace u16 {
export const MIN_VALUE: u16;
/** Largest representable value. */
export const MAX_VALUE: u16;
/** Converts a string to a floating-point number and cast to target integer after. */
export function parseFloat(string: string): u16;
/** Converts A string to an integer. */
export function parseInt(string: string, radix?: i32): u16;
}
/** Converts any other numeric value to a 32-bit unsigned integer. */
declare function u32(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i32;
@ -274,10 +258,6 @@ declare namespace u32 {
export const MIN_VALUE: u32;
/** Largest representable value. */
export const MAX_VALUE: u32;
/** Converts a string to a floating-point number and cast to target integer after. */
export function parseFloat(string: string): u64;
/** Converts A string to an integer. */
export function parseInt(string: string, radix?: i32): u64;
}
/** Converts any other numeric value to a 64-bit unsigned integer. */
declare function u64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): i64;
@ -286,10 +266,6 @@ declare namespace u64 {
export const MIN_VALUE: u64;
/** Largest representable value. */
export const MAX_VALUE: u64;
/** Converts a string to a floating-point number. */
export function parseFloat(string: string): u64;
/** Converts A string to an integer. */
export function parseInt(string: string, radix?: i32): u64;
}
/** Converts any other numeric value to a 32-bit (in WASM32) respectivel 64-bit (in WASM64) unsigned integer. */
declare var usize: typeof u32 | typeof u64;
@ -316,26 +292,10 @@ declare namespace f32 {
export const MAX_SAFE_INTEGER: f32;
/** Difference between 1 and the smallest representable value greater than 1. */
export const EPSILON: f32;
/** Returns the floating-point remainder of `x / y` (rounded towards zero). */
export function mod(x: f32, y: f32): f32;
/** Returns the floating-point remainder of `x / y` (rounded to nearest). */
export function rem(x: f32, y: f32): f32;
/** Loads a 32-bit float from memory. */
export function load(offset: usize, constantOffset?: usize): f32;
export function load(offset: usize, immOffset?: usize, immAlign?: usize): f32;
/** Stores a 32-bit float to memory. */
export function store(offset: usize, value: f32, constantOffset?: usize): void;
/** Returns a boolean value that indicates whether a value is the reserved value NaN (not a number). */
export function isNaN(value: f32): bool;
/** Returns true if passed value is finite. */
export function isFinite(value: f32): bool;
/** Returns true if the value passed is a safe integer. */
export function isSafeInteger(value: f32): bool;
/** Returns true if the value passed is an integer, false otherwise. */
export function isInteger(value: f32): bool;
/** Converts a string to a floating-point number. */
export function parseFloat(string: string): f32;
/** Converts a string to an integer. */
export function parseInt(string: string, radix?: i32): f32;
export function store(offset: usize, value: f32, immOffset?: usize, immAlign?: usize): void;
}
/** Converts any other numeric value to a 64-bit float. */
declare function f64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): f64;
@ -353,9 +313,373 @@ declare namespace f64 {
/** Difference between 1 and the smallest representable value greater than 1. */
export const EPSILON: f64;
/** Loads a 64-bit float from memory. */
export function load(offset: usize, constantOffset?: usize): f64;
export function load(offset: usize, immOffset?: usize, immAlign?: usize): f64;
/** Stores a 64-bit float to memory. */
export function store(offset: usize, value: f64, constantOffset?: usize): void;
export function store(offset: usize, value: f64, immOffset?: usize, immAlign?: usize): void;
}
/** Initializes a 128-bit vector from sixteen 8-bit integer values. Arguments must be compile-time constants. */
declare function v128(a: i8, b: i8, c: i8, d: i8, e: i8, f: i8, g: i8, h: i8, i: i8, j: i8, k: i8, l: i8, m: i8, n: i8, o: i8, p: i8): v128;
declare namespace v128 {
/** Creates a 128-bit vector with identical lanes. */
export function splat<T>(x: T): v128;
/** Extracts one lane from a 128-bit vector as a scalar. */
export function extract_lane<T>(x: v128, idx: u8): T;
/** Replaces one lane in a 128-bit vector. */
export function replace_lane<T>(x: v128, idx: u8, value: T): v128;
/** Selects lanes from either 128-bit vector according to the specified lane indexes. */
export function shuffle<T>(a: v128, b: v128, ...lanes: u8[]): v128;
/** Loads a 128-bit vector from memory. */
export function load(offset: usize, immOffset?: usize, immAlign?: usize): v128;
/** Stores a 128-bit vector to memory. */
export function store(offset: usize, value: v128, immOffset?: usize, immAlign?: usize): void;
/** Adds each lane of two 128-bit vectors. */
export function add<T>(a: v128, b: v128): v128;
/** Subtracts each lane of two 128-bit vectors. */
export function sub<T>(a: v128, b: v128): v128;
/** Multiplies each lane of two 128-bit vectors. */
export function mul<T>(a: v128, b: v128): v128; // except i64
/** Divides each lane of two 128-bit vectors. */
export function div<T = f32 | f64>(a: v128, b: v128): v128;
/** Negates each lane of a 128-bit vector */
export function neg<T>(a: v128): v128;
/** Adds each lane of two 128-bit vectors using saturation. */
export function add_saturate<T>(a: v128, b: v128): v128;
/** Subtracts each lane of two 128-bit vectors using saturation. */
export function sub_saturate<T>(a: v128, b: v128): v128;
/** Performs a bitwise left shift on each lane of a 128-bit vector by a scalar. */
export function shl<T>(a: v128, b: i32): v128;
/** Performs a bitwise right shift on each lane of a 128-bit vector by a scalar. */
export function shr<T>(a: v128, b: i32): v128;
/** Performs the bitwise AND operation on each lane of two 128-bit vectors. */
export function and(a: v128, b: v128): v128;
/** Performs the bitwise OR operation on each lane of two 128-bit vectors. */
export function or(a: v128, b: v128): v128;
/** Performs the bitwise XOR operation on each lane of two 128-bit vectors. */
export function xor(a: v128, b: v128): v128;
/** Performs the bitwise NOT operation on each lane of a 128-bit vector. */
export function not(a: v128): v128;
/** Selects bits of either 128-bit vector according to the specified mask. */
export function bitselect(v1: v128, v2: v128, mask: v128): v128;
/** Reduces a 128-bit vector to a scalar indicating whether any lane is considered `true`. */
export function any_true<T>(a: v128): bool;
/** Reduces a 128-bit vector to a scalar indicating whether all lanes are considered `true`. */
export function all_true<T>(a: v128): bool;
/** Computes the minimum of each lane of two 128-bit vectors. */
export function min<T = f32 | f64>(a: v128, b: v128): v128;
/** Computes the maximum of each lane of two 128-bit vectors. */
export function max<T = f32 | f64>(a: v128, b: v128): v128;
/** Computes the absolute value of each lane of a 128-bit vector. */
export function abs<T = f32 | f64>(a: v128): v128;
/** Computes the square root of each lane of a 128-bit vector. */
export function sqrt<T = f32 | f64>(a: v128): v128;
/** Computes which lanes of two 128-bit vectors are equal. */
export function eq<T>(a: v128, b: v128): v128;
/** Computes which lanes of two 128-bit vectors are not equal. */
export function ne<T>(a: v128, b: v128): v128;
/** Computes which lanes of the first 128-bit vector are less than those of the second. */
export function lt<T>(a: v128, b: v128): v128;
/** Computes which lanes of the first 128-bit vector are less than or equal those of the second. */
export function le<T>(a: v128, b: v128): v128;
/** Computes which lanes of the first 128-bit vector are greater than those of the second. */
export function gt<T>(a: v128, b: v128): v128;
/** Computes which lanes of the first 128-bit vector are greater than or equal those of the second. */
export function ge<T>(a: v128, b: v128): v128;
/** Converts each lane of a 128-bit vector from integer to floating point. */
export function convert<TFrom = i32 | u32 | i64 | u64>(a: v128): v128;
/** Truncates each lane of a 128-bit vector from floating point to integer with saturation. */
export function trunc<TTo = i32 | u32 | i64 | u64>(a: v128): v128;
}
/** Initializes a 128-bit vector from sixteen 8-bit integer values. Arguments must be compile-time constants. */
declare function i8x16(a: i8, b: i8, c: i8, d: i8, e: i8, f: i8, g: i8, h: i8, i: i8, j: i8, k: i8, l: i8, m: i8, n: i8, o: i8, p: i8): v128;
declare namespace i8x16 {
/** Creates a vector with sixteen identical 8-bit integer lanes. */
export function splat(x: i8): v128;
/** Extracts one 8-bit integer lane from a 128-bit vector as a signed scalar. */
export function extract_lane_s(x: v128, idx: u8): i8;
/** Extracts one 8-bit integer lane from a 128-bit vector as an unsigned scalar. */
export function extract_lane_u(x: v128, idx: u8): u8;
/** Replaces one 8-bit integer lane in a 128-bit vector. */
export function replace_lane(x: v128, idx: u8, value: i8): v128;
/** Adds each 8-bit integer lane of two 128-bit vectors. */
export function add(a: v128, b: v128): v128;
/** Subtracts each 8-bit integer lane of two 128-bit vectors. */
export function sub(a: v128, b: v128): v128;
/** Multiplies each 8-bit integer lane of two 128-bit vectors. */
export function mul(a: v128, b: v128): v128;
/** Negates each 8-bit integer lane of a 128-bit vector. */
export function neg(a: v128): v128;
/** Adds each 8-bit integer lane of two 128-bit vectors using signed saturation. */
export function add_saturate_s(a: v128, b: v128): v128;
/** Adds each 8-bit integer lane of two 128-bit vectors using unsigned saturation. */
export function add_saturate_u(a: v128, b: v128): v128;
/** Subtracts each 8-bit integer lane of two 128-bit vectors using signed saturation. */
export function sub_saturate_s(a: v128, b: v128): v128;
/** Subtracts each 8-bit integer lane of two 128-bit vectors using unsigned saturation. */
export function sub_saturate_u(a: v128, b: v128): v128;
/** Performs a bitwise left shift on each 8-bit integer lane of a 128-bit vector by a scalar. */
export function shl(a: v128, b: i32): v128;
/** Performs a bitwise arithmetic right shift on each 8-bit integer lane of a 128-bit vector by a scalar. */
export function shr_s(a: v128, b: i32): v128;
/** Performs a bitwise logical right shift on each 8-bit integer lane of a 128-bit vector by a scalar. */
export function shr_u(a: v128, b: i32): v128;
/** Reduces a 128-bit vector to a scalar indicating whether any 8-bit integer lane is considered `true`. */
export function any_true(a: v128): bool;
/** Reduces a 128-bit vector to a scalar indicating whether all 8-bit integer lanes are considered `true`. */
export function all_true(a: v128): bool;
/** Computes which 8-bit integer lanes of two 128-bit vectors are equal. */
export function eq(a: v128, b: v128): v128;
/** Computes which 8-bit integer lanes of two 128-bit vectors are not equal. */
export function ne(a: v128, b: v128): v128;
/** Computes which 8-bit signed integer lanes of the first 128-bit vector are less than those of the second. */
export function lt_s(a: v128, b: v128): v128;
/** Computes which 8-bit unsigned integer lanes of the first 128-bit vector are less than those of the second. */
export function lt_u(a: v128, b: v128): v128;
/** Computes which 8-bit signed integer lanes of the first 128-bit vector are less than or equal those of the second. */
export function le_s(a: v128, b: v128): v128;
/** Computes which 8-bit unsigned integer lanes of the first 128-bit vector are less than or equal those of the second. */
export function le_u(a: v128, b: v128): v128;
/** Computes which 8-bit signed integer lanes of the first 128-bit vector are greater than those of the second. */
export function gt_s(a: v128, b: v128): v128;
/** Computes which 8-bit unsigned integer lanes of the first 128-bit vector are greater than those of the second. */
export function gt_u(a: v128, b: v128): v128;
/** Computes which 8-bit signed integer lanes of the first 128-bit vector are greater than or equal those of the second. */
export function ge_s(a: v128, b: v128): v128;
/** Computes which 8-bit unsigned integer lanes of the first 128-bit vector are greater than or equal those of the second. */
export function ge_u(a: v128, b: v128): v128;
}
/** Initializes a 128-bit vector from eight 16-bit integer values. Arguments must be compile-time constants. */
declare function i16x8(a: i16, b: i16, c: i16, d: i16, e: i16, f: i16, g: i16, h: i16): v128;
declare namespace i16x8 {
/** Creates a vector with eight identical 16-bit integer lanes. */
export function splat(x: i16): v128;
/** Extracts one 16-bit integer lane from a 128-bit vector as a signed scalar. */
export function extract_lane_s(x: v128, idx: u8): i16;
/** Extracts one 16-bit integer lane from a 128-bit vector as an unsigned scalar. */
export function extract_lane_u(x: v128, idx: u8): u16;
/** Replaces one 16-bit integer lane in a 128-bit vector. */
export function replace_lane(x: v128, idx: u8, value: i16): v128;
/** Adds each 16-bit integer lane of two 128-bit vectors. */
export function add(a: v128, b: v128): v128;
/** Subtracts each 16-bit integer lane of two 128-bit vectors. */
export function sub(a: v128, b: v128): v128;
/** Multiplies each 16-bit integer lane of two 128-bit vectors. */
export function mul(a: v128, b: v128): v128;
/** Negates each 16-bit integer lane of a 128-bit vector. */
export function neg(a: v128): v128;
/** Adds each 16-bit integer lane of two 128-bit vectors using signed saturation. */
export function add_saturate_s(a: v128, b: v128): v128;
/** Adds each 16-bit integer lane of two 128-bit vectors using unsigned saturation. */
export function add_saturate_u(a: v128, b: v128): v128;
/** Subtracts each 16-bit integer lane of two 128-bit vectors using signed saturation. */
export function sub_saturate_s(a: v128, b: v128): v128;
/** Subtracts each 16-bit integer lane of two 128-bit vectors using unsigned saturation. */
export function sub_saturate_u(a: v128, b: v128): v128;
/** Performs a bitwise left shift on each 16-bit integer lane of a 128-bit vector by a scalar. */
export function shl(a: v128, b: i32): v128;
/** Performs a bitwise arithmetic right shift each 16-bit integer lane of a 128-bit vector by a scalar. */
export function shr_s(a: v128, b: i32): v128;
/** Performs a bitwise logical right shift on each 16-bit integer lane of a 128-bit vector by a scalar. */
export function shr_u(a: v128, b: i32): v128;
/** Reduces a 128-bit vector to a scalar indicating whether any 16-bit integer lane is considered `true`. */
export function any_true(a: v128): bool;
/** Reduces a 128-bit vector to a scalar indicating whether all 16-bit integer lanes are considered `true`. */
export function all_true(a: v128): bool;
/** Computes which 16-bit integer lanes of two 128-bit vectors are equal. */
export function eq(a: v128, b: v128): v128;
/** Computes which 16-bit integer lanes of two 128-bit vectors are not equal. */
export function ne(a: v128, b: v128): v128;
/** Computes which 16-bit signed integer lanes of the first 128-bit vector are less than those of the second. */
export function lt_s(a: v128, b: v128): v128;
/** Computes which 16-bit unsigned integer lanes of the first 128-bit vector are less than those of the second. */
export function lt_u(a: v128, b: v128): v128;
/** Computes which 16-bit signed integer lanes of the first 128-bit vector are less than or equal those of the second. */
export function le_s(a: v128, b: v128): v128;
/** Computes which 16-bit unsigned integer lanes of the first 128-bit vector are less than or equal those of the second. */
export function le_u(a: v128, b: v128): v128;
/** Computes which 16-bit signed integer lanes of the first 128-bit vector are greater than those of the second. */
export function gt_s(a: v128, b: v128): v128;
/** Computes which 16-bit unsigned integer lanes of the first 128-bit vector are greater than those of the second. */
export function gt_u(a: v128, b: v128): v128;
/** Computes which 16-bit signed integer lanes of the first 128-bit vector are greater than or equal those of the second. */
export function ge_s(a: v128, b: v128): v128;
/** Computes which 16-bit unsigned integer lanes of the first 128-bit vector are greater than or equal those of the second. */
export function ge_u(a: v128, b: v128): v128;
}
/** Initializes a 128-bit vector from four 32-bit integer values. Arguments must be compile-time constants. */
declare function i32x4(a: i32, b: i32, c: i32, d: i32): v128;
declare namespace i32x4 {
/** Creates a 128-bit vector with four identical 32-bit integer lanes. */
export function splat(x: i32): v128;
/** Extracts one 32-bit integer lane from a 128-bit vector as a scalar. */
export function extract_lane(x: v128, idx: u8): i32;
/** Replaces one 32-bit integer lane in a 128-bit vector. */
export function replace_lane(x: v128, idx: u8, value: i32): v128;
/** Adds each 32-bit integer lane of two 128-bit vectors. */
export function add(a: v128, b: v128): v128;
/** Subtracts each 32-bit integer lane of two 128-bit vectors. */
export function sub(a: v128, b: v128): v128;
/** Multiplies each 32-bit integer lane of two 128-bit vectors. */
export function mul(a: v128, b: v128): v128;
/** Negates each 32-bit integer lane of a 128-bit vector. */
export function neg(a: v128): v128;
/** Performs a bitwise left shift on each 32-bit integer lane of a 128-bit vector by a scalar. */
export function shl(a: v128, b: i32): v128;
/** Performs a bitwise arithmetic right shift on each 32-bit integer lane of a 128-bit vector by a scalar. */
export function shr_s(a: v128, b: i32): v128;
/** Performs a bitwise logical right shift on each 32-bit integer lane of a 128-bit vector by a scalar. */
export function shr_u(a: v128, b: i32): v128;
/** Reduces a 128-bit vector to a scalar indicating whether any 32-bit integer lane is considered `true`. */
export function any_true(a: v128): bool;
/** Reduces a 128-bit vector to a scalar indicating whether all 32-bit integer lanes are considered `true`. */
export function all_true(a: v128): bool;
/** Computes which 32-bit integer lanes of two 128-bit vectors are equal. */
export function eq(a: v128, b: v128): v128;
/** Computes which 32-bit integer lanes of two 128-bit vectors are not equal. */
export function ne(a: v128, b: v128): v128;
/** Computes which 32-bit signed integer lanes of the first 128-bit vector are less than those of the second. */
export function lt_s(a: v128, b: v128): v128;
/** Computes which 32-bit unsigned integer lanes of the first 128-bit vector are less than those of the second. */
export function lt_u(a: v128, b: v128): v128;
/** Computes which 32-bit signed integer lanes of the first 128-bit vector are less than or equal those of the second. */
export function le_s(a: v128, b: v128): v128;
/** Computes which 32-bit unsigned integer lanes of the first 128-bit vector are less than or equal those of the second. */
export function le_u(a: v128, b: v128): v128;
/** Computes which 32-bit signed integer lanes of the first 128-bit vector are greater than those of the second. */
export function gt_s(a: v128, b: v128): v128;
/** Computes which 32-bit unsigned integer lanes of the first 128-bit vector are greater than those of the second. */
export function gt_u(a: v128, b: v128): v128;
/** Computes which 32-bit signed integer lanes of the first 128-bit vector are greater than or equal those of the second. */
export function ge_s(a: v128, b: v128): v128;
/** Computes which 32-bit unsigned integer lanes of the first 128-bit vector are greater than or equal those of the second. */
export function ge_u(a: v128, b: v128): v128;
/** Truncates each 32-bit float lane of a 128-bit vector to a signed integer with saturation. */
export function trunc_s_f32x4_sat(a: v128): v128;
/** Truncates each 32-bit float lane of a 128-bit vector to an unsigned integer with saturation. */
export function trunc_u_f32x4_sat(a: v128): v128;
}
/** Initializes a 128-bit vector from two 64-bit integer values. Arguments must be compile-time constants. */
declare function i64x2(a: i64, b: i64): v128;
declare namespace i64x2 {
/** Creates a 128-bit vector with two identical 64-bit integer lanes. */
export function splat(x: i64): v128;
/** Extracts one 64-bit integer lane from a 128-bit vector as a scalar. */
export function extract_lane(x: v128, idx: u8): i64;
/** Replaces one 64-bit integer lane in a 128-bit vector. */
export function replace_lane(x: v128, idx: u8, value: i64): v128;
/** Adds each 64-bit integer lane of two 128-bit vectors. */
export function add(a: v128, b: v128): v128;
/** Subtracts each 64-bit integer lane of two 128-bit vectors. */
export function sub(a: v128, b: v128): v128;
/** Multiplies each 64-bit integer lane of two 128-bit vectors. */
export function mul(a: v128, b: v128): v128;
/** Negates each 64-bit integer lane of a 128-bit vector. */
export function neg(a: v128): v128;
/** Performs a bitwise left shift on each 64-bit integer lane of a 128-bit vector by a scalar. */
export function shl(a: v128, b: i32): v128;
/** Performs a bitwise arithmetic right shift on each 64-bit integer lane of a 128-bit vector by a scalar. */
export function shr_s(a: v128, b: i32): v128;
/** Performs a bitwise logical right shift on each 64-bit integer lane of a 128-bit vector by a scalar. */
export function shr_u(a: v128, b: i32): v128;
/** Reduces a 128-bit vector to a scalar indicating whether any 64-bit integer lane is considered `true`. */
export function any_true(a: v128): bool;
/** Reduces a 128-bit vector to a scalar indicating whether all 64-bit integer lanes are considered `true`. */
export function all_true(a: v128): bool;
/** Truncates each 64-bit float lane of a 128-bit vector to a signed integer with saturation. */
export function trunc_s_f64x2_sat(a: v128): v128;
/** Truncates each 64-bit float lane of a 128-bit vector to an unsigned integer with saturation. */
export function trunc_u_f64x2_sat(a: v128): v128;
}
/** Initializes a 128-bit vector from four 32-bit float values. Arguments must be compile-time constants. */
declare function f32x4(a: f32, b: f32, c: f32, d: f32): v128;
declare namespace f32x4 {
/** Creates a 128-bit vector with four identical 32-bit float lanes. */
export function splat(x: f32): v128;
/** Extracts one 32-bit float lane from a 128-bit vector as a scalar. */
export function extract_lane(x: v128, idx: u8): f32;
/** Replaces one 32-bit float lane in a 128-bit vector. */
export function replace_lane(x: v128, idx: u8, value: f32): v128;
/** Adds each 32-bit float lane of two 128-bit vectors. */
export function add(a: v128, b: v128): v128;
/** Subtracts each 32-bit float lane of two 128-bit vectors. */
export function sub(a: v128, b: v128): v128;
/** Multiplies each 32-bit float lane of two 128-bit vectors. */
export function mul(a: v128, b: v128): v128;
/** Divides each 32-bit float lane of two 128-bit vectors. */
export function div(a: v128, b: v128): v128;
/** Negates each 32-bit float lane of a 128-bit vector. */
export function neg(a: v128): v128;
/** Computes the minimum of each 32-bit float lane of two 128-bit vectors. */
export function min(a: v128, b: v128): v128;
/** Computes the maximum of each 32-bit float lane of two 128-bit vectors. */
export function max(a: v128, b: v128): v128;
/** Computes the absolute value of each 32-bit float lane of a 128-bit vector. */
export function abs(a: v128): v128;
/** Computes the square root of each 32-bit float lane of a 128-bit vector. */
export function sqrt(a: v128): v128;
/** Computes which 32-bit float lanes of two 128-bit vectors are equal. */
export function eq(a: v128, b: v128): v128;
/** Computes which 32-bit float lanes of two 128-bit vectors are not equal. */
export function ne(a: v128, b: v128): v128;
/** Computes which 32-bit float lanes of the first 128-bit vector are less than those of the second. */
export function lt(a: v128, b: v128): v128;
/** Computes which 32-bit float lanes of the first 128-bit vector are less than or equal those of the second. */
export function le(a: v128, b: v128): v128;
/** Computes which 32-bit float lanes of the first 128-bit vector are greater than those of the second. */
export function gt(a: v128, b: v128): v128;
/** Computes which 32-bit float lanes of the first 128-bit vector are greater than or equal those of the second. */
export function ge(a: v128, b: v128): v128;
/** Converts each 32-bit signed integer lane of a 128-bit vector to floating point. */
export function convert_s_i32x4(a: v128): v128;
/** Converts each 32-bit unsigned integer lane of a 128-bit vector to floating point. */
export function convert_u_i32x4(a: v128): v128;
}
/** Initializes a 128-bit vector from two 64-bit float values. Arguments must be compile-time constants. */
declare function f64x2(a: f64, b: f64): v128;
declare namespace f64x2 {
/** Creates a 128-bit vector with two identical 64-bit float lanes. */
export function splat(x: f64): v128;
/** Extracts one 64-bit float lane from a 128-bit vector as a scalar. */
export function extract_lane(x: v128, idx: u8): f64;
/** Replaces one 64-bit float lane in a 128-bit vector. */
export function replace_lane(x: v128, idx: u8, value: f64): v128;
/** Adds each 64-bit float lane of two 128-bit vectors. */
export function add(a: v128, b: v128): v128;
/** Subtracts each 64-bit float lane of two 128-bit vectors. */
export function sub(a: v128, b: v128): v128;
/** Multiplies each 64-bit float lane of two 128-bit vectors. */
export function mul(a: v128, b: v128): v128;
/** Divides each 64-bit float lane of two 128-bit vectors. */
export function div(a: v128, b: v128): v128;
/** Negates each 64-bit float lane of a 128-bit vector. */
export function neg(a: v128): v128;
/** Computes the minimum of each 64-bit float lane of two 128-bit vectors. */
export function min(a: v128, b: v128): v128;
/** Computes the maximum of each 64-bit float lane of two 128-bit vectors. */
export function max(a: v128, b: v128): v128;
/** Computes the absolute value of each 64-bit float lane of a 128-bit vector. */
export function abs(a: v128): v128;
/** Computes the square root of each 64-bit float lane of a 128-bit vector. */
export function sqrt(a: v128): v128;
/** Computes which 64-bit float lanes of two 128-bit vectors are equal. */
export function eq(a: v128, b: v128): v128;
/** Computes which 64-bit float lanes of two 128-bit vectors are not equal. */
export function ne(a: v128, b: v128): v128;
/** Computes which 64-bit float lanes of the first 128-bit vector are less than those of the second. */
export function lt(a: v128, b: v128): v128;
/** Computes which 64-bit float lanes of the first 128-bit vector are less than or equal those of the second. */
export function le(a: v128, b: v128): v128;
/** Computes which 64-bit float lanes of the first 128-bit vector are greater than those of the second. */
export function gt(a: v128, b: v128): v128;
/** Computes which 64-bit float lanes of the first 128-bit vector are greater than or equal those of the second. */
export function ge(a: v128, b: v128): v128;
/** Converts each 64-bit signed integer lane of a 128-bit vector to floating point. */
export function convert_s_i64x2(a: v128): v128;
/** Converts each 64-bit unsigned integer lane of a 128-bit vector to floating point. */
export function convert_u_i64x2(a: v128): v128;
}
declare namespace v8x16 {
/** Selects 8-bit lanes from either 128-bit vector according to the specified lane indexes. */
export function shuffle(a: v128, b: v128, l0: u8, l1: u8, l2: u8, l3: u8, l4: u8, l5: u8, l6: u8, l7: u8, l8: u8, l9: u8, l10: u8, l11: u8, l12: u8, l13: u8, l14: u8, l15: u8): v128;
}
/** Macro type evaluating to the underlying native WebAssembly type. */
declare type native<T> = T;
@ -398,7 +722,7 @@ declare class _Float {
static isSafeInteger(value: f32 | f64): bool;
/** Returns true if the value passed is an integer, false otherwise. */
static isInteger(value: f32 | f64): bool;
/** Converts A string to an integer. */
/** Converts a string to an integer. */
static parseInt(value: string, radix?: i32): f32 | f64;
/** Converts a string to a floating-point number. */
static parseFloat(value: string): f32 | f64;

View File

@ -1,6 +1,7 @@
const fs = require("fs");
const path = require("path");
const os = require("os");
const v8 = require("v8");
const glob = require("glob");
const colorsUtil = require("../cli/util/colors");
const optionsUtil = require("../cli/util/options");
@ -48,6 +49,9 @@ if (args.help) {
process.exit(0);
}
const features = process.env.ASC_FEATURES ? process.env.ASC_FEATURES.split(",") : [];
const featuresConfig = require("./features.json");
var successes = 0;
var failedTests = [];
var failedInstantiates = new Map();
@ -89,6 +93,40 @@ tests.forEach(filename => {
const stderr = asc.createMemoryStream(chunk => process.stderr.write(chunk.toString().replace(/^(?!$)/mg, " ")));
stderr.isTTY = true;
const configPath = path.join(basedir, basename + ".json");
const config = fs.existsSync(configPath)
? require(configPath)
: {};
var asc_flags = [];
var v8_flags = "";
var v8_no_flags = "";
var missing_features = [];
if (config.features) {
config.features.forEach(feature => {
if (!features.includes(feature)) missing_features.push(feature);
var featureConfig = featuresConfig[feature];
if (featureConfig.asc_flags) {
featureConfig.asc_flags.forEach(flag => {
Array.prototype.push.apply(asc_flags, flag.split(" "));
});
}
if (featureConfig.v8_flags) {
featureConfig.v8_flags.forEach(flag => {
if (v8_flags) v8_flags += " ";
v8_flags += flag;
if (v8_no_flags) v8_no_flags += " ";
v8_no_flags += "--no-" + flag.substring(2);
});
v8.setFlagsFromString(v8_flags);
}
});
if (missing_features.length) {
console.log("- " + colorsUtil.yellow("feature SKIPPED") + " (" + missing_features.join(", ") + ")\n");
return;
}
}
var failed = false;
// TODO: also save stdout/stderr and diff it (-> expected failures)
@ -102,6 +140,8 @@ tests.forEach(filename => {
"--debug",
"--textFile" // -> stdout
];
if (asc_flags)
Array.prototype.push.apply(cmd, asc_flags);
if (args.createBinary)
cmd.push("--binaryFile", basename + ".untouched.wasm");
asc.main(cmd, {
@ -167,6 +207,8 @@ tests.forEach(filename => {
"--binaryFile", // -> stdout
"-O3"
];
if (asc_flags)
Array.prototype.push.apply(cmd, asc_flags);
if (args.create)
cmd.push("--textFile", basename + ".optimized.wat");
asc.main(cmd, {
@ -261,6 +303,7 @@ tests.forEach(filename => {
console.log();
});
});
if (v8_no_flags) v8.setFlagsFromString(v8_no_flags);
});
if (failedTests.length) {

View File

@ -5,3 +5,6 @@ ASC_OPTIMIZE_LEVEL;
ASC_SHRINK_LEVEL;
ASC_FEATURE_MUTABLE_GLOBAL;
ASC_FEATURE_SIGN_EXTENSION;
ASC_FEATURE_BULK_MEMORY;
ASC_FEATURE_SIMD;
ASC_FEATURE_THREADS;

View File

@ -10,6 +10,9 @@
(global $~lib/ASC_SHRINK_LEVEL i32 (i32.const 0))
(global $~lib/ASC_FEATURE_MUTABLE_GLOBAL i32 (i32.const 0))
(global $~lib/ASC_FEATURE_SIGN_EXTENSION i32 (i32.const 0))
(global $~lib/ASC_FEATURE_BULK_MEMORY i32 (i32.const 0))
(global $~lib/ASC_FEATURE_SIMD i32 (i32.const 0))
(global $~lib/ASC_FEATURE_THREADS i32 (i32.const 0))
(global $~lib/memory/HEAP_BASE i32 (i32.const 8))
(export "memory" (memory $0))
(export "table" (table $0))
@ -29,6 +32,12 @@
drop
i32.const 0
drop
i32.const 0
drop
i32.const 0
drop
i32.const 0
drop
)
(func $start (; 1 ;) (type $_)
call $start:asc-constants

5
tests/compiler/simd.json Normal file
View File

@ -0,0 +1,5 @@
{
"features": [
"simd"
]
}

View File

@ -0,0 +1,21 @@
(module
(type $_ (func))
(memory $0 1)
(data (i32.const 8) "\07\00\00\00s\00i\00m\00d\00.\00t\00s")
(table $0 1 funcref)
(elem (i32.const 0) $null)
(global $~lib/allocator/arena/startOffset (mut i32) (i32.const 0))
(global $~lib/allocator/arena/offset (mut i32) (i32.const 0))
(export "memory" (memory $0))
(export "table" (table $0))
(start $start)
(func $start (; 0 ;) (type $_)
i32.const 32
global.set $~lib/allocator/arena/startOffset
global.get $~lib/allocator/arena/startOffset
global.set $~lib/allocator/arena/offset
)
(func $null (; 1 ;) (type $_)
nop
)
)

424
tests/compiler/simd.ts Normal file
View File

@ -0,0 +1,424 @@
// hint: asc tests/compiler/simd --enable simd --validate
import "allocator/arena";
function test_v128(): void {
// equality and inequality
assert(
v128(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
== // i8x16.all_true(i8x16.eq(lhs, rhs))
v128(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
);
assert(
v128(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
!= // i8x16.any_true(i8x16.ne(lhs, rhs))
v128(2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
);
// bitwise
assert(
v128.and(
v128(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
v128(1, 1, 1, 1, 1, 1, 1, 1, 1, 1 , 1 , 1 , 1 , 1 , 1 , 1)
) ==
v128(1, 0, 1, 0, 1, 0, 1, 0, 1, 0 , 1 , 0 , 1 , 0 , 1 , 0)
);
assert(
v128.or(
v128(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
v128(1, 1, 1, 1, 1, 1, 1, 1, 1, 1 , 1 , 1 , 1 , 1 , 1 , 1)
) ==
v128(1, 3, 3, 5, 5, 7, 7, 9, 9, 11, 11, 13, 13, 15, 15, 17)
);
assert(
v128.xor(
v128(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
v128(1, 1, 1, 1, 1, 1, 1, 1, 1, 1 , 1 , 1 , 1 , 1 , 1 , 1)
) ==
v128(0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 17)
);
assert(
v128.not(
v128(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
) ==
v128(-2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17)
);
assert(
v128.bitselect(
v128(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
v128(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1),
v128(0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1),
) ==
v128(16, 2, 14, 4, 12, 6, 10, 8, 8, 10, 6, 12, 4, 14, 2, 16),
);
// generic operations are tested by the aliases below already
// FIXME: node/nightly currently fails to validate this. works in node/v8-canary.
// var base = memory.allocate(256);
// v128.store(base, v128.load(base + 16, 32), 64);
}
function test_i8x16(): void {
var a = i8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 127);
assert(a == v128(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 127));
var b = i8x16.splat(1);
assert(b == v128(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1));
var c = i8x16.add(a, b);
assert(c == i8x16(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -128));
assert(i8x16.sub(c, b) == a);
assert(i8x16.mul(c, b) == c);
assert(
i8x16.neg(a)
==
i8x16(-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -127)
);
assert(i8x16.extract_lane_s(c, 0) == 2);
assert(i8x16.extract_lane_s(c, 15) == -128);
assert(i8x16.extract_lane_u(c, 15) == 128);
assert(
i8x16.replace_lane(c, 15, 17)
==
i8x16(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)
);
assert(
v128.shuffle<i8>(a, b, 0, 1, 2, 3, 4, 5, 6, 7, 24, 25, 26, 27, 28, 29, 30, 31)
==
i8x16(1, 2, 3, 4, 5, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1)
);
assert(
i8x16.add_saturate_s(
i8x16(126, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127),
i8x16.splat(2)
) == i8x16.splat(127)
);
assert(
i8x16.add_saturate_u(
i8x16(-2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
i8x16.splat(2)
) == i8x16.splat(-1)
);
assert(
i8x16.sub_saturate_s(
i8x16(-127, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128, -128),
i8x16.splat(2)
) == i8x16.splat(-128)
);
assert(
i8x16.sub_saturate_u(
i8x16(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
i8x16.splat(2)
) == i8x16.splat(0)
);
assert(i8x16.shl(i8x16.splat(1), 1) == i8x16.splat(2));
assert(i8x16.shr_s(i8x16.splat(-2), 1) == i8x16.splat(-1));
assert(i8x16.shr_u(i8x16.splat(-1), 1) == i8x16.splat(127));
assert(i8x16.any_true(i8x16(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) == true);
assert(i8x16.all_true(i8x16.splat(1)) == true);
var one = i8x16.replace_lane(i8x16.splat(0), 0, 1);
var negOne = i8x16.replace_lane(i8x16.splat(0), 0, -1);
var only1st = negOne;
var excl1st = v128.not(negOne);
assert(i8x16.eq(negOne, one) == excl1st);
assert(i8x16.ne(negOne, one) == only1st);
assert(i8x16.lt_s(negOne, one) == only1st);
assert(i8x16.lt_u(one, negOne) == only1st);
assert(i8x16.le_s(one, negOne) == excl1st);
assert(i8x16.le_u(negOne, one) == excl1st);
assert(i8x16.gt_s(one, negOne) == only1st);
assert(i8x16.gt_u(negOne, one) == only1st);
assert(i8x16.ge_s(negOne, one) == excl1st);
assert(i8x16.ge_u(one, negOne) == excl1st);
}
function test_i16x8(): void {
var a = i16x8(1, 2, 3, 4, 5, 6, 7, 32767);
assert(a == v128(1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, -1, 127));
var b = i16x8.splat(1);
assert(b == v128(1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0));
var c = i16x8.add(a, b);
assert(c == i16x8(2, 3, 4, 5, 6, 7, 8, -32768));
assert(i16x8.sub(c, b) == a);
assert(i16x8.mul(c, b) == c);
assert(
i16x8.neg(a)
==
i16x8(-1, -2, -3, -4, -5, -6, -7, -32767)
);
assert(i16x8.extract_lane_s(c, 0) == 2);
assert(i16x8.extract_lane_s(c, 7) == -32768);
assert(i16x8.extract_lane_u(c, 7) == 32768);
assert(
i16x8.replace_lane(c, 7, 9)
==
i16x8(2, 3, 4, 5, 6, 7, 8, 9)
);
assert(
v128.shuffle<i16>(a, b, 0, 1, 2, 3, 12, 13, 14, 15)
==
i16x8(1, 2, 3, 4, 1, 1, 1, 1)
);
assert(
i16x8.add_saturate_s(
i16x8(32766, 32767, 32767, 32767, 32767, 32767, 32767, 32767),
i16x8.splat(2)
) == i16x8.splat(32767)
);
assert(
i16x8.add_saturate_u(
i16x8(-2, -1, -1, -1, -1, -1, -1, -1),
i16x8.splat(2)
) == i16x8.splat(-1)
);
assert(
i16x8.sub_saturate_s(
i16x8(-32767, -32768, -32768, -32768, -32768, -32768, -32768, -32768),
i16x8.splat(2)
) == i16x8.splat(-32768)
);
assert(
i16x8.sub_saturate_u(
i16x8(1, 0, 0, 0, 0, 0, 0, 0),
i16x8.splat(2)
) == i16x8.splat(0)
);
assert(i16x8.shl(i16x8.splat(1), 1) == i16x8.splat(2));
assert(i16x8.shr_s(i16x8.splat(-2), 1) == i16x8.splat(-1));
assert(i16x8.shr_u(i16x8.splat(-1), 1) == i16x8.splat(32767));
assert(i16x8.any_true(i16x8(1, 0, 0, 0, 0, 0, 0, 0)) == true);
assert(i16x8.all_true(i16x8.splat(1)) == true);
var one = i16x8.replace_lane(i16x8.splat(0), 0, 1);
var negOne = i16x8.replace_lane(i16x8.splat(0), 0, -1);
var only1st = negOne;
var excl1st = v128.not(negOne);
assert(i16x8.eq(negOne, one) == excl1st);
assert(i16x8.ne(negOne, one) == only1st);
assert(i16x8.lt_s(negOne, one) == only1st);
assert(i16x8.lt_u(one, negOne) == only1st);
assert(i16x8.le_s(one, negOne) == excl1st);
assert(i16x8.le_u(negOne, one) == excl1st);
assert(i16x8.gt_s(one, negOne) == only1st);
assert(i16x8.gt_u(negOne, one) == only1st);
assert(i16x8.ge_s(negOne, one) == excl1st);
assert(i16x8.ge_u(one, negOne) == excl1st);
}
function test_i32x4(): void {
var a = i32x4(1, 2, 3, 2147483647);
assert(a == v128(1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, -1, -1, -1, 127));
var b = i32x4.splat(1);
assert(b == v128(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0));
var c = i32x4.add(a, b);
assert(c == i32x4(2, 3, 4, -2147483648));
assert(i32x4.sub(c, b) == a);
assert(i32x4.mul(c, b) == c);
assert(
i32x4.neg(a)
==
i32x4(-1, -2, -3, -2147483647)
);
assert(i32x4.extract_lane(c, 0) == 2);
assert(i32x4.extract_lane(c, 3) == -2147483648);
assert(
i32x4.replace_lane(c, 3, 5)
==
i32x4(2, 3, 4, 5)
);
assert(
v128.shuffle<i32>(a, b, 0, 1, 6, 7)
==
i32x4(1, 2, 1, 1)
);
assert(i32x4.shl(i32x4.splat(1), 1) == i32x4.splat(2));
assert(i32x4.shr_s(i32x4.splat(-2), 1) == i32x4.splat(-1));
assert(i32x4.shr_u(i32x4.splat(-1), 1) == i32x4.splat(2147483647));
assert(i32x4.any_true(i32x4(1, 0, 0, 0)) == true);
assert(i32x4.all_true(i32x4.splat(1)) == true);
var one = i32x4.replace_lane(i32x4.splat(0), 0, 1);
var negOne = i32x4.replace_lane(i32x4.splat(0), 0, -1);
var only1st = negOne;
var excl1st = v128.not(negOne);
assert(i32x4.eq(negOne, one) == excl1st);
assert(i32x4.ne(negOne, one) == only1st);
assert(i32x4.lt_s(negOne, one) == only1st);
assert(i32x4.lt_u(one, negOne) == only1st);
assert(i32x4.le_s(one, negOne) == excl1st);
assert(i32x4.le_u(negOne, one) == excl1st);
assert(i32x4.gt_s(one, negOne) == only1st);
assert(i32x4.gt_u(negOne, one) == only1st);
assert(i32x4.ge_s(negOne, one) == excl1st);
assert(i32x4.ge_u(one, negOne) == excl1st);
assert(
i32x4.trunc_s_f32x4_sat(f32x4.splat(-1.5))
==
i32x4.splat(-1)
);
assert(
i32x4.trunc_u_f32x4_sat(f32x4.splat(-1.5))
==
i32x4.splat(0)
);
}
function test_i64x2(): void {
var a = i64x2(1, 9223372036854775807);
assert(a == v128(1, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, 127));
var b = i64x2.splat(1);
assert(b == v128(1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0));
var c = i64x2.add(a, b);
assert(c == i64x2(2, -9223372036854775808));
assert(i64x2.sub(c, b) == a);
assert(
i64x2.neg(a)
==
i64x2(-1, -9223372036854775807)
);
assert(i64x2.extract_lane(c, 0) == 2);
assert(i64x2.extract_lane(c, 1) == -9223372036854775808);
assert(
i64x2.replace_lane(c, 1, 3)
==
i64x2(2, 3)
);
assert(
v128.shuffle<i64>(a, b, 0, 3)
==
i64x2(1, 1)
);
assert(i64x2.shl(i64x2.splat(1), 1) == i64x2.splat(2));
assert(i64x2.shr_s(i64x2.splat(-2), 1) == i64x2.splat(-1));
assert(i64x2.shr_u(i64x2.splat(-1), 1) == i64x2.splat(9223372036854775807));
assert(i64x2.any_true(i64x2(1, 0)) == true);
assert(i64x2.all_true(i64x2.splat(1)) == true);
assert(
i64x2.trunc_s_f64x2_sat(f64x2.splat(-1.5))
==
i64x2.splat(-1)
);
assert(
i64x2.trunc_u_f64x2_sat(f64x2.splat(-1.5))
==
i64x2.splat(0)
);
}
function test_f32x4(): void {
var a = f32x4(1.5, 2.5, 3.5, 4.5);
assert(a == v128(0, 0, -64, 63, 0, 0, 32, 64, 0, 0, 96, 64, 0, 0, -112, 64));
var b = f32x4.splat(1.0);
assert(b == v128(0, 0, -128, 63, 0, 0, -128, 63, 0, 0, -128, 63, 0, 0, -128, 63));
var c = f32x4.add(a, b);
assert(c == f32x4(2.5, 3.5, 4.5, 5.5));
assert(f32x4.sub(c, b) == a);
assert(f32x4.mul(c, b) == c);
var d = f32x4.mul(a, a);
assert(f32x4.div(d, a) == a);
assert(f32x4.mul(d, a) != a);
assert(f32x4.neg(a) == f32x4(-1.5, -2.5, -3.5, -4.5));
assert(f32x4.extract_lane(c, 0) == 2.5);
assert(f32x4.extract_lane(c, 3) == 5.5);
assert(
f32x4.replace_lane(c, 3, 6.5)
==
f32x4(2.5, 3.5, 4.5, 6.5)
);
assert(
v128.shuffle<f32>(a, b, 0, 1, 6, 7)
==
f32x4(1.5, 2.5, 1.0, 1.0)
);
var one = f32x4.replace_lane(f32x4.splat(0), 0, 1);
var negOne = f32x4.replace_lane(f32x4.splat(0), 0, -1);
var only1st = i32x4(-1, 0, 0, 0);
var excl1st = i32x4(0, -1, -1, -1);
assert(f32x4.eq(negOne, one) == excl1st);
assert(f32x4.ne(negOne, one) == only1st);
assert(f32x4.lt(negOne, one) == only1st);
assert(f32x4.le(one, negOne) == excl1st);
assert(f32x4.gt(one, negOne) == only1st);
assert(f32x4.ge(negOne, one) == excl1st);
assert(f32x4.min(negOne, one) == negOne);
assert(f32x4.max(negOne, one) == one);
assert(f32x4.abs(negOne) == one);
assert(f32x4.sqrt(f32x4(4.0, 9.0, 16.0, 25.0)) == f32x4(2.0, 3.0, 4.0, 5.0));
assert(
f32x4.convert_s_i32x4(i32x4.splat(-1))
==
f32x4.splat(-1.0)
);
assert(
f32x4.convert_u_i32x4(i32x4.splat(-1))
==
f32x4.splat(4294967296.0)
);
}
function test_f64x2(): void {
var a = f64x2(1.5, 2.5);
assert(a == v128(0, 0, 0, 0, 0, 0, -8, 63, 0, 0, 0, 0, 0, 0, 4, 64));
var b = f64x2.splat(1.0);
assert(b == v128(0, 0, 0, 0, 0, 0, -16, 63, 0, 0, 0, 0, 0, 0, -16, 63));
var c = f64x2.add(a, b);
assert(c == f64x2(2.5, 3.5));
assert(f64x2.sub(c, b) == a);
assert(f64x2.mul(c, b) == c);
var d = f64x2.mul(a, a);
assert(f64x2.div(d, a) == a);
assert(f64x2.mul(d, a) != a);
assert(f64x2.neg(a) == f64x2(-1.5, -2.5));
assert(f64x2.extract_lane(c, 0) == 2.5);
assert(f64x2.extract_lane(c, 1) == 3.5);
assert(
f64x2.replace_lane(c, 1, 4.5)
==
f64x2(2.5, 4.5)
);
assert(
v128.shuffle<f64>(a, b, 0, 3)
==
f64x2(1.5, 1.0)
);
var one = f64x2.replace_lane(f64x2.splat(0), 0, 1);
var negOne = f64x2.replace_lane(f64x2.splat(0), 0, -1);
var only1st = i64x2(-1, 0);
var excl1st = i64x2(0, -1);
assert(f64x2.eq(negOne, one) == excl1st);
assert(f64x2.ne(negOne, one) == only1st);
assert(f64x2.lt(negOne, one) == only1st);
assert(f64x2.le(one, negOne) == excl1st);
assert(f64x2.gt(one, negOne) == only1st);
assert(f64x2.ge(negOne, one) == excl1st);
assert(f64x2.min(negOne, one) == negOne);
assert(f64x2.max(negOne, one) == one);
assert(f64x2.abs(negOne) == one);
assert(f64x2.sqrt(f64x2(4.0, 9.0)) == f64x2(2.0, 3.0));
assert(
f64x2.convert_s_i64x2(i64x2.splat(-1))
==
f64x2.splat(-1.0)
);
assert(
f64x2.convert_u_i64x2(i64x2.splat(-1))
==
f64x2.splat(18446744073709551615.0)
);
}
function test_v8x16(): void {
var a = v128( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
var b = v128(16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31);
assert(
v8x16.shuffle(a, b, 0, 17, 2, 19, 4, 21, 6, 23, 8, 25, 10, 27, 12, 29, 14, 31)
==
v128(0, 17, 2, 19, 4, 21, 6, 23, 8, 25, 10, 27, 12, 29, 14, 31)
);
}
if (ASC_FEATURE_SIMD) {
test_v128();
test_i8x16();
test_i16x8();
test_i32x4();
test_i64x2();
test_f32x4();
test_f64x2();
test_v8x16();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
(module
(type $_ (func))
(memory $0 0)
(table $0 1 funcref)
(elem (i32.const 0) $null)
(export "memory" (memory $0))
(export "table" (table $0))
(func $null (; 0 ;) (type $_)
nop
)
)

View File

@ -0,0 +1,31 @@
// hint: asc tests/compiler/std/simd --enable simd --validate
@sealed
class I8x16 {
@inline static from(vec: v128): I8x16 {
return changetype<I8x16>(vec);
}
// TODO: not possible due to arguments becoming locals, no longer being compile-time constants
// @inline constructor(
// a: i8, b: i8, c: i8, d: i8, e: i8, f: i8, g: i8, h: i8, i: i8, j: i8, k: i8, l: i8, m: i8, n: i8, o: i8, p: i8
// ) {
// return changetype<I8x16>(i8x16(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p));
// }
private constructor() { unreachable(); }
@inline @operator("+")
add(vec: I8x16): I8x16 {
return changetype<I8x16>(v128.add<i8>(changetype<v128>(this), changetype<v128>(vec)));
}
}
function test_I8x16(): void {
var a = I8x16.from(i8x16(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16));
var c = a + a;
}
if (ASC_FEATURE_SIMD) {
test_I8x16();
}

View File

@ -0,0 +1,12 @@
(module
(type $_ (func))
(memory $0 0)
(table $0 1 funcref)
(elem (i32.const 0) $null)
(global $~lib/ASC_FEATURE_SIMD i32 (i32.const 0))
(global $~lib/memory/HEAP_BASE i32 (i32.const 8))
(export "memory" (memory $0))
(export "table" (table $0))
(func $null (; 0 ;) (type $_)
)
)

10
tests/features.json Normal file
View File

@ -0,0 +1,10 @@
{
"simd": {
"asc_flags": [
"--enable simd"
],
"v8_flags": [
"--experimental-wasm-simd"
]
}
}