github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/src/cmd/internal/obj/arm64/asm7.go (about)

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