Help us shape the future of Go! Take the 2026 Go Developer Survey

Source file src/cmd/internal/obj/x86/asm6.go

     1  // Inferno utils/6l/span.c
     2  // https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/span.c
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors. All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    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  // Instruction layout.
    49  
    50  // Loop alignment constants:
    51  // want to align loop entry to loopAlign-byte boundary,
    52  // and willing to insert at most maxLoopPad bytes of NOP to do so.
    53  // We define a loop entry as the target of a backward jump.
    54  //
    55  // gcc uses maxLoopPad = 10 for its 'generic x86-64' config,
    56  // and it aligns all jump targets, not just backward jump targets.
    57  //
    58  // As of 6/1/2012, the effect of setting maxLoopPad = 10 here
    59  // is very slight but negative, so the alignment is disabled by
    60  // setting MaxLoopPad = 0. The code is here for reference and
    61  // for future experiments.
    62  const (
    63  	loopAlign  = 16
    64  	maxLoopPad = 0
    65  )
    66  
    67  // Bit flags that are used to express jump target properties.
    68  const (
    69  	// branchBackwards marks targets that are located behind.
    70  	// Used to express jumps to loop headers.
    71  	branchBackwards = (1 << iota)
    72  	// branchShort marks branches those target is close,
    73  	// with offset is in -128..127 range.
    74  	branchShort
    75  	// branchLoopHead marks loop entry.
    76  	// Used to insert padding for misaligned loops.
    77  	branchLoopHead
    78  )
    79  
    80  // opBytes holds optab encoding bytes.
    81  // Each ytab reserves fixed amount of bytes in this array.
    82  //
    83  // The size should be the minimal number of bytes that
    84  // are enough to hold biggest optab op lines.
    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 // $0
   107  	Yi1 // $1
   108  	Yu2 // $x, x fits in uint2
   109  	Yi8 // $x, x fits in int8
   110  	Yu8 // $x, x fits in uint8
   111  	Yu7 // $x, x in 0..127 (fits in both int8 and uint8)
   112  	Ys32
   113  	Yi32
   114  	Yi64
   115  	Yiauto
   116  	Yal
   117  	Ycl
   118  	Yax
   119  	Ycx
   120  	Yrb
   121  	Yrl
   122  	Yrl32 // Yrl on 32-bit system
   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          // X0 only. "<XMM0>" notation in Intel manual.
   169  	YxrEvexMulti4 // [ X<n> - X<n+3> ]; multisource YxrEvex
   170  	Yxr           // X0..X15
   171  	YxrEvex       // X0..X31
   172  	Yxm
   173  	YxmEvex       // YxrEvex+Ym
   174  	Yxvm          // VSIB vector array; vm32x/vm64x
   175  	YxvmEvex      // Yxvm which permits High-16 X register as index.
   176  	YyrEvexMulti4 // [ Y<n> - Y<n+3> ]; multisource YyrEvex
   177  	Yyr           // Y0..Y15
   178  	YyrEvex       // Y0..Y31
   179  	Yym
   180  	YymEvex   // YyrEvex+Ym
   181  	Yyvm      // VSIB vector array; vm32y/vm64y
   182  	YyvmEvex  // Yyvm which permits High-16 Y register as index.
   183  	YzrMulti4 // [ Z<n> - Z<n+3> ]; multisource YzrEvex
   184  	Yzr       // Z0..Z31
   185  	Yzm       // Yzr+Ym
   186  	Yzvm      // VSIB vector array; vm32z/vm64z
   187  	Yk0       // K0
   188  	Yknot0    // K1..K7; write mask
   189  	Yk        // K0..K7; used for KOP
   190  	Ykm       // Yk+Ym; used for KOP
   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 // mmx1,mmx2/mem64,imm8
   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    // symbolic; exact value doesn't matter
   285  	P32  = 0x32 // 32-bit only
   286  	Pe   = 0x66 // operand escape
   287  	Pm   = 0x0f // 2byte opcode escape
   288  	Pq   = 0xff // both escapes: 66 0f
   289  	Pb   = 0xfe // byte operands
   290  	Pf2  = 0xf2 // xmm escape 1: f2 0f
   291  	Pf3  = 0xf3 // xmm escape 2: f3 0f
   292  	Pef3 = 0xf5 // xmm escape 2 with 16-bit prefix: 66 f3 0f
   293  	Pq3  = 0x67 // xmm escape 3: 66 48 0f
   294  	Pq4  = 0x68 // xmm escape 4: 66 0F 38
   295  	Pq4w = 0x69 // Pq4 with Rex.w 66 0F 38
   296  	Pq5  = 0x6a // xmm escape 5: F3 0F 38
   297  	Pq5w = 0x6b // Pq5 with Rex.w F3 0F 38
   298  	Pfw  = 0xf4 // Pf3 with Rex.w: f3 48 0f
   299  	Pw   = 0x48 // Rex.w
   300  	Pw8  = 0x90 // symbolic; exact value doesn't matter
   301  	Py   = 0x80 // defaults to 64-bit mode
   302  	Py1  = 0x81 // symbolic; exact value doesn't matter
   303  	Py3  = 0x83 // symbolic; exact value doesn't matter
   304  	Pavx = 0x84 // symbolic; exact value doesn't matter
   305  
   306  	RxrEvex = 1 << 4 // AVX512 extension to REX.R/VEX.R
   307  	Rxw     = 1 << 3 // =1, 64-bit operand size
   308  	Rxr     = 1 << 2 // extend modrm reg
   309  	Rxx     = 1 << 1 // extend sib index
   310  	Rxb     = 1 << 0 // extend modrm r/m, sib base, or opcode reg
   311  )
   312  
   313  const (
   314  	// Encoding for VEX prefix in tables.
   315  	// The P, L, and W fields are chosen to match
   316  	// their eventual locations in the VEX prefix bytes.
   317  
   318  	// Encoding for VEX prefix in tables.
   319  	// The P, L, and W fields are chosen to match
   320  	// their eventual locations in the VEX prefix bytes.
   321  
   322  	// Using spare bit to make leading [E]VEX encoding byte different from
   323  	// 0x0f even if all other VEX fields are 0.
   324  	avxEscape = 1 << 6
   325  
   326  	// P field - 2 bits
   327  	vex66 = 1 << 0
   328  	vexF3 = 2 << 0
   329  	vexF2 = 3 << 0
   330  	// L field - 1 bit
   331  	vexLZ  = 0 << 2
   332  	vexLIG = 0 << 2
   333  	vex128 = 0 << 2
   334  	vex256 = 1 << 2
   335  	// W field - 1 bit
   336  	vexWIG = 0 << 7
   337  	vexW0  = 0 << 7
   338  	vexW1  = 1 << 7
   339  	// M field - 5 bits, but mostly reserved; we can store up to 3
   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}}, // MMX MOVD
   465  	{Zr_m_xm, 1, argList{Ymr, Yml}}, // MMX MOVD
   466  	{Zm_r_xm, 2, argList{Yml, Yxr}}, // XMM MOVD (32 bit)
   467  	{Zr_m_xm, 2, argList{Yxr, Yml}}, // XMM MOVD (32 bit)
   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  	// valid in 32-bit mode
   478  	{Zm_r_xm_nr, 1, argList{Ym, Ymr}},  // 0x6f MMX MOVQ (shorter encoding)
   479  	{Zr_m_xm_nr, 1, argList{Ymr, Ym}},  // 0x7f MMX MOVQ
   480  	{Zm_r_xm_nr, 2, argList{Yxr, Ymr}}, // Pf2, 0xd6 MOVDQ2Q
   481  	{Zm_r_xm_nr, 2, argList{Yxm, Yxr}}, // Pf3, 0x7e MOVQ xmm1/m64 -> xmm2
   482  	{Zr_m_xm_nr, 2, argList{Yxr, Yxm}}, // Pe, 0xd6 MOVQ xmm1 -> xmm2/m64
   483  
   484  	// valid only in 64-bit mode, usually with 64-bit prefix
   485  	{Zr_m, 1, argList{Yrl, Yml}},      // 0x89
   486  	{Zm_r, 1, argList{Yml, Yrl}},      // 0x8b
   487  	{Ziq_rp, 1, argList{Yi64, Yrl}},   // 0xb8 -- 32/64 bit immediate (Ziq_rp picks 5/7/10-byte form)
   488  	{Zilo_m, 2, argList{Yi32, Yml}},   // 0xc7,(0)
   489  	{Zm_r_xm, 1, argList{Ymm, Ymr}},   // 0x6e MMX MOVD
   490  	{Zr_m_xm, 1, argList{Ymr, Ymm}},   // 0x7e MMX MOVD
   491  	{Zm_r_xm, 2, argList{Yml, Yxr}},   // Pe, 0x6e MOVD xmm load
   492  	{Zr_m_xm, 2, argList{Yxr, Yml}},   // Pe, 0x7e MOVD xmm store
   493  	{Zaut_r, 1, argList{Yiauto, Yrl}}, // 0 built-in LEAQ
   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}}, // botch is really f0,f1
   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  // unaryDst version of "ysvrs_mo".
   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  // It should never have more than 1 entry,
   777  // because some optab entries have opcode sequences that
   778  // are longer than 2 bytes (zoffset=2 here),
   779  // ROUNDPD and ROUNDPS and recently added BLENDPD,
   780  // to name a few.
   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  // You are doasm, holding in your hand a *obj.Prog with p.As set to, say,
   865  // ACRC32, and p.From and p.To as operands (obj.Addr).  The linker scans optab
   866  // to find the entry with the given p.As and then looks through the ytable for
   867  // that instruction (the second field in the optab struct) for a line whose
   868  // first two values match the Ytypes of the p.From and p.To operands.  The
   869  // function oclass computes the specific Ytype of an operand and then the set
   870  // of more general Ytypes that it satisfies is implied by the ycover table, set
   871  // up in instinit.  For example, oclass distinguishes the constants 0 and 1
   872  // from the more general 8-bit constants, but instinit says
   873  //
   874  //	ycover[Yi0*Ymax+Ys32] = 1
   875  //	ycover[Yi1*Ymax+Ys32] = 1
   876  //	ycover[Yi8*Ymax+Ys32] = 1
   877  //
   878  // which means that Yi0, Yi1, and Yi8 all count as Ys32 (signed 32)
   879  // if that's what an instruction can handle.
   880  //
   881  // In parallel with the scan through the ytable for the appropriate line, there
   882  // is a z pointer that starts out pointing at the strange magic byte list in
   883  // the Optab struct.  With each step past a non-matching ytable line, z
   884  // advances by the 4th entry in the line.  When a matching line is found, that
   885  // z pointer has the extra data to use in laying down the instruction bytes.
   886  // The actual bytes laid down are a function of the 3rd entry in the line (that
   887  // is, the Ztype) and the z bytes.
   888  //
   889  // For example, let's look at AADDL.  The optab line says:
   890  //
   891  //	{AADDL, yaddl, Px, opBytes{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}},
   892  //
   893  // and yaddl says
   894  //
   895  //	var yaddl = []ytab{
   896  //	        {Yi8, Ynone, Yml, Zibo_m, 2},
   897  //	        {Yi32, Ynone, Yax, Zil_, 1},
   898  //	        {Yi32, Ynone, Yml, Zilo_m, 2},
   899  //	        {Yrl, Ynone, Yml, Zr_m, 1},
   900  //	        {Yml, Ynone, Yrl, Zm_r, 1},
   901  //	}
   902  //
   903  // so there are 5 possible types of ADDL instruction that can be laid down, and
   904  // possible states used to lay them down (Ztype and z pointer, assuming z
   905  // points at opBytes{0x83, 00, 0x05,0x81, 00, 0x01, 0x03}) are:
   906  //
   907  //	Yi8, Yml -> Zibo_m, z (0x83, 00)
   908  //	Yi32, Yax -> Zil_, z+2 (0x05)
   909  //	Yi32, Yml -> Zilo_m, z+2+1 (0x81, 0x00)
   910  //	Yrl, Yml -> Zr_m, z+2+1+2 (0x01)
   911  //	Yml, Yrl -> Zm_r, z+2+1+2+1 (0x03)
   912  //
   913  // The Pconstant in the optab line controls the prefix bytes to emit.  That's
   914  // relatively straightforward as this program goes.
   915  //
   916  // The switch on yt.zcase in doasm implements the various Z cases.  Zibo_m, for
   917  // example, is an opcode byte (z[0]) then an asmando (which is some kind of
   918  // encoded addressing mode for the Yml arg), and then a single immediate byte.
   919  // Zilo_m is the same but a long (32-bit) immediate.
   920  var optab =
   921  // as, ytab, andproto, opcode
   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{}}, // botch
  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}}, // TODO(rsc): yscond is wrong here.
  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}}, // XCHGB AH,AL; PUSH AX; POPFL
  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}}, // fast syscall
  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}},  // botch
  1559  	{AFCOMDP, yfadd, Px, opBytes{0xdc, 03, 0xd8, 03, 0xdc, 03}}, // botch
  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  // useAbs reports whether s describes a symbol that must avoid pc-relative addressing.
  1800  // This happens on systems like Solaris that call .so functions instead of system calls.
  1801  // It does not seem to be necessary for any other systems. This is probably working
  1802  // around a Solaris-specific bug that should be fixed differently, but we don't know
  1803  // what that bug is. And this does fix it.
  1804  func useAbs(ctxt *obj.Link, s *obj.LSym) bool {
  1805  	if ctxt.Headtype == objabi.Hsolaris {
  1806  		// All the Solaris dynamic imports from libc.so begin with "libc_".
  1807  		return strings.HasPrefix(s.Name, "libc_")
  1808  	}
  1809  	return ctxt.Arch.Family == sys.I386 && !ctxt.Flag_shared
  1810  }
  1811  
  1812  // single-instruction no-ops of various lengths.
  1813  // constructed by hand and disassembled with gdb to verify.
  1814  // see http://www.agner.org/optimize/optimizing_assembly.pdf for discussion.
  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  // Native Client rejects the repeated 0x66 prefix.
  1828  // {0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
  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  // isJump returns whether p is a jump instruction.
  1857  // It is used to ensure that no standalone or macro-fused jump will straddle
  1858  // or end on a 32 byte boundary by inserting NOPs before the jumps.
  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  // lookForJCC returns the first real instruction starting from p, if that instruction is a conditional
  1865  // jump. Otherwise, nil is returned.
  1866  func lookForJCC(p *obj.Prog) *obj.Prog {
  1867  	// Skip any PCDATA, FUNCDATA or NOP instructions
  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  // fusedJump determines whether p can be fused with a subsequent conditional jump instruction.
  1887  // If it can, we return true followed by the total size of the fused jump. If it can't, we return false.
  1888  // Macro fusion rules are derived from the Intel Optimization Manual (April 2019) section 3.4.2.2.
  1889  func fusedJump(p *obj.Prog) (bool, uint8) {
  1890  	var fusedSize uint8
  1891  
  1892  	// The first instruction in a macro fused pair may be preceded by the LOCK prefix,
  1893  	// or possibly an XACQUIRE/XRELEASE prefix followed by a LOCK prefix. If it is, we
  1894  	// need to be careful to insert any padding before the locks rather than directly after them.
  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  	// Disable jump padding on 32 bit builds by setting
  1982  	// padJumps to 0.
  1983  	if ctxt.Arch.Family == sys.I386 {
  1984  		return padJumpsCtx(0)
  1985  	}
  1986  
  1987  	// Disable jump padding for hand written assembly code.
  1988  	if ctxt.IsAsm {
  1989  		return padJumpsCtx(0)
  1990  	}
  1991  
  1992  	return padJumpsCtx(32)
  1993  }
  1994  
  1995  // padJump detects whether the instruction being assembled is a standalone or a macro-fused
  1996  // jump that needs to be padded. If it is, NOPs are inserted to ensure that the jump does
  1997  // not cross or end on a 32 byte boundary.
  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  // reAssemble is called if an instruction's size changes during assembly. If
  2023  // it does and the instruction is a standalone or a macro-fused jump we need to
  2024  // reassemble.
  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 // Instruction before the pad
  2036  	n int32     // Size of the pad
  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 // don't keep printing
  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  			// Generate 'ADDQ $x, SP' or 'SUBQ $x, SP', with x positive.
  2063  			// One exception: It is smaller to encode $-0x80 than $0x80.
  2064  			// For that case, flip the sign and the op:
  2065  			// Instead of 'ADDQ $0x80, SP', generate 'SUBQ $-0x80, SP'.
  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 // rough count of number of instructions
  2090  	for p := s.Func().Text; p != nil; p = p.Link {
  2091  		count++
  2092  		p.Back = branchShort // use short branches first time through
  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) // preallocate roughly 5 bytes per instruction
  2099  
  2100  	var ab AsmBuf
  2101  	var n int
  2102  	var c int32
  2103  	errors := ctxt.Errors
  2104  	var nops []nopPad // Padding for a particular assembly (reuse slice storage if multiple assemblies)
  2105  	nrelocs0 := len(s.R)
  2106  	for {
  2107  		// This loop continues while there are reasons to re-assemble
  2108  		// whole block, like the presence of long forward jumps.
  2109  		reAssemble := false
  2110  		for i := range s.R[nrelocs0:] {
  2111  			s.R[nrelocs0+i] = obj.Reloc{}
  2112  		}
  2113  		s.R = s.R[:nrelocs0] // preserve marker relocations generated by the compiler
  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  				// pad with NOPs
  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  			// process forward jumps to p
  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  					// We need to re-assemble here to check for jumps and fused jumps
  2174  					// that span or end on 32 byte boundaries.
  2175  					reAssemble = true
  2176  				}
  2177  			}
  2178  
  2179  			s.Grow(p.Pc + int64(m))
  2180  			copy(s.P[p.Pc:], ab.Bytes())
  2181  			// If there was padding, remember it.
  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  	// splice padding nops into Progs
  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 { /* debug['a'] > 1 */
  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  	// Mark nonpreemptible instruction sequences.
  2231  	// The 2-instruction TLS access sequence
  2232  	//	MOVQ TLS, BX
  2233  	//	MOVQ 0(BX)(TLS*1), BX
  2234  	// is not async preemptible, as if it is preempted and resumed on
  2235  	// a different thread, the TLS address may become invalid.
  2236  	if !CanUse1InsnTLS(ctxt) {
  2237  		useTLS := func(p *obj.Prog) bool {
  2238  			// Only need to mark the second instruction, which has
  2239  			// REG_TLS as Index. (It is okay to interrupt and restart
  2240  			// the first instruction.)
  2241  			return p.From.Index == REG_TLS
  2242  		}
  2243  		obj.MarkUnsafePoints(ctxt, s.Func().Text, newprog, useTLS, nil)
  2244  	}
  2245  
  2246  	// Now that we know byte offsets, we can generate jump table entries.
  2247  	// TODO: could this live in obj instead of obj/$ARCH?
  2248  	for _, jt := range s.Func().JumpTables {
  2249  		for i, p := range jt.Targets {
  2250  			// The ith jumptable entry points to the p.Pc'th
  2251  			// byte in the function symbol s.
  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  		// Already initialized; stop now.
  2260  		// This happens in the cmd/asm tests,
  2261  		// each of which re-initializes the arch.
  2262  		return
  2263  	}
  2264  
  2265  	switch ctxt.Headtype {
  2266  	case objabi.Hplan9:
  2267  		// _privates is a special symbol on Plan 9 that
  2268  		// points to per–process private data (like TLS area).
  2269  		// See https://9p.io/magic/man2html/2/exec .
  2270  		// The assembler inserts a reference to this symbol
  2271  		// for accessing the G. Mark it as linkname so it is
  2272  		// allowed to access from anywhere. (Would be nice to
  2273  		// mark it external, but we don't have a mechanism for
  2274  		// that.)
  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 // but not Yrl32
  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 // but not Yrl32
  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 { // fast path
  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  			// NOTE: Systems listed here should be only systems that
  2525  			// support direct TLS references like 8(TLS) implemented as
  2526  			// direct references from FS or GS. Systems that require
  2527  			// the initial-exec model, where you load the TLS base into
  2528  			// a register and then index from that register, do not reach
  2529  			// this code and should not be listed.
  2530  			if ctxt.Arch.Family == sys.I386 {
  2531  				switch ctxt.Headtype {
  2532  				default:
  2533  					if isAndroid {
  2534  						return 0x65 // GS
  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 // GS
  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 // FS
  2554  				}
  2555  
  2556  				if ctxt.Flag_shared {
  2557  					log.Fatalf("unknown TLS base register for linux with -shared")
  2558  				} else {
  2559  					return 0x64 // FS
  2560  				}
  2561  
  2562  			case objabi.Hdragonfly,
  2563  				objabi.Hfreebsd,
  2564  				objabi.Hnetbsd,
  2565  				objabi.Hopenbsd,
  2566  				objabi.Hsolaris:
  2567  				return 0x64 // FS
  2568  
  2569  			case objabi.Hdarwin:
  2570  				return 0x65 // GS
  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  			// When building for inclusion into a shared library, an instruction of the form
  2588  			//     MOV off(CX)(TLS*1), AX
  2589  			// becomes
  2590  			//     mov %gs:off(%ecx), %eax // on i386
  2591  			//     mov %fs:off(%rcx), %rax // on amd64
  2592  			// which assumes that the correct TLS offset has been loaded into CX (today
  2593  			// there is only one TLS variable -- g -- so this is OK). When not building for
  2594  			// a shared library the instruction it becomes
  2595  			//     mov 0x0(%ecx), %eax // on i386
  2596  			//     mov 0x0(%rcx), %rax // on amd64
  2597  			// and a R_TLS_LE relocation, and so does not require a prefix.
  2598  			if ctxt.Arch.Family == sys.I386 {
  2599  				return 0x65 // GS
  2600  			}
  2601  			return 0x64 // FS
  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  // oclassRegList returns multisource operand class for addr.
  2615  func oclassRegList(ctxt *obj.Link, addr *obj.Addr) int {
  2616  	// TODO(quasilyte): when oclass register case is refactored into
  2617  	// lookup table, use it here to get register kind more easily.
  2618  	// Helper functions like regIsXmm should go away too (they will become redundant).
  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  // oclassVMem returns V-mem (vector memory with VSIB) operand class.
  2652  // For addr that is not V-mem returns (Yxxx, false).
  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  		// Pseudo registers have negative index, but SP is
  2800  		// not pseudo on x86, hence REG_SP check is not redundant.
  2801  		if a.Index == REG_SP || a.Index < 0 {
  2802  			// Can't use FP/SB/PC/SP as the index register.
  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  				// Global variables can't use index registers and their
  2814  				// base register is %rip (%rip is encoded as REG_NONE).
  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  				// These names must have a base of SP.  The old compiler
  2820  				// uses 0 for the base register. SSA uses REG_SP.
  2821  				if a.Reg != REG_SP && a.Reg != 0 {
  2822  					return Yxxx
  2823  				}
  2824  			case obj.NAME_NONE:
  2825  				// everything is ok
  2826  			default:
  2827  				// unknown name
  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 // use pc-relative addressing
  2845  
  2846  		case obj.NAME_AUTO,
  2847  			obj.NAME_PARAM:
  2848  			return Yiauto
  2849  		}
  2850  
  2851  		// TODO(rsc): DUFFZERO/DUFFCOPY encoding forgot to set a->index
  2852  		// and got Yi32 in an earlier version of this code.
  2853  		// Keep doing that until we fix yduff etc.
  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 // can sign extend
  2892  		}
  2893  		if v>>32 == 0 {
  2894  			return Yi32 // unsigned
  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  		/*
  2915  			case REG_SPB:
  2916  		*/
  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, // not really Yrl
  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  // AsmBuf is a simple buffer to assemble variable-length x86 instructions into
  3200  // and hold assembly state.
  3201  type AsmBuf struct {
  3202  	buf      [100]byte
  3203  	off      int
  3204  	rexflag  int
  3205  	vexflag  bool // Per inst: true for VEX-encoded
  3206  	evexflag bool // Per inst: true for EVEX-encoded
  3207  	rep      bool
  3208  	repn     bool
  3209  	lock     bool
  3210  
  3211  	evex evexBits // Initialized when evexflag is true
  3212  }
  3213  
  3214  // Put1 appends one byte to the end of the buffer.
  3215  func (ab *AsmBuf) Put1(x byte) {
  3216  	ab.buf[ab.off] = x
  3217  	ab.off++
  3218  }
  3219  
  3220  // Put2 appends two bytes to the end of the buffer.
  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  // Put3 appends three bytes to the end of the buffer.
  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  // Put4 appends four bytes to the end of the buffer.
  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  // PutInt16 writes v into the buffer using little-endian encoding.
  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  // PutInt32 writes v into the buffer using little-endian encoding.
  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  // PutInt64 writes v into the buffer using little-endian encoding.
  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  // Put copies b into the buffer.
  3274  func (ab *AsmBuf) Put(b []byte) {
  3275  	copy(ab.buf[ab.off:], b)
  3276  	ab.off += len(b)
  3277  }
  3278  
  3279  // PutOpBytesLit writes zero terminated sequence of bytes from op,
  3280  // starting at specified offset (e.g. z counter value).
  3281  // Trailing 0 is not written.
  3282  //
  3283  // Intended to be used for literal Z cases.
  3284  // Literal Z cases usually have "Zlit" in their name (Zlit, Zlitr_m, Zlitm_r).
  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  // Insert inserts b at offset i.
  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  // Last returns the byte at the end of the buffer.
  3300  func (ab *AsmBuf) Last() byte { return ab.buf[ab.off-1] }
  3301  
  3302  // Len returns the length of the buffer.
  3303  func (ab *AsmBuf) Len() int { return ab.off }
  3304  
  3305  // Bytes returns the contents of the buffer.
  3306  func (ab *AsmBuf) Bytes() []byte { return ab.buf[:ab.off] }
  3307  
  3308  // Reset empties the buffer.
  3309  func (ab *AsmBuf) Reset() { ab.off = 0 }
  3310  
  3311  // At returns the byte at offset i.
  3312  func (ab *AsmBuf) At(i int) byte { return ab.buf[i] }
  3313  
  3314  // asmidx emits SIB byte.
  3315  func (ab *AsmBuf) asmidx(ctxt *obj.Link, scale int, index int, base int) {
  3316  	var i int
  3317  
  3318  	// X/Y index register is used in VSIB.
  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: // must be mod=00
  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 // caller must fill in
  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 // caller must fill in
  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  		// The rules are slightly different for 386 and AMD64,
  3576  		// mostly for historical reasons. We may unify them later,
  3577  		// but it must be discussed beforehand.
  3578  		//
  3579  		// For 64bit mode only LEAL is allowed to overflow.
  3580  		// It's how https://golang.org/cl/59630 made it.
  3581  		// crypto/sha1/sha1block_amd64.s depends on this feature.
  3582  		//
  3583  		// For 32bit mode rules are more permissive.
  3584  		// If offset fits uint32, it's permitted.
  3585  		// This is allowed for assembly that wants to use 32-bit hex
  3586  		// constants, e.g. LEAL 0x99999999(AX), AX.
  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  				// The base register has already been set. It holds the PC
  3637  				// of this instruction returned by a PC-reading thunk.
  3638  				// See obj6.go:rewriteToPcrel.
  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  			// The base register has already been set. It holds the PC
  3684  			// of this instruction returned by a PC-reading thunk.
  3685  			// See obj6.go:rewriteToPcrel.
  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  		// temporary
  3711  		ab.Put2(
  3712  			byte(0<<6|4<<0|r<<3), // sib present
  3713  			0<<6|4<<3|5<<0,       // DS:d32
  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 // Like Zlit
  3806  	movRegMem
  3807  	movMemReg
  3808  	movRegMem2op
  3809  	movMemReg2op
  3810  	movFullPtr // Load full pointer, trash heap (unsupported)
  3811  	movDoubleShift
  3812  	movTLSReg
  3813  )
  3814  
  3815  var ymovtab = []movtab{
  3816  	// push
  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  	// pop
  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  	// mov seg
  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  	// mov cr
  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  	// mov dr
  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  	// mov tr
  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  	// lgdt, sgdt, lidt, sidt
  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  	// lldt, sldt
  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  	// lmsw, smsw
  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  	// ltr, str
  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  	/* load full pointer - unsupported
  3929  	{AMOVL, Yml, Ycol, movFullPtr, [4]uint8{0, 0, 0, 0}},
  3930  	{AMOVW, Yml, Ycol, movFullPtr, [4]uint8{Pe, 0, 0, 0}},
  3931  	*/
  3932  
  3933  	// double shift
  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  	// load TLS base
  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 { /* debug['Q'] */
  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 { /* debug['Q'] */
  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  // asmevex emits EVEX pregis and opcode byte.
  4023  // In addition to asmvex r/m, vvvv and reg fields also requires optional
  4024  // K-masking register.
  4025  //
  4026  // Expects asmbuf.evex to be properly initialized.
  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 // "ModR/M.reg" selector 4th bit.
  4038  		}
  4039  		if regrex[r.Reg]&RxrEvex != 0 {
  4040  			evexR = 0 // "ModR/M.reg" selector 5th bit.
  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  	// P0 = [R][X][B][R'][00][mm]
  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  		// 4bit-wide reg index.
  4064  		vexV = byte(reg[v.Reg]|(regrex[v.Reg]&Rxr)<<1) & 0xF
  4065  	}
  4066  	vexV ^= 0x0F
  4067  	// P1 = [W][vvvv][1][pp]
  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  			// When you request zeroing you must specify a mask register.
  4085  			// See issue 57952.
  4086  			ctxt.Diag("mask register must be specified for .Z instructions: %v", p)
  4087  		} else if k.Reg == REG_K0 {
  4088  			// The mask register must not be K0. That restriction is already
  4089  			// handled by the Yknot0 restriction in the opcode tables, so we
  4090  			// won't ever reach here. But put something sensible here just in case.
  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 // VSR selector 5th bit.
  4123  	}
  4124  	if k != nil {
  4125  		evexA = byte(reg[k.Reg])
  4126  	}
  4127  	// P2 = [z][L'L][b][V'][aaa]
  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  // Emit VEX prefix and opcode byte.
  4140  // The three addresses are the r/m, vvvv, and reg fields.
  4141  // The reg and rm arguments appear in the same order as the
  4142  // arguments to asmand, which typically follows the call to asmvex.
  4143  // The final two arguments are the VEX prefix (see encoding above)
  4144  // and the opcode byte.
  4145  // For details about vex prefix see:
  4146  // https://en.wikipedia.org/wiki/VEX_prefix#Technical_description
  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  		// Can use 2-byte encoding.
  4168  		ab.Put2(0xc5, byte(rexR<<5)^0x80|vexV<<3|vexWLP)
  4169  	} else {
  4170  		// Must use 3-byte encoding.
  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  // regIndex returns register index that fits in 5 bits.
  4180  //
  4181  //	R         : 3 bit | legacy instructions     | N/A
  4182  //	[R/V]EX.R : 1 bit | REX / VEX extension bit | Rxr
  4183  //	EVEX.R    : 1 bit | EVEX extension bit      | RxrEvex
  4184  //
  4185  // Examples:
  4186  //
  4187  //	REG_Z30 => 30
  4188  //	REG_X15 => 15
  4189  //	REG_R9  => 9
  4190  //	REG_AX  => 0
  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  // avx2gatherValid reports whether p satisfies AVX2 gather constraints.
  4199  // Reports errors via ctxt.
  4200  func avx2gatherValid(ctxt *obj.Link, p *obj.Prog) bool {
  4201  	// If any pair of the index, mask, or destination registers
  4202  	// are the same, illegal instruction trap (#UD) is triggered.
  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  // avx512gatherValid reports whether p satisfies AVX512 gather constraints.
  4215  // Reports errors via ctxt.
  4216  func avx512gatherValid(ctxt *obj.Link, p *obj.Prog) bool {
  4217  	// Illegal instruction trap (#UD) is triggered if the destination vector
  4218  	// register is the same as index vector in VSIB.
  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  	// Checks to warn about instruction/arguments combinations that
  4245  	// will unconditionally trigger illegal instruction trap (#UD).
  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  			// gathers need a 3rd arg. See issue 58822.
  4257  			ctxt.Diag("need a third arg for gather instruction: %v", p)
  4258  			return
  4259  		}
  4260  		// AVX512 gather requires explicit K mask.
  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  		// ytab matching is purely args-based,
  4299  		// but AVX512 suffixes like "Z" or "RU_SAE" will
  4300  		// add EVEX-only filter that will reject non-EVEX matches.
  4301  		//
  4302  		// Consider "VADDPD.BCST 2032(DX), X0, X0".
  4303  		// Without this rule, operands will lead to VEX-encoded form
  4304  		// and produce "c5b15813" encoding.
  4305  		if !yt.match(args) {
  4306  			// "xo" is always zero for VEX/EVEX encoded insts.
  4307  			z += int(yt.zoffset) + xo
  4308  		} else {
  4309  			if p.Scond != 0 && !evexZcase(yt.zcase) {
  4310  				// Do not signal error and continue to search
  4311  				// for matching EVEX-encoded form.
  4312  				z += int(yt.zoffset)
  4313  				continue
  4314  			}
  4315  
  4316  			switch o.prefix {
  4317  			case Px1: // first option valid only in 32-bit mode
  4318  				if ctxt.Arch.Family == sys.AMD64 && z == 0 {
  4319  					z += int(yt.zoffset) + xo
  4320  					continue
  4321  				}
  4322  			case Pq: // 16 bit escape and opcode escape
  4323  				ab.Put2(Pe, Pm)
  4324  
  4325  			case Pq3: // 16 bit escape and opcode escape + REX.W
  4326  				ab.rexflag |= Pw
  4327  				ab.Put2(Pe, Pm)
  4328  
  4329  			case Pq4: // 66 0F 38
  4330  				ab.Put3(0x66, 0x0F, 0x38)
  4331  
  4332  			case Pq4w: // 66 0F 38 + REX.W
  4333  				ab.rexflag |= Pw
  4334  				ab.Put3(0x66, 0x0F, 0x38)
  4335  
  4336  			case Pq5: // F3 0F 38
  4337  				ab.Put3(0xF3, 0x0F, 0x38)
  4338  
  4339  			case Pq5w: //  F3 0F 38 + REX.W
  4340  				ab.rexflag |= Pw
  4341  				ab.Put3(0xF3, 0x0F, 0x38)
  4342  
  4343  			case Pf2, // xmm opcode escape
  4344  				Pf3:
  4345  				ab.Put2(o.prefix, Pm)
  4346  
  4347  			case Pef3:
  4348  				ab.Put3(Pe, Pf3, Pm)
  4349  
  4350  			case Pfw: // xmm opcode escape + REX.W
  4351  				ab.rexflag |= Pw
  4352  				ab.Put2(Pf3, Pm)
  4353  
  4354  			case Pm: // opcode escape
  4355  				ab.Put1(Pm)
  4356  
  4357  			case Pe: // 16 bit escape
  4358  				ab.Put1(Pe)
  4359  
  4360  			case Pw: // 64-bit escape
  4361  				if ctxt.Arch.Family != sys.AMD64 {
  4362  					ctxt.Diag("asmins: illegal 64: %v", p)
  4363  				}
  4364  				ab.rexflag |= Pw
  4365  
  4366  			case Pw8: // 64-bit escape if z >= 8
  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: // botch
  4375  				if ctxt.Arch.Family != sys.AMD64 && (isbadbyte(&p.From) || isbadbyte(&p.To)) {
  4376  					goto bad
  4377  				}
  4378  				// NOTE(rsc): This is probably safe to do always,
  4379  				// but when enabled it chooses different encodings
  4380  				// than the old cmd/internal/obj/i386 code did,
  4381  				// which breaks our "same bits out" checks.
  4382  				// In particular, CMPB AX, $0 encodes as 80 f8 00
  4383  				// in the original obj/i386, and it would encode
  4384  				// (using a valid, shorter form) as 3c 00 if we enabled
  4385  				// the call to bytereg here.
  4386  				if ctxt.Arch.Family == sys.AMD64 {
  4387  					bytereg(&p.From, &p.Ft)
  4388  					bytereg(&p.To, &p.Tt)
  4389  				}
  4390  
  4391  			case P32: // 32 bit but illegal if 64-bit mode
  4392  				if ctxt.Arch.Family == sys.AMD64 {
  4393  					ctxt.Diag("asmins: illegal in 64-bit mode: %v", p)
  4394  				}
  4395  
  4396  			case Py: // 64-bit only, no prefix
  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: // 64-bit only if z < 1, no prefix
  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: // 64-bit only if z < 3, no prefix
  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) // leal
  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 { // sign extend
  4748  					ab.Put1(0xc7)
  4749  					ab.asmando(ctxt, cursym, p, &p.To, 0)
  4750  
  4751  					ab.PutInt32(int32(v)) // need all 8
  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  			// TODO: jump across functions needs reloc
  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  						// Note: R_CALL instead of R_PCREL. R_CALL is more permissive in that
  4884  						// it can point to a trampoline instead of the destination itself.
  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  				// Assumes q is in this function.
  4895  				// TODO: Check in input, preserve in brchain.
  4896  
  4897  				// Fill in backward jump now.
  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  				// Annotate target; will fill in later.
  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: // r,m - 2op
  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  				// NOTE: The systems listed here are the ones that use the "TLS initial exec" model,
  5071  				// where you load the TLS base register into a register and then index off that
  5072  				// register to access the actual TLS variables. Systems that allow direct TLS access
  5073  				// are handled in prefixof above and should not be listed here.
  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  						// NOTE: The systems listed here are the ones that use the "TLS initial exec" model,
  5081  						// where you load the TLS base register into a register and then index off that
  5082  						// register to access the actual TLS variables. Systems that allow direct TLS access
  5083  						// are handled in prefixof above and should not be listed here.
  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  								// Note that this is not generating the same insns as the other cases.
  5091  								//     MOV TLS, dst
  5092  								// becomes
  5093  								//     call __x86.get_pc_thunk.dst
  5094  								//     movl (gotpc + g@gotntpoff)(dst), dst
  5095  								// which is encoded as
  5096  								//     call __x86.get_pc_thunk.dst
  5097  								//     movq 0(dst), dst
  5098  								// and R_CALL & R_TLS_IE relocs. This all assumes the only tls variable we access
  5099  								// is g, which we can't check here, but will when we assemble the second
  5100  								// instruction.
  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  								// ELF TLS base is 0(GS).
  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, // GS
  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  						// Note that this is not generating the same insn as the other cases.
  5154  						//     MOV TLS, R_to
  5155  						// becomes
  5156  						//     movq g@gottpoff(%rip), R_to
  5157  						// which is encoded as
  5158  						//     movq 0(%rip), R_to
  5159  						// and a R_TLS_IE reloc. This all assumes the only tls variable we access
  5160  						// is g, which we can't check here, but will when we assemble the second
  5161  						// instruction.
  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: // TODO(rsc): Delete Hsolaris from list. Should not use this code. See progedit in obj6.c.
  5185  						// TLS base is 0(FS).
  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, // FS
  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  		// here, the assembly has failed.
  5209  		// if it's a byte instruction that has
  5210  		// unaddressable registers, try to
  5211  		// exchange registers and reissue the
  5212  		// instruction with the operands renamed.
  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  			// TODO(rsc): Use this code for x86-64 too. It has bug fixes not present in the amd64 code base.
  5221  			// For now, different to keep bit-for-bit compatibility.
  5222  			if ctxt.Arch.Family == sys.I386 {
  5223  				breg := byteswapreg(ctxt, &p.To)
  5224  				if breg != REG_AX {
  5225  					ab.Put1(0x87) // xchg lhs,bx
  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) // xchg lhs,bx
  5230  					ab.asmando(ctxt, cursym, p, &p.From, reg[breg])
  5231  				} else {
  5232  					ab.Put1(byte(0x90 + reg[z])) // xchg lsh,ax
  5233  					subreg(&pp, z, REG_AX)
  5234  					ab.doasm(ctxt, cursym, &pp)
  5235  					ab.Put1(byte(0x90 + reg[z])) // xchg lsh,ax
  5236  				}
  5237  				return
  5238  			}
  5239  
  5240  			if isax(&p.To) || p.To.Type == obj.TYPE_NONE {
  5241  				// We certainly don't want to exchange
  5242  				// with AX if the op is MUL or DIV.
  5243  				ab.Put1(0x87) // xchg lhs,bx
  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) // xchg lhs,bx
  5248  				ab.asmando(ctxt, cursym, p, &p.From, reg[REG_BX])
  5249  			} else {
  5250  				ab.Put1(byte(0x90 + reg[z])) // xchg lsh,ax
  5251  				subreg(&pp, z, REG_AX)
  5252  				ab.doasm(ctxt, cursym, &pp)
  5253  				ab.Put1(byte(0x90 + reg[z])) // xchg lsh,ax
  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  			// TODO(rsc): Use this code for x86-64 too. It has bug fixes not present in the amd64 code base.
  5261  			// For now, different to keep bit-for-bit compatibility.
  5262  			if ctxt.Arch.Family == sys.I386 {
  5263  				breg := byteswapreg(ctxt, &p.From)
  5264  				if breg != REG_AX {
  5265  					ab.Put1(0x87) //xchg rhs,bx
  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) // xchg rhs,bx
  5270  					ab.asmando(ctxt, cursym, p, &p.To, reg[breg])
  5271  				} else {
  5272  					ab.Put1(byte(0x90 + reg[z])) // xchg rsh,ax
  5273  					subreg(&pp, z, REG_AX)
  5274  					ab.doasm(ctxt, cursym, &pp)
  5275  					ab.Put1(byte(0x90 + reg[z])) // xchg rsh,ax
  5276  				}
  5277  				return
  5278  			}
  5279  
  5280  			if isax(&p.From) {
  5281  				ab.Put1(0x87) // xchg rhs,bx
  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) // xchg rhs,bx
  5286  				ab.asmando(ctxt, cursym, p, &p.To, reg[REG_BX])
  5287  			} else {
  5288  				ab.Put1(byte(0x90 + reg[z])) // xchg rsh,ax
  5289  				subreg(&pp, z, REG_AX)
  5290  				ab.doasm(ctxt, cursym, &pp)
  5291  				ab.Put1(byte(0x90 + reg[z])) // xchg rsh,ax
  5292  			}
  5293  			return
  5294  		}
  5295  	}
  5296  
  5297  	ctxt.Diag("%s: invalid instruction: %v", cursym.Name, p)
  5298  }
  5299  
  5300  // byteswapreg returns a byte-addressable register (AX, BX, CX, DX)
  5301  // which is not referenced in a.
  5302  // If a is empty, it returns BX to account for MULB-like instructions
  5303  // that might use DX and AX.
  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  		// as befits the whole approach of the architecture,
  5369  		// the rex prefix must appear before the first opcode byte
  5370  		// (and thus after any 66/67/f2/f3/26/2e/3e prefix bytes, but
  5371  		// before the 0f opcode escape!), or it might be ignored.
  5372  		// note that the handbook often misleadingly shows 66/f2/f3 in `opcode'.
  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  				// PC-relative addressing is relative to the end of the instruction,
  5399  				// but the relocations applied by the linker are relative to the end
  5400  				// of the relocation. Because immediate instruction
  5401  				// arguments can follow the PC-relative memory reference in the
  5402  				// instruction encoding, the two may not coincide. In this case,
  5403  				// adjust addend so that linker can keep relocating relative to the
  5404  				// end of the relocation.
  5405  				r.Add -= p.Pc + int64(n) - (int64(r.Off) + int64(r.Siz))
  5406  			} else if ctxt.Arch.Family == sys.I386 {
  5407  				// On 386 PC-relative addressing (for non-call/jmp instructions)
  5408  				// assumes that the previous instruction loaded the PC of the end
  5409  				// of that instruction into CX, so the adjustment is relative to
  5410  				// that.
  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  			// On 386, R_GOTPCREL makes the same assumptions as R_PCREL.
  5416  			r.Add += int64(r.Off) - p.Pc + int64(r.Siz)
  5417  		}
  5418  
  5419  	}
  5420  }
  5421  
  5422  // unpackOps4 extracts 4 operands from p.
  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  // unpackOps5 extracts 5 operands from p.
  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