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

View as plain text