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