@@ -542,32 +542,35 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
542
542
c .autosize += 8
543
543
}
544
544
545
- if c .autosize != 0 && c .autosize & (16 - 1 ) != 0 {
546
- // The frame includes an LR.
547
- // If the frame size is 8, it's only an LR,
548
- // so there's no potential for breaking references to
549
- // local variables by growing the frame size,
550
- // because there are no local variables.
551
- // But otherwise, if there is a non-empty locals section,
552
- // the author of the code is responsible for making sure
553
- // that the frame size is 8 mod 16.
554
- if c .autosize == 8 {
555
- c .autosize += 8
556
- c .cursym .Func .Locals += 8
545
+ if c .autosize != 0 {
546
+ extrasize := int32 (0 )
547
+ if c .autosize % 16 == 8 {
548
+ // Allocate extra 8 bytes on the frame top to save FP
549
+ extrasize = 8
550
+ } else if c .autosize & (16 - 1 ) == 0 {
551
+ // Allocate extra 16 bytes to save FP for the old frame whose size is 8 mod 16
552
+ extrasize = 16
557
553
} else {
558
- c .ctxt .Diag ("%v: unaligned frame size %d - must be 8 mod 16 (or 0) " , p , c .autosize - 8 )
554
+ c .ctxt .Diag ("%v: unaligned frame size %d - must be 16 aligned " , p , c .autosize - 8 )
559
555
}
556
+ c .autosize += extrasize
557
+ c .cursym .Func .Locals += extrasize
558
+
559
+ // low 32 bits for autosize
560
+ // high 32 bits for extrasize
561
+ p .To .Offset = int64 (c .autosize ) | int64 (extrasize )<< 32
562
+ } else {
563
+ // NOFRAME
564
+ p .To .Offset = 0
560
565
}
566
+
561
567
if c .autosize == 0 && c .cursym .Func .Text .Mark & LEAF == 0 {
562
568
if c .ctxt .Debugvlog {
563
569
c .ctxt .Logf ("save suppressed in: %s\n " , c .cursym .Func .Text .From .Sym .Name )
564
570
}
565
571
c .cursym .Func .Text .Mark |= LEAF
566
572
}
567
573
568
- // FP offsets need an updated p.To.Offset.
569
- p .To .Offset = int64 (c .autosize ) - 8
570
-
571
574
if cursym .Func .Text .Mark & LEAF != 0 {
572
575
cursym .Set (obj .AttrLeaf , true )
573
576
if p .From .Sym .NoFrame () {
@@ -631,6 +634,26 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
631
634
q1 .Spadj = aoffset
632
635
}
633
636
637
+ if objabi .Framepointer_enabled (objabi .GOOS , objabi .GOARCH ) {
638
+ q1 = obj .Appendp (q1 , c .newprog )
639
+ q1 .Pos = p .Pos
640
+ q1 .As = AMOVD
641
+ q1 .From .Type = obj .TYPE_REG
642
+ q1 .From .Reg = REGFP
643
+ q1 .To .Type = obj .TYPE_MEM
644
+ q1 .To .Reg = REGSP
645
+ q1 .To .Offset = - 8
646
+
647
+ q1 = obj .Appendp (q1 , c .newprog )
648
+ q1 .Pos = p .Pos
649
+ q1 .As = ASUB
650
+ q1 .From .Type = obj .TYPE_CONST
651
+ q1 .From .Offset = 8
652
+ q1 .Reg = REGSP
653
+ q1 .To .Type = obj .TYPE_REG
654
+ q1 .To .Reg = REGFP
655
+ }
656
+
634
657
if c .cursym .Func .Text .From .Sym .Wrapper () {
635
658
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
636
659
//
@@ -753,9 +776,30 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
753
776
p .To .Type = obj .TYPE_REG
754
777
p .To .Reg = REGSP
755
778
p .Spadj = - c .autosize
779
+
780
+ if objabi .Framepointer_enabled (objabi .GOOS , objabi .GOARCH ) {
781
+ p = obj .Appendp (p , c .newprog )
782
+ p .As = ASUB
783
+ p .From .Type = obj .TYPE_CONST
784
+ p .From .Offset = 8
785
+ p .Reg = REGSP
786
+ p .To .Type = obj .TYPE_REG
787
+ p .To .Reg = REGFP
788
+ }
756
789
}
757
790
} else {
758
791
/* want write-back pre-indexed SP+autosize -> SP, loading REGLINK*/
792
+
793
+ if objabi .Framepointer_enabled (objabi .GOOS , objabi .GOARCH ) {
794
+ p .As = AMOVD
795
+ p .From .Type = obj .TYPE_MEM
796
+ p .From .Reg = REGSP
797
+ p .From .Offset = - 8
798
+ p .To .Type = obj .TYPE_REG
799
+ p .To .Reg = REGFP
800
+ p = obj .Appendp (p , c .newprog )
801
+ }
802
+
759
803
aoffset := c .autosize
760
804
761
805
if aoffset > 0xF0 {
@@ -814,7 +858,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
814
858
p .Spadj = int32 (+ p .From .Offset )
815
859
}
816
860
}
817
- break
818
861
819
862
case obj .AGETCALLERPC :
820
863
if cursym .Leaf () {
@@ -828,6 +871,112 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
828
871
p .From .Type = obj .TYPE_MEM
829
872
p .From .Reg = REGSP
830
873
}
874
+
875
+ case obj .ADUFFCOPY :
876
+ if objabi .Framepointer_enabled (objabi .GOOS , objabi .GOARCH ) {
877
+ // ADR ret_addr, R27
878
+ // STP (FP, R27), -24(SP)
879
+ // SUB 24, SP, FP
880
+ // DUFFCOPY
881
+ // ret_addr:
882
+ // SUB 8, SP, FP
883
+
884
+ q1 := p
885
+ // copy DUFFCOPY from q1 to q4
886
+ q4 := obj .Appendp (p , c .newprog )
887
+ q4 .Pos = p .Pos
888
+ q4 .As = obj .ADUFFCOPY
889
+ q4 .To = p .To
890
+
891
+ q1 .As = AADR
892
+ q1 .From .Type = obj .TYPE_BRANCH
893
+ q1 .To .Type = obj .TYPE_REG
894
+ q1 .To .Reg = REG_R27
895
+
896
+ q2 := obj .Appendp (q1 , c .newprog )
897
+ q2 .Pos = p .Pos
898
+ q2 .As = ASTP
899
+ q2 .From .Type = obj .TYPE_REGREG
900
+ q2 .From .Reg = REGFP
901
+ q2 .From .Offset = int64 (REG_R27 )
902
+ q2 .To .Type = obj .TYPE_MEM
903
+ q2 .To .Reg = REGSP
904
+ q2 .To .Offset = - 24
905
+
906
+ // maintaine FP for DUFFCOPY
907
+ q3 := obj .Appendp (q2 , c .newprog )
908
+ q3 .Pos = p .Pos
909
+ q3 .As = ASUB
910
+ q3 .From .Type = obj .TYPE_CONST
911
+ q3 .From .Offset = 24
912
+ q3 .Reg = REGSP
913
+ q3 .To .Type = obj .TYPE_REG
914
+ q3 .To .Reg = REGFP
915
+
916
+ q5 := obj .Appendp (q4 , c .newprog )
917
+ q5 .Pos = p .Pos
918
+ q5 .As = ASUB
919
+ q5 .From .Type = obj .TYPE_CONST
920
+ q5 .From .Offset = 8
921
+ q5 .Reg = REGSP
922
+ q5 .To .Type = obj .TYPE_REG
923
+ q5 .To .Reg = REGFP
924
+ q1 .Pcond = q5
925
+ p = q5
926
+ }
927
+
928
+ case obj .ADUFFZERO :
929
+ if objabi .Framepointer_enabled (objabi .GOOS , objabi .GOARCH ) {
930
+ // ADR ret_addr, R27
931
+ // STP (FP, R27), -24(SP)
932
+ // SUB 24, SP, FP
933
+ // DUFFZERO
934
+ // ret_addr:
935
+ // SUB 8, SP, FP
936
+
937
+ q1 := p
938
+ // copy DUFFZERO from q1 to q4
939
+ q4 := obj .Appendp (p , c .newprog )
940
+ q4 .Pos = p .Pos
941
+ q4 .As = obj .ADUFFZERO
942
+ q4 .To = p .To
943
+
944
+ q1 .As = AADR
945
+ q1 .From .Type = obj .TYPE_BRANCH
946
+ q1 .To .Type = obj .TYPE_REG
947
+ q1 .To .Reg = REG_R27
948
+
949
+ q2 := obj .Appendp (q1 , c .newprog )
950
+ q2 .Pos = p .Pos
951
+ q2 .As = ASTP
952
+ q2 .From .Type = obj .TYPE_REGREG
953
+ q2 .From .Reg = REGFP
954
+ q2 .From .Offset = int64 (REG_R27 )
955
+ q2 .To .Type = obj .TYPE_MEM
956
+ q2 .To .Reg = REGSP
957
+ q2 .To .Offset = - 24
958
+
959
+ // maintaine FP for DUFFZERO
960
+ q3 := obj .Appendp (q2 , c .newprog )
961
+ q3 .Pos = p .Pos
962
+ q3 .As = ASUB
963
+ q3 .From .Type = obj .TYPE_CONST
964
+ q3 .From .Offset = 24
965
+ q3 .Reg = REGSP
966
+ q3 .To .Type = obj .TYPE_REG
967
+ q3 .To .Reg = REGFP
968
+
969
+ q5 := obj .Appendp (q4 , c .newprog )
970
+ q5 .Pos = p .Pos
971
+ q5 .As = ASUB
972
+ q5 .From .Type = obj .TYPE_CONST
973
+ q5 .From .Offset = 8
974
+ q5 .Reg = REGSP
975
+ q5 .To .Type = obj .TYPE_REG
976
+ q5 .To .Reg = REGFP
977
+ q1 .Pcond = q5
978
+ p = q5
979
+ }
831
980
}
832
981
}
833
982
}
0 commit comments