@@ -3542,20 +3542,39 @@ function builtin_i8x16(ctx: BuiltinContext): ExpressionRef {
3542
3542
}
3543
3543
var operands = ctx . operands ;
3544
3544
var bytes = new Uint8Array ( 16 ) ;
3545
+ var vars = new Array < ExpressionRef > ( 16 ) ;
3546
+ var numVars = 0 ;
3547
+
3545
3548
for ( let i = 0 ; i < 16 ; ++ i ) {
3546
3549
let expr = compiler . compileExpression ( operands [ i ] , Type . i8 , Constraints . CONV_IMPLICIT ) ;
3547
3550
let precomp = module . runExpression ( expr , ExpressionRunnerFlags . PreserveSideeffects ) ;
3548
3551
if ( precomp ) {
3549
3552
writeI8 ( getConstValueI32 ( precomp ) , bytes , i ) ;
3550
3553
} else {
3551
- compiler . error (
3552
- DiagnosticCode . Expression_must_be_a_compile_time_constant ,
3553
- operands [ i ] . range
3554
- ) ;
3554
+ vars [ i ] = expr ;
3555
+ numVars ++ ;
3555
3556
}
3556
3557
}
3557
3558
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
+ }
3559
3578
}
3560
3579
builtins . set ( BuiltinNames . i8x16 , builtin_i8x16 ) ;
3561
3580
@@ -3573,20 +3592,39 @@ function builtin_i16x8(ctx: BuiltinContext): ExpressionRef {
3573
3592
}
3574
3593
var operands = ctx . operands ;
3575
3594
var bytes = new Uint8Array ( 16 ) ;
3595
+ var vars = new Array < ExpressionRef > ( 8 ) ;
3596
+ var numVars = 0 ;
3597
+
3576
3598
for ( let i = 0 ; i < 8 ; ++ i ) {
3577
3599
let expr = compiler . compileExpression ( operands [ i ] , Type . i16 , Constraints . CONV_IMPLICIT ) ;
3578
3600
let precomp = module . runExpression ( expr , ExpressionRunnerFlags . PreserveSideeffects ) ;
3579
3601
if ( precomp ) {
3580
3602
writeI16 ( getConstValueI32 ( precomp ) , bytes , i << 1 ) ;
3581
3603
} else {
3582
- compiler . error (
3583
- DiagnosticCode . Expression_must_be_a_compile_time_constant ,
3584
- operands [ i ] . range
3585
- ) ;
3604
+ vars [ i ] = expr ;
3605
+ numVars ++ ;
3586
3606
}
3587
3607
}
3588
3608
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
+ }
3590
3628
}
3591
3629
builtins . set ( BuiltinNames . i16x8 , builtin_i16x8 ) ;
3592
3630
@@ -3604,20 +3642,39 @@ function builtin_i32x4(ctx: BuiltinContext): ExpressionRef {
3604
3642
}
3605
3643
var operands = ctx . operands ;
3606
3644
var bytes = new Uint8Array ( 16 ) ;
3645
+ var vars = new Array < ExpressionRef > ( 4 ) ;
3646
+ var numVars = 0 ;
3647
+
3607
3648
for ( let i = 0 ; i < 4 ; ++ i ) {
3608
3649
let expr = compiler . compileExpression ( operands [ i ] , Type . i32 , Constraints . CONV_IMPLICIT ) ;
3609
3650
let precomp = module . runExpression ( expr , ExpressionRunnerFlags . PreserveSideeffects ) ;
3610
3651
if ( precomp ) {
3611
3652
writeI32 ( getConstValueI32 ( precomp ) , bytes , i << 2 ) ;
3612
3653
} else {
3613
- compiler . error (
3614
- DiagnosticCode . Expression_must_be_a_compile_time_constant ,
3615
- operands [ i ] . range
3616
- ) ;
3654
+ vars [ i ] = expr ;
3655
+ numVars ++ ;
3617
3656
}
3618
3657
}
3619
3658
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
+ }
3621
3678
}
3622
3679
builtins . set ( BuiltinNames . i32x4 , builtin_i32x4 ) ;
3623
3680
@@ -3635,22 +3692,41 @@ function builtin_i64x2(ctx: BuiltinContext): ExpressionRef {
3635
3692
}
3636
3693
var operands = ctx . operands ;
3637
3694
var bytes = new Uint8Array ( 16 ) ;
3695
+ var vars = new Array < ExpressionRef > ( 2 ) ;
3696
+ var numVars = 0 ;
3697
+
3638
3698
for ( let i = 0 ; i < 2 ; ++ i ) {
3639
3699
let expr = compiler . compileExpression ( operands [ i ] , Type . i64 , Constraints . CONV_IMPLICIT ) ;
3640
3700
let precomp = module . runExpression ( expr , ExpressionRunnerFlags . PreserveSideeffects ) ;
3641
3701
if ( precomp ) {
3642
3702
let off = i << 3 ;
3643
- writeI32 ( getConstValueI64Low ( precomp ) , bytes , off ) ;
3703
+ writeI32 ( getConstValueI64Low ( precomp ) , bytes , off + 0 ) ;
3644
3704
writeI32 ( getConstValueI64High ( precomp ) , bytes , off + 4 ) ;
3645
3705
} else {
3646
- compiler . error (
3647
- DiagnosticCode . Expression_must_be_a_compile_time_constant ,
3648
- operands [ i ] . range
3649
- ) ;
3706
+ vars [ i ] = expr ;
3707
+ numVars ++ ;
3650
3708
}
3651
3709
}
3652
3710
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
+ }
3654
3730
}
3655
3731
builtins . set ( BuiltinNames . i64x2 , builtin_i64x2 ) ;
3656
3732
@@ -3668,20 +3744,39 @@ function builtin_f32x4(ctx: BuiltinContext): ExpressionRef {
3668
3744
}
3669
3745
var operands = ctx . operands ;
3670
3746
var bytes = new Uint8Array ( 16 ) ;
3747
+ var vars = new Array < ExpressionRef > ( 4 ) ;
3748
+ var numVars = 0 ;
3749
+
3671
3750
for ( let i = 0 ; i < 4 ; ++ i ) {
3672
3751
let expr = compiler . compileExpression ( operands [ i ] , Type . f32 , Constraints . CONV_IMPLICIT ) ;
3673
3752
let precomp = module . runExpression ( expr , ExpressionRunnerFlags . PreserveSideeffects ) ;
3674
3753
if ( precomp ) {
3675
3754
writeF32 ( getConstValueF32 ( precomp ) , bytes , i << 2 ) ;
3676
3755
} else {
3677
- compiler . error (
3678
- DiagnosticCode . Expression_must_be_a_compile_time_constant ,
3679
- operands [ i ] . range
3680
- ) ;
3756
+ vars [ i ] = expr ;
3757
+ numVars ++ ;
3681
3758
}
3682
3759
}
3683
3760
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
+ }
3685
3780
}
3686
3781
builtins . set ( BuiltinNames . f32x4 , builtin_f32x4 ) ;
3687
3782
@@ -3699,20 +3794,39 @@ function builtin_f64x2(ctx: BuiltinContext): ExpressionRef {
3699
3794
}
3700
3795
var operands = ctx . operands ;
3701
3796
var bytes = new Uint8Array ( 16 ) ;
3797
+ var vars = new Array < ExpressionRef > ( 2 ) ;
3798
+ var numVars = 0 ;
3799
+
3702
3800
for ( let i = 0 ; i < 2 ; ++ i ) {
3703
3801
let expr = compiler . compileExpression ( operands [ i ] , Type . f64 , Constraints . CONV_IMPLICIT ) ;
3704
3802
let precomp = module . runExpression ( expr , ExpressionRunnerFlags . PreserveSideeffects ) ;
3705
3803
if ( precomp ) {
3706
3804
writeF64 ( getConstValueF64 ( precomp ) , bytes , i << 3 ) ;
3707
3805
} else {
3708
- compiler . error (
3709
- DiagnosticCode . Expression_must_be_a_compile_time_constant ,
3710
- operands [ i ] . range
3711
- ) ;
3806
+ vars [ i ] = expr ;
3807
+ numVars ++ ;
3712
3808
}
3713
3809
}
3714
3810
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
+ }
3716
3830
}
3717
3831
builtins . set ( BuiltinNames . f64x2 , builtin_f64x2 ) ;
3718
3832
0 commit comments