github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/cmd/internal/obj/arm64/asm7.go (about)

     1  // cmd/7l/asm.c, cmd/7l/asmout.c, cmd/7l/optab.c, cmd/7l/span.c, cmd/ld/sub.c, cmd/ld/mod.c, from Vita Nuova.
     2  // https://code.google.com/p/ken-cc/source/browse/
     3  //
     4  // 	Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
     5  // 	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  // 	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  // 	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  // 	Portions Copyright © 2004,2006 Bruce Ellis
     9  // 	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  // 	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  // 	Portions Copyright © 2009 The Go Authors. All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  package arm64
    32  
    33  import (
    34  	"cmd/internal/obj"
    35  	"fmt"
    36  	"log"
    37  	"math"
    38  	"sort"
    39  )
    40  
    41  // ctxt7 holds state while assembling a single function.
    42  // Each function gets a fresh ctxt7.
    43  // This allows for multiple functions to be safely concurrently assembled.
    44  type ctxt7 struct {
    45  	ctxt       *obj.Link
    46  	newprog    obj.ProgAlloc
    47  	cursym     *obj.LSym
    48  	blitrl     *obj.Prog
    49  	elitrl     *obj.Prog
    50  	autosize   int32
    51  	instoffset int64
    52  	pc         int64
    53  	pool       struct {
    54  		start uint32
    55  		size  uint32
    56  	}
    57  }
    58  
    59  const (
    60  	funcAlign = 16
    61  )
    62  
    63  const (
    64  	REGFROM = 1
    65  )
    66  
    67  type Optab struct {
    68  	as    obj.As
    69  	a1    uint8
    70  	a2    uint8
    71  	a3    uint8
    72  	type_ int8
    73  	size  int8
    74  	param int16
    75  	flag  int8
    76  	scond uint16
    77  }
    78  
    79  var oprange [ALAST & obj.AMask][]Optab
    80  
    81  var xcmp [C_NCLASS][C_NCLASS]bool
    82  
    83  const (
    84  	S32     = 0 << 31
    85  	S64     = 1 << 31
    86  	Sbit    = 1 << 29
    87  	LSL0_32 = 2 << 13
    88  	LSL0_64 = 3 << 13
    89  )
    90  
    91  func OPDP2(x uint32) uint32 {
    92  	return 0<<30 | 0<<29 | 0xd6<<21 | x<<10
    93  }
    94  
    95  func OPDP3(sf uint32, op54 uint32, op31 uint32, o0 uint32) uint32 {
    96  	return sf<<31 | op54<<29 | 0x1B<<24 | op31<<21 | o0<<15
    97  }
    98  
    99  func OPBcc(x uint32) uint32 {
   100  	return 0x2A<<25 | 0<<24 | 0<<4 | x&15
   101  }
   102  
   103  func OPBLR(x uint32) uint32 {
   104  	/* x=0, JMP; 1, CALL; 2, RET */
   105  	return 0x6B<<25 | 0<<23 | x<<21 | 0x1F<<16 | 0<<10
   106  }
   107  
   108  func SYSOP(l uint32, op0 uint32, op1 uint32, crn uint32, crm uint32, op2 uint32, rt uint32) uint32 {
   109  	return 0x354<<22 | l<<21 | op0<<19 | op1<<16 | crn&15<<12 | crm&15<<8 | op2<<5 | rt
   110  }
   111  
   112  func SYSHINT(x uint32) uint32 {
   113  	return SYSOP(0, 0, 3, 2, 0, x, 0x1F)
   114  }
   115  
   116  func LDSTR12U(sz uint32, v uint32, opc uint32) uint32 {
   117  	return sz<<30 | 7<<27 | v<<26 | 1<<24 | opc<<22
   118  }
   119  
   120  func LDSTR9S(sz uint32, v uint32, opc uint32) uint32 {
   121  	return sz<<30 | 7<<27 | v<<26 | 0<<24 | opc<<22
   122  }
   123  
   124  func LD2STR(o uint32) uint32 {
   125  	return o &^ (3 << 22)
   126  }
   127  
   128  func LDSTX(sz uint32, o2 uint32, l uint32, o1 uint32, o0 uint32) uint32 {
   129  	return sz<<30 | 0x8<<24 | o2<<23 | l<<22 | o1<<21 | o0<<15
   130  }
   131  
   132  func FPCMP(m uint32, s uint32, type_ uint32, op uint32, op2 uint32) uint32 {
   133  	return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<14 | 8<<10 | op2
   134  }
   135  
   136  func FPCCMP(m uint32, s uint32, type_ uint32, op uint32) uint32 {
   137  	return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | 1<<10 | op<<4
   138  }
   139  
   140  func FPOP1S(m uint32, s uint32, type_ uint32, op uint32) uint32 {
   141  	return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<15 | 0x10<<10
   142  }
   143  
   144  func FPOP2S(m uint32, s uint32, type_ uint32, op uint32) uint32 {
   145  	return m<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | op<<12 | 2<<10
   146  }
   147  
   148  func FPCVTI(sf uint32, s uint32, type_ uint32, rmode uint32, op uint32) uint32 {
   149  	return sf<<31 | s<<29 | 0x1E<<24 | type_<<22 | 1<<21 | rmode<<19 | op<<16 | 0<<10
   150  }
   151  
   152  func ADR(p uint32, o uint32, rt uint32) uint32 {
   153  	return p<<31 | (o&3)<<29 | 0x10<<24 | ((o>>2)&0x7FFFF)<<5 | rt&31
   154  }
   155  
   156  func OPBIT(x uint32) uint32 {
   157  	return 1<<30 | 0<<29 | 0xD6<<21 | 0<<16 | x<<10
   158  }
   159  
   160  const (
   161  	LFROM = 1 << 0
   162  	LTO   = 1 << 1
   163  )
   164  
   165  var optab = []Optab{
   166  	/* struct Optab:
   167  	OPCODE, from, prog->reg, to, type,size,param,flag,scond */
   168  	{obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0},
   169  
   170  	/* arithmetic operations */
   171  	{AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
   172  	{AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
   173  	{AADC, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
   174  	{AADC, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
   175  	{ANEG, C_REG, C_NONE, C_REG, 25, 4, 0, 0, 0},
   176  	{ANEG, C_NONE, C_NONE, C_REG, 25, 4, 0, 0, 0},
   177  	{ANGC, C_REG, C_NONE, C_REG, 17, 4, 0, 0, 0},
   178  	{ACMP, C_REG, C_REG, C_NONE, 1, 4, 0, 0, 0},
   179  	{AADD, C_ADDCON, C_RSP, C_RSP, 2, 4, 0, 0, 0},
   180  	{AADD, C_ADDCON, C_NONE, C_RSP, 2, 4, 0, 0, 0},
   181  	{ACMP, C_ADDCON, C_RSP, C_NONE, 2, 4, 0, 0, 0},
   182  	{AADD, C_MOVCON, C_RSP, C_RSP, 62, 8, 0, 0, 0},
   183  	{AADD, C_MOVCON, C_NONE, C_RSP, 62, 8, 0, 0, 0},
   184  	{ACMP, C_MOVCON, C_RSP, C_NONE, 62, 8, 0, 0, 0},
   185  	{AADD, C_BITCON, C_RSP, C_RSP, 62, 8, 0, 0, 0},
   186  	{AADD, C_BITCON, C_NONE, C_RSP, 62, 8, 0, 0, 0},
   187  	{ACMP, C_BITCON, C_RSP, C_NONE, 62, 8, 0, 0, 0},
   188  	{AADD, C_VCON, C_RSP, C_RSP, 13, 8, 0, LFROM, 0},
   189  	{AADD, C_VCON, C_NONE, C_RSP, 13, 8, 0, LFROM, 0},
   190  	{ACMP, C_VCON, C_REG, C_NONE, 13, 8, 0, LFROM, 0},
   191  	{AADD, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0},
   192  	{AADD, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
   193  	{AMVN, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
   194  	{ACMP, C_SHIFT, C_REG, C_NONE, 3, 4, 0, 0, 0},
   195  	{ANEG, C_SHIFT, C_NONE, C_REG, 26, 4, 0, 0, 0},
   196  	{AADD, C_REG, C_RSP, C_RSP, 27, 4, 0, 0, 0},
   197  	{AADD, C_REG, C_NONE, C_RSP, 27, 4, 0, 0, 0},
   198  	{ACMP, C_REG, C_RSP, C_NONE, 27, 4, 0, 0, 0},
   199  	{AADD, C_EXTREG, C_RSP, C_RSP, 27, 4, 0, 0, 0},
   200  	{AADD, C_EXTREG, C_NONE, C_RSP, 27, 4, 0, 0, 0},
   201  	{AMVN, C_EXTREG, C_NONE, C_RSP, 27, 4, 0, 0, 0},
   202  	{ACMP, C_EXTREG, C_RSP, C_NONE, 27, 4, 0, 0, 0},
   203  	{AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
   204  	{AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
   205  
   206  	/* logical operations */
   207  	{AAND, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
   208  	{AAND, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
   209  	{ABIC, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
   210  	{ABIC, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
   211  	{AAND, C_MBCON, C_REG, C_REG, 53, 4, 0, 0, 0},
   212  	{AAND, C_MBCON, C_NONE, C_REG, 53, 4, 0, 0, 0},
   213  	{ABIC, C_MBCON, C_REG, C_REG, 53, 4, 0, 0, 0},
   214  	{ABIC, C_MBCON, C_NONE, C_REG, 53, 4, 0, 0, 0},
   215  	{AAND, C_BITCON, C_REG, C_REG, 53, 4, 0, 0, 0},
   216  	{AAND, C_BITCON, C_NONE, C_REG, 53, 4, 0, 0, 0},
   217  	{ABIC, C_BITCON, C_REG, C_REG, 53, 4, 0, 0, 0},
   218  	{ABIC, C_BITCON, C_NONE, C_REG, 53, 4, 0, 0, 0},
   219  	{AAND, C_MOVCON, C_REG, C_REG, 62, 8, 0, 0, 0},
   220  	{AAND, C_MOVCON, C_NONE, C_REG, 62, 8, 0, 0, 0},
   221  	{ABIC, C_MOVCON, C_REG, C_REG, 62, 8, 0, 0, 0},
   222  	{ABIC, C_MOVCON, C_NONE, C_REG, 62, 8, 0, 0, 0},
   223  	{AAND, C_VCON, C_REG, C_REG, 28, 8, 0, LFROM, 0},
   224  	{AAND, C_VCON, C_NONE, C_REG, 28, 8, 0, LFROM, 0},
   225  	{ABIC, C_VCON, C_REG, C_REG, 28, 8, 0, LFROM, 0},
   226  	{ABIC, C_VCON, C_NONE, C_REG, 28, 8, 0, LFROM, 0},
   227  	{AAND, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0},
   228  	{AAND, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
   229  	{ABIC, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0},
   230  	{ABIC, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0},
   231  	{AMOVD, C_RSP, C_NONE, C_RSP, 24, 4, 0, 0, 0},
   232  	{AMVN, C_REG, C_NONE, C_REG, 24, 4, 0, 0, 0},
   233  	{AMOVB, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0},
   234  	{AMOVBU, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0},
   235  	{AMOVH, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0}, /* also MOVHU */
   236  	{AMOVW, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0}, /* also MOVWU */
   237  	/* TODO: MVN C_SHIFT */
   238  
   239  	/* MOVs that become MOVK/MOVN/MOVZ/ADD/SUB/OR */
   240  	{AMOVW, C_MOVCON, C_NONE, C_REG, 32, 4, 0, 0, 0},
   241  	{AMOVD, C_MOVCON, C_NONE, C_REG, 32, 4, 0, 0, 0},
   242  
   243  	// TODO: these don't work properly.
   244  	// { AMOVW,		C_ADDCON,	C_NONE,	C_REG,		2, 4, 0 , 0},
   245  	// { AMOVD,		C_ADDCON,	C_NONE,	C_REG,		2, 4, 0 , 0},
   246  	{AMOVW, C_BITCON, C_NONE, C_REG, 32, 4, 0, 0, 0},
   247  	{AMOVD, C_BITCON, C_NONE, C_REG, 32, 4, 0, 0, 0},
   248  
   249  	{AMOVK, C_VCON, C_NONE, C_REG, 33, 4, 0, 0, 0},
   250  	{AMOVD, C_AACON, C_NONE, C_REG, 4, 4, REGFROM, 0, 0},
   251  	{ASDIV, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
   252  	{ASDIV, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0},
   253  	{AB, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0},
   254  	{ABL, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0},
   255  	{AB, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0},
   256  	{ABL, C_NONE, C_NONE, C_REG, 6, 4, 0, 0, 0},
   257  	{ABL, C_REG, C_NONE, C_REG, 6, 4, 0, 0, 0},
   258  	{ABL, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0},
   259  	{obj.ARET, C_NONE, C_NONE, C_REG, 6, 4, 0, 0, 0},
   260  	{obj.ARET, C_NONE, C_NONE, C_ZOREG, 6, 4, 0, 0, 0},
   261  	{AADRP, C_SBRA, C_NONE, C_REG, 60, 4, 0, 0, 0},
   262  	{AADR, C_SBRA, C_NONE, C_REG, 61, 4, 0, 0, 0},
   263  	{ABFM, C_VCON, C_REG, C_REG, 42, 4, 0, 0, 0},
   264  	{ABFI, C_VCON, C_REG, C_REG, 43, 4, 0, 0, 0},
   265  	{AEXTR, C_VCON, C_REG, C_REG, 44, 4, 0, 0, 0},
   266  	{ASXTB, C_REG, C_NONE, C_REG, 45, 4, 0, 0, 0},
   267  	{ACLS, C_REG, C_NONE, C_REG, 46, 4, 0, 0, 0},
   268  	{ABEQ, C_NONE, C_NONE, C_SBRA, 7, 4, 0, 0, 0},
   269  	{ALSL, C_VCON, C_REG, C_REG, 8, 4, 0, 0, 0},
   270  	{ALSL, C_VCON, C_NONE, C_REG, 8, 4, 0, 0, 0},
   271  	{ALSL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0},
   272  	{ALSL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0},
   273  	{ASVC, C_NONE, C_NONE, C_VCON, 10, 4, 0, 0, 0},
   274  	{ASVC, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0},
   275  	{ADWORD, C_NONE, C_NONE, C_VCON, 11, 8, 0, 0, 0},
   276  	{ADWORD, C_NONE, C_NONE, C_LEXT, 11, 8, 0, 0, 0},
   277  	{ADWORD, C_NONE, C_NONE, C_ADDR, 11, 8, 0, 0, 0},
   278  	{ADWORD, C_NONE, C_NONE, C_LACON, 11, 8, 0, 0, 0},
   279  	{AWORD, C_NONE, C_NONE, C_LCON, 14, 4, 0, 0, 0},
   280  	{AWORD, C_NONE, C_NONE, C_LEXT, 14, 4, 0, 0, 0},
   281  	{AWORD, C_NONE, C_NONE, C_ADDR, 14, 4, 0, 0, 0},
   282  	{AMOVW, C_VCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0},
   283  	{AMOVW, C_VCONADDR, C_NONE, C_REG, 68, 8, 0, 0, 0},
   284  	{AMOVD, C_VCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0},
   285  	{AMOVD, C_VCONADDR, C_NONE, C_REG, 68, 8, 0, 0, 0},
   286  	{AMOVB, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
   287  	{AMOVBU, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
   288  	{AMOVH, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
   289  	{AMOVW, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
   290  	{AMOVD, C_REG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
   291  	{AMOVB, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
   292  	{AMOVBU, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
   293  	{AMOVH, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
   294  	{AMOVW, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
   295  	{AMOVD, C_ADDR, C_NONE, C_REG, 65, 12, 0, 0, 0},
   296  	{AMOVD, C_GOTADDR, C_NONE, C_REG, 71, 8, 0, 0, 0},
   297  	{AMOVD, C_TLS_LE, C_NONE, C_REG, 69, 4, 0, 0, 0},
   298  	{AMOVD, C_TLS_IE, C_NONE, C_REG, 70, 8, 0, 0, 0},
   299  	{AMUL, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0},
   300  	{AMUL, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0},
   301  	{AMADD, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0},
   302  	{AREM, C_REG, C_REG, C_REG, 16, 8, 0, 0, 0},
   303  	{AREM, C_REG, C_NONE, C_REG, 16, 8, 0, 0, 0},
   304  	{ACSEL, C_COND, C_REG, C_REG, 18, 4, 0, 0, 0}, /* from3 optional */
   305  	{ACSET, C_COND, C_NONE, C_REG, 18, 4, 0, 0, 0},
   306  	{ACCMN, C_COND, C_REG, C_VCON, 19, 4, 0, 0, 0}, /* from3 either C_REG or C_VCON */
   307  
   308  	/* scaled 12-bit unsigned displacement store */
   309  	{AMOVB, C_REG, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0},
   310  	{AMOVB, C_REG, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0},
   311  	{AMOVBU, C_REG, C_NONE, C_UAUTO4K, 20, 4, REGSP, 0, 0},
   312  	{AMOVBU, C_REG, C_NONE, C_UOREG4K, 20, 4, 0, 0, 0},
   313  
   314  	{AMOVH, C_REG, C_NONE, C_UAUTO8K, 20, 4, REGSP, 0, 0},
   315  	{AMOVH, C_REG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
   316  	{AMOVH, C_REG, C_NONE, C_UOREG8K, 20, 4, 0, 0, 0},
   317  
   318  	{AMOVW, C_REG, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0},
   319  	{AMOVW, C_REG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
   320  	{AMOVW, C_REG, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0},
   321  
   322  	/* unscaled 9-bit signed displacement store */
   323  	{AMOVB, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
   324  	{AMOVB, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
   325  	{AMOVBU, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
   326  	{AMOVBU, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
   327  
   328  	{AMOVH, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
   329  	{AMOVH, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
   330  	{AMOVW, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
   331  	{AMOVW, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
   332  
   333  	{AMOVD, C_REG, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0},
   334  	{AMOVD, C_REG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
   335  	{AMOVD, C_REG, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0},
   336  	{AMOVD, C_REG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
   337  	{AMOVD, C_REG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
   338  
   339  	/* short displacement load */
   340  	{AMOVB, C_UAUTO4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   341  	{AMOVB, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   342  	{AMOVB, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
   343  	{AMOVB, C_UOREG4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   344  	{AMOVB, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   345  
   346  	{AMOVBU, C_UAUTO4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   347  	{AMOVBU, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   348  	{AMOVBU, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
   349  	{AMOVBU, C_UOREG4K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   350  	{AMOVBU, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   351  
   352  	{AMOVH, C_UAUTO8K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   353  	{AMOVH, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   354  	{AMOVH, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
   355  	{AMOVH, C_UOREG8K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   356  	{AMOVH, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   357  
   358  	{AMOVW, C_UAUTO16K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   359  	{AMOVW, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   360  	{AMOVW, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
   361  	{AMOVW, C_UOREG16K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   362  	{AMOVW, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   363  
   364  	{AMOVD, C_UAUTO32K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   365  	{AMOVD, C_NSAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   366  	{AMOVD, C_ZOREG, C_NONE, C_REG, 21, 4, 0, 0, 0},
   367  	{AMOVD, C_UOREG32K, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   368  	{AMOVD, C_NSOREG, C_NONE, C_REG, 21, 4, REGSP, 0, 0},
   369  
   370  	/* long displacement store */
   371  	{AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0},
   372  	{AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0},
   373  	{AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0},
   374  	{AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0},
   375  	{AMOVH, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0},
   376  	{AMOVH, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0},
   377  	{AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0},
   378  	{AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0},
   379  	{AMOVD, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, 0, 0},
   380  	{AMOVD, C_REG, C_NONE, C_LOREG, 30, 8, 0, 0, 0},
   381  
   382  	/* long displacement load */
   383  	{AMOVB, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0},
   384  	{AMOVB, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
   385  	{AMOVB, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
   386  	{AMOVBU, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0},
   387  	{AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
   388  	{AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
   389  	{AMOVH, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0},
   390  	{AMOVH, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
   391  	{AMOVH, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
   392  	{AMOVW, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0},
   393  	{AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
   394  	{AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
   395  	{AMOVD, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, 0, 0},
   396  	{AMOVD, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
   397  	{AMOVD, C_LOREG, C_NONE, C_REG, 31, 8, 0, 0, 0},
   398  
   399  	/* load long effective stack address (load int32 offset and add) */
   400  	{AMOVD, C_LACON, C_NONE, C_REG, 34, 8, REGSP, LFROM, 0},
   401  
   402  	/* pre/post-indexed load (unscaled, signed 9-bit offset) */
   403  	{AMOVD, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
   404  	{AMOVW, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
   405  	{AMOVH, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
   406  	{AMOVB, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
   407  	{AMOVBU, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPOST},
   408  	{AFMOVS, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST},
   409  	{AFMOVD, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPOST},
   410  	{AMOVD, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
   411  	{AMOVW, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
   412  	{AMOVH, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
   413  	{AMOVB, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
   414  	{AMOVBU, C_LOREG, C_NONE, C_REG, 22, 4, 0, 0, C_XPRE},
   415  	{AFMOVS, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE},
   416  	{AFMOVD, C_LOREG, C_NONE, C_FREG, 22, 4, 0, 0, C_XPRE},
   417  
   418  	/* pre/post-indexed store (unscaled, signed 9-bit offset) */
   419  	{AMOVD, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
   420  	{AMOVW, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
   421  	{AMOVH, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
   422  	{AMOVB, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
   423  	{AMOVBU, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
   424  	{AFMOVS, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
   425  	{AFMOVD, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPOST},
   426  	{AMOVD, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
   427  	{AMOVW, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
   428  	{AMOVH, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
   429  	{AMOVB, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
   430  	{AMOVBU, C_REG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
   431  	{AFMOVS, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
   432  	{AFMOVD, C_FREG, C_NONE, C_LOREG, 23, 4, 0, 0, C_XPRE},
   433  
   434  	/* pre/post-indexed load/store register pair
   435  	   (unscaled, signed 10-bit quad-aligned offset) */
   436  	{ALDP, C_LOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPRE},
   437  	{ALDP, C_LOREG, C_NONE, C_PAIR, 66, 4, 0, 0, C_XPOST},
   438  	{ASTP, C_PAIR, C_NONE, C_LOREG, 67, 4, 0, 0, C_XPRE},
   439  	{ASTP, C_PAIR, C_NONE, C_LOREG, 67, 4, 0, 0, C_XPOST},
   440  
   441  	/* special */
   442  	{AMOVD, C_SPR, C_NONE, C_REG, 35, 4, 0, 0, 0},
   443  	{AMRS, C_SPR, C_NONE, C_REG, 35, 4, 0, 0, 0},
   444  	{AMOVD, C_REG, C_NONE, C_SPR, 36, 4, 0, 0, 0},
   445  	{AMSR, C_REG, C_NONE, C_SPR, 36, 4, 0, 0, 0},
   446  	{AMOVD, C_VCON, C_NONE, C_SPR, 37, 4, 0, 0, 0},
   447  	{AMSR, C_VCON, C_NONE, C_SPR, 37, 4, 0, 0, 0},
   448  	{AERET, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0},
   449  	{AFMOVS, C_FREG, C_NONE, C_UAUTO16K, 20, 4, REGSP, 0, 0},
   450  	{AFMOVS, C_FREG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
   451  	{AFMOVS, C_FREG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
   452  	{AFMOVS, C_FREG, C_NONE, C_UOREG16K, 20, 4, 0, 0, 0},
   453  	{AFMOVS, C_FREG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
   454  	{AFMOVD, C_FREG, C_NONE, C_UAUTO32K, 20, 4, REGSP, 0, 0},
   455  	{AFMOVD, C_FREG, C_NONE, C_NSAUTO, 20, 4, REGSP, 0, 0},
   456  	{AFMOVD, C_FREG, C_NONE, C_ZOREG, 20, 4, 0, 0, 0},
   457  	{AFMOVD, C_FREG, C_NONE, C_UOREG32K, 20, 4, 0, 0, 0},
   458  	{AFMOVD, C_FREG, C_NONE, C_NSOREG, 20, 4, 0, 0, 0},
   459  	{AFMOVS, C_UAUTO16K, C_NONE, C_FREG, 21, 4, REGSP, 0, 0},
   460  	{AFMOVS, C_NSAUTO, C_NONE, C_FREG, 21, 4, REGSP, 0, 0},
   461  	{AFMOVS, C_ZOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0},
   462  	{AFMOVS, C_UOREG16K, C_NONE, C_FREG, 21, 4, 0, 0, 0},
   463  	{AFMOVS, C_NSOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0},
   464  	{AFMOVD, C_UAUTO32K, C_NONE, C_FREG, 21, 4, REGSP, 0, 0},
   465  	{AFMOVD, C_NSAUTO, C_NONE, C_FREG, 21, 4, REGSP, 0, 0},
   466  	{AFMOVD, C_ZOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0},
   467  	{AFMOVD, C_UOREG32K, C_NONE, C_FREG, 21, 4, 0, 0, 0},
   468  	{AFMOVD, C_NSOREG, C_NONE, C_FREG, 21, 4, 0, 0, 0},
   469  	{AFMOVS, C_FREG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
   470  	{AFMOVS, C_FREG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
   471  	{AFMOVD, C_FREG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0},
   472  	{AFMOVD, C_FREG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0},
   473  	{AFMOVS, C_LAUTO, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0},
   474  	{AFMOVS, C_LOREG, C_NONE, C_FREG, 31, 8, 0, LFROM, 0},
   475  	{AFMOVD, C_LAUTO, C_NONE, C_FREG, 31, 8, REGSP, LFROM, 0},
   476  	{AFMOVD, C_LOREG, C_NONE, C_FREG, 31, 8, 0, LFROM, 0},
   477  	{AFMOVS, C_FREG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
   478  	{AFMOVS, C_ADDR, C_NONE, C_FREG, 65, 12, 0, 0, 0},
   479  	{AFMOVD, C_FREG, C_NONE, C_ADDR, 64, 12, 0, 0, 0},
   480  	{AFMOVD, C_ADDR, C_NONE, C_FREG, 65, 12, 0, 0, 0},
   481  	{AFADDS, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0},
   482  	{AFADDS, C_FREG, C_FREG, C_FREG, 54, 4, 0, 0, 0},
   483  	{AFADDS, C_FCON, C_NONE, C_FREG, 54, 4, 0, 0, 0},
   484  	{AFADDS, C_FCON, C_FREG, C_FREG, 54, 4, 0, 0, 0},
   485  	{AFMOVS, C_FCON, C_NONE, C_FREG, 54, 4, 0, 0, 0},
   486  	{AFMOVS, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0},
   487  	{AFMOVD, C_FCON, C_NONE, C_FREG, 54, 4, 0, 0, 0},
   488  	{AFMOVD, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0},
   489  	{AFCVTZSD, C_FREG, C_NONE, C_REG, 29, 4, 0, 0, 0},
   490  	{ASCVTFD, C_REG, C_NONE, C_FREG, 29, 4, 0, 0, 0},
   491  	{AFMOVS, C_REG, C_NONE, C_FREG, 29, 4, 0, 0, 0},
   492  	{AFMOVS, C_FREG, C_NONE, C_REG, 29, 4, 0, 0, 0},
   493  	{AFMOVD, C_REG, C_NONE, C_FREG, 29, 4, 0, 0, 0},
   494  	{AFMOVD, C_FREG, C_NONE, C_REG, 29, 4, 0, 0, 0},
   495  	{AFCMPS, C_FREG, C_FREG, C_NONE, 56, 4, 0, 0, 0},
   496  	{AFCMPS, C_FCON, C_FREG, C_NONE, 56, 4, 0, 0, 0},
   497  	{AFCCMPS, C_COND, C_REG, C_VCON, 57, 4, 0, 0, 0},
   498  	{AFCSELD, C_COND, C_REG, C_FREG, 18, 4, 0, 0, 0},
   499  	{AFCVTSD, C_FREG, C_NONE, C_FREG, 29, 4, 0, 0, 0},
   500  	{ACLREX, C_NONE, C_NONE, C_VCON, 38, 4, 0, 0, 0},
   501  	{ACLREX, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0, 0},
   502  	{ACBZ, C_REG, C_NONE, C_SBRA, 39, 4, 0, 0, 0},
   503  	{ATBZ, C_VCON, C_REG, C_SBRA, 40, 4, 0, 0, 0},
   504  	{ASYS, C_VCON, C_NONE, C_NONE, 50, 4, 0, 0, 0},
   505  	{ASYS, C_VCON, C_REG, C_NONE, 50, 4, 0, 0, 0},
   506  	{ASYSL, C_VCON, C_NONE, C_REG, 50, 4, 0, 0, 0},
   507  	{ADMB, C_VCON, C_NONE, C_NONE, 51, 4, 0, 0, 0},
   508  	{AHINT, C_VCON, C_NONE, C_NONE, 52, 4, 0, 0, 0},
   509  	{ALDAR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
   510  	{ALDXR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
   511  	{ALDAXR, C_ZOREG, C_NONE, C_REG, 58, 4, 0, 0, 0},
   512  	{ALDXP, C_ZOREG, C_REG, C_REG, 58, 4, 0, 0, 0},
   513  	{ASTLR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0},  // to3=C_NONE
   514  	{ASTXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0},  // to3=C_REG
   515  	{ASTLXR, C_REG, C_NONE, C_ZOREG, 59, 4, 0, 0, 0}, // to3=C_REG
   516  
   517  	//	{ ASTXP,		C_REG, C_NONE,	C_ZOREG,		59, 4, 0 , 0}, // TODO(aram):
   518  
   519  	{AAESD, C_VREG, C_NONE, C_VREG, 29, 4, 0, 0, 0},
   520  	{ASHA1C, C_VREG, C_REG, C_VREG, 1, 4, 0, 0, 0},
   521  
   522  	{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 90, 4, 0, 0, 0},
   523  	{obj.APCDATA, C_VCON, C_NONE, C_VCON, 0, 0, 0, 0, 0},
   524  	{obj.AFUNCDATA, C_VCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0},
   525  	{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
   526  	{obj.ADUFFZERO, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as AB/ABL
   527  	{obj.ADUFFCOPY, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as AB/ABL
   528  
   529  	{obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0},
   530  }
   531  
   532  /*
   533   * valid pstate field values, and value to use in instruction
   534   */
   535  var pstatefield = []struct {
   536  	a uint32
   537  	b uint32
   538  }{
   539  	{REG_SPSel, 0<<16 | 4<<12 | 5<<5},
   540  	{REG_DAIFSet, 3<<16 | 4<<12 | 6<<5},
   541  	{REG_DAIFClr, 3<<16 | 4<<12 | 7<<5},
   542  }
   543  
   544  func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
   545  	p := cursym.Text
   546  	if p == nil || p.Link == nil { // handle external functions and ELF section symbols
   547  		return
   548  	}
   549  
   550  	if oprange[AAND&obj.AMask] == nil {
   551  		ctxt.Diag("arm64 ops not initialized, call arm64.buildop first")
   552  	}
   553  
   554  	c := ctxt7{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset&0xffffffff) + 8}
   555  
   556  	bflag := 1
   557  	pc := int64(0)
   558  	p.Pc = pc
   559  	var m int
   560  	var o *Optab
   561  	for p = p.Link; p != nil; p = p.Link {
   562  		if p.As == ADWORD && (pc&7) != 0 {
   563  			pc += 4
   564  		}
   565  		p.Pc = pc
   566  		o = c.oplook(p)
   567  		m = int(o.size)
   568  		if m == 0 {
   569  			if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
   570  				c.ctxt.Diag("zero-width instruction\n%v", p)
   571  			}
   572  			continue
   573  		}
   574  
   575  		switch o.flag & (LFROM | LTO) {
   576  		case LFROM:
   577  			c.addpool(p, &p.From)
   578  
   579  		case LTO:
   580  			c.addpool(p, &p.To)
   581  			break
   582  		}
   583  
   584  		if p.As == AB || p.As == obj.ARET || p.As == AERET { /* TODO: other unconditional operations */
   585  			c.checkpool(p, 0)
   586  		}
   587  		pc += int64(m)
   588  		if c.blitrl != nil {
   589  			c.checkpool(p, 1)
   590  		}
   591  	}
   592  
   593  	c.cursym.Size = pc
   594  
   595  	/*
   596  	 * if any procedure is large enough to
   597  	 * generate a large SBRA branch, then
   598  	 * generate extra passes putting branches
   599  	 * around jmps to fix. this is rare.
   600  	 */
   601  	for bflag != 0 {
   602  		bflag = 0
   603  		pc = 0
   604  		for p = c.cursym.Text.Link; p != nil; p = p.Link {
   605  			if p.As == ADWORD && (pc&7) != 0 {
   606  				pc += 4
   607  			}
   608  			p.Pc = pc
   609  			o = c.oplook(p)
   610  
   611  			/* very large branches */
   612  			if (o.type_ == 7 || o.type_ == 39) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like
   613  				otxt := p.Pcond.Pc - pc
   614  				if otxt <= -(1<<18)+10 || otxt >= (1<<18)-10 {
   615  					q := c.newprog()
   616  					q.Link = p.Link
   617  					p.Link = q
   618  					q.As = AB
   619  					q.To.Type = obj.TYPE_BRANCH
   620  					q.Pcond = p.Pcond
   621  					p.Pcond = q
   622  					q = c.newprog()
   623  					q.Link = p.Link
   624  					p.Link = q
   625  					q.As = AB
   626  					q.To.Type = obj.TYPE_BRANCH
   627  					q.Pcond = q.Link.Link
   628  					bflag = 1
   629  				}
   630  			}
   631  			m = int(o.size)
   632  
   633  			if m == 0 {
   634  				if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
   635  					c.ctxt.Diag("zero-width instruction\n%v", p)
   636  				}
   637  				continue
   638  			}
   639  
   640  			pc += int64(m)
   641  		}
   642  	}
   643  
   644  	pc += -pc & (funcAlign - 1)
   645  	c.cursym.Size = pc
   646  
   647  	/*
   648  	 * lay out the code, emitting code and data relocations.
   649  	 */
   650  	c.cursym.Grow(c.cursym.Size)
   651  	bp := c.cursym.P
   652  	psz := int32(0)
   653  	var i int
   654  	var out [6]uint32
   655  	for p := c.cursym.Text.Link; p != nil; p = p.Link {
   656  		c.pc = p.Pc
   657  		o = c.oplook(p)
   658  
   659  		// need to align DWORDs on 8-byte boundary. The ISA doesn't
   660  		// require it, but the various 64-bit loads we generate assume it.
   661  		if o.as == ADWORD && psz%8 != 0 {
   662  			bp[3] = 0
   663  			bp[2] = bp[3]
   664  			bp[1] = bp[2]
   665  			bp[0] = bp[1]
   666  			bp = bp[4:]
   667  			psz += 4
   668  		}
   669  
   670  		if int(o.size) > 4*len(out) {
   671  			log.Fatalf("out array in span7 is too small, need at least %d for %v", o.size/4, p)
   672  		}
   673  		c.asmout(p, o, out[:])
   674  		for i = 0; i < int(o.size/4); i++ {
   675  			c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
   676  			bp = bp[4:]
   677  			psz += 4
   678  		}
   679  	}
   680  }
   681  
   682  /*
   683   * when the first reference to the literal pool threatens
   684   * to go out of range of a 1Mb PC-relative offset
   685   * drop the pool now, and branch round it.
   686   */
   687  func (c *ctxt7) checkpool(p *obj.Prog, skip int) {
   688  	if c.pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(c.pool.size)-int64(c.pool.start)+8)) {
   689  		c.flushpool(p, skip)
   690  	} else if p.Link == nil {
   691  		c.flushpool(p, 2)
   692  	}
   693  }
   694  
   695  func (c *ctxt7) flushpool(p *obj.Prog, skip int) {
   696  	if c.blitrl != nil {
   697  		if skip != 0 {
   698  			if c.ctxt.Debugvlog && skip == 1 {
   699  				fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), c.pool.size, c.pool.start)
   700  			}
   701  			q := c.newprog()
   702  			q.As = AB
   703  			q.To.Type = obj.TYPE_BRANCH
   704  			q.Pcond = p.Link
   705  			q.Link = c.blitrl
   706  			q.Pos = p.Pos
   707  			c.blitrl = q
   708  		} else if p.Pc+int64(c.pool.size)-int64(c.pool.start) < maxPCDisp {
   709  			return
   710  		}
   711  
   712  		// The line number for constant pool entries doesn't really matter.
   713  		// We set it to the line number of the preceding instruction so that
   714  		// there are no deltas to encode in the pc-line tables.
   715  		for q := c.blitrl; q != nil; q = q.Link {
   716  			q.Pos = p.Pos
   717  		}
   718  
   719  		c.elitrl.Link = p.Link
   720  		p.Link = c.blitrl
   721  
   722  		c.blitrl = nil /* BUG: should refer back to values until out-of-range */
   723  		c.elitrl = nil
   724  		c.pool.size = 0
   725  		c.pool.start = 0
   726  	}
   727  }
   728  
   729  /*
   730   * TODO: hash
   731   */
   732  func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
   733  	cls := c.aclass(a)
   734  	lit := c.instoffset
   735  	t := c.newprog()
   736  	t.As = AWORD
   737  	sz := 4
   738  
   739  	// MOVD foo(SB), R is actually
   740  	//	MOVD addr, REGTMP
   741  	//	MOVD REGTMP, R
   742  	// where addr is the address of the DWORD containing the address of foo.
   743  	if p.As == AMOVD || cls == C_ADDR || cls == C_VCON || int64(lit) != int64(int32(lit)) || uint64(lit) != uint64(uint32(lit)) {
   744  		// conservative: don't know if we want signed or unsigned extension.
   745  		// in case of ambiguity, store 64-bit
   746  		t.As = ADWORD
   747  		sz = 8
   748  	}
   749  
   750  	switch cls {
   751  	// TODO(aram): remove.
   752  	default:
   753  		if a.Name != obj.NAME_EXTERN {
   754  			fmt.Printf("addpool: %v in %v shouldn't go to default case\n", DRconv(cls), p)
   755  		}
   756  
   757  		t.To.Offset = a.Offset
   758  		t.To.Sym = a.Sym
   759  		t.To.Type = a.Type
   760  		t.To.Name = a.Name
   761  
   762  	/* This is here because MOV uint12<<12, R is disabled in optab.
   763  	Because of this, we need to load the constant from memory. */
   764  	case C_ADDCON:
   765  		fallthrough
   766  
   767  	case C_PSAUTO,
   768  		C_PPAUTO,
   769  		C_UAUTO4K,
   770  		C_UAUTO8K,
   771  		C_UAUTO16K,
   772  		C_UAUTO32K,
   773  		C_UAUTO64K,
   774  		C_NSAUTO,
   775  		C_NPAUTO,
   776  		C_LAUTO,
   777  		C_PPOREG,
   778  		C_PSOREG,
   779  		C_UOREG4K,
   780  		C_UOREG8K,
   781  		C_UOREG16K,
   782  		C_UOREG32K,
   783  		C_UOREG64K,
   784  		C_NSOREG,
   785  		C_NPOREG,
   786  		C_LOREG,
   787  		C_LACON,
   788  		C_LCON,
   789  		C_VCON:
   790  		if a.Name == obj.NAME_EXTERN {
   791  			fmt.Printf("addpool: %v in %v needs reloc\n", DRconv(cls), p)
   792  		}
   793  
   794  		t.To.Type = obj.TYPE_CONST
   795  		t.To.Offset = lit
   796  		break
   797  	}
   798  
   799  	for q := c.blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
   800  		if q.To == t.To {
   801  			p.Pcond = q
   802  			return
   803  		}
   804  	}
   805  
   806  	q := c.newprog()
   807  	*q = *t
   808  	q.Pc = int64(c.pool.size)
   809  	if c.blitrl == nil {
   810  		c.blitrl = q
   811  		c.pool.start = uint32(p.Pc)
   812  	} else {
   813  		c.elitrl.Link = q
   814  	}
   815  	c.elitrl = q
   816  	c.pool.size = -c.pool.size & (funcAlign - 1)
   817  	c.pool.size += uint32(sz)
   818  	p.Pcond = q
   819  }
   820  
   821  func (c *ctxt7) regoff(a *obj.Addr) uint32 {
   822  	c.instoffset = 0
   823  	c.aclass(a)
   824  	return uint32(c.instoffset)
   825  }
   826  
   827  // Maximum PC-relative displacement.
   828  // The actual limit is ±2²⁰, but we are conservative
   829  // to avoid needing to recompute the literal pool flush points
   830  // as span-dependent jumps are enlarged.
   831  const maxPCDisp = 512 * 1024
   832  
   833  // ispcdisp reports whether v is a valid PC-relative displacement.
   834  func ispcdisp(v int32) bool {
   835  	return -maxPCDisp < v && v < maxPCDisp && v&3 == 0
   836  }
   837  
   838  func isaddcon(v int64) bool {
   839  	/* uimm12 or uimm24? */
   840  	if v < 0 {
   841  		return false
   842  	}
   843  	if (v & 0xFFF) == 0 {
   844  		v >>= 12
   845  	}
   846  	return v <= 0xFFF
   847  }
   848  
   849  // isbitcon returns whether a constant can be encoded into a logical instruction.
   850  // bitcon has a binary form of repetition of a bit sequence of length 2, 4, 8, 16, 32, or 64,
   851  // which itself is a rotate (w.r.t. the length of the unit) of a sequence of ones.
   852  // special cases: 0 and -1 are not bitcon.
   853  // this function needs to run against virtually all the constants, so it needs to be fast.
   854  // for this reason, bitcon testing and bitcon encoding are separate functions.
   855  func isbitcon(x uint64) bool {
   856  	if x == 1<<64-1 || x == 0 {
   857  		return false
   858  	}
   859  	// determine the period and sign-extend a unit to 64 bits
   860  	switch {
   861  	case x != x>>32|x<<32:
   862  		// period is 64
   863  		// nothing to do
   864  	case x != x>>16|x<<48:
   865  		// period is 32
   866  		x = uint64(int64(int32(x)))
   867  	case x != x>>8|x<<56:
   868  		// period is 16
   869  		x = uint64(int64(int16(x)))
   870  	case x != x>>4|x<<60:
   871  		// period is 8
   872  		x = uint64(int64(int8(x)))
   873  	default:
   874  		// period is 4 or 2, always true
   875  		// 0001, 0010, 0100, 1000 -- 0001 rotate
   876  		// 0011, 0110, 1100, 1001 -- 0011 rotate
   877  		// 0111, 1011, 1101, 1110 -- 0111 rotate
   878  		// 0101, 1010             -- 01   rotate, repeat
   879  		return true
   880  	}
   881  	return sequenceOfOnes(x) || sequenceOfOnes(^x)
   882  }
   883  
   884  // sequenceOfOnes tests whether a constant is a sequence of ones in binary, with leading and trailing zeros
   885  func sequenceOfOnes(x uint64) bool {
   886  	y := x & -x // lowest set bit of x. x is good iff x+y is a power of 2
   887  	y += x
   888  	return (y-1)&y == 0
   889  }
   890  
   891  // bitconEncode returns the encoding of a bitcon used in logical instructions
   892  // x is known to be a bitcon
   893  // a bitcon is a sequence of n ones at low bits (i.e. 1<<n-1), right rotated
   894  // by R bits, and repeated with period of 64, 32, 16, 8, 4, or 2.
   895  // it is encoded in logical instructions with 3 bitfields
   896  // N (1 bit) : R (6 bits) : S (6 bits), where
   897  // N=1           -- period=64
   898  // N=0, S=0xxxxx -- period=32
   899  // N=0, S=10xxxx -- period=16
   900  // N=0, S=110xxx -- period=8
   901  // N=0, S=1110xx -- period=4
   902  // N=0, S=11110x -- period=2
   903  // R is the shift amount, low bits of S = n-1
   904  func bitconEncode(x uint64, mode int) uint32 {
   905  	var period uint32
   906  	// determine the period and sign-extend a unit to 64 bits
   907  	switch {
   908  	case x != x>>32|x<<32:
   909  		period = 64
   910  	case x != x>>16|x<<48:
   911  		period = 32
   912  		x = uint64(int64(int32(x)))
   913  	case x != x>>8|x<<56:
   914  		period = 16
   915  		x = uint64(int64(int16(x)))
   916  	case x != x>>4|x<<60:
   917  		period = 8
   918  		x = uint64(int64(int8(x)))
   919  	case x != x>>2|x<<62:
   920  		period = 4
   921  		x = uint64(int64(x<<60) >> 60)
   922  	default:
   923  		period = 2
   924  		x = uint64(int64(x<<62) >> 62)
   925  	}
   926  	neg := false
   927  	if int64(x) < 0 {
   928  		x = ^x
   929  		neg = true
   930  	}
   931  	y := x & -x // lowest set bit of x.
   932  	s := log2(y)
   933  	n := log2(x+y) - s // x (or ^x) is a sequence of n ones left shifted by s bits
   934  	if neg {
   935  		// ^x is a sequence of n ones left shifted by s bits
   936  		// adjust n, s for x
   937  		s = n + s
   938  		n = period - n
   939  	}
   940  
   941  	N := uint32(0)
   942  	if mode == 64 && period == 64 {
   943  		N = 1
   944  	}
   945  	R := (period - s) & (period - 1) & uint32(mode-1) // shift amount of right rotate
   946  	S := (n - 1) | 63&^(period<<1-1)                  // low bits = #ones - 1, high bits encodes period
   947  	return N<<22 | R<<16 | S<<10
   948  }
   949  
   950  func log2(x uint64) uint32 {
   951  	if x == 0 {
   952  		panic("log2 of 0")
   953  	}
   954  	n := uint32(0)
   955  	if x >= 1<<32 {
   956  		x >>= 32
   957  		n += 32
   958  	}
   959  	if x >= 1<<16 {
   960  		x >>= 16
   961  		n += 16
   962  	}
   963  	if x >= 1<<8 {
   964  		x >>= 8
   965  		n += 8
   966  	}
   967  	if x >= 1<<4 {
   968  		x >>= 4
   969  		n += 4
   970  	}
   971  	if x >= 1<<2 {
   972  		x >>= 2
   973  		n += 2
   974  	}
   975  	if x >= 1<<1 {
   976  		x >>= 1
   977  		n += 1
   978  	}
   979  	return n
   980  }
   981  
   982  func autoclass(l int64) int {
   983  	if l < 0 {
   984  		if l >= -256 {
   985  			return C_NSAUTO
   986  		}
   987  		if l >= -512 && (l&7) == 0 {
   988  			return C_NPAUTO
   989  		}
   990  		return C_LAUTO
   991  	}
   992  
   993  	if l <= 255 {
   994  		return C_PSAUTO
   995  	}
   996  	if l <= 504 && (l&7) == 0 {
   997  		return C_PPAUTO
   998  	}
   999  	if l <= 4095 {
  1000  		return C_UAUTO4K
  1001  	}
  1002  	if l <= 8190 && (l&1) == 0 {
  1003  		return C_UAUTO8K
  1004  	}
  1005  	if l <= 16380 && (l&3) == 0 {
  1006  		return C_UAUTO16K
  1007  	}
  1008  	if l <= 32760 && (l&7) == 0 {
  1009  		return C_UAUTO32K
  1010  	}
  1011  	if l <= 65520 && (l&0xF) == 0 {
  1012  		return C_UAUTO64K
  1013  	}
  1014  	return C_LAUTO
  1015  }
  1016  
  1017  func oregclass(l int64) int {
  1018  	if l == 0 {
  1019  		return C_ZOREG
  1020  	}
  1021  	return autoclass(l) - C_NPAUTO + C_NPOREG
  1022  }
  1023  
  1024  /*
  1025   * given an offset v and a class c (see above)
  1026   * return the offset value to use in the instruction,
  1027   * scaled if necessary
  1028   */
  1029  func (c *ctxt7) offsetshift(p *obj.Prog, v int64, cls int) int64 {
  1030  	s := 0
  1031  	if cls >= C_SEXT1 && cls <= C_SEXT16 {
  1032  		s = cls - C_SEXT1
  1033  	} else if cls >= C_UAUTO4K && cls <= C_UAUTO64K {
  1034  		s = cls - C_UAUTO4K
  1035  	} else if cls >= C_UOREG4K && cls <= C_UOREG64K {
  1036  		s = cls - C_UOREG4K
  1037  	}
  1038  	vs := v >> uint(s)
  1039  	if vs<<uint(s) != v {
  1040  		c.ctxt.Diag("odd offset: %d\n%v", v, p)
  1041  	}
  1042  	return vs
  1043  }
  1044  
  1045  /*
  1046   * if v contains a single 16-bit value aligned
  1047   * on a 16-bit field, and thus suitable for movk/movn,
  1048   * return the field index 0 to 3; otherwise return -1
  1049   */
  1050  func movcon(v int64) int {
  1051  	for s := 0; s < 64; s += 16 {
  1052  		if (uint64(v) &^ (uint64(0xFFFF) << uint(s))) == 0 {
  1053  			return s / 16
  1054  		}
  1055  	}
  1056  	return -1
  1057  }
  1058  
  1059  func rclass(r int16) int {
  1060  	switch {
  1061  	case REG_R0 <= r && r <= REG_R30: // not 31
  1062  		return C_REG
  1063  	case r == REGZERO:
  1064  		return C_ZCON
  1065  	case REG_F0 <= r && r <= REG_F31:
  1066  		return C_FREG
  1067  	case REG_V0 <= r && r <= REG_V31:
  1068  		return C_VREG
  1069  	case COND_EQ <= r && r <= COND_NV:
  1070  		return C_COND
  1071  	case r == REGSP:
  1072  		return C_RSP
  1073  	case r&REG_EXT != 0:
  1074  		return C_EXTREG
  1075  	case r >= REG_SPECIAL:
  1076  		return C_SPR
  1077  	}
  1078  	return C_GOK
  1079  }
  1080  
  1081  func (c *ctxt7) aclass(a *obj.Addr) int {
  1082  	switch a.Type {
  1083  	case obj.TYPE_NONE:
  1084  		return C_NONE
  1085  
  1086  	case obj.TYPE_REG:
  1087  		return rclass(a.Reg)
  1088  
  1089  	case obj.TYPE_REGREG:
  1090  		return C_PAIR
  1091  
  1092  	case obj.TYPE_SHIFT:
  1093  		return C_SHIFT
  1094  
  1095  	case obj.TYPE_MEM:
  1096  		switch a.Name {
  1097  		case obj.NAME_EXTERN, obj.NAME_STATIC:
  1098  			if a.Sym == nil {
  1099  				break
  1100  			}
  1101  			c.instoffset = a.Offset
  1102  			if a.Sym != nil { // use relocation
  1103  				if a.Sym.Type == obj.STLSBSS {
  1104  					if c.ctxt.Flag_shared {
  1105  						return C_TLS_IE
  1106  					} else {
  1107  						return C_TLS_LE
  1108  					}
  1109  				}
  1110  				return C_ADDR
  1111  			}
  1112  			return C_LEXT
  1113  
  1114  		case obj.NAME_GOTREF:
  1115  			return C_GOTADDR
  1116  
  1117  		case obj.NAME_AUTO:
  1118  			c.instoffset = int64(c.autosize) + a.Offset
  1119  			return autoclass(c.instoffset)
  1120  
  1121  		case obj.NAME_PARAM:
  1122  			c.instoffset = int64(c.autosize) + a.Offset + 8
  1123  			return autoclass(c.instoffset)
  1124  
  1125  		case obj.NAME_NONE:
  1126  			c.instoffset = a.Offset
  1127  			return oregclass(c.instoffset)
  1128  		}
  1129  		return C_GOK
  1130  
  1131  	case obj.TYPE_FCONST:
  1132  		return C_FCON
  1133  
  1134  	case obj.TYPE_TEXTSIZE:
  1135  		return C_TEXTSIZE
  1136  
  1137  	case obj.TYPE_CONST, obj.TYPE_ADDR:
  1138  		switch a.Name {
  1139  		case obj.NAME_NONE:
  1140  			c.instoffset = a.Offset
  1141  			if a.Reg != 0 && a.Reg != REGZERO {
  1142  				goto aconsize
  1143  			}
  1144  			v := c.instoffset
  1145  			if v == 0 {
  1146  				return C_ZCON
  1147  			}
  1148  			if isaddcon(v) {
  1149  				if v <= 0xFFF {
  1150  					if isbitcon(uint64(v)) {
  1151  						return C_ABCON0
  1152  					}
  1153  					return C_ADDCON0
  1154  				}
  1155  				if isbitcon(uint64(v)) {
  1156  					return C_ABCON
  1157  				}
  1158  				return C_ADDCON
  1159  			}
  1160  
  1161  			t := movcon(v)
  1162  			if t >= 0 {
  1163  				if isbitcon(uint64(v)) {
  1164  					return C_MBCON
  1165  				}
  1166  				return C_MOVCON
  1167  			}
  1168  
  1169  			t = movcon(^v)
  1170  			if t >= 0 {
  1171  				if isbitcon(uint64(v)) {
  1172  					return C_MBCON
  1173  				}
  1174  				return C_MOVCON
  1175  			}
  1176  
  1177  			if isbitcon(uint64(v)) {
  1178  				return C_BITCON
  1179  			}
  1180  
  1181  			if uint64(v) == uint64(uint32(v)) || v == int64(int32(v)) {
  1182  				return C_LCON
  1183  			}
  1184  			return C_VCON
  1185  
  1186  		case obj.NAME_EXTERN, obj.NAME_STATIC:
  1187  			if a.Sym == nil {
  1188  				break
  1189  			}
  1190  			if a.Sym.Type == obj.STLSBSS {
  1191  				c.ctxt.Diag("taking address of TLS variable is not supported")
  1192  			}
  1193  			c.instoffset = a.Offset
  1194  			return C_VCONADDR
  1195  
  1196  		case obj.NAME_AUTO:
  1197  			c.instoffset = int64(c.autosize) + a.Offset
  1198  			goto aconsize
  1199  
  1200  		case obj.NAME_PARAM:
  1201  			c.instoffset = int64(c.autosize) + a.Offset + 8
  1202  			goto aconsize
  1203  		}
  1204  		return C_GOK
  1205  
  1206  	aconsize:
  1207  		if isaddcon(c.instoffset) {
  1208  			return C_AACON
  1209  		}
  1210  		return C_LACON
  1211  
  1212  	case obj.TYPE_BRANCH:
  1213  		return C_SBRA
  1214  	}
  1215  
  1216  	return C_GOK
  1217  }
  1218  
  1219  func oclass(a *obj.Addr) int {
  1220  	return int(a.Class) - 1
  1221  }
  1222  
  1223  func (c *ctxt7) oplook(p *obj.Prog) *Optab {
  1224  	a1 := int(p.Optab)
  1225  	if a1 != 0 {
  1226  		return &optab[a1-1]
  1227  	}
  1228  	a1 = int(p.From.Class)
  1229  	if a1 == 0 {
  1230  		a1 = c.aclass(&p.From) + 1
  1231  		p.From.Class = int8(a1)
  1232  	}
  1233  
  1234  	a1--
  1235  	a3 := int(p.To.Class)
  1236  	if a3 == 0 {
  1237  		a3 = c.aclass(&p.To) + 1
  1238  		p.To.Class = int8(a3)
  1239  	}
  1240  
  1241  	a3--
  1242  	a2 := C_NONE
  1243  	if p.Reg != 0 {
  1244  		a2 = rclass(p.Reg)
  1245  	}
  1246  
  1247  	if false {
  1248  		fmt.Printf("oplook %v %d %d %d\n", p.As, a1, a2, a3)
  1249  		fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type)
  1250  	}
  1251  
  1252  	ops := oprange[p.As&obj.AMask]
  1253  	c1 := &xcmp[a1]
  1254  	c2 := &xcmp[a2]
  1255  	c3 := &xcmp[a3]
  1256  	c4 := &xcmp[p.Scond>>5]
  1257  	for i := range ops {
  1258  		op := &ops[i]
  1259  		if (int(op.a2) == a2 || c2[op.a2]) && c4[op.scond>>5] && c1[op.a1] && c3[op.a3] {
  1260  			p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
  1261  			return op
  1262  		}
  1263  	}
  1264  
  1265  	c.ctxt.Diag("illegal combination %v %v %v %v, %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), p.From.Type, p.To.Type)
  1266  	if ops == nil {
  1267  		ops = optab
  1268  	}
  1269  	return &ops[0]
  1270  }
  1271  
  1272  func cmp(a int, b int) bool {
  1273  	if a == b {
  1274  		return true
  1275  	}
  1276  	switch a {
  1277  	case C_RSP:
  1278  		if b == C_REG {
  1279  			return true
  1280  		}
  1281  
  1282  	case C_REG:
  1283  		if b == C_ZCON {
  1284  			return true
  1285  		}
  1286  
  1287  	case C_ADDCON0:
  1288  		if b == C_ZCON || b == C_ABCON0 {
  1289  			return true
  1290  		}
  1291  
  1292  	case C_ADDCON:
  1293  		if b == C_ZCON || b == C_ABCON0 || b == C_ADDCON0 || b == C_ABCON {
  1294  			return true
  1295  		}
  1296  
  1297  	case C_BITCON:
  1298  		if b == C_ABCON0 || b == C_ABCON || b == C_MBCON {
  1299  			return true
  1300  		}
  1301  
  1302  	case C_MOVCON:
  1303  		if b == C_MBCON || b == C_ZCON || b == C_ADDCON0 {
  1304  			return true
  1305  		}
  1306  
  1307  	case C_LCON:
  1308  		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 {
  1309  			return true
  1310  		}
  1311  
  1312  	case C_VCON:
  1313  		return cmp(C_LCON, b)
  1314  
  1315  	case C_LACON:
  1316  		if b == C_AACON {
  1317  			return true
  1318  		}
  1319  
  1320  	case C_SEXT2:
  1321  		if b == C_SEXT1 {
  1322  			return true
  1323  		}
  1324  
  1325  	case C_SEXT4:
  1326  		if b == C_SEXT1 || b == C_SEXT2 {
  1327  			return true
  1328  		}
  1329  
  1330  	case C_SEXT8:
  1331  		if b >= C_SEXT1 && b <= C_SEXT4 {
  1332  			return true
  1333  		}
  1334  
  1335  	case C_SEXT16:
  1336  		if b >= C_SEXT1 && b <= C_SEXT8 {
  1337  			return true
  1338  		}
  1339  
  1340  	case C_LEXT:
  1341  		if b >= C_SEXT1 && b <= C_SEXT16 {
  1342  			return true
  1343  		}
  1344  
  1345  	case C_PPAUTO:
  1346  		if b == C_PSAUTO {
  1347  			return true
  1348  		}
  1349  
  1350  	case C_UAUTO4K:
  1351  		if b == C_PSAUTO || b == C_PPAUTO {
  1352  			return true
  1353  		}
  1354  
  1355  	case C_UAUTO8K:
  1356  		return cmp(C_UAUTO4K, b)
  1357  
  1358  	case C_UAUTO16K:
  1359  		return cmp(C_UAUTO8K, b)
  1360  
  1361  	case C_UAUTO32K:
  1362  		return cmp(C_UAUTO16K, b)
  1363  
  1364  	case C_UAUTO64K:
  1365  		return cmp(C_UAUTO32K, b)
  1366  
  1367  	case C_NPAUTO:
  1368  		return cmp(C_NSAUTO, b)
  1369  
  1370  	case C_LAUTO:
  1371  		return cmp(C_NPAUTO, b) || cmp(C_UAUTO64K, b)
  1372  
  1373  	case C_PSOREG:
  1374  		if b == C_ZOREG {
  1375  			return true
  1376  		}
  1377  
  1378  	case C_PPOREG:
  1379  		if b == C_ZOREG || b == C_PSOREG {
  1380  			return true
  1381  		}
  1382  
  1383  	case C_UOREG4K:
  1384  		if b == C_ZOREG || b == C_PSAUTO || b == C_PSOREG || b == C_PPAUTO || b == C_PPOREG {
  1385  			return true
  1386  		}
  1387  
  1388  	case C_UOREG8K:
  1389  		return cmp(C_UOREG4K, b)
  1390  
  1391  	case C_UOREG16K:
  1392  		return cmp(C_UOREG8K, b)
  1393  
  1394  	case C_UOREG32K:
  1395  		return cmp(C_UOREG16K, b)
  1396  
  1397  	case C_UOREG64K:
  1398  		return cmp(C_UOREG32K, b)
  1399  
  1400  	case C_NPOREG:
  1401  		return cmp(C_NSOREG, b)
  1402  
  1403  	case C_LOREG:
  1404  		return cmp(C_NPOREG, b) || cmp(C_UOREG64K, b)
  1405  
  1406  	case C_LBRA:
  1407  		if b == C_SBRA {
  1408  			return true
  1409  		}
  1410  	}
  1411  
  1412  	return false
  1413  }
  1414  
  1415  type ocmp []Optab
  1416  
  1417  func (x ocmp) Len() int {
  1418  	return len(x)
  1419  }
  1420  
  1421  func (x ocmp) Swap(i, j int) {
  1422  	x[i], x[j] = x[j], x[i]
  1423  }
  1424  
  1425  func (x ocmp) Less(i, j int) bool {
  1426  	p1 := &x[i]
  1427  	p2 := &x[j]
  1428  	if p1.as != p2.as {
  1429  		return p1.as < p2.as
  1430  	}
  1431  	if p1.a1 != p2.a1 {
  1432  		return p1.a1 < p2.a1
  1433  	}
  1434  	if p1.a2 != p2.a2 {
  1435  		return p1.a2 < p2.a2
  1436  	}
  1437  	if p1.a3 != p2.a3 {
  1438  		return p1.a3 < p2.a3
  1439  	}
  1440  	if p1.scond != p2.scond {
  1441  		return p1.scond < p2.scond
  1442  	}
  1443  	return false
  1444  }
  1445  
  1446  func oprangeset(a obj.As, t []Optab) {
  1447  	oprange[a&obj.AMask] = t
  1448  }
  1449  
  1450  func buildop(ctxt *obj.Link) {
  1451  	if oprange[AAND&obj.AMask] != nil {
  1452  		// Already initialized; stop now.
  1453  		// This happens in the cmd/asm tests,
  1454  		// each of which re-initializes the arch.
  1455  		return
  1456  	}
  1457  
  1458  	var n int
  1459  	for i := 0; i < C_GOK; i++ {
  1460  		for n = 0; n < C_GOK; n++ {
  1461  			if cmp(n, i) {
  1462  				xcmp[i][n] = true
  1463  			}
  1464  		}
  1465  	}
  1466  	for n = 0; optab[n].as != obj.AXXX; n++ {
  1467  	}
  1468  	sort.Sort(ocmp(optab[:n]))
  1469  	for i := 0; i < n; i++ {
  1470  		r := optab[i].as
  1471  		start := i
  1472  		for optab[i].as == r {
  1473  			i++
  1474  		}
  1475  		t := optab[start:i]
  1476  		i--
  1477  		oprangeset(r, t)
  1478  		switch r {
  1479  		default:
  1480  			ctxt.Diag("unknown op in build: %v", r)
  1481  			log.Fatalf("bad code")
  1482  
  1483  		case AADD:
  1484  			oprangeset(AADDS, t)
  1485  			oprangeset(ASUB, t)
  1486  			oprangeset(ASUBS, t)
  1487  			oprangeset(AADDW, t)
  1488  			oprangeset(AADDSW, t)
  1489  			oprangeset(ASUBW, t)
  1490  			oprangeset(ASUBSW, t)
  1491  
  1492  		case AAND: /* logical immediate, logical shifted register */
  1493  			oprangeset(AANDS, t)
  1494  
  1495  			oprangeset(AANDSW, t)
  1496  			oprangeset(AANDW, t)
  1497  			oprangeset(AEOR, t)
  1498  			oprangeset(AEORW, t)
  1499  			oprangeset(AORR, t)
  1500  			oprangeset(AORRW, t)
  1501  
  1502  		case ABIC: /* only logical shifted register */
  1503  			oprangeset(ABICS, t)
  1504  
  1505  			oprangeset(ABICSW, t)
  1506  			oprangeset(ABICW, t)
  1507  			oprangeset(AEON, t)
  1508  			oprangeset(AEONW, t)
  1509  			oprangeset(AORN, t)
  1510  			oprangeset(AORNW, t)
  1511  
  1512  		case ANEG:
  1513  			oprangeset(ANEGS, t)
  1514  			oprangeset(ANEGSW, t)
  1515  			oprangeset(ANEGW, t)
  1516  
  1517  		case AADC: /* rn=Rd */
  1518  			oprangeset(AADCW, t)
  1519  
  1520  			oprangeset(AADCS, t)
  1521  			oprangeset(AADCSW, t)
  1522  			oprangeset(ASBC, t)
  1523  			oprangeset(ASBCW, t)
  1524  			oprangeset(ASBCS, t)
  1525  			oprangeset(ASBCSW, t)
  1526  
  1527  		case ANGC: /* rn=REGZERO */
  1528  			oprangeset(ANGCW, t)
  1529  
  1530  			oprangeset(ANGCS, t)
  1531  			oprangeset(ANGCSW, t)
  1532  
  1533  		case ACMP:
  1534  			oprangeset(ACMPW, t)
  1535  			oprangeset(ACMN, t)
  1536  			oprangeset(ACMNW, t)
  1537  
  1538  		case ATST:
  1539  			oprangeset(ATSTW, t)
  1540  
  1541  			/* register/register, and shifted */
  1542  		case AMVN:
  1543  			oprangeset(AMVNW, t)
  1544  
  1545  		case AMOVK:
  1546  			oprangeset(AMOVKW, t)
  1547  			oprangeset(AMOVN, t)
  1548  			oprangeset(AMOVNW, t)
  1549  			oprangeset(AMOVZ, t)
  1550  			oprangeset(AMOVZW, t)
  1551  
  1552  		case ABEQ:
  1553  			oprangeset(ABNE, t)
  1554  			oprangeset(ABCS, t)
  1555  			oprangeset(ABHS, t)
  1556  			oprangeset(ABCC, t)
  1557  			oprangeset(ABLO, t)
  1558  			oprangeset(ABMI, t)
  1559  			oprangeset(ABPL, t)
  1560  			oprangeset(ABVS, t)
  1561  			oprangeset(ABVC, t)
  1562  			oprangeset(ABHI, t)
  1563  			oprangeset(ABLS, t)
  1564  			oprangeset(ABGE, t)
  1565  			oprangeset(ABLT, t)
  1566  			oprangeset(ABGT, t)
  1567  			oprangeset(ABLE, t)
  1568  
  1569  		case ALSL:
  1570  			oprangeset(ALSLW, t)
  1571  			oprangeset(ALSR, t)
  1572  			oprangeset(ALSRW, t)
  1573  			oprangeset(AASR, t)
  1574  			oprangeset(AASRW, t)
  1575  			oprangeset(AROR, t)
  1576  			oprangeset(ARORW, t)
  1577  
  1578  		case ACLS:
  1579  			oprangeset(ACLSW, t)
  1580  			oprangeset(ACLZ, t)
  1581  			oprangeset(ACLZW, t)
  1582  			oprangeset(ARBIT, t)
  1583  			oprangeset(ARBITW, t)
  1584  			oprangeset(AREV, t)
  1585  			oprangeset(AREVW, t)
  1586  			oprangeset(AREV16, t)
  1587  			oprangeset(AREV16W, t)
  1588  			oprangeset(AREV32, t)
  1589  
  1590  		case ASDIV:
  1591  			oprangeset(ASDIVW, t)
  1592  			oprangeset(AUDIV, t)
  1593  			oprangeset(AUDIVW, t)
  1594  			oprangeset(ACRC32B, t)
  1595  			oprangeset(ACRC32CB, t)
  1596  			oprangeset(ACRC32CH, t)
  1597  			oprangeset(ACRC32CW, t)
  1598  			oprangeset(ACRC32CX, t)
  1599  			oprangeset(ACRC32H, t)
  1600  			oprangeset(ACRC32W, t)
  1601  			oprangeset(ACRC32X, t)
  1602  
  1603  		case AMADD:
  1604  			oprangeset(AMADDW, t)
  1605  			oprangeset(AMSUB, t)
  1606  			oprangeset(AMSUBW, t)
  1607  			oprangeset(ASMADDL, t)
  1608  			oprangeset(ASMSUBL, t)
  1609  			oprangeset(AUMADDL, t)
  1610  			oprangeset(AUMSUBL, t)
  1611  
  1612  		case AREM:
  1613  			oprangeset(AREMW, t)
  1614  			oprangeset(AUREM, t)
  1615  			oprangeset(AUREMW, t)
  1616  
  1617  		case AMUL:
  1618  			oprangeset(AMULW, t)
  1619  			oprangeset(AMNEG, t)
  1620  			oprangeset(AMNEGW, t)
  1621  			oprangeset(ASMNEGL, t)
  1622  			oprangeset(ASMULL, t)
  1623  			oprangeset(ASMULH, t)
  1624  			oprangeset(AUMNEGL, t)
  1625  			oprangeset(AUMULH, t)
  1626  			oprangeset(AUMULL, t)
  1627  
  1628  		case AMOVB:
  1629  			oprangeset(AMOVBU, t)
  1630  
  1631  		case AMOVH:
  1632  			oprangeset(AMOVHU, t)
  1633  
  1634  		case AMOVW:
  1635  			oprangeset(AMOVWU, t)
  1636  
  1637  		case ABFM:
  1638  			oprangeset(ABFMW, t)
  1639  			oprangeset(ASBFM, t)
  1640  			oprangeset(ASBFMW, t)
  1641  			oprangeset(AUBFM, t)
  1642  			oprangeset(AUBFMW, t)
  1643  
  1644  		case ABFI:
  1645  			oprangeset(ABFIW, t)
  1646  			oprangeset(ABFXIL, t)
  1647  			oprangeset(ABFXILW, t)
  1648  			oprangeset(ASBFIZ, t)
  1649  			oprangeset(ASBFIZW, t)
  1650  			oprangeset(ASBFX, t)
  1651  			oprangeset(ASBFXW, t)
  1652  			oprangeset(AUBFIZ, t)
  1653  			oprangeset(AUBFIZW, t)
  1654  			oprangeset(AUBFX, t)
  1655  			oprangeset(AUBFXW, t)
  1656  
  1657  		case AEXTR:
  1658  			oprangeset(AEXTRW, t)
  1659  
  1660  		case ASXTB:
  1661  			oprangeset(ASXTBW, t)
  1662  			oprangeset(ASXTH, t)
  1663  			oprangeset(ASXTHW, t)
  1664  			oprangeset(ASXTW, t)
  1665  			oprangeset(AUXTB, t)
  1666  			oprangeset(AUXTH, t)
  1667  			oprangeset(AUXTW, t)
  1668  			oprangeset(AUXTBW, t)
  1669  			oprangeset(AUXTHW, t)
  1670  
  1671  		case ACCMN:
  1672  			oprangeset(ACCMNW, t)
  1673  			oprangeset(ACCMP, t)
  1674  			oprangeset(ACCMPW, t)
  1675  
  1676  		case ACSEL:
  1677  			oprangeset(ACSELW, t)
  1678  			oprangeset(ACSINC, t)
  1679  			oprangeset(ACSINCW, t)
  1680  			oprangeset(ACSINV, t)
  1681  			oprangeset(ACSINVW, t)
  1682  			oprangeset(ACSNEG, t)
  1683  			oprangeset(ACSNEGW, t)
  1684  
  1685  			// aliases Rm=Rn, !cond
  1686  			oprangeset(ACINC, t)
  1687  
  1688  			oprangeset(ACINCW, t)
  1689  			oprangeset(ACINV, t)
  1690  			oprangeset(ACINVW, t)
  1691  			oprangeset(ACNEG, t)
  1692  			oprangeset(ACNEGW, t)
  1693  
  1694  			// aliases, Rm=Rn=REGZERO, !cond
  1695  		case ACSET:
  1696  			oprangeset(ACSETW, t)
  1697  
  1698  			oprangeset(ACSETM, t)
  1699  			oprangeset(ACSETMW, t)
  1700  
  1701  		case AMOVD,
  1702  			AMOVBU,
  1703  			AB,
  1704  			ABL,
  1705  			AWORD,
  1706  			ADWORD,
  1707  			obj.ARET,
  1708  			obj.ATEXT,
  1709  			ASTP,
  1710  			ALDP:
  1711  			break
  1712  
  1713  		case AERET:
  1714  			oprangeset(AWFE, t)
  1715  			oprangeset(AWFI, t)
  1716  			oprangeset(AYIELD, t)
  1717  			oprangeset(ASEV, t)
  1718  			oprangeset(ASEVL, t)
  1719  			oprangeset(ADRPS, t)
  1720  
  1721  		case ACBZ:
  1722  			oprangeset(ACBZW, t)
  1723  			oprangeset(ACBNZ, t)
  1724  			oprangeset(ACBNZW, t)
  1725  
  1726  		case ATBZ:
  1727  			oprangeset(ATBNZ, t)
  1728  
  1729  		case AADR, AADRP:
  1730  			break
  1731  
  1732  		case ACLREX:
  1733  			break
  1734  
  1735  		case ASVC:
  1736  			oprangeset(AHLT, t)
  1737  			oprangeset(AHVC, t)
  1738  			oprangeset(ASMC, t)
  1739  			oprangeset(ABRK, t)
  1740  			oprangeset(ADCPS1, t)
  1741  			oprangeset(ADCPS2, t)
  1742  			oprangeset(ADCPS3, t)
  1743  
  1744  		case AFADDS:
  1745  			oprangeset(AFADDD, t)
  1746  			oprangeset(AFSUBS, t)
  1747  			oprangeset(AFSUBD, t)
  1748  			oprangeset(AFMULS, t)
  1749  			oprangeset(AFMULD, t)
  1750  			oprangeset(AFNMULS, t)
  1751  			oprangeset(AFNMULD, t)
  1752  			oprangeset(AFDIVS, t)
  1753  			oprangeset(AFMAXD, t)
  1754  			oprangeset(AFMAXS, t)
  1755  			oprangeset(AFMIND, t)
  1756  			oprangeset(AFMINS, t)
  1757  			oprangeset(AFMAXNMD, t)
  1758  			oprangeset(AFMAXNMS, t)
  1759  			oprangeset(AFMINNMD, t)
  1760  			oprangeset(AFMINNMS, t)
  1761  			oprangeset(AFDIVD, t)
  1762  
  1763  		case AFCVTSD:
  1764  			oprangeset(AFCVTDS, t)
  1765  			oprangeset(AFABSD, t)
  1766  			oprangeset(AFABSS, t)
  1767  			oprangeset(AFNEGD, t)
  1768  			oprangeset(AFNEGS, t)
  1769  			oprangeset(AFSQRTD, t)
  1770  			oprangeset(AFSQRTS, t)
  1771  			oprangeset(AFRINTNS, t)
  1772  			oprangeset(AFRINTND, t)
  1773  			oprangeset(AFRINTPS, t)
  1774  			oprangeset(AFRINTPD, t)
  1775  			oprangeset(AFRINTMS, t)
  1776  			oprangeset(AFRINTMD, t)
  1777  			oprangeset(AFRINTZS, t)
  1778  			oprangeset(AFRINTZD, t)
  1779  			oprangeset(AFRINTAS, t)
  1780  			oprangeset(AFRINTAD, t)
  1781  			oprangeset(AFRINTXS, t)
  1782  			oprangeset(AFRINTXD, t)
  1783  			oprangeset(AFRINTIS, t)
  1784  			oprangeset(AFRINTID, t)
  1785  			oprangeset(AFCVTDH, t)
  1786  			oprangeset(AFCVTHS, t)
  1787  			oprangeset(AFCVTHD, t)
  1788  			oprangeset(AFCVTSH, t)
  1789  
  1790  		case AFCMPS:
  1791  			oprangeset(AFCMPD, t)
  1792  			oprangeset(AFCMPES, t)
  1793  			oprangeset(AFCMPED, t)
  1794  
  1795  		case AFCCMPS:
  1796  			oprangeset(AFCCMPD, t)
  1797  			oprangeset(AFCCMPES, t)
  1798  			oprangeset(AFCCMPED, t)
  1799  
  1800  		case AFCSELD:
  1801  			oprangeset(AFCSELS, t)
  1802  
  1803  		case AFMOVS, AFMOVD:
  1804  			break
  1805  
  1806  		case AFCVTZSD:
  1807  			oprangeset(AFCVTZSDW, t)
  1808  			oprangeset(AFCVTZSS, t)
  1809  			oprangeset(AFCVTZSSW, t)
  1810  			oprangeset(AFCVTZUD, t)
  1811  			oprangeset(AFCVTZUDW, t)
  1812  			oprangeset(AFCVTZUS, t)
  1813  			oprangeset(AFCVTZUSW, t)
  1814  
  1815  		case ASCVTFD:
  1816  			oprangeset(ASCVTFS, t)
  1817  			oprangeset(ASCVTFWD, t)
  1818  			oprangeset(ASCVTFWS, t)
  1819  			oprangeset(AUCVTFD, t)
  1820  			oprangeset(AUCVTFS, t)
  1821  			oprangeset(AUCVTFWD, t)
  1822  			oprangeset(AUCVTFWS, t)
  1823  
  1824  		case ASYS:
  1825  			oprangeset(AAT, t)
  1826  			oprangeset(ADC, t)
  1827  			oprangeset(AIC, t)
  1828  			oprangeset(ATLBI, t)
  1829  
  1830  		case ASYSL, AHINT:
  1831  			break
  1832  
  1833  		case ADMB:
  1834  			oprangeset(ADSB, t)
  1835  			oprangeset(AISB, t)
  1836  
  1837  		case AMRS, AMSR:
  1838  			break
  1839  
  1840  		case ALDAR:
  1841  			oprangeset(ALDARW, t)
  1842  			fallthrough
  1843  
  1844  		case ALDXR:
  1845  			oprangeset(ALDXRB, t)
  1846  			oprangeset(ALDXRH, t)
  1847  			oprangeset(ALDXRW, t)
  1848  
  1849  		case ALDAXR:
  1850  			oprangeset(ALDAXRB, t)
  1851  			oprangeset(ALDAXRH, t)
  1852  			oprangeset(ALDAXRW, t)
  1853  
  1854  		case ALDXP:
  1855  			oprangeset(ALDXPW, t)
  1856  
  1857  		case ASTLR:
  1858  			oprangeset(ASTLRW, t)
  1859  
  1860  		case ASTXR:
  1861  			oprangeset(ASTXRB, t)
  1862  			oprangeset(ASTXRH, t)
  1863  			oprangeset(ASTXRW, t)
  1864  
  1865  		case ASTLXR:
  1866  			oprangeset(ASTLXRB, t)
  1867  			oprangeset(ASTLXRH, t)
  1868  			oprangeset(ASTLXRW, t)
  1869  
  1870  		case ASTXP:
  1871  			oprangeset(ASTXPW, t)
  1872  
  1873  		case AAESD:
  1874  			oprangeset(AAESE, t)
  1875  			oprangeset(AAESMC, t)
  1876  			oprangeset(AAESIMC, t)
  1877  			oprangeset(ASHA1H, t)
  1878  			oprangeset(ASHA1SU1, t)
  1879  			oprangeset(ASHA256SU0, t)
  1880  
  1881  		case ASHA1C:
  1882  			oprangeset(ASHA1P, t)
  1883  			oprangeset(ASHA1M, t)
  1884  			oprangeset(ASHA1SU0, t)
  1885  			oprangeset(ASHA256H, t)
  1886  			oprangeset(ASHA256H2, t)
  1887  			oprangeset(ASHA256SU1, t)
  1888  
  1889  		case obj.ANOP,
  1890  			obj.AUNDEF,
  1891  			obj.AFUNCDATA,
  1892  			obj.APCDATA,
  1893  			obj.ADUFFZERO,
  1894  			obj.ADUFFCOPY:
  1895  			break
  1896  		}
  1897  	}
  1898  }
  1899  
  1900  func (c *ctxt7) chipfloat7(e float64) int {
  1901  	ei := math.Float64bits(e)
  1902  	l := uint32(int32(ei))
  1903  	h := uint32(int32(ei >> 32))
  1904  
  1905  	if l != 0 || h&0xffff != 0 {
  1906  		return -1
  1907  	}
  1908  	h1 := h & 0x7fc00000
  1909  	if h1 != 0x40000000 && h1 != 0x3fc00000 {
  1910  		return -1
  1911  	}
  1912  	n := 0
  1913  
  1914  	// sign bit (a)
  1915  	if h&0x80000000 != 0 {
  1916  		n |= 1 << 7
  1917  	}
  1918  
  1919  	// exp sign bit (b)
  1920  	if h1 == 0x3fc00000 {
  1921  		n |= 1 << 6
  1922  	}
  1923  
  1924  	// rest of exp and mantissa (cd-efgh)
  1925  	n |= int((h >> 16) & 0x3f)
  1926  
  1927  	//print("match %.8lux %.8lux %d\n", l, h, n);
  1928  	return n
  1929  }
  1930  
  1931  /* form offset parameter to SYS; special register number */
  1932  func SYSARG5(op0 int, op1 int, Cn int, Cm int, op2 int) int {
  1933  	return op0<<19 | op1<<16 | Cn<<12 | Cm<<8 | op2<<5
  1934  }
  1935  
  1936  func SYSARG4(op1 int, Cn int, Cm int, op2 int) int {
  1937  	return SYSARG5(0, op1, Cn, Cm, op2)
  1938  }
  1939  
  1940  func (c *ctxt7) asmout(p *obj.Prog, o *Optab, out []uint32) {
  1941  	o1 := uint32(0)
  1942  	o2 := uint32(0)
  1943  	o3 := uint32(0)
  1944  	o4 := uint32(0)
  1945  	o5 := uint32(0)
  1946  	if false { /*debug['P']*/
  1947  		fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_)
  1948  	}
  1949  	switch o.type_ {
  1950  	default:
  1951  		c.ctxt.Diag("%v: unknown asm %d", p, o.type_)
  1952  
  1953  	case 0: /* pseudo ops */
  1954  		break
  1955  
  1956  	case 1: /* op Rm,[Rn],Rd; default Rn=Rd -> op Rm<<0,[Rn,]Rd (shifted register) */
  1957  		o1 = c.oprrr(p, p.As)
  1958  
  1959  		rf := int(p.From.Reg)
  1960  		rt := int(p.To.Reg)
  1961  		r := int(p.Reg)
  1962  		if p.To.Type == obj.TYPE_NONE {
  1963  			rt = REGZERO
  1964  		}
  1965  		if r == 0 {
  1966  			r = rt
  1967  		}
  1968  		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
  1969  
  1970  	case 2: /* add/sub $(uimm12|uimm24)[,R],R; cmp $(uimm12|uimm24),R */
  1971  		o1 = c.opirr(p, p.As)
  1972  
  1973  		rt := int(p.To.Reg)
  1974  		if p.To.Type == obj.TYPE_NONE {
  1975  			if (o1 & Sbit) == 0 {
  1976  				c.ctxt.Diag("ineffective ZR destination\n%v", p)
  1977  			}
  1978  			rt = REGZERO
  1979  		}
  1980  
  1981  		r := int(p.Reg)
  1982  		if r == 0 {
  1983  			r = rt
  1984  		}
  1985  		v := int32(c.regoff(&p.From))
  1986  		o1 = c.oaddi(p, int32(o1), v, r, rt)
  1987  
  1988  	case 3: /* op R<<n[,R],R (shifted register) */
  1989  		o1 = c.oprrr(p, p.As)
  1990  
  1991  		o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
  1992  		rt := int(p.To.Reg)
  1993  		if p.To.Type == obj.TYPE_NONE {
  1994  			rt = REGZERO
  1995  		}
  1996  		r := int(p.Reg)
  1997  		if p.As == AMVN || p.As == AMVNW {
  1998  			r = REGZERO
  1999  		} else if r == 0 {
  2000  			r = rt
  2001  		}
  2002  		o1 |= (uint32(r&31) << 5) | uint32(rt&31)
  2003  
  2004  	case 4: /* mov $addcon, R; mov $recon, R; mov $racon, R */
  2005  		o1 = c.opirr(p, p.As)
  2006  
  2007  		rt := int(p.To.Reg)
  2008  		r := int(o.param)
  2009  		if r == 0 {
  2010  			r = REGZERO
  2011  		} else if r == REGFROM {
  2012  			r = int(p.From.Reg)
  2013  		}
  2014  		if r == 0 {
  2015  			r = REGSP
  2016  		}
  2017  		v := int32(c.regoff(&p.From))
  2018  		if (v & 0xFFF000) != 0 {
  2019  			v >>= 12
  2020  			o1 |= 1 << 22 /* shift, by 12 */
  2021  		}
  2022  
  2023  		o1 |= ((uint32(v) & 0xFFF) << 10) | (uint32(r&31) << 5) | uint32(rt&31)
  2024  
  2025  	case 5: /* b s; bl s */
  2026  		o1 = c.opbra(p, p.As)
  2027  
  2028  		if p.To.Sym == nil {
  2029  			o1 |= uint32(c.brdist(p, 0, 26, 2))
  2030  			break
  2031  		}
  2032  
  2033  		rel := obj.Addrel(c.cursym)
  2034  		rel.Off = int32(c.pc)
  2035  		rel.Siz = 4
  2036  		rel.Sym = p.To.Sym
  2037  		rel.Add = p.To.Offset
  2038  		rel.Type = obj.R_CALLARM64
  2039  
  2040  	case 6: /* b ,O(R); bl ,O(R) */
  2041  		o1 = c.opbrr(p, p.As)
  2042  
  2043  		o1 |= uint32(p.To.Reg&31) << 5
  2044  		rel := obj.Addrel(c.cursym)
  2045  		rel.Off = int32(c.pc)
  2046  		rel.Siz = 0
  2047  		rel.Type = obj.R_CALLIND
  2048  
  2049  	case 7: /* beq s */
  2050  		o1 = c.opbra(p, p.As)
  2051  
  2052  		o1 |= uint32(c.brdist(p, 0, 19, 2) << 5)
  2053  
  2054  	case 8: /* lsl $c,[R],R -> ubfm $(W-1)-c,$(-c MOD (W-1)),Rn,Rd */
  2055  		rt := int(p.To.Reg)
  2056  
  2057  		rf := int(p.Reg)
  2058  		if rf == 0 {
  2059  			rf = rt
  2060  		}
  2061  		v := int32(p.From.Offset)
  2062  		switch p.As {
  2063  		case AASR:
  2064  			o1 = c.opbfm(p, ASBFM, int(v), 63, rf, rt)
  2065  
  2066  		case AASRW:
  2067  			o1 = c.opbfm(p, ASBFMW, int(v), 31, rf, rt)
  2068  
  2069  		case ALSL:
  2070  			o1 = c.opbfm(p, AUBFM, int((64-v)&63), int(63-v), rf, rt)
  2071  
  2072  		case ALSLW:
  2073  			o1 = c.opbfm(p, AUBFMW, int((32-v)&31), int(31-v), rf, rt)
  2074  
  2075  		case ALSR:
  2076  			o1 = c.opbfm(p, AUBFM, int(v), 63, rf, rt)
  2077  
  2078  		case ALSRW:
  2079  			o1 = c.opbfm(p, AUBFMW, int(v), 31, rf, rt)
  2080  
  2081  		case AROR:
  2082  			o1 = c.opextr(p, AEXTR, v, rf, rf, rt)
  2083  
  2084  		case ARORW:
  2085  			o1 = c.opextr(p, AEXTRW, v, rf, rf, rt)
  2086  
  2087  		default:
  2088  			c.ctxt.Diag("bad shift $con\n%v", p)
  2089  			break
  2090  		}
  2091  
  2092  	case 9: /* lsl Rm,[Rn],Rd -> lslv Rm, Rn, Rd */
  2093  		o1 = c.oprrr(p, p.As)
  2094  
  2095  		r := int(p.Reg)
  2096  		if r == 0 {
  2097  			r = int(p.To.Reg)
  2098  		}
  2099  		o1 |= (uint32(p.From.Reg&31) << 16) | (uint32(r&31) << 5) | uint32(p.To.Reg&31)
  2100  
  2101  	case 10: /* brk/hvc/.../svc [$con] */
  2102  		o1 = c.opimm(p, p.As)
  2103  
  2104  		if p.To.Type != obj.TYPE_NONE {
  2105  			o1 |= uint32((p.To.Offset & 0xffff) << 5)
  2106  		}
  2107  
  2108  	case 11: /* dword */
  2109  		c.aclass(&p.To)
  2110  
  2111  		o1 = uint32(c.instoffset)
  2112  		o2 = uint32(c.instoffset >> 32)
  2113  		if p.To.Sym != nil {
  2114  			rel := obj.Addrel(c.cursym)
  2115  			rel.Off = int32(c.pc)
  2116  			rel.Siz = 8
  2117  			rel.Sym = p.To.Sym
  2118  			rel.Add = p.To.Offset
  2119  			rel.Type = obj.R_ADDR
  2120  			o2 = 0
  2121  			o1 = o2
  2122  		}
  2123  
  2124  	case 12: /* movT $vcon, reg */
  2125  		o1 = c.omovlit(p.As, p, &p.From, int(p.To.Reg))
  2126  
  2127  	case 13: /* addop $vcon, [R], R (64 bit literal); cmp $lcon,R -> addop $lcon,R, ZR */
  2128  		o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
  2129  
  2130  		if !(o1 != 0) {
  2131  			break
  2132  		}
  2133  		rt := int(p.To.Reg)
  2134  		if p.To.Type == obj.TYPE_NONE {
  2135  			rt = REGZERO
  2136  		}
  2137  		r := int(p.Reg)
  2138  		if r == 0 {
  2139  			r = rt
  2140  		}
  2141  		if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) {
  2142  			o2 = c.opxrrr(p, p.As)
  2143  			o2 |= REGTMP & 31 << 16
  2144  			o2 |= LSL0_64
  2145  		} else {
  2146  			o2 = c.oprrr(p, p.As)
  2147  			o2 |= REGTMP & 31 << 16 /* shift is 0 */
  2148  		}
  2149  
  2150  		o2 |= uint32(r&31) << 5
  2151  		o2 |= uint32(rt & 31)
  2152  
  2153  	case 14: /* word */
  2154  		if c.aclass(&p.To) == C_ADDR {
  2155  			c.ctxt.Diag("address constant needs DWORD\n%v", p)
  2156  		}
  2157  		o1 = uint32(c.instoffset)
  2158  		if p.To.Sym != nil {
  2159  			// This case happens with words generated
  2160  			// in the PC stream as part of the literal pool.
  2161  			rel := obj.Addrel(c.cursym)
  2162  
  2163  			rel.Off = int32(c.pc)
  2164  			rel.Siz = 4
  2165  			rel.Sym = p.To.Sym
  2166  			rel.Add = p.To.Offset
  2167  			rel.Type = obj.R_ADDR
  2168  			o1 = 0
  2169  		}
  2170  
  2171  	case 15: /* mul/mneg/umulh/umull r,[r,]r; madd/msub Rm,Rn,Ra,Rd */
  2172  		o1 = c.oprrr(p, p.As)
  2173  
  2174  		rf := int(p.From.Reg)
  2175  		rt := int(p.To.Reg)
  2176  		var r int
  2177  		var ra int
  2178  		if p.From3Type() == obj.TYPE_REG {
  2179  			r = int(p.From3.Reg)
  2180  			ra = int(p.Reg)
  2181  			if ra == 0 {
  2182  				ra = REGZERO
  2183  			}
  2184  		} else {
  2185  			r = int(p.Reg)
  2186  			if r == 0 {
  2187  				r = rt
  2188  			}
  2189  			ra = REGZERO
  2190  		}
  2191  
  2192  		o1 |= (uint32(rf&31) << 16) | (uint32(ra&31) << 10) | (uint32(r&31) << 5) | uint32(rt&31)
  2193  
  2194  	case 16: /* XremY R[,R],R -> XdivY; XmsubY */
  2195  		o1 = c.oprrr(p, p.As)
  2196  
  2197  		rf := int(p.From.Reg)
  2198  		rt := int(p.To.Reg)
  2199  		r := int(p.Reg)
  2200  		if r == 0 {
  2201  			r = rt
  2202  		}
  2203  		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | REGTMP&31
  2204  		o2 = c.oprrr(p, AMSUBW)
  2205  		o2 |= o1 & (1 << 31) /* same size */
  2206  		o2 |= (uint32(rf&31) << 16) | (uint32(r&31) << 10) | (REGTMP & 31 << 5) | uint32(rt&31)
  2207  
  2208  	case 17: /* op Rm,[Rn],Rd; default Rn=ZR */
  2209  		o1 = c.oprrr(p, p.As)
  2210  
  2211  		rf := int(p.From.Reg)
  2212  		rt := int(p.To.Reg)
  2213  		r := int(p.Reg)
  2214  		if p.To.Type == obj.TYPE_NONE {
  2215  			rt = REGZERO
  2216  		}
  2217  		if r == 0 {
  2218  			r = REGZERO
  2219  		}
  2220  		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
  2221  
  2222  	case 18: /* csel cond,Rn,Rm,Rd; cinc/cinv/cneg cond,Rn,Rd; cset cond,Rd */
  2223  		o1 = c.oprrr(p, p.As)
  2224  
  2225  		cond := int(p.From.Reg)
  2226  		r := int(p.Reg)
  2227  		var rf int
  2228  		if r != 0 {
  2229  			if p.From3Type() == obj.TYPE_NONE {
  2230  				/* CINC/CINV/CNEG */
  2231  				rf = r
  2232  
  2233  				cond ^= 1
  2234  			} else {
  2235  				rf = int(p.From3.Reg) /* CSEL */
  2236  			}
  2237  		} else {
  2238  			/* CSET */
  2239  			if p.From3Type() != obj.TYPE_NONE {
  2240  				c.ctxt.Diag("invalid combination\n%v", p)
  2241  			}
  2242  			rf = REGZERO
  2243  			r = rf
  2244  			cond ^= 1
  2245  		}
  2246  
  2247  		rt := int(p.To.Reg)
  2248  		o1 |= (uint32(rf&31) << 16) | (uint32(cond&31) << 12) | (uint32(r&31) << 5) | uint32(rt&31)
  2249  
  2250  	case 19: /* CCMN cond, (Rm|uimm5),Rn, uimm4 -> ccmn Rn,Rm,uimm4,cond */
  2251  		nzcv := int(p.To.Offset)
  2252  
  2253  		cond := int(p.From.Reg)
  2254  		var rf int
  2255  		if p.From3.Type == obj.TYPE_REG {
  2256  			o1 = c.oprrr(p, p.As)
  2257  			rf = int(p.From3.Reg) /* Rm */
  2258  		} else {
  2259  			o1 = c.opirr(p, p.As)
  2260  			rf = int(p.From3.Offset & 0x1F)
  2261  		}
  2262  
  2263  		o1 |= (uint32(rf&31) << 16) | (uint32(cond) << 12) | (uint32(p.Reg&31) << 5) | uint32(nzcv)
  2264  
  2265  	case 20: /* movT R,O(R) -> strT */
  2266  		v := int32(c.regoff(&p.To))
  2267  		sz := int32(1 << uint(movesize(p.As)))
  2268  
  2269  		r := int(p.To.Reg)
  2270  		if r == 0 {
  2271  			r = int(o.param)
  2272  		}
  2273  		if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */
  2274  			o1 = c.olsr9s(p, int32(c.opstr9(p, p.As)), v, r, int(p.From.Reg))
  2275  		} else {
  2276  			v = int32(c.offsetshift(p, int64(v), int(o.a3)))
  2277  			o1 = c.olsr12u(p, int32(c.opstr12(p, p.As)), v, r, int(p.From.Reg))
  2278  		}
  2279  
  2280  	case 21: /* movT O(R),R -> ldrT */
  2281  		v := int32(c.regoff(&p.From))
  2282  		sz := int32(1 << uint(movesize(p.As)))
  2283  
  2284  		r := int(p.From.Reg)
  2285  		if r == 0 {
  2286  			r = int(o.param)
  2287  		}
  2288  		if v < 0 || v%sz != 0 { /* unscaled 9-bit signed */
  2289  			o1 = c.olsr9s(p, int32(c.opldr9(p, p.As)), v, r, int(p.To.Reg))
  2290  		} else {
  2291  			v = int32(c.offsetshift(p, int64(v), int(o.a1)))
  2292  			//print("offset=%lld v=%ld a1=%d\n", instoffset, v, o->a1);
  2293  			o1 = c.olsr12u(p, int32(c.opldr12(p, p.As)), v, r, int(p.To.Reg))
  2294  		}
  2295  
  2296  	case 22: /* movT (R)O!,R; movT O(R)!, R -> ldrT */
  2297  		v := int32(p.From.Offset)
  2298  
  2299  		if v < -256 || v > 255 {
  2300  			c.ctxt.Diag("offset out of range\n%v", p)
  2301  		}
  2302  		o1 = c.opldrpp(p, p.As)
  2303  		if o.scond == C_XPOST {
  2304  			o1 |= 1 << 10
  2305  		} else {
  2306  			o1 |= 3 << 10
  2307  		}
  2308  		o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.From.Reg&31) << 5) | uint32(p.To.Reg&31)
  2309  
  2310  	case 23: /* movT R,(R)O!; movT O(R)!, R -> strT */
  2311  		v := int32(p.To.Offset)
  2312  
  2313  		if v < -256 || v > 255 {
  2314  			c.ctxt.Diag("offset out of range\n%v", p)
  2315  		}
  2316  		o1 = LD2STR(c.opldrpp(p, p.As))
  2317  		if o.scond == C_XPOST {
  2318  			o1 |= 1 << 10
  2319  		} else {
  2320  			o1 |= 3 << 10
  2321  		}
  2322  		o1 |= ((uint32(v) & 0x1FF) << 12) | (uint32(p.To.Reg&31) << 5) | uint32(p.From.Reg&31)
  2323  
  2324  	case 24: /* mov/mvn Rs,Rd -> add $0,Rs,Rd or orr Rs,ZR,Rd */
  2325  		rf := int(p.From.Reg)
  2326  		rt := int(p.To.Reg)
  2327  		s := rf == REGSP || rt == REGSP
  2328  		if p.As == AMVN || p.As == AMVNW {
  2329  			if s {
  2330  				c.ctxt.Diag("illegal SP reference\n%v", p)
  2331  			}
  2332  			o1 = c.oprrr(p, p.As)
  2333  			o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
  2334  		} else if s {
  2335  			o1 = c.opirr(p, p.As)
  2336  			o1 |= (uint32(rf&31) << 5) | uint32(rt&31)
  2337  		} else {
  2338  			o1 = c.oprrr(p, p.As)
  2339  			o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
  2340  		}
  2341  
  2342  	case 25: /* negX Rs, Rd -> subX Rs<<0, ZR, Rd */
  2343  		o1 = c.oprrr(p, p.As)
  2344  
  2345  		rf := int(p.From.Reg)
  2346  		if rf == C_NONE {
  2347  			rf = int(p.To.Reg)
  2348  		}
  2349  		rt := int(p.To.Reg)
  2350  		o1 |= (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
  2351  
  2352  	case 26: /* negX Rm<<s, Rd -> subX Rm<<s, ZR, Rd */
  2353  		o1 = c.oprrr(p, p.As)
  2354  
  2355  		o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
  2356  		rt := int(p.To.Reg)
  2357  		o1 |= (REGZERO & 31 << 5) | uint32(rt&31)
  2358  
  2359  	case 27: /* op Rm<<n[,Rn],Rd (extended register) */
  2360  		o1 = c.opxrrr(p, p.As)
  2361  
  2362  		if (p.From.Reg-obj.RBaseARM64)&REG_EXT != 0 {
  2363  			c.ctxt.Diag("extended register not implemented\n%v", p)
  2364  			// o1 |= uint32(p.From.Offset) /* includes reg, op, etc */
  2365  		} else {
  2366  			o1 |= uint32(p.From.Reg&31) << 16
  2367  		}
  2368  		rt := int(p.To.Reg)
  2369  		if p.To.Type == obj.TYPE_NONE {
  2370  			rt = REGZERO
  2371  		}
  2372  		r := int(p.Reg)
  2373  		if r == 0 {
  2374  			r = rt
  2375  		}
  2376  		o1 |= (uint32(r&31) << 5) | uint32(rt&31)
  2377  
  2378  	case 28: /* logop $vcon, [R], R (64 bit literal) */
  2379  		o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
  2380  
  2381  		if !(o1 != 0) {
  2382  			break
  2383  		}
  2384  		r := int(p.Reg)
  2385  		if r == 0 {
  2386  			r = int(p.To.Reg)
  2387  		}
  2388  		o2 = c.oprrr(p, p.As)
  2389  		o2 |= REGTMP & 31 << 16 /* shift is 0 */
  2390  		o2 |= uint32(r&31) << 5
  2391  		o2 |= uint32(p.To.Reg & 31)
  2392  
  2393  	case 29: /* op Rn, Rd */
  2394  		fc := c.aclass(&p.From)
  2395  		tc := c.aclass(&p.To)
  2396  		if (p.As == AFMOVD || p.As == AFMOVS) && (fc == C_REG || fc == C_ZCON || tc == C_REG || tc == C_ZCON) {
  2397  			// FMOV Rx, Fy or FMOV Fy, Rx
  2398  			o1 = FPCVTI(0, 0, 0, 0, 6)
  2399  			if p.As == AFMOVD {
  2400  				o1 |= 1<<31 | 1<<22 // 64-bit
  2401  			}
  2402  			if fc == C_REG || fc == C_ZCON {
  2403  				o1 |= 1 << 16 // FMOV Rx, Fy
  2404  			}
  2405  		} else {
  2406  			o1 = c.oprrr(p, p.As)
  2407  		}
  2408  		o1 |= uint32(p.From.Reg&31)<<5 | uint32(p.To.Reg&31)
  2409  
  2410  	case 30: /* movT R,L(R) -> strT */
  2411  		s := movesize(o.as)
  2412  
  2413  		if s < 0 {
  2414  			c.ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p)
  2415  		}
  2416  		v := int32(c.regoff(&p.To))
  2417  		if v < 0 {
  2418  			c.ctxt.Diag("negative large offset\n%v", p)
  2419  		}
  2420  		if (v & ((1 << uint(s)) - 1)) != 0 {
  2421  			c.ctxt.Diag("misaligned offset\n%v", p)
  2422  		}
  2423  		hi := v - (v & (0xFFF << uint(s)))
  2424  		if (hi & 0xFFF) != 0 {
  2425  			c.ctxt.Diag("internal: miscalculated offset %d [%d]\n%v", v, s, p)
  2426  		}
  2427  
  2428  		//fprint(2, "v=%ld (%#lux) s=%d hi=%ld (%#lux) v'=%ld (%#lux)\n", v, v, s, hi, hi, ((v-hi)>>s)&0xFFF, ((v-hi)>>s)&0xFFF);
  2429  		r := int(p.To.Reg)
  2430  
  2431  		if r == 0 {
  2432  			r = int(o.param)
  2433  		}
  2434  		o1 = c.oaddi(p, int32(c.opirr(p, AADD)), hi, r, REGTMP)
  2435  		o2 = c.olsr12u(p, int32(c.opstr12(p, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.From.Reg))
  2436  
  2437  	case 31: /* movT L(R), R -> ldrT */
  2438  		s := movesize(o.as)
  2439  
  2440  		if s < 0 {
  2441  			c.ctxt.Diag("unexpected long move, op %v tab %v\n%v", p.As, o.as, p)
  2442  		}
  2443  		v := int32(c.regoff(&p.From))
  2444  		if v < 0 {
  2445  			c.ctxt.Diag("negative large offset\n%v", p)
  2446  		}
  2447  		if (v & ((1 << uint(s)) - 1)) != 0 {
  2448  			c.ctxt.Diag("misaligned offset\n%v", p)
  2449  		}
  2450  		hi := v - (v & (0xFFF << uint(s)))
  2451  		if (hi & 0xFFF) != 0 {
  2452  			c.ctxt.Diag("internal: miscalculated offset %d [%d]\n%v", v, s, p)
  2453  		}
  2454  
  2455  		//fprint(2, "v=%ld (%#lux) s=%d hi=%ld (%#lux) v'=%ld (%#lux)\n", v, v, s, hi, hi, ((v-hi)>>s)&0xFFF, ((v-hi)>>s)&0xFFF);
  2456  		r := int(p.From.Reg)
  2457  
  2458  		if r == 0 {
  2459  			r = int(o.param)
  2460  		}
  2461  		o1 = c.oaddi(p, int32(c.opirr(p, AADD)), hi, r, REGTMP)
  2462  		o2 = c.olsr12u(p, int32(c.opldr12(p, p.As)), ((v-hi)>>uint(s))&0xFFF, REGTMP, int(p.To.Reg))
  2463  
  2464  	case 32: /* mov $con, R -> movz/movn */
  2465  		o1 = c.omovconst(p.As, p, &p.From, int(p.To.Reg))
  2466  
  2467  	case 33: /* movk $uimm16 << pos */
  2468  		o1 = c.opirr(p, p.As)
  2469  
  2470  		d := p.From.Offset
  2471  		if (d >> 16) != 0 {
  2472  			c.ctxt.Diag("requires uimm16\n%v", p)
  2473  		}
  2474  		s := 0
  2475  		if p.From3Type() != obj.TYPE_NONE {
  2476  			if p.From3.Type != obj.TYPE_CONST {
  2477  				c.ctxt.Diag("missing bit position\n%v", p)
  2478  			}
  2479  			s = int(p.From3.Offset / 16)
  2480  			if (s*16&0xF) != 0 || s >= 4 || (o1&S64) == 0 && s >= 2 {
  2481  				c.ctxt.Diag("illegal bit position\n%v", p)
  2482  			}
  2483  		}
  2484  
  2485  		rt := int(p.To.Reg)
  2486  		o1 |= uint32(((d & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31))
  2487  
  2488  	case 34: /* mov $lacon,R */
  2489  		o1 = c.omovlit(AMOVD, p, &p.From, REGTMP)
  2490  
  2491  		if !(o1 != 0) {
  2492  			break
  2493  		}
  2494  		o2 = c.opxrrr(p, AADD)
  2495  		o2 |= REGTMP & 31 << 16
  2496  		o2 |= LSL0_64
  2497  		r := int(p.From.Reg)
  2498  		if r == 0 {
  2499  			r = int(o.param)
  2500  		}
  2501  		o2 |= uint32(r&31) << 5
  2502  		o2 |= uint32(p.To.Reg & 31)
  2503  
  2504  	case 35: /* mov SPR,R -> mrs */
  2505  		o1 = c.oprrr(p, AMRS)
  2506  
  2507  		v := int32(p.From.Offset)
  2508  		if (o1 & uint32(v&^(3<<19))) != 0 {
  2509  			c.ctxt.Diag("MRS register value overlap\n%v", p)
  2510  		}
  2511  		o1 |= uint32(v)
  2512  		o1 |= uint32(p.To.Reg & 31)
  2513  
  2514  	case 36: /* mov R,SPR */
  2515  		o1 = c.oprrr(p, AMSR)
  2516  
  2517  		v := int32(p.To.Offset)
  2518  		if (o1 & uint32(v&^(3<<19))) != 0 {
  2519  			c.ctxt.Diag("MSR register value overlap\n%v", p)
  2520  		}
  2521  		o1 |= uint32(v)
  2522  		o1 |= uint32(p.From.Reg & 31)
  2523  
  2524  	case 37: /* mov $con,PSTATEfield -> MSR [immediate] */
  2525  		if (uint64(p.From.Offset) &^ uint64(0xF)) != 0 {
  2526  			c.ctxt.Diag("illegal immediate for PSTATE field\n%v", p)
  2527  		}
  2528  		o1 = c.opirr(p, AMSR)
  2529  		o1 |= uint32((p.From.Offset & 0xF) << 8) /* Crm */
  2530  		v := int32(0)
  2531  		for i := 0; i < len(pstatefield); i++ {
  2532  			if int64(pstatefield[i].a) == p.To.Offset {
  2533  				v = int32(pstatefield[i].b)
  2534  				break
  2535  			}
  2536  		}
  2537  
  2538  		if v == 0 {
  2539  			c.ctxt.Diag("illegal PSTATE field for immediate move\n%v", p)
  2540  		}
  2541  		o1 |= uint32(v)
  2542  
  2543  	case 38: /* clrex [$imm] */
  2544  		o1 = c.opimm(p, p.As)
  2545  
  2546  		if p.To.Type == obj.TYPE_NONE {
  2547  			o1 |= 0xF << 8
  2548  		} else {
  2549  			o1 |= uint32((p.To.Offset & 0xF) << 8)
  2550  		}
  2551  
  2552  	case 39: /* cbz R, rel */
  2553  		o1 = c.opirr(p, p.As)
  2554  
  2555  		o1 |= uint32(p.From.Reg & 31)
  2556  		o1 |= uint32(c.brdist(p, 0, 19, 2) << 5)
  2557  
  2558  	case 40: /* tbz */
  2559  		o1 = c.opirr(p, p.As)
  2560  
  2561  		v := int32(p.From.Offset)
  2562  		if v < 0 || v > 63 {
  2563  			c.ctxt.Diag("illegal bit number\n%v", p)
  2564  		}
  2565  		o1 |= ((uint32(v) & 0x20) << (31 - 5)) | ((uint32(v) & 0x1F) << 19)
  2566  		o1 |= uint32(c.brdist(p, 0, 14, 2) << 5)
  2567  		o1 |= uint32(p.Reg & 31)
  2568  
  2569  	case 41: /* eret, nop, others with no operands */
  2570  		o1 = c.op0(p, p.As)
  2571  
  2572  	case 42: /* bfm R,r,s,R */
  2573  		o1 = c.opbfm(p, p.As, int(p.From.Offset), int(p.From3.Offset), int(p.Reg), int(p.To.Reg))
  2574  
  2575  	case 43: /* bfm aliases */
  2576  		r := int(p.From.Offset)
  2577  
  2578  		s := int(p.From3.Offset)
  2579  		rf := int(p.Reg)
  2580  		rt := int(p.To.Reg)
  2581  		if rf == 0 {
  2582  			rf = rt
  2583  		}
  2584  		switch p.As {
  2585  		case ABFI:
  2586  			o1 = c.opbfm(p, ABFM, 64-r, s-1, rf, rt)
  2587  
  2588  		case ABFIW:
  2589  			o1 = c.opbfm(p, ABFMW, 32-r, s-1, rf, rt)
  2590  
  2591  		case ABFXIL:
  2592  			o1 = c.opbfm(p, ABFM, r, r+s-1, rf, rt)
  2593  
  2594  		case ABFXILW:
  2595  			o1 = c.opbfm(p, ABFMW, r, r+s-1, rf, rt)
  2596  
  2597  		case ASBFIZ:
  2598  			o1 = c.opbfm(p, ASBFM, 64-r, s-1, rf, rt)
  2599  
  2600  		case ASBFIZW:
  2601  			o1 = c.opbfm(p, ASBFMW, 32-r, s-1, rf, rt)
  2602  
  2603  		case ASBFX:
  2604  			o1 = c.opbfm(p, ASBFM, r, r+s-1, rf, rt)
  2605  
  2606  		case ASBFXW:
  2607  			o1 = c.opbfm(p, ASBFMW, r, r+s-1, rf, rt)
  2608  
  2609  		case AUBFIZ:
  2610  			o1 = c.opbfm(p, AUBFM, 64-r, s-1, rf, rt)
  2611  
  2612  		case AUBFIZW:
  2613  			o1 = c.opbfm(p, AUBFMW, 32-r, s-1, rf, rt)
  2614  
  2615  		case AUBFX:
  2616  			o1 = c.opbfm(p, AUBFM, r, r+s-1, rf, rt)
  2617  
  2618  		case AUBFXW:
  2619  			o1 = c.opbfm(p, AUBFMW, r, r+s-1, rf, rt)
  2620  
  2621  		default:
  2622  			c.ctxt.Diag("bad bfm alias\n%v", p)
  2623  			break
  2624  		}
  2625  
  2626  	case 44: /* extr $b, Rn, Rm, Rd */
  2627  		o1 = c.opextr(p, p.As, int32(p.From.Offset), int(p.From3.Reg), int(p.Reg), int(p.To.Reg))
  2628  
  2629  	case 45: /* sxt/uxt[bhw] R,R; movT R,R -> sxtT R,R */
  2630  		rf := int(p.From.Reg)
  2631  
  2632  		rt := int(p.To.Reg)
  2633  		as := p.As
  2634  		if rf == REGZERO {
  2635  			as = AMOVWU /* clearer in disassembly */
  2636  		}
  2637  		switch as {
  2638  		case AMOVB, ASXTB:
  2639  			o1 = c.opbfm(p, ASBFM, 0, 7, rf, rt)
  2640  
  2641  		case AMOVH, ASXTH:
  2642  			o1 = c.opbfm(p, ASBFM, 0, 15, rf, rt)
  2643  
  2644  		case AMOVW, ASXTW:
  2645  			o1 = c.opbfm(p, ASBFM, 0, 31, rf, rt)
  2646  
  2647  		case AMOVBU, AUXTB:
  2648  			o1 = c.opbfm(p, AUBFM, 0, 7, rf, rt)
  2649  
  2650  		case AMOVHU, AUXTH:
  2651  			o1 = c.opbfm(p, AUBFM, 0, 15, rf, rt)
  2652  
  2653  		case AMOVWU:
  2654  			o1 = c.oprrr(p, as) | (uint32(rf&31) << 16) | (REGZERO & 31 << 5) | uint32(rt&31)
  2655  
  2656  		case AUXTW:
  2657  			o1 = c.opbfm(p, AUBFM, 0, 31, rf, rt)
  2658  
  2659  		case ASXTBW:
  2660  			o1 = c.opbfm(p, ASBFMW, 0, 7, rf, rt)
  2661  
  2662  		case ASXTHW:
  2663  			o1 = c.opbfm(p, ASBFMW, 0, 15, rf, rt)
  2664  
  2665  		case AUXTBW:
  2666  			o1 = c.opbfm(p, AUBFMW, 0, 7, rf, rt)
  2667  
  2668  		case AUXTHW:
  2669  			o1 = c.opbfm(p, AUBFMW, 0, 15, rf, rt)
  2670  
  2671  		default:
  2672  			c.ctxt.Diag("bad sxt %v", as)
  2673  			break
  2674  		}
  2675  
  2676  	case 46: /* cls */
  2677  		o1 = c.opbit(p, p.As)
  2678  
  2679  		o1 |= uint32(p.From.Reg&31) << 5
  2680  		o1 |= uint32(p.To.Reg & 31)
  2681  
  2682  	case 47: /* movT R,V(R) -> strT (huge offset) */
  2683  		o1 = c.omovlit(AMOVW, p, &p.To, REGTMP)
  2684  
  2685  		if !(o1 != 0) {
  2686  			break
  2687  		}
  2688  		r := int(p.To.Reg)
  2689  		if r == 0 {
  2690  			r = int(o.param)
  2691  		}
  2692  		o2 = c.olsxrr(p, p.As, REGTMP, r, int(p.From.Reg))
  2693  
  2694  	case 48: /* movT V(R), R -> ldrT (huge offset) */
  2695  		o1 = c.omovlit(AMOVW, p, &p.From, REGTMP)
  2696  
  2697  		if !(o1 != 0) {
  2698  			break
  2699  		}
  2700  		r := int(p.From.Reg)
  2701  		if r == 0 {
  2702  			r = int(o.param)
  2703  		}
  2704  		o2 = c.olsxrr(p, p.As, REGTMP, r, int(p.To.Reg))
  2705  
  2706  	case 50: /* sys/sysl */
  2707  		o1 = c.opirr(p, p.As)
  2708  
  2709  		if (p.From.Offset &^ int64(SYSARG4(0x7, 0xF, 0xF, 0x7))) != 0 {
  2710  			c.ctxt.Diag("illegal SYS argument\n%v", p)
  2711  		}
  2712  		o1 |= uint32(p.From.Offset)
  2713  		if p.To.Type == obj.TYPE_REG {
  2714  			o1 |= uint32(p.To.Reg & 31)
  2715  		} else if p.Reg != 0 {
  2716  			o1 |= uint32(p.Reg & 31)
  2717  		} else {
  2718  			o1 |= 0x1F
  2719  		}
  2720  
  2721  	case 51: /* dmb */
  2722  		o1 = c.opirr(p, p.As)
  2723  
  2724  		if p.From.Type == obj.TYPE_CONST {
  2725  			o1 |= uint32((p.From.Offset & 0xF) << 8)
  2726  		}
  2727  
  2728  	case 52: /* hint */
  2729  		o1 = c.opirr(p, p.As)
  2730  
  2731  		o1 |= uint32((p.From.Offset & 0x7F) << 5)
  2732  
  2733  	case 53: /* and/or/eor/bic/... $bitcon, Rn, Rd */
  2734  		a := p.As
  2735  		rt := int(p.To.Reg)
  2736  		r := int(p.Reg)
  2737  		if r == 0 {
  2738  			r = rt
  2739  		}
  2740  		mode := 64
  2741  		v := uint64(p.From.Offset)
  2742  		switch p.As {
  2743  		case AANDW, AORRW, AEORW, AANDSW:
  2744  			mode = 32
  2745  		case ABIC, AORN, AEON, ABICS:
  2746  			v = ^v
  2747  		case ABICW, AORNW, AEONW, ABICSW:
  2748  			v = ^v
  2749  			mode = 32
  2750  		}
  2751  		o1 = c.opirr(p, a)
  2752  		o1 |= bitconEncode(v, mode) | uint32(r&31)<<5 | uint32(rt&31)
  2753  
  2754  	case 54: /* floating point arith */
  2755  		o1 = c.oprrr(p, p.As)
  2756  
  2757  		var rf int
  2758  		if p.From.Type == obj.TYPE_CONST {
  2759  			rf = c.chipfloat7(p.From.Val.(float64))
  2760  			if rf < 0 || true {
  2761  				c.ctxt.Diag("invalid floating-point immediate\n%v", p)
  2762  				rf = 0
  2763  			}
  2764  
  2765  			rf |= (1 << 3)
  2766  		} else {
  2767  			rf = int(p.From.Reg)
  2768  		}
  2769  		rt := int(p.To.Reg)
  2770  		r := int(p.Reg)
  2771  		if (o1&(0x1F<<24)) == (0x1E<<24) && (o1&(1<<11)) == 0 { /* monadic */
  2772  			r = rf
  2773  			rf = 0
  2774  		} else if r == 0 {
  2775  			r = rt
  2776  		}
  2777  		o1 |= (uint32(rf&31) << 16) | (uint32(r&31) << 5) | uint32(rt&31)
  2778  
  2779  	case 56: /* floating point compare */
  2780  		o1 = c.oprrr(p, p.As)
  2781  
  2782  		var rf int
  2783  		if p.From.Type == obj.TYPE_CONST {
  2784  			o1 |= 8 /* zero */
  2785  			rf = 0
  2786  		} else {
  2787  			rf = int(p.From.Reg)
  2788  		}
  2789  		rt := int(p.Reg)
  2790  		o1 |= uint32(rf&31)<<16 | uint32(rt&31)<<5
  2791  
  2792  	case 57: /* floating point conditional compare */
  2793  		o1 = c.oprrr(p, p.As)
  2794  
  2795  		cond := int(p.From.Reg)
  2796  		nzcv := int(p.To.Offset)
  2797  		if nzcv&^0xF != 0 {
  2798  			c.ctxt.Diag("implausible condition\n%v", p)
  2799  		}
  2800  		rf := int(p.Reg)
  2801  		if p.From3 == nil || p.From3.Reg < REG_F0 || p.From3.Reg > REG_F31 {
  2802  			c.ctxt.Diag("illegal FCCMP\n%v", p)
  2803  			break
  2804  		}
  2805  		rt := int(p.From3.Reg)
  2806  		o1 |= uint32(rf&31)<<16 | uint32(cond)<<12 | uint32(rt&31)<<5 | uint32(nzcv)
  2807  
  2808  	case 58: /* ldar/ldxr/ldaxr */
  2809  		o1 = c.opload(p, p.As)
  2810  
  2811  		o1 |= 0x1F << 16
  2812  		o1 |= uint32(p.From.Reg) << 5
  2813  		if p.Reg != 0 {
  2814  			o1 |= uint32(p.Reg) << 10
  2815  		} else {
  2816  			o1 |= 0x1F << 10
  2817  		}
  2818  		o1 |= uint32(p.To.Reg & 31)
  2819  
  2820  	case 59: /* stxr/stlxr */
  2821  		o1 = c.opstore(p, p.As)
  2822  
  2823  		if p.RegTo2 != obj.REG_NONE {
  2824  			o1 |= uint32(p.RegTo2&31) << 16
  2825  		} else {
  2826  			o1 |= 0x1F << 16
  2827  		}
  2828  
  2829  		// TODO(aram): add support for STXP
  2830  		o1 |= uint32(p.To.Reg&31) << 5
  2831  
  2832  		o1 |= uint32(p.From.Reg & 31)
  2833  
  2834  	case 60: /* adrp label,r */
  2835  		d := c.brdist(p, 12, 21, 0)
  2836  
  2837  		o1 = ADR(1, uint32(d), uint32(p.To.Reg))
  2838  
  2839  	case 61: /* adr label, r */
  2840  		d := c.brdist(p, 0, 21, 0)
  2841  
  2842  		o1 = ADR(0, uint32(d), uint32(p.To.Reg))
  2843  
  2844  	case 62: /* op $movcon, [R], R -> mov $movcon, REGTMP + op REGTMP, [R], R */
  2845  		if p.Reg == REGTMP {
  2846  			c.ctxt.Diag("cannot use REGTMP as source: %v\n", p)
  2847  		}
  2848  		o1 = c.omovconst(AMOVD, p, &p.From, REGTMP)
  2849  
  2850  		rt := int(p.To.Reg)
  2851  		if p.To.Type == obj.TYPE_NONE {
  2852  			rt = REGZERO
  2853  		}
  2854  		r := int(p.Reg)
  2855  		if r == 0 {
  2856  			r = rt
  2857  		}
  2858  		if p.To.Type != obj.TYPE_NONE && (p.To.Reg == REGSP || r == REGSP) {
  2859  			o2 = c.opxrrr(p, p.As)
  2860  			o2 |= REGTMP & 31 << 16
  2861  			o2 |= LSL0_64
  2862  		} else {
  2863  			o2 = c.oprrr(p, p.As)
  2864  			o2 |= REGTMP & 31 << 16 /* shift is 0 */
  2865  		}
  2866  		o2 |= uint32(r&31) << 5
  2867  		o2 |= uint32(rt & 31)
  2868  
  2869  		/* reloc ops */
  2870  	case 64: /* movT R,addr -> adrp + add + movT R, (REGTMP) */
  2871  		o1 = ADR(1, 0, REGTMP)
  2872  		o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
  2873  		rel := obj.Addrel(c.cursym)
  2874  		rel.Off = int32(c.pc)
  2875  		rel.Siz = 8
  2876  		rel.Sym = p.To.Sym
  2877  		rel.Add = p.To.Offset
  2878  		rel.Type = obj.R_ADDRARM64
  2879  		o3 = c.olsr12u(p, int32(c.opstr12(p, p.As)), 0, REGTMP, int(p.From.Reg))
  2880  
  2881  	case 65: /* movT addr,R -> adrp + add + movT (REGTMP), R */
  2882  		o1 = ADR(1, 0, REGTMP)
  2883  		o2 = c.opirr(p, AADD) | REGTMP&31<<5 | REGTMP&31
  2884  		rel := obj.Addrel(c.cursym)
  2885  		rel.Off = int32(c.pc)
  2886  		rel.Siz = 8
  2887  		rel.Sym = p.From.Sym
  2888  		rel.Add = p.From.Offset
  2889  		rel.Type = obj.R_ADDRARM64
  2890  		o3 = c.olsr12u(p, int32(c.opldr12(p, p.As)), 0, REGTMP, int(p.To.Reg))
  2891  
  2892  	case 66: /* ldp O(R)!, (r1, r2); ldp (R)O!, (r1, r2) */
  2893  		v := int32(p.From.Offset)
  2894  
  2895  		if v < -512 || v > 504 {
  2896  			c.ctxt.Diag("offset out of range\n%v", p)
  2897  		}
  2898  		if o.scond == C_XPOST {
  2899  			o1 |= 1 << 23
  2900  		} else {
  2901  			o1 |= 3 << 23
  2902  		}
  2903  		o1 |= 1 << 22
  2904  		o1 |= uint32(int64(2<<30|5<<27|((uint32(v)/8)&0x7f)<<15) | p.To.Offset<<10 | int64(uint32(p.From.Reg&31)<<5) | int64(p.To.Reg&31))
  2905  
  2906  	case 67: /* stp (r1, r2), O(R)!; stp (r1, r2), (R)O! */
  2907  		v := int32(p.To.Offset)
  2908  
  2909  		if v < -512 || v > 504 {
  2910  			c.ctxt.Diag("offset out of range\n%v", p)
  2911  		}
  2912  		if o.scond == C_XPOST {
  2913  			o1 |= 1 << 23
  2914  		} else {
  2915  			o1 |= 3 << 23
  2916  		}
  2917  		o1 |= uint32(int64(2<<30|5<<27|((uint32(v)/8)&0x7f)<<15) | p.From.Offset<<10 | int64(uint32(p.To.Reg&31)<<5) | int64(p.From.Reg&31))
  2918  
  2919  	case 68: /* movT $vconaddr(SB), reg -> adrp + add + reloc */
  2920  		if p.As == AMOVW {
  2921  			c.ctxt.Diag("invalid load of 32-bit address: %v", p)
  2922  		}
  2923  		o1 = ADR(1, 0, uint32(p.To.Reg))
  2924  		o2 = c.opirr(p, AADD) | uint32(p.To.Reg&31)<<5 | uint32(p.To.Reg&31)
  2925  		rel := obj.Addrel(c.cursym)
  2926  		rel.Off = int32(c.pc)
  2927  		rel.Siz = 8
  2928  		rel.Sym = p.From.Sym
  2929  		rel.Add = p.From.Offset
  2930  		rel.Type = obj.R_ADDRARM64
  2931  
  2932  	case 69: /* LE model movd $tlsvar, reg -> movz reg, 0 + reloc */
  2933  		o1 = c.opirr(p, AMOVZ)
  2934  		o1 |= uint32(p.To.Reg & 31)
  2935  		rel := obj.Addrel(c.cursym)
  2936  		rel.Off = int32(c.pc)
  2937  		rel.Siz = 4
  2938  		rel.Sym = p.From.Sym
  2939  		rel.Type = obj.R_ARM64_TLS_LE
  2940  		if p.From.Offset != 0 {
  2941  			c.ctxt.Diag("invalid offset on MOVW $tlsvar")
  2942  		}
  2943  
  2944  	case 70: /* IE model movd $tlsvar, reg -> adrp REGTMP, 0; ldr reg, [REGTMP, #0] + relocs */
  2945  		o1 = ADR(1, 0, REGTMP)
  2946  		o2 = c.olsr12u(p, int32(c.opldr12(p, AMOVD)), 0, REGTMP, int(p.To.Reg))
  2947  		rel := obj.Addrel(c.cursym)
  2948  		rel.Off = int32(c.pc)
  2949  		rel.Siz = 8
  2950  		rel.Sym = p.From.Sym
  2951  		rel.Add = 0
  2952  		rel.Type = obj.R_ARM64_TLS_IE
  2953  		if p.From.Offset != 0 {
  2954  			c.ctxt.Diag("invalid offset on MOVW $tlsvar")
  2955  		}
  2956  
  2957  	case 71: /* movd sym@GOT, reg -> adrp REGTMP, #0; ldr reg, [REGTMP, #0] + relocs */
  2958  		o1 = ADR(1, 0, REGTMP)
  2959  		o2 = c.olsr12u(p, int32(c.opldr12(p, AMOVD)), 0, REGTMP, int(p.To.Reg))
  2960  		rel := obj.Addrel(c.cursym)
  2961  		rel.Off = int32(c.pc)
  2962  		rel.Siz = 8
  2963  		rel.Sym = p.From.Sym
  2964  		rel.Add = 0
  2965  		rel.Type = obj.R_ARM64_GOTPCREL
  2966  
  2967  	// This is supposed to be something that stops execution.
  2968  	// It's not supposed to be reached, ever, but if it is, we'd
  2969  	// like to be able to tell how we got there. Assemble as
  2970  	// 0xbea71700 which is guaranteed to raise undefined instruction
  2971  	// exception.
  2972  	case 90:
  2973  		o1 = 0xbea71700
  2974  
  2975  		break
  2976  	}
  2977  
  2978  	out[0] = o1
  2979  	out[1] = o2
  2980  	out[2] = o3
  2981  	out[3] = o4
  2982  	out[4] = o5
  2983  	return
  2984  }
  2985  
  2986  /*
  2987   * basic Rm op Rn -> Rd (using shifted register with 0)
  2988   * also op Rn -> Rt
  2989   * also Rm*Rn op Ra -> Rd
  2990   */
  2991  func (c *ctxt7) oprrr(p *obj.Prog, a obj.As) uint32 {
  2992  	switch a {
  2993  	case AADC:
  2994  		return S64 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10
  2995  
  2996  	case AADCW:
  2997  		return S32 | 0<<30 | 0<<29 | 0xd0<<21 | 0<<10
  2998  
  2999  	case AADCS:
  3000  		return S64 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10
  3001  
  3002  	case AADCSW:
  3003  		return S32 | 0<<30 | 1<<29 | 0xd0<<21 | 0<<10
  3004  
  3005  	case ANGC, ASBC:
  3006  		return S64 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10
  3007  
  3008  	case ANGCS, ASBCS:
  3009  		return S64 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10
  3010  
  3011  	case ANGCW, ASBCW:
  3012  		return S32 | 1<<30 | 0<<29 | 0xd0<<21 | 0<<10
  3013  
  3014  	case ANGCSW, ASBCSW:
  3015  		return S32 | 1<<30 | 1<<29 | 0xd0<<21 | 0<<10
  3016  
  3017  	case AADD:
  3018  		return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  3019  
  3020  	case AADDW:
  3021  		return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  3022  
  3023  	case ACMN, AADDS:
  3024  		return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  3025  
  3026  	case ACMNW, AADDSW:
  3027  		return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  3028  
  3029  	case ASUB:
  3030  		return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  3031  
  3032  	case ASUBW:
  3033  		return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  3034  
  3035  	case ACMP, ASUBS:
  3036  		return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  3037  
  3038  	case ACMPW, ASUBSW:
  3039  		return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 0<<21 | 0<<10
  3040  
  3041  	case AAND:
  3042  		return S64 | 0<<29 | 0xA<<24
  3043  
  3044  	case AANDW:
  3045  		return S32 | 0<<29 | 0xA<<24
  3046  
  3047  	case AMOVD, AORR:
  3048  		return S64 | 1<<29 | 0xA<<24
  3049  
  3050  		//	case AMOVW:
  3051  	case AMOVWU, AORRW:
  3052  		return S32 | 1<<29 | 0xA<<24
  3053  
  3054  	case AEOR:
  3055  		return S64 | 2<<29 | 0xA<<24
  3056  
  3057  	case AEORW:
  3058  		return S32 | 2<<29 | 0xA<<24
  3059  
  3060  	case AANDS:
  3061  		return S64 | 3<<29 | 0xA<<24
  3062  
  3063  	case AANDSW:
  3064  		return S32 | 3<<29 | 0xA<<24
  3065  
  3066  	case ABIC:
  3067  		return S64 | 0<<29 | 0xA<<24 | 1<<21
  3068  
  3069  	case ABICW:
  3070  		return S32 | 0<<29 | 0xA<<24 | 1<<21
  3071  
  3072  	case ABICS:
  3073  		return S64 | 3<<29 | 0xA<<24 | 1<<21
  3074  
  3075  	case ABICSW:
  3076  		return S32 | 3<<29 | 0xA<<24 | 1<<21
  3077  
  3078  	case AEON:
  3079  		return S64 | 2<<29 | 0xA<<24 | 1<<21
  3080  
  3081  	case AEONW:
  3082  		return S32 | 2<<29 | 0xA<<24 | 1<<21
  3083  
  3084  	case AMVN, AORN:
  3085  		return S64 | 1<<29 | 0xA<<24 | 1<<21
  3086  
  3087  	case AMVNW, AORNW:
  3088  		return S32 | 1<<29 | 0xA<<24 | 1<<21
  3089  
  3090  	case AASR:
  3091  		return S64 | OPDP2(10) /* also ASRV */
  3092  
  3093  	case AASRW:
  3094  		return S32 | OPDP2(10)
  3095  
  3096  	case ALSL:
  3097  		return S64 | OPDP2(8)
  3098  
  3099  	case ALSLW:
  3100  		return S32 | OPDP2(8)
  3101  
  3102  	case ALSR:
  3103  		return S64 | OPDP2(9)
  3104  
  3105  	case ALSRW:
  3106  		return S32 | OPDP2(9)
  3107  
  3108  	case AROR:
  3109  		return S64 | OPDP2(11)
  3110  
  3111  	case ARORW:
  3112  		return S32 | OPDP2(11)
  3113  
  3114  	case ACCMN:
  3115  		return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 /* cond<<12 | nzcv<<0 */
  3116  
  3117  	case ACCMNW:
  3118  		return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4
  3119  
  3120  	case ACCMP:
  3121  		return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */
  3122  
  3123  	case ACCMPW:
  3124  		return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 0<<11 | 0<<10 | 0<<4
  3125  
  3126  	case ACRC32B:
  3127  		return S32 | OPDP2(16)
  3128  
  3129  	case ACRC32H:
  3130  		return S32 | OPDP2(17)
  3131  
  3132  	case ACRC32W:
  3133  		return S32 | OPDP2(18)
  3134  
  3135  	case ACRC32X:
  3136  		return S64 | OPDP2(19)
  3137  
  3138  	case ACRC32CB:
  3139  		return S32 | OPDP2(20)
  3140  
  3141  	case ACRC32CH:
  3142  		return S32 | OPDP2(21)
  3143  
  3144  	case ACRC32CW:
  3145  		return S32 | OPDP2(22)
  3146  
  3147  	case ACRC32CX:
  3148  		return S64 | OPDP2(23)
  3149  
  3150  	case ACSEL:
  3151  		return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  3152  
  3153  	case ACSELW:
  3154  		return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  3155  
  3156  	case ACSET:
  3157  		return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  3158  
  3159  	case ACSETW:
  3160  		return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  3161  
  3162  	case ACSETM:
  3163  		return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  3164  
  3165  	case ACSETMW:
  3166  		return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  3167  
  3168  	case ACINC, ACSINC:
  3169  		return S64 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  3170  
  3171  	case ACINCW, ACSINCW:
  3172  		return S32 | 0<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  3173  
  3174  	case ACINV, ACSINV:
  3175  		return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  3176  
  3177  	case ACINVW, ACSINVW:
  3178  		return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 0<<10
  3179  
  3180  	case ACNEG, ACSNEG:
  3181  		return S64 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  3182  
  3183  	case ACNEGW, ACSNEGW:
  3184  		return S32 | 1<<30 | 0<<29 | 0xD4<<21 | 0<<11 | 1<<10
  3185  
  3186  	case AMUL, AMADD:
  3187  		return S64 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15
  3188  
  3189  	case AMULW, AMADDW:
  3190  		return S32 | 0<<29 | 0x1B<<24 | 0<<21 | 0<<15
  3191  
  3192  	case AMNEG, AMSUB:
  3193  		return S64 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15
  3194  
  3195  	case AMNEGW, AMSUBW:
  3196  		return S32 | 0<<29 | 0x1B<<24 | 0<<21 | 1<<15
  3197  
  3198  	case AMRS:
  3199  		return SYSOP(1, 2, 0, 0, 0, 0, 0)
  3200  
  3201  	case AMSR:
  3202  		return SYSOP(0, 2, 0, 0, 0, 0, 0)
  3203  
  3204  	case ANEG:
  3205  		return S64 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21
  3206  
  3207  	case ANEGW:
  3208  		return S32 | 1<<30 | 0<<29 | 0xB<<24 | 0<<21
  3209  
  3210  	case ANEGS:
  3211  		return S64 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21
  3212  
  3213  	case ANEGSW:
  3214  		return S32 | 1<<30 | 1<<29 | 0xB<<24 | 0<<21
  3215  
  3216  	case AREM, ASDIV:
  3217  		return S64 | OPDP2(3)
  3218  
  3219  	case AREMW, ASDIVW:
  3220  		return S32 | OPDP2(3)
  3221  
  3222  	case ASMULL, ASMADDL:
  3223  		return OPDP3(1, 0, 1, 0)
  3224  
  3225  	case ASMNEGL, ASMSUBL:
  3226  		return OPDP3(1, 0, 1, 1)
  3227  
  3228  	case ASMULH:
  3229  		return OPDP3(1, 0, 2, 0)
  3230  
  3231  	case AUMULL, AUMADDL:
  3232  		return OPDP3(1, 0, 5, 0)
  3233  
  3234  	case AUMNEGL, AUMSUBL:
  3235  		return OPDP3(1, 0, 5, 1)
  3236  
  3237  	case AUMULH:
  3238  		return OPDP3(1, 0, 6, 0)
  3239  
  3240  	case AUREM, AUDIV:
  3241  		return S64 | OPDP2(2)
  3242  
  3243  	case AUREMW, AUDIVW:
  3244  		return S32 | OPDP2(2)
  3245  
  3246  	case AAESE:
  3247  		return 0x4E<<24 | 2<<20 | 8<<16 | 4<<12 | 2<<10
  3248  
  3249  	case AAESD:
  3250  		return 0x4E<<24 | 2<<20 | 8<<16 | 5<<12 | 2<<10
  3251  
  3252  	case AAESMC:
  3253  		return 0x4E<<24 | 2<<20 | 8<<16 | 6<<12 | 2<<10
  3254  
  3255  	case AAESIMC:
  3256  		return 0x4E<<24 | 2<<20 | 8<<16 | 7<<12 | 2<<10
  3257  
  3258  	case ASHA1C:
  3259  		return 0x5E<<24 | 0<<12
  3260  
  3261  	case ASHA1P:
  3262  		return 0x5E<<24 | 1<<12
  3263  
  3264  	case ASHA1M:
  3265  		return 0x5E<<24 | 2<<12
  3266  
  3267  	case ASHA1SU0:
  3268  		return 0x5E<<24 | 3<<12
  3269  
  3270  	case ASHA256H:
  3271  		return 0x5E<<24 | 4<<12
  3272  
  3273  	case ASHA256H2:
  3274  		return 0x5E<<24 | 5<<12
  3275  
  3276  	case ASHA256SU1:
  3277  		return 0x5E<<24 | 6<<12
  3278  
  3279  	case ASHA1H:
  3280  		return 0x5E<<24 | 2<<20 | 8<<16 | 0<<12 | 2<<10
  3281  
  3282  	case ASHA1SU1:
  3283  		return 0x5E<<24 | 2<<20 | 8<<16 | 1<<12 | 2<<10
  3284  
  3285  	case ASHA256SU0:
  3286  		return 0x5E<<24 | 2<<20 | 8<<16 | 2<<12 | 2<<10
  3287  
  3288  	case AFCVTZSD:
  3289  		return FPCVTI(1, 0, 1, 3, 0)
  3290  
  3291  	case AFCVTZSDW:
  3292  		return FPCVTI(0, 0, 1, 3, 0)
  3293  
  3294  	case AFCVTZSS:
  3295  		return FPCVTI(1, 0, 0, 3, 0)
  3296  
  3297  	case AFCVTZSSW:
  3298  		return FPCVTI(0, 0, 0, 3, 0)
  3299  
  3300  	case AFCVTZUD:
  3301  		return FPCVTI(1, 0, 1, 3, 1)
  3302  
  3303  	case AFCVTZUDW:
  3304  		return FPCVTI(0, 0, 1, 3, 1)
  3305  
  3306  	case AFCVTZUS:
  3307  		return FPCVTI(1, 0, 0, 3, 1)
  3308  
  3309  	case AFCVTZUSW:
  3310  		return FPCVTI(0, 0, 0, 3, 1)
  3311  
  3312  	case ASCVTFD:
  3313  		return FPCVTI(1, 0, 1, 0, 2)
  3314  
  3315  	case ASCVTFS:
  3316  		return FPCVTI(1, 0, 0, 0, 2)
  3317  
  3318  	case ASCVTFWD:
  3319  		return FPCVTI(0, 0, 1, 0, 2)
  3320  
  3321  	case ASCVTFWS:
  3322  		return FPCVTI(0, 0, 0, 0, 2)
  3323  
  3324  	case AUCVTFD:
  3325  		return FPCVTI(1, 0, 1, 0, 3)
  3326  
  3327  	case AUCVTFS:
  3328  		return FPCVTI(1, 0, 0, 0, 3)
  3329  
  3330  	case AUCVTFWD:
  3331  		return FPCVTI(0, 0, 1, 0, 3)
  3332  
  3333  	case AUCVTFWS:
  3334  		return FPCVTI(0, 0, 0, 0, 3)
  3335  
  3336  	case AFADDS:
  3337  		return FPOP2S(0, 0, 0, 2)
  3338  
  3339  	case AFADDD:
  3340  		return FPOP2S(0, 0, 1, 2)
  3341  
  3342  	case AFSUBS:
  3343  		return FPOP2S(0, 0, 0, 3)
  3344  
  3345  	case AFSUBD:
  3346  		return FPOP2S(0, 0, 1, 3)
  3347  
  3348  	case AFMULS:
  3349  		return FPOP2S(0, 0, 0, 0)
  3350  
  3351  	case AFMULD:
  3352  		return FPOP2S(0, 0, 1, 0)
  3353  
  3354  	case AFDIVS:
  3355  		return FPOP2S(0, 0, 0, 1)
  3356  
  3357  	case AFDIVD:
  3358  		return FPOP2S(0, 0, 1, 1)
  3359  
  3360  	case AFMAXS:
  3361  		return FPOP2S(0, 0, 0, 4)
  3362  
  3363  	case AFMINS:
  3364  		return FPOP2S(0, 0, 0, 5)
  3365  
  3366  	case AFMAXD:
  3367  		return FPOP2S(0, 0, 1, 4)
  3368  
  3369  	case AFMIND:
  3370  		return FPOP2S(0, 0, 1, 5)
  3371  
  3372  	case AFMAXNMS:
  3373  		return FPOP2S(0, 0, 0, 6)
  3374  
  3375  	case AFMAXNMD:
  3376  		return FPOP2S(0, 0, 1, 6)
  3377  
  3378  	case AFMINNMS:
  3379  		return FPOP2S(0, 0, 0, 7)
  3380  
  3381  	case AFMINNMD:
  3382  		return FPOP2S(0, 0, 1, 7)
  3383  
  3384  	case AFNMULS:
  3385  		return FPOP2S(0, 0, 0, 8)
  3386  
  3387  	case AFNMULD:
  3388  		return FPOP2S(0, 0, 1, 8)
  3389  
  3390  	case AFCMPS:
  3391  		return FPCMP(0, 0, 0, 0, 0)
  3392  
  3393  	case AFCMPD:
  3394  		return FPCMP(0, 0, 1, 0, 0)
  3395  
  3396  	case AFCMPES:
  3397  		return FPCMP(0, 0, 0, 0, 16)
  3398  
  3399  	case AFCMPED:
  3400  		return FPCMP(0, 0, 1, 0, 16)
  3401  
  3402  	case AFCCMPS:
  3403  		return FPCCMP(0, 0, 0, 0)
  3404  
  3405  	case AFCCMPD:
  3406  		return FPCCMP(0, 0, 1, 0)
  3407  
  3408  	case AFCCMPES:
  3409  		return FPCCMP(0, 0, 0, 1)
  3410  
  3411  	case AFCCMPED:
  3412  		return FPCCMP(0, 0, 1, 1)
  3413  
  3414  	case AFCSELS:
  3415  		return 0x1E<<24 | 0<<22 | 1<<21 | 3<<10
  3416  
  3417  	case AFCSELD:
  3418  		return 0x1E<<24 | 1<<22 | 1<<21 | 3<<10
  3419  
  3420  	case AFMOVS:
  3421  		return FPOP1S(0, 0, 0, 0)
  3422  
  3423  	case AFABSS:
  3424  		return FPOP1S(0, 0, 0, 1)
  3425  
  3426  	case AFNEGS:
  3427  		return FPOP1S(0, 0, 0, 2)
  3428  
  3429  	case AFSQRTS:
  3430  		return FPOP1S(0, 0, 0, 3)
  3431  
  3432  	case AFCVTSD:
  3433  		return FPOP1S(0, 0, 0, 5)
  3434  
  3435  	case AFCVTSH:
  3436  		return FPOP1S(0, 0, 0, 7)
  3437  
  3438  	case AFRINTNS:
  3439  		return FPOP1S(0, 0, 0, 8)
  3440  
  3441  	case AFRINTPS:
  3442  		return FPOP1S(0, 0, 0, 9)
  3443  
  3444  	case AFRINTMS:
  3445  		return FPOP1S(0, 0, 0, 10)
  3446  
  3447  	case AFRINTZS:
  3448  		return FPOP1S(0, 0, 0, 11)
  3449  
  3450  	case AFRINTAS:
  3451  		return FPOP1S(0, 0, 0, 12)
  3452  
  3453  	case AFRINTXS:
  3454  		return FPOP1S(0, 0, 0, 14)
  3455  
  3456  	case AFRINTIS:
  3457  		return FPOP1S(0, 0, 0, 15)
  3458  
  3459  	case AFMOVD:
  3460  		return FPOP1S(0, 0, 1, 0)
  3461  
  3462  	case AFABSD:
  3463  		return FPOP1S(0, 0, 1, 1)
  3464  
  3465  	case AFNEGD:
  3466  		return FPOP1S(0, 0, 1, 2)
  3467  
  3468  	case AFSQRTD:
  3469  		return FPOP1S(0, 0, 1, 3)
  3470  
  3471  	case AFCVTDS:
  3472  		return FPOP1S(0, 0, 1, 4)
  3473  
  3474  	case AFCVTDH:
  3475  		return FPOP1S(0, 0, 1, 7)
  3476  
  3477  	case AFRINTND:
  3478  		return FPOP1S(0, 0, 1, 8)
  3479  
  3480  	case AFRINTPD:
  3481  		return FPOP1S(0, 0, 1, 9)
  3482  
  3483  	case AFRINTMD:
  3484  		return FPOP1S(0, 0, 1, 10)
  3485  
  3486  	case AFRINTZD:
  3487  		return FPOP1S(0, 0, 1, 11)
  3488  
  3489  	case AFRINTAD:
  3490  		return FPOP1S(0, 0, 1, 12)
  3491  
  3492  	case AFRINTXD:
  3493  		return FPOP1S(0, 0, 1, 14)
  3494  
  3495  	case AFRINTID:
  3496  		return FPOP1S(0, 0, 1, 15)
  3497  
  3498  	case AFCVTHS:
  3499  		return FPOP1S(0, 0, 3, 4)
  3500  
  3501  	case AFCVTHD:
  3502  		return FPOP1S(0, 0, 3, 5)
  3503  	}
  3504  
  3505  	c.ctxt.Diag("%v: bad rrr %d %v", p, a, a)
  3506  	return 0
  3507  }
  3508  
  3509  /*
  3510   * imm -> Rd
  3511   * imm op Rn -> Rd
  3512   */
  3513  func (c *ctxt7) opirr(p *obj.Prog, a obj.As) uint32 {
  3514  	switch a {
  3515  	/* op $addcon, Rn, Rd */
  3516  	case AMOVD, AADD:
  3517  		return S64 | 0<<30 | 0<<29 | 0x11<<24
  3518  
  3519  	case ACMN, AADDS:
  3520  		return S64 | 0<<30 | 1<<29 | 0x11<<24
  3521  
  3522  	case AMOVW, AADDW:
  3523  		return S32 | 0<<30 | 0<<29 | 0x11<<24
  3524  
  3525  	case ACMNW, AADDSW:
  3526  		return S32 | 0<<30 | 1<<29 | 0x11<<24
  3527  
  3528  	case ASUB:
  3529  		return S64 | 1<<30 | 0<<29 | 0x11<<24
  3530  
  3531  	case ACMP, ASUBS:
  3532  		return S64 | 1<<30 | 1<<29 | 0x11<<24
  3533  
  3534  	case ASUBW:
  3535  		return S32 | 1<<30 | 0<<29 | 0x11<<24
  3536  
  3537  	case ACMPW, ASUBSW:
  3538  		return S32 | 1<<30 | 1<<29 | 0x11<<24
  3539  
  3540  		/* op $imm(SB), Rd; op label, Rd */
  3541  	case AADR:
  3542  		return 0<<31 | 0x10<<24
  3543  
  3544  	case AADRP:
  3545  		return 1<<31 | 0x10<<24
  3546  
  3547  		/* op $bimm, Rn, Rd */
  3548  	case AAND, ABIC:
  3549  		return S64 | 0<<29 | 0x24<<23
  3550  
  3551  	case AANDW, ABICW:
  3552  		return S32 | 0<<29 | 0x24<<23 | 0<<22
  3553  
  3554  	case AORR, AORN:
  3555  		return S64 | 1<<29 | 0x24<<23
  3556  
  3557  	case AORRW, AORNW:
  3558  		return S32 | 1<<29 | 0x24<<23 | 0<<22
  3559  
  3560  	case AEOR, AEON:
  3561  		return S64 | 2<<29 | 0x24<<23
  3562  
  3563  	case AEORW, AEONW:
  3564  		return S32 | 2<<29 | 0x24<<23 | 0<<22
  3565  
  3566  	case AANDS, ABICS:
  3567  		return S64 | 3<<29 | 0x24<<23
  3568  
  3569  	case AANDSW, ABICSW:
  3570  		return S32 | 3<<29 | 0x24<<23 | 0<<22
  3571  
  3572  	case AASR:
  3573  		return S64 | 0<<29 | 0x26<<23 /* alias of SBFM */
  3574  
  3575  	case AASRW:
  3576  		return S32 | 0<<29 | 0x26<<23 | 0<<22
  3577  
  3578  		/* op $width, $lsb, Rn, Rd */
  3579  	case ABFI:
  3580  		return S64 | 2<<29 | 0x26<<23 | 1<<22
  3581  		/* alias of BFM */
  3582  
  3583  	case ABFIW:
  3584  		return S32 | 2<<29 | 0x26<<23 | 0<<22
  3585  
  3586  		/* op $imms, $immr, Rn, Rd */
  3587  	case ABFM:
  3588  		return S64 | 1<<29 | 0x26<<23 | 1<<22
  3589  
  3590  	case ABFMW:
  3591  		return S32 | 1<<29 | 0x26<<23 | 0<<22
  3592  
  3593  	case ASBFM:
  3594  		return S64 | 0<<29 | 0x26<<23 | 1<<22
  3595  
  3596  	case ASBFMW:
  3597  		return S32 | 0<<29 | 0x26<<23 | 0<<22
  3598  
  3599  	case AUBFM:
  3600  		return S64 | 2<<29 | 0x26<<23 | 1<<22
  3601  
  3602  	case AUBFMW:
  3603  		return S32 | 2<<29 | 0x26<<23 | 0<<22
  3604  
  3605  	case ABFXIL:
  3606  		return S64 | 1<<29 | 0x26<<23 | 1<<22 /* alias of BFM */
  3607  
  3608  	case ABFXILW:
  3609  		return S32 | 1<<29 | 0x26<<23 | 0<<22
  3610  
  3611  	case AEXTR:
  3612  		return S64 | 0<<29 | 0x27<<23 | 1<<22 | 0<<21
  3613  
  3614  	case AEXTRW:
  3615  		return S32 | 0<<29 | 0x27<<23 | 0<<22 | 0<<21
  3616  
  3617  	case ACBNZ:
  3618  		return S64 | 0x1A<<25 | 1<<24
  3619  
  3620  	case ACBNZW:
  3621  		return S32 | 0x1A<<25 | 1<<24
  3622  
  3623  	case ACBZ:
  3624  		return S64 | 0x1A<<25 | 0<<24
  3625  
  3626  	case ACBZW:
  3627  		return S32 | 0x1A<<25 | 0<<24
  3628  
  3629  	case ACCMN:
  3630  		return S64 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */
  3631  
  3632  	case ACCMNW:
  3633  		return S32 | 0<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4
  3634  
  3635  	case ACCMP:
  3636  		return S64 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4 /* imm5<<16 | cond<<12 | nzcv<<0 */
  3637  
  3638  	case ACCMPW:
  3639  		return S32 | 1<<30 | 1<<29 | 0xD2<<21 | 1<<11 | 0<<10 | 0<<4
  3640  
  3641  	case AMOVK:
  3642  		return S64 | 3<<29 | 0x25<<23
  3643  
  3644  	case AMOVKW:
  3645  		return S32 | 3<<29 | 0x25<<23
  3646  
  3647  	case AMOVN:
  3648  		return S64 | 0<<29 | 0x25<<23
  3649  
  3650  	case AMOVNW:
  3651  		return S32 | 0<<29 | 0x25<<23
  3652  
  3653  	case AMOVZ:
  3654  		return S64 | 2<<29 | 0x25<<23
  3655  
  3656  	case AMOVZW:
  3657  		return S32 | 2<<29 | 0x25<<23
  3658  
  3659  	case AMSR:
  3660  		return SYSOP(0, 0, 0, 4, 0, 0, 0x1F) /* MSR (immediate) */
  3661  
  3662  	case AAT,
  3663  		ADC,
  3664  		AIC,
  3665  		ATLBI,
  3666  		ASYS:
  3667  		return SYSOP(0, 1, 0, 0, 0, 0, 0)
  3668  
  3669  	case ASYSL:
  3670  		return SYSOP(1, 1, 0, 0, 0, 0, 0)
  3671  
  3672  	case ATBZ:
  3673  		return 0x36 << 24
  3674  
  3675  	case ATBNZ:
  3676  		return 0x37 << 24
  3677  
  3678  	case ADSB:
  3679  		return SYSOP(0, 0, 3, 3, 0, 4, 0x1F)
  3680  
  3681  	case ADMB:
  3682  		return SYSOP(0, 0, 3, 3, 0, 5, 0x1F)
  3683  
  3684  	case AISB:
  3685  		return SYSOP(0, 0, 3, 3, 0, 6, 0x1F)
  3686  
  3687  	case AHINT:
  3688  		return SYSOP(0, 0, 3, 2, 0, 0, 0x1F)
  3689  	}
  3690  
  3691  	c.ctxt.Diag("%v: bad irr %v", p, a)
  3692  	return 0
  3693  }
  3694  
  3695  func (c *ctxt7) opbit(p *obj.Prog, a obj.As) uint32 {
  3696  	switch a {
  3697  	case ACLS:
  3698  		return S64 | OPBIT(5)
  3699  
  3700  	case ACLSW:
  3701  		return S32 | OPBIT(5)
  3702  
  3703  	case ACLZ:
  3704  		return S64 | OPBIT(4)
  3705  
  3706  	case ACLZW:
  3707  		return S32 | OPBIT(4)
  3708  
  3709  	case ARBIT:
  3710  		return S64 | OPBIT(0)
  3711  
  3712  	case ARBITW:
  3713  		return S32 | OPBIT(0)
  3714  
  3715  	case AREV:
  3716  		return S64 | OPBIT(3)
  3717  
  3718  	case AREVW:
  3719  		return S32 | OPBIT(2)
  3720  
  3721  	case AREV16:
  3722  		return S64 | OPBIT(1)
  3723  
  3724  	case AREV16W:
  3725  		return S32 | OPBIT(1)
  3726  
  3727  	case AREV32:
  3728  		return S64 | OPBIT(2)
  3729  
  3730  	default:
  3731  		c.ctxt.Diag("bad bit op\n%v", p)
  3732  		return 0
  3733  	}
  3734  }
  3735  
  3736  /*
  3737   * add/subtract extended register
  3738   */
  3739  func (c *ctxt7) opxrrr(p *obj.Prog, a obj.As) uint32 {
  3740  	switch a {
  3741  	case AADD:
  3742  		return S64 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
  3743  
  3744  	case AADDW:
  3745  		return S32 | 0<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
  3746  
  3747  	case ACMN, AADDS:
  3748  		return S64 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
  3749  
  3750  	case ACMNW, AADDSW:
  3751  		return S32 | 0<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
  3752  
  3753  	case ASUB:
  3754  		return S64 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
  3755  
  3756  	case ASUBW:
  3757  		return S32 | 1<<30 | 0<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
  3758  
  3759  	case ACMP, ASUBS:
  3760  		return S64 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_64
  3761  
  3762  	case ACMPW, ASUBSW:
  3763  		return S32 | 1<<30 | 1<<29 | 0x0b<<24 | 0<<22 | 1<<21 | LSL0_32
  3764  	}
  3765  
  3766  	c.ctxt.Diag("bad opxrrr %v\n%v", a, p)
  3767  	return 0
  3768  }
  3769  
  3770  func (c *ctxt7) opimm(p *obj.Prog, a obj.As) uint32 {
  3771  	switch a {
  3772  	case ASVC:
  3773  		return 0xD4<<24 | 0<<21 | 1 /* imm16<<5 */
  3774  
  3775  	case AHVC:
  3776  		return 0xD4<<24 | 0<<21 | 2
  3777  
  3778  	case ASMC:
  3779  		return 0xD4<<24 | 0<<21 | 3
  3780  
  3781  	case ABRK:
  3782  		return 0xD4<<24 | 1<<21 | 0
  3783  
  3784  	case AHLT:
  3785  		return 0xD4<<24 | 2<<21 | 0
  3786  
  3787  	case ADCPS1:
  3788  		return 0xD4<<24 | 5<<21 | 1
  3789  
  3790  	case ADCPS2:
  3791  		return 0xD4<<24 | 5<<21 | 2
  3792  
  3793  	case ADCPS3:
  3794  		return 0xD4<<24 | 5<<21 | 3
  3795  
  3796  	case ACLREX:
  3797  		return SYSOP(0, 0, 3, 3, 0, 2, 0x1F)
  3798  	}
  3799  
  3800  	c.ctxt.Diag("%v: bad imm %v", p, a)
  3801  	return 0
  3802  }
  3803  
  3804  func (c *ctxt7) brdist(p *obj.Prog, preshift int, flen int, shift int) int64 {
  3805  	v := int64(0)
  3806  	t := int64(0)
  3807  	if p.Pcond != nil {
  3808  		v = (p.Pcond.Pc >> uint(preshift)) - (c.pc >> uint(preshift))
  3809  		if (v & ((1 << uint(shift)) - 1)) != 0 {
  3810  			c.ctxt.Diag("misaligned label\n%v", p)
  3811  		}
  3812  		v >>= uint(shift)
  3813  		t = int64(1) << uint(flen-1)
  3814  		if v < -t || v >= t {
  3815  			c.ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, c.blitrl, p, p.Pcond)
  3816  			panic("branch too far")
  3817  		}
  3818  	}
  3819  
  3820  	return v & ((t << 1) - 1)
  3821  }
  3822  
  3823  /*
  3824   * pc-relative branches
  3825   */
  3826  func (c *ctxt7) opbra(p *obj.Prog, a obj.As) uint32 {
  3827  	switch a {
  3828  	case ABEQ:
  3829  		return OPBcc(0x0)
  3830  
  3831  	case ABNE:
  3832  		return OPBcc(0x1)
  3833  
  3834  	case ABCS:
  3835  		return OPBcc(0x2)
  3836  
  3837  	case ABHS:
  3838  		return OPBcc(0x2)
  3839  
  3840  	case ABCC:
  3841  		return OPBcc(0x3)
  3842  
  3843  	case ABLO:
  3844  		return OPBcc(0x3)
  3845  
  3846  	case ABMI:
  3847  		return OPBcc(0x4)
  3848  
  3849  	case ABPL:
  3850  		return OPBcc(0x5)
  3851  
  3852  	case ABVS:
  3853  		return OPBcc(0x6)
  3854  
  3855  	case ABVC:
  3856  		return OPBcc(0x7)
  3857  
  3858  	case ABHI:
  3859  		return OPBcc(0x8)
  3860  
  3861  	case ABLS:
  3862  		return OPBcc(0x9)
  3863  
  3864  	case ABGE:
  3865  		return OPBcc(0xa)
  3866  
  3867  	case ABLT:
  3868  		return OPBcc(0xb)
  3869  
  3870  	case ABGT:
  3871  		return OPBcc(0xc)
  3872  
  3873  	case ABLE:
  3874  		return OPBcc(0xd) /* imm19<<5 | cond */
  3875  
  3876  	case AB:
  3877  		return 0<<31 | 5<<26 /* imm26 */
  3878  
  3879  	case obj.ADUFFZERO, obj.ADUFFCOPY, ABL:
  3880  		return 1<<31 | 5<<26
  3881  	}
  3882  
  3883  	c.ctxt.Diag("%v: bad bra %v", p, a)
  3884  	return 0
  3885  }
  3886  
  3887  func (c *ctxt7) opbrr(p *obj.Prog, a obj.As) uint32 {
  3888  	switch a {
  3889  	case ABL:
  3890  		return OPBLR(1) /* BLR */
  3891  
  3892  	case AB:
  3893  		return OPBLR(0) /* BR */
  3894  
  3895  	case obj.ARET:
  3896  		return OPBLR(2) /* RET */
  3897  	}
  3898  
  3899  	c.ctxt.Diag("%v: bad brr %v", p, a)
  3900  	return 0
  3901  }
  3902  
  3903  func (c *ctxt7) op0(p *obj.Prog, a obj.As) uint32 {
  3904  	switch a {
  3905  	case ADRPS:
  3906  		return 0x6B<<25 | 5<<21 | 0x1F<<16 | 0x1F<<5
  3907  
  3908  	case AERET:
  3909  		return 0x6B<<25 | 4<<21 | 0x1F<<16 | 0<<10 | 0x1F<<5
  3910  
  3911  	// case ANOP:
  3912  	// 	return SYSHINT(0)
  3913  
  3914  	case AYIELD:
  3915  		return SYSHINT(1)
  3916  
  3917  	case AWFE:
  3918  		return SYSHINT(2)
  3919  
  3920  	case AWFI:
  3921  		return SYSHINT(3)
  3922  
  3923  	case ASEV:
  3924  		return SYSHINT(4)
  3925  
  3926  	case ASEVL:
  3927  		return SYSHINT(5)
  3928  	}
  3929  
  3930  	c.ctxt.Diag("%v: bad op0 %v", p, a)
  3931  	return 0
  3932  }
  3933  
  3934  /*
  3935   * register offset
  3936   */
  3937  func (c *ctxt7) opload(p *obj.Prog, a obj.As) uint32 {
  3938  	switch a {
  3939  	case ALDAR:
  3940  		return LDSTX(3, 1, 1, 0, 1) | 0x1F<<10
  3941  
  3942  	case ALDARW:
  3943  		return LDSTX(2, 1, 1, 0, 1) | 0x1F<<10
  3944  
  3945  	case ALDARB:
  3946  		return LDSTX(0, 1, 1, 0, 1) | 0x1F<<10
  3947  
  3948  	case ALDARH:
  3949  		return LDSTX(1, 1, 1, 0, 1) | 0x1F<<10
  3950  
  3951  	case ALDAXP:
  3952  		return LDSTX(3, 0, 1, 1, 1)
  3953  
  3954  	case ALDAXPW:
  3955  		return LDSTX(2, 0, 1, 1, 1)
  3956  
  3957  	case ALDAXR:
  3958  		return LDSTX(3, 0, 1, 0, 1) | 0x1F<<10
  3959  
  3960  	case ALDAXRW:
  3961  		return LDSTX(2, 0, 1, 0, 1) | 0x1F<<10
  3962  
  3963  	case ALDAXRB:
  3964  		return LDSTX(0, 0, 1, 0, 1) | 0x1F<<10
  3965  
  3966  	case ALDAXRH:
  3967  		return LDSTX(1, 0, 1, 0, 1) | 0x1F<<10
  3968  
  3969  	case ALDXR:
  3970  		return LDSTX(3, 0, 1, 0, 0) | 0x1F<<10
  3971  
  3972  	case ALDXRB:
  3973  		return LDSTX(0, 0, 1, 0, 0) | 0x1F<<10
  3974  
  3975  	case ALDXRH:
  3976  		return LDSTX(1, 0, 1, 0, 0) | 0x1F<<10
  3977  
  3978  	case ALDXRW:
  3979  		return LDSTX(2, 0, 1, 0, 0) | 0x1F<<10
  3980  
  3981  	case ALDXP:
  3982  		return LDSTX(3, 0, 1, 1, 0)
  3983  
  3984  	case ALDXPW:
  3985  		return LDSTX(2, 0, 1, 1, 0)
  3986  
  3987  	case AMOVNP:
  3988  		return S64 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22
  3989  
  3990  	case AMOVNPW:
  3991  		return S32 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22
  3992  	}
  3993  
  3994  	c.ctxt.Diag("bad opload %v\n%v", a, p)
  3995  	return 0
  3996  }
  3997  
  3998  func (c *ctxt7) opstore(p *obj.Prog, a obj.As) uint32 {
  3999  	switch a {
  4000  	case ASTLR:
  4001  		return LDSTX(3, 1, 0, 0, 1) | 0x1F<<10
  4002  
  4003  	case ASTLRB:
  4004  		return LDSTX(0, 1, 0, 0, 1) | 0x1F<<10
  4005  
  4006  	case ASTLRH:
  4007  		return LDSTX(1, 1, 0, 0, 1) | 0x1F<<10
  4008  
  4009  	case ASTLP:
  4010  		return LDSTX(3, 0, 0, 1, 1)
  4011  
  4012  	case ASTLPW:
  4013  		return LDSTX(2, 0, 0, 1, 1)
  4014  
  4015  	case ASTLRW:
  4016  		return LDSTX(2, 1, 0, 0, 1) | 0x1F<<10
  4017  
  4018  	case ASTLXP:
  4019  		return LDSTX(2, 0, 0, 1, 1)
  4020  
  4021  	case ASTLXPW:
  4022  		return LDSTX(3, 0, 0, 1, 1)
  4023  
  4024  	case ASTLXR:
  4025  		return LDSTX(3, 0, 0, 0, 1) | 0x1F<<10
  4026  
  4027  	case ASTLXRB:
  4028  		return LDSTX(0, 0, 0, 0, 1) | 0x1F<<10
  4029  
  4030  	case ASTLXRH:
  4031  		return LDSTX(1, 0, 0, 0, 1) | 0x1F<<10
  4032  
  4033  	case ASTLXRW:
  4034  		return LDSTX(2, 0, 0, 0, 1) | 0x1F<<10
  4035  
  4036  	case ASTXR:
  4037  		return LDSTX(3, 0, 0, 0, 0) | 0x1F<<10
  4038  
  4039  	case ASTXRB:
  4040  		return LDSTX(0, 0, 0, 0, 0) | 0x1F<<10
  4041  
  4042  	case ASTXRH:
  4043  		return LDSTX(1, 0, 0, 0, 0) | 0x1F<<10
  4044  
  4045  	case ASTXP:
  4046  		return LDSTX(3, 0, 0, 1, 0)
  4047  
  4048  	case ASTXPW:
  4049  		return LDSTX(2, 0, 0, 1, 0)
  4050  
  4051  	case ASTXRW:
  4052  		return LDSTX(2, 0, 0, 0, 0) | 0x1F<<10
  4053  
  4054  	case AMOVNP:
  4055  		return S64 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22
  4056  
  4057  	case AMOVNPW:
  4058  		return S32 | 0<<30 | 5<<27 | 0<<26 | 0<<23 | 1<<22
  4059  	}
  4060  
  4061  	c.ctxt.Diag("bad opstore %v\n%v", a, p)
  4062  	return 0
  4063  }
  4064  
  4065  /*
  4066   * load/store register (unsigned immediate) C3.3.13
  4067   *	these produce 64-bit values (when there's an option)
  4068   */
  4069  func (c *ctxt7) olsr12u(p *obj.Prog, o int32, v int32, b int, r int) uint32 {
  4070  	if v < 0 || v >= (1<<12) {
  4071  		c.ctxt.Diag("offset out of range: %d\n%v", v, p)
  4072  	}
  4073  	o |= (v & 0xFFF) << 10
  4074  	o |= int32(b&31) << 5
  4075  	o |= int32(r & 31)
  4076  	return uint32(o)
  4077  }
  4078  
  4079  func (c *ctxt7) opldr12(p *obj.Prog, a obj.As) uint32 {
  4080  	switch a {
  4081  	case AMOVD:
  4082  		return LDSTR12U(3, 0, 1) /* imm12<<10 | Rn<<5 | Rt */
  4083  
  4084  	case AMOVW:
  4085  		return LDSTR12U(2, 0, 2)
  4086  
  4087  	case AMOVWU:
  4088  		return LDSTR12U(2, 0, 1)
  4089  
  4090  	case AMOVH:
  4091  		return LDSTR12U(1, 0, 2)
  4092  
  4093  	case AMOVHU:
  4094  		return LDSTR12U(1, 0, 1)
  4095  
  4096  	case AMOVB:
  4097  		return LDSTR12U(0, 0, 2)
  4098  
  4099  	case AMOVBU:
  4100  		return LDSTR12U(0, 0, 1)
  4101  
  4102  	case AFMOVS:
  4103  		return LDSTR12U(2, 1, 1)
  4104  
  4105  	case AFMOVD:
  4106  		return LDSTR12U(3, 1, 1)
  4107  	}
  4108  
  4109  	c.ctxt.Diag("bad opldr12 %v\n%v", a, p)
  4110  	return 0
  4111  }
  4112  
  4113  func (c *ctxt7) opstr12(p *obj.Prog, a obj.As) uint32 {
  4114  	return LD2STR(c.opldr12(p, a))
  4115  }
  4116  
  4117  /*
  4118   * load/store register (unscaled immediate) C3.3.12
  4119   */
  4120  func (c *ctxt7) olsr9s(p *obj.Prog, o int32, v int32, b int, r int) uint32 {
  4121  	if v < -256 || v > 255 {
  4122  		c.ctxt.Diag("offset out of range: %d\n%v", v, p)
  4123  	}
  4124  	o |= (v & 0x1FF) << 12
  4125  	o |= int32(b&31) << 5
  4126  	o |= int32(r & 31)
  4127  	return uint32(o)
  4128  }
  4129  
  4130  func (c *ctxt7) opldr9(p *obj.Prog, a obj.As) uint32 {
  4131  	switch a {
  4132  	case AMOVD:
  4133  		return LDSTR9S(3, 0, 1) /* simm9<<12 | Rn<<5 | Rt */
  4134  
  4135  	case AMOVW:
  4136  		return LDSTR9S(2, 0, 2)
  4137  
  4138  	case AMOVWU:
  4139  		return LDSTR9S(2, 0, 1)
  4140  
  4141  	case AMOVH:
  4142  		return LDSTR9S(1, 0, 2)
  4143  
  4144  	case AMOVHU:
  4145  		return LDSTR9S(1, 0, 1)
  4146  
  4147  	case AMOVB:
  4148  		return LDSTR9S(0, 0, 2)
  4149  
  4150  	case AMOVBU:
  4151  		return LDSTR9S(0, 0, 1)
  4152  
  4153  	case AFMOVS:
  4154  		return LDSTR9S(2, 1, 1)
  4155  
  4156  	case AFMOVD:
  4157  		return LDSTR9S(3, 1, 1)
  4158  	}
  4159  
  4160  	c.ctxt.Diag("bad opldr9 %v\n%v", a, p)
  4161  	return 0
  4162  }
  4163  
  4164  func (c *ctxt7) opstr9(p *obj.Prog, a obj.As) uint32 {
  4165  	return LD2STR(c.opldr9(p, a))
  4166  }
  4167  
  4168  func (c *ctxt7) opldrpp(p *obj.Prog, a obj.As) uint32 {
  4169  	switch a {
  4170  	case AMOVD:
  4171  		return 3<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22 /* simm9<<12 | Rn<<5 | Rt */
  4172  
  4173  	case AMOVW:
  4174  		return 2<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22
  4175  
  4176  	case AMOVWU:
  4177  		return 2<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22
  4178  
  4179  	case AMOVH:
  4180  		return 1<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22
  4181  
  4182  	case AMOVHU:
  4183  		return 1<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22
  4184  
  4185  	case AMOVB:
  4186  		return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 2<<22
  4187  
  4188  	case AMOVBU:
  4189  		return 0<<30 | 7<<27 | 0<<26 | 0<<24 | 1<<22
  4190  	}
  4191  
  4192  	c.ctxt.Diag("bad opldr %v\n%v", a, p)
  4193  	return 0
  4194  }
  4195  
  4196  /*
  4197   * load/store register (extended register)
  4198   */
  4199  func (c *ctxt7) olsxrr(p *obj.Prog, as obj.As, rt int, r1 int, r2 int) uint32 {
  4200  	c.ctxt.Diag("need load/store extended register\n%v", p)
  4201  	return 0xffffffff
  4202  }
  4203  
  4204  func (c *ctxt7) oaddi(p *obj.Prog, o1 int32, v int32, r int, rt int) uint32 {
  4205  	if (v & 0xFFF000) != 0 {
  4206  		if v&0xFFF != 0 {
  4207  			c.ctxt.Diag("%v misuses oaddi", p)
  4208  		}
  4209  		v >>= 12
  4210  		o1 |= 1 << 22
  4211  	}
  4212  
  4213  	o1 |= ((v & 0xFFF) << 10) | (int32(r&31) << 5) | int32(rt&31)
  4214  	return uint32(o1)
  4215  }
  4216  
  4217  /*
  4218   * load a a literal value into dr
  4219   */
  4220  func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
  4221  	var o1 int32
  4222  	if p.Pcond == nil { /* not in literal pool */
  4223  		c.aclass(a)
  4224  		c.ctxt.Logf("omovlit add %d (%#x)\n", c.instoffset, uint64(c.instoffset))
  4225  
  4226  		/* TODO: could be clever, and use general constant builder */
  4227  		o1 = int32(c.opirr(p, AADD))
  4228  
  4229  		v := int32(c.instoffset)
  4230  		if v != 0 && (v&0xFFF) == 0 {
  4231  			v >>= 12
  4232  			o1 |= 1 << 22 /* shift, by 12 */
  4233  		}
  4234  
  4235  		o1 |= ((v & 0xFFF) << 10) | (REGZERO & 31 << 5) | int32(dr&31)
  4236  	} else {
  4237  		fp := 0
  4238  		w := 0 /* default: 32 bit, unsigned */
  4239  		switch as {
  4240  		case AFMOVS:
  4241  			fp = 1
  4242  
  4243  		case AFMOVD:
  4244  			fp = 1
  4245  			w = 1 /* 64 bit simd&fp */
  4246  
  4247  		case AMOVD:
  4248  			if p.Pcond.As == ADWORD {
  4249  				w = 1 /* 64 bit */
  4250  			} else if p.Pcond.To.Offset < 0 {
  4251  				w = 2 /* sign extend */
  4252  			}
  4253  
  4254  		case AMOVB, AMOVH, AMOVW:
  4255  			w = 2 /* 32 bit, sign-extended to 64 */
  4256  			break
  4257  		}
  4258  
  4259  		v := int32(c.brdist(p, 0, 19, 2))
  4260  		o1 = (int32(w) << 30) | (int32(fp) << 26) | (3 << 27)
  4261  		o1 |= (v & 0x7FFFF) << 5
  4262  		o1 |= int32(dr & 31)
  4263  	}
  4264  
  4265  	return uint32(o1)
  4266  }
  4267  
  4268  // load a constant (MOVCON or BITCON) in a into rt
  4269  func (c *ctxt7) omovconst(as obj.As, p *obj.Prog, a *obj.Addr, rt int) (o1 uint32) {
  4270  	if cls := oclass(a); cls == C_BITCON || cls == C_ABCON || cls == C_ABCON0 {
  4271  		// or $bitcon, REGZERO, rt
  4272  		mode := 64
  4273  		var as1 obj.As
  4274  		switch as {
  4275  		case AMOVW:
  4276  			as1 = AORRW
  4277  			mode = 32
  4278  		case AMOVD:
  4279  			as1 = AORR
  4280  		}
  4281  		o1 = c.opirr(p, as1)
  4282  		o1 |= bitconEncode(uint64(a.Offset), mode) | uint32(REGZERO&31)<<5 | uint32(rt&31)
  4283  		return o1
  4284  	}
  4285  
  4286  	r := 32
  4287  	if as == AMOVD {
  4288  		r = 64
  4289  	}
  4290  	d := a.Offset
  4291  	s := movcon(d)
  4292  	if s < 0 || s >= r {
  4293  		d = ^d
  4294  		s = movcon(d)
  4295  		if s < 0 || s >= r {
  4296  			c.ctxt.Diag("impossible move wide: %#x\n%v", uint64(a.Offset), p)
  4297  		}
  4298  		if as == AMOVD {
  4299  			o1 = c.opirr(p, AMOVN)
  4300  		} else {
  4301  			o1 = c.opirr(p, AMOVNW)
  4302  		}
  4303  	} else {
  4304  		if as == AMOVD {
  4305  			o1 = c.opirr(p, AMOVZ)
  4306  		} else {
  4307  			o1 = c.opirr(p, AMOVZW)
  4308  		}
  4309  	}
  4310  	o1 |= uint32((((d >> uint(s*16)) & 0xFFFF) << 5) | int64((uint32(s)&3)<<21) | int64(rt&31))
  4311  	return o1
  4312  }
  4313  
  4314  func (c *ctxt7) opbfm(p *obj.Prog, a obj.As, r int, s int, rf int, rt int) uint32 {
  4315  	var b uint32
  4316  	o := c.opirr(p, a)
  4317  	if (o & (1 << 31)) == 0 {
  4318  		b = 32
  4319  	} else {
  4320  		b = 64
  4321  	}
  4322  	if r < 0 || uint32(r) >= b {
  4323  		c.ctxt.Diag("illegal bit number\n%v", p)
  4324  	}
  4325  	o |= (uint32(r) & 0x3F) << 16
  4326  	if s < 0 || uint32(s) >= b {
  4327  		c.ctxt.Diag("illegal bit number\n%v", p)
  4328  	}
  4329  	o |= (uint32(s) & 0x3F) << 10
  4330  	o |= (uint32(rf&31) << 5) | uint32(rt&31)
  4331  	return o
  4332  }
  4333  
  4334  func (c *ctxt7) opextr(p *obj.Prog, a obj.As, v int32, rn int, rm int, rt int) uint32 {
  4335  	var b uint32
  4336  	o := c.opirr(p, a)
  4337  	if (o & (1 << 31)) != 0 {
  4338  		b = 63
  4339  	} else {
  4340  		b = 31
  4341  	}
  4342  	if v < 0 || uint32(v) > b {
  4343  		c.ctxt.Diag("illegal bit number\n%v", p)
  4344  	}
  4345  	o |= uint32(v) << 10
  4346  	o |= uint32(rn&31) << 5
  4347  	o |= uint32(rm&31) << 16
  4348  	o |= uint32(rt & 31)
  4349  	return o
  4350  }
  4351  
  4352  /*
  4353   * size in log2(bytes)
  4354   */
  4355  func movesize(a obj.As) int {
  4356  	switch a {
  4357  	case AMOVD:
  4358  		return 3
  4359  
  4360  	case AMOVW, AMOVWU:
  4361  		return 2
  4362  
  4363  	case AMOVH, AMOVHU:
  4364  		return 1
  4365  
  4366  	case AMOVB, AMOVBU:
  4367  		return 0
  4368  
  4369  	case AFMOVS:
  4370  		return 2
  4371  
  4372  	case AFMOVD:
  4373  		return 3
  4374  
  4375  	default:
  4376  		return -1
  4377  	}
  4378  }