1
2
3
4
5 package loong64
6
7 import (
8 "cmd/internal/obj"
9 "cmd/internal/objabi"
10 "cmd/internal/src"
11 "cmd/internal/sys"
12 "internal/abi"
13 "log"
14 "math"
15 )
16
17 func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
18
19 switch p.As {
20 case AJMP,
21 AJAL,
22 ARET,
23 obj.ADUFFZERO,
24 obj.ADUFFCOPY:
25 if p.To.Sym != nil {
26 p.To.Type = obj.TYPE_BRANCH
27 }
28 }
29
30
31 switch p.As {
32 case AMOVF:
33 if p.From.Type == obj.TYPE_FCONST {
34 f32 := float32(p.From.Val.(float64))
35 if math.Float32bits(f32) == 0 {
36 p.As = AMOVW
37 p.From.Type = obj.TYPE_REG
38 p.From.Reg = REGZERO
39 break
40 }
41 p.From.Type = obj.TYPE_MEM
42 p.From.Sym = ctxt.Float32Sym(f32)
43 p.From.Name = obj.NAME_EXTERN
44 p.From.Offset = 0
45 }
46
47 case AMOVD:
48 if p.From.Type == obj.TYPE_FCONST {
49 f64 := p.From.Val.(float64)
50 if math.Float64bits(f64) == 0 {
51 p.As = AMOVV
52 p.From.Type = obj.TYPE_REG
53 p.From.Reg = REGZERO
54 break
55 }
56 p.From.Type = obj.TYPE_MEM
57 p.From.Sym = ctxt.Float64Sym(f64)
58 p.From.Name = obj.NAME_EXTERN
59 p.From.Offset = 0
60 }
61 }
62
63
64 switch p.As {
65 case ASUB:
66 if p.From.Type == obj.TYPE_CONST {
67 p.From.Offset = -p.From.Offset
68 p.As = AADD
69 }
70
71 case ASUBU:
72 if p.From.Type == obj.TYPE_CONST {
73 p.From.Offset = -p.From.Offset
74 p.As = AADDU
75 }
76
77 case ASUBV:
78 if p.From.Type == obj.TYPE_CONST {
79 p.From.Offset = -p.From.Offset
80 p.As = AADDV
81 }
82
83 case ASUBVU:
84 if p.From.Type == obj.TYPE_CONST {
85 p.From.Offset = -p.From.Offset
86 p.As = AADDVU
87 }
88 }
89
90 if ctxt.Flag_dynlink {
91 rewriteToUseGot(ctxt, p, newprog)
92 }
93 }
94
95 func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
96
97
98
99
100
101 if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
102 var sym *obj.LSym
103 if p.As == obj.ADUFFZERO {
104 sym = ctxt.LookupABI("runtime.duffzero", obj.ABIInternal)
105 } else {
106 sym = ctxt.LookupABI("runtime.duffcopy", obj.ABIInternal)
107 }
108 offset := p.To.Offset
109 p.As = AMOVV
110 p.From.Type = obj.TYPE_MEM
111 p.From.Sym = sym
112 p.From.Name = obj.NAME_GOTREF
113 p.To.Type = obj.TYPE_REG
114 p.To.Reg = REGTMP
115 p.To.Name = obj.NAME_NONE
116 p.To.Offset = 0
117 p.To.Sym = nil
118 p1 := obj.Appendp(p, newprog)
119 p1.As = AADDV
120 p1.From.Type = obj.TYPE_CONST
121 p1.From.Offset = offset
122 p1.To.Type = obj.TYPE_REG
123 p1.To.Reg = REGTMP
124 p2 := obj.Appendp(p1, newprog)
125 p2.As = AJAL
126 p2.To.Type = obj.TYPE_MEM
127 p2.To.Reg = REGTMP
128 }
129
130
131
132
133 if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
134
135
136 if p.As != AMOVV {
137 ctxt.Diag("do not know how to handle TYPE_ADDR in %v with -shared", p)
138 }
139 if p.To.Type != obj.TYPE_REG {
140 ctxt.Diag("do not know how to handle LEAQ-type insn to non-register in %v with -shared", p)
141 }
142 p.From.Type = obj.TYPE_MEM
143 p.From.Name = obj.NAME_GOTREF
144 if p.From.Offset != 0 {
145 q := obj.Appendp(p, newprog)
146 q.As = AADDV
147 q.From.Type = obj.TYPE_CONST
148 q.From.Offset = p.From.Offset
149 q.To = p.To
150 p.From.Offset = 0
151 }
152 }
153 if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
154 ctxt.Diag("don't know how to handle %v with -shared", p)
155 }
156
157 var source *obj.Addr
158
159
160
161 if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
162 if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
163 ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -shared", p)
164 }
165 source = &p.From
166 } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
167 source = &p.To
168 } else {
169 return
170 }
171 if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP {
172 return
173 }
174 if source.Sym.Type == objabi.STLSBSS {
175 return
176 }
177 if source.Type != obj.TYPE_MEM {
178 ctxt.Diag("don't know how to handle %v with -shared", p)
179 }
180 p1 := obj.Appendp(p, newprog)
181 p2 := obj.Appendp(p1, newprog)
182 p1.As = AMOVV
183 p1.From.Type = obj.TYPE_MEM
184 p1.From.Sym = source.Sym
185 p1.From.Name = obj.NAME_GOTREF
186 p1.To.Type = obj.TYPE_REG
187 p1.To.Reg = REGTMP
188
189 p2.As = p.As
190 p2.From = p.From
191 p2.To = p.To
192 if p.From.Name == obj.NAME_EXTERN {
193 p2.From.Reg = REGTMP
194 p2.From.Name = obj.NAME_NONE
195 p2.From.Sym = nil
196 } else if p.To.Name == obj.NAME_EXTERN {
197 p2.To.Reg = REGTMP
198 p2.To.Name = obj.NAME_NONE
199 p2.To.Sym = nil
200 } else {
201 return
202 }
203
204 obj.Nopout(p)
205 }
206
207 func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
208 c := ctxt0{ctxt: ctxt, newprog: newprog, cursym: cursym}
209
210 p := c.cursym.Func().Text
211 textstksiz := p.To.Offset
212
213 if textstksiz < 0 {
214 c.ctxt.Diag("negative frame size %d - did you mean NOFRAME?", textstksiz)
215 }
216 if p.From.Sym.NoFrame() {
217 if textstksiz != 0 {
218 c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz)
219 }
220 }
221
222 c.cursym.Func().Args = p.To.Val.(int32)
223 c.cursym.Func().Locals = int32(textstksiz)
224
225
229
230 for p := c.cursym.Func().Text; p != nil; p = p.Link {
231 switch p.As {
232 case obj.ATEXT:
233 p.Mark |= LABEL | LEAF | SYNC
234 if p.Link != nil {
235 p.Link.Mark |= LABEL
236 }
237
238 case AMOVW,
239 AMOVV:
240 if p.To.Type == obj.TYPE_REG && p.To.Reg >= REG_SPECIAL {
241 p.Mark |= LABEL | SYNC
242 break
243 }
244 if p.From.Type == obj.TYPE_REG && p.From.Reg >= REG_SPECIAL {
245 p.Mark |= LABEL | SYNC
246 }
247
248 case ASYSCALL,
249 AWORD:
250 p.Mark |= LABEL | SYNC
251
252 case ANOR:
253 if p.To.Type == obj.TYPE_REG {
254 if p.To.Reg == REGZERO {
255 p.Mark |= LABEL | SYNC
256 }
257 }
258
259 case AJAL,
260 obj.ADUFFZERO,
261 obj.ADUFFCOPY:
262 c.cursym.Func().Text.Mark &^= LEAF
263 fallthrough
264
265 case AJMP,
266 ABEQ,
267 ABGEU,
268 ABLTU,
269 ABLTZ,
270 ABNE,
271 ABFPT, ABFPF:
272 p.Mark |= BRANCH
273 q1 := p.To.Target()
274 if q1 != nil {
275 for q1.As == obj.ANOP {
276 q1 = q1.Link
277 p.To.SetTarget(q1)
278 }
279
280 if q1.Mark&LEAF == 0 {
281 q1.Mark |= LABEL
282 }
283 }
284 q1 = p.Link
285 if q1 != nil {
286 q1.Mark |= LABEL
287 }
288
289 case ARET:
290 if p.Link != nil {
291 p.Link.Mark |= LABEL
292 }
293 }
294 }
295
296 var mov, add obj.As
297
298 add = AADDV
299 mov = AMOVV
300
301 var q *obj.Prog
302 var q1 *obj.Prog
303 autosize := int32(0)
304 var p1 *obj.Prog
305 var p2 *obj.Prog
306 for p := c.cursym.Func().Text; p != nil; p = p.Link {
307 o := p.As
308 switch o {
309 case obj.ATEXT:
310 autosize = int32(textstksiz)
311
312 if p.Mark&LEAF != 0 && autosize == 0 {
313
314 p.From.Sym.Set(obj.AttrNoFrame, true)
315 }
316
317 if !p.From.Sym.NoFrame() {
318
319
320 autosize += int32(c.ctxt.Arch.FixedFrameSize)
321 }
322
323 if p.Mark&LEAF != 0 && autosize < abi.StackSmall {
324
325
326 p.From.Sym.Set(obj.AttrNoSplit, true)
327 }
328
329 if autosize&4 != 0 {
330 autosize += 4
331 }
332
333 if autosize == 0 && c.cursym.Func().Text.Mark&LEAF == 0 {
334 if c.cursym.Func().Text.From.Sym.NoSplit() {
335 if ctxt.Debugvlog {
336 ctxt.Logf("save suppressed in: %s\n", c.cursym.Name)
337 }
338
339 c.cursym.Func().Text.Mark |= LEAF
340 }
341 }
342
343 p.To.Offset = int64(autosize) - ctxt.Arch.FixedFrameSize
344
345 if c.cursym.Func().Text.Mark&LEAF != 0 {
346 c.cursym.Set(obj.AttrLeaf, true)
347 if p.From.Sym.NoFrame() {
348 break
349 }
350 }
351
352 if !p.From.Sym.NoSplit() {
353 p = c.stacksplit(p, autosize)
354 }
355
356 q = p
357
358 if autosize != 0 {
359
360
361
362
363
364
365
366 q = c.ctxt.StartUnsafePoint(q, c.newprog)
367
368 q = obj.Appendp(q, newprog)
369 q.As = mov
370 q.Pos = p.Pos
371 q.From.Type = obj.TYPE_REG
372 q.From.Reg = REGLINK
373 q.To.Type = obj.TYPE_MEM
374 q.To.Offset = int64(-autosize)
375 q.To.Reg = REGSP
376
377 q = obj.Appendp(q, newprog)
378 q.As = add
379 q.Pos = p.Pos
380 q.Pos = q.Pos.WithXlogue(src.PosPrologueEnd)
381 q.From.Type = obj.TYPE_CONST
382 q.From.Offset = int64(-autosize)
383 q.To.Type = obj.TYPE_REG
384 q.To.Reg = REGSP
385 q.Spadj = +autosize
386
387 q = c.ctxt.EndUnsafePoint(q, c.newprog, -1)
388
389
390
391
392
393
394 q = obj.Appendp(q, newprog)
395 q.As = mov
396 q.Pos = p.Pos
397 q.From.Type = obj.TYPE_REG
398 q.From.Reg = REGLINK
399 q.To.Type = obj.TYPE_MEM
400 q.To.Offset = 0
401 q.To.Reg = REGSP
402 }
403
404 if c.cursym.Func().Text.From.Sym.Wrapper() && c.cursym.Func().Text.Mark&LEAF == 0 {
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423 q = obj.Appendp(q, newprog)
424
425 q.As = mov
426 q.From.Type = obj.TYPE_MEM
427 q.From.Reg = REGG
428 q.From.Offset = 4 * int64(c.ctxt.Arch.PtrSize)
429 q.To.Type = obj.TYPE_REG
430 q.To.Reg = REG_R20
431
432 q = obj.Appendp(q, newprog)
433 q.As = ABEQ
434 q.From.Type = obj.TYPE_REG
435 q.From.Reg = REG_R20
436 q.To.Type = obj.TYPE_BRANCH
437 q.Mark |= BRANCH
438 p1 = q
439
440 q = obj.Appendp(q, newprog)
441 q.As = mov
442 q.From.Type = obj.TYPE_MEM
443 q.From.Reg = REG_R20
444 q.From.Offset = 0
445 q.To.Type = obj.TYPE_REG
446 q.To.Reg = REG_R24
447
448 q = obj.Appendp(q, newprog)
449 q.As = add
450 q.From.Type = obj.TYPE_CONST
451 q.From.Offset = int64(autosize) + ctxt.Arch.FixedFrameSize
452 q.Reg = REGSP
453 q.To.Type = obj.TYPE_REG
454 q.To.Reg = REG_R30
455
456 q = obj.Appendp(q, newprog)
457 q.As = ABNE
458 q.From.Type = obj.TYPE_REG
459 q.From.Reg = REG_R24
460 q.Reg = REG_R30
461 q.To.Type = obj.TYPE_BRANCH
462 q.Mark |= BRANCH
463 p2 = q
464
465 q = obj.Appendp(q, newprog)
466 q.As = add
467 q.From.Type = obj.TYPE_CONST
468 q.From.Offset = ctxt.Arch.FixedFrameSize
469 q.Reg = REGSP
470 q.To.Type = obj.TYPE_REG
471 q.To.Reg = REG_R24
472
473 q = obj.Appendp(q, newprog)
474 q.As = mov
475 q.From.Type = obj.TYPE_REG
476 q.From.Reg = REG_R24
477 q.To.Type = obj.TYPE_MEM
478 q.To.Reg = REG_R20
479 q.To.Offset = 0
480
481 q = obj.Appendp(q, newprog)
482
483 q.As = obj.ANOP
484 p1.To.SetTarget(q)
485 p2.To.SetTarget(q)
486 }
487
488 case ARET:
489 if p.From.Type == obj.TYPE_CONST {
490 ctxt.Diag("using BECOME (%v) is not supported!", p)
491 break
492 }
493
494 retSym := p.To.Sym
495 p.To.Name = obj.NAME_NONE
496 p.To.Sym = nil
497
498 if c.cursym.Func().Text.Mark&LEAF != 0 {
499 if autosize == 0 {
500 p.As = AJMP
501 p.From = obj.Addr{}
502 if retSym != nil {
503 p.To.Type = obj.TYPE_BRANCH
504 p.To.Name = obj.NAME_EXTERN
505 p.To.Sym = retSym
506 } else {
507 p.To.Type = obj.TYPE_MEM
508 p.To.Reg = REGLINK
509 p.To.Offset = 0
510 }
511 p.Mark |= BRANCH
512 break
513 }
514
515 p.As = add
516 p.From.Type = obj.TYPE_CONST
517 p.From.Offset = int64(autosize)
518 p.To.Type = obj.TYPE_REG
519 p.To.Reg = REGSP
520 p.Spadj = -autosize
521
522 q = c.newprog()
523 q.As = AJMP
524 q.Pos = p.Pos
525 if retSym != nil {
526 q.To.Type = obj.TYPE_BRANCH
527 q.To.Name = obj.NAME_EXTERN
528 q.To.Sym = retSym
529 } else {
530 q.To.Type = obj.TYPE_MEM
531 q.To.Offset = 0
532 q.To.Reg = REGLINK
533 }
534 q.Mark |= BRANCH
535 q.Spadj = +autosize
536
537 q.Link = p.Link
538 p.Link = q
539 break
540 }
541
542 p.As = mov
543 p.From.Type = obj.TYPE_MEM
544 p.From.Offset = 0
545 p.From.Reg = REGSP
546 p.To.Type = obj.TYPE_REG
547 p.To.Reg = REGLINK
548
549 if autosize != 0 {
550 q = c.newprog()
551 q.As = add
552 q.Pos = p.Pos
553 q.From.Type = obj.TYPE_CONST
554 q.From.Offset = int64(autosize)
555 q.To.Type = obj.TYPE_REG
556 q.To.Reg = REGSP
557 q.Spadj = -autosize
558
559 q.Link = p.Link
560 p.Link = q
561 }
562
563 q1 = c.newprog()
564 q1.As = AJMP
565 q1.Pos = p.Pos
566 if retSym != nil {
567 q1.To.Type = obj.TYPE_BRANCH
568 q1.To.Name = obj.NAME_EXTERN
569 q1.To.Sym = retSym
570 } else {
571 q1.To.Type = obj.TYPE_MEM
572 q1.To.Offset = 0
573 q1.To.Reg = REGLINK
574 }
575 q1.Mark |= BRANCH
576 q1.Spadj = +autosize
577
578 q1.Link = q.Link
579 q.Link = q1
580
581 case AADD,
582 AADDU,
583 AADDV,
584 AADDVU:
585 if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST {
586 p.Spadj = int32(-p.From.Offset)
587 }
588
589 case obj.AGETCALLERPC:
590 if cursym.Leaf() {
591
592 p.As = mov
593 p.From.Type = obj.TYPE_REG
594 p.From.Reg = REGLINK
595 } else {
596
597 p.As = mov
598 p.From.Type = obj.TYPE_MEM
599 p.From.Reg = REGSP
600 }
601 }
602
603 if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
604 f := c.cursym.Func()
605 if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
606 c.cursym.Func().FuncFlag |= abi.FuncFlagSPWrite
607 if ctxt.Debugvlog || !ctxt.IsAsm {
608 ctxt.Logf("auto-SPWRITE: %s %v\n", c.cursym.Name, p)
609 if !ctxt.IsAsm {
610 ctxt.Diag("invalid auto-SPWRITE in non-assembly")
611 ctxt.DiagFlush()
612 log.Fatalf("bad SPWRITE")
613 }
614 }
615 }
616 }
617 }
618 }
619
620 func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
621 var mov, add obj.As
622
623 add = AADDV
624 mov = AMOVV
625 if c.ctxt.Flag_maymorestack != "" {
626
627 frameSize := 2 * c.ctxt.Arch.PtrSize
628
629 p = c.ctxt.StartUnsafePoint(p, c.newprog)
630
631
632
633 p = c.cursym.Func().SpillRegisterArgs(p, c.newprog)
634
635
636 p = obj.Appendp(p, c.newprog)
637 p.As = mov
638 p.From.Type = obj.TYPE_REG
639 p.From.Reg = REGLINK
640 p.To.Type = obj.TYPE_MEM
641 p.To.Offset = int64(-frameSize)
642 p.To.Reg = REGSP
643
644
645 p = obj.Appendp(p, c.newprog)
646 p.As = mov
647 p.From.Type = obj.TYPE_REG
648 p.From.Reg = REGCTXT
649 p.To.Type = obj.TYPE_MEM
650 p.To.Offset = -int64(c.ctxt.Arch.PtrSize)
651 p.To.Reg = REGSP
652
653
654 p = obj.Appendp(p, c.newprog)
655 p.As = add
656 p.From.Type = obj.TYPE_CONST
657 p.From.Offset = int64(-frameSize)
658 p.To.Type = obj.TYPE_REG
659 p.To.Reg = REGSP
660 p.Spadj = int32(frameSize)
661
662
663 p = obj.Appendp(p, c.newprog)
664 p.As = AJAL
665 p.To.Type = obj.TYPE_BRANCH
666
667 p.To.Sym = c.ctxt.LookupABI(c.ctxt.Flag_maymorestack, c.cursym.ABI())
668 p.Mark |= BRANCH
669
670
671
672
673 p = obj.Appendp(p, c.newprog)
674 p.As = mov
675 p.From.Type = obj.TYPE_MEM
676 p.From.Offset = 0
677 p.From.Reg = REGSP
678 p.To.Type = obj.TYPE_REG
679 p.To.Reg = REGLINK
680
681
682 p = obj.Appendp(p, c.newprog)
683 p.As = mov
684 p.From.Type = obj.TYPE_MEM
685 p.From.Offset = int64(c.ctxt.Arch.PtrSize)
686 p.From.Reg = REGSP
687 p.To.Type = obj.TYPE_REG
688 p.To.Reg = REGCTXT
689
690
691 p = obj.Appendp(p, c.newprog)
692 p.As = add
693 p.From.Type = obj.TYPE_CONST
694 p.From.Offset = int64(frameSize)
695 p.To.Type = obj.TYPE_REG
696 p.To.Reg = REGSP
697 p.Spadj = int32(-frameSize)
698
699
700 p = c.cursym.Func().UnspillRegisterArgs(p, c.newprog)
701 p = c.ctxt.EndUnsafePoint(p, c.newprog, -1)
702 }
703
704
705 startPred := p
706
707
708 p = obj.Appendp(p, c.newprog)
709
710 p.As = mov
711 p.From.Type = obj.TYPE_MEM
712 p.From.Reg = REGG
713 p.From.Offset = 2 * int64(c.ctxt.Arch.PtrSize)
714 if c.cursym.CFunc() {
715 p.From.Offset = 3 * int64(c.ctxt.Arch.PtrSize)
716 }
717 p.To.Type = obj.TYPE_REG
718 p.To.Reg = REG_R20
719
720
721
722
723
724 p = c.ctxt.StartUnsafePoint(p, c.newprog)
725
726 var q *obj.Prog
727 if framesize <= abi.StackSmall {
728
729
730 p = obj.Appendp(p, c.newprog)
731
732 p.As = ASGTU
733 p.From.Type = obj.TYPE_REG
734 p.From.Reg = REGSP
735 p.Reg = REG_R20
736 p.To.Type = obj.TYPE_REG
737 p.To.Reg = REG_R20
738 } else {
739
740 offset := int64(framesize) - abi.StackSmall
741 if framesize > abi.StackBig {
742
743
744
745
746
747
748
749
750
751
752 p = obj.Appendp(p, c.newprog)
753 p.As = ASGTU
754 p.From.Type = obj.TYPE_CONST
755 p.From.Offset = offset
756 p.Reg = REGSP
757 p.To.Type = obj.TYPE_REG
758 p.To.Reg = REG_R24
759
760 p = obj.Appendp(p, c.newprog)
761 q = p
762 p.As = ABNE
763 p.From.Type = obj.TYPE_REG
764 p.From.Reg = REG_R24
765 p.To.Type = obj.TYPE_BRANCH
766 p.Mark |= BRANCH
767 }
768
769 p = obj.Appendp(p, c.newprog)
770
771 p.As = add
772 p.From.Type = obj.TYPE_CONST
773 p.From.Offset = -offset
774 p.Reg = REGSP
775 p.To.Type = obj.TYPE_REG
776 p.To.Reg = REG_R24
777
778 p = obj.Appendp(p, c.newprog)
779 p.As = ASGTU
780 p.From.Type = obj.TYPE_REG
781 p.From.Reg = REG_R24
782 p.Reg = REG_R20
783 p.To.Type = obj.TYPE_REG
784 p.To.Reg = REG_R20
785 }
786
787
788 p = obj.Appendp(p, c.newprog)
789 q1 := p
790
791 p.As = ABEQ
792 p.From.Type = obj.TYPE_REG
793 p.From.Reg = REG_R20
794 p.To.Type = obj.TYPE_BRANCH
795 p.Mark |= BRANCH
796
797 end := c.ctxt.EndUnsafePoint(p, c.newprog, -1)
798
799 var last *obj.Prog
800 for last = c.cursym.Func().Text; last.Link != nil; last = last.Link {
801 }
802
803
804
805
806 spfix := obj.Appendp(last, c.newprog)
807 spfix.As = obj.ANOP
808 spfix.Spadj = -framesize
809
810 pcdata := c.ctxt.EmitEntryStackMap(c.cursym, spfix, c.newprog)
811 pcdata = c.ctxt.StartUnsafePoint(pcdata, c.newprog)
812
813 if q != nil {
814 q.To.SetTarget(pcdata)
815 }
816 q1.To.SetTarget(pcdata)
817
818 p = c.cursym.Func().SpillRegisterArgs(pcdata, c.newprog)
819
820
821 p = obj.Appendp(p, c.newprog)
822 p.As = mov
823 p.From.Type = obj.TYPE_REG
824 p.From.Reg = REGLINK
825 p.To.Type = obj.TYPE_REG
826 p.To.Reg = REG_R31
827 if q != nil {
828 q.To.SetTarget(p)
829 p.Mark |= LABEL
830 }
831
832
833 call := obj.Appendp(p, c.newprog)
834 call.As = AJAL
835 call.To.Type = obj.TYPE_BRANCH
836
837 if c.cursym.CFunc() {
838 call.To.Sym = c.ctxt.Lookup("runtime.morestackc")
839 } else if !c.cursym.Func().Text.From.Sym.NeedCtxt() {
840 call.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt")
841 } else {
842 call.To.Sym = c.ctxt.Lookup("runtime.morestack")
843 }
844 call.Mark |= BRANCH
845
846
847 pcdata = c.ctxt.EndUnsafePoint(call, c.newprog, -1)
848 unspill := c.cursym.Func().UnspillRegisterArgs(pcdata, c.newprog)
849
850
851 jmp := obj.Appendp(unspill, c.newprog)
852 jmp.As = AJMP
853 jmp.To.Type = obj.TYPE_BRANCH
854 jmp.To.SetTarget(startPred.Link)
855 jmp.Spadj = +framesize
856
857 return end
858 }
859
860 func (c *ctxt0) addnop(p *obj.Prog) {
861 q := c.newprog()
862 q.As = ANOOP
863 q.Pos = p.Pos
864 q.Link = p.Link
865 p.Link = q
866 }
867
868 var Linkloong64 = obj.LinkArch{
869 Arch: sys.ArchLoong64,
870 Init: buildop,
871 Preprocess: preprocess,
872 Assemble: span0,
873 Progedit: progedit,
874 DWARFRegisters: LOONG64DWARFRegisters,
875 }
876
View as plain text