@@ -748,16 +748,22 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
748
748
//
749
749
// MOVQ g_panic(CX), BX
750
750
// TESTQ BX, BX
751
- // JEQ end
751
+ // JNE checkargp
752
+ // end:
753
+ // NOP
754
+ // ... rest of function ...
755
+ // checkargp:
752
756
// LEAQ (autoffset+8)(SP), DI
753
757
// CMPQ panic_argp(BX), DI
754
758
// JNE end
755
- // MOVQ SP, panic_argp(BX)
756
- // end:
757
- // NOP
759
+ // MOVQ SP, panic_argp(BX)
760
+ // JMP end
758
761
//
759
762
// The NOP is needed to give the jumps somewhere to land.
760
763
// It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes.
764
+ //
765
+ // The layout is chosen to help static branch prediction:
766
+ // Both conditional jumps are unlikely, so they are arranged to be forward jumps.
761
767
762
768
// MOVQ g_panic(CX), BX
763
769
p = obj .Appendp (ctxt , p )
@@ -789,14 +795,23 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
789
795
p .As = ATESTL
790
796
}
791
797
792
- // JEQ end
793
- p = obj .Appendp (ctxt , p )
794
- p .As = AJEQ
795
- p .To .Type = obj .TYPE_BRANCH
796
- p1 := p
798
+ // JNE checkargp (checkargp to be resolved later)
799
+ jne := obj .Appendp (ctxt , p )
800
+ jne .As = AJNE
801
+ jne .To .Type = obj .TYPE_BRANCH
802
+
803
+ // end:
804
+ // NOP
805
+ end := obj .Appendp (ctxt , jne )
806
+ end .As = obj .ANOP
807
+
808
+ // Fast forward to end of function.
809
+ var last * obj.Prog
810
+ for last = end ; last .Link != nil ; last = last .Link {
811
+ }
797
812
798
813
// LEAQ (autoffset+8)(SP), DI
799
- p = obj .Appendp (ctxt , p )
814
+ p = obj .Appendp (ctxt , last )
800
815
p .As = ALEAQ
801
816
p .From .Type = obj .TYPE_MEM
802
817
p .From .Reg = REG_SP
@@ -807,6 +822,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
807
822
p .As = ALEAL
808
823
}
809
824
825
+ // Set jne branch target.
826
+ jne .Pcond = p
827
+
810
828
// CMPQ panic_argp(BX), DI
811
829
p = obj .Appendp (ctxt , p )
812
830
p .As = ACMPQ
@@ -830,7 +848,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
830
848
p = obj .Appendp (ctxt , p )
831
849
p .As = AJNE
832
850
p .To .Type = obj .TYPE_BRANCH
833
- p2 := p
851
+ p . Pcond = end
834
852
835
853
// MOVQ SP, panic_argp(BX)
836
854
p = obj .Appendp (ctxt , p )
@@ -851,13 +869,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
851
869
p .As = AMOVL
852
870
}
853
871
854
- // NOP
872
+ // JMP end
855
873
p = obj .Appendp (ctxt , p )
856
- p .As = obj .ANOP
874
+ p .As = obj .AJMP
875
+ p .To .Type = obj .TYPE_BRANCH
876
+ p .Pcond = end
857
877
858
- // Set targets for jumps above to the NOP
859
- p1 .Pcond = p
860
- p2 .Pcond = p
878
+ // Reset p for following code.
879
+ p = end
861
880
}
862
881
863
882
for ; p != nil ; p = p .Link {
0 commit comments