@@ -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}
35603579builtins . 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}
35913629builtins . 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}
36223679builtins . 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}
36553731builtins . 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}
36863781builtins . 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}
37173831builtins . set ( BuiltinNames . f64x2 , builtin_f64x2 ) ;
37183832
0 commit comments