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
2643
2644 AROL & obj.AMask: {enc: rIIIEncoding, ternary: true},
2645 AROLW & obj.AMask: {enc: rIIIEncoding, ternary: true},
2646 AROR & obj.AMask: {enc: rIIIEncoding, immForm: ARORI, ternary: true},
2647 ARORI & obj.AMask: {enc: iIIEncoding, ternary: true},
2648 ARORIW & obj.AMask: {enc: iIIEncoding, ternary: true},
2649 ARORW & obj.AMask: {enc: rIIIEncoding, immForm: ARORIW, ternary: true},
2650 AORCB & obj.AMask: {enc: rIIEncoding},
2651 AREV8 & obj.AMask: {enc: rIIEncoding},
2652
2653
2654 ACLMUL & obj.AMask: {enc: rIIIEncoding, ternary: true},
2655 ACLMULH & obj.AMask: {enc: rIIIEncoding, ternary: true},
2656 ACLMULR & obj.AMask: {enc: rIIIEncoding, ternary: true},
2657
2658
2659 ABCLR & obj.AMask: {enc: rIIIEncoding, immForm: ABCLRI, ternary: true},
2660 ABCLRI & obj.AMask: {enc: iIIEncoding, ternary: true},
2661 ABEXT & obj.AMask: {enc: rIIIEncoding, immForm: ABEXTI, ternary: true},
2662 ABEXTI & obj.AMask: {enc: iIIEncoding, ternary: true},
2663 ABINV & obj.AMask: {enc: rIIIEncoding, immForm: ABINVI, ternary: true},
2664 ABINVI & obj.AMask: {enc: iIIEncoding, ternary: true},
2665 ABSET & obj.AMask: {enc: rIIIEncoding, immForm: ABSETI, ternary: true},
2666 ABSETI & obj.AMask: {enc: iIIEncoding, ternary: true},
2667
2668
2669
2670
2671
2672
2673 AVSETVLI & obj.AMask: {enc: vsetvliEncoding, immForm: AVSETIVLI},
2674 AVSETIVLI & obj.AMask: {enc: vsetivliEncoding},
2675 AVSETVL & obj.AMask: {enc: vsetvlEncoding},
2676
2677
2678 AVLE8V & obj.AMask: {enc: iVEncoding},
2679 AVLE16V & obj.AMask: {enc: iVEncoding},
2680 AVLE32V & obj.AMask: {enc: iVEncoding},
2681 AVLE64V & obj.AMask: {enc: iVEncoding},
2682 AVSE8V & obj.AMask: {enc: sVEncoding},
2683 AVSE16V & obj.AMask: {enc: sVEncoding},
2684 AVSE32V & obj.AMask: {enc: sVEncoding},
2685 AVSE64V & obj.AMask: {enc: sVEncoding},
2686 AVLMV & obj.AMask: {enc: iVEncoding},
2687 AVSMV & obj.AMask: {enc: sVEncoding},
2688
2689
2690 AVLSE8V & obj.AMask: {enc: iIIVEncoding},
2691 AVLSE16V & obj.AMask: {enc: iIIVEncoding},
2692 AVLSE32V & obj.AMask: {enc: iIIVEncoding},
2693 AVLSE64V & obj.AMask: {enc: iIIVEncoding},
2694 AVSSE8V & obj.AMask: {enc: sVIIEncoding},
2695 AVSSE16V & obj.AMask: {enc: sVIIEncoding},
2696 AVSSE32V & obj.AMask: {enc: sVIIEncoding},
2697 AVSSE64V & obj.AMask: {enc: sVIIEncoding},
2698
2699
2700 AVLUXEI8V & obj.AMask: {enc: iVIVEncoding},
2701 AVLUXEI16V & obj.AMask: {enc: iVIVEncoding},
2702 AVLUXEI32V & obj.AMask: {enc: iVIVEncoding},
2703 AVLUXEI64V & obj.AMask: {enc: iVIVEncoding},
2704 AVLOXEI8V & obj.AMask: {enc: iVIVEncoding},
2705 AVLOXEI16V & obj.AMask: {enc: iVIVEncoding},
2706 AVLOXEI32V & obj.AMask: {enc: iVIVEncoding},
2707 AVLOXEI64V & obj.AMask: {enc: iVIVEncoding},
2708 AVSUXEI8V & obj.AMask: {enc: sVIVEncoding},
2709 AVSUXEI16V & obj.AMask: {enc: sVIVEncoding},
2710 AVSUXEI32V & obj.AMask: {enc: sVIVEncoding},
2711 AVSUXEI64V & obj.AMask: {enc: sVIVEncoding},
2712 AVSOXEI8V & obj.AMask: {enc: sVIVEncoding},
2713 AVSOXEI16V & obj.AMask: {enc: sVIVEncoding},
2714 AVSOXEI32V & obj.AMask: {enc: sVIVEncoding},
2715 AVSOXEI64V & obj.AMask: {enc: sVIVEncoding},
2716
2717
2718 AVLE8FFV & obj.AMask: {enc: iVEncoding},
2719 AVLE16FFV & obj.AMask: {enc: iVEncoding},
2720 AVLE32FFV & obj.AMask: {enc: iVEncoding},
2721 AVLE64FFV & obj.AMask: {enc: iVEncoding},
2722
2723
2724 AVLSEG2E8V & obj.AMask: {enc: iVEncoding},
2725 AVLSEG3E8V & obj.AMask: {enc: iVEncoding},
2726 AVLSEG4E8V & obj.AMask: {enc: iVEncoding},
2727 AVLSEG5E8V & obj.AMask: {enc: iVEncoding},
2728 AVLSEG6E8V & obj.AMask: {enc: iVEncoding},
2729 AVLSEG7E8V & obj.AMask: {enc: iVEncoding},
2730 AVLSEG8E8V & obj.AMask: {enc: iVEncoding},
2731 AVLSEG2E16V & obj.AMask: {enc: iVEncoding},
2732 AVLSEG3E16V & obj.AMask: {enc: iVEncoding},
2733 AVLSEG4E16V & obj.AMask: {enc: iVEncoding},
2734 AVLSEG5E16V & obj.AMask: {enc: iVEncoding},
2735 AVLSEG6E16V & obj.AMask: {enc: iVEncoding},
2736 AVLSEG7E16V & obj.AMask: {enc: iVEncoding},
2737 AVLSEG8E16V & obj.AMask: {enc: iVEncoding},
2738 AVLSEG2E32V & obj.AMask: {enc: iVEncoding},
2739 AVLSEG3E32V & obj.AMask: {enc: iVEncoding},
2740 AVLSEG4E32V & obj.AMask: {enc: iVEncoding},
2741 AVLSEG5E32V & obj.AMask: {enc: iVEncoding},
2742 AVLSEG6E32V & obj.AMask: {enc: iVEncoding},
2743 AVLSEG7E32V & obj.AMask: {enc: iVEncoding},
2744 AVLSEG8E32V & obj.AMask: {enc: iVEncoding},
2745 AVLSEG2E64V & obj.AMask: {enc: iVEncoding},
2746 AVLSEG3E64V & obj.AMask: {enc: iVEncoding},
2747 AVLSEG4E64V & obj.AMask: {enc: iVEncoding},
2748 AVLSEG5E64V & obj.AMask: {enc: iVEncoding},
2749 AVLSEG6E64V & obj.AMask: {enc: iVEncoding},
2750 AVLSEG7E64V & obj.AMask: {enc: iVEncoding},
2751 AVLSEG8E64V & obj.AMask: {enc: iVEncoding},
2752 AVSSEG2E8V & obj.AMask: {enc: sVEncoding},
2753 AVSSEG3E8V & obj.AMask: {enc: sVEncoding},
2754 AVSSEG4E8V & obj.AMask: {enc: sVEncoding},
2755 AVSSEG5E8V & obj.AMask: {enc: sVEncoding},
2756 AVSSEG6E8V & obj.AMask: {enc: sVEncoding},
2757 AVSSEG7E8V & obj.AMask: {enc: sVEncoding},
2758 AVSSEG8E8V & obj.AMask: {enc: sVEncoding},
2759 AVSSEG2E16V & obj.AMask: {enc: sVEncoding},
2760 AVSSEG3E16V & obj.AMask: {enc: sVEncoding},
2761 AVSSEG4E16V & obj.AMask: {enc: sVEncoding},
2762 AVSSEG5E16V & obj.AMask: {enc: sVEncoding},
2763 AVSSEG6E16V & obj.AMask: {enc: sVEncoding},
2764 AVSSEG7E16V & obj.AMask: {enc: sVEncoding},
2765 AVSSEG8E16V & obj.AMask: {enc: sVEncoding},
2766 AVSSEG2E32V & obj.AMask: {enc: sVEncoding},
2767 AVSSEG3E32V & obj.AMask: {enc: sVEncoding},
2768 AVSSEG4E32V & obj.AMask: {enc: sVEncoding},
2769 AVSSEG5E32V & obj.AMask: {enc: sVEncoding},
2770 AVSSEG6E32V & obj.AMask: {enc: sVEncoding},
2771 AVSSEG7E32V & obj.AMask: {enc: sVEncoding},
2772 AVSSEG8E32V & obj.AMask: {enc: sVEncoding},
2773 AVSSEG2E64V & obj.AMask: {enc: sVEncoding},
2774 AVSSEG3E64V & obj.AMask: {enc: sVEncoding},
2775 AVSSEG4E64V & obj.AMask: {enc: sVEncoding},
2776 AVSSEG5E64V & obj.AMask: {enc: sVEncoding},
2777 AVSSEG6E64V & obj.AMask: {enc: sVEncoding},
2778 AVSSEG7E64V & obj.AMask: {enc: sVEncoding},
2779 AVSSEG8E64V & obj.AMask: {enc: sVEncoding},
2780 AVLSEG2E8FFV & obj.AMask: {enc: iVEncoding},
2781 AVLSEG3E8FFV & obj.AMask: {enc: iVEncoding},
2782 AVLSEG4E8FFV & obj.AMask: {enc: iVEncoding},
2783 AVLSEG5E8FFV & obj.AMask: {enc: iVEncoding},
2784 AVLSEG6E8FFV & obj.AMask: {enc: iVEncoding},
2785 AVLSEG7E8FFV & obj.AMask: {enc: iVEncoding},
2786 AVLSEG8E8FFV & obj.AMask: {enc: iVEncoding},
2787 AVLSEG2E16FFV & obj.AMask: {enc: iVEncoding},
2788 AVLSEG3E16FFV & obj.AMask: {enc: iVEncoding},
2789 AVLSEG4E16FFV & obj.AMask: {enc: iVEncoding},
2790 AVLSEG5E16FFV & obj.AMask: {enc: iVEncoding},
2791 AVLSEG6E16FFV & obj.AMask: {enc: iVEncoding},
2792 AVLSEG7E16FFV & obj.AMask: {enc: iVEncoding},
2793 AVLSEG8E16FFV & obj.AMask: {enc: iVEncoding},
2794 AVLSEG2E32FFV & obj.AMask: {enc: iVEncoding},
2795 AVLSEG3E32FFV & obj.AMask: {enc: iVEncoding},
2796 AVLSEG4E32FFV & obj.AMask: {enc: iVEncoding},
2797 AVLSEG5E32FFV & obj.AMask: {enc: iVEncoding},
2798 AVLSEG6E32FFV & obj.AMask: {enc: iVEncoding},
2799 AVLSEG7E32FFV & obj.AMask: {enc: iVEncoding},
2800 AVLSEG8E32FFV & obj.AMask: {enc: iVEncoding},
2801 AVLSEG2E64FFV & obj.AMask: {enc: iVEncoding},
2802 AVLSEG3E64FFV & obj.AMask: {enc: iVEncoding},
2803 AVLSEG4E64FFV & obj.AMask: {enc: iVEncoding},
2804 AVLSEG5E64FFV & obj.AMask: {enc: iVEncoding},
2805 AVLSEG6E64FFV & obj.AMask: {enc: iVEncoding},
2806 AVLSEG7E64FFV & obj.AMask: {enc: iVEncoding},
2807 AVLSEG8E64FFV & obj.AMask: {enc: iVEncoding},
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 AVLOXSEG2EI8V & obj.AMask: {enc: iVIVEncoding},
2865 AVLOXSEG3EI8V & obj.AMask: {enc: iVIVEncoding},
2866 AVLOXSEG4EI8V & obj.AMask: {enc: iVIVEncoding},
2867 AVLOXSEG5EI8V & obj.AMask: {enc: iVIVEncoding},
2868 AVLOXSEG6EI8V & obj.AMask: {enc: iVIVEncoding},
2869 AVLOXSEG7EI8V & obj.AMask: {enc: iVIVEncoding},
2870 AVLOXSEG8EI8V & obj.AMask: {enc: iVIVEncoding},
2871 AVLOXSEG2EI16V & obj.AMask: {enc: iVIVEncoding},
2872 AVLOXSEG3EI16V & obj.AMask: {enc: iVIVEncoding},
2873 AVLOXSEG4EI16V & obj.AMask: {enc: iVIVEncoding},
2874 AVLOXSEG5EI16V & obj.AMask: {enc: iVIVEncoding},
2875 AVLOXSEG6EI16V & obj.AMask: {enc: iVIVEncoding},
2876 AVLOXSEG7EI16V & obj.AMask: {enc: iVIVEncoding},
2877 AVLOXSEG8EI16V & obj.AMask: {enc: iVIVEncoding},
2878 AVLOXSEG2EI32V & obj.AMask: {enc: iVIVEncoding},
2879 AVLOXSEG3EI32V & obj.AMask: {enc: iVIVEncoding},
2880 AVLOXSEG4EI32V & obj.AMask: {enc: iVIVEncoding},
2881 AVLOXSEG5EI32V & obj.AMask: {enc: iVIVEncoding},
2882 AVLOXSEG6EI32V & obj.AMask: {enc: iVIVEncoding},
2883 AVLOXSEG7EI32V & obj.AMask: {enc: iVIVEncoding},
2884 AVLOXSEG8EI32V & obj.AMask: {enc: iVIVEncoding},
2885 AVLOXSEG2EI64V & obj.AMask: {enc: iVIVEncoding},
2886 AVLOXSEG3EI64V & obj.AMask: {enc: iVIVEncoding},
2887 AVLOXSEG4EI64V & obj.AMask: {enc: iVIVEncoding},
2888 AVLOXSEG5EI64V & obj.AMask: {enc: iVIVEncoding},
2889 AVLOXSEG6EI64V & obj.AMask: {enc: iVIVEncoding},
2890 AVLOXSEG7EI64V & obj.AMask: {enc: iVIVEncoding},
2891 AVLOXSEG8EI64V & obj.AMask: {enc: iVIVEncoding},
2892 AVSOXSEG2EI8V & obj.AMask: {enc: sVIVEncoding},
2893 AVSOXSEG3EI8V & obj.AMask: {enc: sVIVEncoding},
2894 AVSOXSEG4EI8V & obj.AMask: {enc: sVIVEncoding},
2895 AVSOXSEG5EI8V & obj.AMask: {enc: sVIVEncoding},
2896 AVSOXSEG6EI8V & obj.AMask: {enc: sVIVEncoding},
2897 AVSOXSEG7EI8V & obj.AMask: {enc: sVIVEncoding},
2898 AVSOXSEG8EI8V & obj.AMask: {enc: sVIVEncoding},
2899 AVSOXSEG2EI16V & obj.AMask: {enc: sVIVEncoding},
2900 AVSOXSEG3EI16V & obj.AMask: {enc: sVIVEncoding},
2901 AVSOXSEG4EI16V & obj.AMask: {enc: sVIVEncoding},
2902 AVSOXSEG5EI16V & obj.AMask: {enc: sVIVEncoding},
2903 AVSOXSEG6EI16V & obj.AMask: {enc: sVIVEncoding},
2904 AVSOXSEG7EI16V & obj.AMask: {enc: sVIVEncoding},
2905 AVSOXSEG8EI16V & obj.AMask: {enc: sVIVEncoding},
2906 AVSOXSEG2EI32V & obj.AMask: {enc: sVIVEncoding},
2907 AVSOXSEG3EI32V & obj.AMask: {enc: sVIVEncoding},
2908 AVSOXSEG4EI32V & obj.AMask: {enc: sVIVEncoding},
2909 AVSOXSEG5EI32V & obj.AMask: {enc: sVIVEncoding},
2910 AVSOXSEG6EI32V & obj.AMask: {enc: sVIVEncoding},
2911 AVSOXSEG7EI32V & obj.AMask: {enc: sVIVEncoding},
2912 AVSOXSEG8EI32V & obj.AMask: {enc: sVIVEncoding},
2913 AVSOXSEG2EI64V & obj.AMask: {enc: sVIVEncoding},
2914 AVSOXSEG3EI64V & obj.AMask: {enc: sVIVEncoding},
2915 AVSOXSEG4EI64V & obj.AMask: {enc: sVIVEncoding},
2916 AVSOXSEG5EI64V & obj.AMask: {enc: sVIVEncoding},
2917 AVSOXSEG6EI64V & obj.AMask: {enc: sVIVEncoding},
2918 AVSOXSEG7EI64V & obj.AMask: {enc: sVIVEncoding},
2919 AVSOXSEG8EI64V & obj.AMask: {enc: sVIVEncoding},
2920 AVLUXSEG2EI8V & obj.AMask: {enc: iVIVEncoding},
2921 AVLUXSEG3EI8V & obj.AMask: {enc: iVIVEncoding},
2922 AVLUXSEG4EI8V & obj.AMask: {enc: iVIVEncoding},
2923 AVLUXSEG5EI8V & obj.AMask: {enc: iVIVEncoding},
2924 AVLUXSEG6EI8V & obj.AMask: {enc: iVIVEncoding},
2925 AVLUXSEG7EI8V & obj.AMask: {enc: iVIVEncoding},
2926 AVLUXSEG8EI8V & obj.AMask: {enc: iVIVEncoding},
2927 AVLUXSEG2EI16V & obj.AMask: {enc: iVIVEncoding},
2928 AVLUXSEG3EI16V & obj.AMask: {enc: iVIVEncoding},
2929 AVLUXSEG4EI16V & obj.AMask: {enc: iVIVEncoding},
2930 AVLUXSEG5EI16V & obj.AMask: {enc: iVIVEncoding},
2931 AVLUXSEG6EI16V & obj.AMask: {enc: iVIVEncoding},
2932 AVLUXSEG7EI16V & obj.AMask: {enc: iVIVEncoding},
2933 AVLUXSEG8EI16V & obj.AMask: {enc: iVIVEncoding},
2934 AVLUXSEG2EI32V & obj.AMask: {enc: iVIVEncoding},
2935 AVLUXSEG3EI32V & obj.AMask: {enc: iVIVEncoding},
2936 AVLUXSEG4EI32V & obj.AMask: {enc: iVIVEncoding},
2937 AVLUXSEG5EI32V & obj.AMask: {enc: iVIVEncoding},
2938 AVLUXSEG6EI32V & obj.AMask: {enc: iVIVEncoding},
2939 AVLUXSEG7EI32V & obj.AMask: {enc: iVIVEncoding},
2940 AVLUXSEG8EI32V & obj.AMask: {enc: iVIVEncoding},
2941 AVLUXSEG2EI64V & obj.AMask: {enc: iVIVEncoding},
2942 AVLUXSEG3EI64V & obj.AMask: {enc: iVIVEncoding},
2943 AVLUXSEG4EI64V & obj.AMask: {enc: iVIVEncoding},
2944 AVLUXSEG5EI64V & obj.AMask: {enc: iVIVEncoding},
2945 AVLUXSEG6EI64V & obj.AMask: {enc: iVIVEncoding},
2946 AVLUXSEG7EI64V & obj.AMask: {enc: iVIVEncoding},
2947 AVLUXSEG8EI64V & obj.AMask: {enc: iVIVEncoding},
2948 AVSUXSEG2EI8V & obj.AMask: {enc: sVIVEncoding},
2949 AVSUXSEG3EI8V & obj.AMask: {enc: sVIVEncoding},
2950 AVSUXSEG4EI8V & obj.AMask: {enc: sVIVEncoding},
2951 AVSUXSEG5EI8V & obj.AMask: {enc: sVIVEncoding},
2952 AVSUXSEG6EI8V & obj.AMask: {enc: sVIVEncoding},
2953 AVSUXSEG7EI8V & obj.AMask: {enc: sVIVEncoding},
2954 AVSUXSEG8EI8V & obj.AMask: {enc: sVIVEncoding},
2955 AVSUXSEG2EI16V & obj.AMask: {enc: sVIVEncoding},
2956 AVSUXSEG3EI16V & obj.AMask: {enc: sVIVEncoding},
2957 AVSUXSEG4EI16V & obj.AMask: {enc: sVIVEncoding},
2958 AVSUXSEG5EI16V & obj.AMask: {enc: sVIVEncoding},
2959 AVSUXSEG6EI16V & obj.AMask: {enc: sVIVEncoding},
2960 AVSUXSEG7EI16V & obj.AMask: {enc: sVIVEncoding},
2961 AVSUXSEG8EI16V & obj.AMask: {enc: sVIVEncoding},
2962 AVSUXSEG2EI32V & obj.AMask: {enc: sVIVEncoding},
2963 AVSUXSEG3EI32V & obj.AMask: {enc: sVIVEncoding},
2964 AVSUXSEG4EI32V & obj.AMask: {enc: sVIVEncoding},
2965 AVSUXSEG5EI32V & obj.AMask: {enc: sVIVEncoding},
2966 AVSUXSEG6EI32V & obj.AMask: {enc: sVIVEncoding},
2967 AVSUXSEG7EI32V & obj.AMask: {enc: sVIVEncoding},
2968 AVSUXSEG8EI32V & obj.AMask: {enc: sVIVEncoding},
2969 AVSUXSEG2EI64V & obj.AMask: {enc: sVIVEncoding},
2970 AVSUXSEG3EI64V & obj.AMask: {enc: sVIVEncoding},
2971 AVSUXSEG4EI64V & obj.AMask: {enc: sVIVEncoding},
2972 AVSUXSEG5EI64V & obj.AMask: {enc: sVIVEncoding},
2973 AVSUXSEG6EI64V & obj.AMask: {enc: sVIVEncoding},
2974 AVSUXSEG7EI64V & obj.AMask: {enc: sVIVEncoding},
2975 AVSUXSEG8EI64V & obj.AMask: {enc: sVIVEncoding},
2976
2977
2978 AVL1RE8V & obj.AMask: {enc: iVEncoding},
2979 AVL1RE16V & obj.AMask: {enc: iVEncoding},
2980 AVL1RE32V & obj.AMask: {enc: iVEncoding},
2981 AVL1RE64V & obj.AMask: {enc: iVEncoding},
2982 AVL2RE8V & obj.AMask: {enc: iVEncoding},
2983 AVL2RE16V & obj.AMask: {enc: iVEncoding},
2984 AVL2RE32V & obj.AMask: {enc: iVEncoding},
2985 AVL2RE64V & obj.AMask: {enc: iVEncoding},
2986 AVL4RE8V & obj.AMask: {enc: iVEncoding},
2987 AVL4RE16V & obj.AMask: {enc: iVEncoding},
2988 AVL4RE32V & obj.AMask: {enc: iVEncoding},
2989 AVL4RE64V & obj.AMask: {enc: iVEncoding},
2990 AVL8RE8V & obj.AMask: {enc: iVEncoding},
2991 AVL8RE16V & obj.AMask: {enc: iVEncoding},
2992 AVL8RE32V & obj.AMask: {enc: iVEncoding},
2993 AVL8RE64V & obj.AMask: {enc: iVEncoding},
2994 AVS1RV & obj.AMask: {enc: sVEncoding},
2995 AVS2RV & obj.AMask: {enc: sVEncoding},
2996 AVS4RV & obj.AMask: {enc: sVEncoding},
2997 AVS8RV & obj.AMask: {enc: sVEncoding},
2998
2999
3000 AVADDVV & obj.AMask: {enc: rVVVEncoding},
3001 AVADDVX & obj.AMask: {enc: rVIVEncoding},
3002 AVADDVI & obj.AMask: {enc: rVViEncoding},
3003 AVSUBVV & obj.AMask: {enc: rVVVEncoding},
3004 AVSUBVX & obj.AMask: {enc: rVIVEncoding},
3005 AVRSUBVX & obj.AMask: {enc: rVIVEncoding},
3006 AVRSUBVI & obj.AMask: {enc: rVViEncoding},
3007
3008
3009 AVWADDUVV & obj.AMask: {enc: rVVVEncoding},
3010 AVWADDUVX & obj.AMask: {enc: rVIVEncoding},
3011 AVWSUBUVV & obj.AMask: {enc: rVVVEncoding},
3012 AVWSUBUVX & obj.AMask: {enc: rVIVEncoding},
3013 AVWADDVV & obj.AMask: {enc: rVVVEncoding},
3014 AVWADDVX & obj.AMask: {enc: rVIVEncoding},
3015 AVWSUBVV & obj.AMask: {enc: rVVVEncoding},
3016 AVWSUBVX & obj.AMask: {enc: rVIVEncoding},
3017 AVWADDUWV & obj.AMask: {enc: rVVVEncoding},
3018 AVWADDUWX & obj.AMask: {enc: rVIVEncoding},
3019 AVWSUBUWV & obj.AMask: {enc: rVVVEncoding},
3020 AVWSUBUWX & obj.AMask: {enc: rVIVEncoding},
3021 AVWADDWV & obj.AMask: {enc: rVVVEncoding},
3022 AVWADDWX & obj.AMask: {enc: rVIVEncoding},
3023 AVWSUBWV & obj.AMask: {enc: rVVVEncoding},
3024 AVWSUBWX & obj.AMask: {enc: rVIVEncoding},
3025
3026
3027 AVZEXTVF2 & obj.AMask: {enc: rVVEncoding},
3028 AVSEXTVF2 & obj.AMask: {enc: rVVEncoding},
3029 AVZEXTVF4 & obj.AMask: {enc: rVVEncoding},
3030 AVSEXTVF4 & obj.AMask: {enc: rVVEncoding},
3031 AVZEXTVF8 & obj.AMask: {enc: rVVEncoding},
3032 AVSEXTVF8 & obj.AMask: {enc: rVVEncoding},
3033
3034
3035 AVADCVVM & obj.AMask: {enc: rVVVEncoding},
3036 AVADCVXM & obj.AMask: {enc: rVIVEncoding},
3037 AVADCVIM & obj.AMask: {enc: rVViEncoding},
3038 AVMADCVVM & obj.AMask: {enc: rVVVEncoding},
3039 AVMADCVXM & obj.AMask: {enc: rVIVEncoding},
3040 AVMADCVIM & obj.AMask: {enc: rVViEncoding},
3041 AVMADCVV & obj.AMask: {enc: rVVVEncoding},
3042 AVMADCVX & obj.AMask: {enc: rVIVEncoding},
3043 AVMADCVI & obj.AMask: {enc: rVViEncoding},
3044 AVSBCVVM & obj.AMask: {enc: rVVVEncoding},
3045 AVSBCVXM & obj.AMask: {enc: rVIVEncoding},
3046 AVMSBCVVM & obj.AMask: {enc: rVVVEncoding},
3047 AVMSBCVXM & obj.AMask: {enc: rVIVEncoding},
3048 AVMSBCVV & obj.AMask: {enc: rVVVEncoding},
3049 AVMSBCVX & obj.AMask: {enc: rVIVEncoding},
3050
3051
3052 AVANDVV & obj.AMask: {enc: rVVVEncoding},
3053 AVANDVX & obj.AMask: {enc: rVIVEncoding},
3054 AVANDVI & obj.AMask: {enc: rVViEncoding},
3055 AVORVV & obj.AMask: {enc: rVVVEncoding},
3056 AVORVX & obj.AMask: {enc: rVIVEncoding},
3057 AVORVI & obj.AMask: {enc: rVViEncoding},
3058 AVXORVV & obj.AMask: {enc: rVVVEncoding},
3059 AVXORVX & obj.AMask: {enc: rVIVEncoding},
3060 AVXORVI & obj.AMask: {enc: rVViEncoding},
3061
3062
3063 AVSLLVV & obj.AMask: {enc: rVVVEncoding},
3064 AVSLLVX & obj.AMask: {enc: rVIVEncoding},
3065 AVSLLVI & obj.AMask: {enc: rVVuEncoding},
3066 AVSRLVV & obj.AMask: {enc: rVVVEncoding},
3067 AVSRLVX & obj.AMask: {enc: rVIVEncoding},
3068 AVSRLVI & obj.AMask: {enc: rVVuEncoding},
3069 AVSRAVV & obj.AMask: {enc: rVVVEncoding},
3070 AVSRAVX & obj.AMask: {enc: rVIVEncoding},
3071 AVSRAVI & obj.AMask: {enc: rVVuEncoding},
3072
3073
3074 AVNSRLWV & obj.AMask: {enc: rVVVEncoding},
3075 AVNSRLWX & obj.AMask: {enc: rVIVEncoding},
3076 AVNSRLWI & obj.AMask: {enc: rVVuEncoding},
3077 AVNSRAWV & obj.AMask: {enc: rVVVEncoding},
3078 AVNSRAWX & obj.AMask: {enc: rVIVEncoding},
3079 AVNSRAWI & obj.AMask: {enc: rVVuEncoding},
3080
3081
3082 AVMSEQVV & obj.AMask: {enc: rVVVEncoding},
3083 AVMSEQVX & obj.AMask: {enc: rVIVEncoding},
3084 AVMSEQVI & obj.AMask: {enc: rVViEncoding},
3085 AVMSNEVV & obj.AMask: {enc: rVVVEncoding},
3086 AVMSNEVX & obj.AMask: {enc: rVIVEncoding},
3087 AVMSNEVI & obj.AMask: {enc: rVViEncoding},
3088 AVMSLTUVV & obj.AMask: {enc: rVVVEncoding},
3089 AVMSLTUVX & obj.AMask: {enc: rVIVEncoding},
3090 AVMSLTVV & obj.AMask: {enc: rVVVEncoding},
3091 AVMSLTVX & obj.AMask: {enc: rVIVEncoding},
3092 AVMSLEUVV & obj.AMask: {enc: rVVVEncoding},
3093 AVMSLEUVX & obj.AMask: {enc: rVIVEncoding},
3094 AVMSLEUVI & obj.AMask: {enc: rVViEncoding},
3095 AVMSLEVV & obj.AMask: {enc: rVVVEncoding},
3096 AVMSLEVX & obj.AMask: {enc: rVIVEncoding},
3097 AVMSLEVI & obj.AMask: {enc: rVViEncoding},
3098 AVMSGTUVX & obj.AMask: {enc: rVIVEncoding},
3099 AVMSGTUVI & obj.AMask: {enc: rVViEncoding},
3100 AVMSGTVX & obj.AMask: {enc: rVIVEncoding},
3101 AVMSGTVI & obj.AMask: {enc: rVViEncoding},
3102
3103
3104 AVMINUVV & obj.AMask: {enc: rVVVEncoding},
3105 AVMINUVX & obj.AMask: {enc: rVIVEncoding},
3106 AVMINVV & obj.AMask: {enc: rVVVEncoding},
3107 AVMINVX & obj.AMask: {enc: rVIVEncoding},
3108 AVMAXUVV & obj.AMask: {enc: rVVVEncoding},
3109 AVMAXUVX & obj.AMask: {enc: rVIVEncoding},
3110 AVMAXVV & obj.AMask: {enc: rVVVEncoding},
3111 AVMAXVX & obj.AMask: {enc: rVIVEncoding},
3112
3113
3114 AVMULVV & obj.AMask: {enc: rVVVEncoding},
3115 AVMULVX & obj.AMask: {enc: rVIVEncoding},
3116 AVMULHVV & obj.AMask: {enc: rVVVEncoding},
3117 AVMULHVX & obj.AMask: {enc: rVIVEncoding},
3118 AVMULHUVV & obj.AMask: {enc: rVVVEncoding},
3119 AVMULHUVX & obj.AMask: {enc: rVIVEncoding},
3120 AVMULHSUVV & obj.AMask: {enc: rVVVEncoding},
3121 AVMULHSUVX & obj.AMask: {enc: rVIVEncoding},
3122
3123
3124 AVDIVUVV & obj.AMask: {enc: rVVVEncoding},
3125 AVDIVUVX & obj.AMask: {enc: rVIVEncoding},
3126 AVDIVVV & obj.AMask: {enc: rVVVEncoding},
3127 AVDIVVX & obj.AMask: {enc: rVIVEncoding},
3128 AVREMUVV & obj.AMask: {enc: rVVVEncoding},
3129 AVREMUVX & obj.AMask: {enc: rVIVEncoding},
3130 AVREMVV & obj.AMask: {enc: rVVVEncoding},
3131 AVREMVX & obj.AMask: {enc: rVIVEncoding},
3132
3133
3134 AVWMULVV & obj.AMask: {enc: rVVVEncoding},
3135 AVWMULVX & obj.AMask: {enc: rVIVEncoding},
3136 AVWMULUVV & obj.AMask: {enc: rVVVEncoding},
3137 AVWMULUVX & obj.AMask: {enc: rVIVEncoding},
3138 AVWMULSUVV & obj.AMask: {enc: rVVVEncoding},
3139 AVWMULSUVX & obj.AMask: {enc: rVIVEncoding},
3140
3141
3142 AVMACCVV & obj.AMask: {enc: rVVVEncoding},
3143 AVMACCVX & obj.AMask: {enc: rVIVEncoding},
3144 AVNMSACVV & obj.AMask: {enc: rVVVEncoding},
3145 AVNMSACVX & obj.AMask: {enc: rVIVEncoding},
3146 AVMADDVV & obj.AMask: {enc: rVVVEncoding},
3147 AVMADDVX & obj.AMask: {enc: rVIVEncoding},
3148 AVNMSUBVV & obj.AMask: {enc: rVVVEncoding},
3149 AVNMSUBVX & obj.AMask: {enc: rVIVEncoding},
3150
3151
3152 AVWMACCUVV & obj.AMask: {enc: rVVVEncoding},
3153 AVWMACCUVX & obj.AMask: {enc: rVIVEncoding},
3154 AVWMACCVV & obj.AMask: {enc: rVVVEncoding},
3155 AVWMACCVX & obj.AMask: {enc: rVIVEncoding},
3156 AVWMACCSUVV & obj.AMask: {enc: rVVVEncoding},
3157 AVWMACCSUVX & obj.AMask: {enc: rVIVEncoding},
3158 AVWMACCUSVX & obj.AMask: {enc: rVIVEncoding},
3159
3160
3161 AVMERGEVVM & obj.AMask: {enc: rVVVEncoding},
3162 AVMERGEVXM & obj.AMask: {enc: rVIVEncoding},
3163 AVMERGEVIM & obj.AMask: {enc: rVViEncoding},
3164
3165
3166 AVMVVV & obj.AMask: {enc: rVVVEncoding},
3167 AVMVVX & obj.AMask: {enc: rVIVEncoding},
3168 AVMVVI & obj.AMask: {enc: rVViEncoding},
3169
3170
3171 AVSADDUVV & obj.AMask: {enc: rVVVEncoding},
3172 AVSADDUVX & obj.AMask: {enc: rVIVEncoding},
3173 AVSADDUVI & obj.AMask: {enc: rVViEncoding},
3174 AVSADDVV & obj.AMask: {enc: rVVVEncoding},
3175 AVSADDVX & obj.AMask: {enc: rVIVEncoding},
3176 AVSADDVI & obj.AMask: {enc: rVViEncoding},
3177 AVSSUBUVV & obj.AMask: {enc: rVVVEncoding},
3178 AVSSUBUVX & obj.AMask: {enc: rVIVEncoding},
3179 AVSSUBVV & obj.AMask: {enc: rVVVEncoding},
3180 AVSSUBVX & obj.AMask: {enc: rVIVEncoding},
3181
3182
3183 AVAADDUVV & obj.AMask: {enc: rVVVEncoding},
3184 AVAADDUVX & obj.AMask: {enc: rVIVEncoding},
3185 AVAADDVV & obj.AMask: {enc: rVVVEncoding},
3186 AVAADDVX & obj.AMask: {enc: rVIVEncoding},
3187 AVASUBUVV & obj.AMask: {enc: rVVVEncoding},
3188 AVASUBUVX & obj.AMask: {enc: rVIVEncoding},
3189 AVASUBVV & obj.AMask: {enc: rVVVEncoding},
3190 AVASUBVX & obj.AMask: {enc: rVIVEncoding},
3191
3192
3193 AVSMULVV & obj.AMask: {enc: rVVVEncoding},
3194 AVSMULVX & obj.AMask: {enc: rVIVEncoding},
3195
3196
3197 AVSSRLVV & obj.AMask: {enc: rVVVEncoding},
3198 AVSSRLVX & obj.AMask: {enc: rVIVEncoding},
3199 AVSSRLVI & obj.AMask: {enc: rVVuEncoding},
3200 AVSSRAVV & obj.AMask: {enc: rVVVEncoding},
3201 AVSSRAVX & obj.AMask: {enc: rVIVEncoding},
3202 AVSSRAVI & obj.AMask: {enc: rVVuEncoding},
3203
3204
3205 AVNCLIPUWV & obj.AMask: {enc: rVVVEncoding},
3206 AVNCLIPUWX & obj.AMask: {enc: rVIVEncoding},
3207 AVNCLIPUWI & obj.AMask: {enc: rVVuEncoding},
3208 AVNCLIPWV & obj.AMask: {enc: rVVVEncoding},
3209 AVNCLIPWX & obj.AMask: {enc: rVIVEncoding},
3210 AVNCLIPWI & obj.AMask: {enc: rVVuEncoding},
3211
3212
3213 AVFADDVV & obj.AMask: {enc: rVVVEncoding},
3214 AVFADDVF & obj.AMask: {enc: rVFVEncoding},
3215 AVFSUBVV & obj.AMask: {enc: rVVVEncoding},
3216 AVFSUBVF & obj.AMask: {enc: rVFVEncoding},
3217 AVFRSUBVF & obj.AMask: {enc: rVFVEncoding},
3218
3219
3220 AVFWADDVV & obj.AMask: {enc: rVVVEncoding},
3221 AVFWADDVF & obj.AMask: {enc: rVFVEncoding},
3222 AVFWSUBVV & obj.AMask: {enc: rVVVEncoding},
3223 AVFWSUBVF & obj.AMask: {enc: rVFVEncoding},
3224 AVFWADDWV & obj.AMask: {enc: rVVVEncoding},
3225 AVFWADDWF & obj.AMask: {enc: rVFVEncoding},
3226 AVFWSUBWV & obj.AMask: {enc: rVVVEncoding},
3227 AVFWSUBWF & obj.AMask: {enc: rVFVEncoding},
3228
3229
3230 AVFMULVV & obj.AMask: {enc: rVVVEncoding},
3231 AVFMULVF & obj.AMask: {enc: rVFVEncoding},
3232 AVFDIVVV & obj.AMask: {enc: rVVVEncoding},
3233 AVFDIVVF & obj.AMask: {enc: rVFVEncoding},
3234 AVFRDIVVF & obj.AMask: {enc: rVFVEncoding},
3235
3236
3237 AVFWMULVV & obj.AMask: {enc: rVVVEncoding},
3238 AVFWMULVF & obj.AMask: {enc: rVFVEncoding},
3239
3240
3241 AVFMACCVV & obj.AMask: {enc: rVVVEncoding},
3242 AVFMACCVF & obj.AMask: {enc: rVFVEncoding},
3243 AVFNMACCVV & obj.AMask: {enc: rVVVEncoding},
3244 AVFNMACCVF & obj.AMask: {enc: rVFVEncoding},
3245 AVFMSACVV & obj.AMask: {enc: rVVVEncoding},
3246 AVFMSACVF & obj.AMask: {enc: rVFVEncoding},
3247 AVFNMSACVV & obj.AMask: {enc: rVVVEncoding},
3248 AVFNMSACVF & obj.AMask: {enc: rVFVEncoding},
3249 AVFMADDVV & obj.AMask: {enc: rVVVEncoding},
3250 AVFMADDVF & obj.AMask: {enc: rVFVEncoding},
3251 AVFNMADDVV & obj.AMask: {enc: rVVVEncoding},
3252 AVFNMADDVF & obj.AMask: {enc: rVFVEncoding},
3253 AVFMSUBVV & obj.AMask: {enc: rVVVEncoding},
3254 AVFMSUBVF & obj.AMask: {enc: rVFVEncoding},
3255 AVFNMSUBVV & obj.AMask: {enc: rVVVEncoding},
3256 AVFNMSUBVF & obj.AMask: {enc: rVFVEncoding},
3257
3258
3259 AVFWMACCVV & obj.AMask: {enc: rVVVEncoding},
3260 AVFWMACCVF & obj.AMask: {enc: rVFVEncoding},
3261 AVFWNMACCVV & obj.AMask: {enc: rVVVEncoding},
3262 AVFWNMACCVF & obj.AMask: {enc: rVFVEncoding},
3263 AVFWMSACVV & obj.AMask: {enc: rVVVEncoding},
3264 AVFWMSACVF & obj.AMask: {enc: rVFVEncoding},
3265 AVFWNMSACVV & obj.AMask: {enc: rVVVEncoding},
3266 AVFWNMSACVF & obj.AMask: {enc: rVFVEncoding},
3267
3268
3269 AVFSQRTV & obj.AMask: {enc: rVVEncoding},
3270
3271
3272 AVFRSQRT7V & obj.AMask: {enc: rVVEncoding},
3273
3274
3275 AVFREC7V & obj.AMask: {enc: rVVEncoding},
3276
3277
3278 AVFMINVV & obj.AMask: {enc: rVVVEncoding},
3279 AVFMINVF & obj.AMask: {enc: rVFVEncoding},
3280 AVFMAXVV & obj.AMask: {enc: rVVVEncoding},
3281 AVFMAXVF & obj.AMask: {enc: rVFVEncoding},
3282
3283
3284 AVFSGNJVV & obj.AMask: {enc: rVVVEncoding},
3285 AVFSGNJVF & obj.AMask: {enc: rVFVEncoding},
3286 AVFSGNJNVV & obj.AMask: {enc: rVVVEncoding},
3287 AVFSGNJNVF & obj.AMask: {enc: rVFVEncoding},
3288 AVFSGNJXVV & obj.AMask: {enc: rVVVEncoding},
3289 AVFSGNJXVF & obj.AMask: {enc: rVFVEncoding},
3290
3291
3292 AVMFEQVV & obj.AMask: {enc: rVVVEncoding},
3293 AVMFEQVF & obj.AMask: {enc: rVFVEncoding},
3294 AVMFNEVV & obj.AMask: {enc: rVVVEncoding},
3295 AVMFNEVF & obj.AMask: {enc: rVFVEncoding},
3296 AVMFLTVV & obj.AMask: {enc: rVVVEncoding},
3297 AVMFLTVF & obj.AMask: {enc: rVFVEncoding},
3298 AVMFLEVV & obj.AMask: {enc: rVVVEncoding},
3299 AVMFLEVF & obj.AMask: {enc: rVFVEncoding},
3300 AVMFGTVF & obj.AMask: {enc: rVFVEncoding},
3301 AVMFGEVF & obj.AMask: {enc: rVFVEncoding},
3302
3303
3304 AVFCLASSV & obj.AMask: {enc: rVVEncoding},
3305
3306
3307 AVFMERGEVFM & obj.AMask: {enc: rVFVEncoding},
3308
3309
3310 AVFMVVF & obj.AMask: {enc: rVFVEncoding},
3311
3312
3313 AVFCVTXUFV & obj.AMask: {enc: rVVEncoding},
3314 AVFCVTXFV & obj.AMask: {enc: rVVEncoding},
3315 AVFCVTRTZXUFV & obj.AMask: {enc: rVVEncoding},
3316 AVFCVTRTZXFV & obj.AMask: {enc: rVVEncoding},
3317 AVFCVTFXUV & obj.AMask: {enc: rVVEncoding},
3318 AVFCVTFXV & obj.AMask: {enc: rVVEncoding},
3319
3320
3321 AVFWCVTXUFV & obj.AMask: {enc: rVVEncoding},
3322 AVFWCVTXFV & obj.AMask: {enc: rVVEncoding},
3323 AVFWCVTRTZXUFV & obj.AMask: {enc: rVVEncoding},
3324 AVFWCVTRTZXFV & obj.AMask: {enc: rVVEncoding},
3325 AVFWCVTFXUV & obj.AMask: {enc: rVVEncoding},
3326 AVFWCVTFXV & obj.AMask: {enc: rVVEncoding},
3327 AVFWCVTFFV & obj.AMask: {enc: rVVEncoding},
3328
3329
3330 AVFNCVTXUFW & obj.AMask: {enc: rVVEncoding},
3331 AVFNCVTXFW & obj.AMask: {enc: rVVEncoding},
3332 AVFNCVTRTZXUFW & obj.AMask: {enc: rVVEncoding},
3333 AVFNCVTRTZXFW & obj.AMask: {enc: rVVEncoding},
3334 AVFNCVTFXUW & obj.AMask: {enc: rVVEncoding},
3335 AVFNCVTFXW & obj.AMask: {enc: rVVEncoding},
3336 AVFNCVTFFW & obj.AMask: {enc: rVVEncoding},
3337 AVFNCVTRODFFW & obj.AMask: {enc: rVVEncoding},
3338
3339
3340 AVREDSUMVS & obj.AMask: {enc: rVVVEncoding},
3341 AVREDMAXUVS & obj.AMask: {enc: rVVVEncoding},
3342 AVREDMAXVS & obj.AMask: {enc: rVVVEncoding},
3343 AVREDMINUVS & obj.AMask: {enc: rVVVEncoding},
3344 AVREDMINVS & obj.AMask: {enc: rVVVEncoding},
3345 AVREDANDVS & obj.AMask: {enc: rVVVEncoding},
3346 AVREDORVS & obj.AMask: {enc: rVVVEncoding},
3347 AVREDXORVS & obj.AMask: {enc: rVVVEncoding},
3348
3349
3350 AVWREDSUMUVS & obj.AMask: {enc: rVVVEncoding},
3351 AVWREDSUMVS & obj.AMask: {enc: rVVVEncoding},
3352
3353
3354 AVFREDOSUMVS & obj.AMask: {enc: rVVVEncoding},
3355 AVFREDUSUMVS & obj.AMask: {enc: rVVVEncoding},
3356 AVFREDMAXVS & obj.AMask: {enc: rVVVEncoding},
3357 AVFREDMINVS & obj.AMask: {enc: rVVVEncoding},
3358
3359
3360 AVFWREDOSUMVS & obj.AMask: {enc: rVVVEncoding},
3361 AVFWREDUSUMVS & obj.AMask: {enc: rVVVEncoding},
3362
3363
3364 AVMANDMM & obj.AMask: {enc: rVVVEncoding},
3365 AVMNANDMM & obj.AMask: {enc: rVVVEncoding},
3366 AVMANDNMM & obj.AMask: {enc: rVVVEncoding},
3367 AVMXORMM & obj.AMask: {enc: rVVVEncoding},
3368 AVMORMM & obj.AMask: {enc: rVVVEncoding},
3369 AVMNORMM & obj.AMask: {enc: rVVVEncoding},
3370 AVMORNMM & obj.AMask: {enc: rVVVEncoding},
3371 AVMXNORMM & obj.AMask: {enc: rVVVEncoding},
3372 AVCPOPM & obj.AMask: {enc: rVIEncoding},
3373 AVFIRSTM & obj.AMask: {enc: rVIEncoding},
3374 AVMSBFM & obj.AMask: {enc: rVVEncoding},
3375 AVMSIFM & obj.AMask: {enc: rVVEncoding},
3376 AVMSOFM & obj.AMask: {enc: rVVEncoding},
3377 AVIOTAM & obj.AMask: {enc: rVVEncoding},
3378 AVIDV & obj.AMask: {enc: rVVEncoding},
3379
3380
3381 AVMVXS & obj.AMask: {enc: rVIEncoding},
3382 AVMVSX & obj.AMask: {enc: rIVEncoding},
3383
3384
3385 AVFMVFS & obj.AMask: {enc: rVFEncoding},
3386 AVFMVSF & obj.AMask: {enc: rFVEncoding},
3387
3388
3389 AVSLIDEUPVX & obj.AMask: {enc: rVIVEncoding},
3390 AVSLIDEUPVI & obj.AMask: {enc: rVVuEncoding},
3391 AVSLIDEDOWNVX & obj.AMask: {enc: rVIVEncoding},
3392 AVSLIDEDOWNVI & obj.AMask: {enc: rVVuEncoding},
3393 AVSLIDE1UPVX & obj.AMask: {enc: rVIVEncoding},
3394 AVFSLIDE1UPVF & obj.AMask: {enc: rVFVEncoding},
3395 AVSLIDE1DOWNVX & obj.AMask: {enc: rVIVEncoding},
3396 AVFSLIDE1DOWNVF & obj.AMask: {enc: rVFVEncoding},
3397
3398
3399 AVRGATHERVV & obj.AMask: {enc: rVVVEncoding},
3400 AVRGATHEREI16VV & obj.AMask: {enc: rVVVEncoding},
3401 AVRGATHERVX & obj.AMask: {enc: rVIVEncoding},
3402 AVRGATHERVI & obj.AMask: {enc: rVVuEncoding},
3403
3404
3405 AVCOMPRESSVM & obj.AMask: {enc: rVVVEncoding},
3406
3407
3408 AVMV1RV & obj.AMask: {enc: rVVEncoding},
3409 AVMV2RV & obj.AMask: {enc: rVVEncoding},
3410 AVMV4RV & obj.AMask: {enc: rVVEncoding},
3411 AVMV8RV & obj.AMask: {enc: rVVEncoding},
3412
3413
3414
3415
3416
3417
3418 AECALL & obj.AMask: {enc: iIIEncoding},
3419 AEBREAK & obj.AMask: {enc: iIIEncoding},
3420
3421
3422 AWORD & obj.AMask: {enc: rawEncoding},
3423
3424
3425 obj.AFUNCDATA: {enc: pseudoOpEncoding},
3426 obj.APCDATA: {enc: pseudoOpEncoding},
3427 obj.ATEXT: {enc: pseudoOpEncoding},
3428 obj.ANOP: {enc: pseudoOpEncoding},
3429 obj.APCALIGN: {enc: pseudoOpEncoding},
3430 }
3431
3432
3433 func instructionDataForAs(as obj.As) (*instructionData, error) {
3434 if base := as &^ obj.AMask; base != obj.ABaseRISCV && base != 0 {
3435 return nil, fmt.Errorf("%v is not a RISC-V instruction", as)
3436 }
3437 asi := as & obj.AMask
3438 if int(asi) >= len(instructions) {
3439 return nil, fmt.Errorf("bad RISC-V instruction %v", as)
3440 }
3441 return &instructions[asi], nil
3442 }
3443
3444
3445 func encodingForAs(as obj.As) (*encoding, error) {
3446 insData, err := instructionDataForAs(as)
3447 if err != nil {
3448 return &badEncoding, err
3449 }
3450 if insData.enc.validate == nil {
3451 return &badEncoding, fmt.Errorf("no encoding for instruction %s", as)
3452 }
3453 return &insData.enc, nil
3454 }
3455
3456
3457
3458 func splitShiftConst(v int64) (imm int64, lsh int, rsh int, ok bool) {
3459
3460 lsh = bits.TrailingZeros64(uint64(v))
3461 c := v >> lsh
3462 if int64(int32(c)) == c {
3463 return c, lsh, 0, true
3464 }
3465
3466
3467 rsh = bits.LeadingZeros64(uint64(v))
3468 ones := bits.OnesCount64((uint64(v) >> lsh) >> 11)
3469 if rsh+ones+lsh+11 == 64 {
3470 c = signExtend(1<<11|((v>>lsh)&0x7ff), 12)
3471 if lsh > 0 || c != -1 {
3472 lsh += rsh
3473 }
3474 return c, lsh, rsh, true
3475 }
3476
3477
3478
3479
3480 if int64(uint32(c)) == c {
3481 c = int64(int32(c))
3482 lsh, rsh = 32, 32-lsh
3483 return c, lsh, rsh, true
3484 }
3485
3486 return 0, 0, 0, false
3487 }
3488
3489
3490
3491 func isShiftConst(v int64) bool {
3492 _, lsh, rsh, ok := splitShiftConst(v)
3493 return ok && (lsh > 0 || rsh > 0)
3494 }
3495
3496
3497
3498 func isMaterialisableConst(v int64) bool {
3499
3500
3501 if int64(int32(v)) == v {
3502 return true
3503 }
3504 return isShiftConst(v)
3505 }
3506
3507 type instruction struct {
3508 p *obj.Prog
3509 as obj.As
3510 rd uint32
3511 rs1 uint32
3512 rs2 uint32
3513 rs3 uint32
3514 imm int64
3515 funct3 uint32
3516 funct7 uint32
3517 }
3518
3519 func (ins *instruction) String() string {
3520 if ins.p == nil {
3521 return ins.as.String()
3522 }
3523 var suffix string
3524 if ins.p.As != ins.as {
3525 suffix = fmt.Sprintf(" (%v)", ins.as)
3526 }
3527 return fmt.Sprintf("%v%v", ins.p, suffix)
3528 }
3529
3530 func (ins *instruction) encode() (uint32, error) {
3531 enc, err := encodingForAs(ins.as)
3532 if err != nil {
3533 return 0, err
3534 }
3535 if enc.length <= 0 {
3536 return 0, fmt.Errorf("%v: encoding called for a pseudo instruction", ins.as)
3537 }
3538 return enc.encode(ins), nil
3539 }
3540
3541 func (ins *instruction) length() int {
3542 enc, err := encodingForAs(ins.as)
3543 if err != nil {
3544 return 0
3545 }
3546 return enc.length
3547 }
3548
3549 func (ins *instruction) validate(ctxt *obj.Link) {
3550 enc, err := encodingForAs(ins.as)
3551 if err != nil {
3552 ctxt.Diag("%v", err)
3553 return
3554 }
3555 enc.validate(ctxt, ins)
3556 }
3557
3558 func (ins *instruction) usesRegTmp() bool {
3559 return ins.rd == REG_TMP || ins.rs1 == REG_TMP || ins.rs2 == REG_TMP
3560 }
3561
3562 func (ins *instruction) compress() {
3563 switch ins.as {
3564 case ALW:
3565 if ins.rd != REG_X0 && ins.rs1 == REG_SP && isScaledImmU(ins.imm, 8, 4) {
3566 ins.as, ins.rs1, ins.rs2 = ACLWSP, obj.REG_NONE, ins.rs1
3567 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 7, 4) {
3568 ins.as = ACLW
3569 }
3570
3571 case ALD:
3572 if ins.rs1 == REG_SP && ins.rd != REG_X0 && isScaledImmU(ins.imm, 9, 8) {
3573 ins.as, ins.rs1, ins.rs2 = ACLDSP, obj.REG_NONE, ins.rs1
3574 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 8, 8) {
3575 ins.as = ACLD
3576 }
3577
3578 case AFLD:
3579 if ins.rs1 == REG_SP && isScaledImmU(ins.imm, 9, 8) {
3580 ins.as, ins.rs1, ins.rs2 = ACFLDSP, obj.REG_NONE, ins.rs1
3581 } else if isFloatPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 8, 8) {
3582 ins.as = ACFLD
3583 }
3584
3585 case ASW:
3586 if ins.rd == REG_SP && isScaledImmU(ins.imm, 8, 4) {
3587 ins.as, ins.rs1, ins.rs2 = ACSWSP, obj.REG_NONE, ins.rs1
3588 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 7, 4) {
3589 ins.as, ins.rd, ins.rs1, ins.rs2 = ACSW, obj.REG_NONE, ins.rd, ins.rs1
3590 }
3591
3592 case ASD:
3593 if ins.rd == REG_SP && isScaledImmU(ins.imm, 9, 8) {
3594 ins.as, ins.rs1, ins.rs2 = ACSDSP, obj.REG_NONE, ins.rs1
3595 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 8, 8) {
3596 ins.as, ins.rd, ins.rs1, ins.rs2 = ACSD, obj.REG_NONE, ins.rd, ins.rs1
3597 }
3598
3599 case AFSD:
3600 if ins.rd == REG_SP && isScaledImmU(ins.imm, 9, 8) {
3601 ins.as, ins.rs1, ins.rs2 = ACFSDSP, obj.REG_NONE, ins.rs1
3602 } else if isIntPrimeReg(ins.rd) && isFloatPrimeReg(ins.rs1) && isScaledImmU(ins.imm, 8, 8) {
3603 ins.as, ins.rd, ins.rs1, ins.rs2 = ACFSD, obj.REG_NONE, ins.rd, ins.rs1
3604 }
3605
3606 case AADDI:
3607 if ins.rd == REG_SP && ins.rs1 == REG_SP && ins.imm != 0 && isScaledImmI(ins.imm, 10, 16) {
3608 ins.as = ACADDI16SP
3609 } else if ins.rd != REG_X0 && ins.rd == ins.rs1 && ins.imm != 0 && immIFits(ins.imm, 6) == nil {
3610 ins.as = ACADDI
3611 } else if isIntPrimeReg(ins.rd) && ins.rs1 == REG_SP && ins.imm != 0 && isScaledImmU(ins.imm, 10, 4) {
3612 ins.as = ACADDI4SPN
3613 } else if ins.rd != REG_X0 && ins.rs1 == REG_X0 && immIFits(ins.imm, 6) == nil {
3614 ins.as, ins.rs1 = ACLI, obj.REG_NONE
3615 } else if ins.rd != REG_X0 && ins.rs1 != REG_X0 && ins.imm == 0 {
3616 ins.as, ins.rs1, ins.rs2 = ACMV, obj.REG_NONE, ins.rs1
3617 } else if ins.rd == REG_X0 && ins.rs1 == REG_X0 && ins.imm == 0 {
3618 ins.as, ins.rs1 = ACNOP, ins.rd
3619 }
3620
3621 case AADDIW:
3622 if ins.rd == ins.rs1 && immIFits(ins.imm, 6) == nil {
3623 ins.as = ACADDIW
3624 }
3625
3626 case ALUI:
3627 if ins.rd != REG_X0 && ins.rd != REG_SP && ins.imm != 0 && immIFits(ins.imm, 6) == nil {
3628 ins.as = ACLUI
3629 }
3630
3631 case ASLLI:
3632 if ins.rd != REG_X0 && ins.rd == ins.rs1 && ins.imm != 0 {
3633 ins.as = ACSLLI
3634 }
3635
3636 case ASRLI:
3637 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && ins.imm != 0 {
3638 ins.as = ACSRLI
3639 }
3640
3641 case ASRAI:
3642 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && ins.imm != 0 {
3643 ins.as = ACSRAI
3644 }
3645
3646 case AANDI:
3647 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && immIFits(ins.imm, 6) == nil {
3648 ins.as = ACANDI
3649 }
3650
3651 case AADD:
3652 if ins.rd != REG_X0 && ins.rd == ins.rs1 && ins.rs2 != REG_X0 {
3653 ins.as = ACADD
3654 } else if ins.rd != REG_X0 && ins.rd == ins.rs2 && ins.rs1 != REG_X0 {
3655 ins.as, ins.rs1, ins.rs2 = ACADD, ins.rs2, ins.rs1
3656 } else if ins.rd != REG_X0 && ins.rs1 == REG_X0 && ins.rs2 != REG_X0 {
3657 ins.as = ACMV
3658 }
3659
3660 case AADDW:
3661 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3662 ins.as = ACADDW
3663 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && ins.rd == ins.rs2 {
3664 ins.as, ins.rs1, ins.rs2 = ACADDW, ins.rs2, ins.rs1
3665 }
3666
3667 case ASUB:
3668 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3669 ins.as = ACSUB
3670 }
3671
3672 case ASUBW:
3673 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3674 ins.as = ACSUBW
3675 }
3676
3677 case AAND:
3678 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3679 ins.as = ACAND
3680 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && ins.rd == ins.rs2 {
3681 ins.as, ins.rs1, ins.rs2 = ACAND, ins.rs2, ins.rs1
3682 }
3683
3684 case AOR:
3685 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3686 ins.as = ACOR
3687 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && ins.rd == ins.rs2 {
3688 ins.as, ins.rs1, ins.rs2 = ACOR, ins.rs2, ins.rs1
3689 }
3690
3691 case AXOR:
3692 if isIntPrimeReg(ins.rd) && ins.rd == ins.rs1 && isIntPrimeReg(ins.rs2) {
3693 ins.as = ACXOR
3694 } else if isIntPrimeReg(ins.rd) && isIntPrimeReg(ins.rs1) && ins.rd == ins.rs2 {
3695 ins.as, ins.rs1, ins.rs2 = ACXOR, ins.rs2, ins.rs1
3696 }
3697
3698 case AEBREAK:
3699 ins.as, ins.rd, ins.rs1 = ACEBREAK, obj.REG_NONE, obj.REG_NONE
3700 }
3701 }
3702
3703 func encodeFenceOperand(a *obj.Addr) (uint32, bool) {
3704 if a.Type == obj.TYPE_SPECIAL && a.Offset > int64(SPOP_FENCE_BEGIN) && a.Offset < int64(SPOP_FENCE_END) {
3705 return SpecialOperand(a.Offset).encode(), true
3706 }
3707 if a.Type == obj.TYPE_NONE {
3708 return SPOP_FENCE_IORW.encode(), true
3709 }
3710 return 0, false
3711 }
3712
3713
3714 func instructionForProg(p *obj.Prog) *instruction {
3715 ins := &instruction{
3716 as: p.As,
3717 rd: uint32(p.To.Reg),
3718 rs1: uint32(p.Reg),
3719 rs2: uint32(p.From.Reg),
3720 imm: p.From.Offset,
3721 }
3722 if len(p.RestArgs) == 1 {
3723 ins.rs3 = uint32(p.RestArgs[0].Reg)
3724 }
3725 return ins
3726 }
3727
3728
3729
3730
3731 func instructionsForOpImmediate(p *obj.Prog, as obj.As, rs int16) []*instruction {
3732
3733 ins := instructionForProg(p)
3734 ins.as, ins.rs1, ins.rs2 = as, uint32(rs), obj.REG_NONE
3735
3736 low, high, err := Split32BitImmediate(ins.imm)
3737 if err != nil {
3738 p.Ctxt.Diag("%v: constant %d too large: %v", p, ins.imm, err)
3739 return nil
3740 }
3741 if high == 0 {
3742 return []*instruction{ins}
3743 }
3744
3745
3746
3747 if p.Spadj == 0 && ins.as == AADDI && ins.imm >= -(1<<12) && ins.imm < 1<<12-1 {
3748 imm0 := ins.imm / 2
3749 imm1 := ins.imm - imm0
3750
3751
3752
3753 ins.imm = imm0
3754 insADDI := &instruction{as: AADDI, rd: ins.rd, rs1: ins.rd, imm: imm1}
3755 return []*instruction{ins, insADDI}
3756 }
3757
3758
3759
3760
3761 insLUI := &instruction{as: ALUI, rd: REG_TMP, imm: high}
3762 insADDIW := &instruction{as: AADDIW, rd: REG_TMP, rs1: REG_TMP, imm: low}
3763 switch ins.as {
3764 case AADDI:
3765 ins.as = AADD
3766 case AANDI:
3767 ins.as = AAND
3768 case AORI:
3769 ins.as = AOR
3770 case AXORI:
3771 ins.as = AXOR
3772 default:
3773 p.Ctxt.Diag("unsupported immediate instruction %v for splitting", p)
3774 return nil
3775 }
3776 ins.rs2 = REG_TMP
3777 if low == 0 {
3778 return []*instruction{insLUI, ins}
3779 }
3780 return []*instruction{insLUI, insADDIW, ins}
3781 }
3782
3783
3784
3785
3786 func instructionsForLoad(p *obj.Prog, as obj.As, rs int16) []*instruction {
3787 if p.From.Type != obj.TYPE_MEM {
3788 p.Ctxt.Diag("%v requires memory for source", p)
3789 return nil
3790 }
3791
3792 switch as {
3793 case ALD, ALB, ALH, ALW, ALBU, ALHU, ALWU, AFLW, AFLD:
3794 default:
3795 p.Ctxt.Diag("%v: unknown load instruction %v", p, as)
3796 return nil
3797 }
3798
3799
3800 ins := instructionForProg(p)
3801 ins.as, ins.rs1, ins.rs2 = as, uint32(rs), obj.REG_NONE
3802 ins.imm = p.From.Offset
3803
3804 low, high, err := Split32BitImmediate(ins.imm)
3805 if err != nil {
3806 p.Ctxt.Diag("%v: constant %d too large", p, ins.imm)
3807 return nil
3808 }
3809 if high == 0 {
3810 return []*instruction{ins}
3811 }
3812
3813
3814
3815
3816 insLUI := &instruction{as: ALUI, rd: REG_TMP, imm: high}
3817 insADD := &instruction{as: AADD, rd: REG_TMP, rs1: REG_TMP, rs2: ins.rs1}
3818 ins.rs1, ins.imm = REG_TMP, low
3819
3820 return []*instruction{insLUI, insADD, ins}
3821 }
3822
3823
3824
3825
3826 func instructionsForStore(p *obj.Prog, as obj.As, rd int16) []*instruction {
3827 if p.To.Type != obj.TYPE_MEM {
3828 p.Ctxt.Diag("%v requires memory for destination", p)
3829 return nil
3830 }
3831
3832 switch as {
3833 case ASW, ASH, ASB, ASD, AFSW, AFSD:
3834 default:
3835 p.Ctxt.Diag("%v: unknown store instruction %v", p, as)
3836 return nil
3837 }
3838
3839
3840 ins := instructionForProg(p)
3841 ins.as, ins.rd, ins.rs1, ins.rs2 = as, uint32(rd), uint32(p.From.Reg), obj.REG_NONE
3842 ins.imm = p.To.Offset
3843
3844 low, high, err := Split32BitImmediate(ins.imm)
3845 if err != nil {
3846 p.Ctxt.Diag("%v: constant %d too large", p, ins.imm)
3847 return nil
3848 }
3849 if high == 0 {
3850 return []*instruction{ins}
3851 }
3852
3853
3854
3855
3856 insLUI := &instruction{as: ALUI, rd: REG_TMP, imm: high}
3857 insADD := &instruction{as: AADD, rd: REG_TMP, rs1: REG_TMP, rs2: ins.rd}
3858 ins.rd, ins.imm = REG_TMP, low
3859
3860 return []*instruction{insLUI, insADD, ins}
3861 }
3862
3863 func instructionsForTLS(p *obj.Prog, ins *instruction) []*instruction {
3864 insAddTP := &instruction{as: AADD, rd: REG_TMP, rs1: REG_TMP, rs2: REG_TP}
3865
3866 var inss []*instruction
3867 if p.Ctxt.Flag_shared {
3868
3869
3870 insAUIPC := &instruction{as: AAUIPC, rd: REG_TMP}
3871 insLoadTLSOffset := &instruction{as: ALD, rd: REG_TMP, rs1: REG_TMP}
3872 inss = []*instruction{insAUIPC, insLoadTLSOffset, insAddTP, ins}
3873 } else {
3874
3875
3876
3877
3878
3879 insLUI := &instruction{as: ALUI, rd: REG_TMP}
3880 insADDIW := &instruction{as: AADDIW, rd: REG_TMP, rs1: REG_TMP}
3881 inss = []*instruction{insLUI, insADDIW, insAddTP, ins}
3882 }
3883 return inss
3884 }
3885
3886 func instructionsForTLSLoad(p *obj.Prog) []*instruction {
3887 if p.From.Sym.Type != objabi.STLSBSS {
3888 p.Ctxt.Diag("%v: %v is not a TLS symbol", p, p.From.Sym)
3889 return nil
3890 }
3891
3892 ins := instructionForProg(p)
3893 ins.as, ins.rs1, ins.rs2, ins.imm = movToLoad(p.As), REG_TMP, obj.REG_NONE, 0
3894
3895 return instructionsForTLS(p, ins)
3896 }
3897
3898 func instructionsForTLSStore(p *obj.Prog) []*instruction {
3899 if p.To.Sym.Type != objabi.STLSBSS {
3900 p.Ctxt.Diag("%v: %v is not a TLS symbol", p, p.To.Sym)
3901 return nil
3902 }
3903
3904 ins := instructionForProg(p)
3905 ins.as, ins.rd, ins.rs1, ins.rs2, ins.imm = movToStore(p.As), REG_TMP, uint32(p.From.Reg), obj.REG_NONE, 0
3906
3907 return instructionsForTLS(p, ins)
3908 }
3909
3910 func instructionsForMOVConst(p *obj.Prog) []*instruction {
3911 ins := instructionForProg(p)
3912 inss := []*instruction{ins}
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935 var insSLLI, insSRLI, insMOVWU *instruction
3936 if err := immIFits(ins.imm, 32); err != nil {
3937 if c, lsh, rsh, ok := splitShiftConst(ins.imm); ok {
3938 ins.imm = c
3939 if buildcfg.GORISCV64 >= 22 && lsh == 32 && rsh == 32 {
3940 insMOVWU = &instruction{as: AADDUW, rd: ins.rd, rs1: ins.rd, rs2: REG_ZERO}
3941 lsh, rsh = 0, 0
3942 }
3943 if lsh > 0 {
3944 insSLLI = &instruction{as: ASLLI, rd: ins.rd, rs1: ins.rd, imm: int64(lsh)}
3945 }
3946 if rsh > 0 {
3947 insSRLI = &instruction{as: ASRLI, rd: ins.rd, rs1: ins.rd, imm: int64(rsh)}
3948 }
3949 }
3950 }
3951
3952 low, high, err := Split32BitImmediate(ins.imm)
3953 if err != nil {
3954 p.Ctxt.Diag("%v: constant %d too large: %v", p, ins.imm, err)
3955 return nil
3956 }
3957
3958
3959 ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, REG_ZERO, obj.REG_NONE, low
3960
3961
3962 if high != 0 {
3963
3964
3965 insLUI := &instruction{as: ALUI, rd: ins.rd, imm: high}
3966 inss = []*instruction{insLUI}
3967 if low != 0 {
3968 ins.as, ins.rs1 = AADDIW, ins.rd
3969 inss = append(inss, ins)
3970 }
3971 }
3972 if insMOVWU != nil {
3973 inss = append(inss, insMOVWU)
3974 }
3975 if insSLLI != nil {
3976 inss = append(inss, insSLLI)
3977 }
3978 if insSRLI != nil {
3979 inss = append(inss, insSRLI)
3980 }
3981
3982 return inss
3983 }
3984
3985
3986
3987 func instructionsForMOV(p *obj.Prog) []*instruction {
3988 ins := instructionForProg(p)
3989 inss := []*instruction{ins}
3990
3991 if p.Reg != 0 {
3992 p.Ctxt.Diag("%v: illegal MOV instruction", p)
3993 return nil
3994 }
3995
3996 switch {
3997 case p.From.Type == obj.TYPE_CONST && p.To.Type == obj.TYPE_REG:
3998
3999 if p.As != AMOV {
4000 p.Ctxt.Diag("%v: unsupported constant load", p)
4001 return nil
4002 }
4003 return instructionsForMOVConst(p)
4004
4005 case p.From.Type == obj.TYPE_CONST && p.To.Type != obj.TYPE_REG:
4006 p.Ctxt.Diag("%v: constant load must target register", p)
4007 return nil
4008
4009 case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_REG:
4010
4011 switch p.As {
4012 case AMOV:
4013
4014 ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, uint32(p.From.Reg), obj.REG_NONE, 0
4015 case AMOVW:
4016
4017 ins.as, ins.rs1, ins.rs2, ins.imm = AADDIW, uint32(p.From.Reg), obj.REG_NONE, 0
4018 case AMOVBU:
4019
4020 ins.as, ins.rs1, ins.rs2, ins.imm = AANDI, uint32(p.From.Reg), obj.REG_NONE, 255
4021 case AMOVF:
4022
4023
4024
4025 if ins.rs2 >= REG_X0 && ins.rs2 <= REG_X31 && ins.rd >= REG_F0 && ins.rd <= REG_F31 {
4026 ins.as = AFMVWX
4027 } else if ins.rs2 >= REG_F0 && ins.rs2 <= REG_F31 && ins.rd >= REG_X0 && ins.rd <= REG_X31 {
4028 ins.as = AFMVXW
4029 } else {
4030 ins.as, ins.rs1 = AFSGNJS, uint32(p.From.Reg)
4031 }
4032 case AMOVD:
4033
4034
4035
4036 if ins.rs2 >= REG_X0 && ins.rs2 <= REG_X31 && ins.rd >= REG_F0 && ins.rd <= REG_F31 {
4037 ins.as = AFMVDX
4038 } else if ins.rs2 >= REG_F0 && ins.rs2 <= REG_F31 && ins.rd >= REG_X0 && ins.rd <= REG_X31 {
4039 ins.as = AFMVXD
4040 } else {
4041 ins.as, ins.rs1 = AFSGNJD, uint32(p.From.Reg)
4042 }
4043 case AMOVB, AMOVH:
4044 if buildcfg.GORISCV64 >= 22 {
4045
4046 ins.as, ins.rs1, ins.rs2 = ASEXTB, uint32(p.From.Reg), obj.REG_NONE
4047 if p.As == AMOVH {
4048 ins.as = ASEXTH
4049 }
4050 } else {
4051
4052 ins.as, ins.rs1, ins.rs2 = ASLLI, uint32(p.From.Reg), obj.REG_NONE
4053 if p.As == AMOVB {
4054 ins.imm = 56
4055 } else if p.As == AMOVH {
4056 ins.imm = 48
4057 }
4058 ins2 := &instruction{as: ASRAI, rd: ins.rd, rs1: ins.rd, imm: ins.imm}
4059 inss = append(inss, ins2)
4060 }
4061 case AMOVHU, AMOVWU:
4062 if buildcfg.GORISCV64 >= 22 {
4063
4064 ins.as, ins.rs1, ins.rs2, ins.imm = AZEXTH, uint32(p.From.Reg), obj.REG_NONE, 0
4065 if p.As == AMOVWU {
4066 ins.as, ins.rs2 = AADDUW, REG_ZERO
4067 }
4068 } else {
4069
4070 ins.as, ins.rs1, ins.rs2 = ASLLI, uint32(p.From.Reg), obj.REG_NONE
4071 if p.As == AMOVHU {
4072 ins.imm = 48
4073 } else if p.As == AMOVWU {
4074 ins.imm = 32
4075 }
4076 ins2 := &instruction{as: ASRLI, rd: ins.rd, rs1: ins.rd, imm: ins.imm}
4077 inss = append(inss, ins2)
4078 }
4079 }
4080
4081 case p.From.Type == obj.TYPE_MEM && p.To.Type == obj.TYPE_REG:
4082
4083 switch p.From.Name {
4084 case obj.NAME_AUTO, obj.NAME_PARAM, obj.NAME_NONE:
4085
4086 inss = instructionsForLoad(p, movToLoad(p.As), addrToReg(p.From))
4087
4088 case obj.NAME_EXTERN, obj.NAME_STATIC, obj.NAME_GOTREF:
4089 if p.From.Sym.Type == objabi.STLSBSS {
4090 return instructionsForTLSLoad(p)
4091 }
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101 addrReg := ins.rd
4102 if addrReg < REG_X0 || addrReg > REG_X31 {
4103 addrReg = REG_TMP
4104 }
4105 insAUIPC := &instruction{as: AAUIPC, rd: addrReg}
4106 ins.as, ins.rs1, ins.rs2, ins.imm = movToLoad(p.As), addrReg, obj.REG_NONE, 0
4107 inss = []*instruction{insAUIPC, ins}
4108
4109 default:
4110 p.Ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
4111 return nil
4112 }
4113
4114 case p.From.Type == obj.TYPE_REG && p.To.Type == obj.TYPE_MEM:
4115
4116 switch p.As {
4117 case AMOVBU, AMOVHU, AMOVWU:
4118 p.Ctxt.Diag("%v: unsupported unsigned store", p)
4119 return nil
4120 }
4121 switch p.To.Name {
4122 case obj.NAME_AUTO, obj.NAME_PARAM, obj.NAME_NONE:
4123
4124 inss = instructionsForStore(p, movToStore(p.As), addrToReg(p.To))
4125
4126 case obj.NAME_EXTERN, obj.NAME_STATIC:
4127 if p.To.Sym.Type == objabi.STLSBSS {
4128 return instructionsForTLSStore(p)
4129 }
4130
4131
4132
4133
4134
4135
4136 insAUIPC := &instruction{as: AAUIPC, rd: REG_TMP}
4137 ins.as, ins.rd, ins.rs1, ins.rs2, ins.imm = movToStore(p.As), REG_TMP, uint32(p.From.Reg), obj.REG_NONE, 0
4138 inss = []*instruction{insAUIPC, ins}
4139
4140 default:
4141 p.Ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
4142 return nil
4143 }
4144
4145 case p.From.Type == obj.TYPE_ADDR && p.To.Type == obj.TYPE_REG:
4146
4147 if p.As != AMOV {
4148 p.Ctxt.Diag("%v: unsupported address load", p)
4149 return nil
4150 }
4151 switch p.From.Name {
4152 case obj.NAME_AUTO, obj.NAME_PARAM, obj.NAME_NONE:
4153 inss = instructionsForOpImmediate(p, AADDI, addrToReg(p.From))
4154
4155 case obj.NAME_EXTERN, obj.NAME_STATIC:
4156
4157
4158
4159
4160
4161 insAUIPC := &instruction{as: AAUIPC, rd: ins.rd}
4162 ins.as, ins.rs1, ins.rs2, ins.imm = AADDI, ins.rd, obj.REG_NONE, 0
4163 inss = []*instruction{insAUIPC, ins}
4164
4165 default:
4166 p.Ctxt.Diag("unsupported name %d for %v", p.From.Name, p)
4167 return nil
4168 }
4169
4170 case p.From.Type == obj.TYPE_ADDR && p.To.Type != obj.TYPE_REG:
4171 p.Ctxt.Diag("%v: address load must target register", p)
4172 return nil
4173
4174 default:
4175 p.Ctxt.Diag("%v: unsupported MOV", p)
4176 return nil
4177 }
4178
4179 return inss
4180 }
4181
4182
4183 func instructionsForRotate(p *obj.Prog, ins *instruction) []*instruction {
4184 if buildcfg.GORISCV64 >= 22 {
4185
4186 return []*instruction{ins}
4187 }
4188
4189 switch ins.as {
4190 case AROL, AROLW, AROR, ARORW:
4191
4192
4193 sllOp, srlOp := ASLL, ASRL
4194 if ins.as == AROLW || ins.as == ARORW {
4195 sllOp, srlOp = ASLLW, ASRLW
4196 }
4197 shift1, shift2 := sllOp, srlOp
4198 if ins.as == AROR || ins.as == ARORW {
4199 shift1, shift2 = shift2, shift1
4200 }
4201 return []*instruction{
4202 &instruction{as: ASUB, rs1: REG_ZERO, rs2: ins.rs2, rd: REG_TMP},
4203 &instruction{as: shift2, rs1: ins.rs1, rs2: REG_TMP, rd: REG_TMP},
4204 &instruction{as: shift1, rs1: ins.rs1, rs2: ins.rs2, rd: ins.rd},
4205 &instruction{as: AOR, rs1: REG_TMP, rs2: ins.rd, rd: ins.rd},
4206 }
4207
4208 case ARORI, ARORIW:
4209
4210 sllOp, srlOp := ASLLI, ASRLI
4211 sllImm := int64(int8(-ins.imm) & 63)
4212 if ins.as == ARORIW {
4213 sllOp, srlOp = ASLLIW, ASRLIW
4214 sllImm = int64(int8(-ins.imm) & 31)
4215 }
4216 return []*instruction{
4217 &instruction{as: srlOp, rs1: ins.rs1, rd: REG_TMP, imm: ins.imm},
4218 &instruction{as: sllOp, rs1: ins.rs1, rd: ins.rd, imm: sllImm},
4219 &instruction{as: AOR, rs1: REG_TMP, rs2: ins.rd, rd: ins.rd},
4220 }
4221
4222 default:
4223 p.Ctxt.Diag("%v: unknown rotation", p)
4224 return nil
4225 }
4226 }
4227
4228
4229 func instructionsForMinMax(p *obj.Prog, ins *instruction) []*instruction {
4230 if buildcfg.GORISCV64 >= 22 {
4231
4232 return []*instruction{ins}
4233 }
4234
4235
4236 if ins.rs1 == ins.rs2 {
4237 ins.as, ins.rs2, ins.imm = AADDI, obj.REG_NONE, 0
4238 return []*instruction{ins}
4239 }
4240
4241
4242
4243 if ins.rs1 == ins.rd {
4244 ins.rs1, ins.rs2 = ins.rs2, ins.rs1
4245 }
4246 sltReg1, sltReg2 := ins.rs2, ins.rs1
4247
4248
4249
4250 switch ins.as {
4251 case AMIN:
4252 ins.as = ASLT
4253 case AMAX:
4254 ins.as, sltReg1, sltReg2 = ASLT, sltReg2, sltReg1
4255 case AMINU:
4256 ins.as = ASLTU
4257 case AMAXU:
4258 ins.as, sltReg1, sltReg2 = ASLTU, sltReg2, sltReg1
4259 }
4260 return []*instruction{
4261 &instruction{as: ins.as, rs1: sltReg1, rs2: sltReg2, rd: REG_TMP},
4262 &instruction{as: ASUB, rs1: REG_ZERO, rs2: REG_TMP, rd: REG_TMP},
4263 &instruction{as: AXOR, rs1: ins.rs1, rs2: ins.rs2, rd: ins.rd},
4264 &instruction{as: AAND, rs1: REG_TMP, rs2: ins.rd, rd: ins.rd},
4265 &instruction{as: AXOR, rs1: ins.rs1, rs2: ins.rd, rd: ins.rd},
4266 }
4267 }
4268
4269
4270 func instructionsForProg(p *obj.Prog, compress bool) []*instruction {
4271 ins := instructionForProg(p)
4272 inss := []*instruction{ins}
4273
4274 if ins.as == AVSETVLI || ins.as == AVSETIVLI {
4275 if len(p.RestArgs) != 4 {
4276 p.Ctxt.Diag("incorrect number of arguments for instruction")
4277 return nil
4278 }
4279 } else if len(p.RestArgs) > 1 {
4280 p.Ctxt.Diag("too many source registers")
4281 return nil
4282 }
4283
4284 switch ins.as {
4285 case ACJALR, AJAL, AJALR:
4286 ins.rd, ins.rs1, ins.rs2 = uint32(p.From.Reg), uint32(p.To.Reg), obj.REG_NONE
4287 ins.imm = p.To.Offset
4288
4289 case ABEQ, ABEQZ, ABGE, ABGEU, ABGEZ, ABGT, ABGTU, ABGTZ, ABLE, ABLEU, ABLEZ, ABLT, ABLTU, ABLTZ, ABNE, ABNEZ:
4290 switch ins.as {
4291 case ABEQZ:
4292 ins.as, ins.rs1, ins.rs2 = ABEQ, REG_ZERO, uint32(p.From.Reg)
4293 case ABGEZ:
4294 ins.as, ins.rs1, ins.rs2 = ABGE, REG_ZERO, uint32(p.From.Reg)
4295 case ABGT:
4296 ins.as, ins.rs1, ins.rs2 = ABLT, uint32(p.From.Reg), uint32(p.Reg)
4297 case ABGTU:
4298 ins.as, ins.rs1, ins.rs2 = ABLTU, uint32(p.From.Reg), uint32(p.Reg)
4299 case ABGTZ:
4300 ins.as, ins.rs1, ins.rs2 = ABLT, uint32(p.From.Reg), REG_ZERO
4301 case ABLE:
4302 ins.as, ins.rs1, ins.rs2 = ABGE, uint32(p.From.Reg), uint32(p.Reg)
4303 case ABLEU:
4304 ins.as, ins.rs1, ins.rs2 = ABGEU, uint32(p.From.Reg), uint32(p.Reg)
4305 case ABLEZ:
4306 ins.as, ins.rs1, ins.rs2 = ABGE, uint32(p.From.Reg), REG_ZERO
4307 case ABLTZ:
4308 ins.as, ins.rs1, ins.rs2 = ABLT, REG_ZERO, uint32(p.From.Reg)
4309 case ABNEZ:
4310 ins.as, ins.rs1, ins.rs2 = ABNE, REG_ZERO, uint32(p.From.Reg)
4311 }
4312 ins.imm = p.To.Offset
4313
4314 case AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD:
4315 inss = instructionsForMOV(p)
4316
4317 case ALW, ALWU, ALH, ALHU, ALB, ALBU, ALD, AFLW, AFLD:
4318 inss = instructionsForLoad(p, ins.as, p.From.Reg)
4319
4320 case ASW, ASH, ASB, ASD, AFSW, AFSD:
4321 inss = instructionsForStore(p, ins.as, p.To.Reg)
4322
4323 case ALRW, ALRD:
4324
4325 ins.funct7 = 2
4326 ins.rs1, ins.rs2 = uint32(p.From.Reg), REG_ZERO
4327
4328 case AADDI, AANDI, AORI, AXORI:
4329 inss = instructionsForOpImmediate(p, ins.as, p.Reg)
4330
4331 case ASCW, ASCD:
4332
4333 ins.funct7 = 1
4334 ins.rd, ins.rs1, ins.rs2 = uint32(p.RegTo2), uint32(p.To.Reg), uint32(p.From.Reg)
4335
4336 case AAMOSWAPW, AAMOSWAPD, AAMOADDW, AAMOADDD, AAMOANDW, AAMOANDD, AAMOORW, AAMOORD,
4337 AAMOXORW, AAMOXORD, AAMOMINW, AAMOMIND, AAMOMINUW, AAMOMINUD, AAMOMAXW, AAMOMAXD, AAMOMAXUW, AAMOMAXUD:
4338
4339 ins.funct7 = 3
4340 ins.rd, ins.rs1, ins.rs2 = uint32(p.RegTo2), uint32(p.To.Reg), uint32(p.From.Reg)
4341
4342 case AECALL, AEBREAK:
4343 insEnc := encode(p.As)
4344 if p.To.Type == obj.TYPE_NONE {
4345 ins.rd = REG_ZERO
4346 }
4347 ins.rs1 = REG_ZERO
4348 ins.imm = insEnc.csr
4349
4350 case ARDCYCLE, ARDTIME, ARDINSTRET:
4351 ins.as = ACSRRS
4352 if p.To.Type == obj.TYPE_NONE {
4353 ins.rd = REG_ZERO
4354 }
4355 ins.rs1 = REG_ZERO
4356 switch p.As {
4357 case ARDCYCLE:
4358 ins.imm = -1024
4359 case ARDTIME:
4360 ins.imm = -1023
4361 case ARDINSTRET:
4362 ins.imm = -1022
4363 }
4364
4365 case ACSRRC, ACSRRCI, ACSRRS, ACSRRSI, ACSRRW, ACSRRWI:
4366 if len(p.RestArgs) == 0 || p.RestArgs[0].Type != obj.TYPE_SPECIAL {
4367 p.Ctxt.Diag("%v: missing CSR name", p)
4368 return nil
4369 }
4370 if p.From.Type == obj.TYPE_CONST {
4371 imm := p.From.Offset
4372 if imm < 0 || imm >= 32 {
4373 p.Ctxt.Diag("%v: immediate out of range 0 to 31", p)
4374 return nil
4375 }
4376 ins.rs1 = uint32(imm) + REG_ZERO
4377 } else if p.From.Type == obj.TYPE_REG {
4378 ins.rs1 = uint32(p.From.Reg)
4379 } else {
4380 p.Ctxt.Diag("%v: integer register or immediate expected for 1st operand", p)
4381 return nil
4382 }
4383 if p.To.Type != obj.TYPE_REG {
4384 p.Ctxt.Diag("%v: needs an integer register output", p)
4385 return nil
4386 }
4387 csrNum := SpecialOperand(p.RestArgs[0].Offset).encode()
4388 if csrNum >= 1<<12 {
4389 p.Ctxt.Diag("%v: unknown CSR", p)
4390 return nil
4391 }
4392 if _, ok := CSRs[uint16(csrNum)]; !ok {
4393 p.Ctxt.Diag("%v: unknown CSR", p)
4394 return nil
4395 }
4396 ins.imm = int64(csrNum)
4397 if ins.imm > 2047 {
4398 ins.imm -= 4096
4399 }
4400 ins.rs2 = obj.REG_NONE
4401
4402 case AFENCE:
4403 ins.rd, ins.rs1, ins.rs2 = REG_ZERO, REG_ZERO, obj.REG_NONE
4404 if p.Scond == fenceTsoSuffixBit {
4405 if p.From.Type != obj.TYPE_NONE || p.To.Type != obj.TYPE_NONE {
4406 p.Ctxt.Diag("FENCE.TSO must not have operands: %v", p)
4407 }
4408
4409 ins.imm = signExtend((8<<8)|(3<<4)|3, 12)
4410 } else {
4411 pred, ok := encodeFenceOperand(&p.From)
4412 if !ok {
4413 p.Ctxt.Diag("invalid FENCE predecessor operand: %v", p)
4414 }
4415 succ, ok := encodeFenceOperand(&p.To)
4416 if !ok {
4417 p.Ctxt.Diag("invalid FENCE successor operand: %v", p)
4418 }
4419
4420
4421 ins.imm = int64((pred << 4) | succ)
4422 }
4423
4424 case APAUSE:
4425 ins.as, ins.rd, ins.rs1, ins.rs2 = AFENCE, REG_ZERO, REG_ZERO, obj.REG_NONE
4426 ins.imm = 0x010
4427
4428 case AFCVTWS, AFCVTLS, AFCVTWUS, AFCVTLUS, AFCVTWD, AFCVTLD, AFCVTWUD, AFCVTLUD:
4429
4430 if p.Scond&rmSuffixBit == 0 {
4431 ins.funct3 = uint32(RM_RTZ)
4432 } else {
4433 ins.funct3 = uint32(p.Scond &^ rmSuffixBit)
4434 }
4435
4436 case AFNES, AFNED:
4437
4438 if p.To.Type != obj.TYPE_REG {
4439 p.Ctxt.Diag("%v needs an integer register output", p)
4440 return nil
4441 }
4442 if ins.as == AFNES {
4443 ins.as = AFEQS
4444 } else {
4445 ins.as = AFEQD
4446 }
4447 ins2 := &instruction{
4448 as: AXORI,
4449 rd: ins.rd,
4450 rs1: ins.rd,
4451 imm: 1,
4452 }
4453 inss = append(inss, ins2)
4454
4455 case AFSQRTS, AFSQRTD:
4456
4457
4458 ins.rs1 = uint32(p.From.Reg)
4459 ins.rs2 = REG_F0
4460
4461 case AFMADDS, AFMSUBS, AFNMADDS, AFNMSUBS,
4462 AFMADDD, AFMSUBD, AFNMADDD, AFNMSUBD:
4463
4464
4465 ins.rs1, ins.rs2 = ins.rs2, ins.rs1
4466
4467 case ANEG, ANEGW:
4468
4469 ins.as = ASUB
4470 if p.As == ANEGW {
4471 ins.as = ASUBW
4472 }
4473 ins.rs1 = REG_ZERO
4474 if ins.rd == obj.REG_NONE {
4475 ins.rd = ins.rs2
4476 }
4477
4478 case ANOT:
4479
4480 ins.as = AXORI
4481 ins.rs1, ins.rs2 = uint32(p.From.Reg), obj.REG_NONE
4482 if ins.rd == obj.REG_NONE {
4483 ins.rd = ins.rs1
4484 }
4485 ins.imm = -1
4486
4487 case ASEQZ:
4488
4489 ins.as = ASLTIU
4490 ins.rs1, ins.rs2 = uint32(p.From.Reg), obj.REG_NONE
4491 ins.imm = 1
4492
4493 case ASNEZ:
4494
4495 ins.as = ASLTU
4496 ins.rs1 = REG_ZERO
4497
4498 case AFABSS:
4499
4500 ins.as = AFSGNJXS
4501 ins.rs1 = uint32(p.From.Reg)
4502
4503 case AFABSD:
4504
4505 ins.as = AFSGNJXD
4506 ins.rs1 = uint32(p.From.Reg)
4507
4508 case AFNEGS:
4509
4510 ins.as = AFSGNJNS
4511 ins.rs1 = uint32(p.From.Reg)
4512
4513 case AFNEGD:
4514
4515 ins.as = AFSGNJND
4516 ins.rs1 = uint32(p.From.Reg)
4517
4518 case ACLW, ACLD, ACFLD:
4519 ins.rs1, ins.rs2 = ins.rs2, obj.REG_NONE
4520
4521 case ACSW, ACSD, ACFSD:
4522 ins.rs1, ins.rd = ins.rd, obj.REG_NONE
4523 ins.imm = p.To.Offset
4524
4525 case ACSWSP, ACSDSP, ACFSDSP:
4526 ins.imm = p.To.Offset
4527
4528 case ACANDI, ACSRLI, ACSRAI:
4529 ins.rs1, ins.rd = ins.rd, ins.rs1
4530
4531 case ACBEQZ, ACBNEZ:
4532 ins.rd, ins.rs1, ins.rs2 = obj.REG_NONE, uint32(p.From.Reg), obj.REG_NONE
4533 ins.imm = p.To.Offset
4534
4535 case ACJR:
4536 ins.rd, ins.rs1 = obj.REG_NONE, uint32(p.To.Reg)
4537
4538 case ACJ:
4539 ins.imm = p.To.Offset
4540
4541 case ACNOP:
4542 ins.rd, ins.rs1 = REG_ZERO, REG_ZERO
4543
4544 case AROL, AROLW, AROR, ARORW:
4545 inss = instructionsForRotate(p, ins)
4546
4547 case ARORI:
4548 if ins.imm < 0 || ins.imm > 63 {
4549 p.Ctxt.Diag("%v: immediate out of range 0 to 63", p)
4550 }
4551 inss = instructionsForRotate(p, ins)
4552
4553 case ARORIW:
4554 if ins.imm < 0 || ins.imm > 31 {
4555 p.Ctxt.Diag("%v: immediate out of range 0 to 31", p)
4556 }
4557 inss = instructionsForRotate(p, ins)
4558
4559 case ASLLI, ASRLI, ASRAI:
4560 if ins.imm < 0 || ins.imm > 63 {
4561 p.Ctxt.Diag("%v: immediate out of range 0 to 63", p)
4562 }
4563
4564 case ASLLIW, ASRLIW, ASRAIW:
4565 if ins.imm < 0 || ins.imm > 31 {
4566 p.Ctxt.Diag("%v: immediate out of range 0 to 31", p)
4567 }
4568
4569 case ACLZ, ACLZW, ACTZ, ACTZW, ACPOP, ACPOPW, ASEXTB, ASEXTH, AZEXTH:
4570 ins.rs1, ins.rs2 = uint32(p.From.Reg), obj.REG_NONE
4571
4572 case AORCB, AREV8:
4573 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
4574
4575 case AANDN, AORN:
4576 if buildcfg.GORISCV64 >= 22 {
4577
4578 break
4579 }
4580
4581
4582 bitwiseOp, notReg := AAND, ins.rd
4583 if ins.as == AORN {
4584 bitwiseOp = AOR
4585 }
4586 if ins.rs1 == notReg {
4587 notReg = REG_TMP
4588 }
4589 inss = []*instruction{
4590 &instruction{as: AXORI, rs1: ins.rs2, rs2: obj.REG_NONE, rd: notReg, imm: -1},
4591 &instruction{as: bitwiseOp, rs1: ins.rs1, rs2: notReg, rd: ins.rd},
4592 }
4593
4594 case AXNOR:
4595 if buildcfg.GORISCV64 >= 22 {
4596
4597 break
4598 }
4599
4600 ins.as = AXOR
4601 inss = append(inss, &instruction{as: AXORI, rs1: ins.rd, rs2: obj.REG_NONE, rd: ins.rd, imm: -1})
4602
4603 case AMIN, AMAX, AMINU, AMAXU:
4604 inss = instructionsForMinMax(p, ins)
4605
4606 case AVSETVLI, AVSETIVLI:
4607 ins.rs1, ins.rs2 = ins.rs2, obj.REG_NONE
4608 vtype, err := EncodeVectorType(p.RestArgs[0].Offset, p.RestArgs[1].Offset, p.RestArgs[2].Offset, p.RestArgs[3].Offset)
4609 if err != nil {
4610 p.Ctxt.Diag("%v: %v", p, err)
4611 }
4612 ins.imm = vtype
4613 if ins.as == AVSETIVLI {
4614 if p.From.Type != obj.TYPE_CONST {
4615 p.Ctxt.Diag("%v: expected immediate value", p)
4616 }
4617 ins.rs1 = uint32(p.From.Offset)
4618 }
4619
4620 case AVLE8V, AVLE16V, AVLE32V, AVLE64V, AVSE8V, AVSE16V, AVSE32V, AVSE64V, AVLE8FFV, AVLE16FFV, AVLE32FFV, AVLE64FFV, AVLMV, AVSMV,
4621 AVLSEG2E8V, AVLSEG3E8V, AVLSEG4E8V, AVLSEG5E8V, AVLSEG6E8V, AVLSEG7E8V, AVLSEG8E8V,
4622 AVLSEG2E16V, AVLSEG3E16V, AVLSEG4E16V, AVLSEG5E16V, AVLSEG6E16V, AVLSEG7E16V, AVLSEG8E16V,
4623 AVLSEG2E32V, AVLSEG3E32V, AVLSEG4E32V, AVLSEG5E32V, AVLSEG6E32V, AVLSEG7E32V, AVLSEG8E32V,
4624 AVLSEG2E64V, AVLSEG3E64V, AVLSEG4E64V, AVLSEG5E64V, AVLSEG6E64V, AVLSEG7E64V, AVLSEG8E64V,
4625 AVSSEG2E8V, AVSSEG3E8V, AVSSEG4E8V, AVSSEG5E8V, AVSSEG6E8V, AVSSEG7E8V, AVSSEG8E8V,
4626 AVSSEG2E16V, AVSSEG3E16V, AVSSEG4E16V, AVSSEG5E16V, AVSSEG6E16V, AVSSEG7E16V, AVSSEG8E16V,
4627 AVSSEG2E32V, AVSSEG3E32V, AVSSEG4E32V, AVSSEG5E32V, AVSSEG6E32V, AVSSEG7E32V, AVSSEG8E32V,
4628 AVSSEG2E64V, AVSSEG3E64V, AVSSEG4E64V, AVSSEG5E64V, AVSSEG6E64V, AVSSEG7E64V, AVSSEG8E64V,
4629 AVLSEG2E8FFV, AVLSEG3E8FFV, AVLSEG4E8FFV, AVLSEG5E8FFV, AVLSEG6E8FFV, AVLSEG7E8FFV, AVLSEG8E8FFV,
4630 AVLSEG2E16FFV, AVLSEG3E16FFV, AVLSEG4E16FFV, AVLSEG5E16FFV, AVLSEG6E16FFV, AVLSEG7E16FFV, AVLSEG8E16FFV,
4631 AVLSEG2E32FFV, AVLSEG3E32FFV, AVLSEG4E32FFV, AVLSEG5E32FFV, AVLSEG6E32FFV, AVLSEG7E32FFV, AVLSEG8E32FFV,
4632 AVLSEG2E64FFV, AVLSEG3E64FFV, AVLSEG4E64FFV, AVLSEG5E64FFV, AVLSEG6E64FFV, AVLSEG7E64FFV, AVLSEG8E64FFV:
4633
4634 switch {
4635 case ins.rs1 == obj.REG_NONE:
4636 ins.funct7 |= 1
4637 case ins.rs1 != REG_V0:
4638 p.Ctxt.Diag("%v: invalid vector mask register", p)
4639 }
4640 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
4641
4642 case AVLSE8V, AVLSE16V, AVLSE32V, AVLSE64V,
4643 AVLUXEI8V, AVLUXEI16V, AVLUXEI32V, AVLUXEI64V, AVLOXEI8V, AVLOXEI16V, AVLOXEI32V, AVLOXEI64V,
4644 AVLSSEG2E8V, AVLSSEG3E8V, AVLSSEG4E8V, AVLSSEG5E8V, AVLSSEG6E8V, AVLSSEG7E8V, AVLSSEG8E8V,
4645 AVLSSEG2E16V, AVLSSEG3E16V, AVLSSEG4E16V, AVLSSEG5E16V, AVLSSEG6E16V, AVLSSEG7E16V, AVLSSEG8E16V,
4646 AVLSSEG2E32V, AVLSSEG3E32V, AVLSSEG4E32V, AVLSSEG5E32V, AVLSSEG6E32V, AVLSSEG7E32V, AVLSSEG8E32V,
4647 AVLSSEG2E64V, AVLSSEG3E64V, AVLSSEG4E64V, AVLSSEG5E64V, AVLSSEG6E64V, AVLSSEG7E64V, AVLSSEG8E64V,
4648 AVLOXSEG2EI8V, AVLOXSEG3EI8V, AVLOXSEG4EI8V, AVLOXSEG5EI8V, AVLOXSEG6EI8V, AVLOXSEG7EI8V, AVLOXSEG8EI8V,
4649 AVLOXSEG2EI16V, AVLOXSEG3EI16V, AVLOXSEG4EI16V, AVLOXSEG5EI16V, AVLOXSEG6EI16V, AVLOXSEG7EI16V, AVLOXSEG8EI16V,
4650 AVLOXSEG2EI32V, AVLOXSEG3EI32V, AVLOXSEG4EI32V, AVLOXSEG5EI32V, AVLOXSEG6EI32V, AVLOXSEG7EI32V, AVLOXSEG8EI32V,
4651 AVLOXSEG2EI64V, AVLOXSEG3EI64V, AVLOXSEG4EI64V, AVLOXSEG5EI64V, AVLOXSEG6EI64V, AVLOXSEG7EI64V, AVLOXSEG8EI64V,
4652 AVLUXSEG2EI8V, AVLUXSEG3EI8V, AVLUXSEG4EI8V, AVLUXSEG5EI8V, AVLUXSEG6EI8V, AVLUXSEG7EI8V, AVLUXSEG8EI8V,
4653 AVLUXSEG2EI16V, AVLUXSEG3EI16V, AVLUXSEG4EI16V, AVLUXSEG5EI16V, AVLUXSEG6EI16V, AVLUXSEG7EI16V, AVLUXSEG8EI16V,
4654 AVLUXSEG2EI32V, AVLUXSEG3EI32V, AVLUXSEG4EI32V, AVLUXSEG5EI32V, AVLUXSEG6EI32V, AVLUXSEG7EI32V, AVLUXSEG8EI32V,
4655 AVLUXSEG2EI64V, AVLUXSEG3EI64V, AVLUXSEG4EI64V, AVLUXSEG5EI64V, AVLUXSEG6EI64V, AVLUXSEG7EI64V, AVLUXSEG8EI64V:
4656
4657 switch {
4658 case ins.rs3 == obj.REG_NONE:
4659 ins.funct7 |= 1
4660 case ins.rs3 != REG_V0:
4661 p.Ctxt.Diag("%v: invalid vector mask register", p)
4662 }
4663 ins.rs1, ins.rs2, ins.rs3 = ins.rs2, ins.rs1, obj.REG_NONE
4664
4665 case AVSSE8V, AVSSE16V, AVSSE32V, AVSSE64V,
4666 AVSUXEI8V, AVSUXEI16V, AVSUXEI32V, AVSUXEI64V, AVSOXEI8V, AVSOXEI16V, AVSOXEI32V, AVSOXEI64V,
4667 AVSSSEG2E8V, AVSSSEG3E8V, AVSSSEG4E8V, AVSSSEG5E8V, AVSSSEG6E8V, AVSSSEG7E8V, AVSSSEG8E8V,
4668 AVSSSEG2E16V, AVSSSEG3E16V, AVSSSEG4E16V, AVSSSEG5E16V, AVSSSEG6E16V, AVSSSEG7E16V, AVSSSEG8E16V,
4669 AVSSSEG2E32V, AVSSSEG3E32V, AVSSSEG4E32V, AVSSSEG5E32V, AVSSSEG6E32V, AVSSSEG7E32V, AVSSSEG8E32V,
4670 AVSSSEG2E64V, AVSSSEG3E64V, AVSSSEG4E64V, AVSSSEG5E64V, AVSSSEG6E64V, AVSSSEG7E64V, AVSSSEG8E64V,
4671 AVSOXSEG2EI8V, AVSOXSEG3EI8V, AVSOXSEG4EI8V, AVSOXSEG5EI8V, AVSOXSEG6EI8V, AVSOXSEG7EI8V, AVSOXSEG8EI8V,
4672 AVSOXSEG2EI16V, AVSOXSEG3EI16V, AVSOXSEG4EI16V, AVSOXSEG5EI16V, AVSOXSEG6EI16V, AVSOXSEG7EI16V, AVSOXSEG8EI16V,
4673 AVSOXSEG2EI32V, AVSOXSEG3EI32V, AVSOXSEG4EI32V, AVSOXSEG5EI32V, AVSOXSEG6EI32V, AVSOXSEG7EI32V, AVSOXSEG8EI32V,
4674 AVSOXSEG2EI64V, AVSOXSEG3EI64V, AVSOXSEG4EI64V, AVSOXSEG5EI64V, AVSOXSEG6EI64V, AVSOXSEG7EI64V, AVSOXSEG8EI64V,
4675 AVSUXSEG2EI8V, AVSUXSEG3EI8V, AVSUXSEG4EI8V, AVSUXSEG5EI8V, AVSUXSEG6EI8V, AVSUXSEG7EI8V, AVSUXSEG8EI8V,
4676 AVSUXSEG2EI16V, AVSUXSEG3EI16V, AVSUXSEG4EI16V, AVSUXSEG5EI16V, AVSUXSEG6EI16V, AVSUXSEG7EI16V, AVSUXSEG8EI16V,
4677 AVSUXSEG2EI32V, AVSUXSEG3EI32V, AVSUXSEG4EI32V, AVSUXSEG5EI32V, AVSUXSEG6EI32V, AVSUXSEG7EI32V, AVSUXSEG8EI32V,
4678 AVSUXSEG2EI64V, AVSUXSEG3EI64V, AVSUXSEG4EI64V, AVSUXSEG5EI64V, AVSUXSEG6EI64V, AVSUXSEG7EI64V, AVSUXSEG8EI64V:
4679
4680 switch {
4681 case ins.rs3 == obj.REG_NONE:
4682 ins.funct7 |= 1
4683 case ins.rs3 != REG_V0:
4684 p.Ctxt.Diag("%v: invalid vector mask register", p)
4685 }
4686 ins.rd, ins.rs1, ins.rs2, ins.rs3 = ins.rs2, ins.rd, ins.rs1, obj.REG_NONE
4687
4688 case AVL1RV, AVL1RE8V, AVL1RE16V, AVL1RE32V, AVL1RE64V, AVL2RV, AVL2RE8V, AVL2RE16V, AVL2RE32V, AVL2RE64V,
4689 AVL4RV, AVL4RE8V, AVL4RE16V, AVL4RE32V, AVL4RE64V, AVL8RV, AVL8RE8V, AVL8RE16V, AVL8RE32V, AVL8RE64V:
4690 switch ins.as {
4691 case AVL1RV:
4692 ins.as = AVL1RE8V
4693 case AVL2RV:
4694 ins.as = AVL2RE8V
4695 case AVL4RV:
4696 ins.as = AVL4RE8V
4697 case AVL8RV:
4698 ins.as = AVL8RE8V
4699 }
4700 if ins.rs1 != obj.REG_NONE {
4701 p.Ctxt.Diag("%v: too many operands for instruction", p)
4702 }
4703 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
4704
4705 case AVS1RV, AVS2RV, AVS4RV, AVS8RV:
4706 if ins.rs1 != obj.REG_NONE {
4707 p.Ctxt.Diag("%v: too many operands for instruction", p)
4708 }
4709 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE
4710
4711 case AVADDVV, AVADDVX, AVSUBVV, AVSUBVX, AVRSUBVX, AVWADDUVV, AVWADDUVX, AVWSUBUVV, AVWSUBUVX,
4712 AVWADDVV, AVWADDVX, AVWSUBVV, AVWSUBVX, AVWADDUWV, AVWADDUWX, AVWSUBUWV, AVWSUBUWX,
4713 AVWADDWV, AVWADDWX, AVWSUBWV, AVWSUBWX, AVANDVV, AVANDVX, AVORVV, AVORVX, AVXORVV, AVXORVX,
4714 AVSLLVV, AVSLLVX, AVSRLVV, AVSRLVX, AVSRAVV, AVSRAVX,
4715 AVMSEQVV, AVMSEQVX, AVMSNEVV, AVMSNEVX, AVMSLTUVV, AVMSLTUVX, AVMSLTVV, AVMSLTVX,
4716 AVMSLEUVV, AVMSLEUVX, AVMSLEVV, AVMSLEVX, AVMSGTUVX, AVMSGTVX,
4717 AVMINUVV, AVMINUVX, AVMINVV, AVMINVX, AVMAXUVV, AVMAXUVX, AVMAXVV, AVMAXVX,
4718 AVMULVV, AVMULVX, AVMULHVV, AVMULHVX, AVMULHUVV, AVMULHUVX, AVMULHSUVV, AVMULHSUVX,
4719 AVDIVUVV, AVDIVUVX, AVDIVVV, AVDIVVX, AVREMUVV, AVREMUVX, AVREMVV, AVREMVX,
4720 AVWMULVV, AVWMULVX, AVWMULUVV, AVWMULUVX, AVWMULSUVV, AVWMULSUVX, AVNSRLWV, AVNSRLWX, AVNSRAWV, AVNSRAWX,
4721 AVSADDUVV, AVSADDUVX, AVSADDUVI, AVSADDVV, AVSADDVX, AVSADDVI, AVSSUBUVV, AVSSUBUVX, AVSSUBVV, AVSSUBVX,
4722 AVAADDUVV, AVAADDUVX, AVAADDVV, AVAADDVX, AVASUBUVV, AVASUBUVX, AVASUBVV, AVASUBVX,
4723 AVSMULVV, AVSMULVX, AVSSRLVV, AVSSRLVX, AVSSRLVI, AVSSRAVV, AVSSRAVX, AVSSRAVI,
4724 AVNCLIPUWV, AVNCLIPUWX, AVNCLIPUWI, AVNCLIPWV, AVNCLIPWX, AVNCLIPWI,
4725 AVFADDVV, AVFADDVF, AVFSUBVV, AVFSUBVF, AVFRSUBVF,
4726 AVFWADDVV, AVFWADDVF, AVFWSUBVV, AVFWSUBVF, AVFWADDWV, AVFWADDWF, AVFWSUBWV, AVFWSUBWF,
4727 AVFMULVV, AVFMULVF, AVFDIVVV, AVFDIVVF, AVFRDIVVF, AVFWMULVV, AVFWMULVF,
4728 AVFMINVV, AVFMINVF, AVFMAXVV, AVFMAXVF,
4729 AVFSGNJVV, AVFSGNJVF, AVFSGNJNVV, AVFSGNJNVF, AVFSGNJXVV, AVFSGNJXVF,
4730 AVMFEQVV, AVMFEQVF, AVMFNEVV, AVMFNEVF, AVMFLTVV, AVMFLTVF, AVMFLEVV, AVMFLEVF, AVMFGTVF, AVMFGEVF,
4731 AVREDSUMVS, AVREDMAXUVS, AVREDMAXVS, AVREDMINUVS, AVREDMINVS, AVREDANDVS, AVREDORVS, AVREDXORVS,
4732 AVWREDSUMUVS, AVWREDSUMVS, AVFREDOSUMVS, AVFREDUSUMVS, AVFREDMAXVS, AVFREDMINVS, AVFWREDOSUMVS, AVFWREDUSUMVS,
4733 AVSLIDEUPVX, AVSLIDEDOWNVX, AVSLIDE1UPVX, AVFSLIDE1UPVF, AVSLIDE1DOWNVX, AVFSLIDE1DOWNVF,
4734 AVRGATHERVV, AVRGATHEREI16VV, AVRGATHERVX:
4735
4736 switch {
4737 case ins.rs3 == obj.REG_NONE:
4738 ins.funct7 |= 1
4739 case ins.rs3 != REG_V0:
4740 p.Ctxt.Diag("%v: invalid vector mask register", p)
4741 }
4742 ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), obj.REG_NONE
4743
4744 case AVFMACCVV, AVFMACCVF, AVFNMACCVV, AVFNMACCVF, AVFMSACVV, AVFMSACVF, AVFNMSACVV, AVFNMSACVF,
4745 AVFMADDVV, AVFMADDVF, AVFNMADDVV, AVFNMADDVF, AVFMSUBVV, AVFMSUBVF, AVFNMSUBVV, AVFNMSUBVF,
4746 AVFWMACCVV, AVFWMACCVF, AVFWNMACCVV, AVFWNMACCVF, AVFWMSACVV, AVFWMSACVF, AVFWNMSACVV, AVFWNMSACVF,
4747 AVMACCVV, AVMACCVX, AVNMSACVV, AVNMSACVX, AVMADDVV, AVMADDVX, AVNMSUBVV, AVNMSUBVX,
4748 AVWMACCUVV, AVWMACCUVX, AVWMACCVV, AVWMACCVX, AVWMACCSUVV, AVWMACCSUVX, AVWMACCUSVX:
4749 switch {
4750 case ins.rs3 == obj.REG_NONE:
4751 ins.funct7 |= 1
4752 case ins.rs3 != REG_V0:
4753 p.Ctxt.Diag("%v: invalid vector mask register", p)
4754 }
4755 ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), obj.REG_NONE
4756
4757 case AVADDVI, AVRSUBVI, AVANDVI, AVORVI, AVXORVI, AVMSEQVI, AVMSNEVI, AVMSLEUVI, AVMSLEVI, AVMSGTUVI, AVMSGTVI,
4758 AVSLLVI, AVSRLVI, AVSRAVI, AVNSRLWI, AVNSRAWI, AVRGATHERVI, AVSLIDEUPVI, AVSLIDEDOWNVI:
4759
4760 switch {
4761 case ins.rs3 == obj.REG_NONE:
4762 ins.funct7 |= 1
4763 case ins.rs3 != REG_V0:
4764 p.Ctxt.Diag("%v: invalid vector mask register", p)
4765 }
4766 ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), obj.REG_NONE, uint32(p.Reg), obj.REG_NONE
4767
4768 case AVZEXTVF2, AVSEXTVF2, AVZEXTVF4, AVSEXTVF4, AVZEXTVF8, AVSEXTVF8, AVFSQRTV, AVFRSQRT7V, AVFREC7V, AVFCLASSV,
4769 AVFCVTXUFV, AVFCVTXFV, AVFCVTRTZXUFV, AVFCVTRTZXFV, AVFCVTFXUV, AVFCVTFXV,
4770 AVFWCVTXUFV, AVFWCVTXFV, AVFWCVTRTZXUFV, AVFWCVTRTZXFV, AVFWCVTFXUV, AVFWCVTFXV, AVFWCVTFFV,
4771 AVFNCVTXUFW, AVFNCVTXFW, AVFNCVTRTZXUFW, AVFNCVTRTZXFW, AVFNCVTFXUW, AVFNCVTFXW, AVFNCVTFFW, AVFNCVTRODFFW:
4772
4773 switch {
4774 case ins.rs1 == obj.REG_NONE:
4775 ins.funct7 |= 1
4776 case ins.rs1 != REG_V0:
4777 p.Ctxt.Diag("%v: invalid vector mask register", p)
4778 }
4779 ins.rs1 = obj.REG_NONE
4780
4781 case AVMVVV, AVMVVX:
4782 if ins.rs1 != obj.REG_NONE {
4783 p.Ctxt.Diag("%v: too many operands for instruction", p)
4784 }
4785 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), REG_V0
4786
4787 case AVMVVI:
4788 if ins.rs1 != obj.REG_NONE {
4789 p.Ctxt.Diag("%v: too many operands for instruction", p)
4790 }
4791 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), obj.REG_NONE, REG_V0
4792
4793 case AVFMVVF:
4794 ins.funct7 |= 1
4795 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), REG_V0
4796
4797 case AVADCVIM, AVADCVVM, AVADCVXM, AVSBCVVM, AVSBCVXM:
4798 if ins.rd == REG_V0 {
4799 p.Ctxt.Diag("%v: invalid destination register V0", p)
4800 }
4801 fallthrough
4802
4803 case AVMADCVVM, AVMADCVXM, AVMSBCVVM, AVMSBCVXM, AVMADCVIM, AVMERGEVVM, AVMERGEVXM, AVMERGEVIM, AVFMERGEVFM:
4804 if ins.rs3 != REG_V0 {
4805 p.Ctxt.Diag("%v: invalid vector mask register", p)
4806 }
4807 ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), obj.REG_NONE
4808
4809 case AVMADCVV, AVMADCVX, AVMSBCVV, AVMSBCVX, AVMADCVI:
4810 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)
4811
4812 case AVNEGV, AVWCVTXXV, AVWCVTUXXV, AVNCVTXXW:
4813
4814 switch {
4815 case ins.rs1 == obj.REG_NONE:
4816 ins.funct7 |= 1
4817 case ins.rs1 != REG_V0:
4818 p.Ctxt.Diag("%v: invalid vector mask register", p)
4819 }
4820 switch ins.as {
4821 case AVNEGV:
4822 ins.as = AVRSUBVX
4823 case AVWCVTXXV:
4824 ins.as = AVWADDVX
4825 case AVWCVTUXXV:
4826 ins.as = AVWADDUVX
4827 case AVNCVTXXW:
4828 ins.as = AVNSRLWX
4829 }
4830 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), REG_X0, uint32(p.From.Reg)
4831
4832 case AVNOTV:
4833
4834 switch {
4835 case ins.rs1 == obj.REG_NONE:
4836 ins.funct7 |= 1
4837 case ins.rs1 != REG_V0:
4838 p.Ctxt.Diag("%v: invalid vector mask register", p)
4839 }
4840 ins.as = AVXORVI
4841 ins.rd, ins.rs1, ins.rs2, ins.imm = uint32(p.To.Reg), obj.REG_NONE, uint32(p.From.Reg), -1
4842
4843 case AVMSGTVV, AVMSGTUVV, AVMSGEVV, AVMSGEUVV, AVMFGTVV, AVMFGEVV:
4844
4845 switch {
4846 case ins.rs3 == obj.REG_NONE:
4847 ins.funct7 |= 1
4848 case ins.rs3 != REG_V0:
4849 p.Ctxt.Diag("%v: invalid vector mask register", p)
4850 }
4851 switch ins.as {
4852 case AVMSGTVV:
4853 ins.as = AVMSLTVV
4854 case AVMSGTUVV:
4855 ins.as = AVMSLTUVV
4856 case AVMSGEVV:
4857 ins.as = AVMSLEVV
4858 case AVMSGEUVV:
4859 ins.as = AVMSLEUVV
4860 case AVMFGTVV:
4861 ins.as = AVMFLTVV
4862 case AVMFGEVV:
4863 ins.as = AVMFLEVV
4864 }
4865 ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), obj.REG_NONE
4866
4867 case AVMSLTVI, AVMSLTUVI, AVMSGEVI, AVMSGEUVI:
4868
4869 switch {
4870 case ins.rs3 == obj.REG_NONE:
4871 ins.funct7 |= 1
4872 case ins.rs3 != REG_V0:
4873 p.Ctxt.Diag("%v: invalid vector mask register", p)
4874 }
4875 switch ins.as {
4876 case AVMSLTVI:
4877 ins.as = AVMSLEVI
4878 case AVMSLTUVI:
4879 ins.as = AVMSLEUVI
4880 case AVMSGEVI:
4881 ins.as = AVMSGTVI
4882 case AVMSGEUVI:
4883 ins.as = AVMSGTUVI
4884 }
4885 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
4886
4887 case AVFABSV, AVFNEGV:
4888
4889 switch {
4890 case ins.rs1 == obj.REG_NONE:
4891 ins.funct7 |= 1
4892 case ins.rs1 != REG_V0:
4893 p.Ctxt.Diag("%v: invalid vector mask register", p)
4894 }
4895 switch ins.as {
4896 case AVFABSV:
4897 ins.as = AVFSGNJXVV
4898 case AVFNEGV:
4899 ins.as = AVFSGNJNVV
4900 }
4901 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg)
4902
4903 case AVMANDMM, AVMNANDMM, AVMANDNMM, AVMXORMM, AVMORMM, AVMNORMM, AVMORNMM, AVMXNORMM, AVMMVM, AVMNOTM, AVCOMPRESSVM:
4904 ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)
4905 switch ins.as {
4906 case AVMMVM:
4907 ins.as, ins.rs2 = AVMANDMM, ins.rs1
4908 case AVMNOTM:
4909 ins.as, ins.rs2 = AVMNANDMM, ins.rs1
4910 }
4911
4912 case AVMCLRM, AVMSETM:
4913 ins.rd, ins.rs1, ins.rs2 = uint32(p.From.Reg), uint32(p.From.Reg), uint32(p.From.Reg)
4914 switch ins.as {
4915 case AVMCLRM:
4916 ins.as = AVMXORMM
4917 case AVMSETM:
4918 ins.as = AVMXNORMM
4919 }
4920
4921 case AVCPOPM, AVFIRSTM, AVMSBFM, AVMSIFM, AVMSOFM, AVIOTAM:
4922
4923 switch {
4924 case ins.rs1 == obj.REG_NONE:
4925 ins.funct7 |= 1
4926 case ins.rs1 != REG_V0:
4927 p.Ctxt.Diag("%v: invalid vector mask register", p)
4928 }
4929 ins.rs1 = obj.REG_NONE
4930
4931 case AVIDV:
4932
4933 switch {
4934 case ins.rd == obj.REG_NONE:
4935 ins.funct7 |= 1
4936 case ins.rd != obj.REG_NONE && ins.rs2 != REG_V0:
4937 p.Ctxt.Diag("%v: invalid vector mask register", p)
4938 }
4939 if ins.rd == obj.REG_NONE {
4940 ins.rd = uint32(p.From.Reg)
4941 }
4942 ins.rs1, ins.rs2 = obj.REG_NONE, REG_V0
4943 }
4944
4945
4946
4947
4948 if compress && p.Mark&NEED_RELOC == 0 {
4949 for _, ins := range inss {
4950 ins.compress()
4951 }
4952 }
4953
4954 for _, ins := range inss {
4955 ins.p = p
4956 }
4957
4958 return inss
4959 }
4960
4961
4962
4963 func assemble(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
4964 if ctxt.Retpoline {
4965 ctxt.Diag("-spectre=ret not supported on riscv")
4966 ctxt.Retpoline = false
4967 }
4968
4969
4970
4971 if ctxt.Errors > 0 {
4972 return
4973 }
4974
4975 for p := cursym.Func().Text; p != nil; p = p.Link {
4976 switch p.As {
4977 case AJAL:
4978 if p.Mark&NEED_JAL_RELOC == NEED_JAL_RELOC {
4979 cursym.AddRel(ctxt, obj.Reloc{
4980 Type: objabi.R_RISCV_JAL,
4981 Off: int32(p.Pc),
4982 Siz: 4,
4983 Sym: p.To.Sym,
4984 Add: p.To.Offset,
4985 })
4986 }
4987
4988 case ACJALR, AJALR:
4989 if p.To.Sym != nil {
4990 ctxt.Diag("%v: unexpected AJALR with to symbol", p)
4991 }
4992
4993 case AAUIPC, AMOV, AMOVB, AMOVH, AMOVW, AMOVBU, AMOVHU, AMOVWU, AMOVF, AMOVD:
4994 var addr *obj.Addr
4995 var rt objabi.RelocType
4996 if p.Mark&NEED_CALL_RELOC == NEED_CALL_RELOC {
4997 rt = objabi.R_RISCV_CALL
4998 addr = &p.From
4999 } else if p.Mark&NEED_PCREL_ITYPE_RELOC == NEED_PCREL_ITYPE_RELOC {
5000 rt = objabi.R_RISCV_PCREL_ITYPE
5001 addr = &p.From
5002 } else if p.Mark&NEED_PCREL_STYPE_RELOC == NEED_PCREL_STYPE_RELOC {
5003 rt = objabi.R_RISCV_PCREL_STYPE
5004 addr = &p.To
5005 } else if p.Mark&NEED_GOT_PCREL_ITYPE_RELOC == NEED_GOT_PCREL_ITYPE_RELOC {
5006 rt = objabi.R_RISCV_GOT_PCREL_ITYPE
5007 addr = &p.From
5008 } else {
5009 break
5010 }
5011 if p.As == AAUIPC {
5012 if p.Link == nil {
5013 ctxt.Diag("AUIPC needing PC-relative reloc missing following instruction")
5014 break
5015 }
5016 addr = &p.RestArgs[0].Addr
5017 }
5018 if addr.Sym == nil {
5019 ctxt.Diag("PC-relative relocation missing symbol")
5020 break
5021 }
5022 if addr.Sym.Type == objabi.STLSBSS {
5023 if ctxt.Flag_shared {
5024 rt = objabi.R_RISCV_TLS_IE
5025 } else {
5026 rt = objabi.R_RISCV_TLS_LE
5027 }
5028 }
5029
5030 cursym.AddRel(ctxt, obj.Reloc{
5031 Type: rt,
5032 Off: int32(p.Pc),
5033 Siz: 8,
5034 Sym: addr.Sym,
5035 Add: addr.Offset,
5036 })
5037
5038 case obj.APCALIGN:
5039 alignedValue := p.From.Offset
5040 v := pcAlignPadLength(p.Pc, alignedValue)
5041 offset := p.Pc
5042 for ; v >= 4; v -= 4 {
5043
5044 cursym.WriteBytes(ctxt, offset, []byte{0x13, 0x00, 0x00, 0x00})
5045 offset += 4
5046 }
5047 if v == 2 {
5048
5049 cursym.WriteBytes(ctxt, offset, []byte{0x01, 0x00})
5050 offset += 2
5051 } else if v != 0 {
5052 ctxt.Diag("bad PCALIGN pad length")
5053 }
5054 continue
5055 }
5056
5057 offset := p.Pc
5058 for _, ins := range instructionsForProg(p, ctxt.CompressInstructions) {
5059 if ic, err := ins.encode(); err == nil {
5060 cursym.WriteInt(ctxt, offset, ins.length(), int64(ic))
5061 offset += int64(ins.length())
5062 }
5063 if ins.usesRegTmp() {
5064 p.Mark |= USES_REG_TMP
5065 }
5066 }
5067 }
5068
5069 obj.MarkUnsafePoints(ctxt, cursym.Func().Text, newprog, isUnsafePoint, nil)
5070 }
5071
5072 func isUnsafePoint(p *obj.Prog) bool {
5073 return p.Mark&USES_REG_TMP == USES_REG_TMP || p.From.Reg == REG_TMP || p.To.Reg == REG_TMP || p.Reg == REG_TMP
5074 }
5075
5076 func ParseSuffix(prog *obj.Prog, cond string) (err error) {
5077 cond = strings.TrimPrefix(cond, ".")
5078 switch prog.As {
5079 case AFCVTWS, AFCVTLS, AFCVTWUS, AFCVTLUS, AFCVTWD, AFCVTLD, AFCVTWUD, AFCVTLUD:
5080 prog.Scond, err = rmSuffixEncode(cond)
5081 case AFENCE:
5082 if cond == "TSO" {
5083 prog.Scond = fenceTsoSuffixBit
5084 } else {
5085 err = fmt.Errorf("unrecognized suffix .%q", cond)
5086 }
5087 default:
5088 if cond != "" {
5089 err = fmt.Errorf("unrecognized suffix .%q", cond)
5090 }
5091 }
5092 return
5093 }
5094
5095 var LinkRISCV64 = obj.LinkArch{
5096 Arch: sys.ArchRISCV64,
5097 Init: buildop,
5098 Preprocess: preprocess,
5099 Assemble: assemble,
5100 Progedit: progedit,
5101 UnaryDst: unaryDst,
5102 DWARFRegisters: RISCV64DWARFRegisters,
5103 }
5104
View as plain text