github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/obj/arm64/asm7.go (about)

     1  // cmd/7l/asm.c, cmd/7l/asmout.c, cmd/7l/optab.c, cmd/7l/span.c, cmd/ld/sub.c, cmd/ld/mod.c, from Vita Nuova.
     2  // https://bitbucket.org/plan9-from-bell-labs/9-cc/src/master/
     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 arm64
    32  
    33  import (
    34  	"fmt"
    35  	"log"
    36  	"math"
    37  	"sort"
    38  	"strings"
    39  
    40  	"github.com/go-asm/go/cmd/obj"
    41  	"github.com/go-asm/go/cmd/objabi"
    42  )
    43  
    44  // ctxt7 holds state while assembling a single function.
    45  // Each function gets a fresh ctxt7.
    46  // This allows for multiple functions to be safely concurrently assembled.
    47  type ctxt7 struct {
    48  	ctxt       *obj.Link
    49  	newprog    obj.ProgAlloc
    50  	cursym     *obj.LSym
    51  	blitrl     *obj.Prog
    52  	elitrl     *obj.Prog
    53  	autosize   int32
    54  	extrasize  int32
    55  	instoffset int64
    56  	pc         int64
    57  	pool       struct {
    58  		start uint32
    59  		size  uint32
    60  	}
    61  }
    62  
    63  const (
    64  	funcAlign = 16
    65  )
    66  
    67  const (
    68  	REGFROM = 1
    69  )
    70  
    71  type Optab struct {
    72  	as    obj.As
    73  	a1    uint8 // Prog.From
    74  	a2    uint8 // 2nd source operand, Prog.Reg or Prog.RestArgs[XXX]
    75  	a3    uint8 // 3rd source operand, Prog.RestArgs[XXX]
    76  	a4    uint8 // Prog.To
    77  	a5    uint8 // 2nd destination operand, Prog.RegTo2 or Prog.RestArgs[XXX]
    78  	type_ int8
    79  	size_ int8 // the value of this field is not static, use the size() method to return the value
    80  	param int16
    81  	flag  int8
    82  	scond uint8
    83  }
    84  
    85  func IsAtomicInstruction(as obj.As) bool {
    86  	if _, ok := atomicLDADD[as]; ok {
    87  		return true
    88  	}
    89  	if _, ok := atomicSWP[as]; ok {
    90  		return true
    91  	}
    92  	return false
    93  }
    94  
    95  // known field values of an instruction.
    96  var atomicLDADD = map[obj.As]uint32{
    97  	ALDADDAD:  3<<30 | 0x1c5<<21 | 0x00<<10,
    98  	ALDADDAW:  2<<30 | 0x1c5<<21 | 0x00<<10,
    99  	ALDADDAH:  1<<30 | 0x1c5<<21 | 0x00<<10,
   100  	ALDADDAB:  0<<30 | 0x1c5<<21 | 0x00<<10,
   101  	ALDADDALD: 3<<30 | 0x1c7<<21 | 0x00<<10,
   102  	ALDADDALW: 2<<30 | 0x1c7<<21 | 0x00<<10,
   103  	ALDADDALH: 1<<30 | 0x1c7<<21 | 0x00<<10,
   104  	ALDADDALB: 0<<30 | 0x1c7<<21 | 0x00<<10,
   105  	ALDADDD:   3<<30 | 0x1c1<<21 | 0x00<<10,
   106  	ALDADDW:   2<<30 | 0x1c1<<21 | 0x00<<10,
   107  	ALDADDH:   1<<30 | 0x1c1<<21 | 0x00<<10,
   108  	ALDADDB:   0<<30 | 0x1c1<<21 | 0x00<<10,
   109  	ALDADDLD:  3<<30 | 0x1c3<<21 | 0x00<<10,
   110  	ALDADDLW:  2<<30 | 0x1c3<<21 | 0x00<<10,
   111  	ALDADDLH:  1<<30 | 0x1c3<<21 | 0x00<<10,
   112  	ALDADDLB:  0<<30 | 0x1c3<<21 | 0x00<<10,
   113  	ALDCLRAD:  3<<30 | 0x1c5<<21 | 0x04<<10,
   114  	ALDCLRAW:  2<<30 | 0x1c5<<21 | 0x04<<10,
   115  	ALDCLRAH:  1<<30 | 0x1c5<<21 | 0x04<<10,
   116  	ALDCLRAB:  0<<30 | 0x1c5<<21 | 0x04<<10,
   117  	ALDCLRALD: 3<<30 | 0x1c7<<21 | 0x04<<10,
   118  	ALDCLRALW: 2<<30 | 0x1c7<<21 | 0x04<<10,
   119  	ALDCLRALH: 1<<30 | 0x1c7<<21 | 0x04<<10,
   120  	ALDCLRALB: 0<<30 | 0x1c7<<21 | 0x04<<10,
   121  	ALDCLRD:   3<<30 | 0x1c1<<21 | 0x04<<10,
   122  	ALDCLRW:   2<<30 | 0x1c1<<21 | 0x04<<10,
   123  	ALDCLRH:   1<<30 | 0x1c1<<21 | 0x04<<10,
   124  	ALDCLRB:   0<<30 | 0x1c1<<21 | 0x04<<10,
   125  	ALDCLRLD:  3<<30 | 0x1c3<<21 | 0x04<<10,
   126  	ALDCLRLW:  2<<30 | 0x1c3<<21 | 0x04<<10,
   127  	ALDCLRLH:  1<<30 | 0x1c3<<21 | 0x04<<10,
   128  	ALDCLRLB:  0<<30 | 0x1c3<<21 | 0x04<<10,
   129  	ALDEORAD:  3<<30 | 0x1c5<<21 | 0x08<<10,
   130  	ALDEORAW:  2<<30 | 0x1c5<<21 | 0x08<<10,
   131  	ALDEORAH:  1<<30 | 0x1c5<<21 | 0x08<<10,
   132  	ALDEORAB:  0<<30 | 0x1c5<<21 | 0x08<<10,
   133  	ALDEORALD: 3<<30 | 0x1c7<<21 | 0x08<<10,
   134  	ALDEORALW: 2<<30 | 0x1c7<<21 | 0x08<<10,
   135  	ALDEORALH: 1<<30 | 0x1c7<<21 | 0x08<<10,
   136  	ALDEORALB: 0<<30 | 0x1c7<<21 | 0x08<<10,
   137  	ALDEORD:   3<<30 | 0x1c1<<21 | 0x08<<10,
   138  	ALDEORW:   2<<30 | 0x1c1<<21 | 0x08<<10,
   139  	ALDEORH:   1<<30 | 0x1c1<<21 | 0x08<<10,
   140  	ALDEORB:   0<<30 | 0x1c1<<21 | 0x08<<10,
   141  	ALDEORLD:  3<<30 | 0x1c3<<21 | 0x08<<10,
   142  	ALDEORLW:  2<<30 | 0x1c3<<21 | 0x08<<10,
   143  	ALDEORLH:  1<<30 | 0x1c3<<21 | 0x08<<10,
   144  	ALDEORLB:  0<<30 | 0x1c3<<21 | 0x08<<10,
   145  	ALDORAD:   3<<30 | 0x1c5<<21 | 0x0c<<10,
   146  	ALDORAW:   2<<30 | 0x1c5<<21 | 0x0c<<10,
   147  	ALDORAH:   1<<30 | 0x1c5<<21 | 0x0c<<10,
   148  	ALDORAB:   0<<30 | 0x1c5<<21 | 0x0c<<10,
   149  	ALDORALD:  3<<30 | 0x1c7<<21 | 0x0c<<10,
   150  	ALDORALW:  2<<30 | 0x1c7<<21 | 0x0c<<10,
   151  	ALDORALH:  1<<30 | 0x1c7<<21 | 0x0c<<10,
   152  	ALDORALB:  0<<30 | 0x1c7<<21 | 0x0c<<10,
   153  	ALDORD:    3<<30 | 0x1c1<<21 | 0x0c<<10,
   154  	ALDORW:    2<<30 | 0x1c1<<21 | 0x0c<<10,
   155  	ALDORH:    1<<30 | 0x1c1<<21 | 0x0c<<10,
   156  	ALDORB:    0<<30 | 0x1c1<<21 | 0x0c<<10,
   157  	ALDORLD:   3<<30 | 0x1c3<<21 | 0x0c<<10,
   158  	ALDORLW:   2<<30 | 0x1c3<<21 | 0x0c<<10,
   159  	ALDORLH:   1<<30 | 0x1c3<<21 | 0x0c<<10,
   160  	ALDORLB:   0<<30 | 0x1c3<<21 | 0x0c<<10,
   161  }
   162  
   163  var atomicSWP = map[obj.As]uint32{
   164  	ASWPAD:  3<<30 | 0x1c5<<21 | 0x20<<10,
   165  	ASWPAW:  2<<30 | 0x1c5<<21 | 0x20<<10,
   166  	ASWPAH:  1<<30 | 0x1c5<<21 | 0x20<<10,
   167  	ASWPAB:  0<<30 | 0x1c5<<21 | 0x20<<10,
   168  	ASWPALD: 3<<30 | 0x1c7<<21 | 0x20<<10,
   169  	ASWPALW: 2<<30 | 0x1c7<<21 | 0x20<<10,
   170  	ASWPALH: 1<<30 | 0x1c7<<21 | 0x20<<10,
   171  	ASWPALB: 0<<30 | 0x1c7<<21 | 0x20<<10,
   172  	ASWPD:   3<<30 | 0x1c1<<21 | 0x20<<10,
   173  	ASWPW:   2<<30 | 0x1c1<<21 | 0x20<<10,
   174  	ASWPH:   1<<30 | 0x1c1<<21 | 0x20<<10,
   175  	ASWPB:   0<<30 | 0x1c1<<21 | 0x20<<10,
   176  	ASWPLD:  3<<30 | 0x1c3<<21 | 0x20<<10,
   177  	ASWPLW:  2<<30 | 0x1c3<<21 | 0x20<<10,
   178  	ASWPLH:  1<<30 | 0x1c3<<21 | 0x20<<10,
   179  	ASWPLB:  0<<30 | 0x1c3<<21 | 0x20<<10,
   180  	ACASD:   3<<30 | 0x45<<21 | 0x1f<<10,
   181  	ACASW:   2<<30 | 0x45<<21 | 0x1f<<10,
   182  	ACASH:   1<<30 | 0x45<<21 | 0x1f<<10,
   183  	ACASB:   0<<30 | 0x45<<21 | 0x1f<<10,
   184  	ACASAD:  3<<30 | 0x47<<21 | 0x1f<<10,
   185  	ACASAW:  2<<30 | 0x47<<21 | 0x1f<<10,
   186  	ACASLD:  3<<30 | 0x45<<21 | 0x3f<<10,
   187  	ACASLW:  2<<30 | 0x45<<21 | 0x3f<<10,
   188  	ACASALD: 3<<30 | 0x47<<21 | 0x3f<<10,
   189  	ACASALW: 2<<30 | 0x47<<21 | 0x3f<<10,
   190  	ACASALH: 1<<30 | 0x47<<21 | 0x3f<<10,
   191  	ACASALB: 0<<30 | 0x47<<21 | 0x3f<<10,
   192  }
   193  var atomicCASP = map[obj.As]uint32{
   194  	ACASPD: 1<<30 | 0x41<<21 | 0x1f<<10,
   195  	ACASPW: 0<<30 | 0x41<<21 | 0x1f<<10,
   196  }
   197  
   198  var oprange [ALAST & obj.AMask][]Optab
   199  
   200  var xcmp [C_NCLASS][C_NCLASS]bool
   201  
   202  const (
   203  	S32     = 0 << 31
   204  	S64     = 1 << 31
   205  	Sbit    = 1 << 29
   206  	LSL0_32 = 2 << 13
   207  	LSL0_64 = 3 << 13
   208  )
   209  
   210  func OPDP2(x uint32) uint32 {
   211  	return 0<<30 | 0<<29 | 0xd6<<21 | x<<10
   212  }
   213  
   214  func OPDP3(sf uint32, op54 uint32, op31 uint32, o0 uint32) uint32 {
   215  	return sf<<31 | op54<<29 | 0x1B<<24 | op31<<21 | o0<<15
   216  }
   217  
   218  func OPBcc(x uint32) uint32 {
   219  	return 0x2A<<25 | 0<<24 | 0<<4 | x&15
   220  }
   221  
   222  func OPBLR(x uint32) uint32 {
   223  	/* x=0, JMP; 1, CALL; 2, RET */
   224  	return 0x6B<<25 | 0<<23 | x<<21 | 0x1F<<16 | 0<<10
   225  }
   226  
   227  func SYSOP(l uint32, op0 uint32, op1 uint32, crn uint32, crm uint32, op2 uint32, rt uint32) uint32 {
   228  	return 0x354<<22 | l<<21 | op0<<19 | op1<<16 | crn&15<<12 | crm&15<<8 | op2<<5 | rt
   229  }
   230  
   231  func SYSHINT(x uint32) uint32 {
   232  	return SYSOP(0, 0, 3, 2, 0, x, 0x1F)
   233  }
   234  
   235  func LDSTR(sz uint32, v uint32, opc uint32) uint32 {
   236  	return sz<<30 | 7<<27 | v<<26 | opc<<22
   237  }
   238  
   239  func LD2STR(o uint32) uint32 {
   240  	return o &^ (3 << 22)
   241  }
   242  
   243  func LDSTX(sz uint32, o2 uint32, l uint32, o1 uint32, o0 uint32) uint32 {
   244  	return sz<<30 | 0x8<<24 | o2<<23 | l<<22 | o1<<21 | o0<<15
   245  }
   246  
   247  func FPCMP(m uint32, s uint32, type_ uint32, op uint32, op2 uint32) uint32 {
   248  	return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<14 | 8<<10 | op2
   249  }
   250  
   251  func FPCCMP(m uint32, s uint32, type_ uint32, op uint32) uint32 {
   252  	return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | 1<<10 | op<<4
   253  }
   254  
   255  func FPOP1S(m uint32, s uint32, type_ uint32, op uint32) uint32 {
   256  	return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<15 | 0x10<<10
   257  }
   258  
   259  func FPOP2S(m uint32, s uint32, type_ uint32, op uint32) uint32 {
   260  	return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<12 | 2<<10
   261  }
   262  
   263  func FPOP3S(m uint32, s uint32, type_ uint32, op uint32, op2 uint32) uint32 {
   264  	return m<<31 | s<<29 | 0x1F<<24 | type_<<22 | op<<21 | op2<<15
   265  }
   266  
   267  func FPCVTI(sf uint32, s uint32, type_ uint32, rmode uint32, op uint32) uint32 {
   268  	return sf<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | rmode<<19 | op<<16 | 0<<10
   269  }
   270  
   271  func ADR(p uint32, o uint32, rt uint32) uint32 {
   272  	return p<<31 | (o&3)<<29 | 0x10<<24 | ((o>>2)&0x7FFFF)<<5 | rt&31
   273  }
   274  
   275  func OPBIT(x uint32) uint32 {
   276  	return 1<<30 | 0<<29 | 0xD6<<21 | 0<<16 | x<<10
   277  }
   278  
   279  func MOVCONST(d int64, s int, rt int) uint32 {
   280  	return uint32(((d>>uint(s*16))&0xFFFF)<<5) | uint32(s)&3<<21 | uint32(rt&31)
   281  }
   282  
   283  const (
   284  	// Optab.flag
   285  	LFROM        = 1 << iota // p.From uses constant pool
   286  	LTO                      // p.To uses constant pool
   287  	NOTUSETMP                // p expands to multiple instructions, but does NOT use REGTMP
   288  	BRANCH14BITS             // branch instruction encodes 14 bits
   289  	BRANCH19BITS             // branch instruction encodes 19 bits
   290  )
   291  
   292  var optab = []Optab{
   293  	/* struct Optab:
   294  	OPCODE, from, prog->reg, from3, to, to2, type,size,param,flag,scond */
   295  	{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, C_NONE, 0, 0, 0, 0, 0},
   296  
   297  	/* arithmetic operations */
   298  	{AADD, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   299  	{AADD, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   300  	{AADC, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   301  	{AADC, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   302  	{ANEG, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 25, 4, 0, 0, 0},
   303  	{ANEG, C_NONE, C_NONE, C_NONE, C_ZREG, C_NONE, 25, 4, 0, 0, 0},
   304  	{ANGC, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 17, 4, 0, 0, 0},
   305  	{ACMP, C_ZREG, C_ZREG, C_NONE, C_NONE, C_NONE, 1, 4, 0, 0, 0},
   306  	{AADD, C_ADDCON, C_RSP, C_NONE, C_RSP, C_NONE, 2, 4, 0, 0, 0},
   307  	{AADD, C_ADDCON, C_NONE, C_NONE, C_RSP, C_NONE, 2, 4, 0, 0, 0},
   308  	{ACMP, C_ADDCON, C_RSP, C_NONE, C_NONE, C_NONE, 2, 4, 0, 0, 0},
   309  	{AADD, C_MOVCON, C_RSP, C_NONE, C_RSP, C_NONE, 62, 8, 0, 0, 0},
   310  	{AADD, C_MOVCON, C_NONE, C_NONE, C_RSP, C_NONE, 62, 8, 0, 0, 0},
   311  	{ACMP, C_MOVCON, C_RSP, C_NONE, C_NONE, C_NONE, 62, 8, 0, 0, 0},
   312  	{AADD, C_BITCON, C_RSP, C_NONE, C_RSP, C_NONE, 62, 8, 0, 0, 0},
   313  	{AADD, C_BITCON, C_NONE, C_NONE, C_RSP, C_NONE, 62, 8, 0, 0, 0},
   314  	{ACMP, C_BITCON, C_RSP, C_NONE, C_NONE, C_NONE, 62, 8, 0, 0, 0},
   315  	{AADD, C_ADDCON2, C_RSP, C_NONE, C_RSP, C_NONE, 48, 8, 0, NOTUSETMP, 0},
   316  	{AADD, C_ADDCON2, C_NONE, C_NONE, C_RSP, C_NONE, 48, 8, 0, NOTUSETMP, 0},
   317  	{AADD, C_MOVCON2, C_RSP, C_NONE, C_RSP, C_NONE, 13, 12, 0, 0, 0},
   318  	{AADD, C_MOVCON2, C_NONE, C_NONE, C_RSP, C_NONE, 13, 12, 0, 0, 0},
   319  	{AADD, C_MOVCON3, C_RSP, C_NONE, C_RSP, C_NONE, 13, 16, 0, 0, 0},
   320  	{AADD, C_MOVCON3, C_NONE, C_NONE, C_RSP, C_NONE, 13, 16, 0, 0, 0},
   321  	{AADD, C_VCON, C_RSP, C_NONE, C_RSP, C_NONE, 13, 20, 0, 0, 0},
   322  	{AADD, C_VCON, C_NONE, C_NONE, C_RSP, C_NONE, 13, 20, 0, 0, 0},
   323  	{ACMP, C_MOVCON2, C_ZREG, C_NONE, C_NONE, C_NONE, 13, 12, 0, 0, 0},
   324  	{ACMP, C_MOVCON3, C_ZREG, C_NONE, C_NONE, C_NONE, 13, 16, 0, 0, 0},
   325  	{ACMP, C_VCON, C_ZREG, C_NONE, C_NONE, C_NONE, 13, 20, 0, 0, 0},
   326  	{AADD, C_SHIFT, C_ZREG, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
   327  	{AADD, C_SHIFT, C_NONE, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
   328  	{AMVN, C_SHIFT, C_NONE, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
   329  	{ACMP, C_SHIFT, C_ZREG, C_NONE, C_NONE, C_NONE, 3, 4, 0, 0, 0},
   330  	{ANEG, C_SHIFT, C_NONE, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
   331  	{AADD, C_ZREG, C_RSP, C_NONE, C_RSP, C_NONE, 27, 4, 0, 0, 0},
   332  	{AADD, C_ZREG, C_NONE, C_NONE, C_RSP, C_NONE, 27, 4, 0, 0, 0},
   333  	{ACMP, C_ZREG, C_RSP, C_NONE, C_NONE, C_NONE, 27, 4, 0, 0, 0},
   334  	{AADD, C_EXTREG, C_RSP, C_NONE, C_RSP, C_NONE, 27, 4, 0, 0, 0},
   335  	{AADD, C_EXTREG, C_NONE, C_NONE, C_RSP, C_NONE, 27, 4, 0, 0, 0},
   336  	{ACMP, C_EXTREG, C_RSP, C_NONE, C_NONE, C_NONE, 27, 4, 0, 0, 0},
   337  	{AADD, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   338  	{AADD, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   339  	{AMUL, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 15, 4, 0, 0, 0},
   340  	{AMUL, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 15, 4, 0, 0, 0},
   341  	{AMADD, C_ZREG, C_ZREG, C_ZREG, C_ZREG, C_NONE, 15, 4, 0, 0, 0},
   342  	{AREM, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 16, 8, 0, 0, 0},
   343  	{AREM, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 16, 8, 0, 0, 0},
   344  	{ASDIV, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   345  	{ASDIV, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   346  
   347  	{AFADDS, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 54, 4, 0, 0, 0},
   348  	{AFADDS, C_FREG, C_FREG, C_NONE, C_FREG, C_NONE, 54, 4, 0, 0, 0},
   349  	{AFMSUBD, C_FREG, C_FREG, C_FREG, C_FREG, C_NONE, 15, 4, 0, 0, 0},
   350  	{AFCMPS, C_FREG, C_FREG, C_NONE, C_NONE, C_NONE, 56, 4, 0, 0, 0},
   351  	{AFCMPS, C_FCON, C_FREG, C_NONE, C_NONE, C_NONE, 56, 4, 0, 0, 0},
   352  	{AVADDP, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 72, 4, 0, 0, 0},
   353  	{AVADD, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 72, 4, 0, 0, 0},
   354  	{AVADD, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 89, 4, 0, 0, 0},
   355  	{AVADD, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 89, 4, 0, 0, 0},
   356  	{AVADDV, C_ARNG, C_NONE, C_NONE, C_VREG, C_NONE, 85, 4, 0, 0, 0},
   357  
   358  	/* logical operations */
   359  	{AAND, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   360  	{AAND, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   361  	{AANDS, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   362  	{AANDS, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 1, 4, 0, 0, 0},
   363  	{ATST, C_ZREG, C_ZREG, C_NONE, C_NONE, C_NONE, 1, 4, 0, 0, 0},
   364  	{AAND, C_MBCON, C_ZREG, C_NONE, C_RSP, C_NONE, 53, 4, 0, 0, 0},
   365  	{AAND, C_MBCON, C_NONE, C_NONE, C_RSP, C_NONE, 53, 4, 0, 0, 0},
   366  	{AANDS, C_MBCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 53, 4, 0, 0, 0},
   367  	{AANDS, C_MBCON, C_NONE, C_NONE, C_ZREG, C_NONE, 53, 4, 0, 0, 0},
   368  	{ATST, C_MBCON, C_ZREG, C_NONE, C_NONE, C_NONE, 53, 4, 0, 0, 0},
   369  	{AAND, C_BITCON, C_ZREG, C_NONE, C_RSP, C_NONE, 53, 4, 0, 0, 0},
   370  	{AAND, C_BITCON, C_NONE, C_NONE, C_RSP, C_NONE, 53, 4, 0, 0, 0},
   371  	{AANDS, C_BITCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 53, 4, 0, 0, 0},
   372  	{AANDS, C_BITCON, C_NONE, C_NONE, C_ZREG, C_NONE, 53, 4, 0, 0, 0},
   373  	{ATST, C_BITCON, C_ZREG, C_NONE, C_NONE, C_NONE, 53, 4, 0, 0, 0},
   374  	{AAND, C_MOVCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 62, 8, 0, 0, 0},
   375  	{AAND, C_MOVCON, C_NONE, C_NONE, C_ZREG, C_NONE, 62, 8, 0, 0, 0},
   376  	{AANDS, C_MOVCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 62, 8, 0, 0, 0},
   377  	{AANDS, C_MOVCON, C_NONE, C_NONE, C_ZREG, C_NONE, 62, 8, 0, 0, 0},
   378  	{ATST, C_MOVCON, C_ZREG, C_NONE, C_NONE, C_NONE, 62, 8, 0, 0, 0},
   379  	{AAND, C_MOVCON2, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 12, 0, 0, 0},
   380  	{AAND, C_MOVCON2, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 12, 0, 0, 0},
   381  	{AAND, C_MOVCON3, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 16, 0, 0, 0},
   382  	{AAND, C_MOVCON3, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 16, 0, 0, 0},
   383  	{AAND, C_VCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 20, 0, 0, 0},
   384  	{AAND, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 20, 0, 0, 0},
   385  	{AANDS, C_MOVCON2, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 12, 0, 0, 0},
   386  	{AANDS, C_MOVCON2, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 12, 0, 0, 0},
   387  	{AANDS, C_MOVCON3, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 16, 0, 0, 0},
   388  	{AANDS, C_MOVCON3, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 16, 0, 0, 0},
   389  	{AANDS, C_VCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 28, 20, 0, 0, 0},
   390  	{AANDS, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 28, 20, 0, 0, 0},
   391  	{ATST, C_MOVCON2, C_ZREG, C_NONE, C_NONE, C_NONE, 28, 12, 0, 0, 0},
   392  	{ATST, C_MOVCON3, C_ZREG, C_NONE, C_NONE, C_NONE, 28, 16, 0, 0, 0},
   393  	{ATST, C_VCON, C_ZREG, C_NONE, C_NONE, C_NONE, 28, 20, 0, 0, 0},
   394  	{AAND, C_SHIFT, C_ZREG, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
   395  	{AAND, C_SHIFT, C_NONE, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
   396  	{AANDS, C_SHIFT, C_ZREG, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
   397  	{AANDS, C_SHIFT, C_NONE, C_NONE, C_ZREG, C_NONE, 3, 4, 0, 0, 0},
   398  	{ATST, C_SHIFT, C_ZREG, C_NONE, C_NONE, C_NONE, 3, 4, 0, 0, 0},
   399  	{AMOVD, C_RSP, C_NONE, C_NONE, C_RSP, C_NONE, 24, 4, 0, 0, 0},
   400  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 24, 4, 0, 0, 0},
   401  	{AMVN, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 24, 4, 0, 0, 0},
   402  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 45, 4, 0, 0, 0}, /* also MOVBU */
   403  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 45, 4, 0, 0, 0}, /* also MOVHU */
   404  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 45, 4, 0, 0, 0}, /* also MOVWU */
   405  	/* TODO: MVN C_SHIFT */
   406  
   407  	/* MOVs that become MOVK/MOVN/MOVZ/ADD/SUB/OR */
   408  	{AMOVW, C_MBCON, C_NONE, C_NONE, C_ZREG, C_NONE, 32, 4, 0, 0, 0},
   409  	{AMOVD, C_MBCON, C_NONE, C_NONE, C_ZREG, C_NONE, 32, 4, 0, 0, 0},
   410  	{AMOVW, C_MOVCON, C_NONE, C_NONE, C_ZREG, C_NONE, 32, 4, 0, 0, 0},
   411  	{AMOVD, C_MOVCON, C_NONE, C_NONE, C_ZREG, C_NONE, 32, 4, 0, 0, 0},
   412  	{AMOVW, C_BITCON, C_NONE, C_NONE, C_RSP, C_NONE, 32, 4, 0, 0, 0},
   413  	{AMOVD, C_BITCON, C_NONE, C_NONE, C_RSP, C_NONE, 32, 4, 0, 0, 0},
   414  	{AMOVW, C_MOVCON2, C_NONE, C_NONE, C_ZREG, C_NONE, 12, 8, 0, NOTUSETMP, 0},
   415  	{AMOVD, C_MOVCON2, C_NONE, C_NONE, C_ZREG, C_NONE, 12, 8, 0, NOTUSETMP, 0},
   416  	{AMOVD, C_MOVCON3, C_NONE, C_NONE, C_ZREG, C_NONE, 12, 12, 0, NOTUSETMP, 0},
   417  	{AMOVD, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 12, 16, 0, NOTUSETMP, 0},
   418  
   419  	{AMOVK, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 33, 4, 0, 0, 0},
   420  	{AMOVD, C_AACON, C_NONE, C_NONE, C_RSP, C_NONE, 4, 4, REGFROM, 0, 0},
   421  	{AMOVD, C_AACON2, C_NONE, C_NONE, C_RSP, C_NONE, 4, 8, REGFROM, NOTUSETMP, 0},
   422  
   423  	/* load long effective stack address (load int32 offset and add) */
   424  	{AMOVD, C_LACON, C_NONE, C_NONE, C_RSP, C_NONE, 34, 8, REGSP, LFROM, 0},
   425  
   426  	// Load a large constant into a vector register.
   427  	{AVMOVS, C_ADDR, C_NONE, C_NONE, C_VREG, C_NONE, 65, 12, 0, 0, 0},
   428  	{AVMOVD, C_ADDR, C_NONE, C_NONE, C_VREG, C_NONE, 65, 12, 0, 0, 0},
   429  	{AVMOVQ, C_ADDR, C_NONE, C_NONE, C_VREG, C_NONE, 65, 12, 0, 0, 0},
   430  
   431  	/* jump operations */
   432  	{AB, C_NONE, C_NONE, C_NONE, C_SBRA, C_NONE, 5, 4, 0, 0, 0},
   433  	{ABL, C_NONE, C_NONE, C_NONE, C_SBRA, C_NONE, 5, 4, 0, 0, 0},
   434  	{AB, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 6, 4, 0, 0, 0},
   435  	{ABL, C_NONE, C_NONE, C_NONE, C_ZREG, C_NONE, 6, 4, 0, 0, 0},
   436  	{ABL, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 6, 4, 0, 0, 0},
   437  	{obj.ARET, C_NONE, C_NONE, C_NONE, C_ZREG, C_NONE, 6, 4, 0, 0, 0},
   438  	{obj.ARET, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 6, 4, 0, 0, 0},
   439  	{ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, C_NONE, 7, 4, 0, BRANCH19BITS, 0},
   440  	{ACBZ, C_ZREG, C_NONE, C_NONE, C_SBRA, C_NONE, 39, 4, 0, BRANCH19BITS, 0},
   441  	{ATBZ, C_VCON, C_ZREG, C_NONE, C_SBRA, C_NONE, 40, 4, 0, BRANCH14BITS, 0},
   442  	{AERET, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0},
   443  
   444  	// get a PC-relative address
   445  	{AADRP, C_SBRA, C_NONE, C_NONE, C_ZREG, C_NONE, 60, 4, 0, 0, 0},
   446  	{AADR, C_SBRA, C_NONE, C_NONE, C_ZREG, C_NONE, 61, 4, 0, 0, 0},
   447  
   448  	{ACLREX, C_NONE, C_NONE, C_NONE, C_VCON, C_NONE, 38, 4, 0, 0, 0},
   449  	{ACLREX, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0, 0},
   450  	{ABFM, C_VCON, C_ZREG, C_VCON, C_ZREG, C_NONE, 42, 4, 0, 0, 0},
   451  	{ABFI, C_VCON, C_ZREG, C_VCON, C_ZREG, C_NONE, 43, 4, 0, 0, 0},
   452  	{AEXTR, C_VCON, C_ZREG, C_ZREG, C_ZREG, C_NONE, 44, 4, 0, 0, 0},
   453  	{ASXTB, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 45, 4, 0, 0, 0},
   454  	{ACLS, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 46, 4, 0, 0, 0},
   455  	{ALSL, C_VCON, C_ZREG, C_NONE, C_ZREG, C_NONE, 8, 4, 0, 0, 0},
   456  	{ALSL, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 8, 4, 0, 0, 0},
   457  	{ALSL, C_ZREG, C_NONE, C_NONE, C_ZREG, C_NONE, 9, 4, 0, 0, 0},
   458  	{ALSL, C_ZREG, C_ZREG, C_NONE, C_ZREG, C_NONE, 9, 4, 0, 0, 0},
   459  	{ASVC, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0},
   460  	{ASVC, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0},
   461  	{ADWORD, C_NONE, C_NONE, C_NONE, C_VCON, C_NONE, 11, 8, 0, NOTUSETMP, 0},
   462  	{ADWORD, C_NONE, C_NONE, C_NONE, C_LEXT, C_NONE, 11, 8, 0, NOTUSETMP, 0},
   463  	{ADWORD, C_NONE, C_NONE, C_NONE, C_ADDR, C_NONE, 11, 8, 0, NOTUSETMP, 0},
   464  	{ADWORD, C_NONE, C_NONE, C_NONE, C_LACON, C_NONE, 11, 8, 0, NOTUSETMP, 0},
   465  	{AWORD, C_NONE, C_NONE, C_NONE, C_LCON, C_NONE, 14, 4, 0, 0, 0},
   466  	{AWORD, C_NONE, C_NONE, C_NONE, C_LEXT, C_NONE, 14, 4, 0, 0, 0},
   467  	{AWORD, C_NONE, C_NONE, C_NONE, C_ADDR, C_NONE, 14, 4, 0, 0, 0},
   468  	{AMOVW, C_VCONADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 68, 8, 0, NOTUSETMP, 0},
   469  	{AMOVD, C_VCONADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 68, 8, 0, NOTUSETMP, 0},
   470  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
   471  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
   472  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
   473  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
   474  	{AMOVB, C_ADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 65, 12, 0, 0, 0},
   475  	{AMOVH, C_ADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 65, 12, 0, 0, 0},
   476  	{AMOVW, C_ADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 65, 12, 0, 0, 0},
   477  	{AMOVD, C_ADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 65, 12, 0, 0, 0},
   478  	{AMOVD, C_GOTADDR, C_NONE, C_NONE, C_ZREG, C_NONE, 71, 8, 0, 0, 0},
   479  	{AMOVD, C_TLS_LE, C_NONE, C_NONE, C_ZREG, C_NONE, 69, 4, 0, 0, 0},
   480  	{AMOVD, C_TLS_IE, C_NONE, C_NONE, C_ZREG, C_NONE, 70, 8, 0, 0, 0},
   481  
   482  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
   483  	{AFMOVS, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 65, 12, 0, 0, 0},
   484  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 64, 12, 0, 0, 0},
   485  	{AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 65, 12, 0, 0, 0},
   486  	{AFMOVS, C_FCON, C_NONE, C_NONE, C_FREG, C_NONE, 55, 4, 0, 0, 0},
   487  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 54, 4, 0, 0, 0},
   488  	{AFMOVD, C_FCON, C_NONE, C_NONE, C_FREG, C_NONE, 55, 4, 0, 0, 0},
   489  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 54, 4, 0, 0, 0},
   490  	{AFMOVS, C_ZREG, C_NONE, C_NONE, C_FREG, C_NONE, 29, 4, 0, 0, 0},
   491  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_ZREG, C_NONE, 29, 4, 0, 0, 0},
   492  	{AFMOVD, C_ZREG, C_NONE, C_NONE, C_FREG, C_NONE, 29, 4, 0, 0, 0},
   493  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_ZREG, C_NONE, 29, 4, 0, 0, 0},
   494  	{AFCVTZSD, C_FREG, C_NONE, C_NONE, C_ZREG, C_NONE, 29, 4, 0, 0, 0},
   495  	{ASCVTFD, C_ZREG, C_NONE, C_NONE, C_FREG, C_NONE, 29, 4, 0, 0, 0},
   496  	{AFCVTSD, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 29, 4, 0, 0, 0},
   497  	{AVMOV, C_ELEM, C_NONE, C_NONE, C_ZREG, C_NONE, 73, 4, 0, 0, 0},
   498  	{AVMOV, C_ELEM, C_NONE, C_NONE, C_ELEM, C_NONE, 92, 4, 0, 0, 0},
   499  	{AVMOV, C_ELEM, C_NONE, C_NONE, C_VREG, C_NONE, 80, 4, 0, 0, 0},
   500  	{AVMOV, C_ZREG, C_NONE, C_NONE, C_ARNG, C_NONE, 82, 4, 0, 0, 0},
   501  	{AVMOV, C_ZREG, C_NONE, C_NONE, C_ELEM, C_NONE, 78, 4, 0, 0, 0},
   502  	{AVMOV, C_ARNG, C_NONE, C_NONE, C_ARNG, C_NONE, 83, 4, 0, 0, 0},
   503  	{AVDUP, C_ELEM, C_NONE, C_NONE, C_ARNG, C_NONE, 79, 4, 0, 0, 0},
   504  	{AVDUP, C_ELEM, C_NONE, C_NONE, C_VREG, C_NONE, 80, 4, 0, 0, 0},
   505  	{AVDUP, C_ZREG, C_NONE, C_NONE, C_ARNG, C_NONE, 82, 4, 0, 0, 0},
   506  	{AVMOVI, C_ADDCON, C_NONE, C_NONE, C_ARNG, C_NONE, 86, 4, 0, 0, 0},
   507  	{AVFMLA, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 72, 4, 0, 0, 0},
   508  	{AVEXT, C_VCON, C_ARNG, C_ARNG, C_ARNG, C_NONE, 94, 4, 0, 0, 0},
   509  	{AVTBL, C_ARNG, C_NONE, C_LIST, C_ARNG, C_NONE, 100, 4, 0, 0, 0},
   510  	{AVUSHR, C_VCON, C_ARNG, C_NONE, C_ARNG, C_NONE, 95, 4, 0, 0, 0},
   511  	{AVZIP1, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 72, 4, 0, 0, 0},
   512  	{AVUSHLL, C_VCON, C_ARNG, C_NONE, C_ARNG, C_NONE, 102, 4, 0, 0, 0},
   513  	{AVUXTL, C_ARNG, C_NONE, C_NONE, C_ARNG, C_NONE, 102, 4, 0, 0, 0},
   514  	{AVUADDW, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 105, 4, 0, 0, 0},
   515  
   516  	/* conditional operations */
   517  	{ACSEL, C_COND, C_ZREG, C_ZREG, C_ZREG, C_NONE, 18, 4, 0, 0, 0},
   518  	{ACINC, C_COND, C_ZREG, C_NONE, C_ZREG, C_NONE, 18, 4, 0, 0, 0},
   519  	{ACSET, C_COND, C_NONE, C_NONE, C_ZREG, C_NONE, 18, 4, 0, 0, 0},
   520  	{AFCSELD, C_COND, C_FREG, C_FREG, C_FREG, C_NONE, 18, 4, 0, 0, 0},
   521  	{ACCMN, C_COND, C_ZREG, C_ZREG, C_VCON, C_NONE, 19, 4, 0, 0, 0},
   522  	{ACCMN, C_COND, C_ZREG, C_VCON, C_VCON, C_NONE, 19, 4, 0, 0, 0},
   523  	{AFCCMPS, C_COND, C_FREG, C_FREG, C_VCON, C_NONE, 57, 4, 0, 0, 0},
   524  
   525  	/* scaled 12-bit unsigned displacement store */
   526  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_UAUTO4K, C_NONE, 20, 4, REGSP, 0, 0},
   527  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_UOREG4K, C_NONE, 20, 4, 0, 0, 0},
   528  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_UAUTO8K, C_NONE, 20, 4, REGSP, 0, 0},
   529  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_UOREG8K, C_NONE, 20, 4, 0, 0, 0},
   530  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_UAUTO16K, C_NONE, 20, 4, REGSP, 0, 0},
   531  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_UOREG16K, C_NONE, 20, 4, 0, 0, 0},
   532  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_UAUTO32K, C_NONE, 20, 4, REGSP, 0, 0},
   533  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_UOREG32K, C_NONE, 20, 4, 0, 0, 0},
   534  
   535  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_UAUTO16K, C_NONE, 20, 4, REGSP, 0, 0},
   536  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_UOREG16K, C_NONE, 20, 4, 0, 0, 0},
   537  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_UAUTO32K, C_NONE, 20, 4, REGSP, 0, 0},
   538  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_UOREG32K, C_NONE, 20, 4, 0, 0, 0},
   539  	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_UAUTO64K, C_NONE, 20, 4, REGSP, 0, 0},
   540  	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_UOREG64K, C_NONE, 20, 4, 0, 0, 0},
   541  
   542  	/* unscaled 9-bit signed displacement store */
   543  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
   544  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
   545  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
   546  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
   547  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
   548  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
   549  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
   550  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
   551  
   552  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
   553  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
   554  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
   555  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
   556  	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_NSAUTO, C_NONE, 20, 4, REGSP, 0, 0},
   557  	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_NSOREG, C_NONE, 20, 4, 0, 0, 0},
   558  
   559  	/* scaled 12-bit unsigned displacement load */
   560  	{AMOVB, C_UAUTO4K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
   561  	{AMOVB, C_UOREG4K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
   562  	{AMOVH, C_UAUTO8K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
   563  	{AMOVH, C_UOREG8K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
   564  	{AMOVW, C_UAUTO16K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
   565  	{AMOVW, C_UOREG16K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
   566  	{AMOVD, C_UAUTO32K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
   567  	{AMOVD, C_UOREG32K, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
   568  
   569  	{AFMOVS, C_UAUTO16K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
   570  	{AFMOVS, C_UOREG16K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
   571  	{AFMOVD, C_UAUTO32K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
   572  	{AFMOVD, C_UOREG32K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
   573  	{AFMOVQ, C_UAUTO64K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
   574  	{AFMOVQ, C_UOREG64K, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
   575  
   576  	/* unscaled 9-bit signed displacement load */
   577  	{AMOVB, C_NSAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
   578  	{AMOVB, C_NSOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
   579  	{AMOVH, C_NSAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
   580  	{AMOVH, C_NSOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
   581  	{AMOVW, C_NSAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
   582  	{AMOVW, C_NSOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
   583  	{AMOVD, C_NSAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, REGSP, 0, 0},
   584  	{AMOVD, C_NSOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 21, 4, 0, 0, 0},
   585  
   586  	{AFMOVS, C_NSAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
   587  	{AFMOVS, C_NSOREG, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
   588  	{AFMOVD, C_NSAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
   589  	{AFMOVD, C_NSOREG, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
   590  	{AFMOVQ, C_NSAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, REGSP, 0, 0},
   591  	{AFMOVQ, C_NSOREG, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0, 0},
   592  
   593  	/* long displacement store */
   594  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
   595  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
   596  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
   597  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
   598  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
   599  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
   600  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
   601  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
   602  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
   603  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
   604  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
   605  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
   606  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
   607  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
   608  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
   609  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
   610  
   611  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
   612  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
   613  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
   614  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
   615  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
   616  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
   617  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
   618  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
   619  	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 30, 8, REGSP, 0, 0},
   620  	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 30, 8, REGSP, LTO, 0},
   621  	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 30, 8, 0, 0, 0},
   622  	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 30, 8, 0, LTO, 0},
   623  
   624  	/* long displacement load */
   625  	{AMOVB, C_LAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, 0, 0},
   626  	{AMOVB, C_LAUTOPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, LFROM, 0},
   627  	{AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, 0, 0},
   628  	{AMOVB, C_LOREGPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, LFROM, 0},
   629  	{AMOVH, C_LAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, 0, 0},
   630  	{AMOVH, C_LAUTOPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, LFROM, 0},
   631  	{AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, 0, 0},
   632  	{AMOVH, C_LOREGPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, LFROM, 0},
   633  	{AMOVW, C_LAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, 0, 0},
   634  	{AMOVW, C_LAUTOPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, LFROM, 0},
   635  	{AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, 0, 0},
   636  	{AMOVW, C_LOREGPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, LFROM, 0},
   637  	{AMOVD, C_LAUTO, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, 0, 0},
   638  	{AMOVD, C_LAUTOPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, REGSP, LFROM, 0},
   639  	{AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, 0, 0},
   640  	{AMOVD, C_LOREGPOOL, C_NONE, C_NONE, C_ZREG, C_NONE, 31, 8, 0, LFROM, 0},
   641  
   642  	{AFMOVS, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, 0, 0},
   643  	{AFMOVS, C_LAUTOPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, LFROM, 0},
   644  	{AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, 0, 0},
   645  	{AFMOVS, C_LOREGPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, LFROM, 0},
   646  	{AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, 0, 0},
   647  	{AFMOVD, C_LAUTOPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, LFROM, 0},
   648  	{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, 0, 0},
   649  	{AFMOVD, C_LOREGPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, LFROM, 0},
   650  	{AFMOVQ, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, 0, 0},
   651  	{AFMOVQ, C_LAUTOPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, REGSP, LFROM, 0},
   652  	{AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, 0, 0},
   653  	{AFMOVQ, C_LOREGPOOL, C_NONE, C_NONE, C_FREG, C_NONE, 31, 8, 0, LFROM, 0},
   654  
   655  	/* pre/post-indexed load (unscaled, signed 9-bit offset) */
   656  	{AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPOST},
   657  	{AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPOST},
   658  	{AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPOST},
   659  	{AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPOST},
   660  	{AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPOST},
   661  	{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPOST},
   662  	{AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPOST},
   663  
   664  	{AMOVD, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPRE},
   665  	{AMOVW, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPRE},
   666  	{AMOVH, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPRE},
   667  	{AMOVB, C_LOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 22, 4, 0, 0, C_XPRE},
   668  	{AFMOVS, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPRE},
   669  	{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPRE},
   670  	{AFMOVQ, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 22, 4, 0, 0, C_XPRE},
   671  
   672  	/* pre/post-indexed store (unscaled, signed 9-bit offset) */
   673  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
   674  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
   675  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
   676  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
   677  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
   678  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
   679  	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPOST},
   680  
   681  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
   682  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
   683  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
   684  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
   685  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
   686  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
   687  	{AFMOVQ, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 23, 4, 0, 0, C_XPRE},
   688  
   689  	/* load with shifted or extended register offset */
   690  	{AMOVD, C_ROFF, C_NONE, C_NONE, C_ZREG, C_NONE, 98, 4, 0, 0, 0},
   691  	{AMOVW, C_ROFF, C_NONE, C_NONE, C_ZREG, C_NONE, 98, 4, 0, 0, 0},
   692  	{AMOVH, C_ROFF, C_NONE, C_NONE, C_ZREG, C_NONE, 98, 4, 0, 0, 0},
   693  	{AMOVB, C_ROFF, C_NONE, C_NONE, C_ZREG, C_NONE, 98, 4, 0, 0, 0},
   694  	{AFMOVS, C_ROFF, C_NONE, C_NONE, C_FREG, C_NONE, 98, 4, 0, 0, 0},
   695  	{AFMOVD, C_ROFF, C_NONE, C_NONE, C_FREG, C_NONE, 98, 4, 0, 0, 0},
   696  
   697  	/* store with extended register offset */
   698  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
   699  	{AMOVW, C_ZREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
   700  	{AMOVH, C_ZREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
   701  	{AMOVB, C_ZREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
   702  	{AFMOVS, C_FREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
   703  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_ROFF, C_NONE, 99, 4, 0, 0, 0},
   704  
   705  	/* pre/post-indexed/signed-offset load/store register pair
   706  	   (unscaled, signed 10-bit quad-aligned and long offset).
   707  	The pre/post-indexed format only supports OREG cases because
   708  	the RSP and pseudo registers are not allowed to be modified
   709  	in this way. */
   710  	{AFLDPQ, C_NQAUTO_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
   711  	{AFLDPQ, C_PQAUTO_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
   712  	{AFLDPQ, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
   713  	{AFLDPQ, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
   714  	{AFLDPQ, C_LAUTO, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, 0, 0},
   715  	{AFLDPQ, C_LAUTOPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, LFROM, 0},
   716  	{AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
   717  	{AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
   718  	{AFLDPQ, C_NQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
   719  	{AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
   720  	{AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
   721  	{AFLDPQ, C_PQOREG_16, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
   722  	{AFLDPQ, C_UOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
   723  	{AFLDPQ, C_NOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
   724  	{AFLDPQ, C_LOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, 0, 0},
   725  	{AFLDPQ, C_LOREGPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, LFROM, 0},
   726  	{AFLDPQ, C_ADDR, C_NONE, C_NONE, C_PAIR, C_NONE, 88, 12, 0, 0, 0},
   727  
   728  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQAUTO_16, C_NONE, 67, 4, REGSP, 0, 0},
   729  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQAUTO_16, C_NONE, 67, 4, REGSP, 0, 0},
   730  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
   731  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
   732  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LAUTO, C_NONE, 77, 12, REGSP, 0, 0},
   733  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 77, 12, REGSP, LTO, 0},
   734  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, C_NONE, 67, 4, 0, 0, 0},
   735  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, C_NONE, 67, 4, 0, 0, C_XPRE},
   736  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NQOREG_16, C_NONE, 67, 4, 0, 0, C_XPOST},
   737  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, C_NONE, 67, 4, 0, 0, 0},
   738  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, C_NONE, 67, 4, 0, 0, C_XPRE},
   739  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_PQOREG_16, C_NONE, 67, 4, 0, 0, C_XPOST},
   740  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_UOREG4K, C_NONE, 76, 8, 0, 0, 0},
   741  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_NOREG4K, C_NONE, 76, 8, 0, 0, 0},
   742  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LOREG, C_NONE, 77, 12, 0, 0, 0},
   743  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 77, 12, 0, LTO, 0},
   744  	{AFSTPQ, C_PAIR, C_NONE, C_NONE, C_ADDR, C_NONE, 87, 12, 0, 0, 0},
   745  
   746  	{ALDP, C_NPAUTO, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
   747  	{ALDP, C_PPAUTO, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
   748  	{ALDP, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
   749  	{ALDP, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
   750  	{ALDP, C_LAUTO, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, 0, 0},
   751  	{ALDP, C_LAUTOPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, LFROM, 0},
   752  	{ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
   753  	{ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
   754  	{ALDP, C_NPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
   755  	{ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
   756  	{ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
   757  	{ALDP, C_PPOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
   758  	{ALDP, C_UOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
   759  	{ALDP, C_NOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
   760  	{ALDP, C_LOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, 0, 0},
   761  	{ALDP, C_LOREGPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, LFROM, 0},
   762  	{ALDP, C_ADDR, C_NONE, C_NONE, C_PAIR, C_NONE, 88, 12, 0, 0, 0},
   763  
   764  	{ASTP, C_PAIR, C_NONE, C_NONE, C_NPAUTO, C_NONE, 67, 4, REGSP, 0, 0},
   765  	{ASTP, C_PAIR, C_NONE, C_NONE, C_PPAUTO, C_NONE, 67, 4, REGSP, 0, 0},
   766  	{ASTP, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
   767  	{ASTP, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
   768  	{ASTP, C_PAIR, C_NONE, C_NONE, C_LAUTO, C_NONE, 77, 12, REGSP, 0, 0},
   769  	{ASTP, C_PAIR, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 77, 12, REGSP, LTO, 0},
   770  	{ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, C_NONE, 67, 4, 0, 0, 0},
   771  	{ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, C_NONE, 67, 4, 0, 0, C_XPRE},
   772  	{ASTP, C_PAIR, C_NONE, C_NONE, C_NPOREG, C_NONE, 67, 4, 0, 0, C_XPOST},
   773  	{ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, C_NONE, 67, 4, 0, 0, 0},
   774  	{ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, C_NONE, 67, 4, 0, 0, C_XPRE},
   775  	{ASTP, C_PAIR, C_NONE, C_NONE, C_PPOREG, C_NONE, 67, 4, 0, 0, C_XPOST},
   776  	{ASTP, C_PAIR, C_NONE, C_NONE, C_UOREG4K, C_NONE, 76, 8, 0, 0, 0},
   777  	{ASTP, C_PAIR, C_NONE, C_NONE, C_NOREG4K, C_NONE, 76, 8, 0, 0, 0},
   778  	{ASTP, C_PAIR, C_NONE, C_NONE, C_LOREG, C_NONE, 77, 12, 0, 0, 0},
   779  	{ASTP, C_PAIR, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 77, 12, 0, LTO, 0},
   780  	{ASTP, C_PAIR, C_NONE, C_NONE, C_ADDR, C_NONE, 87, 12, 0, 0, 0},
   781  
   782  	// differ from LDP/STP for C_NSAUTO_4/C_PSAUTO_4/C_NSOREG_4/C_PSOREG_4
   783  	{ALDPW, C_NSAUTO_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
   784  	{ALDPW, C_PSAUTO_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, REGSP, 0, 0},
   785  	{ALDPW, C_UAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
   786  	{ALDPW, C_NAUTO4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, REGSP, 0, 0},
   787  	{ALDPW, C_LAUTO, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, 0, 0},
   788  	{ALDPW, C_LAUTOPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, REGSP, LFROM, 0},
   789  	{ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
   790  	{ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
   791  	{ALDPW, C_NSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
   792  	{ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, 0},
   793  	{ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPRE},
   794  	{ALDPW, C_PSOREG_4, C_NONE, C_NONE, C_PAIR, C_NONE, 66, 4, 0, 0, C_XPOST},
   795  	{ALDPW, C_UOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
   796  	{ALDPW, C_NOREG4K, C_NONE, C_NONE, C_PAIR, C_NONE, 74, 8, 0, 0, 0},
   797  	{ALDPW, C_LOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, 0, 0},
   798  	{ALDPW, C_LOREGPOOL, C_NONE, C_NONE, C_PAIR, C_NONE, 75, 12, 0, LFROM, 0},
   799  	{ALDPW, C_ADDR, C_NONE, C_NONE, C_PAIR, C_NONE, 88, 12, 0, 0, 0},
   800  
   801  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NSAUTO_4, C_NONE, 67, 4, REGSP, 0, 0},
   802  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_PSAUTO_4, C_NONE, 67, 4, REGSP, 0, 0},
   803  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_UAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
   804  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NAUTO4K, C_NONE, 76, 8, REGSP, 0, 0},
   805  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LAUTO, C_NONE, 77, 12, REGSP, 0, 0},
   806  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LAUTOPOOL, C_NONE, 77, 12, REGSP, LTO, 0},
   807  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, C_NONE, 67, 4, 0, 0, 0},
   808  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, C_NONE, 67, 4, 0, 0, C_XPRE},
   809  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NSOREG_4, C_NONE, 67, 4, 0, 0, C_XPOST},
   810  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, C_NONE, 67, 4, 0, 0, 0},
   811  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, C_NONE, 67, 4, 0, 0, C_XPRE},
   812  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_PSOREG_4, C_NONE, 67, 4, 0, 0, C_XPOST},
   813  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_UOREG4K, C_NONE, 76, 8, 0, 0, 0},
   814  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_NOREG4K, C_NONE, 76, 8, 0, 0, 0},
   815  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LOREG, C_NONE, 77, 12, 0, 0, 0},
   816  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_LOREGPOOL, C_NONE, 77, 12, 0, LTO, 0},
   817  	{ASTPW, C_PAIR, C_NONE, C_NONE, C_ADDR, C_NONE, 87, 12, 0, 0, 0},
   818  
   819  	{ASWPD, C_ZREG, C_NONE, C_NONE, C_ZOREG, C_ZREG, 47, 4, 0, 0, 0},
   820  	{ASWPD, C_ZREG, C_NONE, C_NONE, C_ZAUTO, C_ZREG, 47, 4, REGSP, 0, 0},
   821  	{ACASPD, C_PAIR, C_NONE, C_NONE, C_ZOREG, C_PAIR, 106, 4, 0, 0, 0},
   822  	{ACASPD, C_PAIR, C_NONE, C_NONE, C_ZAUTO, C_PAIR, 106, 4, REGSP, 0, 0},
   823  	{ALDAR, C_ZOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 58, 4, 0, 0, 0},
   824  	{ALDXR, C_ZOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 58, 4, 0, 0, 0},
   825  	{ALDAXR, C_ZOREG, C_NONE, C_NONE, C_ZREG, C_NONE, 58, 4, 0, 0, 0},
   826  	{ALDXP, C_ZOREG, C_NONE, C_NONE, C_PAIR, C_NONE, 58, 4, 0, 0, 0},
   827  	{ASTLR, C_ZREG, C_NONE, C_NONE, C_ZOREG, C_NONE, 59, 4, 0, 0, 0},
   828  	{ASTXR, C_ZREG, C_NONE, C_NONE, C_ZOREG, C_ZREG, 59, 4, 0, 0, 0},
   829  	{ASTLXR, C_ZREG, C_NONE, C_NONE, C_ZOREG, C_ZREG, 59, 4, 0, 0, 0},
   830  	{ASTXP, C_PAIR, C_NONE, C_NONE, C_ZOREG, C_ZREG, 59, 4, 0, 0, 0},
   831  
   832  	/* VLD[1-4]/VST[1-4] */
   833  	{AVLD1, C_ZOREG, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, 0},
   834  	{AVLD1, C_LOREG, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, C_XPOST},
   835  	{AVLD1, C_ROFF, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, C_XPOST},
   836  	{AVLD1R, C_ZOREG, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, 0},
   837  	{AVLD1R, C_LOREG, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, C_XPOST},
   838  	{AVLD1R, C_ROFF, C_NONE, C_NONE, C_LIST, C_NONE, 81, 4, 0, 0, C_XPOST},
   839  	{AVLD1, C_LOREG, C_NONE, C_NONE, C_ELEM, C_NONE, 97, 4, 0, 0, C_XPOST},
   840  	{AVLD1, C_ROFF, C_NONE, C_NONE, C_ELEM, C_NONE, 97, 4, 0, 0, C_XPOST},
   841  	{AVLD1, C_LOREG, C_NONE, C_NONE, C_ELEM, C_NONE, 97, 4, 0, 0, 0},
   842  	{AVST1, C_LIST, C_NONE, C_NONE, C_ZOREG, C_NONE, 84, 4, 0, 0, 0},
   843  	{AVST1, C_LIST, C_NONE, C_NONE, C_LOREG, C_NONE, 84, 4, 0, 0, C_XPOST},
   844  	{AVST1, C_LIST, C_NONE, C_NONE, C_ROFF, C_NONE, 84, 4, 0, 0, C_XPOST},
   845  	{AVST2, C_LIST, C_NONE, C_NONE, C_ZOREG, C_NONE, 84, 4, 0, 0, 0},
   846  	{AVST2, C_LIST, C_NONE, C_NONE, C_LOREG, C_NONE, 84, 4, 0, 0, C_XPOST},
   847  	{AVST2, C_LIST, C_NONE, C_NONE, C_ROFF, C_NONE, 84, 4, 0, 0, C_XPOST},
   848  	{AVST3, C_LIST, C_NONE, C_NONE, C_ZOREG, C_NONE, 84, 4, 0, 0, 0},
   849  	{AVST3, C_LIST, C_NONE, C_NONE, C_LOREG, C_NONE, 84, 4, 0, 0, C_XPOST},
   850  	{AVST3, C_LIST, C_NONE, C_NONE, C_ROFF, C_NONE, 84, 4, 0, 0, C_XPOST},
   851  	{AVST4, C_LIST, C_NONE, C_NONE, C_ZOREG, C_NONE, 84, 4, 0, 0, 0},
   852  	{AVST4, C_LIST, C_NONE, C_NONE, C_LOREG, C_NONE, 84, 4, 0, 0, C_XPOST},
   853  	{AVST4, C_LIST, C_NONE, C_NONE, C_ROFF, C_NONE, 84, 4, 0, 0, C_XPOST},
   854  	{AVST1, C_ELEM, C_NONE, C_NONE, C_LOREG, C_NONE, 96, 4, 0, 0, C_XPOST},
   855  	{AVST1, C_ELEM, C_NONE, C_NONE, C_ROFF, C_NONE, 96, 4, 0, 0, C_XPOST},
   856  	{AVST1, C_ELEM, C_NONE, C_NONE, C_LOREG, C_NONE, 96, 4, 0, 0, 0},
   857  
   858  	/* special */
   859  	{AMOVD, C_SPR, C_NONE, C_NONE, C_ZREG, C_NONE, 35, 4, 0, 0, 0},
   860  	{AMRS, C_SPR, C_NONE, C_NONE, C_ZREG, C_NONE, 35, 4, 0, 0, 0},
   861  	{AMOVD, C_ZREG, C_NONE, C_NONE, C_SPR, C_NONE, 36, 4, 0, 0, 0},
   862  	{AMSR, C_ZREG, C_NONE, C_NONE, C_SPR, C_NONE, 36, 4, 0, 0, 0},
   863  	{AMOVD, C_VCON, C_NONE, C_NONE, C_SPR, C_NONE, 37, 4, 0, 0, 0},
   864  	{AMSR, C_VCON, C_NONE, C_NONE, C_SPR, C_NONE, 37, 4, 0, 0, 0},
   865  	{AMSR, C_VCON, C_NONE, C_NONE, C_SPOP, C_NONE, 37, 4, 0, 0, 0},
   866  	{APRFM, C_UOREG32K, C_NONE, C_NONE, C_SPOP, C_NONE, 91, 4, 0, 0, 0},
   867  	{APRFM, C_UOREG32K, C_NONE, C_NONE, C_LCON, C_NONE, 91, 4, 0, 0, 0},
   868  	{ADMB, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 51, 4, 0, 0, 0},
   869  	{AHINT, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 52, 4, 0, 0, 0},
   870  	{ASYS, C_VCON, C_NONE, C_NONE, C_NONE, C_NONE, 50, 4, 0, 0, 0},
   871  	{ASYS, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 50, 4, 0, 0, 0},
   872  	{ASYSL, C_VCON, C_NONE, C_NONE, C_ZREG, C_NONE, 50, 4, 0, 0, 0},
   873  	{ATLBI, C_SPOP, C_NONE, C_NONE, C_NONE, C_NONE, 107, 4, 0, 0, 0},
   874  	{ATLBI, C_SPOP, C_NONE, C_NONE, C_ZREG, C_NONE, 107, 4, 0, 0, 0},
   875  
   876  	/* encryption instructions */
   877  	{AAESD, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 26, 4, 0, 0, 0}, // for compatibility with old code
   878  	{AAESD, C_ARNG, C_NONE, C_NONE, C_ARNG, C_NONE, 26, 4, 0, 0, 0}, // recommend using the new one for better readability
   879  	{ASHA1C, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 49, 4, 0, 0, 0},
   880  	{ASHA1C, C_ARNG, C_VREG, C_NONE, C_VREG, C_NONE, 49, 4, 0, 0, 0},
   881  	{ASHA1SU0, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 63, 4, 0, 0, 0},
   882  	{AVREV32, C_ARNG, C_NONE, C_NONE, C_ARNG, C_NONE, 83, 4, 0, 0, 0},
   883  	{AVPMULL, C_ARNG, C_ARNG, C_NONE, C_ARNG, C_NONE, 93, 4, 0, 0, 0},
   884  	{AVEOR3, C_ARNG, C_ARNG, C_ARNG, C_ARNG, C_NONE, 103, 4, 0, 0, 0},
   885  	{AVXAR, C_VCON, C_ARNG, C_ARNG, C_ARNG, C_NONE, 104, 4, 0, 0, 0},
   886  	{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0},
   887  	{obj.APCDATA, C_VCON, C_NONE, C_NONE, C_VCON, C_NONE, 0, 0, 0, 0, 0},
   888  	{obj.AFUNCDATA, C_VCON, C_NONE, C_NONE, C_ADDR, C_NONE, 0, 0, 0, 0, 0},
   889  	{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
   890  	{obj.ANOP, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, // nop variants, see #40689
   891  	{obj.ANOP, C_ZREG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
   892  	{obj.ANOP, C_VREG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
   893  	{obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_SBRA, C_NONE, 5, 4, 0, 0, 0}, // same as AB/ABL
   894  	{obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_SBRA, C_NONE, 5, 4, 0, 0, 0}, // same as AB/ABL
   895  	{obj.APCALIGN, C_LCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},  // align code
   896  }
   897  
   898  // Valid pstate field values, and value to use in instruction.
   899  // Doesn't include special registers.
   900  var pstatefield = []struct {
   901  	opd SpecialOperand
   902  	enc uint32
   903  }{
   904  	{SPOP_DAIFSet, 3<<16 | 4<<12 | 6<<5},
   905  	{SPOP_DAIFClr, 3<<16 | 4<<12 | 7<<5},
   906  }
   907  
   908  var prfopfield = map[SpecialOperand]uint32{
   909  	SPOP_PLDL1KEEP: 0,
   910  	SPOP_PLDL1STRM: 1,
   911  	SPOP_PLDL2KEEP: 2,
   912  	SPOP_PLDL2STRM: 3,
   913  	SPOP_PLDL3KEEP: 4,
   914  	SPOP_PLDL3STRM: 5,
   915  	SPOP_PLIL1KEEP: 8,
   916  	SPOP_PLIL1STRM: 9,
   917  	SPOP_PLIL2KEEP: 10,
   918  	SPOP_PLIL2STRM: 11,
   919  	SPOP_PLIL3KEEP: 12,
   920  	SPOP_PLIL3STRM: 13,
   921  	SPOP_PSTL1KEEP: 16,
   922  	SPOP_PSTL1STRM: 17,
   923  	SPOP_PSTL2KEEP: 18,
   924  	SPOP_PSTL2STRM: 19,
   925  	SPOP_PSTL3KEEP: 20,
   926  	SPOP_PSTL3STRM: 21,
   927  }
   928  
   929  // sysInstFields helps convert SYS alias instructions to SYS instructions.
   930  // For example, the format of TLBI is: TLBI <tlbi_op>{, <Xt>}.
   931  // It's equivalent to: SYS #<op1>, C8, <Cm>, #<op2>{, <Xt>}.
   932  // The field hasOperand2 indicates whether Xt is required. It helps to check
   933  // some combinations that may be undefined, such as TLBI VMALLE1IS, R0.
   934  var sysInstFields = map[SpecialOperand]struct {
   935  	op1         uint8
   936  	cn          uint8
   937  	cm          uint8
   938  	op2         uint8
   939  	hasOperand2 bool
   940  }{
   941  	// TLBI
   942  	SPOP_VMALLE1IS:    {0, 8, 3, 0, false},
   943  	SPOP_VAE1IS:       {0, 8, 3, 1, true},
   944  	SPOP_ASIDE1IS:     {0, 8, 3, 2, true},
   945  	SPOP_VAAE1IS:      {0, 8, 3, 3, true},
   946  	SPOP_VALE1IS:      {0, 8, 3, 5, true},
   947  	SPOP_VAALE1IS:     {0, 8, 3, 7, true},
   948  	SPOP_VMALLE1:      {0, 8, 7, 0, false},
   949  	SPOP_VAE1:         {0, 8, 7, 1, true},
   950  	SPOP_ASIDE1:       {0, 8, 7, 2, true},
   951  	SPOP_VAAE1:        {0, 8, 7, 3, true},
   952  	SPOP_VALE1:        {0, 8, 7, 5, true},
   953  	SPOP_VAALE1:       {0, 8, 7, 7, true},
   954  	SPOP_IPAS2E1IS:    {4, 8, 0, 1, true},
   955  	SPOP_IPAS2LE1IS:   {4, 8, 0, 5, true},
   956  	SPOP_ALLE2IS:      {4, 8, 3, 0, false},
   957  	SPOP_VAE2IS:       {4, 8, 3, 1, true},
   958  	SPOP_ALLE1IS:      {4, 8, 3, 4, false},
   959  	SPOP_VALE2IS:      {4, 8, 3, 5, true},
   960  	SPOP_VMALLS12E1IS: {4, 8, 3, 6, false},
   961  	SPOP_IPAS2E1:      {4, 8, 4, 1, true},
   962  	SPOP_IPAS2LE1:     {4, 8, 4, 5, true},
   963  	SPOP_ALLE2:        {4, 8, 7, 0, false},
   964  	SPOP_VAE2:         {4, 8, 7, 1, true},
   965  	SPOP_ALLE1:        {4, 8, 7, 4, false},
   966  	SPOP_VALE2:        {4, 8, 7, 5, true},
   967  	SPOP_VMALLS12E1:   {4, 8, 7, 6, false},
   968  	SPOP_ALLE3IS:      {6, 8, 3, 0, false},
   969  	SPOP_VAE3IS:       {6, 8, 3, 1, true},
   970  	SPOP_VALE3IS:      {6, 8, 3, 5, true},
   971  	SPOP_ALLE3:        {6, 8, 7, 0, false},
   972  	SPOP_VAE3:         {6, 8, 7, 1, true},
   973  	SPOP_VALE3:        {6, 8, 7, 5, true},
   974  	SPOP_VMALLE1OS:    {0, 8, 1, 0, false},
   975  	SPOP_VAE1OS:       {0, 8, 1, 1, true},
   976  	SPOP_ASIDE1OS:     {0, 8, 1, 2, true},
   977  	SPOP_VAAE1OS:      {0, 8, 1, 3, true},
   978  	SPOP_VALE1OS:      {0, 8, 1, 5, true},
   979  	SPOP_VAALE1OS:     {0, 8, 1, 7, true},
   980  	SPOP_RVAE1IS:      {0, 8, 2, 1, true},
   981  	SPOP_RVAAE1IS:     {0, 8, 2, 3, true},
   982  	SPOP_RVALE1IS:     {0, 8, 2, 5, true},
   983  	SPOP_RVAALE1IS:    {0, 8, 2, 7, true},
   984  	SPOP_RVAE1OS:      {0, 8, 5, 1, true},
   985  	SPOP_RVAAE1OS:     {0, 8, 5, 3, true},
   986  	SPOP_RVALE1OS:     {0, 8, 5, 5, true},
   987  	SPOP_RVAALE1OS:    {0, 8, 5, 7, true},
   988  	SPOP_RVAE1:        {0, 8, 6, 1, true},
   989  	SPOP_RVAAE1:       {0, 8, 6, 3, true},
   990  	SPOP_RVALE1:       {0, 8, 6, 5, true},
   991  	SPOP_RVAALE1:      {0, 8, 6, 7, true},
   992  	SPOP_RIPAS2E1IS:   {4, 8, 0, 2, true},
   993  	SPOP_RIPAS2LE1IS:  {4, 8, 0, 6, true},
   994  	SPOP_ALLE2OS:      {4, 8, 1, 0, false},
   995  	SPOP_VAE2OS:       {4, 8, 1, 1, true},
   996  	SPOP_ALLE1OS:      {4, 8, 1, 4, false},
   997  	SPOP_VALE2OS:      {4, 8, 1, 5, true},
   998  	SPOP_VMALLS12E1OS: {4, 8, 1, 6, false},
   999  	SPOP_RVAE2IS:      {4, 8, 2, 1, true},
  1000  	SPOP_RVALE2IS:     {4, 8, 2, 5, true},
  1001  	SPOP_IPAS2E1OS:    {4, 8, 4, 0, true},
  1002  	SPOP_RIPAS2E1:     {4, 8, 4, 2, true},
  1003  	SPOP_RIPAS2E1OS:   {4, 8, 4, 3, true},
  1004  	SPOP_IPAS2LE1OS:   {4, 8, 4, 4, true},
  1005  	SPOP_RIPAS2LE1:    {4, 8, 4, 6, true},
  1006  	SPOP_RIPAS2LE1OS:  {4, 8, 4, 7, true},
  1007  	SPOP_RVAE2OS:      {4, 8, 5, 1, true},
  1008  	SPOP_RVALE2OS:     {4, 8, 5, 5, true},
  1009  	SPOP_RVAE2:        {4, 8, 6, 1, true},
  1010  	SPOP_RVALE2:       {4, 8, 6, 5, true},
  1011  	SPOP_ALLE3OS:      {6, 8, 1, 0, false},
  1012  	SPOP_VAE3OS:       {6, 8, 1, 1, true},
  1013  	SPOP_VALE3OS:      {6, 8, 1, 5, true},
  1014  	SPOP_RVAE3IS:      {6, 8, 2, 1, true},
  1015  	SPOP_RVALE3IS:     {6, 8, 2, 5, true},
  1016  	SPOP_RVAE3OS:      {6, 8, 5, 1, true},
  1017  	SPOP_RVALE3OS:     {6, 8, 5, 5, true},
  1018  	SPOP_RVAE3:        {6, 8, 6, 1, true},
  1019  	SPOP_RVALE3:       {6, 8, 6, 5, true},
  1020  	// DC
  1021  	SPOP_IVAC:    {0, 7, 6, 1, true},
  1022  	SPOP_ISW:     {0, 7, 6, 2, true},
  1023  	SPOP_CSW:     {0, 7, 10, 2, true},
  1024  	SPOP_CISW:    {0, 7, 14, 2, true},
  1025  	SPOP_ZVA:     {3, 7, 4, 1, true},
  1026  	SPOP_CVAC:    {3, 7, 10, 1, true},
  1027  	SPOP_CVAU:    {3, 7, 11, 1, true},
  1028  	SPOP_CIVAC:   {3, 7, 14, 1, true},
  1029  	SPOP_IGVAC:   {0, 7, 6, 3, true},
  1030  	SPOP_IGSW:    {0, 7, 6, 4, true},
  1031  	SPOP_IGDVAC:  {0, 7, 6, 5, true},
  1032  	SPOP_IGDSW:   {0, 7, 6, 6, true},
  1033  	SPOP_CGSW:    {0, 7, 10, 4, true},
  1034  	SPOP_CGDSW:   {0, 7, 10, 6, true},
  1035  	SPOP_CIGSW:   {0, 7, 14, 4, true},
  1036  	SPOP_CIGDSW:  {0, 7, 14, 6, true},
  1037  	SPOP_GVA:     {3, 7, 4, 3, true},
  1038  	SPOP_GZVA:    {3, 7, 4, 4, true},
  1039  	SPOP_CGVAC:   {3, 7, 10, 3, true},
  1040  	SPOP_CGDVAC:  {3, 7, 10, 5, true},
  1041  	SPOP_CGVAP:   {3, 7, 12, 3, true},
  1042  	SPOP_CGDVAP:  {3, 7, 12, 5, true},
  1043  	SPOP_CGVADP:  {3, 7, 13, 3, true},
  1044  	SPOP_CGDVADP: {3, 7, 13, 5, true},
  1045  	SPOP_CIGVAC:  {3, 7, 14, 3, true},
  1046  	SPOP_CIGDVAC: {3, 7, 14, 5, true},
  1047  	SPOP_CVAP:    {3, 7, 12, 1, true},
  1048  	SPOP_CVADP:   {3, 7, 13, 1, true},
  1049  }
  1050  
  1051  // Used for padding NOOP instruction
  1052  const OP_NOOP = 0xd503201f
  1053  
  1054  // pcAlignPadLength returns the number of bytes required to align pc to alignedValue,
  1055  // reporting an error if alignedValue is not a power of two or is out of range.
  1056  func pcAlignPadLength(ctxt *obj.Link, pc int64, alignedValue int64) int {
  1057  	if !((alignedValue&(alignedValue-1) == 0) && 8 <= alignedValue && alignedValue <= 2048) {
  1058  		ctxt.Diag("alignment value of an instruction must be a power of two and in the range [8, 2048], got %d\n", alignedValue)
  1059  	}
  1060  	return int(-pc & (alignedValue - 1))
  1061  }
  1062  
  1063  // size returns the size of the sequence of machine instructions when p is encoded with o.
  1064  // Usually it just returns o.size directly, in some cases it checks whether the optimization
  1065  // conditions are met, and if so returns the size of the optimized instruction sequence.
  1066  // These optimizations need to be synchronized with the asmout function.
  1067  func (o *Optab) size(ctxt *obj.Link, p *obj.Prog) int {
  1068  	// Optimize adrp+add+ld/st to adrp+ld/st(offset).
  1069  	sz := movesize(p.As)
  1070  	if sz != -1 {
  1071  		// Relocations R_AARCH64_LDST{64,32,16,8}_ABS_LO12_NC can only generate 8-byte, 4-byte,
  1072  		// 2-byte and 1-byte aligned addresses, so the address of load/store must be aligned.
  1073  		// Also symbols with prefix of "go:string." are Go strings, which will go into
  1074  		// the symbol table, their addresses are not necessary aligned, rule this out.
  1075  		align := int64(1 << sz)
  1076  		if o.a1 == C_ADDR && p.From.Offset%align == 0 && !strings.HasPrefix(p.From.Sym.Name, "go:string.") ||
  1077  			o.a4 == C_ADDR && p.To.Offset%align == 0 && !strings.HasPrefix(p.To.Sym.Name, "go:string.") {
  1078  			return 8
  1079  		}
  1080  	}
  1081  	return int(o.size_)
  1082  }
  1083  
  1084  func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
  1085  	if ctxt.Retpoline {
  1086  		ctxt.Diag("-spectre=ret not supported on arm64")
  1087  		ctxt.Retpoline = false // don't keep printing
  1088  	}
  1089  
  1090  	p := cursym.Func().Text
  1091  	if p == nil || p.Link == nil { // handle external functions and ELF section symbols
  1092  		return
  1093  	}
  1094  
  1095  	if oprange[AAND&obj.AMask] == nil {
  1096  		ctxt.Diag("arm64 ops not initialized, call arm64.buildop first")
  1097  	}
  1098  
  1099  	c := ctxt7{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset & 0xffffffff), extrasize: int32(p.To.Offset >> 32)}
  1100  	p.To.Offset &= 0xffffffff // extrasize is no longer needed
  1101  
  1102  	bflag := 1
  1103  	pc := int64(0)
  1104  	p.Pc = pc
  1105  	var m int
  1106  	var o *Optab
  1107  	for p = p.Link; p != nil; p = p.Link {
  1108  		p.Pc = pc
  1109  		o = c.oplook(p)
  1110  		m = o.size(c.ctxt, p)
  1111  		if m == 0 {
  1112  			switch p.As {
  1113  			case obj.APCALIGN:
  1114  				alignedValue := p.From.Offset
  1115  				m = pcAlignPadLength(ctxt, pc, alignedValue)
  1116  				// Update the current text symbol alignment value.
  1117  				if int32(alignedValue) > cursym.Func().Align {
  1118  					cursym.Func().Align = int32(alignedValue)
  1119  				}
  1120  				break
  1121  			case obj.ANOP, obj.AFUNCDATA, obj.APCDATA:
  1122  				continue
  1123  			default:
  1124  				c.ctxt.Diag("zero-width instruction\n%v", p)
  1125  			}
  1126  		}
  1127  		pc += int64(m)
  1128  
  1129  		if o.flag&LFROM != 0 {
  1130  			c.addpool(p, &p.From)
  1131  		}
  1132  		if o.flag&LTO != 0 {
  1133  			c.addpool(p, &p.To)
  1134  		}
  1135  		if c.blitrl != nil {
  1136  			c.checkpool(p)
  1137  		}
  1138  	}
  1139  
  1140  	c.cursym.Size = pc
  1141  
  1142  	/*
  1143  	 * if any procedure is large enough to
  1144  	 * generate a large SBRA branch, then
  1145  	 * generate extra passes putting branches
  1146  	 * around jmps to fix. this is rare.
  1147  	 */
  1148  	for bflag != 0 {
  1149  		bflag = 0
  1150  		pc = 0
  1151  		for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
  1152  			p.Pc = pc
  1153  			o = c.oplook(p)
  1154  
  1155  			/* very large branches */
  1156  			if (o.flag&BRANCH14BITS != 0 || o.flag&BRANCH19BITS != 0) && p.To.Target() != nil {
  1157  				otxt := p.To.Target().Pc - pc
  1158  				var toofar bool
  1159  				if o.flag&BRANCH14BITS != 0 { // branch instruction encodes 14 bits
  1160  					toofar = otxt <= -(1<<15)+10 || otxt >= (1<<15)-10
  1161  				} else if o.flag&BRANCH19BITS != 0 { // branch instruction encodes 19 bits
  1162  					toofar = otxt <= -(1<<20)+10 || otxt >= (1<<20)-10
  1163  				}
  1164  				if toofar {
  1165  					q := c.newprog()
  1166  					q.Link = p.Link
  1167  					p.Link = q
  1168  					q.As = AB
  1169  					q.To.Type = obj.TYPE_BRANCH
  1170  					q.To.SetTarget(p.To.Target())
  1171  					p.To.SetTarget(q)
  1172  					q = c.newprog()
  1173  					q.Link = p.Link
  1174  					p.Link = q
  1175  					q.As = AB
  1176  					q.To.Type = obj.TYPE_BRANCH
  1177  					q.To.SetTarget(q.Link.Link)
  1178  					bflag = 1
  1179  				}
  1180  			}
  1181  			m = o.size(c.ctxt, p)
  1182  
  1183  			if m == 0 {
  1184  				switch p.As {
  1185  				case obj.APCALIGN:
  1186  					alignedValue := p.From.Offset
  1187  					m = pcAlignPadLength(ctxt, pc, alignedValue)
  1188  					break
  1189  				case obj.ANOP, obj.AFUNCDATA, obj.APCDATA:
  1190  					continue
  1191  				default:
  1192  					c.ctxt.Diag("zero-width instruction\n%v", p)
  1193  				}
  1194  			}
  1195  
  1196  			pc += int64(m)
  1197  		}
  1198  	}
  1199  
  1200  	pc += -pc & (funcAlign - 1)
  1201  	c.cursym.Size = pc
  1202  
  1203  	/*
  1204  	 * lay out the code, emitting code and data relocations.
  1205  	 */
  1206  	c.cursym.Grow(c.cursym.Size)
  1207  	bp := c.cursym.P
  1208  	psz := int32(0)
  1209  	var i int
  1210  	var out [6]uint32
  1211  	for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
  1212  		c.pc = p.Pc
  1213  		o = c.oplook(p)
  1214  		sz := o.size(c.ctxt, p)
  1215  		if sz > 4*len(out) {
  1216  			log.Fatalf("out array in span7 is too small, need at least %d for %v", sz/4, p)
  1217  		}
  1218  		if p.As == obj.APCALIGN {
  1219  			alignedValue := p.From.Offset
  1220  			v := pcAlignPadLength(c.ctxt, p.Pc, alignedValue)
  1221  			for i = 0; i < int(v/4); i++ {
  1222  				// emit ANOOP instruction by the padding size
  1223  				c.ctxt.Arch.ByteOrder.PutUint32(bp, OP_NOOP)
  1224  				bp = bp[4:]
  1225  				psz += 4
  1226  			}
  1227  		} else {
  1228  			c.asmout(p, o, out[:])
  1229  			for i = 0; i < sz/4; i++ {
  1230  				c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
  1231  				bp = bp[4:]
  1232  				psz += 4
  1233  			}
  1234  		}
  1235  	}
  1236  
  1237  	// Mark nonpreemptible instruction sequences.
  1238  	// We use REGTMP as a scratch register during call injection,
  1239  	// so instruction sequences that use REGTMP are unsafe to
  1240  	// preempt asynchronously.
  1241  	obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable)
  1242  
  1243  	// Now that we know byte offsets, we can generate jump table entries.
  1244  	for _, jt := range cursym.Func().JumpTables {
  1245  		for i, p := range jt.Targets {
  1246  			// The ith jumptable entry points to the p.Pc'th
  1247  			// byte in the function symbol s.
  1248  			// TODO: try using relative PCs.
  1249  			jt.Sym.WriteAddr(ctxt, int64(i)*8, 8, cursym, p.Pc)
  1250  		}
  1251  	}
  1252  }
  1253  
  1254  // isUnsafePoint returns whether p is an unsafe point.
  1255  func (c *ctxt7) isUnsafePoint(p *obj.Prog) bool {
  1256  	// If p explicitly uses REGTMP, it's unsafe to preempt, because the
  1257  	// preemption sequence clobbers REGTMP.
  1258  	return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP ||
  1259  		p.From.Type == obj.TYPE_REGREG && p.From.Offset == REGTMP ||
  1260  		p.To.Type == obj.TYPE_REGREG && p.To.Offset == REGTMP
  1261  }
  1262  
  1263  // isRestartable returns whether p is a multi-instruction sequence that,
  1264  // if preempted, can be restarted.
  1265  func (c *ctxt7) isRestartable(p *obj.Prog) bool {
  1266  	if c.isUnsafePoint(p) {
  1267  		return false
  1268  	}
  1269  	// If p is a multi-instruction sequence with uses REGTMP inserted by
  1270  	// the assembler in order to materialize a large constant/offset, we
  1271  	// can restart p (at the start of the instruction sequence), recompute
  1272  	// the content of REGTMP, upon async preemption. Currently, all cases
  1273  	// of assembler-inserted REGTMP fall into this category.
  1274  	// If p doesn't use REGTMP, it can be simply preempted, so we don't
  1275  	// mark it.
  1276  	o := c.oplook(p)
  1277  	return o.size(c.ctxt, p) > 4 && o.flag&NOTUSETMP == 0
  1278  }
  1279  
  1280  /*
  1281   * when the first reference to the literal pool threatens
  1282   * to go out of range of a 1Mb PC-relative offset
  1283   * drop the pool now.
  1284   */
  1285  func (c *ctxt7) checkpool(p *obj.Prog) {
  1286  	// If the pool is going to go out of range or p is the last instruction of the function,
  1287  	// flush the pool.
  1288  	if c.pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(c.pool.size)-int64(c.pool.start)+8)) || p.Link == nil {
  1289  		c.flushpool(p)
  1290  	}
  1291  }
  1292  
  1293  func (c *ctxt7) flushpool(p *obj.Prog) {
  1294  	// Needs to insert a branch before flushing the pool.
  1295  	// We don't need the jump if following an unconditional branch.
  1296  	// TODO: other unconditional operations.
  1297  	if !(p.As == AB || p.As == obj.ARET || p.As == AERET) {
  1298  		if c.ctxt.Debugvlog {
  1299  			fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), c.pool.size, c.pool.start)
  1300  		}
  1301  		q := c.newprog()
  1302  		if p.Link == nil {
  1303  			// If p is the last instruction of the function, insert an UNDEF instruction in case the
  1304  			// execution fall through to the pool.
  1305  			q.As = obj.AUNDEF
  1306  		} else {
  1307  			// Else insert a branch to the next instruction of p.
  1308  			q.As = AB
  1309  			q.To.Type = obj.TYPE_BRANCH
  1310  			q.To.SetTarget(p.Link)
  1311  		}
  1312  		q.Link = c.blitrl
  1313  		q.Pos = p.Pos
  1314  		c.blitrl = q
  1315  	}
  1316  
  1317  	// The line number for constant pool entries doesn't really matter.
  1318  	// We set it to the line number of the preceding instruction so that
  1319  	// there are no deltas to encode in the pc-line tables.
  1320  	for q := c.blitrl; q != nil; q = q.Link {
  1321  		q.Pos = p.Pos
  1322  	}
  1323  
  1324  	c.elitrl.Link = p.Link
  1325  	p.Link = c.blitrl
  1326  
  1327  	c.blitrl = nil /* BUG: should refer back to values until out-of-range */
  1328  	c.elitrl = nil
  1329  	c.pool.size = 0
  1330  	c.pool.start = 0
  1331  }
  1332  
  1333  /*
  1334   * MOVD foo(SB), R is actually
  1335   *   MOVD addr, REGTMP
  1336   *   MOVD REGTMP, R
  1337   * where addr is the address of the DWORD containing the address of foo.
  1338   *
  1339   * TODO: hash
  1340   */
  1341  func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
  1342  	cls := c.aclass(a)
  1343  	lit := c.instoffset
  1344  	t := c.newprog()
  1345  	t.As = AWORD
  1346  	sz := 4
  1347  
  1348  	if a.Type == obj.TYPE_CONST {
  1349  		if lit != int64(int32(lit)) && uint64(lit) != uint64(uint32(lit)) {
  1350  			// out of range -0x80000000 ~ 0xffffffff, must store 64-bit.
  1351  			t.As = ADWORD
  1352  			sz = 8
  1353  		} // else store 32-bit
  1354  	} else if p.As == AMOVD && a.Type != obj.TYPE_MEM || cls == C_ADDR || cls == C_VCON || lit != int64(int32(lit)) || uint64(lit) != uint64(uint32(lit)) {
  1355  		// conservative: don't know if we want signed or unsigned extension.
  1356  		// in case of ambiguity, store 64-bit
  1357  		t.As = ADWORD
  1358  		sz = 8
  1359  	}
  1360  
  1361  	t.To.Type = obj.TYPE_CONST
  1362  	t.To.Offset = lit
  1363  
  1364  	for q := c.blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
  1365  		if q.To == t.To {
  1366  			p.Pool = q
  1367  			return
  1368  		}
  1369  	}
  1370  
  1371  	if c.blitrl == nil {
  1372  		c.blitrl = t
  1373  		c.pool.start = uint32(p.Pc)
  1374  	} else {
  1375  		c.elitrl.Link = t
  1376  	}
  1377  	c.elitrl = t
  1378  	if t.As == ADWORD {
  1379  		// make DWORD 8-byte aligned, this is not required by ISA,
  1380  		// just to avoid performance penalties when loading from
  1381  		// the constant pool across a cache line.
  1382  		c.pool.size = roundUp(c.pool.size, 8)
  1383  	}
  1384  	c.pool.size += uint32(sz)
  1385  	p.Pool = t
  1386  }
  1387  
  1388  // roundUp rounds up x to "to".
  1389  func roundUp(x, to uint32) uint32 {
  1390  	if to == 0 || to&(to-1) != 0 {
  1391  		log.Fatalf("rounded up to a value that is not a power of 2: %d\n", to)
  1392  	}
  1393  	return (x + to - 1) &^ (to - 1)
  1394  }
  1395  
  1396  // splitImm24uScaled splits an immediate into a scaled 12 bit unsigned lo value
  1397  // and an unscaled shifted 12 bit unsigned hi value. These are typically used
  1398  // by adding or subtracting the hi value and using the lo value as the offset
  1399  // for a load or store.
  1400  func splitImm24uScaled(v int32, shift int) (int32, int32, error) {
  1401  	if v < 0 {
  1402  		return 0, 0, fmt.Errorf("%d is not a 24 bit unsigned immediate", v)
  1403  	}
  1404  	if v > 0xfff000+0xfff<<shift {
  1405  		return 0, 0, fmt.Errorf("%d is too large for a scaled 24 bit unsigned immediate", v)
  1406  	}
  1407  	if v&((1<<shift)-1) != 0 {
  1408  		return 0, 0, fmt.Errorf("%d is not a multiple of %d", v, 1<<shift)
  1409  	}
  1410  	lo := (v >> shift) & 0xfff
  1411  	hi := v - (lo << shift)
  1412  	if hi > 0xfff000 {
  1413  		hi = 0xfff000
  1414  		lo = (v - hi) >> shift
  1415  	}
  1416  	if hi & ^0xfff000 != 0 {
  1417  		panic(fmt.Sprintf("bad split for %x with shift %v (%x, %x)", v, shift, hi, lo))
  1418  	}
  1419  	return hi, lo, nil
  1420  }
  1421  
  1422  func (c *ctxt7) regoff(a *obj.Addr) int32 {
  1423  	c.instoffset = 0
  1424  	c.aclass(a)
  1425  	return int32(c.instoffset)
  1426  }
  1427  
  1428  func isSTLXRop(op obj.As) bool {
  1429  	switch op {
  1430  	case ASTLXR, ASTLXRW, ASTLXRB, ASTLXRH,
  1431  		ASTXR, ASTXRW, ASTXRB, ASTXRH:
  1432  		return true
  1433  	}
  1434  	return false
  1435  }
  1436  
  1437  func isSTXPop(op obj.As) bool {
  1438  	switch op {
  1439  	case ASTXP, ASTLXP, ASTXPW, ASTLXPW:
  1440  		return true
  1441  	}
  1442  	return false
  1443  }
  1444  
  1445  func isANDop(op obj.As) bool {
  1446  	switch op {
  1447  	case AAND, AORR, AEOR, AANDS, ATST,
  1448  		ABIC, AEON, AORN, ABICS:
  1449  		return true
  1450  	}
  1451  	return false
  1452  }
  1453  
  1454  func isANDWop(op obj.As) bool {
  1455  	switch op {
  1456  	case AANDW, AORRW, AEORW, AANDSW, ATSTW,
  1457  		ABICW, AEONW, AORNW, ABICSW:
  1458  		return true
  1459  	}
  1460  	return false
  1461  }
  1462  
  1463  func isADDop(op obj.As) bool {
  1464  	switch op {
  1465  	case AADD, AADDS, ASUB, ASUBS, ACMN, ACMP:
  1466  		return true
  1467  	}
  1468  	return false
  1469  }
  1470  
  1471  func isADDWop(op obj.As) bool {
  1472  	switch op {
  1473  	case AADDW, AADDSW, ASUBW, ASUBSW, ACMNW, ACMPW:
  1474  		return true
  1475  	}
  1476  	return false
  1477  }
  1478  
  1479  func isADDSop(op obj.As) bool {
  1480  	switch op {
  1481  	case AADDS, AADDSW, ASUBS, ASUBSW:
  1482  		return true
  1483  	}
  1484  	return false
  1485  }
  1486  
  1487  func isNEGop(op obj.As) bool {
  1488  	switch op {
  1489  	case ANEG, ANEGW, ANEGS, ANEGSW:
  1490  		return true
  1491  	}
  1492  	return false
  1493  }
  1494  
  1495  func isLoadStorePairOp(op obj.As) bool {
  1496  	switch op {
  1497  	case AFLDPQ, AFSTPQ, ALDP, ASTP, ALDPW, ASTPW:
  1498  		return true
  1499  	}
  1500  	return false
  1501  }
  1502  
  1503  func isMOVop(op obj.As) bool {
  1504  	switch op {
  1505  	case AMOVB, AMOVBU, AMOVH, AMOVHU, AMOVW, AMOVWU, AMOVD, AFMOVS, AFMOVD, AFMOVQ:
  1506  		return true
  1507  	}
  1508  	return false
  1509  }
  1510  
  1511  func isRegShiftOrExt(a *obj.Addr) bool {
  1512  	return (a.Index-obj.RBaseARM64)&REG_EXT != 0 || (a.Index-obj.RBaseARM64)&REG_LSL != 0
  1513  }
  1514  
  1515  // Maximum PC-relative displacement.
  1516  // The actual limit is ±2²⁰, but we are conservative
  1517  // to avoid needing to recompute the literal pool flush points
  1518  // as span-dependent jumps are enlarged.
  1519  const maxPCDisp = 512 * 1024
  1520  
  1521  // ispcdisp reports whether v is a valid PC-relative displacement.
  1522  func ispcdisp(v int32) bool {
  1523  	return -maxPCDisp < v && v < maxPCDisp && v&3 == 0
  1524  }
  1525  
  1526  func isaddcon(v int64) bool {
  1527  	/* uimm12 or uimm24? */
  1528  	if v < 0 {
  1529  		return false
  1530  	}
  1531  	if (v & 0xFFF) == 0 {
  1532  		v >>= 12
  1533  	}
  1534  	return v <= 0xFFF
  1535  }
  1536  
  1537  func isaddcon2(v int64) bool {
  1538  	return 0 <= v && v <= 0xFFFFFF
  1539  }
  1540  
  1541  // isbitcon reports whether a constant can be encoded into a logical instruction.
  1542  // bitcon has a binary form of repetition of a bit sequence of length 2, 4, 8, 16, 32, or 64,
  1543  // which itself is a rotate (w.r.t. the length of the unit) of a sequence of ones.
  1544  // special cases: 0 and -1 are not bitcon.
  1545  // this function needs to run against virtually all the constants, so it needs to be fast.
  1546  // for this reason, bitcon testing and bitcon encoding are separate functions.
  1547  func isbitcon(x uint64) bool {
  1548  	if x == 1<<64-1 || x == 0 {
  1549  		return false
  1550  	}
  1551  	// determine the period and sign-extend a unit to 64 bits
  1552  	switch {
  1553  	case x != x>>32|x<<32:
  1554  		// period is 64
  1555  		// nothing to do
  1556  	case x != x>>16|x<<48:
  1557  		// period is 32
  1558  		x = uint64(int64(int32(x)))
  1559  	case x != x>>8|x<<56:
  1560  		// period is 16
  1561  		x = uint64(int64(int16(x)))
  1562  	case x != x>>4|x<<60:
  1563  		// period is 8
  1564  		x = uint64(int64(int8(x)))
  1565  	default:
  1566  		// period is 4 or 2, always true
  1567  		// 0001, 0010, 0100, 1000 -- 0001 rotate
  1568  		// 0011, 0110, 1100, 1001 -- 0011 rotate
  1569  		// 0111, 1011, 1101, 1110 -- 0111 rotate
  1570  		// 0101, 1010             -- 01   rotate, repeat
  1571  		return true
  1572  	}
  1573  	return sequenceOfOnes(x) || sequenceOfOnes(^x)
  1574  }
  1575  
  1576  // sequenceOfOnes tests whether a constant is a sequence of ones in binary, with leading and trailing zeros.
  1577  func sequenceOfOnes(x uint64) bool {
  1578  	y := x & -x // lowest set bit of x. x is good iff x+y is a power of 2
  1579  	y += x
  1580  	return (y-1)&y == 0
  1581  }
  1582  
  1583  // bitconEncode returns the encoding of a bitcon used in logical instructions
  1584  // x is known to be a bitcon
  1585  // a bitcon is a sequence of n ones at low bits (i.e. 1<<n-1), right rotated
  1586  // by R bits, and repeated with period of 64, 32, 16, 8, 4, or 2.
  1587  // it is encoded in logical instructions with 3 bitfields
  1588  // N (1 bit) : R (6 bits) : S (6 bits), where
  1589  // N=1           -- period=64
  1590  // N=0, S=0xxxxx -- period=32
  1591  // N=0, S=10xxxx -- period=16
  1592  // N=0, S=110xxx -- period=8
  1593  // N=0, S=1110xx -- period=4
  1594  // N=0, S=11110x -- period=2
  1595  // R is the shift amount, low bits of S = n-1
  1596  func bitconEncode(x uint64, mode int) uint32 {
  1597  	if mode == 32 {
  1598  		x &= 0xffffffff
  1599  		x = x<<32 | x
  1600  	}
  1601  	var period uint32
  1602  	// determine the period and sign-extend a unit to 64 bits
  1603  	switch {
  1604  	case x != x>>32|x<<32:
  1605  		period = 64
  1606  	case x != x>>16|x<<48:
  1607  		period = 32
  1608  		x = uint64(int64(int32(x)))
  1609  	case x != x>>8|x<<56:
  1610  		period = 16
  1611  		x = uint64(int64(int16(x)))
  1612  	case x != x>>4|x<<60:
  1613  		period = 8
  1614  		x = uint64(int64(int8(x)))
  1615  	case x != x>>2|x<<62:
  1616  		period = 4
  1617  		x = uint64(int64(x<<60) >> 60)
  1618  	default:
  1619  		period = 2
  1620  		x = uint64(int64(x<<62) >> 62)
  1621  	}
  1622  	neg := false
  1623  	if int64(x) < 0 {
  1624  		x = ^x
  1625  		neg = true
  1626  	}
  1627  	y := x & -x // lowest set bit of x.
  1628  	s := log2(y)
  1629  	n := log2(x+y) - s // x (or ^x) is a sequence of n ones left shifted by s bits
  1630  	if neg {
  1631  		// ^x is a sequence of n ones left shifted by s bits
  1632  		// adjust n, s for x
  1633  		s = n + s
  1634  		n = period - n
  1635  	}
  1636  
  1637  	N := uint32(0)
  1638  	if mode == 64 && period == 64 {
  1639  		N = 1
  1640  	}
  1641  	R := (period - s) & (period - 1) & uint32(mode-1) // shift amount of right rotate
  1642  	S := (n - 1) | 63&^(period<<1-1)                  // low bits = #ones - 1, high bits encodes period
  1643  	return N<<22 | R<<16 | S<<10
  1644  }
  1645  
  1646  func log2(x uint64) uint32 {
  1647  	if x == 0 {
  1648  		panic("log2 of 0")
  1649  	}
  1650  	n := uint32(0)
  1651  	if x >= 1<<32 {
  1652  		x >>= 32
  1653  		n += 32
  1654  	}
  1655  	if x >= 1<<16 {
  1656  		x >>= 16
  1657  		n += 16
  1658  	}
  1659  	if x >= 1<<8 {
  1660  		x >>= 8
  1661  		n += 8
  1662  	}
  1663  	if x >= 1<<4 {
  1664  		x >>= 4
  1665  		n += 4
  1666  	}
  1667  	if x >= 1<<2 {
  1668  		x >>= 2
  1669  		n += 2
  1670  	}
  1671  	if x >= 1<<1 {
  1672  		x >>= 1
  1673  		n += 1
  1674  	}
  1675  	return n
  1676  }
  1677  
  1678  func autoclass(l int64) int {
  1679  	if l == 0 {
  1680  		return C_ZAUTO
  1681  	}
  1682  
  1683  	if l < 0 {
  1684  		if l >= -256 && (l&15) == 0 {
  1685  			return C_NSAUTO_16
  1686  		}
  1687  		if l >= -256 && (l&7) == 0 {
  1688  			return C_NSAUTO_8
  1689  		}
  1690  		if l >= -256 && (l&3) == 0 {
  1691  			return C_NSAUTO_4
  1692  		}
  1693  		if l >= -256 {
  1694  			return C_NSAUTO
  1695  		}
  1696  		if l >= -512 && (l&15) == 0 {
  1697  			return C_NPAUTO_16
  1698  		}
  1699  		if l >= -512 && (l&7) == 0 {
  1700  			return C_NPAUTO
  1701  		}
  1702  		if l >= -1024 && (l&15) == 0 {
  1703  			return C_NQAUTO_16
  1704  		}
  1705  		if l >= -4095 {
  1706  			return C_NAUTO4K
  1707  		}
  1708  		return C_LAUTO
  1709  	}
  1710  
  1711  	if l <= 255 {
  1712  		if (l & 15) == 0 {
  1713  			return C_PSAUTO_16
  1714  		}
  1715  		if (l & 7) == 0 {
  1716  			return C_PSAUTO_8
  1717  		}
  1718  		if (l & 3) == 0 {
  1719  			return C_PSAUTO_4
  1720  		}
  1721  		return C_PSAUTO
  1722  	}
  1723  	if l <= 504 {
  1724  		if l&15 == 0 {
  1725  			return C_PPAUTO_16
  1726  		}
  1727  		if l&7 == 0 {
  1728  			return C_PPAUTO
  1729  		}
  1730  	}
  1731  	if l <= 1008 {
  1732  		if l&15 == 0 {
  1733  			return C_PQAUTO_16
  1734  		}
  1735  	}
  1736  	if l <= 4095 {
  1737  		if l&15 == 0 {
  1738  			return C_UAUTO4K_16
  1739  		}
  1740  		if l&7 == 0 {
  1741  			return C_UAUTO4K_8
  1742  		}
  1743  		if l&3 == 0 {
  1744  			return C_UAUTO4K_4
  1745  		}
  1746  		if l&1 == 0 {
  1747  			return C_UAUTO4K_2
  1748  		}
  1749  		return C_UAUTO4K
  1750  	}
  1751  	if l <= 8190 {
  1752  		if l&15 == 0 {
  1753  			return C_UAUTO8K_16
  1754  		}
  1755  		if l&7 == 0 {
  1756  			return C_UAUTO8K_8
  1757  		}
  1758  		if l&3 == 0 {
  1759  			return C_UAUTO8K_4
  1760  		}
  1761  		if l&1 == 0 {
  1762  			return C_UAUTO8K
  1763  		}
  1764  	}
  1765  	if l <= 16380 {
  1766  		if l&15 == 0 {
  1767  			return C_UAUTO16K_16
  1768  		}
  1769  		if l&7 == 0 {
  1770  			return C_UAUTO16K_8
  1771  		}
  1772  		if l&3 == 0 {
  1773  			return C_UAUTO16K
  1774  		}
  1775  	}
  1776  	if l <= 32760 {
  1777  		if l&15 == 0 {
  1778  			return C_UAUTO32K_16
  1779  		}
  1780  		if l&7 == 0 {
  1781  			return C_UAUTO32K
  1782  		}
  1783  	}
  1784  	if l <= 65520 && (l&15) == 0 {
  1785  		return C_UAUTO64K
  1786  	}
  1787  	return C_LAUTO
  1788  }
  1789  
  1790  func oregclass(l int64) int {
  1791  	return autoclass(l) - C_ZAUTO + C_ZOREG
  1792  }
  1793  
  1794  /*
  1795   * given an offset v and a class c (see above)
  1796   * return the offset value to use in the instruction,
  1797   * scaled if necessary
  1798   */
  1799  func (c *ctxt7) offsetshift(p *obj.Prog, v int64, cls int) int64 {
  1800  	s := 0
  1801  	if cls >= C_SEXT1 && cls <= C_SEXT16 {
  1802  		s = cls - C_SEXT1
  1803  	} else {
  1804  		switch cls {
  1805  		case C_UAUTO4K, C_UOREG4K, C_ZOREG:
  1806  			s = 0
  1807  		case C_UAUTO8K, C_UOREG8K:
  1808  			s = 1
  1809  		case C_UAUTO16K, C_UOREG16K:
  1810  			s = 2
  1811  		case C_UAUTO32K, C_UOREG32K:
  1812  			s = 3
  1813  		case C_UAUTO64K, C_UOREG64K:
  1814  			s = 4
  1815  		default:
  1816  			c.ctxt.Diag("bad class: %v\n%v", DRconv(cls), p)
  1817  		}
  1818  	}
  1819  	vs := v >> uint(s)
  1820  	if vs<<uint(s) != v {
  1821  		c.ctxt.Diag("odd offset: %d\n%v", v, p)
  1822  	}
  1823  	return vs
  1824  }
  1825  
  1826  /*
  1827   * if v contains a single 16-bit value aligned
  1828   * on a 16-bit field, and thus suitable for movk/movn,
  1829   * return the field index 0 to 3; otherwise return -1.
  1830   */
  1831  func movcon(v int64) int {
  1832  	for s := 0; s < 64; s += 16 {
  1833  		if (uint64(v) &^ (uint64(0xFFFF) << uint(s))) == 0 {
  1834  			return s / 16
  1835  		}
  1836  	}
  1837  	return -1
  1838  }
  1839  
  1840  func rclass(r int16) int {
  1841  	switch {
  1842  	case REG_R0 <= r && r <= REG_R30: // not 31
  1843  		return C_REG
  1844  	case r == REGZERO:
  1845  		return C_ZREG
  1846  	case REG_F0 <= r && r <= REG_F31:
  1847  		return C_FREG
  1848  	case REG_V0 <= r && r <= REG_V31:
  1849  		return C_VREG
  1850  	case r == REGSP:
  1851  		return C_RSP
  1852  	case r >= REG_ARNG && r < REG_ELEM:
  1853  		return C_ARNG
  1854  	case r >= REG_ELEM && r < REG_ELEM_END:
  1855  		return C_ELEM
  1856  	case r >= REG_UXTB && r < REG_SPECIAL,
  1857  		r >= REG_LSL && r < REG_ARNG:
  1858  		return C_EXTREG
  1859  	case r >= REG_SPECIAL:
  1860  		return C_SPR
  1861  	}
  1862  	return C_GOK
  1863  }
  1864  
  1865  // con32class reclassifies the constant of 32-bit instruction. Because the constant type is 32-bit,
  1866  // but saved in Offset which type is int64, con32class treats it as uint32 type and reclassifies it.
  1867  func (c *ctxt7) con32class(a *obj.Addr) int {
  1868  	v := uint32(a.Offset)
  1869  	// For 32-bit instruction with constant, rewrite
  1870  	// the high 32-bit to be a repetition of the low
  1871  	// 32-bit, so that the BITCON test can be shared
  1872  	// for both 32-bit and 64-bit. 32-bit ops will
  1873  	// zero the high 32-bit of the destination register
  1874  	// anyway.
  1875  	vbitcon := uint64(v)<<32 | uint64(v)
  1876  	if v == 0 {
  1877  		return C_ZCON
  1878  	}
  1879  	if isaddcon(int64(v)) {
  1880  		if v <= 0xFFF {
  1881  			if isbitcon(vbitcon) {
  1882  				return C_ABCON0
  1883  			}
  1884  			return C_ADDCON0
  1885  		}
  1886  		if isbitcon(vbitcon) {
  1887  			return C_ABCON
  1888  		}
  1889  		if movcon(int64(v)) >= 0 {
  1890  			return C_AMCON
  1891  		}
  1892  		if movcon(int64(^v)) >= 0 {
  1893  			return C_AMCON
  1894  		}
  1895  		return C_ADDCON
  1896  	}
  1897  
  1898  	t := movcon(int64(v))
  1899  	if t >= 0 {
  1900  		if isbitcon(vbitcon) {
  1901  			return C_MBCON
  1902  		}
  1903  		return C_MOVCON
  1904  	}
  1905  
  1906  	t = movcon(int64(^v))
  1907  	if t >= 0 {
  1908  		if isbitcon(vbitcon) {
  1909  			return C_MBCON
  1910  		}
  1911  		return C_MOVCON
  1912  	}
  1913  
  1914  	if isbitcon(vbitcon) {
  1915  		return C_BITCON
  1916  	}
  1917  
  1918  	if 0 <= v && v <= 0xffffff {
  1919  		return C_ADDCON2
  1920  	}
  1921  	return C_LCON
  1922  }
  1923  
  1924  // con64class reclassifies the constant of C_VCON and C_LCON class.
  1925  func (c *ctxt7) con64class(a *obj.Addr) int {
  1926  	zeroCount := 0
  1927  	negCount := 0
  1928  	for i := uint(0); i < 4; i++ {
  1929  		immh := uint32(a.Offset >> (i * 16) & 0xffff)
  1930  		if immh == 0 {
  1931  			zeroCount++
  1932  		} else if immh == 0xffff {
  1933  			negCount++
  1934  		}
  1935  	}
  1936  	if zeroCount >= 3 || negCount >= 3 {
  1937  		return C_MOVCON
  1938  	} else if zeroCount == 2 || negCount == 2 {
  1939  		return C_MOVCON2
  1940  	} else if zeroCount == 1 || negCount == 1 {
  1941  		return C_MOVCON3
  1942  	} else {
  1943  		return C_VCON
  1944  	}
  1945  }
  1946  
  1947  // loadStoreClass reclassifies a load or store operation based on its offset.
  1948  func (c *ctxt7) loadStoreClass(p *obj.Prog, lsc int, v int64) int {
  1949  	// Avoid reclassification of pre/post-indexed loads and stores.
  1950  	if p.Scond == C_XPRE || p.Scond == C_XPOST {
  1951  		return lsc
  1952  	}
  1953  	if cmp(C_NSAUTO, lsc) || cmp(C_NSOREG, lsc) {
  1954  		return lsc
  1955  	}
  1956  
  1957  	needsPool := true
  1958  	if v >= -4095 && v <= 4095 {
  1959  		needsPool = false
  1960  	}
  1961  
  1962  	switch p.As {
  1963  	case AMOVB, AMOVBU:
  1964  		if cmp(C_UAUTO4K, lsc) || cmp(C_UOREG4K, lsc) {
  1965  			return lsc
  1966  		}
  1967  		if v >= 0 && v <= 0xffffff {
  1968  			needsPool = false
  1969  		}
  1970  	case AMOVH, AMOVHU:
  1971  		if cmp(C_UAUTO8K, lsc) || cmp(C_UOREG8K, lsc) {
  1972  			return lsc
  1973  		}
  1974  		if v >= 0 && v <= 0xfff000+0xfff<<1 && v&1 == 0 {
  1975  			needsPool = false
  1976  		}
  1977  	case AMOVW, AMOVWU, AFMOVS:
  1978  		if cmp(C_UAUTO16K, lsc) || cmp(C_UOREG16K, lsc) {
  1979  			return lsc
  1980  		}
  1981  		if v >= 0 && v <= 0xfff000+0xfff<<2 && v&3 == 0 {
  1982  			needsPool = false
  1983  		}
  1984  	case AMOVD, AFMOVD:
  1985  		if cmp(C_UAUTO32K, lsc) || cmp(C_UOREG32K, lsc) {
  1986  			return lsc
  1987  		}
  1988  		if v >= 0 && v <= 0xfff000+0xfff<<3 && v&7 == 0 {
  1989  			needsPool = false
  1990  		}
  1991  	case AFMOVQ:
  1992  		if cmp(C_UAUTO64K, lsc) || cmp(C_UOREG64K, lsc) {
  1993  			return lsc
  1994  		}
  1995  		if v >= 0 && v <= 0xfff000+0xfff<<4 && v&15 == 0 {
  1996  			needsPool = false
  1997  		}
  1998  	}
  1999  	if needsPool && cmp(C_LAUTO, lsc) {
  2000  		return C_LAUTOPOOL
  2001  	}
  2002  	if needsPool && cmp(C_LOREG, lsc) {
  2003  		return C_LOREGPOOL
  2004  	}
  2005  	return lsc
  2006  }
  2007  
  2008  // loadStorePairClass reclassifies a load or store pair operation based on its offset.
  2009  func (c *ctxt7) loadStorePairClass(p *obj.Prog, lsc int, v int64) int {
  2010  	// Avoid reclassification of pre/post-indexed loads and stores.
  2011  	if p.Scond == C_XPRE || p.Scond == C_XPOST {
  2012  		return lsc
  2013  	}
  2014  
  2015  	if cmp(C_NAUTO4K, lsc) || cmp(C_NOREG4K, lsc) {
  2016  		return lsc
  2017  	}
  2018  	if cmp(C_UAUTO4K, lsc) || cmp(C_UOREG4K, lsc) {
  2019  		return lsc
  2020  	}
  2021  
  2022  	needsPool := true
  2023  	if v >= 0 && v <= 0xffffff {
  2024  		needsPool = false
  2025  	}
  2026  	if needsPool && cmp(C_LAUTO, lsc) {
  2027  		return C_LAUTOPOOL
  2028  	}
  2029  	if needsPool && cmp(C_LOREG, lsc) {
  2030  		return C_LOREGPOOL
  2031  	}
  2032  	return lsc
  2033  }
  2034  
  2035  func (c *ctxt7) aclass(a *obj.Addr) int {
  2036  	switch a.Type {
  2037  	case obj.TYPE_NONE:
  2038  		return C_NONE
  2039  
  2040  	case obj.TYPE_REG:
  2041  		return rclass(a.Reg)
  2042  
  2043  	case obj.TYPE_REGREG:
  2044  		return C_PAIR
  2045  
  2046  	case obj.TYPE_SHIFT:
  2047  		return C_SHIFT
  2048  
  2049  	case obj.TYPE_REGLIST:
  2050  		return C_LIST
  2051  
  2052  	case obj.TYPE_MEM:
  2053  		// The base register should be an integer register.
  2054  		if int16(REG_F0) <= a.Reg && a.Reg <= int16(REG_V31) {
  2055  			break
  2056  		}
  2057  		switch a.Name {
  2058  		case obj.NAME_EXTERN, obj.NAME_STATIC:
  2059  			if a.Sym == nil {
  2060  				break
  2061  			}
  2062  			c.instoffset = a.Offset
  2063  			if a.Sym != nil { // use relocation
  2064  				if a.Sym.Type == objabi.STLSBSS {
  2065  					if c.ctxt.Flag_shared {
  2066  						return C_TLS_IE
  2067  					} else {
  2068  						return C_TLS_LE
  2069  					}
  2070  				}
  2071  				return C_ADDR
  2072  			}
  2073  			return C_LEXT
  2074  
  2075  		case obj.NAME_GOTREF:
  2076  			return C_GOTADDR
  2077  
  2078  		case obj.NAME_AUTO:
  2079  			if a.Reg == REGSP {
  2080  				// unset base register for better printing, since
  2081  				// a.Offset is still relative to pseudo-SP.
  2082  				a.Reg = obj.REG_NONE
  2083  			}
  2084  			// The frame top 8 or 16 bytes are for FP
  2085  			c.instoffset = int64(c.autosize) + a.Offset - int64(c.extrasize)
  2086  			return autoclass(c.instoffset)
  2087  
  2088  		case obj.NAME_PARAM:
  2089  			if a.Reg == REGSP {
  2090  				// unset base register for better printing, since
  2091  				// a.Offset is still relative to pseudo-FP.
  2092  				a.Reg = obj.REG_NONE
  2093  			}
  2094  			c.instoffset = int64(c.autosize) + a.Offset + 8
  2095  			return autoclass(c.instoffset)
  2096  
  2097  		case obj.NAME_NONE:
  2098  			if a.Index != 0 {
  2099  				if a.Offset != 0 {
  2100  					if isRegShiftOrExt(a) {
  2101  						// extended or shifted register offset, (Rn)(Rm.UXTW<<2) or (Rn)(Rm<<2).
  2102  						return C_ROFF
  2103  					}
  2104  					return C_GOK
  2105  				}
  2106  				// register offset, (Rn)(Rm)
  2107  				return C_ROFF
  2108  			}
  2109  			c.instoffset = a.Offset
  2110  			return oregclass(c.instoffset)
  2111  		}
  2112  		return C_GOK
  2113  
  2114  	case obj.TYPE_FCONST:
  2115  		return C_FCON
  2116  
  2117  	case obj.TYPE_TEXTSIZE:
  2118  		return C_TEXTSIZE
  2119  
  2120  	case obj.TYPE_CONST, obj.TYPE_ADDR:
  2121  		switch a.Name {
  2122  		case obj.NAME_NONE:
  2123  			c.instoffset = a.Offset
  2124  			if a.Reg != 0 && a.Reg != REGZERO {
  2125  				break
  2126  			}
  2127  			v := c.instoffset
  2128  			if v == 0 {
  2129  				return C_ZCON
  2130  			}
  2131  			if isaddcon(v) {
  2132  				if v <= 0xFFF {
  2133  					if isbitcon(uint64(v)) {
  2134  						return C_ABCON0
  2135  					}
  2136  					return C_ADDCON0
  2137  				}
  2138  				if isbitcon(uint64(v)) {
  2139  					return C_ABCON
  2140  				}
  2141  				if movcon(v) >= 0 {
  2142  					return C_AMCON
  2143  				}
  2144  				if movcon(^v) >= 0 {
  2145  					return C_AMCON
  2146  				}
  2147  				return C_ADDCON
  2148  			}
  2149  
  2150  			t := movcon(v)
  2151  			if t >= 0 {
  2152  				if isbitcon(uint64(v)) {
  2153  					return C_MBCON
  2154  				}
  2155  				return C_MOVCON
  2156  			}
  2157  
  2158  			t = movcon(^v)
  2159  			if t >= 0 {
  2160  				if isbitcon(uint64(v)) {
  2161  					return C_MBCON
  2162  				}
  2163  				return C_MOVCON
  2164  			}
  2165  
  2166  			if isbitcon(uint64(v)) {
  2167  				return C_BITCON
  2168  			}
  2169  
  2170  			if 0 <= v && v <= 0xffffff {
  2171  				return C_ADDCON2
  2172  			}
  2173  
  2174  			if uint64(v) == uint64(uint32(v)) || v == int64(int32(v)) {
  2175  				return C_LCON
  2176  			}
  2177  			return C_VCON
  2178  
  2179  		case obj.NAME_EXTERN, obj.NAME_STATIC:
  2180  			if a.Sym == nil {
  2181  				return C_GOK
  2182  			}
  2183  			if a.Sym.Type == objabi.STLSBSS {
  2184  				c.ctxt.Diag("taking address of TLS variable is not supported")
  2185  			}
  2186  			c.instoffset = a.Offset
  2187  			return C_VCONADDR
  2188  
  2189  		case obj.NAME_AUTO:
  2190  			if a.Reg == REGSP {
  2191  				// unset base register for better printing, since
  2192  				// a.Offset is still relative to pseudo-SP.
  2193  				a.Reg = obj.REG_NONE
  2194  			}
  2195  			// The frame top 8 or 16 bytes are for FP
  2196  			c.instoffset = int64(c.autosize) + a.Offset - int64(c.extrasize)
  2197  
  2198  		case obj.NAME_PARAM:
  2199  			if a.Reg == REGSP {
  2200  				// unset base register for better printing, since
  2201  				// a.Offset is still relative to pseudo-FP.
  2202  				a.Reg = obj.REG_NONE
  2203  			}
  2204  			c.instoffset = int64(c.autosize) + a.Offset + 8
  2205  		default:
  2206  			return C_GOK
  2207  		}
  2208  		cf := c.instoffset
  2209  		if isaddcon(cf) || isaddcon(-cf) {
  2210  			return C_AACON
  2211  		}
  2212  		if isaddcon2(cf) {
  2213  			return C_AACON2
  2214  		}
  2215  
  2216  		return C_LACON
  2217  
  2218  	case obj.TYPE_BRANCH:
  2219  		return C_SBRA
  2220  
  2221  	case obj.TYPE_SPECIAL:
  2222  		opd := SpecialOperand(a.Offset)
  2223  		if SPOP_EQ <= opd && opd <= SPOP_NV {
  2224  			return C_COND
  2225  		}
  2226  		return C_SPOP
  2227  	}
  2228  	return C_GOK
  2229  }
  2230  
  2231  func (c *ctxt7) oplook(p *obj.Prog) *Optab {
  2232  	a1 := int(p.Optab)
  2233  	if a1 != 0 {
  2234  		return &optab[a1-1]
  2235  	}
  2236  	a1 = int(p.From.Class)
  2237  	if a1 == 0 {
  2238  		a1 = c.aclass(&p.From)
  2239  		// do not break C_ADDCON2 when S bit is set
  2240  		if (p.As == AADDS || p.As == AADDSW || p.As == ASUBS || p.As == ASUBSW) && a1 == C_ADDCON2 {
  2241  			a1 = C_LCON
  2242  		}
  2243  		if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE {
  2244  			if p.As == AMOVW || isADDWop(p.As) || isANDWop(p.As) {
  2245  				// For 32-bit instruction with constant, we need to
  2246  				// treat its offset value as 32 bits to classify it.
  2247  				a1 = c.con32class(&p.From)
  2248  				// do not break C_ADDCON2 when S bit is set
  2249  				if (p.As == AADDSW || p.As == ASUBSW) && a1 == C_ADDCON2 {
  2250  					a1 = C_LCON
  2251  				}
  2252  			}
  2253  			if ((p.As == AMOVD) || isANDop(p.As) || isADDop(p.As)) && (a1 == C_LCON || a1 == C_VCON) {
  2254  				// more specific classification of 64-bit integers
  2255  				a1 = c.con64class(&p.From)
  2256  			}
  2257  		}
  2258  		if p.From.Type == obj.TYPE_MEM {
  2259  			if isMOVop(p.As) && (cmp(C_LAUTO, a1) || cmp(C_LOREG, a1)) {
  2260  				// More specific classification of large offset loads and stores.
  2261  				a1 = c.loadStoreClass(p, a1, c.instoffset)
  2262  			}
  2263  			if isLoadStorePairOp(p.As) && (cmp(C_LAUTO, a1) || cmp(C_LOREG, a1)) {
  2264  				// More specific classification of large offset loads and stores.
  2265  				a1 = c.loadStorePairClass(p, a1, c.instoffset)
  2266  			}
  2267  		}
  2268  		p.From.Class = int8(a1)
  2269  	}
  2270  
  2271  	a2 := C_NONE
  2272  	if p.Reg != 0 {
  2273  		a2 = rclass(p.Reg)
  2274  	}
  2275  
  2276  	a3 := C_NONE
  2277  	if p.GetFrom3() != nil {
  2278  		a3 = int(p.GetFrom3().Class)
  2279  		if a3 == 0 {
  2280  			a3 = c.aclass(p.GetFrom3())
  2281  			p.GetFrom3().Class = int8(a3)
  2282  		}
  2283  	}
  2284  
  2285  	a4 := int(p.To.Class)
  2286  	if a4 == 0 {
  2287  		a4 = c.aclass(&p.To)
  2288  		if p.To.Type == obj.TYPE_MEM {
  2289  			if isMOVop(p.As) && (cmp(C_LAUTO, a4) || cmp(C_LOREG, a4)) {
  2290  				// More specific classification of large offset loads and stores.
  2291  				a4 = c.loadStoreClass(p, a4, c.instoffset)
  2292  			}
  2293  			if isLoadStorePairOp(p.As) && (cmp(C_LAUTO, a4) || cmp(C_LOREG, a4)) {
  2294  				// More specific classification of large offset loads and stores.
  2295  				a4 = c.loadStorePairClass(p, a4, c.instoffset)
  2296  			}
  2297  		}
  2298  		p.To.Class = int8(a4)
  2299  	}
  2300  
  2301  	a5 := C_NONE
  2302  	if p.RegTo2 != 0 {
  2303  		a5 = rclass(p.RegTo2)
  2304  	} else if p.GetTo2() != nil {
  2305  		a5 = int(p.GetTo2().Class)
  2306  		if a5 == 0 {
  2307  			a5 = c.aclass(p.GetTo2())
  2308  			p.GetTo2().Class = int8(a5)
  2309  		}
  2310  	}
  2311  
  2312  	if false {
  2313  		fmt.Printf("oplook %v %d %d %d %d %d\n", p.As, a1, a2, a3, a4, a5)
  2314  		fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type)
  2315  	}
  2316  
  2317  	ops := oprange[p.As&obj.AMask]
  2318  	c1 := &xcmp[a1]
  2319  	c2 := &xcmp[a2]
  2320  	c3 := &xcmp[a3]
  2321  	c4 := &xcmp[a4]
  2322  	c5 := &xcmp[a5]
  2323  	for i := range ops {
  2324  		op := &ops[i]
  2325  		if c1[op.a1] && c2[op.a2] && c3[op.a3] && c4[op.a4] && c5[op.a5] && p.Scond == op.scond {
  2326  			p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
  2327  			return op
  2328  		}
  2329  	}
  2330  
  2331  	c.ctxt.Diag("illegal combination: %v %v %v %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4), DRconv(a5), p.From.Type, p.To.Type)
  2332  	// Turn illegal instruction into an UNDEF, avoid crashing in asmout
  2333  	return &Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0}
  2334  }
  2335  
  2336  func cmp(a int, b int) bool {
  2337  	if a == b {
  2338  		return true
  2339  	}
  2340  	switch a {
  2341  	case C_RSP:
  2342  		if b == C_REG {
  2343  			return true
  2344  		}
  2345  
  2346  	case C_ZREG:
  2347  		if b == C_REG {
  2348  			return true
  2349  		}
  2350  
  2351  	case C_ADDCON0:
  2352  		if b == C_ZCON || b == C_ABCON0 {
  2353  			return true
  2354  		}
  2355  
  2356  	case C_ADDCON:
  2357  		if b == C_ZCON || b == C_ABCON0 || b == C_ADDCON0 || b == C_ABCON || b == C_AMCON {
  2358  			return true
  2359  		}
  2360  
  2361  	case C_MBCON:
  2362  		if b == C_ABCON0 {
  2363  			return true
  2364  		}
  2365  
  2366  	case C_BITCON:
  2367  		if b == C_ABCON0 || b == C_ABCON || b == C_MBCON {
  2368  			return true
  2369  		}
  2370  
  2371  	case C_MOVCON:
  2372  		if b == C_MBCON || b == C_ZCON || b == C_ADDCON0 || b == C_ABCON0 || b == C_AMCON {
  2373  			return true
  2374  		}
  2375  
  2376  	case C_ADDCON2:
  2377  		if b == C_ZCON || b == C_ADDCON || b == C_ADDCON0 {
  2378  			return true
  2379  		}
  2380  
  2381  	case C_LCON:
  2382  		if b == C_ZCON || b == C_BITCON || b == C_ADDCON || b == C_ADDCON0 || b == C_ABCON || b == C_ABCON0 || b == C_MBCON || b == C_MOVCON || b == C_ADDCON2 || b == C_AMCON {
  2383  			return true
  2384  		}
  2385  
  2386  	case C_MOVCON2:
  2387  		return cmp(C_LCON, b)
  2388  
  2389  	case C_VCON:
  2390  		return cmp(C_LCON, b)
  2391  
  2392  	case C_LACON:
  2393  		if b == C_AACON || b == C_AACON2 {
  2394  			return true
  2395  		}
  2396  
  2397  	case C_SEXT2:
  2398  		if b == C_SEXT1 {
  2399  			return true
  2400  		}
  2401  
  2402  	case C_SEXT4:
  2403  		if b == C_SEXT1 || b == C_SEXT2 {
  2404  			return true
  2405  		}
  2406  
  2407  	case C_SEXT8:
  2408  		if b >= C_SEXT1 && b <= C_SEXT4 {
  2409  			return true
  2410  		}
  2411  
  2412  	case C_SEXT16:
  2413  		if b >= C_SEXT1 && b <= C_SEXT8 {
  2414  			return true
  2415  		}
  2416  
  2417  	case C_LEXT:
  2418  		if b >= C_SEXT1 && b <= C_SEXT16 {
  2419  			return true
  2420  		}
  2421  
  2422  	case C_NSAUTO_8:
  2423  		if b == C_NSAUTO_16 {
  2424  			return true
  2425  		}
  2426  
  2427  	case C_NSAUTO_4:
  2428  		if b == C_NSAUTO_16 || b == C_NSAUTO_8 {
  2429  			return true
  2430  		}
  2431  
  2432  	case C_NSAUTO:
  2433  		switch b {
  2434  		case C_NSAUTO_4, C_NSAUTO_8, C_NSAUTO_16:
  2435  			return true
  2436  		}
  2437  
  2438  	case C_NPAUTO_16:
  2439  		switch b {
  2440  		case C_NSAUTO_16:
  2441  			return true
  2442  		}
  2443  
  2444  	case C_NPAUTO:
  2445  		switch b {
  2446  		case C_NSAUTO_16, C_NSAUTO_8, C_NPAUTO_16:
  2447  			return true
  2448  		}
  2449  
  2450  	case C_NQAUTO_16:
  2451  		switch b {
  2452  		case C_NSAUTO_16, C_NPAUTO_16:
  2453  			return true
  2454  		}
  2455  
  2456  	case C_NAUTO4K:
  2457  		switch b {
  2458  		case C_NSAUTO_16, C_NSAUTO_8, C_NSAUTO_4, C_NSAUTO, C_NPAUTO_16,
  2459  			C_NPAUTO, C_NQAUTO_16:
  2460  			return true
  2461  		}
  2462  
  2463  	case C_PSAUTO_16:
  2464  		if b == C_ZAUTO {
  2465  			return true
  2466  		}
  2467  
  2468  	case C_PSAUTO_8:
  2469  		if b == C_ZAUTO || b == C_PSAUTO_16 {
  2470  			return true
  2471  		}
  2472  
  2473  	case C_PSAUTO_4:
  2474  		switch b {
  2475  		case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8:
  2476  			return true
  2477  		}
  2478  
  2479  	case C_PSAUTO:
  2480  		switch b {
  2481  		case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8, C_PSAUTO_4:
  2482  			return true
  2483  		}
  2484  
  2485  	case C_PPAUTO_16:
  2486  		switch b {
  2487  		case C_ZAUTO, C_PSAUTO_16:
  2488  			return true
  2489  		}
  2490  
  2491  	case C_PPAUTO:
  2492  		switch b {
  2493  		case C_ZAUTO, C_PSAUTO_16, C_PSAUTO_8, C_PPAUTO_16:
  2494  			return true
  2495  		}
  2496  
  2497  	case C_PQAUTO_16:
  2498  		switch b {
  2499  		case C_ZAUTO, C_PSAUTO_16, C_PPAUTO_16:
  2500  			return true
  2501  		}
  2502  
  2503  	case C_UAUTO4K:
  2504  		switch b {
  2505  		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
  2506  			C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
  2507  			C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16:
  2508  			return true
  2509  		}
  2510  
  2511  	case C_UAUTO8K:
  2512  		switch b {
  2513  		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
  2514  			C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
  2515  			C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16,
  2516  			C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16:
  2517  			return true
  2518  		}
  2519  
  2520  	case C_UAUTO16K:
  2521  		switch b {
  2522  		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
  2523  			C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
  2524  			C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16,
  2525  			C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16,
  2526  			C_UAUTO16K_8, C_UAUTO16K_16:
  2527  			return true
  2528  		}
  2529  
  2530  	case C_UAUTO32K:
  2531  		switch b {
  2532  		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
  2533  			C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
  2534  			C_UAUTO4K_8, C_UAUTO4K_16,
  2535  			C_UAUTO8K_8, C_UAUTO8K_16,
  2536  			C_UAUTO16K_8, C_UAUTO16K_16,
  2537  			C_UAUTO32K_16:
  2538  			return true
  2539  		}
  2540  
  2541  	case C_UAUTO64K:
  2542  		switch b {
  2543  		case C_ZAUTO, C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
  2544  			C_PPAUTO_16, C_PQAUTO_16, C_UAUTO4K_16, C_UAUTO8K_16, C_UAUTO16K_16,
  2545  			C_UAUTO32K_16:
  2546  			return true
  2547  		}
  2548  
  2549  	case C_LAUTO:
  2550  		switch b {
  2551  		case C_ZAUTO, C_NSAUTO, C_NSAUTO_4, C_NSAUTO_8, C_NSAUTO_16, C_NPAUTO_16, C_NPAUTO, C_NQAUTO_16, C_NAUTO4K,
  2552  			C_PSAUTO, C_PSAUTO_4, C_PSAUTO_8, C_PSAUTO_16,
  2553  			C_PPAUTO, C_PPAUTO_16, C_PQAUTO_16,
  2554  			C_UAUTO4K, C_UAUTO4K_2, C_UAUTO4K_4, C_UAUTO4K_8, C_UAUTO4K_16,
  2555  			C_UAUTO8K, C_UAUTO8K_4, C_UAUTO8K_8, C_UAUTO8K_16,
  2556  			C_UAUTO16K, C_UAUTO16K_8, C_UAUTO16K_16,
  2557  			C_UAUTO32K, C_UAUTO32K_16,
  2558  			C_UAUTO64K:
  2559  			return true
  2560  		}
  2561  
  2562  	case C_NSOREG_8:
  2563  		if b == C_NSOREG_16 {
  2564  			return true
  2565  		}
  2566  
  2567  	case C_NSOREG_4:
  2568  		if b == C_NSOREG_8 || b == C_NSOREG_16 {
  2569  			return true
  2570  		}
  2571  
  2572  	case C_NSOREG:
  2573  		switch b {
  2574  		case C_NSOREG_4, C_NSOREG_8, C_NSOREG_16:
  2575  			return true
  2576  		}
  2577  
  2578  	case C_NPOREG_16:
  2579  		switch b {
  2580  		case C_NSOREG_16:
  2581  			return true
  2582  		}
  2583  
  2584  	case C_NPOREG:
  2585  		switch b {
  2586  		case C_NSOREG_16, C_NSOREG_8, C_NPOREG_16:
  2587  			return true
  2588  		}
  2589  
  2590  	case C_NQOREG_16:
  2591  		switch b {
  2592  		case C_NSOREG_16, C_NPOREG_16:
  2593  			return true
  2594  		}
  2595  
  2596  	case C_NOREG4K:
  2597  		switch b {
  2598  		case C_NSOREG_16, C_NSOREG_8, C_NSOREG_4, C_NSOREG, C_NPOREG_16, C_NPOREG, C_NQOREG_16:
  2599  			return true
  2600  		}
  2601  
  2602  	case C_PSOREG_16:
  2603  		if b == C_ZOREG {
  2604  			return true
  2605  		}
  2606  
  2607  	case C_PSOREG_8:
  2608  		if b == C_ZOREG || b == C_PSOREG_16 {
  2609  			return true
  2610  		}
  2611  
  2612  	case C_PSOREG_4:
  2613  		switch b {
  2614  		case C_ZOREG, C_PSOREG_16, C_PSOREG_8:
  2615  			return true
  2616  		}
  2617  
  2618  	case C_PSOREG:
  2619  		switch b {
  2620  		case C_ZOREG, C_PSOREG_16, C_PSOREG_8, C_PSOREG_4:
  2621  			return true
  2622  		}
  2623  
  2624  	case C_PPOREG_16:
  2625  		switch b {
  2626  		case C_ZOREG, C_PSOREG_16:
  2627  			return true
  2628  		}
  2629  
  2630  	case C_PPOREG:
  2631  		switch b {
  2632  		case C_ZOREG, C_PSOREG_16, C_PSOREG_8, C_PPOREG_16:
  2633  			return true
  2634  		}
  2635  
  2636  	case C_PQOREG_16:
  2637  		switch b {
  2638  		case C_ZOREG, C_PSOREG_16, C_PPOREG_16:
  2639  			return true
  2640  		}
  2641  
  2642  	case C_UOREG4K:
  2643  		switch b {
  2644  		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
  2645  			C_PPOREG, C_PPOREG_16, C_PQOREG_16,
  2646  			C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16:
  2647  			return true
  2648  		}
  2649  
  2650  	case C_UOREG8K:
  2651  		switch b {
  2652  		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
  2653  			C_PPOREG, C_PPOREG_16, C_PQOREG_16,
  2654  			C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16,
  2655  			C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16:
  2656  			return true
  2657  		}
  2658  
  2659  	case C_UOREG16K:
  2660  		switch b {
  2661  		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
  2662  			C_PPOREG, C_PPOREG_16, C_PQOREG_16,
  2663  			C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16,
  2664  			C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16,
  2665  			C_UOREG16K_8, C_UOREG16K_16:
  2666  			return true
  2667  		}
  2668  
  2669  	case C_UOREG32K:
  2670  		switch b {
  2671  		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
  2672  			C_PPOREG, C_PPOREG_16, C_PQOREG_16,
  2673  			C_UOREG4K_8, C_UOREG4K_16,
  2674  			C_UOREG8K_8, C_UOREG8K_16,
  2675  			C_UOREG16K_8, C_UOREG16K_16,
  2676  			C_UOREG32K_16:
  2677  			return true
  2678  		}
  2679  
  2680  	case C_UOREG64K:
  2681  		switch b {
  2682  		case C_ZOREG, C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
  2683  			C_PPOREG_16, C_PQOREG_16, C_UOREG4K_16, C_UOREG8K_16, C_UOREG16K_16,
  2684  			C_UOREG32K_16:
  2685  			return true
  2686  		}
  2687  
  2688  	case C_LOREG:
  2689  		switch b {
  2690  		case C_ZOREG, C_NSOREG, C_NSOREG_4, C_NSOREG_8, C_NSOREG_16, C_NPOREG, C_NPOREG_16, C_NQOREG_16, C_NOREG4K,
  2691  			C_PSOREG, C_PSOREG_4, C_PSOREG_8, C_PSOREG_16,
  2692  			C_PPOREG, C_PPOREG_16, C_PQOREG_16,
  2693  			C_UOREG4K, C_UOREG4K_2, C_UOREG4K_4, C_UOREG4K_8, C_UOREG4K_16,
  2694  			C_UOREG8K, C_UOREG8K_4, C_UOREG8K_8, C_UOREG8K_16,
  2695  			C_UOREG16K, C_UOREG16K_8, C_UOREG16K_16,
  2696  			C_UOREG32K, C_UOREG32K_16,
  2697  			C_UOREG64K:
  2698  			return true
  2699  		}
  2700  
  2701  	case C_LBRA:
  2702  		if b == C_SBRA {
  2703  			return true
  2704  		}
  2705  	}
  2706  
  2707  	return false
  2708  }
  2709  
  2710  type ocmp []Optab
  2711  
  2712  func (x ocmp) Len() int {
  2713  	return len(x)
  2714  }
  2715  
  2716  func (x ocmp) Swap(i, j int) {
  2717  	x[i], x[j] = x[j], x[i]
  2718  }
  2719  
  2720  func (x ocmp) Less(i, j int) bool {
  2721  	p1 := &x[i]
  2722  	p2 := &x[j]
  2723  	if p1.as != p2.as {
  2724  		return p1.as < p2.as
  2725  	}
  2726  	if p1.a1 != p2.a1 {
  2727  		return p1.a1 < p2.a1
  2728  	}
  2729  	if p1.a2 != p2.a2 {
  2730  		return p1.a2 < p2.a2
  2731  	}
  2732  	if p1.a3 != p2.a3 {
  2733  		return p1.a3 < p2.a3
  2734  	}
  2735  	if p1.a4 != p2.a4 {
  2736  		return p1.a4 < p2.a4
  2737  	}
  2738  	if p1.scond != p2.scond {
  2739  		return p1.scond < p2.scond
  2740  	}
  2741  	return false
  2742  }
  2743  
  2744  func oprangeset(a obj.As, t []Optab) {
  2745  	oprange[a&obj.AMask] = t
  2746  }
  2747  
  2748  func buildop(ctxt *obj.Link) {
  2749  	if oprange[AAND&obj.AMask] != nil {
  2750  		// Already initialized; stop now.
  2751  		// This happens in the cmd/asm tests,
  2752  		// each of which re-initializes the arch.
  2753  		return
  2754  	}
  2755  
  2756  	for i := 0; i < C_GOK; i++ {
  2757  		for j := 0; j < C_GOK; j++ {
  2758  			if cmp(j, i) {
  2759  				xcmp[i][j] = true
  2760  			}
  2761  		}
  2762  	}
  2763  
  2764  	sort.Sort(ocmp(optab))
  2765  	for i := 0; i < len(optab); i++ {
  2766  		as, start := optab[i].as, i
  2767  		for ; i < len(optab)-1; i++ {
  2768  			if optab[i+1].as != as {
  2769  				break
  2770  			}
  2771  		}
  2772  		t := optab[start : i+1]
  2773  		oprangeset(as, t)
  2774  		switch as {
  2775  		default:
  2776  			ctxt.Diag("unknown op in build: %v", as)
  2777  			ctxt.DiagFlush()
  2778  			log.Fatalf("bad code")
  2779  
  2780  		case AADD:
  2781  			oprangeset(AADDS, t)
  2782  			oprangeset(ASUB, t)
  2783  			oprangeset(ASUBS, t)
  2784  			oprangeset(AADDW, t)
  2785  			oprangeset(AADDSW, t)
  2786  			oprangeset(ASUBW, t)
  2787  			oprangeset(ASUBSW, t)
  2788  
  2789  		case AAND: /* logical immediate, logical shifted register */
  2790  			oprangeset(AANDW, t)
  2791  			oprangeset(AEOR, t)
  2792  			oprangeset(AEORW, t)
  2793  			oprangeset(AORR, t)
  2794  			oprangeset(AORRW, t)
  2795  			oprangeset(ABIC, t)
  2796  			oprangeset(ABICW, t)
  2797  			oprangeset(AEON, t)
  2798  			oprangeset(AEONW, t)
  2799  			oprangeset(AORN, t)
  2800  			oprangeset(AORNW, t)
  2801  
  2802  		case AANDS: /* logical immediate, logical shifted register, set flags, cannot target RSP */
  2803  			oprangeset(AANDSW, t)
  2804  			oprangeset(ABICS, t)
  2805  			oprangeset(ABICSW, t)
  2806  
  2807  		case ANEG:
  2808  			oprangeset(ANEGS, t)
  2809  			oprangeset(ANEGSW, t)
  2810  			oprangeset(ANEGW, t)
  2811  
  2812  		case AADC: /* rn=Rd */
  2813  			oprangeset(AADCW, t)
  2814  
  2815  			oprangeset(AADCS, t)
  2816  			oprangeset(AADCSW, t)
  2817  			oprangeset(ASBC, t)
  2818  			oprangeset(ASBCW, t)
  2819  			oprangeset(ASBCS, t)
  2820  			oprangeset(ASBCSW, t)
  2821  
  2822  		case ANGC: /* rn=REGZERO */
  2823  			oprangeset(ANGCW, t)
  2824  
  2825  			oprangeset(ANGCS, t)
  2826  			oprangeset(ANGCSW, t)
  2827  
  2828  		case ACMP:
  2829  			oprangeset(ACMPW, t)
  2830  			oprangeset(ACMN, t)
  2831  			oprangeset(ACMNW, t)
  2832  
  2833  		case ATST:
  2834  			oprangeset(ATSTW, t)
  2835  
  2836  			/* register/register, and shifted */
  2837  		case AMVN:
  2838  			oprangeset(AMVNW, t)
  2839  
  2840  		case AMOVK:
  2841  			oprangeset(AMOVKW, t)
  2842  			oprangeset(AMOVN, t)
  2843  			oprangeset(AMOVNW, t)
  2844  			oprangeset(AMOVZ, t)
  2845  			oprangeset(AMOVZW, t)
  2846  
  2847  		case ASWPD:
  2848  			for i := range atomicLDADD {
  2849  				oprangeset(i, t)
  2850  			}
  2851  			for i := range atomicSWP {
  2852  				if i == ASWPD {
  2853  					continue
  2854  				}
  2855  				oprangeset(i, t)
  2856  			}
  2857  
  2858  		case ACASPD:
  2859  			oprangeset(ACASPW, t)
  2860  		case ABEQ:
  2861  			oprangeset(ABNE, t)
  2862  			oprangeset(ABCS, t)
  2863  			oprangeset(ABHS, t)
  2864  			oprangeset(ABCC, t)
  2865  			oprangeset(ABLO, t)
  2866  			oprangeset(ABMI, t)
  2867  			oprangeset(ABPL, t)
  2868  			oprangeset(ABVS, t)
  2869  			oprangeset(ABVC, t)
  2870  			oprangeset(ABHI, t)
  2871  			oprangeset(ABLS, t)
  2872  			oprangeset(ABGE, t)
  2873  			oprangeset(ABLT, t)
  2874  			oprangeset(ABGT, t)
  2875  			oprangeset(ABLE, t)
  2876  
  2877  		case ALSL:
  2878  			oprangeset(ALSLW, t)
  2879  			oprangeset(ALSR, t)
  2880  			oprangeset(ALSRW, t)
  2881  			oprangeset(AASR, t)
  2882  			oprangeset(AASRW, t)
  2883  			oprangeset(AROR, t)
  2884  			oprangeset(ARORW, t)
  2885  
  2886  		case ACLS:
  2887  			oprangeset(ACLSW, t)
  2888  			oprangeset(ACLZ, t)
  2889  			oprangeset(ACLZW, t)
  2890  			oprangeset(ARBIT, t)
  2891  			oprangeset(ARBITW, t)
  2892  			oprangeset(AREV, t)
  2893  			oprangeset(AREVW, t)
  2894  			oprangeset(AREV16, t)
  2895  			oprangeset(AREV16W, t)
  2896  			oprangeset(AREV32, t)
  2897  
  2898  		case ASDIV:
  2899  			oprangeset(ASDIVW, t)
  2900  			oprangeset(AUDIV, t)
  2901  			oprangeset(AUDIVW, t)
  2902  			oprangeset(ACRC32B, t)
  2903  			oprangeset(ACRC32CB, t)
  2904  			oprangeset(ACRC32CH, t)
  2905  			oprangeset(ACRC32CW, t)
  2906  			oprangeset(ACRC32CX, t)
  2907  			oprangeset(ACRC32H, t)
  2908  			oprangeset(ACRC32W, t)
  2909  			oprangeset(ACRC32X, t)
  2910  
  2911  		case AMADD:
  2912  			oprangeset(AMADDW, t)
  2913  			oprangeset(AMSUB, t)
  2914  			oprangeset(AMSUBW, t)
  2915  			oprangeset(ASMADDL, t)
  2916  			oprangeset(ASMSUBL, t)
  2917  			oprangeset(AUMADDL, t)
  2918  			oprangeset(AUMSUBL, t)
  2919  
  2920  		case AREM:
  2921  			oprangeset(AREMW, t)
  2922  			oprangeset(AUREM, t)
  2923  			oprangeset(AUREMW, t)
  2924  
  2925  		case AMUL:
  2926  			oprangeset(AMULW, t)
  2927  			oprangeset(AMNEG, t)
  2928  			oprangeset(AMNEGW, t)
  2929  			oprangeset(ASMNEGL, t)
  2930  			oprangeset(ASMULL, t)
  2931  			oprangeset(ASMULH, t)
  2932  			oprangeset(AUMNEGL, t)
  2933  			oprangeset(AUMULH, t)
  2934  			oprangeset(AUMULL, t)
  2935  
  2936  		case AMOVB:
  2937  			oprangeset(AMOVBU, t)
  2938  
  2939  		case AMOVH:
  2940  			oprangeset(AMOVHU, t)
  2941  
  2942  		case AMOVW:
  2943  			oprangeset(AMOVWU, t)
  2944  
  2945  		case ABFM:
  2946  			oprangeset(ABFMW, t)
  2947  			oprangeset(ASBFM, t)
  2948  			oprangeset(ASBFMW, t)
  2949  			oprangeset(AUBFM, t)
  2950  			oprangeset(AUBFMW, t)
  2951  
  2952  		case ABFI:
  2953  			oprangeset(ABFIW, t)
  2954  			oprangeset(ABFXIL, t)
  2955  			oprangeset(ABFXILW, t)
  2956  			oprangeset(ASBFIZ, t)
  2957  			oprangeset(ASBFIZW, t)
  2958  			oprangeset(ASBFX, t)
  2959  			oprangeset(ASBFXW, t)
  2960  			oprangeset(AUBFIZ, t)
  2961  			oprangeset(AUBFIZW, t)
  2962  			oprangeset(AUBFX, t)
  2963  			oprangeset(AUBFXW, t)
  2964  
  2965  		case AEXTR:
  2966  			oprangeset(AEXTRW, t)
  2967  
  2968  		case ASXTB:
  2969  			oprangeset(ASXTBW, t)
  2970  			oprangeset(ASXTH, t)
  2971  			oprangeset(ASXTHW, t)
  2972  			oprangeset(ASXTW, t)
  2973  			oprangeset(AUXTB, t)
  2974  			oprangeset(AUXTH, t)
  2975  			oprangeset(AUXTW, t)
  2976  			oprangeset(AUXTBW, t)
  2977  			oprangeset(AUXTHW, t)
  2978  
  2979  		case ACCMN:
  2980  			oprangeset(ACCMNW, t)
  2981  			oprangeset(ACCMP, t)
  2982  			oprangeset(ACCMPW, t)
  2983  
  2984  		case ACSEL:
  2985  			oprangeset(ACSELW, t)
  2986  			oprangeset(ACSINC, t)
  2987  			oprangeset(ACSINCW, t)
  2988  			oprangeset(ACSINV, t)
  2989  			oprangeset(ACSINVW, t)
  2990  			oprangeset(ACSNEG, t)
  2991  			oprangeset(ACSNEGW, t)
  2992  
  2993  		case ACINC:
  2994  			// aliases Rm=Rn, !cond
  2995  			oprangeset(ACINCW, t)
  2996  			oprangeset(ACINV, t)
  2997  			oprangeset(ACINVW, t)
  2998  			oprangeset(ACNEG, t)
  2999  			oprangeset(ACNEGW, t)
  3000  
  3001  			// aliases, Rm=Rn=REGZERO, !cond
  3002  		case ACSET:
  3003  			oprangeset(ACSETW, t)
  3004  
  3005  			oprangeset(ACSETM, t)
  3006  			oprangeset(ACSETMW, t)
  3007  
  3008  		case AMOVD,
  3009  			AB,
  3010  			ABL,
  3011  			AWORD,
  3012  			ADWORD,
  3013  			obj.ARET,
  3014  			obj.ATEXT:
  3015  			break
  3016  
  3017  		case AFLDPQ:
  3018  			break
  3019  		case AFSTPQ:
  3020  			break
  3021  		case ALDP:
  3022  			oprangeset(AFLDPD, t)
  3023  
  3024  		case ASTP:
  3025  			oprangeset(AFSTPD, t)
  3026  
  3027  		case ASTPW:
  3028  			oprangeset(AFSTPS, t)
  3029  
  3030  		case ALDPW:
  3031  			oprangeset(ALDPSW, t)
  3032  			oprangeset(AFLDPS, t)
  3033  
  3034  		case AERET:
  3035  			oprangeset(AWFE, t)
  3036  			oprangeset(AWFI, t)
  3037  			oprangeset(AYIELD, t)
  3038  			oprangeset(ASEV, t)
  3039  			oprangeset(ASEVL, t)
  3040  			oprangeset(ANOOP, t)
  3041  			oprangeset(ADRPS, t)
  3042  
  3043  		case ACBZ:
  3044  			oprangeset(ACBZW, t)
  3045  			oprangeset(ACBNZ, t)
  3046  			oprangeset(ACBNZW, t)
  3047  
  3048  		case ATBZ:
  3049  			oprangeset(ATBNZ, t)
  3050  
  3051  		case AADR, AADRP:
  3052  			break
  3053  
  3054  		case ACLREX:
  3055  			break
  3056  
  3057  		case ASVC:
  3058  			oprangeset(AHVC, t)
  3059  			oprangeset(AHLT, t)
  3060  			oprangeset(ASMC, t)
  3061  			oprangeset(ABRK, t)
  3062  			oprangeset(ADCPS1, t)
  3063  			oprangeset(ADCPS2, t)
  3064  			oprangeset(ADCPS3, t)
  3065  
  3066  		case AFADDS:
  3067  			oprangeset(AFADDD, t)
  3068  			oprangeset(AFSUBS, t)
  3069  			oprangeset(AFSUBD, t)
  3070  			oprangeset(AFMULS, t)
  3071  			oprangeset(AFMULD, t)
  3072  			oprangeset(AFNMULS, t)
  3073  			oprangeset(AFNMULD, t)
  3074  			oprangeset(AFDIVS, t)
  3075  			oprangeset(AFMAXD, t)
  3076  			oprangeset(AFMAXS, t)
  3077  			oprangeset(AFMIND, t)
  3078  			oprangeset(AFMINS, t)
  3079  			oprangeset(AFMAXNMD, t)
  3080  			oprangeset(AFMAXNMS, t)
  3081  			oprangeset(AFMINNMD, t)
  3082  			oprangeset(AFMINNMS, t)
  3083  			oprangeset(AFDIVD, t)
  3084  
  3085  		case AFMSUBD:
  3086  			oprangeset(AFMSUBS, t)
  3087  			oprangeset(AFMADDS, t)
  3088  			oprangeset(AFMADDD, t)
  3089  			oprangeset(AFNMSUBS, t)
  3090  			oprangeset(AFNMSUBD, t)
  3091  			oprangeset(AFNMADDS, t)
  3092  			oprangeset(AFNMADDD, t)
  3093  
  3094  		case AFCVTSD:
  3095  			oprangeset(AFCVTDS, t)
  3096  			oprangeset(AFABSD, t)
  3097  			oprangeset(AFABSS, t)
  3098  			oprangeset(AFNEGD, t)
  3099  			oprangeset(AFNEGS, t)
  3100  			oprangeset(AFSQRTD, t)
  3101  			oprangeset(AFSQRTS, t)
  3102  			oprangeset(AFRINTNS, t)
  3103  			oprangeset(AFRINTND, t)
  3104  			oprangeset(AFRINTPS, t)
  3105  			oprangeset(AFRINTPD, t)
  3106  			oprangeset(AFRINTMS, t)
  3107  			oprangeset(AFRINTMD, t)
  3108  			oprangeset(AFRINTZS, t)
  3109  			oprangeset(AFRINTZD, t)
  3110  			oprangeset(AFRINTAS, t)
  3111  			oprangeset(AFRINTAD, t)
  3112  			oprangeset(AFRINTXS, t)
  3113  			oprangeset(AFRINTXD, t)
  3114  			oprangeset(AFRINTIS, t)
  3115  			oprangeset(AFRINTID, t)
  3116  			oprangeset(AFCVTDH, t)
  3117  			oprangeset(AFCVTHS, t)
  3118  			oprangeset(AFCVTHD, t)
  3119  			oprangeset(AFCVTSH, t)
  3120  
  3121  		case AFCMPS:
  3122  			oprangeset(AFCMPD, t)
  3123  			oprangeset(AFCMPES, t)
  3124  			oprangeset(AFCMPED, t)
  3125  
  3126  		case AFCCMPS:
  3127  			oprangeset(AFCCMPD, t)
  3128  			oprangeset(AFCCMPES, t)
  3129  			oprangeset(AFCCMPED, t)
  3130  
  3131  		case AFCSELD:
  3132  			oprangeset(AFCSELS, t)
  3133  
  3134  		case AFMOVQ, AFMOVD, AFMOVS,
  3135  			AVMOVQ, AVMOVD, AVMOVS:
  3136  			break
  3137  
  3138  		case AFCVTZSD:
  3139  			oprangeset(AFCVTZSDW, t)
  3140  			oprangeset(AFCVTZSS, t)
  3141  			oprangeset(AFCVTZSSW, t)
  3142  			oprangeset(AFCVTZUD, t)
  3143  			oprangeset(AFCVTZUDW, t)
  3144  			oprangeset(AFCVTZUS, t)
  3145  			oprangeset(AFCVTZUSW, t)
  3146  
  3147  		case ASCVTFD:
  3148  			oprangeset(ASCVTFS, t)
  3149  			oprangeset(ASCVTFWD, t)
  3150  			oprangeset(ASCVTFWS, t)
  3151  			oprangeset(AUCVTFD, t)
  3152  			oprangeset(AUCVTFS, t)
  3153  			oprangeset(AUCVTFWD, t)
  3154  			oprangeset(AUCVTFWS, t)
  3155  
  3156  		case ASYS:
  3157  			oprangeset(AAT, t)
  3158  			oprangeset(AIC, t)
  3159  
  3160  		case ATLBI:
  3161  			oprangeset(ADC, t)
  3162  
  3163  		case ASYSL, AHINT:
  3164  			break
  3165  
  3166  		case ADMB:
  3167  			oprangeset(ADSB, t)
  3168  			oprangeset(AISB, t)
  3169  
  3170  		case AMRS, AMSR:
  3171  			break
  3172  
  3173  		case ALDAR:
  3174  			oprangeset(ALDARW, t)
  3175  			oprangeset(ALDARB, t)
  3176  			oprangeset(ALDARH, t)
  3177  			fallthrough
  3178  
  3179  		case ALDXR:
  3180  			oprangeset(ALDXRB, t)
  3181  			oprangeset(ALDXRH, t)
  3182  			oprangeset(ALDXRW, t)
  3183  
  3184  		case ALDAXR:
  3185  			oprangeset(ALDAXRB, t)
  3186  			oprangeset(ALDAXRH, t)
  3187  			oprangeset(ALDAXRW, t)
  3188  
  3189  		case ALDXP:
  3190  			oprangeset(ALDXPW, t)
  3191  			oprangeset(ALDAXP, t)
  3192  			oprangeset(ALDAXPW, t)
  3193  
  3194  		case ASTLR:
  3195  			oprangeset(ASTLRB, t)
  3196  			oprangeset(ASTLRH, t)
  3197  			oprangeset(ASTLRW, t)
  3198  
  3199  		case ASTXR:
  3200  			oprangeset(ASTXRB, t)
  3201  			oprangeset(ASTXRH, t)
  3202  			oprangeset(ASTXRW, t)
  3203  
  3204  		case ASTLXR:
  3205  			oprangeset(ASTLXRB, t)
  3206  			oprangeset(ASTLXRH, t)
  3207  			oprangeset(ASTLXRW, t)
  3208  
  3209  		case ASTXP:
  3210  			oprangeset(ASTLXP, t)
  3211  			oprangeset(ASTLXPW, t)
  3212  			oprangeset(ASTXPW, t)
  3213  
  3214  		case AVADDP:
  3215  			oprangeset(AVAND, t)
  3216  			oprangeset(AVCMEQ, t)
  3217  			oprangeset(AVORR, t)
  3218  			oprangeset(AVEOR, t)
  3219  			oprangeset(AVBSL, t)
  3220  			oprangeset(AVBIT, t)
  3221  			oprangeset(AVCMTST, t)
  3222  			oprangeset(AVUMAX, t)
  3223  			oprangeset(AVUMIN, t)
  3224  			oprangeset(AVUZP1, t)
  3225  			oprangeset(AVUZP2, t)
  3226  			oprangeset(AVBIF, t)
  3227  
  3228  		case AVADD:
  3229  			oprangeset(AVSUB, t)
  3230  			oprangeset(AVRAX1, t)
  3231  
  3232  		case AAESD:
  3233  			oprangeset(AAESE, t)
  3234  			oprangeset(AAESMC, t)
  3235  			oprangeset(AAESIMC, t)
  3236  			oprangeset(ASHA1SU1, t)
  3237  			oprangeset(ASHA256SU0, t)
  3238  			oprangeset(ASHA512SU0, t)
  3239  			oprangeset(ASHA1H, t)
  3240  
  3241  		case ASHA1C:
  3242  			oprangeset(ASHA1P, t)
  3243  			oprangeset(ASHA1M, t)
  3244  			oprangeset(ASHA256H, t)
  3245  			oprangeset(ASHA256H2, t)
  3246  			oprangeset(ASHA512H, t)
  3247  			oprangeset(ASHA512H2, t)
  3248  
  3249  		case ASHA1SU0:
  3250  			oprangeset(ASHA256SU1, t)
  3251  			oprangeset(ASHA512SU1, t)
  3252  
  3253  		case AVADDV:
  3254  			oprangeset(AVUADDLV, t)
  3255  
  3256  		case AVFMLA:
  3257  			oprangeset(AVFMLS, t)
  3258  
  3259  		case AVPMULL:
  3260  			oprangeset(AVPMULL2, t)
  3261  
  3262  		case AVUSHR:
  3263  			oprangeset(AVSHL, t)
  3264  			oprangeset(AVSRI, t)
  3265  			oprangeset(AVSLI, t)
  3266  			oprangeset(AVUSRA, t)
  3267  
  3268  		case AVREV32:
  3269  			oprangeset(AVCNT, t)
  3270  			oprangeset(AVRBIT, t)
  3271  			oprangeset(AVREV64, t)
  3272  			oprangeset(AVREV16, t)
  3273  
  3274  		case AVZIP1:
  3275  			oprangeset(AVZIP2, t)
  3276  			oprangeset(AVTRN1, t)
  3277  			oprangeset(AVTRN2, t)
  3278  
  3279  		case AVUXTL:
  3280  			oprangeset(AVUXTL2, t)
  3281  
  3282  		case AVUSHLL:
  3283  			oprangeset(AVUSHLL2, t)
  3284  
  3285  		case AVLD1R:
  3286  			oprangeset(AVLD2, t)
  3287  			oprangeset(AVLD2R, t)
  3288  			oprangeset(AVLD3, t)
  3289  			oprangeset(AVLD3R, t)
  3290  			oprangeset(AVLD4, t)
  3291  			oprangeset(AVLD4R, t)
  3292  
  3293  		case AVEOR3:
  3294  			oprangeset(AVBCAX, t)
  3295  
  3296  		case AVUADDW:
  3297  			oprangeset(AVUADDW2, t)
  3298  
  3299  		case AVTBL:
  3300  			oprangeset(AVTBX, t)
  3301  
  3302  		case AVCNT,
  3303  			AVMOV,
  3304  			AVLD1,
  3305  			AVST1,
  3306  			AVST2,
  3307  			AVST3,
  3308  			AVST4,
  3309  			AVDUP,
  3310  			AVMOVI,
  3311  			APRFM,
  3312  			AVEXT,
  3313  			AVXAR:
  3314  			break
  3315  
  3316  		case obj.ANOP,
  3317  			obj.AUNDEF,
  3318  			obj.AFUNCDATA,
  3319  			obj.APCALIGN,
  3320  			obj.APCDATA,
  3321  			obj.ADUFFZERO,
  3322  			obj.ADUFFCOPY:
  3323  			break
  3324  		}
  3325  	}
  3326  }
  3327  
  3328  // chipfloat7() checks if the immediate constants available in  FMOVS/FMOVD instructions.
  3329  // For details of the range of constants available, see
  3330  // http://infocenter.arm.com/help/topic/com.arm.doc.dui0473m/dom1359731199385.html.
  3331  func (c *ctxt7) chipfloat7(e float64) int {
  3332  	ei := math.Float64bits(e)
  3333  	l := uint32(int32(ei))
  3334  	h := uint32(int32(ei >> 32))
  3335  
  3336  	if l != 0 || h&0xffff != 0 {
  3337  		return -1
  3338  	}
  3339  	h1 := h & 0x7fc00000
  3340  	if h1 != 0x40000000 && h1 != 0x3fc00000 {
  3341  		return -1
  3342  	}
  3343  	n := 0
  3344  
  3345  	// sign bit (a)
  3346  	if h&0x80000000 != 0 {
  3347  		n |= 1 << 7
  3348  	}
  3349  
  3350  	// exp sign bit (b)
  3351  	if h1 == 0x3fc00000 {
  3352  		n |= 1 << 6
  3353  	}
  3354  
  3355  	// rest of exp and mantissa (cd-efgh)
  3356  	n |= int((h >> 16) & 0x3f)
  3357  
  3358  	//print("match %.8lux %.8lux %d\n", l, h, n);
  3359  	return n
  3360  }
  3361  
  3362  /* form offset parameter to SYS; special register number */
  3363  func SYSARG5(op0 int, op1 int, Cn int, Cm int, op2 int) int {
  3364  	return op0<<19 | op1<<16 | Cn<<12 | Cm<<8 | op2<<5
  3365  }
  3366  
  3367  func SYSARG4(op1 int, Cn int, Cm int, op2 int) int {
  3368  	return SYSARG5(0, op1, Cn, Cm, op2)
  3369  }
  3370  
  3371  // checkUnpredictable checks if the source and transfer registers are the same register.
  3372  // ARM64 manual says it is "constrained unpredictable" if the src and dst registers of STP/LDP are same.
  3373  func (c *ctxt7) checkUnpredictable(p *obj.Prog, isload bool, wback bool, rn int16, rt1 int16, rt2 int16) {
  3374  	if wback && rn != REGSP && (rn == rt1 || rn == rt2) {
  3375  		c.ctxt.Diag("constrained unpredictable behavior: %v", p)
  3376  	}
  3377  	if isload && rt1 == rt2 {
  3378  		c.ctxt.Diag("constrained unpredictable behavior: %v", p)
  3379  	}
  3380  }
  3381  
  3382  /* checkindex checks if index >= 0 && index <= maxindex */
  3383  func (c *ctxt7) checkindex(p *obj.Prog, index, maxindex int) {
  3384  	if index < 0 || index > maxindex {
  3385  		c.ctxt.Diag("register element index out of range 0 to %d: %v", maxindex, p)
  3386  	}
  3387  }
  3388  
  3389  /* checkoffset checks whether the immediate offset is valid for VLD[1-4].P and VST[1-4].P */
  3390  func (c *ctxt7) checkoffset(p *obj.Prog, as obj.As) {
  3391  	var offset, list, n, expect int64
  3392  	switch as {
  3393  	case AVLD1, AVLD2, AVLD3, AVLD4, AVLD1R, AVLD2R, AVLD3R, AVLD4R:
  3394  		offset = p.From.Offset
  3395  		list = p.To.Offset
  3396  	case AVST1, AVST2, AVST3, AVST4:
  3397  		offset = p.To.Offset
  3398  		list = p.From.Offset
  3399  	default:
  3400  		c.ctxt.Diag("invalid operation on op %v", p.As)
  3401  	}
  3402  	opcode := (list >> 12) & 15
  3403  	q := (list >> 30) & 1
  3404  	size := (list >> 10) & 3
  3405  	if offset == 0 {
  3406  		return
  3407  	}
  3408  	switch opcode {
  3409  	case 0x7:
  3410  		n = 1 // one register
  3411  	case 0xa:
  3412  		n = 2 // two registers
  3413  	case 0x6:
  3414  		n = 3 // three registers
  3415  	case 0x2:
  3416  		n = 4 // four registers
  3417  	default:
  3418  		c.ctxt.Diag("invalid register numbers in ARM64 register list: %v", p)
  3419  	}
  3420  
  3421  	switch as {
  3422  	case AVLD1R, AVLD2R, AVLD3R, AVLD4R:
  3423  		if offset != n*(1<<uint(size)) {
  3424  			c.ctxt.Diag("invalid post-increment offset: %v", p)
  3425  		}
  3426  	default:
  3427  		if !(q == 0 && offset == n*8) && !(q == 1 && offset == n*16) {
  3428  			c.ctxt.Diag("invalid post-increment offset: %v", p)
  3429  		}
  3430  	}
  3431  
  3432  	switch as {
  3433  	case AVLD1, AVST1:
  3434  		return
  3435  	case AVLD1R:
  3436  		expect = 1
  3437  	case AVLD2, AVST2, AVLD2R:
  3438  		expect = 2
  3439  	case AVLD3, AVST3, AVLD3R:
  3440  		expect = 3
  3441  	case AVLD4, AVST4, AVLD4R:
  3442  		expect = 4
  3443  	}
  3444  
  3445  	if expect != n {
  3446  		c.ctxt.Diag("expected %d registers, got %d: %v.", expect, n, p)
  3447  	}
  3448  }
  3449  
  3450  /* checkShiftAmount checks whether the index shift amount is valid */
  3451  /* for load with register offset instructions */
  3452  func (c *ctxt7) checkShiftAmount(p *obj.Prog, a *obj.Addr) {
  3453  	var amount int16
  3454  	amount = (a.Index >> 5) & 7
  3455  	switch p.As {
  3456  	case AMOVB, AMOVBU:
  3457  		if amount != 0 {
  3458  			c.ctxt.Diag("invalid index shift amount: %v", p)
  3459  		}
  3460  	case AMOVH, AMOVHU:
  3461  		if amount != 1 && amount != 0 {
  3462  			c.ctxt.Diag("invalid index shift amount: %v", p)
  3463  		}
  3464  	case AMOVW, AMOVWU, AFMOVS:
  3465  		if amount != 2 && amount != 0 {
  3466  			c.ctxt.Diag("invalid index shift amount: %v", p)
  3467  		}
  3468  	case AMOVD, AFMOVD:
  3469  		if amount != 3 && amount != 0 {
  3470  			c.ctxt.Diag("invalid index shift amount: %v", p)
  3471  		}
  3472  	default:
  3473  		panic("invalid operation")
  3474  	}
  3475  }
  3476  
  3477  func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
  3478  	var os [5]uint32
  3479  	o1 := uint32(0)
  3480  	o2 := uint32(0)
  3481  	o3 := uint32(0)
  3482  	o4 := uint32(0)
  3483  	o5 := uint32(0)
  3484  	if false { /*debug['P']*/
  3485  		fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_)
  3486  	}
  3487  	switch o.type_ {
  3488  	default:
  3489  		c.ctxt.Diag("%v: unknown asm %d", p, o.type_)
  3490  
  3491  	case 0: /* pseudo ops */
  3492  		break
  3493  
  3494  	case 1: /* op Rm,[Rn],Rd; default Rn=Rd -> op Rm<<0,[Rn,]Rd (shifted register) */
  3495  		o1 = c.oprrr(p, p.As)
  3496  
  3497  		rf := int(p.From.Reg)
  3498  		rt := int(p.To.Reg)
  3499  		r := int(p.Reg)
  3500  		if p.To.Type == obj.TYPE_NONE {
  3501  			rt = REGZERO
  3502  		}
  3503  		if r == obj.REG_NONE {
  3504  			r = rt
  3505  		}
  3506  		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
  3507  
  3508  	case 2: /* add/sub $(uimm12|uimm24)[,R],R; cmp $(uimm12|uimm24),R */
  3509  		if p.To.Reg == REG_RSP && isADDSop(p.As) {
  3510  			c.ctxt.Diag("illegal destination register: %v\n", p)
  3511  		}
  3512  		o1 = c.opirr(p, p.As)
  3513  
  3514  		rt, r := p.To.Reg, p.Reg
  3515  		if p.To.Type == obj.TYPE_NONE {
  3516  			if (o1 & Sbit) == 0 {
  3517  				c.ctxt.Diag("ineffective ZR destination\n%v", p)
  3518  			}
  3519  			rt = REGZERO
  3520  		}
  3521  		if r == obj.REG_NONE {
  3522  			r = rt
  3523  		}
  3524  		v := c.regoff(&p.From)
  3525  		o1 = c.oaddi(p, p.As, v, rt, r)
  3526  
  3527  	case 3: /* op R<<n[,R],R (shifted register) */
  3528  		o1 = c.oprrr(p, p.As)
  3529  
  3530  		amount := (p.From.Offset >> 10) & 63
  3531  		is64bit := o1 & (1 << 31)
  3532  		if is64bit == 0 && amount >= 32 {
  3533  			c.ctxt.Diag("shift amount out of range 0 to 31: %v", p)
  3534  		}
  3535  		shift := (p.From.Offset >> 22) & 3
  3536  		if (shift > 2 || shift < 0) && (isADDop(p.As) || isADDWop(p.As) || isNEGop(p.As)) {
  3537  			c.ctxt.Diag("unsupported shift operator: %v", p)
  3538  		}
  3539  		o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
  3540  		rt := int(p.To.Reg)
  3541  		if p.To.Type == obj.TYPE_NONE {
  3542  			rt = REGZERO
  3543  		}
  3544  		r := int(p.Reg)
  3545  		if p.As == AMVN || p.As == AMVNW || isNEGop(p.As) {
  3546  			r = REGZERO
  3547  		} else if r == obj.REG_NONE {
  3548  			r = rt
  3549  		}
  3550  		o1 |= (uint32(r&31) << 5) | uint32(rt&31)
  3551  
  3552  	case 4: /* mov $addcon, R; mov $recon, R; mov $racon, R; mov $addcon2, R */
  3553  		rt, r := p.To.Reg, o.param
  3554  		if r == obj.REG_NONE {
  3555  			r = REGZERO
  3556  		} else if r == REGFROM {
  3557  			r = p.From.Reg
  3558  		}
  3559  		if r == obj.REG_NONE {
  3560  			r = REGSP
  3561  		}
  3562  
  3563  		v := c.regoff(&p.From)
  3564  		a := AADD
  3565  		if v < 0 {
  3566  			a = ASUB
  3567  			v = -v
  3568  		}
  3569  
  3570  		if o.size(c.ctxt, p) == 8 {
  3571  			// NOTE: this case does not use REGTMP. If it ever does,
  3572  			// remove the NOTUSETMP flag in optab.
  3573  			o1 = c.oaddi(p, a, v&0xfff000, rt, r)
  3574  			o2 = c.oaddi(p, a, v&0x000fff, rt, rt)
  3575  			break
  3576  		}
  3577  
  3578  		o1 = c.oaddi(p, a, v, rt, r)
  3579  
  3580  	case 5: /* b s; bl s */
  3581  		o1 = c.opbra(p, p.As)
  3582  
  3583  		if p.To.Sym == nil {
  3584  			o1 |= uint32(c.brdist(p, 0, 26, 2))
  3585  			break
  3586  		}
  3587  
  3588  		rel := obj.Addrel(c.cursym)
  3589  		rel.Off = int32(c.pc)
  3590  		rel.Siz = 4
  3591  		rel.Sym = p.To.Sym
  3592  		rel.Add = p.To.Offset
  3593  		rel.Type = objabi.R_CALLARM64
  3594  
  3595  	case 6: /* b ,O(R); bl ,O(R) */
  3596  		o1 = c.opbrr(p, p.As)
  3597  		o1 |= uint32(p.To.Reg&31) << 5
  3598  		if p.As == obj.ACALL {
  3599  			rel := obj.Addrel(c.cursym)
  3600  			rel.Off = int32(c.pc)
  3601  			rel.Siz = 0
  3602  			rel.Type = objabi.R_CALLIND
  3603  		}
  3604  
  3605  	case 7: /* beq s */
  3606  		o1 = c.opbra(p, p.As)
  3607  
  3608  		o1 |= uint32(c.brdist(p, 0, 19, 2) << 5)
  3609  
  3610  	case 8: /* lsl $c,[R],R -> ubfm $(W-1)-c,$(-c MOD (W-1)),Rn,Rd */
  3611  		rt, rf := p.To.Reg, p.Reg
  3612  		if rf == obj.REG_NONE {
  3613  			rf = rt
  3614  		}
  3615  		v := p.From.Offset
  3616  		switch p.As {
  3617  		case AASR:
  3618  			o1 = c.opbfm(p, ASBFM, v, 63, rf, rt)
  3619  
  3620  		case AASRW:
  3621  			o1 = c.opbfm(p, ASBFMW, v, 31, rf, rt)
  3622  
  3623  		case ALSL:
  3624  			o1 = c.opbfm(p, AUBFM, (64-v)&63, 63-v, rf, rt)
  3625  
  3626  		case ALSLW:
  3627  			o1 = c.opbfm(p, AUBFMW, (32-v)&31, 31-v, rf, rt)
  3628  
  3629  		case ALSR:
  3630  			o1 = c.opbfm(p, AUBFM, v, 63, rf, rt)
  3631  
  3632  		case ALSRW:
  3633  			o1 = c.opbfm(p, AUBFMW, v, 31, rf, rt)
  3634  
  3635  		case AROR:
  3636  			o1 = c.opextr(p, AEXTR, v, rf, rf, rt)
  3637  
  3638  		case ARORW:
  3639  			o1 = c.opextr(p, AEXTRW, v, rf, rf, rt)
  3640  
  3641  		default:
  3642  			c.ctxt.Diag("bad shift $con\n%v", p)
  3643  			break
  3644  		}
  3645  
  3646  	case 9: /* lsl Rm,[Rn],Rd -> lslv Rm, Rn, Rd */
  3647  		o1 = c.oprrr(p, p.As)
  3648  
  3649  		r := int(p.Reg)
  3650  		if r == obj.REG_NONE {
  3651  			r = int(p.To.Reg)
  3652  		}
  3653  		o1 |= (uint32(p.From.Reg&31) << 16) | (uint32(r&31) << 5) | uint32(p.To.Reg&31)
  3654  
  3655  	case 10: /* brk/hvc/.../svc [$con] */
  3656  		o1 = c.opimm(p, p.As)
  3657  
  3658  		if p.From.Type != obj.TYPE_NONE {
  3659  			o1 |= uint32((p.From.Offset & 0xffff) << 5)
  3660  		}
  3661  
  3662  	case 11: /* dword */
  3663  		c.aclass(&p.To)
  3664  
  3665  		o1 = uint32(c.instoffset)
  3666  		o2 = uint32(c.instoffset >> 32)
  3667  		if p.To.Sym != nil {
  3668  			rel := obj.Addrel(c.cursym)
  3669  			rel.Off = int32(c.pc)
  3670  			rel.Siz = 8
  3671  			rel.Sym = p.To.Sym
  3672  			rel.Add = p.To.Offset
  3673  			rel.Type = objabi.R_ADDR
  3674  			o2 = 0
  3675  			o1 = o2
  3676  		}
  3677  
  3678  	case 12: /* movT $vcon, reg */
  3679  		// NOTE: this case does not use REGTMP. If it ever does,
  3680  		// remove the NOTUSETMP flag in optab.
  3681  		num := c.omovlconst(p.As, p, &p.From, int(p.To.Reg), os[:])
  3682  		if num == 0 {
  3683  			c.ctxt.Diag("invalid constant: %v", p)
  3684  		}
  3685  		o1 = os[0]
  3686  		o2 = os[1]
  3687  		o3 = os[2]
  3688  		o4 = os[3]
  3689  
  3690  	case 13: /* addop $vcon, [R], R (64 bit literal); cmp $lcon,R -> addop $lcon,R, ZR */
  3691  		if p.Reg == REGTMP {
  3692  			c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
  3693  		}
  3694  		if p.To.Reg == REG_RSP && isADDSop(p.As) {
  3695  			c.ctxt.Diag("illegal destination register: %v\n", p)
  3696  		}
  3697  		o := uint32(0)
  3698  		num := uint8(0)
  3699  		cls := int(p.From.Class)
  3700  		if isADDWop(p.As) {
  3701  			if !cmp(C_LCON, cls) {
  3702  				c.ctxt.Diag("illegal combination: %v", p)
  3703  			}
  3704  			num = c.omovlconst(AMOVW, p, &p.From, REGTMP, os[:])
  3705  		} else {
  3706  			num = c.omovlconst(AMOVD, p, &p.From, REGTMP, os[:])
  3707  		}
  3708  		if num == 0 {
  3709  			c.ctxt.Diag("invalid constant: %v", p)
  3710  		}
  3711  
  3712  		rt, r, rf := p.To.Reg, p.Reg, int16(REGTMP)
  3713  		if p.To.Type == obj.TYPE_NONE {
  3714  			rt = REGZERO
  3715  		}
  3716  		if r == obj.REG_NONE {
  3717  			r = rt
  3718  		}
  3719  		if p.To.Type != obj.TYPE_NONE && (rt == REGSP || r == REGSP) {
  3720  			o = c.opxrrr(p, p.As, rt, r, rf, false)
  3721  			o |= LSL0_64
  3722  		} else {
  3723  			o = c.oprrr(p, p.As)
  3724  			o |= uint32(rf&31) << 16 /* shift is 0 */
  3725  			o |= uint32(r&31) << 5
  3726  			o |= uint32(rt & 31)
  3727  		}
  3728  
  3729  		os[num] = o
  3730  		o1 = os[0]
  3731  		o2 = os[1]
  3732  		o3 = os[2]
  3733  		o4 = os[3]
  3734  		o5 = os[4]
  3735  
  3736  	case 14: /* word */
  3737  		if c.aclass(&p.To) == C_ADDR {
  3738  			c.ctxt.Diag("address constant needs DWORD\n%v", p)
  3739  		}
  3740  		o1 = uint32(c.instoffset)
  3741  		if p.To.Sym != nil {
  3742  			// This case happens with words generated
  3743  			// in the PC stream as part of the literal pool.
  3744  			rel := obj.Addrel(c.cursym)
  3745  
  3746  			rel.Off = int32(c.pc)
  3747  			rel.Siz = 4
  3748  			rel.Sym = p.To.Sym
  3749  			rel.Add = p.To.Offset
  3750  			rel.Type = objabi.R_ADDR
  3751  			o1 = 0
  3752  		}
  3753  
  3754  	case 15: /* mul/mneg/umulh/umull r,[r,]r; madd/msub/fmadd/fmsub/fnmadd/fnmsub Rm,Ra,Rn,Rd */
  3755  		o1 = c.oprrr(p, p.As)
  3756  
  3757  		rf := int(p.From.Reg)
  3758  		rt := int(p.To.Reg)
  3759  		var r int
  3760  		var ra int
  3761  		if p.From3Type() == obj.TYPE_REG {
  3762  			r = int(p.GetFrom3().Reg)
  3763  			ra = int(p.Reg)
  3764  			if ra == obj.REG_NONE {
  3765  				ra = REGZERO
  3766  			}
  3767  		} else {
  3768  			r = int(p.Reg)
  3769  			if r == obj.REG_NONE {
  3770  				r = rt
  3771  			}
  3772  			ra = REGZERO
  3773  		}
  3774  
  3775  		o1 |= (uint32(rf&31) << 16) | (uint32(ra&31) << 10) | (uint32(r&31) << 5) | uint32(rt&31)
  3776  
  3777  	case 16: /* XremY R[,R],R -> XdivY; XmsubY */
  3778  		o1 = c.oprrr(p, p.As)
  3779  
  3780  		rf := int(p.From.Reg)
  3781  		rt := int(p.To.Reg)
  3782  		r := int(p.Reg)
  3783  		if r == obj.REG_NONE {
  3784  			r = rt
  3785  		}
  3786  		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | REGTMP&31
  3787  		o2 = c.oprrr(p, AMSUBW)
  3788  		o2 |= o1 & (1 << 31) /* same size */
  3789  		o2 |= (uint32(rf&31) << 16) | (uint32(r&31) << 10) | (REGTMP & 31 << 5) | uint32(rt&31)
  3790  
  3791  	case 17: /* op Rm,[Rn],Rd; default Rn=ZR */
  3792  		o1 = c.oprrr(p, p.As)
  3793  
  3794  		rf := int(p.From.Reg)
  3795  		rt := int(p.To.Reg)
  3796  		r := int(p.Reg)
  3797  		if p.To.Type == obj.TYPE_NONE {
  3798  			rt = REGZERO
  3799  		}
  3800  		if r == obj.REG_NONE {
  3801  			r = REGZERO
  3802  		}
  3803  		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
  3804  
  3805  	case 18: /* csel cond,Rn,Rm,Rd; cinc/cinv/cneg cond,Rn,Rd; cset cond,Rd */
  3806  		o1 = c.oprrr(p, p.As)
  3807  
  3808  		cond := SpecialOperand(p.From.Offset)
  3809  		if cond < SPOP_EQ || cond > SPOP_NV || (cond == SPOP_AL || cond == SPOP_NV) && p.From3Type() == obj.TYPE_NONE {
  3810  			c.ctxt.Diag("invalid condition: %v", p)
  3811  		} else {
  3812  			cond -= SPOP_EQ
  3813  		}
  3814  
  3815  		r := int(p.Reg)
  3816  		var rf int = r
  3817  		if p.From3Type() == obj.TYPE_NONE {
  3818  			/* CINC/CINV/CNEG or CSET/CSETM*/
  3819  			if r == obj.REG_NONE {
  3820  				/* CSET/CSETM */
  3821  				rf = REGZERO
  3822  				r = rf
  3823  			}
  3824  			cond ^= 1
  3825  		} else {
  3826  			rf = int(p.GetFrom3().Reg) /* CSEL */
  3827  		}
  3828  
  3829  		rt := int(p.To.Reg)
  3830  		o1 |= (uint32(rf&31) << 16) | (uint32(cond&15) << 12) | (uint32(r&31) << 5) | uint32(rt&31)
  3831  
  3832  	case 19: /* CCMN cond, (Rm|uimm5),Rn, uimm4 -> ccmn Rn,Rm,uimm4,cond */
  3833  		nzcv := int(p.To.Offset)
  3834  
  3835  		cond := SpecialOperand(p.From.Offset)
  3836  		if cond < SPOP_EQ || cond > SPOP_NV {
  3837  			c.ctxt.Diag("invalid condition\n%v", p)
  3838  		} else {
  3839  			cond -= SPOP_EQ
  3840  		}
  3841  		var rf int
  3842  		if p.GetFrom3().Type == obj.TYPE_REG {
  3843  			o1 = c.oprrr(p, p.As)
  3844  			rf = int(p.GetFrom3().Reg) /* Rm */
  3845  		} else {
  3846  			o1 = c.opirr(p, p.As)
  3847  			rf = int(p.GetFrom3().Offset & 0x1F)
  3848  		}
  3849  
  3850  		o1 |= (uint32(rf&31) << 16) | (uint32(cond&15) << 12) | (uint32(p.Reg&31) << 5) | uint32(nzcv)
  3851  
  3852  	case 20: /* movT R,O(R) -> strT */
  3853  		v := c.regoff(&p.To)
  3854  		sz := int32(1 << uint(movesize(p.As)))
  3855  
  3856  		rt, rf := p.To.Reg, p.From.Reg
  3857  		if rt == obj.REG_NONE {
  3858  			rt = o.param
  3859  		}
  3860  		if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */
  3861  			o1 = c.olsr9s(p, c.opstr(p, p.As), v, rt, rf)
  3862  		} else {
  3863  			v = int32(c.offsetshift(p, int64(v), int(o.a4)))
  3864  			o1 = c.olsr12u(p, c.opstr(p, p.As), v, rt, rf)
  3865  		}
  3866  
  3867  	case 21: /* movT O(R),R -> ldrT */
  3868  		v := c.regoff(&p.From)
  3869  		sz := int32(1 << uint(movesize(p.As)))
  3870  
  3871  		rt, rf := p.To.Reg, p.From.Reg
  3872  		if rf == obj.REG_NONE {
  3873  			rf = o.param
  3874  		}
  3875  		if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */
  3876  			o1 = c.olsr9s(p, c.opldr(p, p.As), v, rf, rt)
  3877  		} else {
  3878  			v = int32(c.offsetshift(p, int64(v), int(o.a1)))
  3879  			o1 = c.olsr12u(p, c.opldr(p, p.As), v, rf, rt)
  3880  		}
  3881  
  3882  	case 22: /* movT (R)O!,R; movT O(R)!, R -> ldrT */
  3883  		if p.From.Reg != REGSP && p.From.Reg == p.To.Reg {
  3884  			c.ctxt.Diag("constrained unpredictable behavior: %v", p)
  3885  		}
  3886  
  3887  		v := int32(p.From.Offset)
  3888  
  3889  		if v < -256 || v > 255 {
  3890  			c.ctxt.Diag("offset out of range [-256,255]: %v", p)
  3891  		}
  3892  		o1 = c.opldr(p, p.As)
  3893  		if o.scond == C_XPOST {
  3894  			o1 |= 1 << 10
  3895  		} else {
  3896  			o1 |= 3 << 10
  3897  		}
  3898  		o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.From.Reg&31) << 5) | uint32(p.To.Reg&31)
  3899  
  3900  	case 23: /* movT R,(R)O!; movT O(R)!, R -> strT */
  3901  		if p.To.Reg != REGSP && p.From.Reg == p.To.Reg {
  3902  			c.ctxt.Diag("constrained unpredictable behavior: %v", p)
  3903  		}
  3904  
  3905  		v := int32(p.To.Offset)
  3906  
  3907  		if v < -256 || v > 255 {
  3908  			c.ctxt.Diag("offset out of range [-256,255]: %v", p)
  3909  		}
  3910  		o1 = c.opstr(p, p.As)
  3911  		if o.scond == C_XPOST {
  3912  			o1 |= 1 << 10
  3913  		} else {
  3914  			o1 |= 3 << 10
  3915  		}
  3916  		o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.To.Reg&31) << 5) | uint32(p.From.Reg&31)
  3917  
  3918  	case 24: /* mov/mvn Rs,Rd -> add $0,Rs,Rd or orr Rs,ZR,Rd */
  3919  		rf := int(p.From.Reg)
  3920  		rt := int(p.To.Reg)
  3921  		if rf == REGSP || rt == REGSP {
  3922  			if p.As == AMVN || p.As == AMVNW {
  3923  				c.ctxt.Diag("illegal SP reference\n%v", p)
  3924  			}
  3925  			o1 = c.opirr(p, p.As)
  3926  			o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
  3927  		} else {
  3928  			o1 = c.oprrr(p, p.As)
  3929  			o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
  3930  		}
  3931  
  3932  	case 25: /* negX Rs, Rd -> subX Rs<<0, ZR, Rd */
  3933  		o1 = c.oprrr(p, p.As)
  3934  
  3935  		rf := int(p.From.Reg)
  3936  		if rf == C_NONE {
  3937  			rf = int(p.To.Reg)
  3938  		}
  3939  		rt := int(p.To.Reg)
  3940  		o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
  3941  
  3942  	case 26: /* op Vn, Vd; op Vn.<T>, Vd.<T> */
  3943  		o1 = c.oprrr(p, p.As)
  3944  		cf := c.aclass(&p.From)
  3945  		af := (p.From.Reg >> 5) & 15
  3946  		at := (p.To.Reg >> 5) & 15
  3947  		var sz int16
  3948  		switch p.As {
  3949  		case AAESD, AAESE, AAESIMC, AAESMC:
  3950  			sz = ARNG_16B
  3951  		case ASHA1SU1, ASHA256SU0:
  3952  			sz = ARNG_4S
  3953  		case ASHA512SU0:
  3954  			sz = ARNG_2D
  3955  		}
  3956  
  3957  		if cf == C_ARNG {
  3958  			if p.As == ASHA1H {
  3959  				c.ctxt.Diag("invalid operands: %v", p)
  3960  			} else {
  3961  				if af != sz || af != at {
  3962  					c.ctxt.Diag("invalid arrangement: %v", p)
  3963  				}
  3964  			}
  3965  		}
  3966  		o1 |= uint32(p.From.Reg&31)<<5 | uint32(p.To.Reg&31)
  3967  
  3968  	case 27: /* op Rm<<n[,Rn],Rd (extended register) */
  3969  		if p.To.Reg == REG_RSP && isADDSop(p.As) {
  3970  			c.ctxt.Diag("illegal destination register: %v\n", p)
  3971  		}
  3972  		rt, r, rf := p.To.Reg, p.Reg, p.From.Reg
  3973  		if p.To.Type == obj.TYPE_NONE {
  3974  			rt = REGZERO
  3975  		}
  3976  		if r == obj.REG_NONE {
  3977  			r = rt
  3978  		}
  3979  		if (p.From.Reg-obj.RBaseARM64)&REG_EXT != 0 ||
  3980  			(p.From.Reg >= REG_LSL && p.From.Reg < REG_ARNG) {
  3981  			amount := (p.From.Reg >> 5) & 7
  3982  			if amount > 4 {
  3983  				c.ctxt.Diag("shift amount out of range 0 to 4: %v", p)
  3984  			}
  3985  			o1 = c.opxrrr(p, p.As, rt, r, obj.REG_NONE, true)
  3986  			o1 |= c.encRegShiftOrExt(p, &p.From, p.From.Reg) /* includes reg, op, etc */
  3987  		} else {
  3988  			o1 = c.opxrrr(p, p.As, rt, r, rf, false)
  3989  		}
  3990  
  3991  	case 28: /* logop $vcon, [R], R (64 bit literal) */
  3992  		if p.Reg == REGTMP {
  3993  			c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
  3994  		}
  3995  		o := uint32(0)
  3996  		num := uint8(0)
  3997  		cls := int(p.From.Class)
  3998  		if isANDWop(p.As) {
  3999  			if !cmp(C_LCON, cls) {
  4000  				c.ctxt.Diag("illegal combination: %v", p)
  4001  			}
  4002  			num = c.omovlconst(AMOVW, p, &p.From, REGTMP, os[:])
  4003  		} else {
  4004  			num = c.omovlconst(AMOVD, p, &p.From, REGTMP, os[:])
  4005  		}
  4006  
  4007  		if num == 0 {
  4008  			c.ctxt.Diag("invalid constant: %v", p)
  4009  		}
  4010  		rt := int(p.To.Reg)
  4011  		if p.To.Type == obj.TYPE_NONE {
  4012  			rt = REGZERO
  4013  		}
  4014  		r := int(p.Reg)
  4015  		if r == obj.REG_NONE {
  4016  			r = rt
  4017  		}
  4018  		o = c.oprrr(p, p.As)
  4019  		o |= REGTMP & 31 << 16 /* shift is 0 */
  4020  		o |= uint32(r&31) << 5
  4021  		o |= uint32(rt & 31)
  4022  
  4023  		os[num] = o
  4024  		o1 = os[0]
  4025  		o2 = os[1]
  4026  		o3 = os[2]
  4027  		o4 = os[3]
  4028  		o5 = os[4]
  4029  
  4030  	case 29: /* op Rn, Rd */
  4031  		fc := c.aclass(&p.From)
  4032  		tc := c.aclass(&p.To)
  4033  		if (p.As == AFMOVD || p.As == AFMOVS) && (fc == C_REG || fc == C_ZREG || tc == C_REG || tc == C_ZREG) {
  4034  			// FMOV Rx, Fy or FMOV Fy, Rx
  4035  			o1 = FPCVTI(0, 0, 0, 0, 6)
  4036  			if p.As == AFMOVD {
  4037  				o1 |= 1<<31 | 1<<22 // 64-bit
  4038  			}
  4039  			if fc == C_REG || fc == C_ZREG {
  4040  				o1 |= 1 << 16 // FMOV Rx, Fy
  4041  			}
  4042  		} else {
  4043  			o1 = c.oprrr(p, p.As)
  4044  		}
  4045  		o1 |= uint32(p.From.Reg&31)<<5 | uint32(p.To.Reg&31)
  4046  
  4047  	case 30: /* movT R,L(R) -> strT */
  4048  		// If offset L fits in a 12 bit unsigned immediate:
  4049  		//	add $L, R, Rtmp  or  sub $L, R, Rtmp
  4050  		//	str R, (Rtmp)
  4051  		// Otherwise, if offset L can be split into hi+lo, and both fit into instructions:
  4052  		//	add $hi, R, Rtmp
  4053  		//	str R, lo(Rtmp)
  4054  		// Otherwise, use constant pool:
  4055  		//	mov $L, Rtmp (from constant pool)
  4056  		//	str R, (R+Rtmp)
  4057  		s := movesize(o.as)
  4058  		if s < 0 {
  4059  			c.ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p)
  4060  		}
  4061  
  4062  		r := p.To.Reg
  4063  		if r == obj.REG_NONE {
  4064  			r = o.param
  4065  		}
  4066  
  4067  		v := c.regoff(&p.To)
  4068  		if v >= -256 && v <= 256 {
  4069  			c.ctxt.Diag("%v: bad type for offset %d (should be 9 bit signed immediate store)", p, v)
  4070  		}
  4071  		if v >= 0 && v <= 4095 && v&((1<<int32(s))-1) == 0 {
  4072  			c.ctxt.Diag("%v: bad type for offset %d (should be 12 bit unsigned immediate store)", p, v)
  4073  		}
  4074  
  4075  		// Handle smaller unaligned and negative offsets via addition or subtraction.
  4076  		if v >= -4095 && v <= 4095 {
  4077  			o1 = c.oaddi12(p, v, REGTMP, int16(r))
  4078  			o2 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg)
  4079  			break
  4080  		}
  4081  
  4082  		hi, lo, err := splitImm24uScaled(v, s)
  4083  		if err != nil {
  4084  			goto storeusepool
  4085  		}
  4086  		if p.Pool != nil {
  4087  			c.ctxt.Diag("%v: unused constant in pool (%v)\n", p, v)
  4088  		}
  4089  		o1 = c.oaddi(p, AADD, hi, REGTMP, r)
  4090  		o2 = c.olsr12u(p, c.opstr(p, p.As), lo, REGTMP, p.From.Reg)
  4091  		break
  4092  
  4093  	storeusepool:
  4094  		if p.Pool == nil {
  4095  			c.ctxt.Diag("%v: constant is not in pool", p)
  4096  		}
  4097  		if r == REGTMP || p.From.Reg == REGTMP {
  4098  			c.ctxt.Diag("REGTMP used in large offset store: %v", p)
  4099  		}
  4100  		o1 = c.omovlit(AMOVD, p, &p.To, REGTMP)
  4101  		o2 = c.olsxrr(p, int32(c.opstrr(p, p.As, false)), int(p.From.Reg), int(r), REGTMP)
  4102  
  4103  	case 31: /* movT L(R), R -> ldrT */
  4104  		// If offset L fits in a 12 bit unsigned immediate:
  4105  		//	add $L, R, Rtmp  or  sub $L, R, Rtmp
  4106  		//	ldr R, (Rtmp)
  4107  		// Otherwise, if offset L can be split into hi+lo, and both fit into instructions:
  4108  		//	add $hi, R, Rtmp
  4109  		//	ldr lo(Rtmp), R
  4110  		// Otherwise, use constant pool:
  4111  		//	mov $L, Rtmp (from constant pool)
  4112  		//	ldr (R+Rtmp), R
  4113  		s := movesize(o.as)
  4114  		if s < 0 {
  4115  			c.ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p)
  4116  		}
  4117  
  4118  		r := p.From.Reg
  4119  		if r == obj.REG_NONE {
  4120  			r = o.param
  4121  		}
  4122  
  4123  		v := c.regoff(&p.From)
  4124  		if v >= -256 && v <= 256 {
  4125  			c.ctxt.Diag("%v: bad type for offset %d (should be 9 bit signed immediate load)", p, v)
  4126  		}
  4127  		if v >= 0 && v <= 4095 && v&((1<<int32(s))-1) == 0 {
  4128  			c.ctxt.Diag("%v: bad type for offset %d (should be 12 bit unsigned immediate load)", p, v)
  4129  		}
  4130  
  4131  		// Handle smaller unaligned and negative offsets via addition or subtraction.
  4132  		if v >= -4095 && v <= 4095 {
  4133  			o1 = c.oaddi12(p, v, REGTMP, int16(r))
  4134  			o2 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg)
  4135  			break
  4136  		}
  4137  
  4138  		hi, lo, err := splitImm24uScaled(v, s)
  4139  		if err != nil {
  4140  			goto loadusepool
  4141  		}
  4142  		if p.Pool != nil {
  4143  			c.ctxt.Diag("%v: unused constant in pool (%v)\n", p, v)
  4144  		}
  4145  		o1 = c.oaddi(p, AADD, hi, REGTMP, r)
  4146  		o2 = c.olsr12u(p, c.opldr(p, p.As), lo, REGTMP, p.To.Reg)
  4147  		break
  4148  
  4149  	loadusepool:
  4150  		if p.Pool == nil {
  4151  			c.ctxt.Diag("%v: constant is not in pool", p)
  4152  		}
  4153  		if r == REGTMP || p.From.Reg == REGTMP {
  4154  			c.ctxt.Diag("REGTMP used in large offset load: %v", p)
  4155  		}
  4156  		o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
  4157  		o2 = c.olsxrr(p, int32(c.opldrr(p, p.As, false)), int(p.To.Reg), int(r), REGTMP)
  4158  
  4159  	case 32: /* mov $con, R -> movz/movn */
  4160  		o1 = c.omovconst(p.As, p, &p.From, int(p.To.Reg))
  4161  
  4162  	case 33: /* movk $uimm16 << pos */
  4163  		o1 = c.opirr(p, p.As)
  4164  
  4165  		d := p.From.Offset
  4166  		if d == 0 {
  4167  			c.ctxt.Diag("zero shifts cannot be handled correctly: %v", p)
  4168  		}
  4169  		s := movcon(d)
  4170  		if s < 0 || s >= 4 {
  4171  			c.ctxt.Diag("bad constant for MOVK: %#x\n%v", uint64(d), p)
  4172  		}
  4173  		if (o1&S64) == 0 && s >= 2 {
  4174  			c.ctxt.Diag("illegal bit position\n%v", p)
  4175  		}
  4176  		if ((uint64(d) >> uint(s*16)) >> 16) != 0 {
  4177  			c.ctxt.Diag("requires uimm16\n%v", p)
  4178  		}
  4179  		rt := int(p.To.Reg)
  4180  
  4181  		o1 |= uint32((((d >> uint(s*16)) & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31))
  4182  
  4183  	case 34: /* mov $lacon,R */
  4184  		o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
  4185  		rt, r, rf := p.To.Reg, p.From.Reg, int16(REGTMP)
  4186  		if r == obj.REG_NONE {
  4187  			r = o.param
  4188  		}
  4189  		o2 = c.opxrrr(p, AADD, rt, r, rf, false)
  4190  		o2 |= LSL0_64
  4191  
  4192  	case 35: /* mov SPR,R -> mrs */
  4193  		o1 = c.oprrr(p, AMRS)
  4194  
  4195  		// SysRegEnc function returns the system register encoding and accessFlags.
  4196  		_, v, accessFlags := SysRegEnc(p.From.Reg)
  4197  		if v == 0 {
  4198  			c.ctxt.Diag("illegal system register:\n%v", p)
  4199  		}
  4200  		if (o1 & (v &^ (3 << 19))) != 0 {
  4201  			c.ctxt.Diag("MRS register value overlap\n%v", p)
  4202  		}
  4203  		if accessFlags&SR_READ == 0 {
  4204  			c.ctxt.Diag("system register is not readable: %v", p)
  4205  		}
  4206  
  4207  		o1 |= v
  4208  		o1 |= uint32(p.To.Reg & 31)
  4209  
  4210  	case 36: /* mov R,SPR */
  4211  		o1 = c.oprrr(p, AMSR)
  4212  
  4213  		// SysRegEnc function returns the system register encoding and accessFlags.
  4214  		_, v, accessFlags := SysRegEnc(p.To.Reg)
  4215  		if v == 0 {
  4216  			c.ctxt.Diag("illegal system register:\n%v", p)
  4217  		}
  4218  		if (o1 & (v &^ (3 << 19))) != 0 {
  4219  			c.ctxt.Diag("MSR register value overlap\n%v", p)
  4220  		}
  4221  		if accessFlags&SR_WRITE == 0 {
  4222  			c.ctxt.Diag("system register is not writable: %v", p)
  4223  		}
  4224  
  4225  		o1 |= v
  4226  		o1 |= uint32(p.From.Reg & 31)
  4227  
  4228  	case 37: /* mov $con,PSTATEfield -> MSR [immediate] */
  4229  		if (uint64(p.From.Offset) &^ uint64(0xF)) != 0 {
  4230  			c.ctxt.Diag("illegal immediate for PSTATE field\n%v", p)
  4231  		}
  4232  		o1 = c.opirr(p, AMSR)
  4233  		o1 |= uint32((p.From.Offset & 0xF) << 8) /* Crm */
  4234  		v := uint32(0)
  4235  		// PSTATEfield can be special registers and special operands.
  4236  		if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_SPSel {
  4237  			v = 0<<16 | 4<<12 | 5<<5
  4238  		} else if p.To.Type == obj.TYPE_SPECIAL {
  4239  			opd := SpecialOperand(p.To.Offset)
  4240  			for _, pf := range pstatefield {
  4241  				if pf.opd == opd {
  4242  					v = pf.enc
  4243  					break
  4244  				}
  4245  			}
  4246  		}
  4247  
  4248  		if v == 0 {
  4249  			c.ctxt.Diag("illegal PSTATE field for immediate move\n%v", p)
  4250  		}
  4251  		o1 |= v
  4252  
  4253  	case 38: /* clrex [$imm] */
  4254  		o1 = c.opimm(p, p.As)
  4255  
  4256  		if p.To.Type == obj.TYPE_NONE {
  4257  			o1 |= 0xF << 8
  4258  		} else {
  4259  			o1 |= uint32((p.To.Offset & 0xF) << 8)
  4260  		}
  4261  
  4262  	case 39: /* cbz R, rel */
  4263  		o1 = c.opirr(p, p.As)
  4264  
  4265  		o1 |= uint32(p.From.Reg & 31)
  4266  		o1 |= uint32(c.brdist(p, 0, 19, 2) << 5)
  4267  
  4268  	case 40: /* tbz */
  4269  		o1 = c.opirr(p, p.As)
  4270  
  4271  		v := int32(p.From.Offset)
  4272  		if v < 0 || v > 63 {
  4273  			c.ctxt.Diag("illegal bit number\n%v", p)
  4274  		}
  4275  		o1 |= ((uint32(v) & 0x20) << (31 - 5)) | ((uint32(v) & 0x1F) << 19)
  4276  		o1 |= uint32(c.brdist(p, 0, 14, 2) << 5)
  4277  		o1 |= uint32(p.Reg & 31)
  4278  
  4279  	case 41: /* eret, nop, others with no operands */
  4280  		o1 = c.op0(p, p.As)
  4281  
  4282  	case 42: /* bfm R,r,s,R */
  4283  		o1 = c.opbfm(p, p.As, p.From.Offset, p.GetFrom3().Offset, p.Reg, p.To.Reg)
  4284  
  4285  	case 43: /* bfm aliases */
  4286  		rt, rf := p.To.Reg, p.Reg
  4287  		if rf == obj.REG_NONE {
  4288  			rf = rt
  4289  		}
  4290  		r, s := p.From.Offset, p.GetFrom3().Offset
  4291  		switch p.As {
  4292  		case ABFI:
  4293  			if r != 0 {
  4294  				r = 64 - r
  4295  			}
  4296  			o1 = c.opbfm(p, ABFM, r, s-1, rf, rt)
  4297  
  4298  		case ABFIW:
  4299  			if r != 0 {
  4300  				r = 32 - r
  4301  			}
  4302  			o1 = c.opbfm(p, ABFMW, r, s-1, rf, rt)
  4303  
  4304  		case ABFXIL:
  4305  			o1 = c.opbfm(p, ABFM, r, r+s-1, rf, rt)
  4306  
  4307  		case ABFXILW:
  4308  			o1 = c.opbfm(p, ABFMW, r, r+s-1, rf, rt)
  4309  
  4310  		case ASBFIZ:
  4311  			if r != 0 {
  4312  				r = 64 - r
  4313  			}
  4314  			o1 = c.opbfm(p, ASBFM, r, s-1, rf, rt)
  4315  
  4316  		case ASBFIZW:
  4317  			if r != 0 {
  4318  				r = 32 - r
  4319  			}
  4320  			o1 = c.opbfm(p, ASBFMW, r, s-1, rf, rt)
  4321  
  4322  		case ASBFX:
  4323  			o1 = c.opbfm(p, ASBFM, r, r+s-1, rf, rt)
  4324  
  4325  		case ASBFXW:
  4326  			o1 = c.opbfm(p, ASBFMW, r, r+s-1, rf, rt)
  4327  
  4328  		case AUBFIZ:
  4329  			if r != 0 {
  4330  				r = 64 - r
  4331  			}
  4332  			o1 = c.opbfm(p, AUBFM, r, s-1, rf, rt)
  4333  
  4334  		case AUBFIZW:
  4335  			if r != 0 {
  4336  				r = 32 - r
  4337  			}
  4338  			o1 = c.opbfm(p, AUBFMW, r, s-1, rf, rt)
  4339  
  4340  		case AUBFX:
  4341  			o1 = c.opbfm(p, AUBFM, r, r+s-1, rf, rt)
  4342  
  4343  		case AUBFXW:
  4344  			o1 = c.opbfm(p, AUBFMW, r, r+s-1, rf, rt)
  4345  
  4346  		default:
  4347  			c.ctxt.Diag("bad bfm alias\n%v", p)
  4348  			break
  4349  		}
  4350  
  4351  	case 44: /* extr $b, Rn, Rm, Rd */
  4352  		o1 = c.opextr(p, p.As, p.From.Offset, p.GetFrom3().Reg, p.Reg, p.To.Reg)
  4353  
  4354  	case 45: /* sxt/uxt[bhw] R,R; movT R,R -> sxtT R,R */
  4355  		as := p.As
  4356  		rt, rf := p.To.Reg, p.From.Reg
  4357  		if rf == REGZERO {
  4358  			as = AMOVWU /* clearer in disassembly */
  4359  		}
  4360  		switch as {
  4361  		case AMOVB, ASXTB:
  4362  			o1 = c.opbfm(p, ASBFM, 0, 7, rf, rt)
  4363  
  4364  		case AMOVH, ASXTH:
  4365  			o1 = c.opbfm(p, ASBFM, 0, 15, rf, rt)
  4366  
  4367  		case AMOVW, ASXTW:
  4368  			o1 = c.opbfm(p, ASBFM, 0, 31, rf, rt)
  4369  
  4370  		case AMOVBU, AUXTB:
  4371  			o1 = c.opbfm(p, AUBFM, 0, 7, rf, rt)
  4372  
  4373  		case AMOVHU, AUXTH:
  4374  			o1 = c.opbfm(p, AUBFM, 0, 15, rf, rt)
  4375  
  4376  		case AMOVWU:
  4377  			o1 = c.oprrr(p, as) | (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
  4378  
  4379  		case AUXTW:
  4380  			o1 = c.opbfm(p, AUBFM, 0, 31, rf, rt)
  4381  
  4382  		case ASXTBW:
  4383  			o1 = c.opbfm(p, ASBFMW, 0, 7, rf, rt)
  4384  
  4385  		case ASXTHW:
  4386  			o1 = c.opbfm(p, ASBFMW, 0, 15, rf, rt)
  4387  
  4388  		case AUXTBW:
  4389  			o1 = c.opbfm(p, AUBFMW, 0, 7, rf, rt)
  4390  
  4391  		case AUXTHW:
  4392  			o1 = c.opbfm(p, AUBFMW, 0, 15, rf, rt)
  4393  
  4394  		default:
  4395  			c.ctxt.Diag("bad sxt %v", as)
  4396  			break
  4397  		}
  4398  
  4399  	case 46: /* cls */
  4400  		o1 = c.opbit(p, p.As)
  4401  
  4402  		o1 |= uint32(p.From.Reg&31) << 5
  4403  		o1 |= uint32(p.To.Reg & 31)
  4404  
  4405  	case 47: // SWPx/LDADDx/LDCLRx/LDEORx/LDORx/CASx Rs, (Rb), Rt
  4406  		rs := p.From.Reg
  4407  		rt := p.RegTo2
  4408  		rb := p.To.Reg
  4409  
  4410  		// rt can't be sp.
  4411  		if rt == REG_RSP {
  4412  			c.ctxt.Diag("illegal destination register: %v\n", p)
  4413  		}
  4414  
  4415  		o1 = atomicLDADD[p.As] | atomicSWP[p.As]
  4416  		o1 |= uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
  4417  
  4418  	case 48: /* ADD $C_ADDCON2, Rm, Rd */
  4419  		// NOTE: this case does not use REGTMP. If it ever does,
  4420  		// remove the NOTUSETMP flag in optab.
  4421  		op := c.opirr(p, p.As)
  4422  		if op&Sbit != 0 {
  4423  			c.ctxt.Diag("can not break addition/subtraction when S bit is set", p)
  4424  		}
  4425  		rt, r := p.To.Reg, p.Reg
  4426  		if r == obj.REG_NONE {
  4427  			r = rt
  4428  		}
  4429  		o1 = c.oaddi(p, p.As, c.regoff(&p.From)&0x000fff, rt, r)
  4430  		o2 = c.oaddi(p, p.As, c.regoff(&p.From)&0xfff000, rt, rt)
  4431  
  4432  	case 49: /* op Vm.<T>, Vn, Vd */
  4433  		o1 = c.oprrr(p, p.As)
  4434  		cf := c.aclass(&p.From)
  4435  		af := (p.From.Reg >> 5) & 15
  4436  		sz := ARNG_4S
  4437  		if p.As == ASHA512H || p.As == ASHA512H2 {
  4438  			sz = ARNG_2D
  4439  		}
  4440  		if cf == C_ARNG && af != int16(sz) {
  4441  			c.ctxt.Diag("invalid arrangement: %v", p)
  4442  		}
  4443  		o1 |= uint32(p.From.Reg&31)<<16 | uint32(p.Reg&31)<<5 | uint32(p.To.Reg&31)
  4444  
  4445  	case 50: /* sys/sysl */
  4446  		o1 = c.opirr(p, p.As)
  4447  
  4448  		if (p.From.Offset &^ int64(SYSARG4(0x7, 0xF, 0xF, 0x7))) != 0 {
  4449  			c.ctxt.Diag("illegal SYS argument\n%v", p)
  4450  		}
  4451  		o1 |= uint32(p.From.Offset)
  4452  		if p.To.Type == obj.TYPE_REG {
  4453  			o1 |= uint32(p.To.Reg & 31)
  4454  		} else {
  4455  			o1 |= 0x1F
  4456  		}
  4457  
  4458  	case 51: /* dmb */
  4459  		o1 = c.opirr(p, p.As)
  4460  
  4461  		if p.From.Type == obj.TYPE_CONST {
  4462  			o1 |= uint32((p.From.Offset & 0xF) << 8)
  4463  		}
  4464  
  4465  	case 52: /* hint */
  4466  		o1 = c.opirr(p, p.As)
  4467  
  4468  		o1 |= uint32((p.From.Offset & 0x7F) << 5)
  4469  
  4470  	case 53: /* and/or/eor/bic/tst/... $bitcon, Rn, Rd */
  4471  		a := p.As
  4472  		rt := int(p.To.Reg)
  4473  		if p.To.Type == obj.TYPE_NONE {
  4474  			rt = REGZERO
  4475  		}
  4476  		r := int(p.Reg)
  4477  		if r == obj.REG_NONE {
  4478  			r = rt
  4479  		}
  4480  		if r == REG_RSP {
  4481  			c.ctxt.Diag("illegal source register: %v", p)
  4482  			break
  4483  		}
  4484  		mode := 64
  4485  		v := uint64(p.From.Offset)
  4486  		switch p.As {
  4487  		case AANDW, AORRW, AEORW, AANDSW, ATSTW:
  4488  			mode = 32
  4489  		case ABIC, AORN, AEON, ABICS:
  4490  			v = ^v
  4491  		case ABICW, AORNW, AEONW, ABICSW:
  4492  			v = ^v
  4493  			mode = 32
  4494  		}
  4495  		o1 = c.opirr(p, a)
  4496  		o1 |= bitconEncode(v, mode) | uint32(r&31)<<5 | uint32(rt&31)
  4497  
  4498  	case 54: /* floating point arith */
  4499  		o1 = c.oprrr(p, p.As)
  4500  		rf := int(p.From.Reg)
  4501  		rt := int(p.To.Reg)
  4502  		r := int(p.Reg)
  4503  		if (o1&(0x1F<<24)) == (0x1E<<24) && (o1&(1<<11)) == 0 { /* monadic */
  4504  			r = rf
  4505  			rf = 0
  4506  		} else if r == obj.REG_NONE {
  4507  			r = rt
  4508  		}
  4509  		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
  4510  
  4511  	case 55: /* floating-point constant */
  4512  		var rf int
  4513  		o1 = 0xf<<25 | 1<<21 | 1<<12
  4514  		rf = c.chipfloat7(p.From.Val.(float64))
  4515  		if rf < 0 {
  4516  			c.ctxt.Diag("invalid floating-point immediate\n%v", p)
  4517  		}
  4518  		if p.As == AFMOVD {
  4519  			o1 |= 1 << 22
  4520  		}
  4521  		o1 |= (uint32(rf&0xff) << 13) | uint32(p.To.Reg&31)
  4522  
  4523  	case 56: /* floating point compare */
  4524  		o1 = c.oprrr(p, p.As)
  4525  
  4526  		var rf int
  4527  		if p.From.Type == obj.TYPE_FCONST {
  4528  			o1 |= 8 /* zero */
  4529  			rf = 0
  4530  		} else {
  4531  			rf = int(p.From.Reg)
  4532  		}
  4533  		rt := int(p.Reg)
  4534  		o1 |= uint32(rf&31)<<16 | uint32(rt&31)<<5
  4535  
  4536  	case 57: /* floating point conditional compare */
  4537  		o1 = c.oprrr(p, p.As)
  4538  
  4539  		cond := SpecialOperand(p.From.Offset)
  4540  		if cond < SPOP_EQ || cond > SPOP_NV {
  4541  			c.ctxt.Diag("invalid condition\n%v", p)
  4542  		} else {
  4543  			cond -= SPOP_EQ
  4544  		}
  4545  
  4546  		nzcv := int(p.To.Offset)
  4547  		if nzcv&^0xF != 0 {
  4548  			c.ctxt.Diag("implausible condition\n%v", p)
  4549  		}
  4550  		rf := int(p.Reg)
  4551  		if p.GetFrom3() == nil || p.GetFrom3().Reg < REG_F0 || p.GetFrom3().Reg > REG_F31 {
  4552  			c.ctxt.Diag("illegal FCCMP\n%v", p)
  4553  			break
  4554  		}
  4555  		rt := int(p.GetFrom3().Reg)
  4556  		o1 |= uint32(rf&31)<<16 | uint32(cond&15)<<12 | uint32(rt&31)<<5 | uint32(nzcv)
  4557  
  4558  	case 58: /* ldar/ldarb/ldarh/ldaxp/ldxp/ldaxr/ldxr */
  4559  		o1 = c.opload(p, p.As)
  4560  
  4561  		o1 |= 0x1F << 16
  4562  		o1 |= uint32(p.From.Reg&31) << 5
  4563  		if p.As == ALDXP || p.As == ALDXPW || p.As == ALDAXP || p.As == ALDAXPW {
  4564  			if int(p.To.Reg) == int(p.To.Offset) {
  4565  				c.ctxt.Diag("constrained unpredictable behavior: %v", p)
  4566  			}
  4567  			o1 |= uint32(p.To.Offset&31) << 10
  4568  		} else {
  4569  			o1 |= 0x1F << 10
  4570  		}
  4571  		o1 |= uint32(p.To.Reg & 31)
  4572  
  4573  	case 59: /* stxr/stlxr/stxp/stlxp */
  4574  		s := p.RegTo2
  4575  		n := p.To.Reg
  4576  		t := p.From.Reg
  4577  		if isSTLXRop(p.As) {
  4578  			if s == t || (s == n && n != REGSP) {
  4579  				c.ctxt.Diag("constrained unpredictable behavior: %v", p)
  4580  			}
  4581  		} else if isSTXPop(p.As) {
  4582  			t2 := int16(p.From.Offset)
  4583  			if (s == t || s == t2) || (s == n && n != REGSP) {
  4584  				c.ctxt.Diag("constrained unpredictable behavior: %v", p)
  4585  			}
  4586  		}
  4587  		if s == REG_RSP {
  4588  			c.ctxt.Diag("illegal destination register: %v\n", p)
  4589  		}
  4590  		o1 = c.opstore(p, p.As)
  4591  
  4592  		if p.RegTo2 != obj.REG_NONE {
  4593  			o1 |= uint32(p.RegTo2&31) << 16
  4594  		} else {
  4595  			o1 |= 0x1F << 16
  4596  		}
  4597  		if isSTXPop(p.As) {
  4598  			o1 |= uint32(p.From.Offset&31) << 10
  4599  		}
  4600  		o1 |= uint32(p.To.Reg&31)<<5 | uint32(p.From.Reg&31)
  4601  
  4602  	case 60: /* adrp label,r */
  4603  		d := c.brdist(p, 12, 21, 0)
  4604  
  4605  		o1 = ADR(1, uint32(d), uint32(p.To.Reg))
  4606  
  4607  	case 61: /* adr label, r */
  4608  		d := c.brdist(p, 0, 21, 0)
  4609  
  4610  		o1 = ADR(0, uint32(d), uint32(p.To.Reg))
  4611  
  4612  	case 62: /* op $movcon, [R], R -> mov $movcon, REGTMP + op REGTMP, [R], R */
  4613  		if p.Reg == REGTMP {
  4614  			c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
  4615  		}
  4616  		if p.To.Reg == REG_RSP && isADDSop(p.As) {
  4617  			c.ctxt.Diag("illegal destination register: %v\n", p)
  4618  		}
  4619  		lsl0 := LSL0_64
  4620  		if isADDWop(p.As) || isANDWop(p.As) {
  4621  			o1 = c.omovconst(AMOVW, p, &p.From, REGTMP)
  4622  			lsl0 = LSL0_32
  4623  		} else {
  4624  			o1 = c.omovconst(AMOVD, p, &p.From, REGTMP)
  4625  		}
  4626  
  4627  		rt, r, rf := p.To.Reg, p.Reg, int16(REGTMP)
  4628  		if p.To.Type == obj.TYPE_NONE {
  4629  			rt = REGZERO
  4630  		}
  4631  		if r == obj.REG_NONE {
  4632  			r = rt
  4633  		}
  4634  		if rt == REGSP || r == REGSP {
  4635  			o2 = c.opxrrr(p, p.As, rt, r, rf, false)
  4636  			o2 |= uint32(lsl0)
  4637  		} else {
  4638  			o2 = c.oprrr(p, p.As)
  4639  			o2 |= uint32(rf&31) << 16 /* shift is 0 */
  4640  			o2 |= uint32(r&31) << 5
  4641  			o2 |= uint32(rt & 31)
  4642  		}
  4643  
  4644  	case 63: /* op Vm.<t>, Vn.<T>, Vd.<T> */
  4645  		o1 |= c.oprrr(p, p.As)
  4646  		af := (p.From.Reg >> 5) & 15
  4647  		at := (p.To.Reg >> 5) & 15
  4648  		ar := (p.Reg >> 5) & 15
  4649  		sz := ARNG_4S
  4650  		if p.As == ASHA512SU1 {
  4651  			sz = ARNG_2D
  4652  		}
  4653  		if af != at || af != ar || af != int16(sz) {
  4654  			c.ctxt.Diag("invalid arrangement: %v", p)
  4655  		}
  4656  		o1 |= uint32(p.From.Reg&31)<<16 | uint32(p.Reg&31)<<5 | uint32(p.To.Reg&31)
  4657  
  4658  	/* reloc ops */
  4659  	case 64: /* movT R,addr -> adrp + movT R, (REGTMP) */
  4660  		if p.From.Reg == REGTMP {
  4661  			c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
  4662  		}
  4663  		o1 = ADR(1, 0, REGTMP)
  4664  		rel := obj.Addrel(c.cursym)
  4665  		rel.Off = int32(c.pc)
  4666  		rel.Siz = 8
  4667  		rel.Sym = p.To.Sym
  4668  		rel.Add = p.To.Offset
  4669  		// For unaligned access, fall back to adrp + add + movT R, (REGTMP).
  4670  		if o.size(c.ctxt, p) != 8 {
  4671  			o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
  4672  			o3 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg)
  4673  			rel.Type = objabi.R_ADDRARM64
  4674  			break
  4675  		}
  4676  		o2 = c.olsr12u(p, c.opstr(p, p.As), 0, REGTMP, p.From.Reg)
  4677  		rel.Type = c.addrRelocType(p)
  4678  
  4679  	case 65: /* movT addr,R -> adrp + movT (REGTMP), R */
  4680  		o1 = ADR(1, 0, REGTMP)
  4681  		rel := obj.Addrel(c.cursym)
  4682  		rel.Off = int32(c.pc)
  4683  		rel.Siz = 8
  4684  		rel.Sym = p.From.Sym
  4685  		rel.Add = p.From.Offset
  4686  		// For unaligned access, fall back to adrp + add + movT (REGTMP), R.
  4687  		if o.size(c.ctxt, p) != 8 {
  4688  			o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
  4689  			o3 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg)
  4690  			rel.Type = objabi.R_ADDRARM64
  4691  			break
  4692  		}
  4693  		o2 = c.olsr12u(p, c.opldr(p, p.As), 0, REGTMP, p.To.Reg)
  4694  		rel.Type = c.addrRelocType(p)
  4695  
  4696  	case 66: /* ldp O(R)!, (r1, r2); ldp (R)O!, (r1, r2) */
  4697  		rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset)
  4698  		if rf == obj.REG_NONE {
  4699  			rf = o.param
  4700  		}
  4701  		if rf == obj.REG_NONE {
  4702  			c.ctxt.Diag("invalid ldp source: %v\n", p)
  4703  		}
  4704  		v := c.regoff(&p.From)
  4705  		o1 = c.opldpstp(p, o, v, rf, rt1, rt2, 1)
  4706  
  4707  	case 67: /* stp (r1, r2), O(R)!; stp (r1, r2), (R)O! */
  4708  		rt, rf1, rf2 := p.To.Reg, p.From.Reg, int16(p.From.Offset)
  4709  		if rt == obj.REG_NONE {
  4710  			rt = o.param
  4711  		}
  4712  		if rt == obj.REG_NONE {
  4713  			c.ctxt.Diag("invalid stp destination: %v\n", p)
  4714  		}
  4715  		v := c.regoff(&p.To)
  4716  		o1 = c.opldpstp(p, o, v, rt, rf1, rf2, 0)
  4717  
  4718  	case 68: /* movT $vconaddr(SB), reg -> adrp + add + reloc */
  4719  		// NOTE: this case does not use REGTMP. If it ever does,
  4720  		// remove the NOTUSETMP flag in optab.
  4721  		if p.As == AMOVW {
  4722  			c.ctxt.Diag("invalid load of 32-bit address: %v", p)
  4723  		}
  4724  		o1 = ADR(1, 0, uint32(p.To.Reg))
  4725  		o2 = c.opirr(p, AADD) | uint32(p.To.Reg&31)<<5 | uint32(p.To.Reg&31)
  4726  		rel := obj.Addrel(c.cursym)
  4727  		rel.Off = int32(c.pc)
  4728  		rel.Siz = 8
  4729  		rel.Sym = p.From.Sym
  4730  		rel.Add = p.From.Offset
  4731  		rel.Type = objabi.R_ADDRARM64
  4732  
  4733  	case 69: /* LE model movd $tlsvar, reg -> movz reg, 0 + reloc */
  4734  		o1 = c.opirr(p, AMOVZ)
  4735  		o1 |= uint32(p.To.Reg & 31)
  4736  		rel := obj.Addrel(c.cursym)
  4737  		rel.Off = int32(c.pc)
  4738  		rel.Siz = 4
  4739  		rel.Sym = p.From.Sym
  4740  		rel.Type = objabi.R_ARM64_TLS_LE
  4741  		if p.From.Offset != 0 {
  4742  			c.ctxt.Diag("invalid offset on MOVW $tlsvar")
  4743  		}
  4744  
  4745  	case 70: /* IE model movd $tlsvar, reg -> adrp REGTMP, 0; ldr reg, [REGTMP, #0] + relocs */
  4746  		o1 = ADR(1, 0, REGTMP)
  4747  		o2 = c.olsr12u(p, c.opldr(p, AMOVD), 0, REGTMP, p.To.Reg)
  4748  		rel := obj.Addrel(c.cursym)
  4749  		rel.Off = int32(c.pc)
  4750  		rel.Siz = 8
  4751  		rel.Sym = p.From.Sym
  4752  		rel.Add = 0
  4753  		rel.Type = objabi.R_ARM64_TLS_IE
  4754  		if p.From.Offset != 0 {
  4755  			c.ctxt.Diag("invalid offset on MOVW $tlsvar")
  4756  		}
  4757  
  4758  	case 71: /* movd sym@GOT, reg -> adrp REGTMP, #0; ldr reg, [REGTMP, #0] + relocs */
  4759  		o1 = ADR(1, 0, REGTMP)
  4760  		o2 = c.olsr12u(p, c.opldr(p, AMOVD), 0, REGTMP, p.To.Reg)
  4761  		rel := obj.Addrel(c.cursym)
  4762  		rel.Off = int32(c.pc)
  4763  		rel.Siz = 8
  4764  		rel.Sym = p.From.Sym
  4765  		rel.Add = 0
  4766  		rel.Type = objabi.R_ARM64_GOTPCREL
  4767  
  4768  	case 72: /* vaddp/vand/vcmeq/vorr/vadd/veor/vfmla/vfmls/vbit/vbsl/vcmtst/vsub/vbif/vuzip1/vuzip2/vrax1 Vm.<T>, Vn.<T>, Vd.<T> */
  4769  		af := int((p.From.Reg >> 5) & 15)
  4770  		af3 := int((p.Reg >> 5) & 15)
  4771  		at := int((p.To.Reg >> 5) & 15)
  4772  		if af != af3 || af != at {
  4773  			c.ctxt.Diag("operand mismatch: %v", p)
  4774  			break
  4775  		}
  4776  		o1 = c.oprrr(p, p.As)
  4777  		rf := int((p.From.Reg) & 31)
  4778  		rt := int((p.To.Reg) & 31)
  4779  		r := int((p.Reg) & 31)
  4780  
  4781  		Q := 0
  4782  		size := 0
  4783  		switch af {
  4784  		case ARNG_16B:
  4785  			Q = 1
  4786  			size = 0
  4787  		case ARNG_2D:
  4788  			Q = 1
  4789  			size = 3
  4790  		case ARNG_2S:
  4791  			Q = 0
  4792  			size = 2
  4793  		case ARNG_4H:
  4794  			Q = 0
  4795  			size = 1
  4796  		case ARNG_4S:
  4797  			Q = 1
  4798  			size = 2
  4799  		case ARNG_8B:
  4800  			Q = 0
  4801  			size = 0
  4802  		case ARNG_8H:
  4803  			Q = 1
  4804  			size = 1
  4805  		default:
  4806  			c.ctxt.Diag("invalid arrangement: %v", p)
  4807  		}
  4808  
  4809  		switch p.As {
  4810  		case AVORR, AVAND, AVEOR, AVBIT, AVBSL, AVBIF:
  4811  			if af != ARNG_16B && af != ARNG_8B {
  4812  				c.ctxt.Diag("invalid arrangement: %v", p)
  4813  			}
  4814  		case AVFMLA, AVFMLS:
  4815  			if af != ARNG_2D && af != ARNG_2S && af != ARNG_4S {
  4816  				c.ctxt.Diag("invalid arrangement: %v", p)
  4817  			}
  4818  		case AVUMAX, AVUMIN:
  4819  			if af == ARNG_2D {
  4820  				c.ctxt.Diag("invalid arrangement: %v", p)
  4821  			}
  4822  		}
  4823  		switch p.As {
  4824  		case AVAND, AVEOR:
  4825  			size = 0
  4826  		case AVBSL:
  4827  			size = 1
  4828  		case AVORR, AVBIT, AVBIF:
  4829  			size = 2
  4830  		case AVFMLA, AVFMLS:
  4831  			if af == ARNG_2D {
  4832  				size = 1
  4833  			} else {
  4834  				size = 0
  4835  			}
  4836  		case AVRAX1:
  4837  			if af != ARNG_2D {
  4838  				c.ctxt.Diag("invalid arrangement: %v", p)
  4839  			}
  4840  			size = 0
  4841  			Q = 0
  4842  		}
  4843  
  4844  		o1 |= (uint32(Q&1) << 30) | (uint32(size&3) << 22) | (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
  4845  
  4846  	case 73: /* vmov V.<T>[index], R */
  4847  		rf := int(p.From.Reg)
  4848  		rt := int(p.To.Reg)
  4849  		imm5 := 0
  4850  		o1 = 7<<25 | 0xf<<10
  4851  		index := int(p.From.Index)
  4852  		switch (p.From.Reg >> 5) & 15 {
  4853  		case ARNG_B:
  4854  			c.checkindex(p, index, 15)
  4855  			imm5 |= 1
  4856  			imm5 |= index << 1
  4857  		case ARNG_H:
  4858  			c.checkindex(p, index, 7)
  4859  			imm5 |= 2
  4860  			imm5 |= index << 2
  4861  		case ARNG_S:
  4862  			c.checkindex(p, index, 3)
  4863  			imm5 |= 4
  4864  			imm5 |= index << 3
  4865  		case ARNG_D:
  4866  			c.checkindex(p, index, 1)
  4867  			imm5 |= 8
  4868  			imm5 |= index << 4
  4869  			o1 |= 1 << 30
  4870  		default:
  4871  			c.ctxt.Diag("invalid arrangement: %v", p)
  4872  		}
  4873  		o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
  4874  
  4875  	case 74:
  4876  		//	add $O, R, Rtmp or sub $O, R, Rtmp
  4877  		//	ldp (Rtmp), (R1, R2)
  4878  		rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset)
  4879  		if rf == obj.REG_NONE {
  4880  			rf = o.param
  4881  		}
  4882  		if rf == obj.REG_NONE {
  4883  			c.ctxt.Diag("invalid ldp source: %v", p)
  4884  		}
  4885  		v := c.regoff(&p.From)
  4886  		o1 = c.oaddi12(p, v, REGTMP, rf)
  4887  		o2 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1)
  4888  
  4889  	case 75:
  4890  		// If offset L fits in a 24 bit unsigned immediate:
  4891  		//	add $lo, R, Rtmp
  4892  		//	add $hi, Rtmp, Rtmp
  4893  		//	ldr (Rtmp), R
  4894  		// Otherwise, use constant pool:
  4895  		//	mov $L, Rtmp (from constant pool)
  4896  		//	add Rtmp, R, Rtmp
  4897  		//	ldp (Rtmp), (R1, R2)
  4898  		rf, rt1, rt2 := p.From.Reg, p.To.Reg, int16(p.To.Offset)
  4899  		if rf == REGTMP {
  4900  			c.ctxt.Diag("REGTMP used in large offset load: %v", p)
  4901  		}
  4902  		if rf == obj.REG_NONE {
  4903  			rf = o.param
  4904  		}
  4905  		if rf == obj.REG_NONE {
  4906  			c.ctxt.Diag("invalid ldp source: %v", p)
  4907  		}
  4908  
  4909  		v := c.regoff(&p.From)
  4910  		if v >= -4095 && v <= 4095 {
  4911  			c.ctxt.Diag("%v: bad type for offset %d (should be add/sub+ldp)", p, v)
  4912  		}
  4913  
  4914  		hi, lo, err := splitImm24uScaled(v, 0)
  4915  		if err != nil {
  4916  			goto loadpairusepool
  4917  		}
  4918  		if p.Pool != nil {
  4919  			c.ctxt.Diag("%v: unused constant in pool (%v)\n", p, v)
  4920  		}
  4921  		o1 = c.oaddi(p, AADD, lo, REGTMP, int16(rf))
  4922  		o2 = c.oaddi(p, AADD, hi, REGTMP, REGTMP)
  4923  		o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1)
  4924  		break
  4925  
  4926  	loadpairusepool:
  4927  		if p.Pool == nil {
  4928  			c.ctxt.Diag("%v: constant is not in pool", p)
  4929  		}
  4930  		if rf == REGTMP || p.From.Reg == REGTMP {
  4931  			c.ctxt.Diag("REGTMP used in large offset load: %v", p)
  4932  		}
  4933  		o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
  4934  		o2 = c.opxrrr(p, AADD, REGTMP, rf, REGTMP, false)
  4935  		o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1)
  4936  
  4937  	case 76:
  4938  		//	add $O, R, Rtmp or sub $O, R, Rtmp
  4939  		//	stp (R1, R2), (Rtmp)
  4940  		rt, rf1, rf2 := p.To.Reg, p.From.Reg, int16(p.From.Offset)
  4941  		if rf1 == REGTMP || rf2 == REGTMP {
  4942  			c.ctxt.Diag("cannot use REGTMP as source: %v", p)
  4943  		}
  4944  		if rt == obj.REG_NONE {
  4945  			rt = o.param
  4946  		}
  4947  		if rt == obj.REG_NONE {
  4948  			c.ctxt.Diag("invalid stp destination: %v", p)
  4949  		}
  4950  		v := c.regoff(&p.To)
  4951  		o1 = c.oaddi12(p, v, REGTMP, rt)
  4952  		o2 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0)
  4953  
  4954  	case 77:
  4955  		// If offset L fits in a 24 bit unsigned immediate:
  4956  		//	add $lo, R, Rtmp
  4957  		//	add $hi, Rtmp, Rtmp
  4958  		//	stp (R1, R2), (Rtmp)
  4959  		// Otherwise, use constant pool:
  4960  		//	mov $L, Rtmp (from constant pool)
  4961  		//	add Rtmp, R, Rtmp
  4962  		//	stp (R1, R2), (Rtmp)
  4963  		rt, rf1, rf2 := p.To.Reg, p.From.Reg, int16(p.From.Offset)
  4964  		if rt == REGTMP || rf1 == REGTMP || rf2 == REGTMP {
  4965  			c.ctxt.Diag("REGTMP used in large offset store: %v", p)
  4966  		}
  4967  		if rt == obj.REG_NONE {
  4968  			rt = o.param
  4969  		}
  4970  		if rt == obj.REG_NONE {
  4971  			c.ctxt.Diag("invalid stp destination: %v", p)
  4972  		}
  4973  
  4974  		v := c.regoff(&p.To)
  4975  		if v >= -4095 && v <= 4095 {
  4976  			c.ctxt.Diag("%v: bad type for offset %d (should be add/sub+stp)", p, v)
  4977  		}
  4978  
  4979  		hi, lo, err := splitImm24uScaled(v, 0)
  4980  		if err != nil {
  4981  			goto storepairusepool
  4982  		}
  4983  		if p.Pool != nil {
  4984  			c.ctxt.Diag("%v: unused constant in pool (%v)\n", p, v)
  4985  		}
  4986  		o1 = c.oaddi(p, AADD, lo, REGTMP, int16(rt))
  4987  		o2 = c.oaddi(p, AADD, hi, REGTMP, REGTMP)
  4988  		o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0)
  4989  		break
  4990  
  4991  	storepairusepool:
  4992  		if p.Pool == nil {
  4993  			c.ctxt.Diag("%v: constant is not in pool", p)
  4994  		}
  4995  		if rt == REGTMP || p.From.Reg == REGTMP {
  4996  			c.ctxt.Diag("REGTMP used in large offset store: %v", p)
  4997  		}
  4998  		o1 = c.omovlit(AMOVD, p, &p.To, REGTMP)
  4999  		o2 = c.opxrrr(p, AADD, REGTMP, rt, REGTMP, false)
  5000  		o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0)
  5001  
  5002  	case 78: /* vmov R, V.<T>[index] */
  5003  		rf := int(p.From.Reg)
  5004  		rt := int(p.To.Reg)
  5005  		imm5 := 0
  5006  		o1 = 1<<30 | 7<<25 | 7<<10
  5007  		index := int(p.To.Index)
  5008  		switch (p.To.Reg >> 5) & 15 {
  5009  		case ARNG_B:
  5010  			c.checkindex(p, index, 15)
  5011  			imm5 |= 1
  5012  			imm5 |= index << 1
  5013  		case ARNG_H:
  5014  			c.checkindex(p, index, 7)
  5015  			imm5 |= 2
  5016  			imm5 |= index << 2
  5017  		case ARNG_S:
  5018  			c.checkindex(p, index, 3)
  5019  			imm5 |= 4
  5020  			imm5 |= index << 3
  5021  		case ARNG_D:
  5022  			c.checkindex(p, index, 1)
  5023  			imm5 |= 8
  5024  			imm5 |= index << 4
  5025  		default:
  5026  			c.ctxt.Diag("invalid arrangement: %v", p)
  5027  		}
  5028  		o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
  5029  
  5030  	case 79: /* vdup Vn.<T>[index], Vd.<T> */
  5031  		rf := int(p.From.Reg)
  5032  		rt := int(p.To.Reg)
  5033  		o1 = 7<<25 | 1<<10
  5034  		var imm5, Q int
  5035  		index := int(p.From.Index)
  5036  		switch (p.To.Reg >> 5) & 15 {
  5037  		case ARNG_16B:
  5038  			c.checkindex(p, index, 15)
  5039  			Q = 1
  5040  			imm5 = 1
  5041  			imm5 |= index << 1
  5042  		case ARNG_2D:
  5043  			c.checkindex(p, index, 1)
  5044  			Q = 1
  5045  			imm5 = 8
  5046  			imm5 |= index << 4
  5047  		case ARNG_2S:
  5048  			c.checkindex(p, index, 3)
  5049  			Q = 0
  5050  			imm5 = 4
  5051  			imm5 |= index << 3
  5052  		case ARNG_4H:
  5053  			c.checkindex(p, index, 7)
  5054  			Q = 0
  5055  			imm5 = 2
  5056  			imm5 |= index << 2
  5057  		case ARNG_4S:
  5058  			c.checkindex(p, index, 3)
  5059  			Q = 1
  5060  			imm5 = 4
  5061  			imm5 |= index << 3
  5062  		case ARNG_8B:
  5063  			c.checkindex(p, index, 15)
  5064  			Q = 0
  5065  			imm5 = 1
  5066  			imm5 |= index << 1
  5067  		case ARNG_8H:
  5068  			c.checkindex(p, index, 7)
  5069  			Q = 1
  5070  			imm5 = 2
  5071  			imm5 |= index << 2
  5072  		default:
  5073  			c.ctxt.Diag("invalid arrangement: %v", p)
  5074  		}
  5075  		o1 |= (uint32(Q&1) << 30) | (uint32(imm5&0x1f) << 16)
  5076  		o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
  5077  
  5078  	case 80: /* vmov/vdup V.<T>[index], Vn */
  5079  		rf := int(p.From.Reg)
  5080  		rt := int(p.To.Reg)
  5081  		imm5 := 0
  5082  		index := int(p.From.Index)
  5083  		switch p.As {
  5084  		case AVMOV, AVDUP:
  5085  			o1 = 1<<30 | 15<<25 | 1<<10
  5086  			switch (p.From.Reg >> 5) & 15 {
  5087  			case ARNG_B:
  5088  				c.checkindex(p, index, 15)
  5089  				imm5 |= 1
  5090  				imm5 |= index << 1
  5091  			case ARNG_H:
  5092  				c.checkindex(p, index, 7)
  5093  				imm5 |= 2
  5094  				imm5 |= index << 2
  5095  			case ARNG_S:
  5096  				c.checkindex(p, index, 3)
  5097  				imm5 |= 4
  5098  				imm5 |= index << 3
  5099  			case ARNG_D:
  5100  				c.checkindex(p, index, 1)
  5101  				imm5 |= 8
  5102  				imm5 |= index << 4
  5103  			default:
  5104  				c.ctxt.Diag("invalid arrangement: %v", p)
  5105  			}
  5106  		default:
  5107  			c.ctxt.Diag("unsupported op %v", p.As)
  5108  		}
  5109  		o1 |= (uint32(imm5&0x1f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
  5110  
  5111  	case 81: /* vld[1-4]|vld[1-4]r (Rn), [Vt1.<T>, Vt2.<T>, ...] */
  5112  		c.checkoffset(p, p.As)
  5113  		r := int(p.From.Reg)
  5114  		o1 = c.oprrr(p, p.As)
  5115  		if o.scond == C_XPOST {
  5116  			o1 |= 1 << 23
  5117  			if p.From.Index == 0 {
  5118  				// immediate offset variant
  5119  				o1 |= 0x1f << 16
  5120  			} else {
  5121  				// register offset variant
  5122  				if isRegShiftOrExt(&p.From) {
  5123  					c.ctxt.Diag("invalid extended register op: %v\n", p)
  5124  				}
  5125  				o1 |= uint32(p.From.Index&0x1f) << 16
  5126  			}
  5127  		}
  5128  		o1 |= uint32(p.To.Offset)
  5129  		// github.com/go-asm/go/cmd/asm/arch/arm64.go:ARM64RegisterListOffset
  5130  		// add opcode(bit 12-15) for vld1, mask it off if it's not vld1
  5131  		o1 = c.maskOpvldvst(p, o1)
  5132  		o1 |= uint32(r&31) << 5
  5133  
  5134  	case 82: /* vmov/vdup Rn, Vd.<T> */
  5135  		rf := int(p.From.Reg)
  5136  		rt := int(p.To.Reg)
  5137  		o1 = 7<<25 | 3<<10
  5138  		var imm5, Q uint32
  5139  		switch (p.To.Reg >> 5) & 15 {
  5140  		case ARNG_16B:
  5141  			Q = 1
  5142  			imm5 = 1
  5143  		case ARNG_2D:
  5144  			Q = 1
  5145  			imm5 = 8
  5146  		case ARNG_2S:
  5147  			Q = 0
  5148  			imm5 = 4
  5149  		case ARNG_4H:
  5150  			Q = 0
  5151  			imm5 = 2
  5152  		case ARNG_4S:
  5153  			Q = 1
  5154  			imm5 = 4
  5155  		case ARNG_8B:
  5156  			Q = 0
  5157  			imm5 = 1
  5158  		case ARNG_8H:
  5159  			Q = 1
  5160  			imm5 = 2
  5161  		default:
  5162  			c.ctxt.Diag("invalid arrangement: %v\n", p)
  5163  		}
  5164  		o1 |= (Q & 1 << 30) | (imm5 & 0x1f << 16)
  5165  		o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
  5166  
  5167  	case 83: /* vmov Vn.<T>, Vd.<T> */
  5168  		af := int((p.From.Reg >> 5) & 15)
  5169  		at := int((p.To.Reg >> 5) & 15)
  5170  		if af != at {
  5171  			c.ctxt.Diag("invalid arrangement: %v\n", p)
  5172  		}
  5173  		o1 = c.oprrr(p, p.As)
  5174  		rf := int((p.From.Reg) & 31)
  5175  		rt := int((p.To.Reg) & 31)
  5176  
  5177  		var Q, size uint32
  5178  		switch af {
  5179  		case ARNG_8B:
  5180  			Q = 0
  5181  			size = 0
  5182  		case ARNG_16B:
  5183  			Q = 1
  5184  			size = 0
  5185  		case ARNG_4H:
  5186  			Q = 0
  5187  			size = 1
  5188  		case ARNG_8H:
  5189  			Q = 1
  5190  			size = 1
  5191  		case ARNG_2S:
  5192  			Q = 0
  5193  			size = 2
  5194  		case ARNG_4S:
  5195  			Q = 1
  5196  			size = 2
  5197  		default:
  5198  			c.ctxt.Diag("invalid arrangement: %v\n", p)
  5199  		}
  5200  
  5201  		if (p.As == AVMOV || p.As == AVRBIT || p.As == AVCNT) && (af != ARNG_16B && af != ARNG_8B) {
  5202  			c.ctxt.Diag("invalid arrangement: %v", p)
  5203  		}
  5204  
  5205  		if p.As == AVREV32 && (af == ARNG_2S || af == ARNG_4S) {
  5206  			c.ctxt.Diag("invalid arrangement: %v", p)
  5207  		}
  5208  
  5209  		if p.As == AVREV16 && af != ARNG_8B && af != ARNG_16B {
  5210  			c.ctxt.Diag("invalid arrangement: %v", p)
  5211  		}
  5212  
  5213  		if p.As == AVMOV {
  5214  			o1 |= uint32(rf&31) << 16
  5215  		}
  5216  
  5217  		if p.As == AVRBIT {
  5218  			size = 1
  5219  		}
  5220  
  5221  		o1 |= (Q&1)<<30 | (size&3)<<22 | uint32(rf&31)<<5 | uint32(rt&31)
  5222  
  5223  	case 84: /* vst[1-4] [Vt1.<T>, Vt2.<T>, ...], (Rn) */
  5224  		c.checkoffset(p, p.As)
  5225  		r := int(p.To.Reg)
  5226  		o1 = 3 << 26
  5227  		if o.scond == C_XPOST {
  5228  			o1 |= 1 << 23
  5229  			if p.To.Index == 0 {
  5230  				// immediate offset variant
  5231  				o1 |= 0x1f << 16
  5232  			} else {
  5233  				// register offset variant
  5234  				if isRegShiftOrExt(&p.To) {
  5235  					c.ctxt.Diag("invalid extended register: %v\n", p)
  5236  				}
  5237  				o1 |= uint32(p.To.Index&31) << 16
  5238  			}
  5239  		}
  5240  		o1 |= uint32(p.From.Offset)
  5241  		// github.com/go-asm/go/cmd/asm/arch/arm64.go:ARM64RegisterListOffset
  5242  		// add opcode(bit 12-15) for vst1, mask it off if it's not vst1
  5243  		o1 = c.maskOpvldvst(p, o1)
  5244  		o1 |= uint32(r&31) << 5
  5245  
  5246  	case 85: /* vaddv/vuaddlv Vn.<T>, Vd*/
  5247  		af := int((p.From.Reg >> 5) & 15)
  5248  		o1 = c.oprrr(p, p.As)
  5249  		rf := int((p.From.Reg) & 31)
  5250  		rt := int((p.To.Reg) & 31)
  5251  		Q := 0
  5252  		size := 0
  5253  		switch af {
  5254  		case ARNG_8B:
  5255  			Q = 0
  5256  			size = 0
  5257  		case ARNG_16B:
  5258  			Q = 1
  5259  			size = 0
  5260  		case ARNG_4H:
  5261  			Q = 0
  5262  			size = 1
  5263  		case ARNG_8H:
  5264  			Q = 1
  5265  			size = 1
  5266  		case ARNG_4S:
  5267  			Q = 1
  5268  			size = 2
  5269  		default:
  5270  			c.ctxt.Diag("invalid arrangement: %v\n", p)
  5271  		}
  5272  		o1 |= (uint32(Q&1) << 30) | (uint32(size&3) << 22) | (uint32(rf&31) << 5) | uint32(rt&31)
  5273  
  5274  	case 86: /* vmovi $imm8, Vd.<T>*/
  5275  		at := int((p.To.Reg >> 5) & 15)
  5276  		r := int(p.From.Offset)
  5277  		if r > 255 || r < 0 {
  5278  			c.ctxt.Diag("immediate constant out of range: %v\n", p)
  5279  		}
  5280  		rt := int((p.To.Reg) & 31)
  5281  		Q := 0
  5282  		switch at {
  5283  		case ARNG_8B:
  5284  			Q = 0
  5285  		case ARNG_16B:
  5286  			Q = 1
  5287  		default:
  5288  			c.ctxt.Diag("invalid arrangement: %v\n", p)
  5289  		}
  5290  		o1 = 0xf<<24 | 0xe<<12 | 1<<10
  5291  		o1 |= (uint32(Q&1) << 30) | (uint32((r>>5)&7) << 16) | (uint32(r&0x1f) << 5) | uint32(rt&31)
  5292  
  5293  	case 87: /* stp (r,r), addr(SB) -> adrp + add + stp */
  5294  		rf1, rf2 := p.From.Reg, int16(p.From.Offset)
  5295  		if rf1 == REGTMP || rf2 == REGTMP {
  5296  			c.ctxt.Diag("cannot use REGTMP as source: %v", p)
  5297  		}
  5298  		o1 = ADR(1, 0, REGTMP)
  5299  		o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
  5300  		rel := obj.Addrel(c.cursym)
  5301  		rel.Off = int32(c.pc)
  5302  		rel.Siz = 8
  5303  		rel.Sym = p.To.Sym
  5304  		rel.Add = p.To.Offset
  5305  		rel.Type = objabi.R_ADDRARM64
  5306  		o3 = c.opldpstp(p, o, 0, REGTMP, rf1, rf2, 0)
  5307  
  5308  	case 88: /* ldp addr(SB), (r,r) -> adrp + add + ldp */
  5309  		rt1, rt2 := p.To.Reg, int16(p.To.Offset)
  5310  		o1 = ADR(1, 0, REGTMP)
  5311  		o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
  5312  		rel := obj.Addrel(c.cursym)
  5313  		rel.Off = int32(c.pc)
  5314  		rel.Siz = 8
  5315  		rel.Sym = p.From.Sym
  5316  		rel.Add = p.From.Offset
  5317  		rel.Type = objabi.R_ADDRARM64
  5318  		o3 = c.opldpstp(p, o, 0, REGTMP, rt1, rt2, 1)
  5319  
  5320  	case 89: /* vadd/vsub Vm, Vn, Vd */
  5321  		switch p.As {
  5322  		case AVADD:
  5323  			o1 = 5<<28 | 7<<25 | 7<<21 | 1<<15 | 1<<10
  5324  
  5325  		case AVSUB:
  5326  			o1 = 7<<28 | 7<<25 | 7<<21 | 1<<15 | 1<<10
  5327  
  5328  		default:
  5329  			c.ctxt.Diag("bad opcode: %v\n", p)
  5330  			break
  5331  		}
  5332  
  5333  		rf := int(p.From.Reg)
  5334  		rt := int(p.To.Reg)
  5335  		r := int(p.Reg)
  5336  		if r == obj.REG_NONE {
  5337  			r = rt
  5338  		}
  5339  		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
  5340  
  5341  	// This is supposed to be something that stops execution.
  5342  	// It's not supposed to be reached, ever, but if it is, we'd
  5343  	// like to be able to tell how we got there. Assemble as
  5344  	// 0xbea71700 which is guaranteed to raise undefined instruction
  5345  	// exception.
  5346  	case 90:
  5347  		o1 = 0xbea71700
  5348  
  5349  	case 91: /* prfm imm(Rn), <prfop | $imm5> */
  5350  		imm := uint32(p.From.Offset)
  5351  		r := p.From.Reg
  5352  		var v uint32
  5353  		var ok bool
  5354  		if p.To.Type == obj.TYPE_CONST {
  5355  			v = uint32(p.To.Offset)
  5356  			ok = v <= 31
  5357  		} else {
  5358  			v, ok = prfopfield[SpecialOperand(p.To.Offset)]
  5359  		}
  5360  		if !ok {
  5361  			c.ctxt.Diag("illegal prefetch operation:\n%v", p)
  5362  		}
  5363  
  5364  		o1 = c.opirr(p, p.As)
  5365  		o1 |= (uint32(r&31) << 5) | (uint32((imm>>3)&0xfff) << 10) | (uint32(v & 31))
  5366  
  5367  	case 92: /* vmov Vn.<T>[index], Vd.<T>[index] */
  5368  		rf := int(p.From.Reg)
  5369  		rt := int(p.To.Reg)
  5370  		imm4 := 0
  5371  		imm5 := 0
  5372  		o1 = 3<<29 | 7<<25 | 1<<10
  5373  		index1 := int(p.To.Index)
  5374  		index2 := int(p.From.Index)
  5375  		if ((p.To.Reg >> 5) & 15) != ((p.From.Reg >> 5) & 15) {
  5376  			c.ctxt.Diag("operand mismatch: %v", p)
  5377  		}
  5378  		switch (p.To.Reg >> 5) & 15 {
  5379  		case ARNG_B:
  5380  			c.checkindex(p, index1, 15)
  5381  			c.checkindex(p, index2, 15)
  5382  			imm5 |= 1
  5383  			imm5 |= index1 << 1
  5384  			imm4 |= index2
  5385  		case ARNG_H:
  5386  			c.checkindex(p, index1, 7)
  5387  			c.checkindex(p, index2, 7)
  5388  			imm5 |= 2
  5389  			imm5 |= index1 << 2
  5390  			imm4 |= index2 << 1
  5391  		case ARNG_S:
  5392  			c.checkindex(p, index1, 3)
  5393  			c.checkindex(p, index2, 3)
  5394  			imm5 |= 4
  5395  			imm5 |= index1 << 3
  5396  			imm4 |= index2 << 2
  5397  		case ARNG_D:
  5398  			c.checkindex(p, index1, 1)
  5399  			c.checkindex(p, index2, 1)
  5400  			imm5 |= 8
  5401  			imm5 |= index1 << 4
  5402  			imm4 |= index2 << 3
  5403  		default:
  5404  			c.ctxt.Diag("invalid arrangement: %v", p)
  5405  		}
  5406  		o1 |= (uint32(imm5&0x1f) << 16) | (uint32(imm4&0xf) << 11) | (uint32(rf&31) << 5) | uint32(rt&31)
  5407  
  5408  	case 93: /* vpmull{2} Vm.<Tb>, Vn.<Tb>, Vd.<Ta> */
  5409  		af := uint8((p.From.Reg >> 5) & 15)
  5410  		at := uint8((p.To.Reg >> 5) & 15)
  5411  		a := uint8((p.Reg >> 5) & 15)
  5412  		if af != a {
  5413  			c.ctxt.Diag("invalid arrangement: %v", p)
  5414  		}
  5415  
  5416  		var Q, size uint32
  5417  		if p.As == AVPMULL2 {
  5418  			Q = 1
  5419  		}
  5420  		switch pack(Q, at, af) {
  5421  		case pack(0, ARNG_8H, ARNG_8B), pack(1, ARNG_8H, ARNG_16B):
  5422  			size = 0
  5423  		case pack(0, ARNG_1Q, ARNG_1D), pack(1, ARNG_1Q, ARNG_2D):
  5424  			size = 3
  5425  		default:
  5426  			c.ctxt.Diag("operand mismatch: %v\n", p)
  5427  		}
  5428  
  5429  		o1 = c.oprrr(p, p.As)
  5430  		rf := int((p.From.Reg) & 31)
  5431  		rt := int((p.To.Reg) & 31)
  5432  		r := int((p.Reg) & 31)
  5433  		o1 |= ((Q & 1) << 30) | ((size & 3) << 22) | (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
  5434  
  5435  	case 94: /* vext $imm4, Vm.<T>, Vn.<T>, Vd.<T> */
  5436  		af := int(((p.GetFrom3().Reg) >> 5) & 15)
  5437  		at := int((p.To.Reg >> 5) & 15)
  5438  		a := int((p.Reg >> 5) & 15)
  5439  		index := int(p.From.Offset)
  5440  
  5441  		if af != a || af != at {
  5442  			c.ctxt.Diag("invalid arrangement: %v", p)
  5443  			break
  5444  		}
  5445  
  5446  		var Q uint32
  5447  		var b int
  5448  		if af == ARNG_8B {
  5449  			Q = 0
  5450  			b = 7
  5451  		} else if af == ARNG_16B {
  5452  			Q = 1
  5453  			b = 15
  5454  		} else {
  5455  			c.ctxt.Diag("invalid arrangement, should be B8 or B16: %v", p)
  5456  			break
  5457  		}
  5458  
  5459  		if index < 0 || index > b {
  5460  			c.ctxt.Diag("illegal offset: %v", p)
  5461  		}
  5462  
  5463  		o1 = c.opirr(p, p.As)
  5464  		rf := int((p.GetFrom3().Reg) & 31)
  5465  		rt := int((p.To.Reg) & 31)
  5466  		r := int((p.Reg) & 31)
  5467  
  5468  		o1 |= ((Q & 1) << 30) | (uint32(r&31) << 16) | (uint32(index&15) << 11) | (uint32(rf&31) << 5) | uint32(rt&31)
  5469  
  5470  	case 95: /* vushr/vshl/vsri/vsli/vusra $shift, Vn.<T>, Vd.<T> */
  5471  		at := int((p.To.Reg >> 5) & 15)
  5472  		af := int((p.Reg >> 5) & 15)
  5473  		shift := int(p.From.Offset)
  5474  
  5475  		if af != at {
  5476  			c.ctxt.Diag("invalid arrangement on op Vn.<T>, Vd.<T>: %v", p)
  5477  		}
  5478  
  5479  		var Q uint32
  5480  		var imax, esize int
  5481  
  5482  		switch af {
  5483  		case ARNG_8B, ARNG_4H, ARNG_2S:
  5484  			Q = 0
  5485  		case ARNG_16B, ARNG_8H, ARNG_4S, ARNG_2D:
  5486  			Q = 1
  5487  		default:
  5488  			c.ctxt.Diag("invalid arrangement on op Vn.<T>, Vd.<T>: %v", p)
  5489  		}
  5490  
  5491  		switch af {
  5492  		case ARNG_8B, ARNG_16B:
  5493  			imax = 15
  5494  			esize = 8
  5495  		case ARNG_4H, ARNG_8H:
  5496  			imax = 31
  5497  			esize = 16
  5498  		case ARNG_2S, ARNG_4S:
  5499  			imax = 63
  5500  			esize = 32
  5501  		case ARNG_2D:
  5502  			imax = 127
  5503  			esize = 64
  5504  		}
  5505  
  5506  		imm := 0
  5507  		switch p.As {
  5508  		case AVUSHR, AVSRI, AVUSRA:
  5509  			imm = esize*2 - shift
  5510  			if imm < esize || imm > imax {
  5511  				c.ctxt.Diag("shift out of range: %v", p)
  5512  			}
  5513  		case AVSHL, AVSLI:
  5514  			imm = esize + shift
  5515  			if imm > imax {
  5516  				c.ctxt.Diag("shift out of range: %v", p)
  5517  			}
  5518  		default:
  5519  			c.ctxt.Diag("invalid instruction %v\n", p)
  5520  		}
  5521  
  5522  		o1 = c.opirr(p, p.As)
  5523  		rt := int((p.To.Reg) & 31)
  5524  		rf := int((p.Reg) & 31)
  5525  
  5526  		o1 |= ((Q & 1) << 30) | (uint32(imm&0x7f) << 16) | (uint32(rf&31) << 5) | uint32(rt&31)
  5527  
  5528  	case 96: /* vst1 Vt1.<T>[index], offset(Rn) */
  5529  		af := int((p.From.Reg >> 5) & 15)
  5530  		rt := int((p.From.Reg) & 31)
  5531  		rf := int((p.To.Reg) & 31)
  5532  		r := int(p.To.Index & 31)
  5533  		index := int(p.From.Index)
  5534  		offset := c.regoff(&p.To)
  5535  
  5536  		if o.scond == C_XPOST {
  5537  			if (p.To.Index != 0) && (offset != 0) {
  5538  				c.ctxt.Diag("invalid offset: %v", p)
  5539  			}
  5540  			if p.To.Index == 0 && offset == 0 {
  5541  				c.ctxt.Diag("invalid offset: %v", p)
  5542  			}
  5543  		}
  5544  
  5545  		if offset != 0 {
  5546  			r = 31
  5547  		}
  5548  
  5549  		var Q, S, size int
  5550  		var opcode uint32
  5551  		switch af {
  5552  		case ARNG_B:
  5553  			c.checkindex(p, index, 15)
  5554  			if o.scond == C_XPOST && offset != 0 && offset != 1 {
  5555  				c.ctxt.Diag("invalid offset: %v", p)
  5556  			}
  5557  			Q = index >> 3
  5558  			S = (index >> 2) & 1
  5559  			size = index & 3
  5560  			opcode = 0
  5561  		case ARNG_H:
  5562  			c.checkindex(p, index, 7)
  5563  			if o.scond == C_XPOST && offset != 0 && offset != 2 {
  5564  				c.ctxt.Diag("invalid offset: %v", p)
  5565  			}
  5566  			Q = index >> 2
  5567  			S = (index >> 1) & 1
  5568  			size = (index & 1) << 1
  5569  			opcode = 2
  5570  		case ARNG_S:
  5571  			c.checkindex(p, index, 3)
  5572  			if o.scond == C_XPOST && offset != 0 && offset != 4 {
  5573  				c.ctxt.Diag("invalid offset: %v", p)
  5574  			}
  5575  			Q = index >> 1
  5576  			S = index & 1
  5577  			size = 0
  5578  			opcode = 4
  5579  		case ARNG_D:
  5580  			c.checkindex(p, index, 1)
  5581  			if o.scond == C_XPOST && offset != 0 && offset != 8 {
  5582  				c.ctxt.Diag("invalid offset: %v", p)
  5583  			}
  5584  			Q = index
  5585  			S = 0
  5586  			size = 1
  5587  			opcode = 4
  5588  		default:
  5589  			c.ctxt.Diag("invalid arrangement: %v", p)
  5590  		}
  5591  
  5592  		if o.scond == C_XPOST {
  5593  			o1 |= 27 << 23
  5594  		} else {
  5595  			o1 |= 26 << 23
  5596  		}
  5597  
  5598  		o1 |= (uint32(Q&1) << 30) | (uint32(r&31) << 16) | ((opcode & 7) << 13) | (uint32(S&1) << 12) | (uint32(size&3) << 10) | (uint32(rf&31) << 5) | uint32(rt&31)
  5599  
  5600  	case 97: /* vld1 offset(Rn), vt.<T>[index] */
  5601  		at := int((p.To.Reg >> 5) & 15)
  5602  		rt := int((p.To.Reg) & 31)
  5603  		rf := int((p.From.Reg) & 31)
  5604  		r := int(p.From.Index & 31)
  5605  		index := int(p.To.Index)
  5606  		offset := c.regoff(&p.From)
  5607  
  5608  		if o.scond == C_XPOST {
  5609  			if (p.From.Index != 0) && (offset != 0) {
  5610  				c.ctxt.Diag("invalid offset: %v", p)
  5611  			}
  5612  			if p.From.Index == 0 && offset == 0 {
  5613  				c.ctxt.Diag("invalid offset: %v", p)
  5614  			}
  5615  		}
  5616  
  5617  		if offset != 0 {
  5618  			r = 31
  5619  		}
  5620  
  5621  		Q := 0
  5622  		S := 0
  5623  		size := 0
  5624  		var opcode uint32
  5625  		switch at {
  5626  		case ARNG_B:
  5627  			c.checkindex(p, index, 15)
  5628  			if o.scond == C_XPOST && offset != 0 && offset != 1 {
  5629  				c.ctxt.Diag("invalid offset: %v", p)
  5630  			}
  5631  			Q = index >> 3
  5632  			S = (index >> 2) & 1
  5633  			size = index & 3
  5634  			opcode = 0
  5635  		case ARNG_H:
  5636  			c.checkindex(p, index, 7)
  5637  			if o.scond == C_XPOST && offset != 0 && offset != 2 {
  5638  				c.ctxt.Diag("invalid offset: %v", p)
  5639  			}
  5640  			Q = index >> 2
  5641  			S = (index >> 1) & 1
  5642  			size = (index & 1) << 1
  5643  			opcode = 2
  5644  		case ARNG_S:
  5645  			c.checkindex(p, index, 3)
  5646  			if o.scond == C_XPOST && offset != 0 && offset != 4 {
  5647  				c.ctxt.Diag("invalid offset: %v", p)
  5648  			}
  5649  			Q = index >> 1
  5650  			S = index & 1
  5651  			size = 0
  5652  			opcode = 4
  5653  		case ARNG_D:
  5654  			c.checkindex(p, index, 1)
  5655  			if o.scond == C_XPOST && offset != 0 && offset != 8 {
  5656  				c.ctxt.Diag("invalid offset: %v", p)
  5657  			}
  5658  			Q = index
  5659  			S = 0
  5660  			size = 1
  5661  			opcode = 4
  5662  		default:
  5663  			c.ctxt.Diag("invalid arrangement: %v", p)
  5664  		}
  5665  
  5666  		if o.scond == C_XPOST {
  5667  			o1 |= 110 << 21
  5668  		} else {
  5669  			o1 |= 106 << 21
  5670  		}
  5671  
  5672  		o1 |= (uint32(Q&1) << 30) | (uint32(r&31) << 16) | ((opcode & 7) << 13) | (uint32(S&1) << 12) | (uint32(size&3) << 10) | (uint32(rf&31) << 5) | uint32(rt&31)
  5673  
  5674  	case 98: /* MOVD (Rn)(Rm.SXTW[<<amount]),Rd */
  5675  		if isRegShiftOrExt(&p.From) {
  5676  			// extended or shifted offset register.
  5677  			c.checkShiftAmount(p, &p.From)
  5678  
  5679  			o1 = c.opldrr(p, p.As, true)
  5680  			o1 |= c.encRegShiftOrExt(p, &p.From, p.From.Index) /* includes reg, op, etc */
  5681  		} else {
  5682  			// (Rn)(Rm), no extension or shift.
  5683  			o1 = c.opldrr(p, p.As, false)
  5684  			o1 |= uint32(p.From.Index&31) << 16
  5685  		}
  5686  		o1 |= uint32(p.From.Reg&31) << 5
  5687  		rt := int(p.To.Reg)
  5688  		o1 |= uint32(rt & 31)
  5689  
  5690  	case 99: /* MOVD Rt, (Rn)(Rm.SXTW[<<amount]) */
  5691  		if isRegShiftOrExt(&p.To) {
  5692  			// extended or shifted offset register.
  5693  			c.checkShiftAmount(p, &p.To)
  5694  
  5695  			o1 = c.opstrr(p, p.As, true)
  5696  			o1 |= c.encRegShiftOrExt(p, &p.To, p.To.Index) /* includes reg, op, etc */
  5697  		} else {
  5698  			// (Rn)(Rm), no extension or shift.
  5699  			o1 = c.opstrr(p, p.As, false)
  5700  			o1 |= uint32(p.To.Index&31) << 16
  5701  		}
  5702  		o1 |= uint32(p.To.Reg&31) << 5
  5703  		rf := int(p.From.Reg)
  5704  		o1 |= uint32(rf & 31)
  5705  
  5706  	case 100: /* VTBL/VTBX Vn.<T>, [Vt1.<T>, Vt2.<T>, ...], Vd.<T> */
  5707  		af := int((p.From.Reg >> 5) & 15)
  5708  		at := int((p.To.Reg >> 5) & 15)
  5709  		if af != at {
  5710  			c.ctxt.Diag("invalid arrangement: %v\n", p)
  5711  		}
  5712  		var q, len uint32
  5713  		switch af {
  5714  		case ARNG_8B:
  5715  			q = 0
  5716  		case ARNG_16B:
  5717  			q = 1
  5718  		default:
  5719  			c.ctxt.Diag("invalid arrangement: %v", p)
  5720  		}
  5721  		rf := int(p.From.Reg)
  5722  		rt := int(p.To.Reg)
  5723  		offset := int(p.GetFrom3().Offset)
  5724  		opcode := (offset >> 12) & 15
  5725  		switch opcode {
  5726  		case 0x7:
  5727  			len = 0 // one register
  5728  		case 0xa:
  5729  			len = 1 // two register
  5730  		case 0x6:
  5731  			len = 2 // three registers
  5732  		case 0x2:
  5733  			len = 3 // four registers
  5734  		default:
  5735  			c.ctxt.Diag("invalid register numbers in ARM64 register list: %v", p)
  5736  		}
  5737  		var op uint32
  5738  		switch p.As {
  5739  		case AVTBL:
  5740  			op = 0
  5741  		case AVTBX:
  5742  			op = 1
  5743  		}
  5744  		o1 = q<<30 | 0xe<<24 | len<<13 | op<<12
  5745  		o1 |= (uint32(rf&31) << 16) | uint32(offset&31)<<5 | uint32(rt&31)
  5746  
  5747  	case 102: /* vushll, vushll2, vuxtl, vuxtl2 */
  5748  		o1 = c.opirr(p, p.As)
  5749  		rf := p.Reg
  5750  		af := uint8((p.Reg >> 5) & 15)
  5751  		at := uint8((p.To.Reg >> 5) & 15)
  5752  		shift := int(p.From.Offset)
  5753  		if p.As == AVUXTL || p.As == AVUXTL2 {
  5754  			rf = p.From.Reg
  5755  			af = uint8((p.From.Reg >> 5) & 15)
  5756  			shift = 0
  5757  		}
  5758  
  5759  		Q := (o1 >> 30) & 1
  5760  		var immh, width uint8
  5761  		switch pack(Q, af, at) {
  5762  		case pack(0, ARNG_8B, ARNG_8H):
  5763  			immh, width = 1, 8
  5764  		case pack(1, ARNG_16B, ARNG_8H):
  5765  			immh, width = 1, 8
  5766  		case pack(0, ARNG_4H, ARNG_4S):
  5767  			immh, width = 2, 16
  5768  		case pack(1, ARNG_8H, ARNG_4S):
  5769  			immh, width = 2, 16
  5770  		case pack(0, ARNG_2S, ARNG_2D):
  5771  			immh, width = 4, 32
  5772  		case pack(1, ARNG_4S, ARNG_2D):
  5773  			immh, width = 4, 32
  5774  		default:
  5775  			c.ctxt.Diag("operand mismatch: %v\n", p)
  5776  		}
  5777  		if !(0 <= shift && shift <= int(width-1)) {
  5778  			c.ctxt.Diag("shift amount out of range: %v\n", p)
  5779  		}
  5780  		o1 |= uint32(immh)<<19 | uint32(shift)<<16 | uint32(rf&31)<<5 | uint32(p.To.Reg&31)
  5781  
  5782  	case 103: /* VEOR3/VBCAX Va.B16, Vm.B16, Vn.B16, Vd.B16 */
  5783  		ta := (p.From.Reg >> 5) & 15
  5784  		tm := (p.Reg >> 5) & 15
  5785  		td := (p.To.Reg >> 5) & 15
  5786  		tn := ((p.GetFrom3().Reg) >> 5) & 15
  5787  
  5788  		if ta != tm || ta != tn || ta != td || ta != ARNG_16B {
  5789  			c.ctxt.Diag("invalid arrangement: %v", p)
  5790  			break
  5791  		}
  5792  
  5793  		o1 = c.oprrr(p, p.As)
  5794  		ra := int(p.From.Reg)
  5795  		rm := int(p.Reg)
  5796  		rn := int(p.GetFrom3().Reg)
  5797  		rd := int(p.To.Reg)
  5798  		o1 |= uint32(rm&31)<<16 | uint32(ra&31)<<10 | uint32(rn&31)<<5 | uint32(rd)&31
  5799  
  5800  	case 104: /* vxar $imm4, Vm.<T>, Vn.<T>, Vd.<T> */
  5801  		af := ((p.GetFrom3().Reg) >> 5) & 15
  5802  		at := (p.To.Reg >> 5) & 15
  5803  		a := (p.Reg >> 5) & 15
  5804  		index := int(p.From.Offset)
  5805  
  5806  		if af != a || af != at {
  5807  			c.ctxt.Diag("invalid arrangement: %v", p)
  5808  			break
  5809  		}
  5810  
  5811  		if af != ARNG_2D {
  5812  			c.ctxt.Diag("invalid arrangement, should be D2: %v", p)
  5813  			break
  5814  		}
  5815  
  5816  		if index < 0 || index > 63 {
  5817  			c.ctxt.Diag("illegal offset: %v", p)
  5818  		}
  5819  
  5820  		o1 = c.opirr(p, p.As)
  5821  		rf := (p.GetFrom3().Reg) & 31
  5822  		rt := (p.To.Reg) & 31
  5823  		r := (p.Reg) & 31
  5824  
  5825  		o1 |= (uint32(r&31) << 16) | (uint32(index&63) << 10) | (uint32(rf&31) << 5) | uint32(rt&31)
  5826  
  5827  	case 105: /* vuaddw{2} Vm.<Tb>, Vn.<Ta>, Vd.<Ta> */
  5828  		af := uint8((p.From.Reg >> 5) & 15)
  5829  		at := uint8((p.To.Reg >> 5) & 15)
  5830  		a := uint8((p.Reg >> 5) & 15)
  5831  		if at != a {
  5832  			c.ctxt.Diag("invalid arrangement: %v", p)
  5833  			break
  5834  		}
  5835  
  5836  		var Q, size uint32
  5837  		if p.As == AVUADDW2 {
  5838  			Q = 1
  5839  		}
  5840  		switch pack(Q, at, af) {
  5841  		case pack(0, ARNG_8H, ARNG_8B), pack(1, ARNG_8H, ARNG_16B):
  5842  			size = 0
  5843  		case pack(0, ARNG_4S, ARNG_4H), pack(1, ARNG_4S, ARNG_8H):
  5844  			size = 1
  5845  		case pack(0, ARNG_2D, ARNG_2S), pack(1, ARNG_2D, ARNG_4S):
  5846  			size = 2
  5847  		default:
  5848  			c.ctxt.Diag("operand mismatch: %v\n", p)
  5849  		}
  5850  
  5851  		o1 = c.oprrr(p, p.As)
  5852  		rf := int((p.From.Reg) & 31)
  5853  		rt := int((p.To.Reg) & 31)
  5854  		r := int((p.Reg) & 31)
  5855  		o1 |= ((Q & 1) << 30) | ((size & 3) << 22) | (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
  5856  
  5857  	case 106: // CASPx (Rs, Rs+1), (Rb), (Rt, Rt+1)
  5858  		rs := p.From.Reg
  5859  		rt := p.GetTo2().Reg
  5860  		rb := p.To.Reg
  5861  		rs1 := int16(p.From.Offset)
  5862  		rt1 := int16(p.GetTo2().Offset)
  5863  
  5864  		enc, ok := atomicCASP[p.As]
  5865  		if !ok {
  5866  			c.ctxt.Diag("invalid CASP-like atomic instructions: %v\n", p)
  5867  		}
  5868  		// for CASPx-like instructions, Rs<0> != 1 && Rt<0> != 1
  5869  		switch {
  5870  		case rs&1 != 0:
  5871  			c.ctxt.Diag("source register pair must start from even register: %v\n", p)
  5872  			break
  5873  		case rt&1 != 0:
  5874  			c.ctxt.Diag("destination register pair must start from even register: %v\n", p)
  5875  			break
  5876  		case rs != rs1-1:
  5877  			c.ctxt.Diag("source register pair must be contiguous: %v\n", p)
  5878  			break
  5879  		case rt != rt1-1:
  5880  			c.ctxt.Diag("destination register pair must be contiguous: %v\n", p)
  5881  			break
  5882  		}
  5883  		// rt can't be sp.
  5884  		if rt == REG_RSP {
  5885  			c.ctxt.Diag("illegal destination register: %v\n", p)
  5886  		}
  5887  		o1 |= enc | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
  5888  
  5889  	case 107: /* tlbi, dc */
  5890  		op, ok := sysInstFields[SpecialOperand(p.From.Offset)]
  5891  		if !ok || (p.As == ATLBI && op.cn != 8) || (p.As == ADC && op.cn != 7) {
  5892  			c.ctxt.Diag("illegal argument: %v\n", p)
  5893  			break
  5894  		}
  5895  		o1 = c.opirr(p, p.As)
  5896  		if op.hasOperand2 {
  5897  			if p.To.Reg == obj.REG_NONE {
  5898  				c.ctxt.Diag("missing register at operand 2: %v\n", p)
  5899  			}
  5900  			o1 |= uint32(p.To.Reg & 0x1F)
  5901  		} else {
  5902  			if p.To.Reg != obj.REG_NONE || p.Reg != obj.REG_NONE {
  5903  				c.ctxt.Diag("extraneous register at operand 2: %v\n", p)
  5904  			}
  5905  			o1 |= uint32(0x1F)
  5906  		}
  5907  		o1 |= uint32(SYSARG4(int(op.op1), int(op.cn), int(op.cm), int(op.op2)))
  5908  	}
  5909  	out[0] = o1
  5910  	out[1] = o2
  5911  	out[2] = o3
  5912  	out[3] = o4
  5913  	out[4] = o5
  5914  }
  5915  
  5916  func (c *ctxt7) addrRelocType(p *obj.Prog) objabi.RelocType {
  5917  	switch movesize(p.As) {
  5918  	case 0:
  5919  		return objabi.R_ARM64_PCREL_LDST8
  5920  	case 1:
  5921  		return objabi.R_ARM64_PCREL_LDST16
  5922  	case 2:
  5923  		return objabi.R_ARM64_PCREL_LDST32
  5924  	case 3:
  5925  		return objabi.R_ARM64_PCREL_LDST64
  5926  	default:
  5927  		c.ctxt.Diag("use R_ADDRARM64 relocation type for: %v\n", p)
  5928  	}
  5929  	return -1
  5930  }
  5931  
  5932  /*
  5933   * basic Rm op Rn -> Rd (using shifted register with 0)
  5934   * also op Rn -> Rt
  5935   * also Rm*Rn op Ra -> Rd
  5936   * also Vm op Vn -> Vd
  5937   */
  5938  func (c *ctxt7) oprrr(p *obj.Prog, a obj.As) uint32 {
  5939  	switch a {
  5940  	case AADC:
  5941  		return S64 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10
  5942  
  5943  	case AADCW:
  5944  		return S32 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10
  5945  
  5946  	case AADCS:
  5947  		return S64 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10
  5948  
  5949  	case AADCSW:
  5950  		return S32 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10
  5951  
  5952  	case ANGC, ASBC:
  5953  		return S64 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10
  5954  
  5955  	case ANGCS, ASBCS:
  5956  		return S64 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10
  5957  
  5958  	case ANGCW, ASBCW:
  5959  		return S32 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10
  5960  
  5961  	case ANGCSW, ASBCSW:
  5962  		return S32 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10
  5963  
  5964  	case AADD:
  5965  		return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  5966  
  5967  	case AADDW:
  5968  		return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  5969  
  5970  	case ACMN, AADDS:
  5971  		return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  5972  
  5973  	case ACMNW, AADDSW:
  5974  		return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  5975  
  5976  	case ASUB:
  5977  		return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  5978  
  5979  	case ASUBW:
  5980  		return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  5981  
  5982  	case ACMP, ASUBS:
  5983  		return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  5984  
  5985  	case ACMPW, ASUBSW:
  5986  		return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  5987  
  5988  	case AAND:
  5989  		return S64 | 0<<29 | 0xA<<24
  5990  
  5991  	case AANDW:
  5992  		return S32 | 0<<29 | 0xA<<24
  5993  
  5994  	case AMOVD, AORR:
  5995  		return S64 | 1<<29 | 0xA<<24
  5996  
  5997  		//	case AMOVW:
  5998  	case AMOVWU, AORRW:
  5999  		return S32 | 1<<29 | 0xA<<24
  6000  
  6001  	case AEOR:
  6002  		return S64 | 2<<29 | 0xA<<24
  6003  
  6004  	case AEORW:
  6005  		return S32 | 2<<29 | 0xA<<24
  6006  
  6007  	case AANDS, ATST:
  6008  		return S64 | 3<<29 | 0xA<<24
  6009  
  6010  	case AANDSW, ATSTW:
  6011  		return S32 | 3<<29 | 0xA<<24
  6012  
  6013  	case ABIC:
  6014  		return S64 | 0<<29 | 0xA<<24 | 1<<21
  6015  
  6016  	case ABICW:
  6017  		return S32 | 0<<29 | 0xA<<24 | 1<<21
  6018  
  6019  	case ABICS:
  6020  		return S64 | 3<<29 | 0xA<<24 | 1<<21
  6021  
  6022  	case ABICSW:
  6023  		return S32 | 3<<29 | 0xA<<24 | 1<<21
  6024  
  6025  	case AEON:
  6026  		return S64 | 2<<29 | 0xA<<24 | 1<<21
  6027  
  6028  	case AEONW:
  6029  		return S32 | 2<<29 | 0xA<<24 | 1<<21
  6030  
  6031  	case AMVN, AORN:
  6032  		return S64 | 1<<29 | 0xA<<24 | 1<<21
  6033  
  6034  	case AMVNW, AORNW:
  6035  		return S32 | 1<<29 | 0xA<<24 | 1<<21
  6036  
  6037  	case AASR:
  6038  		return S64 | OPDP2(10) /* also ASRV */
  6039  
  6040  	case AASRW:
  6041  		return S32 | OPDP2(10)
  6042  
  6043  	case ALSL:
  6044  		return S64 | OPDP2(8)
  6045  
  6046  	case ALSLW:
  6047  		return S32 | OPDP2(8)
  6048  
  6049  	case ALSR:
  6050  		return S64 | OPDP2(9)
  6051  
  6052  	case ALSRW:
  6053  		return S32 | OPDP2(9)
  6054  
  6055  	case AROR:
  6056  		return S64 | OPDP2(11)
  6057  
  6058  	case ARORW:
  6059  		return S32 | OPDP2(11)
  6060  
  6061  	case ACCMN:
  6062  		return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 /* cond<<12 | nzcv<<0 */
  6063  
  6064  	case ACCMNW:
  6065  		return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4
  6066  
  6067  	case ACCMP:
  6068  		return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */
  6069  
  6070  	case ACCMPW:
  6071  		return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4
  6072  
  6073  	case ACRC32B:
  6074  		return S32 | OPDP2(16)
  6075  
  6076  	case ACRC32H:
  6077  		return S32 | OPDP2(17)
  6078  
  6079  	case ACRC32W:
  6080  		return S32 | OPDP2(18)
  6081  
  6082  	case ACRC32X:
  6083  		return S64 | OPDP2(19)
  6084  
  6085  	case ACRC32CB:
  6086  		return S32 | OPDP2(20)
  6087  
  6088  	case ACRC32CH:
  6089  		return S32 | OPDP2(21)
  6090  
  6091  	case ACRC32CW:
  6092  		return S32 | OPDP2(22)
  6093  
  6094  	case ACRC32CX:
  6095  		return S64 | OPDP2(23)
  6096  
  6097  	case ACSEL:
  6098  		return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  6099  
  6100  	case ACSELW:
  6101  		return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  6102  
  6103  	case ACSET:
  6104  		return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  6105  
  6106  	case ACSETW:
  6107  		return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  6108  
  6109  	case ACSETM:
  6110  		return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  6111  
  6112  	case ACSETMW:
  6113  		return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  6114  
  6115  	case ACINC, ACSINC:
  6116  		return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  6117  
  6118  	case ACINCW, ACSINCW:
  6119  		return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  6120  
  6121  	case ACINV, ACSINV:
  6122  		return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  6123  
  6124  	case ACINVW, ACSINVW:
  6125  		return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  6126  
  6127  	case ACNEG, ACSNEG:
  6128  		return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  6129  
  6130  	case ACNEGW, ACSNEGW:
  6131  		return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  6132  
  6133  	case AMUL, AMADD:
  6134  		return S64 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15
  6135  
  6136  	case AMULW, AMADDW:
  6137  		return S32 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15
  6138  
  6139  	case AMNEG, AMSUB:
  6140  		return S64 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15
  6141  
  6142  	case AMNEGW, AMSUBW:
  6143  		return S32 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15
  6144  
  6145  	case AMRS:
  6146  		return SYSOP(1, 2, 0, 0, 0, 0, 0)
  6147  
  6148  	case AMSR:
  6149  		return SYSOP(0, 2, 0, 0, 0, 0, 0)
  6150  
  6151  	case ANEG:
  6152  		return S64 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21
  6153  
  6154  	case ANEGW:
  6155  		return S32 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21
  6156  
  6157  	case ANEGS:
  6158  		return S64 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21
  6159  
  6160  	case ANEGSW:
  6161  		return S32 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21
  6162  
  6163  	case AREM, ASDIV:
  6164  		return S64 | OPDP2(3)
  6165  
  6166  	case AREMW, ASDIVW:
  6167  		return S32 | OPDP2(3)
  6168  
  6169  	case ASMULL, ASMADDL:
  6170  		return OPDP3(1, 0, 1, 0)
  6171  
  6172  	case ASMNEGL, ASMSUBL:
  6173  		return OPDP3(1, 0, 1, 1)
  6174  
  6175  	case ASMULH:
  6176  		return OPDP3(1, 0, 2, 0)
  6177  
  6178  	case AUMULL, AUMADDL:
  6179  		return OPDP3(1, 0, 5, 0)
  6180  
  6181  	case AUMNEGL, AUMSUBL:
  6182  		return OPDP3(1, 0, 5, 1)
  6183  
  6184  	case AUMULH:
  6185  		return OPDP3(1, 0, 6, 0)
  6186  
  6187  	case AUREM, AUDIV:
  6188  		return S64 | OPDP2(2)
  6189  
  6190  	case AUREMW, AUDIVW:
  6191  		return S32 | OPDP2(2)
  6192  
  6193  	case AAESE:
  6194  		return 0x4E<<24 | 2<<20 | 8<<16 | 4<<12 | 2<<10
  6195  
  6196  	case AAESD:
  6197  		return 0x4E<<24 | 2<<20 | 8<<16 | 5<<12 | 2<<10
  6198  
  6199  	case AAESMC:
  6200  		return 0x4E<<24 | 2<<20 | 8<<16 | 6<<12 | 2<<10
  6201  
  6202  	case AAESIMC:
  6203  		return 0x4E<<24 | 2<<20 | 8<<16 | 7<<12 | 2<<10
  6204  
  6205  	case ASHA1C:
  6206  		return 0x5E<<24 | 0<<12
  6207  
  6208  	case ASHA1P:
  6209  		return 0x5E<<24 | 1<<12
  6210  
  6211  	case ASHA1M:
  6212  		return 0x5E<<24 | 2<<12
  6213  
  6214  	case ASHA1SU0:
  6215  		return 0x5E<<24 | 3<<12
  6216  
  6217  	case ASHA256H:
  6218  		return 0x5E<<24 | 4<<12
  6219  
  6220  	case ASHA256H2:
  6221  		return 0x5E<<24 | 5<<12
  6222  
  6223  	case ASHA256SU1:
  6224  		return 0x5E<<24 | 6<<12
  6225  
  6226  	case ASHA1H:
  6227  		return 0x5E<<24 | 2<<20 | 8<<16 | 0<<12 | 2<<10
  6228  
  6229  	case ASHA1SU1:
  6230  		return 0x5E<<24 | 2<<20 | 8<<16 | 1<<12 | 2<<10
  6231  
  6232  	case ASHA256SU0:
  6233  		return 0x5E<<24 | 2<<20 | 8<<16 | 2<<12 | 2<<10
  6234  
  6235  	case ASHA512H:
  6236  		return 0xCE<<24 | 3<<21 | 8<<12
  6237  
  6238  	case ASHA512H2:
  6239  		return 0xCE<<24 | 3<<21 | 8<<12 | 4<<8
  6240  
  6241  	case ASHA512SU1:
  6242  		return 0xCE<<24 | 3<<21 | 8<<12 | 8<<8
  6243  
  6244  	case ASHA512SU0:
  6245  		return 0xCE<<24 | 3<<22 | 8<<12
  6246  
  6247  	case AFCVTZSD:
  6248  		return FPCVTI(1, 0, 1, 3, 0)
  6249  
  6250  	case AFCVTZSDW:
  6251  		return FPCVTI(0, 0, 1, 3, 0)
  6252  
  6253  	case AFCVTZSS:
  6254  		return FPCVTI(1, 0, 0, 3, 0)
  6255  
  6256  	case AFCVTZSSW:
  6257  		return FPCVTI(0, 0, 0, 3, 0)
  6258  
  6259  	case AFCVTZUD:
  6260  		return FPCVTI(1, 0, 1, 3, 1)
  6261  
  6262  	case AFCVTZUDW:
  6263  		return FPCVTI(0, 0, 1, 3, 1)
  6264  
  6265  	case AFCVTZUS:
  6266  		return FPCVTI(1, 0, 0, 3, 1)
  6267  
  6268  	case AFCVTZUSW:
  6269  		return FPCVTI(0, 0, 0, 3, 1)
  6270  
  6271  	case ASCVTFD:
  6272  		return FPCVTI(1, 0, 1, 0, 2)
  6273  
  6274  	case ASCVTFS:
  6275  		return FPCVTI(1, 0, 0, 0, 2)
  6276  
  6277  	case ASCVTFWD:
  6278  		return FPCVTI(0, 0, 1, 0, 2)
  6279  
  6280  	case ASCVTFWS:
  6281  		return FPCVTI(0, 0, 0, 0, 2)
  6282  
  6283  	case AUCVTFD:
  6284  		return FPCVTI(1, 0, 1, 0, 3)
  6285  
  6286  	case AUCVTFS:
  6287  		return FPCVTI(1, 0, 0, 0, 3)
  6288  
  6289  	case AUCVTFWD:
  6290  		return FPCVTI(0, 0, 1, 0, 3)
  6291  
  6292  	case AUCVTFWS:
  6293  		return FPCVTI(0, 0, 0, 0, 3)
  6294  
  6295  	case AFADDS:
  6296  		return FPOP2S(0, 0, 0, 2)
  6297  
  6298  	case AFADDD:
  6299  		return FPOP2S(0, 0, 1, 2)
  6300  
  6301  	case AFSUBS:
  6302  		return FPOP2S(0, 0, 0, 3)
  6303  
  6304  	case AFSUBD:
  6305  		return FPOP2S(0, 0, 1, 3)
  6306  
  6307  	case AFMADDD:
  6308  		return FPOP3S(0, 0, 1, 0, 0)
  6309  
  6310  	case AFMADDS:
  6311  		return FPOP3S(0, 0, 0, 0, 0)
  6312  
  6313  	case AFMSUBD:
  6314  		return FPOP3S(0, 0, 1, 0, 1)
  6315  
  6316  	case AFMSUBS:
  6317  		return FPOP3S(0, 0, 0, 0, 1)
  6318  
  6319  	case AFNMADDD:
  6320  		return FPOP3S(0, 0, 1, 1, 0)
  6321  
  6322  	case AFNMADDS:
  6323  		return FPOP3S(0, 0, 0, 1, 0)
  6324  
  6325  	case AFNMSUBD:
  6326  		return FPOP3S(0, 0, 1, 1, 1)
  6327  
  6328  	case AFNMSUBS:
  6329  		return FPOP3S(0, 0, 0, 1, 1)
  6330  
  6331  	case AFMULS:
  6332  		return FPOP2S(0, 0, 0, 0)
  6333  
  6334  	case AFMULD:
  6335  		return FPOP2S(0, 0, 1, 0)
  6336  
  6337  	case AFDIVS:
  6338  		return FPOP2S(0, 0, 0, 1)
  6339  
  6340  	case AFDIVD:
  6341  		return FPOP2S(0, 0, 1, 1)
  6342  
  6343  	case AFMAXS:
  6344  		return FPOP2S(0, 0, 0, 4)
  6345  
  6346  	case AFMINS:
  6347  		return FPOP2S(0, 0, 0, 5)
  6348  
  6349  	case AFMAXD:
  6350  		return FPOP2S(0, 0, 1, 4)
  6351  
  6352  	case AFMIND:
  6353  		return FPOP2S(0, 0, 1, 5)
  6354  
  6355  	case AFMAXNMS:
  6356  		return FPOP2S(0, 0, 0, 6)
  6357  
  6358  	case AFMAXNMD:
  6359  		return FPOP2S(0, 0, 1, 6)
  6360  
  6361  	case AFMINNMS:
  6362  		return FPOP2S(0, 0, 0, 7)
  6363  
  6364  	case AFMINNMD:
  6365  		return FPOP2S(0, 0, 1, 7)
  6366  
  6367  	case AFNMULS:
  6368  		return FPOP2S(0, 0, 0, 8)
  6369  
  6370  	case AFNMULD:
  6371  		return FPOP2S(0, 0, 1, 8)
  6372  
  6373  	case AFCMPS:
  6374  		return FPCMP(0, 0, 0, 0, 0)
  6375  
  6376  	case AFCMPD:
  6377  		return FPCMP(0, 0, 1, 0, 0)
  6378  
  6379  	case AFCMPES:
  6380  		return FPCMP(0, 0, 0, 0, 16)
  6381  
  6382  	case AFCMPED:
  6383  		return FPCMP(0, 0, 1, 0, 16)
  6384  
  6385  	case AFCCMPS:
  6386  		return FPCCMP(0, 0, 0, 0)
  6387  
  6388  	case AFCCMPD:
  6389  		return FPCCMP(0, 0, 1, 0)
  6390  
  6391  	case AFCCMPES:
  6392  		return FPCCMP(0, 0, 0, 1)
  6393  
  6394  	case AFCCMPED:
  6395  		return FPCCMP(0, 0, 1, 1)
  6396  
  6397  	case AFCSELS:
  6398  		return 0x1E<<24 | 0<<22 | 1<<21 | 3<<10
  6399  
  6400  	case AFCSELD:
  6401  		return 0x1E<<24 | 1<<22 | 1<<21 | 3<<10
  6402  
  6403  	case AFMOVS:
  6404  		return FPOP1S(0, 0, 0, 0)
  6405  
  6406  	case AFABSS:
  6407  		return FPOP1S(0, 0, 0, 1)
  6408  
  6409  	case AFNEGS:
  6410  		return FPOP1S(0, 0, 0, 2)
  6411  
  6412  	case AFSQRTS:
  6413  		return FPOP1S(0, 0, 0, 3)
  6414  
  6415  	case AFCVTSD:
  6416  		return FPOP1S(0, 0, 0, 5)
  6417  
  6418  	case AFCVTSH:
  6419  		return FPOP1S(0, 0, 0, 7)
  6420  
  6421  	case AFRINTNS:
  6422  		return FPOP1S(0, 0, 0, 8)
  6423  
  6424  	case AFRINTPS:
  6425  		return FPOP1S(0, 0, 0, 9)
  6426  
  6427  	case AFRINTMS:
  6428  		return FPOP1S(0, 0, 0, 10)
  6429  
  6430  	case AFRINTZS:
  6431  		return FPOP1S(0, 0, 0, 11)
  6432  
  6433  	case AFRINTAS:
  6434  		return FPOP1S(0, 0, 0, 12)
  6435  
  6436  	case AFRINTXS:
  6437  		return FPOP1S(0, 0, 0, 14)
  6438  
  6439  	case AFRINTIS:
  6440  		return FPOP1S(0, 0, 0, 15)
  6441  
  6442  	case AFMOVD:
  6443  		return FPOP1S(0, 0, 1, 0)
  6444  
  6445  	case AFABSD:
  6446  		return FPOP1S(0, 0, 1, 1)
  6447  
  6448  	case AFNEGD:
  6449  		return FPOP1S(0, 0, 1, 2)
  6450  
  6451  	case AFSQRTD:
  6452  		return FPOP1S(0, 0, 1, 3)
  6453  
  6454  	case AFCVTDS:
  6455  		return FPOP1S(0, 0, 1, 4)
  6456  
  6457  	case AFCVTDH:
  6458  		return FPOP1S(0, 0, 1, 7)
  6459  
  6460  	case AFRINTND:
  6461  		return FPOP1S(0, 0, 1, 8)
  6462  
  6463  	case AFRINTPD:
  6464  		return FPOP1S(0, 0, 1, 9)
  6465  
  6466  	case AFRINTMD:
  6467  		return FPOP1S(0, 0, 1, 10)
  6468  
  6469  	case AFRINTZD:
  6470  		return FPOP1S(0, 0, 1, 11)
  6471  
  6472  	case AFRINTAD:
  6473  		return FPOP1S(0, 0, 1, 12)
  6474  
  6475  	case AFRINTXD:
  6476  		return FPOP1S(0, 0, 1, 14)
  6477  
  6478  	case AFRINTID:
  6479  		return FPOP1S(0, 0, 1, 15)
  6480  
  6481  	case AFCVTHS:
  6482  		return FPOP1S(0, 0, 3, 4)
  6483  
  6484  	case AFCVTHD:
  6485  		return FPOP1S(0, 0, 3, 5)
  6486  
  6487  	case AVADD:
  6488  		return 7<<25 | 1<<21 | 1<<15 | 1<<10
  6489  
  6490  	case AVSUB:
  6491  		return 0x17<<25 | 1<<21 | 1<<15 | 1<<10
  6492  
  6493  	case AVADDP:
  6494  		return 7<<25 | 1<<21 | 1<<15 | 15<<10
  6495  
  6496  	case AVAND:
  6497  		return 7<<25 | 1<<21 | 7<<10
  6498  
  6499  	case AVBCAX:
  6500  		return 0xCE<<24 | 1<<21
  6501  
  6502  	case AVCMEQ:
  6503  		return 1<<29 | 0x71<<21 | 0x23<<10
  6504  
  6505  	case AVCNT:
  6506  		return 0xE<<24 | 0x10<<17 | 5<<12 | 2<<10
  6507  
  6508  	case AVZIP1:
  6509  		return 0xE<<24 | 3<<12 | 2<<10
  6510  
  6511  	case AVZIP2:
  6512  		return 0xE<<24 | 1<<14 | 3<<12 | 2<<10
  6513  
  6514  	case AVEOR:
  6515  		return 1<<29 | 0x71<<21 | 7<<10
  6516  
  6517  	case AVEOR3:
  6518  		return 0xCE << 24
  6519  
  6520  	case AVORR:
  6521  		return 7<<25 | 5<<21 | 7<<10
  6522  
  6523  	case AVREV16:
  6524  		return 3<<26 | 2<<24 | 1<<21 | 3<<11
  6525  
  6526  	case AVRAX1:
  6527  		return 0xCE<<24 | 3<<21 | 1<<15 | 3<<10
  6528  
  6529  	case AVREV32:
  6530  		return 11<<26 | 2<<24 | 1<<21 | 1<<11
  6531  
  6532  	case AVREV64:
  6533  		return 3<<26 | 2<<24 | 1<<21 | 1<<11
  6534  
  6535  	case AVMOV:
  6536  		return 7<<25 | 5<<21 | 7<<10
  6537  
  6538  	case AVADDV:
  6539  		return 7<<25 | 3<<20 | 3<<15 | 7<<11
  6540  
  6541  	case AVUADDLV:
  6542  		return 1<<29 | 7<<25 | 3<<20 | 7<<11
  6543  
  6544  	case AVFMLA:
  6545  		return 7<<25 | 0<<23 | 1<<21 | 3<<14 | 3<<10
  6546  
  6547  	case AVFMLS:
  6548  		return 7<<25 | 1<<23 | 1<<21 | 3<<14 | 3<<10
  6549  
  6550  	case AVPMULL, AVPMULL2:
  6551  		return 0xE<<24 | 1<<21 | 0x38<<10
  6552  
  6553  	case AVRBIT:
  6554  		return 0x2E<<24 | 1<<22 | 0x10<<17 | 5<<12 | 2<<10
  6555  
  6556  	case AVLD1, AVLD2, AVLD3, AVLD4:
  6557  		return 3<<26 | 1<<22
  6558  
  6559  	case AVLD1R, AVLD3R:
  6560  		return 0xD<<24 | 1<<22
  6561  
  6562  	case AVLD2R, AVLD4R:
  6563  		return 0xD<<24 | 3<<21
  6564  
  6565  	case AVBIF:
  6566  		return 1<<29 | 7<<25 | 7<<21 | 7<<10
  6567  
  6568  	case AVBIT:
  6569  		return 1<<29 | 0x75<<21 | 7<<10
  6570  
  6571  	case AVBSL:
  6572  		return 1<<29 | 0x73<<21 | 7<<10
  6573  
  6574  	case AVCMTST:
  6575  		return 0xE<<24 | 1<<21 | 0x23<<10
  6576  
  6577  	case AVUMAX:
  6578  		return 1<<29 | 7<<25 | 1<<21 | 0x19<<10
  6579  
  6580  	case AVUMIN:
  6581  		return 1<<29 | 7<<25 | 1<<21 | 0x1b<<10
  6582  
  6583  	case AVUZP1:
  6584  		return 7<<25 | 3<<11
  6585  
  6586  	case AVUZP2:
  6587  		return 7<<25 | 1<<14 | 3<<11
  6588  
  6589  	case AVUADDW, AVUADDW2:
  6590  		return 0x17<<25 | 1<<21 | 1<<12
  6591  
  6592  	case AVTRN1:
  6593  		return 7<<25 | 5<<11
  6594  
  6595  	case AVTRN2:
  6596  		return 7<<25 | 1<<14 | 5<<11
  6597  	}
  6598  
  6599  	c.ctxt.Diag("%v: bad rrr %d %v", p, a, a)
  6600  	return 0
  6601  }
  6602  
  6603  /*
  6604   * imm -> Rd
  6605   * imm op Rn -> Rd
  6606   */
  6607  func (c *ctxt7) opirr(p *obj.Prog, a obj.As) uint32 {
  6608  	switch a {
  6609  	/* op $addcon, Rn, Rd */
  6610  	case AMOVD, AADD:
  6611  		return S64 | 0<<30 | 0<<29 | 0x11<<24
  6612  
  6613  	case ACMN, AADDS:
  6614  		return S64 | 0<<30 | 1<<29 | 0x11<<24
  6615  
  6616  	case AMOVW, AADDW:
  6617  		return S32 | 0<<30 | 0<<29 | 0x11<<24
  6618  
  6619  	case ACMNW, AADDSW:
  6620  		return S32 | 0<<30 | 1<<29 | 0x11<<24
  6621  
  6622  	case ASUB:
  6623  		return S64 | 1<<30 | 0<<29 | 0x11<<24
  6624  
  6625  	case ACMP, ASUBS:
  6626  		return S64 | 1<<30 | 1<<29 | 0x11<<24
  6627  
  6628  	case ASUBW:
  6629  		return S32 | 1<<30 | 0<<29 | 0x11<<24
  6630  
  6631  	case ACMPW, ASUBSW:
  6632  		return S32 | 1<<30 | 1<<29 | 0x11<<24
  6633  
  6634  		/* op $imm(SB), Rd; op label, Rd */
  6635  	case AADR:
  6636  		return 0<<31 | 0x10<<24
  6637  
  6638  	case AADRP:
  6639  		return 1<<31 | 0x10<<24
  6640  
  6641  		/* op $bimm, Rn, Rd */
  6642  	case AAND, ABIC:
  6643  		return S64 | 0<<29 | 0x24<<23
  6644  
  6645  	case AANDW, ABICW:
  6646  		return S32 | 0<<29 | 0x24<<23 | 0<<22
  6647  
  6648  	case AORR, AORN:
  6649  		return S64 | 1<<29 | 0x24<<23
  6650  
  6651  	case AORRW, AORNW:
  6652  		return S32 | 1<<29 | 0x24<<23 | 0<<22
  6653  
  6654  	case AEOR, AEON:
  6655  		return S64 | 2<<29 | 0x24<<23
  6656  
  6657  	case AEORW, AEONW:
  6658  		return S32 | 2<<29 | 0x24<<23 | 0<<22
  6659  
  6660  	case AANDS, ABICS, ATST:
  6661  		return S64 | 3<<29 | 0x24<<23
  6662  
  6663  	case AANDSW, ABICSW, ATSTW:
  6664  		return S32 | 3<<29 | 0x24<<23 | 0<<22
  6665  
  6666  	case AASR:
  6667  		return S64 | 0<<29 | 0x26<<23 /* alias of SBFM */
  6668  
  6669  	case AASRW:
  6670  		return S32 | 0<<29 | 0x26<<23 | 0<<22
  6671  
  6672  		/* op $width, $lsb, Rn, Rd */
  6673  	case ABFI:
  6674  		return S64 | 2<<29 | 0x26<<23 | 1<<22
  6675  		/* alias of BFM */
  6676  
  6677  	case ABFIW:
  6678  		return S32 | 2<<29 | 0x26<<23 | 0<<22
  6679  
  6680  		/* op $imms, $immr, Rn, Rd */
  6681  	case ABFM:
  6682  		return S64 | 1<<29 | 0x26<<23 | 1<<22
  6683  
  6684  	case ABFMW:
  6685  		return S32 | 1<<29 | 0x26<<23 | 0<<22
  6686  
  6687  	case ASBFM:
  6688  		return S64 | 0<<29 | 0x26<<23 | 1<<22
  6689  
  6690  	case ASBFMW:
  6691  		return S32 | 0<<29 | 0x26<<23 | 0<<22
  6692  
  6693  	case AUBFM:
  6694  		return S64 | 2<<29 | 0x26<<23 | 1<<22
  6695  
  6696  	case AUBFMW:
  6697  		return S32 | 2<<29 | 0x26<<23 | 0<<22
  6698  
  6699  	case ABFXIL:
  6700  		return S64 | 1<<29 | 0x26<<23 | 1<<22 /* alias of BFM */
  6701  
  6702  	case ABFXILW:
  6703  		return S32 | 1<<29 | 0x26<<23 | 0<<22
  6704  
  6705  	case AEXTR:
  6706  		return S64 | 0<<29 | 0x27<<23 | 1<<22 | 0<<21
  6707  
  6708  	case AEXTRW:
  6709  		return S32 | 0<<29 | 0x27<<23 | 0<<22 | 0<<21
  6710  
  6711  	case ACBNZ:
  6712  		return S64 | 0x1A<<25 | 1<<24
  6713  
  6714  	case ACBNZW:
  6715  		return S32 | 0x1A<<25 | 1<<24
  6716  
  6717  	case ACBZ:
  6718  		return S64 | 0x1A<<25 | 0<<24
  6719  
  6720  	case ACBZW:
  6721  		return S32 | 0x1A<<25 | 0<<24
  6722  
  6723  	case ACCMN:
  6724  		return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */
  6725  
  6726  	case ACCMNW:
  6727  		return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4
  6728  
  6729  	case ACCMP:
  6730  		return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */
  6731  
  6732  	case ACCMPW:
  6733  		return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4
  6734  
  6735  	case AMOVK:
  6736  		return S64 | 3<<29 | 0x25<<23
  6737  
  6738  	case AMOVKW:
  6739  		return S32 | 3<<29 | 0x25<<23
  6740  
  6741  	case AMOVN:
  6742  		return S64 | 0<<29 | 0x25<<23
  6743  
  6744  	case AMOVNW:
  6745  		return S32 | 0<<29 | 0x25<<23
  6746  
  6747  	case AMOVZ:
  6748  		return S64 | 2<<29 | 0x25<<23
  6749  
  6750  	case AMOVZW:
  6751  		return S32 | 2<<29 | 0x25<<23
  6752  
  6753  	case AMSR:
  6754  		return SYSOP(0, 0, 0, 4, 0, 0, 0x1F) /* MSR (immediate) */
  6755  
  6756  	case AAT,
  6757  		ADC,
  6758  		AIC,
  6759  		ATLBI,
  6760  		ASYS:
  6761  		return SYSOP(0, 1, 0, 0, 0, 0, 0)
  6762  
  6763  	case ASYSL:
  6764  		return SYSOP(1, 1, 0, 0, 0, 0, 0)
  6765  
  6766  	case ATBZ:
  6767  		return 0x36 << 24
  6768  
  6769  	case ATBNZ:
  6770  		return 0x37 << 24
  6771  
  6772  	case ADSB:
  6773  		return SYSOP(0, 0, 3, 3, 0, 4, 0x1F)
  6774  
  6775  	case ADMB:
  6776  		return SYSOP(0, 0, 3, 3, 0, 5, 0x1F)
  6777  
  6778  	case AISB:
  6779  		return SYSOP(0, 0, 3, 3, 0, 6, 0x1F)
  6780  
  6781  	case AHINT:
  6782  		return SYSOP(0, 0, 3, 2, 0, 0, 0x1F)
  6783  
  6784  	case AVEXT:
  6785  		return 0x2E<<24 | 0<<23 | 0<<21 | 0<<15
  6786  
  6787  	case AVUSHR:
  6788  		return 0x5E<<23 | 1<<10
  6789  
  6790  	case AVSHL:
  6791  		return 0x1E<<23 | 21<<10
  6792  
  6793  	case AVSRI:
  6794  		return 0x5E<<23 | 17<<10
  6795  
  6796  	case AVSLI:
  6797  		return 0x5E<<23 | 21<<10
  6798  
  6799  	case AVUSHLL, AVUXTL:
  6800  		return 1<<29 | 15<<24 | 0x29<<10
  6801  
  6802  	case AVUSHLL2, AVUXTL2:
  6803  		return 3<<29 | 15<<24 | 0x29<<10
  6804  
  6805  	case AVXAR:
  6806  		return 0xCE<<24 | 1<<23
  6807  
  6808  	case AVUSRA:
  6809  		return 1<<29 | 15<<24 | 5<<10
  6810  
  6811  	case APRFM:
  6812  		return 0xf9<<24 | 2<<22
  6813  	}
  6814  
  6815  	c.ctxt.Diag("%v: bad irr %v", p, a)
  6816  	return 0
  6817  }
  6818  
  6819  func (c *ctxt7) opbit(p *obj.Prog, a obj.As) uint32 {
  6820  	switch a {
  6821  	case ACLS:
  6822  		return S64 | OPBIT(5)
  6823  
  6824  	case ACLSW:
  6825  		return S32 | OPBIT(5)
  6826  
  6827  	case ACLZ:
  6828  		return S64 | OPBIT(4)
  6829  
  6830  	case ACLZW:
  6831  		return S32 | OPBIT(4)
  6832  
  6833  	case ARBIT:
  6834  		return S64 | OPBIT(0)
  6835  
  6836  	case ARBITW:
  6837  		return S32 | OPBIT(0)
  6838  
  6839  	case AREV:
  6840  		return S64 | OPBIT(3)
  6841  
  6842  	case AREVW:
  6843  		return S32 | OPBIT(2)
  6844  
  6845  	case AREV16:
  6846  		return S64 | OPBIT(1)
  6847  
  6848  	case AREV16W:
  6849  		return S32 | OPBIT(1)
  6850  
  6851  	case AREV32:
  6852  		return S64 | OPBIT(2)
  6853  
  6854  	default:
  6855  		c.ctxt.Diag("bad bit op\n%v", p)
  6856  		return 0
  6857  	}
  6858  }
  6859  
  6860  /*
  6861   * add/subtract sign or zero-extended register
  6862   */
  6863  func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As, rd, rn, rm int16, extend bool) uint32 {
  6864  	extension := uint32(0)
  6865  	if !extend {
  6866  		if isADDop(a) {
  6867  			extension = LSL0_64
  6868  		}
  6869  		if isADDWop(a) {
  6870  			extension = LSL0_32
  6871  		}
  6872  	}
  6873  
  6874  	var op uint32
  6875  
  6876  	switch a {
  6877  	case AADD:
  6878  		op = S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
  6879  
  6880  	case AADDW:
  6881  		op = S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
  6882  
  6883  	case ACMN, AADDS:
  6884  		op = S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
  6885  
  6886  	case ACMNW, AADDSW:
  6887  		op = S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
  6888  
  6889  	case ASUB:
  6890  		op = S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
  6891  
  6892  	case ASUBW:
  6893  		op = S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
  6894  
  6895  	case ACMP, ASUBS:
  6896  		op = S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
  6897  
  6898  	case ACMPW, ASUBSW:
  6899  		op = S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | extension
  6900  
  6901  	default:
  6902  		c.ctxt.Diag("bad opxrrr %v\n%v", a, p)
  6903  		return 0
  6904  	}
  6905  
  6906  	op |= uint32(rm&0x1f)<<16 | uint32(rn&0x1f)<<5 | uint32(rd&0x1f)
  6907  
  6908  	return op
  6909  }
  6910  
  6911  func (c *ctxt7) opimm(p *obj.Prog, a obj.As) uint32 {
  6912  	switch a {
  6913  	case ASVC:
  6914  		return 0xD4<<24 | 0<<21 | 1 /* imm16<<5 */
  6915  
  6916  	case AHVC:
  6917  		return 0xD4<<24 | 0<<21 | 2
  6918  
  6919  	case ASMC:
  6920  		return 0xD4<<24 | 0<<21 | 3
  6921  
  6922  	case ABRK:
  6923  		return 0xD4<<24 | 1<<21 | 0
  6924  
  6925  	case AHLT:
  6926  		return 0xD4<<24 | 2<<21 | 0
  6927  
  6928  	case ADCPS1:
  6929  		return 0xD4<<24 | 5<<21 | 1
  6930  
  6931  	case ADCPS2:
  6932  		return 0xD4<<24 | 5<<21 | 2
  6933  
  6934  	case ADCPS3:
  6935  		return 0xD4<<24 | 5<<21 | 3
  6936  
  6937  	case ACLREX:
  6938  		return SYSOP(0, 0, 3, 3, 0, 2, 0x1F)
  6939  	}
  6940  
  6941  	c.ctxt.Diag("%v: bad imm %v", p, a)
  6942  	return 0
  6943  }
  6944  
  6945  func (c *ctxt7) brdist(p *obj.Prog, preshift int, flen int, shift int) int64 {
  6946  	v := int64(0)
  6947  	t := int64(0)
  6948  	var q *obj.Prog
  6949  	if p.To.Type == obj.TYPE_BRANCH {
  6950  		q = p.To.Target()
  6951  	} else if p.From.Type == obj.TYPE_BRANCH { // adr, adrp
  6952  		q = p.From.Target()
  6953  	}
  6954  	if q == nil {
  6955  		// TODO: don't use brdist for this case, as it isn't a branch.
  6956  		// (Calls from omovlit, and maybe adr/adrp opcodes as well.)
  6957  		q = p.Pool
  6958  	}
  6959  	if q != nil {
  6960  		v = (q.Pc >> uint(preshift)) - (c.pc >> uint(preshift))
  6961  		if (v & ((1 << uint(shift)) - 1)) != 0 {
  6962  			c.ctxt.Diag("misaligned label\n%v", p)
  6963  		}
  6964  		v >>= uint(shift)
  6965  		t = int64(1) << uint(flen-1)
  6966  		if v < -t || v >= t {
  6967  			c.ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, c.blitrl, p, q)
  6968  			panic("branch too far")
  6969  		}
  6970  	}
  6971  
  6972  	return v & ((t << 1) - 1)
  6973  }
  6974  
  6975  /*
  6976   * pc-relative branches
  6977   */
  6978  func (c *ctxt7) opbra(p *obj.Prog, a obj.As) uint32 {
  6979  	switch a {
  6980  	case ABEQ:
  6981  		return OPBcc(0x0)
  6982  
  6983  	case ABNE:
  6984  		return OPBcc(0x1)
  6985  
  6986  	case ABCS:
  6987  		return OPBcc(0x2)
  6988  
  6989  	case ABHS:
  6990  		return OPBcc(0x2)
  6991  
  6992  	case ABCC:
  6993  		return OPBcc(0x3)
  6994  
  6995  	case ABLO:
  6996  		return OPBcc(0x3)
  6997  
  6998  	case ABMI:
  6999  		return OPBcc(0x4)
  7000  
  7001  	case ABPL:
  7002  		return OPBcc(0x5)
  7003  
  7004  	case ABVS:
  7005  		return OPBcc(0x6)
  7006  
  7007  	case ABVC:
  7008  		return OPBcc(0x7)
  7009  
  7010  	case ABHI:
  7011  		return OPBcc(0x8)
  7012  
  7013  	case ABLS:
  7014  		return OPBcc(0x9)
  7015  
  7016  	case ABGE:
  7017  		return OPBcc(0xa)
  7018  
  7019  	case ABLT:
  7020  		return OPBcc(0xb)
  7021  
  7022  	case ABGT:
  7023  		return OPBcc(0xc)
  7024  
  7025  	case ABLE:
  7026  		return OPBcc(0xd) /* imm19<<5 | cond */
  7027  
  7028  	case AB:
  7029  		return 0<<31 | 5<<26 /* imm26 */
  7030  
  7031  	case obj.ADUFFZERO, obj.ADUFFCOPY, ABL:
  7032  		return 1<<31 | 5<<26
  7033  	}
  7034  
  7035  	c.ctxt.Diag("%v: bad bra %v", p, a)
  7036  	return 0
  7037  }
  7038  
  7039  func (c *ctxt7) opbrr(p *obj.Prog, a obj.As) uint32 {
  7040  	switch a {
  7041  	case ABL:
  7042  		return OPBLR(1) /* BLR */
  7043  
  7044  	case AB:
  7045  		return OPBLR(0) /* BR */
  7046  
  7047  	case obj.ARET:
  7048  		return OPBLR(2) /* RET */
  7049  	}
  7050  
  7051  	c.ctxt.Diag("%v: bad brr %v", p, a)
  7052  	return 0
  7053  }
  7054  
  7055  func (c *ctxt7) op0(p *obj.Prog, a obj.As) uint32 {
  7056  	switch a {
  7057  	case ADRPS:
  7058  		return 0x6B<<25 | 5<<21 | 0x1F<<16 | 0x1F<<5
  7059  
  7060  	case AERET:
  7061  		return 0x6B<<25 | 4<<21 | 0x1F<<16 | 0<<10 | 0x1F<<5
  7062  
  7063  	case ANOOP:
  7064  		return SYSHINT(0)
  7065  
  7066  	case AYIELD:
  7067  		return SYSHINT(1)
  7068  
  7069  	case AWFE:
  7070  		return SYSHINT(2)
  7071  
  7072  	case AWFI:
  7073  		return SYSHINT(3)
  7074  
  7075  	case ASEV:
  7076  		return SYSHINT(4)
  7077  
  7078  	case ASEVL:
  7079  		return SYSHINT(5)
  7080  	}
  7081  
  7082  	c.ctxt.Diag("%v: bad op0 %v", p, a)
  7083  	return 0
  7084  }
  7085  
  7086  /*
  7087   * register offset
  7088   */
  7089  func (c *ctxt7) opload(p *obj.Prog, a obj.As) uint32 {
  7090  	switch a {
  7091  	case ALDAR:
  7092  		return LDSTX(3, 1, 1, 0, 1) | 0x1F<<10
  7093  
  7094  	case ALDARW:
  7095  		return LDSTX(2, 1, 1, 0, 1) | 0x1F<<10
  7096  
  7097  	case ALDARB:
  7098  		return LDSTX(0, 1, 1, 0, 1) | 0x1F<<10
  7099  
  7100  	case ALDARH:
  7101  		return LDSTX(1, 1, 1, 0, 1) | 0x1F<<10
  7102  
  7103  	case ALDAXP:
  7104  		return LDSTX(3, 0, 1, 1, 1)
  7105  
  7106  	case ALDAXPW:
  7107  		return LDSTX(2, 0, 1, 1, 1)
  7108  
  7109  	case ALDAXR:
  7110  		return LDSTX(3, 0, 1, 0, 1) | 0x1F<<10
  7111  
  7112  	case ALDAXRW:
  7113  		return LDSTX(2, 0, 1, 0, 1) | 0x1F<<10
  7114  
  7115  	case ALDAXRB:
  7116  		return LDSTX(0, 0, 1, 0, 1) | 0x1F<<10
  7117  
  7118  	case ALDAXRH:
  7119  		return LDSTX(1, 0, 1, 0, 1) | 0x1F<<10
  7120  
  7121  	case ALDXR:
  7122  		return LDSTX(3, 0, 1, 0, 0) | 0x1F<<10
  7123  
  7124  	case ALDXRB:
  7125  		return LDSTX(0, 0, 1, 0, 0) | 0x1F<<10
  7126  
  7127  	case ALDXRH:
  7128  		return LDSTX(1, 0, 1, 0, 0) | 0x1F<<10
  7129  
  7130  	case ALDXRW:
  7131  		return LDSTX(2, 0, 1, 0, 0) | 0x1F<<10
  7132  
  7133  	case ALDXP:
  7134  		return LDSTX(3, 0, 1, 1, 0)
  7135  
  7136  	case ALDXPW:
  7137  		return LDSTX(2, 0, 1, 1, 0)
  7138  	}
  7139  
  7140  	c.ctxt.Diag("bad opload %v\n%v", a, p)
  7141  	return 0
  7142  }
  7143  
  7144  func (c *ctxt7) opstore(p *obj.Prog, a obj.As) uint32 {
  7145  	switch a {
  7146  	case ASTLR:
  7147  		return LDSTX(3, 1, 0, 0, 1) | 0x1F<<10
  7148  
  7149  	case ASTLRB:
  7150  		return LDSTX(0, 1, 0, 0, 1) | 0x1F<<10
  7151  
  7152  	case ASTLRH:
  7153  		return LDSTX(1, 1, 0, 0, 1) | 0x1F<<10
  7154  
  7155  	case ASTLRW:
  7156  		return LDSTX(2, 1, 0, 0, 1) | 0x1F<<10
  7157  
  7158  	case ASTLXP:
  7159  		return LDSTX(3, 0, 0, 1, 1)
  7160  
  7161  	case ASTLXPW:
  7162  		return LDSTX(2, 0, 0, 1, 1)
  7163  
  7164  	case ASTLXR:
  7165  		return LDSTX(3, 0, 0, 0, 1) | 0x1F<<10
  7166  
  7167  	case ASTLXRB:
  7168  		return LDSTX(0, 0, 0, 0, 1) | 0x1F<<10
  7169  
  7170  	case ASTLXRH:
  7171  		return LDSTX(1, 0, 0, 0, 1) | 0x1F<<10
  7172  
  7173  	case ASTLXRW:
  7174  		return LDSTX(2, 0, 0, 0, 1) | 0x1F<<10
  7175  
  7176  	case ASTXR:
  7177  		return LDSTX(3, 0, 0, 0, 0) | 0x1F<<10
  7178  
  7179  	case ASTXRB:
  7180  		return LDSTX(0, 0, 0, 0, 0) | 0x1F<<10
  7181  
  7182  	case ASTXRH:
  7183  		return LDSTX(1, 0, 0, 0, 0) | 0x1F<<10
  7184  
  7185  	case ASTXP:
  7186  		return LDSTX(3, 0, 0, 1, 0)
  7187  
  7188  	case ASTXPW:
  7189  		return LDSTX(2, 0, 0, 1, 0)
  7190  
  7191  	case ASTXRW:
  7192  		return LDSTX(2, 0, 0, 0, 0) | 0x1F<<10
  7193  	}
  7194  
  7195  	c.ctxt.Diag("bad opstore %v\n%v", a, p)
  7196  	return 0
  7197  }
  7198  
  7199  /*
  7200   * load/store register (scaled 12-bit unsigned immediate) C3.3.13
  7201   *	these produce 64-bit values (when there's an option)
  7202   */
  7203  func (c *ctxt7) olsr12u(p *obj.Prog, o uint32, v int32, rn, rt int16) uint32 {
  7204  	if v < 0 || v >= (1<<12) {
  7205  		c.ctxt.Diag("offset out of range: %d\n%v", v, p)
  7206  	}
  7207  	o |= uint32(v&0xFFF) << 10
  7208  	o |= uint32(rn&31) << 5
  7209  	o |= uint32(rt & 31)
  7210  	o |= 1 << 24
  7211  	return o
  7212  }
  7213  
  7214  /*
  7215   * load/store register (unscaled 9-bit signed immediate) C3.3.12
  7216   */
  7217  func (c *ctxt7) olsr9s(p *obj.Prog, o uint32, v int32, rn, rt int16) uint32 {
  7218  	if v < -256 || v > 255 {
  7219  		c.ctxt.Diag("offset out of range: %d\n%v", v, p)
  7220  	}
  7221  	o |= uint32((v & 0x1FF) << 12)
  7222  	o |= uint32(rn&31) << 5
  7223  	o |= uint32(rt & 31)
  7224  	return o
  7225  }
  7226  
  7227  // store(immediate)
  7228  // scaled 12-bit unsigned immediate offset.
  7229  // unscaled 9-bit signed immediate offset.
  7230  // pre/post-indexed store.
  7231  // and the 12-bit and 9-bit are distinguished in olsr12u and oslr9s.
  7232  func (c *ctxt7) opstr(p *obj.Prog, a obj.As) uint32 {
  7233  	enc := c.opldr(p, a)
  7234  	switch p.As {
  7235  	case AFMOVQ:
  7236  		enc = enc &^ (1 << 22)
  7237  	default:
  7238  		enc = LD2STR(enc)
  7239  	}
  7240  	return enc
  7241  }
  7242  
  7243  // load(immediate)
  7244  // scaled 12-bit unsigned immediate offset.
  7245  // unscaled 9-bit signed immediate offset.
  7246  // pre/post-indexed load.
  7247  // and the 12-bit and 9-bit are distinguished in olsr12u and oslr9s.
  7248  func (c *ctxt7) opldr(p *obj.Prog, a obj.As) uint32 {
  7249  	switch a {
  7250  	case AMOVD:
  7251  		return LDSTR(3, 0, 1) /* simm9<<12 | Rn<<5 | Rt */
  7252  
  7253  	case AMOVW:
  7254  		return LDSTR(2, 0, 2)
  7255  
  7256  	case AMOVWU:
  7257  		return LDSTR(2, 0, 1)
  7258  
  7259  	case AMOVH:
  7260  		return LDSTR(1, 0, 2)
  7261  
  7262  	case AMOVHU:
  7263  		return LDSTR(1, 0, 1)
  7264  
  7265  	case AMOVB:
  7266  		return LDSTR(0, 0, 2)
  7267  
  7268  	case AMOVBU:
  7269  		return LDSTR(0, 0, 1)
  7270  
  7271  	case AFMOVS, AVMOVS:
  7272  		return LDSTR(2, 1, 1)
  7273  
  7274  	case AFMOVD, AVMOVD:
  7275  		return LDSTR(3, 1, 1)
  7276  
  7277  	case AFMOVQ, AVMOVQ:
  7278  		return LDSTR(0, 1, 3)
  7279  	}
  7280  
  7281  	c.ctxt.Diag("bad opldr %v\n%v", a, p)
  7282  	return 0
  7283  }
  7284  
  7285  // olsxrr attaches register operands to a load/store opcode supplied in o.
  7286  // The result either encodes a load of r from (r1+r2) or a store of r to (r1+r2).
  7287  func (c *ctxt7) olsxrr(p *obj.Prog, o int32, r int, r1 int, r2 int) uint32 {
  7288  	o |= int32(r1&31) << 5
  7289  	o |= int32(r2&31) << 16
  7290  	o |= int32(r & 31)
  7291  	return uint32(o)
  7292  }
  7293  
  7294  // opldrr returns the ARM64 opcode encoding corresponding to the obj.As opcode
  7295  // for load instruction with register offset.
  7296  // The offset register can be (Rn)(Rm.UXTW<<2) or (Rn)(Rm<<2) or (Rn)(Rm).
  7297  func (c *ctxt7) opldrr(p *obj.Prog, a obj.As, extension bool) uint32 {
  7298  	OptionS := uint32(0x1a)
  7299  	if extension {
  7300  		OptionS = uint32(0) // option value and S value have been encoded into p.From.Offset.
  7301  	}
  7302  	switch a {
  7303  	case AMOVD:
  7304  		return OptionS<<10 | 0x3<<21 | 0x1f<<27
  7305  	case AMOVW:
  7306  		return OptionS<<10 | 0x5<<21 | 0x17<<27
  7307  	case AMOVWU:
  7308  		return OptionS<<10 | 0x3<<21 | 0x17<<27
  7309  	case AMOVH:
  7310  		return OptionS<<10 | 0x5<<21 | 0x0f<<27
  7311  	case AMOVHU:
  7312  		return OptionS<<10 | 0x3<<21 | 0x0f<<27
  7313  	case AMOVB:
  7314  		return OptionS<<10 | 0x5<<21 | 0x07<<27
  7315  	case AMOVBU:
  7316  		return OptionS<<10 | 0x3<<21 | 0x07<<27
  7317  	case AFMOVS:
  7318  		return OptionS<<10 | 0x3<<21 | 0x17<<27 | 1<<26
  7319  	case AFMOVD:
  7320  		return OptionS<<10 | 0x3<<21 | 0x1f<<27 | 1<<26
  7321  	}
  7322  	c.ctxt.Diag("bad opldrr %v\n%v", a, p)
  7323  	return 0
  7324  }
  7325  
  7326  // opstrr returns the ARM64 opcode encoding corresponding to the obj.As opcode
  7327  // for store instruction with register offset.
  7328  // The offset register can be (Rn)(Rm.UXTW<<2) or (Rn)(Rm<<2) or (Rn)(Rm).
  7329  func (c *ctxt7) opstrr(p *obj.Prog, a obj.As, extension bool) uint32 {
  7330  	OptionS := uint32(0x1a)
  7331  	if extension {
  7332  		OptionS = uint32(0) // option value and S value have been encoded into p.To.Offset.
  7333  	}
  7334  	switch a {
  7335  	case AMOVD:
  7336  		return OptionS<<10 | 0x1<<21 | 0x1f<<27
  7337  	case AMOVW, AMOVWU:
  7338  		return OptionS<<10 | 0x1<<21 | 0x17<<27
  7339  	case AMOVH, AMOVHU:
  7340  		return OptionS<<10 | 0x1<<21 | 0x0f<<27
  7341  	case AMOVB, AMOVBU:
  7342  		return OptionS<<10 | 0x1<<21 | 0x07<<27
  7343  	case AFMOVS:
  7344  		return OptionS<<10 | 0x1<<21 | 0x17<<27 | 1<<26
  7345  	case AFMOVD:
  7346  		return OptionS<<10 | 0x1<<21 | 0x1f<<27 | 1<<26
  7347  	}
  7348  	c.ctxt.Diag("bad opstrr %v\n%v", a, p)
  7349  	return 0
  7350  }
  7351  
  7352  func (c *ctxt7) oaddi(p *obj.Prog, a obj.As, v int32, rd, rn int16) uint32 {
  7353  	op := c.opirr(p, a)
  7354  
  7355  	if (v & 0xFFF000) != 0 {
  7356  		if v&0xFFF != 0 {
  7357  			c.ctxt.Diag("%v misuses oaddi", p)
  7358  		}
  7359  		v >>= 12
  7360  		op |= 1 << 22
  7361  	}
  7362  
  7363  	op |= (uint32(v&0xFFF) << 10) | (uint32(rn&31) << 5) | uint32(rd&31)
  7364  
  7365  	return op
  7366  }
  7367  
  7368  func (c *ctxt7) oaddi12(p *obj.Prog, v int32, rd, rn int16) uint32 {
  7369  	if v < -4095 || v > 4095 {
  7370  		c.ctxt.Diag("%v is not a 12 bit immediate: %v", v, p)
  7371  		return 0
  7372  	}
  7373  	a := AADD
  7374  	if v < 0 {
  7375  		a = ASUB
  7376  		v = -v
  7377  	}
  7378  	return c.oaddi(p, a, v, rd, rn)
  7379  }
  7380  
  7381  /*
  7382   * load a literal value into dr
  7383   */
  7384  func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
  7385  	var o1 int32
  7386  	if p.Pool == nil { /* not in literal pool */
  7387  		c.aclass(a)
  7388  		c.ctxt.Logf("omovlit add %d (%#x)\n", c.instoffset, uint64(c.instoffset))
  7389  
  7390  		/* TODO: could be clever, and use general constant builder */
  7391  		o1 = int32(c.opirr(p, AADD))
  7392  
  7393  		v := int32(c.instoffset)
  7394  		if v != 0 && (v&0xFFF) == 0 {
  7395  			v >>= 12
  7396  			o1 |= 1 << 22 /* shift, by 12 */
  7397  		}
  7398  
  7399  		o1 |= ((v & 0xFFF) << 10) | (REGZERO & 31 << 5) | int32(dr&31)
  7400  	} else {
  7401  		fp, w := 0, 0
  7402  		switch as {
  7403  		case AFMOVS, AVMOVS:
  7404  			fp = 1
  7405  			w = 0 /* 32-bit SIMD/FP */
  7406  
  7407  		case AFMOVD, AVMOVD:
  7408  			fp = 1
  7409  			w = 1 /* 64-bit SIMD/FP */
  7410  
  7411  		case AVMOVQ:
  7412  			fp = 1
  7413  			w = 2 /* 128-bit SIMD/FP */
  7414  
  7415  		case AMOVD:
  7416  			if p.Pool.As == ADWORD {
  7417  				w = 1 /* 64-bit */
  7418  			} else if p.Pool.To.Offset < 0 {
  7419  				w = 2 /* 32-bit, sign-extended to 64-bit */
  7420  			} else if p.Pool.To.Offset >= 0 {
  7421  				w = 0 /* 32-bit, zero-extended to 64-bit */
  7422  			} else {
  7423  				c.ctxt.Diag("invalid operand %v in %v", a, p)
  7424  			}
  7425  
  7426  		case AMOVBU, AMOVHU, AMOVWU:
  7427  			w = 0 /* 32-bit, zero-extended to 64-bit */
  7428  
  7429  		case AMOVB, AMOVH, AMOVW:
  7430  			w = 2 /* 32-bit, sign-extended to 64-bit */
  7431  
  7432  		default:
  7433  			c.ctxt.Diag("invalid operation %v in %v", as, p)
  7434  		}
  7435  
  7436  		v := int32(c.brdist(p, 0, 19, 2))
  7437  		o1 = (int32(w) << 30) | (int32(fp) << 26) | (3 << 27)
  7438  		o1 |= (v & 0x7FFFF) << 5
  7439  		o1 |= int32(dr & 31)
  7440  	}
  7441  
  7442  	return uint32(o1)
  7443  }
  7444  
  7445  // load a constant (MOVCON or BITCON) in a into rt
  7446  func (c *ctxt7) omovconst(as obj.As, p *obj.Prog, a *obj.Addr, rt int) (o1 uint32) {
  7447  	if cls := int(a.Class); (cls == C_BITCON || cls == C_ABCON || cls == C_ABCON0) && rt != REGZERO {
  7448  		// or $bitcon, REGZERO, rt. rt can't be ZR.
  7449  		mode := 64
  7450  		var as1 obj.As
  7451  		switch as {
  7452  		case AMOVW:
  7453  			as1 = AORRW
  7454  			mode = 32
  7455  		case AMOVD:
  7456  			as1 = AORR
  7457  		}
  7458  		o1 = c.opirr(p, as1)
  7459  		o1 |= bitconEncode(uint64(a.Offset), mode) | uint32(REGZERO&31)<<5 | uint32(rt&31)
  7460  		return o1
  7461  	}
  7462  
  7463  	if as == AMOVW {
  7464  		d := uint32(a.Offset)
  7465  		s := movcon(int64(d))
  7466  		if s < 0 || 16*s >= 32 {
  7467  			d = ^d
  7468  			s = movcon(int64(d))
  7469  			if s < 0 || 16*s >= 32 {
  7470  				c.ctxt.Diag("impossible 32-bit move wide: %#x\n%v", uint32(a.Offset), p)
  7471  			}
  7472  			o1 = c.opirr(p, AMOVNW)
  7473  		} else {
  7474  			o1 = c.opirr(p, AMOVZW)
  7475  		}
  7476  		o1 |= MOVCONST(int64(d), s, rt)
  7477  	}
  7478  	if as == AMOVD {
  7479  		d := a.Offset
  7480  		s := movcon(d)
  7481  		if s < 0 || 16*s >= 64 {
  7482  			d = ^d
  7483  			s = movcon(d)
  7484  			if s < 0 || 16*s >= 64 {
  7485  				c.ctxt.Diag("impossible 64-bit move wide: %#x\n%v", uint64(a.Offset), p)
  7486  			}
  7487  			o1 = c.opirr(p, AMOVN)
  7488  		} else {
  7489  			o1 = c.opirr(p, AMOVZ)
  7490  		}
  7491  		o1 |= MOVCONST(d, s, rt)
  7492  	}
  7493  	return o1
  7494  }
  7495  
  7496  // load a 32-bit/64-bit large constant (LCON or VCON) in a.Offset into rt
  7497  // put the instruction sequence in os and return the number of instructions.
  7498  func (c *ctxt7) omovlconst(as obj.As, p *obj.Prog, a *obj.Addr, rt int, os []uint32) (num uint8) {
  7499  	switch as {
  7500  	case AMOVW:
  7501  		d := uint32(a.Offset)
  7502  		// use MOVZW and MOVKW to load a constant to rt
  7503  		os[0] = c.opirr(p, AMOVZW)
  7504  		os[0] |= MOVCONST(int64(d), 0, rt)
  7505  		os[1] = c.opirr(p, AMOVKW)
  7506  		os[1] |= MOVCONST(int64(d), 1, rt)
  7507  		return 2
  7508  
  7509  	case AMOVD:
  7510  		d := a.Offset
  7511  		dn := ^d
  7512  		var immh [4]uint64
  7513  		var i int
  7514  		zeroCount := int(0)
  7515  		negCount := int(0)
  7516  		for i = 0; i < 4; i++ {
  7517  			immh[i] = uint64((d >> uint(i*16)) & 0xffff)
  7518  			if immh[i] == 0 {
  7519  				zeroCount++
  7520  			} else if immh[i] == 0xffff {
  7521  				negCount++
  7522  			}
  7523  		}
  7524  
  7525  		if zeroCount == 4 || negCount == 4 {
  7526  			c.ctxt.Diag("the immediate should be MOVCON: %v", p)
  7527  		}
  7528  		switch {
  7529  		case zeroCount == 3:
  7530  			// one MOVZ
  7531  			for i = 0; i < 4; i++ {
  7532  				if immh[i] != 0 {
  7533  					os[0] = c.opirr(p, AMOVZ)
  7534  					os[0] |= MOVCONST(d, i, rt)
  7535  					break
  7536  				}
  7537  			}
  7538  			return 1
  7539  
  7540  		case negCount == 3:
  7541  			// one MOVN
  7542  			for i = 0; i < 4; i++ {
  7543  				if immh[i] != 0xffff {
  7544  					os[0] = c.opirr(p, AMOVN)
  7545  					os[0] |= MOVCONST(dn, i, rt)
  7546  					break
  7547  				}
  7548  			}
  7549  			return 1
  7550  
  7551  		case zeroCount == 2:
  7552  			// one MOVZ and one MOVK
  7553  			for i = 0; i < 4; i++ {
  7554  				if immh[i] != 0 {
  7555  					os[0] = c.opirr(p, AMOVZ)
  7556  					os[0] |= MOVCONST(d, i, rt)
  7557  					i++
  7558  					break
  7559  				}
  7560  			}
  7561  			for ; i < 4; i++ {
  7562  				if immh[i] != 0 {
  7563  					os[1] = c.opirr(p, AMOVK)
  7564  					os[1] |= MOVCONST(d, i, rt)
  7565  				}
  7566  			}
  7567  			return 2
  7568  
  7569  		case negCount == 2:
  7570  			// one MOVN and one MOVK
  7571  			for i = 0; i < 4; i++ {
  7572  				if immh[i] != 0xffff {
  7573  					os[0] = c.opirr(p, AMOVN)
  7574  					os[0] |= MOVCONST(dn, i, rt)
  7575  					i++
  7576  					break
  7577  				}
  7578  			}
  7579  			for ; i < 4; i++ {
  7580  				if immh[i] != 0xffff {
  7581  					os[1] = c.opirr(p, AMOVK)
  7582  					os[1] |= MOVCONST(d, i, rt)
  7583  				}
  7584  			}
  7585  			return 2
  7586  
  7587  		case zeroCount == 1:
  7588  			// one MOVZ and two MOVKs
  7589  			for i = 0; i < 4; i++ {
  7590  				if immh[i] != 0 {
  7591  					os[0] = c.opirr(p, AMOVZ)
  7592  					os[0] |= MOVCONST(d, i, rt)
  7593  					i++
  7594  					break
  7595  				}
  7596  			}
  7597  
  7598  			for j := 1; i < 4; i++ {
  7599  				if immh[i] != 0 {
  7600  					os[j] = c.opirr(p, AMOVK)
  7601  					os[j] |= MOVCONST(d, i, rt)
  7602  					j++
  7603  				}
  7604  			}
  7605  			return 3
  7606  
  7607  		case negCount == 1:
  7608  			// one MOVN and two MOVKs
  7609  			for i = 0; i < 4; i++ {
  7610  				if immh[i] != 0xffff {
  7611  					os[0] = c.opirr(p, AMOVN)
  7612  					os[0] |= MOVCONST(dn, i, rt)
  7613  					i++
  7614  					break
  7615  				}
  7616  			}
  7617  
  7618  			for j := 1; i < 4; i++ {
  7619  				if immh[i] != 0xffff {
  7620  					os[j] = c.opirr(p, AMOVK)
  7621  					os[j] |= MOVCONST(d, i, rt)
  7622  					j++
  7623  				}
  7624  			}
  7625  			return 3
  7626  
  7627  		default:
  7628  			// one MOVZ and 3 MOVKs
  7629  			os[0] = c.opirr(p, AMOVZ)
  7630  			os[0] |= MOVCONST(d, 0, rt)
  7631  			for i = 1; i < 4; i++ {
  7632  				os[i] = c.opirr(p, AMOVK)
  7633  				os[i] |= MOVCONST(d, i, rt)
  7634  			}
  7635  			return 4
  7636  		}
  7637  	default:
  7638  		return 0
  7639  	}
  7640  }
  7641  
  7642  func (c *ctxt7) opbfm(p *obj.Prog, a obj.As, r, s int64, rf, rt int16) uint32 {
  7643  	var b uint32
  7644  	o := c.opirr(p, a)
  7645  	if (o & (1 << 31)) == 0 {
  7646  		b = 32
  7647  	} else {
  7648  		b = 64
  7649  	}
  7650  	if r < 0 || uint32(r) >= b {
  7651  		c.ctxt.Diag("illegal bit number\n%v", p)
  7652  	}
  7653  	o |= (uint32(r) & 0x3F) << 16
  7654  	if s < 0 || uint32(s) >= b {
  7655  		c.ctxt.Diag("illegal bit number\n%v", p)
  7656  	}
  7657  	o |= (uint32(s) & 0x3F) << 10
  7658  	o |= (uint32(rf&31) << 5) | uint32(rt&31)
  7659  	return o
  7660  }
  7661  
  7662  func (c *ctxt7) opextr(p *obj.Prog, a obj.As, v int64, rn, rm, rt int16) uint32 {
  7663  	var b uint32
  7664  	o := c.opirr(p, a)
  7665  	if (o & (1 << 31)) != 0 {
  7666  		b = 63
  7667  	} else {
  7668  		b = 31
  7669  	}
  7670  	if v < 0 || uint32(v) > b {
  7671  		c.ctxt.Diag("illegal bit number\n%v", p)
  7672  	}
  7673  	o |= uint32(v) << 10
  7674  	o |= uint32(rn&31) << 5
  7675  	o |= uint32(rm&31) << 16
  7676  	o |= uint32(rt & 31)
  7677  	return o
  7678  }
  7679  
  7680  /* generate instruction encoding for ldp and stp series */
  7681  func (c *ctxt7) opldpstp(p *obj.Prog, o *Optab, vo int32, rbase, rl, rh int16, ldp uint32) uint32 {
  7682  	wback := false
  7683  	if o.scond == C_XPOST || o.scond == C_XPRE {
  7684  		wback = true
  7685  	}
  7686  	switch p.As {
  7687  	case ALDP, ALDPW, ALDPSW:
  7688  		c.checkUnpredictable(p, true, wback, p.From.Reg, p.To.Reg, int16(p.To.Offset))
  7689  	case ASTP, ASTPW:
  7690  		if wback {
  7691  			c.checkUnpredictable(p, false, true, p.To.Reg, p.From.Reg, int16(p.From.Offset))
  7692  		}
  7693  	case AFLDPD, AFLDPQ, AFLDPS:
  7694  		c.checkUnpredictable(p, true, false, p.From.Reg, p.To.Reg, int16(p.To.Offset))
  7695  	}
  7696  	var ret uint32
  7697  	// check offset
  7698  	switch p.As {
  7699  	case AFLDPQ, AFSTPQ:
  7700  		if vo < -1024 || vo > 1008 || vo%16 != 0 {
  7701  			c.ctxt.Diag("invalid offset %v\n", p)
  7702  		}
  7703  		vo /= 16
  7704  		ret = 2<<30 | 1<<26
  7705  	case AFLDPD, AFSTPD:
  7706  		if vo < -512 || vo > 504 || vo%8 != 0 {
  7707  			c.ctxt.Diag("invalid offset %v\n", p)
  7708  		}
  7709  		vo /= 8
  7710  		ret = 1<<30 | 1<<26
  7711  	case AFLDPS, AFSTPS:
  7712  		if vo < -256 || vo > 252 || vo%4 != 0 {
  7713  			c.ctxt.Diag("invalid offset %v\n", p)
  7714  		}
  7715  		vo /= 4
  7716  		ret = 1 << 26
  7717  	case ALDP, ASTP:
  7718  		if vo < -512 || vo > 504 || vo%8 != 0 {
  7719  			c.ctxt.Diag("invalid offset %v\n", p)
  7720  		}
  7721  		vo /= 8
  7722  		ret = 2 << 30
  7723  	case ALDPW, ASTPW:
  7724  		if vo < -256 || vo > 252 || vo%4 != 0 {
  7725  			c.ctxt.Diag("invalid offset %v\n", p)
  7726  		}
  7727  		vo /= 4
  7728  		ret = 0
  7729  	case ALDPSW:
  7730  		if vo < -256 || vo > 252 || vo%4 != 0 {
  7731  			c.ctxt.Diag("invalid offset %v\n", p)
  7732  		}
  7733  		vo /= 4
  7734  		ret = 1 << 30
  7735  	default:
  7736  		c.ctxt.Diag("invalid instruction %v\n", p)
  7737  	}
  7738  	// check register pair
  7739  	switch p.As {
  7740  	case AFLDPQ, AFLDPD, AFLDPS, AFSTPQ, AFSTPD, AFSTPS:
  7741  		if rl < REG_F0 || REG_F31 < rl || rh < REG_F0 || REG_F31 < rh {
  7742  			c.ctxt.Diag("invalid register pair %v\n", p)
  7743  		}
  7744  	case ALDP, ALDPW, ALDPSW:
  7745  		if rl < REG_R0 || REG_R31 < rl || rh < REG_R0 || REG_R31 < rh {
  7746  			c.ctxt.Diag("invalid register pair %v\n", p)
  7747  		}
  7748  	case ASTP, ASTPW:
  7749  		if rl < REG_R0 || REG_R31 < rl || rh < REG_R0 || REG_R31 < rh {
  7750  			c.ctxt.Diag("invalid register pair %v\n", p)
  7751  		}
  7752  	}
  7753  	// other conditional flag bits
  7754  	switch o.scond {
  7755  	case C_XPOST:
  7756  		ret |= 1 << 23
  7757  	case C_XPRE:
  7758  		ret |= 3 << 23
  7759  	default:
  7760  		ret |= 2 << 23
  7761  	}
  7762  	ret |= 5<<27 | (ldp&1)<<22 | uint32(vo&0x7f)<<15 | uint32(rh&31)<<10 | uint32(rbase&31)<<5 | uint32(rl&31)
  7763  	return ret
  7764  }
  7765  
  7766  func (c *ctxt7) maskOpvldvst(p *obj.Prog, o1 uint32) uint32 {
  7767  	if p.As == AVLD1 || p.As == AVST1 {
  7768  		return o1
  7769  	}
  7770  
  7771  	o1 &^= 0xf000 // mask out "opcode" field (bit 12-15)
  7772  	switch p.As {
  7773  	case AVLD1R, AVLD2R:
  7774  		o1 |= 0xC << 12
  7775  	case AVLD3R, AVLD4R:
  7776  		o1 |= 0xE << 12
  7777  	case AVLD2, AVST2:
  7778  		o1 |= 8 << 12
  7779  	case AVLD3, AVST3:
  7780  		o1 |= 4 << 12
  7781  	case AVLD4, AVST4:
  7782  	default:
  7783  		c.ctxt.Diag("unsupported instruction:%v\n", p.As)
  7784  	}
  7785  	return o1
  7786  }
  7787  
  7788  /*
  7789   * size in log2(bytes)
  7790   */
  7791  func movesize(a obj.As) int {
  7792  	switch a {
  7793  	case AFMOVQ:
  7794  		return 4
  7795  
  7796  	case AMOVD, AFMOVD:
  7797  		return 3
  7798  
  7799  	case AMOVW, AMOVWU, AFMOVS:
  7800  		return 2
  7801  
  7802  	case AMOVH, AMOVHU:
  7803  		return 1
  7804  
  7805  	case AMOVB, AMOVBU:
  7806  		return 0
  7807  
  7808  	default:
  7809  		return -1
  7810  	}
  7811  }
  7812  
  7813  // rm is the Rm register value, o is the extension, amount is the left shift value.
  7814  func roff(rm int16, o uint32, amount int16) uint32 {
  7815  	return uint32(rm&31)<<16 | o<<13 | uint32(amount)<<10
  7816  }
  7817  
  7818  // encRegShiftOrExt returns the encoding of shifted/extended register, Rx<<n and Rx.UXTW<<n, etc.
  7819  func (c *ctxt7) encRegShiftOrExt(p *obj.Prog, a *obj.Addr, r int16) uint32 {
  7820  	var num, rm int16
  7821  	num = (r >> 5) & 7
  7822  	rm = r & 31
  7823  	switch {
  7824  	case REG_UXTB <= r && r < REG_UXTH:
  7825  		return roff(rm, 0, num)
  7826  	case REG_UXTH <= r && r < REG_UXTW:
  7827  		return roff(rm, 1, num)
  7828  	case REG_UXTW <= r && r < REG_UXTX:
  7829  		if a.Type == obj.TYPE_MEM {
  7830  			if num == 0 {
  7831  				// According to the arm64 specification, for instructions MOVB, MOVBU and FMOVB,
  7832  				// the extension amount must be 0, encoded in "S" as 0 if omitted, or as 1 if present.
  7833  				// But in Go, we don't distinguish between Rn.UXTW and Rn.UXTW<<0, so we encode it as
  7834  				// that does not present. This makes no difference to the function of the instruction.
  7835  				// This is also true for extensions LSL, SXTW and SXTX.
  7836  				return roff(rm, 2, 2)
  7837  			} else {
  7838  				return roff(rm, 2, 6)
  7839  			}
  7840  		} else {
  7841  			return roff(rm, 2, num)
  7842  		}
  7843  	case REG_UXTX <= r && r < REG_SXTB:
  7844  		return roff(rm, 3, num)
  7845  	case REG_SXTB <= r && r < REG_SXTH:
  7846  		return roff(rm, 4, num)
  7847  	case REG_SXTH <= r && r < REG_SXTW:
  7848  		return roff(rm, 5, num)
  7849  	case REG_SXTW <= r && r < REG_SXTX:
  7850  		if a.Type == obj.TYPE_MEM {
  7851  			if num == 0 {
  7852  				return roff(rm, 6, 2)
  7853  			} else {
  7854  				return roff(rm, 6, 6)
  7855  			}
  7856  		} else {
  7857  			return roff(rm, 6, num)
  7858  		}
  7859  	case REG_SXTX <= r && r < REG_SPECIAL:
  7860  		if a.Type == obj.TYPE_MEM {
  7861  			if num == 0 {
  7862  				return roff(rm, 7, 2)
  7863  			} else {
  7864  				return roff(rm, 7, 6)
  7865  			}
  7866  		} else {
  7867  			return roff(rm, 7, num)
  7868  		}
  7869  	case REG_LSL <= r && r < REG_ARNG:
  7870  		if a.Type == obj.TYPE_MEM { // (R1)(R2<<1)
  7871  			if num == 0 {
  7872  				return roff(rm, 3, 2)
  7873  			} else {
  7874  				return roff(rm, 3, 6)
  7875  			}
  7876  		} else if isADDWop(p.As) {
  7877  			return roff(rm, 2, num)
  7878  		}
  7879  		return roff(rm, 3, num)
  7880  	default:
  7881  		c.ctxt.Diag("unsupported register extension type.")
  7882  	}
  7883  
  7884  	return 0
  7885  }
  7886  
  7887  // pack returns the encoding of the "Q" field and two arrangement specifiers.
  7888  func pack(q uint32, arngA, arngB uint8) uint32 {
  7889  	return uint32(q)<<16 | uint32(arngA)<<8 | uint32(arngB)
  7890  }