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