1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package riscv
22
23 import (
24 "cmd/internal/obj"
25 "cmd/internal/objabi"
26 "cmd/internal/src"
27 "cmd/internal/sys"
28 "fmt"
29 "internal/abi"
30 "internal/buildcfg"
31 "log"
32 "math"
33 "math/bits"
34 "strings"
35 )
36
37 func buildop(ctxt *obj.Link) {}
38
39 func jalToSym(ctxt *obj.Link, p *obj.Prog, lr int16) {
40 switch p.As {
41 case obj.ACALL, obj.AJMP, obj.ARET:
42 default:
43 ctxt.Diag("unexpected Prog in jalToSym: %v", p)
44 return
45 }
46
47 p.As = AJAL
48 p.Mark |= NEED_JAL_RELOC
49 p.From.Type = obj.TYPE_REG
50 p.From.Reg = lr
51 p.Reg = obj.REG_NONE
52 }
53
54
55
56 func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
57 insData, err := instructionDataForAs(p.As)
58 if err != nil {
59 panic(fmt.Sprintf("failed to lookup instruction data for %v: %v", p.As, err))
60 }
61
62
63 if p.Reg == obj.REG_NONE {
64 if insData.ternary {
65 p.Reg = p.To.Reg
66 }
67 }
68
69
70
71 if p.From.Type == obj.TYPE_CONST {
72 switch p.As {
73 case ACSUB:
74 p.As, p.From.Offset = ACADDI, -p.From.Offset
75 case ACSUBW:
76 p.As, p.From.Offset = ACADDIW, -p.From.Offset
77 case ASUB:
78 p.As, p.From.Offset = AADDI, -p.From.Offset
79 case ASUBW:
80 p.As, p.From.Offset = AADDIW, -p.From.Offset
81 default:
82 if insData.immForm != obj.AXXX {
83 p.As = insData.immForm
84 }
85 }
86 }
87
88 switch p.As {
89 case obj.AJMP:
90
91 p.From.Type = obj.TYPE_REG
92 p.From.Reg = REG_ZERO
93
94 switch p.To.Type {
95 case obj.TYPE_BRANCH:
96 p.As = AJAL
97 case obj.TYPE_MEM:
98 switch p.To.Name {
99 case obj.NAME_NONE:
100 p.As = AJALR
101 case obj.NAME_EXTERN, obj.NAME_STATIC:
102
103 default:
104 ctxt.Diag("unsupported name %d for %v", p.To.Name, p)
105 }
106 default:
107 panic(fmt.Sprintf("unhandled type %+v", p.To.Type))
108 }
109
110 case obj.ACALL:
111 switch p.To.Type {
112 case obj.TYPE_MEM:
113
114 case obj.TYPE_REG:
115 p.As = AJALR
116 p.From.Type = obj.TYPE_REG
117 p.From.Reg = REG_LR
118 default:
119 ctxt.Diag("unknown destination type %+v in CALL: %v", p.To.Type, p)
120 }
121
122 case obj.AUNDEF:
123 p.As = AEBREAK
124
125 case AFMVXS:
126
127 p.As = AFMVXW
128
129 case AFMVSX:
130
131 p.As = AFMVWX
132
133 case ASCALL:
134
135 p.As = AECALL
136
137 case ASBREAK:
138
139 p.As = AEBREAK
140
141 case AMOV:
142 if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == obj.REG_NONE {
143 if isMaterialisableConst(p.From.Offset) {
144 break
145 }
146
147 p.From.Type = obj.TYPE_MEM
148 p.From.Sym = ctxt.Int64Sym(p.From.Offset)
149 p.From.Name = obj.NAME_EXTERN
150 p.From.Offset = 0
151 }
152
153 case AMOVF:
154 if p.From.Type == obj.TYPE_FCONST && p.From.Name == obj.NAME_NONE && p.From.Reg == obj.REG_NONE {
155 f64 := p.From.Val.(float64)
156 f32 := float32(f64)
157 if math.Float32bits(f32) == 0 {
158 p.From.Type = obj.TYPE_REG
159 p.From.Reg = REG_ZERO
160 break
161 }
162 p.From.Type = obj.TYPE_MEM
163 p.From.Sym = ctxt.Float32Sym(f32)
164 p.From.Name = obj.NAME_EXTERN
165 p.From.Offset = 0
166 }
167
168 case AMOVD:
169 if p.From.Type == obj.TYPE_FCONST && p.From.Name == obj.NAME_NONE && p.From.Reg == obj.REG_NONE {
170 f64 := p.From.Val.(float64)
171 if math.Float64bits(f64) == 0 {
172 p.From.Type = obj.TYPE_REG
173 p.From.Reg = REG_ZERO
174 break
175 }
176 p.From.Type = obj.TYPE_MEM
177 p.From.Sym = ctxt.Float64Sym(f64)
178 p.From.Name = obj.NAME_EXTERN
179 p.From.Offset = 0
180 }
181 }
182
183 if ctxt.Flag_dynlink {
184 rewriteToUseGot(ctxt, p, newprog)
185 }
186 }
187
188
189 func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
190
191
192
193 if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
194
195
196 if p.As != AMOV {
197 ctxt.Diag("don't know how to handle TYPE_ADDR in %v with -dynlink", p)
198 }
199 if p.To.Type != obj.TYPE_REG {
200 ctxt.Diag("don't know how to handle LD instruction to non-register in %v with -dynlink", p)
201 }
202 p.From.Type = obj.TYPE_MEM
203 p.From.Name = obj.NAME_GOTREF
204 if p.From.Offset != 0 {
205 q := obj.Appendp(p, newprog)
206 q.As = AADD
207 q.From.Type = obj.TYPE_CONST
208 q.From.Offset = p.From.Offset
209 q.To = p.To
210 p.From.Offset = 0
211 }
212
213 }
214
215 if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
216 ctxt.Diag("don't know how to handle %v with -dynlink", p)
217 }
218
219 var source *obj.Addr
220
221
222
223 if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
224 if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
225 ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
226 }
227 source = &p.From
228 } else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
229 source = &p.To
230 } else {
231 return
232 }
233 if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP {
234 return
235 }
236 if source.Sym.Type == objabi.STLSBSS {
237 return
238 }
239 if source.Type != obj.TYPE_MEM {
240 ctxt.Diag("don't know how to handle %v with -dynlink", p)
241 }
242 p1 := obj.Appendp(p, newprog)
243 p1.As = AMOV
244 p1.From.Type = obj.TYPE_MEM
245 p1.From.Sym = source.Sym
246 p1.From.Name = obj.NAME_GOTREF
247 p1.To.Type = obj.TYPE_REG
248 p1.To.Reg = REG_TMP
249
250 p2 := obj.Appendp(p1, newprog)
251 p2.As = p.As
252 p2.From = p.From
253 p2.To = p.To
254 if p.From.Name == obj.NAME_EXTERN {
255 p2.From.Reg = REG_TMP
256 p2.From.Name = obj.NAME_NONE
257 p2.From.Sym = nil
258 } else if p.To.Name == obj.NAME_EXTERN {
259 p2.To.Reg = REG_TMP
260 p2.To.Name = obj.NAME_NONE
261 p2.To.Sym = nil
262 } else {
263 return
264 }
265 obj.Nopout(p)
266
267 }
268
269
270 func addrToReg(a obj.Addr) int16 {
271 switch a.Name {
272 case obj.NAME_PARAM, obj.NAME_AUTO:
273 return REG_SP
274 }
275 return a.Reg
276 }
277
278
279 func movToLoad(mnemonic obj.As) obj.As {
280 switch mnemonic {
281 case AMOV:
282 return ALD
283 case AMOVB:
284 return ALB
285 case AMOVH:
286 return ALH
287 case AMOVW:
288 return ALW
289 case AMOVBU:
290 return ALBU
291 case AMOVHU:
292 return ALHU
293 case AMOVWU:
294 return ALWU
295 case AMOVF:
296 return AFLW
297 case AMOVD:
298 return AFLD
299 default:
300 panic(fmt.Sprintf("%+v is not a MOV", mnemonic))
301 }
302 }
303
304
305 func movToStore(mnemonic obj.As) obj.As {
306 switch mnemonic {
307 case AMOV:
308 return ASD
309 case AMOVB:
310 return ASB
311 case AMOVH:
312 return ASH
313 case AMOVW:
314 return ASW
315 case AMOVF:
316 return AFSW
317 case AMOVD:
318 return AFSD
319 default:
320 panic(fmt.Sprintf("%+v is not a MOV", mnemonic))
321 }
322 }
323
324
325
326 func markRelocs(p *obj.Prog) {
327 switch p.As {
328 case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD:
329 switch {
330 case p.From.Type == obj.TYPE_ADDR && p.To.Type == obj.TYPE_REG:
331 switch p.From.Name {
332 case obj.NAME_EXTERN, obj.NAME_STATIC:
333 p.Mark |= NEED_PCREL_ITYPE_RELOC
334 case obj.NAME_GOTREF:
335 p.Mark |= NEED_GOT_PCREL_ITYPE_RELOC
336 }
337 case p.From.Type == obj.TYPE_MEM && p.To.Type == obj.TYPE_REG:
338 switch p.From.Name {
339 case obj.NAME_EXTERN, obj.NAME_STATIC:
340 p.Mark |= NEED_PCREL_ITYPE_RELOC
341 case obj.NAME_GOTREF:
342 p.Mark |= NEED_GOT_PCREL_ITYPE_RELOC
343 }
344 case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_MEM:
345 switch p.To.Name {
346 case obj.NAME_EXTERN, obj.NAME_STATIC:
347 p.Mark |= NEED_PCREL_STYPE_RELOC
348 }
349 }
350 }
351 }
352
353
354 func InvertBranch(as obj.As) obj.As {
355 switch as {
356 case ABEQ:
357 return ABNE
358 case ABEQZ:
359 return ABNEZ
360 case ABGE:
361 return ABLT
362 case ABGEU:
363 return ABLTU
364 case ABGEZ:
365 return ABLTZ
366 case ABGT:
367 return ABLE
368 case ABGTU:
369 return ABLEU
370 case ABGTZ:
371 return ABLEZ
372 case ABLE:
373 return ABGT
374 case ABLEU:
375 return ABGTU
376 case ABLEZ:
377 return ABGTZ
378 case ABLT:
379 return ABGE
380 case ABLTU:
381 return ABGEU
382 case ABLTZ:
383 return ABGEZ
384 case ABNE:
385 return ABEQ
386 case ABNEZ:
387 return ABEQZ
388 case ACBEQZ:
389 return ACBNEZ
390 case ACBNEZ:
391 return ACBEQZ
392 default:
393 panic("InvertBranch: not a branch")
394 }
395 }
396
397
398
399 func containsCall(sym *obj.LSym) bool {
400
401 for p := sym.Func().Text; p != nil; p = p.Link {
402 switch p.As {
403 case obj.ACALL:
404 return true
405 case ACJALR, AJAL, AJALR:
406 if p.From.Type == obj.TYPE_REG && p.From.Reg == REG_LR {
407 return true
408 }
409 }
410 }
411
412 return false
413 }
414
415
416
417 func setPCs(p *obj.Prog, pc int64, compress bool) int64 {
418 for ; p != nil; p = p.Link {
419 p.Pc = pc
420 for _, ins := range instructionsForProg(p, compress) {
421 pc += int64(ins.length())
422 }
423
424 if p.As == obj.APCALIGN {
425 alignedValue := p.From.Offset
426 v := pcAlignPadLength(pc, alignedValue)
427 pc += int64(v)
428 }
429 }
430 return pc
431 }
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457 func stackOffset(a *obj.Addr, stacksize int64) {
458 switch a.Name {
459 case obj.NAME_AUTO:
460
461 a.Offset += stacksize
462 case obj.NAME_PARAM:
463
464 a.Offset += stacksize + 8
465 }
466 }
467
468
469
470
471
472
473
474
475
476 func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
477 if cursym.Func().Text == nil || cursym.Func().Text.Link == nil {
478 return
479 }
480
481
482 text := cursym.Func().Text
483 if text.As != obj.ATEXT {
484 ctxt.Diag("preprocess: found symbol that does not start with TEXT directive")
485 return
486 }
487
488 stacksize := text.To.Offset
489 if stacksize == -8 {
490
491 text.From.Sym.Set(obj.AttrNoFrame, true)
492 stacksize = 0
493 }
494 if stacksize < 0 {
495 ctxt.Diag("negative frame size %d - did you mean NOFRAME?", stacksize)
496 }
497 if text.From.Sym.NoFrame() {
498 if stacksize != 0 {
499 ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", stacksize)
500 }
501 }
502
503 if !containsCall(cursym) {
504 text.From.Sym.Set(obj.AttrLeaf, true)
505 if stacksize == 0 {
506
507 text.From.Sym.Set(obj.AttrNoFrame, true)
508 }
509 }
510
511
512 if !text.From.Sym.NoFrame() {
513 stacksize += ctxt.Arch.FixedFrameSize
514 }
515
516 cursym.Func().Args = text.To.Val.(int32)
517 cursym.Func().Locals = int32(stacksize)
518
519 prologue := text
520
521 if !cursym.Func().Text.From.Sym.NoSplit() {
522 prologue = stacksplit(ctxt, prologue, cursym, newprog, stacksize)
523 }
524
525 q := prologue
526
527 if stacksize != 0 {
528 prologue = ctxt.StartUnsafePoint(prologue, newprog)
529
530
531 prologue = obj.Appendp(prologue, newprog)
532 prologue.As = AMOV
533 prologue.Pos = q.Pos
534 prologue.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_LR}
535 prologue.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: -stacksize}
536
537
538 prologue = obj.Appendp(prologue, newprog)
539 prologue.As = AADDI
540 prologue.Pos = q.Pos
541 prologue.Pos = prologue.Pos.WithXlogue(src.PosPrologueEnd)
542 prologue.From = obj.Addr{Type: obj.TYPE_CONST, Offset: -stacksize}
543 prologue.Reg = REG_SP
544 prologue.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_SP}
545 prologue.Spadj = int32(stacksize)
546
547 prologue = ctxt.EndUnsafePoint(prologue, newprog, -1)
548
549
550
551
552
553
554 prologue = obj.Appendp(prologue, newprog)
555 prologue.As = AMOV
556 prologue.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_LR}
557 prologue.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: 0}
558 }
559
560
561 for p := cursym.Func().Text; p != nil; p = p.Link {
562 stackOffset(&p.From, stacksize)
563 stackOffset(&p.To, stacksize)
564 }
565
566
567 for p := cursym.Func().Text; p != nil; p = p.Link {
568 switch p.As {
569 case obj.AGETCALLERPC:
570 if cursym.Leaf() {
571
572 p.As = AMOV
573 p.From.Type = obj.TYPE_REG
574 p.From.Reg = REG_LR
575 } else {
576
577 p.As = AMOV
578 p.From.Type = obj.TYPE_MEM
579 p.From.Reg = REG_SP
580 }
581
582 case obj.ACALL:
583 switch p.To.Type {
584 case obj.TYPE_MEM:
585 jalToSym(ctxt, p, REG_LR)
586 }
587
588 case obj.AJMP:
589 switch p.To.Type {
590 case obj.TYPE_MEM:
591 switch p.To.Name {
592 case obj.NAME_EXTERN, obj.NAME_STATIC:
593 jalToSym(ctxt, p, REG_ZERO)
594 }
595 }
596
597 case obj.ARET:
598
599 retJMP, retReg := p.To.Sym, p.To.Reg
600 if retReg == obj.REG_NONE {
601 retReg = REG_LR
602 }
603
604 if stacksize != 0 {
605
606 p.As = AMOV
607 p.From = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: 0}
608 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_LR}
609 p = obj.Appendp(p, newprog)
610
611 p.As = AADDI
612 p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: stacksize}
613 p.Reg = REG_SP
614 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_SP}
615 p.Spadj = int32(-stacksize)
616 p = obj.Appendp(p, newprog)
617 }
618
619 if retJMP != nil {
620 p.As = obj.ARET
621 p.To.Sym = retJMP
622 jalToSym(ctxt, p, REG_ZERO)
623 } else {
624 p.As = AJALR
625 p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
626 p.Reg = obj.REG_NONE
627 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: retReg}
628 }
629
630
631
632
633
634
635
636 p.Spadj = int32(stacksize)
637
638 case AADDI:
639
640 if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_SP && p.From.Type == obj.TYPE_CONST {
641 p.Spadj = int32(-p.From.Offset)
642 }
643 }
644
645 if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.Spadj == 0 {
646 f := cursym.Func()
647 if f.FuncFlag&abi.FuncFlagSPWrite == 0 {
648 f.FuncFlag |= abi.FuncFlagSPWrite
649 if ctxt.Debugvlog || !ctxt.IsAsm {
650 ctxt.Logf("auto-SPWRITE: %s %v\n", cursym.Name, p)
651 if !ctxt.IsAsm {
652 ctxt.Diag("invalid auto-SPWRITE in non-assembly")
653 ctxt.DiagFlush()
654 log.Fatalf("bad SPWRITE")
655 }
656 }
657 }
658 }
659 }
660
661 var callCount int
662 for p := cursym.Func().Text; p != nil; p = p.Link {
663 markRelocs(p)
664 if p.Mark&NEED_JAL_RELOC == NEED_JAL_RELOC {
665 callCount++
666 }
667 }
668 const callTrampSize = 8
669 maxTrampSize := int64(callCount * callTrampSize)
670
671
672
673
674
675 for {
676 big, rescan := false, false
677 maxPC := setPCs(cursym.Func().Text, 0, ctxt.CompressInstructions)
678 if maxPC+maxTrampSize > (1 << 20) {
679 big = true
680 }
681
682 for p := cursym.Func().Text; p != nil; p = p.Link {
683 switch p.As {
684 case ABEQ, ABEQZ, ABGE, ABGEU, ABGEZ, ABGT, ABGTU, ABGTZ, ABLE, ABLEU, ABLEZ, ABLT, ABLTU, ABLTZ, ABNE, ABNEZ, ACBEQZ, ACBNEZ, ACJ:
685 if p.To.Type != obj.TYPE_BRANCH {
686 ctxt.Diag("%v: instruction with branch-like opcode lacks destination", p)
687 break
688 }
689 offset := p.To.Target().Pc - p.Pc
690 if offset < -4096 || 4096 <= offset {
691
692 jmp := obj.Appendp(p, newprog)
693 jmp.As = AJAL
694 jmp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
695 jmp.To = obj.Addr{Type: obj.TYPE_BRANCH}
696 jmp.To.SetTarget(p.To.Target())
697
698 p.As = InvertBranch(p.As)
699 p.To.SetTarget(jmp.Link)
700
701
702
703 rescan = true
704 }
705 case AJAL:
706
707 if p.To.Target() == nil {
708 if !big {
709 break
710 }
711
712
713 jmp := obj.Appendp(p, newprog)
714 jmp.As = AJALR
715 jmp.From = p.From
716 jmp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
717
718 p.As = AAUIPC
719 p.Mark = (p.Mark &^ NEED_JAL_RELOC) | NEED_CALL_RELOC
720 p.AddRestSource(obj.Addr{Type: obj.TYPE_CONST, Offset: p.To.Offset, Sym: p.To.Sym})
721 p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 0}
722 p.Reg = obj.REG_NONE
723 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
724
725 rescan = true
726 break
727 }
728 offset := p.To.Target().Pc - p.Pc
729 if offset < -(1<<20) || (1<<20) <= offset {
730
731
732
733 jmp := obj.Appendp(p, newprog)
734 jmp.As = AJALR
735 jmp.From = p.From
736 jmp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
737
738
739
740 p.As = AAUIPC
741 p.From = obj.Addr{Type: obj.TYPE_BRANCH, Sym: p.From.Sym}
742 p.From.SetTarget(p.To.Target())
743 p.Reg = obj.REG_NONE
744 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
745
746 rescan = true
747 }
748 }
749 }
750
751
752
753 if ctxt.Errors > 0 {
754 return
755 }
756 if !rescan {
757 break
758 }
759 }
760
761
762
763
764 for p := cursym.Func().Text; p != nil; p = p.Link {
765 switch p.As {
766 case ABEQ, ABEQZ, ABGE, ABGEU, ABGEZ, ABGT, ABGTU, ABGTZ, ABLE, ABLEU, ABLEZ, ABLT, ABLTU, ABLTZ, ABNE, ABNEZ, ACBEQZ, ACBNEZ, ACJ:
767 switch p.To.Type {
768 case obj.TYPE_BRANCH:
769 p.To.Type, p.To.Offset = obj.TYPE_CONST, p.To.Target().Pc-p.Pc
770 case obj.TYPE_MEM:
771 if ctxt.Errors == 0 {
772
773 panic("unhandled type")
774 }
775 }
776
777 case AJAL:
778
779 if p.To.Target() != nil {
780 p.To.Type, p.To.Offset = obj.TYPE_CONST, p.To.Target().Pc-p.Pc
781 }
782
783 case AAUIPC:
784 if p.From.Type == obj.TYPE_BRANCH {
785 low, high, err := Split32BitImmediate(p.From.Target().Pc - p.Pc)
786 if err != nil {
787 ctxt.Diag("%v: jump displacement %d too large", p, p.To.Target().Pc-p.Pc)
788 }
789 p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: high, Sym: cursym}
790 p.Link.To.Offset = low
791 }
792
793 case obj.APCALIGN:
794 alignedValue := p.From.Offset
795 if (alignedValue&(alignedValue-1) != 0) || 4 > alignedValue || alignedValue > 2048 {
796 ctxt.Diag("alignment value of an instruction must be a power of two and in the range [4, 2048], got %d\n", alignedValue)
797 }
798
799 if int16(alignedValue) > cursym.Align {
800 cursym.Align = int16(alignedValue)
801 }
802 }
803 }
804
805
806 for p := cursym.Func().Text; p != nil; p = p.Link {
807 for _, ins := range instructionsForProg(p, ctxt.CompressInstructions) {
808 ins.validate(ctxt)
809 }
810 }
811 }
812
813 func pcAlignPadLength(pc int64, alignedValue int64) int {
814 return int(-pc & (alignedValue - 1))
815 }
816
817 func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgAlloc, framesize int64) *obj.Prog {
818
819 if framesize == 0 {
820 return p
821 }
822
823 if ctxt.Flag_maymorestack != "" {
824
825 const frameSize = 16
826 p = ctxt.StartUnsafePoint(p, newprog)
827
828
829
830 p = cursym.Func().SpillRegisterArgs(p, newprog)
831
832
833 p = obj.Appendp(p, newprog)
834 p.As = AMOV
835 p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_LR}
836 p.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: -frameSize}
837
838 p = obj.Appendp(p, newprog)
839 p.As = AADDI
840 p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: -frameSize}
841 p.Reg = REG_SP
842 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_SP}
843 p.Spadj = frameSize
844
845 p = obj.Appendp(p, newprog)
846 p.As = AMOV
847 p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_CTXT}
848 p.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: 8}
849
850
851 p = obj.Appendp(p, newprog)
852 p.As = obj.ACALL
853 p.To.Type = obj.TYPE_BRANCH
854
855 p.To.Sym = ctxt.LookupABI(ctxt.Flag_maymorestack, cursym.ABI())
856 jalToSym(ctxt, p, REG_X5)
857
858
859
860
861 p = obj.Appendp(p, newprog)
862 p.As = AMOV
863 p.From = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: 8}
864 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_CTXT}
865
866 p = obj.Appendp(p, newprog)
867 p.As = AMOV
868 p.From = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_SP, Offset: 0}
869 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_LR}
870
871 p = obj.Appendp(p, newprog)
872 p.As = AADDI
873 p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: frameSize}
874 p.Reg = REG_SP
875 p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_SP}
876 p.Spadj = -frameSize
877
878
879 p = cursym.Func().UnspillRegisterArgs(p, newprog)
880 p = ctxt.EndUnsafePoint(p, newprog, -1)
881 }
882
883
884 startPred := p
885
886
887 p = obj.Appendp(p, newprog)
888 p.As = AMOV
889 p.From.Type = obj.TYPE_MEM
890 p.From.Reg = REGG
891 p.From.Offset = 2 * int64(ctxt.Arch.PtrSize)
892 if cursym.CFunc() {
893 p.From.Offset = 3 * int64(ctxt.Arch.PtrSize)
894 }
895 p.To.Type = obj.TYPE_REG
896 p.To.Reg = REG_X6
897
898
899
900
901
902 p = ctxt.StartUnsafePoint(p, newprog)
903
904 var to_done, to_more *obj.Prog
905
906 if framesize <= abi.StackSmall {
907
908
909
910 p = obj.Appendp(p, newprog)
911 p.As = ABLTU
912 p.From.Type = obj.TYPE_REG
913 p.From.Reg = REG_X6
914 p.Reg = REG_SP
915 p.To.Type = obj.TYPE_BRANCH
916 to_done = p
917 } else {
918
919 offset := framesize - abi.StackSmall
920 if framesize > abi.StackBig {
921
922
923
924
925
926
927
928
929
930
931 p = obj.Appendp(p, newprog)
932 p.As = AMOV
933 p.From.Type = obj.TYPE_CONST
934 p.From.Offset = offset
935 p.To.Type = obj.TYPE_REG
936 p.To.Reg = REG_X7
937
938 p = obj.Appendp(p, newprog)
939 p.As = ABLTU
940 p.From.Type = obj.TYPE_REG
941 p.From.Reg = REG_SP
942 p.Reg = REG_X7
943 p.To.Type = obj.TYPE_BRANCH
944 to_more = p
945 }
946
947
948
949
950
951 p = obj.Appendp(p, newprog)
952 p.As = AADDI
953 p.From.Type = obj.TYPE_CONST
954 p.From.Offset = -offset
955 p.Reg = REG_SP
956 p.To.Type = obj.TYPE_REG
957 p.To.Reg = REG_X7
958
959 p = obj.Appendp(p, newprog)
960 p.As = ABLTU
961 p.From.Type = obj.TYPE_REG
962 p.From.Reg = REG_X6
963 p.Reg = REG_X7
964 p.To.Type = obj.TYPE_BRANCH
965 to_done = p
966 }
967
968
969
970 p = ctxt.EmitEntryStackMap(cursym, p, newprog)
971 p = cursym.Func().SpillRegisterArgs(p, newprog)
972
973
974 p = obj.Appendp(p, newprog)
975 p.As = obj.ACALL
976 p.To.Type = obj.TYPE_BRANCH
977
978 if cursym.CFunc() {
979 p.To.Sym = ctxt.Lookup("runtime.morestackc")
980 } else if !cursym.Func().Text.From.Sym.NeedCtxt() {
981 p.To.Sym = ctxt.Lookup("runtime.morestack_noctxt")
982 } else {
983 p.To.Sym = ctxt.Lookup("runtime.morestack")
984 }
985 if to_more != nil {
986 to_more.To.SetTarget(p)
987 }
988 jalToSym(ctxt, p, REG_X5)
989
990
991 p = ctxt.EndUnsafePoint(p, newprog, -1)
992 p = cursym.Func().UnspillRegisterArgs(p, newprog)
993
994
995 p = obj.Appendp(p, newprog)
996 p.As = AJAL
997 p.To = obj.Addr{Type: obj.TYPE_BRANCH}
998 p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
999 p.To.SetTarget(startPred.Link)
1000
1001
1002 p = obj.Appendp(p, newprog)
1003 p.As = obj.ANOP
1004 to_done.To.SetTarget(p)
1005
1006 return p
1007 }
1008
1009
1010 func signExtend(val int64, bit uint) int64 {
1011 return val << (64 - bit) >> (64 - bit)
1012 }
1013
1014
1015
1016
1017
1018 func Split32BitImmediate(imm int64) (low, high int64, err error) {
1019 if err := immIFits(imm, 32); err != nil {
1020 return 0, 0, err
1021 }
1022
1023
1024 if err := immIFits(imm, 12); err == nil {
1025 return imm, 0, nil
1026 }
1027
1028 high = imm >> 12
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039 if imm&(1<<11) != 0 {
1040 high++
1041 }
1042
1043 low = signExtend(imm, 12)
1044 high = signExtend(high, 20)
1045
1046 return low, high, nil
1047 }
1048
1049 func regVal(r, min, max uint32) uint32 {
1050 if r < min || r > max {
1051 panic(fmt.Sprintf("register out of range, want %d <= %d <= %d", min, r, max))
1052 }
1053 return r - min
1054 }
1055
1056
1057 func regCI(r uint32) uint32 {
1058 return regVal(r, REG_X8, REG_X15)
1059 }
1060
1061
1062 func regCF(r uint32) uint32 {
1063 return regVal(r, REG_F8, REG_F15)
1064 }
1065
1066
1067 func regI(r uint32) uint32 {
1068 return regVal(r, REG_X0, REG_X31)
1069 }
1070
1071
1072 func regF(r uint32) uint32 {
1073 return regVal(r, REG_F0, REG_F31)
1074 }
1075
1076
1077 func regV(r uint32) uint32 {
1078 return regVal(r, REG_V0, REG_V31)
1079 }
1080
1081
1082
1083 func immEven(x int64) error {
1084 if x&1 != 0 {
1085 return fmt.Errorf("immediate %#x is not a multiple of two", x)
1086 }
1087 return nil
1088 }
1089
1090 func immFits(x int64, nbits uint, signed bool) error {
1091 label := "unsigned"
1092 min, max := int64(0), int64(1)<<nbits-1
1093 if signed {
1094 label = "signed"
1095 sbits := nbits - 1
1096 min, max = int64(-1)<<sbits, int64(1)<<sbits-1
1097 }
1098 if x < min || x > max {
1099 if nbits <= 16 {
1100 return fmt.Errorf("%s immediate %d must be in range [%d, %d] (%d bits)", label, x, min, max, nbits)
1101 }
1102 return fmt.Errorf("%s immediate %#x must be in range [%#x, %#x] (%d bits)", label, x, min, max, nbits)
1103 }
1104 return nil
1105 }
1106
1107
1108
1109 func immIFits(x int64, nbits uint) error {
1110 return immFits(x, nbits, true)
1111 }
1112
1113
1114 func immI(as obj.As, imm int64, nbits uint) uint32 {
1115 if err := immIFits(imm, nbits); err != nil {
1116 panic(fmt.Sprintf("%v: %v", as, err))
1117 }
1118 return uint32(imm) & ((1 << nbits) - 1)
1119 }
1120
1121 func wantImmI(ctxt *obj.Link, ins *instruction, imm int64, nbits uint) {
1122 if err := immIFits(imm, nbits); err != nil {
1123 ctxt.Diag("%v: %v", ins, err)
1124 }
1125 }
1126
1127
1128
1129 func immUFits(x int64, nbits uint) error {
1130 return immFits(x, nbits, false)
1131 }
1132
1133
1134 func immU(as obj.As, imm int64, nbits uint) uint32 {
1135 if err := immUFits(imm, nbits); err != nil {
1136 panic(fmt.Sprintf("%v: %v", as, err))
1137 }
1138 return uint32(imm) & ((1 << nbits) - 1)
1139 }
1140
1141 func wantImmU(ctxt *obj.Link, ins *instruction, imm int64, nbits uint) {
1142 if err := immUFits(imm, nbits); err != nil {
1143 ctxt.Diag("%v: %v", ins, err)
1144 }
1145 }
1146
1147 func isScaledImmI(imm int64, nbits uint, scale int64) bool {
1148 return immFits(imm, nbits, true) == nil && imm%scale == 0
1149 }
1150
1151 func isScaledImmU(imm int64, nbits uint, scale int64) bool {
1152 return immFits(imm, nbits, false) == nil && imm%scale == 0
1153 }
1154
1155 func wantScaledImm(ctxt *obj.Link, ins *instruction, imm int64, nbits uint, scale int64, signed bool) {
1156 if err := immFits(imm, nbits, signed); err != nil {
1157 ctxt.Diag("%v: %v", ins, err)
1158 return
1159 }
1160 if imm%scale != 0 {
1161 ctxt.Diag("%v: unsigned immediate %d must be a multiple of %d", ins, imm, scale)
1162 }
1163 }
1164
1165 func wantScaledImmI(ctxt *obj.Link, ins *instruction, imm int64, nbits uint, scale int64) {
1166 wantScaledImm(ctxt, ins, imm, nbits, scale, true)
1167 }
1168
1169 func wantScaledImmU(ctxt *obj.Link, ins *instruction, imm int64, nbits uint, scale int64) {
1170 wantScaledImm(ctxt, ins, imm, nbits, scale, false)
1171 }
1172
1173 func wantReg(ctxt *obj.Link, ins *instruction, pos string, descr string, r, min, max uint32) {
1174 if r < min || r > max {
1175 var suffix string
1176 if r != obj.REG_NONE {
1177 suffix = fmt.Sprintf(" but got non-%s register %s", descr, RegName(int(r)))
1178 }
1179 ctxt.Diag("%v: expected %s register in %s position%s", ins, descr, pos, suffix)
1180 }
1181 }
1182
1183 func wantNoneReg(ctxt *obj.Link, ins *instruction, pos string, r uint32) {
1184 if r != obj.REG_NONE {
1185 ctxt.Diag("%v: expected no register in %s but got register %s", ins, pos, RegName(int(r)))
1186 }
1187 }
1188
1189
1190 func wantIntReg(ctxt *obj.Link, ins *instruction, pos string, r uint32) {
1191 wantReg(ctxt, ins, pos, "integer", r, REG_X0, REG_X31)
1192 }
1193
1194 func isIntPrimeReg(r uint32) bool {
1195 return r >= REG_X8 && r <= REG_X15
1196 }
1197
1198
1199
1200 func wantIntPrimeReg(ctxt *obj.Link, ins *instruction, pos string, r uint32) {
1201 wantReg(ctxt, ins, pos, "integer prime", r, REG_X8, REG_X15)
1202 }
1203
1204
1205 func wantFloatReg(ctxt *obj.Link, ins *instruction, pos string, r uint32) {
1206 wantReg(ctxt, ins, pos, "float", r, REG_F0, REG_F31)
1207 }
1208
1209 func isFloatPrimeReg(r uint32) bool {
1210 return r >= REG_F8 && r <= REG_F15
1211 }
1212
1213
1214
1215 func wantFloatPrimeReg(ctxt *obj.Link, ins *instruction, pos string, r uint32) {
1216 wantReg(ctxt, ins, pos, "float prime", r, REG_F8, REG_F15)
1217 }
1218
1219
1220 func wantVectorReg(ctxt *obj.Link, ins *instruction, pos string, r uint32) {
1221 wantReg(ctxt, ins, pos, "vector", r, REG_V0, REG_V31)
1222 }
1223
1224
1225 func wantEvenOffset(ctxt *obj.Link, ins *instruction, offset int64) {
1226 if err := immEven(offset); err != nil {
1227 ctxt.Diag("%v: %v", ins, err)
1228 }
1229 }
1230
1231 func validateCA(ctxt *obj.Link, ins *instruction) {
1232 wantIntPrimeReg(ctxt, ins, "rd", ins.rd)
1233 if ins.rd != ins.rs1 {
1234 ctxt.Diag("%v: rd must be the same as rs1", ins)
1235 }
1236 wantIntPrimeReg(ctxt, ins, "rs2", ins.rs2)
1237 }
1238
1239 func validateCB(ctxt *obj.Link, ins *instruction) {
1240 if (ins.as == ACSRAI || ins.as == ACSRLI) && ins.imm == 0 {
1241 ctxt.Diag("%v: immediate cannot be zero", ins)
1242 } else if ins.as == ACSRAI || ins.as == ACSRLI {
1243 wantImmU(ctxt, ins, ins.imm, 6)
1244 } else if ins.as == ACBEQZ || ins.as == ACBNEZ {
1245 wantImmI(ctxt, ins, ins.imm, 9)
1246 } else {
1247 wantImmI(ctxt, ins, ins.imm, 6)
1248 }
1249 if ins.as == ACBEQZ || ins.as == ACBNEZ {
1250 wantNoneReg(ctxt, ins, "rd", ins.rd)
1251 wantIntPrimeReg(ctxt, ins, "rs1", ins.rs1)
1252 } else {
1253 wantIntPrimeReg(ctxt, ins, "rd", ins.rd)
1254 if ins.rd != ins.rs1 {
1255 ctxt.Diag("%v: rd must be the same as rs1", ins)
1256 }
1257 }
1258 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1259 }
1260
1261 func validateCI(ctxt *obj.Link, ins *instruction) {
1262 if ins.as != ACNOP && ins.rd == REG_X0 {
1263 ctxt.Diag("%v: cannot use register X0 in rd", ins)
1264 }
1265 if ins.as == ACLUI && ins.rd == REG_X2 {
1266 ctxt.Diag("%v: cannot use register SP/X2 in rd", ins)
1267 }
1268 if ins.as != ACLI && ins.as != ACLUI && ins.as != ACLWSP && ins.as != ACLDSP && ins.as != ACFLDSP && ins.rd != ins.rs1 {
1269 ctxt.Diag("%v: rd must be the same as rs1", ins)
1270 }
1271 if ins.as == ACADDI16SP && ins.rd != REG_SP {
1272 ctxt.Diag("%v: rd must be SP/X2", ins)
1273 }
1274 if (ins.as == ACLWSP || ins.as == ACLDSP || ins.as == ACFLDSP) && ins.rs2 != REG_SP {
1275 ctxt.Diag("%v: rs2 must be SP/X2", ins)
1276 }
1277 if (ins.as == ACADDI || ins.as == ACADDI16SP || ins.as == ACLUI || ins.as == ACSLLI) && ins.imm == 0 {
1278 ctxt.Diag("%v: immediate cannot be zero", ins)
1279 } else if ins.as == ACSLLI {
1280 wantImmU(ctxt, ins, ins.imm, 6)
1281 } else if ins.as == ACLWSP {
1282 wantScaledImmU(ctxt, ins, ins.imm, 8, 4)
1283 } else if ins.as == ACLDSP || ins.as == ACFLDSP {
1284 wantScaledImmU(ctxt, ins, ins.imm, 9, 8)
1285 } else if ins.as == ACADDI16SP {
1286 wantScaledImmI(ctxt, ins, ins.imm, 10, 16)
1287 } else {
1288 wantImmI(ctxt, ins, ins.imm, 6)
1289 }
1290 switch ins.as {
1291 case ACNOP, ACADDI, ACADDIW, ACSLLI:
1292 wantIntReg(ctxt, ins, "rd", ins.rd)
1293 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1294 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1295 case ACLWSP, ACLDSP:
1296 wantIntReg(ctxt, ins, "rd", ins.rd)
1297 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1298 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1299 case ACFLDSP:
1300 wantFloatReg(ctxt, ins, "rd", ins.rd)
1301 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1302 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1303 case ACADDI16SP:
1304 wantIntReg(ctxt, ins, "rd", ins.rd)
1305 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1306 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1307 default:
1308 wantIntReg(ctxt, ins, "rd", ins.rd)
1309 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1310 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1311 }
1312 }
1313
1314 func validateCIW(ctxt *obj.Link, ins *instruction) {
1315 wantScaledImmU(ctxt, ins, ins.imm, 10, 4)
1316 wantIntPrimeReg(ctxt, ins, "rd", ins.rd)
1317 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1318 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1319 if ins.imm == 0 {
1320 ctxt.Diag("%v: immediate cannot be zero", ins)
1321 }
1322 if ins.rs1 != REG_SP {
1323 ctxt.Diag("%v: SP/X2 must be in rs1", ins)
1324 }
1325 }
1326
1327 func validateCJ(ctxt *obj.Link, ins *instruction) {
1328 wantEvenOffset(ctxt, ins, ins.imm)
1329 wantImmI(ctxt, ins, ins.imm, 12)
1330 if ins.as != ACJ {
1331 wantNoneReg(ctxt, ins, "rd", ins.rd)
1332 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1333 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1334 if ins.rs1 == REG_X0 {
1335 ctxt.Diag("%v: cannot use register X0 in rs1", ins)
1336 }
1337 }
1338 }
1339
1340 func validateCL(ctxt *obj.Link, ins *instruction) {
1341 if ins.as == ACLW {
1342 wantScaledImmU(ctxt, ins, ins.imm, 7, 4)
1343 } else if ins.as == ACLD || ins.as == ACFLD {
1344 wantScaledImmU(ctxt, ins, ins.imm, 8, 8)
1345 } else {
1346 wantImmI(ctxt, ins, ins.imm, 5)
1347 }
1348 if ins.as == ACFLD {
1349 wantFloatPrimeReg(ctxt, ins, "rd", ins.rd)
1350 } else {
1351 wantIntPrimeReg(ctxt, ins, "rd", ins.rd)
1352 }
1353 wantIntPrimeReg(ctxt, ins, "rs1", ins.rs1)
1354 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1355 }
1356
1357 func validateCR(ctxt *obj.Link, ins *instruction) {
1358 switch ins.as {
1359 case ACJR, ACJALR:
1360 wantNoneReg(ctxt, ins, "rd", ins.rd)
1361 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1362 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1363 if ins.rs1 == REG_X0 {
1364 ctxt.Diag("%v: cannot use register X0 in rs1", ins)
1365 }
1366 case ACMV:
1367 wantIntReg(ctxt, ins, "rd", ins.rd)
1368 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1369 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1370 if ins.rd == REG_X0 {
1371 ctxt.Diag("%v: cannot use register X0 in rd", ins)
1372 }
1373 if ins.rs2 == REG_X0 {
1374 ctxt.Diag("%v: cannot use register X0 in rs2", ins)
1375 }
1376 case ACEBREAK:
1377 wantNoneReg(ctxt, ins, "rd", ins.rd)
1378 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1379 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1380 case ACADD:
1381 wantIntReg(ctxt, ins, "rd", ins.rd)
1382 if ins.rd == REG_X0 {
1383 ctxt.Diag("%v: cannot use register X0 in rd", ins)
1384 }
1385 if ins.rd != ins.rs1 {
1386 ctxt.Diag("%v: rd must be the same as rs1", ins)
1387 }
1388 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1389 if ins.rs2 == REG_X0 {
1390 ctxt.Diag("%v: cannot use register X0 in rs2", ins)
1391 }
1392 }
1393 }
1394
1395 func validateCS(ctxt *obj.Link, ins *instruction) {
1396 if ins.as == ACSW {
1397 wantScaledImmU(ctxt, ins, ins.imm, 7, 4)
1398 } else if ins.as == ACSD || ins.as == ACFSD {
1399 wantScaledImmU(ctxt, ins, ins.imm, 8, 8)
1400 } else {
1401 wantImmI(ctxt, ins, ins.imm, 5)
1402 }
1403 wantNoneReg(ctxt, ins, "rd", ins.rd)
1404 wantIntPrimeReg(ctxt, ins, "rs1", ins.rs1)
1405 if ins.as == ACFSD {
1406 wantFloatPrimeReg(ctxt, ins, "rs2", ins.rs2)
1407 } else {
1408 wantIntPrimeReg(ctxt, ins, "rs2", ins.rs2)
1409 }
1410 }
1411
1412 func validateCSS(ctxt *obj.Link, ins *instruction) {
1413 if ins.rd != REG_SP {
1414 ctxt.Diag("%v: rd must be SP/X2", ins)
1415 }
1416 if ins.as == ACSWSP {
1417 wantScaledImmU(ctxt, ins, ins.imm, 8, 4)
1418 } else if ins.as == ACSDSP || ins.as == ACFSDSP {
1419 wantScaledImmU(ctxt, ins, ins.imm, 9, 8)
1420 } else {
1421 wantImmI(ctxt, ins, ins.imm, 6)
1422 }
1423 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1424 if ins.as == ACFSDSP {
1425 wantFloatReg(ctxt, ins, "rs2", ins.rs2)
1426 } else {
1427 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1428 }
1429 }
1430
1431 func validateRII(ctxt *obj.Link, ins *instruction) {
1432 wantIntReg(ctxt, ins, "rd", ins.rd)
1433 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1434 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1435 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1436 }
1437
1438 func validateRIII(ctxt *obj.Link, ins *instruction) {
1439 wantIntReg(ctxt, ins, "rd", ins.rd)
1440 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1441 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1442 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1443 }
1444
1445 func validateRFFF(ctxt *obj.Link, ins *instruction) {
1446 wantFloatReg(ctxt, ins, "rd", ins.rd)
1447 wantFloatReg(ctxt, ins, "rs1", ins.rs1)
1448 wantFloatReg(ctxt, ins, "rs2", ins.rs2)
1449 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1450 }
1451
1452 func validateRFFFF(ctxt *obj.Link, ins *instruction) {
1453 wantFloatReg(ctxt, ins, "rd", ins.rd)
1454 wantFloatReg(ctxt, ins, "rs1", ins.rs1)
1455 wantFloatReg(ctxt, ins, "rs2", ins.rs2)
1456 wantFloatReg(ctxt, ins, "rs3", ins.rs3)
1457 }
1458
1459 func validateRFFI(ctxt *obj.Link, ins *instruction) {
1460 wantIntReg(ctxt, ins, "rd", ins.rd)
1461 wantFloatReg(ctxt, ins, "rs1", ins.rs1)
1462 wantFloatReg(ctxt, ins, "rs2", ins.rs2)
1463 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1464 }
1465
1466 func validateRFI(ctxt *obj.Link, ins *instruction) {
1467 wantIntReg(ctxt, ins, "rd", ins.rd)
1468 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1469 wantFloatReg(ctxt, ins, "rs2", ins.rs2)
1470 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1471 }
1472
1473 func validateRFV(ctxt *obj.Link, ins *instruction) {
1474 wantVectorReg(ctxt, ins, "vd", ins.rd)
1475 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1476 wantFloatReg(ctxt, ins, "rs2", ins.rs2)
1477 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1478 }
1479
1480 func validateRFF(ctxt *obj.Link, ins *instruction) {
1481 wantFloatReg(ctxt, ins, "rd", ins.rd)
1482 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1483 wantFloatReg(ctxt, ins, "rs2", ins.rs2)
1484 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1485 }
1486
1487 func validateRIF(ctxt *obj.Link, ins *instruction) {
1488 wantFloatReg(ctxt, ins, "rd", ins.rd)
1489 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1490 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1491 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1492 }
1493
1494 func validateRIV(ctxt *obj.Link, ins *instruction) {
1495 wantVectorReg(ctxt, ins, "vd", ins.rd)
1496 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1497 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1498 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1499 }
1500
1501 func validateRVF(ctxt *obj.Link, ins *instruction) {
1502 wantFloatReg(ctxt, ins, "rd", ins.rd)
1503 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1504 wantVectorReg(ctxt, ins, "vs2", ins.rs2)
1505 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1506 }
1507
1508 func validateRVFV(ctxt *obj.Link, ins *instruction) {
1509 wantVectorReg(ctxt, ins, "vd", ins.rd)
1510 wantFloatReg(ctxt, ins, "rs1", ins.rs1)
1511 wantVectorReg(ctxt, ins, "vs2", ins.rs2)
1512 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1513 }
1514
1515 func validateRVI(ctxt *obj.Link, ins *instruction) {
1516 wantIntReg(ctxt, ins, "rd", ins.rd)
1517 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1518 wantVectorReg(ctxt, ins, "vs2", ins.rs2)
1519 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1520 }
1521
1522 func validateRVIV(ctxt *obj.Link, ins *instruction) {
1523 wantVectorReg(ctxt, ins, "vd", ins.rd)
1524 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1525 wantVectorReg(ctxt, ins, "vs2", ins.rs2)
1526 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1527 }
1528
1529 func validateRVV(ctxt *obj.Link, ins *instruction) {
1530 wantVectorReg(ctxt, ins, "vd", ins.rd)
1531 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1532 wantVectorReg(ctxt, ins, "vs2", ins.rs2)
1533 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1534 }
1535
1536 func validateRVVi(ctxt *obj.Link, ins *instruction) {
1537 wantImmI(ctxt, ins, ins.imm, 5)
1538 wantVectorReg(ctxt, ins, "vd", ins.rd)
1539 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1540 wantVectorReg(ctxt, ins, "vs2", ins.rs2)
1541 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1542 }
1543
1544 func validateRVVu(ctxt *obj.Link, ins *instruction) {
1545 wantImmU(ctxt, ins, ins.imm, 5)
1546 wantVectorReg(ctxt, ins, "vd", ins.rd)
1547 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1548 wantVectorReg(ctxt, ins, "vs2", ins.rs2)
1549 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1550 }
1551
1552 func validateRVVV(ctxt *obj.Link, ins *instruction) {
1553 wantVectorReg(ctxt, ins, "vd", ins.rd)
1554 wantVectorReg(ctxt, ins, "vs1", ins.rs1)
1555 wantVectorReg(ctxt, ins, "vs2", ins.rs2)
1556 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1557 }
1558
1559 func validateIII(ctxt *obj.Link, ins *instruction) {
1560 wantImmI(ctxt, ins, ins.imm, 12)
1561 wantIntReg(ctxt, ins, "rd", ins.rd)
1562 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1563 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1564 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1565 }
1566
1567 func validateIF(ctxt *obj.Link, ins *instruction) {
1568 wantImmI(ctxt, ins, ins.imm, 12)
1569 wantFloatReg(ctxt, ins, "rd", ins.rd)
1570 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1571 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1572 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1573 }
1574
1575 func validateIV(ctxt *obj.Link, ins *instruction) {
1576 wantVectorReg(ctxt, ins, "vd", ins.rd)
1577 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1578 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1579 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1580 }
1581
1582 func validateIIIV(ctxt *obj.Link, ins *instruction) {
1583 wantVectorReg(ctxt, ins, "vd", ins.rd)
1584 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1585 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1586 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1587 }
1588
1589 func validateIVIV(ctxt *obj.Link, ins *instruction) {
1590 wantVectorReg(ctxt, ins, "vd", ins.rd)
1591 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1592 wantVectorReg(ctxt, ins, "vs2", ins.rs2)
1593 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1594 }
1595
1596 func validateSI(ctxt *obj.Link, ins *instruction) {
1597 wantImmI(ctxt, ins, ins.imm, 12)
1598 wantIntReg(ctxt, ins, "rd", ins.rd)
1599 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1600 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1601 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1602 }
1603
1604 func validateSF(ctxt *obj.Link, ins *instruction) {
1605 wantImmI(ctxt, ins, ins.imm, 12)
1606 wantIntReg(ctxt, ins, "rd", ins.rd)
1607 wantFloatReg(ctxt, ins, "rs1", ins.rs1)
1608 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1609 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1610 }
1611
1612 func validateSV(ctxt *obj.Link, ins *instruction) {
1613 wantIntReg(ctxt, ins, "rd", ins.rd)
1614 wantVectorReg(ctxt, ins, "vs1", ins.rs1)
1615 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1616 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1617 }
1618
1619 func validateSVII(ctxt *obj.Link, ins *instruction) {
1620 wantVectorReg(ctxt, ins, "vd", ins.rd)
1621 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1622 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1623 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1624 }
1625
1626 func validateSVIV(ctxt *obj.Link, ins *instruction) {
1627 wantVectorReg(ctxt, ins, "vd", ins.rd)
1628 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1629 wantVectorReg(ctxt, ins, "vs2", ins.rs2)
1630 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1631 }
1632
1633 func validateB(ctxt *obj.Link, ins *instruction) {
1634
1635
1636 wantEvenOffset(ctxt, ins, ins.imm)
1637 wantImmI(ctxt, ins, ins.imm, 13)
1638 wantNoneReg(ctxt, ins, "rd", ins.rd)
1639 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1640 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1641 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1642 }
1643
1644 func validateU(ctxt *obj.Link, ins *instruction) {
1645 wantImmI(ctxt, ins, ins.imm, 20)
1646 wantIntReg(ctxt, ins, "rd", ins.rd)
1647 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1648 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1649 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1650 }
1651
1652 func validateJ(ctxt *obj.Link, ins *instruction) {
1653
1654
1655 wantEvenOffset(ctxt, ins, ins.imm)
1656 wantImmI(ctxt, ins, ins.imm, 21)
1657 wantIntReg(ctxt, ins, "rd", ins.rd)
1658 wantNoneReg(ctxt, ins, "rs1", ins.rs1)
1659 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1660 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1661 }
1662
1663 func validateVsetvli(ctxt *obj.Link, ins *instruction) {
1664 wantImmU(ctxt, ins, ins.imm, 11)
1665 wantIntReg(ctxt, ins, "rd", ins.rd)
1666 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1667 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1668 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1669 }
1670
1671 func validateVsetivli(ctxt *obj.Link, ins *instruction) {
1672 wantImmU(ctxt, ins, ins.imm, 10)
1673 wantIntReg(ctxt, ins, "rd", ins.rd)
1674 wantImmU(ctxt, ins, int64(ins.rs1), 5)
1675 wantNoneReg(ctxt, ins, "rs2", ins.rs2)
1676 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1677 }
1678
1679 func validateVsetvl(ctxt *obj.Link, ins *instruction) {
1680 wantIntReg(ctxt, ins, "rd", ins.rd)
1681 wantIntReg(ctxt, ins, "rs1", ins.rs1)
1682 wantIntReg(ctxt, ins, "rs2", ins.rs2)
1683 wantNoneReg(ctxt, ins, "rs3", ins.rs3)
1684 }
1685
1686 func validateRaw(ctxt *obj.Link, ins *instruction) {
1687
1688
1689 wantImmU(ctxt, ins, ins.imm, 32)
1690 }
1691
1692
1693
1694 func compressedEncoding(as obj.As) uint32 {
1695 enc := encode(as)
1696 if enc == nil {
1697 panic("compressedEncoding: could not encode instruction")
1698 }
1699
1700
1701
1702 op := uint32(0)
1703 switch as {
1704 case ACSUB:
1705 op = 0b100011<<10 | 0b00<<5
1706 case ACXOR:
1707 op = 0b100011<<10 | 0b01<<5
1708 case ACOR:
1709 op = 0b100011<<10 | 0b10<<5
1710 case ACAND:
1711 op = 0b100011<<10 | 0b11<<5
1712 case ACSUBW:
1713 op = 0b100111<<10 | 0b00<<5
1714 case ACADDW:
1715 op = 0b100111<<10 | 0b01<<5
1716 case ACBEQZ:
1717 op = 0b110 << 13
1718 case ACBNEZ:
1719 op = 0b111 << 13
1720 case ACANDI:
1721 op = 0b100<<13 | 0b10<<10
1722 case ACSRAI:
1723 op = 0b100<<13 | 0b01<<10
1724 case ACSRLI:
1725 op = 0b100<<13 | 0b00<<10
1726 case ACLI:
1727 op = 0b010 << 13
1728 case ACLUI:
1729 op = 0b011 << 13
1730 case ACLWSP:
1731 op = 0b010 << 13
1732 case ACLDSP:
1733 op = 0b011 << 13
1734 case ACFLDSP:
1735 op = 0b001 << 13
1736 case ACADDIW:
1737 op = 0b001 << 13
1738 case ACADDI16SP:
1739 op = 0b011 << 13
1740 case ACADDI4SPN:
1741 op = 0b000 << 13
1742 case ACJ:
1743 op = 0b101 << 13
1744 case ACLW:
1745 op = 0b010 << 13
1746 case ACLD:
1747 op = 0b011 << 13
1748 case ACFLD:
1749 op = 0b001 << 13
1750 case ACJR:
1751 op = 0b1000 << 12
1752 case ACMV:
1753 op = 0b1000 << 12
1754 case ACEBREAK:
1755 op = 0b1001 << 12
1756 case ACJALR:
1757 op = 0b1001 << 12
1758 case ACADD:
1759 op = 0b1001 << 12
1760 case ACSW:
1761 op = 0b110 << 13
1762 case ACSD:
1763 op = 0b111 << 13
1764 case ACFSD:
1765 op = 0b101 << 13
1766 case ACSWSP:
1767 op = 0b110 << 13
1768 case ACSDSP:
1769 op = 0b111 << 13
1770 case ACFSDSP:
1771 op = 0b101 << 13
1772 }
1773
1774 return op | enc.opcode
1775 }
1776
1777
1778
1779
1780
1781 func encodeBitPattern(imm uint32, pattern []int) uint32 {
1782 outImm := uint32(0)
1783 for _, bit := range pattern {
1784 outImm = outImm<<1 | (imm>>bit)&1
1785 }
1786 return outImm
1787 }
1788
1789
1790 func encodeCA(ins *instruction) uint32 {
1791 return compressedEncoding(ins.as) | regCI(ins.rd)<<7 | regCI(ins.rs2)<<2
1792 }
1793
1794
1795 func encodeCBImmediate(imm uint32) uint32 {
1796
1797 bits := encodeBitPattern(imm, []int{8, 4, 3, 7, 6, 2, 1, 5})
1798 return (bits>>5)<<10 | (bits&0x1f)<<2
1799 }
1800
1801
1802 func encodeCB(ins *instruction) uint32 {
1803 imm := uint32(0)
1804 if ins.as == ACBEQZ || ins.as == ACBNEZ {
1805 imm = immI(ins.as, ins.imm, 9)
1806 imm = encodeBitPattern(imm, []int{8, 4, 3, 7, 6, 2, 1, 5})
1807 } else if ins.as == ACANDI {
1808 imm = immI(ins.as, ins.imm, 6)
1809 imm = (imm>>5)<<7 | imm&0x1f
1810 } else if ins.as == ACSRAI || ins.as == ACSRLI {
1811 imm = immU(ins.as, ins.imm, 6)
1812 imm = (imm>>5)<<7 | imm&0x1f
1813 }
1814 return compressedEncoding(ins.as) | (imm>>5)<<10 | regCI(ins.rs1)<<7 | (imm&0x1f)<<2
1815 }
1816
1817
1818 func encodeCI(ins *instruction) uint32 {
1819 imm := uint32(ins.imm)
1820 if ins.as == ACLWSP {
1821
1822 imm = encodeBitPattern(imm, []int{5, 4, 3, 2, 7, 6})
1823 } else if ins.as == ACLDSP || ins.as == ACFLDSP {
1824
1825 imm = encodeBitPattern(imm, []int{5, 4, 3, 8, 7, 6})
1826 } else if ins.as == ACADDI16SP {
1827
1828 imm = encodeBitPattern(imm, []int{9, 4, 6, 8, 7, 5})
1829 }
1830 rd := uint32(0)
1831 if ins.as == ACFLDSP {
1832 rd = regF(ins.rd)
1833 } else {
1834 rd = regI(ins.rd)
1835 }
1836 return compressedEncoding(ins.as) | ((imm>>5)&0x1)<<12 | rd<<7 | (imm&0x1f)<<2
1837 }
1838
1839
1840 func encodeCIW(ins *instruction) uint32 {
1841 imm := uint32(ins.imm)
1842 if ins.as == ACADDI4SPN {
1843
1844 imm = encodeBitPattern(imm, []int{5, 4, 9, 8, 7, 6, 2, 3})
1845 }
1846 return compressedEncoding(ins.as) | imm<<5 | regCI(ins.rd)<<2
1847 }
1848
1849
1850 func encodeCJImmediate(imm uint32) uint32 {
1851
1852 bits := encodeBitPattern(imm, []int{11, 4, 9, 8, 10, 6, 7, 3, 2, 1, 5})
1853 return bits << 2
1854 }
1855
1856
1857 func encodeCJ(ins *instruction) uint32 {
1858 return compressedEncoding(ins.as) | encodeCJImmediate(uint32(ins.imm))
1859 }
1860
1861
1862 func encodeCL(ins *instruction) uint32 {
1863 imm := uint32(ins.imm)
1864 if ins.as == ACLW {
1865
1866 imm = encodeBitPattern(imm, []int{5, 4, 3, 2, 6})
1867 } else if ins.as == ACLD || ins.as == ACFLD {
1868
1869 imm = encodeBitPattern(imm, []int{5, 4, 3, 7, 6})
1870 }
1871 rd := uint32(0)
1872 if ins.as == ACFLD {
1873 rd = regCF(ins.rd)
1874 } else {
1875 rd = regCI(ins.rd)
1876 }
1877 return compressedEncoding(ins.as) | (imm>>2)<<10 | regCI(ins.rs1)<<7 | (imm&0x3)<<5 | rd<<2
1878 }
1879
1880
1881 func encodeCR(ins *instruction) uint32 {
1882 rs1, rs2 := uint32(0), uint32(0)
1883 switch ins.as {
1884 case ACJR, ACJALR:
1885 rs1 = regI(ins.rs1)
1886 case ACMV:
1887 rs1, rs2 = regI(ins.rd), regI(ins.rs2)
1888 case ACADD:
1889 rs1, rs2 = regI(ins.rs1), regI(ins.rs2)
1890 }
1891 return compressedEncoding(ins.as) | rs1<<7 | rs2<<2
1892 }
1893
1894
1895 func encodeCS(ins *instruction) uint32 {
1896 imm := uint32(ins.imm)
1897 if ins.as == ACSW {
1898
1899 imm = encodeBitPattern(imm, []int{5, 4, 3, 2, 6})
1900 } else if ins.as == ACSD || ins.as == ACFSD {
1901
1902 imm = encodeBitPattern(imm, []int{5, 4, 3, 7, 6})
1903 }
1904 rs2 := uint32(0)
1905 if ins.as == ACFSD {
1906 rs2 = regCF(ins.rs2)
1907 } else {
1908 rs2 = regCI(ins.rs2)
1909 }
1910 return compressedEncoding(ins.as) | ((imm>>2)&0x7)<<10 | regCI(ins.rs1)<<7 | (imm&3)<<5 | rs2<<2
1911 }
1912
1913
1914 func encodeCSS(ins *instruction) uint32 {
1915 imm := uint32(ins.imm)
1916 if ins.as == ACSWSP {
1917
1918 imm = encodeBitPattern(imm, []int{5, 4, 3, 2, 7, 6})
1919 } else if ins.as == ACSDSP || ins.as == ACFSDSP {
1920
1921 imm = encodeBitPattern(imm, []int{5, 4, 3, 8, 7, 6})
1922 }
1923 rs2 := uint32(0)
1924 if ins.as == ACFSDSP {
1925 rs2 = regF(ins.rs2)
1926 } else {
1927 rs2 = regI(ins.rs2)
1928 }
1929 return compressedEncoding(ins.as) | imm<<7 | rs2<<2
1930 }
1931
1932
1933 func encodeR(as obj.As, rs1, rs2, rd, funct3, funct7 uint32) uint32 {
1934 enc := encode(as)
1935 if enc == nil {
1936 panic("encodeR: could not encode instruction")
1937 }
1938 if enc.rs1 != 0 && rs1 != 0 {
1939 panic("encodeR: instruction uses rs1, but rs1 is nonzero")
1940 }
1941 if enc.rs2 != 0 && rs2 != 0 {
1942 panic("encodeR: instruction uses rs2, but rs2 is nonzero")
1943 }
1944 funct3 |= enc.funct3
1945 funct7 |= enc.funct7
1946 rs1 |= enc.rs1
1947 rs2 |= enc.rs2
1948 return funct7<<25 | rs2<<20 | rs1<<15 | funct3<<12 | rd<<7 | enc.opcode
1949 }
1950
1951
1952 func encodeR4(as obj.As, rs1, rs2, rs3, rd, funct3, funct2 uint32) uint32 {
1953 enc := encode(as)
1954 if enc == nil {
1955 panic("encodeR4: could not encode instruction")
1956 }
1957 if enc.rs2 != 0 {
1958 panic("encodeR4: instruction uses rs2")
1959 }
1960 funct2 |= enc.funct7
1961 if funct2&^3 != 0 {
1962 panic("encodeR4: funct2 requires more than 2 bits")
1963 }
1964 return rs3<<27 | funct2<<25 | rs2<<20 | rs1<<15 | enc.funct3<<12 | funct3<<12 | rd<<7 | enc.opcode
1965 }
1966
1967 func encodeRII(ins *instruction) uint32 {
1968 return encodeR(ins.as, regI(ins.rs1), 0, regI(ins.rd), ins.funct3, ins.funct7)
1969 }
1970
1971 func encodeRIII(ins *instruction) uint32 {
1972 return encodeR(ins.as, regI(ins.rs1), regI(ins.rs2), regI(ins.rd), ins.funct3, ins.funct7)
1973 }
1974
1975 func encodeRFFF(ins *instruction) uint32 {
1976 return encodeR(ins.as, regF(ins.rs1), regF(ins.rs2), regF(ins.rd), ins.funct3, ins.funct7)
1977 }
1978
1979 func encodeRFFFF(ins *instruction) uint32 {
1980 return encodeR4(ins.as, regF(ins.rs1), regF(ins.rs2), regF(ins.rs3), regF(ins.rd), ins.funct3, ins.funct7)
1981 }
1982
1983 func encodeRFFI(ins *instruction) uint32 {
1984 return encodeR(ins.as, regF(ins.rs1), regF(ins.rs2), regI(ins.rd), ins.funct3, ins.funct7)
1985 }
1986
1987 func encodeRFI(ins *instruction) uint32 {
1988 return encodeR(ins.as, regF(ins.rs2), 0, regI(ins.rd), ins.funct3, ins.funct7)
1989 }
1990
1991 func encodeRFF(ins *instruction) uint32 {
1992 return encodeR(ins.as, regF(ins.rs2), 0, regF(ins.rd), ins.funct3, ins.funct7)
1993 }
1994
1995 func encodeRFV(ins *instruction) uint32 {
1996 return encodeR(ins.as, regF(ins.rs2), 0, regV(ins.rd), ins.funct3, ins.funct7)
1997 }
1998
1999 func encodeRIF(ins *instruction) uint32 {
2000 return encodeR(ins.as, regI(ins.rs2), 0, regF(ins.rd), ins.funct3, ins.funct7)
2001 }
2002
2003 func encodeRIV(ins *instruction) uint32 {
2004 return encodeR(ins.as, regI(ins.rs2), 0, regV(ins.rd), ins.funct3, ins.funct7)
2005 }
2006
2007 func encodeRVF(ins *instruction) uint32 {
2008 return encodeR(ins.as, 0, regV(ins.rs2), regF(ins.rd), ins.funct3, ins.funct7)
2009 }
2010
2011 func encodeRVFV(ins *instruction) uint32 {
2012 return encodeR(ins.as, regF(ins.rs1), regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7)
2013 }
2014
2015 func encodeRVI(ins *instruction) uint32 {
2016 return encodeR(ins.as, 0, regV(ins.rs2), regI(ins.rd), ins.funct3, ins.funct7)
2017 }
2018
2019 func encodeRVIV(ins *instruction) uint32 {
2020 return encodeR(ins.as, regI(ins.rs1), regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7)
2021 }
2022
2023 func encodeRVV(ins *instruction) uint32 {
2024 return encodeR(ins.as, 0, regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7)
2025 }
2026
2027 func encodeRVVi(ins *instruction) uint32 {
2028 return encodeR(ins.as, immI(ins.as, ins.imm, 5), regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7)
2029 }
2030
2031 func encodeRVVu(ins *instruction) uint32 {
2032 return encodeR(ins.as, immU(ins.as, ins.imm, 5), regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7)
2033 }
2034
2035 func encodeRVVV(ins *instruction) uint32 {
2036 return encodeR(ins.as, regV(ins.rs1), regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7)
2037 }
2038
2039
2040 func encodeI(as obj.As, rs1, rd, imm, funct7 uint32) uint32 {
2041 enc := encode(as)
2042 if enc == nil {
2043 panic("encodeI: could not encode instruction")
2044 }
2045 imm |= uint32(enc.csr)
2046 return funct7<<25 | imm<<20 | rs1<<15 | enc.funct3<<12 | rd<<7 | enc.opcode
2047 }
2048
2049 func encodeIII(ins *instruction) uint32 {
2050 return encodeI(ins.as, regI(ins.rs1), regI(ins.rd), uint32(ins.imm), 0)
2051 }
2052
2053 func encodeIF(ins *instruction) uint32 {
2054 return encodeI(ins.as, regI(ins.rs1), regF(ins.rd), uint32(ins.imm), 0)
2055 }
2056
2057 func encodeIV(ins *instruction) uint32 {
2058 return encodeI(ins.as, regI(ins.rs1), regV(ins.rd), uint32(ins.imm), ins.funct7)
2059 }
2060
2061 func encodeIIIV(ins *instruction) uint32 {
2062 return encodeI(ins.as, regI(ins.rs1), regV(ins.rd), regI(ins.rs2), ins.funct7)
2063 }
2064
2065 func encodeIVIV(ins *instruction) uint32 {
2066 return encodeI(ins.as, regI(ins.rs1), regV(ins.rd), regV(ins.rs2), ins.funct7)
2067 }
2068
2069
2070 func encodeS(as obj.As, rs1, rs2, imm, funct7 uint32) uint32 {
2071 enc := encode(as)
2072 if enc == nil {
2073 panic("encodeS: could not encode instruction")
2074 }
2075 if enc.rs2 != 0 && rs2 != 0 {
2076 panic("encodeS: instruction uses rs2, but rs2 was nonzero")
2077 }
2078 rs2 |= enc.rs2
2079 imm |= uint32(enc.csr) &^ 0x1f
2080 return funct7<<25 | (imm>>5)<<25 | rs2<<20 | rs1<<15 | enc.funct3<<12 | (imm&0x1f)<<7 | enc.opcode
2081 }
2082
2083 func encodeSI(ins *instruction) uint32 {
2084 return encodeS(ins.as, regI(ins.rd), regI(ins.rs1), uint32(ins.imm), 0)
2085 }
2086
2087 func encodeSF(ins *instruction) uint32 {
2088 return encodeS(ins.as, regI(ins.rd), regF(ins.rs1), uint32(ins.imm), 0)
2089 }
2090
2091 func encodeSV(ins *instruction) uint32 {
2092 return encodeS(ins.as, regI(ins.rd), 0, regV(ins.rs1), ins.funct7)
2093 }
2094
2095 func encodeSVII(ins *instruction) uint32 {
2096 return encodeS(ins.as, regI(ins.rs1), regI(ins.rs2), regV(ins.rd), ins.funct7)
2097 }
2098
2099 func encodeSVIV(ins *instruction) uint32 {
2100 return encodeS(ins.as, regI(ins.rs1), regV(ins.rs2), regV(ins.rd), ins.funct7)
2101 }
2102
2103
2104 func encodeBImmediate(imm uint32) uint32 {
2105 return (imm>>12)<<31 | ((imm>>5)&0x3f)<<25 | ((imm>>1)&0xf)<<8 | ((imm>>11)&0x1)<<7
2106 }
2107
2108
2109 func encodeB(ins *instruction) uint32 {
2110 imm := immI(ins.as, ins.imm, 13)
2111 rs2 := regI(ins.rs1)
2112 rs1 := regI(ins.rs2)
2113 enc := encode(ins.as)
2114 if enc == nil {
2115 panic("encodeB: could not encode instruction")
2116 }
2117 return encodeBImmediate(imm) | rs2<<20 | rs1<<15 | enc.funct3<<12 | enc.opcode
2118 }
2119
2120
2121 func encodeU(ins *instruction) uint32 {
2122
2123
2124
2125
2126 imm := immI(ins.as, ins.imm, 20)
2127 rd := regI(ins.rd)
2128 enc := encode(ins.as)
2129 if enc == nil {
2130 panic("encodeU: could not encode instruction")
2131 }
2132 return imm<<12 | rd<<7 | enc.opcode
2133 }
2134
2135
2136 func encodeJImmediate(imm uint32) uint32 {
2137 return (imm>>20)<<31 | ((imm>>1)&0x3ff)<<21 | ((imm>>11)&0x1)<<20 | ((imm>>12)&0xff)<<12
2138 }
2139
2140
2141 func encodeJ(ins *instruction) uint32 {
2142 imm := immI(ins.as, ins.imm, 21)
2143 rd := regI(ins.rd)
2144 enc := encode(ins.as)
2145 if enc == nil {
2146 panic("encodeJ: could not encode instruction")
2147 }
2148 return encodeJImmediate(imm) | rd<<7 | enc.opcode
2149 }
2150
2151 func encodeVset(as obj.As, rs1, rs2, rd uint32) uint32 {
2152 enc := encode(as)
2153 if enc == nil {
2154 panic("encodeVset: could not encode instruction")
2155 }
2156 return enc.funct7<<25 | rs2<<20 | rs1<<15 | enc.funct3<<12 | rd<<7 | enc.opcode
2157 }
2158
2159 func encodeVsetvli(ins *instruction) uint32 {
2160 vtype := immU(ins.as, ins.imm, 11)
2161 return encodeVset(ins.as, regI(ins.rs1), vtype, regI(ins.rd))
2162 }
2163
2164 func encodeVsetivli(ins *instruction) uint32 {
2165 vtype := immU(ins.as, ins.imm, 10)
2166 avl := immU(ins.as, int64(ins.rs1), 5)
2167 return encodeVset(ins.as, avl, vtype, regI(ins.rd))
2168 }
2169
2170 func encodeVsetvl(ins *instruction) uint32 {
2171 return encodeVset(ins.as, regI(ins.rs1), regI(ins.rs2), regI(ins.rd))
2172 }
2173
2174 func encodeRawIns(ins *instruction) uint32 {
2175
2176
2177 return immU(ins.as, ins.imm, 32)
2178 }
2179
2180 func EncodeBImmediate(imm int64) (int64, error) {
2181 if err := immIFits(imm, 13); err != nil {
2182 return 0, err
2183 }
2184 if err := immEven(imm); err != nil {
2185 return 0, err
2186 }
2187 return int64(encodeBImmediate(uint32(imm))), nil
2188 }
2189
2190 func EncodeCBImmediate(imm int64) (int64, error) {
2191 if err := immIFits(imm, 9); err != nil {
2192 return 0, err
2193 }
2194 if err := immEven(imm); err != nil {
2195 return 0, err
2196 }
2197 return int64(encodeCBImmediate(uint32(imm))), nil
2198 }
2199
2200 func EncodeCJImmediate(imm int64) (int64, error) {
2201 if err := immIFits(imm, 12); err != nil {
2202 return 0, err
2203 }
2204 if err := immEven(imm); err != nil {
2205 return 0, err
2206 }
2207 return int64(encodeCJImmediate(uint32(imm))), nil
2208 }
2209
2210 func EncodeIImmediate(imm int64) (int64, error) {
2211 if err := immIFits(imm, 12); err != nil {
2212 return 0, err
2213 }
2214 return imm << 20, nil
2215 }
2216
2217 func EncodeJImmediate(imm int64) (int64, error) {
2218 if err := immIFits(imm, 21); err != nil {
2219 return 0, err
2220 }
2221 if err := immEven(imm); err != nil {
2222 return 0, err
2223 }
2224 return int64(encodeJImmediate(uint32(imm))), nil
2225 }
2226
2227 func EncodeSImmediate(imm int64) (int64, error) {
2228 if err := immIFits(imm, 12); err != nil {
2229 return 0, err
2230 }
2231 return ((imm >> 5) << 25) | ((imm & 0x1f) << 7), nil
2232 }
2233
2234 func EncodeUImmediate(imm int64) (int64, error) {
2235 if err := immIFits(imm, 20); err != nil {
2236 return 0, err
2237 }
2238 return imm << 12, nil
2239 }
2240
2241 func EncodeVectorType(vsew, vlmul, vtail, vmask int64) (int64, error) {
2242 vsewSO := SpecialOperand(vsew)
2243 if vsewSO < SPOP_E8 || vsewSO > SPOP_E64 {
2244 return -1, fmt.Errorf("invalid vector selected element width %q", vsewSO)
2245 }
2246 vlmulSO := SpecialOperand(vlmul)
2247 if vlmulSO < SPOP_M1 || vlmulSO > SPOP_MF8 {
2248 return -1, fmt.Errorf("invalid vector register group multiplier %q", vlmulSO)
2249 }
2250 vtailSO := SpecialOperand(vtail)
2251 if vtailSO != SPOP_TA && vtailSO != SPOP_TU {
2252 return -1, fmt.Errorf("invalid vector tail policy %q", vtailSO)
2253 }
2254 vmaskSO := SpecialOperand(vmask)
2255 if vmaskSO != SPOP_MA && vmaskSO != SPOP_MU {
2256 return -1, fmt.Errorf("invalid vector mask policy %q", vmaskSO)
2257 }
2258 vtype := vmaskSO.encode()<<7 | vtailSO.encode()<<6 | vsewSO.encode()<<3 | vlmulSO.encode()
2259 return int64(vtype), nil
2260 }
2261
2262 type encoding struct {
2263 encode func(*instruction) uint32
2264 validate func(*obj.Link, *instruction)
2265 length int
2266 }
2267
2268 var (
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280 rIIIEncoding = encoding{encode: encodeRIII, validate: validateRIII, length: 4}
2281 rIIEncoding = encoding{encode: encodeRII, validate: validateRII, length: 4}
2282 rFFFEncoding = encoding{encode: encodeRFFF, validate: validateRFFF, length: 4}
2283 rFFFFEncoding = encoding{encode: encodeRFFFF, validate: validateRFFFF, length: 4}
2284 rFFIEncoding = encoding{encode: encodeRFFI, validate: validateRFFI, length: 4}
2285 rFIEncoding = encoding{encode: encodeRFI, validate: validateRFI, length: 4}
2286 rFVEncoding = encoding{encode: encodeRFV, validate: validateRFV, length: 4}
2287 rIFEncoding = encoding{encode: encodeRIF, validate: validateRIF, length: 4}
2288 rIVEncoding = encoding{encode: encodeRIV, validate: validateRIV, length: 4}
2289 rFFEncoding = encoding{encode: encodeRFF, validate: validateRFF, length: 4}
2290 rVFEncoding = encoding{encode: encodeRVF, validate: validateRVF, length: 4}
2291 rVFVEncoding = encoding{encode: encodeRVFV, validate: validateRVFV, length: 4}
2292 rVIEncoding = encoding{encode: encodeRVI, validate: validateRVI, length: 4}
2293 rVIVEncoding = encoding{encode: encodeRVIV, validate: validateRVIV, length: 4}
2294 rVVEncoding = encoding{encode: encodeRVV, validate: validateRVV, length: 4}
2295 rVViEncoding = encoding{encode: encodeRVVi, validate: validateRVVi, length: 4}
2296 rVVuEncoding = encoding{encode: encodeRVVu, validate: validateRVVu, length: 4}
2297 rVVVEncoding = encoding{encode: encodeRVVV, validate: validateRVVV, length: 4}
2298
2299 iIIEncoding = encoding{encode: encodeIII, validate: validateIII, length: 4}
2300 iFEncoding = encoding{encode: encodeIF, validate: validateIF, length: 4}
2301 iVEncoding = encoding{encode: encodeIV, validate: validateIV, length: 4}
2302 iIIVEncoding = encoding{encode: encodeIIIV, validate: validateIIIV, length: 4}
2303 iVIVEncoding = encoding{encode: encodeIVIV, validate: validateIVIV, length: 4}
2304
2305 sIEncoding = encoding{encode: encodeSI, validate: validateSI, length: 4}
2306 sFEncoding = encoding{encode: encodeSF, validate: validateSF, length: 4}
2307 sVEncoding = encoding{encode: encodeSV, validate: validateSV, length: 4}
2308 sVIIEncoding = encoding{encode: encodeSVII, validate: validateSVII, length: 4}
2309 sVIVEncoding = encoding{encode: encodeSVIV, validate: validateSVIV, length: 4}
2310
2311 bEncoding = encoding{encode: encodeB, validate: validateB, length: 4}
2312 uEncoding = encoding{encode: encodeU, validate: validateU, length: 4}
2313 jEncoding = encoding{encode: encodeJ, validate: validateJ, length: 4}
2314
2315
2316 caEncoding = encoding{encode: encodeCA, validate: validateCA, length: 2}
2317 cbEncoding = encoding{encode: encodeCB, validate: validateCB, length: 2}
2318 ciEncoding = encoding{encode: encodeCI, validate: validateCI, length: 2}
2319 ciwEncoding = encoding{encode: encodeCIW, validate: validateCIW, length: 2}
2320 cjEncoding = encoding{encode: encodeCJ, validate: validateCJ, length: 2}
2321 clEncoding = encoding{encode: encodeCL, validate: validateCL, length: 2}
2322 crEncoding = encoding{encode: encodeCR, validate: validateCR, length: 2}
2323 csEncoding = encoding{encode: encodeCS, validate: validateCS, length: 2}
2324 cssEncoding = encoding{encode: encodeCSS, validate: validateCSS, length: 2}
2325
2326
2327 vsetvliEncoding = encoding{encode: encodeVsetvli, validate: validateVsetvli, length: 4}
2328 vsetivliEncoding = encoding{encode: encodeVsetivli, validate: validateVsetivli, length: 4}
2329 vsetvlEncoding = encoding{encode: encodeVsetvl, validate: validateVsetvl, length: 4}
2330
2331
2332 rawEncoding = encoding{encode: encodeRawIns, validate: validateRaw, length: 4}
2333
2334
2335 pseudoOpEncoding = encoding{encode: nil, validate: func(*obj.Link, *instruction) {}, length: 0}
2336
2337
2338
2339 badEncoding = encoding{encode: func(*instruction) uint32 { return 0 }, validate: func(*obj.Link, *instruction) {}, length: 0}
2340 )
2341
2342
2343 type instructionData struct {
2344 enc encoding
2345 immForm obj.As
2346 ternary bool
2347 }
2348
2349
2350
2351
2352 var instructions = [ALAST & obj.AMask]instructionData{
2353
2354
2355
2356
2357
2358 AADDI & obj.AMask: {enc: iIIEncoding, ternary: true},
2359 ASLTI & obj.AMask: {enc: iIIEncoding, ternary: true},
2360 ASLTIU & obj.AMask: {enc: iIIEncoding, ternary: true},
2361 AANDI & obj.AMask: {enc: iIIEncoding, ternary: true},
2362 AORI & obj.AMask: {enc: iIIEncoding, ternary: true},
2363 AXORI & obj.AMask: {enc: iIIEncoding, ternary: true},
2364 ASLLI & obj.AMask: {enc: iIIEncoding, ternary: true},
2365 ASRLI & obj.AMask: {enc: iIIEncoding, ternary: true},
2366 ASRAI & obj.AMask: {enc: iIIEncoding, ternary: true},
2367 ALUI & obj.AMask: {enc: uEncoding},
2368 AAUIPC & obj.AMask: {enc: uEncoding},
2369 AADD & obj.AMask: {enc: rIIIEncoding, immForm: AADDI, ternary: true},
2370 ASLT & obj.AMask: {enc: rIIIEncoding, immForm: ASLTI, ternary: true},
2371 ASLTU & obj.AMask: {enc: rIIIEncoding, immForm: ASLTIU, ternary: true},
2372 AAND & obj.AMask: {enc: rIIIEncoding, immForm: AANDI, ternary: true},
2373 AOR & obj.AMask: {enc: rIIIEncoding, immForm: AORI, ternary: true},
2374 AXOR & obj.AMask: {enc: rIIIEncoding, immForm: AXORI, ternary: true},
2375 ASLL & obj.AMask: {enc: rIIIEncoding, immForm: ASLLI, ternary: true},
2376 ASRL & obj.AMask: {enc: rIIIEncoding, immForm: ASRLI, ternary: true},
2377 ASUB & obj.AMask: {enc: rIIIEncoding, ternary: true},
2378 ASRA & obj.AMask: {enc: rIIIEncoding, immForm: ASRAI, ternary: true},
2379
2380
2381 AJAL & obj.AMask: {enc: jEncoding},
2382 AJALR & obj.AMask: {enc: iIIEncoding},
2383 ABEQ & obj.AMask: {enc: bEncoding},
2384 ABNE & obj.AMask: {enc: bEncoding},
2385 ABLT & obj.AMask: {enc: bEncoding},
2386 ABLTU & obj.AMask: {enc: bEncoding},
2387 ABGE & obj.AMask: {enc: bEncoding},
2388 ABGEU & obj.AMask: {enc: bEncoding},
2389
2390
2391 ALW & obj.AMask: {enc: iIIEncoding},
2392 ALWU & obj.AMask: {enc: iIIEncoding},
2393 ALH & obj.AMask: {enc: iIIEncoding},
2394 ALHU & obj.AMask: {enc: iIIEncoding},
2395 ALB & obj.AMask: {enc: iIIEncoding},
2396 ALBU & obj.AMask: {enc: iIIEncoding},
2397 ASW & obj.AMask: {enc: sIEncoding},
2398 ASH & obj.AMask: {enc: sIEncoding},
2399 ASB & obj.AMask: {enc: sIEncoding},
2400
2401
2402 AFENCE & obj.AMask: {enc: iIIEncoding},
2403
2404
2405 AADDIW & obj.AMask: {enc: iIIEncoding, ternary: true},
2406 ASLLIW & obj.AMask: {enc: iIIEncoding, ternary: true},
2407 ASRLIW & obj.AMask: {enc: iIIEncoding, ternary: true},
2408 ASRAIW & obj.AMask: {enc: iIIEncoding, ternary: true},
2409 AADDW & obj.AMask: {enc: rIIIEncoding, immForm: AADDIW, ternary: true},
2410 ASLLW & obj.AMask: {enc: rIIIEncoding, immForm: ASLLIW, ternary: true},
2411 ASRLW & obj.AMask: {enc: rIIIEncoding, immForm: ASRLIW, ternary: true},
2412 ASUBW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2413 ASRAW & obj.AMask: {enc: rIIIEncoding, immForm: ASRAIW, ternary: true},
2414
2415
2416 ALD & obj.AMask: {enc: iIIEncoding},
2417 ASD & obj.AMask: {enc: sIEncoding},
2418
2419
2420 ACSRRC & obj.AMask: {enc: iIIEncoding, immForm: ACSRRCI},
2421 ACSRRCI & obj.AMask: {enc: iIIEncoding},
2422 ACSRRS & obj.AMask: {enc: iIIEncoding, immForm: ACSRRSI},
2423 ACSRRSI & obj.AMask: {enc: iIIEncoding},
2424 ACSRRW & obj.AMask: {enc: iIIEncoding, immForm: ACSRRWI},
2425 ACSRRWI & obj.AMask: {enc: iIIEncoding},
2426
2427
2428 ACZERONEZ & obj.AMask: {enc: rIIIEncoding, ternary: true},
2429 ACZEROEQZ & obj.AMask: {enc: rIIIEncoding, ternary: true},
2430
2431
2432 AMUL & obj.AMask: {enc: rIIIEncoding, ternary: true},
2433 AMULH & obj.AMask: {enc: rIIIEncoding, ternary: true},
2434 AMULHU & obj.AMask: {enc: rIIIEncoding, ternary: true},
2435 AMULHSU & obj.AMask: {enc: rIIIEncoding, ternary: true},
2436 AMULW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2437 ADIV & obj.AMask: {enc: rIIIEncoding, ternary: true},
2438 ADIVU & obj.AMask: {enc: rIIIEncoding, ternary: true},
2439 AREM & obj.AMask: {enc: rIIIEncoding, ternary: true},
2440 AREMU & obj.AMask: {enc: rIIIEncoding, ternary: true},
2441 ADIVW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2442 ADIVUW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2443 AREMW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2444 AREMUW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2445
2446
2447 ALRW & obj.AMask: {enc: rIIIEncoding},
2448 ALRD & obj.AMask: {enc: rIIIEncoding},
2449 ASCW & obj.AMask: {enc: rIIIEncoding},
2450 ASCD & obj.AMask: {enc: rIIIEncoding},
2451
2452
2453 AAMOSWAPW & obj.AMask: {enc: rIIIEncoding},
2454 AAMOSWAPD & obj.AMask: {enc: rIIIEncoding},
2455 AAMOADDW & obj.AMask: {enc: rIIIEncoding},
2456 AAMOADDD & obj.AMask: {enc: rIIIEncoding},
2457 AAMOANDW & obj.AMask: {enc: rIIIEncoding},
2458 AAMOANDD & obj.AMask: {enc: rIIIEncoding},
2459 AAMOORW & obj.AMask: {enc: rIIIEncoding},
2460 AAMOORD & obj.AMask: {enc: rIIIEncoding},
2461 AAMOXORW & obj.AMask: {enc: rIIIEncoding},
2462 AAMOXORD & obj.AMask: {enc: rIIIEncoding},
2463 AAMOMAXW & obj.AMask: {enc: rIIIEncoding},
2464 AAMOMAXD & obj.AMask: {enc: rIIIEncoding},
2465 AAMOMAXUW & obj.AMask: {enc: rIIIEncoding},
2466 AAMOMAXUD & obj.AMask: {enc: rIIIEncoding},
2467 AAMOMINW & obj.AMask: {enc: rIIIEncoding},
2468 AAMOMIND & obj.AMask: {enc: rIIIEncoding},
2469 AAMOMINUW & obj.AMask: {enc: rIIIEncoding},
2470 AAMOMINUD & obj.AMask: {enc: rIIIEncoding},
2471
2472
2473 AFLW & obj.AMask: {enc: iFEncoding},
2474 AFSW & obj.AMask: {enc: sFEncoding},
2475
2476
2477 AFADDS & obj.AMask: {enc: rFFFEncoding},
2478 AFSUBS & obj.AMask: {enc: rFFFEncoding},
2479 AFMULS & obj.AMask: {enc: rFFFEncoding},
2480 AFDIVS & obj.AMask: {enc: rFFFEncoding},
2481 AFMINS & obj.AMask: {enc: rFFFEncoding},
2482 AFMAXS & obj.AMask: {enc: rFFFEncoding},
2483 AFSQRTS & obj.AMask: {enc: rFFFEncoding},
2484 AFMADDS & obj.AMask: {enc: rFFFFEncoding},
2485 AFMSUBS & obj.AMask: {enc: rFFFFEncoding},
2486 AFNMSUBS & obj.AMask: {enc: rFFFFEncoding},
2487 AFNMADDS & obj.AMask: {enc: rFFFFEncoding},
2488
2489
2490 AFCVTWS & obj.AMask: {enc: rFIEncoding},
2491 AFCVTLS & obj.AMask: {enc: rFIEncoding},
2492 AFCVTSW & obj.AMask: {enc: rIFEncoding},
2493 AFCVTSL & obj.AMask: {enc: rIFEncoding},
2494 AFCVTWUS & obj.AMask: {enc: rFIEncoding},
2495 AFCVTLUS & obj.AMask: {enc: rFIEncoding},
2496 AFCVTSWU & obj.AMask: {enc: rIFEncoding},
2497 AFCVTSLU & obj.AMask: {enc: rIFEncoding},
2498 AFSGNJS & obj.AMask: {enc: rFFFEncoding},
2499 AFSGNJNS & obj.AMask: {enc: rFFFEncoding},
2500 AFSGNJXS & obj.AMask: {enc: rFFFEncoding},
2501 AFMVXW & obj.AMask: {enc: rFIEncoding},
2502 AFMVWX & obj.AMask: {enc: rIFEncoding},
2503
2504
2505 AFEQS & obj.AMask: {enc: rFFIEncoding},
2506 AFLTS & obj.AMask: {enc: rFFIEncoding},
2507 AFLES & obj.AMask: {enc: rFFIEncoding},
2508
2509
2510 AFCLASSS & obj.AMask: {enc: rFIEncoding},
2511
2512
2513 AFLD & obj.AMask: {enc: iFEncoding},
2514 AFSD & obj.AMask: {enc: sFEncoding},
2515
2516
2517 AFADDD & obj.AMask: {enc: rFFFEncoding},
2518 AFSUBD & obj.AMask: {enc: rFFFEncoding},
2519 AFMULD & obj.AMask: {enc: rFFFEncoding},
2520 AFDIVD & obj.AMask: {enc: rFFFEncoding},
2521 AFMIND & obj.AMask: {enc: rFFFEncoding},
2522 AFMAXD & obj.AMask: {enc: rFFFEncoding},
2523 AFSQRTD & obj.AMask: {enc: rFFFEncoding},
2524 AFMADDD & obj.AMask: {enc: rFFFFEncoding},
2525 AFMSUBD & obj.AMask: {enc: rFFFFEncoding},
2526 AFNMSUBD & obj.AMask: {enc: rFFFFEncoding},
2527 AFNMADDD & obj.AMask: {enc: rFFFFEncoding},
2528
2529
2530 AFCVTWD & obj.AMask: {enc: rFIEncoding},
2531 AFCVTLD & obj.AMask: {enc: rFIEncoding},
2532 AFCVTDW & obj.AMask: {enc: rIFEncoding},
2533 AFCVTDL & obj.AMask: {enc: rIFEncoding},
2534 AFCVTWUD & obj.AMask: {enc: rFIEncoding},
2535 AFCVTLUD & obj.AMask: {enc: rFIEncoding},
2536 AFCVTDWU & obj.AMask: {enc: rIFEncoding},
2537 AFCVTDLU & obj.AMask: {enc: rIFEncoding},
2538 AFCVTSD & obj.AMask: {enc: rFFEncoding},
2539 AFCVTDS & obj.AMask: {enc: rFFEncoding},
2540 AFSGNJD & obj.AMask: {enc: rFFFEncoding},
2541 AFSGNJND & obj.AMask: {enc: rFFFEncoding},
2542 AFSGNJXD & obj.AMask: {enc: rFFFEncoding},
2543 AFMVXD & obj.AMask: {enc: rFIEncoding},
2544 AFMVDX & obj.AMask: {enc: rIFEncoding},
2545
2546
2547 AFEQD & obj.AMask: {enc: rFFIEncoding},
2548 AFLTD & obj.AMask: {enc: rFFIEncoding},
2549 AFLED & obj.AMask: {enc: rFFIEncoding},
2550
2551
2552 AFCLASSD & obj.AMask: {enc: rFIEncoding},
2553
2554
2555
2556
2557
2558
2559 ACLWSP & obj.AMask: {enc: ciEncoding},
2560 ACLDSP & obj.AMask: {enc: ciEncoding},
2561 ACFLDSP & obj.AMask: {enc: ciEncoding},
2562 ACSWSP & obj.AMask: {enc: cssEncoding},
2563 ACSDSP & obj.AMask: {enc: cssEncoding},
2564 ACFSDSP & obj.AMask: {enc: cssEncoding},
2565
2566
2567 ACLW & obj.AMask: {enc: clEncoding},
2568 ACLD & obj.AMask: {enc: clEncoding},
2569 ACFLD & obj.AMask: {enc: clEncoding},
2570 ACSW & obj.AMask: {enc: csEncoding},
2571 ACSD & obj.AMask: {enc: csEncoding},
2572 ACFSD & obj.AMask: {enc: csEncoding},
2573
2574
2575 ACJ & obj.AMask: {enc: cjEncoding},
2576 ACJR & obj.AMask: {enc: crEncoding},
2577 ACJALR & obj.AMask: {enc: crEncoding},
2578 ACBEQZ & obj.AMask: {enc: cbEncoding},
2579 ACBNEZ & obj.AMask: {enc: cbEncoding},
2580
2581
2582 ACLI & obj.AMask: {enc: ciEncoding},
2583 ACLUI & obj.AMask: {enc: ciEncoding},
2584
2585
2586 ACADDI & obj.AMask: {enc: ciEncoding, ternary: true},
2587 ACADDIW & obj.AMask: {enc: ciEncoding, ternary: true},
2588 ACADDI16SP & obj.AMask: {enc: ciEncoding, ternary: true},
2589 ACADDI4SPN & obj.AMask: {enc: ciwEncoding, ternary: true},
2590 ACSLLI & obj.AMask: {enc: ciEncoding, ternary: true},
2591 ACSRLI & obj.AMask: {enc: cbEncoding, ternary: true},
2592 ACSRAI & obj.AMask: {enc: cbEncoding, ternary: true},
2593 ACANDI & obj.AMask: {enc: cbEncoding, ternary: true},
2594
2595
2596 ACMV & obj.AMask: {enc: crEncoding},
2597 ACADD & obj.AMask: {enc: crEncoding, immForm: ACADDI, ternary: true},
2598 ACAND & obj.AMask: {enc: caEncoding, immForm: ACANDI, ternary: true},
2599 ACOR & obj.AMask: {enc: caEncoding, ternary: true},
2600 ACXOR & obj.AMask: {enc: caEncoding, ternary: true},
2601 ACSUB & obj.AMask: {enc: caEncoding, ternary: true},
2602 ACADDW & obj.AMask: {enc: caEncoding, immForm: ACADDIW, ternary: true},
2603 ACSUBW & obj.AMask: {enc: caEncoding, ternary: true},
2604
2605
2606 ACNOP & obj.AMask: {enc: ciEncoding},
2607
2608
2609 ACEBREAK & obj.AMask: {enc: crEncoding},
2610
2611
2612
2613
2614
2615
2616 AADDUW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2617 ASH1ADD & obj.AMask: {enc: rIIIEncoding, ternary: true},
2618 ASH1ADDUW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2619 ASH2ADD & obj.AMask: {enc: rIIIEncoding, ternary: true},
2620 ASH2ADDUW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2621 ASH3ADD & obj.AMask: {enc: rIIIEncoding, ternary: true},
2622 ASH3ADDUW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2623 ASLLIUW & obj.AMask: {enc: iIIEncoding, ternary: true},
2624
2625
2626 AANDN & obj.AMask: {enc: rIIIEncoding, ternary: true},
2627 ACLZ & obj.AMask: {enc: rIIEncoding},
2628 ACLZW & obj.AMask: {enc: rIIEncoding},
2629 ACPOP & obj.AMask: {enc: rIIEncoding},
2630 ACPOPW & obj.AMask: {enc: rIIEncoding},
2631 ACTZ & obj.AMask: {enc: rIIEncoding},
2632 ACTZW & obj.AMask: {enc: rIIEncoding},
2633 AMAX & obj.AMask: {enc: rIIIEncoding, ternary: true},
2634 AMAXU & obj.AMask: {enc: rIIIEncoding, ternary: true},
2635 AMIN & obj.AMask: {enc: rIIIEncoding, ternary: true},
2636 AMINU & obj.AMask: {enc: rIIIEncoding, ternary: true},
2637 AORN & obj.AMask: {enc: rIIIEncoding, ternary: true},
2638 ASEXTB & obj.AMask: {enc: rIIEncoding},
2639 ASEXTH & obj.AMask: {enc: rIIEncoding},
2640 AXNOR & obj.AMask: {enc: rIIIEncoding, ternary: true},
2641 AZEXTH & obj.AMask: {enc: rIIEncoding},
2642 AROL & obj.AMask: {enc: rIIIEncoding, ternary: true},
2643 AROLW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2644 AROR & obj.AMask: {enc: rIIIEncoding, immForm: ARORI, ternary: true},
2645 ARORI & obj.AMask: {enc: iIIEncoding, ternary: true},
2646 ARORIW & obj.AMask: {enc: iIIEncoding, ternary: true},
2647 ARORW & obj.AMask: {enc: rIIIEncoding, immForm: ARORIW, ternary: true},
2648 AORCB & obj.AMask: {enc: rIIEncoding},
2649 AREV8 & obj.AMask: {enc: rIIEncoding},
2650
2651
2652 ACLMUL & obj.AMask: {enc: rIIIEncoding, ternary: true},
2653 ACLMULH & obj.AMask: {enc: rIIIEncoding, ternary: true},
2654 ACLMULR & obj.AMask: {enc: rIIIEncoding, ternary: true},
2655
2656
2657 ABCLR & obj.AMask: {enc: rIIIEncoding, immForm: ABCLRI, ternary: true},
2658 ABCLRI & obj.AMask: {enc: iIIEncoding, ternary: true},
2659 ABEXT & obj.AMask: {enc: rIIIEncoding, immForm: ABEXTI, ternary: true},
2660 ABEXTI & obj.AMask: {enc: iIIEncoding, ternary: true},
2661 ABINV & obj.AMask: {enc: rIIIEncoding, immForm: ABINVI, ternary: true},
2662 ABINVI & obj.AMask: {enc: iIIEncoding, ternary: true},
2663 ABSET & obj.AMask: {enc: rIIIEncoding, immForm: ABSETI, ternary: true},
2664 ABSETI & obj.AMask: {enc: iIIEncoding, ternary: true},
2665
2666
2667
2668
2669
2670
2671 AVSETVLI & obj.AMask: {enc: vsetvliEncoding, immForm: AVSETIVLI},
2672 AVSETIVLI & obj.AMask: {enc: vsetivliEncoding},
2673 AVSETVL & obj.AMask: {enc: vsetvlEncoding},
2674
2675
2676 AVLE8V & obj.AMask: {enc: iVEncoding},
2677 AVLE16V & obj.AMask: {enc: iVEncoding},
2678 AVLE32V & obj.AMask: {enc: iVEncoding},
2679 AVLE64V & obj.AMask: {enc: iVEncoding},
2680 AVSE8V & obj.AMask: {enc: sVEncoding},
2681 AVSE16V & obj.AMask: {enc: sVEncoding},
2682 AVSE32V & obj.AMask: {enc: sVEncoding},
2683 AVSE64V & obj.AMask: {enc: sVEncoding},
2684 AVLMV & obj.AMask: {enc: iVEncoding},
2685 AVSMV & obj.AMask: {enc: sVEncoding},
2686
2687
2688 AVLSE8V & obj.AMask: {enc: iIIVEncoding},
2689 AVLSE16V & obj.AMask: {enc: iIIVEncoding},
2690 AVLSE32V & obj.AMask: {enc: iIIVEncoding},
2691 AVLSE64V & obj.AMask: {enc: iIIVEncoding},
2692 AVSSE8V & obj.AMask: {enc: sVIIEncoding},
2693 AVSSE16V & obj.AMask: {enc: sVIIEncoding},
2694 AVSSE32V & obj.AMask: {enc: sVIIEncoding},
2695 AVSSE64V & obj.AMask: {enc: sVIIEncoding},
2696
2697
2698 AVLUXEI8V & obj.AMask: {enc: iVIVEncoding},
2699 AVLUXEI16V & obj.AMask: {enc: iVIVEncoding},
2700 AVLUXEI32V & obj.AMask: {enc: iVIVEncoding},
2701 AVLUXEI64V & obj.AMask: {enc: iVIVEncoding},
2702 AVLOXEI8V & obj.AMask: {enc: iVIVEncoding},
2703 AVLOXEI16V & obj.AMask: {enc: iVIVEncoding},
2704 AVLOXEI32V & obj.AMask: {enc: iVIVEncoding},
2705 AVLOXEI64V & obj.AMask: {enc: iVIVEncoding},
2706 AVSUXEI8V & obj.AMask: {enc: sVIVEncoding},
2707 AVSUXEI16V & obj.AMask: {enc: sVIVEncoding},
2708 AVSUXEI32V & obj.AMask: {enc: sVIVEncoding},
2709 AVSUXEI64V & obj.AMask: {enc: sVIVEncoding},
2710 AVSOXEI8V & obj.AMask: {enc: sVIVEncoding},
2711 AVSOXEI16V & obj.AMask: {enc: sVIVEncoding},
2712 AVSOXEI32V & obj.AMask: {enc: sVIVEncoding},
2713 AVSOXEI64V & obj.AMask: {enc: sVIVEncoding},
2714
2715
2716 AVLE8FFV & obj.AMask: {enc: iVEncoding},
2717 AVLE16FFV & obj.AMask: {enc: iVEncoding},
2718 AVLE32FFV & obj.AMask: {enc: iVEncoding},
2719 AVLE64FFV & obj.AMask: {enc: iVEncoding},
2720
2721
2722 AVLSEG2E8V & obj.AMask: {enc: iVEncoding},
2723 AVLSEG3E8V & obj.AMask: {enc: iVEncoding},
2724 AVLSEG4E8V & obj.AMask: {enc: iVEncoding},
2725 AVLSEG5E8V & obj.AMask: {enc: iVEncoding},
2726 AVLSEG6E8V & obj.AMask: {enc: iVEncoding},
2727 AVLSEG7E8V & obj.AMask: {enc: iVEncoding},
2728 AVLSEG8E8V & obj.AMask: {enc: iVEncoding},
2729 AVLSEG2E16V & obj.AMask: {enc: iVEncoding},
2730 AVLSEG3E16V & obj.AMask: {enc: iVEncoding},
2731 AVLSEG4E16V & obj.AMask: {enc: iVEncoding},
2732 AVLSEG5E16V & obj.AMask: {enc: iVEncoding},
2733 AVLSEG6E16V & obj.AMask: {enc: iVEncoding},
2734 AVLSEG7E16V & obj.AMask: {enc: iVEncoding},
2735 AVLSEG8E16V & obj.AMask: {enc: iVEncoding},
2736 AVLSEG2E32V & obj.AMask: {enc: iVEncoding},
2737 AVLSEG3E32V & obj.AMask: {enc: iVEncoding},
2738 AVLSEG4E32V & obj.AMask: {enc: iVEncoding},
2739 AVLSEG5E32V & obj.AMask: {enc: iVEncoding},
2740 AVLSEG6E32V & obj.AMask: {enc: iVEncoding},
2741 AVLSEG7E32V & obj.AMask: {enc: iVEncoding},
2742 AVLSEG8E32V & obj.AMask: {enc: iVEncoding},
2743 AVLSEG2E64V & obj.AMask: {enc: iVEncoding},
2744 AVLSEG3E64V & obj.AMask: {enc: iVEncoding},
2745 AVLSEG4E64V & obj.AMask: {enc: iVEncoding},
2746 AVLSEG5E64V & obj.AMask: {enc: iVEncoding},
2747 AVLSEG6E64V & obj.AMask: {enc: iVEncoding},
2748 AVLSEG7E64V & obj.AMask: {enc: iVEncoding},
2749 AVLSEG8E64V & obj.AMask: {enc: iVEncoding},
2750 AVSSEG2E8V & obj.AMask: {enc: sVEncoding},
2751 AVSSEG3E8V & obj.AMask: {enc: sVEncoding},
2752 AVSSEG4E8V & obj.AMask: {enc: sVEncoding},
2753 AVSSEG5E8V & obj.AMask: {enc: sVEncoding},
2754 AVSSEG6E8V & obj.AMask: {enc: sVEncoding},
2755 AVSSEG7E8V & obj.AMask: {enc: sVEncoding},
2756 AVSSEG8E8V & obj.AMask: {enc: sVEncoding},
2757 AVSSEG2E16V & obj.AMask: {enc: sVEncoding},
2758 AVSSEG3E16V & obj.AMask: {enc: sVEncoding},
2759 AVSSEG4E16V & obj.AMask: {enc: sVEncoding},
2760 AVSSEG5E16V & obj.AMask: {enc: sVEncoding},
2761 AVSSEG6E16V & obj.AMask: {enc: sVEncoding},
2762 AVSSEG7E16V & obj.AMask: {enc: sVEncoding},
2763 AVSSEG8E16V & obj.AMask: {enc: sVEncoding},
2764 AVSSEG2E32V & obj.AMask: {enc: sVEncoding},
2765 AVSSEG3E32V & obj.AMask: {enc: sVEncoding},
2766 AVSSEG4E32V & obj.AMask: {enc: sVEncoding},
2767 AVSSEG5E32V & obj.AMask: {enc: sVEncoding},
2768 AVSSEG6E32V & obj.AMask: {enc: sVEncoding},
2769 AVSSEG7E32V & obj.AMask: {enc: sVEncoding},
2770 AVSSEG8E32V & obj.AMask: {enc: sVEncoding},
2771 AVSSEG2E64V & obj.AMask: {enc: sVEncoding},
2772 AVSSEG3E64V & obj.AMask: {enc: sVEncoding},
2773 AVSSEG4E64V & obj.AMask: {enc: sVEncoding},
2774 AVSSEG5E64V & obj.AMask: {enc: sVEncoding},
2775 AVSSEG6E64V & obj.AMask: {enc: sVEncoding},
2776 AVSSEG7E64V & obj.AMask: {enc: sVEncoding},
2777 AVSSEG8E64V & obj.AMask: {enc: sVEncoding},
2778 AVLSEG2E8FFV & obj.AMask: {enc: iVEncoding},
2779 AVLSEG3E8FFV & obj.AMask: {enc: iVEncoding},
2780 AVLSEG4E8FFV & obj.AMask: {enc: iVEncoding},
2781 AVLSEG5E8FFV & obj.AMask: {enc: iVEncoding},
2782 AVLSEG6E8FFV & obj.AMask: {enc: iVEncoding},
2783 AVLSEG7E8FFV & obj.AMask: {enc: iVEncoding},
2784 AVLSEG8E8FFV & obj.AMask: {enc: iVEncoding},
2785 AVLSEG2E16FFV & obj.AMask: {enc: iVEncoding},
2786 AVLSEG3E16FFV & obj.AMask: {enc: iVEncoding},
2787 AVLSEG4E16FFV & obj.AMask: {enc: iVEncoding},
2788 AVLSEG5E16FFV & obj.AMask: {enc: iVEncoding},
2789 AVLSEG6E16FFV & obj.AMask: {enc: iVEncoding},
2790 AVLSEG7E16FFV & obj.AMask: {enc: iVEncoding},
2791 AVLSEG8E16FFV & obj.AMask: {enc: iVEncoding},
2792 AVLSEG2E32FFV & obj.AMask: {enc: iVEncoding},
2793 AVLSEG3E32FFV & obj.AMask: {enc: iVEncoding},
2794 AVLSEG4E32FFV & obj.AMask: {enc: iVEncoding},
2795 AVLSEG5E32FFV & obj.AMask: {enc: iVEncoding},
2796 AVLSEG6E32FFV & obj.AMask: {enc: iVEncoding},
2797 AVLSEG7E32FFV & obj.AMask: {enc: iVEncoding},
2798 AVLSEG8E32FFV & obj.AMask: {enc: iVEncoding},
2799 AVLSEG2E64FFV & obj.AMask: {enc: iVEncoding},
2800 AVLSEG3E64FFV & obj.AMask: {enc: iVEncoding},
2801 AVLSEG4E64FFV & obj.AMask: {enc: iVEncoding},
2802 AVLSEG5E64FFV & obj.AMask: {enc: iVEncoding},
2803 AVLSEG6E64FFV & obj.AMask: {enc: iVEncoding},
2804 AVLSEG7E64FFV & obj.AMask: {enc: iVEncoding},
2805 AVLSEG8E64FFV & obj.AMask: {enc: iVEncoding},
2806
2807
2808 AVLSSEG2E8V & obj.AMask: {enc: iIIVEncoding},
2809 AVLSSEG3E8V & obj.AMask: {enc: iIIVEncoding},
2810 AVLSSEG4E8V & obj.AMask: {enc: iIIVEncoding},
2811 AVLSSEG5E8V & obj.AMask: {enc: iIIVEncoding},
2812 AVLSSEG6E8V & obj.AMask: {enc: iIIVEncoding},
2813 AVLSSEG7E8V & obj.AMask: {enc: iIIVEncoding},
2814 AVLSSEG8E8V & obj.AMask: {enc: iIIVEncoding},
2815 AVLSSEG2E16V & obj.AMask: {enc: iIIVEncoding},
2816 AVLSSEG3E16V & obj.AMask: {enc: iIIVEncoding},
2817 AVLSSEG4E16V & obj.AMask: {enc: iIIVEncoding},
2818 AVLSSEG5E16V & obj.AMask: {enc: iIIVEncoding},
2819 AVLSSEG6E16V & obj.AMask: {enc: iIIVEncoding},
2820 AVLSSEG7E16V & obj.AMask: {enc: iIIVEncoding},
2821 AVLSSEG8E16V & obj.AMask: {enc: iIIVEncoding},
2822 AVLSSEG2E32V & obj.AMask: {enc: iIIVEncoding},
2823 AVLSSEG3E32V & obj.AMask: {enc: iIIVEncoding},
2824 AVLSSEG4E32V & obj.AMask: {enc: iIIVEncoding},
2825 AVLSSEG5E32V & obj.AMask: {enc: iIIVEncoding},
2826 AVLSSEG6E32V & obj.AMask: {enc: iIIVEncoding},
2827 AVLSSEG7E32V & obj.AMask: {enc: iIIVEncoding},
2828 AVLSSEG8E32V & obj.AMask: {enc: iIIVEncoding},
2829 AVLSSEG2E64V & obj.AMask: {enc: iIIVEncoding},
2830 AVLSSEG3E64V & obj.AMask: {enc: iIIVEncoding},
2831 AVLSSEG4E64V & obj.AMask: {enc: iIIVEncoding},
2832 AVLSSEG5E64V & obj.AMask: {enc: iIIVEncoding},
2833 AVLSSEG6E64V & obj.AMask: {enc: iIIVEncoding},
2834 AVLSSEG7E64V & obj.AMask: {enc: iIIVEncoding},
2835 AVLSSEG8E64V & obj.AMask: {enc: iIIVEncoding},
2836 AVSSSEG2E8V & obj.AMask: {enc: sVIIEncoding},
2837 AVSSSEG3E8V & obj.AMask: {enc: sVIIEncoding},
2838 AVSSSEG4E8V & obj.AMask: {enc: sVIIEncoding},
2839 AVSSSEG5E8V & obj.AMask: {enc: sVIIEncoding},
2840 AVSSSEG6E8V & obj.AMask: {enc: sVIIEncoding},
2841 AVSSSEG7E8V & obj.AMask: {enc: sVIIEncoding},
2842 AVSSSEG8E8V & obj.AMask: {enc: sVIIEncoding},
2843 AVSSSEG2E16V & obj.AMask: {enc: sVIIEncoding},
2844 AVSSSEG3E16V & obj.AMask: {enc: sVIIEncoding},
2845 AVSSSEG4E16V & obj.AMask: {enc: sVIIEncoding},
2846 AVSSSEG5E16V & obj.AMask: {enc: sVIIEncoding},
2847 AVSSSEG6E16V & obj.AMask: {enc: sVIIEncoding},
2848 AVSSSEG7E16V & obj.AMask: {enc: sVIIEncoding},
2849 AVSSSEG8E16V & obj.AMask: {enc: sVIIEncoding},
2850 AVSSSEG2E32V & obj.AMask: {enc: sVIIEncoding},
2851 AVSSSEG3E32V & obj.AMask: {enc: sVIIEncoding},
2852 AVSSSEG4E32V & obj.AMask: {enc: sVIIEncoding},
2853 AVSSSEG5E32V & obj.AMask: {enc: sVIIEncoding},
2854 AVSSSEG6E32V & obj.AMask: {enc: sVIIEncoding},
2855 AVSSSEG7E32V & obj.AMask: {enc: sVIIEncoding},
2856 AVSSSEG8E32V & obj.AMask: {enc: sVIIEncoding},
2857 AVSSSEG2E64V & obj.AMask: {enc: sVIIEncoding},
2858 AVSSSEG3E64V & obj.AMask: {enc: sVIIEncoding},
2859 AVSSSEG4E64V & obj.AMask: {enc: sVIIEncoding},
2860 AVSSSEG5E64V & obj.AMask: {enc: sVIIEncoding},
2861 AVSSSEG6E64V & obj.AMask: {enc: sVIIEncoding},
2862 AVSSSEG7E64V & obj.AMask: {enc: sVIIEncoding},
2863 AVSSSEG8E64V & obj.AMask: {enc: sVIIEncoding},
2864
2865
2866 AVLOXSEG2EI8V & obj.AMask: {enc: iVIVEncoding},
2867 AVLOXSEG3EI8V & obj.AMask: {enc: iVIVEncoding},
2868 AVLOXSEG4EI8V & obj.AMask: {enc: iVIVEncoding},
2869 AVLOXSEG5EI8V & obj.AMask: {enc: iVIVEncoding},
2870 AVLOXSEG6EI8V & obj.AMask: {enc: iVIVEncoding},
2871 AVLOXSEG7EI8V & obj.AMask: {enc: iVIVEncoding},
2872 AVLOXSEG8EI8V & obj.AMask: {enc: iVIVEncoding},
2873 AVLOXSEG2EI16V & obj.AMask: {enc: iVIVEncoding},
2874 AVLOXSEG3EI16V & obj.AMask: {enc: iVIVEncoding},
2875 AVLOXSEG4EI16V & obj.AMask: {enc: iVIVEncoding},
2876 AVLOXSEG5EI16V & obj.AMask: {enc: iVIVEncoding},
2877 AVLOXSEG6EI16V & obj.AMask: {enc: iVIVEncoding},
2878 AVLOXSEG7EI16V & obj.AMask: {enc: iVIVEncoding},
2879 AVLOXSEG8EI16V & obj.AMask: {enc: iVIVEncoding},
2880 AVLOXSEG2EI32V & obj.AMask: {enc: iVIVEncoding},
2881 AVLOXSEG3EI32V & obj.AMask: {enc: iVIVEncoding},
2882 AVLOXSEG4EI32V & obj.AMask: {enc: iVIVEncoding},
2883 AVLOXSEG5EI32V & obj.AMask: {enc: iVIVEncoding},
2884 AVLOXSEG6EI32V & obj.AMask: {enc: iVIVEncoding},
2885 AVLOXSEG7EI32V & obj.AMask: {enc: iVIVEncoding},
2886 AVLOXSEG8EI32V & obj.AMask: {enc: iVIVEncoding},
2887 AVLOXSEG2EI64V & obj.AMask: {enc: iVIVEncoding},
2888 AVLOXSEG3EI64V & obj.AMask: {enc: iVIVEncoding},
2889 AVLOXSEG4EI64V & obj.AMask: {enc: iVIVEncoding},
2890 AVLOXSEG5EI64V & obj.AMask: {enc: iVIVEncoding},
2891 AVLOXSEG6EI64V & obj.AMask: {enc: iVIVEncoding},
2892 AVLOXSEG7EI64V & obj.AMask: {enc: iVIVEncoding},
2893 AVLOXSEG8EI64V & obj.AMask: {enc: iVIVEncoding},
2894 AVSOXSEG2EI8V & obj.AMask: {enc: sVIVEncoding},
2895 AVSOXSEG3EI8V & obj.AMask: {enc: sVIVEncoding},
2896 AVSOXSEG4EI8V & obj.AMask: {enc: sVIVEncoding},
2897 AVSOXSEG5EI8V & obj.AMask: {enc: sVIVEncoding},
2898 AVSOXSEG6EI8V & obj.AMask: {enc: sVIVEncoding},
2899 AVSOXSEG7EI8V & obj.AMask: {enc: sVIVEncoding},
2900 AVSOXSEG8EI8V & obj.AMask: {enc: sVIVEncoding},
2901 AVSOXSEG2EI16V & obj.AMask: {enc: sVIVEncoding},
2902 AVSOXSEG3EI16V & obj.AMask: {enc: sVIVEncoding},
2903 AVSOXSEG4EI16V & obj.AMask: {enc: sVIVEncoding},
2904 AVSOXSEG5EI16V & obj.AMask: {enc: sVIVEncoding},
2905 AVSOXSEG6EI16V & obj.AMask: {enc: sVIVEncoding},
2906 AVSOXSEG7EI16V & obj.AMask: {enc: sVIVEncoding},
2907 AVSOXSEG8EI16V & obj.AMask: {enc: sVIVEncoding},
2908 AVSOXSEG2EI32V & obj.AMask: {enc: sVIVEncoding},
2909 AVSOXSEG3EI32V & obj.AMask: {enc: sVIVEncoding},
2910 AVSOXSEG4EI32V & obj.AMask: {enc: sVIVEncoding},
2911 AVSOXSEG5EI32V & obj.AMask: {enc: sVIVEncoding},
2912 AVSOXSEG6EI32V & obj.AMask: {enc: sVIVEncoding},
2913 AVSOXSEG7EI32V & obj.AMask: {enc: sVIVEncoding},
2914 AVSOXSEG8EI32V & obj.AMask: {enc: sVIVEncoding},
2915 AVSOXSEG2EI64V & obj.AMask: {enc: sVIVEncoding},
2916 AVSOXSEG3EI64V & obj.AMask: {enc: sVIVEncoding},
2917 AVSOXSEG4EI64V & obj.AMask: {enc: sVIVEncoding},
2918 AVSOXSEG5EI64V & obj.AMask: {enc: sVIVEncoding},
2919 AVSOXSEG6EI64V & obj.AMask: {enc: sVIVEncoding},
2920 AVSOXSEG7EI64V & obj.AMask: {enc: sVIVEncoding},
2921 AVSOXSEG8EI64V & obj.AMask: {enc: sVIVEncoding},
2922 AVLUXSEG2EI8V & obj.AMask: {enc: iVIVEncoding},
2923 AVLUXSEG3EI8V & obj.AMask: {enc: iVIVEncoding},
2924 AVLUXSEG4EI8V & obj.AMask: {enc: iVIVEncoding},
2925 AVLUXSEG5EI8V & obj.AMask: {enc: iVIVEncoding},
2926 AVLUXSEG6EI8V & obj.AMask: {enc: iVIVEncoding},
2927 AVLUXSEG7EI8V & obj.AMask: {enc: iVIVEncoding},
2928 AVLUXSEG8EI8V & obj.AMask: {enc: iVIVEncoding},
2929 AVLUXSEG2EI16V & obj.AMask: {enc: iVIVEncoding},
2930 AVLUXSEG3EI16V & obj.AMask: {enc: iVIVEncoding},
2931 AVLUXSEG4EI16V & obj.AMask: {enc: iVIVEncoding},
2932 AVLUXSEG5EI16V & obj.AMask: {enc: iVIVEncoding},
2933 AVLUXSEG6EI16V & obj.AMask: {enc: iVIVEncoding},
2934 AVLUXSEG7EI16V & obj.AMask: {enc: iVIVEncoding},
2935 AVLUXSEG8EI16V & obj.AMask: {enc: iVIVEncoding},
2936 AVLUXSEG2EI32V & obj.AMask: {enc: iVIVEncoding},
2937 AVLUXSEG3EI32V & obj.AMask: {enc: iVIVEncoding},
2938 AVLUXSEG4EI32V & obj.AMask: {enc: iVIVEncoding},
2939 AVLUXSEG5EI32V & obj.AMask: {enc: iVIVEncoding},
2940 AVLUXSEG6EI32V & obj.AMask: {enc: iVIVEncoding},
2941 AVLUXSEG7EI32V & obj.AMask: {enc: iVIVEncoding},
2942 AVLUXSEG8EI32V & obj.AMask: {enc: iVIVEncoding},
2943 AVLUXSEG2EI64V & obj.AMask: {enc: iVIVEncoding},
2944 AVLUXSEG3EI64V & obj.AMask: {enc: iVIVEncoding},
2945 AVLUXSEG4EI64V & obj.AMask: {enc: iVIVEncoding},
2946 AVLUXSEG5EI64V & obj.AMask: {enc: iVIVEncoding},
2947 AVLUXSEG6EI64V & obj.AMask: {enc: iVIVEncoding},
2948 AVLUXSEG7EI64V & obj.AMask: {enc: iVIVEncoding},
2949 AVLUXSEG8EI64V & obj.AMask: {enc: iVIVEncoding},
2950 AVSUXSEG2EI8V & obj.AMask: {enc: sVIVEncoding},
2951 AVSUXSEG3EI8V & obj.AMask: {enc: sVIVEncoding},
2952 AVSUXSEG4EI8V & obj.AMask: {enc: sVIVEncoding},
2953 AVSUXSEG5EI8V & obj.AMask: {enc: sVIVEncoding},
2954 AVSUXSEG6EI8V & obj.AMask: {enc: sVIVEncoding},
2955 AVSUXSEG7EI8V & obj.AMask: {enc: sVIVEncoding},
2956 AVSUXSEG8EI8V & obj.AMask: {enc: sVIVEncoding},
2957 AVSUXSEG2EI16V & obj.AMask: {enc: sVIVEncoding},
2958 AVSUXSEG3EI16V & obj.AMask: {enc: sVIVEncoding},
2959 AVSUXSEG4EI16V & obj.AMask: {enc: sVIVEncoding},
2960 AVSUXSEG5EI16V & obj.AMask: {enc: sVIVEncoding},
2961 AVSUXSEG6EI16V & obj.AMask: {enc: sVIVEncoding},
2962 AVSUXSEG7EI16V & obj.AMask: {enc: sVIVEncoding},
2963 AVSUXSEG8EI16V & obj.AMask: {enc: sVIVEncoding},
2964 AVSUXSEG2EI32V & obj.AMask: {enc: sVIVEncoding},
2965 AVSUXSEG3EI32V & obj.AMask: {enc: sVIVEncoding},
2966 AVSUXSEG4EI32V & obj.AMask: {enc: sVIVEncoding},
2967 AVSUXSEG5EI32V & obj.AMask: {enc: sVIVEncoding},
2968 AVSUXSEG6EI32V & obj.AMask: {enc: sVIVEncoding},
2969 AVSUXSEG7EI32V & obj.AMask: {enc: sVIVEncoding},
2970 AVSUXSEG8EI32V & obj.AMask: {enc: sVIVEncoding},
2971 AVSUXSEG2EI64V & obj.AMask: {enc: sVIVEncoding},
2972 AVSUXSEG3EI64V & obj.AMask: {enc: sVIVEncoding},
2973 AVSUXSEG4EI64V & obj.AMask: {enc: sVIVEncoding},
2974 AVSUXSEG5EI64V & obj.AMask: {enc: sVIVEncoding},
2975 AVSUXSEG6EI64V & obj.AMask: {enc: sVIVEncoding},
2976 AVSUXSEG7EI64V & obj.AMask: {enc: sVIVEncoding},
2977 AVSUXSEG8EI64V & obj.AMask: {enc: sVIVEncoding},
2978
2979
2980 AVL1RE8V & obj.AMask: {enc: iVEncoding},
2981 AVL1RE16V & obj.AMask: {enc: iVEncoding},
2982 AVL1RE32V & obj.AMask: {enc: iVEncoding},
2983 AVL1RE64V & obj.AMask: {enc: iVEncoding},
2984 AVL2RE8V & obj.AMask: {enc: iVEncoding},
2985 AVL2RE16V & obj.AMask: {enc: iVEncoding},
2986 AVL2RE32V & obj.AMask: {enc: iVEncoding},
2987 AVL2RE64V & obj.AMask: {enc: iVEncoding},
2988 AVL4RE8V & obj.AMask: {enc: iVEncoding},
2989 AVL4RE16V & obj.AMask: {enc: iVEncoding},
2990 AVL4RE32V & obj.AMask: {enc: iVEncoding},
2991 AVL4RE64V & obj.AMask: {enc: iVEncoding},
2992 AVL8RE8V & obj.AMask: {enc: iVEncoding},
2993 AVL8RE16V & obj.AMask: {enc: iVEncoding},
2994 AVL8RE32V & obj.AMask: {enc: iVEncoding},
2995 AVL8RE64V & obj.AMask: {enc: iVEncoding},
2996 AVS1RV & obj.AMask: {enc: sVEncoding},
2997 AVS2RV & obj.AMask: {enc: sVEncoding},
2998 AVS4RV & obj.AMask: {enc: sVEncoding},
2999 AVS8RV & obj.AMask: {enc: sVEncoding},
3000
3001
3002 AVADDVV & obj.AMask: {enc: rVVVEncoding},
3003 AVADDVX & obj.AMask: {enc: rVIVEncoding},
3004 AVADDVI & obj.AMask: {enc: rVViEncoding},
3005 AVSUBVV & obj.AMask: {enc: rVVVEncoding},
3006 AVSUBVX & obj.AMask: {enc: rVIVEncoding},
3007 AVRSUBVX & obj.AMask: {enc: rVIVEncoding},
3008 AVRSUBVI & obj.AMask: {enc: rVViEncoding},
3009
3010
3011 AVWADDUVV & obj.AMask: {enc: rVVVEncoding},
3012 AVWADDUVX & obj.AMask: {enc: rVIVEncoding},
3013 AVWSUBUVV & obj.AMask: {enc: rVVVEncoding},
3014 AVWSUBUVX & obj.AMask: {enc: rVIVEncoding},
3015 AVWADDVV & obj.AMask: {enc: rVVVEncoding},
3016 AVWADDVX & obj.AMask: {enc: rVIVEncoding},
3017 AVWSUBVV & obj.AMask: {enc: rVVVEncoding},
3018 AVWSUBVX & obj.AMask: {enc: rVIVEncoding},
3019 AVWADDUWV & obj.AMask: {enc: rVVVEncoding},
3020 AVWADDUWX & obj.AMask: {enc: rVIVEncoding},
3021 AVWSUBUWV & obj.AMask: {enc: rVVVEncoding},
3022 AVWSUBUWX & obj.AMask: {enc: rVIVEncoding},
3023 AVWADDWV & obj.AMask: {enc: rVVVEncoding},
3024 AVWADDWX & obj.AMask: {enc: rVIVEncoding},
3025 AVWSUBWV & obj.AMask: {enc: rVVVEncoding},
3026 AVWSUBWX & obj.AMask: {enc: rVIVEncoding},
3027
3028
3029 AVZEXTVF2 & obj.AMask: {enc: rVVEncoding},
3030 AVSEXTVF2 & obj.AMask: {enc: rVVEncoding},
3031 AVZEXTVF4 & obj.AMask: {enc: rVVEncoding},
3032 AVSEXTVF4 & obj.AMask: {enc: rVVEncoding},
3033 AVZEXTVF8 & obj.AMask: {enc: rVVEncoding},
3034 AVSEXTVF8 & obj.AMask: {enc: rVVEncoding},
3035
3036
3037 AVADCVVM & obj.AMask: {enc: rVVVEncoding},
3038 AVADCVXM & obj.AMask: {enc: rVIVEncoding},
3039 AVADCVIM & obj.AMask: {enc: rVViEncoding},
3040 AVMADCVVM & obj.AMask: {enc: rVVVEncoding},
3041 AVMADCVXM & obj.AMask: {enc: rVIVEncoding},
3042 AVMADCVIM & obj.AMask: {enc: rVViEncoding},
3043 AVMADCVV & obj.AMask: {enc: rVVVEncoding},
3044 AVMADCVX & obj.AMask: {enc: rVIVEncoding},
3045 AVMADCVI & obj.AMask: {enc: rVViEncoding},
3046 AVSBCVVM & obj.AMask: {enc: rVVVEncoding},
3047 AVSBCVXM & obj.AMask: {enc: rVIVEncoding},
3048 AVMSBCVVM & obj.AMask: {enc: rVVVEncoding},
3049 AVMSBCVXM & obj.AMask: {enc: rVIVEncoding},
3050 AVMSBCVV & obj.AMask: {enc: rVVVEncoding},
3051 AVMSBCVX & obj.AMask: {enc: rVIVEncoding},
3052
3053
3054 AVANDVV & obj.AMask: {enc: rVVVEncoding},
3055 AVANDVX & obj.AMask: {enc: rVIVEncoding},
3056 AVANDVI & obj.AMask: {enc: rVViEncoding},
3057 AVORVV & obj.AMask: {enc: rVVVEncoding},
3058 AVORVX & obj.AMask: {enc: rVIVEncoding},
3059 AVORVI & obj.AMask: {enc: rVViEncoding},
3060 AVXORVV & obj.AMask: {enc: rVVVEncoding},
3061 AVXORVX & obj.AMask: {enc: rVIVEncoding},
3062 AVXORVI & obj.AMask: {enc: rVViEncoding},
3063
3064
3065 AVSLLVV & obj.AMask: {enc: rVVVEncoding},
3066 AVSLLVX & obj.AMask: {enc: rVIVEncoding},
3067 AVSLLVI & obj.AMask: {enc: rVVuEncoding},
3068 AVSRLVV & obj.AMask: {enc: rVVVEncoding},
3069 AVSRLVX & obj.AMask: {enc: rVIVEncoding},
3070 AVSRLVI & obj.AMask: {enc: rVVuEncoding},
3071 AVSRAVV & obj.AMask: {enc: rVVVEncoding},
3072 AVSRAVX & obj.AMask: {enc: rVIVEncoding},
3073 AVSRAVI & obj.AMask: {enc: rVVuEncoding},
3074
3075
3076 AVNSRLWV & obj.AMask: {enc: rVVVEncoding},
3077 AVNSRLWX & obj.AMask: {enc: rVIVEncoding},
3078 AVNSRLWI & obj.AMask: {enc: rVVuEncoding},
3079 AVNSRAWV & obj.AMask: {enc: rVVVEncoding},
3080 AVNSRAWX & obj.AMask: {enc: rVIVEncoding},
3081 AVNSRAWI & obj.AMask: {enc: rVVuEncoding},
3082
3083
3084 AVMSEQVV & obj.AMask: {enc: rVVVEncoding},
3085 AVMSEQVX & obj.AMask: {enc: rVIVEncoding},
3086 AVMSEQVI & obj.AMask: {enc: rVViEncoding},
3087 AVMSNEVV & obj.AMask: {enc: rVVVEncoding},
3088 AVMSNEVX & obj.AMask: {enc: rVIVEncoding},
3089 AVMSNEVI & obj.AMask: {enc: rVViEncoding},
3090 AVMSLTUVV & obj.AMask: {enc: rVVVEncoding},
3091 AVMSLTUVX & obj.AMask: {enc: rVIVEncoding},
3092 AVMSLTVV & obj.AMask: {enc: rVVVEncoding},
3093 AVMSLTVX & obj.AMask: {enc: rVIVEncoding},
3094 AVMSLEUVV & obj.AMask: {enc: rVVVEncoding},
3095 AVMSLEUVX & obj.AMask: {enc: rVIVEncoding},
3096 AVMSLEUVI & obj.AMask: {enc: rVViEncoding},
3097 AVMSLEVV & obj.AMask: {enc: rVVVEncoding},
3098 AVMSLEVX & obj.AMask: {enc: rVIVEncoding},
3099 AVMSLEVI & obj.AMask: {enc: rVViEncoding},
3100 AVMSGTUVX & obj.AMask: {enc: rVIVEncoding},
3101 AVMSGTUVI & obj.AMask: {enc: rVViEncoding},
3102 AVMSGTVX & obj.AMask: {enc: rVIVEncoding},
3103 AVMSGTVI & obj.AMask: {enc: rVViEncoding},
3104
3105
3106 AVMINUVV & obj.AMask: {enc: rVVVEncoding},
3107 AVMINUVX & obj.AMask: {enc: rVIVEncoding},
3108 AVMINVV & obj.AMask: {enc: rVVVEncoding},
3109 AVMINVX & obj.AMask: {enc: rVIVEncoding},
3110 AVMAXUVV & obj.AMask: {enc: rVVVEncoding},
3111 AVMAXUVX & obj.AMask: {enc: rVIVEncoding},
3112 AVMAXVV & obj.AMask: {enc: rVVVEncoding},
3113 AVMAXVX & obj.AMask: {enc: rVIVEncoding},
3114
3115
3116 AVMULVV & obj.AMask: {enc: rVVVEncoding},
3117 AVMULVX & obj.AMask: {enc: rVIVEncoding},
3118 AVMULHVV & obj.AMask: {enc: rVVVEncoding},
3119 AVMULHVX & obj.AMask: {enc: rVIVEncoding},
3120 AVMULHUVV & obj.AMask: {enc: rVVVEncoding},
3121 AVMULHUVX & obj.AMask: {enc: rVIVEncoding},
3122 AVMULHSUVV & obj.AMask: {enc: rVVVEncoding},
3123 AVMULHSUVX & obj.AMask: {enc: rVIVEncoding},
3124
3125
3126 AVDIVUVV & obj.AMask: {enc: rVVVEncoding},
3127 AVDIVUVX & obj.AMask: {enc: rVIVEncoding},
3128 AVDIVVV & obj.AMask: {enc: rVVVEncoding},
3129 AVDIVVX & obj.AMask: {enc: rVIVEncoding},
3130 AVREMUVV & obj.AMask: {enc: rVVVEncoding},
3131 AVREMUVX & obj.AMask: {enc: rVIVEncoding},
3132 AVREMVV & obj.AMask: {enc: rVVVEncoding},
3133 AVREMVX & obj.AMask: {enc: rVIVEncoding},
3134
3135
3136 AVWMULVV & obj.AMask: {enc: rVVVEncoding},
3137 AVWMULVX & obj.AMask: {enc: rVIVEncoding},
3138 AVWMULUVV & obj.AMask: {enc: rVVVEncoding},
3139 AVWMULUVX & obj.AMask: {enc: rVIVEncoding},
3140 AVWMULSUVV & obj.AMask: {enc: rVVVEncoding},
3141 AVWMULSUVX & obj.AMask: {enc: rVIVEncoding},
3142
3143
3144 AVMACCVV & obj.AMask: {enc: rVVVEncoding},
3145 AVMACCVX & obj.AMask: {enc: rVIVEncoding},
3146 AVNMSACVV & obj.AMask: {enc: rVVVEncoding},
3147 AVNMSACVX & obj.AMask: {enc: rVIVEncoding},
3148 AVMADDVV & obj.AMask: {enc: rVVVEncoding},
3149 AVMADDVX & obj.AMask: {enc: rVIVEncoding},
3150 AVNMSUBVV & obj.AMask: {enc: rVVVEncoding},
3151 AVNMSUBVX & obj.AMask: {enc: rVIVEncoding},
3152
3153
3154 AVWMACCUVV & obj.AMask: {enc: rVVVEncoding},
3155 AVWMACCUVX & obj.AMask: {enc: rVIVEncoding},
3156 AVWMACCVV & obj.AMask: {enc: rVVVEncoding},
3157 AVWMACCVX & obj.AMask: {enc: rVIVEncoding},
3158 AVWMACCSUVV & obj.AMask: {enc: rVVVEncoding},
3159 AVWMACCSUVX & obj.AMask: {enc: rVIVEncoding},
3160 AVWMACCUSVX & obj.AMask: {enc: rVIVEncoding},
3161
3162
3163 AVMERGEVVM & obj.AMask: {enc: rVVVEncoding},
3164 AVMERGEVXM & obj.AMask: {enc: rVIVEncoding},
3165 AVMERGEVIM & obj.AMask: {enc: rVViEncoding},
3166
3167
3168 AVMVVV & obj.AMask: {enc: rVVVEncoding},
3169 AVMVVX & obj.AMask: {enc: rVIVEncoding},
3170 AVMVVI & obj.AMask: {enc: rVViEncoding},
3171
3172
3173 AVSADDUVV & obj.AMask: {enc: rVVVEncoding},
3174 AVSADDUVX & obj.AMask: {enc: rVIVEncoding},
3175 AVSADDUVI & obj.AMask: {enc: rVViEncoding},
3176 AVSADDVV & obj.AMask: {enc: rVVVEncoding},
3177 AVSADDVX & obj.AMask: {enc: rVIVEncoding},
3178 AVSADDVI & obj.AMask: {enc: rVViEncoding},
3179 AVSSUBUVV & obj.AMask: {enc: rVVVEncoding},
3180 AVSSUBUVX & obj.AMask: {enc: rVIVEncoding},
3181 AVSSUBVV & obj.AMask: {enc: rVVVEncoding},
3182 AVSSUBVX & obj.AMask: {enc: rVIVEncoding},
3183
3184
3185 AVAADDUVV & obj.AMask: {enc: rVVVEncoding},
3186 AVAADDUVX & obj.AMask: {enc: rVIVEncoding},
3187 AVAADDVV & obj.AMask: {enc: rVVVEncoding},
3188 AVAADDVX & obj.AMask: {enc: rVIVEncoding},
3189 AVASUBUVV & obj.AMask: {enc: rVVVEncoding},
3190 AVASUBUVX & obj.AMask: {enc: rVIVEncoding},
3191 AVASUBVV & obj.AMask: {enc: rVVVEncoding},
3192 AVASUBVX & obj.AMask: {enc: rVIVEncoding},
3193
3194
3195 AVSMULVV & obj.AMask: {enc: rVVVEncoding},
3196 AVSMULVX & obj.AMask: {enc: rVIVEncoding},
3197
3198
3199 AVSSRLVV & obj.AMask: {enc: rVVVEncoding},
3200 AVSSRLVX & obj.AMask: {enc: rVIVEncoding},
3201 AVSSRLVI & obj.AMask: {enc: rVVuEncoding},
3202 AVSSRAVV & obj.AMask: {enc: rVVVEncoding},
3203 AVSSRAVX & obj.AMask: {enc: rVIVEncoding},
3204 AVSSRAVI & obj.AMask: {enc: rVVuEncoding},
3205
3206
3207 AVNCLIPUWV & obj.AMask: {enc: rVVVEncoding},
3208 AVNCLIPUWX & obj.AMask: {enc: rVIVEncoding},
3209 AVNCLIPUWI & obj.AMask: {enc: rVVuEncoding},
3210 AVNCLIPWV & obj.AMask: {enc: rVVVEncoding},
3211 AVNCLIPWX & obj.AMask: {enc: rVIVEncoding},
3212 AVNCLIPWI & obj.AMask: {enc: rVVuEncoding},
3213
3214
3215 AVFADDVV & obj.AMask: {enc: rVVVEncoding},
3216 AVFADDVF & obj.AMask: {enc: rVFVEncoding},
3217 AVFSUBVV & obj.AMask: {enc: rVVVEncoding},
3218 AVFSUBVF & obj.AMask: {enc: rVFVEncoding},
3219 AVFRSUBVF & obj.AMask: {enc: rVFVEncoding},
3220
3221
3222 AVFWADDVV & obj.AMask: {enc: rVVVEncoding},
3223 AVFWADDVF & obj.AMask: {enc: rVFVEncoding},
3224 AVFWSUBVV & obj.AMask: {enc: rVVVEncoding},
3225 AVFWSUBVF & obj.AMask: {enc: rVFVEncoding},
3226 AVFWADDWV & obj.AMask: {enc: rVVVEncoding},
3227 AVFWADDWF & obj.AMask: {enc: rVFVEncoding},
3228 AVFWSUBWV & obj.AMask: {enc: rVVVEncoding},
3229 AVFWSUBWF & obj.AMask: {enc: rVFVEncoding},
3230
3231
3232 AVFMULVV & obj.AMask: {enc: rVVVEncoding},
3233 AVFMULVF & obj.AMask: {enc: rVFVEncoding},
3234 AVFDIVVV & obj.AMask: {enc: rVVVEncoding},
3235 AVFDIVVF & obj.AMask: {enc: rVFVEncoding},
3236 AVFRDIVVF & obj.AMask: {enc: rVFVEncoding},
3237
3238
3239 AVFWMULVV & obj.AMask: {enc: rVVVEncoding},
3240 AVFWMULVF & obj.AMask: {enc: rVFVEncoding},
3241
3242
3243 AVFMACCVV & obj.AMask: {enc: rVVVEncoding},
3244 AVFMACCVF & obj.AMask: {enc: rVFVEncoding},
3245 AVFNMACCVV & obj.AMask: {enc: rVVVEncoding},
3246 AVFNMACCVF & obj.AMask: {enc: rVFVEncoding},
3247 AVFMSACVV & obj.AMask: {enc: rVVVEncoding},
3248 AVFMSACVF & obj.AMask: {enc: rVFVEncoding},
3249 AVFNMSACVV & obj.AMask: {enc: rVVVEncoding},
3250 AVFNMSACVF & obj.AMask: {enc: rVFVEncoding},
3251 AVFMADDVV & obj.AMask: {enc: rVVVEncoding},
3252 AVFMADDVF & obj.AMask: {enc: rVFVEncoding},
3253 AVFNMADDVV & obj.AMask: {enc: rVVVEncoding},
3254 AVFNMADDVF & obj.AMask: {enc: rVFVEncoding},
3255 AVFMSUBVV & obj.AMask: {enc: rVVVEncoding},
3256 AVFMSUBVF & obj.AMask: {enc: rVFVEncoding},
3257 AVFNMSUBVV & obj.AMask: {enc: rVVVEncoding},
3258 AVFNMSUBVF & obj.AMask: {enc: rVFVEncoding},
3259
3260
3261 AVFWMACCVV & obj.AMask: {enc: rVVVEncoding},
3262 AVFWMACCVF & obj.AMask: {enc: rVFVEncoding},
3263 AVFWNMACCVV & obj.AMask: {enc: rVVVEncoding},
3264 AVFWNMACCVF & obj.AMask: {enc: rVFVEncoding},
3265 AVFWMSACVV & obj.AMask: {enc: rVVVEncoding},
3266 AVFWMSACVF & obj.AMask: {enc: rVFVEncoding},
3267 AVFWNMSACVV & obj.AMask: {enc: rVVVEncoding},
3268 AVFWNMSACVF & obj.AMask: {enc: rVFVEncoding},
3269
3270
3271 AVFSQRTV & obj.AMask: {enc: rVVEncoding},
3272
3273
3274 AVFRSQRT7V & obj.AMask: {enc: rVVEncoding},
3275
3276
3277 AVFREC7V & obj.AMask: {enc: rVVEncoding},
3278
3279
3280 AVFMINVV & obj.AMask: {enc: rVVVEncoding},
3281 AVFMINVF & obj.AMask: {enc: rVFVEncoding},
3282 AVFMAXVV & obj.AMask: {enc: rVVVEncoding},
3283 AVFMAXVF & obj.AMask: {enc: rVFVEncoding},
3284
3285
3286 AVFSGNJVV & obj.AMask: {enc: rVVVEncoding},
3287 AVFSGNJVF & obj.AMask: {enc: rVFVEncoding},
3288 AVFSGNJNVV & obj.AMask: {enc: rVVVEncoding},
3289 AVFSGNJNVF & obj.AMask: {enc: rVFVEncoding},
3290 AVFSGNJXVV & obj.AMask: {enc: rVVVEncoding},
3291 AVFSGNJXVF & obj.AMask: {enc: rVFVEncoding},
3292
3293
3294 AVMFEQVV & obj.AMask: {enc: rVVVEncoding},
3295 AVMFEQVF & obj.AMask: {enc: rVFVEncoding},
3296 AVMFNEVV & obj.AMask: {enc: rVVVEncoding},
3297 AVMFNEVF & obj.AMask: {enc: rVFVEncoding},
3298 AVMFLTVV & obj.AMask: {enc: rVVVEncoding},
3299 AVMFLTVF & obj.AMask: {enc: rVFVEncoding},
3300 AVMFLEVV & obj.AMask: {enc: rVVVEncoding},
3301 AVMFLEVF & obj.AMask: {enc: rVFVEncoding},
3302 AVMFGTVF & obj.AMask: {enc: rVFVEncoding},
3303 AVMFGEVF & obj.AMask: {enc: rVFVEncoding},
3304
3305
3306 AVFCLASSV & obj.AMask: {enc: rVVEncoding},
3307
3308
3309 AVFMERGEVFM & obj.AMask: {enc: rVFVEncoding},
3310
3311
3312 AVFMVVF & obj.AMask: {enc: rVFVEncoding},
3313
3314
3315 AVFCVTXUFV & obj.AMask: {enc: rVVEncoding},
3316 AVFCVTXFV & obj.AMask: {enc: rVVEncoding},
3317 AVFCVTRTZXUFV & obj.AMask: {enc: rVVEncoding},
3318 AVFCVTRTZXFV & obj.AMask: {enc: rVVEncoding},
3319 AVFCVTFXUV & obj.AMask: {enc: rVVEncoding},
3320 AVFCVTFXV & obj.AMask: {enc: rVVEncoding},
3321
3322
3323 AVFWCVTXUFV & obj.AMask: {enc: rVVEncoding},
3324 AVFWCVTXFV & obj.AMask: {enc: rVVEncoding},
3325 AVFWCVTRTZXUFV & obj.AMask: {enc: rVVEncoding},
3326 AVFWCVTRTZXFV & obj.AMask: {enc: rVVEncoding},
3327 AVFWCVTFXUV & obj.AMask: {enc: rVVEncoding},
3328 AVFWCVTFXV & obj.AMask: {enc: rVVEncoding},
3329 AVFWCVTFFV & obj.AMask: {enc: rVVEncoding},
3330
3331
3332 AVFNCVTXUFW & obj.AMask: {enc: rVVEncoding},
3333 AVFNCVTXFW & obj.AMask: {enc: rVVEncoding},
3334 AVFNCVTRTZXUFW & obj.AMask: {enc: rVVEncoding},
3335 AVFNCVTRTZXFW & obj.AMask: {enc: rVVEncoding},
3336 AVFNCVTFXUW & obj.AMask: {enc: rVVEncoding},
3337 AVFNCVTFXW & obj.AMask: {enc: rVVEncoding},
3338 AVFNCVTFFW & obj.AMask: {enc: rVVEncoding},
3339 AVFNCVTRODFFW & obj.AMask: {enc: rVVEncoding},
3340
3341
3342 AVREDSUMVS & obj.AMask: {enc: rVVVEncoding},
3343 AVREDMAXUVS & obj.AMask: {enc: rVVVEncoding},
3344 AVREDMAXVS & obj.AMask: {enc: rVVVEncoding},
3345 AVREDMINUVS & obj.AMask: {enc: rVVVEncoding},
3346 AVREDMINVS & obj.AMask: {enc: rVVVEncoding},
3347 AVREDANDVS & obj.AMask: {enc: rVVVEncoding},
3348 AVREDORVS & obj.AMask: {enc: rVVVEncoding},
3349 AVREDXORVS & obj.AMask: {enc: rVVVEncoding},
3350
3351
3352 AVWREDSUMUVS & obj.AMask: {enc: rVVVEncoding},
3353 AVWREDSUMVS & obj.AMask: {enc: rVVVEncoding},
3354
3355
3356 AVFREDOSUMVS & obj.AMask: {enc: rVVVEncoding},
3357 AVFREDUSUMVS & obj.AMask: {enc: rVVVEncoding},
3358 AVFREDMAXVS & obj.AMask: {enc: rVVVEncoding},
3359 AVFREDMINVS & obj.AMask: {enc: rVVVEncoding},
3360
3361
3362 AVFWREDOSUMVS & obj.AMask: {enc: rVVVEncoding},
3363 AVFWREDUSUMVS & obj.AMask: {enc: rVVVEncoding},
3364
3365
3366 AVMANDMM & obj.AMask: {enc: rVVVEncoding},
3367 AVMNANDMM & obj.AMask: {enc: rVVVEncoding},
3368 AVMANDNMM & obj.AMask: {enc: rVVVEncoding},
3369 AVMXORMM & obj.AMask: {enc: rVVVEncoding},
3370 AVMORMM & obj.AMask: {enc: rVVVEncoding},
3371 AVMNORMM & obj.AMask: {enc: rVVVEncoding},
3372 AVMORNMM & obj.AMask: {enc: rVVVEncoding},
3373 AVMXNORMM & obj.AMask: {enc: rVVVEncoding},
3374 AVCPOPM & obj.AMask: {enc: rVIEncoding},
3375 AVFIRSTM & obj.AMask: {enc: rVIEncoding},
3376 AVMSBFM & obj.AMask: {enc: rVVEncoding},
3377 AVMSIFM & obj.AMask: {enc: rVVEncoding},
3378 AVMSOFM & obj.AMask: {enc: rVVEncoding},
3379 AVIOTAM & obj.AMask: {enc: rVVEncoding},
3380 AVIDV & obj.AMask: {enc: rVVEncoding},
3381
3382
3383 AVMVXS & obj.AMask: {enc: rVIEncoding},
3384 AVMVSX & obj.AMask: {enc: rIVEncoding},
3385
3386
3387 AVFMVFS & obj.AMask: {enc: rVFEncoding},
3388 AVFMVSF & obj.AMask: {enc: rFVEncoding},
3389
3390
3391 AVSLIDEUPVX & obj.AMask: {enc: rVIVEncoding},
3392 AVSLIDEUPVI & obj.AMask: {enc: rVVuEncoding},
3393 AVSLIDEDOWNVX & obj.AMask: {enc: rVIVEncoding},
3394 AVSLIDEDOWNVI & obj.AMask: {enc: rVVuEncoding},
3395 AVSLIDE1UPVX & obj.AMask: {enc: rVIVEncoding},
3396 AVFSLIDE1UPVF & obj.AMask: {enc: rVFVEncoding},
3397 AVSLIDE1DOWNVX & obj.AMask: {enc: rVIVEncoding},
3398 AVFSLIDE1DOWNVF & obj.AMask: {enc: rVFVEncoding},
3399
3400
3401 AVRGATHERVV & obj.AMask: {enc: rVVVEncoding},
3402 AVRGATHEREI16VV & obj.AMask: {enc: rVVVEncoding},
3403 AVRGATHERVX & obj.AMask: {enc: rVIVEncoding},
3404 AVRGATHERVI & obj.AMask: {enc: rVVuEncoding},
3405
3406
3407 AVCOMPRESSVM & obj.AMask: {enc: rVVVEncoding},
3408
3409
3410 AVMV1RV & obj.AMask: {enc: rVVEncoding},
3411 AVMV2RV & obj.AMask: {enc: rVVEncoding},
3412 AVMV4RV & obj.AMask: {enc: rVVEncoding},
3413 AVMV8RV & obj.AMask: {enc: rVVEncoding},
3414
3415
3416 AVANDNVV & obj.AMask: {enc: rVVVEncoding},
3417 AVANDNVX & obj.AMask: {enc: rVIVEncoding},
3418 AVBREVV & obj.AMask: {enc: rVVEncoding},
3419 AVBREV8V & obj.AMask: {enc: rVVEncoding},
3420 AVREV8V & obj.AMask: {enc: rVVEncoding},
3421 AVCLZV & obj.AMask: {enc: rVVEncoding},
3422 AVCTZV & obj.AMask: {enc: rVVEncoding},
3423 AVCPOPV & obj.AMask: {enc: rVVEncoding},
3424 AVROLVV & obj.AMask: {enc: rVVVEncoding},
3425 AVROLVX & obj.AMask: {enc: rVIVEncoding},
3426 AVRORVV & obj.AMask: {enc: rVVVEncoding},
3427 AVRORVX & obj.AMask: {enc: rVIVEncoding},
3428 AVRORVI & obj.AMask: {enc: rVVuEncoding},
3429 AVWSLLVV & obj.AMask: {enc: rVVVEncoding},
3430 AVWSLLVX & obj.AMask: {enc: rVIVEncoding},
3431 AVWSLLVI & obj.AMask: {enc: rVVuEncoding},
3432
3433
3434 AVCLMULVV & obj.AMask: {enc: rVVVEncoding},
3435 AVCLMULVX & obj.AMask: {enc: rVIVEncoding},
3436 AVCLMULHVV & obj.AMask: {enc: rVVVEncoding},
3437 AVCLMULHVX & obj.AMask: {enc: rVIVEncoding},
3438
3439
3440
3441
3442
3443
3444 AECALL & obj.AMask: {enc: iIIEncoding},
3445 AEBREAK & obj.AMask: {enc: iIIEncoding},
3446
3447
3448 AWORD & obj.AMask: {enc: rawEncoding},
3449
3450
3451 obj.AFUNCDATA: {enc: pseudoOpEncoding},
3452 obj.APCDATA: {enc: pseudoOpEncoding},
3453 obj.ATEXT: {enc: pseudoOpEncoding},
3454 obj.ANOP: {enc: pseudoOpEncoding},
3455 obj.APCALIGN: {enc: pseudoOpEncoding},
3456 }
3457
3458
3459 func instructionDataForAs(as obj.As) (*instructionData, error) {
3460 if base := as &^ obj.AMask; base != obj.ABaseRISCV && base != 0 {
3461 return nil, fmt.Errorf("%v is not a RISC-V instruction", as)
3462 }
3463 asi := as & obj.AMask
3464 if int(asi) >= len(instructions) {
3465 return nil, fmt.Errorf("bad RISC-V instruction %v", as)
3466 }
3467 return &instructions[asi], nil
3468 }
3469
3470
3471 func encodingForAs(as obj.As) (*encoding, error) {
3472 insData, err := instructionDataForAs(as)
3473 if err != nil {
3474 return &badEncoding, err
3475 }
3476 if insData.enc.validate == nil {
3477 return &badEncoding, fmt.Errorf("no encoding for instruction %s", as)
3478 }
3479 return &insData.enc, nil
3480 }
3481
3482
3483
3484 func splitShiftConst(v int64) (imm int64, lsh int, rsh int, ok bool) {
3485
3486 lsh = bits.TrailingZeros64(uint64(v))
3487 c := v >> lsh
3488 if int64(int32(c)) == c {
3489 return c, lsh, 0, true
3490 }
3491
3492
3493 rsh = bits.LeadingZeros64(uint64(v))
3494 ones := bits.OnesCount64((uint64(v) >> lsh) >> 11)
3495 if rsh+ones+lsh+11 == 64 {
3496 c = signExtend(1<<11|((v>>lsh)&0x7ff), 12)
3497 if lsh > 0 || c != -1 {
3498 lsh += rsh
3499 }
3500 return c, lsh, rsh, true
3501 }
3502
3503
3504
3505
3506 if int64(uint32(c)) == c {
3507 c = int64(int32(c))
3508 lsh, rsh = 32, 32-lsh
3509 return c, lsh, rsh, true
3510 }
3511
3512 return 0, 0, 0, false
3513 }
3514
3515
3516
3517 func isShiftConst(v int64) bool {
3518 _, lsh, rsh, ok := splitShiftConst(v)
3519 return ok && (lsh > 0 || rsh > 0)
3520 }
3521
3522
3523
3524 func isMaterialisableConst(v int64) bool {
3525
3526
3527 if int64(int32(v)) == v {
3528 return true
3529 }
3530 return isShiftConst(v)
3531 }
3532
3533 type instruction struct {
3534 p *obj.Prog
3535 as obj.As
3536 rd uint32
3537 rs1 uint32
3538 rs2 uint32
3539 rs3 uint32
3540 imm int64
3541 funct3 uint32
3542 funct7 uint32
3543 }
3544
3545 func (ins *instruction) String() string {
3546 if ins.p == nil {
3547 return ins.as.String()
3548 }
3549 var suffix string
3550 if ins.p.As != ins.as {
3551 suffix = fmt.Sprintf(" (%v)", ins.as)
3552 }
3553 return fmt.Sprintf("%v%v", ins.p, suffix)
3554 }
3555
3556 func (ins *instruction) encode() (uint32, error) {
3557 enc, err := encodingForAs(ins.as)
3558 if err != nil {
3559 return 0, err
3560 }
3561 if enc.length <= 0 {
3562 return 0, fmt.Errorf("%v: encoding called for a pseudo instruction", ins.as)
3563 }
3564 return enc.encode(ins), nil
3565 }
3566
3567 func (ins *instruction) length() int {
3568 enc, err := encodingForAs(ins.as)
3569 if err != nil {
3570 return 0
3571 }
3572 return enc.length
3573 }
3574
3575 func (ins *instruction) validate(ctxt *obj.Link) {
3576 enc, err := encodingForAs(ins.as)
3577 if err != nil {
3578 ctxt.Diag("%v", err)
3579 return
3580 }
3581 enc.validate(ctxt, ins)
3582 }
3583
3584 func (ins *instruction) usesRegTmp() bool {
3585 return ins.rd == REG_TMP || ins.rs1 == REG_TMP || ins.rs2 == REG_TMP
3586 }
3587
3588 func (ins *instruction) compress() {
3589 switch ins.as {
3590 case ALW:
3591 if ins.rd != REG_X0 && ins.rs1 == REG_SP && isScaledImmU(ins.imm, 8, 4) {
3592 ins.as, ins.rs1, ins.rs2 = ACLWSP, obj.REG_NONE, ins.rs1
3593 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 7, 4) {
3594 ins.as = ACLW
3595 }
3596
3597 case ALD:
3598 if ins.rs1 == REG_SP && ins.rd != REG_X0 && isScaledImmU(ins.imm, 9, 8) {
3599 ins.as, ins.rs1, ins.rs2 = ACLDSP, obj.REG_NONE, ins.rs1
3600 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 8, 8) {
3601 ins.as = ACLD
3602 }
3603
3604 case AFLD:
3605 if ins.rs1 == REG_SP && isScaledImmU(ins.imm, 9, 8) {
3606 ins.as, ins.rs1, ins.rs2 = ACFLDSP, obj.REG_NONE, ins.rs1
3607 } else if isFloatPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 8, 8) {
3608 ins.as = ACFLD
3609 }
3610
3611 case ASW:
3612 if ins.rd == REG_SP && isScaledImmU(ins.imm, 8, 4) {
3613 ins.as, ins.rs1, ins.rs2 = ACSWSP, obj.REG_NONE, ins.rs1
3614 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 7, 4) {
3615 ins.as, ins.rd, ins.rs1, ins.rs2 = ACSW, obj.REG_NONE, ins.rd, ins.rs1
3616 }
3617
3618 case ASD:
3619 if ins.rd == REG_SP && isScaledImmU(ins.imm, 9, 8) {
3620 ins.as, ins.rs1, ins.rs2 = ACSDSP, obj.REG_NONE, ins.rs1
3621 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 8, 8) {
3622 ins.as, ins.rd, ins.rs1, ins.rs2 = ACSD, obj.REG_NONE, ins.rd, ins.rs1
3623 }
3624
3625 case AFSD:
3626 if ins.rd == REG_SP && isScaledImmU(ins.imm, 9, 8) {
3627 ins.as, ins.rs1, ins.rs2 = ACFSDSP, obj.REG_NONE, ins.rs1
3628 } else if isIntPrimeReg(ins.rd) && isFloatPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 8, 8) {
3629 ins.as, ins.rd, ins.rs1, ins.rs2 = ACFSD, obj.REG_NONE, ins.rd, ins.rs1
3630 }
3631
3632 case AADDI:
3633 if ins.rd == REG_SP && ins.rs1 == REG_SP && ins.imm != 0 && isScaledImmI(ins.imm, 10, 16) {
3634 ins.as = ACADDI16SP
3635 } else if ins.rd != REG_X0 && ins.rd == ins.rs1 && ins.imm != 0 && immIFits(ins.imm, 6) == nil {
3636 ins.as = ACADDI
3637 } else if isIntPrimeReg(ins.rd) && ins.rs1 == REG_SP && ins.imm != 0 && isScaledImmU(ins.imm, 10, 4) {
3638 ins.as = ACADDI4SPN
3639 } else if ins.rd != REG_X0 && ins.rs1 == REG_X0 && immIFits(ins.imm, 6) == nil {
3640 ins.as, ins.rs1 = ACLI, obj.REG_NONE
3641 } else if ins.rd != REG_X0 && ins.rs1 != REG_X0 && ins.imm == 0 {
3642 ins.as, ins.rs1, ins.rs2 = ACMV, obj.REG_NONE, ins.rs1
3643 } else if ins.rd == REG_X0 && ins.rs1 == REG_X0 && ins.imm == 0 {
3644 ins.as, ins.rs1 = ACNOP, ins.rd
3645 }
3646
3647 case AADDIW:
3648 if ins.rd == ins.rs1 && immIFits(ins.imm, 6) == nil {
3649 ins.as = ACADDIW
3650 }
3651
3652 case ALUI:
3653 if ins.rd != REG_X0 && ins.rd != REG_SP && ins.imm != 0 && immIFits(ins.imm, 6) == nil {
3654 ins.as = ACLUI
3655 }
3656
3657 case ASLLI:
3658 if ins.rd != REG_X0 && ins.rd == ins.rs1 && ins.imm != 0 {
3659 ins.as = ACSLLI
3660 }
3661
3662 case ASRLI:
3663 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && ins.imm != 0 {
3664 ins.as = ACSRLI
3665 }
3666
3667 case ASRAI:
3668 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && ins.imm != 0 {
3669 ins.as = ACSRAI
3670 }
3671
3672 case AANDI:
3673 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && immIFits(ins.imm, 6) == nil {
3674 ins.as = ACANDI
3675 }
3676
3677 case AADD:
3678 if ins.rd != REG_X0 && ins.rd == ins.rs1 && ins.rs2 != REG_X0 {
3679 ins.as = ACADD
3680 } else if ins.rd != REG_X0 && ins.rd == ins.rs2 && ins.rs1 != REG_X0 {
3681 ins.as, ins.rs1, ins.rs2 = ACADD, ins.rs2, ins.rs1
3682 } else if ins.rd != REG_X0 && ins.rs1 == REG_X0 && ins.rs2 != REG_X0 {
3683 ins.as = ACMV
3684 }
3685
3686 case AADDW:
3687 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3688 ins.as = ACADDW
3689 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && ins.rd == ins.rs2 {
3690 ins.as, ins.rs1, ins.rs2 = ACADDW, ins.rs2, ins.rs1
3691 }
3692
3693 case ASUB:
3694 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3695 ins.as = ACSUB
3696 }
3697
3698 case ASUBW:
3699 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3700 ins.as = ACSUBW
3701 }
3702
3703 case AAND:
3704 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3705 ins.as = ACAND
3706 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && ins.rd == ins.rs2 {
3707 ins.as, ins.rs1, ins.rs2 = ACAND, ins.rs2, ins.rs1
3708 }
3709
3710 case AOR:
3711 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3712 ins.as = ACOR
3713 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && ins.rd == ins.rs2 {
3714 ins.as, ins.rs1, ins.rs2 = ACOR, ins.rs2, ins.rs1
3715 }
3716
3717 case AXOR:
3718 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3719 ins.as = ACXOR
3720 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && ins.rd == ins.rs2 {
3721 ins.as, ins.rs1, ins.rs2 = ACXOR, ins.rs2, ins.rs1
3722 }
3723
3724 case AEBREAK:
3725 ins.as, ins.rd, ins.rs1 = ACEBREAK, obj.REG_NONE, obj.REG_NONE
3726 }
3727 }
3728
3729 func encodeFenceOperand(a *obj.Addr) (uint32, bool) {
3730 if a.Type == obj.TYPE_SPECIAL && a.Offset > int64(SPOP_FENCE_BEGIN) && a.Offset < int64(SPOP_FENCE_END) {
3731 return SpecialOperand(a.Offset).encode(), true
3732 }
3733 if a.Type == obj.TYPE_NONE {
3734 return SPOP_FENCE_IORW.encode(), true
3735 }
3736 return 0, false
3737 }
3738
3739
3740 func instructionForProg(p *obj.Prog) *instruction {
3741 ins := &instruction{
3742 as: p.As,
3743 rd: uint32(p.To.Reg),
3744 rs1: uint32(p.Reg),
3745 rs2: uint32(p.From.Reg),
3746 imm: p.From.Offset,
3747 }
3748 if len(p.RestArgs) == 1 {
3749 ins.rs3 = uint32(p.RestArgs[0].Reg)
3750 }
3751 return ins
3752 }
3753
3754
3755
3756
3757 func instructionsForOpImmediate(p *obj.Prog, as obj.As, rs int16) []*instruction {
3758
3759 ins := instructionForProg(p)
3760 ins.as, ins.rs1, ins.rs2 = as, uint32(rs), obj.REG_NONE
3761
3762 low, high, err := Split32BitImmediate(ins.imm)
3763 if err != nil {
3764 p.Ctxt.Diag("%v: constant %d too large: %v", p, ins.imm, err)
3765 return nil
3766 }
3767 if high == 0 {
3768 return []*instruction{ins}
3769 }
3770
3771
3772
3773 if p.Spadj == 0 && ins.as == AADDI && ins.imm >= -(1<<12) && ins.imm < 1<<12-1 {
3774 imm0 := ins.imm / 2
3775 imm1 := ins.imm - imm0
3776
3777
3778
3779 ins.imm = imm0
3780 insADDI := &instruction{as: AADDI, rd: ins.rd, rs1: ins.rd, imm: imm1}
3781 return []*instruction{ins, insADDI}
3782 }
3783
3784
3785
3786
3787 insLUI := &instruction{as: ALUI, rd: REG_TMP, imm: high}
3788 insADDIW := &instruction{as: AADDIW, rd: REG_TMP, rs1: REG_TMP, imm: low}
3789 switch ins.as {
3790 case AADDI:
3791 ins.as = AADD
3792 case AANDI:
3793 ins.as = AAND
3794 case AORI:
3795 ins.as = AOR
3796 case AXORI:
3797 ins.as = AXOR
3798 default:
3799 p.Ctxt.Diag("unsupported immediate instruction %v for splitting", p)
3800 return nil
3801 }
3802 ins.rs2 = REG_TMP
3803 if low == 0 {
3804 return []*instruction{insLUI, ins}
3805 }
3806 return []*instruction{insLUI, insADDIW, ins}
3807 }
3808
3809
3810
3811
3812 func instructionsForLoad(p *obj.Prog, as obj.As, rs int16) []*instruction {
3813 if p.From.Type != obj.TYPE_MEM {
3814 p.Ctxt.Diag("%v requires memory for source", p)
3815 return nil
3816 }
3817
3818 switch as {
3819 case ALD, ALB, ALH, ALW, ALBU, ALHU, ALWU, AFLW, AFLD:
3820 default:
3821 p.Ctxt.Diag("%v: unknown load instruction %v", p, as)
3822 return nil
3823 }
3824
3825
3826 ins := instructionForProg(p)
3827 ins.as, ins.rs1, ins.rs2 = as, uint32(rs), obj.REG_NONE
3828 ins.imm = p.From.Offset
3829
3830 low, high, err := Split32BitImmediate(ins.imm)
3831 if err != nil {
3832 p.Ctxt.Diag("%v: constant %d too large", p, ins.imm)
3833 return nil
3834 }
3835 if high == 0 {
3836 return []*instruction{ins}
3837 }
3838
3839
3840
3841
3842 insLUI := &instruction{as: ALUI, rd: REG_TMP, imm: high}
3843 insADD := &instruction{as: AADD, rd: REG_TMP, rs1: REG_TMP, rs2: ins.rs1}
3844 ins.rs1, ins.imm = REG_TMP, low
3845
3846 return []*instruction{insLUI, insADD, ins}
3847 }
3848
3849
3850
3851
3852 func instructionsForStore(p *obj.Prog, as obj.As, rd int16) []*instruction {
3853 if p.To.Type != obj.TYPE_MEM {
3854 p.Ctxt.Diag("%v requires memory for destination", p)
3855 return nil
3856 }
3857
3858 switch as {
3859 case ASW, ASH, ASB, ASD, AFSW, AFSD:
3860 default:
3861 p.Ctxt.Diag("%v: unknown store instruction %v", p, as)
3862 return nil
3863 }
3864
3865
3866 ins := instructionForProg(p)
3867 ins.as, ins.rd, ins.rs1, ins.rs2 = as, uint32(rd), uint32(p.From.Reg), obj.REG_NONE
3868 ins.imm = p.To.Offset
3869
3870 low, high, err := Split32BitImmediate(ins.imm)
3871 if err != nil {
3872 p.Ctxt.Diag("%v: constant %d too large", p, ins.imm)
3873 return nil
3874 }
3875 if high == 0 {
3876 return []*instruction{ins}
3877 }
3878
3879
3880
3881
3882 insLUI := &instruction{as: ALUI, rd: REG_TMP, imm: high}
3883 insADD := &instruction{as: AADD, rd: REG_TMP, rs1: REG_TMP, rs2: ins.rd}
3884 ins.rd, ins.imm = REG_TMP, low
3885
3886 return []*instruction{insLUI, insADD, ins}
3887 }
3888
3889 func instructionsForTLS(p *obj.Prog, ins *instruction) []*instruction {
3890 insAddTP := &instruction{as: AADD, rd: REG_TMP, rs1: REG_TMP, rs2: REG_TP}
3891
3892 var inss []*instruction
3893 if p.Ctxt.Flag_shared {
3894
3895
3896 insAUIPC := &instruction{as: AAUIPC, rd: REG_TMP}
3897 insLoadTLSOffset := &instruction{as: ALD, rd: REG_TMP, rs1: REG_TMP}
3898 inss = []*instruction{insAUIPC, insLoadTLSOffset, insAddTP, ins}
3899 } else {
3900
3901
3902
3903
3904
3905 insLUI := &instruction{as: ALUI, rd: REG_TMP}
3906 insADDIW := &instruction{as: AADDIW, rd: REG_TMP, rs1: REG_TMP}
3907 inss = []*instruction{insLUI, insADDIW, insAddTP, ins}
3908 }
3909 return inss
3910 }
3911
3912 func instructionsForTLSLoad(p *obj.Prog) []*instruction {
3913 if p.From.Sym.Type != objabi.STLSBSS {
3914 p.Ctxt.Diag("%v: %v is not a TLS symbol", p, p.From.Sym)
3915 return nil
3916 }
3917
3918 ins := instructionForProg(p)
3919 ins.as, ins.rs1, ins.rs2, ins.imm = movToLoad(p.As), REG_TMP, obj.REG_NONE, 0
3920
3921 return instructionsForTLS(p, ins)
3922 }
3923
3924 func instructionsForTLSStore(p *obj.Prog) []*instruction {
3925 if p.To.Sym.Type != objabi.STLSBSS {
3926 p.Ctxt.Diag("%v: %v is not a TLS symbol", p, p.To.Sym)
3927 return nil
3928 }
3929
3930 ins := instructionForProg(p)
3931 ins.as, ins.rd, ins.rs1, ins.rs2, ins.imm = movToStore(p.As), REG_TMP, uint32(p.From.Reg), obj.REG_NONE, 0
3932
3933 return instructionsForTLS(p, ins)
3934 }
3935
3936 func instructionsForMOVConst(p *obj.Prog) []*instruction {
3937 ins := instructionForProg(p)
3938 inss := []*instruction{ins}
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961 var insSLLI, insSRLI, insMOVWU *instruction
3962 if err := immIFits(ins.imm, 32); err != nil {
3963 if c, lsh, rsh, ok := splitShiftConst(ins.imm); ok {
3964 ins.imm = c
3965 if buildcfg.GORISCV64 >= 22 && lsh == 32 && rsh == 32 {
3966 insMOVWU = &instruction{as: AADDUW, rd: ins.rd, rs1: ins.rd, rs2: REG_ZERO}
3967 lsh, rsh = 0, 0
3968 }
3969 if lsh > 0 {
3970 insSLLI = &instruction{as: ASLLI, rd: ins.rd, rs1: ins.rd, imm: int64(lsh)}
3971 }
3972 if rsh > 0 {
3973 insSRLI = &instruction{as: ASRLI, rd: ins.rd, rs1: ins.rd, imm: int64(rsh)}
3974 }
3975 }
3976 }
3977
3978 low, high, err := Split32BitImmediate(ins.imm)
3979 if err != nil {
3980 p.Ctxt.Diag("%v: constant %d too large: %v", p, ins.imm, err)
3981 return nil
3982 }
3983
3984
3985 ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, REG_ZERO, obj.REG_NONE, low
3986
3987
3988 if high != 0 {
3989
3990
3991 insLUI := &instruction{as: ALUI, rd: ins.rd, imm: high}
3992 inss = []*instruction{insLUI}
3993 if low != 0 {
3994 ins.as, ins.rs1 = AADDIW, ins.rd
3995 inss = append(inss, ins)
3996 }
3997 }
3998 if insMOVWU != nil {
3999 inss = append(inss, insMOVWU)
4000 }
4001 if insSLLI != nil {
4002 inss = append(inss, insSLLI)
4003 }
4004 if insSRLI != nil {
4005 inss = append(inss, insSRLI)
4006 }
4007
4008 return inss
4009 }
4010
4011
4012
4013 func instructionsForMOV(p *obj.Prog) []*instruction {
4014 ins := instructionForProg(p)
4015 inss := []*instruction{ins}
4016
4017 if p.Reg != 0 {
4018 p.Ctxt.Diag("%v: illegal MOV instruction", p)
4019 return nil
4020 }
4021
4022 switch {
4023 case p.From.Type == obj.TYPE_CONST && p.To.Type == obj.TYPE_REG:
4024
4025 if p.As != AMOV {
4026 p.Ctxt.Diag("%v: unsupported constant load", p)
4027 return nil
4028 }
4029 return instructionsForMOVConst(p)
4030
4031 case p.From.Type == obj.TYPE_CONST && p.To.Type != obj.TYPE_REG:
4032 p.Ctxt.Diag("%v: constant load must target register", p)
4033 return nil
4034
4035 case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_REG:
4036
4037 switch p.As {
4038 case AMOV:
4039
4040 ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, uint32(p.From.Reg), obj.REG_NONE, 0
4041 case AMOVW:
4042
4043 ins.as, ins.rs1, ins.rs2, ins.imm = AADDIW, uint32(p.From.Reg), obj.REG_NONE, 0
4044 case AMOVBU:
4045
4046 ins.as, ins.rs1, ins.rs2, ins.imm = AANDI, uint32(p.From.Reg), obj.REG_NONE, 255
4047 case AMOVF:
4048
4049
4050
4051 if ins.rs2 >= REG_X0 && ins.rs2 <= REG_X31 && ins.rd >= REG_F0 && ins.rd <= REG_F31 {
4052 ins.as = AFMVWX
4053 } else if ins.rs2 >= REG_F0 && ins.rs2 <= REG_F31 && ins.rd >= REG_X0 && ins.rd <= REG_X31 {
4054 ins.as = AFMVXW
4055 } else {
4056 ins.as, ins.rs1 = AFSGNJS, uint32(p.From.Reg)
4057 }
4058 case AMOVD:
4059
4060
4061
4062 if ins.rs2 >= REG_X0 && ins.rs2 <= REG_X31 && ins.rd >= REG_F0 && ins.rd <= REG_F31 {
4063 ins.as = AFMVDX
4064 } else if ins.rs2 >= REG_F0 && ins.rs2 <= REG_F31 && ins.rd >= REG_X0 && ins.rd <= REG_X31 {
4065 ins.as = AFMVXD
4066 } else {
4067 ins.as, ins.rs1 = AFSGNJD, uint32(p.From.Reg)
4068 }
4069 case AMOVB, AMOVH:
4070 if buildcfg.GORISCV64 >= 22 {
4071
4072 ins.as, ins.rs1, ins.rs2 = ASEXTB, uint32(p.From.Reg), obj.REG_NONE
4073 if p.As == AMOVH {
4074 ins.as = ASEXTH
4075 }
4076 } else {
4077
4078 ins.as, ins.rs1, ins.rs2 = ASLLI, uint32(p.From.Reg), obj.REG_NONE
4079 if p.As == AMOVB {
4080 ins.imm = 56
4081 } else if p.As == AMOVH {
4082 ins.imm = 48
4083 }
4084 ins2 := &instruction{as: ASRAI, rd: ins.rd, rs1: ins.rd, imm: ins.imm}
4085 inss = append(inss, ins2)
4086 }
4087 case AMOVHU, AMOVWU:
4088 if buildcfg.GORISCV64 >= 22 {
4089
4090 ins.as, ins.rs1, ins.rs2, ins.imm = AZEXTH, uint32(p.From.Reg), obj.REG_NONE, 0
4091 if p.As == AMOVWU {
4092 ins.as, ins.rs2 = AADDUW, REG_ZERO
4093 }
4094 } else {
4095
4096 ins.as, ins.rs1, ins.rs2 = ASLLI, uint32(p.From.Reg), obj.REG_NONE
4097 if p.As == AMOVHU {
4098 ins.imm = 48
4099 } else if p.As == AMOVWU {
4100 ins.imm = 32
4101 }
4102 ins2 := &instruction{as: ASRLI, rd: ins.rd, rs1: ins.rd, imm: ins.imm}
4103 inss = append(inss, ins2)
4104 }
4105 }
4106
4107 case p.From.Type == obj.TYPE_MEM && p.To.Type == obj.TYPE_REG:
4108
4109 switch p.From.Name {
4110 case obj.NAME_AUTO, obj.NAME_PARAM, obj.NAME_NONE:
4111
4112 inss = instructionsForLoad(p, movToLoad(p.As), addrToReg(p.From))
4113
4114 case obj.NAME_EXTERN, obj.NAME_STATIC, obj.NAME_GOTREF:
4115 if p.From.Sym.Type == objabi.STLSBSS {
4116 return instructionsForTLSLoad(p)
4117 }
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127 addrReg := ins.rd
4128 if addrReg < REG_X0 || addrReg > REG_X31 {
4129 addrReg = REG_TMP
4130 }
4131 insAUIPC := &instruction{as: AAUIPC, rd: addrReg}
4132 ins.as, ins.rs1, ins.rs2, ins.imm = movToLoad(p.As), addrReg, obj.REG_NONE, 0
4133 inss = []*instruction{insAUIPC, ins}
4134
4135 default:
4136 p.Ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
4137 return nil
4138 }
4139
4140 case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_MEM:
4141
4142 switch p.As {
4143 case AMOVBU, AMOVHU, AMOVWU:
4144 p.Ctxt.Diag("%v: unsupported unsigned store", p)
4145 return nil
4146 }
4147 switch p.To.Name {
4148 case obj.NAME_AUTO, obj.NAME_PARAM, obj.NAME_NONE:
4149
4150 inss = instructionsForStore(p, movToStore(p.As), addrToReg(p.To))
4151
4152 case obj.NAME_EXTERN, obj.NAME_STATIC:
4153 if p.To.Sym.Type == objabi.STLSBSS {
4154 return instructionsForTLSStore(p)
4155 }
4156
4157
4158
4159
4160
4161
4162 insAUIPC := &instruction{as: AAUIPC, rd: REG_TMP}
4163 ins.as, ins.rd, ins.rs1, ins.rs2, ins.imm = movToStore(p.As), REG_TMP, uint32(p.From.Reg), obj.REG_NONE, 0
4164 inss = []*instruction{insAUIPC, ins}
4165
4166 default:
4167 p.Ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
4168 return nil
4169 }
4170
4171 case p.From.Type == obj.TYPE_ADDR && p.To.Type == obj.TYPE_REG:
4172
4173 if p.As != AMOV {
4174 p.Ctxt.Diag("%v: unsupported address load", p)
4175 return nil
4176 }
4177 switch p.From.Name {
4178 case obj.NAME_AUTO, obj.NAME_PARAM, obj.NAME_NONE:
4179 inss = instructionsForOpImmediate(p, AADDI, addrToReg(p.From))
4180
4181 case obj.NAME_EXTERN, obj.NAME_STATIC:
4182
4183
4184
4185
4186
4187 insAUIPC := &instruction{as: AAUIPC, rd: ins.rd}
4188 ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, ins.rd, obj.REG_NONE, 0
4189 inss = []*instruction{insAUIPC, ins}
4190
4191 default:
4192 p.Ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
4193 return nil
4194 }
4195
4196 case p.From.Type == obj.TYPE_ADDR && p.To.Type != obj.TYPE_REG:
4197 p.Ctxt.Diag("%v: address load must target register", p)
4198 return nil
4199
4200 default:
4201 p.Ctxt.Diag("%v: unsupported MOV", p)
4202 return nil
4203 }
4204
4205 return inss
4206 }
4207
4208
4209 func instructionsForRotate(p *obj.Prog, ins *instruction) []*instruction {
4210 if buildcfg.GORISCV64 >= 22 {
4211
4212 return []*instruction{ins}
4213 }
4214
4215 switch ins.as {
4216 case AROL, AROLW, AROR, ARORW:
4217
4218
4219 sllOp, srlOp := ASLL, ASRL
4220 if ins.as == AROLW || ins.as == ARORW {
4221 sllOp, srlOp = ASLLW, ASRLW
4222 }
4223 shift1, shift2 := sllOp, srlOp
4224 if ins.as == AROR || ins.as == ARORW {
4225 shift1, shift2 = shift2, shift1
4226 }
4227 return []*instruction{
4228 &instruction{as: ASUB, rs1: REG_ZERO, rs2: ins.rs2, rd: REG_TMP},
4229 &instruction{as: shift2, rs1: ins.rs1, rs2: REG_TMP, rd: REG_TMP},
4230 &instruction{as: shift1, rs1: ins.rs1, rs2: ins.rs2, rd: ins.rd},
4231 &instruction{as: AOR, rs1: REG_TMP, rs2: ins.rd, rd: ins.rd},
4232 }
4233
4234 case ARORI, ARORIW:
4235
4236 sllOp, srlOp := ASLLI, ASRLI
4237 sllImm := int64(int8(-ins.imm) & 63)
4238 if ins.as == ARORIW {
4239 sllOp, srlOp = ASLLIW, ASRLIW
4240 sllImm = int64(int8(-ins.imm) & 31)
4241 }
4242 return []*instruction{
4243 &instruction{as: srlOp, rs1: ins.rs1, rd: REG_TMP, imm: ins.imm},
4244 &instruction{as: sllOp, rs1: ins.rs1, rd: ins.rd, imm: sllImm},
4245 &instruction{as: AOR, rs1: REG_TMP, rs2: ins.rd, rd: ins.rd},
4246 }
4247
4248 default:
4249 p.Ctxt.Diag("%v: unknown rotation", p)
4250 return nil
4251 }
4252 }
4253
4254
4255 func instructionsForMinMax(p *obj.Prog, ins *instruction) []*instruction {
4256 if buildcfg.GORISCV64 >= 22 {
4257
4258 return []*instruction{ins}
4259 }
4260
4261
4262 if ins.rs1 == ins.rs2 {
4263 ins.as, ins.rs2, ins.imm = AADDI, obj.REG_NONE, 0
4264 return []*instruction{ins}
4265 }
4266
4267
4268
4269 if ins.rs1 == ins.rd {
4270 ins.rs1, ins.rs2 = ins.rs2, ins.rs1
4271 }
4272 sltReg1, sltReg2 := ins.rs2, ins.rs1
4273
4274
4275
4276 switch ins.as {
4277 case AMIN:
4278 ins.as = ASLT
4279 case AMAX:
4280 ins.as, sltReg1, sltReg2 = ASLT, sltReg2, sltReg1
4281 case AMINU:
4282 ins.as = ASLTU
4283 case AMAXU:
4284 ins.as, sltReg1, sltReg2 = ASLTU, sltReg2, sltReg1
4285 }
4286 return []*instruction{
4287 &instruction{as: ins.as, rs1: sltReg1, rs2: sltReg2, rd: REG_TMP},
4288 &instruction{as: ASUB, rs1: REG_ZERO, rs2: REG_TMP, rd: REG_TMP},
4289 &instruction{as: AXOR, rs1: ins.rs1, rs2: ins.rs2, rd: ins.rd},
4290 &instruction{as: AAND, rs1: REG_TMP, rs2: ins.rd, rd: ins.rd},
4291 &instruction{as: AXOR, rs1: ins.rs1, rs2: ins.rd, rd: ins.rd},
4292 }
4293 }
4294
4295
4296 func instructionsForProg(p *obj.Prog, compress bool) []*instruction {
4297 ins := instructionForProg(p)
4298 inss := []*instruction{ins}
4299
4300 if ins.as == AVSETVLI || ins.as == AVSETIVLI {
4301 if len(p.RestArgs) != 4 {
4302 p.Ctxt.Diag("incorrect number of arguments for instruction")
4303 return nil
4304 }
4305 } else if len(p.RestArgs) > 1 {
4306 p.Ctxt.Diag("too many source registers")
4307 return nil
4308 }
4309
4310 switch ins.as {
4311 case ACJALR, AJAL, AJALR:
4312 ins.rd, ins.rs1, ins.rs2 = uint32(p.From.Reg), uint32(p.To.Reg), obj.REG_NONE
4313 ins.imm = p.To.Offset
4314
4315 case ABEQ, ABEQZ, ABGE, ABGEU, ABGEZ, ABGT, ABGTU, ABGTZ, ABLE, ABLEU, ABLEZ, ABLT, ABLTU, ABLTZ, ABNE, ABNEZ:
4316 switch ins.as {
4317 case ABEQZ:
4318 ins.as, ins.rs1, ins.rs2 = ABEQ, REG_ZERO, uint32(p.From.Reg)
4319 case ABGEZ:
4320 ins.as, ins.rs1, ins.rs2 = ABGE, REG_ZERO, uint32(p.From.Reg)
4321 case ABGT:
4322 ins.as, ins.rs1, ins.rs2 = ABLT, uint32(p.From.Reg), uint32(p.Reg)
4323 case ABGTU:
4324 ins.as, ins.rs1, ins.rs2 = ABLTU, uint32(p.From.Reg), uint32(p.Reg)
4325 case ABGTZ:
4326 ins.as, ins.rs1, ins.rs2 = ABLT, uint32(p.From.Reg), REG_ZERO
4327 case ABLE:
4328 ins.as, ins.rs1, ins.rs2 = ABGE, uint32(p.From.Reg), uint32(p.Reg)
4329 case ABLEU:
4330 ins.as, ins.rs1, ins.rs2 = ABGEU, uint32(p.From.Reg), uint32(p.Reg)
4331 case ABLEZ:
4332 ins.as, ins.rs1, ins.rs2 = ABGE, uint32(p.From.Reg), REG_ZERO
4333 case ABLTZ:
4334 ins.as, ins.rs1, ins.rs2 = ABLT, REG_ZERO, uint32(p.From.Reg)
4335 case ABNEZ:
4336 ins.as, ins.rs1, ins.rs2 = ABNE, REG_ZERO, uint32(p.From.Reg)
4337 }
4338 ins.imm = p.To.Offset
4339
4340 case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD:
4341 inss = instructionsForMOV(p)
4342
4343 case ALW, ALWU, ALH, ALHU, ALB, ALBU, ALD, AFLW, AFLD:
4344 inss = instructionsForLoad(p, ins.as, p.From.Reg)
4345
4346 case ASW, ASH, ASB, ASD, AFSW, AFSD:
4347 inss = instructionsForStore(p, ins.as, p.To.Reg)
4348
4349 case ALRW, ALRD:
4350
4351 ins.funct7 = 2
4352 ins.rs1, ins.rs2 = uint32(p.From.Reg), REG_ZERO
4353
4354 case AADDI, AANDI, AORI, AXORI:
4355 inss = instructionsForOpImmediate(p, ins.as, p.Reg)
4356
4357 case ASCW, ASCD:
4358
4359 ins.funct7 = 1
4360 ins.rd, ins.rs1, ins.rs2 = uint32(p.RegTo2), uint32(p.To.Reg), uint32(p.From.Reg)
4361
4362 case AAMOSWAPW, AAMOSWAPD, AAMOADDW, AAMOADDD, AAMOANDW, AAMOANDD, AAMOORW, AAMOORD,
4363 AAMOXORW, AAMOXORD, AAMOMINW, AAMOMIND, AAMOMINUW, AAMOMINUD, AAMOMAXW, AAMOMAXD, AAMOMAXUW, AAMOMAXUD:
4364
4365 ins.funct7 = 3
4366 ins.rd, ins.rs1, ins.rs2 = uint32(p.RegTo2), uint32(p.To.Reg), uint32(p.From.Reg)
4367
4368 case AECALL, AEBREAK:
4369 insEnc := encode(p.As)
4370 if p.To.Type == obj.TYPE_NONE {
4371 ins.rd = REG_ZERO
4372 }
4373 ins.rs1 = REG_ZERO
4374 ins.imm = insEnc.csr
4375
4376 case ARDCYCLE, ARDTIME, ARDINSTRET:
4377 ins.as = ACSRRS
4378 if p.To.Type == obj.TYPE_NONE {
4379 ins.rd = REG_ZERO
4380 }
4381 ins.rs1 = REG_ZERO
4382 switch p.As {
4383 case ARDCYCLE:
4384 ins.imm = -1024
4385 case ARDTIME:
4386 ins.imm = -1023
4387 case ARDINSTRET:
4388 ins.imm = -1022
4389 }
4390
4391 case ACSRC, ACSRRC, ACSRCI, ACSRRCI, ACSRR, ACSRS, ACSRSI, ACSRRS, ACSRRSI, ACSRRW, ACSRRWI, ACSRW, ACSRWI:
4392 switch {
4393 case ins.as == ACSRCI || (ins.as == ACSRC && p.From.Type == obj.TYPE_CONST):
4394 ins.as = ACSRRCI
4395 ins.rd = REG_ZERO
4396 case ins.as == ACSRC:
4397 ins.as = ACSRRC
4398 ins.rd = REG_ZERO
4399 case ins.as == ACSRSI || (ins.as == ACSRS && p.From.Type == obj.TYPE_CONST):
4400 ins.as = ACSRRSI
4401 ins.rd = REG_ZERO
4402 case ins.as == ACSRS:
4403 ins.as = ACSRRS
4404 ins.rd = REG_ZERO
4405 case ins.as == ACSRWI || (ins.as == ACSRW && p.From.Type == obj.TYPE_CONST):
4406 ins.as = ACSRRWI
4407 ins.rd = REG_ZERO
4408 case ins.as == ACSRW:
4409 ins.as = ACSRRW
4410 ins.rd = REG_ZERO
4411 default:
4412 if p.To.Type != obj.TYPE_REG {
4413 p.Ctxt.Diag("%v: needs an integer register output", p)
4414 return nil
4415 }
4416 }
4417
4418 if len(p.RestArgs) == 0 || p.RestArgs[0].Type != obj.TYPE_SPECIAL {
4419 p.Ctxt.Diag("%v: missing CSR name", p)
4420 return nil
4421 }
4422 if ins.as == ACSRR {
4423 ins.as = ACSRRS
4424 ins.rs1 = REG_ZERO
4425 } else if p.From.Type == obj.TYPE_CONST {
4426 imm := p.From.Offset
4427 if imm < 0 || imm >= 32 {
4428 p.Ctxt.Diag("%v: immediate out of range 0 to 31", p)
4429 return nil
4430 }
4431 ins.rs1 = uint32(imm) + REG_ZERO
4432 } else if p.From.Type == obj.TYPE_REG {
4433 ins.rs1 = uint32(p.From.Reg)
4434 } else {
4435 p.Ctxt.Diag("%v: integer register or immediate expected for 1st operand", p)
4436 return nil
4437 }
4438 csrNum := SpecialOperand(p.RestArgs[0].Offset).encode()
4439 if csrNum >= 1<<12 {
4440 p.Ctxt.Diag("%v: unknown CSR", p)
4441 return nil
4442 }
4443 if _, ok := CSRs[uint16(csrNum)]; !ok {
4444 p.Ctxt.Diag("%v: unknown CSR", p)
4445 return nil
4446 }
4447 ins.imm = int64(csrNum)
4448 if ins.imm > 2047 {
4449 ins.imm -= 4096
4450 }
4451 ins.rs2 = obj.REG_NONE
4452
4453 case AFENCE:
4454 ins.rd, ins.rs1, ins.rs2 = REG_ZERO, REG_ZERO, obj.REG_NONE
4455 if p.Scond == fenceTsoSuffixBit {
4456 if p.From.Type != obj.TYPE_NONE || p.To.Type != obj.TYPE_NONE {
4457 p.Ctxt.Diag("FENCE.TSO must not have operands: %v", p)
4458 }
4459
4460 ins.imm = signExtend((8<<8)|(3<<4)|3, 12)
4461 } else {
4462 pred, ok := encodeFenceOperand(&p.From)
4463 if !ok {
4464 p.Ctxt.Diag("invalid FENCE predecessor operand: %v", p)
4465 }
4466 succ, ok := encodeFenceOperand(&p.To)
4467 if !ok {
4468 p.Ctxt.Diag("invalid FENCE successor operand: %v", p)
4469 }
4470
4471
4472 ins.imm = int64((pred << 4) | succ)
4473 }
4474
4475 case APAUSE:
4476 ins.as, ins.rd, ins.rs1, ins.rs2 = AFENCE, REG_ZERO, REG_ZERO, obj.REG_NONE
4477 ins.imm = 0x010
4478
4479 case AFCVTWS, AFCVTLS, AFCVTWUS, AFCVTLUS, AFCVTWD, AFCVTLD, AFCVTWUD, AFCVTLUD:
4480
4481 if p.Scond&rmSuffixBit == 0 {
4482 ins.funct3 = uint32(RM_RTZ)
4483 } else {
4484 ins.funct3 = uint32(p.Scond &^ rmSuffixBit)
4485 }
4486
4487 case AFNES, AFNED:
4488
4489 if p.To.Type != obj.TYPE_REG {
4490 p.Ctxt.Diag("%v needs an integer register output", p)
4491 return nil
4492 }
4493 if ins.as == AFNES {
4494 ins.as = AFEQS
4495 } else {
4496 ins.as = AFEQD
4497 }
4498 ins2 := &instruction{
4499 as: AXORI,
4500 rd: ins.rd,
4501 rs1: ins.rd,
4502 imm: 1,
4503 }
4504 inss = append(inss, ins2)
4505
4506 case AFSQRTS, AFSQRTD:
4507
4508
4509 ins.rs1 = uint32(p.From.Reg)
4510 ins.rs2 = REG_F0
4511
4512 case AFMADDS, AFMSUBS, AFNMADDS, AFNMSUBS,
4513 AFMADDD, AFMSUBD, AFNMADDD, AFNMSUBD:
4514
4515
4516 ins.rs1, ins.rs2 = ins.rs2, ins.rs1
4517
4518 case ANEG, ANEGW:
4519
4520 ins.as = ASUB
4521 if p.As == ANEGW {
4522 ins.as = ASUBW
4523 }
4524 ins.rs1 = REG_ZERO
4525 if ins.rd == obj.REG_NONE {
4526 ins.rd = ins.rs2
4527 }
4528
4529 case ANOT:
4530
4531 ins.as = AXORI
4532 ins.rs1, ins.rs2 = uint32(p.From.Reg), obj.REG_NONE
4533 if ins.rd == obj.REG_NONE {
4534 ins.rd = ins.rs1
4535 }
4536 ins.imm = -1
4537
4538 case ASEQZ:
4539
4540 ins.as = ASLTIU
4541 ins.rs1, ins.rs2 = uint32(p.From.Reg), obj.REG_NONE
4542 ins.imm = 1
4543
4544 case ASNEZ:
4545
4546 ins.as = ASLTU
4547 ins.rs1 = REG_ZERO
4548
4549 case AFABSS:
4550
4551 ins.as = AFSGNJXS
4552 ins.rs1 = uint32(p.From.Reg)
4553
4554 case AFABSD:
4555
4556 ins.as = AFSGNJXD
4557 ins.rs1 = uint32(p.From.Reg)
4558
4559 case AFNEGS:
4560
4561 ins.as = AFSGNJNS
4562 ins.rs1 = uint32(p.From.Reg)
4563
4564 case AFNEGD:
4565
4566 ins.as = AFSGNJND
4567 ins.rs1 = uint32(p.From.Reg)
4568
4569 case ACLW, ACLD, ACFLD:
4570 ins.rs1, ins.rs2 = ins.rs2, obj.REG_NONE
4571
4572 case ACSW, ACSD, ACFSD:
4573 ins.rs1, ins.rd = ins.rd, obj.REG_NONE
4574 ins.imm = p.To.Offset
4575
4576 case ACSWSP, ACSDSP, ACFSDSP:
4577 ins.imm = p.To.Offset
4578
4579 case ACANDI, ACSRLI, ACSRAI:
4580 ins.rs1, ins.rd = ins.rd, ins.rs1
4581
4582 case ACBEQZ, ACBNEZ:
4583 ins.rd, ins.rs1, ins.rs2 = obj.REG_NONE, uint32(p.From.Reg), obj.REG_NONE
4584 ins.imm = p.To.Offset
4585
4586 case ACJR:
4587 ins.rd, ins.rs1 = obj.REG_NONE, uint32(p.To.Reg)
4588
4589 case ACJ:
4590 ins.imm = p.To.Offset
4591
4592 case ACNOP:
4593 ins.rd, ins.rs1 = REG_ZERO, REG_ZERO
4594
4595 case AROL, AROLW, AROR, ARORW:
4596 inss = instructionsForRotate(p, ins)
4597
4598 case ARORI:
4599 if ins.imm < 0 || ins.imm > 63 {
4600 p.Ctxt.Diag("%v: immediate out of range 0 to 63", p)
4601 }
4602 inss = instructionsForRotate(p, ins)
4603
4604 case ARORIW:
4605 if ins.imm < 0 || ins.imm > 31 {
4606 p.Ctxt.Diag("%v: immediate out of range 0 to 31", p)
4607 }
4608 inss = instructionsForRotate(p, ins)
4609
4610 case ASLLI, ASRLI, ASRAI:
4611 if ins.imm < 0 || ins.imm > 63 {
4612 p.Ctxt.Diag("%v: immediate out of range 0 to 63", p)
4613 }
4614
4615 case ASLLIW, ASRLIW, ASRAIW:
4616 if ins.imm < 0 || ins.imm > 31 {
4617 p.Ctxt.Diag("%v: immediate out of range 0 to 31", p)
4618 }
4619
4620 case ACLZ, ACLZW, ACTZ, ACTZW, ACPOP, ACPOPW, ASEXTB, ASEXTH, AZEXTH:
4621 ins.rs1, ins.rs2 = uint32(p.From.Reg), obj.REG_NONE
4622
4623 case AORCB, AREV8:
4624 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
4625
4626 case AANDN, AORN:
4627 if buildcfg.GORISCV64 >= 22 {
4628
4629 break
4630 }
4631
4632
4633 bitwiseOp, notReg := AAND, ins.rd
4634 if ins.as == AORN {
4635 bitwiseOp = AOR
4636 }
4637 if ins.rs1 == notReg {
4638 notReg = REG_TMP
4639 }
4640 inss = []*instruction{
4641 &instruction{as: AXORI, rs1: ins.rs2, rs2: obj.REG_NONE, rd: notReg, imm: -1},
4642 &instruction{as: bitwiseOp, rs1: ins.rs1, rs2: notReg, rd: ins.rd},
4643 }
4644
4645 case AXNOR:
4646 if buildcfg.GORISCV64 >= 22 {
4647
4648 break
4649 }
4650
4651 ins.as = AXOR
4652 inss = append(inss, &instruction{as: AXORI, rs1: ins.rd, rs2: obj.REG_NONE, rd: ins.rd, imm: -1})
4653
4654 case AMIN, AMAX, AMINU, AMAXU:
4655 inss = instructionsForMinMax(p, ins)
4656
4657 case AVSETVLI, AVSETIVLI:
4658 ins.rs1, ins.rs2 = ins.rs2, obj.REG_NONE
4659 vtype, err := EncodeVectorType(p.RestArgs[0].Offset, p.RestArgs[1].Offset, p.RestArgs[2].Offset, p.RestArgs[3].Offset)
4660 if err != nil {
4661 p.Ctxt.Diag("%v: %v", p, err)
4662 }
4663 ins.imm = vtype
4664 if ins.as == AVSETIVLI {
4665 if p.From.Type != obj.TYPE_CONST {
4666 p.Ctxt.Diag("%v: expected immediate value", p)
4667 }
4668 ins.rs1 = uint32(p.From.Offset)
4669 }
4670
4671 case AVLE8V, AVLE16V, AVLE32V, AVLE64V, AVSE8V, AVSE16V, AVSE32V, AVSE64V, AVLE8FFV, AVLE16FFV, AVLE32FFV, AVLE64FFV, AVLMV, AVSMV,
4672 AVLSEG2E8V, AVLSEG3E8V, AVLSEG4E8V, AVLSEG5E8V, AVLSEG6E8V, AVLSEG7E8V, AVLSEG8E8V,
4673 AVLSEG2E16V, AVLSEG3E16V, AVLSEG4E16V, AVLSEG5E16V, AVLSEG6E16V, AVLSEG7E16V, AVLSEG8E16V,
4674 AVLSEG2E32V, AVLSEG3E32V, AVLSEG4E32V, AVLSEG5E32V, AVLSEG6E32V, AVLSEG7E32V, AVLSEG8E32V,
4675 AVLSEG2E64V, AVLSEG3E64V, AVLSEG4E64V, AVLSEG5E64V, AVLSEG6E64V, AVLSEG7E64V, AVLSEG8E64V,
4676 AVSSEG2E8V, AVSSEG3E8V, AVSSEG4E8V, AVSSEG5E8V, AVSSEG6E8V, AVSSEG7E8V, AVSSEG8E8V,
4677 AVSSEG2E16V, AVSSEG3E16V, AVSSEG4E16V, AVSSEG5E16V, AVSSEG6E16V, AVSSEG7E16V, AVSSEG8E16V,
4678 AVSSEG2E32V, AVSSEG3E32V, AVSSEG4E32V, AVSSEG5E32V, AVSSEG6E32V, AVSSEG7E32V, AVSSEG8E32V,
4679 AVSSEG2E64V, AVSSEG3E64V, AVSSEG4E64V, AVSSEG5E64V, AVSSEG6E64V, AVSSEG7E64V, AVSSEG8E64V,
4680 AVLSEG2E8FFV, AVLSEG3E8FFV, AVLSEG4E8FFV, AVLSEG5E8FFV, AVLSEG6E8FFV, AVLSEG7E8FFV, AVLSEG8E8FFV,
4681 AVLSEG2E16FFV, AVLSEG3E16FFV, AVLSEG4E16FFV, AVLSEG5E16FFV, AVLSEG6E16FFV, AVLSEG7E16FFV, AVLSEG8E16FFV,
4682 AVLSEG2E32FFV, AVLSEG3E32FFV, AVLSEG4E32FFV, AVLSEG5E32FFV, AVLSEG6E32FFV, AVLSEG7E32FFV, AVLSEG8E32FFV,
4683 AVLSEG2E64FFV, AVLSEG3E64FFV, AVLSEG4E64FFV, AVLSEG5E64FFV, AVLSEG6E64FFV, AVLSEG7E64FFV, AVLSEG8E64FFV:
4684
4685 switch {
4686 case ins.rs1 == obj.REG_NONE:
4687 ins.funct7 |= 1
4688 case ins.rs1 != REG_V0:
4689 p.Ctxt.Diag("%v: invalid vector mask register", p)
4690 }
4691 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
4692
4693 case AVLSE8V, AVLSE16V, AVLSE32V, AVLSE64V,
4694 AVLUXEI8V, AVLUXEI16V, AVLUXEI32V, AVLUXEI64V, AVLOXEI8V, AVLOXEI16V, AVLOXEI32V, AVLOXEI64V,
4695 AVLSSEG2E8V, AVLSSEG3E8V, AVLSSEG4E8V, AVLSSEG5E8V, AVLSSEG6E8V, AVLSSEG7E8V, AVLSSEG8E8V,
4696 AVLSSEG2E16V, AVLSSEG3E16V, AVLSSEG4E16V, AVLSSEG5E16V, AVLSSEG6E16V, AVLSSEG7E16V, AVLSSEG8E16V,
4697 AVLSSEG2E32V, AVLSSEG3E32V, AVLSSEG4E32V, AVLSSEG5E32V, AVLSSEG6E32V, AVLSSEG7E32V, AVLSSEG8E32V,
4698 AVLSSEG2E64V, AVLSSEG3E64V, AVLSSEG4E64V, AVLSSEG5E64V, AVLSSEG6E64V, AVLSSEG7E64V, AVLSSEG8E64V,
4699 AVLOXSEG2EI8V, AVLOXSEG3EI8V, AVLOXSEG4EI8V, AVLOXSEG5EI8V, AVLOXSEG6EI8V, AVLOXSEG7EI8V, AVLOXSEG8EI8V,
4700 AVLOXSEG2EI16V, AVLOXSEG3EI16V, AVLOXSEG4EI16V, AVLOXSEG5EI16V, AVLOXSEG6EI16V, AVLOXSEG7EI16V, AVLOXSEG8EI16V,
4701 AVLOXSEG2EI32V, AVLOXSEG3EI32V, AVLOXSEG4EI32V, AVLOXSEG5EI32V, AVLOXSEG6EI32V, AVLOXSEG7EI32V, AVLOXSEG8EI32V,
4702 AVLOXSEG2EI64V, AVLOXSEG3EI64V, AVLOXSEG4EI64V, AVLOXSEG5EI64V, AVLOXSEG6EI64V, AVLOXSEG7EI64V, AVLOXSEG8EI64V,
4703 AVLUXSEG2EI8V, AVLUXSEG3EI8V, AVLUXSEG4EI8V, AVLUXSEG5EI8V, AVLUXSEG6EI8V, AVLUXSEG7EI8V, AVLUXSEG8EI8V,
4704 AVLUXSEG2EI16V, AVLUXSEG3EI16V, AVLUXSEG4EI16V, AVLUXSEG5EI16V, AVLUXSEG6EI16V, AVLUXSEG7EI16V, AVLUXSEG8EI16V,
4705 AVLUXSEG2EI32V, AVLUXSEG3EI32V, AVLUXSEG4EI32V, AVLUXSEG5EI32V, AVLUXSEG6EI32V, AVLUXSEG7EI32V, AVLUXSEG8EI32V,
4706 AVLUXSEG2EI64V, AVLUXSEG3EI64V, AVLUXSEG4EI64V, AVLUXSEG5EI64V, AVLUXSEG6EI64V, AVLUXSEG7EI64V, AVLUXSEG8EI64V:
4707
4708 switch {
4709 case ins.rs3 == obj.REG_NONE:
4710 ins.funct7 |= 1
4711 case ins.rs3 != REG_V0:
4712 p.Ctxt.Diag("%v: invalid vector mask register", p)
4713 }
4714 ins.rs1, ins.rs2, ins.rs3 = ins.rs2, ins.rs1, obj.REG_NONE
4715
4716 case AVSSE8V, AVSSE16V, AVSSE32V, AVSSE64V,
4717 AVSUXEI8V, AVSUXEI16V, AVSUXEI32V, AVSUXEI64V, AVSOXEI8V, AVSOXEI16V, AVSOXEI32V, AVSOXEI64V,
4718 AVSSSEG2E8V, AVSSSEG3E8V, AVSSSEG4E8V, AVSSSEG5E8V, AVSSSEG6E8V, AVSSSEG7E8V, AVSSSEG8E8V,
4719 AVSSSEG2E16V, AVSSSEG3E16V, AVSSSEG4E16V, AVSSSEG5E16V, AVSSSEG6E16V, AVSSSEG7E16V, AVSSSEG8E16V,
4720 AVSSSEG2E32V, AVSSSEG3E32V, AVSSSEG4E32V, AVSSSEG5E32V, AVSSSEG6E32V, AVSSSEG7E32V, AVSSSEG8E32V,
4721 AVSSSEG2E64V, AVSSSEG3E64V, AVSSSEG4E64V, AVSSSEG5E64V, AVSSSEG6E64V, AVSSSEG7E64V, AVSSSEG8E64V,
4722 AVSOXSEG2EI8V, AVSOXSEG3EI8V, AVSOXSEG4EI8V, AVSOXSEG5EI8V, AVSOXSEG6EI8V, AVSOXSEG7EI8V, AVSOXSEG8EI8V,
4723 AVSOXSEG2EI16V, AVSOXSEG3EI16V, AVSOXSEG4EI16V, AVSOXSEG5EI16V, AVSOXSEG6EI16V, AVSOXSEG7EI16V, AVSOXSEG8EI16V,
4724 AVSOXSEG2EI32V, AVSOXSEG3EI32V, AVSOXSEG4EI32V, AVSOXSEG5EI32V, AVSOXSEG6EI32V, AVSOXSEG7EI32V, AVSOXSEG8EI32V,
4725 AVSOXSEG2EI64V, AVSOXSEG3EI64V, AVSOXSEG4EI64V, AVSOXSEG5EI64V, AVSOXSEG6EI64V, AVSOXSEG7EI64V, AVSOXSEG8EI64V,
4726 AVSUXSEG2EI8V, AVSUXSEG3EI8V, AVSUXSEG4EI8V, AVSUXSEG5EI8V, AVSUXSEG6EI8V, AVSUXSEG7EI8V, AVSUXSEG8EI8V,
4727 AVSUXSEG2EI16V, AVSUXSEG3EI16V, AVSUXSEG4EI16V, AVSUXSEG5EI16V, AVSUXSEG6EI16V, AVSUXSEG7EI16V, AVSUXSEG8EI16V,
4728 AVSUXSEG2EI32V, AVSUXSEG3EI32V, AVSUXSEG4EI32V, AVSUXSEG5EI32V, AVSUXSEG6EI32V, AVSUXSEG7EI32V, AVSUXSEG8EI32V,
4729 AVSUXSEG2EI64V, AVSUXSEG3EI64V, AVSUXSEG4EI64V, AVSUXSEG5EI64V, AVSUXSEG6EI64V, AVSUXSEG7EI64V, AVSUXSEG8EI64V:
4730
4731 switch {
4732 case ins.rs3 == obj.REG_NONE:
4733 ins.funct7 |= 1
4734 case ins.rs3 != REG_V0:
4735 p.Ctxt.Diag("%v: invalid vector mask register", p)
4736 }
4737 ins.rd, ins.rs1, ins.rs2, ins.rs3 = ins.rs2, ins.rd, ins.rs1, obj.REG_NONE
4738
4739 case AVL1RV, AVL1RE8V, AVL1RE16V, AVL1RE32V, AVL1RE64V, AVL2RV, AVL2RE8V, AVL2RE16V, AVL2RE32V, AVL2RE64V,
4740 AVL4RV, AVL4RE8V, AVL4RE16V, AVL4RE32V, AVL4RE64V, AVL8RV, AVL8RE8V, AVL8RE16V, AVL8RE32V, AVL8RE64V:
4741 switch ins.as {
4742 case AVL1RV:
4743 ins.as = AVL1RE8V
4744 case AVL2RV:
4745 ins.as = AVL2RE8V
4746 case AVL4RV:
4747 ins.as = AVL4RE8V
4748 case AVL8RV:
4749 ins.as = AVL8RE8V
4750 }
4751 if ins.rs1 != obj.REG_NONE {
4752 p.Ctxt.Diag("%v: too many operands for instruction", p)
4753 }
4754 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
4755
4756 case AVS1RV, AVS2RV, AVS4RV, AVS8RV:
4757 if ins.rs1 != obj.REG_NONE {
4758 p.Ctxt.Diag("%v: too many operands for instruction", p)
4759 }
4760 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
4761
4762 case AVADDVV, AVADDVX, AVSUBVV, AVSUBVX, AVRSUBVX, AVWADDUVV, AVWADDUVX, AVWSUBUVV, AVWSUBUVX,
4763 AVWADDVV, AVWADDVX, AVWSUBVV, AVWSUBVX, AVWADDUWV, AVWADDUWX, AVWSUBUWV, AVWSUBUWX,
4764 AVWADDWV, AVWADDWX, AVWSUBWV, AVWSUBWX, AVANDVV, AVANDVX, AVORVV, AVORVX, AVXORVV, AVXORVX,
4765 AVSLLVV, AVSLLVX, AVSRLVV, AVSRLVX, AVSRAVV, AVSRAVX,
4766 AVMSEQVV, AVMSEQVX, AVMSNEVV, AVMSNEVX, AVMSLTUVV, AVMSLTUVX, AVMSLTVV, AVMSLTVX,
4767 AVMSLEUVV, AVMSLEUVX, AVMSLEVV, AVMSLEVX, AVMSGTUVX, AVMSGTVX,
4768 AVMINUVV, AVMINUVX, AVMINVV, AVMINVX, AVMAXUVV, AVMAXUVX, AVMAXVV, AVMAXVX,
4769 AVMULVV, AVMULVX, AVMULHVV, AVMULHVX, AVMULHUVV, AVMULHUVX, AVMULHSUVV, AVMULHSUVX,
4770 AVDIVUVV, AVDIVUVX, AVDIVVV, AVDIVVX, AVREMUVV, AVREMUVX, AVREMVV, AVREMVX,
4771 AVWMULVV, AVWMULVX, AVWMULUVV, AVWMULUVX, AVWMULSUVV, AVWMULSUVX, AVNSRLWV, AVNSRLWX, AVNSRAWV, AVNSRAWX,
4772 AVSADDUVV, AVSADDUVX, AVSADDUVI, AVSADDVV, AVSADDVX, AVSADDVI, AVSSUBUVV, AVSSUBUVX, AVSSUBVV, AVSSUBVX,
4773 AVAADDUVV, AVAADDUVX, AVAADDVV, AVAADDVX, AVASUBUVV, AVASUBUVX, AVASUBVV, AVASUBVX,
4774 AVSMULVV, AVSMULVX, AVSSRLVV, AVSSRLVX, AVSSRLVI, AVSSRAVV, AVSSRAVX, AVSSRAVI,
4775 AVNCLIPUWV, AVNCLIPUWX, AVNCLIPUWI, AVNCLIPWV, AVNCLIPWX, AVNCLIPWI,
4776 AVFADDVV, AVFADDVF, AVFSUBVV, AVFSUBVF, AVFRSUBVF,
4777 AVFWADDVV, AVFWADDVF, AVFWSUBVV, AVFWSUBVF, AVFWADDWV, AVFWADDWF, AVFWSUBWV, AVFWSUBWF,
4778 AVFMULVV, AVFMULVF, AVFDIVVV, AVFDIVVF, AVFRDIVVF, AVFWMULVV, AVFWMULVF,
4779 AVFMINVV, AVFMINVF, AVFMAXVV, AVFMAXVF,
4780 AVFSGNJVV, AVFSGNJVF, AVFSGNJNVV, AVFSGNJNVF, AVFSGNJXVV, AVFSGNJXVF,
4781 AVMFEQVV, AVMFEQVF, AVMFNEVV, AVMFNEVF, AVMFLTVV, AVMFLTVF, AVMFLEVV, AVMFLEVF, AVMFGTVF, AVMFGEVF,
4782 AVREDSUMVS, AVREDMAXUVS, AVREDMAXVS, AVREDMINUVS, AVREDMINVS, AVREDANDVS, AVREDORVS, AVREDXORVS,
4783 AVWREDSUMUVS, AVWREDSUMVS, AVFREDOSUMVS, AVFREDUSUMVS, AVFREDMAXVS, AVFREDMINVS, AVFWREDOSUMVS, AVFWREDUSUMVS,
4784 AVSLIDEUPVX, AVSLIDEDOWNVX, AVSLIDE1UPVX, AVFSLIDE1UPVF, AVSLIDE1DOWNVX, AVFSLIDE1DOWNVF,
4785 AVRGATHERVV, AVRGATHEREI16VV, AVRGATHERVX,
4786 AVANDNVV, AVANDNVX, AVROLVV, AVROLVX, AVRORVV, AVRORVX,
4787 AVWSLLVV, AVWSLLVX, AVCLMULVV, AVCLMULVX, AVCLMULHVV, AVCLMULHVX:
4788
4789 switch {
4790 case ins.rs3 == obj.REG_NONE:
4791 ins.funct7 |= 1
4792 case ins.rs3 != REG_V0:
4793 p.Ctxt.Diag("%v: invalid vector mask register", p)
4794 }
4795 ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), obj.REG_NONE
4796
4797 case AVFMACCVV, AVFMACCVF, AVFNMACCVV, AVFNMACCVF, AVFMSACVV, AVFMSACVF, AVFNMSACVV, AVFNMSACVF,
4798 AVFMADDVV, AVFMADDVF, AVFNMADDVV, AVFNMADDVF, AVFMSUBVV, AVFMSUBVF, AVFNMSUBVV, AVFNMSUBVF,
4799 AVFWMACCVV, AVFWMACCVF, AVFWNMACCVV, AVFWNMACCVF, AVFWMSACVV, AVFWMSACVF, AVFWNMSACVV, AVFWNMSACVF,
4800 AVMACCVV, AVMACCVX, AVNMSACVV, AVNMSACVX, AVMADDVV, AVMADDVX, AVNMSUBVV, AVNMSUBVX,
4801 AVWMACCUVV, AVWMACCUVX, AVWMACCVV, AVWMACCVX, AVWMACCSUVV, AVWMACCSUVX, AVWMACCUSVX:
4802 switch {
4803 case ins.rs3 == obj.REG_NONE:
4804 ins.funct7 |= 1
4805 case ins.rs3 != REG_V0:
4806 p.Ctxt.Diag("%v: invalid vector mask register", p)
4807 }
4808 ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), obj.REG_NONE
4809
4810 case AVADDVI, AVRSUBVI, AVANDVI, AVORVI, AVXORVI, AVMSEQVI, AVMSNEVI, AVMSLEUVI, AVMSLEVI, AVMSGTUVI, AVMSGTVI,
4811 AVSLLVI, AVSRLVI, AVSRAVI, AVNSRLWI, AVNSRAWI, AVRGATHERVI, AVSLIDEUPVI, AVSLIDEDOWNVI,
4812 AVRORVI, AVWSLLVI:
4813
4814 switch {
4815 case ins.rs3 == obj.REG_NONE:
4816 ins.funct7 |= 1
4817 case ins.rs3 != REG_V0:
4818 p.Ctxt.Diag("%v: invalid vector mask register", p)
4819 }
4820 ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), obj.REG_NONE, uint32(p.Reg), obj.REG_NONE
4821
4822 case AVZEXTVF2, AVSEXTVF2, AVZEXTVF4, AVSEXTVF4, AVZEXTVF8, AVSEXTVF8,
4823 AVFSQRTV, AVFRSQRT7V, AVFREC7V, AVFCLASSV,
4824 AVFCVTXUFV, AVFCVTXFV, AVFCVTRTZXUFV, AVFCVTRTZXFV, AVFCVTFXUV, AVFCVTFXV,
4825 AVFWCVTXUFV, AVFWCVTXFV, AVFWCVTRTZXUFV, AVFWCVTRTZXFV, AVFWCVTFXUV, AVFWCVTFXV,
4826 AVFWCVTFFV, AVFNCVTXUFW, AVFNCVTXFW, AVFNCVTRTZXUFW, AVFNCVTRTZXFW, AVFNCVTFXUW,
4827 AVFNCVTFXW, AVFNCVTFFW, AVFNCVTRODFFW,
4828 AVBREVV, AVBREV8V, AVREV8V, AVCLZV, AVCTZV, AVCPOPV:
4829
4830 switch {
4831 case ins.rs1 == obj.REG_NONE:
4832 ins.funct7 |= 1
4833 case ins.rs1 != REG_V0:
4834 p.Ctxt.Diag("%v: invalid vector mask register", p)
4835 }
4836 ins.rs1 = obj.REG_NONE
4837
4838 case AVMVVV, AVMVVX:
4839 if ins.rs1 != obj.REG_NONE {
4840 p.Ctxt.Diag("%v: too many operands for instruction", p)
4841 }
4842 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), REG_V0
4843
4844 case AVMVVI:
4845 if ins.rs1 != obj.REG_NONE {
4846 p.Ctxt.Diag("%v: too many operands for instruction", p)
4847 }
4848 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), obj.REG_NONE, REG_V0
4849
4850 case AVFMVVF:
4851 ins.funct7 |= 1
4852 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), REG_V0
4853
4854 case AVADCVIM, AVADCVVM, AVADCVXM, AVSBCVVM, AVSBCVXM:
4855 if ins.rd == REG_V0 {
4856 p.Ctxt.Diag("%v: invalid destination register V0", p)
4857 }
4858 fallthrough
4859
4860 case AVMADCVVM, AVMADCVXM, AVMSBCVVM, AVMSBCVXM, AVMADCVIM, AVMERGEVVM, AVMERGEVXM, AVMERGEVIM, AVFMERGEVFM:
4861 if ins.rs3 != REG_V0 {
4862 p.Ctxt.Diag("%v: invalid vector mask register", p)
4863 }
4864 ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), obj.REG_NONE
4865
4866 case AVMADCVV, AVMADCVX, AVMSBCVV, AVMSBCVX, AVMADCVI:
4867 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)
4868
4869 case AVNEGV, AVWCVTXXV, AVWCVTUXXV, AVNCVTXXW:
4870
4871 switch {
4872 case ins.rs1 == obj.REG_NONE:
4873 ins.funct7 |= 1
4874 case ins.rs1 != REG_V0:
4875 p.Ctxt.Diag("%v: invalid vector mask register", p)
4876 }
4877 switch ins.as {
4878 case AVNEGV:
4879 ins.as = AVRSUBVX
4880 case AVWCVTXXV:
4881 ins.as = AVWADDVX
4882 case AVWCVTUXXV:
4883 ins.as = AVWADDUVX
4884 case AVNCVTXXW:
4885 ins.as = AVNSRLWX
4886 }
4887 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), REG_X0, uint32(p.From.Reg)
4888
4889 case AVNOTV:
4890
4891 switch {
4892 case ins.rs1 == obj.REG_NONE:
4893 ins.funct7 |= 1
4894 case ins.rs1 != REG_V0:
4895 p.Ctxt.Diag("%v: invalid vector mask register", p)
4896 }
4897 ins.as = AVXORVI
4898 ins.rd, ins.rs1, ins.rs2, ins.imm = uint32(p.To.Reg), obj.REG_NONE, uint32(p.From.Reg), -1
4899
4900 case AVMSGTVV, AVMSGTUVV, AVMSGEVV, AVMSGEUVV, AVMFGTVV, AVMFGEVV:
4901
4902 switch {
4903 case ins.rs3 == obj.REG_NONE:
4904 ins.funct7 |= 1
4905 case ins.rs3 != REG_V0:
4906 p.Ctxt.Diag("%v: invalid vector mask register", p)
4907 }
4908 switch ins.as {
4909 case AVMSGTVV:
4910 ins.as = AVMSLTVV
4911 case AVMSGTUVV:
4912 ins.as = AVMSLTUVV
4913 case AVMSGEVV:
4914 ins.as = AVMSLEVV
4915 case AVMSGEUVV:
4916 ins.as = AVMSLEUVV
4917 case AVMFGTVV:
4918 ins.as = AVMFLTVV
4919 case AVMFGEVV:
4920 ins.as = AVMFLEVV
4921 }
4922 ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), obj.REG_NONE
4923
4924 case AVMSLTVI, AVMSLTUVI, AVMSGEVI, AVMSGEUVI:
4925
4926 switch {
4927 case ins.rs3 == obj.REG_NONE:
4928 ins.funct7 |= 1
4929 case ins.rs3 != REG_V0:
4930 p.Ctxt.Diag("%v: invalid vector mask register", p)
4931 }
4932 switch ins.as {
4933 case AVMSLTVI:
4934 ins.as = AVMSLEVI
4935 case AVMSLTUVI:
4936 ins.as = AVMSLEUVI
4937 case AVMSGEVI:
4938 ins.as = AVMSGTVI
4939 case AVMSGEUVI:
4940 ins.as = AVMSGTUVI
4941 }
4942 ins.rd, ins.rs1, ins.rs2, ins.rs3, ins.imm = uint32(p.To.Reg), obj.REG_NONE, uint32(p.Reg), obj.REG_NONE, ins.imm-1
4943
4944 case AVFABSV, AVFNEGV:
4945
4946 switch {
4947 case ins.rs1 == obj.REG_NONE:
4948 ins.funct7 |= 1
4949 case ins.rs1 != REG_V0:
4950 p.Ctxt.Diag("%v: invalid vector mask register", p)
4951 }
4952 switch ins.as {
4953 case AVFABSV:
4954 ins.as = AVFSGNJXVV
4955 case AVFNEGV:
4956 ins.as = AVFSGNJNVV
4957 }
4958 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg)
4959
4960 case AVMANDMM, AVMNANDMM, AVMANDNMM, AVMXORMM, AVMORMM, AVMNORMM, AVMORNMM, AVMXNORMM, AVMMVM, AVMNOTM, AVCOMPRESSVM:
4961 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)
4962 switch ins.as {
4963 case AVMMVM:
4964 ins.as, ins.rs2 = AVMANDMM, ins.rs1
4965 case AVMNOTM:
4966 ins.as, ins.rs2 = AVMNANDMM, ins.rs1
4967 }
4968
4969 case AVMCLRM, AVMSETM:
4970 ins.rd, ins.rs1, ins.rs2 = uint32(p.From.Reg), uint32(p.From.Reg), uint32(p.From.Reg)
4971 switch ins.as {
4972 case AVMCLRM:
4973 ins.as = AVMXORMM
4974 case AVMSETM:
4975 ins.as = AVMXNORMM
4976 }
4977
4978 case AVCPOPM, AVFIRSTM, AVMSBFM, AVMSIFM, AVMSOFM, AVIOTAM:
4979
4980 switch {
4981 case ins.rs1 == obj.REG_NONE:
4982 ins.funct7 |= 1
4983 case ins.rs1 != REG_V0:
4984 p.Ctxt.Diag("%v: invalid vector mask register", p)
4985 }
4986 ins.rs1 = obj.REG_NONE
4987
4988 case AVIDV:
4989
4990 switch {
4991 case ins.rd == obj.REG_NONE:
4992 ins.funct7 |= 1
4993 case ins.rd != obj.REG_NONE && ins.rs2 != REG_V0:
4994 p.Ctxt.Diag("%v: invalid vector mask register", p)
4995 }
4996 if ins.rd == obj.REG_NONE {
4997 ins.rd = uint32(p.From.Reg)
4998 }
4999 ins.rs1, ins.rs2 = obj.REG_NONE, REG_V0
5000 }
5001
5002
5003
5004
5005 if compress && p.Mark&NEED_RELOC == 0 {
5006 for _, ins := range inss {
5007 ins.compress()
5008 }
5009 }
5010
5011 for _, ins := range inss {
5012 ins.p = p
5013 }
5014
5015 return inss
5016 }
5017
5018
5019
5020 func assemble(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
5021 if ctxt.Retpoline {
5022 ctxt.Diag("-spectre=ret not supported on riscv")
5023 ctxt.Retpoline = false
5024 }
5025
5026
5027
5028 if ctxt.Errors > 0 {
5029 return
5030 }
5031
5032 for p := cursym.Func().Text; p != nil; p = p.Link {
5033 switch p.As {
5034 case AJAL:
5035 if p.Mark&NEED_JAL_RELOC == NEED_JAL_RELOC {
5036 cursym.AddRel(ctxt, obj.Reloc{
5037 Type: objabi.R_RISCV_JAL,
5038 Off: int32(p.Pc),
5039 Siz: 4,
5040 Sym: p.To.Sym,
5041 Add: p.To.Offset,
5042 })
5043 }
5044
5045 case ACJALR, AJALR:
5046 if p.To.Sym != nil {
5047 ctxt.Diag("%v: unexpected AJALR with to symbol", p)
5048 }
5049
5050 case AAUIPC, AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD:
5051 var addr *obj.Addr
5052 var rt objabi.RelocType
5053 if p.Mark&NEED_CALL_RELOC == NEED_CALL_RELOC {
5054 rt = objabi.R_RISCV_CALL
5055 addr = &p.From
5056 } else if p.Mark&NEED_PCREL_ITYPE_RELOC == NEED_PCREL_ITYPE_RELOC {
5057 rt = objabi.R_RISCV_PCREL_ITYPE
5058 addr = &p.From
5059 } else if p.Mark&NEED_PCREL_STYPE_RELOC == NEED_PCREL_STYPE_RELOC {
5060 rt = objabi.R_RISCV_PCREL_STYPE
5061 addr = &p.To
5062 } else if p.Mark&NEED_GOT_PCREL_ITYPE_RELOC == NEED_GOT_PCREL_ITYPE_RELOC {
5063 rt = objabi.R_RISCV_GOT_PCREL_ITYPE
5064 addr = &p.From
5065 } else {
5066 break
5067 }
5068 if p.As == AAUIPC {
5069 if p.Link == nil {
5070 ctxt.Diag("AUIPC needing PC-relative reloc missing following instruction")
5071 break
5072 }
5073 addr = &p.RestArgs[0].Addr
5074 }
5075 if addr.Sym == nil {
5076 ctxt.Diag("PC-relative relocation missing symbol")
5077 break
5078 }
5079 if addr.Sym.Type == objabi.STLSBSS {
5080 if ctxt.Flag_shared {
5081 rt = objabi.R_RISCV_TLS_IE
5082 } else {
5083 rt = objabi.R_RISCV_TLS_LE
5084 }
5085 }
5086
5087 cursym.AddRel(ctxt, obj.Reloc{
5088 Type: rt,
5089 Off: int32(p.Pc),
5090 Siz: 8,
5091 Sym: addr.Sym,
5092 Add: addr.Offset,
5093 })
5094
5095 case obj.APCALIGN:
5096 alignedValue := p.From.Offset
5097 v := pcAlignPadLength(p.Pc, alignedValue)
5098 offset := p.Pc
5099 for ; v >= 4; v -= 4 {
5100
5101 cursym.WriteBytes(ctxt, offset, []byte{0x13, 0x00, 0x00, 0x00})
5102 offset += 4
5103 }
5104 if v == 2 {
5105
5106 cursym.WriteBytes(ctxt, offset, []byte{0x01, 0x00})
5107 offset += 2
5108 } else if v != 0 {
5109 ctxt.Diag("bad PCALIGN pad length")
5110 }
5111 continue
5112 }
5113
5114 offset := p.Pc
5115 for _, ins := range instructionsForProg(p, ctxt.CompressInstructions) {
5116 if ic, err := ins.encode(); err == nil {
5117 cursym.WriteInt(ctxt, offset, ins.length(), int64(ic))
5118 offset += int64(ins.length())
5119 }
5120 if ins.usesRegTmp() {
5121 p.Mark |= USES_REG_TMP
5122 }
5123 }
5124 }
5125
5126 obj.MarkUnsafePoints(ctxt, cursym.Func().Text, newprog, isUnsafePoint, nil)
5127 }
5128
5129 func isUnsafePoint(p *obj.Prog) bool {
5130 return p.Mark&USES_REG_TMP == USES_REG_TMP || p.From.Reg == REG_TMP || p.To.Reg == REG_TMP || p.Reg == REG_TMP
5131 }
5132
5133 func ParseSuffix(prog *obj.Prog, cond string) (err error) {
5134 cond = strings.TrimPrefix(cond, ".")
5135 switch prog.As {
5136 case AFCVTWS, AFCVTLS, AFCVTWUS, AFCVTLUS, AFCVTWD, AFCVTLD, AFCVTWUD, AFCVTLUD:
5137 prog.Scond, err = rmSuffixEncode(cond)
5138 case AFENCE:
5139 if cond == "TSO" {
5140 prog.Scond = fenceTsoSuffixBit
5141 } else {
5142 err = fmt.Errorf("unrecognized suffix .%q", cond)
5143 }
5144 default:
5145 if cond != "" {
5146 err = fmt.Errorf("unrecognized suffix .%q", cond)
5147 }
5148 }
5149 return
5150 }
5151
5152 var LinkRISCV64 = obj.LinkArch{
5153 Arch: sys.ArchRISCV64,
5154 Init: buildop,
5155 Preprocess: preprocess,
5156 Assemble: assemble,
5157 Progedit: progedit,
5158 UnaryDst: unaryDst,
5159 DWARFRegisters: RISCV64DWARFRegisters,
5160 }
5161
View as plain text