Skip to content

Commit 3d84f2d

Browse files
authored
feat: Support dynamic operands to SIMD constructors (#2143)
1 parent f3d580b commit 3d84f2d

File tree

4 files changed

+505
-31
lines changed

4 files changed

+505
-31
lines changed

Diff for: src/builtins.ts

+145-31
Original file line numberDiff line numberDiff line change
@@ -3542,20 +3542,39 @@ function builtin_i8x16(ctx: BuiltinContext): ExpressionRef {
35423542
}
35433543
var operands = ctx.operands;
35443544
var bytes = new Uint8Array(16);
3545+
var vars = new Array<ExpressionRef>(16);
3546+
var numVars = 0;
3547+
35453548
for (let i = 0; i < 16; ++i) {
35463549
let expr = compiler.compileExpression(operands[i], Type.i8, Constraints.CONV_IMPLICIT);
35473550
let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);
35483551
if (precomp) {
35493552
writeI8(getConstValueI32(precomp), bytes, i);
35503553
} else {
3551-
compiler.error(
3552-
DiagnosticCode.Expression_must_be_a_compile_time_constant,
3553-
operands[i].range
3554-
);
3554+
vars[i] = expr;
3555+
numVars++;
35553556
}
35563557
}
35573558
compiler.currentType = Type.v128;
3558-
return module.v128(bytes);
3559+
if (numVars == 0) {
3560+
// all constants
3561+
return module.v128(bytes);
3562+
} else {
3563+
let vec: ExpressionRef;
3564+
let fullVars = numVars == 16;
3565+
if (fullVars) {
3566+
// all variants
3567+
vec = module.unary(UnaryOp.SplatI8x16, vars[0]);
3568+
} else {
3569+
// mixed constants / variants
3570+
vec = module.v128(bytes);
3571+
}
3572+
for (let i = i32(fullVars); i < 16; i++) {
3573+
let expr = vars[i];
3574+
if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneI8x16, vec, <u8>i, expr);
3575+
}
3576+
return vec;
3577+
}
35593578
}
35603579
builtins.set(BuiltinNames.i8x16, builtin_i8x16);
35613580

@@ -3573,20 +3592,39 @@ function builtin_i16x8(ctx: BuiltinContext): ExpressionRef {
35733592
}
35743593
var operands = ctx.operands;
35753594
var bytes = new Uint8Array(16);
3595+
var vars = new Array<ExpressionRef>(8);
3596+
var numVars = 0;
3597+
35763598
for (let i = 0; i < 8; ++i) {
35773599
let expr = compiler.compileExpression(operands[i], Type.i16, Constraints.CONV_IMPLICIT);
35783600
let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);
35793601
if (precomp) {
35803602
writeI16(getConstValueI32(precomp), bytes, i << 1);
35813603
} else {
3582-
compiler.error(
3583-
DiagnosticCode.Expression_must_be_a_compile_time_constant,
3584-
operands[i].range
3585-
);
3604+
vars[i] = expr;
3605+
numVars++;
35863606
}
35873607
}
35883608
compiler.currentType = Type.v128;
3589-
return module.v128(bytes);
3609+
if (numVars == 0) {
3610+
// all constants
3611+
return module.v128(bytes);
3612+
} else {
3613+
let vec: ExpressionRef;
3614+
let fullVars = numVars == 8;
3615+
if (fullVars) {
3616+
// all variants
3617+
vec = module.unary(UnaryOp.SplatI16x8, vars[0]);
3618+
} else {
3619+
// mixed constants / variants
3620+
vec = module.v128(bytes);
3621+
}
3622+
for (let i = i32(fullVars); i < 8; i++) {
3623+
let expr = vars[i];
3624+
if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneI16x8, vec, <u8>i, expr);
3625+
}
3626+
return vec;
3627+
}
35903628
}
35913629
builtins.set(BuiltinNames.i16x8, builtin_i16x8);
35923630

@@ -3604,20 +3642,39 @@ function builtin_i32x4(ctx: BuiltinContext): ExpressionRef {
36043642
}
36053643
var operands = ctx.operands;
36063644
var bytes = new Uint8Array(16);
3645+
var vars = new Array<ExpressionRef>(4);
3646+
var numVars = 0;
3647+
36073648
for (let i = 0; i < 4; ++i) {
36083649
let expr = compiler.compileExpression(operands[i], Type.i32, Constraints.CONV_IMPLICIT);
36093650
let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);
36103651
if (precomp) {
36113652
writeI32(getConstValueI32(precomp), bytes, i << 2);
36123653
} else {
3613-
compiler.error(
3614-
DiagnosticCode.Expression_must_be_a_compile_time_constant,
3615-
operands[i].range
3616-
);
3654+
vars[i] = expr;
3655+
numVars++;
36173656
}
36183657
}
36193658
compiler.currentType = Type.v128;
3620-
return module.v128(bytes);
3659+
if (numVars == 0) {
3660+
// all constants
3661+
return module.v128(bytes);
3662+
} else {
3663+
let vec: ExpressionRef;
3664+
let fullVars = numVars == 4;
3665+
if (fullVars) {
3666+
// all variants
3667+
vec = module.unary(UnaryOp.SplatI32x4, vars[0]);
3668+
} else {
3669+
// mixed constants / variants
3670+
vec = module.v128(bytes);
3671+
}
3672+
for (let i = i32(fullVars); i < 4; i++) {
3673+
let expr = vars[i];
3674+
if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneI32x4, vec, <u8>i, expr);
3675+
}
3676+
return vec;
3677+
}
36213678
}
36223679
builtins.set(BuiltinNames.i32x4, builtin_i32x4);
36233680

