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