@@ -972,6 +972,7 @@ export function generate_wasm_body (
972
972
append_stloc_tail ( builder , getArgU16 ( ip , 1 ) , isI32 ? WasmOpcode . i32_store : WasmOpcode . i64_store ) ;
973
973
break ;
974
974
}
975
+
975
976
case MintOpcode . MINT_MONO_CMPXCHG_I4 :
976
977
builder . local ( "pLocals" ) ;
977
978
append_ldloc ( builder , getArgU16 ( ip , 2 ) , WasmOpcode . i32_load ) ; // dest
@@ -992,6 +993,33 @@ export function generate_wasm_body (
992
993
builder . callImport ( "cmpxchg_i64" ) ;
993
994
break ;
994
995
996
+ case MintOpcode . MINT_FMA :
997
+ case MintOpcode . MINT_FMAF : {
998
+ const isF32 = ( opcode === MintOpcode . MINT_FMAF ) ,
999
+ loadOp = isF32 ? WasmOpcode . f32_load : WasmOpcode . f64_load ,
1000
+ storeOp = isF32 ? WasmOpcode . f32_store : WasmOpcode . f64_store ;
1001
+
1002
+ builder . local ( "pLocals" ) ;
1003
+
1004
+ // LOCAL_VAR (ip [1], double) = fma (LOCAL_VAR (ip [2], double), LOCAL_VAR (ip [3], double), LOCAL_VAR (ip [4], double));
1005
+ append_ldloc ( builder , getArgU16 ( ip , 2 ) , loadOp ) ;
1006
+ if ( isF32 )
1007
+ builder . appendU8 ( WasmOpcode . f64_promote_f32 ) ;
1008
+ append_ldloc ( builder , getArgU16 ( ip , 3 ) , loadOp ) ;
1009
+ if ( isF32 )
1010
+ builder . appendU8 ( WasmOpcode . f64_promote_f32 ) ;
1011
+ append_ldloc ( builder , getArgU16 ( ip , 4 ) , loadOp ) ;
1012
+ if ( isF32 )
1013
+ builder . appendU8 ( WasmOpcode . f64_promote_f32 ) ;
1014
+
1015
+ builder . callImport ( "fma" ) ;
1016
+
1017
+ if ( isF32 )
1018
+ builder . appendU8 ( WasmOpcode . f32_demote_f64 ) ;
1019
+ append_stloc_tail ( builder , getArgU16 ( ip , 1 ) , storeOp ) ;
1020
+ break ;
1021
+ }
1022
+
995
1023
default :
996
1024
if (
997
1025
(
@@ -1064,7 +1092,7 @@ export function generate_wasm_body (
1064
1092
( opcode >= MintOpcode . MINT_LDELEM_I1 ) &&
1065
1093
( opcode <= MintOpcode . MINT_LDLEN )
1066
1094
) {
1067
- if ( ! emit_arrayop ( builder , ip , opcode ) )
1095
+ if ( ! emit_arrayop ( builder , frame , ip , opcode ) )
1068
1096
ip = abort ;
1069
1097
} else if (
1070
1098
( opcode >= MintOpcode . MINT_BRFALSE_I4_SP ) &&
@@ -2478,113 +2506,66 @@ function emit_relop_branch (builder: WasmBuilder, ip: MintOpcodePtr, opcode: Min
2478
2506
return emit_branch ( builder , ip , opcode , displacement ) ;
2479
2507
}
2480
2508
2509
+ const mathIntrinsicTable : { [ opcode : number ] : [ isUnary : boolean , isF32 : boolean , opcodeOrFuncName : WasmOpcode | string ] } = {
2510
+ [ MintOpcode . MINT_SQRT ] : [ true , false , WasmOpcode . f64_sqrt ] ,
2511
+ [ MintOpcode . MINT_SQRTF ] : [ true , true , WasmOpcode . f32_sqrt ] ,
2512
+ [ MintOpcode . MINT_CEILING ] : [ true , false , WasmOpcode . f64_ceil ] ,
2513
+ [ MintOpcode . MINT_CEILINGF ] : [ true , true , WasmOpcode . f32_ceil ] ,
2514
+ [ MintOpcode . MINT_FLOOR ] : [ true , false , WasmOpcode . f64_floor ] ,
2515
+ [ MintOpcode . MINT_FLOORF ] : [ true , true , WasmOpcode . f32_floor ] ,
2516
+ [ MintOpcode . MINT_ABS ] : [ true , false , WasmOpcode . f64_abs ] ,
2517
+ [ MintOpcode . MINT_ABSF ] : [ true , true , WasmOpcode . f32_abs ] ,
2518
+ [ MintOpcode . MINT_MIN ] : [ true , false , WasmOpcode . f64_min ] ,
2519
+ [ MintOpcode . MINT_MINF ] : [ true , true , WasmOpcode . f32_min ] ,
2520
+ [ MintOpcode . MINT_MAX ] : [ true , false , WasmOpcode . f64_max ] ,
2521
+ [ MintOpcode . MINT_MAXF ] : [ true , true , WasmOpcode . f32_max ] ,
2522
+
2523
+ [ MintOpcode . MINT_ACOS ] : [ true , false , "acos" ] ,
2524
+ [ MintOpcode . MINT_ACOSF ] : [ true , true , "acos" ] ,
2525
+ [ MintOpcode . MINT_COS ] : [ true , false , "cos" ] ,
2526
+ [ MintOpcode . MINT_COSF ] : [ true , true , "cos" ] ,
2527
+ [ MintOpcode . MINT_ASIN ] : [ true , false , "asin" ] ,
2528
+ [ MintOpcode . MINT_ASINF ] : [ true , true , "asin" ] ,
2529
+ [ MintOpcode . MINT_SIN ] : [ true , false , "sin" ] ,
2530
+ [ MintOpcode . MINT_SINF ] : [ true , true , "sin" ] ,
2531
+ [ MintOpcode . MINT_ATAN ] : [ true , false , "atan" ] ,
2532
+ [ MintOpcode . MINT_ATANF ] : [ true , true , "atan" ] ,
2533
+ [ MintOpcode . MINT_TAN ] : [ true , false , "tan" ] ,
2534
+ [ MintOpcode . MINT_TANF ] : [ true , true , "tan" ] ,
2535
+ [ MintOpcode . MINT_EXP ] : [ true , false , "exp" ] ,
2536
+ [ MintOpcode . MINT_EXPF ] : [ true , true , "exp" ] ,
2537
+ [ MintOpcode . MINT_LOG ] : [ true , false , "log" ] ,
2538
+ [ MintOpcode . MINT_LOGF ] : [ true , true , "log" ] ,
2539
+ [ MintOpcode . MINT_LOG2 ] : [ true , false , "log2" ] ,
2540
+ [ MintOpcode . MINT_LOG2F ] : [ true , true , "log2" ] ,
2541
+ [ MintOpcode . MINT_LOG10 ] : [ true , false , "log10" ] ,
2542
+ [ MintOpcode . MINT_LOG10F ] : [ true , true , "log10" ] ,
2543
+
2544
+ [ MintOpcode . MINT_ATAN2 ] : [ false , false , "atan2" ] ,
2545
+ [ MintOpcode . MINT_ATAN2F ] : [ false , true , "atan2" ] ,
2546
+ [ MintOpcode . MINT_POW ] : [ false , false , "pow" ] ,
2547
+ [ MintOpcode . MINT_POWF ] : [ false , true , "pow" ] ,
2548
+ [ MintOpcode . MINT_REM_R4 ] : [ false , true , "rem" ] ,
2549
+ [ MintOpcode . MINT_REM_R8 ] : [ false , false , "rem" ] ,
2550
+ } ;
2551
+
2481
2552
function emit_math_intrinsic ( builder : WasmBuilder , ip : MintOpcodePtr , opcode : MintOpcode ) : boolean {
2482
2553
let isUnary : boolean , isF32 : boolean , name : string | undefined ;
2483
2554
let wasmOp : WasmOpcode | undefined ;
2484
2555
const destOffset = getArgU16 ( ip , 1 ) ,
2485
2556
srcOffset = getArgU16 ( ip , 2 ) ,
2486
2557
rhsOffset = getArgU16 ( ip , 3 ) ;
2487
2558
2488
- switch ( opcode ) {
2489
- // oddly the interpreter has no opcodes for abs!
2490
- case MintOpcode . MINT_SQRT :
2491
- case MintOpcode . MINT_SQRTF :
2492
- isUnary = true ;
2493
- isF32 = ( opcode === MintOpcode . MINT_SQRTF ) ;
2494
- wasmOp = isF32
2495
- ? WasmOpcode . f32_sqrt
2496
- : WasmOpcode . f64_sqrt ;
2497
- break ;
2498
- case MintOpcode . MINT_CEILING :
2499
- case MintOpcode . MINT_CEILINGF :
2500
- isUnary = true ;
2501
- isF32 = ( opcode === MintOpcode . MINT_CEILINGF ) ;
2502
- wasmOp = isF32
2503
- ? WasmOpcode . f32_ceil
2504
- : WasmOpcode . f64_ceil ;
2505
- break ;
2506
- case MintOpcode . MINT_FLOOR :
2507
- case MintOpcode . MINT_FLOORF :
2508
- isUnary = true ;
2509
- isF32 = ( opcode === MintOpcode . MINT_FLOORF ) ;
2510
- wasmOp = isF32
2511
- ? WasmOpcode . f32_floor
2512
- : WasmOpcode . f64_floor ;
2513
- break ;
2514
- case MintOpcode . MINT_ABS :
2515
- case MintOpcode . MINT_ABSF :
2516
- isUnary = true ;
2517
- isF32 = ( opcode === MintOpcode . MINT_ABSF ) ;
2518
- wasmOp = isF32
2519
- ? WasmOpcode . f32_abs
2520
- : WasmOpcode . f64_abs ;
2521
- break ;
2522
- case MintOpcode . MINT_REM_R4 :
2523
- case MintOpcode . MINT_REM_R8 :
2524
- isUnary = false ;
2525
- isF32 = ( opcode === MintOpcode . MINT_REM_R4 ) ;
2526
- name = "rem" ;
2527
- break ;
2528
- case MintOpcode . MINT_ATAN2 :
2529
- case MintOpcode . MINT_ATAN2F :
2530
- isUnary = false ;
2531
- isF32 = ( opcode === MintOpcode . MINT_ATAN2F ) ;
2532
- name = "atan2" ;
2533
- break ;
2534
- case MintOpcode . MINT_ACOS :
2535
- case MintOpcode . MINT_ACOSF :
2536
- isUnary = true ;
2537
- isF32 = ( opcode === MintOpcode . MINT_ACOSF ) ;
2538
- name = "acos" ;
2539
- break ;
2540
- case MintOpcode . MINT_COS :
2541
- case MintOpcode . MINT_COSF :
2542
- isUnary = true ;
2543
- isF32 = ( opcode === MintOpcode . MINT_COSF ) ;
2544
- name = "cos" ;
2545
- break ;
2546
- case MintOpcode . MINT_SIN :
2547
- case MintOpcode . MINT_SINF :
2548
- isUnary = true ;
2549
- isF32 = ( opcode === MintOpcode . MINT_SINF ) ;
2550
- name = "sin" ;
2551
- break ;
2552
- case MintOpcode . MINT_ASIN :
2553
- case MintOpcode . MINT_ASINF :
2554
- isUnary = true ;
2555
- isF32 = ( opcode === MintOpcode . MINT_ASINF ) ;
2556
- name = "asin" ;
2557
- break ;
2558
- case MintOpcode . MINT_TAN :
2559
- case MintOpcode . MINT_TANF :
2560
- isUnary = true ;
2561
- isF32 = ( opcode === MintOpcode . MINT_TANF ) ;
2562
- name = "tan" ;
2563
- break ;
2564
- case MintOpcode . MINT_ATAN :
2565
- case MintOpcode . MINT_ATANF :
2566
- isUnary = true ;
2567
- isF32 = ( opcode === MintOpcode . MINT_ATANF ) ;
2568
- name = "atan" ;
2569
- break ;
2570
- case MintOpcode . MINT_MIN :
2571
- case MintOpcode . MINT_MINF :
2572
- isUnary = false ;
2573
- isF32 = ( opcode === MintOpcode . MINT_MINF ) ;
2574
- wasmOp = isF32
2575
- ? WasmOpcode . f32_min
2576
- : WasmOpcode . f64_min ;
2577
- break ;
2578
- case MintOpcode . MINT_MAX :
2579
- case MintOpcode . MINT_MAXF :
2580
- isUnary = false ;
2581
- isF32 = ( opcode === MintOpcode . MINT_MAXF ) ;
2582
- wasmOp = isF32
2583
- ? WasmOpcode . f32_max
2584
- : WasmOpcode . f64_max ;
2585
- break ;
2586
- default :
2587
- return false ;
2559
+ const tableEntry = mathIntrinsicTable [ opcode ] ;
2560
+ if ( tableEntry ) {
2561
+ isUnary = tableEntry [ 0 ] ;
2562
+ isF32 = tableEntry [ 1 ] ;
2563
+ if ( typeof ( tableEntry [ 2 ] ) === "string" )
2564
+ name = tableEntry [ 2 ] ;
2565
+ else
2566
+ wasmOp = tableEntry [ 2 ] ;
2567
+ } else {
2568
+ return false ;
2588
2569
}
2589
2570
2590
2571
// Pre-load locals for the stloc at the end
@@ -2859,7 +2840,7 @@ function append_getelema1 (
2859
2840
// append_getelema1 leaves the address on the stack
2860
2841
}
2861
2842
2862
- function emit_arrayop ( builder : WasmBuilder , ip : MintOpcodePtr , opcode : MintOpcode ) : boolean {
2843
+ function emit_arrayop ( builder : WasmBuilder , frame : NativePointer , ip : MintOpcodePtr , opcode : MintOpcode ) : boolean {
2863
2844
const isLoad = (
2864
2845
( opcode <= MintOpcode . MINT_LDELEMA_TC ) &&
2865
2846
( opcode >= MintOpcode . MINT_LDELEM_I1 )
@@ -2977,6 +2958,17 @@ function emit_arrayop (builder: WasmBuilder, ip: MintOpcodePtr, opcode: MintOpco
2977
2958
invalidate_local_range ( getArgU16 ( ip , 1 ) , elementSize ) ;
2978
2959
return true ;
2979
2960
}
2961
+ case MintOpcode . MINT_STELEM_VT : {
2962
+ const elementSize = getArgU16 ( ip , 5 ) ,
2963
+ klass = get_imethod_data ( frame , getArgU16 ( ip , 4 ) ) ;
2964
+ // dest
2965
+ append_getelema1 ( builder , ip , objectOffset , indexOffset , elementSize ) ;
2966
+ // src
2967
+ append_ldloca ( builder , valueOffset , 0 ) ;
2968
+ builder . ptr_const ( klass ) ;
2969
+ builder . callImport ( "value_copy" ) ;
2970
+ return true ;
2971
+ }
2980
2972
default :
2981
2973
return false ;
2982
2974
}
0 commit comments