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