Skip to content

Commit 625f87a

Browse files
committed
Add concrete SIMD types
1 parent 98f2986 commit 625f87a

File tree

8 files changed

+395
-98
lines changed

8 files changed

+395
-98
lines changed

src/builtins.ts

Lines changed: 90 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,13 @@ export namespace BuiltinSymbols {
341341
export const v128_qfms = "~lib/builtins/v128.qfms";
342342

343343
export const i8x16 = "~lib/builtins/i8x16";
344+
export const u8x16 = "~lib/builtins/u8x16";
344345
export const i16x8 = "~lib/builtins/i16x8";
346+
export const u16x8 = "~lib/builtins/u16x8";
345347
export const i32x4 = "~lib/builtins/i32x4";
348+
export const u32x4 = "~lib/builtins/u32x4";
346349
export const i64x2 = "~lib/builtins/i64x2";
350+
export const u64x2 = "~lib/builtins/u64x2";
347351
export const f32x4 = "~lib/builtins/f32x4";
348352
export const f64x2 = "~lib/builtins/f64x2";
349353

@@ -597,6 +601,7 @@ export function compileCall(
597601
isAsm: bool = false
598602
): ExpressionRef {
599603
var module = compiler.module;
604+
var alt: bool = false;
600605

601606
switch (prototype.internalName) {
602607

@@ -2544,13 +2549,15 @@ export function compileCall(
25442549
// === SIMD ===================================================================================
25452550

25462551
case BuiltinSymbols.v128: // alias for now
2547-
case BuiltinSymbols.i8x16: {
2552+
case BuiltinSymbols.i8x16: alt = true;
2553+
case BuiltinSymbols.u8x16: {
2554+
let outType = alt ? Type.i8x16 : Type.u8x16;
25482555
if (
25492556
checkFeatureEnabled(Feature.SIMD, reportNode, compiler) |
25502557
checkTypeAbsent(typeArguments, reportNode, prototype) |
25512558
checkArgsRequired(operands, 16, reportNode, compiler)
25522559
) {
2553-
compiler.currentType = Type.v128;
2560+
compiler.currentType = outType;
25542561
return module.unreachable();
25552562
}
25562563
let bytes = new Uint8Array(16);
@@ -2563,23 +2570,25 @@ export function compileCall(
25632570
DiagnosticCode.Expression_must_be_a_compile_time_constant,
25642571
value.range
25652572
);
2566-
compiler.currentType = Type.v128;
2573+
compiler.currentType = outType;
25672574
return module.unreachable();
25682575
}
25692576
assert(getExpressionType(expr) == NativeType.I32);
25702577
writeI8(getConstValueI32(expr), bytes, i);
25712578
}
25722579
}
2573-
compiler.currentType = Type.v128;
2580+
compiler.currentType = outType;
25742581
return module.v128(bytes);
25752582
}
2576-
case BuiltinSymbols.i16x8: {
2583+
case BuiltinSymbols.i16x8: alt = true;
2584+
case BuiltinSymbols.u16x8: {
2585+
let outType = alt ? Type.i16x8 : Type.u16x8;
25772586
if (
25782587
checkFeatureEnabled(Feature.SIMD, reportNode, compiler) |
25792588
checkTypeAbsent(typeArguments, reportNode, prototype) |
25802589
checkArgsRequired(operands, 8, reportNode, compiler)
25812590
) {
2582-
compiler.currentType = Type.v128;
2591+
compiler.currentType = outType;
25832592
return module.unreachable();
25842593
}
25852594
let bytes = new Uint8Array(16);
@@ -2592,23 +2601,25 @@ export function compileCall(
25922601
DiagnosticCode.Expression_must_be_a_compile_time_constant,
25932602
value.range
25942603
);
2595-
compiler.currentType = Type.v128;
2604+
compiler.currentType = outType;
25962605
return module.unreachable();
25972606
}
25982607
assert(getExpressionType(expr) == NativeType.I32);
25992608
writeI16(getConstValueI32(expr), bytes, i << 1);
26002609
}
26012610
}
2602-
compiler.currentType = Type.v128;
2611+
compiler.currentType = outType;
26032612
return module.v128(bytes);
26042613
}
2605-
case BuiltinSymbols.i32x4: {
2614+
case BuiltinSymbols.i32x4: alt = true;
2615+
case BuiltinSymbols.u32x4: {
2616+
let outType = alt ? Type.i32x4 : Type.u32x4;
26062617
if (
26072618
checkFeatureEnabled(Feature.SIMD, reportNode, compiler) |
26082619
checkTypeAbsent(typeArguments, reportNode, prototype) |
26092620
checkArgsRequired(operands, 4, reportNode, compiler)
26102621
) {
2611-
compiler.currentType = Type.v128;
2622+
compiler.currentType = outType;
26122623
return module.unreachable();
26132624
}
26142625
let bytes = new Uint8Array(16);
@@ -2621,23 +2632,25 @@ export function compileCall(
26212632
DiagnosticCode.Expression_must_be_a_compile_time_constant,
26222633
value.range
26232634
);
2624-
compiler.currentType = Type.v128;
2635+
compiler.currentType = outType;
26252636
return module.unreachable();
26262637
}
26272638
assert(getExpressionType(expr) == NativeType.I32);
26282639
writeI32(getConstValueI32(expr), bytes, i << 2);
26292640
}
26302641
}
2631-
compiler.currentType = Type.v128;
2642+
compiler.currentType = outType;
26322643
return module.v128(bytes);
26332644
}
2634-
case BuiltinSymbols.i64x2: {
2645+
case BuiltinSymbols.i64x2: alt = true;
2646+
case BuiltinSymbols.u64x2: {
2647+
let outType = alt ? Type.i64x2 : Type.u64x2;
26352648
if (
26362649
checkFeatureEnabled(Feature.SIMD, reportNode, compiler) |
26372650
checkTypeAbsent(typeArguments, reportNode, prototype) |
26382651
checkArgsRequired(operands, 2, reportNode, compiler)
26392652
) {
2640-
compiler.currentType = Type.v128;
2653+
compiler.currentType = outType;
26412654
return module.unreachable();
26422655
}
26432656
let bytes = new Uint8Array(16);
@@ -2650,7 +2663,7 @@ export function compileCall(
26502663
DiagnosticCode.Expression_must_be_a_compile_time_constant,
26512664
value.range
26522665
);
2653-
compiler.currentType = Type.v128;
2666+
compiler.currentType = outType;
26542667
return module.unreachable();
26552668
}
26562669
assert(getExpressionType(expr) == NativeType.I64);
@@ -2659,7 +2672,7 @@ export function compileCall(
26592672
writeI32(getConstValueI64High(expr), bytes, off + 4);
26602673
}
26612674
}
2662-
compiler.currentType = Type.v128;
2675+
compiler.currentType = outType;
26632676
return module.v128(bytes);
26642677
}
26652678
case BuiltinSymbols.f32x4: {
@@ -2668,7 +2681,7 @@ export function compileCall(
26682681
checkTypeAbsent(typeArguments, reportNode, prototype) |
26692682
checkArgsRequired(operands, 4, reportNode, compiler)
26702683
) {
2671-
compiler.currentType = Type.v128;
2684+
compiler.currentType = Type.f32x4;
26722685
return module.unreachable();
26732686
}
26742687
let bytes = new Uint8Array(16);
@@ -2681,14 +2694,14 @@ export function compileCall(
26812694
DiagnosticCode.Expression_must_be_a_compile_time_constant,
26822695
value.range
26832696
);
2684-
compiler.currentType = Type.v128;
2697+
compiler.currentType = Type.f32x4;
26852698
return module.unreachable();
26862699
}
26872700
assert(getExpressionType(expr) == NativeType.F32);
26882701
writeF32(getConstValueF32(expr), bytes, i << 2);
26892702
}
26902703
}
2691-
compiler.currentType = Type.v128;
2704+
compiler.currentType = Type.f32x4;
26922705
return module.v128(bytes);
26932706
}
26942707
case BuiltinSymbols.f64x2: {
@@ -2697,7 +2710,7 @@ export function compileCall(
26972710
checkTypeAbsent(typeArguments, reportNode, prototype) |
26982711
checkArgsRequired(operands, 2, reportNode, compiler)
26992712
) {
2700-
compiler.currentType = Type.v128;
2713+
compiler.currentType = Type.f64x2;
27012714
return module.unreachable();
27022715
}
27032716
let bytes = new Uint8Array(16);
@@ -2710,14 +2723,14 @@ export function compileCall(
27102723
DiagnosticCode.Expression_must_be_a_compile_time_constant,
27112724
value.range
27122725
);
2713-
compiler.currentType = Type.v128;
2726+
compiler.currentType = Type.f64x2;
27142727
return module.unreachable();
27152728
}
27162729
assert(getExpressionType(expr) == NativeType.F64);
27172730
writeF64(getConstValueF64(expr), bytes, i << 3);
27182731
}
27192732
}
2720-
compiler.currentType = Type.v128;
2733+
compiler.currentType = Type.f64x2;
27212734
return module.v128(bytes);
27222735
}
27232736
case BuiltinSymbols.v128_splat: { // splat<T!>(x: T) -> v128
@@ -2731,30 +2744,67 @@ export function compileCall(
27312744
}
27322745
let type = typeArguments![0];
27332746
let arg0 = compiler.compileExpression(operands[0], type, Constraints.CONV_IMPLICIT);
2734-
compiler.currentType = Type.v128;
27352747
if (!type.is(TypeFlags.REFERENCE)) {
27362748
switch (type.kind) {
2737-
case TypeKind.I8:
2738-
case TypeKind.U8: return module.unary(UnaryOp.SplatI8x16, arg0);
2739-
case TypeKind.I16:
2740-
case TypeKind.U16: return module.unary(UnaryOp.SplatI16x8, arg0);
2741-
case TypeKind.I32:
2742-
case TypeKind.U32: return module.unary(UnaryOp.SplatI32x4, arg0);
2743-
case TypeKind.I64:
2744-
case TypeKind.U64: return module.unary(UnaryOp.SplatI64x2, arg0);
2745-
case TypeKind.ISIZE:
2749+
case TypeKind.I8: {
2750+
compiler.currentType = Type.i8x16;
2751+
return module.unary(UnaryOp.SplatI8x16, arg0);
2752+
}
2753+
case TypeKind.U8: {
2754+
compiler.currentType = Type.u8x16;
2755+
return module.unary(UnaryOp.SplatI8x16, arg0);
2756+
}
2757+
case TypeKind.I16: {
2758+
compiler.currentType = Type.i16x8;
2759+
return module.unary(UnaryOp.SplatI16x8, arg0);
2760+
}
2761+
case TypeKind.U16: {
2762+
compiler.currentType = Type.u16x8;
2763+
return module.unary(UnaryOp.SplatI16x8, arg0);
2764+
}
2765+
case TypeKind.I32: {
2766+
compiler.currentType = Type.i32x4;
2767+
return module.unary(UnaryOp.SplatI32x4, arg0);
2768+
}
2769+
case TypeKind.U32: {
2770+
compiler.currentType = Type.u32x4;
2771+
return module.unary(UnaryOp.SplatI32x4, arg0);
2772+
}
2773+
case TypeKind.I64: {
2774+
compiler.currentType = Type.i64x2;
2775+
return module.unary(UnaryOp.SplatI64x2, arg0);
2776+
}
2777+
case TypeKind.U64: {
2778+
compiler.currentType = Type.u64x2;
2779+
return module.unary(UnaryOp.SplatI64x2, arg0);
2780+
}
2781+
case TypeKind.ISIZE: {
2782+
if (compiler.options.isWasm64) {
2783+
compiler.currentType = Type.i64x2;
2784+
return module.unary(UnaryOp.SplatI64x2, arg0);
2785+
}
2786+
compiler.currentType = Type.i32x4;
2787+
return module.unary(UnaryOp.SplatI32x4, arg0);
2788+
}
27462789
case TypeKind.USIZE: {
2747-
return module.unary(
2748-
compiler.options.isWasm64
2749-
? UnaryOp.SplatI64x2
2750-
: UnaryOp.SplatI32x4,
2751-
arg0
2752-
);
2790+
if (compiler.options.isWasm64) {
2791+
compiler.currentType = Type.u64x2;
2792+
return module.unary(UnaryOp.SplatI64x2, arg0);
2793+
}
2794+
compiler.currentType = Type.u32x4;
2795+
return module.unary(UnaryOp.SplatI32x4, arg0);
2796+
}
2797+
case TypeKind.F32: {
2798+
compiler.currentType = Type.f32x4;
2799+
return module.unary(UnaryOp.SplatF32x4, arg0);
2800+
}
2801+
case TypeKind.F64: {
2802+
compiler.currentType = Type.f64x2;
2803+
return module.unary(UnaryOp.SplatF64x2, arg0);
27532804
}
2754-
case TypeKind.F32: return module.unary(UnaryOp.SplatF32x4, arg0);
2755-
case TypeKind.F64: return module.unary(UnaryOp.SplatF64x2, arg0);
27562805
}
27572806
}
2807+
compiler.currentType = Type.v128;
27582808
compiler.error(
27592809
DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,
27602810
reportNode.typeArgumentsRange, "v128.splat", type.toString()

src/common.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export namespace CommonSymbols {
138138
export const indexof = "indexof";
139139
export const valueof = "valueof";
140140
export const returnof = "returnof";
141+
export const vectorof = "vectorof";
141142
// aliases
142143
export const null_ = "null";
143144
export const true_ = "true";
@@ -177,6 +178,16 @@ export namespace CommonSymbols {
177178
export const F32 = "F32";
178179
export const F64 = "F64";
179180
export const V128 = "V128";
181+
export const I8x16 = "I8x16";
182+
export const U8x16 = "U8x16";
183+
export const I16x8 = "I16x8";
184+
export const U16x8 = "U16x8";
185+
export const I32x4 = "I32x4";
186+
export const U32x4 = "U32x4";
187+
export const I64x2 = "I64x2";
188+
export const U64x2 = "U64x2";
189+
export const F32x4 = "F32x4";
190+
export const F64x2 = "F64x2";
180191
export const Anyref = "Anyref";
181192
export const String = "String";
182193
export const Array = "Array";

src/program.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,25 @@ export class Program extends DiagnosticEmitter {
661661
this.makeNativeTypeDeclaration(CommonSymbols.returnof, CommonFlags.EXPORT | CommonFlags.GENERIC),
662662
DecoratorFlags.BUILTIN
663663
));
664-
if (options.hasFeature(Feature.SIMD)) this.registerNativeType(CommonSymbols.v128, Type.v128);
664+
if (options.hasFeature(Feature.SIMD)) {
665+
this.nativeFile.add(CommonSymbols.vectorof, new TypeDefinition(
666+
CommonSymbols.vectorof,
667+
this.nativeFile,
668+
this.makeNativeTypeDeclaration(CommonSymbols.vectorof, CommonFlags.EXPORT | CommonFlags.GENERIC),
669+
DecoratorFlags.BUILTIN
670+
));
671+
this.registerNativeType(CommonSymbols.v128, Type.v128);
672+
this.registerNativeType(CommonSymbols.i8x16, Type.i8x16);
673+
this.registerNativeType(CommonSymbols.u8x16, Type.u8x16);
674+
this.registerNativeType(CommonSymbols.i16x8, Type.i16x8);
675+
this.registerNativeType(CommonSymbols.u16x8, Type.u16x8);
676+
this.registerNativeType(CommonSymbols.i32x4, Type.i32x4);
677+
this.registerNativeType(CommonSymbols.u32x4, Type.u32x4);
678+
this.registerNativeType(CommonSymbols.i64x2, Type.i64x2);
679+
this.registerNativeType(CommonSymbols.u64x2, Type.u64x2);
680+
this.registerNativeType(CommonSymbols.f32x4, Type.f32x4);
681+
this.registerNativeType(CommonSymbols.f64x2, Type.f64x2);
682+
}
665683
if (options.hasFeature(Feature.REFERENCE_TYPES)) this.registerNativeType(CommonSymbols.anyref, Type.anyref);
666684

667685
// register compiler hints
@@ -879,7 +897,19 @@ export class Program extends DiagnosticEmitter {
879897
this.registerWrapperClass(Type.bool, CommonSymbols.Bool);
880898
this.registerWrapperClass(Type.f32, CommonSymbols.F32);
881899
this.registerWrapperClass(Type.f64, CommonSymbols.F64);
882-
if (options.hasFeature(Feature.SIMD)) this.registerWrapperClass(Type.v128, CommonSymbols.V128);
900+
if (options.hasFeature(Feature.SIMD)) {
901+
this.registerWrapperClass(Type.v128, CommonSymbols.V128);
902+
this.registerWrapperClass(Type.i8x16, CommonSymbols.I8x16);
903+
this.registerWrapperClass(Type.u8x16, CommonSymbols.U8x16);
904+
this.registerWrapperClass(Type.i16x8, CommonSymbols.I16x8);
905+
this.registerWrapperClass(Type.u16x8, CommonSymbols.U16x8);
906+
this.registerWrapperClass(Type.i32x4, CommonSymbols.I32x4);
907+
this.registerWrapperClass(Type.u32x4, CommonSymbols.U32x4);
908+
this.registerWrapperClass(Type.i64x2, CommonSymbols.I64x2);
909+
this.registerWrapperClass(Type.u64x2, CommonSymbols.U64x2);
910+
this.registerWrapperClass(Type.f32x4, CommonSymbols.F32x4);
911+
this.registerWrapperClass(Type.f64x2, CommonSymbols.F64x2);
912+
}
883913
if (options.hasFeature(Feature.REFERENCE_TYPES)) this.registerWrapperClass(Type.anyref, CommonSymbols.Anyref);
884914

885915
// register views but don't instantiate them yet

0 commit comments

Comments
 (0)