gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

asm7.go (176941B)


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