Skip to content

Add new min/max/dot SIMD instructions #952

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"url": "https://github.com/AssemblyScript/assemblyscript/issues"
},
"dependencies": {
"binaryen": "89.0.0-nightly.20191012",
"binaryen": "89.0.0-nightly.20191113",
"long": "^4.0.0",
"source-map-support": "^0.5.16",
"ts-node": "^6.2.0",
Expand Down
78 changes: 78 additions & 0 deletions src/builtins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ export namespace BuiltinSymbols {
export const v128_all_true = "~lib/builtins/v128.all_true";
export const v128_min = "~lib/builtins/v128.min";
export const v128_max = "~lib/builtins/v128.max";
export const v128_dot = "~lib/builtins/v128.dot";
export const v128_abs = "~lib/builtins/v128.abs";
export const v128_sqrt = "~lib/builtins/v128.sqrt";
export const v128_eq = "~lib/builtins/v128.eq";
Expand Down Expand Up @@ -353,6 +354,10 @@ export namespace BuiltinSymbols {
export const i8x16_add = "~lib/builtins/i8x16.add";
export const i8x16_sub = "~lib/builtins/i8x16.sub";
export const i8x16_mul = "~lib/builtins/i8x16.mul";
export const i8x16_min_s = "~lib/builtins/i8x16.min_s";
export const i8x16_min_u = "~lib/builtins/i8x16.min_u";
export const i8x16_max_s = "~lib/builtins/i8x16.max_s";
export const i8x16_max_u = "~lib/builtins/i8x16.max_u";
export const i8x16_neg = "~lib/builtins/i8x16.neg";
export const i8x16_add_saturate_s = "~lib/builtins/i8x16.add_saturate_s";
export const i8x16_add_saturate_u = "~lib/builtins/i8x16.add_saturate_u";
Expand Down Expand Up @@ -383,6 +388,10 @@ export namespace BuiltinSymbols {
export const i16x8_add = "~lib/builtins/i16x8.add";
export const i16x8_sub = "~lib/builtins/i16x8.sub";
export const i16x8_mul = "~lib/builtins/i16x8.mul";
export const i16x8_min_s = "~lib/builtins/i16x8.min_s";
export const i16x8_min_u = "~lib/builtins/i16x8.min_u";
export const i16x8_max_s = "~lib/builtins/i16x8.max_s";
export const i16x8_max_u = "~lib/builtins/i16x8.max_u";
export const i16x8_neg = "~lib/builtins/i16x8.neg";
export const i16x8_add_saturate_s = "~lib/builtins/i16x8.add_saturate_s";
export const i16x8_add_saturate_u = "~lib/builtins/i16x8.add_saturate_u";
Expand Down Expand Up @@ -418,6 +427,11 @@ export namespace BuiltinSymbols {
export const i32x4_add = "~lib/builtins/i32x4.add";
export const i32x4_sub = "~lib/builtins/i32x4.sub";
export const i32x4_mul = "~lib/builtins/i32x4.mul";
export const i32x4_min_s = "~lib/builtins/i32x4.min_s";
export const i32x4_min_u = "~lib/builtins/i32x4.min_u";
export const i32x4_max_s = "~lib/builtins/i32x4.max_s";
export const i32x4_max_u = "~lib/builtins/i32x4.max_u";
export const i32x4_dot_i16x8_s = "~lib/builtins/i32x4.dot_i16x8_s";
export const i32x4_neg = "~lib/builtins/i32x4.neg";
export const i32x4_shl = "~lib/builtins/i32x4.shl";
export const i32x4_shr_s = "~lib/builtins/i32x4.shr_s";
Expand Down Expand Up @@ -3332,6 +3346,20 @@ export function compileCall(
let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.CONV_IMPLICIT);
if (!type.is(TypeFlags.REFERENCE)) {
switch (type.kind) {
case TypeKind.I8: return module.binary(BinaryOp.MinI8x16, arg0, arg1);
case TypeKind.U8: return module.binary(BinaryOp.MinU8x16, arg0, arg1);
case TypeKind.I16: return module.binary(BinaryOp.MinI16x8, arg0, arg1);
case TypeKind.U16: return module.binary(BinaryOp.MinU16x8, arg0, arg1);
case TypeKind.ISIZE: {
if (compiler.options.isWasm64) break;
// fall-through
}
case TypeKind.I32: return module.binary(BinaryOp.MinI32x4, arg0, arg1);
case TypeKind.USIZE: {
if (compiler.options.isWasm64) break;
// fall-through
}
case TypeKind.U32: return module.binary(BinaryOp.MinU32x4, arg0, arg1);
case TypeKind.F32: return module.binary(BinaryOp.MinF32x4, arg0, arg1);
case TypeKind.F64: return module.binary(BinaryOp.MinF64x2, arg0, arg1);
}
Expand All @@ -3356,6 +3384,20 @@ export function compileCall(
let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.CONV_IMPLICIT);
if (!type.is(TypeFlags.REFERENCE)) {
switch (type.kind) {
case TypeKind.I8: return module.binary(BinaryOp.MaxI8x16, arg0, arg1);
case TypeKind.U8: return module.binary(BinaryOp.MaxU8x16, arg0, arg1);
case TypeKind.I16: return module.binary(BinaryOp.MaxI16x8, arg0, arg1);
case TypeKind.U16: return module.binary(BinaryOp.MaxU16x8, arg0, arg1);
case TypeKind.ISIZE: {
if (compiler.options.isWasm64) break;
// fall-through
}
case TypeKind.I32: return module.binary(BinaryOp.MaxI32x4, arg0, arg1);
case TypeKind.USIZE: {
if (compiler.options.isWasm64) break;
// fall-through
}
case TypeKind.U32: return module.binary(BinaryOp.MaxU32x4, arg0, arg1);
case TypeKind.F32: return module.binary(BinaryOp.MaxF32x4, arg0, arg1);
case TypeKind.F64: return module.binary(BinaryOp.MaxF64x2, arg0, arg1);
}
Expand All @@ -3366,6 +3408,29 @@ export function compileCall(
);
return module.unreachable();
}
case BuiltinSymbols.v128_dot: { // dot<T!>(a: v128, b: v128) -> v128
if (
checkFeatureEnabled(Feature.SIMD, reportNode, compiler) |
checkTypeRequired(typeArguments, reportNode, compiler) |
checkArgsRequired(operands, 2, reportNode, compiler)
) {
compiler.currentType = Type.v128;
return module.unreachable();
}
let type = typeArguments![0];
let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.CONV_IMPLICIT);
let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.CONV_IMPLICIT);
if (!type.is(TypeFlags.REFERENCE)) {
switch (type.kind) {
case TypeKind.I16: return module.binary(BinaryOp.DotI16x8, arg0, arg1);
}
}
compiler.error(
DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,
reportNode.typeArgumentsRange, "v128.dot", type.toString()
);
return module.unreachable();
}
case BuiltinSymbols.v128_eq: { // eq<T!>(a: v128, b: v128) -> v128
if (
checkFeatureEnabled(Feature.SIMD, reportNode, compiler) |
Expand Down Expand Up @@ -4501,6 +4566,10 @@ function tryDeferASM(
case BuiltinSymbols.i8x16_add: return deferASM(BuiltinSymbols.v128_add, compiler, Type.i8, operands, Type.v128, reportNode);
case BuiltinSymbols.i8x16_sub: return deferASM(BuiltinSymbols.v128_sub, compiler, Type.i8, operands, Type.v128, reportNode);
case BuiltinSymbols.i8x16_mul: return deferASM(BuiltinSymbols.v128_mul, compiler, Type.i8, operands, Type.v128, reportNode);
case BuiltinSymbols.i8x16_min_s: return deferASM(BuiltinSymbols.v128_min, compiler, Type.i8, operands, Type.v128, reportNode);
case BuiltinSymbols.i8x16_min_u: return deferASM(BuiltinSymbols.v128_min, compiler, Type.u8, operands, Type.v128, reportNode);
case BuiltinSymbols.i8x16_max_s: return deferASM(BuiltinSymbols.v128_max, compiler, Type.i8, operands, Type.v128, reportNode);
case BuiltinSymbols.i8x16_max_u: return deferASM(BuiltinSymbols.v128_max, compiler, Type.u8, operands, Type.v128, reportNode);
case BuiltinSymbols.i8x16_neg: return deferASM(BuiltinSymbols.v128_neg, compiler, Type.i8, operands, Type.v128, reportNode);
case BuiltinSymbols.i8x16_add_saturate_s: return deferASM(BuiltinSymbols.v128_add_saturate, compiler, Type.i8, operands, Type.v128, reportNode);
case BuiltinSymbols.i8x16_add_saturate_u: return deferASM(BuiltinSymbols.v128_add_saturate, compiler, Type.u8, operands, Type.v128, reportNode);
Expand Down Expand Up @@ -4531,6 +4600,10 @@ function tryDeferASM(
case BuiltinSymbols.i16x8_add: return deferASM(BuiltinSymbols.v128_add, compiler, Type.i16, operands, Type.v128, reportNode);
case BuiltinSymbols.i16x8_sub: return deferASM(BuiltinSymbols.v128_sub, compiler, Type.i16, operands, Type.v128, reportNode);
case BuiltinSymbols.i16x8_mul: return deferASM(BuiltinSymbols.v128_mul, compiler, Type.i16, operands, Type.v128, reportNode);
case BuiltinSymbols.i16x8_min_s: return deferASM(BuiltinSymbols.v128_min, compiler, Type.i16, operands, Type.v128, reportNode);
case BuiltinSymbols.i16x8_min_u: return deferASM(BuiltinSymbols.v128_min, compiler, Type.u16, operands, Type.v128, reportNode);
case BuiltinSymbols.i16x8_max_s: return deferASM(BuiltinSymbols.v128_max, compiler, Type.i16, operands, Type.v128, reportNode);
case BuiltinSymbols.i16x8_max_u: return deferASM(BuiltinSymbols.v128_max, compiler, Type.u16, operands, Type.v128, reportNode);
case BuiltinSymbols.i16x8_neg: return deferASM(BuiltinSymbols.v128_neg, compiler, Type.i16, operands, Type.v128, reportNode);
case BuiltinSymbols.i16x8_add_saturate_s: return deferASM(BuiltinSymbols.v128_add_saturate, compiler, Type.i16, operands, Type.v128, reportNode);
case BuiltinSymbols.i16x8_add_saturate_u: return deferASM(BuiltinSymbols.v128_add_saturate, compiler, Type.u16, operands, Type.v128, reportNode);
Expand Down Expand Up @@ -4566,6 +4639,11 @@ function tryDeferASM(
case BuiltinSymbols.i32x4_add: return deferASM(BuiltinSymbols.v128_add, compiler, Type.i32, operands, Type.v128, reportNode);
case BuiltinSymbols.i32x4_sub: return deferASM(BuiltinSymbols.v128_sub, compiler, Type.i32, operands, Type.v128, reportNode);
case BuiltinSymbols.i32x4_mul: return deferASM(BuiltinSymbols.v128_mul, compiler, Type.i32, operands, Type.v128, reportNode);
case BuiltinSymbols.i32x4_min_s: return deferASM(BuiltinSymbols.v128_min, compiler, Type.i32, operands, Type.v128, reportNode);
case BuiltinSymbols.i32x4_min_u: return deferASM(BuiltinSymbols.v128_min, compiler, Type.u32, operands, Type.v128, reportNode);
case BuiltinSymbols.i32x4_max_s: return deferASM(BuiltinSymbols.v128_max, compiler, Type.i32, operands, Type.v128, reportNode);
case BuiltinSymbols.i32x4_max_u: return deferASM(BuiltinSymbols.v128_max, compiler, Type.u32, operands, Type.v128, reportNode);
case BuiltinSymbols.i32x4_dot_i16x8_s: return deferASM(BuiltinSymbols.v128_dot, compiler, Type.i16, operands, Type.v128, reportNode);
case BuiltinSymbols.i32x4_neg: return deferASM(BuiltinSymbols.v128_neg, compiler, Type.i32, operands, Type.v128, reportNode);
case BuiltinSymbols.i32x4_shl: return deferASM(BuiltinSymbols.v128_shl, compiler, Type.i32, operands, Type.v128, reportNode);
case BuiltinSymbols.i32x4_shr_s: return deferASM(BuiltinSymbols.v128_shr, compiler, Type.i32, operands, Type.v128, reportNode);
Expand Down
21 changes: 21 additions & 0 deletions src/glue/binaryen.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ declare function _BinaryenSubVecI8x16(): BinaryenOp;
declare function _BinaryenSubSatSVecI8x16(): BinaryenOp;
declare function _BinaryenSubSatUVecI8x16(): BinaryenOp;
declare function _BinaryenMulVecI8x16(): BinaryenOp;
declare function _BinaryenMinSVecI8x16(): BinaryenOp;
declare function _BinaryenMinUVecI8x16(): BinaryenOp;
declare function _BinaryenMaxSVecI8x16(): BinaryenOp;
declare function _BinaryenMaxUVecI8x16(): BinaryenOp;
declare function _BinaryenNegVecI16x8(): BinaryenOp;
declare function _BinaryenAnyTrueVecI16x8(): BinaryenOp;
declare function _BinaryenAllTrueVecI16x8(): BinaryenOp;
Expand All @@ -344,6 +348,10 @@ declare function _BinaryenSubVecI16x8(): BinaryenOp;
declare function _BinaryenSubSatSVecI16x8(): BinaryenOp;
declare function _BinaryenSubSatUVecI16x8(): BinaryenOp;
declare function _BinaryenMulVecI16x8(): BinaryenOp;
declare function _BinaryenMinSVecI16x8(): BinaryenOp;
declare function _BinaryenMinUVecI16x8(): BinaryenOp;
declare function _BinaryenMaxSVecI16x8(): BinaryenOp;
declare function _BinaryenMaxUVecI16x8(): BinaryenOp;
declare function _BinaryenNegVecI32x4(): BinaryenOp;
declare function _BinaryenAnyTrueVecI32x4(): BinaryenOp;
declare function _BinaryenAllTrueVecI32x4(): BinaryenOp;
Expand All @@ -353,6 +361,11 @@ declare function _BinaryenShrUVecI32x4(): BinaryenOp;
declare function _BinaryenAddVecI32x4(): BinaryenOp;
declare function _BinaryenSubVecI32x4(): BinaryenOp;
declare function _BinaryenMulVecI32x4(): BinaryenOp;
declare function _BinaryenMinSVecI32x4(): BinaryenOp;
declare function _BinaryenMinUVecI32x4(): BinaryenOp;
declare function _BinaryenMaxSVecI32x4(): BinaryenOp;
declare function _BinaryenMaxUVecI32x4(): BinaryenOp;
declare function _BinaryenDotSVecI16x8ToVecI32x4(): BinaryenOp;
declare function _BinaryenNegVecI64x2(): BinaryenOp;
declare function _BinaryenAnyTrueVecI64x2(): BinaryenOp;
declare function _BinaryenAllTrueVecI64x2(): BinaryenOp;
Expand Down Expand Up @@ -650,6 +663,8 @@ declare type BinaryenFunctionRef = usize;
declare function _BinaryenAddFunction(module: BinaryenModuleRef, name: usize, type: BinaryenFunctionTypeRef, varTypes: usize, numVarTypes: BinaryenIndex, body: BinaryenExpressionRef): BinaryenFunctionRef;
declare function _BinaryenGetFunction(module: BinaryenModuleRef, name: usize): BinaryenFunctionRef;
declare function _BinaryenRemoveFunction(module: BinaryenModuleRef, name: usize): void;
declare function _BinaryenGetNumFunctions(module: BinaryenModuleRef): BinaryenIndex;
declare function _BinaryenGetFunctionByIndex(module: BinaryenModuleRef, index: BinaryenIndex): BinaryenFunctionRef;

declare function _BinaryenFunctionGetName(func: BinaryenFunctionRef): usize;
declare function _BinaryenFunctionGetType(func: BinaryenFunctionRef): BinaryenFunctionTypeRef;
Expand Down Expand Up @@ -679,6 +694,8 @@ declare function _BinaryenAddMemoryExport(module: BinaryenModuleRef, internalNam
declare function _BinaryenAddGlobalExport(module: BinaryenModuleRef, internalName: usize, externalName: usize): BinaryenExportRef;
declare function _BinaryenAddEventExport(module: BinaryenModuleRef, internalName: usize, externalName: usize): BinaryenExportRef;
declare function _BinaryenRemoveExport(module: BinaryenModuleRef, externalName: usize): void;
declare function _BinaryenGetNumExports(module: BinaryenModuleRef): BinaryenIndex;
declare function _BinaryenGetExportByIndex(module: BinaryenModuleRef, index: BinaryenIndex): BinaryenExportRef;

declare type BinaryenGlobalRef = usize;

Expand All @@ -700,6 +717,10 @@ declare function _BinaryenEventGetParam(event: BinaryenEventRef, index: Binaryen
declare function _BinaryenSetFunctionTable(module: BinaryenModuleRef, initial: BinaryenIndex, maximum: BinaryenIndex, funcs: usize, numFuncs: BinaryenIndex, offset: BinaryenExpressionRef): void;

declare function _BinaryenSetMemory(module: BinaryenModuleRef, initial: BinaryenIndex, maximum: BinaryenIndex, exportName: usize, segments: usize, segmentPassive: usize, segmentOffsets: usize, segmentSizes: usize, numSegments: BinaryenIndex, shared: bool): void;
declare function _BinaryenGetNumMemorySegments(module: BinaryenModuleRef): BinaryenIndex;
declare function _BinaryenGetMemorySegmentByteOffset(module: BinaryenModuleRef, index: BinaryenIndex): u32;
declare function _BinaryenGetMemorySegmentByteLength(module: BinaryenModuleRef, id: BinaryenIndex): usize;
declare function _BinaryenCopyMemorySegmentData(module: BinaryenModuleRef, id: BinaryenIndex, buffer: usize): void;

declare function _BinaryenSetStart(module: BinaryenModuleRef, start: BinaryenFunctionRef): void;

Expand Down
13 changes: 13 additions & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,16 +333,29 @@ export enum BinaryOp {
SubSatI8x16 = _BinaryenSubSatSVecI8x16(),
SubSatU8x16 = _BinaryenSubSatUVecI8x16(),
MulI8x16 = _BinaryenMulVecI8x16(),
MinI8x16 = _BinaryenMinSVecI8x16(),
MinU8x16 = _BinaryenMinUVecI8x16(),
MaxI8x16 = _BinaryenMaxSVecI8x16(),
MaxU8x16 = _BinaryenMaxUVecI8x16(),
AddI16x8 = _BinaryenAddVecI16x8(),
AddSatI16x8 = _BinaryenAddSatSVecI16x8(),
AddSatU16x8 = _BinaryenAddSatUVecI16x8(),
SubI16x8 = _BinaryenSubVecI16x8(),
SubSatI16x8 = _BinaryenSubSatSVecI16x8(),
SubSatU16x8 = _BinaryenSubSatUVecI16x8(),
MulI16x8 = _BinaryenMulVecI16x8(),
MinI16x8 = _BinaryenMinSVecI16x8(),
MinU16x8 = _BinaryenMinUVecI16x8(),
MaxI16x8 = _BinaryenMaxSVecI16x8(),
MaxU16x8 = _BinaryenMaxUVecI16x8(),
AddI32x4 = _BinaryenAddVecI32x4(),
SubI32x4 = _BinaryenSubVecI32x4(),
MulI32x4 = _BinaryenMulVecI32x4(),
MinI32x4 = _BinaryenMinSVecI32x4(),
MinU32x4 = _BinaryenMinUVecI32x4(),
MaxI32x4 = _BinaryenMaxSVecI32x4(),
MaxU32x4 = _BinaryenMaxUVecI32x4(),
DotI16x8 = _BinaryenDotSVecI16x8ToVecI32x4(),
AddI64x2 = _BinaryenAddVecI64x2(),
SubI64x2 = _BinaryenSubVecI64x2(),
AddF32x4 = _BinaryenAddVecF32x4(),
Expand Down
60 changes: 58 additions & 2 deletions std/assembly/builtins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1091,11 +1091,15 @@ export namespace v128 {

// @ts-ignore: decorator
@builtin
export declare function min<T>(a: v128, b: v128): v128; // f32, f64 only
export declare function min<T>(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function max<T>(a: v128, b: v128): v128; // f32, f64 only
export declare function max<T>(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function dot<T>(a: v128, b: v128): v128; // i16 only

// @ts-ignore: decorator
@builtin
Expand Down Expand Up @@ -1195,6 +1199,22 @@ export namespace i8x16 {
@builtin
export declare function mul(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function min_s(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function min_u(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function max_s(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function max_u(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function neg(a: v128): v128;
Expand Down Expand Up @@ -1318,6 +1338,22 @@ export namespace i16x8 {
@builtin
export declare function mul(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function min_s(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function min_u(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function max_s(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function max_u(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function neg(a: v128): v128;
Expand Down Expand Up @@ -1461,6 +1497,26 @@ export namespace i32x4 {
@builtin
export declare function mul(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function min_s(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function min_u(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function max_s(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function max_u(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function dot_i16x8_s(a: v128, b: v128): v128;

// @ts-ignore: decorator
@builtin
export declare function neg(a: v128): v128;
Expand Down
Loading