@@ -1126,8 +1126,8 @@ function builtin_popcnt(ctx: BuiltinContext): ExpressionRef {
11261126 var type = compiler . currentType ;
11271127 if ( type . isValue ) {
11281128 switch ( compiler . currentType . kind ) {
1129- case TypeKind . BOOL : // not wrapped
1130- case TypeKind . I8 :
1129+ case TypeKind . BOOL : return arg0 ;
1130+ case TypeKind . I8 : // not wrapped
11311131 case TypeKind . U8 :
11321132 case TypeKind . I16 :
11331133 case TypeKind . U16 :
@@ -1171,14 +1171,27 @@ function builtin_rotl(ctx: BuiltinContext): ExpressionRef {
11711171 if ( type . isValue ) {
11721172 let arg1 = compiler . compileExpression ( operands [ 1 ] , type , Constraints . CONV_IMPLICIT ) ;
11731173 switch ( type . kind ) {
1174+ case TypeKind . BOOL : return arg0 ;
11741175 case TypeKind . I8 :
11751176 case TypeKind . I16 :
11761177 case TypeKind . U8 :
1177- case TypeKind . U16 :
1178- case TypeKind . BOOL : {
1179- return compiler . ensureSmallIntegerWrap (
1180- module . binary ( BinaryOp . RotlI32 , arg0 , arg1 ) ,
1181- type
1178+ case TypeKind . U16 : {
1179+ // (value << (shift & mask)) | (value >>> ((0 - shift) & mask))
1180+ return module . binary ( BinaryOp . OrI32 ,
1181+ module . binary (
1182+ BinaryOp . ShlI32 ,
1183+ arg0 ,
1184+ module . binary ( BinaryOp . AndI32 , arg1 , module . i32 ( type . size - 1 ) )
1185+ ) ,
1186+ module . binary (
1187+ BinaryOp . ShrU32 ,
1188+ arg0 ,
1189+ module . binary (
1190+ BinaryOp . AndI32 ,
1191+ module . binary ( BinaryOp . SubI32 , module . i32 ( 0 ) , arg1 ) ,
1192+ module . i32 ( type . size - 1 )
1193+ )
1194+ )
11821195 ) ;
11831196 }
11841197 case TypeKind . I32 :
@@ -1221,14 +1234,27 @@ function builtin_rotr(ctx: BuiltinContext): ExpressionRef {
12211234 if ( type . isValue ) {
12221235 let arg1 = compiler . compileExpression ( operands [ 1 ] , type , Constraints . CONV_IMPLICIT ) ;
12231236 switch ( type . kind ) {
1237+ case TypeKind . BOOL : return arg0 ;
12241238 case TypeKind . I8 :
12251239 case TypeKind . I16 :
12261240 case TypeKind . U8 :
1227- case TypeKind . U16 :
1228- case TypeKind . BOOL : {
1229- return compiler . ensureSmallIntegerWrap (
1230- module . binary ( BinaryOp . RotrI32 , arg0 , arg1 ) ,
1231- type
1241+ case TypeKind . U16 : {
1242+ // (value >>> (shift & mask)) | (value << ((0 - shift) & mask))
1243+ return module . binary ( BinaryOp . OrI32 ,
1244+ module . binary (
1245+ BinaryOp . ShrU32 ,
1246+ arg0 ,
1247+ module . binary ( BinaryOp . AndI32 , arg1 , module . i32 ( type . size - 1 ) )
1248+ ) ,
1249+ module . binary (
1250+ BinaryOp . ShlI32 ,
1251+ arg0 ,
1252+ module . binary (
1253+ BinaryOp . AndI32 ,
1254+ module . binary ( BinaryOp . SubI32 , module . i32 ( 0 ) , arg1 ) ,
1255+ module . i32 ( type . size - 1 )
1256+ )
1257+ )
12321258 ) ;
12331259 }
12341260 case TypeKind . I32 :
@@ -2129,7 +2155,7 @@ function builtin_add(ctx: BuiltinContext): ExpressionRef {
21292155 {
21302156 op = BinaryOp . AddI32 ;
21312157 break ;
2132- }
2158+ }
21332159 case TypeKind . I64 :
21342160 case TypeKind . U64 : {
21352161 op = BinaryOp . AddI64 ;
@@ -2220,7 +2246,7 @@ function builtin_sub(ctx: BuiltinContext): ExpressionRef {
22202246 {
22212247 op = BinaryOp . SubI32 ;
22222248 break ;
2223- }
2249+ }
22242250 case TypeKind . I64 :
22252251 case TypeKind . U64 : {
22262252 op = BinaryOp . SubI64 ;
@@ -2311,7 +2337,7 @@ function builtin_mul(ctx: BuiltinContext): ExpressionRef {
23112337 {
23122338 op = BinaryOp . MulI32 ;
23132339 break ;
2314- }
2340+ }
23152341 case TypeKind . I64 :
23162342 case TypeKind . U64 : {
23172343 op = BinaryOp . MulI64 ;
@@ -3041,7 +3067,7 @@ function builtin_assert(ctx: BuiltinContext): ExpressionRef {
30413067 case TypeKind . EXTERNREF :
30423068 case TypeKind . EXNREF :
30433069 case TypeKind . ANYREF : return module . if ( module . ref_is_null ( arg0 ) , abort ) ;
3044-
3070+
30453071 }
30463072 } else {
30473073 compiler . currentType = type . nonNullableType ;
0 commit comments