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

View as plain text