@@ -3635,22 +3692,41 @@ function builtin_i64x2(ctx: BuiltinContext): ExpressionRef {
36353692
}
36363693
var operands = ctx.operands;
36373694
var bytes = new Uint8Array(16);
3695+
var vars = new Array<ExpressionRef>(2);
3696+
var numVars = 0;
3697+
36383698
for (let i = 0; i < 2; ++i) {
36393699
let expr = compiler.compileExpression(operands[i], Type.i64, Constraints.CONV_IMPLICIT);
36403700
let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);
36413701
if (precomp) {
36423702
let off = i << 3;
3643-
writeI32(getConstValueI64Low(precomp), bytes, off);
3703+
writeI32(getConstValueI64Low(precomp), bytes, off + 0);
36443704
writeI32(getConstValueI64High(precomp), bytes, off + 4);
36453705
} else {
3646-
compiler.error(
3647-
DiagnosticCode.Expression_must_be_a_compile_time_constant,
3648-
operands[i].range
3649-
);
3706+
vars[i] = expr;
3707+
numVars++;
36503708
}
36513709
}
36523710
compiler.currentType = Type.v128;
3653-
return module.v128(bytes);
3711+
if (numVars == 0) {
3712+
// all constants
3713+
return module.v128(bytes);
3714+
} else {
3715+
let vec: ExpressionRef;
3716+
let fullVars = numVars == 2;
3717+
if (fullVars) {
3718+
// all variants
3719+
vec = module.unary(UnaryOp.SplatI64x2, vars[0]);
3720+
} else {
3721+
// mixed constants / variants
3722+
vec = module.v128(bytes);
3723+
}
3724+
for (let i = i32(fullVars); i < 2; i++) {
3725+
let expr = vars[i];
3726+
if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneI64x2, vec, <u8>i, expr);
3727+
}
3728+
return vec;
3729+
}
36543730
}
36553731
builtins.set(BuiltinNames.i64x2, builtin_i64x2);
36563732

@@ -3668,20 +3744,39 @@ function builtin_f32x4(ctx: BuiltinContext): ExpressionRef {
36683744
}
36693745
var operands = ctx.operands;
36703746
var bytes = new Uint8Array(16);
3747+
var vars = new Array<ExpressionRef>(4);
3748+
var numVars = 0;
3749+
36713750
for (let i = 0; i < 4; ++i) {
36723751
let expr = compiler.compileExpression(operands[i], Type.f32, Constraints.CONV_IMPLICIT);
36733752
let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);
36743753
if (precomp) {
36753754
writeF32(getConstValueF32(precomp), bytes, i << 2);
36763755
} else {
3677-
compiler.error(
3678-
DiagnosticCode.Expression_must_be_a_compile_time_constant,
3679-
operands[i].range
3680-
);
3756+
vars[i] = expr;
3757+
numVars++;
36813758
}
36823759
}
36833760
compiler.currentType = Type.v128;
3684-
return module.v128(bytes);
3761+
if (numVars == 0) {
3762+
// all constants
3763+
return module.v128(bytes);
3764+
} else {
3765+
let vec: ExpressionRef;
3766+
let fullVars = numVars == 4;
3767+
if (fullVars) {
3768+
// all variants
3769+
vec = module.unary(UnaryOp.SplatF32x4, vars[0]);
3770+
} else {
3771+
// mixed constants / variants
3772+
vec = module.v128(bytes);
3773+
}
3774+
for (let i = i32(fullVars); i < 4; i++) {
3775+
let expr = vars[i];
3776+
if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneF32x4, vec, <u8>i, expr);
3777+
}
3778+
return vec;
3779+
}
36853780
}
36863781
builtins.set(BuiltinNames.f32x4, builtin_f32x4);
36873782

@@ -3699,20 +3794,39 @@ function builtin_f64x2(ctx: BuiltinContext): ExpressionRef {
36993794
}
37003795
var operands = ctx.operands;
37013796
var bytes = new Uint8Array(16);
3797+
var vars = new Array<ExpressionRef>(2);
3798+
var numVars = 0;
3799+
37023800
for (let i = 0; i < 2; ++i) {
37033801
let expr = compiler.compileExpression(operands[i], Type.f64, Constraints.CONV_IMPLICIT);
37043802
let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);
37053803
if (precomp) {
37063804
writeF64(getConstValueF64(precomp), bytes, i << 3);
37073805
} else {
3708-
compiler.error(
3709-
DiagnosticCode.Expression_must_be_a_compile_time_constant,
3710-
operands[i].range
3711-
);
3806+
vars[i] = expr;
3807+
numVars++;
37123808
}
37133809
}
37143810
compiler.currentType = Type.v128;
3715-
return module.v128(bytes);
3811+
if (numVars == 0) {
3812+
// all constants
3813+
return module.v128(bytes);
3814+
} else {
3815+
let vec: ExpressionRef;
3816+
let fullVars = numVars == 2;
3817+
if (fullVars) {
3818+
// all variants
3819+
vec = module.unary(UnaryOp.SplatF64x2, vars[0]);
3820+
} else {
3821+
// mixed constants / variants
3822+
vec = module.v128(bytes);
3823+
}
3824+
for (let i = i32(fullVars); i < 2; i++) {
3825+
let expr = vars[i];
3826+
if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneF64x2, vec, <u8>i, expr);
3827+
}
3828+
return vec;
3829+
}
37163830
}
37173831
builtins.set(BuiltinNames.f64x2, builtin_f64x2);
37183832

0 commit comments

Comments
 (0)