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

View as plain text