@@ -640,55 +640,80 @@ export function compileCall(
640
640
case TypeKind . I8 :
641
641
case TypeKind . I16 :
642
642
case TypeKind . I32 : {
643
+ let currentFunction = compiler . currentFunction ;
644
+
643
645
// possibly overflows, e.g. abs<i8>(-128) == 128
644
- let tempLocal = compiler . currentFunction . getAndFreeTempLocal ( Type . i32 , false ) ;
645
- ret = module . createSelect ( // x > 0 ? x : 0-x
646
- module . createTeeLocal ( tempLocal . index , arg0 ) ,
647
- module . createBinary ( BinaryOp . SubI32 , // ifFalse
648
- module . createI32 ( 0 ) ,
649
- module . createGetLocal ( tempLocal . index , NativeType . I32 )
646
+ let tempLocal1 = currentFunction . getTempLocal ( Type . i32 , false ) ;
647
+ let tempLocalIndex2 = currentFunction . getAndFreeTempLocal ( Type . i32 , false ) . index ;
648
+ let tempLocalIndex1 = tempLocal1 . index ;
649
+
650
+ // (x + (x >> 31)) ^ (x >> 31)
651
+ ret = module . createBinary ( BinaryOp . XorI32 ,
652
+ module . createBinary ( BinaryOp . AddI32 ,
653
+ module . createTeeLocal (
654
+ tempLocalIndex2 ,
655
+ module . createBinary ( BinaryOp . ShrI32 ,
656
+ module . createTeeLocal ( tempLocalIndex1 , arg0 ) ,
657
+ module . createI32 ( 31 )
658
+ )
659
+ ) ,
660
+ module . createGetLocal ( tempLocalIndex1 , NativeType . I32 )
650
661
) ,
651
- module . createBinary ( BinaryOp . GtI32 ,
652
- module . createGetLocal ( tempLocal . index , NativeType . I32 ) ,
653
- module . createI32 ( 0 )
654
- )
662
+ module . createGetLocal ( tempLocalIndex2 , NativeType . I32 )
655
663
) ;
664
+
665
+ currentFunction . freeTempLocal ( tempLocal1 ) ;
656
666
break ;
657
667
}
658
668
case TypeKind . ISIZE : {
659
- let tempLocal = compiler . currentFunction . getAndFreeTempLocal ( compiler . options . usizeType , false ) ;
660
- ret = module . createSelect (
661
- module . createTeeLocal ( tempLocal . index , arg0 ) ,
662
- module . createBinary (
663
- compiler . options . isWasm64
664
- ? BinaryOp . SubI64
665
- : BinaryOp . SubI32 ,
666
- compiler . options . usizeType . toNativeZero ( module ) ,
667
- module . createGetLocal ( tempLocal . index , compiler . options . nativeSizeType )
669
+ let options = compiler . options ;
670
+ let currentFunction = compiler . currentFunction ;
671
+ let wasm64 = options . isWasm64 ;
672
+
673
+ let tempLocal1 = currentFunction . getTempLocal ( options . usizeType , false ) ;
674
+ let tempLocalIndex2 = currentFunction . getAndFreeTempLocal ( options . usizeType , false ) . index ;
675
+ let tempLocalIndex1 = tempLocal1 . index ;
676
+
677
+ ret = module . createBinary ( wasm64 ? BinaryOp . XorI64 : BinaryOp . XorI32 ,
678
+ module . createBinary ( wasm64 ? BinaryOp . AddI64 : BinaryOp . AddI32 ,
679
+ module . createTeeLocal (
680
+ tempLocalIndex2 ,
681
+ module . createBinary ( wasm64 ? BinaryOp . ShrI64 : BinaryOp . ShrI32 ,
682
+ module . createTeeLocal ( tempLocalIndex1 , arg0 ) ,
683
+ wasm64 ? module . createI64 ( 63 ) : module . createI32 ( 31 )
684
+ )
685
+ ) ,
686
+ module . createGetLocal ( tempLocalIndex1 , options . nativeSizeType )
668
687
) ,
669
- module . createBinary (
670
- compiler . options . isWasm64
671
- ? BinaryOp . GtI64
672
- : BinaryOp . GtI32 ,
673
- module . createGetLocal ( tempLocal . index , compiler . options . nativeSizeType ) ,
674
- compiler . options . usizeType . toNativeZero ( module )
675
- )
688
+ module . createGetLocal ( tempLocalIndex2 , options . nativeSizeType )
676
689
) ;
690
+
691
+ currentFunction . freeTempLocal ( tempLocal1 ) ;
677
692
break ;
678
693
}
679
694
case TypeKind . I64 : {
680
- let tempLocal = compiler . currentFunction . getAndFreeTempLocal ( Type . i64 , false ) ;
681
- ret = module . createSelect (
682
- module . createTeeLocal ( tempLocal . index , arg0 ) ,
683
- module . createBinary ( BinaryOp . SubI64 ,
684
- module . createI64 ( 0 , 0 ) ,
685
- module . createGetLocal ( tempLocal . index , NativeType . I64 ) ,
695
+ let currentFunction = compiler . currentFunction ;
696
+
697
+ let tempLocal1 = currentFunction . getTempLocal ( Type . i64 , false ) ;
698
+ let tempLocalIndex2 = currentFunction . getAndFreeTempLocal ( Type . i64 , false ) . index ;
699
+ let tempLocalIndex1 = tempLocal1 . index ;
700
+
701
+ // (x + (x >> 63)) ^ (x >> 63)
702
+ ret = module . createBinary ( BinaryOp . XorI64 ,
703
+ module . createBinary ( BinaryOp . AddI64 ,
704
+ module . createTeeLocal (
705
+ tempLocalIndex2 ,
706
+ module . createBinary ( BinaryOp . ShrI64 ,
707
+ module . createTeeLocal ( tempLocalIndex1 , arg0 ) ,
708
+ module . createI64 ( 63 )
709
+ )
710
+ ) ,
711
+ module . createGetLocal ( tempLocalIndex1 , NativeType . I64 )
686
712
) ,
687
- module . createBinary ( BinaryOp . GtI64 ,
688
- module . createGetLocal ( tempLocal . index , NativeType . I64 ) ,
689
- module . createI64 ( 0 , 0 )
690
- )
713
+ module . createGetLocal ( tempLocalIndex2 , NativeType . I64 )
691
714
) ;
715
+
716
+ currentFunction . freeTempLocal ( tempLocal1 ) ;
692
717
break ;
693
718
}
694
719
case TypeKind . USIZE : {
0 commit comments