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

View as plain text