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 return p.From.Index == REG_TLS
2242 }
2243 obj.MarkUnsafePoints(ctxt, s.Func().Text, newprog, useTLS, nil)
2244 }
2245
2246
2247
2248 for _, jt := range s.Func().JumpTables {
2249 for i, p := range jt.Targets {
2250
2251
2252 jt.Sym.WriteAddr(ctxt, int64(i)*8, 8, s, p.Pc)
2253 }
2254 }
2255 }
2256
2257 func instinit(ctxt *obj.Link) {
2258 if ycover[0] != 0 {
2259
2260
2261
2262 return
2263 }
2264
2265 switch ctxt.Headtype {
2266 case objabi.Hplan9:
2267
2268
2269
2270
2271
2272
2273
2274
2275 plan9privates = ctxt.Lookup("_privates")
2276 plan9privates.Set(obj.AttrLinkname, true)
2277 }
2278
2279 for i := range avxOptab {
2280 c := avxOptab[i].as
2281 if opindex[c&obj.AMask] != nil {
2282 ctxt.Diag("phase error in avxOptab: %d (%v)", i, c)
2283 }
2284 opindex[c&obj.AMask] = &avxOptab[i]
2285 }
2286 for i := 1; optab[i].as != 0; i++ {
2287 c := optab[i].as
2288 if opindex[c&obj.AMask] != nil {
2289 ctxt.Diag("phase error in optab: %d (%v)", i, c)
2290 }
2291 opindex[c&obj.AMask] = &optab[i]
2292 }
2293
2294 for i := 0; i < Ymax; i++ {
2295 ycover[i*Ymax+i] = 1
2296 }
2297
2298 ycover[Yi0*Ymax+Yu2] = 1
2299 ycover[Yi1*Ymax+Yu2] = 1
2300
2301 ycover[Yi0*Ymax+Yi8] = 1
2302 ycover[Yi1*Ymax+Yi8] = 1
2303 ycover[Yu2*Ymax+Yi8] = 1
2304 ycover[Yu7*Ymax+Yi8] = 1
2305
2306 ycover[Yi0*Ymax+Yu7] = 1
2307 ycover[Yi1*Ymax+Yu7] = 1
2308 ycover[Yu2*Ymax+Yu7] = 1
2309
2310 ycover[Yi0*Ymax+Yu8] = 1
2311 ycover[Yi1*Ymax+Yu8] = 1
2312 ycover[Yu2*Ymax+Yu8] = 1
2313 ycover[Yu7*Ymax+Yu8] = 1
2314
2315 ycover[Yi0*Ymax+Ys32] = 1
2316 ycover[Yi1*Ymax+Ys32] = 1
2317 ycover[Yu2*Ymax+Ys32] = 1
2318 ycover[Yu7*Ymax+Ys32] = 1
2319 ycover[Yu8*Ymax+Ys32] = 1
2320 ycover[Yi8*Ymax+Ys32] = 1
2321
2322 ycover[Yi0*Ymax+Yi32] = 1
2323 ycover[Yi1*Ymax+Yi32] = 1
2324 ycover[Yu2*Ymax+Yi32] = 1
2325 ycover[Yu7*Ymax+Yi32] = 1
2326 ycover[Yu8*Ymax+Yi32] = 1
2327 ycover[Yi8*Ymax+Yi32] = 1
2328 ycover[Ys32*Ymax+Yi32] = 1
2329
2330 ycover[Yi0*Ymax+Yi64] = 1
2331 ycover[Yi1*Ymax+Yi64] = 1
2332 ycover[Yu7*Ymax+Yi64] = 1
2333 ycover[Yu2*Ymax+Yi64] = 1
2334 ycover[Yu8*Ymax+Yi64] = 1
2335 ycover[Yi8*Ymax+Yi64] = 1
2336 ycover[Ys32*Ymax+Yi64] = 1
2337 ycover[Yi32*Ymax+Yi64] = 1
2338
2339 ycover[Yal*Ymax+Yrb] = 1
2340 ycover[Ycl*Ymax+Yrb] = 1
2341 ycover[Yax*Ymax+Yrb] = 1
2342 ycover[Ycx*Ymax+Yrb] = 1
2343 ycover[Yrx*Ymax+Yrb] = 1
2344 ycover[Yrl*Ymax+Yrb] = 1
2345
2346 ycover[Ycl*Ymax+Ycx] = 1
2347
2348 ycover[Yax*Ymax+Yrx] = 1
2349 ycover[Ycx*Ymax+Yrx] = 1
2350
2351 ycover[Yax*Ymax+Yrl] = 1
2352 ycover[Ycx*Ymax+Yrl] = 1
2353 ycover[Yrx*Ymax+Yrl] = 1
2354 ycover[Yrl32*Ymax+Yrl] = 1
2355
2356 ycover[Yf0*Ymax+Yrf] = 1
2357
2358 ycover[Yal*Ymax+Ymb] = 1
2359 ycover[Ycl*Ymax+Ymb] = 1
2360 ycover[Yax*Ymax+Ymb] = 1
2361 ycover[Ycx*Ymax+Ymb] = 1
2362 ycover[Yrx*Ymax+Ymb] = 1
2363 ycover[Yrb*Ymax+Ymb] = 1
2364 ycover[Yrl*Ymax+Ymb] = 1
2365 ycover[Ym*Ymax+Ymb] = 1
2366
2367 ycover[Yax*Ymax+Yml] = 1
2368 ycover[Ycx*Ymax+Yml] = 1
2369 ycover[Yrx*Ymax+Yml] = 1
2370 ycover[Yrl*Ymax+Yml] = 1
2371 ycover[Yrl32*Ymax+Yml] = 1
2372 ycover[Ym*Ymax+Yml] = 1
2373
2374 ycover[Yax*Ymax+Ymm] = 1
2375 ycover[Ycx*Ymax+Ymm] = 1
2376 ycover[Yrx*Ymax+Ymm] = 1
2377 ycover[Yrl*Ymax+Ymm] = 1
2378 ycover[Yrl32*Ymax+Ymm] = 1
2379 ycover[Ym*Ymax+Ymm] = 1
2380 ycover[Ymr*Ymax+Ymm] = 1
2381
2382 ycover[Yxr0*Ymax+Yxr] = 1
2383
2384 ycover[Ym*Ymax+Yxm] = 1
2385 ycover[Yxr0*Ymax+Yxm] = 1
2386 ycover[Yxr*Ymax+Yxm] = 1
2387
2388 ycover[Ym*Ymax+Yym] = 1
2389 ycover[Yyr*Ymax+Yym] = 1
2390
2391 ycover[Yxr0*Ymax+YxrEvex] = 1
2392 ycover[Yxr*Ymax+YxrEvex] = 1
2393
2394 ycover[Ym*Ymax+YxmEvex] = 1
2395 ycover[Yxr0*Ymax+YxmEvex] = 1
2396 ycover[Yxr*Ymax+YxmEvex] = 1
2397 ycover[YxrEvex*Ymax+YxmEvex] = 1
2398
2399 ycover[Yyr*Ymax+YyrEvex] = 1
2400
2401 ycover[Ym*Ymax+YymEvex] = 1
2402 ycover[Yyr*Ymax+YymEvex] = 1
2403 ycover[YyrEvex*Ymax+YymEvex] = 1
2404
2405 ycover[Ym*Ymax+Yzm] = 1
2406 ycover[Yzr*Ymax+Yzm] = 1
2407
2408 ycover[Yk0*Ymax+Yk] = 1
2409 ycover[Yknot0*Ymax+Yk] = 1
2410
2411 ycover[Yk0*Ymax+Ykm] = 1
2412 ycover[Yknot0*Ymax+Ykm] = 1
2413 ycover[Yk*Ymax+Ykm] = 1
2414 ycover[Ym*Ymax+Ykm] = 1
2415
2416 ycover[Yxvm*Ymax+YxvmEvex] = 1
2417
2418 ycover[Yyvm*Ymax+YyvmEvex] = 1
2419
2420 for i := 0; i < MAXREG; i++ {
2421 reg[i] = -1
2422 if i >= REG_AL && i <= REG_R15B {
2423 reg[i] = (i - REG_AL) & 7
2424 if i >= REG_SPB && i <= REG_DIB {
2425 regrex[i] = 0x40
2426 }
2427 if i >= REG_R8B && i <= REG_R15B {
2428 regrex[i] = Rxr | Rxx | Rxb
2429 }
2430 }
2431
2432 if i >= REG_AH && i <= REG_BH {
2433 reg[i] = 4 + ((i - REG_AH) & 7)
2434 }
2435 if i >= REG_AX && i <= REG_R15 {
2436 reg[i] = (i - REG_AX) & 7
2437 if i >= REG_R8 {
2438 regrex[i] = Rxr | Rxx | Rxb
2439 }
2440 }
2441
2442 if i >= REG_F0 && i <= REG_F0+7 {
2443 reg[i] = (i - REG_F0) & 7
2444 }
2445 if i >= REG_M0 && i <= REG_M0+7 {
2446 reg[i] = (i - REG_M0) & 7
2447 }
2448 if i >= REG_K0 && i <= REG_K0+7 {
2449 reg[i] = (i - REG_K0) & 7
2450 }
2451 if i >= REG_X0 && i <= REG_X0+15 {
2452 reg[i] = (i - REG_X0) & 7
2453 if i >= REG_X0+8 {
2454 regrex[i] = Rxr | Rxx | Rxb
2455 }
2456 }
2457 if i >= REG_X16 && i <= REG_X16+15 {
2458 reg[i] = (i - REG_X16) & 7
2459 if i >= REG_X16+8 {
2460 regrex[i] = Rxr | Rxx | Rxb | RxrEvex
2461 } else {
2462 regrex[i] = RxrEvex
2463 }
2464 }
2465 if i >= REG_Y0 && i <= REG_Y0+15 {
2466 reg[i] = (i - REG_Y0) & 7
2467 if i >= REG_Y0+8 {
2468 regrex[i] = Rxr | Rxx | Rxb
2469 }
2470 }
2471 if i >= REG_Y16 && i <= REG_Y16+15 {
2472 reg[i] = (i - REG_Y16) & 7
2473 if i >= REG_Y16+8 {
2474 regrex[i] = Rxr | Rxx | Rxb | RxrEvex
2475 } else {
2476 regrex[i] = RxrEvex
2477 }
2478 }
2479 if i >= REG_Z0 && i <= REG_Z0+15 {
2480 reg[i] = (i - REG_Z0) & 7
2481 if i > REG_Z0+7 {
2482 regrex[i] = Rxr | Rxx | Rxb
2483 }
2484 }
2485 if i >= REG_Z16 && i <= REG_Z16+15 {
2486 reg[i] = (i - REG_Z16) & 7
2487 if i >= REG_Z16+8 {
2488 regrex[i] = Rxr | Rxx | Rxb | RxrEvex
2489 } else {
2490 regrex[i] = RxrEvex
2491 }
2492 }
2493
2494 if i >= REG_CR+8 && i <= REG_CR+15 {
2495 regrex[i] = Rxr
2496 }
2497 }
2498 }
2499
2500 var isAndroid = buildcfg.GOOS == "android"
2501
2502 func prefixof(ctxt *obj.Link, a *obj.Addr) int {
2503 if a.Reg < REG_CS && a.Index < REG_CS {
2504 return 0
2505 }
2506 if a.Type == obj.TYPE_MEM && a.Name == obj.NAME_NONE {
2507 switch a.Reg {
2508 case REG_CS:
2509 return 0x2e
2510
2511 case REG_DS:
2512 return 0x3e
2513
2514 case REG_ES:
2515 return 0x26
2516
2517 case REG_FS:
2518 return 0x64
2519
2520 case REG_GS:
2521 return 0x65
2522
2523 case REG_TLS:
2524
2525
2526
2527
2528
2529
2530 if ctxt.Arch.Family == sys.I386 {
2531 switch ctxt.Headtype {
2532 default:
2533 if isAndroid {
2534 return 0x65
2535 }
2536 log.Fatalf("unknown TLS base register for %v", ctxt.Headtype)
2537
2538 case objabi.Hdarwin,
2539 objabi.Hdragonfly,
2540 objabi.Hfreebsd,
2541 objabi.Hnetbsd,
2542 objabi.Hopenbsd:
2543 return 0x65
2544 }
2545 }
2546
2547 switch ctxt.Headtype {
2548 default:
2549 log.Fatalf("unknown TLS base register for %v", ctxt.Headtype)
2550
2551 case objabi.Hlinux:
2552 if isAndroid {
2553 return 0x64
2554 }
2555
2556 if ctxt.Flag_shared {
2557 log.Fatalf("unknown TLS base register for linux with -shared")
2558 } else {
2559 return 0x64
2560 }
2561
2562 case objabi.Hdragonfly,
2563 objabi.Hfreebsd,
2564 objabi.Hnetbsd,
2565 objabi.Hopenbsd,
2566 objabi.Hsolaris:
2567 return 0x64
2568
2569 case objabi.Hdarwin:
2570 return 0x65
2571 }
2572 }
2573 }
2574
2575 switch a.Index {
2576 case REG_CS:
2577 return 0x2e
2578
2579 case REG_DS:
2580 return 0x3e
2581
2582 case REG_ES:
2583 return 0x26
2584
2585 case REG_TLS:
2586 if ctxt.Flag_shared && ctxt.Headtype != objabi.Hwindows {
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598 if ctxt.Arch.Family == sys.I386 {
2599 return 0x65
2600 }
2601 return 0x64
2602 }
2603
2604 case REG_FS:
2605 return 0x64
2606
2607 case REG_GS:
2608 return 0x65
2609 }
2610
2611 return 0
2612 }
2613
2614
2615 func oclassRegList(ctxt *obj.Link, addr *obj.Addr) int {
2616
2617
2618
2619
2620 regIsXmm := func(r int) bool { return r >= REG_X0 && r <= REG_X31 }
2621 regIsYmm := func(r int) bool { return r >= REG_Y0 && r <= REG_Y31 }
2622 regIsZmm := func(r int) bool { return r >= REG_Z0 && r <= REG_Z31 }
2623
2624 reg0, reg1 := decodeRegisterRange(addr.Offset)
2625 low := regIndex(int16(reg0))
2626 high := regIndex(int16(reg1))
2627
2628 if ctxt.Arch.Family == sys.I386 {
2629 if low >= 8 || high >= 8 {
2630 return Yxxx
2631 }
2632 }
2633
2634 switch high - low {
2635 case 3:
2636 switch {
2637 case regIsXmm(reg0) && regIsXmm(reg1):
2638 return YxrEvexMulti4
2639 case regIsYmm(reg0) && regIsYmm(reg1):
2640 return YyrEvexMulti4
2641 case regIsZmm(reg0) && regIsZmm(reg1):
2642 return YzrMulti4
2643 default:
2644 return Yxxx
2645 }
2646 default:
2647 return Yxxx
2648 }
2649 }
2650
2651
2652
2653 func oclassVMem(ctxt *obj.Link, addr *obj.Addr) (int, bool) {
2654 switch addr.Index {
2655 case REG_X0 + 0,
2656 REG_X0 + 1,
2657 REG_X0 + 2,
2658 REG_X0 + 3,
2659 REG_X0 + 4,
2660 REG_X0 + 5,
2661 REG_X0 + 6,
2662 REG_X0 + 7:
2663 return Yxvm, true
2664 case REG_X8 + 0,
2665 REG_X8 + 1,
2666 REG_X8 + 2,
2667 REG_X8 + 3,
2668 REG_X8 + 4,
2669 REG_X8 + 5,
2670 REG_X8 + 6,
2671 REG_X8 + 7:
2672 if ctxt.Arch.Family == sys.I386 {
2673 return Yxxx, true
2674 }
2675 return Yxvm, true
2676 case REG_X16 + 0,
2677 REG_X16 + 1,
2678 REG_X16 + 2,
2679 REG_X16 + 3,
2680 REG_X16 + 4,
2681 REG_X16 + 5,
2682 REG_X16 + 6,
2683 REG_X16 + 7,
2684 REG_X16 + 8,
2685 REG_X16 + 9,
2686 REG_X16 + 10,
2687 REG_X16 + 11,
2688 REG_X16 + 12,
2689 REG_X16 + 13,
2690 REG_X16 + 14,
2691 REG_X16 + 15:
2692 if ctxt.Arch.Family == sys.I386 {
2693 return Yxxx, true
2694 }
2695 return YxvmEvex, true
2696
2697 case REG_Y0 + 0,
2698 REG_Y0 + 1,
2699 REG_Y0 + 2,
2700 REG_Y0 + 3,
2701 REG_Y0 + 4,
2702 REG_Y0 + 5,
2703 REG_Y0 + 6,
2704 REG_Y0 + 7:
2705 return Yyvm, true
2706 case REG_Y8 + 0,
2707 REG_Y8 + 1,
2708 REG_Y8 + 2,
2709 REG_Y8 + 3,
2710 REG_Y8 + 4,
2711 REG_Y8 + 5,
2712 REG_Y8 + 6,
2713 REG_Y8 + 7:
2714 if ctxt.Arch.Family == sys.I386 {
2715 return Yxxx, true
2716 }
2717 return Yyvm, true
2718 case REG_Y16 + 0,
2719 REG_Y16 + 1,
2720 REG_Y16 + 2,
2721 REG_Y16 + 3,
2722 REG_Y16 + 4,
2723 REG_Y16 + 5,
2724 REG_Y16 + 6,
2725 REG_Y16 + 7,
2726 REG_Y16 + 8,
2727 REG_Y16 + 9,
2728 REG_Y16 + 10,
2729 REG_Y16 + 11,
2730 REG_Y16 + 12,
2731 REG_Y16 + 13,
2732 REG_Y16 + 14,
2733 REG_Y16 + 15:
2734 if ctxt.Arch.Family == sys.I386 {
2735 return Yxxx, true
2736 }
2737 return YyvmEvex, true
2738
2739 case REG_Z0 + 0,
2740 REG_Z0 + 1,
2741 REG_Z0 + 2,
2742 REG_Z0 + 3,
2743 REG_Z0 + 4,
2744 REG_Z0 + 5,
2745 REG_Z0 + 6,
2746 REG_Z0 + 7:
2747 return Yzvm, true
2748 case REG_Z8 + 0,
2749 REG_Z8 + 1,
2750 REG_Z8 + 2,
2751 REG_Z8 + 3,
2752 REG_Z8 + 4,
2753 REG_Z8 + 5,
2754 REG_Z8 + 6,
2755 REG_Z8 + 7,
2756 REG_Z8 + 8,
2757 REG_Z8 + 9,
2758 REG_Z8 + 10,
2759 REG_Z8 + 11,
2760 REG_Z8 + 12,
2761 REG_Z8 + 13,
2762 REG_Z8 + 14,
2763 REG_Z8 + 15,
2764 REG_Z8 + 16,
2765 REG_Z8 + 17,
2766 REG_Z8 + 18,
2767 REG_Z8 + 19,
2768 REG_Z8 + 20,
2769 REG_Z8 + 21,
2770 REG_Z8 + 22,
2771 REG_Z8 + 23:
2772 if ctxt.Arch.Family == sys.I386 {
2773 return Yxxx, true
2774 }
2775 return Yzvm, true
2776 }
2777
2778 return Yxxx, false
2779 }
2780
2781 func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
2782 switch a.Type {
2783 case obj.TYPE_REGLIST:
2784 return oclassRegList(ctxt, a)
2785
2786 case obj.TYPE_NONE:
2787 return Ynone
2788
2789 case obj.TYPE_BRANCH:
2790 return Ybr
2791
2792 case obj.TYPE_INDIR:
2793 if a.Name != obj.NAME_NONE && a.Reg == REG_NONE && a.Index == REG_NONE && a.Scale == 0 {
2794 return Yindir
2795 }
2796 return Yxxx
2797
2798 case obj.TYPE_MEM:
2799
2800
2801 if a.Index == REG_SP || a.Index < 0 {
2802
2803 return Yxxx
2804 }
2805
2806 if vmem, ok := oclassVMem(ctxt, a); ok {
2807 return vmem
2808 }
2809
2810 if ctxt.Arch.Family == sys.AMD64 {
2811 switch a.Name {
2812 case obj.NAME_EXTERN, obj.NAME_STATIC, obj.NAME_GOTREF:
2813
2814
2815 if a.Reg != REG_NONE || a.Index != REG_NONE || a.Scale != 0 {
2816 return Yxxx
2817 }
2818 case obj.NAME_AUTO, obj.NAME_PARAM:
2819
2820
2821 if a.Reg != REG_SP && a.Reg != 0 {
2822 return Yxxx
2823 }
2824 case obj.NAME_NONE:
2825
2826 default:
2827
2828 return Yxxx
2829 }
2830 }
2831 return Ym
2832
2833 case obj.TYPE_ADDR:
2834 switch a.Name {
2835 case obj.NAME_GOTREF:
2836 ctxt.Diag("unexpected TYPE_ADDR with NAME_GOTREF")
2837 return Yxxx
2838
2839 case obj.NAME_EXTERN,
2840 obj.NAME_STATIC:
2841 if a.Sym != nil && useAbs(ctxt, a.Sym) {
2842 return Yi32
2843 }
2844 return Yiauto
2845
2846 case obj.NAME_AUTO,
2847 obj.NAME_PARAM:
2848 return Yiauto
2849 }
2850
2851
2852
2853
2854 if a.Sym != nil && strings.HasPrefix(a.Sym.Name, "runtime.duff") {
2855 return Yi32
2856 }
2857
2858 if a.Sym != nil || a.Name != obj.NAME_NONE {
2859 ctxt.Diag("unexpected addr: %v", obj.Dconv(p, a))
2860 }
2861 fallthrough
2862
2863 case obj.TYPE_CONST:
2864 if a.Sym != nil {
2865 ctxt.Diag("TYPE_CONST with symbol: %v", obj.Dconv(p, a))
2866 }
2867
2868 v := a.Offset
2869 if ctxt.Arch.Family == sys.I386 {
2870 v = int64(int32(v))
2871 }
2872 switch {
2873 case v == 0:
2874 return Yi0
2875 case v == 1:
2876 return Yi1
2877 case v >= 0 && v <= 3:
2878 return Yu2
2879 case v >= 0 && v <= 127:
2880 return Yu7
2881 case v >= 0 && v <= 255:
2882 return Yu8
2883 case v >= -128 && v <= 127:
2884 return Yi8
2885 }
2886 if ctxt.Arch.Family == sys.I386 {
2887 return Yi32
2888 }
2889 l := int32(v)
2890 if int64(l) == v {
2891 return Ys32
2892 }
2893 if v>>32 == 0 {
2894 return Yi32
2895 }
2896 return Yi64
2897
2898 case obj.TYPE_TEXTSIZE:
2899 return Ytextsize
2900 }
2901
2902 if a.Type != obj.TYPE_REG {
2903 ctxt.Diag("unexpected addr1: type=%d %v", a.Type, obj.Dconv(p, a))
2904 return Yxxx
2905 }
2906
2907 switch a.Reg {
2908 case REG_AL:
2909 return Yal
2910
2911 case REG_AX:
2912 return Yax
2913
2914
2917 case REG_BPB,
2918 REG_SIB,
2919 REG_DIB,
2920 REG_R8B,
2921 REG_R9B,
2922 REG_R10B,
2923 REG_R11B,
2924 REG_R12B,
2925 REG_R13B,
2926 REG_R14B,
2927 REG_R15B:
2928 if ctxt.Arch.Family == sys.I386 {
2929 return Yxxx
2930 }
2931 fallthrough
2932
2933 case REG_DL,
2934 REG_BL,
2935 REG_AH,
2936 REG_CH,
2937 REG_DH,
2938 REG_BH:
2939 return Yrb
2940
2941 case REG_CL:
2942 return Ycl
2943
2944 case REG_CX:
2945 return Ycx
2946
2947 case REG_DX, REG_BX:
2948 return Yrx
2949
2950 case REG_R8,
2951 REG_R9,
2952 REG_R10,
2953 REG_R11,
2954 REG_R12,
2955 REG_R13,
2956 REG_R14,
2957 REG_R15:
2958 if ctxt.Arch.Family == sys.I386 {
2959 return Yxxx
2960 }
2961 fallthrough
2962
2963 case REG_SP, REG_BP, REG_SI, REG_DI:
2964 if ctxt.Arch.Family == sys.I386 {
2965 return Yrl32
2966 }
2967 return Yrl
2968
2969 case REG_F0 + 0:
2970 return Yf0
2971
2972 case REG_F0 + 1,
2973 REG_F0 + 2,
2974 REG_F0 + 3,
2975 REG_F0 + 4,
2976 REG_F0 + 5,
2977 REG_F0 + 6,
2978 REG_F0 + 7:
2979 return Yrf
2980
2981 case REG_M0 + 0,
2982 REG_M0 + 1,
2983 REG_M0 + 2,
2984 REG_M0 + 3,
2985 REG_M0 + 4,
2986 REG_M0 + 5,
2987 REG_M0 + 6,
2988 REG_M0 + 7:
2989 return Ymr
2990
2991 case REG_X0:
2992 return Yxr0
2993
2994 case REG_X0 + 1,
2995 REG_X0 + 2,
2996 REG_X0 + 3,
2997 REG_X0 + 4,
2998 REG_X0 + 5,
2999 REG_X0 + 6,
3000 REG_X0 + 7,
3001 REG_X0 + 8,
3002 REG_X0 + 9,
3003 REG_X0 + 10,
3004 REG_X0 + 11,
3005 REG_X0 + 12,
3006 REG_X0 + 13,
3007 REG_X0 + 14,
3008 REG_X0 + 15:
3009 return Yxr
3010
3011 case REG_X0 + 16,
3012 REG_X0 + 17,
3013 REG_X0 + 18,
3014 REG_X0 + 19,
3015 REG_X0 + 20,
3016 REG_X0 + 21,
3017 REG_X0 + 22,
3018 REG_X0 + 23,
3019 REG_X0 + 24,
3020 REG_X0 + 25,
3021 REG_X0 + 26,
3022 REG_X0 + 27,
3023 REG_X0 + 28,
3024 REG_X0 + 29,
3025 REG_X0 + 30,
3026 REG_X0 + 31:
3027 return YxrEvex
3028
3029 case REG_Y0 + 0,
3030 REG_Y0 + 1,
3031 REG_Y0 + 2,
3032 REG_Y0 + 3,
3033 REG_Y0 + 4,
3034 REG_Y0 + 5,
3035 REG_Y0 + 6,
3036 REG_Y0 + 7,
3037 REG_Y0 + 8,
3038 REG_Y0 + 9,
3039 REG_Y0 + 10,
3040 REG_Y0 + 11,
3041 REG_Y0 + 12,
3042 REG_Y0 + 13,
3043 REG_Y0 + 14,
3044 REG_Y0 + 15:
3045 return Yyr
3046
3047 case REG_Y0 + 16,
3048 REG_Y0 + 17,
3049 REG_Y0 + 18,
3050 REG_Y0 + 19,
3051 REG_Y0 + 20,
3052 REG_Y0 + 21,
3053 REG_Y0 + 22,
3054 REG_Y0 + 23,
3055 REG_Y0 + 24,
3056 REG_Y0 + 25,
3057 REG_Y0 + 26,
3058 REG_Y0 + 27,
3059 REG_Y0 + 28,
3060 REG_Y0 + 29,
3061 REG_Y0 + 30,
3062 REG_Y0 + 31:
3063 return YyrEvex
3064
3065 case REG_Z0 + 0,
3066 REG_Z0 + 1,
3067 REG_Z0 + 2,
3068 REG_Z0 + 3,
3069 REG_Z0 + 4,
3070 REG_Z0 + 5,
3071 REG_Z0 + 6,
3072 REG_Z0 + 7:
3073 return Yzr
3074
3075 case REG_Z0 + 8,
3076 REG_Z0 + 9,
3077 REG_Z0 + 10,
3078 REG_Z0 + 11,
3079 REG_Z0 + 12,
3080 REG_Z0 + 13,
3081 REG_Z0 + 14,
3082 REG_Z0 + 15,
3083 REG_Z0 + 16,
3084 REG_Z0 + 17,
3085 REG_Z0 + 18,
3086 REG_Z0 + 19,
3087 REG_Z0 + 20,
3088 REG_Z0 + 21,
3089 REG_Z0 + 22,
3090 REG_Z0 + 23,
3091 REG_Z0 + 24,
3092 REG_Z0 + 25,
3093 REG_Z0 + 26,
3094 REG_Z0 + 27,
3095 REG_Z0 + 28,
3096 REG_Z0 + 29,
3097 REG_Z0 + 30,
3098 REG_Z0 + 31:
3099 if ctxt.Arch.Family == sys.I386 {
3100 return Yxxx
3101 }
3102 return Yzr
3103
3104 case REG_K0:
3105 return Yk0
3106
3107 case REG_K0 + 1,
3108 REG_K0 + 2,
3109 REG_K0 + 3,
3110 REG_K0 + 4,
3111 REG_K0 + 5,
3112 REG_K0 + 6,
3113 REG_K0 + 7:
3114 return Yknot0
3115
3116 case REG_CS:
3117 return Ycs
3118 case REG_SS:
3119 return Yss
3120 case REG_DS:
3121 return Yds
3122 case REG_ES:
3123 return Yes
3124 case REG_FS:
3125 return Yfs
3126 case REG_GS:
3127 return Ygs
3128 case REG_TLS:
3129 return Ytls
3130
3131 case REG_GDTR:
3132 return Ygdtr
3133 case REG_IDTR:
3134 return Yidtr
3135 case REG_LDTR:
3136 return Yldtr
3137 case REG_MSW:
3138 return Ymsw
3139 case REG_TASK:
3140 return Ytask
3141
3142 case REG_CR + 0:
3143 return Ycr0
3144 case REG_CR + 1:
3145 return Ycr1
3146 case REG_CR + 2:
3147 return Ycr2
3148 case REG_CR + 3:
3149 return Ycr3
3150 case REG_CR + 4:
3151 return Ycr4
3152 case REG_CR + 5:
3153 return Ycr5
3154 case REG_CR + 6:
3155 return Ycr6
3156 case REG_CR + 7:
3157 return Ycr7
3158 case REG_CR + 8:
3159 return Ycr8
3160
3161 case REG_DR + 0:
3162 return Ydr0
3163 case REG_DR + 1:
3164 return Ydr1
3165 case REG_DR + 2:
3166 return Ydr2
3167 case REG_DR + 3:
3168 return Ydr3
3169 case REG_DR + 4:
3170 return Ydr4
3171 case REG_DR + 5:
3172 return Ydr5
3173 case REG_DR + 6:
3174 return Ydr6
3175 case REG_DR + 7:
3176 return Ydr7
3177
3178 case REG_TR + 0:
3179 return Ytr0
3180 case REG_TR + 1:
3181 return Ytr1
3182 case REG_TR + 2:
3183 return Ytr2
3184 case REG_TR + 3:
3185 return Ytr3
3186 case REG_TR + 4:
3187 return Ytr4
3188 case REG_TR + 5:
3189 return Ytr5
3190 case REG_TR + 6:
3191 return Ytr6
3192 case REG_TR + 7:
3193 return Ytr7
3194 }
3195
3196 return Yxxx
3197 }
3198
3199
3200
3201 type AsmBuf struct {
3202 buf [100]byte
3203 off int
3204 rexflag int
3205 vexflag bool
3206 evexflag bool
3207 rep bool
3208 repn bool
3209 lock bool
3210
3211 evex evexBits
3212 }
3213
3214
3215 func (ab *AsmBuf) Put1(x byte) {
3216 ab.buf[ab.off] = x
3217 ab.off++
3218 }
3219
3220
3221 func (ab *AsmBuf) Put2(x, y byte) {
3222 ab.buf[ab.off+0] = x
3223 ab.buf[ab.off+1] = y
3224 ab.off += 2
3225 }
3226
3227
3228 func (ab *AsmBuf) Put3(x, y, z byte) {
3229 ab.buf[ab.off+0] = x
3230 ab.buf[ab.off+1] = y
3231 ab.buf[ab.off+2] = z
3232 ab.off += 3
3233 }
3234
3235
3236 func (ab *AsmBuf) Put4(x, y, z, w byte) {
3237 ab.buf[ab.off+0] = x
3238 ab.buf[ab.off+1] = y
3239 ab.buf[ab.off+2] = z
3240 ab.buf[ab.off+3] = w
3241 ab.off += 4
3242 }
3243
3244
3245 func (ab *AsmBuf) PutInt16(v int16) {
3246 ab.buf[ab.off+0] = byte(v)
3247 ab.buf[ab.off+1] = byte(v >> 8)
3248 ab.off += 2
3249 }
3250
3251
3252 func (ab *AsmBuf) PutInt32(v int32) {
3253 ab.buf[ab.off+0] = byte(v)
3254 ab.buf[ab.off+1] = byte(v >> 8)
3255 ab.buf[ab.off+2] = byte(v >> 16)
3256 ab.buf[ab.off+3] = byte(v >> 24)
3257 ab.off += 4
3258 }
3259
3260
3261 func (ab *AsmBuf) PutInt64(v int64) {
3262 ab.buf[ab.off+0] = byte(v)
3263 ab.buf[ab.off+1] = byte(v >> 8)
3264 ab.buf[ab.off+2] = byte(v >> 16)
3265 ab.buf[ab.off+3] = byte(v >> 24)
3266 ab.buf[ab.off+4] = byte(v >> 32)
3267 ab.buf[ab.off+5] = byte(v >> 40)
3268 ab.buf[ab.off+6] = byte(v >> 48)
3269 ab.buf[ab.off+7] = byte(v >> 56)
3270 ab.off += 8
3271 }
3272
3273
3274 func (ab *AsmBuf) Put(b []byte) {
3275 copy(ab.buf[ab.off:], b)
3276 ab.off += len(b)
3277 }
3278
3279
3280
3281
3282
3283
3284
3285 func (ab *AsmBuf) PutOpBytesLit(offset int, op *opBytes) {
3286 for int(op[offset]) != 0 {
3287 ab.Put1(op[offset])
3288 offset++
3289 }
3290 }
3291
3292
3293 func (ab *AsmBuf) Insert(i int, b byte) {
3294 ab.off++
3295 copy(ab.buf[i+1:ab.off], ab.buf[i:ab.off-1])
3296 ab.buf[i] = b
3297 }
3298
3299
3300 func (ab *AsmBuf) Last() byte { return ab.buf[ab.off-1] }
3301
3302
3303 func (ab *AsmBuf) Len() int { return ab.off }
3304
3305
3306 func (ab *AsmBuf) Bytes() []byte { return ab.buf[:ab.off] }
3307
3308
3309 func (ab *AsmBuf) Reset() { ab.off = 0 }
3310
3311
3312 func (ab *AsmBuf) At(i int) byte { return ab.buf[i] }
3313
3314
3315 func (ab *AsmBuf) asmidx(ctxt *obj.Link, scale int, index int, base int) {
3316 var i int
3317
3318
3319 switch index {
3320 default:
3321 goto bad
3322
3323 case REG_NONE:
3324 i = 4 << 3
3325 goto bas
3326
3327 case REG_R8,
3328 REG_R9,
3329 REG_R10,
3330 REG_R11,
3331 REG_R12,
3332 REG_R13,
3333 REG_R14,
3334 REG_R15,
3335 REG_X8,
3336 REG_X9,
3337 REG_X10,
3338 REG_X11,
3339 REG_X12,
3340 REG_X13,
3341 REG_X14,
3342 REG_X15,
3343 REG_X16,
3344 REG_X17,
3345 REG_X18,
3346 REG_X19,
3347 REG_X20,
3348 REG_X21,
3349 REG_X22,
3350 REG_X23,
3351 REG_X24,
3352 REG_X25,
3353 REG_X26,
3354 REG_X27,
3355 REG_X28,
3356 REG_X29,
3357 REG_X30,
3358 REG_X31,
3359 REG_Y8,
3360 REG_Y9,
3361 REG_Y10,
3362 REG_Y11,
3363 REG_Y12,
3364 REG_Y13,
3365 REG_Y14,
3366 REG_Y15,
3367 REG_Y16,
3368 REG_Y17,
3369 REG_Y18,
3370 REG_Y19,
3371 REG_Y20,
3372 REG_Y21,
3373 REG_Y22,
3374 REG_Y23,
3375 REG_Y24,
3376 REG_Y25,
3377 REG_Y26,
3378 REG_Y27,
3379 REG_Y28,
3380 REG_Y29,
3381 REG_Y30,
3382 REG_Y31,
3383 REG_Z8,
3384 REG_Z9,
3385 REG_Z10,
3386 REG_Z11,
3387 REG_Z12,
3388 REG_Z13,
3389 REG_Z14,
3390 REG_Z15,
3391 REG_Z16,
3392 REG_Z17,
3393 REG_Z18,
3394 REG_Z19,
3395 REG_Z20,
3396 REG_Z21,
3397 REG_Z22,
3398 REG_Z23,
3399 REG_Z24,
3400 REG_Z25,
3401 REG_Z26,
3402 REG_Z27,
3403 REG_Z28,
3404 REG_Z29,
3405 REG_Z30,
3406 REG_Z31:
3407 if ctxt.Arch.Family == sys.I386 {
3408 goto bad
3409 }
3410 fallthrough
3411
3412 case REG_AX,
3413 REG_CX,
3414 REG_DX,
3415 REG_BX,
3416 REG_BP,
3417 REG_SI,
3418 REG_DI,
3419 REG_X0,
3420 REG_X1,
3421 REG_X2,
3422 REG_X3,
3423 REG_X4,
3424 REG_X5,
3425 REG_X6,
3426 REG_X7,
3427 REG_Y0,
3428 REG_Y1,
3429 REG_Y2,
3430 REG_Y3,
3431 REG_Y4,
3432 REG_Y5,
3433 REG_Y6,
3434 REG_Y7,
3435 REG_Z0,
3436 REG_Z1,
3437 REG_Z2,
3438 REG_Z3,
3439 REG_Z4,
3440 REG_Z5,
3441 REG_Z6,
3442 REG_Z7:
3443 i = reg[index] << 3
3444 }
3445
3446 switch scale {
3447 default:
3448 goto bad
3449
3450 case 1:
3451 break
3452
3453 case 2:
3454 i |= 1 << 6
3455
3456 case 4:
3457 i |= 2 << 6
3458
3459 case 8:
3460 i |= 3 << 6
3461 }
3462
3463 bas:
3464 switch base {
3465 default:
3466 goto bad
3467
3468 case REG_NONE:
3469 i |= 5
3470
3471 case REG_R8,
3472 REG_R9,
3473 REG_R10,
3474 REG_R11,
3475 REG_R12,
3476 REG_R13,
3477 REG_R14,
3478 REG_R15:
3479 if ctxt.Arch.Family == sys.I386 {
3480 goto bad
3481 }
3482 fallthrough
3483
3484 case REG_AX,
3485 REG_CX,
3486 REG_DX,
3487 REG_BX,
3488 REG_SP,
3489 REG_BP,
3490 REG_SI,
3491 REG_DI:
3492 i |= reg[base]
3493 }
3494
3495 ab.Put1(byte(i))
3496 return
3497
3498 bad:
3499 ctxt.Diag("asmidx: bad address %d/%s/%s", scale, rconv(index), rconv(base))
3500 ab.Put1(0)
3501 }
3502
3503 func (ab *AsmBuf) relput4(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a *obj.Addr) {
3504 var rel obj.Reloc
3505
3506 v := vaddr(ctxt, p, a, &rel)
3507 if rel.Siz != 0 {
3508 if rel.Siz != 4 {
3509 ctxt.Diag("bad reloc")
3510 }
3511 rel.Off = int32(p.Pc + int64(ab.Len()))
3512 cursym.AddRel(ctxt, rel)
3513 }
3514
3515 ab.PutInt32(int32(v))
3516 }
3517
3518 func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int64 {
3519 if r != nil {
3520 *r = obj.Reloc{}
3521 }
3522
3523 switch a.Name {
3524 case obj.NAME_STATIC,
3525 obj.NAME_GOTREF,
3526 obj.NAME_EXTERN:
3527 s := a.Sym
3528 if r == nil {
3529 ctxt.Diag("need reloc for %v", obj.Dconv(p, a))
3530 log.Fatalf("reloc")
3531 }
3532
3533 if a.Name == obj.NAME_GOTREF {
3534 r.Siz = 4
3535 r.Type = objabi.R_GOTPCREL
3536 } else if useAbs(ctxt, s) {
3537 r.Siz = 4
3538 r.Type = objabi.R_ADDR
3539 } else {
3540 r.Siz = 4
3541 r.Type = objabi.R_PCREL
3542 }
3543
3544 r.Off = -1
3545 r.Sym = s
3546 r.Add = a.Offset
3547
3548 return 0
3549 }
3550
3551 if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == REG_TLS {
3552 if r == nil {
3553 ctxt.Diag("need reloc for %v", obj.Dconv(p, a))
3554 log.Fatalf("reloc")
3555 }
3556
3557 if !ctxt.Flag_shared || isAndroid || ctxt.Headtype == objabi.Hdarwin {
3558 r.Type = objabi.R_TLS_LE
3559 r.Siz = 4
3560 r.Off = -1
3561 r.Add = a.Offset
3562 }
3563 return 0
3564 }
3565
3566 return a.Offset
3567 }
3568
3569 func (ab *AsmBuf) asmandsz(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a *obj.Addr, r int, rex int, m64 int) {
3570 var base int
3571 var rel obj.Reloc
3572
3573 rex &= 0x40 | Rxr
3574 if a.Offset != int64(int32(a.Offset)) {
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587 overflowOK := (ctxt.Arch.Family == sys.AMD64 && p.As == ALEAL) ||
3588 (ctxt.Arch.Family != sys.AMD64 &&
3589 int64(uint32(a.Offset)) == a.Offset &&
3590 ab.rexflag&Rxw == 0)
3591 if !overflowOK {
3592 ctxt.Diag("offset too large in %s", p)
3593 }
3594 }
3595 v := int32(a.Offset)
3596 rel.Siz = 0
3597
3598 switch a.Type {
3599 case obj.TYPE_ADDR:
3600 if a.Name == obj.NAME_NONE {
3601 ctxt.Diag("unexpected TYPE_ADDR with NAME_NONE")
3602 }
3603 if a.Index == REG_TLS {
3604 ctxt.Diag("unexpected TYPE_ADDR with index==REG_TLS")
3605 }
3606 goto bad
3607
3608 case obj.TYPE_REG:
3609 const regFirst = REG_AL
3610 const regLast = REG_Z31
3611 if a.Reg < regFirst || regLast < a.Reg {
3612 goto bad
3613 }
3614 if v != 0 {
3615 goto bad
3616 }
3617 ab.Put1(byte(3<<6 | reg[a.Reg]<<0 | r<<3))
3618 ab.rexflag |= regrex[a.Reg]&(0x40|Rxb) | rex
3619 return
3620 }
3621
3622 if a.Type != obj.TYPE_MEM {
3623 goto bad
3624 }
3625
3626 if a.Index != REG_NONE && a.Index != REG_TLS && !(REG_CS <= a.Index && a.Index <= REG_GS) {
3627 base := int(a.Reg)
3628 switch a.Name {
3629 case obj.NAME_EXTERN,
3630 obj.NAME_GOTREF,
3631 obj.NAME_STATIC:
3632 if !useAbs(ctxt, a.Sym) && ctxt.Arch.Family == sys.AMD64 {
3633 goto bad
3634 }
3635 if ctxt.Arch.Family == sys.I386 && ctxt.Flag_shared {
3636
3637
3638
3639 } else {
3640 base = REG_NONE
3641 }
3642 v = int32(vaddr(ctxt, p, a, &rel))
3643
3644 case obj.NAME_AUTO,
3645 obj.NAME_PARAM:
3646 base = REG_SP
3647 }
3648
3649 ab.rexflag |= regrex[int(a.Index)]&Rxx | regrex[base]&Rxb | rex
3650 if base == REG_NONE {
3651 ab.Put1(byte(0<<6 | 4<<0 | r<<3))
3652 ab.asmidx(ctxt, int(a.Scale), int(a.Index), base)
3653 goto putrelv
3654 }
3655
3656 if v == 0 && rel.Siz == 0 && base != REG_BP && base != REG_R13 {
3657 ab.Put1(byte(0<<6 | 4<<0 | r<<3))
3658 ab.asmidx(ctxt, int(a.Scale), int(a.Index), base)
3659 return
3660 }
3661
3662 if disp8, ok := toDisp8(v, p, ab); ok && rel.Siz == 0 {
3663 ab.Put1(byte(1<<6 | 4<<0 | r<<3))
3664 ab.asmidx(ctxt, int(a.Scale), int(a.Index), base)
3665 ab.Put1(disp8)
3666 return
3667 }
3668
3669 ab.Put1(byte(2<<6 | 4<<0 | r<<3))
3670 ab.asmidx(ctxt, int(a.Scale), int(a.Index), base)
3671 goto putrelv
3672 }
3673
3674 base = int(a.Reg)
3675 switch a.Name {
3676 case obj.NAME_STATIC,
3677 obj.NAME_GOTREF,
3678 obj.NAME_EXTERN:
3679 if a.Sym == nil {
3680 ctxt.Diag("bad addr: %v", p)
3681 }
3682 if ctxt.Arch.Family == sys.I386 && ctxt.Flag_shared {
3683
3684
3685
3686 } else {
3687 base = REG_NONE
3688 }
3689 v = int32(vaddr(ctxt, p, a, &rel))
3690
3691 case obj.NAME_AUTO,
3692 obj.NAME_PARAM:
3693 base = REG_SP
3694 }
3695
3696 if base == REG_TLS {
3697 v = int32(vaddr(ctxt, p, a, &rel))
3698 }
3699
3700 ab.rexflag |= regrex[base]&Rxb | rex
3701 if base == REG_NONE || (REG_CS <= base && base <= REG_GS) || base == REG_TLS {
3702 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 {
3703 if a.Name == obj.NAME_GOTREF && (a.Offset != 0 || a.Index != 0 || a.Scale != 0) {
3704 ctxt.Diag("%v has offset against gotref", p)
3705 }
3706 ab.Put1(byte(0<<6 | 5<<0 | r<<3))
3707 goto putrelv
3708 }
3709
3710
3711 ab.Put2(
3712 byte(0<<6|4<<0|r<<3),
3713 0<<6|4<<3|5<<0,
3714 )
3715 goto putrelv
3716 }
3717
3718 if base == REG_SP || base == REG_R12 {
3719 if v == 0 {
3720 ab.Put1(byte(0<<6 | reg[base]<<0 | r<<3))
3721 ab.asmidx(ctxt, int(a.Scale), REG_NONE, base)
3722 return
3723 }
3724
3725 if disp8, ok := toDisp8(v, p, ab); ok {
3726 ab.Put1(byte(1<<6 | reg[base]<<0 | r<<3))
3727 ab.asmidx(ctxt, int(a.Scale), REG_NONE, base)
3728 ab.Put1(disp8)
3729 return
3730 }
3731
3732 ab.Put1(byte(2<<6 | reg[base]<<0 | r<<3))
3733 ab.asmidx(ctxt, int(a.Scale), REG_NONE, base)
3734 goto putrelv
3735 }
3736
3737 if REG_AX <= base && base <= REG_R15 {
3738 if a.Index == REG_TLS && !ctxt.Flag_shared && !isAndroid &&
3739 ctxt.Headtype != objabi.Hwindows {
3740 rel = obj.Reloc{}
3741 rel.Type = objabi.R_TLS_LE
3742 rel.Siz = 4
3743 rel.Sym = nil
3744 rel.Add = int64(v)
3745 v = 0
3746 }
3747
3748 if v == 0 && rel.Siz == 0 && base != REG_BP && base != REG_R13 {
3749 ab.Put1(byte(0<<6 | reg[base]<<0 | r<<3))
3750 return
3751 }
3752
3753 if disp8, ok := toDisp8(v, p, ab); ok && rel.Siz == 0 {
3754 ab.Put2(byte(1<<6|reg[base]<<0|r<<3), disp8)
3755 return
3756 }
3757
3758 ab.Put1(byte(2<<6 | reg[base]<<0 | r<<3))
3759 goto putrelv
3760 }
3761
3762 goto bad
3763
3764 putrelv:
3765 if rel.Siz != 0 {
3766 if rel.Siz != 4 {
3767 ctxt.Diag("bad rel")
3768 goto bad
3769 }
3770
3771 rel.Off = int32(p.Pc + int64(ab.Len()))
3772 cursym.AddRel(ctxt, rel)
3773 }
3774
3775 ab.PutInt32(v)
3776 return
3777
3778 bad:
3779 ctxt.Diag("asmand: bad address %v", obj.Dconv(p, a))
3780 }
3781
3782 func (ab *AsmBuf) asmand(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a *obj.Addr, ra *obj.Addr) {
3783 ab.asmandsz(ctxt, cursym, p, a, reg[ra.Reg], regrex[ra.Reg], 0)
3784 }
3785
3786 func (ab *AsmBuf) asmando(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, a *obj.Addr, o int) {
3787 ab.asmandsz(ctxt, cursym, p, a, o, 0, 0)
3788 }
3789
3790 func bytereg(a *obj.Addr, t *uint8) {
3791 if a.Type == obj.TYPE_REG && a.Index == REG_NONE && (REG_AX <= a.Reg && a.Reg <= REG_R15) {
3792 a.Reg += REG_AL - REG_AX
3793 *t = 0
3794 }
3795 }
3796
3797 func unbytereg(a *obj.Addr, t *uint8) {
3798 if a.Type == obj.TYPE_REG && a.Index == REG_NONE && (REG_AL <= a.Reg && a.Reg <= REG_R15B) {
3799 a.Reg += REG_AX - REG_AL
3800 *t = 0
3801 }
3802 }
3803
3804 const (
3805 movLit uint8 = iota
3806 movRegMem
3807 movMemReg
3808 movRegMem2op
3809 movMemReg2op
3810 movFullPtr
3811 movDoubleShift
3812 movTLSReg
3813 )
3814
3815 var ymovtab = []movtab{
3816
3817 {APUSHL, Ycs, Ynone, Ynone, movLit, [4]uint8{0x0e, 0}},
3818 {APUSHL, Yss, Ynone, Ynone, movLit, [4]uint8{0x16, 0}},
3819 {APUSHL, Yds, Ynone, Ynone, movLit, [4]uint8{0x1e, 0}},
3820 {APUSHL, Yes, Ynone, Ynone, movLit, [4]uint8{0x06, 0}},
3821 {APUSHL, Yfs, Ynone, Ynone, movLit, [4]uint8{0x0f, 0xa0, 0}},
3822 {APUSHL, Ygs, Ynone, Ynone, movLit, [4]uint8{0x0f, 0xa8, 0}},
3823 {APUSHQ, Yfs, Ynone, Ynone, movLit, [4]uint8{0x0f, 0xa0, 0}},
3824 {APUSHQ, Ygs, Ynone, Ynone, movLit, [4]uint8{0x0f, 0xa8, 0}},
3825 {APUSHW, Ycs, Ynone, Ynone, movLit, [4]uint8{Pe, 0x0e, 0}},
3826 {APUSHW, Yss, Ynone, Ynone, movLit, [4]uint8{Pe, 0x16, 0}},
3827 {APUSHW, Yds, Ynone, Ynone, movLit, [4]uint8{Pe, 0x1e, 0}},
3828 {APUSHW, Yes, Ynone, Ynone, movLit, [4]uint8{Pe, 0x06, 0}},
3829 {APUSHW, Yfs, Ynone, Ynone, movLit, [4]uint8{Pe, 0x0f, 0xa0, 0}},
3830 {APUSHW, Ygs, Ynone, Ynone, movLit, [4]uint8{Pe, 0x0f, 0xa8, 0}},
3831
3832
3833 {APOPL, Ynone, Ynone, Yds, movLit, [4]uint8{0x1f, 0}},
3834 {APOPL, Ynone, Ynone, Yes, movLit, [4]uint8{0x07, 0}},
3835 {APOPL, Ynone, Ynone, Yss, movLit, [4]uint8{0x17, 0}},
3836 {APOPL, Ynone, Ynone, Yfs, movLit, [4]uint8{0x0f, 0xa1, 0}},
3837 {APOPL, Ynone, Ynone, Ygs, movLit, [4]uint8{0x0f, 0xa9, 0}},
3838 {APOPQ, Ynone, Ynone, Yfs, movLit, [4]uint8{0x0f, 0xa1, 0}},
3839 {APOPQ, Ynone, Ynone, Ygs, movLit, [4]uint8{0x0f, 0xa9, 0}},
3840 {APOPW, Ynone, Ynone, Yds, movLit, [4]uint8{Pe, 0x1f, 0}},
3841 {APOPW, Ynone, Ynone, Yes, movLit, [4]uint8{Pe, 0x07, 0}},
3842 {APOPW, Ynone, Ynone, Yss, movLit, [4]uint8{Pe, 0x17, 0}},
3843 {APOPW, Ynone, Ynone, Yfs, movLit, [4]uint8{Pe, 0x0f, 0xa1, 0}},
3844 {APOPW, Ynone, Ynone, Ygs, movLit, [4]uint8{Pe, 0x0f, 0xa9, 0}},
3845
3846
3847 {AMOVW, Yes, Ynone, Yml, movRegMem, [4]uint8{0x8c, 0, 0, 0}},
3848 {AMOVW, Ycs, Ynone, Yml, movRegMem, [4]uint8{0x8c, 1, 0, 0}},
3849 {AMOVW, Yss, Ynone, Yml, movRegMem, [4]uint8{0x8c, 2, 0, 0}},
3850 {AMOVW, Yds, Ynone, Yml, movRegMem, [4]uint8{0x8c, 3, 0, 0}},
3851 {AMOVW, Yfs, Ynone, Yml, movRegMem, [4]uint8{0x8c, 4, 0, 0}},
3852 {AMOVW, Ygs, Ynone, Yml, movRegMem, [4]uint8{0x8c, 5, 0, 0}},
3853 {AMOVW, Yml, Ynone, Yes, movMemReg, [4]uint8{0x8e, 0, 0, 0}},
3854 {AMOVW, Yml, Ynone, Ycs, movMemReg, [4]uint8{0x8e, 1, 0, 0}},
3855 {AMOVW, Yml, Ynone, Yss, movMemReg, [4]uint8{0x8e, 2, 0, 0}},
3856 {AMOVW, Yml, Ynone, Yds, movMemReg, [4]uint8{0x8e, 3, 0, 0}},
3857 {AMOVW, Yml, Ynone, Yfs, movMemReg, [4]uint8{0x8e, 4, 0, 0}},
3858 {AMOVW, Yml, Ynone, Ygs, movMemReg, [4]uint8{0x8e, 5, 0, 0}},
3859
3860
3861 {AMOVL, Ycr0, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 0, 0}},
3862 {AMOVL, Ycr2, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 2, 0}},
3863 {AMOVL, Ycr3, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 3, 0}},
3864 {AMOVL, Ycr4, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 4, 0}},
3865 {AMOVL, Ycr8, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 8, 0}},
3866 {AMOVQ, Ycr0, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 0, 0}},
3867 {AMOVQ, Ycr2, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 2, 0}},
3868 {AMOVQ, Ycr3, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 3, 0}},
3869 {AMOVQ, Ycr4, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 4, 0}},
3870 {AMOVQ, Ycr8, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x20, 8, 0}},
3871 {AMOVL, Yrl, Ynone, Ycr0, movMemReg2op, [4]uint8{0x0f, 0x22, 0, 0}},
3872 {AMOVL, Yrl, Ynone, Ycr2, movMemReg2op, [4]uint8{0x0f, 0x22, 2, 0}},
3873 {AMOVL, Yrl, Ynone, Ycr3, movMemReg2op, [4]uint8{0x0f, 0x22, 3, 0}},
3874 {AMOVL, Yrl, Ynone, Ycr4, movMemReg2op, [4]uint8{0x0f, 0x22, 4, 0}},
3875 {AMOVL, Yrl, Ynone, Ycr8, movMemReg2op, [4]uint8{0x0f, 0x22, 8, 0}},
3876 {AMOVQ, Yrl, Ynone, Ycr0, movMemReg2op, [4]uint8{0x0f, 0x22, 0, 0}},
3877 {AMOVQ, Yrl, Ynone, Ycr2, movMemReg2op, [4]uint8{0x0f, 0x22, 2, 0}},
3878 {AMOVQ, Yrl, Ynone, Ycr3, movMemReg2op, [4]uint8{0x0f, 0x22, 3, 0}},
3879 {AMOVQ, Yrl, Ynone, Ycr4, movMemReg2op, [4]uint8{0x0f, 0x22, 4, 0}},
3880 {AMOVQ, Yrl, Ynone, Ycr8, movMemReg2op, [4]uint8{0x0f, 0x22, 8, 0}},
3881
3882
3883 {AMOVL, Ydr0, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 0, 0}},
3884 {AMOVL, Ydr6, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 6, 0}},
3885 {AMOVL, Ydr7, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 7, 0}},
3886 {AMOVQ, Ydr0, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 0, 0}},
3887 {AMOVQ, Ydr2, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 2, 0}},
3888 {AMOVQ, Ydr3, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 3, 0}},
3889 {AMOVQ, Ydr6, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 6, 0}},
3890 {AMOVQ, Ydr7, Ynone, Yrl, movRegMem2op, [4]uint8{0x0f, 0x21, 7, 0}},
3891 {AMOVL, Yrl, Ynone, Ydr0, movMemReg2op, [4]uint8{0x0f, 0x23, 0, 0}},
3892 {AMOVL, Yrl, Ynone, Ydr6, movMemReg2op, [4]uint8{0x0f, 0x23, 6, 0}},
3893 {AMOVL, Yrl, Ynone, Ydr7, movMemReg2op, [4]uint8{0x0f, 0x23, 7, 0}},
3894 {AMOVQ, Yrl, Ynone, Ydr0, movMemReg2op, [4]uint8{0x0f, 0x23, 0, 0}},
3895 {AMOVQ, Yrl, Ynone, Ydr2, movMemReg2op, [4]uint8{0x0f, 0x23, 2, 0}},
3896 {AMOVQ, Yrl, Ynone, Ydr3, movMemReg2op, [4]uint8{0x0f, 0x23, 3, 0}},
3897 {AMOVQ, Yrl, Ynone, Ydr6, movMemReg2op, [4]uint8{0x0f, 0x23, 6, 0}},
3898 {AMOVQ, Yrl, Ynone, Ydr7, movMemReg2op, [4]uint8{0x0f, 0x23, 7, 0}},
3899
3900
3901 {AMOVL, Ytr6, Ynone, Yml, movRegMem2op, [4]uint8{0x0f, 0x24, 6, 0}},
3902 {AMOVL, Ytr7, Ynone, Yml, movRegMem2op, [4]uint8{0x0f, 0x24, 7, 0}},
3903 {AMOVL, Yml, Ynone, Ytr6, movMemReg2op, [4]uint8{0x0f, 0x26, 6, 0xff}},
3904 {AMOVL, Yml, Ynone, Ytr7, movMemReg2op, [4]uint8{0x0f, 0x26, 7, 0xff}},
3905
3906
3907 {AMOVL, Ym, Ynone, Ygdtr, movMemReg2op, [4]uint8{0x0f, 0x01, 2, 0}},
3908 {AMOVL, Ygdtr, Ynone, Ym, movRegMem2op, [4]uint8{0x0f, 0x01, 0, 0}},
3909 {AMOVL, Ym, Ynone, Yidtr, movMemReg2op, [4]uint8{0x0f, 0x01, 3, 0}},
3910 {AMOVL, Yidtr, Ynone, Ym, movRegMem2op, [4]uint8{0x0f, 0x01, 1, 0}},
3911 {AMOVQ, Ym, Ynone, Ygdtr, movMemReg2op, [4]uint8{0x0f, 0x01, 2, 0}},
3912 {AMOVQ, Ygdtr, Ynone, Ym, movRegMem2op, [4]uint8{0x0f, 0x01, 0, 0}},
3913 {AMOVQ, Ym, Ynone, Yidtr, movMemReg2op, [4]uint8{0x0f, 0x01, 3, 0}},
3914 {AMOVQ, Yidtr, Ynone, Ym, movRegMem2op, [4]uint8{0x0f, 0x01, 1, 0}},
3915
3916
3917 {AMOVW, Yml, Ynone, Yldtr, movMemReg2op, [4]uint8{0x0f, 0x00, 2, 0}},
3918 {AMOVW, Yldtr, Ynone, Yml, movRegMem2op, [4]uint8{0x0f, 0x00, 0, 0}},
3919
3920
3921 {AMOVW, Yml, Ynone, Ymsw, movMemReg2op, [4]uint8{0x0f, 0x01, 6, 0}},
3922 {AMOVW, Ymsw, Ynone, Yml, movRegMem2op, [4]uint8{0x0f, 0x01, 4, 0}},
3923
3924
3925 {AMOVW, Yml, Ynone, Ytask, movMemReg2op, [4]uint8{0x0f, 0x00, 3, 0}},
3926 {AMOVW, Ytask, Ynone, Yml, movRegMem2op, [4]uint8{0x0f, 0x00, 1, 0}},
3927
3928
3932
3933
3934 {ASHLL, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{0xa4, 0xa5, 0, 0}},
3935 {ASHLL, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{0xa4, 0xa5, 0, 0}},
3936 {ASHLL, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{0xa4, 0xa5, 0, 0}},
3937 {ASHRL, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{0xac, 0xad, 0, 0}},
3938 {ASHRL, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{0xac, 0xad, 0, 0}},
3939 {ASHRL, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{0xac, 0xad, 0, 0}},
3940 {ASHLQ, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xa4, 0xa5, 0}},
3941 {ASHLQ, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xa4, 0xa5, 0}},
3942 {ASHLQ, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xa4, 0xa5, 0}},
3943 {ASHRQ, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xac, 0xad, 0}},
3944 {ASHRQ, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xac, 0xad, 0}},
3945 {ASHRQ, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{Pw, 0xac, 0xad, 0}},
3946 {ASHLW, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xa4, 0xa5, 0}},
3947 {ASHLW, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xa4, 0xa5, 0}},
3948 {ASHLW, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xa4, 0xa5, 0}},
3949 {ASHRW, Yi8, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xac, 0xad, 0}},
3950 {ASHRW, Ycl, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xac, 0xad, 0}},
3951 {ASHRW, Ycx, Yrl, Yml, movDoubleShift, [4]uint8{Pe, 0xac, 0xad, 0}},
3952
3953
3954 {AMOVL, Ytls, Ynone, Yrl, movTLSReg, [4]uint8{0, 0, 0, 0}},
3955 {AMOVQ, Ytls, Ynone, Yrl, movTLSReg, [4]uint8{0, 0, 0, 0}},
3956 {0, 0, 0, 0, 0, [4]uint8{}},
3957 }
3958
3959 func isax(a *obj.Addr) bool {
3960 switch a.Reg {
3961 case REG_AX, REG_AL, REG_AH:
3962 return true
3963 }
3964
3965 return a.Index == REG_AX
3966 }
3967
3968 func subreg(p *obj.Prog, from int, to int) {
3969 if false {
3970 fmt.Printf("\n%v\ts/%v/%v/\n", p, rconv(from), rconv(to))
3971 }
3972
3973 if int(p.From.Reg) == from {
3974 p.From.Reg = int16(to)
3975 p.Ft = 0
3976 }
3977
3978 if int(p.To.Reg) == from {
3979 p.To.Reg = int16(to)
3980 p.Tt = 0
3981 }
3982
3983 if int(p.From.Index) == from {
3984 p.From.Index = int16(to)
3985 p.Ft = 0
3986 }
3987
3988 if int(p.To.Index) == from {
3989 p.To.Index = int16(to)
3990 p.Tt = 0
3991 }
3992
3993 if false {
3994 fmt.Printf("%v\n", p)
3995 }
3996 }
3997
3998 func (ab *AsmBuf) mediaop(ctxt *obj.Link, o *Optab, op int, osize int, z int) int {
3999 switch op {
4000 case Pm, Pe, Pf2, Pf3:
4001 if osize != 1 {
4002 if op != Pm {
4003 ab.Put1(byte(op))
4004 }
4005 ab.Put1(Pm)
4006 z++
4007 op = int(o.op[z])
4008 break
4009 }
4010 fallthrough
4011
4012 default:
4013 if ab.Len() == 0 || ab.Last() != Pm {
4014 ab.Put1(Pm)
4015 }
4016 }
4017
4018 ab.Put1(byte(op))
4019 return z
4020 }
4021
4022
4023
4024
4025
4026
4027 func (ab *AsmBuf) asmevex(ctxt *obj.Link, p *obj.Prog, rm, v, r, k *obj.Addr) {
4028 ab.evexflag = true
4029 evex := ab.evex
4030
4031 rexR := byte(1)
4032 evexR := byte(1)
4033 rexX := byte(1)
4034 rexB := byte(1)
4035 if r != nil {
4036 if regrex[r.Reg]&Rxr != 0 {
4037 rexR = 0
4038 }
4039 if regrex[r.Reg]&RxrEvex != 0 {
4040 evexR = 0
4041 }
4042 }
4043 if rm != nil {
4044 if rm.Index == REG_NONE && regrex[rm.Reg]&RxrEvex != 0 {
4045 rexX = 0
4046 } else if regrex[rm.Index]&Rxx != 0 {
4047 rexX = 0
4048 }
4049 if regrex[rm.Reg]&Rxb != 0 {
4050 rexB = 0
4051 }
4052 }
4053
4054 p0 := (rexR << 7) |
4055 (rexX << 6) |
4056 (rexB << 5) |
4057 (evexR << 4) |
4058 (0 << 2) |
4059 (evex.M() << 0)
4060
4061 vexV := byte(0)
4062 if v != nil {
4063
4064 vexV = byte(reg[v.Reg]|(regrex[v.Reg]&Rxr)<<1) & 0xF
4065 }
4066 vexV ^= 0x0F
4067
4068 p1 := (evex.W() << 7) |
4069 (vexV << 3) |
4070 (1 << 2) |
4071 (evex.P() << 0)
4072
4073 suffix := evexSuffixMap[p.Scond]
4074 evexZ := byte(0)
4075 evexLL := evex.L()
4076 evexB := byte(0)
4077 evexV := byte(1)
4078 evexA := byte(0)
4079 if suffix.zeroing {
4080 if !evex.ZeroingEnabled() {
4081 ctxt.Diag("unsupported zeroing: %v", p)
4082 }
4083 if k == nil {
4084
4085
4086 ctxt.Diag("mask register must be specified for .Z instructions: %v", p)
4087 } else if k.Reg == REG_K0 {
4088
4089
4090
4091 ctxt.Diag("mask register must not be K0 for .Z instructions: %v", p)
4092 }
4093 evexZ = 1
4094 }
4095 switch {
4096 case suffix.rounding != rcUnset:
4097 if rm != nil && rm.Type == obj.TYPE_MEM {
4098 ctxt.Diag("illegal rounding with memory argument: %v", p)
4099 } else if !evex.RoundingEnabled() {
4100 ctxt.Diag("unsupported rounding: %v", p)
4101 }
4102 evexB = 1
4103 evexLL = suffix.rounding
4104 case suffix.broadcast:
4105 if rm == nil || rm.Type != obj.TYPE_MEM {
4106 ctxt.Diag("illegal broadcast without memory argument: %v", p)
4107 } else if !evex.BroadcastEnabled() {
4108 ctxt.Diag("unsupported broadcast: %v", p)
4109 }
4110 evexB = 1
4111 case suffix.sae:
4112 if rm != nil && rm.Type == obj.TYPE_MEM {
4113 ctxt.Diag("illegal SAE with memory argument: %v", p)
4114 } else if !evex.SaeEnabled() {
4115 ctxt.Diag("unsupported SAE: %v", p)
4116 }
4117 evexB = 1
4118 }
4119 if rm != nil && regrex[rm.Index]&RxrEvex != 0 {
4120 evexV = 0
4121 } else if v != nil && regrex[v.Reg]&RxrEvex != 0 {
4122 evexV = 0
4123 }
4124 if k != nil {
4125 evexA = byte(reg[k.Reg])
4126 }
4127
4128 p2 := (evexZ << 7) |
4129 (evexLL << 5) |
4130 (evexB << 4) |
4131 (evexV << 3) |
4132 (evexA << 0)
4133
4134 const evexEscapeByte = 0x62
4135 ab.Put4(evexEscapeByte, p0, p1, p2)
4136 ab.Put1(evex.opcode)
4137 }
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147 func (ab *AsmBuf) asmvex(ctxt *obj.Link, rm, v, r *obj.Addr, vex, opcode uint8) {
4148 ab.vexflag = true
4149 rexR := 0
4150 if r != nil {
4151 rexR = regrex[r.Reg] & Rxr
4152 }
4153 rexB := 0
4154 rexX := 0
4155 if rm != nil {
4156 rexB = regrex[rm.Reg] & Rxb
4157 rexX = regrex[rm.Index] & Rxx
4158 }
4159 vexM := (vex >> 3) & 0x7
4160 vexWLP := vex & 0x87
4161 vexV := byte(0)
4162 if v != nil {
4163 vexV = byte(reg[v.Reg]|(regrex[v.Reg]&Rxr)<<1) & 0xF
4164 }
4165 vexV ^= 0xF
4166 if vexM == 1 && (rexX|rexB) == 0 && vex&vexW1 == 0 {
4167
4168 ab.Put2(0xc5, byte(rexR<<5)^0x80|vexV<<3|vexWLP)
4169 } else {
4170
4171 ab.Put3(0xc4,
4172 (byte(rexR|rexX|rexB)<<5)^0xE0|vexM,
4173 vexV<<3|vexWLP,
4174 )
4175 }
4176 ab.Put1(opcode)
4177 }
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191 func regIndex(r int16) int {
4192 lower3bits := reg[r]
4193 high4bit := regrex[r] & Rxr << 1
4194 high5bit := regrex[r] & RxrEvex << 0
4195 return lower3bits | high4bit | high5bit
4196 }
4197
4198
4199
4200 func avx2gatherValid(ctxt *obj.Link, p *obj.Prog) bool {
4201
4202
4203 index := regIndex(p.GetFrom3().Index)
4204 mask := regIndex(p.From.Reg)
4205 dest := regIndex(p.To.Reg)
4206 if dest == mask || dest == index || mask == index {
4207 ctxt.Diag("mask, index, and destination registers should be distinct: %v", p)
4208 return false
4209 }
4210
4211 return true
4212 }
4213
4214
4215
4216 func avx512gatherValid(ctxt *obj.Link, p *obj.Prog) bool {
4217
4218
4219 index := regIndex(p.From.Index)
4220 dest := regIndex(p.To.Reg)
4221 if dest == index {
4222 ctxt.Diag("index and destination registers should be distinct: %v", p)
4223 return false
4224 }
4225
4226 return true
4227 }
4228
4229 func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
4230 o := opindex[p.As&obj.AMask]
4231
4232 if o == nil {
4233 ctxt.Diag("asmins: missing op %v", p)
4234 return
4235 }
4236
4237 if pre := prefixof(ctxt, &p.From); pre != 0 {
4238 ab.Put1(byte(pre))
4239 }
4240 if pre := prefixof(ctxt, &p.To); pre != 0 {
4241 ab.Put1(byte(pre))
4242 }
4243
4244
4245
4246 switch p.As {
4247 case AVGATHERDPD,
4248 AVGATHERQPD,
4249 AVGATHERDPS,
4250 AVGATHERQPS,
4251 AVPGATHERDD,
4252 AVPGATHERQD,
4253 AVPGATHERDQ,
4254 AVPGATHERQQ:
4255 if p.GetFrom3() == nil {
4256
4257 ctxt.Diag("need a third arg for gather instruction: %v", p)
4258 return
4259 }
4260
4261 if p.GetFrom3().Reg >= REG_K0 && p.GetFrom3().Reg <= REG_K7 {
4262 if !avx512gatherValid(ctxt, p) {
4263 return
4264 }
4265 } else {
4266 if !avx2gatherValid(ctxt, p) {
4267 return
4268 }
4269 }
4270 }
4271
4272 if p.Ft == 0 {
4273 p.Ft = uint8(oclass(ctxt, p, &p.From))
4274 }
4275 if p.Tt == 0 {
4276 p.Tt = uint8(oclass(ctxt, p, &p.To))
4277 }
4278
4279 ft := int(p.Ft) * Ymax
4280 tt := int(p.Tt) * Ymax
4281
4282 xo := obj.Bool2int(o.op[0] == 0x0f)
4283 z := 0
4284
4285 args := make([]int, 0, argListMax)
4286 if ft != Ynone*Ymax {
4287 args = append(args, ft)
4288 }
4289 for i := range p.RestArgs {
4290 args = append(args, oclass(ctxt, p, &p.RestArgs[i].Addr)*Ymax)
4291 }
4292 if tt != Ynone*Ymax {
4293 args = append(args, tt)
4294 }
4295
4296 var f3t int
4297 for _, yt := range o.ytab {
4298
4299
4300
4301
4302
4303
4304
4305 if !yt.match(args) {
4306
4307 z += int(yt.zoffset) + xo
4308 } else {
4309 if p.Scond != 0 && !evexZcase(yt.zcase) {
4310
4311
4312 z += int(yt.zoffset)
4313 continue
4314 }
4315
4316 switch o.prefix {
4317 case Px1:
4318 if ctxt.Arch.Family == sys.AMD64 && z == 0 {
4319 z += int(yt.zoffset) + xo
4320 continue
4321 }
4322 case Pq:
4323 ab.Put2(Pe, Pm)
4324
4325 case Pq3:
4326 ab.rexflag |= Pw
4327 ab.Put2(Pe, Pm)
4328
4329 case Pq4:
4330 ab.Put3(0x66, 0x0F, 0x38)
4331
4332 case Pq4w:
4333 ab.rexflag |= Pw
4334 ab.Put3(0x66, 0x0F, 0x38)
4335
4336 case Pq5:
4337 ab.Put3(0xF3, 0x0F, 0x38)
4338
4339 case Pq5w:
4340 ab.rexflag |= Pw
4341 ab.Put3(0xF3, 0x0F, 0x38)
4342
4343 case Pf2,
4344 Pf3:
4345 ab.Put2(o.prefix, Pm)
4346
4347 case Pef3:
4348 ab.Put3(Pe, Pf3, Pm)
4349
4350 case Pfw:
4351 ab.rexflag |= Pw
4352 ab.Put2(Pf3, Pm)
4353
4354 case Pm:
4355 ab.Put1(Pm)
4356
4357 case Pe:
4358 ab.Put1(Pe)
4359
4360 case Pw:
4361 if ctxt.Arch.Family != sys.AMD64 {
4362 ctxt.Diag("asmins: illegal 64: %v", p)
4363 }
4364 ab.rexflag |= Pw
4365
4366 case Pw8:
4367 if z >= 8 {
4368 if ctxt.Arch.Family != sys.AMD64 {
4369 ctxt.Diag("asmins: illegal 64: %v", p)
4370 }
4371 ab.rexflag |= Pw
4372 }
4373
4374 case Pb:
4375 if ctxt.Arch.Family != sys.AMD64 && (isbadbyte(&p.From) || isbadbyte(&p.To)) {
4376 goto bad
4377 }
4378
4379
4380
4381
4382
4383
4384
4385
4386 if ctxt.Arch.Family == sys.AMD64 {
4387 bytereg(&p.From, &p.Ft)
4388 bytereg(&p.To, &p.Tt)
4389 }
4390
4391 case P32:
4392 if ctxt.Arch.Family == sys.AMD64 {
4393 ctxt.Diag("asmins: illegal in 64-bit mode: %v", p)
4394 }
4395
4396 case Py:
4397 if ctxt.Arch.Family != sys.AMD64 {
4398 ctxt.Diag("asmins: illegal in %d-bit mode: %v", ctxt.Arch.RegSize*8, p)
4399 }
4400
4401 case Py1:
4402 if z < 1 && ctxt.Arch.Family != sys.AMD64 {
4403 ctxt.Diag("asmins: illegal in %d-bit mode: %v", ctxt.Arch.RegSize*8, p)
4404 }
4405
4406 case Py3:
4407 if z < 3 && ctxt.Arch.Family != sys.AMD64 {
4408 ctxt.Diag("asmins: illegal in %d-bit mode: %v", ctxt.Arch.RegSize*8, p)
4409 }
4410 }
4411
4412 if z >= len(o.op) {
4413 log.Fatalf("asmins bad table %v", p)
4414 }
4415 op := int(o.op[z])
4416 if op == 0x0f {
4417 ab.Put1(byte(op))
4418 z++
4419 op = int(o.op[z])
4420 }
4421
4422 switch yt.zcase {
4423 default:
4424 ctxt.Diag("asmins: unknown z %d %v", yt.zcase, p)
4425 return
4426
4427 case Zpseudo:
4428 break
4429
4430 case Zlit:
4431 ab.PutOpBytesLit(z, &o.op)
4432
4433 case Zlitr_m:
4434 ab.PutOpBytesLit(z, &o.op)
4435 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4436
4437 case Zlitm_r:
4438 ab.PutOpBytesLit(z, &o.op)
4439 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4440
4441 case Zlit_m_r:
4442 ab.PutOpBytesLit(z, &o.op)
4443 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4444
4445 case Zmb_r:
4446 bytereg(&p.From, &p.Ft)
4447 fallthrough
4448
4449 case Zm_r:
4450 ab.Put1(byte(op))
4451 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4452
4453 case Z_m_r:
4454 ab.Put1(byte(op))
4455 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4456
4457 case Zm2_r:
4458 ab.Put2(byte(op), o.op[z+1])
4459 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4460
4461 case Zm_r_xm:
4462 ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4463 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4464
4465 case Zm_r_xm_nr:
4466 ab.rexflag = 0
4467 ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4468 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4469
4470 case Zm_r_i_xm:
4471 ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4472 ab.asmand(ctxt, cursym, p, &p.From, p.GetFrom3())
4473 ab.Put1(byte(p.To.Offset))
4474
4475 case Zibm_r, Zibr_m:
4476 ab.PutOpBytesLit(z, &o.op)
4477 if yt.zcase == Zibr_m {
4478 ab.asmand(ctxt, cursym, p, &p.To, p.GetFrom3())
4479 } else {
4480 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4481 }
4482 switch {
4483 default:
4484 ab.Put1(byte(p.From.Offset))
4485 case yt.args[0] == Yi32 && o.prefix == Pe:
4486 ab.PutInt16(int16(p.From.Offset))
4487 case yt.args[0] == Yi32:
4488 ab.PutInt32(int32(p.From.Offset))
4489 }
4490
4491 case Zaut_r:
4492 ab.Put1(0x8d)
4493 if p.From.Type != obj.TYPE_ADDR {
4494 ctxt.Diag("asmins: Zaut sb type ADDR")
4495 }
4496 p.From.Type = obj.TYPE_MEM
4497 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4498 p.From.Type = obj.TYPE_ADDR
4499
4500 case Zm_o:
4501 ab.Put1(byte(op))
4502 ab.asmando(ctxt, cursym, p, &p.From, int(o.op[z+1]))
4503
4504 case Zr_m:
4505 ab.Put1(byte(op))
4506 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4507
4508 case Zvex:
4509 ab.asmvex(ctxt, &p.From, p.GetFrom3(), &p.To, o.op[z], o.op[z+1])
4510
4511 case Zvex_rm_v_r:
4512 ab.asmvex(ctxt, &p.From, p.GetFrom3(), &p.To, o.op[z], o.op[z+1])
4513 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4514
4515 case Zvex_rm_v_ro:
4516 ab.asmvex(ctxt, &p.From, p.GetFrom3(), &p.To, o.op[z], o.op[z+1])
4517 ab.asmando(ctxt, cursym, p, &p.From, int(o.op[z+2]))
4518
4519 case Zvex_i_rm_vo:
4520 ab.asmvex(ctxt, p.GetFrom3(), &p.To, nil, o.op[z], o.op[z+1])
4521 ab.asmando(ctxt, cursym, p, p.GetFrom3(), int(o.op[z+2]))
4522 ab.Put1(byte(p.From.Offset))
4523
4524 case Zvex_i_r_v:
4525 ab.asmvex(ctxt, p.GetFrom3(), &p.To, nil, o.op[z], o.op[z+1])
4526 regnum := byte(0x7)
4527 if p.GetFrom3().Reg >= REG_X0 && p.GetFrom3().Reg <= REG_X15 {
4528 regnum &= byte(p.GetFrom3().Reg - REG_X0)
4529 } else {
4530 regnum &= byte(p.GetFrom3().Reg - REG_Y0)
4531 }
4532 ab.Put1(o.op[z+2] | regnum)
4533 ab.Put1(byte(p.From.Offset))
4534
4535 case Zvex_i_rm_v_r:
4536 imm, from, from3, to := unpackOps4(p)
4537 ab.asmvex(ctxt, from, from3, to, o.op[z], o.op[z+1])
4538 ab.asmand(ctxt, cursym, p, from, to)
4539 ab.Put1(byte(imm.Offset))
4540
4541 case Zvex_i_rm_r:
4542 ab.asmvex(ctxt, p.GetFrom3(), nil, &p.To, o.op[z], o.op[z+1])
4543 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4544 ab.Put1(byte(p.From.Offset))
4545
4546 case Zvex_v_rm_r:
4547 ab.asmvex(ctxt, p.GetFrom3(), &p.From, &p.To, o.op[z], o.op[z+1])
4548 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4549
4550 case Zvex_r_v_rm:
4551 ab.asmvex(ctxt, &p.To, p.GetFrom3(), &p.From, o.op[z], o.op[z+1])
4552 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4553
4554 case Zvex_rm_r_vo:
4555 ab.asmvex(ctxt, &p.From, &p.To, p.GetFrom3(), o.op[z], o.op[z+1])
4556 ab.asmando(ctxt, cursym, p, &p.From, int(o.op[z+2]))
4557
4558 case Zvex_i_r_rm:
4559 ab.asmvex(ctxt, &p.To, nil, p.GetFrom3(), o.op[z], o.op[z+1])
4560 ab.asmand(ctxt, cursym, p, &p.To, p.GetFrom3())
4561 ab.Put1(byte(p.From.Offset))
4562
4563 case Zvex_hr_rm_v_r:
4564 hr, from, from3, to := unpackOps4(p)
4565 ab.asmvex(ctxt, from, from3, to, o.op[z], o.op[z+1])
4566 ab.asmand(ctxt, cursym, p, from, to)
4567 ab.Put1(byte(regIndex(hr.Reg) << 4))
4568
4569 case Zevex_k_rmo:
4570 ab.evex = newEVEXBits(z, &o.op)
4571 ab.asmevex(ctxt, p, &p.To, nil, nil, &p.From)
4572 ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+3]))
4573
4574 case Zevex_i_rm_vo:
4575 ab.evex = newEVEXBits(z, &o.op)
4576 ab.asmevex(ctxt, p, p.GetFrom3(), &p.To, nil, nil)
4577 ab.asmando(ctxt, cursym, p, p.GetFrom3(), int(o.op[z+3]))
4578 ab.Put1(byte(p.From.Offset))
4579
4580 case Zevex_i_rm_k_vo:
4581 imm, from, kmask, to := unpackOps4(p)
4582 ab.evex = newEVEXBits(z, &o.op)
4583 ab.asmevex(ctxt, p, from, to, nil, kmask)
4584 ab.asmando(ctxt, cursym, p, from, int(o.op[z+3]))
4585 ab.Put1(byte(imm.Offset))
4586
4587 case Zevex_i_r_rm:
4588 ab.evex = newEVEXBits(z, &o.op)
4589 ab.asmevex(ctxt, p, &p.To, nil, p.GetFrom3(), nil)
4590 ab.asmand(ctxt, cursym, p, &p.To, p.GetFrom3())
4591 ab.Put1(byte(p.From.Offset))
4592
4593 case Zevex_i_r_k_rm:
4594 imm, from, kmask, to := unpackOps4(p)
4595 ab.evex = newEVEXBits(z, &o.op)
4596 ab.asmevex(ctxt, p, to, nil, from, kmask)
4597 ab.asmand(ctxt, cursym, p, to, from)
4598 ab.Put1(byte(imm.Offset))
4599
4600 case Zevex_i_rm_r:
4601 ab.evex = newEVEXBits(z, &o.op)
4602 ab.asmevex(ctxt, p, p.GetFrom3(), nil, &p.To, nil)
4603 ab.asmand(ctxt, cursym, p, p.GetFrom3(), &p.To)
4604 ab.Put1(byte(p.From.Offset))
4605
4606 case Zevex_i_rm_k_r:
4607 imm, from, kmask, to := unpackOps4(p)
4608 ab.evex = newEVEXBits(z, &o.op)
4609 ab.asmevex(ctxt, p, from, nil, to, kmask)
4610 ab.asmand(ctxt, cursym, p, from, to)
4611 ab.Put1(byte(imm.Offset))
4612
4613 case Zevex_i_rm_v_r:
4614 imm, from, from3, to := unpackOps4(p)
4615 ab.evex = newEVEXBits(z, &o.op)
4616 ab.asmevex(ctxt, p, from, from3, to, nil)
4617 ab.asmand(ctxt, cursym, p, from, to)
4618 ab.Put1(byte(imm.Offset))
4619
4620 case Zevex_i_rm_v_k_r:
4621 imm, from, from3, kmask, to := unpackOps5(p)
4622 ab.evex = newEVEXBits(z, &o.op)
4623 ab.asmevex(ctxt, p, from, from3, to, kmask)
4624 ab.asmand(ctxt, cursym, p, from, to)
4625 ab.Put1(byte(imm.Offset))
4626
4627 case Zevex_r_v_rm:
4628 ab.evex = newEVEXBits(z, &o.op)
4629 ab.asmevex(ctxt, p, &p.To, p.GetFrom3(), &p.From, nil)
4630 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4631
4632 case Zevex_rm_v_r:
4633 ab.evex = newEVEXBits(z, &o.op)
4634 ab.asmevex(ctxt, p, &p.From, p.GetFrom3(), &p.To, nil)
4635 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4636
4637 case Zevex_rm_k_r:
4638 ab.evex = newEVEXBits(z, &o.op)
4639 ab.asmevex(ctxt, p, &p.From, nil, &p.To, p.GetFrom3())
4640 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
4641
4642 case Zevex_r_k_rm:
4643 ab.evex = newEVEXBits(z, &o.op)
4644 ab.asmevex(ctxt, p, &p.To, nil, &p.From, p.GetFrom3())
4645 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4646
4647 case Zevex_rm_v_k_r:
4648 from, from3, kmask, to := unpackOps4(p)
4649 ab.evex = newEVEXBits(z, &o.op)
4650 ab.asmevex(ctxt, p, from, from3, to, kmask)
4651 ab.asmand(ctxt, cursym, p, from, to)
4652
4653 case Zevex_r_v_k_rm:
4654 from, from3, kmask, to := unpackOps4(p)
4655 ab.evex = newEVEXBits(z, &o.op)
4656 ab.asmevex(ctxt, p, to, from3, from, kmask)
4657 ab.asmand(ctxt, cursym, p, to, from)
4658
4659 case Zr_m_xm:
4660 ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4661 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4662
4663 case Zr_m_xm_nr:
4664 ab.rexflag = 0
4665 ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4666 ab.asmand(ctxt, cursym, p, &p.To, &p.From)
4667
4668 case Zo_m:
4669 ab.Put1(byte(op))
4670 ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+1]))
4671
4672 case Zcallindreg:
4673 cursym.AddRel(ctxt, obj.Reloc{
4674 Type: objabi.R_CALLIND,
4675 Off: int32(p.Pc),
4676 })
4677 fallthrough
4678
4679 case Zo_m64:
4680 ab.Put1(byte(op))
4681 ab.asmandsz(ctxt, cursym, p, &p.To, int(o.op[z+1]), 0, 1)
4682
4683 case Zm_ibo:
4684 ab.Put1(byte(op))
4685 ab.asmando(ctxt, cursym, p, &p.From, int(o.op[z+1]))
4686 ab.Put1(byte(vaddr(ctxt, p, &p.To, nil)))
4687
4688 case Zibo_m:
4689 ab.Put1(byte(op))
4690 ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+1]))
4691 ab.Put1(byte(vaddr(ctxt, p, &p.From, nil)))
4692
4693 case Zibo_m_xm:
4694 z = ab.mediaop(ctxt, o, op, int(yt.zoffset), z)
4695 ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+1]))
4696 ab.Put1(byte(vaddr(ctxt, p, &p.From, nil)))
4697
4698 case Z_ib, Zib_:
4699 var a *obj.Addr
4700 if yt.zcase == Zib_ {
4701 a = &p.From
4702 } else {
4703 a = &p.To
4704 }
4705 ab.Put1(byte(op))
4706 if p.As == AXABORT {
4707 ab.Put1(o.op[z+1])
4708 }
4709 ab.Put1(byte(vaddr(ctxt, p, a, nil)))
4710
4711 case Zib_rp:
4712 ab.rexflag |= regrex[p.To.Reg] & (Rxb | 0x40)
4713 ab.Put2(byte(op+reg[p.To.Reg]), byte(vaddr(ctxt, p, &p.From, nil)))
4714
4715 case Zil_rp:
4716 ab.rexflag |= regrex[p.To.Reg] & Rxb
4717 ab.Put1(byte(op + reg[p.To.Reg]))
4718 if o.prefix == Pe {
4719 v := vaddr(ctxt, p, &p.From, nil)
4720 ab.PutInt16(int16(v))
4721 } else {
4722 ab.relput4(ctxt, cursym, p, &p.From)
4723 }
4724
4725 case Zo_iw:
4726 ab.Put1(byte(op))
4727 if p.From.Type != obj.TYPE_NONE {
4728 v := vaddr(ctxt, p, &p.From, nil)
4729 ab.PutInt16(int16(v))
4730 }
4731
4732 case Ziq_rp:
4733 var rel obj.Reloc
4734 v := vaddr(ctxt, p, &p.From, &rel)
4735 l := int(v >> 32)
4736 if l == 0 && rel.Siz != 8 {
4737 ab.rexflag &^= (0x40 | Rxw)
4738
4739 ab.rexflag |= regrex[p.To.Reg] & Rxb
4740 ab.Put1(byte(0xb8 + reg[p.To.Reg]))
4741 if rel.Type != 0 {
4742 rel.Off = int32(p.Pc + int64(ab.Len()))
4743 cursym.AddRel(ctxt, rel)
4744 }
4745
4746 ab.PutInt32(int32(v))
4747 } else if l == -1 && uint64(v)&(uint64(1)<<31) != 0 {
4748 ab.Put1(0xc7)
4749 ab.asmando(ctxt, cursym, p, &p.To, 0)
4750
4751 ab.PutInt32(int32(v))
4752 } else {
4753 ab.rexflag |= regrex[p.To.Reg] & Rxb
4754 ab.Put1(byte(op + reg[p.To.Reg]))
4755 if rel.Type != 0 {
4756 rel.Off = int32(p.Pc + int64(ab.Len()))
4757 cursym.AddRel(ctxt, rel)
4758 }
4759
4760 ab.PutInt64(v)
4761 }
4762
4763 case Zib_rr:
4764 ab.Put1(byte(op))
4765 ab.asmand(ctxt, cursym, p, &p.To, &p.To)
4766 ab.Put1(byte(vaddr(ctxt, p, &p.From, nil)))
4767
4768 case Z_il, Zil_:
4769 var a *obj.Addr
4770 if yt.zcase == Zil_ {
4771 a = &p.From
4772 } else {
4773 a = &p.To
4774 }
4775 ab.Put1(byte(op))
4776 if o.prefix == Pe {
4777 v := vaddr(ctxt, p, a, nil)
4778 ab.PutInt16(int16(v))
4779 } else {
4780 ab.relput4(ctxt, cursym, p, a)
4781 }
4782
4783 case Zm_ilo, Zilo_m:
4784 var a *obj.Addr
4785 ab.Put1(byte(op))
4786 if yt.zcase == Zilo_m {
4787 a = &p.From
4788 ab.asmando(ctxt, cursym, p, &p.To, int(o.op[z+1]))
4789 } else {
4790 a = &p.To
4791 ab.asmando(ctxt, cursym, p, &p.From, int(o.op[z+1]))
4792 }
4793
4794 if o.prefix == Pe {
4795 v := vaddr(ctxt, p, a, nil)
4796 ab.PutInt16(int16(v))
4797 } else {
4798 ab.relput4(ctxt, cursym, p, a)
4799 }
4800
4801 case Zil_rr:
4802 ab.Put1(byte(op))
4803 ab.asmand(ctxt, cursym, p, &p.To, &p.To)
4804 if o.prefix == Pe {
4805 v := vaddr(ctxt, p, &p.From, nil)
4806 ab.PutInt16(int16(v))
4807 } else {
4808 ab.relput4(ctxt, cursym, p, &p.From)
4809 }
4810
4811 case Z_rp:
4812 ab.rexflag |= regrex[p.To.Reg] & (Rxb | 0x40)
4813 ab.Put1(byte(op + reg[p.To.Reg]))
4814
4815 case Zrp_:
4816 ab.rexflag |= regrex[p.From.Reg] & (Rxb | 0x40)
4817 ab.Put1(byte(op + reg[p.From.Reg]))
4818
4819 case Zcallcon, Zjmpcon:
4820 if yt.zcase == Zcallcon {
4821 ab.Put1(byte(op))
4822 } else {
4823 ab.Put1(o.op[z+1])
4824 }
4825 cursym.AddRel(ctxt, obj.Reloc{
4826 Type: objabi.R_PCREL,
4827 Off: int32(p.Pc + int64(ab.Len())),
4828 Siz: 4,
4829 Add: p.To.Offset,
4830 })
4831 ab.PutInt32(0)
4832
4833 case Zcallind:
4834 ab.Put2(byte(op), o.op[z+1])
4835 typ := objabi.R_ADDR
4836 if ctxt.Arch.Family == sys.AMD64 {
4837 typ = objabi.R_PCREL
4838 }
4839 cursym.AddRel(ctxt, obj.Reloc{
4840 Type: typ,
4841 Off: int32(p.Pc + int64(ab.Len())),
4842 Siz: 4,
4843 Sym: p.To.Sym,
4844 Add: p.To.Offset,
4845 })
4846 ab.PutInt32(0)
4847
4848 case Zcall, Zcallduff:
4849 if p.To.Sym == nil {
4850 ctxt.Diag("call without target")
4851 ctxt.DiagFlush()
4852 log.Fatalf("bad code")
4853 }
4854
4855 if yt.zcase == Zcallduff && ctxt.Flag_dynlink {
4856 ctxt.Diag("directly calling duff when dynamically linking Go")
4857 }
4858
4859 ab.Put1(byte(op))
4860 cursym.AddRel(ctxt, obj.Reloc{
4861 Type: objabi.R_CALL,
4862 Off: int32(p.Pc + int64(ab.Len())),
4863 Siz: 4,
4864 Sym: p.To.Sym,
4865 Add: p.To.Offset,
4866 })
4867 ab.PutInt32(0)
4868
4869
4870 case Zbr, Zjmp, Zloop:
4871 if p.As == AXBEGIN {
4872 ab.Put1(byte(op))
4873 }
4874 if p.To.Sym != nil {
4875 if yt.zcase != Zjmp {
4876 ctxt.Diag("branch to ATEXT")
4877 ctxt.DiagFlush()
4878 log.Fatalf("bad code")
4879 }
4880
4881 ab.Put1(o.op[z+1])
4882 cursym.AddRel(ctxt, obj.Reloc{
4883
4884
4885 Type: objabi.R_CALL,
4886 Off: int32(p.Pc + int64(ab.Len())),
4887 Siz: 4,
4888 Sym: p.To.Sym,
4889 })
4890 ab.PutInt32(0)
4891 break
4892 }
4893
4894
4895
4896
4897
4898 q := p.To.Target()
4899
4900 if q == nil {
4901 ctxt.Diag("jmp/branch/loop without target")
4902 ctxt.DiagFlush()
4903 log.Fatalf("bad code")
4904 }
4905
4906 if p.Back&branchBackwards != 0 {
4907 v := q.Pc - (p.Pc + 2)
4908 if v >= -128 && p.As != AXBEGIN {
4909 if p.As == AJCXZL {
4910 ab.Put1(0x67)
4911 }
4912 ab.Put2(byte(op), byte(v))
4913 } else if yt.zcase == Zloop {
4914 ctxt.Diag("loop too far: %v", p)
4915 } else {
4916 v -= 5 - 2
4917 if p.As == AXBEGIN {
4918 v--
4919 }
4920 if yt.zcase == Zbr {
4921 ab.Put1(0x0f)
4922 v--
4923 }
4924
4925 ab.Put1(o.op[z+1])
4926 ab.PutInt32(int32(v))
4927 }
4928
4929 break
4930 }
4931
4932
4933 p.Forwd = q.Rel
4934
4935 q.Rel = p
4936 if p.Back&branchShort != 0 && p.As != AXBEGIN {
4937 if p.As == AJCXZL {
4938 ab.Put1(0x67)
4939 }
4940 ab.Put2(byte(op), 0)
4941 } else if yt.zcase == Zloop {
4942 ctxt.Diag("loop too far: %v", p)
4943 } else {
4944 if yt.zcase == Zbr {
4945 ab.Put1(0x0f)
4946 }
4947 ab.Put1(o.op[z+1])
4948 ab.PutInt32(0)
4949 }
4950
4951 case Zbyte:
4952 var rel obj.Reloc
4953 v := vaddr(ctxt, p, &p.From, &rel)
4954 if rel.Siz != 0 {
4955 rel.Siz = uint8(op)
4956 rel.Off = int32(p.Pc + int64(ab.Len()))
4957 cursym.AddRel(ctxt, rel)
4958 }
4959
4960 ab.Put1(byte(v))
4961 if op > 1 {
4962 ab.Put1(byte(v >> 8))
4963 if op > 2 {
4964 ab.PutInt16(int16(v >> 16))
4965 if op > 4 {
4966 ab.PutInt32(int32(v >> 32))
4967 }
4968 }
4969 }
4970 }
4971
4972 return
4973 }
4974 }
4975 f3t = Ynone * Ymax
4976 if p.GetFrom3() != nil {
4977 f3t = oclass(ctxt, p, p.GetFrom3()) * Ymax
4978 }
4979 for mo := ymovtab; mo[0].as != 0; mo = mo[1:] {
4980 var pp obj.Prog
4981 var t []byte
4982 if p.As == mo[0].as {
4983 if ycover[ft+int(mo[0].ft)] != 0 && ycover[f3t+int(mo[0].f3t)] != 0 && ycover[tt+int(mo[0].tt)] != 0 {
4984 t = mo[0].op[:]
4985 switch mo[0].code {
4986 default:
4987 ctxt.Diag("asmins: unknown mov %d %v", mo[0].code, p)
4988
4989 case movLit:
4990 for z = 0; t[z] != 0; z++ {
4991 ab.Put1(t[z])
4992 }
4993
4994 case movRegMem:
4995 ab.Put1(t[0])
4996 ab.asmando(ctxt, cursym, p, &p.To, int(t[1]))
4997
4998 case movMemReg:
4999 ab.Put1(t[0])
5000 ab.asmando(ctxt, cursym, p, &p.From, int(t[1]))
5001
5002 case movRegMem2op:
5003 ab.Put2(t[0], t[1])
5004 ab.asmando(ctxt, cursym, p, &p.To, int(t[2]))
5005 ab.rexflag |= regrex[p.From.Reg] & (Rxr | 0x40)
5006
5007 case movMemReg2op:
5008 ab.Put2(t[0], t[1])
5009 ab.asmando(ctxt, cursym, p, &p.From, int(t[2]))
5010 ab.rexflag |= regrex[p.To.Reg] & (Rxr | 0x40)
5011
5012 case movFullPtr:
5013 if t[0] != 0 {
5014 ab.Put1(t[0])
5015 }
5016 switch p.To.Index {
5017 default:
5018 goto bad
5019
5020 case REG_DS:
5021 ab.Put1(0xc5)
5022
5023 case REG_SS:
5024 ab.Put2(0x0f, 0xb2)
5025
5026 case REG_ES:
5027 ab.Put1(0xc4)
5028
5029 case REG_FS:
5030 ab.Put2(0x0f, 0xb4)
5031
5032 case REG_GS:
5033 ab.Put2(0x0f, 0xb5)
5034 }
5035
5036 ab.asmand(ctxt, cursym, p, &p.From, &p.To)
5037
5038 case movDoubleShift:
5039 if t[0] == Pw {
5040 if ctxt.Arch.Family != sys.AMD64 {
5041 ctxt.Diag("asmins: illegal 64: %v", p)
5042 }
5043 ab.rexflag |= Pw
5044 t = t[1:]
5045 } else if t[0] == Pe {
5046 ab.Put1(Pe)
5047 t = t[1:]
5048 }
5049
5050 switch p.From.Type {
5051 default:
5052 goto bad
5053
5054 case obj.TYPE_CONST:
5055 ab.Put2(0x0f, t[0])
5056 ab.asmandsz(ctxt, cursym, p, &p.To, reg[p.GetFrom3().Reg], regrex[p.GetFrom3().Reg], 0)
5057 ab.Put1(byte(p.From.Offset))
5058
5059 case obj.TYPE_REG:
5060 switch p.From.Reg {
5061 default:
5062 goto bad
5063
5064 case REG_CL, REG_CX:
5065 ab.Put2(0x0f, t[1])
5066 ab.asmandsz(ctxt, cursym, p, &p.To, reg[p.GetFrom3().Reg], regrex[p.GetFrom3().Reg], 0)
5067 }
5068 }
5069
5070
5071
5072
5073
5074 case movTLSReg:
5075 if ctxt.Arch.Family == sys.AMD64 && p.As != AMOVQ || ctxt.Arch.Family == sys.I386 && p.As != AMOVL {
5076 ctxt.Diag("invalid load of TLS: %v", p)
5077 }
5078
5079 if ctxt.Arch.Family == sys.I386 {
5080
5081
5082
5083
5084 switch ctxt.Headtype {
5085 default:
5086 log.Fatalf("unknown TLS base location for %v", ctxt.Headtype)
5087
5088 case objabi.Hlinux, objabi.Hfreebsd:
5089 if ctxt.Flag_shared {
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101 dst := p.To.Reg
5102 ab.Put1(0xe8)
5103 cursym.AddRel(ctxt, obj.Reloc{
5104 Type: objabi.R_CALL,
5105 Off: int32(p.Pc + int64(ab.Len())),
5106 Siz: 4,
5107 Sym: ctxt.Lookup("__x86.get_pc_thunk." + strings.ToLower(rconv(int(dst)))),
5108 })
5109 ab.PutInt32(0)
5110
5111 ab.Put2(0x8B, byte(2<<6|reg[dst]|(reg[dst]<<3)))
5112 cursym.AddRel(ctxt, obj.Reloc{
5113 Type: objabi.R_TLS_IE,
5114 Off: int32(p.Pc + int64(ab.Len())),
5115 Siz: 4,
5116 Add: 2,
5117 })
5118 ab.PutInt32(0)
5119 } else {
5120
5121 pp.From = p.From
5122
5123 pp.From.Type = obj.TYPE_MEM
5124 pp.From.Reg = REG_GS
5125 pp.From.Offset = 0
5126 pp.From.Index = REG_NONE
5127 pp.From.Scale = 0
5128 ab.Put2(0x65,
5129 0x8B)
5130 ab.asmand(ctxt, cursym, p, &pp.From, &p.To)
5131 }
5132 case objabi.Hplan9:
5133 pp.From = obj.Addr{}
5134 pp.From.Type = obj.TYPE_MEM
5135 pp.From.Name = obj.NAME_EXTERN
5136 pp.From.Sym = plan9privates
5137 pp.From.Offset = 0
5138 pp.From.Index = REG_NONE
5139 ab.Put1(0x8B)
5140 ab.asmand(ctxt, cursym, p, &pp.From, &p.To)
5141 }
5142 break
5143 }
5144
5145 switch ctxt.Headtype {
5146 default:
5147 log.Fatalf("unknown TLS base location for %v", ctxt.Headtype)
5148
5149 case objabi.Hlinux, objabi.Hfreebsd:
5150 if !ctxt.Flag_shared {
5151 log.Fatalf("unknown TLS base location for linux/freebsd without -shared")
5152 }
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162 ab.rexflag = Pw | (regrex[p.To.Reg] & Rxr)
5163
5164 ab.Put2(0x8B, byte(0x05|(reg[p.To.Reg]<<3)))
5165 cursym.AddRel(ctxt, obj.Reloc{
5166 Type: objabi.R_TLS_IE,
5167 Off: int32(p.Pc + int64(ab.Len())),
5168 Siz: 4,
5169 Add: -4,
5170 })
5171 ab.PutInt32(0)
5172
5173 case objabi.Hplan9:
5174 pp.From = obj.Addr{}
5175 pp.From.Type = obj.TYPE_MEM
5176 pp.From.Name = obj.NAME_EXTERN
5177 pp.From.Sym = plan9privates
5178 pp.From.Offset = 0
5179 pp.From.Index = REG_NONE
5180 ab.rexflag |= Pw
5181 ab.Put1(0x8B)
5182 ab.asmand(ctxt, cursym, p, &pp.From, &p.To)
5183
5184 case objabi.Hsolaris:
5185
5186 pp.From = p.From
5187
5188 pp.From.Type = obj.TYPE_MEM
5189 pp.From.Name = obj.NAME_NONE
5190 pp.From.Reg = REG_NONE
5191 pp.From.Offset = 0
5192 pp.From.Index = REG_NONE
5193 pp.From.Scale = 0
5194 ab.rexflag |= Pw
5195 ab.Put2(0x64,
5196 0x8B)
5197 ab.asmand(ctxt, cursym, p, &pp.From, &p.To)
5198 }
5199 }
5200 return
5201 }
5202 }
5203 }
5204 goto bad
5205
5206 bad:
5207 if ctxt.Arch.Family != sys.AMD64 {
5208
5209
5210
5211
5212
5213 pp := *p
5214
5215 unbytereg(&pp.From, &pp.Ft)
5216 unbytereg(&pp.To, &pp.Tt)
5217
5218 z := int(p.From.Reg)
5219 if p.From.Type == obj.TYPE_REG && z >= REG_BP && z <= REG_DI {
5220
5221
5222 if ctxt.Arch.Family == sys.I386 {
5223 breg := byteswapreg(ctxt, &p.To)
5224 if breg != REG_AX {
5225 ab.Put1(0x87)
5226 ab.asmando(ctxt, cursym, p, &p.From, reg[breg])
5227 subreg(&pp, z, breg)
5228 ab.doasm(ctxt, cursym, &pp)
5229 ab.Put1(0x87)
5230 ab.asmando(ctxt, cursym, p, &p.From, reg[breg])
5231 } else {
5232 ab.Put1(byte(0x90 + reg[z]))
5233 subreg(&pp, z, REG_AX)
5234 ab.doasm(ctxt, cursym, &pp)
5235 ab.Put1(byte(0x90 + reg[z]))
5236 }
5237 return
5238 }
5239
5240 if isax(&p.To) || p.To.Type == obj.TYPE_NONE {
5241
5242
5243 ab.Put1(0x87)
5244 ab.asmando(ctxt, cursym, p, &p.From, reg[REG_BX])
5245 subreg(&pp, z, REG_BX)
5246 ab.doasm(ctxt, cursym, &pp)
5247 ab.Put1(0x87)
5248 ab.asmando(ctxt, cursym, p, &p.From, reg[REG_BX])
5249 } else {
5250 ab.Put1(byte(0x90 + reg[z]))
5251 subreg(&pp, z, REG_AX)
5252 ab.doasm(ctxt, cursym, &pp)
5253 ab.Put1(byte(0x90 + reg[z]))
5254 }
5255 return
5256 }
5257
5258 z = int(p.To.Reg)
5259 if p.To.Type == obj.TYPE_REG && z >= REG_BP && z <= REG_DI {
5260
5261
5262 if ctxt.Arch.Family == sys.I386 {
5263 breg := byteswapreg(ctxt, &p.From)
5264 if breg != REG_AX {
5265 ab.Put1(0x87)
5266 ab.asmando(ctxt, cursym, p, &p.To, reg[breg])
5267 subreg(&pp, z, breg)
5268 ab.doasm(ctxt, cursym, &pp)
5269 ab.Put1(0x87)
5270 ab.asmando(ctxt, cursym, p, &p.To, reg[breg])
5271 } else {
5272 ab.Put1(byte(0x90 + reg[z]))
5273 subreg(&pp, z, REG_AX)
5274 ab.doasm(ctxt, cursym, &pp)
5275 ab.Put1(byte(0x90 + reg[z]))
5276 }
5277 return
5278 }
5279
5280 if isax(&p.From) {
5281 ab.Put1(0x87)
5282 ab.asmando(ctxt, cursym, p, &p.To, reg[REG_BX])
5283 subreg(&pp, z, REG_BX)
5284 ab.doasm(ctxt, cursym, &pp)
5285 ab.Put1(0x87)
5286 ab.asmando(ctxt, cursym, p, &p.To, reg[REG_BX])
5287 } else {
5288 ab.Put1(byte(0x90 + reg[z]))
5289 subreg(&pp, z, REG_AX)
5290 ab.doasm(ctxt, cursym, &pp)
5291 ab.Put1(byte(0x90 + reg[z]))
5292 }
5293 return
5294 }
5295 }
5296
5297 ctxt.Diag("%s: invalid instruction: %v", cursym.Name, p)
5298 }
5299
5300
5301
5302
5303
5304 func byteswapreg(ctxt *obj.Link, a *obj.Addr) int {
5305 cana, canb, canc, cand := true, true, true, true
5306 if a.Type == obj.TYPE_NONE {
5307 cana, cand = false, false
5308 }
5309
5310 if a.Type == obj.TYPE_REG || ((a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Name == obj.NAME_NONE) {
5311 switch a.Reg {
5312 case REG_NONE:
5313 cana, cand = false, false
5314 case REG_AX, REG_AL, REG_AH:
5315 cana = false
5316 case REG_BX, REG_BL, REG_BH:
5317 canb = false
5318 case REG_CX, REG_CL, REG_CH:
5319 canc = false
5320 case REG_DX, REG_DL, REG_DH:
5321 cand = false
5322 }
5323 }
5324
5325 if a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR {
5326 switch a.Index {
5327 case REG_AX:
5328 cana = false
5329 case REG_BX:
5330 canb = false
5331 case REG_CX:
5332 canc = false
5333 case REG_DX:
5334 cand = false
5335 }
5336 }
5337
5338 switch {
5339 case cana:
5340 return REG_AX
5341 case canb:
5342 return REG_BX
5343 case canc:
5344 return REG_CX
5345 case cand:
5346 return REG_DX
5347 default:
5348 ctxt.Diag("impossible byte register")
5349 ctxt.DiagFlush()
5350 log.Fatalf("bad code")
5351 return 0
5352 }
5353 }
5354
5355 func isbadbyte(a *obj.Addr) bool {
5356 return a.Type == obj.TYPE_REG && (REG_BP <= a.Reg && a.Reg <= REG_DI || REG_BPB <= a.Reg && a.Reg <= REG_DIB)
5357 }
5358
5359 func (ab *AsmBuf) asmins(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
5360 ab.Reset()
5361
5362 ab.rexflag = 0
5363 ab.vexflag = false
5364 ab.evexflag = false
5365 mark := ab.Len()
5366 ab.doasm(ctxt, cursym, p)
5367 if ab.rexflag != 0 && !ab.vexflag && !ab.evexflag {
5368
5369
5370
5371
5372
5373 if ctxt.Arch.Family != sys.AMD64 {
5374 ctxt.Diag("asmins: illegal in mode %d: %v (%d %d)", ctxt.Arch.RegSize*8, p, p.Ft, p.Tt)
5375 }
5376 n := ab.Len()
5377 var np int
5378 for np = mark; np < n; np++ {
5379 c := ab.At(np)
5380 if c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26 {
5381 break
5382 }
5383 }
5384 ab.Insert(np, byte(0x40|ab.rexflag))
5385 }
5386
5387 n := ab.Len()
5388 for i := len(cursym.R) - 1; i >= 0; i-- {
5389 r := &cursym.R[i]
5390 if int64(r.Off) < p.Pc {
5391 break
5392 }
5393 if ab.rexflag != 0 && !ab.vexflag && !ab.evexflag {
5394 r.Off++
5395 }
5396 if r.Type == objabi.R_PCREL {
5397 if ctxt.Arch.Family == sys.AMD64 || p.As == obj.AJMP || p.As == obj.ACALL {
5398
5399
5400
5401
5402
5403
5404
5405 r.Add -= p.Pc + int64(n) - (int64(r.Off) + int64(r.Siz))
5406 } else if ctxt.Arch.Family == sys.I386 {
5407
5408
5409
5410
5411 r.Add += int64(r.Off) - p.Pc + int64(r.Siz)
5412 }
5413 }
5414 if r.Type == objabi.R_GOTPCREL && ctxt.Arch.Family == sys.I386 {
5415
5416 r.Add += int64(r.Off) - p.Pc + int64(r.Siz)
5417 }
5418
5419 }
5420 }
5421
5422
5423 func unpackOps4(p *obj.Prog) (arg0, arg1, arg2, dst *obj.Addr) {
5424 return &p.From, &p.RestArgs[0].Addr, &p.RestArgs[1].Addr, &p.To
5425 }
5426
5427
5428 func unpackOps5(p *obj.Prog) (arg0, arg1, arg2, arg3, dst *obj.Addr) {
5429 return &p.From, &p.RestArgs[0].Addr, &p.RestArgs[1].Addr, &p.RestArgs[2].Addr, &p.To
5430 }
5431
View as plain text