@@ -161,6 +161,8 @@ export namespace BuiltinNames {
161161 export const reinterpret = "~lib/builtins/reinterpret" ;
162162 export const sqrt = "~lib/builtins/sqrt" ;
163163 export const trunc = "~lib/builtins/trunc" ;
164+ export const eq = "~lib/builtins/eq" ;
165+ export const ne = "~lib/builtins/ne" ;
164166 export const load = "~lib/builtins/load" ;
165167 export const store = "~lib/builtins/store" ;
166168 export const atomic_load = "~lib/builtins/atomic.load" ;
@@ -258,6 +260,15 @@ export namespace BuiltinNames {
258260 export const f32_div = "~lib/builtins/f32.div" ;
259261 export const f64_div = "~lib/builtins/f64.div" ;
260262
263+ export const i32_eq = "~lib/builtins/i32.eq" ;
264+ export const i64_eq = "~lib/builtins/i64.eq" ;
265+ export const f32_eq = "~lib/builtins/f32.eq" ;
266+ export const f64_eq = "~lib/builtins/f64.eq" ;
267+ export const i32_ne = "~lib/builtins/i32.ne" ;
268+ export const i64_ne = "~lib/builtins/i64.ne" ;
269+ export const f32_ne = "~lib/builtins/f32.ne" ;
270+ export const f64_ne = "~lib/builtins/f64.ne" ;
271+
261272 export const i32_load8_s = "~lib/builtins/i32.load8_s" ;
262273 export const i32_load8_u = "~lib/builtins/i32.load8_u" ;
263274 export const i32_load16_s = "~lib/builtins/i32.load16_s" ;
@@ -2436,6 +2447,116 @@ function builtin_div(ctx: BuiltinContext): ExpressionRef {
24362447}
24372448builtins . set ( BuiltinNames . div , builtin_div ) ;
24382449
2450+ // eq<T?>(left: T, right: T) -> i32
2451+ function builtin_eq ( ctx : BuiltinContext ) : ExpressionRef {
2452+ var compiler = ctx . compiler ;
2453+ var module = compiler . module ;
2454+ if ( checkTypeOptional ( ctx , true ) | checkArgsRequired ( ctx , 2 ) ) {
2455+ return module . unreachable ( ) ;
2456+ }
2457+ var operands = ctx . operands ;
2458+ var typeArguments = ctx . typeArguments ;
2459+ var left = operands [ 0 ] ;
2460+ var arg0 = typeArguments
2461+ ? compiler . compileExpression (
2462+ left ,
2463+ typeArguments [ 0 ] ,
2464+ Constraints . CONV_IMPLICIT
2465+ )
2466+ : compiler . compileExpression ( operands [ 0 ] , Type . auto ) ;
2467+ var type = compiler . currentType ;
2468+ if ( type . isValue ) {
2469+ let arg1 : ExpressionRef ;
2470+ if ( ! typeArguments && left . isNumericLiteral ) {
2471+ // prefer right type
2472+ arg1 = compiler . compileExpression (
2473+ operands [ 1 ] ,
2474+ type
2475+ ) ;
2476+ if ( compiler . currentType != type ) {
2477+ arg0 = compiler . compileExpression (
2478+ left ,
2479+ ( type = compiler . currentType ) ,
2480+ Constraints . CONV_IMPLICIT
2481+ ) ;
2482+ }
2483+ } else {
2484+ arg1 = compiler . compileExpression (
2485+ operands [ 1 ] ,
2486+ type ,
2487+ Constraints . CONV_IMPLICIT
2488+ ) ;
2489+ }
2490+ if ( type . isNumericValue ) {
2491+ compiler . currentType = Type . i32 ;
2492+ return compiler . makeEq ( arg0 , arg1 , type , ctx . reportNode ) ;
2493+ }
2494+ }
2495+ compiler . error (
2496+ DiagnosticCode . Operation_0_cannot_be_applied_to_type_1 ,
2497+ ctx . reportNode . typeArgumentsRange ,
2498+ "eq" ,
2499+ type . toString ( )
2500+ ) ;
2501+ return module . unreachable ( ) ;
2502+ }
2503+ builtins . set ( BuiltinNames . eq , builtin_eq ) ;
2504+
2505+ // ne<T?>(left: T, right: T) -> i32
2506+ function builtin_ne ( ctx : BuiltinContext ) : ExpressionRef {
2507+ var compiler = ctx . compiler ;
2508+ var module = compiler . module ;
2509+ if ( checkTypeOptional ( ctx , true ) | checkArgsRequired ( ctx , 2 ) ) {
2510+ return module . unreachable ( ) ;
2511+ }
2512+ var operands = ctx . operands ;
2513+ var typeArguments = ctx . typeArguments ;
2514+ var left = operands [ 0 ] ;
2515+ var arg0 = typeArguments
2516+ ? compiler . compileExpression (
2517+ left ,
2518+ typeArguments [ 0 ] ,
2519+ Constraints . CONV_IMPLICIT
2520+ )
2521+ : compiler . compileExpression ( operands [ 0 ] , Type . auto ) ;
2522+ var type = compiler . currentType ;
2523+ if ( type . isValue ) {
2524+ let arg1 : ExpressionRef ;
2525+ if ( ! typeArguments && left . isNumericLiteral ) {
2526+ // prefer right type
2527+ arg1 = compiler . compileExpression (
2528+ operands [ 1 ] ,
2529+ type
2530+ ) ;
2531+ if ( compiler . currentType != type ) {
2532+ arg0 = compiler . compileExpression (
2533+ left ,
2534+ ( type = compiler . currentType ) ,
2535+ Constraints . CONV_IMPLICIT
2536+ ) ;
2537+ }
2538+ } else {
2539+ arg1 = compiler . compileExpression (
2540+ operands [ 1 ] ,
2541+ type ,
2542+ Constraints . CONV_IMPLICIT
2543+ ) ;
2544+ }
2545+ if ( type . isNumericValue ) {
2546+ compiler . currentType = Type . i32 ;
2547+ return compiler . makeNe ( arg0 , arg1 , type , ctx . reportNode ) ;
2548+ }
2549+ }
2550+ compiler . error (
2551+ DiagnosticCode . Operation_0_cannot_be_applied_to_type_1 ,
2552+ ctx . reportNode . typeArgumentsRange ,
2553+ "ne" ,
2554+ type . toString ( )
2555+ ) ;
2556+ return module . unreachable ( ) ;
2557+ }
2558+ builtins . set ( BuiltinNames . ne , builtin_ne ) ;
2559+
24392560// === Atomics ================================================================================
24402561
24412562// atomic.load<T!>(offset: usize, immOffset?: usize) -> T*
@@ -6679,6 +6800,78 @@ function builtin_f64_div(ctx: BuiltinContext): ExpressionRef {
66796800}
66806801builtins . set ( BuiltinNames . f64_div , builtin_f64_div ) ;
66816802
6803+ // i32.eq -> eq<i32>
6804+ function builtin_i32_eq ( ctx : BuiltinContext ) : ExpressionRef {
6805+ checkTypeAbsent ( ctx ) ;
6806+ ctx . typeArguments = [ Type . i32 ] ;
6807+ ctx . contextualType = Type . i32 ;
6808+ return builtin_eq ( ctx ) ;
6809+ }
6810+ builtins . set ( BuiltinNames . i32_eq , builtin_i32_eq ) ;
6811+
6812+ // i64.eq -> eq<i64>
6813+ function builtin_i64_eq ( ctx : BuiltinContext ) : ExpressionRef {
6814+ checkTypeAbsent ( ctx ) ;
6815+ ctx . typeArguments = [ Type . i64 ] ;
6816+ ctx . contextualType = Type . i32 ;
6817+ return builtin_eq ( ctx ) ;
6818+ }
6819+ builtins . set ( BuiltinNames . i64_eq , builtin_i64_eq ) ;
6820+
6821+ // f32.eq -> eq<f32>
6822+ function builtin_f32_eq ( ctx : BuiltinContext ) : ExpressionRef {
6823+ checkTypeAbsent ( ctx ) ;
6824+ ctx . typeArguments = [ Type . f32 ] ;
6825+ ctx . contextualType = Type . i32 ;
6826+ return builtin_eq ( ctx ) ;
6827+ }
6828+ builtins . set ( BuiltinNames . f32_eq , builtin_f32_eq ) ;
6829+
6830+ // f64.eq -> eq<f64>
6831+ function builtin_f64_eq ( ctx : BuiltinContext ) : ExpressionRef {
6832+ checkTypeAbsent ( ctx ) ;
6833+ ctx . typeArguments = [ Type . f64 ] ;
6834+ ctx . contextualType = Type . i32 ;
6835+ return builtin_eq ( ctx ) ;
6836+ }
6837+ builtins . set ( BuiltinNames . f64_eq , builtin_f64_eq ) ;
6838+
6839+ // i32.ne -> ne<i32>
6840+ function builtin_i32_ne ( ctx : BuiltinContext ) : ExpressionRef {
6841+ checkTypeAbsent ( ctx ) ;
6842+ ctx . typeArguments = [ Type . i32 ] ;
6843+ ctx . contextualType = Type . i32 ;
6844+ return builtin_ne ( ctx ) ;
6845+ }
6846+ builtins . set ( BuiltinNames . i32_ne , builtin_i32_ne ) ;
6847+
6848+ // i64.ne -> ne<i64>
6849+ function builtin_i64_ne ( ctx : BuiltinContext ) : ExpressionRef {
6850+ checkTypeAbsent ( ctx ) ;
6851+ ctx . typeArguments = [ Type . i64 ] ;
6852+ ctx . contextualType = Type . i32 ;
6853+ return builtin_ne ( ctx ) ;
6854+ }
6855+ builtins . set ( BuiltinNames . i64_ne , builtin_i64_ne ) ;
6856+
6857+ // f32.ne -> ne<f32>
6858+ function builtin_f32_ne ( ctx : BuiltinContext ) : ExpressionRef {
6859+ checkTypeAbsent ( ctx ) ;
6860+ ctx . typeArguments = [ Type . f32 ] ;
6861+ ctx . contextualType = Type . i32 ;
6862+ return builtin_ne ( ctx ) ;
6863+ }
6864+ builtins . set ( BuiltinNames . f32_ne , builtin_f32_ne ) ;
6865+
6866+ // f64.ne-> ne<f64>
6867+ function builtin_f64_ne ( ctx : BuiltinContext ) : ExpressionRef {
6868+ checkTypeAbsent ( ctx ) ;
6869+ ctx . typeArguments = [ Type . f64 ] ;
6870+ ctx . contextualType = Type . i32 ;
6871+ return builtin_ne ( ctx ) ;
6872+ }
6873+ builtins . set ( BuiltinNames . f64_ne , builtin_f64_ne ) ;
6874+
66826875// i32.load8_s -> <i32>load<i8>
66836876function builtin_i32_load8_s ( ctx : BuiltinContext ) : ExpressionRef {
66846877 checkTypeAbsent ( ctx ) ;
0 commit comments