Source file src/cmd/internal/obj/arm64/asm7.go

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

View as plain text