1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package x86
32
33 import (
34 "cmd/internal/obj"
35 "cmd/internal/objabi"
36 "cmd/internal/sys"
37 "encoding/binary"
38 "fmt"
39 "internal/buildcfg"
40 "log"
41 "strings"
42 )
43
44 var (
45 plan9privates *obj.LSym
46 )
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 const (
63 loopAlign = 16
64 maxLoopPad = 0
65 )
66
67
68 const (
69
70
71 branchBackwards = (1 << iota)
72
73
74 branchShort
75
76
77 branchLoopHead
78 )
79
80
81
82
83
84
85 type opBytes [31]uint8
86
87 type Optab struct {
88 as obj.As
89 ytab []ytab
90 prefix uint8
91 op opBytes
92 }
93
94 type movtab struct {
95 as obj.As
96 ft uint8
97 f3t uint8
98 tt uint8
99 code uint8
100 op [4]uint8
101 }
102
103 const (
104 Yxxx = iota
105 Ynone
106 Yi0
107 Yi1
108 Yu2
109 Yi8
110 Yu8
111 Yu7
112 Ys32
113 Yi32
114 Yi64
115 Yiauto
116 Yal
117 Ycl
118 Yax
119 Ycx
120 Yrb
121 Yrl
122 Yrl32
123 Yrf
124 Yf0
125 Yrx
126 Ymb
127 Yml
128 Ym
129 Ybr
130 Ycs
131 Yss
132 Yds
133 Yes
134 Yfs
135 Ygs
136 Ygdtr
137 Yidtr
138 Yldtr
139 Ymsw
140 Ytask
141 Ycr0
142 Ycr1
143 Ycr2
144 Ycr3
145 Ycr4
146 Ycr5
147 Ycr6
148 Ycr7
149 Ycr8
150 Ydr0
151 Ydr1
152 Ydr2
153 Ydr3
154 Ydr4
155 Ydr5
156 Ydr6
157 Ydr7
158 Ytr0
159 Ytr1
160 Ytr2
161 Ytr3
162 Ytr4
163 Ytr5
164 Ytr6
165 Ytr7
166 Ymr
167 Ymm
168 Yxr0
169 YxrEvexMulti4
170 Yxr
171 YxrEvex
172 Yxm
173 YxmEvex
174 Yxvm
175 YxvmEvex
176 YyrEvexMulti4
177 Yyr
178 YyrEvex
179 Yym
180 YymEvex
181 Yyvm
182 YyvmEvex
183 YzrMulti4
184 Yzr
185 Yzm
186 Yzvm
187 Yk0
188 Yknot0
189 Yk
190 Ykm
191 Ytls
192 Ytextsize
193 Yindir
194 Ymax
195 )
196
197 const (
198 Zxxx = iota
199 Zlit
200 Zlitm_r
201 Zlitr_m
202 Zlit_m_r
203 Z_rp
204 Zbr
205 Zcall
206 Zcallcon
207 Zcallduff
208 Zcallind
209 Zcallindreg
210 Zib_
211 Zib_rp
212 Zibo_m
213 Zibo_m_xm
214 Zil_
215 Zil_rp
216 Ziq_rp
217 Zilo_m
218 Zjmp
219 Zjmpcon
220 Zloop
221 Zo_iw
222 Zm_o
223 Zm_r
224 Z_m_r
225 Zm2_r
226 Zm_r_xm
227 Zm_r_i_xm
228 Zm_r_xm_nr
229 Zr_m_xm_nr
230 Zibm_r
231 Zibr_m
232 Zmb_r
233 Zaut_r
234 Zo_m
235 Zo_m64
236 Zpseudo
237 Zr_m
238 Zr_m_xm
239 Zrp_
240 Z_ib
241 Z_il
242 Zm_ibo
243 Zm_ilo
244 Zib_rr
245 Zil_rr
246 Zbyte
247
248 Zvex_rm_v_r
249 Zvex_rm_v_ro
250 Zvex_r_v_rm
251 Zvex_i_rm_vo
252 Zvex_v_rm_r
253 Zvex_i_rm_r
254 Zvex_i_r_v
255 Zvex_i_rm_v_r
256 Zvex
257 Zvex_rm_r_vo
258 Zvex_i_r_rm
259 Zvex_hr_rm_v_r
260
261 Zevex_first
262 Zevex_i_r_k_rm
263 Zevex_i_r_rm
264 Zevex_i_rm_k_r
265 Zevex_i_rm_k_vo
266 Zevex_i_rm_r
267 Zevex_i_rm_v_k_r
268 Zevex_i_rm_v_r
269 Zevex_i_rm_vo
270 Zevex_k_rmo
271 Zevex_r_k_rm
272 Zevex_r_v_k_rm
273 Zevex_r_v_rm
274 Zevex_rm_k_r
275 Zevex_rm_v_k_r
276 Zevex_rm_v_r
277 Zevex_last
278
279 Zmax
280 )
281
282 const (
283 Px = 0
284 Px1 = 1
285 P32 = 0x32
286 Pe = 0x66
287 Pm = 0x0f
288 Pq = 0xff
289 Pb = 0xfe
290 Pf2 = 0xf2
291 Pf3 = 0xf3
292 Pef3 = 0xf5
293 Pq3 = 0x67
294 Pq4 = 0x68
295 Pq4w = 0x69
296 Pq5 = 0x6a
297 Pq5w = 0x6b
298 Pfw = 0xf4
299 Pw = 0x48
300 Pw8 = 0x90
301 Py = 0x80
302 Py1 = 0x81
303 Py3 = 0x83
304 Pavx = 0x84
305
306 RxrEvex = 1 << 4
307 Rxw = 1 << 3
308 Rxr = 1 << 2
309 Rxx = 1 << 1
310 Rxb = 1 << 0
311 )
312
313 const (
314
315
316
317
318
319
320
321
322
323
324 avxEscape = 1 << 6
325
326
327 vex66 = 1 << 0
328 vexF3 = 2 << 0
329 vexF2 = 3 << 0
330
331 vexLZ = 0 << 2
332 vexLIG = 0 << 2
333 vex128 = 0 << 2
334 vex256 = 1 << 2
335
336 vexWIG = 0 << 7
337 vexW0 = 0 << 7
338 vexW1 = 1 << 7
339
340 vex0F = 1 << 3
341 vex0F38 = 2 << 3
342 vex0F3A = 3 << 3
343 )
344
345 var ycover [Ymax * Ymax]uint8
346
347 var reg [MAXREG]int
348
349 var regrex [MAXREG + 1]int
350
351 var ynone = []ytab{
352 {Zlit, 1, argList{}},
353 }
354
355 var ytext = []ytab{
356 {Zpseudo, 0, argList{Ymb, Ytextsize}},
357 {Zpseudo, 1, argList{Ymb, Yi32, Ytextsize}},
358 }
359
360 var ynop = []ytab{
361 {Zpseudo, 0, argList{}},
362 {Zpseudo, 0, argList{Yiauto}},
363 {Zpseudo, 0, argList{Yml}},
364 {Zpseudo, 0, argList{Yrf}},
365 {Zpseudo, 0, argList{Yxr}},
366 {Zpseudo, 0, argList{Yiauto}},
367 {Zpseudo, 0, argList{Yml}},
368 {Zpseudo, 0, argList{Yrf}},
369 {Zpseudo, 1, argList{Yxr}},
370 }
371
372 var yfuncdata = []ytab{
373 {Zpseudo, 0, argList{Yi32, Ym}},
374 }
375
376 var ypcdata = []ytab{
377 {Zpseudo, 0, argList{Yi32, Yi32}},
378 }
379
380 var yxorb = []ytab{
381 {Zib_, 1, argList{Yi32, Yal}},
382 {Zibo_m, 2, argList{Yi32, Ymb}},
383 {Zr_m, 1, argList{Yrb, Ymb}},
384 {Zm_r, 1, argList{Ymb, Yrb}},
385 }
386
387 var yaddl = []ytab{
388 {Zibo_m, 2, argList{Yi8, Yml}},
389 {Zil_, 1, argList{Yi32, Yax}},
390 {Zilo_m, 2, argList{Yi32, Yml}},
391 {Zr_m, 1, argList{Yrl, Yml}},
392 {Zm_r, 1, argList{Yml, Yrl}},
393 }
394
395 var yincl = []ytab{
396 {Z_rp, 1, argList{Yrl}},
397 {Zo_m, 2, argList{Yml}},
398 }
399
400 var yincq = []ytab{
401 {Zo_m, 2, argList{Yml}},
402 }
403
404 var ycmpb = []ytab{
405 {Z_ib, 1, argList{Yal, Yi32}},
406 {Zm_ibo, 2, argList{Ymb, Yi32}},
407 {Zm_r, 1, argList{Ymb, Yrb}},
408 {Zr_m, 1, argList{Yrb, Ymb}},
409 }
410
411 var ycmpl = []ytab{
412 {Zm_ibo, 2, argList{Yml, Yi8}},
413 {Z_il, 1, argList{Yax, Yi32}},
414 {Zm_ilo, 2, argList{Yml, Yi32}},
415 {Zm_r, 1, argList{Yml, Yrl}},
416 {Zr_m, 1, argList{Yrl, Yml}},
417 }
418
419 var yshb = []ytab{
420 {Zo_m, 2, argList{Yi1, Ymb}},
421 {Zibo_m, 2, argList{Yu8, Ymb}},
422 {Zo_m, 2, argList{Ycx, Ymb}},
423 }
424
425 var yshl = []ytab{
426 {Zo_m, 2, argList{Yi1, Yml}},
427 {Zibo_m, 2, argList{Yu8, Yml}},
428 {Zo_m, 2, argList{Ycl, Yml}},
429 {Zo_m, 2, argList{Ycx, Yml}},
430 }
431
432 var ytestl = []ytab{
433 {Zil_, 1, argList{Yi32, Yax}},
434 {Zilo_m, 2, argList{Yi32, Yml}},
435 {Zr_m, 1, argList{Yrl, Yml}},
436 {Zm_r, 1, argList{Yml, Yrl}},
437 }
438
439 var ymovb = []ytab{
440 {Zr_m, 1, argList{Yrb, Ymb}},
441 {Zm_r, 1, argList{Ymb, Yrb}},
442 {Zib_rp, 1, argList{Yi32, Yrb}},
443 {Zibo_m, 2, argList{Yi32, Ymb}},
444 }
445
446 var ybtl = []ytab{
447 {Zibo_m, 2, argList{Yi8, Yml}},
448 {Zr_m, 1, argList{Yrl, Yml}},
449 }
450
451 var ymovw = []ytab{
452 {Zr_m, 1, argList{Yrl, Yml}},
453 {Zm_r, 1, argList{Yml, Yrl}},
454 {Zil_rp, 1, argList{Yi32, Yrl}},
455 {Zilo_m, 2, argList{Yi32, Yml}},
456 {Zaut_r, 2, argList{Yiauto, Yrl}},
457 }
458
459 var ymovl = []ytab{
460 {Zr_m, 1, argList{Yrl, Yml}},
461 {Zm_r, 1, argList{Yml, Yrl}},
462 {Zil_rp, 1, argList{Yi32, Yrl}},
463 {Zilo_m, 2, argList{Yi32, Yml}},
464 {Zm_r_xm, 1, argList{Yml, Ymr}},
465 {Zr_m_xm, 1, argList{Ymr, Yml}},
466 {Zm_r_xm, 2, argList{Yml, Yxr}},
467 {Zr_m_xm, 2, argList{Yxr, Yml}},
468 {Zaut_r, 2, argList{Yiauto, Yrl}},
469 }
470
471 var yret = []ytab{
472 {Zo_iw, 1, argList{}},
473 {Zo_iw, 1, argList{Yi32}},
474 }
475
476 var ymovq = []ytab{
477
478 {Zm_r_xm_nr, 1, argList{Ym, Ymr}},
479 {Zr_m_xm_nr, 1, argList{Ymr, Ym}},
480 {Zm_r_xm_nr, 2, argList{Yxr, Ymr}},
481 {Zm_r_xm_nr, 2, argList{Yxm, Yxr}},
482 {Zr_m_xm_nr, 2, argList{Yxr, Yxm}},
483
484
485 {Zr_m, 1, argList{Yrl, Yml}},
486 {Zm_r, 1, argList{Yml, Yrl}},
487 {Ziq_rp, 1, argList{Yi64, Yrl}},
488 {Zilo_m, 2, argList{Yi32, Yml}},
489 {Zm_r_xm, 1, argList{Ymm, Ymr}},
490 {Zr_m_xm, 1, argList{Ymr, Ymm}},
491 {Zm_r_xm, 2, argList{Yml, Yxr}},
492 {Zr_m_xm, 2, argList{Yxr, Yml}},
493 {Zaut_r, 1, argList{Yiauto, Yrl}},
494 }
495
496 var ymovbe = []ytab{
497 {Zlitm_r, 3, argList{Ym, Yrl}},
498 {Zlitr_m, 3, argList{Yrl, Ym}},
499 }
500
501 var ym_rl = []ytab{
502 {Zm_r, 1, argList{Ym, Yrl}},
503 }
504
505 var yrl_m = []ytab{
506 {Zr_m, 1, argList{Yrl, Ym}},
507 }
508
509 var ymb_rl = []ytab{
510 {Zmb_r, 1, argList{Ymb, Yrl}},
511 }
512
513 var yml_rl = []ytab{
514 {Zm_r, 1, argList{Yml, Yrl}},
515 }
516
517 var yrl_ml = []ytab{
518 {Zr_m, 1, argList{Yrl, Yml}},
519 }
520
521 var yml_mb = []ytab{
522 {Zr_m, 1, argList{Yrb, Ymb}},
523 {Zm_r, 1, argList{Ymb, Yrb}},
524 }
525
526 var yrb_mb = []ytab{
527 {Zr_m, 1, argList{Yrb, Ymb}},
528 }
529
530 var yxchg = []ytab{
531 {Z_rp, 1, argList{Yax, Yrl}},
532 {Zrp_, 1, argList{Yrl, Yax}},
533 {Zr_m, 1, argList{Yrl, Yml}},
534 {Zm_r, 1, argList{Yml, Yrl}},
535 }
536
537 var ydivl = []ytab{
538 {Zm_o, 2, argList{Yml}},
539 }
540
541 var ydivb = []ytab{
542 {Zm_o, 2, argList{Ymb}},
543 }
544
545 var yimul = []ytab{
546 {Zm_o, 2, argList{Yml}},
547 {Zib_rr, 1, argList{Yi8, Yrl}},
548 {Zil_rr, 1, argList{Yi32, Yrl}},
549 {Zm_r, 2, argList{Yml, Yrl}},
550 }
551
552 var yimul3 = []ytab{
553 {Zibm_r, 2, argList{Yi8, Yml, Yrl}},
554 {Zibm_r, 2, argList{Yi32, Yml, Yrl}},
555 }
556
557 var ybyte = []ytab{
558 {Zbyte, 1, argList{Yi64}},
559 }
560
561 var yin = []ytab{
562 {Zib_, 1, argList{Yi32}},
563 {Zlit, 1, argList{}},
564 }
565
566 var yint = []ytab{
567 {Zib_, 1, argList{Yi32}},
568 }
569
570 var ypushl = []ytab{
571 {Zrp_, 1, argList{Yrl}},
572 {Zm_o, 2, argList{Ym}},
573 {Zib_, 1, argList{Yi8}},
574 {Zil_, 1, argList{Yi32}},
575 }
576
577 var ypopl = []ytab{
578 {Z_rp, 1, argList{Yrl}},
579 {Zo_m, 2, argList{Ym}},
580 }
581
582 var ywrfsbase = []ytab{
583 {Zm_o, 2, argList{Yrl}},
584 }
585
586 var yrdrand = []ytab{
587 {Zo_m, 2, argList{Yrl}},
588 }
589
590 var yclflush = []ytab{
591 {Zo_m, 2, argList{Ym}},
592 }
593
594 var ybswap = []ytab{
595 {Z_rp, 2, argList{Yrl}},
596 }
597
598 var yscond = []ytab{
599 {Zo_m, 2, argList{Ymb}},
600 }
601
602 var yjcond = []ytab{
603 {Zbr, 0, argList{Ybr}},
604 {Zbr, 0, argList{Yi0, Ybr}},
605 {Zbr, 1, argList{Yi1, Ybr}},
606 }
607
608 var yloop = []ytab{
609 {Zloop, 1, argList{Ybr}},
610 }
611
612 var ycall = []ytab{
613 {Zcallindreg, 0, argList{Yml}},
614 {Zcallindreg, 2, argList{Yrx, Yrx}},
615 {Zcallind, 2, argList{Yindir}},
616 {Zcall, 0, argList{Ybr}},
617 {Zcallcon, 1, argList{Yi32}},
618 }
619
620 var yduff = []ytab{
621 {Zcallduff, 1, argList{Yi32}},
622 }
623
624 var yjmp = []ytab{
625 {Zo_m64, 2, argList{Yml}},
626 {Zjmp, 0, argList{Ybr}},
627 {Zjmpcon, 1, argList{Yi32}},
628 }
629
630 var yfmvd = []ytab{
631 {Zm_o, 2, argList{Ym, Yf0}},
632 {Zo_m, 2, argList{Yf0, Ym}},
633 {Zm_o, 2, argList{Yrf, Yf0}},
634 {Zo_m, 2, argList{Yf0, Yrf}},
635 }
636
637 var yfmvdp = []ytab{
638 {Zo_m, 2, argList{Yf0, Ym}},
639 {Zo_m, 2, argList{Yf0, Yrf}},
640 }
641
642 var yfmvf = []ytab{
643 {Zm_o, 2, argList{Ym, Yf0}},
644 {Zo_m, 2, argList{Yf0, Ym}},
645 }
646
647 var yfmvx = []ytab{
648 {Zm_o, 2, argList{Ym, Yf0}},
649 }
650
651 var yfmvp = []ytab{
652 {Zo_m, 2, argList{Yf0, Ym}},
653 }
654
655 var yfcmv = []ytab{
656 {Zm_o, 2, argList{Yrf, Yf0}},
657 }
658
659 var yfadd = []ytab{
660 {Zm_o, 2, argList{Ym, Yf0}},
661 {Zm_o, 2, argList{Yrf, Yf0}},
662 {Zo_m, 2, argList{Yf0, Yrf}},
663 }
664
665 var yfxch = []ytab{
666 {Zo_m, 2, argList{Yf0, Yrf}},
667 {Zm_o, 2, argList{Yrf, Yf0}},
668 }
669
670 var ycompp = []ytab{
671 {Zo_m, 2, argList{Yf0, Yrf}},
672 }
673
674 var ystsw = []ytab{
675 {Zo_m, 2, argList{Ym}},
676 {Zlit, 1, argList{Yax}},
677 }
678
679 var ysvrs_mo = []ytab{
680 {Zm_o, 2, argList{Ym}},
681 }
682
683
684 var ysvrs_om = []ytab{
685 {Zo_m, 2, argList{Ym}},
686 }
687
688 var ymm = []ytab{
689 {Zm_r_xm, 1, argList{Ymm, Ymr}},
690 {Zm_r_xm, 2, argList{Yxm, Yxr}},
691 }
692
693 var yxm = []ytab{
694 {Zm_r_xm, 1, argList{Yxm, Yxr}},
695 }
696
697 var yxm_q4 = []ytab{
698 {Zm_r, 1, argList{Yxm, Yxr}},
699 }
700
701 var yxcvm1 = []ytab{
702 {Zm_r_xm, 2, argList{Yxm, Yxr}},
703 {Zm_r_xm, 2, argList{Yxm, Ymr}},
704 }
705
706 var yxcvm2 = []ytab{
707 {Zm_r_xm, 2, argList{Yxm, Yxr}},
708 {Zm_r_xm, 2, argList{Ymm, Yxr}},
709 }
710
711 var yxr = []ytab{
712 {Zm_r_xm, 1, argList{Yxr, Yxr}},
713 }
714
715 var yxr_ml = []ytab{
716 {Zr_m_xm, 1, argList{Yxr, Yml}},
717 }
718
719 var ymr = []ytab{
720 {Zm_r, 1, argList{Ymr, Ymr}},
721 }
722
723 var ymr_ml = []ytab{
724 {Zr_m_xm, 1, argList{Ymr, Yml}},
725 }
726
727 var yxcmpi = []ytab{
728 {Zm_r_i_xm, 2, argList{Yxm, Yxr, Yi8}},
729 }
730
731 var yxmov = []ytab{
732 {Zm_r_xm, 1, argList{Yxm, Yxr}},
733 {Zr_m_xm, 1, argList{Yxr, Yxm}},
734 }
735
736 var yxcvfl = []ytab{
737 {Zm_r_xm, 1, argList{Yxm, Yrl}},
738 }
739
740 var yxcvlf = []ytab{
741 {Zm_r_xm, 1, argList{Yml, Yxr}},
742 }
743
744 var yxcvfq = []ytab{
745 {Zm_r_xm, 2, argList{Yxm, Yrl}},
746 }
747
748 var yxcvqf = []ytab{
749 {Zm_r_xm, 2, argList{Yml, Yxr}},
750 }
751
752 var yps = []ytab{
753 {Zm_r_xm, 1, argList{Ymm, Ymr}},
754 {Zibo_m_xm, 2, argList{Yi8, Ymr}},
755 {Zm_r_xm, 2, argList{Yxm, Yxr}},
756 {Zibo_m_xm, 3, argList{Yi8, Yxr}},
757 }
758
759 var yxrrl = []ytab{
760 {Zm_r, 1, argList{Yxr, Yrl}},
761 }
762
763 var ymrxr = []ytab{
764 {Zm_r, 1, argList{Ymr, Yxr}},
765 {Zm_r_xm, 1, argList{Yxm, Yxr}},
766 }
767
768 var ymshuf = []ytab{
769 {Zibm_r, 2, argList{Yi8, Ymm, Ymr}},
770 }
771
772 var ymshufb = []ytab{
773 {Zm2_r, 2, argList{Yxm, Yxr}},
774 }
775
776
777
778
779
780
781 var yxshuf = []ytab{
782 {Zibm_r, 2, argList{Yu8, Yxm, Yxr}},
783 }
784
785 var yextrw = []ytab{
786 {Zibm_r, 2, argList{Yu8, Yxr, Yrl}},
787 {Zibr_m, 2, argList{Yu8, Yxr, Yml}},
788 }
789
790 var yextr = []ytab{
791 {Zibr_m, 3, argList{Yu8, Yxr, Ymm}},
792 }
793
794 var yinsrw = []ytab{
795 {Zibm_r, 2, argList{Yu8, Yml, Yxr}},
796 }
797
798 var yinsr = []ytab{
799 {Zibm_r, 3, argList{Yu8, Ymm, Yxr}},
800 }
801
802 var ypsdq = []ytab{
803 {Zibo_m, 2, argList{Yi8, Yxr}},
804 }
805
806 var ymskb = []ytab{
807 {Zm_r_xm, 2, argList{Yxr, Yrl}},
808 {Zm_r_xm, 1, argList{Ymr, Yrl}},
809 }
810
811 var ycrc32l = []ytab{
812 {Zlitm_r, 0, argList{Yml, Yrl}},
813 }
814
815 var ycrc32b = []ytab{
816 {Zlitm_r, 0, argList{Ymb, Yrl}},
817 }
818
819 var yprefetch = []ytab{
820 {Zm_o, 2, argList{Ym}},
821 }
822
823 var yaes = []ytab{
824 {Zlitm_r, 2, argList{Yxm, Yxr}},
825 }
826
827 var yxbegin = []ytab{
828 {Zjmp, 1, argList{Ybr}},
829 }
830
831 var yxabort = []ytab{
832 {Zib_, 1, argList{Yu8}},
833 }
834
835 var ylddqu = []ytab{
836 {Zm_r, 1, argList{Ym, Yxr}},
837 }
838
839 var ypalignr = []ytab{
840 {Zibm_r, 2, argList{Yu8, Yxm, Yxr}},
841 }
842
843 var ysha256rnds2 = []ytab{
844 {Zlit_m_r, 0, argList{Yxr0, Yxm, Yxr}},
845 }
846
847 var yblendvpd = []ytab{
848 {Z_m_r, 1, argList{Yxr0, Yxm, Yxr}},
849 }
850
851 var ymmxmm0f38 = []ytab{
852 {Zlitm_r, 3, argList{Ymm, Ymr}},
853 {Zlitm_r, 5, argList{Yxm, Yxr}},
854 }
855
856 var yextractps = []ytab{
857 {Zibr_m, 2, argList{Yu2, Yxr, Yml}},
858 }
859
860 var ysha1rnds4 = []ytab{
861 {Zibm_r, 2, argList{Yu2, Yxm, Yxr}},
862 }
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920 var optab =
921
922 [...]Optab{
923 {obj.AXXX, nil, 0, opBytes{}},
924 {AAAA, ynone, P32, opBytes{0x37}},
925 {AAAD, ynone, P32, opBytes{0xd5, 0x0a}},
926 {AAAM, ynone, P32, opBytes{0xd4, 0x0a}},
927 {AAAS, ynone, P32, opBytes{0x3f}},
928 {AADCB, yxorb, Pb, opBytes{0x14, 0x80, 02, 0x10, 0x12}},
929 {AADCL, yaddl, Px, opBytes{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}},
930 {AADCQ, yaddl, Pw, opBytes{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}},
931 {AADCW, yaddl, Pe, opBytes{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}},
932 {AADCXL, yml_rl, Pq4, opBytes{0xf6}},
933 {AADCXQ, yml_rl, Pq4w, opBytes{0xf6}},
934 {AADDB, yxorb, Pb, opBytes{0x04, 0x80, 00, 0x00, 0x02}},
935 {AADDL, yaddl, Px, opBytes{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}},
936 {AADDPD, yxm, Pq, opBytes{0x58}},
937 {AADDPS, yxm, Pm, opBytes{0x58}},
938 {AADDQ, yaddl, Pw, opBytes{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}},
939 {AADDSD, yxm, Pf2, opBytes{0x58}},
940 {AADDSS, yxm, Pf3, opBytes{0x58}},
941 {AADDSUBPD, yxm, Pq, opBytes{0xd0}},
942 {AADDSUBPS, yxm, Pf2, opBytes{0xd0}},
943 {AADDW, yaddl, Pe, opBytes{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}},
944 {AADOXL, yml_rl, Pq5, opBytes{0xf6}},
945 {AADOXQ, yml_rl, Pq5w, opBytes{0xf6}},
946 {AADJSP, nil, 0, opBytes{}},
947 {AANDB, yxorb, Pb, opBytes{0x24, 0x80, 04, 0x20, 0x22}},
948 {AANDL, yaddl, Px, opBytes{0x83, 04, 0x25, 0x81, 04, 0x21, 0x23}},
949 {AANDNPD, yxm, Pq, opBytes{0x55}},
950 {AANDNPS, yxm, Pm, opBytes{0x55}},
951 {AANDPD, yxm, Pq, opBytes{0x54}},
952 {AANDPS, yxm, Pm, opBytes{0x54}},
953 {AANDQ, yaddl, Pw, opBytes{0x83, 04, 0x25, 0x81, 04, 0x21, 0x23}},
954 {AANDW, yaddl, Pe, opBytes{0x83, 04, 0x25, 0x81, 04, 0x21, 0x23}},
955 {AARPL, yrl_ml, P32, opBytes{0x63}},
956 {ABOUNDL, yrl_m, P32, opBytes{0x62}},
957 {ABOUNDW, yrl_m, Pe, opBytes{0x62}},
958 {ABSFL, yml_rl, Pm, opBytes{0xbc}},
959 {ABSFQ, yml_rl, Pw, opBytes{0x0f, 0xbc}},
960 {ABSFW, yml_rl, Pq, opBytes{0xbc}},
961 {ABSRL, yml_rl, Pm, opBytes{0xbd}},
962 {ABSRQ, yml_rl, Pw, opBytes{0x0f, 0xbd}},
963 {ABSRW, yml_rl, Pq, opBytes{0xbd}},
964 {ABSWAPL, ybswap, Px, opBytes{0x0f, 0xc8}},
965 {ABSWAPQ, ybswap, Pw, opBytes{0x0f, 0xc8}},
966 {ABTCL, ybtl, Pm, opBytes{0xba, 07, 0xbb}},
967 {ABTCQ, ybtl, Pw, opBytes{0x0f, 0xba, 07, 0x0f, 0xbb}},
968 {ABTCW, ybtl, Pq, opBytes{0xba, 07, 0xbb}},
969 {ABTL, ybtl, Pm, opBytes{0xba, 04, 0xa3}},
970 {ABTQ, ybtl, Pw, opBytes{0x0f, 0xba, 04, 0x0f, 0xa3}},
971 {ABTRL, ybtl, Pm, opBytes{0xba, 06, 0xb3}},
972 {ABTRQ, ybtl, Pw, opBytes{0x0f, 0xba, 06, 0x0f, 0xb3}},
973 {ABTRW, ybtl, Pq, opBytes{0xba, 06, 0xb3}},
974 {ABTSL, ybtl, Pm, opBytes{0xba, 05, 0xab}},
975 {ABTSQ, ybtl, Pw, opBytes{0x0f, 0xba, 05, 0x0f, 0xab}},
976 {ABTSW, ybtl, Pq, opBytes{0xba, 05, 0xab}},
977 {ABTW, ybtl, Pq, opBytes{0xba, 04, 0xa3}},
978 {ABYTE, ybyte, Px, opBytes{1}},
979 {obj.ACALL, ycall, Px, opBytes{0xff, 02, 0xff, 0x15, 0xe8}},
980 {ACBW, ynone, Pe, opBytes{0x98}},
981 {ACDQ, ynone, Px, opBytes{0x99}},
982 {ACDQE, ynone, Pw, opBytes{0x98}},
983 {ACLAC, ynone, Pm, opBytes{01, 0xca}},
984 {ACLC, ynone, Px, opBytes{0xf8}},
985 {ACLD, ynone, Px, opBytes{0xfc}},
986 {ACLDEMOTE, yclflush, Pm, opBytes{0x1c, 00}},
987 {ACLFLUSH, yclflush, Pm, opBytes{0xae, 07}},
988 {ACLFLUSHOPT, yclflush, Pq, opBytes{0xae, 07}},
989 {ACLI, ynone, Px, opBytes{0xfa}},
990 {ACLTS, ynone, Pm, opBytes{0x06}},
991 {ACLWB, yclflush, Pq, opBytes{0xae, 06}},
992 {ACMC, ynone, Px, opBytes{0xf5}},
993 {ACMOVLCC, yml_rl, Pm, opBytes{0x43}},
994 {ACMOVLCS, yml_rl, Pm, opBytes{0x42}},
995 {ACMOVLEQ, yml_rl, Pm, opBytes{0x44}},
996 {ACMOVLGE, yml_rl, Pm, opBytes{0x4d}},
997 {ACMOVLGT, yml_rl, Pm, opBytes{0x4f}},
998 {ACMOVLHI, yml_rl, Pm, opBytes{0x47}},
999 {ACMOVLLE, yml_rl, Pm, opBytes{0x4e}},
1000 {ACMOVLLS, yml_rl, Pm, opBytes{0x46}},
1001 {ACMOVLLT, yml_rl, Pm, opBytes{0x4c}},
1002 {ACMOVLMI, yml_rl, Pm, opBytes{0x48}},
1003 {ACMOVLNE, yml_rl, Pm, opBytes{0x45}},
1004 {ACMOVLOC, yml_rl, Pm, opBytes{0x41}},
1005 {ACMOVLOS, yml_rl, Pm, opBytes{0x40}},
1006 {ACMOVLPC, yml_rl, Pm, opBytes{0x4b}},
1007 {ACMOVLPL, yml_rl, Pm, opBytes{0x49}},
1008 {ACMOVLPS, yml_rl, Pm, opBytes{0x4a}},
1009 {ACMOVQCC, yml_rl, Pw, opBytes{0x0f, 0x43}},
1010 {ACMOVQCS, yml_rl, Pw, opBytes{0x0f, 0x42}},
1011 {ACMOVQEQ, yml_rl, Pw, opBytes{0x0f, 0x44}},
1012 {ACMOVQGE, yml_rl, Pw, opBytes{0x0f, 0x4d}},
1013 {ACMOVQGT, yml_rl, Pw, opBytes{0x0f, 0x4f}},
1014 {ACMOVQHI, yml_rl, Pw, opBytes{0x0f, 0x47}},
1015 {ACMOVQLE, yml_rl, Pw, opBytes{0x0f, 0x4e}},
1016 {ACMOVQLS, yml_rl, Pw, opBytes{0x0f, 0x46}},
1017 {ACMOVQLT, yml_rl, Pw, opBytes{0x0f, 0x4c}},
1018 {ACMOVQMI, yml_rl, Pw, opBytes{0x0f, 0x48}},
1019 {ACMOVQNE, yml_rl, Pw, opBytes{0x0f, 0x45}},
1020 {ACMOVQOC, yml_rl, Pw, opBytes{0x0f, 0x41}},
1021 {ACMOVQOS, yml_rl, Pw, opBytes{0x0f, 0x40}},
1022 {ACMOVQPC, yml_rl, Pw, opBytes{0x0f, 0x4b}},
1023 {ACMOVQPL, yml_rl, Pw, opBytes{0x0f, 0x49}},
1024 {ACMOVQPS, yml_rl, Pw, opBytes{0x0f, 0x4a}},
1025 {ACMOVWCC, yml_rl, Pq, opBytes{0x43}},
1026 {ACMOVWCS, yml_rl, Pq, opBytes{0x42}},
1027 {ACMOVWEQ, yml_rl, Pq, opBytes{0x44}},
1028 {ACMOVWGE, yml_rl, Pq, opBytes{0x4d}},
1029 {ACMOVWGT, yml_rl, Pq, opBytes{0x4f}},
1030 {ACMOVWHI, yml_rl, Pq, opBytes{0x47}},
1031 {ACMOVWLE, yml_rl, Pq, opBytes{0x4e}},
1032 {ACMOVWLS, yml_rl, Pq, opBytes{0x46}},
1033 {ACMOVWLT, yml_rl, Pq, opBytes{0x4c}},
1034 {ACMOVWMI, yml_rl, Pq, opBytes{0x48}},
1035 {ACMOVWNE, yml_rl, Pq, opBytes{0x45}},
1036 {ACMOVWOC, yml_rl, Pq, opBytes{0x41}},
1037 {ACMOVWOS, yml_rl, Pq, opBytes{0x40}},
1038 {ACMOVWPC, yml_rl, Pq, opBytes{0x4b}},
1039 {ACMOVWPL, yml_rl, Pq, opBytes{0x49}},
1040 {ACMOVWPS, yml_rl, Pq, opBytes{0x4a}},
1041 {ACMPB, ycmpb, Pb, opBytes{0x3c, 0x80, 07, 0x38, 0x3a}},
1042 {ACMPL, ycmpl, Px, opBytes{0x83, 07, 0x3d, 0x81, 07, 0x39, 0x3b}},
1043 {ACMPPD, yxcmpi, Px, opBytes{Pe, 0xc2}},
1044 {ACMPPS, yxcmpi, Pm, opBytes{0xc2, 0}},
1045 {ACMPQ, ycmpl, Pw, opBytes{0x83, 07, 0x3d, 0x81, 07, 0x39, 0x3b}},
1046 {ACMPSB, ynone, Pb, opBytes{0xa6}},
1047 {ACMPSD, yxcmpi, Px, opBytes{Pf2, 0xc2}},
1048 {ACMPSL, ynone, Px, opBytes{0xa7}},
1049 {ACMPSQ, ynone, Pw, opBytes{0xa7}},
1050 {ACMPSS, yxcmpi, Px, opBytes{Pf3, 0xc2}},
1051 {ACMPSW, ynone, Pe, opBytes{0xa7}},
1052 {ACMPW, ycmpl, Pe, opBytes{0x83, 07, 0x3d, 0x81, 07, 0x39, 0x3b}},
1053 {ACOMISD, yxm, Pe, opBytes{0x2f}},
1054 {ACOMISS, yxm, Pm, opBytes{0x2f}},
1055 {ACPUID, ynone, Pm, opBytes{0xa2}},
1056 {ACVTPL2PD, yxcvm2, Px, opBytes{Pf3, 0xe6, Pe, 0x2a}},
1057 {ACVTPL2PS, yxcvm2, Pm, opBytes{0x5b, 0, 0x2a, 0}},
1058 {ACVTPD2PL, yxcvm1, Px, opBytes{Pf2, 0xe6, Pe, 0x2d}},
1059 {ACVTPD2PS, yxm, Pe, opBytes{0x5a}},
1060 {ACVTPS2PL, yxcvm1, Px, opBytes{Pe, 0x5b, Pm, 0x2d}},
1061 {ACVTPS2PD, yxm, Pm, opBytes{0x5a}},
1062 {ACVTSD2SL, yxcvfl, Pf2, opBytes{0x2d}},
1063 {ACVTSD2SQ, yxcvfq, Pw, opBytes{Pf2, 0x2d}},
1064 {ACVTSD2SS, yxm, Pf2, opBytes{0x5a}},
1065 {ACVTSL2SD, yxcvlf, Pf2, opBytes{0x2a}},
1066 {ACVTSQ2SD, yxcvqf, Pw, opBytes{Pf2, 0x2a}},
1067 {ACVTSL2SS, yxcvlf, Pf3, opBytes{0x2a}},
1068 {ACVTSQ2SS, yxcvqf, Pw, opBytes{Pf3, 0x2a}},
1069 {ACVTSS2SD, yxm, Pf3, opBytes{0x5a}},
1070 {ACVTSS2SL, yxcvfl, Pf3, opBytes{0x2d}},
1071 {ACVTSS2SQ, yxcvfq, Pw, opBytes{Pf3, 0x2d}},
1072 {ACVTTPD2PL, yxcvm1, Px, opBytes{Pe, 0xe6, Pe, 0x2c}},
1073 {ACVTTPS2PL, yxcvm1, Px, opBytes{Pf3, 0x5b, Pm, 0x2c}},
1074 {ACVTTSD2SL, yxcvfl, Pf2, opBytes{0x2c}},
1075 {ACVTTSD2SQ, yxcvfq, Pw, opBytes{Pf2, 0x2c}},
1076 {ACVTTSS2SL, yxcvfl, Pf3, opBytes{0x2c}},
1077 {ACVTTSS2SQ, yxcvfq, Pw, opBytes{Pf3, 0x2c}},
1078 {ACWD, ynone, Pe, opBytes{0x99}},
1079 {ACWDE, ynone, Px, opBytes{0x98}},
1080 {ACQO, ynone, Pw, opBytes{0x99}},
1081 {ADAA, ynone, P32, opBytes{0x27}},
1082 {ADAS, ynone, P32, opBytes{0x2f}},
1083 {ADECB, yscond, Pb, opBytes{0xfe, 01}},
1084 {ADECL, yincl, Px1, opBytes{0x48, 0xff, 01}},
1085 {ADECQ, yincq, Pw, opBytes{0xff, 01}},
1086 {ADECW, yincq, Pe, opBytes{0xff, 01}},
1087 {ADIVB, ydivb, Pb, opBytes{0xf6, 06}},
1088 {ADIVL, ydivl, Px, opBytes{0xf7, 06}},
1089 {ADIVPD, yxm, Pe, opBytes{0x5e}},
1090 {ADIVPS, yxm, Pm, opBytes{0x5e}},
1091 {ADIVQ, ydivl, Pw, opBytes{0xf7, 06}},
1092 {ADIVSD, yxm, Pf2, opBytes{0x5e}},
1093 {ADIVSS, yxm, Pf3, opBytes{0x5e}},
1094 {ADIVW, ydivl, Pe, opBytes{0xf7, 06}},
1095 {ADPPD, yxshuf, Pq, opBytes{0x3a, 0x41, 0}},
1096 {ADPPS, yxshuf, Pq, opBytes{0x3a, 0x40, 0}},
1097 {AEMMS, ynone, Pm, opBytes{0x77}},
1098 {AENDBR64, ynone, Pf3, opBytes{0x1e, 0xfa}},
1099 {AEXTRACTPS, yextractps, Pq, opBytes{0x3a, 0x17, 0}},
1100 {AENTER, nil, 0, opBytes{}},
1101 {AFXRSTOR, ysvrs_mo, Pm, opBytes{0xae, 01, 0xae, 01}},
1102 {AFXSAVE, ysvrs_om, Pm, opBytes{0xae, 00, 0xae, 00}},
1103 {AFXRSTOR64, ysvrs_mo, Pw, opBytes{0x0f, 0xae, 01, 0x0f, 0xae, 01}},
1104 {AFXSAVE64, ysvrs_om, Pw, opBytes{0x0f, 0xae, 00, 0x0f, 0xae, 00}},
1105 {AHLT, ynone, Px, opBytes{0xf4}},
1106 {AIDIVB, ydivb, Pb, opBytes{0xf6, 07}},
1107 {AIDIVL, ydivl, Px, opBytes{0xf7, 07}},
1108 {AIDIVQ, ydivl, Pw, opBytes{0xf7, 07}},
1109 {AIDIVW, ydivl, Pe, opBytes{0xf7, 07}},
1110 {AIMULB, ydivb, Pb, opBytes{0xf6, 05}},
1111 {AIMULL, yimul, Px, opBytes{0xf7, 05, 0x6b, 0x69, Pm, 0xaf}},
1112 {AIMULQ, yimul, Pw, opBytes{0xf7, 05, 0x6b, 0x69, Pm, 0xaf}},
1113 {AIMULW, yimul, Pe, opBytes{0xf7, 05, 0x6b, 0x69, Pm, 0xaf}},
1114 {AIMUL3W, yimul3, Pe, opBytes{0x6b, 00, 0x69, 00}},
1115 {AIMUL3L, yimul3, Px, opBytes{0x6b, 00, 0x69, 00}},
1116 {AIMUL3Q, yimul3, Pw, opBytes{0x6b, 00, 0x69, 00}},
1117 {AINB, yin, Pb, opBytes{0xe4, 0xec}},
1118 {AINW, yin, Pe, opBytes{0xe5, 0xed}},
1119 {AINL, yin, Px, opBytes{0xe5, 0xed}},
1120 {AINCB, yscond, Pb, opBytes{0xfe, 00}},
1121 {AINCL, yincl, Px1, opBytes{0x40, 0xff, 00}},
1122 {AINCQ, yincq, Pw, opBytes{0xff, 00}},
1123 {AINCW, yincq, Pe, opBytes{0xff, 00}},
1124 {AINSB, ynone, Pb, opBytes{0x6c}},
1125 {AINSL, ynone, Px, opBytes{0x6d}},
1126 {AINSERTPS, yxshuf, Pq, opBytes{0x3a, 0x21, 0}},
1127 {AINSW, ynone, Pe, opBytes{0x6d}},
1128 {AICEBP, ynone, Px, opBytes{0xf1}},
1129 {AINT, yint, Px, opBytes{0xcd}},
1130 {AINTO, ynone, P32, opBytes{0xce}},
1131 {AIRETL, ynone, Px, opBytes{0xcf}},
1132 {AIRETQ, ynone, Pw, opBytes{0xcf}},
1133 {AIRETW, ynone, Pe, opBytes{0xcf}},
1134 {AJCC, yjcond, Px, opBytes{0x73, 0x83, 00}},
1135 {AJCS, yjcond, Px, opBytes{0x72, 0x82}},
1136 {AJCXZL, yloop, Px, opBytes{0xe3}},
1137 {AJCXZW, yloop, Px, opBytes{0xe3}},
1138 {AJCXZQ, yloop, Px, opBytes{0xe3}},
1139 {AJEQ, yjcond, Px, opBytes{0x74, 0x84}},
1140 {AJGE, yjcond, Px, opBytes{0x7d, 0x8d}},
1141 {AJGT, yjcond, Px, opBytes{0x7f, 0x8f}},
1142 {AJHI, yjcond, Px, opBytes{0x77, 0x87}},
1143 {AJLE, yjcond, Px, opBytes{0x7e, 0x8e}},
1144 {AJLS, yjcond, Px, opBytes{0x76, 0x86}},
1145 {AJLT, yjcond, Px, opBytes{0x7c, 0x8c}},
1146 {AJMI, yjcond, Px, opBytes{0x78, 0x88}},
1147 {obj.AJMP, yjmp, Px, opBytes{0xff, 04, 0xeb, 0xe9}},
1148 {AJNE, yjcond, Px, opBytes{0x75, 0x85}},
1149 {AJOC, yjcond, Px, opBytes{0x71, 0x81, 00}},
1150 {AJOS, yjcond, Px, opBytes{0x70, 0x80, 00}},
1151 {AJPC, yjcond, Px, opBytes{0x7b, 0x8b}},
1152 {AJPL, yjcond, Px, opBytes{0x79, 0x89}},
1153 {AJPS, yjcond, Px, opBytes{0x7a, 0x8a}},
1154 {AHADDPD, yxm, Pq, opBytes{0x7c}},
1155 {AHADDPS, yxm, Pf2, opBytes{0x7c}},
1156 {AHSUBPD, yxm, Pq, opBytes{0x7d}},
1157 {AHSUBPS, yxm, Pf2, opBytes{0x7d}},
1158 {ALAHF, ynone, Px, opBytes{0x9f}},
1159 {ALARL, yml_rl, Pm, opBytes{0x02}},
1160 {ALARQ, yml_rl, Pw, opBytes{0x0f, 0x02}},
1161 {ALARW, yml_rl, Pq, opBytes{0x02}},
1162 {ALDDQU, ylddqu, Pf2, opBytes{0xf0}},
1163 {ALDMXCSR, ysvrs_mo, Pm, opBytes{0xae, 02, 0xae, 02}},
1164 {ALEAL, ym_rl, Px, opBytes{0x8d}},
1165 {ALEAQ, ym_rl, Pw, opBytes{0x8d}},
1166 {ALEAVEL, ynone, P32, opBytes{0xc9}},
1167 {ALEAVEQ, ynone, Py, opBytes{0xc9}},
1168 {ALEAVEW, ynone, Pe, opBytes{0xc9}},
1169 {ALEAW, ym_rl, Pe, opBytes{0x8d}},
1170 {ALOCK, ynone, Px, opBytes{0xf0}},
1171 {ALODSB, ynone, Pb, opBytes{0xac}},
1172 {ALODSL, ynone, Px, opBytes{0xad}},
1173 {ALODSQ, ynone, Pw, opBytes{0xad}},
1174 {ALODSW, ynone, Pe, opBytes{0xad}},
1175 {ALONG, ybyte, Px, opBytes{4}},
1176 {ALOOP, yloop, Px, opBytes{0xe2}},
1177 {ALOOPEQ, yloop, Px, opBytes{0xe1}},
1178 {ALOOPNE, yloop, Px, opBytes{0xe0}},
1179 {ALTR, ydivl, Pm, opBytes{0x00, 03}},
1180 {ALZCNTL, yml_rl, Pf3, opBytes{0xbd}},
1181 {ALZCNTQ, yml_rl, Pfw, opBytes{0xbd}},
1182 {ALZCNTW, yml_rl, Pef3, opBytes{0xbd}},
1183 {ALSLL, yml_rl, Pm, opBytes{0x03}},
1184 {ALSLW, yml_rl, Pq, opBytes{0x03}},
1185 {ALSLQ, yml_rl, Pw, opBytes{0x0f, 0x03}},
1186 {AMASKMOVOU, yxr, Pe, opBytes{0xf7}},
1187 {AMASKMOVQ, ymr, Pm, opBytes{0xf7}},
1188 {AMAXPD, yxm, Pe, opBytes{0x5f}},
1189 {AMAXPS, yxm, Pm, opBytes{0x5f}},
1190 {AMAXSD, yxm, Pf2, opBytes{0x5f}},
1191 {AMAXSS, yxm, Pf3, opBytes{0x5f}},
1192 {AMINPD, yxm, Pe, opBytes{0x5d}},
1193 {AMINPS, yxm, Pm, opBytes{0x5d}},
1194 {AMINSD, yxm, Pf2, opBytes{0x5d}},
1195 {AMINSS, yxm, Pf3, opBytes{0x5d}},
1196 {AMONITOR, ynone, Px, opBytes{0x0f, 0x01, 0xc8, 0}},
1197 {AMWAIT, ynone, Px, opBytes{0x0f, 0x01, 0xc9, 0}},
1198 {AMOVAPD, yxmov, Pe, opBytes{0x28, 0x29}},
1199 {AMOVAPS, yxmov, Pm, opBytes{0x28, 0x29}},
1200 {AMOVB, ymovb, Pb, opBytes{0x88, 0x8a, 0xb0, 0xc6, 00}},
1201 {AMOVBLSX, ymb_rl, Pm, opBytes{0xbe}},
1202 {AMOVBLZX, ymb_rl, Pm, opBytes{0xb6}},
1203 {AMOVBQSX, ymb_rl, Pw, opBytes{0x0f, 0xbe}},
1204 {AMOVBQZX, ymb_rl, Pw, opBytes{0x0f, 0xb6}},
1205 {AMOVBWSX, ymb_rl, Pq, opBytes{0xbe}},
1206 {AMOVSWW, ymb_rl, Pe, opBytes{0x0f, 0xbf}},
1207 {AMOVBWZX, ymb_rl, Pq, opBytes{0xb6}},
1208 {AMOVZWW, ymb_rl, Pe, opBytes{0x0f, 0xb7}},
1209 {AMOVO, yxmov, Pe, opBytes{0x6f, 0x7f}},
1210 {AMOVOU, yxmov, Pf3, opBytes{0x6f, 0x7f}},
1211 {AMOVHLPS, yxr, Pm, opBytes{0x12}},
1212 {AMOVHPD, yxmov, Pe, opBytes{0x16, 0x17}},
1213 {AMOVHPS, yxmov, Pm, opBytes{0x16, 0x17}},
1214 {AMOVL, ymovl, Px, opBytes{0x89, 0x8b, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}},
1215 {AMOVLHPS, yxr, Pm, opBytes{0x16}},
1216 {AMOVLPD, yxmov, Pe, opBytes{0x12, 0x13}},
1217 {AMOVLPS, yxmov, Pm, opBytes{0x12, 0x13}},
1218 {AMOVLQSX, yml_rl, Pw, opBytes{0x63}},
1219 {AMOVLQZX, yml_rl, Px, opBytes{0x8b}},
1220 {AMOVMSKPD, yxrrl, Pq, opBytes{0x50}},
1221 {AMOVMSKPS, yxrrl, Pm, opBytes{0x50}},
1222 {AMOVNTO, yxr_ml, Pe, opBytes{0xe7}},
1223 {AMOVNTDQA, ylddqu, Pq4, opBytes{0x2a}},
1224 {AMOVNTPD, yxr_ml, Pe, opBytes{0x2b}},
1225 {AMOVNTPS, yxr_ml, Pm, opBytes{0x2b}},
1226 {AMOVNTQ, ymr_ml, Pm, opBytes{0xe7}},
1227 {AMOVQ, ymovq, Pw8, opBytes{0x6f, 0x7f, Pf2, 0xd6, Pf3, 0x7e, Pe, 0xd6, 0x89, 0x8b, 0xb8, 0xc7, 00, 0x6e, 0x7e, Pe, 0x6e, Pe, 0x7e, 0}},
1228 {AMOVQOZX, ymrxr, Pf3, opBytes{0xd6, 0x7e}},
1229 {AMOVSB, ynone, Pb, opBytes{0xa4}},
1230 {AMOVSD, yxmov, Pf2, opBytes{0x10, 0x11}},
1231 {AMOVSL, ynone, Px, opBytes{0xa5}},
1232 {AMOVSQ, ynone, Pw, opBytes{0xa5}},
1233 {AMOVSS, yxmov, Pf3, opBytes{0x10, 0x11}},
1234 {AMOVSW, ynone, Pe, opBytes{0xa5}},
1235 {AMOVUPD, yxmov, Pe, opBytes{0x10, 0x11}},
1236 {AMOVUPS, yxmov, Pm, opBytes{0x10, 0x11}},
1237 {AMOVW, ymovw, Pe, opBytes{0x89, 0x8b, 0xb8, 0xc7, 00, 0}},
1238 {AMOVWLSX, yml_rl, Pm, opBytes{0xbf}},
1239 {AMOVWLZX, yml_rl, Pm, opBytes{0xb7}},
1240 {AMOVWQSX, yml_rl, Pw, opBytes{0x0f, 0xbf}},
1241 {AMOVWQZX, yml_rl, Pw, opBytes{0x0f, 0xb7}},
1242 {AMPSADBW, yxshuf, Pq, opBytes{0x3a, 0x42, 0}},
1243 {AMULB, ydivb, Pb, opBytes{0xf6, 04}},
1244 {AMULL, ydivl, Px, opBytes{0xf7, 04}},
1245 {AMULPD, yxm, Pe, opBytes{0x59}},
1246 {AMULPS, yxm, Ym, opBytes{0x59}},
1247 {AMULQ, ydivl, Pw, opBytes{0xf7, 04}},
1248 {AMULSD, yxm, Pf2, opBytes{0x59}},
1249 {AMULSS, yxm, Pf3, opBytes{0x59}},
1250 {AMULW, ydivl, Pe, opBytes{0xf7, 04}},
1251 {ANEGB, yscond, Pb, opBytes{0xf6, 03}},
1252 {ANEGL, yscond, Px, opBytes{0xf7, 03}},
1253 {ANEGQ, yscond, Pw, opBytes{0xf7, 03}},
1254 {ANEGW, yscond, Pe, opBytes{0xf7, 03}},
1255 {obj.ANOP, ynop, Px, opBytes{0, 0}},
1256 {ANOTB, yscond, Pb, opBytes{0xf6, 02}},
1257 {ANOTL, yscond, Px, opBytes{0xf7, 02}},
1258 {ANOTQ, yscond, Pw, opBytes{0xf7, 02}},
1259 {ANOTW, yscond, Pe, opBytes{0xf7, 02}},
1260 {AORB, yxorb, Pb, opBytes{0x0c, 0x80, 01, 0x08, 0x0a}},
1261 {AORL, yaddl, Px, opBytes{0x83, 01, 0x0d, 0x81, 01, 0x09, 0x0b}},
1262 {AORPD, yxm, Pq, opBytes{0x56}},
1263 {AORPS, yxm, Pm, opBytes{0x56}},
1264 {AORQ, yaddl, Pw, opBytes{0x83, 01, 0x0d, 0x81, 01, 0x09, 0x0b}},
1265 {AORW, yaddl, Pe, opBytes{0x83, 01, 0x0d, 0x81, 01, 0x09, 0x0b}},
1266 {AOUTB, yin, Pb, opBytes{0xe6, 0xee}},
1267 {AOUTL, yin, Px, opBytes{0xe7, 0xef}},
1268 {AOUTW, yin, Pe, opBytes{0xe7, 0xef}},
1269 {AOUTSB, ynone, Pb, opBytes{0x6e}},
1270 {AOUTSL, ynone, Px, opBytes{0x6f}},
1271 {AOUTSW, ynone, Pe, opBytes{0x6f}},
1272 {APABSB, yxm_q4, Pq4, opBytes{0x1c}},
1273 {APABSD, yxm_q4, Pq4, opBytes{0x1e}},
1274 {APABSW, yxm_q4, Pq4, opBytes{0x1d}},
1275 {APACKSSLW, ymm, Py1, opBytes{0x6b, Pe, 0x6b}},
1276 {APACKSSWB, ymm, Py1, opBytes{0x63, Pe, 0x63}},
1277 {APACKUSDW, yxm_q4, Pq4, opBytes{0x2b}},
1278 {APACKUSWB, ymm, Py1, opBytes{0x67, Pe, 0x67}},
1279 {APADDB, ymm, Py1, opBytes{0xfc, Pe, 0xfc}},
1280 {APADDL, ymm, Py1, opBytes{0xfe, Pe, 0xfe}},
1281 {APADDQ, yxm, Pe, opBytes{0xd4}},
1282 {APADDSB, ymm, Py1, opBytes{0xec, Pe, 0xec}},
1283 {APADDSW, ymm, Py1, opBytes{0xed, Pe, 0xed}},
1284 {APADDUSB, ymm, Py1, opBytes{0xdc, Pe, 0xdc}},
1285 {APADDUSW, ymm, Py1, opBytes{0xdd, Pe, 0xdd}},
1286 {APADDW, ymm, Py1, opBytes{0xfd, Pe, 0xfd}},
1287 {APALIGNR, ypalignr, Pq, opBytes{0x3a, 0x0f}},
1288 {APAND, ymm, Py1, opBytes{0xdb, Pe, 0xdb}},
1289 {APANDN, ymm, Py1, opBytes{0xdf, Pe, 0xdf}},
1290 {APAUSE, ynone, Px, opBytes{0xf3, 0x90}},
1291 {APAVGB, ymm, Py1, opBytes{0xe0, Pe, 0xe0}},
1292 {APAVGW, ymm, Py1, opBytes{0xe3, Pe, 0xe3}},
1293 {APBLENDW, yxshuf, Pq, opBytes{0x3a, 0x0e, 0}},
1294 {APCMPEQB, ymm, Py1, opBytes{0x74, Pe, 0x74}},
1295 {APCMPEQL, ymm, Py1, opBytes{0x76, Pe, 0x76}},
1296 {APCMPEQQ, yxm_q4, Pq4, opBytes{0x29}},
1297 {APCMPEQW, ymm, Py1, opBytes{0x75, Pe, 0x75}},
1298 {APCMPGTB, ymm, Py1, opBytes{0x64, Pe, 0x64}},
1299 {APCMPGTL, ymm, Py1, opBytes{0x66, Pe, 0x66}},
1300 {APCMPGTQ, yxm_q4, Pq4, opBytes{0x37}},
1301 {APCMPGTW, ymm, Py1, opBytes{0x65, Pe, 0x65}},
1302 {APCMPISTRI, yxshuf, Pq, opBytes{0x3a, 0x63, 0}},
1303 {APCMPISTRM, yxshuf, Pq, opBytes{0x3a, 0x62, 0}},
1304 {APEXTRW, yextrw, Pq, opBytes{0xc5, 0, 0x3a, 0x15, 0}},
1305 {APEXTRB, yextr, Pq, opBytes{0x3a, 0x14, 00}},
1306 {APEXTRD, yextr, Pq, opBytes{0x3a, 0x16, 00}},
1307 {APEXTRQ, yextr, Pq3, opBytes{0x3a, 0x16, 00}},
1308 {APHADDD, ymmxmm0f38, Px, opBytes{0x0F, 0x38, 0x02, 0, 0x66, 0x0F, 0x38, 0x02, 0}},
1309 {APHADDSW, yxm_q4, Pq4, opBytes{0x03}},
1310 {APHADDW, yxm_q4, Pq4, opBytes{0x01}},
1311 {APHMINPOSUW, yxm_q4, Pq4, opBytes{0x41}},
1312 {APHSUBD, yxm_q4, Pq4, opBytes{0x06}},
1313 {APHSUBSW, yxm_q4, Pq4, opBytes{0x07}},
1314 {APHSUBW, yxm_q4, Pq4, opBytes{0x05}},
1315 {APINSRW, yinsrw, Pq, opBytes{0xc4, 00}},
1316 {APINSRB, yinsr, Pq, opBytes{0x3a, 0x20, 00}},
1317 {APINSRD, yinsr, Pq, opBytes{0x3a, 0x22, 00}},
1318 {APINSRQ, yinsr, Pq3, opBytes{0x3a, 0x22, 00}},
1319 {APMADDUBSW, yxm_q4, Pq4, opBytes{0x04}},
1320 {APMADDWL, ymm, Py1, opBytes{0xf5, Pe, 0xf5}},
1321 {APMAXSB, yxm_q4, Pq4, opBytes{0x3c}},
1322 {APMAXSD, yxm_q4, Pq4, opBytes{0x3d}},
1323 {APMAXSW, yxm, Pe, opBytes{0xee}},
1324 {APMAXUB, yxm, Pe, opBytes{0xde}},
1325 {APMAXUD, yxm_q4, Pq4, opBytes{0x3f}},
1326 {APMAXUW, yxm_q4, Pq4, opBytes{0x3e}},
1327 {APMINSB, yxm_q4, Pq4, opBytes{0x38}},
1328 {APMINSD, yxm_q4, Pq4, opBytes{0x39}},
1329 {APMINSW, yxm, Pe, opBytes{0xea}},
1330 {APMINUB, yxm, Pe, opBytes{0xda}},
1331 {APMINUD, yxm_q4, Pq4, opBytes{0x3b}},
1332 {APMINUW, yxm_q4, Pq4, opBytes{0x3a}},
1333 {APMOVMSKB, ymskb, Px, opBytes{Pe, 0xd7, 0xd7}},
1334 {APMOVSXBD, yxm_q4, Pq4, opBytes{0x21}},
1335 {APMOVSXBQ, yxm_q4, Pq4, opBytes{0x22}},
1336 {APMOVSXBW, yxm_q4, Pq4, opBytes{0x20}},
1337 {APMOVSXDQ, yxm_q4, Pq4, opBytes{0x25}},
1338 {APMOVSXWD, yxm_q4, Pq4, opBytes{0x23}},
1339 {APMOVSXWQ, yxm_q4, Pq4, opBytes{0x24}},
1340 {APMOVZXBD, yxm_q4, Pq4, opBytes{0x31}},
1341 {APMOVZXBQ, yxm_q4, Pq4, opBytes{0x32}},
1342 {APMOVZXBW, yxm_q4, Pq4, opBytes{0x30}},
1343 {APMOVZXDQ, yxm_q4, Pq4, opBytes{0x35}},
1344 {APMOVZXWD, yxm_q4, Pq4, opBytes{0x33}},
1345 {APMOVZXWQ, yxm_q4, Pq4, opBytes{0x34}},
1346 {APMULDQ, yxm_q4, Pq4, opBytes{0x28}},
1347 {APMULHRSW, yxm_q4, Pq4, opBytes{0x0b}},
1348 {APMULHUW, ymm, Py1, opBytes{0xe4, Pe, 0xe4}},
1349 {APMULHW, ymm, Py1, opBytes{0xe5, Pe, 0xe5}},
1350 {APMULLD, yxm_q4, Pq4, opBytes{0x40}},
1351 {APMULLW, ymm, Py1, opBytes{0xd5, Pe, 0xd5}},
1352 {APMULULQ, ymm, Py1, opBytes{0xf4, Pe, 0xf4}},
1353 {APOPAL, ynone, P32, opBytes{0x61}},
1354 {APOPAW, ynone, Pe, opBytes{0x61}},
1355 {APOPCNTW, yml_rl, Pef3, opBytes{0xb8}},
1356 {APOPCNTL, yml_rl, Pf3, opBytes{0xb8}},
1357 {APOPCNTQ, yml_rl, Pfw, opBytes{0xb8}},
1358 {APOPFL, ynone, P32, opBytes{0x9d}},
1359 {APOPFQ, ynone, Py, opBytes{0x9d}},
1360 {APOPFW, ynone, Pe, opBytes{0x9d}},
1361 {APOPL, ypopl, P32, opBytes{0x58, 0x8f, 00}},
1362 {APOPQ, ypopl, Py, opBytes{0x58, 0x8f, 00}},
1363 {APOPW, ypopl, Pe, opBytes{0x58, 0x8f, 00}},
1364 {APOR, ymm, Py1, opBytes{0xeb, Pe, 0xeb}},
1365 {APSADBW, yxm, Pq, opBytes{0xf6}},
1366 {APSHUFHW, yxshuf, Pf3, opBytes{0x70, 00}},
1367 {APSHUFL, yxshuf, Pq, opBytes{0x70, 00}},
1368 {APSHUFLW, yxshuf, Pf2, opBytes{0x70, 00}},
1369 {APSHUFW, ymshuf, Pm, opBytes{0x70, 00}},
1370 {APSHUFB, ymshufb, Pq, opBytes{0x38, 0x00}},
1371 {APSIGNB, yxm_q4, Pq4, opBytes{0x08}},
1372 {APSIGND, yxm_q4, Pq4, opBytes{0x0a}},
1373 {APSIGNW, yxm_q4, Pq4, opBytes{0x09}},
1374 {APSLLO, ypsdq, Pq, opBytes{0x73, 07}},
1375 {APSLLL, yps, Py3, opBytes{0xf2, 0x72, 06, Pe, 0xf2, Pe, 0x72, 06}},
1376 {APSLLQ, yps, Py3, opBytes{0xf3, 0x73, 06, Pe, 0xf3, Pe, 0x73, 06}},
1377 {APSLLW, yps, Py3, opBytes{0xf1, 0x71, 06, Pe, 0xf1, Pe, 0x71, 06}},
1378 {APSRAL, yps, Py3, opBytes{0xe2, 0x72, 04, Pe, 0xe2, Pe, 0x72, 04}},
1379 {APSRAW, yps, Py3, opBytes{0xe1, 0x71, 04, Pe, 0xe1, Pe, 0x71, 04}},
1380 {APSRLO, ypsdq, Pq, opBytes{0x73, 03}},
1381 {APSRLL, yps, Py3, opBytes{0xd2, 0x72, 02, Pe, 0xd2, Pe, 0x72, 02}},
1382 {APSRLQ, yps, Py3, opBytes{0xd3, 0x73, 02, Pe, 0xd3, Pe, 0x73, 02}},
1383 {APSRLW, yps, Py3, opBytes{0xd1, 0x71, 02, Pe, 0xd1, Pe, 0x71, 02}},
1384 {APSUBB, yxm, Pe, opBytes{0xf8}},
1385 {APSUBL, yxm, Pe, opBytes{0xfa}},
1386 {APSUBQ, yxm, Pe, opBytes{0xfb}},
1387 {APSUBSB, yxm, Pe, opBytes{0xe8}},
1388 {APSUBSW, yxm, Pe, opBytes{0xe9}},
1389 {APSUBUSB, yxm, Pe, opBytes{0xd8}},
1390 {APSUBUSW, yxm, Pe, opBytes{0xd9}},
1391 {APSUBW, yxm, Pe, opBytes{0xf9}},
1392 {APTEST, yxm_q4, Pq4, opBytes{0x17}},
1393 {APUNPCKHBW, ymm, Py1, opBytes{0x68, Pe, 0x68}},
1394 {APUNPCKHLQ, ymm, Py1, opBytes{0x6a, Pe, 0x6a}},
1395 {APUNPCKHQDQ, yxm, Pe, opBytes{0x6d}},
1396 {APUNPCKHWL, ymm, Py1, opBytes{0x69, Pe, 0x69}},
1397 {APUNPCKLBW, ymm, Py1, opBytes{0x60, Pe, 0x60}},
1398 {APUNPCKLLQ, ymm, Py1, opBytes{0x62, Pe, 0x62}},
1399 {APUNPCKLQDQ, yxm, Pe, opBytes{0x6c}},
1400 {APUNPCKLWL, ymm, Py1, opBytes{0x61, Pe, 0x61}},
1401 {APUSHAL, ynone, P32, opBytes{0x60}},
1402 {APUSHAW, ynone, Pe, opBytes{0x60}},
1403 {APUSHFL, ynone, P32, opBytes{0x9c}},
1404 {APUSHFQ, ynone, Py, opBytes{0x9c}},
1405 {APUSHFW, ynone, Pe, opBytes{0x9c}},
1406 {APUSHL, ypushl, P32, opBytes{0x50, 0xff, 06, 0x6a, 0x68}},
1407 {APUSHQ, ypushl, Py, opBytes{0x50, 0xff, 06, 0x6a, 0x68}},
1408 {APUSHW, ypushl, Pe, opBytes{0x50, 0xff, 06, 0x6a, 0x68}},
1409 {APXOR, ymm, Py1, opBytes{0xef, Pe, 0xef}},
1410 {AQUAD, ybyte, Px, opBytes{8}},
1411 {ARCLB, yshb, Pb, opBytes{0xd0, 02, 0xc0, 02, 0xd2, 02}},
1412 {ARCLL, yshl, Px, opBytes{0xd1, 02, 0xc1, 02, 0xd3, 02, 0xd3, 02}},
1413 {ARCLQ, yshl, Pw, opBytes{0xd1, 02, 0xc1, 02, 0xd3, 02, 0xd3, 02}},
1414 {ARCLW, yshl, Pe, opBytes{0xd1, 02, 0xc1, 02, 0xd3, 02, 0xd3, 02}},
1415 {ARCPPS, yxm, Pm, opBytes{0x53}},
1416 {ARCPSS, yxm, Pf3, opBytes{0x53}},
1417 {ARCRB, yshb, Pb, opBytes{0xd0, 03, 0xc0, 03, 0xd2, 03}},
1418 {ARCRL, yshl, Px, opBytes{0xd1, 03, 0xc1, 03, 0xd3, 03, 0xd3, 03}},
1419 {ARCRQ, yshl, Pw, opBytes{0xd1, 03, 0xc1, 03, 0xd3, 03, 0xd3, 03}},
1420 {ARCRW, yshl, Pe, opBytes{0xd1, 03, 0xc1, 03, 0xd3, 03, 0xd3, 03}},
1421 {AREP, ynone, Px, opBytes{0xf3}},
1422 {AREPN, ynone, Px, opBytes{0xf2}},
1423 {obj.ARET, ynone, Px, opBytes{0xc3}},
1424 {ARETFW, yret, Pe, opBytes{0xcb, 0xca}},
1425 {ARETFL, yret, Px, opBytes{0xcb, 0xca}},
1426 {ARETFQ, yret, Pw, opBytes{0xcb, 0xca}},
1427 {AROLB, yshb, Pb, opBytes{0xd0, 00, 0xc0, 00, 0xd2, 00}},
1428 {AROLL, yshl, Px, opBytes{0xd1, 00, 0xc1, 00, 0xd3, 00, 0xd3, 00}},
1429 {AROLQ, yshl, Pw, opBytes{0xd1, 00, 0xc1, 00, 0xd3, 00, 0xd3, 00}},
1430 {AROLW, yshl, Pe, opBytes{0xd1, 00, 0xc1, 00, 0xd3, 00, 0xd3, 00}},
1431 {ARORB, yshb, Pb, opBytes{0xd0, 01, 0xc0, 01, 0xd2, 01}},
1432 {ARORL, yshl, Px, opBytes{0xd1, 01, 0xc1, 01, 0xd3, 01, 0xd3, 01}},
1433 {ARORQ, yshl, Pw, opBytes{0xd1, 01, 0xc1, 01, 0xd3, 01, 0xd3, 01}},
1434 {ARORW, yshl, Pe, opBytes{0xd1, 01, 0xc1, 01, 0xd3, 01, 0xd3, 01}},
1435 {ARSQRTPS, yxm, Pm, opBytes{0x52}},
1436 {ARSQRTSS, yxm, Pf3, opBytes{0x52}},
1437 {ASAHF, ynone, Px, opBytes{0x9e, 00, 0x86, 0xe0, 0x50, 0x9d}},
1438 {ASALB, yshb, Pb, opBytes{0xd0, 04, 0xc0, 04, 0xd2, 04}},
1439 {ASALL, yshl, Px, opBytes{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}},
1440 {ASALQ, yshl, Pw, opBytes{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}},
1441 {ASALW, yshl, Pe, opBytes{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}},
1442 {ASARB, yshb, Pb, opBytes{0xd0, 07, 0xc0, 07, 0xd2, 07}},
1443 {ASARL, yshl, Px, opBytes{0xd1, 07, 0xc1, 07, 0xd3, 07, 0xd3, 07}},
1444 {ASARQ, yshl, Pw, opBytes{0xd1, 07, 0xc1, 07, 0xd3, 07, 0xd3, 07}},
1445 {ASARW, yshl, Pe, opBytes{0xd1, 07, 0xc1, 07, 0xd3, 07, 0xd3, 07}},
1446 {ASBBB, yxorb, Pb, opBytes{0x1c, 0x80, 03, 0x18, 0x1a}},
1447 {ASBBL, yaddl, Px, opBytes{0x83, 03, 0x1d, 0x81, 03, 0x19, 0x1b}},
1448 {ASBBQ, yaddl, Pw, opBytes{0x83, 03, 0x1d, 0x81, 03, 0x19, 0x1b}},
1449 {ASBBW, yaddl, Pe, opBytes{0x83, 03, 0x1d, 0x81, 03, 0x19, 0x1b}},
1450 {ASCASB, ynone, Pb, opBytes{0xae}},
1451 {ASCASL, ynone, Px, opBytes{0xaf}},
1452 {ASCASQ, ynone, Pw, opBytes{0xaf}},
1453 {ASCASW, ynone, Pe, opBytes{0xaf}},
1454 {ASETCC, yscond, Pb, opBytes{0x0f, 0x93, 00}},
1455 {ASETCS, yscond, Pb, opBytes{0x0f, 0x92, 00}},
1456 {ASETEQ, yscond, Pb, opBytes{0x0f, 0x94, 00}},
1457 {ASETGE, yscond, Pb, opBytes{0x0f, 0x9d, 00}},
1458 {ASETGT, yscond, Pb, opBytes{0x0f, 0x9f, 00}},
1459 {ASETHI, yscond, Pb, opBytes{0x0f, 0x97, 00}},
1460 {ASETLE, yscond, Pb, opBytes{0x0f, 0x9e, 00}},
1461 {ASETLS, yscond, Pb, opBytes{0x0f, 0x96, 00}},
1462 {ASETLT, yscond, Pb, opBytes{0x0f, 0x9c, 00}},
1463 {ASETMI, yscond, Pb, opBytes{0x0f, 0x98, 00}},
1464 {ASETNE, yscond, Pb, opBytes{0x0f, 0x95, 00}},
1465 {ASETOC, yscond, Pb, opBytes{0x0f, 0x91, 00}},
1466 {ASETOS, yscond, Pb, opBytes{0x0f, 0x90, 00}},
1467 {ASETPC, yscond, Pb, opBytes{0x0f, 0x9b, 00}},
1468 {ASETPL, yscond, Pb, opBytes{0x0f, 0x99, 00}},
1469 {ASETPS, yscond, Pb, opBytes{0x0f, 0x9a, 00}},
1470 {ASHLB, yshb, Pb, opBytes{0xd0, 04, 0xc0, 04, 0xd2, 04}},
1471 {ASHLL, yshl, Px, opBytes{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}},
1472 {ASHLQ, yshl, Pw, opBytes{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}},
1473 {ASHLW, yshl, Pe, opBytes{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}},
1474 {ASHRB, yshb, Pb, opBytes{0xd0, 05, 0xc0, 05, 0xd2, 05}},
1475 {ASHRL, yshl, Px, opBytes{0xd1, 05, 0xc1, 05, 0xd3, 05, 0xd3, 05}},
1476 {ASHRQ, yshl, Pw, opBytes{0xd1, 05, 0xc1, 05, 0xd3, 05, 0xd3, 05}},
1477 {ASHRW, yshl, Pe, opBytes{0xd1, 05, 0xc1, 05, 0xd3, 05, 0xd3, 05}},
1478 {ASHUFPD, yxshuf, Pq, opBytes{0xc6, 00}},
1479 {ASHUFPS, yxshuf, Pm, opBytes{0xc6, 00}},
1480 {ASQRTPD, yxm, Pe, opBytes{0x51}},
1481 {ASQRTPS, yxm, Pm, opBytes{0x51}},
1482 {ASQRTSD, yxm, Pf2, opBytes{0x51}},
1483 {ASQRTSS, yxm, Pf3, opBytes{0x51}},
1484 {ASTC, ynone, Px, opBytes{0xf9}},
1485 {ASTD, ynone, Px, opBytes{0xfd}},
1486 {ASTI, ynone, Px, opBytes{0xfb}},
1487 {ASTMXCSR, ysvrs_om, Pm, opBytes{0xae, 03, 0xae, 03}},
1488 {ASTOSB, ynone, Pb, opBytes{0xaa}},
1489 {ASTOSL, ynone, Px, opBytes{0xab}},
1490 {ASTOSQ, ynone, Pw, opBytes{0xab}},
1491 {ASTOSW, ynone, Pe, opBytes{0xab}},
1492 {ASUBB, yxorb, Pb, opBytes{0x2c, 0x80, 05, 0x28, 0x2a}},
1493 {ASUBL, yaddl, Px, opBytes{0x83, 05, 0x2d, 0x81, 05, 0x29, 0x2b}},
1494 {ASUBPD, yxm, Pe, opBytes{0x5c}},
1495 {ASUBPS, yxm, Pm, opBytes{0x5c}},
1496 {ASUBQ, yaddl, Pw, opBytes{0x83, 05, 0x2d, 0x81, 05, 0x29, 0x2b}},
1497 {ASUBSD, yxm, Pf2, opBytes{0x5c}},
1498 {ASUBSS, yxm, Pf3, opBytes{0x5c}},
1499 {ASUBW, yaddl, Pe, opBytes{0x83, 05, 0x2d, 0x81, 05, 0x29, 0x2b}},
1500 {ASWAPGS, ynone, Pm, opBytes{0x01, 0xf8}},
1501 {ASYSCALL, ynone, Px, opBytes{0x0f, 0x05}},
1502 {ATESTB, yxorb, Pb, opBytes{0xa8, 0xf6, 00, 0x84, 0x84}},
1503 {ATESTL, ytestl, Px, opBytes{0xa9, 0xf7, 00, 0x85, 0x85}},
1504 {ATESTQ, ytestl, Pw, opBytes{0xa9, 0xf7, 00, 0x85, 0x85}},
1505 {ATESTW, ytestl, Pe, opBytes{0xa9, 0xf7, 00, 0x85, 0x85}},
1506 {ATPAUSE, ywrfsbase, Pq, opBytes{0xae, 06}},
1507 {obj.ATEXT, ytext, Px, opBytes{}},
1508 {AUCOMISD, yxm, Pe, opBytes{0x2e}},
1509 {AUCOMISS, yxm, Pm, opBytes{0x2e}},
1510 {AUNPCKHPD, yxm, Pe, opBytes{0x15}},
1511 {AUNPCKHPS, yxm, Pm, opBytes{0x15}},
1512 {AUNPCKLPD, yxm, Pe, opBytes{0x14}},
1513 {AUNPCKLPS, yxm, Pm, opBytes{0x14}},
1514 {AUMONITOR, ywrfsbase, Pf3, opBytes{0xae, 06}},
1515 {AVERR, ydivl, Pm, opBytes{0x00, 04}},
1516 {AVERW, ydivl, Pm, opBytes{0x00, 05}},
1517 {AWAIT, ynone, Px, opBytes{0x9b}},
1518 {AWORD, ybyte, Px, opBytes{2}},
1519 {AXCHGB, yml_mb, Pb, opBytes{0x86, 0x86}},
1520 {AXCHGL, yxchg, Px, opBytes{0x90, 0x90, 0x87, 0x87}},
1521 {AXCHGQ, yxchg, Pw, opBytes{0x90, 0x90, 0x87, 0x87}},
1522 {AXCHGW, yxchg, Pe, opBytes{0x90, 0x90, 0x87, 0x87}},
1523 {AXLAT, ynone, Px, opBytes{0xd7}},
1524 {AXORB, yxorb, Pb, opBytes{0x34, 0x80, 06, 0x30, 0x32}},
1525 {AXORL, yaddl, Px, opBytes{0x83, 06, 0x35, 0x81, 06, 0x31, 0x33}},
1526 {AXORPD, yxm, Pe, opBytes{0x57}},
1527 {AXORPS, yxm, Pm, opBytes{0x57}},
1528 {AXORQ, yaddl, Pw, opBytes{0x83, 06, 0x35, 0x81, 06, 0x31, 0x33}},
1529 {AXORW, yaddl, Pe, opBytes{0x83, 06, 0x35, 0x81, 06, 0x31, 0x33}},
1530 {AFMOVB, yfmvx, Px, opBytes{0xdf, 04}},
1531 {AFMOVBP, yfmvp, Px, opBytes{0xdf, 06}},
1532 {AFMOVD, yfmvd, Px, opBytes{0xdd, 00, 0xdd, 02, 0xd9, 00, 0xdd, 02}},
1533 {AFMOVDP, yfmvdp, Px, opBytes{0xdd, 03, 0xdd, 03}},
1534 {AFMOVF, yfmvf, Px, opBytes{0xd9, 00, 0xd9, 02}},
1535 {AFMOVFP, yfmvp, Px, opBytes{0xd9, 03}},
1536 {AFMOVL, yfmvf, Px, opBytes{0xdb, 00, 0xdb, 02}},
1537 {AFMOVLP, yfmvp, Px, opBytes{0xdb, 03}},
1538 {AFMOVV, yfmvx, Px, opBytes{0xdf, 05}},
1539 {AFMOVVP, yfmvp, Px, opBytes{0xdf, 07}},
1540 {AFMOVW, yfmvf, Px, opBytes{0xdf, 00, 0xdf, 02}},
1541 {AFMOVWP, yfmvp, Px, opBytes{0xdf, 03}},
1542 {AFMOVX, yfmvx, Px, opBytes{0xdb, 05}},
1543 {AFMOVXP, yfmvp, Px, opBytes{0xdb, 07}},
1544 {AFCMOVCC, yfcmv, Px, opBytes{0xdb, 00}},
1545 {AFCMOVCS, yfcmv, Px, opBytes{0xda, 00}},
1546 {AFCMOVEQ, yfcmv, Px, opBytes{0xda, 01}},
1547 {AFCMOVHI, yfcmv, Px, opBytes{0xdb, 02}},
1548 {AFCMOVLS, yfcmv, Px, opBytes{0xda, 02}},
1549 {AFCMOVB, yfcmv, Px, opBytes{0xda, 00}},
1550 {AFCMOVBE, yfcmv, Px, opBytes{0xda, 02}},
1551 {AFCMOVNB, yfcmv, Px, opBytes{0xdb, 00}},
1552 {AFCMOVNBE, yfcmv, Px, opBytes{0xdb, 02}},
1553 {AFCMOVE, yfcmv, Px, opBytes{0xda, 01}},
1554 {AFCMOVNE, yfcmv, Px, opBytes{0xdb, 01}},
1555 {AFCMOVNU, yfcmv, Px, opBytes{0xdb, 03}},
1556 {AFCMOVU, yfcmv, Px, opBytes{0xda, 03}},
1557 {AFCMOVUN, yfcmv, Px, opBytes{0xda, 03}},
1558 {AFCOMD, yfadd, Px, opBytes{0xdc, 02, 0xd8, 02, 0xdc, 02}},
1559 {AFCOMDP, yfadd, Px, opBytes{0xdc, 03, 0xd8, 03, 0xdc, 03}},
1560 {AFCOMDPP, ycompp, Px, opBytes{0xde, 03}},
1561 {AFCOMF, yfmvx, Px, opBytes{0xd8, 02}},
1562 {AFCOMFP, yfmvx, Px, opBytes{0xd8, 03}},
1563 {AFCOMI, yfcmv, Px, opBytes{0xdb, 06}},
1564 {AFCOMIP, yfcmv, Px, opBytes{0xdf, 06}},
1565 {AFCOML, yfmvx, Px, opBytes{0xda, 02}},
1566 {AFCOMLP, yfmvx, Px, opBytes{0xda, 03}},
1567 {AFCOMW, yfmvx, Px, opBytes{0xde, 02}},
1568 {AFCOMWP, yfmvx, Px, opBytes{0xde, 03}},
1569 {AFUCOM, ycompp, Px, opBytes{0xdd, 04}},
1570 {AFUCOMI, ycompp, Px, opBytes{0xdb, 05}},
1571 {AFUCOMIP, ycompp, Px, opBytes{0xdf, 05}},
1572 {AFUCOMP, ycompp, Px, opBytes{0xdd, 05}},
1573 {AFUCOMPP, ycompp, Px, opBytes{0xda, 13}},
1574 {AFADDDP, ycompp, Px, opBytes{0xde, 00}},
1575 {AFADDW, yfmvx, Px, opBytes{0xde, 00}},
1576 {AFADDL, yfmvx, Px, opBytes{0xda, 00}},
1577 {AFADDF, yfmvx, Px, opBytes{0xd8, 00}},
1578 {AFADDD, yfadd, Px, opBytes{0xdc, 00, 0xd8, 00, 0xdc, 00}},
1579 {AFMULDP, ycompp, Px, opBytes{0xde, 01}},
1580 {AFMULW, yfmvx, Px, opBytes{0xde, 01}},
1581 {AFMULL, yfmvx, Px, opBytes{0xda, 01}},
1582 {AFMULF, yfmvx, Px, opBytes{0xd8, 01}},
1583 {AFMULD, yfadd, Px, opBytes{0xdc, 01, 0xd8, 01, 0xdc, 01}},
1584 {AFSUBDP, ycompp, Px, opBytes{0xde, 05}},
1585 {AFSUBW, yfmvx, Px, opBytes{0xde, 04}},
1586 {AFSUBL, yfmvx, Px, opBytes{0xda, 04}},
1587 {AFSUBF, yfmvx, Px, opBytes{0xd8, 04}},
1588 {AFSUBD, yfadd, Px, opBytes{0xdc, 04, 0xd8, 04, 0xdc, 05}},
1589 {AFSUBRDP, ycompp, Px, opBytes{0xde, 04}},
1590 {AFSUBRW, yfmvx, Px, opBytes{0xde, 05}},
1591 {AFSUBRL, yfmvx, Px, opBytes{0xda, 05}},
1592 {AFSUBRF, yfmvx, Px, opBytes{0xd8, 05}},
1593 {AFSUBRD, yfadd, Px, opBytes{0xdc, 05, 0xd8, 05, 0xdc, 04}},
1594 {AFDIVDP, ycompp, Px, opBytes{0xde, 07}},
1595 {AFDIVW, yfmvx, Px, opBytes{0xde, 06}},
1596 {AFDIVL, yfmvx, Px, opBytes{0xda, 06}},
1597 {AFDIVF, yfmvx, Px, opBytes{0xd8, 06}},
1598 {AFDIVD, yfadd, Px, opBytes{0xdc, 06, 0xd8, 06, 0xdc, 07}},
1599 {AFDIVRDP, ycompp, Px, opBytes{0xde, 06}},
1600 {AFDIVRW, yfmvx, Px, opBytes{0xde, 07}},
1601 {AFDIVRL, yfmvx, Px, opBytes{0xda, 07}},
1602 {AFDIVRF, yfmvx, Px, opBytes{0xd8, 07}},
1603 {AFDIVRD, yfadd, Px, opBytes{0xdc, 07, 0xd8, 07, 0xdc, 06}},
1604 {AFXCHD, yfxch, Px, opBytes{0xd9, 01, 0xd9, 01}},
1605 {AFFREE, nil, 0, opBytes{}},
1606 {AFLDCW, ysvrs_mo, Px, opBytes{0xd9, 05, 0xd9, 05}},
1607 {AFLDENV, ysvrs_mo, Px, opBytes{0xd9, 04, 0xd9, 04}},
1608 {AFRSTOR, ysvrs_mo, Px, opBytes{0xdd, 04, 0xdd, 04}},
1609 {AFSAVE, ysvrs_om, Px, opBytes{0xdd, 06, 0xdd, 06}},
1610 {AFSTCW, ysvrs_om, Px, opBytes{0xd9, 07, 0xd9, 07}},
1611 {AFSTENV, ysvrs_om, Px, opBytes{0xd9, 06, 0xd9, 06}},
1612 {AFSTSW, ystsw, Px, opBytes{0xdd, 07, 0xdf, 0xe0}},
1613 {AF2XM1, ynone, Px, opBytes{0xd9, 0xf0}},
1614 {AFABS, ynone, Px, opBytes{0xd9, 0xe1}},
1615 {AFBLD, ysvrs_mo, Px, opBytes{0xdf, 04}},
1616 {AFBSTP, yclflush, Px, opBytes{0xdf, 06}},
1617 {AFCHS, ynone, Px, opBytes{0xd9, 0xe0}},
1618 {AFCLEX, ynone, Px, opBytes{0xdb, 0xe2}},
1619 {AFCOS, ynone, Px, opBytes{0xd9, 0xff}},
1620 {AFDECSTP, ynone, Px, opBytes{0xd9, 0xf6}},
1621 {AFINCSTP, ynone, Px, opBytes{0xd9, 0xf7}},
1622 {AFINIT, ynone, Px, opBytes{0xdb, 0xe3}},
1623 {AFLD1, ynone, Px, opBytes{0xd9, 0xe8}},
1624 {AFLDL2E, ynone, Px, opBytes{0xd9, 0xea}},
1625 {AFLDL2T, ynone, Px, opBytes{0xd9, 0xe9}},
1626 {AFLDLG2, ynone, Px, opBytes{0xd9, 0xec}},
1627 {AFLDLN2, ynone, Px, opBytes{0xd9, 0xed}},
1628 {AFLDPI, ynone, Px, opBytes{0xd9, 0xeb}},
1629 {AFLDZ, ynone, Px, opBytes{0xd9, 0xee}},
1630 {AFNOP, ynone, Px, opBytes{0xd9, 0xd0}},
1631 {AFPATAN, ynone, Px, opBytes{0xd9, 0xf3}},
1632 {AFPREM, ynone, Px, opBytes{0xd9, 0xf8}},
1633 {AFPREM1, ynone, Px, opBytes{0xd9, 0xf5}},
1634 {AFPTAN, ynone, Px, opBytes{0xd9, 0xf2}},
1635 {AFRNDINT, ynone, Px, opBytes{0xd9, 0xfc}},
1636 {AFSCALE, ynone, Px, opBytes{0xd9, 0xfd}},
1637 {AFSIN, ynone, Px, opBytes{0xd9, 0xfe}},
1638 {AFSINCOS, ynone, Px, opBytes{0xd9, 0xfb}},
1639 {AFSQRT, ynone, Px, opBytes{0xd9, 0xfa}},
1640 {AFTST, ynone, Px, opBytes{0xd9, 0xe4}},
1641 {AFXAM, ynone, Px, opBytes{0xd9, 0xe5}},
1642 {AFXTRACT, ynone, Px, opBytes{0xd9, 0xf4}},
1643 {AFYL2X, ynone, Px, opBytes{0xd9, 0xf1}},
1644 {AFYL2XP1, ynone, Px, opBytes{0xd9, 0xf9}},
1645 {ACMPXCHGB, yrb_mb, Pb, opBytes{0x0f, 0xb0}},
1646 {ACMPXCHGL, yrl_ml, Px, opBytes{0x0f, 0xb1}},
1647 {ACMPXCHGW, yrl_ml, Pe, opBytes{0x0f, 0xb1}},
1648 {ACMPXCHGQ, yrl_ml, Pw, opBytes{0x0f, 0xb1}},
1649 {ACMPXCHG8B, yscond, Pm, opBytes{0xc7, 01}},
1650 {ACMPXCHG16B, yscond, Pw, opBytes{0x0f, 0xc7, 01}},
1651 {AINVD, ynone, Pm, opBytes{0x08}},
1652 {AINVLPG, ydivb, Pm, opBytes{0x01, 07}},
1653 {AINVPCID, ycrc32l, Pe, opBytes{0x0f, 0x38, 0x82, 0}},
1654 {ALFENCE, ynone, Pm, opBytes{0xae, 0xe8}},
1655 {AMFENCE, ynone, Pm, opBytes{0xae, 0xf0}},
1656 {AMOVNTIL, yrl_ml, Pm, opBytes{0xc3}},
1657 {AMOVNTIQ, yrl_ml, Pw, opBytes{0x0f, 0xc3}},
1658 {ARDPKRU, ynone, Pm, opBytes{0x01, 0xee, 0}},
1659 {ARDMSR, ynone, Pm, opBytes{0x32}},
1660 {ARDPMC, ynone, Pm, opBytes{0x33}},
1661 {ARDTSC, ynone, Pm, opBytes{0x31}},
1662 {ARSM, ynone, Pm, opBytes{0xaa}},
1663 {ASFENCE, ynone, Pm, opBytes{0xae, 0xf8}},
1664 {ASYSRET, ynone, Pm, opBytes{0x07}},
1665 {AWBINVD, ynone, Pm, opBytes{0x09}},
1666 {AWRMSR, ynone, Pm, opBytes{0x30}},
1667 {AWRPKRU, ynone, Pm, opBytes{0x01, 0xef, 0}},
1668 {AXADDB, yrb_mb, Pb, opBytes{0x0f, 0xc0}},
1669 {AXADDL, yrl_ml, Px, opBytes{0x0f, 0xc1}},
1670 {AXADDQ, yrl_ml, Pw, opBytes{0x0f, 0xc1}},
1671 {AXADDW, yrl_ml, Pe, opBytes{0x0f, 0xc1}},
1672 {ACRC32B, ycrc32b, Px, opBytes{0xf2, 0x0f, 0x38, 0xf0, 0}},
1673 {ACRC32L, ycrc32l, Px, opBytes{0xf2, 0x0f, 0x38, 0xf1, 0}},
1674 {ACRC32Q, ycrc32l, Pw, opBytes{0xf2, 0x0f, 0x38, 0xf1, 0}},
1675 {ACRC32W, ycrc32l, Pe, opBytes{0xf2, 0x0f, 0x38, 0xf1, 0}},
1676 {APREFETCHT0, yprefetch, Pm, opBytes{0x18, 01}},
1677 {APREFETCHT1, yprefetch, Pm, opBytes{0x18, 02}},
1678 {APREFETCHT2, yprefetch, Pm, opBytes{0x18, 03}},
1679 {APREFETCHNTA, yprefetch, Pm, opBytes{0x18, 00}},
1680 {AMOVQL, yrl_ml, Px, opBytes{0x89}},
1681 {obj.AUNDEF, ynone, Px, opBytes{0x0f, 0x0b}},
1682 {AAESENC, yaes, Pq, opBytes{0x38, 0xdc, 0}},
1683 {AAESENCLAST, yaes, Pq, opBytes{0x38, 0xdd, 0}},
1684 {AAESDEC, yaes, Pq, opBytes{0x38, 0xde, 0}},
1685 {AAESDECLAST, yaes, Pq, opBytes{0x38, 0xdf, 0}},
1686 {AAESIMC, yaes, Pq, opBytes{0x38, 0xdb, 0}},
1687 {AAESKEYGENASSIST, yxshuf, Pq, opBytes{0x3a, 0xdf, 0}},
1688 {AROUNDPD, yxshuf, Pq, opBytes{0x3a, 0x09, 0}},
1689 {AROUNDPS, yxshuf, Pq, opBytes{0x3a, 0x08, 0}},
1690 {AROUNDSD, yxshuf, Pq, opBytes{0x3a, 0x0b, 0}},
1691 {AROUNDSS, yxshuf, Pq, opBytes{0x3a, 0x0a, 0}},
1692 {APSHUFD, yxshuf, Pq, opBytes{0x70, 0}},
1693 {APCLMULQDQ, yxshuf, Pq, opBytes{0x3a, 0x44, 0}},
1694 {APCMPESTRI, yxshuf, Pq, opBytes{0x3a, 0x61, 0}},
1695 {APCMPESTRM, yxshuf, Pq, opBytes{0x3a, 0x60, 0}},
1696 {AMOVDDUP, yxm, Pf2, opBytes{0x12}},
1697 {AMOVSHDUP, yxm, Pf3, opBytes{0x16}},
1698 {AMOVSLDUP, yxm, Pf3, opBytes{0x12}},
1699 {ARDTSCP, ynone, Pm, opBytes{0x01, 0xf9, 0}},
1700 {ASTAC, ynone, Pm, opBytes{0x01, 0xcb, 0}},
1701 {AUD1, ynone, Pm, opBytes{0xb9, 0}},
1702 {AUD2, ynone, Pm, opBytes{0x0b, 0}},
1703 {AUMWAIT, ywrfsbase, Pf2, opBytes{0xae, 06}},
1704 {ASYSENTER, ynone, Px, opBytes{0x0f, 0x34, 0}},
1705 {ASYSENTER64, ynone, Pw, opBytes{0x0f, 0x34, 0}},
1706 {ASYSEXIT, ynone, Px, opBytes{0x0f, 0x35, 0}},
1707 {ASYSEXIT64, ynone, Pw, opBytes{0x0f, 0x35, 0}},
1708 {ALMSW, ydivl, Pm, opBytes{0x01, 06}},
1709 {ALLDT, ydivl, Pm, opBytes{0x00, 02}},
1710 {ALIDT, ysvrs_mo, Pm, opBytes{0x01, 03}},
1711 {ALGDT, ysvrs_mo, Pm, opBytes{0x01, 02}},
1712 {ATZCNTW, ycrc32l, Pe, opBytes{0xf3, 0x0f, 0xbc, 0}},
1713 {ATZCNTL, ycrc32l, Px, opBytes{0xf3, 0x0f, 0xbc, 0}},
1714 {ATZCNTQ, ycrc32l, Pw, opBytes{0xf3, 0x0f, 0xbc, 0}},
1715 {AXRSTOR, ydivl, Px, opBytes{0x0f, 0xae, 05}},
1716 {AXRSTOR64, ydivl, Pw, opBytes{0x0f, 0xae, 05}},
1717 {AXRSTORS, ydivl, Px, opBytes{0x0f, 0xc7, 03}},
1718 {AXRSTORS64, ydivl, Pw, opBytes{0x0f, 0xc7, 03}},
1719 {AXSAVE, yclflush, Px, opBytes{0x0f, 0xae, 04}},
1720 {AXSAVE64, yclflush, Pw, opBytes{0x0f, 0xae, 04}},
1721 {AXSAVEOPT, yclflush, Px, opBytes{0x0f, 0xae, 06}},
1722 {AXSAVEOPT64, yclflush, Pw, opBytes{0x0f, 0xae, 06}},
1723 {AXSAVEC, yclflush, Px, opBytes{0x0f, 0xc7, 04}},
1724 {AXSAVEC64, yclflush, Pw, opBytes{0x0f, 0xc7, 04}},
1725 {AXSAVES, yclflush, Px, opBytes{0x0f, 0xc7, 05}},
1726 {AXSAVES64, yclflush, Pw, opBytes{0x0f, 0xc7, 05}},
1727 {ASGDT, yclflush, Pm, opBytes{0x01, 00}},
1728 {ASIDT, yclflush, Pm, opBytes{0x01, 01}},
1729 {ARDRANDW, yrdrand, Pe, opBytes{0x0f, 0xc7, 06}},
1730 {ARDRANDL, yrdrand, Px, opBytes{0x0f, 0xc7, 06}},
1731 {ARDRANDQ, yrdrand, Pw, opBytes{0x0f, 0xc7, 06}},
1732 {ARDSEEDW, yrdrand, Pe, opBytes{0x0f, 0xc7, 07}},
1733 {ARDSEEDL, yrdrand, Px, opBytes{0x0f, 0xc7, 07}},
1734 {ARDSEEDQ, yrdrand, Pw, opBytes{0x0f, 0xc7, 07}},
1735 {ASTRW, yincq, Pe, opBytes{0x0f, 0x00, 01}},
1736 {ASTRL, yincq, Px, opBytes{0x0f, 0x00, 01}},
1737 {ASTRQ, yincq, Pw, opBytes{0x0f, 0x00, 01}},
1738 {AXSETBV, ynone, Pm, opBytes{0x01, 0xd1, 0}},
1739 {AMOVBEW, ymovbe, Pq, opBytes{0x38, 0xf0, 0, 0x38, 0xf1, 0}},
1740 {AMOVBEL, ymovbe, Pm, opBytes{0x38, 0xf0, 0, 0x38, 0xf1, 0}},
1741 {AMOVBEQ, ymovbe, Pw, opBytes{0x0f, 0x38, 0xf0, 0, 0x0f, 0x38, 0xf1, 0}},
1742 {ANOPW, ydivl, Pe, opBytes{0x0f, 0x1f, 00}},
1743 {ANOPL, ydivl, Px, opBytes{0x0f, 0x1f, 00}},
1744 {ASLDTW, yincq, Pe, opBytes{0x0f, 0x00, 00}},
1745 {ASLDTL, yincq, Px, opBytes{0x0f, 0x00, 00}},
1746 {ASLDTQ, yincq, Pw, opBytes{0x0f, 0x00, 00}},
1747 {ASMSWW, yincq, Pe, opBytes{0x0f, 0x01, 04}},
1748 {ASMSWL, yincq, Px, opBytes{0x0f, 0x01, 04}},
1749 {ASMSWQ, yincq, Pw, opBytes{0x0f, 0x01, 04}},
1750 {ABLENDVPS, yblendvpd, Pq4, opBytes{0x14}},
1751 {ABLENDVPD, yblendvpd, Pq4, opBytes{0x15}},
1752 {APBLENDVB, yblendvpd, Pq4, opBytes{0x10}},
1753 {ASHA1MSG1, yaes, Px, opBytes{0x0f, 0x38, 0xc9, 0}},
1754 {ASHA1MSG2, yaes, Px, opBytes{0x0f, 0x38, 0xca, 0}},
1755 {ASHA1NEXTE, yaes, Px, opBytes{0x0f, 0x38, 0xc8, 0}},
1756 {ASHA256MSG1, yaes, Px, opBytes{0x0f, 0x38, 0xcc, 0}},
1757 {ASHA256MSG2, yaes, Px, opBytes{0x0f, 0x38, 0xcd, 0}},
1758 {ASHA1RNDS4, ysha1rnds4, Pm, opBytes{0x3a, 0xcc, 0}},
1759 {ASHA256RNDS2, ysha256rnds2, Px, opBytes{0x0f, 0x38, 0xcb, 0}},
1760 {ARDFSBASEL, yrdrand, Pf3, opBytes{0xae, 00}},
1761 {ARDFSBASEQ, yrdrand, Pfw, opBytes{0xae, 00}},
1762 {ARDGSBASEL, yrdrand, Pf3, opBytes{0xae, 01}},
1763 {ARDGSBASEQ, yrdrand, Pfw, opBytes{0xae, 01}},
1764 {AWRFSBASEL, ywrfsbase, Pf3, opBytes{0xae, 02}},
1765 {AWRFSBASEQ, ywrfsbase, Pfw, opBytes{0xae, 02}},
1766 {AWRGSBASEL, ywrfsbase, Pf3, opBytes{0xae, 03}},
1767 {AWRGSBASEQ, ywrfsbase, Pfw, opBytes{0xae, 03}},
1768 {ALFSW, ym_rl, Pe, opBytes{0x0f, 0xb4}},
1769 {ALFSL, ym_rl, Px, opBytes{0x0f, 0xb4}},
1770 {ALFSQ, ym_rl, Pw, opBytes{0x0f, 0xb4}},
1771 {ALGSW, ym_rl, Pe, opBytes{0x0f, 0xb5}},
1772 {ALGSL, ym_rl, Px, opBytes{0x0f, 0xb5}},
1773 {ALGSQ, ym_rl, Pw, opBytes{0x0f, 0xb5}},
1774 {ALSSW, ym_rl, Pe, opBytes{0x0f, 0xb2}},
1775 {ALSSL, ym_rl, Px, opBytes{0x0f, 0xb2}},
1776 {ALSSQ, ym_rl, Pw, opBytes{0x0f, 0xb2}},
1777 {ARDPID, yrdrand, Pf3, opBytes{0xc7, 07}},
1778
1779 {ABLENDPD, yxshuf, Pq, opBytes{0x3a, 0x0d, 0}},
1780 {ABLENDPS, yxshuf, Pq, opBytes{0x3a, 0x0c, 0}},
1781 {AXACQUIRE, ynone, Px, opBytes{0xf2}},
1782 {AXRELEASE, ynone, Px, opBytes{0xf3}},
1783 {AXBEGIN, yxbegin, Px, opBytes{0xc7, 0xf8}},
1784 {AXABORT, yxabort, Px, opBytes{0xc6, 0xf8}},
1785 {AXEND, ynone, Px, opBytes{0x0f, 01, 0xd5}},
1786 {AXTEST, ynone, Px, opBytes{0x0f, 01, 0xd6}},
1787 {AXGETBV, ynone, Pm, opBytes{01, 0xd0}},
1788 {obj.AFUNCDATA, yfuncdata, Px, opBytes{0, 0}},
1789 {obj.APCDATA, ypcdata, Px, opBytes{0, 0}},
1790 {obj.ADUFFCOPY, yduff, Px, opBytes{0xe8}},
1791 {obj.ADUFFZERO, yduff, Px, opBytes{0xe8}},
1792
1793 {obj.AEND, nil, 0, opBytes{}},
1794 {0, nil, 0, opBytes{}},
1795 }
1796
1797 var opindex [(ALAST + 1) & obj.AMask]*Optab
1798
1799
1800
1801
1802
1803
1804 func useAbs(ctxt *obj.Link, s *obj.LSym) bool {
1805 if ctxt.Headtype == objabi.Hsolaris {
1806
1807 return strings.HasPrefix(s.Name, "libc_")
1808 }
1809 return ctxt.Arch.Family == sys.I386 && !ctxt.Flag_shared
1810 }
1811
1812
1813
1814
1815 var nop = [][16]uint8{
1816 {0x90},
1817 {0x66, 0x90},
1818 {0x0F, 0x1F, 0x00},
1819 {0x0F, 0x1F, 0x40, 0x00},
1820 {0x0F, 0x1F, 0x44, 0x00, 0x00},
1821 {0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00},
1822 {0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00},
1823 {0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
1824 {0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
1825 }
1826
1827
1828
1829 func fillnop(p []byte, n int) {
1830 var m int
1831
1832 for n > 0 {
1833 m = n
1834 if m > len(nop) {
1835 m = len(nop)
1836 }
1837 copy(p[:m], nop[m-1][:m])
1838 p = p[m:]
1839 n -= m
1840 }
1841 }
1842
1843 func noppad(ctxt *obj.Link, s *obj.LSym, c int32, pad int32) int32 {
1844 s.Grow(int64(c) + int64(pad))
1845 fillnop(s.P[c:], int(pad))
1846 return c + pad
1847 }
1848
1849 func spadjop(ctxt *obj.Link, l, q obj.As) obj.As {
1850 if ctxt.Arch.Family != sys.AMD64 || ctxt.Arch.PtrSize == 4 {
1851 return l
1852 }
1853 return q
1854 }
1855
1856
1857
1858
1859 func isJump(p *obj.Prog) bool {
1860 return p.To.Target() != nil || p.As == obj.AJMP || p.As == obj.ACALL ||
1861 p.As == obj.ARET || p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO
1862 }
1863
1864
1865
1866 func lookForJCC(p *obj.Prog) *obj.Prog {
1867
1868 var q *obj.Prog
1869 for q = p.Link; q != nil && (q.As == obj.APCDATA || q.As == obj.AFUNCDATA || q.As == obj.ANOP); q = q.Link {
1870 }
1871
1872 if q == nil || q.To.Target() == nil || p.As == obj.AJMP || p.As == obj.ACALL {
1873 return nil
1874 }
1875
1876 switch q.As {
1877 case AJOS, AJOC, AJCS, AJCC, AJEQ, AJNE, AJLS, AJHI,
1878 AJMI, AJPL, AJPS, AJPC, AJLT, AJGE, AJLE, AJGT:
1879 default:
1880 return nil
1881 }
1882
1883 return q
1884 }
1885
1886
1887
1888
1889 func fusedJump(p *obj.Prog) (bool, uint8) {
1890 var fusedSize uint8
1891
1892
1893
1894
1895
1896 if p.As == AXRELEASE || p.As == AXACQUIRE {
1897 fusedSize += p.Isize
1898 for p = p.Link; p != nil && (p.As == obj.APCDATA || p.As == obj.AFUNCDATA); p = p.Link {
1899 }
1900 if p == nil {
1901 return false, 0
1902 }
1903 }
1904 if p.As == ALOCK {
1905 fusedSize += p.Isize
1906 for p = p.Link; p != nil && (p.As == obj.APCDATA || p.As == obj.AFUNCDATA); p = p.Link {
1907 }
1908 if p == nil {
1909 return false, 0
1910 }
1911 }
1912 cmp := p.As == ACMPB || p.As == ACMPL || p.As == ACMPQ || p.As == ACMPW
1913
1914 cmpAddSub := p.As == AADDB || p.As == AADDL || p.As == AADDW || p.As == AADDQ ||
1915 p.As == ASUBB || p.As == ASUBL || p.As == ASUBW || p.As == ASUBQ || cmp
1916
1917 testAnd := p.As == ATESTB || p.As == ATESTL || p.As == ATESTQ || p.As == ATESTW ||
1918 p.As == AANDB || p.As == AANDL || p.As == AANDQ || p.As == AANDW
1919
1920 incDec := p.As == AINCB || p.As == AINCL || p.As == AINCQ || p.As == AINCW ||
1921 p.As == ADECB || p.As == ADECL || p.As == ADECQ || p.As == ADECW
1922
1923 if !cmpAddSub && !testAnd && !incDec {
1924 return false, 0
1925 }
1926
1927 if !incDec {
1928 var argOne obj.AddrType
1929 var argTwo obj.AddrType
1930 if cmp {
1931 argOne = p.From.Type
1932 argTwo = p.To.Type
1933 } else {
1934 argOne = p.To.Type
1935 argTwo = p.From.Type
1936 }
1937 if argOne == obj.TYPE_REG {
1938 if argTwo != obj.TYPE_REG && argTwo != obj.TYPE_CONST && argTwo != obj.TYPE_MEM {
1939 return false, 0
1940 }
1941 } else if argOne == obj.TYPE_MEM {
1942 if argTwo != obj.TYPE_REG {
1943 return false, 0
1944 }
1945 } else {
1946 return false, 0
1947 }
1948 }
1949
1950 fusedSize += p.Isize
1951 jmp := lookForJCC(p)
1952 if jmp == nil {
1953 return false, 0
1954 }
1955
1956 fusedSize += jmp.Isize
1957
1958 if testAnd {
1959 return true, fusedSize
1960 }
1961
1962 if jmp.As == AJOC || jmp.As == AJOS || jmp.As == AJMI ||
1963 jmp.As == AJPL || jmp.As == AJPS || jmp.As == AJPC {
1964 return false, 0
1965 }
1966
1967 if cmpAddSub {
1968 return true, fusedSize
1969 }
1970
1971 if jmp.As == AJCS || jmp.As == AJCC || jmp.As == AJHI || jmp.As == AJLS {
1972 return false, 0
1973 }
1974
1975 return true, fusedSize
1976 }
1977
1978 type padJumpsCtx int32
1979
1980 func makePjcCtx(ctxt *obj.Link) padJumpsCtx {
1981
1982
1983 if ctxt.Arch.Family == sys.I386 {
1984 return padJumpsCtx(0)
1985 }
1986
1987
1988 if ctxt.IsAsm {
1989 return padJumpsCtx(0)
1990 }
1991
1992 return padJumpsCtx(32)
1993 }
1994
1995
1996
1997
1998 func (pjc padJumpsCtx) padJump(ctxt *obj.Link, s *obj.LSym, p *obj.Prog, c int32) int32 {
1999 if pjc == 0 {
2000 return c
2001 }
2002
2003 var toPad int32
2004 fj, fjSize := fusedJump(p)
2005 mask := int32(pjc - 1)
2006 if fj {
2007 if (c&mask)+int32(fjSize) >= int32(pjc) {
2008 toPad = int32(pjc) - (c & mask)
2009 }
2010 } else if isJump(p) {
2011 if (c&mask)+int32(p.Isize) >= int32(pjc) {
2012 toPad = int32(pjc) - (c & mask)
2013 }
2014 }
2015 if toPad <= 0 {
2016 return c
2017 }
2018
2019 return noppad(ctxt, s, c, toPad)
2020 }
2021
2022
2023
2024
2025 func (pjc padJumpsCtx) reAssemble(p *obj.Prog) bool {
2026 if pjc == 0 {
2027 return false
2028 }
2029
2030 fj, _ := fusedJump(p)
2031 return fj || isJump(p)
2032 }
2033
2034 type nopPad struct {
2035 p *obj.Prog
2036 n int32
2037 }
2038
2039 func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
2040 if ctxt.Retpoline && ctxt.Arch.Family == sys.I386 {
2041 ctxt.Diag("-spectre=ret not supported on 386")
2042 ctxt.Retpoline = false
2043 }
2044
2045 pjc := makePjcCtx(ctxt)
2046
2047 if s.P != nil {
2048 return
2049 }
2050
2051 if ycover[0] == 0 {
2052 ctxt.Diag("x86 tables not initialized, call x86.instinit first")
2053 }
2054
2055 for p := s.Func().Text; p != nil; p = p.Link {
2056 if p.To.Type == obj.TYPE_BRANCH && p.To.Target() == nil {
2057 p.To.SetTarget(p)
2058 }
2059 if p.As == AADJSP {
2060 p.To.Type = obj.TYPE_REG
2061 p.To.Reg = REG_SP
2062
2063
2064
2065
2066 switch v := p.From.Offset; {
2067 case v == 0:
2068 p.As = obj.ANOP
2069 case v == 0x80 || (v < 0 && v != -0x80):
2070 p.As = spadjop(ctxt, AADDL, AADDQ)
2071 p.From.Offset *= -1
2072 default:
2073 p.As = spadjop(ctxt, ASUBL, ASUBQ)
2074 }
2075 }
2076 if ctxt.Retpoline && (p.As == obj.ACALL || p.As == obj.AJMP) && (p.To.Type == obj.TYPE_REG || p.To.Type == obj.TYPE_MEM) {
2077 if p.To.Type != obj.TYPE_REG {
2078 ctxt.Diag("non-retpoline-compatible: %v", p)
2079 continue
2080 }
2081 p.To.Type = obj.TYPE_BRANCH
2082 p.To.Name = obj.NAME_EXTERN
2083 p.To.Sym = ctxt.Lookup("runtime.retpoline" + obj.Rconv(int(p.To.Reg)))
2084 p.To.Reg = 0
2085 p.To.Offset = 0
2086 }
2087 }
2088
2089 var count int64
2090 for p := s.Func().Text; p != nil; p = p.Link {
2091 count++
2092 p.Back = branchShort
2093 if q := p.To.Target(); q != nil && (q.Back&branchShort != 0) {
2094 p.Back |= branchBackwards
2095 q.Back |= branchLoopHead
2096 }
2097 }
2098 s.GrowCap(count * 5)
2099
2100 var ab AsmBuf
2101 var n int
2102 var c int32
2103 errors := ctxt.Errors
2104 var nops []nopPad
2105 nrelocs0 := len(s.R)
2106 for {
2107
2108
2109 reAssemble := false
2110 for i := range s.R[nrelocs0:] {
2111 s.R[nrelocs0+i] = obj.Reloc{}
2112 }
2113 s.R = s.R[:nrelocs0]
2114 s.P = s.P[:0]
2115 c = 0
2116 var pPrev *obj.Prog
2117 nops = nops[:0]
2118 for p := s.Func().Text; p != nil; p = p.Link {
2119 c0 := c
2120 c = pjc.padJump(ctxt, s, p, c)
2121
2122 if maxLoopPad > 0 && p.Back&branchLoopHead != 0 && c&(loopAlign-1) != 0 {
2123
2124 v := -c & (loopAlign - 1)
2125
2126 if v <= maxLoopPad {
2127 s.Grow(int64(c) + int64(v))
2128 fillnop(s.P[c:], int(v))
2129 c += v
2130 }
2131 }
2132
2133 p.Pc = int64(c)
2134
2135
2136 for q := p.Rel; q != nil; q = q.Forwd {
2137 v := int32(p.Pc - (q.Pc + int64(q.Isize)))
2138 if q.Back&branchShort != 0 {
2139 if v > 127 {
2140 reAssemble = true
2141 q.Back ^= branchShort
2142 }
2143
2144 if q.As == AJCXZL || q.As == AXBEGIN {
2145 s.P[q.Pc+2] = byte(v)
2146 } else {
2147 s.P[q.Pc+1] = byte(v)
2148 }
2149 } else {
2150 binary.LittleEndian.PutUint32(s.P[q.Pc+int64(q.Isize)-4:], uint32(v))
2151 }
2152 }
2153 p.Rel = nil
2154
2155 if p.As == obj.APCALIGN || p.As == obj.APCALIGNMAX {
2156 v := obj.AlignmentPadding(c, p, ctxt, s)
2157 if v > 0 {
2158 s.Grow(int64(c) + int64(v))
2159 fillnop(s.P[c:], v)
2160 }
2161 p.Pc = int64(c)
2162 c += int32(v)
2163 pPrev = p
2164 continue
2165 }
2166
2167 p.Pc = int64(c)
2168 ab.asmins(ctxt, s, p)
2169 m := ab.Len()
2170 if int(p.Isize) != m {
2171 p.Isize = uint8(m)
2172 if pjc.reAssemble(p) {
2173
2174
2175 reAssemble = true
2176 }
2177 }
2178
2179 s.Grow(p.Pc + int64(m))
2180 copy(s.P[p.Pc:], ab.Bytes())
2181
2182 if pPrev != nil && !ctxt.IsAsm && c > c0 {
2183 nops = append(nops, nopPad{p: pPrev, n: c - c0})
2184 }
2185 c += int32(m)
2186 pPrev = p
2187 }
2188
2189 n++
2190 if n > 1000 {
2191 ctxt.Diag("span must be looping")
2192 log.Fatalf("loop")
2193 }
2194 if !reAssemble {
2195 break
2196 }
2197 if ctxt.Errors > errors {
2198 return
2199 }
2200 }
2201
2202 for _, n := range nops {
2203 pp := n.p
2204 np := &obj.Prog{Link: pp.Link, Ctxt: pp.Ctxt, As: obj.ANOP, Pos: pp.Pos.WithNotStmt(), Pc: pp.Pc + int64(pp.Isize), Isize: uint8(n.n)}
2205 pp.Link = np
2206 }
2207
2208 s.Size = int64(c)
2209
2210 if false {
2211 fmt.Printf("span1 %s %d (%d tries)\n %.6x", s.Name, s.Size, n, 0)
2212 var i int
2213 for i = 0; i < len(s.P); i++ {
2214 fmt.Printf(" %.2x", s.P[i])
2215 if i%16 == 15 {
2216 fmt.Printf("\n %.6x", uint(i+1))
2217 }
2218 }
2219
2220 if i%16 != 0 {
2221 fmt.Printf("\n")
2222 }
2223
2224 for i := 0; i < len(s.R); i++ {
2225 r := &s.R[i]
2226 fmt.Printf(" rel %#.4x/%d %s%+d\n", uint32(r.Off), r.Siz, r.Sym.Name, r.Add)
2227 }
2228 }
2229
2230
2231
2232
2233
2234
2235
2236 if !CanUse1InsnTLS(ctxt) {
2237 useTLS := func(p *obj.Prog) bool {
2238
2239
2240
2241
2242
2243 return p.From.Index == REG_TLS || p.Mark&unsafeTLS != 0
2244 }
2245 obj.MarkUnsafePoints(ctxt, s.Func().Text, newprog, useTLS, nil)
2246 }
2247 }
2248
2249 func instinit(ctxt *obj.Link) {
2250 if ycover[0] != 0 {
2251
2252
2253
2254 return
2255 }
2256
2257 switch ctxt.Headtype {
2258 case objabi.Hplan9:
2259
2260
2261
2262
2263
2264
2265
2266
2267 plan9privates = ctxt.Lookup("_privates")
2268 plan9privates.Set(obj.AttrLinkname, true)
2269 }
2270
2271 for i := range avxOptab {
2272 c := avxOptab[i].as
2273 if opindex[c&obj.AMask] != nil {
2274 ctxt.Diag("phase error in avxOptab: %d (%v)", i, c)
2275 }
2276 opindex[c&obj.AMask] = &avxOptab[i]
2277 }
2278 for i := 1; optab[i].as != 0; i++ {
2279 c := optab[i].as
2280 if opindex[c&obj.AMask] != nil {
2281 ctxt.Diag("phase error in optab: %d (%v)", i, c)
2282 }
2283 opindex[c&obj.AMask] = &optab[i]
2284 }
2285
2286 for i := 0; i < Ymax; i++ {
2287 ycover[i*Ymax+i] = 1
2288 }
2289
2290 ycover[Yi0*Ymax+Yu2] = 1
2291 ycover[Yi1*Ymax+Yu2] = 1
2292
2293 ycover[Yi0*Ymax+Yi8] = 1
2294 ycover[Yi1*Ymax+Yi8] = 1
2295 ycover[Yu2*Ymax+Yi8] = 1
2296 ycover[Yu7*Ymax+Yi8] = 1
2297
2298 ycover[Yi0*Ymax+Yu7] = 1
2299 ycover[Yi1*Ymax+Yu7] = 1
2300 ycover[Yu2*Ymax+Yu7] = 1
2301
2302 ycover[Yi0*Ymax+Yu8] = 1
2303 ycover[Yi1*Ymax+Yu8] = 1
2304 ycover[Yu2*Ymax+Yu8] = 1
2305 ycover[Yu7*Ymax+Yu8] = 1
2306
2307 ycover[Yi0*Ymax+Ys32] = 1
2308 ycover[Yi1*Ymax+Ys32] = 1
2309 ycover[Yu2*Ymax+Ys32] = 1
2310 ycover[Yu7*Ymax+Ys32] = 1
2311 ycover[Yu8*Ymax+Ys32] = 1
2312 ycover[Yi8*Ymax+Ys32] = 1
2313
2314 ycover[Yi0*Ymax+Yi32] = 1
2315 ycover[Yi1*Ymax+Yi32] = 1
2316 ycover[Yu2*Ymax+Yi32] = 1
2317 ycover[Yu7*Ymax+Yi32] = 1
2318 ycover[Yu8*Ymax+Yi32] = 1
2319 ycover[Yi8*Ymax+Yi32] = 1
2320 ycover[Ys32*Ymax+Yi32] = 1
2321
2322 ycover[Yi0*Ymax+Yi64] = 1
2323 ycover[Yi1*Ymax+Yi64] = 1
2324 ycover[Yu7*Ymax+Yi64] = 1
2325 ycover[Yu2*Ymax+Yi64] = 1
2326 ycover[Yu8*Ymax+Yi64] = 1
2327 ycover[Yi8*Ymax+Yi64] = 1
2328 ycover[Ys32*Ymax+Yi64] = 1
2329 ycover[Yi32*Ymax+Yi64] = 1
2330
2331 ycover[Yal*Ymax+Yrb] = 1
2332 ycover[Ycl*Ymax+Yrb] = 1
2333 ycover[Yax*Ymax+Yrb] = 1
2334 ycover[Ycx*Ymax+Yrb] = 1
2335 ycover[Yrx*Ymax+Yrb] = 1
2336 ycover[Yrl*Ymax+Yrb] = 1
2337
2338 ycover[Ycl*Ymax+Ycx] = 1
2339
2340 ycover[Yax*Ymax+Yrx] = 1
2341 ycover[Ycx*Ymax+Yrx] = 1
2342
2343 ycover[Yax*Ymax+Yrl] = 1
2344 ycover[Ycx*Ymax+Yrl] = 1
2345 ycover[Yrx*Ymax+Yrl] = 1
2346 ycover[Yrl32*Ymax+Yrl] = 1
2347
2348 ycover[Yf0*Ymax+Yrf] = 1
2349
2350 ycover[Yal*Ymax+Ymb] = 1
2351 ycover[Ycl*Ymax+Ymb] = 1
2352 ycover[Yax*Ymax+Ymb] = 1
2353 ycover[Ycx*Ymax+Ymb] = 1
2354 ycover[Yrx*Ymax+Ymb] = 1
2355 ycover[Yrb*Ymax+Ymb] = 1
2356 ycover[Yrl*Ymax+Ymb] = 1
2357 ycover[Ym*Ymax+Ymb] = 1
2358
2359 ycover[Yax*Ymax+Yml] = 1
2360 ycover[Ycx*Ymax+Yml] = 1
2361 ycover[Yrx*Ymax+Yml] = 1
2362 ycover[Yrl*Ymax+Yml] = 1
2363 ycover[Yrl32*Ymax+Yml] = 1
2364 ycover[Ym*Ymax+Yml] = 1
2365
2366 ycover[Yax*Ymax+Ymm] = 1
2367 ycover[Ycx*Ymax+Ymm] = 1
2368 ycover[Yrx*Ymax+Ymm] = 1
2369 ycover[Yrl*Ymax+Ymm] = 1
2370 ycover[Yrl32*Ymax+Ymm] = 1
2371 ycover[Ym*Ymax+Ymm] = 1
2372 ycover[Ymr*Ymax+Ymm] = 1
2373
2374 ycover[Yxr0*Ymax+Yxr] = 1
2375
2376 ycover[Ym*Ymax+Yxm] = 1
2377 ycover[Yxr0*Ymax+Yxm] = 1
2378 ycover[Yxr*Ymax+Yxm] = 1
2379
2380 ycover[Ym*Ymax+Yym] = 1
2381 ycover[Yyr*Ymax+Yym] = 1
2382
2383 ycover[Yxr0*Ymax+YxrEvex] = 1
2384 ycover[Yxr*Ymax+YxrEvex] = 1
2385
2386 ycover[Ym*Ymax+YxmEvex] = 1
2387 ycover[Yxr0*Ymax+YxmEvex] = 1
2388 ycover[Yxr*Ymax+YxmEvex] = 1
2389 ycover[YxrEvex*Ymax+YxmEvex] = 1
2390
2391 ycover[Yyr*Ymax+YyrEvex] = 1
2392
2393 ycover[Ym*Ymax+YymEvex] = 1
2394 ycover[Yyr*Ymax+YymEvex] = 1
2395 ycover[YyrEvex*Ymax+YymEvex] = 1
2396
2397 ycover[Ym*Ymax+Yzm] = 1
2398 ycover[Yzr*Ymax+Yzm] = 1
2399
2400 ycover[Yk0*Ymax+Yk] = 1
2401 ycover[Yknot0*Ymax+Yk] = 1
2402
2403 ycover[Yk0*Ymax+Ykm] = 1
2404 ycover[Yknot0*Ymax+Ykm] = 1
2405 ycover[Yk*Ymax+Ykm] = 1
2406 ycover[Ym*Ymax+Ykm] = 1
2407
2408 ycover[Yxvm*Ymax+YxvmEvex] = 1
2409
2410 ycover[Yyvm*Ymax+YyvmEvex] = 1
2411
2412 for i := 0; i < MAXREG; i++ {
2413 reg[i] = -1
2414 if i >= REG_AL && i <= REG_R15B {
2415 reg[i] = (i - REG_AL) & 7
2416 if i >= REG_SPB && i <= REG_DIB {
2417 regrex[i] = 0x40
2418 }
2419 if i >= REG_R8B && i <= REG_R15B {
2420 regrex[i] = Rxr | Rxx | Rxb
2421 }
2422 }
2423
2424 if i >= REG_AH && i <= REG_BH {
2425 reg[i] = 4 + ((i - REG_AH) & 7)
2426 }
2427 if i >= REG_AX && i <= REG_R15 {
2428 reg[i] = (i - REG_AX) & 7
2429 if i >= REG_R8 {
2430 regrex[i] = Rxr | Rxx | Rxb
2431 }
2432 }
2433
2434 if i >= REG_F0 && i <= REG_F0+7 {
2435 reg[i] = (i - REG_F0) & 7
2436 }
2437 if i >= REG_M0 && i <= REG_M0+7 {
2438 reg[i] = (i - REG_M0) & 7
2439 }
2440 if i >= REG_K0 && i <= REG_K0+7 {
2441 reg[i] = (i - REG_K0) & 7
2442 }
2443 if i >= REG_X0 && i <= REG_X0+15 {
2444 reg[i] = (i - REG_X0) & 7
2445 if i >= REG_X0+8 {
2446 regrex[i] = Rxr | Rxx | Rxb
2447 }
2448 }
2449 if i >= REG_X16 && i <= REG_X16+15 {
2450 reg[i] = (i - REG_X16) & 7
2451 if i >= REG_X16+8 {
2452 regrex[i] = Rxr | Rxx | Rxb | RxrEvex
2453 } else {
2454 regrex[i] = RxrEvex
2455 }
2456 }
2457 if i >= REG_Y0 && i <= REG_Y0+15 {
2458 reg[i] = (i - REG_Y0) & 7
2459 if i >= REG_Y0+8 {
2460 regrex[i] = Rxr | Rxx | Rxb
2461 }
2462 }
2463 if i >= REG_Y16 && i <= REG_Y16+15 {
2464 reg[i] = (i - REG_Y16) & 7
2465 if i >= REG_Y16+8 {
2466 regrex[i] = Rxr | Rxx | Rxb | RxrEvex
2467 } else {
2468 regrex[i] = RxrEvex
2469 }
2470 }
2471 if i >= REG_Z0 && i <= REG_Z0+15 {
2472 reg[i] = (i - REG_Z0) & 7
2473 if i > REG_Z0+7 {
2474 regrex[i] = Rxr | Rxx | Rxb
2475 }
2476 }
2477 if i >= REG_Z16 && i <= REG_Z16+15 {
2478 reg[i] = (i - REG_Z16) & 7
2479 if i >= REG_Z16+8 {
2480 regrex[i] = Rxr | Rxx | Rxb | RxrEvex
2481 } else {
2482 regrex[i] = RxrEvex
2483 }
2484 }
2485
2486 if i >= REG_CR+8 && i <= REG_CR+15 {
2487 regrex[i] = Rxr
2488 }
2489 }
2490 }
2491
2492 var isAndroid = buildcfg.GOOS == "android"
2493
2494 func prefixof(ctxt *obj.Link, a *obj.Addr) int {
2495 if a.Reg < REG_CS && a.Index < REG_CS {
2496 return 0
2497 }
2498 if a.Type == obj.TYPE_MEM && a.Name == obj.NAME_NONE {
2499 switch a.Reg {
2500 case REG_CS:
2501 return 0x2e
2502
2503 case REG_DS:
2504 return 0x3e
2505
2506 case REG_ES:
2507 return 0x26
2508
2509 case REG_FS:
2510 return 0x64
2511
2512 case REG_GS:
2513 return 0x65
2514
2515 case REG_TLS:
2516
2517
2518
2519
2520
2521
2522 if ctxt.Arch.Family == sys.I386 {
2523 switch ctxt.Headtype {
2524 default:
2525 if isAndroid {
2526 return 0x65
2527 }
2528 log.Fatalf("unknown TLS base register for %v", ctxt.Headtype)
2529
2530 case objabi.Hdarwin,
2531 objabi.Hdragonfly,
2532 objabi.Hfreebsd,
2533 objabi.Hnetbsd,
2534 objabi.Hopenbsd:
2535 return 0x65
2536 }
2537 }
2538
2539 switch ctxt.Headtype {
2540 default:
2541 log.Fatalf("unknown TLS base register for %v", ctxt.Headtype)
2542
2543 case objabi.Hlinux:
2544 if isAndroid {
2545 return 0x64
2546 }
2547
2548 if ctxt.Flag_shared {
2549 log.Fatalf("unknown TLS base register for linux with -shared")
2550 } else {
2551 return 0x64
2552 }
2553
2554 case objabi.Hdragonfly,
2555 objabi.Hfreebsd,
2556 objabi.Hnetbsd,
2557 objabi.Hopenbsd,
2558 objabi.Hsolaris:
2559 return 0x64
2560
2561 case objabi.Hdarwin:
2562 return 0x65
2563 }
2564 }
2565 }
2566
2567 switch a.Index {
2568 case REG_CS:
2569 return 0x2e
2570
2571 case REG_DS:
2572 return 0x3e
2573
2574 case REG_ES:
2575 return 0x26
2576
2577 case REG_TLS:
2578 if ctxt.Flag_shared && ctxt.Headtype != objabi.Hwindows {
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590 if ctxt.Arch.Family == sys.I386 {
2591 return 0x65
2592 }
2593 return 0x64
2594 }
2595
2596 case REG_FS:
2597 return 0x64
2598
2599 case REG_GS:
2600 return 0x65
2601 }
2602
2603 return 0
2604 }
2605
2606
2607 func oclassRegList(ctxt *obj.Link, addr *obj.Addr) int {
2608
2609
2610
2611
2612 regIsXmm := func(r int) bool { return r >= REG_X0 && r <= REG_X31 }
2613 regIsYmm := func(r int) bool { return r >= REG_Y0 && r <= REG_Y31 }
2614 regIsZmm := func(r int) bool { return r >= REG_Z0 && r <= REG_Z31 }
2615
2616 reg0, reg1 := decodeRegisterRange(addr.Offset)
2617 low := regIndex(int16(reg0))
2618 high := regIndex(int16(reg1))
2619
2620 if ctxt.Arch.Family == sys.I386 {
2621 if low >= 8 || high >= 8 {
2622 return Yxxx
2623 }
2624 }
2625
2626 switch high - low {
2627 case 3:
2628 switch {
2629 case regIsXmm(reg0) && regIsXmm(reg1):
2630 return YxrEvexMulti4
2631 case regIsYmm(reg0) && regIsYmm(reg1):
2632 return YyrEvexMulti4
2633 case regIsZmm(reg0) && regIsZmm(reg1):
2634 return YzrMulti4
2635 default:
2636 return Yxxx
2637 }
2638 default:
2639 return Yxxx
2640 }
2641 }
2642
2643
2644
2645 func oclassVMem(ctxt *obj.Link, addr *obj.Addr) (int, bool) {
2646 switch addr.Index {
2647 case REG_X0 + 0,
2648 REG_X0 + 1,
2649 REG_X0 + 2,
2650 REG_X0 + 3,
2651 REG_X0 + 4,
2652 REG_X0 + 5,
2653 REG_X0 + 6,
2654 REG_X0 + 7:
2655 return Yxvm, true
2656 case REG_X8 + 0,
2657 REG_X8 + 1,
2658 REG_X8 + 2,
2659 REG_X8 + 3,
2660 REG_X8 + 4,
2661 REG_X8 + 5,
2662 REG_X8 + 6,
2663 REG_X8 + 7:
2664 if ctxt.Arch.Family == sys.I386 {
2665 return Yxxx, true
2666 }
2667 return Yxvm, true
2668 case REG_X16 + 0,
2669 REG_X16 + 1,
2670 REG_X16 + 2,
2671 REG_X16 + 3,
2672 REG_X16 + 4,
2673 REG_X16 + 5,
2674 REG_X16 + 6,
2675 REG_X16 + 7,
2676 REG_X16 + 8,
2677 REG_X16 + 9,
2678 REG_X16 + 10,
2679 REG_X16 + 11,
2680 REG_X16 + 12,
2681 REG_X16 + 13,
2682 REG_X16 + 14,
2683 REG_X16 + 15:
2684 if ctxt.Arch.Family == sys.I386 {
2685 return Yxxx, true
2686 }
2687 return YxvmEvex, true
2688
2689 case REG_Y0 + 0,
2690 REG_Y0 + 1,
2691 REG_Y0 + 2,
2692 REG_Y0 + 3,
2693 REG_Y0 + 4,
2694 REG_Y0 + 5,
2695 REG_Y0 + 6,
2696 REG_Y0 + 7:
2697 return Yyvm, true
2698 case REG_Y8 + 0,
2699 REG_Y8 + 1,
2700 REG_Y8 + 2,
2701 REG_Y8 + 3,
2702 REG_Y8 + 4,
2703 REG_Y8 + 5,
2704 REG_Y8 + 6,
2705 REG_Y8 + 7:
2706 if ctxt.Arch.Family == sys.I386 {
2707 return Yxxx, true
2708 }
2709 return Yyvm, true
2710 case REG_Y16 + 0,
2711 REG_Y16 + 1,
2712 REG_Y16 + 2,
2713 REG_Y16 + 3,
2714 REG_Y16 + 4,
2715 REG_Y16 + 5,
2716 REG_Y16 + 6,
2717 REG_Y16 + 7,
2718 REG_Y16 + 8,
2719 REG_Y16 + 9,
2720 REG_Y16 + 10,
2721 REG_Y16 + 11,
2722 REG_Y16 + 12,
2723 REG_Y16 + 13,
2724 REG_Y16 + 14,
2725 REG_Y16 + 15:
2726 if ctxt.Arch.Family == sys.I386 {
2727 return Yxxx, true
2728 }
2729 return YyvmEvex, true
2730
2731 case REG_Z0 + 0,
2732 REG_Z0 + 1,
2733 REG_Z0 + 2,
2734 REG_Z0 + 3,
2735 REG_Z0 + 4,
2736 REG_Z0 + 5,
2737 REG_Z0 + 6,
2738 REG_Z0 + 7:
2739 return Yzvm, true
2740 case REG_Z8 + 0,
2741 REG_Z8 + 1,
2742 REG_Z8 + 2,
2743 REG_Z8 + 3,
2744 REG_Z8 + 4,
2745 REG_Z8 + 5,
2746 REG_Z8 + 6,
2747 REG_Z8 + 7,
2748 REG_Z8 + 8,
2749 REG_Z8 + 9,
2750 REG_Z8 + 10,
2751 REG_Z8 + 11,
2752 REG_Z8 + 12,
2753 REG_Z8 + 13,
2754 REG_Z8 + 14,
2755 REG_Z8 + 15,
2756 REG_Z8 + 16,
2757 REG_Z8 + 17,
2758 REG_Z8 + 18,
2759 REG_Z8 + 19,
2760 REG_Z8 + 20,
2761 REG_Z8 + 21,
2762 REG_Z8 + 22,
2763 REG_Z8 + 23:
2764 if ctxt.Arch.Family == sys.I386 {
2765 return Yxxx, true
2766 }
2767 return Yzvm, true
2768 }
2769
2770 return Yxxx, false
2771 }
2772
2773 func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
2774 switch a.Type {
2775 case obj.TYPE_REGLIST:
2776 return oclassRegList(ctxt, a)
2777
2778 case obj.TYPE_NONE:
2779 return Ynone
2780
2781 case obj.TYPE_BRANCH:
2782 return Ybr
2783
2784 case obj.TYPE_INDIR:
2785 if a.Name != obj.NAME_NONE && a.Reg == REG_NONE && a.Index == REG_NONE && a.Scale == 0 {
2786 return Yindir
2787 }
2788 return Yxxx
2789
2790 case obj.TYPE_MEM:
2791
2792
2793 if a.Index == REG_SP || a.Index < 0 {
2794
2795 return Yxxx
2796 }
2797
2798 if vmem, ok := oclassVMem(ctxt, a); ok {
2799 return vmem
2800 }
2801
2802 if ctxt.Arch.Family == sys.AMD64 {
2803 switch a.Name {
2804 case obj.NAME_EXTERN, obj.NAME_STATIC, obj.NAME_GOTREF:
2805
2806
2807 if a.Reg != REG_NONE || a.Index != REG_NONE || a.Scale != 0 {
2808 return Yxxx
2809 }
2810 case obj.NAME_AUTO, obj.NAME_PARAM:
2811
2812
2813 if a.Reg != REG_SP && a.Reg != 0 {
2814 return Yxxx
2815 }
2816 case obj.NAME_NONE:
2817
2818 default:
2819
2820 return Yxxx
2821 }
2822 }
2823 return Ym
2824
2825 case obj.TYPE_ADDR:
2826 switch a.Name {
2827 case obj.NAME_GOTREF:
2828 ctxt.Diag("unexpected TYPE_ADDR with NAME_GOTREF")
2829 return Yxxx
2830
2831 case obj.NAME_EXTERN,
2832 obj.NAME_STATIC:
2833 if a.Sym != nil && useAbs(ctxt, a.Sym) {
2834 return Yi32
2835 }
2836 return Yiauto
2837
2838 case obj.NAME_AUTO,
2839 obj.NAME_PARAM:
2840 return Yiauto
2841 }
2842
2843
2844
2845
2846 if a.Sym != nil && strings.HasPrefix(a.Sym.Name, "runtime.duff") {
2847 return Yi32
2848 }
2849
2850 if a.Sym != nil || a.Name != obj.NAME_NONE {
2851 ctxt.Diag("unexpected addr: %v", obj.Dconv(p, a))
2852 }
2853 fallthrough
2854
2855 case obj.TYPE_CONST:
2856 if a.Sym != nil {
2857 ctxt.Diag("TYPE_CONST with symbol: %v", obj.Dconv(p, a))
2858 }
2859
2860 v := a.Offset
2861 if ctxt.Arch.Family == sys.I386 {
2862 v = int64(int32(v))
2863 }
2864 switch {
2865 case v == 0:
2866 return Yi0
2867 case v == 1:
2868 return Yi1
2869 case v >= 0 && v <= 3:
2870 return Yu2
2871 case v >= 0 && v <= 127:
2872 return Yu7
2873 case v >= 0 && v <= 255:
2874 return Yu8
2875 case v >= -128 && v <= 127:
2876 return Yi8
2877 }
2878 if ctxt.Arch.Family == sys.I386 {
2879 return Yi32
2880 }
2881 l := int32(v)
2882 if int64(l) == v {
2883 return Ys32
2884 }
2885 if v>>32 == 0 {
2886 return Yi32
2887 }
2888 return Yi64
2889
2890 case obj.TYPE_TEXTSIZE:
2891 return Ytextsize
2892 }
2893
2894 if a.Type != obj.TYPE_REG {
2895 ctxt.Diag("unexpected addr1: type=%d %v", a.Type, obj.Dconv(p, a))
2896 return Yxxx
2897 }
2898
2899 switch a.Reg {
2900 case REG_AL:
2901 return Yal
2902
2903 case REG_AX:
2904 return Yax
2905
2906
2909 case REG_BPB,
2910 REG_SIB,
2911 REG_DIB,
2912 REG_R8B,
2913 REG_R9B,
2914 REG_R10B,
2915 REG_R11B,
2916 REG_R12B,
2917 REG_R13B,
2918 REG_R14B,
2919 REG_R15B:
2920 if ctxt.Arch.Family == sys.I386 {
2921 return Yxxx
2922 }
2923 fallthrough
2924
2925 case REG_DL,
2926 REG_BL,
2927 REG_AH,
2928 REG_CH,
2929 REG_DH,
2930 REG_BH:
2931 return Yrb
2932
2933 case REG_CL:
2934 return Ycl
2935
2936 case REG_CX:
2937 return Ycx
2938
2939 case REG_DX, REG_BX:
2940 return Yrx
2941
2942 case REG_R8,
2943 REG_R9,
2944 REG_R10,
2945 REG_R11,
2946 REG_R12,
2947 REG_R13,
2948 REG_R14,
2949 REG_R15:
2950 if ctxt.Arch.Family == sys.I386 {
2951 return Yxxx
2952 }
2953 fallthrough
2954
2955 case REG_SP, REG_BP, REG_SI, REG_DI:
2956 if ctxt.Arch.Family == sys.I386 {
2957 return Yrl32
2958 }
2959 return Yrl
2960
2961 case REG_F0 + 0:
2962 return Yf0
2963
2964 case REG_F0 + 1,
2965 REG_F0 + 2,
2966 REG_F0 + 3,
2967 REG_F0 + 4,
2968 REG_F0 + 5,
2969 REG_F0 + 6,
2970 REG_F0 + 7:
2971 return Yrf
2972
2973 case REG_M0 + 0,
2974 REG_M0 + 1,
2975 REG_M0 + 2,
2976 REG_M0 + 3,
2977 REG_M0 + 4,
2978 REG_M0 + 5,
2979 REG_M0 + 6,
2980 REG_M0 + 7:
2981 return Ymr
2982
2983 case REG_X0:
2984 return Yxr0
2985
2986 case REG_X0 + 1,
2987 REG_X0 + 2,
2988 REG_X0 + 3,
2989 REG_X0 + 4,
2990 REG_X0 + 5,
2991 REG_X0 + 6,
2992 REG_X0 + 7,
2993 REG_X0 + 8,
2994 REG_X0 + 9,
2995 REG_X0 + 10,
2996 REG_X0 + 11,
2997 REG_X0 + 12,
2998 REG_X0 + 13,
2999 REG_X0 + 14,
3000 REG_X0 + 15:
3001 return Yxr
3002
3003 case REG_X0 + 16,
3004 REG_X0 + 17,
3005 REG_X0 + 18,
3006 REG_X0 + 19,
3007 REG_X0 + 20,
3008 REG_X0 + 21,
3009 REG_X0 + 22,
3010 REG_X0 + 23,
3011 REG_X0 + 24,
3012 REG_X0 + 25,
3013 REG_X0 + 26,
3014 REG_X0 + 27,
3015 REG_X0 + 28,
3016 REG_X0 + 29,
3017 REG_X0 + 30,
3018 REG_X0 + 31:
3019 return YxrEvex
3020
3021 case REG_Y0 + 0,
3022 REG_Y0 + 1,
3023 REG_Y0 + 2,
3024 REG_Y0 + 3,
3025 REG_Y0 + 4,
3026 REG_Y0 + 5,
3027 REG_Y0 + 6,
3028 REG_Y0 + 7,
3029 REG_Y0 + 8,
3030 REG_Y0 + 9,
3031 REG_Y0 + 10,
3032 REG_Y0 + 11,
3033 REG_Y0 + 12,
3034 REG_Y0 + 13,
3035 REG_Y0 + 14,
3036 REG_Y0 + 15:
3037 return Yyr
3038
3039 case REG_Y0 + 16,
3040 REG_Y0 + 17,
3041 REG_Y0 + 18,
3042 REG_Y0 + 19,
3043 REG_Y0 + 20,
3044 REG_Y0 + 21,
3045 REG_Y0 + 22,
3046 REG_Y0 + 23,
3047 REG_Y0 + 24,
3048 REG_Y0 + 25,
3049 REG_Y0 + 26,
3050 REG_Y0 + 27,
3051 REG_Y0 + 28,
3052 REG_Y0 + 29,
3053 REG_Y0 + 30,
3054 REG_Y0 + 31:
3055 return YyrEvex
3056
3057 case REG_Z0 + 0,
3058 REG_Z0 + 1,
3059 REG_Z0 + 2,
3060 REG_Z0 + 3,
3061 REG_Z0 + 4,
3062 REG_Z0 + 5,
3063 REG_Z0 + 6,
3064 REG_Z0 + 7:
3065 return Yzr
3066
3067 case REG_Z0 + 8,
3068 REG_Z0 + 9,
3069 REG_Z0 + 10,
3070 REG_Z0 + 11,
3071 REG_Z0 + 12,
3072 REG_Z0 + 13,
3073 REG_Z0 + 14,
3074 REG_Z0 + 15,
3075 REG_Z0 + 16,
3076 REG_Z0 + 17,
3077 REG_Z0 + 18,
3078 REG_Z0 + 19,
3079 REG_Z0 + 20,
3080 REG_Z0 + 21,
3081 REG_Z0 + 22,
3082 REG_Z0 + 23,
3083 REG_Z0 + 24,
3084 REG_Z0 + 25,
3085 REG_Z0 + 26,
3086 REG_Z0 + 27,
3087 REG_Z0 + 28,
3088 REG_Z0 + 29,
3089 REG_Z0 + 30,
3090 REG_Z0 + 31:
3091 if ctxt.Arch.Family == sys.I386 {
3092 return Yxxx
3093 }
3094 return Yzr
3095
3096 case REG_K0:
3097 return Yk0
3098
3099 case REG_K0 + 1,
3100 REG_K0 + 2,
3101 REG_K0 + 3,
3102 REG_K0 + 4,
3103 REG_K0 + 5,
3104 REG_K0 + 6,
3105 REG_K0 + 7:
3106 return Yknot0
3107
3108 case REG_CS:
3109 return Ycs
3110 case REG_SS:
3111 return Yss
3112 case REG_DS:
3113 return Yds
3114 case REG_ES:
3115 return Yes
3116 case REG_FS:
3117 return Yfs
3118 case REG_GS:
3119 return Ygs
3120 case REG_TLS:
3121 return Ytls
3122
3123 case REG_GDTR:
3124 return Ygdtr
3125 case REG_IDTR:
3126 return Yidtr
3127 case REG_LDTR:
3128 return Yldtr
3129 case REG_MSW:
3130 return Ymsw
3131 case REG_TASK:
3132 return Ytask
3133
3134 case REG_CR + 0:
3135 return Ycr0
3136 case REG_CR + 1:
3137 return Ycr1
3138 case REG_CR + 2:
3139 return Ycr2
3140 case REG_CR + 3:
3141 return Ycr3
3142 case REG_CR + 4:
3143 return Ycr4
3144 case REG_CR + 5:
3145 return Ycr5
3146 case REG_CR + 6:
3147 return Ycr6
3148 case REG_CR + 7:
3149 return Ycr7
3150 case REG_CR + 8:
3151 return Ycr8
3152
3153 case REG_DR + 0:
3154 return Ydr0
3155 case REG_DR + 1:
3156 return Ydr1
3157 case REG_DR + 2:
3158 return Ydr2
3159 case REG_DR + 3:
3160 return Ydr3
3161 case REG_DR + 4:
3162 return Ydr4
3163 case REG_DR + 5:
3164 return Ydr5
3165 case REG_DR + 6:
3166 return Ydr6
3167 case REG_DR + 7:
3168 return Ydr7
3169
3170 case REG_TR + 0:
3171 return Ytr0
3172 case REG_TR + 1:
3173 return Ytr1
3174 case REG_TR + 2:
3175 return Ytr2
3176 case REG_TR + 3:
3177 return Ytr3
3178 case REG_TR + 4:
3179 return Ytr4
3180 case REG_TR + 5:
3181 return Ytr5
3182 case REG_TR + 6:
3183 return Ytr6
3184 case REG_TR + 7:
3185 return Ytr7
3186 }
3187
3188 return Yxxx
3189 }
3190
3191
3192
3193 type AsmBuf struct {
3194 buf [100]byte
3195 off int
3196 rexflag int
3197 vexflag bool
3198 evexflag bool
3199 rep bool
3200 repn bool
3201 lock bool
3202
3203 evex evexBits
3204 }
3205
3206
3207 func (ab *AsmBuf) Put1(x byte) {
3208 ab.buf[ab.off] = x
3209 ab.off++
3210 }
3211
3212
3213 func (ab *AsmBuf) Put2(x, y byte) {
3214 ab.buf[ab.off+0] = x
3215 ab.buf[ab.off+1] = y
3216 ab.off += 2
3217 }
3218
3219
3220 func (ab *AsmBuf) Put3(x, y, z byte) {
3221 ab.buf[ab.off+0] = x
3222 ab.buf[ab.off+1] = y
3223 ab.buf[ab.off+2] = z
3224 ab.off += 3
3225 }
3226
3227
3228 func (ab *AsmBuf) Put4(x, y, z, w byte) {
3229 ab.buf[ab.off+0] = x
3230 ab.buf[ab.off+1] = y
3231 ab.buf[ab.off+2] = z
3232 ab.buf[ab.off+3] = w
3233 ab.off += 4
3234 }
3235
3236
3237 func (ab *AsmBuf) PutInt16(v int16) {
3238 ab.buf[ab.off+0] = byte(v)
3239 ab.buf[ab.off+1] = byte(v >> 8)
3240 ab.off += 2
3241 }
3242
3243
3244 func (ab *AsmBuf) PutInt32(v int32) {
3245 ab.buf[ab.off+0] = byte(v)
3246 ab.buf[ab.off+1] = byte(v >> 8)
3247 ab.buf[ab.off+2] = byte(v >> 16)
3248 ab.buf[ab.off+3] = byte(v >> 24)
3249 ab.off += 4
3250 }
3251
3252
3253 func (ab *AsmBuf) PutInt64(v int64) {
3254 ab.buf[ab.off+0] = byte(v)
3255 ab.buf[ab.off+1] = byte(v >> 8)
3256 ab.buf[ab.off+2] = byte(v >> 16)
3257 ab.buf[ab.off+3] = byte(v >> 24)
3258 ab.buf[ab.off+4] = byte(v >> 32)
3259 ab.buf[ab.off+5] = byte(v >> 40)
3260 ab.buf[ab.off+6] = byte(v >> 48)
3261 ab.buf[ab.off+7] = byte(v >> 56)
3262 ab.off += 8
3263 }
3264
3265
3266 func (ab *AsmBuf) Put(b []byte) {
3267 copy(ab.buf[ab.off:], b)
3268 ab.off += len(b)
3269 }
3270
3271
3272
3273
3274
3275
3276
3277 func (ab *AsmBuf) PutOpBytesLit(offset int, op *opBytes) {
3278 for int(op[offset]) != 0 {
3279 ab.Put1(op[offset])
3280 offset++
3281 }
3282 }
3283
3284
3285 func (ab *AsmBuf) Insert(i int, b byte) {
3286 ab.off++
3287 copy(ab.buf[i+1:ab.off], ab.buf[i:ab.off-1])
3288 ab.buf[i] = b
3289 }
3290
3291
3292 func (ab *AsmBuf) Last() byte { return ab.buf[ab.off-1] }
3293
3294
3295 func (ab *AsmBuf) Len() int { return ab.off }
3296
3297
3298 func (ab *AsmBuf) Bytes() []byte { return ab.buf[:ab.off] }
3299
3300
3301 func (ab *AsmBuf) Reset() { ab.off = 0 }
3302
3303
3304 func (ab *AsmBuf) At(i int) byte { return ab.buf[i] }
3305
3306
3307 func (ab *AsmBuf) asmidx(ctxt *obj.Link, scale int, index int, base int) {
3308 var i int
3309
3310
3311 switch index {
3312 default:
3313 goto bad
3314
3315 case REG_NONE:
3316 i = 4 << 3
3317 goto bas
3318
3319 case REG_R8,
3320 REG_R9,
3321 REG_R10,
3322 REG_R11,
3323 REG_R12,
3324 REG_R13,
3325 REG_R14,
3326 REG_R15,
3327 REG_X8,
3328 REG_X9,
3329 REG_X10,
3330 REG_X11,
3331 REG_X12,
3332 REG_X13,
3333 REG_X14,
3334 REG_X15,
3335 REG_X16,
3336 REG_X17,
3337 REG_X18,
3338 REG_X19,
3339 REG_X20,
3340 REG_X21,
3341 REG_X22,
3342 REG_X23,
3343 REG_X24,
3344 REG_X25,
3345 REG_X26,
3346 REG_X27,
3347 REG_X28,
3348 REG_X29,
3349 REG_X30,
3350 REG_X31,
3351 REG_Y8,
3352 REG_Y9,
3353 REG_Y10,
3354 REG_Y11,
3355 REG_Y12,
3356 REG_Y13,
3357 REG_Y14,
3358 REG_Y15,
3359 REG_Y16,
3360 REG_Y17,
3361 REG_Y18,
3362 REG_Y19,
3363 REG_Y20,
3364 REG_Y21,
3365 REG_Y22,
3366 REG_Y23,
3367 REG_Y24,
3368 REG_Y25,
3369 REG_Y26,
3370 REG_Y27,
3371 REG_Y28,
3372 REG_Y29,
3373 REG_Y30,
3374 REG_Y31,
3375 REG_Z8,
3376 REG_Z9,
3377 REG_Z10,
3378 REG_Z11,
3379 REG_Z12,
3380 REG_Z13,
3381 REG_Z14,
3382 REG_Z15,
3383 REG_Z16,
3384 REG_Z17,
3385 REG_Z18,
3386 REG_Z19,
3387 REG_Z20,
3388 REG_Z21,
3389 REG_Z22,
3390 REG_Z23,
3391 REG_Z24,
3392 REG_Z25,
3393 REG_Z26,
3394 REG_Z27,
3395 REG_Z28,
3396 REG_Z29,
3397 REG_Z30,
3398 REG_Z31:
3399 if ctxt.Arch.Family == sys.I386 {
3400 goto bad
3401 }
3402 fallthrough
3403
3404 case REG_AX,
3405 REG_CX,
3406 REG_DX,
3407 REG_BX,
3408 REG_BP,
3409 REG_SI,
3410 REG_DI,
3411 REG_X0,
3412 REG_X1,
3413 REG_X2,
3414 REG_X3,
3415 REG_X4,
3416 REG_X5,
3417 REG_X6,
3418 REG_X7,
3419 REG_Y0,
3420 REG_Y1,
3421 REG_Y2,
3422 REG_Y3,
3423 REG_Y4,
3424 REG_Y5,
3425 REG_Y6,
3426 REG_Y7,
3427 REG_Z0,
3428 REG_Z1,
3429 REG_Z2,
3430 REG_Z3,
3431 REG_Z4,
3432 REG_Z5,
3433 REG_Z6,
3434 REG_Z7:
3435 i = reg[index] << 3
3436 }
3437
3438 switch scale {
3439 default:
3440 goto bad
3441
3442 case 1:
3443 break
3444
3445 case 2:
3446 i |= 1 << 6
3447
3448 case 4:
3449 i |= 2 << 6
3450
3451 case 8:
3452 i |= 3 << 6
3453 }
3454
3455 bas:
3456 switch base {
3457 default:
3458 goto bad
3459
3460 case REG_NONE:
3461 i |= 5
3462
3463 case REG_R8,
3464 REG_R9,
3465 REG_R10,
3466 REG_R11,
3467 REG_R12,
3468 REG_R13,
3469 REG_R14,
3470 REG_R15:
3471 if ctxt.Arch.Family == sys.I386 {
3472 goto bad
3473 }
3474 fallthrough
3475
3476 case REG_AX,
3477 REG_CX,
3478 REG_DX,
3479 REG_BX,
3480 REG_SP,
3481 REG_BP,
3482 REG_SI,
3483 REG_DI:
3484 i |= reg[base]
3485 }
3486
3487 ab.Put1(byte(i))
3488 return
3489
3490 bad:
3491 ctxt.Diag("asmidx: bad address %d/%s/%s", scale, rconv(index), rconv(base))
3492 ab.Put1(0)
3493 }
3494
3495 func (ab *AsmBuf) relput4(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a *obj.Addr) {
3496 var rel obj.Reloc
3497
3498 v := vaddr(ctxt, p, a, &rel)
3499 if rel.Siz != 0 {
3500 if rel.Siz != 4 {
3501 ctxt.Diag("bad reloc")
3502 }
3503 rel.Off = int32(p.Pc + int64(ab.Len()))
3504 cursym.AddRel(ctxt, rel)
3505 }
3506
3507 ab.PutInt32(int32(v))
3508 }
3509
3510 func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int64 {
3511 if r != nil {
3512 *r = obj.Reloc{}
3513 }
3514
3515 switch a.Name {
3516 case obj.NAME_STATIC,
3517 obj.NAME_GOTREF,
3518 obj.NAME_EXTERN:
3519 s := a.Sym
3520 if r == nil {
3521 ctxt.Diag("need reloc for %v", obj.Dconv(p, a))
3522 log.Fatalf("reloc")
3523 }
3524
3525 if a.Name == obj.NAME_GOTREF {
3526 r.Siz = 4
3527 r.Type = objabi.R_GOTPCREL
3528 } else if useAbs(ctxt, s) {
3529 r.Siz = 4
3530 r.Type = objabi.R_ADDR
3531 } else {
3532 r.Siz = 4
3533 r.Type = objabi.R_PCREL
3534 }
3535
3536 r.Off = -1
3537 r.Sym = s
3538 r.Add = a.Offset
3539
3540 return 0
3541 }
3542
3543 if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == REG_TLS {
3544 if r == nil {
3545 ctxt.Diag("need reloc for %v", obj.Dconv(p, a))
3546 log.Fatalf("reloc")
3547 }
3548
3549 if !ctxt.Flag_shared || isAndroid || ctxt.Headtype == objabi.Hdarwin {
3550 r.Type = objabi.R_TLS_LE
3551 r.Siz = 4
3552 r.Off = -1
3553 r.Add = a.Offset
3554 }
3555 return 0
3556 }
3557
3558 return a.Offset
3559 }
3560
3561 func (ab *AsmBuf) asmandsz(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a *obj.Addr, r int, rex int, m64 int) {
3562 var base int
3563 var rel obj.Reloc
3564
3565 rex &= 0x40 | Rxr
3566 if a.Offset != int64(int32(a.Offset)) {
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579 overflowOK := (ctxt.Arch.Family == sys.AMD64 && p.As == ALEAL) ||
3580 (ctxt.Arch.Family != sys.AMD64 &&
3581 int64(uint32(a.Offset)) == a.Offset &&
3582 ab.rexflag&Rxw == 0)
3583 if !overflowOK {
3584 ctxt.Diag("offset too large in %s", p)
3585 }
3586 }
3587 v := int32(a.Offset)
3588 rel.Siz = 0
3589
3590 switch a.Type {
3591 case obj.TYPE_ADDR:
3592 if a.Name == obj.NAME_NONE {
3593 ctxt.Diag("unexpected TYPE_ADDR with NAME_NONE")
3594 }
3595 if a.Index == REG_TLS {
3596 ctxt.Diag("unexpected TYPE_ADDR with index==REG_TLS")
3597 }
3598 goto bad
3599
3600 case obj.TYPE_REG:
3601 const regFirst = REG_AL
3602 const regLast = REG_Z31
3603 if a.Reg < regFirst || regLast < a.Reg {
3604 goto bad
3605 }
3606 if v != 0 {
3607 goto bad
3608 }
3609 ab.Put1(byte(3<<6 | reg[a.Reg]<<0 | r<<3))
3610 ab.rexflag |= regrex[a.Reg]&(0x40|Rxb) | rex
3611 return
3612 }
3613
3614 if a.Type != obj.TYPE_MEM {
3615 goto bad
3616 }
3617
3618 if a.Index != REG_NONE && a.Index != REG_TLS && !(REG_CS <= a.Index && a.Index <= REG_GS) {
3619 base := int(a.Reg)
3620 switch a.Name {
3621 case obj.NAME_EXTERN,
3622 obj.NAME_GOTREF,
3623 obj.NAME_STATIC:
3624 if !useAbs(ctxt, a.Sym) && ctxt.Arch.Family == sys.AMD64 {
3625 goto bad
3626 }
3627 if ctxt.Arch.Family == sys.I386 && ctxt.Flag_shared {
3628
3629
3630
3631 } else {
3632 base = REG_NONE
3633 }
3634 v = int32(vaddr(ctxt, p, a, &rel))
3635
3636 case obj.NAME_AUTO,
3637 obj.NAME_PARAM:
3638 base = REG_SP
3639 }
3640
3641 ab.rexflag |= regrex[int(a.Index)]&Rxx | regrex[base]&Rxb | rex
3642 if base == REG_NONE {
3643 ab.Put1(byte(0<<6 | 4<<0 | r<<3))
3644 ab.asmidx(ctxt, int(a.Scale), int(a.Index), base)
3645 goto putrelv
3646 }
3647
3648 if v == 0 && rel.Siz == 0 && base != REG_BP && base != REG_R13 {
3649 ab.Put1(byte(0<<6 | 4<<0 | r<<3))
3650 ab.asmidx(ctxt, int(a.Scale), int(a.Index), base)
3651 return
3652 }
3653
3654 if disp8, ok := toDisp8(v, p, ab); ok && rel.Siz == 0 {
3655 ab.Put1(byte(1<<6 | 4<<0 | r<<3))
3656 ab.asmidx(ctxt, int(a.Scale), int(a.Index), base)
3657 ab.Put1(disp8)
3658 return
3659 }
3660
3661 ab.Put1(byte(2<<6 | 4<<0 | r<<3))
3662 ab.asmidx(ctxt, int(a.Scale), int(a.Index), base)
3663 goto putrelv
3664 }
3665
3666 base = int(a.Reg)
3667 switch a.Name {
3668 case obj.NAME_STATIC,
3669 obj.NAME_GOTREF,
3670 obj.NAME_EXTERN:
3671 if a.Sym == nil {
3672 ctxt.Diag("bad addr: %v", p)
3673 }
3674 if ctxt.Arch.Family == sys.I386 && ctxt.Flag_shared {
3675
3676
3677
3678 } else {
3679 base = REG_NONE
3680 }
3681 v = int32(vaddr(ctxt, p, a, &rel))
3682
3683 case obj.NAME_AUTO,
3684 obj.NAME_PARAM:
3685 base = REG_SP
3686 }
3687
3688 if base == REG_TLS {
3689 v = int32(vaddr(ctxt, p, a, &rel))
3690 }
3691
3692 ab.rexflag |= regrex[base]&Rxb | rex
3693 if base == REG_NONE || (REG_CS <= base && base <= REG_GS) || base == REG_TLS {
3694 if (a.Sym == nil || !useAbs(ctxt, a.Sym)) && base == REG_NONE && (a.Name == obj.NAME_STATIC || a.Name == obj.NAME_EXTERN || a.Name == obj.NAME_GOTREF) || ctxt.Arch.Family != sys.AMD64 {
3695 if a.Name == obj.NAME_GOTREF && (a.Offset != 0 || a.Index != 0 || a.Scale != 0) {
3696 ctxt.Diag("%v has offset against gotref", p)
3697 }
3698 ab.Put1(byte(0<<6 | 5<<0 | r<<3))
3699 goto putrelv
3700 }
3701
3702
3703 ab.Put2(
3704 byte(0<<6|4<<0|r<<3),
3705 0<<6|4<<3|5<<0,
3706 )
3707 goto putrelv
3708 }
3709
3710 if base == REG_SP || base == REG_R12 {
3711 if v == 0 {
3712 ab.Put1(byte(0<<6 | reg[base]<<0 | r<<3))
3713 ab.asmidx(ctxt, int(a.Scale), REG_NONE, base)
3714 return
3715 }
3716
3717 if disp8, ok := toDisp8(v, p, ab); ok {
3718 ab.Put1(byte(1<<6 | reg[base]<<0 | r<<3))
3719 ab.asmidx(ctxt, int(a.Scale), REG_NONE, base)
3720 ab.Put1(disp8)
3721 return
3722 }
3723
3724 ab.Put1(byte(2<<6 | reg[base]<<0 | r<<3))
3725 ab.asmidx(ctxt, int(a.Scale), REG_NONE, base)
3726 goto putrelv
3727 }
3728
3729 if REG_AX <= base && base <= REG_R15 {
3730 if a.Index == REG_TLS && !ctxt.Flag_shared && !isAndroid &&
3731 ctxt.Headtype != objabi.Hwindows {
3732 rel = obj.Reloc{}
3733 rel.Type = objabi.R_TLS_LE
3734 rel.Siz = 4
3735 rel.Sym = nil
3736 rel.Add = int64(v)
3737 v = 0
3738 }
3739
3740 if v == 0 && rel.Siz == 0 && base != REG_BP && base != REG_R13 {
3741 ab.Put1(byte(0<<6 | reg[base]<<0 | r<<3))
3742 return
3743 }
3744
3745 if disp8, ok := toDisp8(v, p, ab); ok && rel.Siz == 0 {
3746 ab.Put2(byte(1<<6|reg[base]<<0|r<<3), disp8)
3747 return
3748 }
3749
3750 ab.Put1(byte(2<<6 | reg[base]<<0 | r<<3))
3751 goto putrelv
3752 }
3753
3754 goto bad
3755
3756 putrelv:
3757 if rel.Siz != 0 {
3758 if rel.Siz != 4 {
3759 ctxt.Diag("bad rel")
3760 goto bad
3761 }
3762
3763 rel.Off = int32(p.Pc + int64(ab.Len()))
3764 cursym.AddRel(ctxt, rel)
3765 }
3766
3767 ab.PutInt32(v)
3768 return
3769
3770 bad:
3771 ctxt.Diag("asmand: bad address %v", obj.Dconv(p, a))
3772 }
3773
3774 func (ab *AsmBuf) asmand(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a *obj.Addr, ra *obj.Addr) {
3775 ab.asmandsz(ctxt, cursym, p, a, reg[ra.Reg], regrex[ra.Reg], 0)
3776 }
3777
3778 func (ab *AsmBuf) asmando(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a *obj.Addr, o int) {
3779 ab.asmandsz(ctxt, cursym, p, a, o, 0, 0)
3780 }
3781
3782 func bytereg(a *obj.Addr, t *uint8) {
3783 if a.Type == obj.TYPE_REG && a.Index == REG_NONE && (REG_AX <= a.Reg && a.Reg <= REG_R15) {
3784 a.Reg += REG_AL - REG_AX
3785 *t = 0
3786 }
3787 }
3788
3789 func unbytereg(a *obj.Addr, t *uint8) {
3790 if a.Type == obj.TYPE_REG && a.Index == REG_NONE && (REG_AL <= a.Reg && a.Reg <= REG_R15B) {
3791 a.Reg += REG_AX - REG_AL
3792 *t = 0
3793 }
3794 }
3795
3796 const (
3797 movLit uint8 = iota
3798 movRegMem
3799 movMemReg
3800 movRegMem2op
3801 movMemReg2op
3802 movFullPtr
3803 movDoubleShift
3804 movTLSReg
3805 )
3806
3807 var ymovtab = []movtab{
3808
3809 {APUSHL, Ycs, Ynone, Ynone, movLit, [4]uint8{0x0e, 0}},
3810 {APUSHL, Yss, Ynone, Ynone, movLit, [4]uint8{0x16, 0}},
3811 {APUSHL, Yds, Ynone, Ynone, movLit, [4]uint8{0x1e, 0}},
3812 {APUSHL, Yes, Ynone, Ynone, movLit, [4]uint8{0x06, 0}},
3813 {APUSHL, Yfs, Ynone, Ynone, movLit, [4]uint8{0x0f, 0xa0, 0}},
3814 {APUSHL, Ygs, Ynone, Ynone, movLit, [4]uint8{0x0f, 0xa8, 0}},
3815 {APUSHQ, Yfs, Ynone, Ynone, movLit, [4]uint8{0x0f, 0xa0, 0}},
3816 {APUSHQ, Ygs, Ynone, Ynone, movLit, [4]uint8{0x0f, 0xa8, 0}},
3817 {APUSHW, Ycs, Ynone, Ynone, movLit, [4]uint8{Pe, 0x0e, 0}},
3818 {APUSHW, Yss, Ynone, Ynone, movLit, [4]uint8{Pe, 0x16, 0}},
3819 {APUSHW, Yds, Ynone, Ynone, movLit, [4]uint8{Pe, 0x1e, 0}},
3820 {APUSHW, Yes, Ynone, Ynone, movLit, [4]uint8{Pe, 0x06, 0}},
3821 {APUSHW, Yfs, Ynone, Ynone, movLit, [4]uint8{Pe, 0x0f, 0xa0, 0}},
3822 {APUSHW, Ygs, Ynone, Ynone, movLit, [4]uint8{Pe, 0x0f, 0xa8, 0}},
3823
3824
3825 {APOPL, Ynone, Ynone, Yds, movLit, [4]uint8{0x1f, 0}},
3826 {APOPL, Ynone, Ynone, Yes, movLit, [4]uint8{0x07, 0}},
3827 {APOPL, Ynone, Ynone, Yss, movLit, [4]uint8{0x17, 0}},
3828 {APOPL, Ynone, Ynone, Yfs, movLit, [4]uint8{0x0f, 0xa1, 0}},
3829 {APOPL, Ynone, Ynone, Ygs, movLit, [4]uint8{0x0f, 0xa9, 0}},
3830 {APOPQ, Ynone, Ynone, Yfs, movLit, [4]uint8{0x0f, 0xa1, 0}},
3831 {APOPQ, Ynone, Ynone, Ygs, movLit, [4]uint8{0x0f, 0xa9, 0}},
3832 {APOPW, Ynone, Ynone, Yds, movLit, [4]uint8{Pe, 0x1f, 0}},
3833 {APOPW, Ynone, Ynone, Yes, movLit, [4]uint8{Pe, 0x07, 0}},
3834 {APOPW, Ynone, Ynone, Yss, movLit, [4]uint8{Pe, 0x17, 0}},
3835 {APOPW, Ynone, Ynone, Yfs, movLit, [4]uint8{Pe, 0x0f, 0xa1, 0}},
3836 {APOPW, Ynone, Ynone, Ygs, movLit, [4]uint8{Pe, 0x0f, 0xa9, 0}},
3837
3838
3839 {AMOVW, Yes, Ynone, Yml, movRegMem, [4]uint8{0x8c, 0, 0, 0}},
3840 {AMOVW, Ycs, Ynone, Yml, movRegMem, [4]uint8{0x8c, 1, 0, 0}},
3841 {AMOVW, Yss, Ynone, Yml, movRegMem, [4]uint8{0x8c, 2, 0, 0}},
3842 {AMOVW, Yds, Ynone, Yml, movRegMem, [4]uint8{0x8c, 3, 0, 0}},
3843 {AMOVW, Yfs, Ynone, Yml, movRegMem, [4]uint8{0x8c, 4, 0, 0}},
3844 {AMOVW, Ygs, Ynone, Yml, movRegMem, [4]uint8{0x8c, 5, 0, 0}},
3845 {AMOVW, Yml, Ynone, Yes, movMemReg, [4]uint8{0x8e, 0, 0, 0}},
3846 {AMOVW, Yml, Ynone, Ycs, movMemReg, [4]uint8{0x8e, 1, 0, 0}},
3847 {AMOVW, Yml, Ynone, Yss, movMemReg, [4]uint8{0x8e, 2, 0, 0}},
3848 {AMOVW, Yml, Ynone, Yds, movMemReg, [4]uint8{0x8e, 3, 0, 0}},
3849 {AMOVW, Yml, Ynone, Yfs, movMemReg, [4]uint8{0x8e, 4, 0, 0}},
3850 {AMOVW, Yml, Ynone, Ygs, movMemReg, [4]uint8{0x8e, 5, 0, 0}},
3851
3852
3853 {AMOVL, Ycr0, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 0, 0}},
3854 {AMOVL, Ycr2, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 2, 0}},
3855 {AMOVL, Ycr3, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 3, 0}},
3856 {AMOVL, Ycr4, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 4, 0}},
3857 {AMOVL, Ycr8, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 8, 0}},
3858 {AMOVQ, Ycr0, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 0, 0}},
3859 {AMOVQ, Ycr2, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 2, 0}},
3860 {AMOVQ, Ycr3, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 3, 0}},
3861 {AMOVQ, Ycr4, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 4, 0}},
3862 {AMOVQ, Ycr8, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 8, 0}},
3863 {AMOVL, Yrl, Ynone, Ycr0, movMemReg2op, [4]uint8{0x0f, 0x22, 0, 0}},
3864 {AMOVL, Yrl, Ynone, Ycr2, movMemReg2op, [4]uint8{0x0f, 0x22, 2, 0}},
3865 {AMOVL, Yrl, Ynone, Ycr3, movMemReg2op, [4]uint8{0x0f, 0x22, 3, 0}},
3866 {AMOVL, Yrl, Ynone, Ycr4, movMemReg2op, [4]uint8{0x0f, 0x22, 4, 0}},
3867 {AMOVL, Yrl, Ynone, Ycr8, movMemReg2op, [4]uint8{0x0f, 0x22, 8, 0}},
3868 {AMOVQ, Yrl, Ynone, Ycr0, movMemReg2op, [4]uint8{0x0f, 0x22, 0, 0}},
3869 {AMOVQ, Yrl, Ynone, Ycr2, movMemReg2op, [4]uint8{0x0f, 0x22, 2, 0}},
3870 {AMOVQ, Yrl, Ynone, Ycr3, movMemReg2op, [4]uint8{0x0f, 0x22, 3, 0}},
3871 {AMOVQ, Yrl, Ynone, Ycr4, movMemReg2op, [4]uint8{0x0f, 0x22, 4, 0}},
3872 {AMOVQ, Yrl, Ynone, Ycr8, movMemReg2op, [4]uint8{0x0f, 0x22, 8, 0}},
3873
3874
3875 {AMOVL, Ydr0, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 0, 0}},
3876 {AMOVL, Ydr6, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 6, 0}},
3877 {AMOVL, Ydr7, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 7, 0}},
3878 {AMOVQ, Ydr0, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 0, 0}},
3879 {AMOVQ, Ydr2, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 2, 0}},
3880 {AMOVQ, Ydr3, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 3, 0}},
3881 {AMOVQ, Ydr6, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 6, 0}},
3882 {AMOVQ, Ydr7, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 7, 0}},
3883 {AMOVL, Yrl, Ynone, Ydr0, movMemReg2op, [4]uint8{0x0f, 0x23, 0, 0}},
3884 {AMOVL, Yrl, Ynone, Ydr6, movMemReg2op, [4]uint8{0x0f, 0x23, 6, 0}},
3885 {AMOVL, Yrl, Ynone, Ydr7, movMemReg2op, [4]uint8{0x0f, 0x23, 7, 0}},
3886 {AMOVQ, Yrl, Ynone, Ydr0, movMemReg2op, [4]uint8{0x0f, 0x23, 0, 0}},
3887 {AMOVQ, Yrl, Ynone, Ydr2, movMemReg2op, [4]uint8{0x0f, 0x23, 2, 0}},
3888 {AMOVQ, Yrl, Ynone, Ydr3, movMemReg2op, [4]uint8{0x0f, 0x23, 3, 0}},
3889 {AMOVQ, Yrl, Ynone, Ydr6, movMemReg2op, [4]uint8{0x0f, 0x23, 6, 0}},
3890 {AMOVQ, Yrl, Ynone, Ydr7, movMemReg2op, [4]uint8{0x0f, 0x23, 7, 0}},
3891
3892
3893 {AMOVL, Ytr6, Ynone, Yml, movRegMem2op, [4]uint8{0x0f, 0x24, 6, 0}},
3894 {AMOVL, Ytr7, Ynone, Yml, movRegMem2op, [4]uint8{0x0f, 0x24, 7, 0}},
3895 {AMOVL, Yml, Ynone, Ytr6, movMemReg2op, [4]uint8{0x0f, 0x26, 6, 0xff}},
3896 {AMOVL, Yml, Ynone, Ytr7, movMemReg2op, [4]uint8{0x0f, 0x26, 7, 0xff}},
3897
3898
3899 {AMOVL, Ym, Ynone, Ygdtr, movMemReg2op, [4]uint8{0x0f, 0x01, 2, 0}},
3900 {AMOVL, Ygdtr, Ynone, Ym, movRegMem2op, [4]uint8{0x0f, 0x01, 0, 0}},
3901 {AMOVL, Ym, Ynone, Yidtr, movMemReg2op, [4]uint8{0x0f, 0x01, 3, 0}},
3902 {AMOVL, Yidtr, Ynone, Ym, movRegMem2op, [4]uint8{0x0f, 0x01, 1, 0}},
3903 {AMOVQ, Ym, Ynone, Ygdtr, movMemReg2op, [4]uint8{0x0f, 0x01, 2, 0}},
3904 {AMOVQ, Ygdtr, Ynone, Ym, movRegMem2op, [4]uint8{0x0f, 0x01, 0, 0}},
3905 {AMOVQ, Ym, Ynone, Yidtr, movMemReg2op, [4]uint8{0x0f, 0x01, 3, 0}},
3906 {AMOVQ, Yidtr, Ynone, Ym, movRegMem2op, [4]uint8{0x0f, 0x01, 1, 0}},
3907
3908
3909 {AMOVW, Yml, Ynone, Yldtr, movMemReg2op, [4]uint8{0x0f, 0x00, 2, 0}},
3910 {AMOVW, Yldtr, Ynone, Yml, movRegMem2op, [4]uint8{0x0f, 0x00, 0, 0}},
3911
3912
3913 {AMOVW, Yml, Ynone, Ymsw, movMemReg2op, [4]uint8{0x0f, 0x01, 6, 0}},
3914 {AMOVW, Ymsw, Ynone, Yml, movRegMem2op, [4]uint8{0x0f, 0x01, 4, 0}},
3915
3916
3917 {AMOVW, Yml, Ynone, Ytask, movMemReg2op, [4]uint8{0x0f, 0x00, 3, 0}},
3918 {AMOVW, Ytask, Ynone, Yml, movRegMem2op, [4]uint8{0x0f, 0x00, 1, 0}},
3919
3920
3924
3925
3926 {ASHLL, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{0xa4, 0xa5, 0, 0}},
3927 {ASHLL, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{0xa4, 0xa5, 0, 0}},
3928 {ASHLL, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{0xa4, 0xa5, 0, 0}},
3929 {ASHRL, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{0xac, 0xad, 0, 0}},
3930 {ASHRL, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{0xac, 0xad, 0, 0}},
3931 {ASHRL, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{0xac, 0xad, 0, 0}},
3932 {ASHLQ, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xa4, 0xa5, 0}},
3933 {ASHLQ, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xa4, 0xa5, 0}},
3934 {ASHLQ, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xa4, 0xa5, 0}},
3935 {ASHRQ, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xac, 0xad, 0}},
3936 {ASHRQ, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xac, 0xad, 0}},
3937 {ASHRQ, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xac, 0xad, 0}},
3938 {ASHLW, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xa4, 0xa5, 0}},
3939 {ASHLW, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xa4, 0xa5, 0}},
3940 {ASHLW, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xa4, 0xa5, 0}},
3941 {ASHRW, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xac, 0xad, 0}},
3942 {ASHRW, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xac, 0xad, 0}},
3943 {ASHRW, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xac, 0xad, 0}},
3944
3945
3946 {AMOVL, Ytls, Ynone, Yrl, movTLSReg, [4]uint8{0, 0, 0, 0}},
3947 {AMOVQ, Ytls, Ynone, Yrl, movTLSReg, [4]uint8{0, 0, 0, 0}},
3948 {0, 0, 0, 0, 0, [4]uint8{}},
3949 }
3950
3951 func isax(a *obj.Addr) bool {
3952 switch a.Reg {
3953 case REG_AX, REG_AL, REG_AH:
3954 return true
3955 }
3956
3957 return a.Index == REG_AX
3958 }
3959
3960 func subreg(p *obj.Prog, from int, to int) {
3961 if false {
3962 fmt.Printf("\n%v\ts/%v/%v/\n", p, rconv(from), rconv(to))
3963 }
3964
3965 if int(p.From.Reg) == from {
3966 p.From.Reg = int16(to)
3967 p.Ft = 0
3968 }
3969
3970 if int(p.To.Reg) == from {
3971 p.To.Reg = int16(to)
3972 p.Tt = 0
3973 }
3974
3975 if int(p.From.Index) == from {
3976 p.From.Index = int16(to)
3977 p.Ft = 0
3978 }
3979
3980 if int(p.To.Index) == from {
3981 p.To.Index = int16(to)
3982 p.Tt = 0
3983 }
3984
3985 if false {
3986 fmt.Printf("%v\n", p)
3987 }
3988 }
3989
3990 func (ab *AsmBuf) mediaop(ctxt *obj.Link, o *Optab, op int, osize int, z int) int {
3991 switch op {
3992 case Pm, Pe, Pf2, Pf3:
3993 if osize != 1 {
3994 if op != Pm {
3995 ab.Put1(byte(op))
3996 }
3997 ab.Put1(Pm)
3998 z++
3999 op = int(o.op[z])
4000 break
4001 }
4002 fallthrough
4003
4004 default:
4005 if ab.Len() == 0 || ab.Last() != Pm {
4006 ab.Put1(Pm)
4007 }
4008 }
4009
4010 ab.Put1(byte(op))
4011 return z
4012 }
4013
4014
4015
4016
4017
4018
4019 func (ab *AsmBuf) asmevex(ctxt *obj.Link, p *obj.Prog, rm, v, r, k *obj.Addr) {
4020 ab.evexflag = true
4021 evex := ab.evex
4022
4023 rexR := byte(1)
4024 evexR := byte(1)
4025 rexX := byte(1)
4026 rexB := byte(1)
4027 if r != nil {
4028 if regrex[r.Reg]&Rxr != 0 {
4029 rexR = 0
4030 }
4031 if regrex[r.Reg]&RxrEvex != 0 {
4032 evexR = 0
4033 }
4034 }
4035 if rm != nil {
4036 if rm.Index == REG_NONE && regrex[rm.Reg]&RxrEvex != 0 {
4037 rexX = 0
4038 } else if regrex[rm.Index]&Rxx != 0 {
4039 rexX = 0
4040 }
4041 if regrex[rm.Reg]&Rxb != 0 {
4042 rexB = 0
4043 }
4044 }
4045
4046 p0 := (rexR << 7) |
4047 (rexX << 6) |
4048 (rexB << 5) |
4049 (evexR << 4) |
4050 (0 << 2) |
4051 (evex.M() << 0)
4052
4053 vexV := byte(0)
4054 if v != nil {
4055
4056 vexV = byte(reg[v.Reg]|(regrex[v.Reg]&Rxr)<<1) & 0xF
4057 }
4058 vexV ^= 0x0F
4059
4060 p1 := (evex.W() << 7) |
4061 (vexV << 3) |
4062 (1 << 2) |
4063 (evex.P() << 0)
4064
4065 suffix := evexSuffixMap[p.Scond]
4066 evexZ := byte(0)
4067 evexLL := evex.L()
4068 evexB := byte(0)
4069 evexV := byte(1)
4070 evexA := byte(0)
4071 if suffix.zeroing {
4072 if !evex.ZeroingEnabled() {
4073 ctxt.Diag("unsupported zeroing: %v", p)
4074 }
4075 if k == nil {
4076
4077
4078 ctxt.Diag("mask register must be specified for .Z instructions: %v", p)
4079 } else if k.Reg == REG_K0 {
4080
4081
4082
4083 ctxt.Diag("mask register must not be K0 for .Z instructions: %v", p)
4084 }
4085 evexZ = 1
4086 }
4087 switch {
4088 case suffix.rounding != rcUnset:
4089 if rm != nil && rm.Type == obj.TYPE_MEM {
4090 ctxt.Diag("illegal rounding with memory argument: %v", p)
4091 } else if !evex.RoundingEnabled() {
4092 ctxt.Diag("unsupported rounding: %v", p)
4093 }
4094 evexB = 1
4095 evexLL = suffix.rounding
4096 case suffix.broadcast:
4097 if rm == nil || rm.Type != obj.TYPE_MEM {
4098 ctxt.Diag("illegal broadcast without memory argument: %v", p)
4099 } else if !evex.BroadcastEnabled() {
4100 ctxt.Diag("unsupported broadcast: %v", p)
4101 }
4102 evexB = 1
4103 case suffix.sae:
4104 if rm != nil && rm.Type == obj.TYPE_MEM {
4105 ctxt.Diag("illegal SAE with memory argument: %v", p)
4106 } else if !evex.SaeEnabled() {
4107 ctxt.Diag("unsupported SAE: %v", p)
4108 }
4109 evexB = 1
4110 }
4111 if rm != nil && regrex[rm.Index]&RxrEvex != 0 {
4112 evexV = 0
4113 } else if v != nil && regrex[v.Reg]&RxrEvex != 0 {
4114 evexV = 0
4115 }
4116 if k != nil {
4117 evexA = byte(reg[k.Reg])
4118 }
4119
4120 p2 := (evexZ << 7) |
4121 (evexLL << 5) |
4122 (evexB << 4) |
4123 (evexV << 3) |
4124 (evexA << 0)
4125
4126 const evexEscapeByte = 0x62
4127 ab.Put4(evexEscapeByte, p0, p1, p2)
4128 ab.Put1(evex.opcode)
4129 }
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139 func (ab *AsmBuf) asmvex(ctxt *obj.Link, rm, v, r *obj.Addr, vex, opcode uint8) {
4140 ab.vexflag = true
4141 rexR := 0
4142 if r != nil {
4143 rexR = regrex[r.Reg] & Rxr
4144 }
4145 rexB := 0
4146 rexX := 0
4147 if rm != nil {
4148 rexB = regrex[rm.Reg] & Rxb
4149 rexX = regrex[rm.Index] & Rxx
4150 }
4151 vexM := (vex >> 3) & 0x7
4152 vexWLP := vex & 0x87
4153 vexV := byte(0)
4154 if v != nil {
4155 vexV = byte(reg[v.Reg]|(regrex[v.Reg]&Rxr)<<1) & 0xF
4156 }
4157 vexV ^= 0xF
4158 if vexM == 1 && (rexX|rexB) == 0 && vex&vexW1 == 0 {
4159
4160 ab.Put2(0xc5, byte(rexR<<5)^0x80|vexV<<3|vexWLP)
4161 } else {
4162
4163 ab.Put3(0xc4,
4164 (byte(rexR|rexX|rexB)<<5)^0xE0|vexM,
4165 vexV<<3|vexWLP,
4166 )
4167 }
4168 ab.Put1(opcode)
4169 }
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183 func regIndex(r int16) int {
4184 lower3bits := reg[r]
4185 high4bit := regrex[r] & Rxr << 1
4186 high5bit := regrex[r] & RxrEvex << 0
4187 return lower3bits | high4bit | high5bit
4188 }
4189
4190
4191
4192 func avx2gatherValid(ctxt *obj.Link, p *obj.Prog) bool {
4193
4194
4195 index := regIndex(p.GetFrom3().Index)
4196 mask := regIndex(p.From.Reg)
4197 dest := regIndex(p.To.Reg)
4198 if dest == mask || dest == index || mask == index {
4199 ctxt.Diag("mask, index, and destination registers should be distinct: %v", p)
4200 return false
4201 }
4202
4203 return true
4204 }
4205
4206
4207
4208 func avx512gatherValid(ctxt *obj.Link, p *obj.Prog) bool {
4209
4210
4211 index := regIndex(p.From.Index)
4212 dest := regIndex(p.To.Reg)
4213 if dest == index {
4214 ctxt.Diag("index and destination registers should be distinct: %v", p)
4215 return false
4216 }
4217
4218 return true
4219 }
4220
4221 func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
4222 o := opindex[p.As&obj.AMask]
4223
4224 if o == nil {
4225 ctxt.Diag("asmins: missing op %v", p)
4226 return
4227 }
4228
4229 if pre := prefixof(ctxt, &p.From); pre != 0 {
4230 ab.Put1(byte(pre))
4231 }
4232 if pre := prefixof(ctxt, &p.To); pre != 0 {
4233 ab.Put1(byte(pre))
4234 }
4235
4236
4237
4238 switch p.As {
4239 case AVGATHERDPD,
4240 AVGATHERQPD,
4241 AVGATHERDPS,
4242 AVGATHERQPS,
4243 AVPGATHERDD,
4244 AVPGATHERQD,
4245 AVPGATHERDQ,
4246 AVPGATHERQQ:
4247 if p.GetFrom3() == nil {
4248
4249 ctxt.Diag("need a third arg for gather instruction: %v", p)
4250 return
4251 }
4252
4253 if p.GetFrom3().Reg >= REG_K0 && p.GetFrom3().Reg <= REG_K7 {
4254 if !avx512gatherValid(ctxt, p) {
4255 return
4256 }
4257 } else {
4258 if !avx2gatherValid(ctxt, p) {
4259 return
4260 }
4261 }
4262 }
4263
4264 if p.Ft == 0 {
4265 p.Ft = uint8(oclass(ctxt, p, &p.From))
4266 }
4267 if p.Tt == 0 {
4268 p.Tt = uint8(oclass(ctxt, p, &p.To))
4269 }
4270
4271 ft := int(p.Ft) * Ymax
4272 tt := int(p.Tt) * Ymax
4273
4274 xo := obj.Bool2int(o.op[0] == 0x0f)
4275 z := 0
4276
4277 args := make([]int, 0, argListMax)
4278 if ft != Ynone*Ymax {
4279 args = append(args, ft)
4280 }
4281 for i := range p.RestArgs {
4282 args = append(args, oclass(ctxt, p, &p.RestArgs[i].Addr)*Ymax)
4283 }
4284 if tt != Ynone*Ymax {
4285 args = append(args, tt)
4286 }
4287
4288 var f3t int
4289 for _, yt := range o.ytab {
4290
4291
4292
4293
4294
4295
4296
4297 if !yt.match(args) {
4298
4299 z += int(yt.zoffset) + xo
4300 } else {
4301 if p.Scond != 0 && !evexZcase(yt.zcase) {
4302
4303
4304 z += int(yt.zoffset)
4305 continue
4306 }
4307
4308 switch o.prefix {
4309 case Px1:
4310 if ctxt.Arch.Family == sys.AMD64 && z == 0 {
4311 z += int(yt.zoffset) + xo
4312 continue
4313 }
4314 case Pq:
4315 ab.Put2(Pe, Pm)
4316
4317 case Pq3:
4318 ab.rexflag |= Pw
4319 ab.Put2(Pe, Pm)
4320
4321 case Pq4:
4322 ab.Put3(0x66, 0x0F, 0x38)
4323
4324 case Pq4w:
4325 ab.rexflag |= Pw
4326 ab.Put3(0x66, 0x0F, 0x38)
4327
4328 case Pq5:
4329 ab.Put3(0xF3, 0x0F, 0x38)
4330
4331 case Pq5w:
4332 ab.rexflag |= Pw
4333 ab.Put3(0xF3, 0x0F, 0x38)
4334
4335 case Pf2,
4336 Pf3:
4337 ab.Put2(o.prefix, Pm)
4338
4339 case Pef3:
4340 ab.Put3(Pe, Pf3, Pm)
4341
4342 case Pfw:
4343 ab.rexflag |= Pw
4344 ab.Put2(Pf3, Pm)
4345
4346 case Pm:
4347 ab.Put1(Pm)
4348
4349 case Pe:
4350 ab.Put1(Pe)
4351
4352 case Pw:
4353 if ctxt.Arch.Family != sys.AMD64 {
4354 ctxt.Diag("asmins: illegal 64: %v", p)
4355 }
4356 ab.rexflag |= Pw
4357
4358 case Pw8:
4359 if z >= 8 {
4360 if ctxt.Arch.Family != sys.AMD64 {
4361 ctxt.Diag("asmins: illegal 64: %v", p)
4362 }
4363 ab.rexflag |= Pw
4364 }
4365
4366 case Pb:
4367 if ctxt.Arch.Family != sys.AMD64 && (isbadbyte(&p.From) || isbadbyte(&p.To)) {
4368 goto bad
4369 }
4370
4371
4372
4373
4374
4375
4376
4377
4378 if ctxt.Arch.Family == sys.AMD64 {
4379 bytereg(&p.From, &p.Ft)
4380 bytereg(&p.To, &p.Tt)
4381 }
4382
4383 case P32:
4384 if ctxt.Arch.Family == sys.AMD64 {
4385 ctxt.Diag("asmins: illegal in 64-bit mode: %v", p)
4386 }
4387
4388 case Py:
4389 if ctxt.Arch.Family != sys.AMD64 {
4390 ctxt.Diag("asmins: illegal in %d-bit mode: %v", ctxt.Arch.RegSize*8, p)
4391 }
4392
4393 case Py1:
4394 if z < 1 && ctxt.Arch.Family != sys.AMD64 {
4395 ctxt.Diag("asmins: illegal in %d-bit mode: %v", ctxt.Arch.RegSize*8, p)
4396 }
4397
4398 case Py3:
4399 if z < 3 && ctxt.Arch.Family != sys.AMD64 {
4400 ctxt.Diag("asmins: illegal in %d-bit mode: %v", ctxt.Arch.RegSize*8, p)
4401 }
4402 }
4403
4404 if z >= len(o.op) {
4405 log.Fatalf("asmins bad table %v", p)
4406 }
4407 op := int(o.op[z])
4408 if op == 0x0f {
4409 ab.Put1(byte(op))
4410 z++
4411 op = int(o.op[z])
4412 }
4413
4414 switch yt.zcase {
4415 default:
4416 ctxt.Diag("asmins: unknown z %d %v", yt.zcase, p)
4417 return
4418
4419 case Zpseudo:
4420 break
4421
4422 case Zlit:
4423 ab.PutOpBytesLit(z, &o.op)
4424
4425 case Zlitr_m:
4426 ab.PutOpBytesLit(z, &o.op)
4427 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4428
4429 case Zlitm_r:
4430 ab.PutOpBytesLit(z, &o.op)
4431 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4432
4433 case Zlit_m_r:
4434 ab.PutOpBytesLit(z, &o.op)
4435 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4436
4437 case Zmb_r:
4438 bytereg(&p.From, &p.Ft)
4439 fallthrough
4440
4441 case Zm_r:
4442 ab.Put1(byte(op))
4443 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4444
4445 case Z_m_r:
4446 ab.Put1(byte(op))
4447 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4448
4449 case Zm2_r:
4450 ab.Put2(byte(op), o.op[z+1])
4451 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4452
4453 case Zm_r_xm:
4454 ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4455 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4456
4457 case Zm_r_xm_nr:
4458 ab.rexflag = 0
4459 ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4460 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4461
4462 case Zm_r_i_xm:
4463 ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4464 ab.asmand(ctxt, cursym, p, &p.From, p.GetFrom3())
4465 ab.Put1(byte(p.To.Offset))
4466
4467 case Zibm_r, Zibr_m:
4468 ab.PutOpBytesLit(z, &o.op)
4469 if yt.zcase == Zibr_m {
4470 ab.asmand(ctxt, cursym, p, &p.To, p.GetFrom3())
4471 } else {
4472 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4473 }
4474 switch {
4475 default:
4476 ab.Put1(byte(p.From.Offset))
4477 case yt.args[0] == Yi32 && o.prefix == Pe:
4478 ab.PutInt16(int16(p.From.Offset))
4479 case yt.args[0] == Yi32:
4480 ab.PutInt32(int32(p.From.Offset))
4481 }
4482
4483 case Zaut_r:
4484 ab.Put1(0x8d)
4485 if p.From.Type != obj.TYPE_ADDR {
4486 ctxt.Diag("asmins: Zaut sb type ADDR")
4487 }
4488 p.From.Type = obj.TYPE_MEM
4489 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4490 p.From.Type = obj.TYPE_ADDR
4491
4492 case Zm_o:
4493 ab.Put1(byte(op))
4494 ab.asmando(ctxt, cursym, p, &p.From, int(o.op[z+1]))
4495
4496 case Zr_m:
4497 ab.Put1(byte(op))
4498 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4499
4500 case Zvex:
4501 ab.asmvex(ctxt, &p.From, p.GetFrom3(), &p.To, o.op[z], o.op[z+1])
4502
4503 case Zvex_rm_v_r:
4504 ab.asmvex(ctxt, &p.From, p.GetFrom3(), &p.To, o.op[z], o.op[z+1])
4505 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4506
4507 case Zvex_rm_v_ro:
4508 ab.asmvex(ctxt, &p.From, p.GetFrom3(), &p.To, o.op[z], o.op[z+1])
4509 ab.asmando(ctxt, cursym, p, &p.From, int(o.op[z+2]))
4510
4511 case Zvex_i_rm_vo:
4512 ab.asmvex(ctxt, p.GetFrom3(), &p.To, nil, o.op[z], o.op[z+1])
4513 ab.asmando(ctxt, cursym, p, p.GetFrom3(), int(o.op[z+2]))
4514 ab.Put1(byte(p.From.Offset))
4515
4516 case Zvex_i_r_v:
4517 ab.asmvex(ctxt, p.GetFrom3(), &p.To, nil, o.op[z], o.op[z+1])
4518 regnum := byte(0x7)
4519 if p.GetFrom3().Reg >= REG_X0 && p.GetFrom3().Reg <= REG_X15 {
4520 regnum &= byte(p.GetFrom3().Reg - REG_X0)
4521 } else {
4522 regnum &= byte(p.GetFrom3().Reg - REG_Y0)
4523 }
4524 ab.Put1(o.op[z+2] | regnum)
4525 ab.Put1(byte(p.From.Offset))
4526
4527 case Zvex_i_rm_v_r:
4528 imm, from, from3, to := unpackOps4(p)
4529 ab.asmvex(ctxt, from, from3, to, o.op[z], o.op[z+1])
4530 ab.asmand(ctxt, cursym, p, from, to)
4531 ab.Put1(byte(imm.Offset))
4532
4533 case Zvex_i_rm_r:
4534 ab.asmvex(ctxt, p.GetFrom3(), nil, &p.To, o.op[z], o.op[z+1])
4535 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4536 ab.Put1(byte(p.From.Offset))
4537
4538 case Zvex_v_rm_r:
4539 ab.asmvex(ctxt, p.GetFrom3(), &p.From, &p.To, o.op[z], o.op[z+1])
4540 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4541
4542 case Zvex_r_v_rm:
4543 ab.asmvex(ctxt, &p.To, p.GetFrom3(), &p.From, o.op[z], o.op[z+1])
4544 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4545
4546 case Zvex_rm_r_vo:
4547 ab.asmvex(ctxt, &p.From, &p.To, p.GetFrom3(), o.op[z], o.op[z+1])
4548 ab.asmando(ctxt, cursym, p, &p.From, int(o.op[z+2]))
4549
4550 case Zvex_i_r_rm:
4551 ab.asmvex(ctxt, &p.To, nil, p.GetFrom3(), o.op[z], o.op[z+1])
4552 ab.asmand(ctxt, cursym, p, &p.To, p.GetFrom3())
4553 ab.Put1(byte(p.From.Offset))
4554
4555 case Zvex_hr_rm_v_r:
4556 hr, from, from3, to := unpackOps4(p)
4557 ab.asmvex(ctxt, from, from3, to, o.op[z], o.op[z+1])
4558 ab.asmand(ctxt, cursym, p, from, to)
4559 ab.Put1(byte(regIndex(hr.Reg) << 4))
4560
4561 case Zevex_k_rmo:
4562 ab.evex = newEVEXBits(z, &o.op)
4563 ab.asmevex(ctxt, p, &p.To, nil, nil, &p.From)
4564 ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+3]))
4565
4566 case Zevex_i_rm_vo:
4567 ab.evex = newEVEXBits(z, &o.op)
4568 ab.asmevex(ctxt, p, p.GetFrom3(), &p.To, nil, nil)
4569 ab.asmando(ctxt, cursym, p, p.GetFrom3(), int(o.op[z+3]))
4570 ab.Put1(byte(p.From.Offset))
4571
4572 case Zevex_i_rm_k_vo:
4573 imm, from, kmask, to := unpackOps4(p)
4574 ab.evex = newEVEXBits(z, &o.op)
4575 ab.asmevex(ctxt, p, from, to, nil, kmask)
4576 ab.asmando(ctxt, cursym, p, from, int(o.op[z+3]))
4577 ab.Put1(byte(imm.Offset))
4578
4579 case Zevex_i_r_rm:
4580 ab.evex = newEVEXBits(z, &o.op)
4581 ab.asmevex(ctxt, p, &p.To, nil, p.GetFrom3(), nil)
4582 ab.asmand(ctxt, cursym, p, &p.To, p.GetFrom3())
4583 ab.Put1(byte(p.From.Offset))
4584
4585 case Zevex_i_r_k_rm:
4586 imm, from, kmask, to := unpackOps4(p)
4587 ab.evex = newEVEXBits(z, &o.op)
4588 ab.asmevex(ctxt, p, to, nil, from, kmask)
4589 ab.asmand(ctxt, cursym, p, to, from)
4590 ab.Put1(byte(imm.Offset))
4591
4592 case Zevex_i_rm_r:
4593 ab.evex = newEVEXBits(z, &o.op)
4594 ab.asmevex(ctxt, p, p.GetFrom3(), nil, &p.To, nil)
4595 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4596 ab.Put1(byte(p.From.Offset))
4597
4598 case Zevex_i_rm_k_r:
4599 imm, from, kmask, to := unpackOps4(p)
4600 ab.evex = newEVEXBits(z, &o.op)
4601 ab.asmevex(ctxt, p, from, nil, to, kmask)
4602 ab.asmand(ctxt, cursym, p, from, to)
4603 ab.Put1(byte(imm.Offset))
4604
4605 case Zevex_i_rm_v_r:
4606 imm, from, from3, to := unpackOps4(p)
4607 ab.evex = newEVEXBits(z, &o.op)
4608 ab.asmevex(ctxt, p, from, from3, to, nil)
4609 ab.asmand(ctxt, cursym, p, from, to)
4610 ab.Put1(byte(imm.Offset))
4611
4612 case Zevex_i_rm_v_k_r:
4613 imm, from, from3, kmask, to := unpackOps5(p)
4614 ab.evex = newEVEXBits(z, &o.op)
4615 ab.asmevex(ctxt, p, from, from3, to, kmask)
4616 ab.asmand(ctxt, cursym, p, from, to)
4617 ab.Put1(byte(imm.Offset))
4618
4619 case Zevex_r_v_rm:
4620 ab.evex = newEVEXBits(z, &o.op)
4621 ab.asmevex(ctxt, p, &p.To, p.GetFrom3(), &p.From, nil)
4622 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4623
4624 case Zevex_rm_v_r:
4625 ab.evex = newEVEXBits(z, &o.op)
4626 ab.asmevex(ctxt, p, &p.From, p.GetFrom3(), &p.To, nil)
4627 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4628
4629 case Zevex_rm_k_r:
4630 ab.evex = newEVEXBits(z, &o.op)
4631 ab.asmevex(ctxt, p, &p.From, nil, &p.To, p.GetFrom3())
4632 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4633
4634 case Zevex_r_k_rm:
4635 ab.evex = newEVEXBits(z, &o.op)
4636 ab.asmevex(ctxt, p, &p.To, nil, &p.From, p.GetFrom3())
4637 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4638
4639 case Zevex_rm_v_k_r:
4640 from, from3, kmask, to := unpackOps4(p)
4641 ab.evex = newEVEXBits(z, &o.op)
4642 ab.asmevex(ctxt, p, from, from3, to, kmask)
4643 ab.asmand(ctxt, cursym, p, from, to)
4644
4645 case Zevex_r_v_k_rm:
4646 from, from3, kmask, to := unpackOps4(p)
4647 ab.evex = newEVEXBits(z, &o.op)
4648 ab.asmevex(ctxt, p, to, from3, from, kmask)
4649 ab.asmand(ctxt, cursym, p, to, from)
4650
4651 case Zr_m_xm:
4652 ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4653 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4654
4655 case Zr_m_xm_nr:
4656 ab.rexflag = 0
4657 ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4658 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4659
4660 case Zo_m:
4661 ab.Put1(byte(op))
4662 ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+1]))
4663
4664 case Zcallindreg:
4665 cursym.AddRel(ctxt, obj.Reloc{
4666 Type: objabi.R_CALLIND,
4667 Off: int32(p.Pc),
4668 })
4669 fallthrough
4670
4671 case Zo_m64:
4672 ab.Put1(byte(op))
4673 ab.asmandsz(ctxt, cursym, p, &p.To, int(o.op[z+1]), 0, 1)
4674
4675 case Zm_ibo:
4676 ab.Put1(byte(op))
4677 ab.asmando(ctxt, cursym, p, &p.From, int(o.op[z+1]))
4678 ab.Put1(byte(vaddr(ctxt, p, &p.To, nil)))
4679
4680 case Zibo_m:
4681 ab.Put1(byte(op))
4682 ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+1]))
4683 ab.Put1(byte(vaddr(ctxt, p, &p.From, nil)))
4684
4685 case Zibo_m_xm:
4686 z = ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4687 ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+1]))
4688 ab.Put1(byte(vaddr(ctxt, p, &p.From, nil)))
4689
4690 case Z_ib, Zib_:
4691 var a *obj.Addr
4692 if yt.zcase == Zib_ {
4693 a = &p.From
4694 } else {
4695 a = &p.To
4696 }
4697 ab.Put1(byte(op))
4698 if p.As == AXABORT {
4699 ab.Put1(o.op[z+1])
4700 }
4701 ab.Put1(byte(vaddr(ctxt, p, a, nil)))
4702
4703 case Zib_rp:
4704 ab.rexflag |= regrex[p.To.Reg] & (Rxb | 0x40)
4705 ab.Put2(byte(op+reg[p.To.Reg]), byte(vaddr(ctxt, p, &p.From, nil)))
4706
4707 case Zil_rp:
4708 ab.rexflag |= regrex[p.To.Reg] & Rxb
4709 ab.Put1(byte(op + reg[p.To.Reg]))
4710 if o.prefix == Pe {
4711 v := vaddr(ctxt, p, &p.From, nil)
4712 ab.PutInt16(int16(v))
4713 } else {
4714 ab.relput4(ctxt, cursym, p, &p.From)
4715 }
4716
4717 case Zo_iw:
4718 ab.Put1(byte(op))
4719 if p.From.Type != obj.TYPE_NONE {
4720 v := vaddr(ctxt, p, &p.From, nil)
4721 ab.PutInt16(int16(v))
4722 }
4723
4724 case Ziq_rp:
4725 var rel obj.Reloc
4726 v := vaddr(ctxt, p, &p.From, &rel)
4727 l := int(v >> 32)
4728 if l == 0 && rel.Siz != 8 {
4729 ab.rexflag &^= (0x40 | Rxw)
4730
4731 ab.rexflag |= regrex[p.To.Reg] & Rxb
4732 ab.Put1(byte(0xb8 + reg[p.To.Reg]))
4733 if rel.Type != 0 {
4734 rel.Off = int32(p.Pc + int64(ab.Len()))
4735 cursym.AddRel(ctxt, rel)
4736 }
4737
4738 ab.PutInt32(int32(v))
4739 } else if l == -1 && uint64(v)&(uint64(1)<<31) != 0 {
4740 ab.Put1(0xc7)
4741 ab.asmando(ctxt, cursym, p, &p.To, 0)
4742
4743 ab.PutInt32(int32(v))
4744 } else {
4745 ab.rexflag |= regrex[p.To.Reg] & Rxb
4746 ab.Put1(byte(op + reg[p.To.Reg]))
4747 if rel.Type != 0 {
4748 rel.Off = int32(p.Pc + int64(ab.Len()))
4749 cursym.AddRel(ctxt, rel)
4750 }
4751
4752 ab.PutInt64(v)
4753 }
4754
4755 case Zib_rr:
4756 ab.Put1(byte(op))
4757 ab.asmand(ctxt, cursym, p, &p.To, &p.To)
4758 ab.Put1(byte(vaddr(ctxt, p, &p.From, nil)))
4759
4760 case Z_il, Zil_:
4761 var a *obj.Addr
4762 if yt.zcase == Zil_ {
4763 a = &p.From
4764 } else {
4765 a = &p.To
4766 }
4767 ab.Put1(byte(op))
4768 if o.prefix == Pe {
4769 v := vaddr(ctxt, p, a, nil)
4770 ab.PutInt16(int16(v))
4771 } else {
4772 ab.relput4(ctxt, cursym, p, a)
4773 }
4774
4775 case Zm_ilo, Zilo_m:
4776 var a *obj.Addr
4777 ab.Put1(byte(op))
4778 if yt.zcase == Zilo_m {
4779 a = &p.From
4780 ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+1]))
4781 } else {
4782 a = &p.To
4783 ab.asmando(ctxt, cursym, p, &p.From, int(o.op[z+1]))
4784 }
4785
4786 if o.prefix == Pe {
4787 v := vaddr(ctxt, p, a, nil)
4788 ab.PutInt16(int16(v))
4789 } else {
4790 ab.relput4(ctxt, cursym, p, a)
4791 }
4792
4793 case Zil_rr:
4794 ab.Put1(byte(op))
4795 ab.asmand(ctxt, cursym, p, &p.To, &p.To)
4796 if o.prefix == Pe {
4797 v := vaddr(ctxt, p, &p.From, nil)
4798 ab.PutInt16(int16(v))
4799 } else {
4800 ab.relput4(ctxt, cursym, p, &p.From)
4801 }
4802
4803 case Z_rp:
4804 ab.rexflag |= regrex[p.To.Reg] & (Rxb | 0x40)
4805 ab.Put1(byte(op + reg[p.To.Reg]))
4806
4807 case Zrp_:
4808 ab.rexflag |= regrex[p.From.Reg] & (Rxb | 0x40)
4809 ab.Put1(byte(op + reg[p.From.Reg]))
4810
4811 case Zcallcon, Zjmpcon:
4812 if yt.zcase == Zcallcon {
4813 ab.Put1(byte(op))
4814 } else {
4815 ab.Put1(o.op[z+1])
4816 }
4817 cursym.AddRel(ctxt, obj.Reloc{
4818 Type: objabi.R_PCREL,
4819 Off: int32(p.Pc + int64(ab.Len())),
4820 Siz: 4,
4821 Add: p.To.Offset,
4822 })
4823 ab.PutInt32(0)
4824
4825 case Zcallind:
4826 ab.Put2(byte(op), o.op[z+1])
4827 typ := objabi.R_ADDR
4828 if ctxt.Arch.Family == sys.AMD64 {
4829 typ = objabi.R_PCREL
4830 }
4831 cursym.AddRel(ctxt, obj.Reloc{
4832 Type: typ,
4833 Off: int32(p.Pc + int64(ab.Len())),
4834 Siz: 4,
4835 Sym: p.To.Sym,
4836 Add: p.To.Offset,
4837 })
4838 ab.PutInt32(0)
4839
4840 case Zcall, Zcallduff:
4841 if p.To.Sym == nil {
4842 ctxt.Diag("call without target")
4843 ctxt.DiagFlush()
4844 log.Fatalf("bad code")
4845 }
4846
4847 if yt.zcase == Zcallduff && ctxt.Flag_dynlink {
4848 ctxt.Diag("directly calling duff when dynamically linking Go")
4849 }
4850
4851 ab.Put1(byte(op))
4852 cursym.AddRel(ctxt, obj.Reloc{
4853 Type: objabi.R_CALL,
4854 Off: int32(p.Pc + int64(ab.Len())),
4855 Siz: 4,
4856 Sym: p.To.Sym,
4857 Add: p.To.Offset,
4858 })
4859 ab.PutInt32(0)
4860
4861
4862 case Zbr, Zjmp, Zloop:
4863 if p.As == AXBEGIN {
4864 ab.Put1(byte(op))
4865 }
4866 if p.To.Sym != nil {
4867 if yt.zcase != Zjmp {
4868 ctxt.Diag("branch to ATEXT")
4869 ctxt.DiagFlush()
4870 log.Fatalf("bad code")
4871 }
4872
4873 ab.Put1(o.op[z+1])
4874 cursym.AddRel(ctxt, obj.Reloc{
4875
4876
4877 Type: objabi.R_CALL,
4878 Off: int32(p.Pc + int64(ab.Len())),
4879 Siz: 4,
4880 Sym: p.To.Sym,
4881 })
4882 ab.PutInt32(0)
4883 break
4884 }
4885
4886
4887
4888
4889
4890 q := p.To.Target()
4891
4892 if q == nil {
4893 ctxt.Diag("jmp/branch/loop without target")
4894 ctxt.DiagFlush()
4895 log.Fatalf("bad code")
4896 }
4897
4898 if p.Back&branchBackwards != 0 {
4899 v := q.Pc - (p.Pc + 2)
4900 if v >= -128 && p.As != AXBEGIN {
4901 if p.As == AJCXZL {
4902 ab.Put1(0x67)
4903 }
4904 ab.Put2(byte(op), byte(v))
4905 } else if yt.zcase == Zloop {
4906 ctxt.Diag("loop too far: %v", p)
4907 } else {
4908 v -= 5 - 2
4909 if p.As == AXBEGIN {
4910 v--
4911 }
4912 if yt.zcase == Zbr {
4913 ab.Put1(0x0f)
4914 v--
4915 }
4916
4917 ab.Put1(o.op[z+1])
4918 ab.PutInt32(int32(v))
4919 }
4920
4921 break
4922 }
4923
4924
4925 p.Forwd = q.Rel
4926
4927 q.Rel = p
4928 if p.Back&branchShort != 0 && p.As != AXBEGIN {
4929 if p.As == AJCXZL {
4930 ab.Put1(0x67)
4931 }
4932 ab.Put2(byte(op), 0)
4933 } else if yt.zcase == Zloop {
4934 ctxt.Diag("loop too far: %v", p)
4935 } else {
4936 if yt.zcase == Zbr {
4937 ab.Put1(0x0f)
4938 }
4939 ab.Put1(o.op[z+1])
4940 ab.PutInt32(0)
4941 }
4942
4943 case Zbyte:
4944 var rel obj.Reloc
4945 v := vaddr(ctxt, p, &p.From, &rel)
4946 if rel.Siz != 0 {
4947 rel.Siz = uint8(op)
4948 rel.Off = int32(p.Pc + int64(ab.Len()))
4949 cursym.AddRel(ctxt, rel)
4950 }
4951
4952 ab.Put1(byte(v))
4953 if op > 1 {
4954 ab.Put1(byte(v >> 8))
4955 if op > 2 {
4956 ab.PutInt16(int16(v >> 16))
4957 if op > 4 {
4958 ab.PutInt32(int32(v >> 32))
4959 }
4960 }
4961 }
4962 }
4963
4964 return
4965 }
4966 }
4967 f3t = Ynone * Ymax
4968 if p.GetFrom3() != nil {
4969 f3t = oclass(ctxt, p, p.GetFrom3()) * Ymax
4970 }
4971 for mo := ymovtab; mo[0].as != 0; mo = mo[1:] {
4972 var pp obj.Prog
4973 var t []byte
4974 if p.As == mo[0].as {
4975 if ycover[ft+int(mo[0].ft)] != 0 && ycover[f3t+int(mo[0].f3t)] != 0 && ycover[tt+int(mo[0].tt)] != 0 {
4976 t = mo[0].op[:]
4977 switch mo[0].code {
4978 default:
4979 ctxt.Diag("asmins: unknown mov %d %v", mo[0].code, p)
4980
4981 case movLit:
4982 for z = 0; t[z] != 0; z++ {
4983 ab.Put1(t[z])
4984 }
4985
4986 case movRegMem:
4987 ab.Put1(t[0])
4988 ab.asmando(ctxt, cursym, p, &p.To, int(t[1]))
4989
4990 case movMemReg:
4991 ab.Put1(t[0])
4992 ab.asmando(ctxt, cursym, p, &p.From, int(t[1]))
4993
4994 case movRegMem2op:
4995 ab.Put2(t[0], t[1])
4996 ab.asmando(ctxt, cursym, p, &p.To, int(t[2]))
4997 ab.rexflag |= regrex[p.From.Reg] & (Rxr | 0x40)
4998
4999 case movMemReg2op:
5000 ab.Put2(t[0], t[1])
5001 ab.asmando(ctxt, cursym, p, &p.From, int(t[2]))
5002 ab.rexflag |= regrex[p.To.Reg] & (Rxr | 0x40)
5003
5004 case movFullPtr:
5005 if t[0] != 0 {
5006 ab.Put1(t[0])
5007 }
5008 switch p.To.Index {
5009 default:
5010 goto bad
5011
5012 case REG_DS:
5013 ab.Put1(0xc5)
5014
5015 case REG_SS:
5016 ab.Put2(0x0f, 0xb2)
5017
5018 case REG_ES:
5019 ab.Put1(0xc4)
5020
5021 case REG_FS:
5022 ab.Put2(0x0f, 0xb4)
5023
5024 case REG_GS:
5025 ab.Put2(0x0f, 0xb5)
5026 }
5027
5028 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
5029
5030 case movDoubleShift:
5031 if t[0] == Pw {
5032 if ctxt.Arch.Family != sys.AMD64 {
5033 ctxt.Diag("asmins: illegal 64: %v", p)
5034 }
5035 ab.rexflag |= Pw
5036 t = t[1:]
5037 } else if t[0] == Pe {
5038 ab.Put1(Pe)
5039 t = t[1:]
5040 }
5041
5042 switch p.From.Type {
5043 default:
5044 goto bad
5045
5046 case obj.TYPE_CONST:
5047 ab.Put2(0x0f, t[0])
5048 ab.asmandsz(ctxt, cursym, p, &p.To, reg[p.GetFrom3().Reg], regrex[p.GetFrom3().Reg], 0)
5049 ab.Put1(byte(p.From.Offset))
5050
5051 case obj.TYPE_REG:
5052 switch p.From.Reg {
5053 default:
5054 goto bad
5055
5056 case REG_CL, REG_CX:
5057 ab.Put2(0x0f, t[1])
5058 ab.asmandsz(ctxt, cursym, p, &p.To, reg[p.GetFrom3().Reg], regrex[p.GetFrom3().Reg], 0)
5059 }
5060 }
5061
5062
5063
5064
5065
5066 case movTLSReg:
5067 if ctxt.Arch.Family == sys.AMD64 && p.As != AMOVQ || ctxt.Arch.Family == sys.I386 && p.As != AMOVL {
5068 ctxt.Diag("invalid load of TLS: %v", p)
5069 }
5070
5071 if ctxt.Arch.Family == sys.I386 {
5072
5073
5074
5075
5076 switch ctxt.Headtype {
5077 default:
5078 log.Fatalf("unknown TLS base location for %v", ctxt.Headtype)
5079
5080 case objabi.Hlinux, objabi.Hfreebsd:
5081 if ctxt.Flag_shared {
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093 dst := p.To.Reg
5094 ab.Put1(0xe8)
5095 cursym.AddRel(ctxt, obj.Reloc{
5096 Type: objabi.R_CALL,
5097 Off: int32(p.Pc + int64(ab.Len())),
5098 Siz: 4,
5099 Sym: ctxt.Lookup("__x86.get_pc_thunk." + strings.ToLower(rconv(int(dst)))),
5100 })
5101 ab.PutInt32(0)
5102
5103 ab.Put2(0x8B, byte(2<<6|reg[dst]|(reg[dst]<<3)))
5104 cursym.AddRel(ctxt, obj.Reloc{
5105 Type: objabi.R_TLS_IE,
5106 Off: int32(p.Pc + int64(ab.Len())),
5107 Siz: 4,
5108 Add: 2,
5109 })
5110 ab.PutInt32(0)
5111 } else {
5112
5113 pp.From = p.From
5114
5115 pp.From.Type = obj.TYPE_MEM
5116 pp.From.Reg = REG_GS
5117 pp.From.Offset = 0
5118 pp.From.Index = REG_NONE
5119 pp.From.Scale = 0
5120 ab.Put2(0x65,
5121 0x8B)
5122 ab.asmand(ctxt, cursym, p, &pp.From, &p.To)
5123 }
5124 case objabi.Hplan9:
5125 pp.From = obj.Addr{}
5126 pp.From.Type = obj.TYPE_MEM
5127 pp.From.Name = obj.NAME_EXTERN
5128 pp.From.Sym = plan9privates
5129 pp.From.Offset = 0
5130 pp.From.Index = REG_NONE
5131 ab.Put1(0x8B)
5132 ab.asmand(ctxt, cursym, p, &pp.From, &p.To)
5133 }
5134 break
5135 }
5136
5137 switch ctxt.Headtype {
5138 default:
5139 log.Fatalf("unknown TLS base location for %v", ctxt.Headtype)
5140
5141 case objabi.Hlinux, objabi.Hfreebsd, objabi.Hopenbsd:
5142 if !ctxt.Flag_shared {
5143 log.Fatalf("unknown TLS base location for %v without -shared", ctxt.Headtype)
5144 }
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154 ab.rexflag = Pw | (regrex[p.To.Reg] & Rxr)
5155
5156 ab.Put2(0x8B, byte(0x05|(reg[p.To.Reg]<<3)))
5157 cursym.AddRel(ctxt, obj.Reloc{
5158 Type: objabi.R_TLS_IE,
5159 Off: int32(p.Pc + int64(ab.Len())),
5160 Siz: 4,
5161 Add: -4,
5162 })
5163 ab.PutInt32(0)
5164
5165 case objabi.Hplan9:
5166 pp.From = obj.Addr{}
5167 pp.From.Type = obj.TYPE_MEM
5168 pp.From.Name = obj.NAME_EXTERN
5169 pp.From.Sym = plan9privates
5170 pp.From.Offset = 0
5171 pp.From.Index = REG_NONE
5172 ab.rexflag |= Pw
5173 ab.Put1(0x8B)
5174 ab.asmand(ctxt, cursym, p, &pp.From, &p.To)
5175
5176 case objabi.Hsolaris:
5177
5178 pp.From = p.From
5179
5180 pp.From.Type = obj.TYPE_MEM
5181 pp.From.Name = obj.NAME_NONE
5182 pp.From.Reg = REG_NONE
5183 pp.From.Offset = 0
5184 pp.From.Index = REG_NONE
5185 pp.From.Scale = 0
5186 ab.rexflag |= Pw
5187 ab.Put2(0x64,
5188 0x8B)
5189 ab.asmand(ctxt, cursym, p, &pp.From, &p.To)
5190 }
5191 }
5192 return
5193 }
5194 }
5195 }
5196 goto bad
5197
5198 bad:
5199 if ctxt.Arch.Family != sys.AMD64 {
5200
5201
5202
5203
5204
5205 pp := *p
5206
5207 unbytereg(&pp.From, &pp.Ft)
5208 unbytereg(&pp.To, &pp.Tt)
5209
5210 z := int(p.From.Reg)
5211 if p.From.Type == obj.TYPE_REG && z >= REG_BP && z <= REG_DI {
5212
5213
5214 if ctxt.Arch.Family == sys.I386 {
5215 breg := byteswapreg(ctxt, &p.To)
5216 if breg != REG_AX {
5217 ab.Put1(0x87)
5218 ab.asmando(ctxt, cursym, p, &p.From, reg[breg])
5219 subreg(&pp, z, breg)
5220 ab.doasm(ctxt, cursym, &pp)
5221 ab.Put1(0x87)
5222 ab.asmando(ctxt, cursym, p, &p.From, reg[breg])
5223 } else {
5224 ab.Put1(byte(0x90 + reg[z]))
5225 subreg(&pp, z, REG_AX)
5226 ab.doasm(ctxt, cursym, &pp)
5227 ab.Put1(byte(0x90 + reg[z]))
5228 }
5229 return
5230 }
5231
5232 if isax(&p.To) || p.To.Type == obj.TYPE_NONE {
5233
5234
5235 ab.Put1(0x87)
5236 ab.asmando(ctxt, cursym, p, &p.From, reg[REG_BX])
5237 subreg(&pp, z, REG_BX)
5238 ab.doasm(ctxt, cursym, &pp)
5239 ab.Put1(0x87)
5240 ab.asmando(ctxt, cursym, p, &p.From, reg[REG_BX])
5241 } else {
5242 ab.Put1(byte(0x90 + reg[z]))
5243 subreg(&pp, z, REG_AX)
5244 ab.doasm(ctxt, cursym, &pp)
5245 ab.Put1(byte(0x90 + reg[z]))
5246 }
5247 return
5248 }
5249
5250 z = int(p.To.Reg)
5251 if p.To.Type == obj.TYPE_REG && z >= REG_BP && z <= REG_DI {
5252
5253
5254 if ctxt.Arch.Family == sys.I386 {
5255 breg := byteswapreg(ctxt, &p.From)
5256 if breg != REG_AX {
5257 ab.Put1(0x87)
5258 ab.asmando(ctxt, cursym, p, &p.To, reg[breg])
5259 subreg(&pp, z, breg)
5260 ab.doasm(ctxt, cursym, &pp)
5261 ab.Put1(0x87)
5262 ab.asmando(ctxt, cursym, p, &p.To, reg[breg])
5263 } else {
5264 ab.Put1(byte(0x90 + reg[z]))
5265 subreg(&pp, z, REG_AX)
5266 ab.doasm(ctxt, cursym, &pp)
5267 ab.Put1(byte(0x90 + reg[z]))
5268 }
5269 return
5270 }
5271
5272 if isax(&p.From) {
5273 ab.Put1(0x87)
5274 ab.asmando(ctxt, cursym, p, &p.To, reg[REG_BX])
5275 subreg(&pp, z, REG_BX)
5276 ab.doasm(ctxt, cursym, &pp)
5277 ab.Put1(0x87)
5278 ab.asmando(ctxt, cursym, p, &p.To, reg[REG_BX])
5279 } else {
5280 ab.Put1(byte(0x90 + reg[z]))
5281 subreg(&pp, z, REG_AX)
5282 ab.doasm(ctxt, cursym, &pp)
5283 ab.Put1(byte(0x90 + reg[z]))
5284 }
5285 return
5286 }
5287 }
5288
5289 ctxt.Diag("%s: invalid instruction: %v", cursym.Name, p)
5290 }
5291
5292
5293
5294
5295
5296 func byteswapreg(ctxt *obj.Link, a *obj.Addr) int {
5297 cana, canb, canc, cand := true, true, true, true
5298 if a.Type == obj.TYPE_NONE {
5299 cana, cand = false, false
5300 }
5301
5302 if a.Type == obj.TYPE_REG || ((a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Name == obj.NAME_NONE) {
5303 switch a.Reg {
5304 case REG_NONE:
5305 cana, cand = false, false
5306 case REG_AX, REG_AL, REG_AH:
5307 cana = false
5308 case REG_BX, REG_BL, REG_BH:
5309 canb = false
5310 case REG_CX, REG_CL, REG_CH:
5311 canc = false
5312 case REG_DX, REG_DL, REG_DH:
5313 cand = false
5314 }
5315 }
5316
5317 if a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR {
5318 switch a.Index {
5319 case REG_AX:
5320 cana = false
5321 case REG_BX:
5322 canb = false
5323 case REG_CX:
5324 canc = false
5325 case REG_DX:
5326 cand = false
5327 }
5328 }
5329
5330 switch {
5331 case cana:
5332 return REG_AX
5333 case canb:
5334 return REG_BX
5335 case canc:
5336 return REG_CX
5337 case cand:
5338 return REG_DX
5339 default:
5340 ctxt.Diag("impossible byte register")
5341 ctxt.DiagFlush()
5342 log.Fatalf("bad code")
5343 return 0
5344 }
5345 }
5346
5347 func isbadbyte(a *obj.Addr) bool {
5348 return a.Type == obj.TYPE_REG && (REG_BP <= a.Reg && a.Reg <= REG_DI || REG_BPB <= a.Reg && a.Reg <= REG_DIB)
5349 }
5350
5351
5352
5353 func highByteReg(p *obj.Prog) int {
5354 isHigh := func(r int16) bool { return REG_AH <= r && r <= REG_BH }
5355 if p.From.Type == obj.TYPE_REG && isHigh(p.From.Reg) {
5356 return int(p.From.Reg)
5357 }
5358 if isHigh(p.Reg) {
5359 return int(p.Reg)
5360 }
5361 for _, a := range p.RestArgs {
5362 if a.Type == obj.TYPE_REG && isHigh(a.Reg) {
5363 return int(a.Reg)
5364 }
5365 }
5366 if p.To.Type == obj.TYPE_REG && isHigh(p.To.Reg) {
5367 return int(p.To.Reg)
5368 }
5369 return 0
5370 }
5371
5372 func (ab *AsmBuf) asmins(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
5373 ab.Reset()
5374
5375 ab.rexflag = 0
5376 ab.vexflag = false
5377 ab.evexflag = false
5378 mark := ab.Len()
5379 ab.doasm(ctxt, cursym, p)
5380 if ab.rexflag != 0 && !ab.vexflag && !ab.evexflag {
5381
5382
5383
5384
5385
5386 if ctxt.Arch.Family != sys.AMD64 {
5387 ctxt.Diag("asmins: illegal in mode %d: %v (%d %d)", ctxt.Arch.RegSize*8, p, p.Ft, p.Tt)
5388 }
5389
5390
5391 if r := highByteReg(p); r != 0 {
5392 ctxt.Diag("cannot use %v in instruction requiring REX prefix: %v", rconv(r), p)
5393 }
5394 n := ab.Len()
5395 var np int
5396 for np = mark; np < n; np++ {
5397 c := ab.At(np)
5398 if c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26 {
5399 break
5400 }
5401 }
5402 ab.Insert(np, byte(0x40|ab.rexflag))
5403 }
5404
5405 n := ab.Len()
5406 for i := len(cursym.R) - 1; i >= 0; i-- {
5407 r := &cursym.R[i]
5408 if int64(r.Off) < p.Pc {
5409 break
5410 }
5411 if ab.rexflag != 0 && !ab.vexflag && !ab.evexflag {
5412 r.Off++
5413 }
5414 if r.Type == objabi.R_PCREL {
5415 if ctxt.Arch.Family == sys.AMD64 || p.As == obj.AJMP || p.As == obj.ACALL {
5416
5417
5418
5419
5420
5421
5422
5423 r.Add -= p.Pc + int64(n) - (int64(r.Off) + int64(r.Siz))
5424 } else if ctxt.Arch.Family == sys.I386 {
5425
5426
5427
5428
5429 r.Add += int64(r.Off) - p.Pc + int64(r.Siz)
5430 }
5431 }
5432 if r.Type == objabi.R_GOTPCREL && ctxt.Arch.Family == sys.I386 {
5433
5434 r.Add += int64(r.Off) - p.Pc + int64(r.Siz)
5435 }
5436
5437 }
5438 }
5439
5440
5441 func unpackOps4(p *obj.Prog) (arg0, arg1, arg2, dst *obj.Addr) {
5442 return &p.From, &p.RestArgs[0].Addr, &p.RestArgs[1].Addr, &p.To
5443 }
5444
5445
5446 func unpackOps5(p *obj.Prog) (arg0, arg1, arg2, arg3, dst *obj.Addr) {
5447 return &p.From, &p.RestArgs[0].Addr, &p.RestArgs[1].Addr, &p.RestArgs[2].Addr, &p.To
5448 }
5449
View as plain text