@@ -163,6 +163,7 @@ export namespace BuiltinNames {
163163 export const trunc = "~lib/builtins/trunc" ;
164164 export const eq = "~lib/builtins/eq" ;
165165 export const ne = "~lib/builtins/ne" ;
166+ export const rem = "~lib/builtins/rem" ;
166167 export const load = "~lib/builtins/load" ;
167168 export const store = "~lib/builtins/store" ;
168169 export const atomic_load = "~lib/builtins/atomic.load" ;
@@ -269,6 +270,11 @@ export namespace BuiltinNames {
269270 export const f32_ne = "~lib/builtins/f32.ne" ;
270271 export const f64_ne = "~lib/builtins/f64.ne" ;
271272
273+ export const i32_rem_s = "~lib/builtins/i32.rem_s" ;
274+ export const i32_rem_u = "~lib/builtins/i32.rem_u" ;
275+ export const i64_rem_s = "~lib/builtins/i64.rem_s" ;
276+ export const i64_rem_u = "~lib/builtins/i64.rem_u" ;
277+
272278 export const i32_load8_s = "~lib/builtins/i32.load8_s" ;
273279 export const i32_load8_u = "~lib/builtins/i32.load8_u" ;
274280 export const i32_load16_s = "~lib/builtins/i32.load16_s" ;
@@ -815,7 +821,7 @@ function builtin_isString(ctx: BuiltinContext): ExpressionRef {
815821 compiler . currentType = Type . bool ;
816822 if ( ! type ) return module . unreachable ( ) ;
817823 var classReference = type . getClass ( ) ;
818- return reifyConstantType ( ctx ,
824+ return reifyConstantType ( ctx ,
819825 module . i32 (
820826 classReference && classReference . isAssignableTo ( compiler . program . stringInstance )
821827 ? 1
@@ -2231,6 +2237,60 @@ function builtin_store(ctx: BuiltinContext): ExpressionRef {
22312237}
22322238builtins . set ( BuiltinNames . store , builtin_store ) ;
22332239
2240+ // rem<T?>(left: T, right: T) -> T
2241+ function builtin_rem ( ctx : BuiltinContext ) : ExpressionRef {
2242+ var compiler = ctx . compiler ;
2243+ var module = compiler . module ;
2244+ if ( checkTypeOptional ( ctx , true ) | checkArgsRequired ( ctx , 2 ) ) {
2245+ return module . unreachable ( ) ;
2246+ }
2247+ var operands = ctx . operands ;
2248+ var typeArguments = ctx . typeArguments ;
2249+ var left = operands [ 0 ] ;
2250+ var arg0 = typeArguments
2251+ ? compiler . compileExpression (
2252+ left ,
2253+ typeArguments [ 0 ] ,
2254+ Constraints . CONV_IMPLICIT
2255+ )
2256+ : compiler . compileExpression ( operands [ 0 ] , Type . auto ) ;
2257+ var type = compiler . currentType ;
2258+ if ( type . isIntegerValue ) {
2259+ let arg1 : ExpressionRef ;
2260+ if ( ! typeArguments && left . isNumericLiteral ) {
2261+ // prefer right type
2262+ arg1 = compiler . compileExpression (
2263+ operands [ 1 ] ,
2264+ type
2265+ ) ;
2266+ if ( compiler . currentType != type ) {
2267+ arg0 = compiler . compileExpression (
2268+ left ,
2269+ ( type = compiler . currentType ) ,
2270+ Constraints . CONV_IMPLICIT
2271+ ) ;
2272+ }
2273+ } else {
2274+ arg1 = compiler . compileExpression (
2275+ operands [ 1 ] ,
2276+ type ,
2277+ Constraints . CONV_IMPLICIT
2278+ ) ;
2279+ }
2280+ if ( type . isIntegerValue ) {
2281+ return compiler . makeRem ( arg0 , arg1 , type , ctx . reportNode ) ;
2282+ }
2283+ }
2284+ compiler . error (
2285+ DiagnosticCode . Operation_0_cannot_be_applied_to_type_1 ,
2286+ ctx . reportNode . typeArgumentsRange ,
2287+ "rem" ,
2288+ type . toString ( )
2289+ ) ;
2290+ return module . unreachable ( ) ;
2291+ }
2292+ builtins . set ( BuiltinNames . rem , builtin_rem ) ;
2293+
22342294// add<T?>(left: T, right: T) -> T
22352295function builtin_add ( ctx : BuiltinContext ) : ExpressionRef {
22362296 var compiler = ctx . compiler ;
@@ -6638,6 +6698,42 @@ function builtin_f64_trunc(ctx: BuiltinContext): ExpressionRef {
66386698}
66396699builtins . set ( BuiltinNames . f64_trunc , builtin_f64_trunc ) ;
66406700
6701+ // i32.rem_s -> rem<i32>
6702+ function builtin_i32_rem_s ( ctx : BuiltinContext ) : ExpressionRef {
6703+ checkTypeAbsent ( ctx ) ;
6704+ ctx . typeArguments = [ Type . i32 ] ;
6705+ ctx . contextualType = Type . i32 ;
6706+ return builtin_rem ( ctx ) ;
6707+ }
6708+ builtins . set ( BuiltinNames . i32_rem_s , builtin_i32_rem_s ) ;
6709+
6710+ // i32.rem_u -> rem<u32>
6711+ function builtin_i32_rem_u ( ctx : BuiltinContext ) : ExpressionRef {
6712+ checkTypeAbsent ( ctx ) ;
6713+ ctx . typeArguments = [ Type . u32 ] ;
6714+ ctx . contextualType = Type . u32 ;
6715+ return builtin_rem ( ctx ) ;
6716+ }
6717+ builtins . set ( BuiltinNames . i32_rem_u , builtin_i32_rem_u ) ;
6718+
6719+ // i64.rem_s -> rem<i64>
6720+ function builtin_i64_rem_s ( ctx : BuiltinContext ) : ExpressionRef {
6721+ checkTypeAbsent ( ctx ) ;
6722+ ctx . typeArguments = [ Type . i64 ] ;
6723+ ctx . contextualType = Type . i64 ;
6724+ return builtin_rem ( ctx ) ;
6725+ }
6726+ builtins . set ( BuiltinNames . i64_rem_s , builtin_i64_rem_s ) ;
6727+
6728+ // i64.rem_u -> rem<u64>
6729+ function builtin_i64_rem_u ( ctx : BuiltinContext ) : ExpressionRef {
6730+ checkTypeAbsent ( ctx ) ;
6731+ ctx . typeArguments = [ Type . u64 ] ;
6732+ ctx . contextualType = Type . u64 ;
6733+ return builtin_rem ( ctx ) ;
6734+ }
6735+ builtins . set ( BuiltinNames . i64_rem_u , builtin_i64_rem_u ) ;
6736+
66416737// i32.add -> add<i32>
66426738function builtin_i32_add ( ctx : BuiltinContext ) : ExpressionRef {
66436739 checkTypeAbsent ( ctx ) ;
0 commit comments