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

View as plain text