@@ -48,29 +48,36 @@ i16 GetStackTopIndex (IM3Compilation o)
4848}
4949
5050
51- u8 GetStackTopType (IM3Compilation o )
51+ u8 GetStackTopTypeAtOffset (IM3Compilation o , u16 i_offset )
5252{
5353 u8 type = c_m3Type_none ;
54-
55- if (o -> stackIndex )
56- type = o -> typeStack [o -> stackIndex - 1 ];
57-
54+
55+ ++ i_offset ;
56+ if (o -> stackIndex >= i_offset )
57+ type = o -> typeStack [o -> stackIndex - i_offset ];
58+
5859 return type ;
5960}
6061
6162
62- u8 GetStackType (IM3Compilation o , u16 i_offset )
63+ u8 GetStackTopType (IM3Compilation o )
6364{
64- u8 type = c_m3Type_none ;
65+ return GetStackTopTypeAtOffset (o , 0 );
66+ }
6567
66- ++ i_offset ;
67- if (o -> stackIndex > i_offset )
68- type = o -> typeStack [o -> stackIndex - i_offset ];
6968
69+ u8 GetStackBottomType (IM3Compilation o , u16 i_offset )
70+ {
71+ u8 type = c_m3Type_none ;
72+
73+ if (i_offset < o -> stackIndex )
74+ type = o -> typeStack [i_offset ];
75+
7076 return type ;
7177}
7278
7379
80+
7481u8 GetBlockType (IM3Compilation o )
7582{
7683 return o -> block .type ;
@@ -83,17 +90,6 @@ bool BlockHasType (IM3Compilation o)
8390}
8491
8592
86- bool IsStackTopTypeInt (IM3Compilation o )
87- {
88- return IsIntType (GetStackTopType (o ));
89- }
90-
91-
92- bool IsStackTopTypeFp (IM3Compilation o )
93- {
94- return IsFpType (GetStackTopType (o ));
95- }
96-
9793i16 GetNumBlockValues (IM3Compilation o )
9894{
9995 return o -> stackIndex - o -> block .initStackIndex ;
@@ -599,12 +595,15 @@ M3Result PreservedCopyTopSlot (IM3Compilation o, u16 i_destSlot, u16 i_preserv
599595
600596 IM3Operation op ;
601597
598+ u8 type = GetStackTopType (o );
599+
602600 if (IsStackTopInRegister (o ))
603601 {
604- bool isFp = IsStackTopTypeFp (o );
605- op = isFp ? op_PreserveSetSlot_f64 : op_PreserveSetSlot_i64 ;
602+ const IM3Operation c_preserveSetSlot [] = { NULL , op_PreserveSetSlot_i32 , op_PreserveSetSlot_i64 , op_PreserveSetSlot_f32 , op_PreserveSetSlot_f64 };
603+
604+ op = c_preserveSetSlot [type ];
606605 }
607- else op = op_PreserveCopySlot_64 ;
606+ else op = Is64BitType ( type ) ? op_PreserveCopySlot_64 : op_PreserveCopySlot_32 ;
608607
609608_ (EmitOp (o , op ));
610609 EmitSlotOffset (o , i_destSlot );
@@ -663,22 +662,22 @@ M3Result ReturnStackTop (IM3Compilation o)
663662
664663
665664// if local is unreferenced, o_preservedSlotIndex will be equal to localIndex on return
666- M3Result FindReferencedLocalsWithCurrentBlock (IM3Compilation o , u16 * o_preservedSlotIndex , u32 i_localIndex )
665+ M3Result FindReferencedLocalWithinCurrentBlock (IM3Compilation o , u16 * o_preservedSlotIndex , u32 i_localIndex )
667666{
668667 M3Result result = m3Err_none ;
669668
670- IM3CompilationScope scope = & o -> block ;
671- i16 startIndex = scope -> initStackIndex ;
669+ IM3CompilationScope scope = & o -> block ;
670+ i16 startIndex = scope -> initStackIndex ;
672671
673- while (scope -> opcode == c_waOp_block )
674- {
675- scope = scope -> outer ;
676- if (not scope )
677- break ;
672+ while (scope -> opcode == c_waOp_block )
673+ {
674+ scope = scope -> outer ;
675+ if (not scope )
676+ break ;
678677
679- startIndex = scope -> initStackIndex ;
680- }
681-
678+ startIndex = scope -> initStackIndex ;
679+ }
680+
682681 * o_preservedSlotIndex = (u16 ) i_localIndex ;
683682
684683 for (u32 i = startIndex ; i < o -> stackIndex ; ++ i )
@@ -802,8 +801,7 @@ _ (EmitOp (o, op_Return));
802801}
803802
804803
805- // todo: else maps to nop now.
806- M3Result Compile_Else_End (IM3Compilation o , u8 i_opcode )
804+ M3Result Compile_End (IM3Compilation o , u8 i_opcode )
807805{
808806 M3Result result = m3Err_none ;
809807
@@ -856,7 +854,7 @@ _ (ReadLEB_u32 (& localSlot, & o->wasm, o->wasmEnd)); // printf (
856854 if (localSlot < GetFunctionNumArgsAndLocals (o -> function ))
857855 {
858856 u16 preserveSlot ;
859- _ (FindReferencedLocalsWithCurrentBlock (o , & preserveSlot , localSlot )); // preserve will be different than local, if referenced
857+ _ (FindReferencedLocalWithinCurrentBlock (o , & preserveSlot , localSlot )); // preserve will be different than local, if referenced
860858
861859 if (preserveSlot == localSlot )
862860_ (CopyTopSlot (o , localSlot ))
@@ -906,16 +904,20 @@ M3Result Compile_SetGlobal (IM3Compilation o, M3Global * i_global)
906904 if (i_global -> isMutable )
907905 {
908906 IM3Operation op ;
907+ u8 type = GetStackTopType (o );
909908
910909 if (IsStackTopInRegister (o ))
911- op = IsStackTopTypeFp (o ) ? op_SetGlobal_f64 : op_SetGlobal_i ;
912- else
913- op = op_SetGlobal_s ;
910+ {
911+ const IM3Operation c_setGlobalOps [] = { NULL , op_SetGlobal_i32 , op_SetGlobal_i64 , op_SetGlobal_f32 , op_SetGlobal_f64 };
912+
913+ op = c_setGlobalOps [type ];
914+ }
915+ else op = Is64BitType (type ) ? op_SetGlobal_s64 : op_SetGlobal_s32 ;
914916
915917_ (EmitOp (o , op ));
916918 EmitPointer (o , & i_global -> intValue );
917919
918- if (op == op_SetGlobal_s )
920+ if (IsStackTopInSlot ( o ) )
919921 EmitSlotOffset (o , GetStackTopSlotIndex (o ));
920922
921923_ (Pop (o ));
@@ -1289,11 +1291,11 @@ M3Result PreserveArgsAndLocals (IM3Compilation o)
12891291 for (u32 i = 0 ; i < numArgsAndLocals ; ++ i )
12901292 {
12911293 u16 preservedSlotIndex ;
1292- _ (FindReferencedLocalsWithCurrentBlock (o , & preservedSlotIndex , i ));
1294+ _ (FindReferencedLocalWithinCurrentBlock (o , & preservedSlotIndex , i ));
12931295
12941296 if (preservedSlotIndex != i )
12951297 {
1296- u8 type = GetStackType (o , i );
1298+ u8 type = GetStackBottomType (o , i );
12971299 IM3Operation op = Is64BitType (type ) ? op_CopySlot_64 : op_CopySlot_32 ;
12981300
12991301 EmitOp (o , op );
@@ -1402,13 +1404,11 @@ M3Result Compile_Select (IM3Compilation o, u8 i_opcode)
14021404 { op_Select_f32_rss , op_Select_f32_rrs , op_Select_f32_rsr } }, // selector in reg
14031405 { { op_Select_f64_sss , op_Select_f64_srs , op_Select_f64_ssr }, // selector in slot
14041406 { op_Select_f64_rss , op_Select_f64_rrs , op_Select_f64_rsr } } }; // selector in reg
1405-
1406-
14071407 M3Result result = m3Err_none ;
14081408
14091409 u16 slots [3 ] = { c_slotUnused , c_slotUnused , c_slotUnused };
14101410
1411- u8 type = GetStackType (o , 1 ); // get type of selection
1411+ u8 type = GetStackTopTypeAtOffset (o , 1 ); // get type of selection
14121412
14131413 IM3Operation op = NULL ;
14141414
@@ -1627,13 +1627,14 @@ _ (Compile_Operator (o, i_opcode));
16271627}
16281628
16291629
1630- #define d_singleOp (OP ) { op_##OP, NULL, NULL, NULL } // these aren't actually used by the compiler, just codepage decoding
1631- #define d_emptyOpList () { NULL, NULL, NULL, NULL }
1632- #define d_unaryOpList (TYPE , NAME ) { op_##TYPE##_##NAME##_r, op_##TYPE##_##NAME##_s, NULL, NULL }
1633- #define d_binOpList (TYPE , NAME ) { op_##TYPE##_##NAME##_sr, op_##TYPE##_##NAME##_rs, op_##TYPE##_##NAME##_ss, NULL }
1634- #define d_storeFpOpList (TYPE , NAME ) { op_##TYPE##_##NAME##_sr, op_##TYPE##_##NAME##_rs, op_##TYPE##_##NAME##_ss, op_##TYPE##_##NAME##_rr }
1635- #define d_commutativeBinOpList (TYPE , NAME ) { op_##TYPE##_##NAME##_sr, NULL, op_##TYPE##_##NAME##_ss, NULL }
1636- #define d_convertOpList (OP ) { op_##OP##_r_r, op_##OP##_r_s, op_##OP##_s_r, op_##OP##_s_s }
1630+ // d_singleOp macros aren't actually used by the compiler, just codepage decoding
1631+ #define d_singleOp (OP ) { op_##OP, NULL, NULL, NULL }
1632+ #define d_emptyOpList () { NULL, NULL, NULL, NULL }
1633+ #define d_unaryOpList (TYPE , NAME ) { op_##TYPE##_##NAME##_r, op_##TYPE##_##NAME##_s, NULL, NULL }
1634+ #define d_binOpList (TYPE , NAME ) { op_##TYPE##_##NAME##_rs, op_##TYPE##_##NAME##_sr, op_##TYPE##_##NAME##_ss, NULL }
1635+ #define d_storeFpOpList (TYPE , NAME ) { op_##TYPE##_##NAME##_rs, op_##TYPE##_##NAME##_sr, op_##TYPE##_##NAME##_ss, op_##TYPE##_##NAME##_rr }
1636+ #define d_commutativeBinOpList (TYPE , NAME ) { op_##TYPE##_##NAME##_rs, NULL, op_##TYPE##_##NAME##_ss, NULL }
1637+ #define d_convertOpList (OP ) { op_##OP##_r_r, op_##OP##_r_s, op_##OP##_s_r, op_##OP##_s_s }
16371638
16381639
16391640const M3OpInfo c_operations [] =
@@ -1643,11 +1644,11 @@ const M3OpInfo c_operations [] =
16431644 M3OP ( "block" , 0 , none , d_emptyOpList (), Compile_LoopOrBlock ), // 0x02
16441645 M3OP ( "loop" , 0 , none , d_singleOp (Loop ), Compile_LoopOrBlock ), // 0x03
16451646 M3OP ( "if" , -1 , none , d_emptyOpList (), Compile_If ), // 0x04
1646- M3OP ( "else" , 0 , none , d_emptyOpList (), Compile_Else_End ), // 0x05
1647+ M3OP ( "else" , 0 , none , d_emptyOpList (), Compile_Nop ), // 0x05
16471648
16481649 M3OP_RESERVED , M3OP_RESERVED , M3OP_RESERVED , M3OP_RESERVED , M3OP_RESERVED , // 0x06 - 0x0a
16491650
1650- M3OP ( "end" , 0 , none , d_emptyOpList (), Compile_Else_End ), // 0x0b
1651+ M3OP ( "end" , 0 , none , d_emptyOpList (), Compile_End ), // 0x0b
16511652 M3OP ( "br" , 0 , none , d_singleOp (Branch ), Compile_Branch ), // 0x0c
16521653 M3OP ( "br_if" , -1 , none , { op_BranchIf_r , op_BranchIf_s }, Compile_Branch ), // 0x0d
16531654 M3OP ( "br_table" , -1 , none , d_singleOp (BranchTable ), Compile_BranchTable ), // 0x0e
@@ -1669,7 +1670,7 @@ const M3OpInfo c_operations [] =
16691670 M3OP ( "local.set" , 1 , none , d_emptyOpList (), Compile_SetLocal ), // 0x21
16701671 M3OP ( "local.tee" , 0 , any , d_emptyOpList (), Compile_SetLocal ), // 0x22
16711672 M3OP ( "global.get" , 1 , none , d_singleOp (GetGlobal ), Compile_GetSetGlobal ), // 0x23
1672- M3OP ( "global.set" , 1 , none , { op_SetGlobal_i , op_SetGlobal_s }, Compile_GetSetGlobal ), // 0x24
1673+ M3OP ( "global.set" , 1 , none , d_emptyOpList (), Compile_GetSetGlobal ), // 0x24
16731674
16741675 M3OP_RESERVED , M3OP_RESERVED , M3OP_RESERVED , // 0x25 - 0x27
16751676
@@ -1853,21 +1854,32 @@ const M3OpInfo c_operations [] =
18531854 M3OP ( "f32.reinterpret/i32" , 0 , f_32 , d_convertOpList (f32_Reinterpret_i32 ), Compile_Convert ), // 0xbe
18541855 M3OP ( "f64.reinterpret/i64" , 0 , f_64 , d_convertOpList (f64_Reinterpret_i64 ), Compile_Convert ), // 0xbf
18551856
1857+ // instr ::= ...
1858+ // | 0xC0 => i32.extend8_s
1859+ // | 0xC1 => i32.extend16_s
1860+ // | 0xC2 => i64.extend8_s
1861+ // | 0xC3 => i64.extend16_s
1862+ // | 0xC4 => i64.extend32_s
1863+ //
1864+ M3OP ( "i32.extend8_s" , 0 , i_32 , d_unaryOpList (i32 , Extend8_s ) ), // 0xc0
1865+ M3OP ( "i32.extend16_s" , 0 , i_32 , d_unaryOpList (i32 , Extend16_s ) ), // 0xc1
1866+ M3OP ( "i64.extend8_s" , 0 , i_64 , d_unaryOpList (i64 , Extend8_s ) ), // 0xc2
1867+ M3OP ( "i64.extend16_s" , 0 , i_64 , d_unaryOpList (i64 , Extend16_s ) ), // 0xc3
1868+ M3OP ( "i64.extend32_s" , 0 , i_64 , d_unaryOpList (i64 , Extend32_s ) ), // 0xc4
1869+
18561870# ifdef DEBUG // for codepage logging:
18571871# define d_m3DebugOp (OP ) M3OP (#OP , 0, none, { op_##OP })
1872+ # define d_m3DebugTypedOp (OP ) M3OP (#OP, 0, none, { op_##OP##_i32, op_##OP##_i64, op_##OP##_f32, op_##OP##_f64, })
18581873
18591874 d_m3DebugOp (Const ), d_m3DebugOp (Entry ), d_m3DebugOp (Compile ),
1860- d_m3DebugOp (Bridge ), d_m3DebugOp (End ), d_m3DebugOp ( SetGlobal_s ),
1875+ d_m3DebugOp (Bridge ), d_m3DebugOp (End ),
18611876
18621877 d_m3DebugOp (ContinueLoop ), d_m3DebugOp (ContinueLoopIf ),
18631878
1864- d_m3DebugOp (CopySlot_32 ), // d_m3DebugOp (PreserveCopySlot_32),
1879+ d_m3DebugOp (CopySlot_32 ), d_m3DebugOp (PreserveCopySlot_32 ),
18651880 d_m3DebugOp (CopySlot_64 ), d_m3DebugOp (PreserveCopySlot_64 ),
18661881
1867- d_m3DebugOp (SetRegister_i32 ), d_m3DebugOp (i32_BranchIf_rs ), d_m3DebugOp (SetSlot_i32 ),
1868- d_m3DebugOp (SetRegister_i64 ), d_m3DebugOp (i32_BranchIf_ss ), d_m3DebugOp (SetSlot_i64 ),
1869- d_m3DebugOp (SetRegister_f32 ), d_m3DebugOp (i64_BranchIf_rs ), d_m3DebugOp (SetSlot_f32 ),
1870- d_m3DebugOp (SetRegister_f64 ), d_m3DebugOp (i64_BranchIf_ss ), d_m3DebugOp (SetSlot_f64 ),
1882+ d_m3DebugOp (i32_BranchIf_rs ), d_m3DebugOp (i32_BranchIf_ss ), d_m3DebugOp (i64_BranchIf_rs ), d_m3DebugOp (i64_BranchIf_ss ),
18711883
18721884 d_m3DebugOp (Select_i32_rss ), d_m3DebugOp (Select_i32_srs ), d_m3DebugOp (Select_i32_ssr ), d_m3DebugOp (Select_i32_sss ),
18731885 d_m3DebugOp (Select_i64_rss ), d_m3DebugOp (Select_i64_srs ), d_m3DebugOp (Select_i64_ssr ), d_m3DebugOp (Select_i64_sss ),
@@ -1878,6 +1890,10 @@ const M3OpInfo c_operations [] =
18781890 d_m3DebugOp (Select_f64_sss ), d_m3DebugOp (Select_f64_srs ), d_m3DebugOp (Select_f64_ssr ),
18791891 d_m3DebugOp (Select_f64_rss ), d_m3DebugOp (Select_f64_rrs ), d_m3DebugOp (Select_f64_rsr ),
18801892
1893+ d_m3DebugTypedOp (SetGlobal ), d_m3DebugOp (SetGlobal_s32 ), d_m3DebugOp (SetGlobal_s64 ),
1894+
1895+ d_m3DebugTypedOp (SetRegister ), d_m3DebugTypedOp (SetSlot ), d_m3DebugTypedOp (PreserveSetSlot ),
1896+
18811897# endif
18821898
18831899 M3OP ( "termination ", 0 , c_m3Type_void ) // termination for find_operation_info ()
0 commit comments