github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/cmd/internal/obj/arm64/asm7.go (about)

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