github.com/Rookout/GoSDK@v0.1.48/pkg/services/assembler/internal/obj/arm/asm5.go (about)

     1  // Inferno utils/5l/span.c
     2  // https://bitbucket.org/inferno-os/inferno-os/src/master/utils/5l/span.c
     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 arm
    32  
    33  import (
    34  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/obj"
    35  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/objabi"
    36  	"fmt"
    37  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/buildcfg"
    38  	"log"
    39  	"math"
    40  	"sort"
    41  )
    42  
    43  
    44  
    45  
    46  type ctxt5 struct {
    47  	ctxt       *obj.Link
    48  	newprog    obj.ProgAlloc
    49  	cursym     *obj.LSym
    50  	printp     *obj.Prog
    51  	blitrl     *obj.Prog
    52  	elitrl     *obj.Prog
    53  	autosize   int64
    54  	instoffset int64
    55  	pc         int64
    56  	pool       struct {
    57  		start uint32
    58  		size  uint32
    59  		extra uint32
    60  	}
    61  }
    62  
    63  type Optab struct {
    64  	as       obj.As
    65  	a1       uint8
    66  	a2       int8
    67  	a3       uint8
    68  	type_    uint8
    69  	size     int8
    70  	param    int16
    71  	flag     int8
    72  	pcrelsiz uint8
    73  	scond    uint8 
    74  }
    75  
    76  type Opcross [32][2][32]uint8
    77  
    78  const (
    79  	LFROM  = 1 << 0
    80  	LTO    = 1 << 1
    81  	LPOOL  = 1 << 2
    82  	LPCREL = 1 << 3
    83  )
    84  
    85  var optab = []Optab{
    86  	
    87  	{obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0, 0},
    88  	{AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0, C_SBIT},
    89  	{AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, C_SBIT},
    90  	{AAND, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0, C_SBIT},
    91  	{AAND, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, C_SBIT},
    92  	{AORR, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0, C_SBIT},
    93  	{AORR, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, C_SBIT},
    94  	{AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, C_SBIT},
    95  	{AMVN, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, C_SBIT},
    96  	{ACMP, C_REG, C_REG, C_NONE, 1, 4, 0, 0, 0, 0},
    97  	{AADD, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0, C_SBIT},
    98  	{AADD, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0, C_SBIT},
    99  	{AAND, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0, C_SBIT},
   100  	{AAND, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0, C_SBIT},
   101  	{AORR, C_RCON, C_REG, C_REG, 2, 4, 0, 0, 0, C_SBIT},
   102  	{AORR, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0, C_SBIT},
   103  	{AMOVW, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0, 0},
   104  	{AMVN, C_RCON, C_NONE, C_REG, 2, 4, 0, 0, 0, 0},
   105  	{ACMP, C_RCON, C_REG, C_NONE, 2, 4, 0, 0, 0, 0},
   106  	{AADD, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0, C_SBIT},
   107  	{AADD, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0, C_SBIT},
   108  	{AAND, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0, C_SBIT},
   109  	{AAND, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0, C_SBIT},
   110  	{AORR, C_SHIFT, C_REG, C_REG, 3, 4, 0, 0, 0, C_SBIT},
   111  	{AORR, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0, C_SBIT},
   112  	{AMVN, C_SHIFT, C_NONE, C_REG, 3, 4, 0, 0, 0, C_SBIT},
   113  	{ACMP, C_SHIFT, C_REG, C_NONE, 3, 4, 0, 0, 0, 0},
   114  	{AMOVW, C_RACON, C_NONE, C_REG, 4, 4, REGSP, 0, 0, C_SBIT},
   115  	{AB, C_NONE, C_NONE, C_SBRA, 5, 4, 0, LPOOL, 0, 0},
   116  	{ABL, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0, 0},
   117  	{ABX, C_NONE, C_NONE, C_SBRA, 74, 20, 0, 0, 0, 0},
   118  	{ABEQ, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0, 0},
   119  	{ABEQ, C_RCON, C_NONE, C_SBRA, 5, 4, 0, 0, 0, 0}, 
   120  	{AB, C_NONE, C_NONE, C_ROREG, 6, 4, 0, LPOOL, 0, 0},
   121  	{ABL, C_NONE, C_NONE, C_ROREG, 7, 4, 0, 0, 0, 0},
   122  	{ABL, C_REG, C_NONE, C_ROREG, 7, 4, 0, 0, 0, 0},
   123  	{ABX, C_NONE, C_NONE, C_ROREG, 75, 12, 0, 0, 0, 0},
   124  	{ABXRET, C_NONE, C_NONE, C_ROREG, 76, 4, 0, 0, 0, 0},
   125  	{ASLL, C_RCON, C_REG, C_REG, 8, 4, 0, 0, 0, C_SBIT},
   126  	{ASLL, C_RCON, C_NONE, C_REG, 8, 4, 0, 0, 0, C_SBIT},
   127  	{ASLL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0, C_SBIT},
   128  	{ASLL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0, C_SBIT},
   129  	{ASWI, C_NONE, C_NONE, C_NONE, 10, 4, 0, 0, 0, 0},
   130  	{ASWI, C_NONE, C_NONE, C_LCON, 10, 4, 0, 0, 0, 0},
   131  	{AWORD, C_NONE, C_NONE, C_LCON, 11, 4, 0, 0, 0, 0},
   132  	{AWORD, C_NONE, C_NONE, C_LCONADDR, 11, 4, 0, 0, 0, 0},
   133  	{AWORD, C_NONE, C_NONE, C_ADDR, 11, 4, 0, 0, 0, 0},
   134  	{AWORD, C_NONE, C_NONE, C_TLS_LE, 103, 4, 0, 0, 0, 0},
   135  	{AWORD, C_NONE, C_NONE, C_TLS_IE, 104, 4, 0, 0, 0, 0},
   136  	{AMOVW, C_NCON, C_NONE, C_REG, 12, 4, 0, 0, 0, 0},
   137  	{AMOVW, C_SCON, C_NONE, C_REG, 12, 4, 0, 0, 0, 0},
   138  	{AMOVW, C_LCON, C_NONE, C_REG, 12, 4, 0, LFROM, 0, 0},
   139  	{AMOVW, C_LCONADDR, C_NONE, C_REG, 12, 4, 0, LFROM | LPCREL, 4, 0},
   140  	{AMVN, C_NCON, C_NONE, C_REG, 12, 4, 0, 0, 0, 0},
   141  	{AADD, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   142  	{AADD, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   143  	{AAND, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   144  	{AAND, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   145  	{AORR, C_NCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   146  	{AORR, C_NCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   147  	{ACMP, C_NCON, C_REG, C_NONE, 13, 8, 0, 0, 0, 0},
   148  	{AADD, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   149  	{AADD, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   150  	{AAND, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   151  	{AAND, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   152  	{AORR, C_SCON, C_REG, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   153  	{AORR, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0, C_SBIT},
   154  	{AMVN, C_SCON, C_NONE, C_REG, 13, 8, 0, 0, 0, 0},
   155  	{ACMP, C_SCON, C_REG, C_NONE, 13, 8, 0, 0, 0, 0},
   156  	{AADD, C_RCON2A, C_REG, C_REG, 106, 8, 0, 0, 0, 0},
   157  	{AADD, C_RCON2A, C_NONE, C_REG, 106, 8, 0, 0, 0, 0},
   158  	{AORR, C_RCON2A, C_REG, C_REG, 106, 8, 0, 0, 0, 0},
   159  	{AORR, C_RCON2A, C_NONE, C_REG, 106, 8, 0, 0, 0, 0},
   160  	{AADD, C_RCON2S, C_REG, C_REG, 107, 8, 0, 0, 0, 0},
   161  	{AADD, C_RCON2S, C_NONE, C_REG, 107, 8, 0, 0, 0, 0},
   162  	{AADD, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
   163  	{AADD, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
   164  	{AAND, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
   165  	{AAND, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
   166  	{AORR, C_LCON, C_REG, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
   167  	{AORR, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0, C_SBIT},
   168  	{AMVN, C_LCON, C_NONE, C_REG, 13, 8, 0, LFROM, 0, 0},
   169  	{ACMP, C_LCON, C_REG, C_NONE, 13, 8, 0, LFROM, 0, 0},
   170  	{AMOVB, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, 0},
   171  	{AMOVBS, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0, 0},
   172  	{AMOVBU, C_REG, C_NONE, C_REG, 58, 4, 0, 0, 0, 0},
   173  	{AMOVH, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0, 0},
   174  	{AMOVHS, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0, 0},
   175  	{AMOVHU, C_REG, C_NONE, C_REG, 14, 8, 0, 0, 0, 0},
   176  	{AMUL, C_REG, C_REG, C_REG, 15, 4, 0, 0, 0, C_SBIT},
   177  	{AMUL, C_REG, C_NONE, C_REG, 15, 4, 0, 0, 0, C_SBIT},
   178  	{ADIV, C_REG, C_REG, C_REG, 16, 4, 0, 0, 0, 0},
   179  	{ADIV, C_REG, C_NONE, C_REG, 16, 4, 0, 0, 0, 0},
   180  	{ADIVHW, C_REG, C_REG, C_REG, 105, 4, 0, 0, 0, 0},
   181  	{ADIVHW, C_REG, C_NONE, C_REG, 105, 4, 0, 0, 0, 0},
   182  	{AMULL, C_REG, C_REG, C_REGREG, 17, 4, 0, 0, 0, C_SBIT},
   183  	{ABFX, C_LCON, C_REG, C_REG, 18, 4, 0, 0, 0, 0},  
   184  	{ABFX, C_LCON, C_NONE, C_REG, 18, 4, 0, 0, 0, 0}, 
   185  	{AMOVW, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   186  	{AMOVW, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   187  	{AMOVB, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   188  	{AMOVB, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   189  	{AMOVBS, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   190  	{AMOVBS, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   191  	{AMOVBU, C_REG, C_NONE, C_SAUTO, 20, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   192  	{AMOVBU, C_REG, C_NONE, C_SOREG, 20, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   193  	{AMOVW, C_SAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   194  	{AMOVW, C_SOREG, C_NONE, C_REG, 21, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   195  	{AMOVBU, C_SAUTO, C_NONE, C_REG, 21, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   196  	{AMOVBU, C_SOREG, C_NONE, C_REG, 21, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   197  	{AXTAB, C_SHIFT, C_REG, C_REG, 22, 4, 0, 0, 0, 0},
   198  	{AXTAB, C_SHIFT, C_NONE, C_REG, 22, 4, 0, 0, 0, 0},
   199  	{AMOVW, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, C_SBIT},
   200  	{AMOVB, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
   201  	{AMOVBS, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
   202  	{AMOVBU, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
   203  	{AMOVH, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
   204  	{AMOVHS, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
   205  	{AMOVHU, C_SHIFT, C_NONE, C_REG, 23, 4, 0, 0, 0, 0},
   206  	{AMOVW, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   207  	{AMOVW, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   208  	{AMOVW, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   209  	{AMOVB, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   210  	{AMOVB, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   211  	{AMOVB, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   212  	{AMOVBS, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   213  	{AMOVBS, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   214  	{AMOVBS, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   215  	{AMOVBU, C_REG, C_NONE, C_LAUTO, 30, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   216  	{AMOVBU, C_REG, C_NONE, C_LOREG, 30, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   217  	{AMOVBU, C_REG, C_NONE, C_ADDR, 64, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   218  	{AMOVW, C_TLS_LE, C_NONE, C_REG, 101, 4, 0, LFROM, 0, 0},
   219  	{AMOVW, C_TLS_IE, C_NONE, C_REG, 102, 8, 0, LFROM, 0, 0},
   220  	{AMOVW, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   221  	{AMOVW, C_LOREG, C_NONE, C_REG, 31, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   222  	{AMOVW, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   223  	{AMOVBU, C_LAUTO, C_NONE, C_REG, 31, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   224  	{AMOVBU, C_LOREG, C_NONE, C_REG, 31, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   225  	{AMOVBU, C_ADDR, C_NONE, C_REG, 65, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   226  	{AMOVW, C_LACON, C_NONE, C_REG, 34, 8, REGSP, LFROM, 0, C_SBIT},
   227  	{AMOVW, C_PSR, C_NONE, C_REG, 35, 4, 0, 0, 0, 0},
   228  	{AMOVW, C_REG, C_NONE, C_PSR, 36, 4, 0, 0, 0, 0},
   229  	{AMOVW, C_RCON, C_NONE, C_PSR, 37, 4, 0, 0, 0, 0},
   230  	{AMOVM, C_REGLIST, C_NONE, C_SOREG, 38, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   231  	{AMOVM, C_SOREG, C_NONE, C_REGLIST, 39, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   232  	{ASWPW, C_SOREG, C_REG, C_REG, 40, 4, 0, 0, 0, 0},
   233  	{ARFE, C_NONE, C_NONE, C_NONE, 41, 4, 0, 0, 0, 0},
   234  	{AMOVF, C_FREG, C_NONE, C_FAUTO, 50, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   235  	{AMOVF, C_FREG, C_NONE, C_FOREG, 50, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   236  	{AMOVF, C_FAUTO, C_NONE, C_FREG, 51, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   237  	{AMOVF, C_FOREG, C_NONE, C_FREG, 51, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   238  	{AMOVF, C_FREG, C_NONE, C_LAUTO, 52, 12, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   239  	{AMOVF, C_FREG, C_NONE, C_LOREG, 52, 12, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   240  	{AMOVF, C_LAUTO, C_NONE, C_FREG, 53, 12, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   241  	{AMOVF, C_LOREG, C_NONE, C_FREG, 53, 12, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   242  	{AMOVF, C_FREG, C_NONE, C_ADDR, 68, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   243  	{AMOVF, C_ADDR, C_NONE, C_FREG, 69, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   244  	{AADDF, C_FREG, C_NONE, C_FREG, 54, 4, 0, 0, 0, 0},
   245  	{AADDF, C_FREG, C_FREG, C_FREG, 54, 4, 0, 0, 0, 0},
   246  	{AMOVF, C_FREG, C_NONE, C_FREG, 55, 4, 0, 0, 0, 0},
   247  	{ANEGF, C_FREG, C_NONE, C_FREG, 55, 4, 0, 0, 0, 0},
   248  	{AMOVW, C_REG, C_NONE, C_FCR, 56, 4, 0, 0, 0, 0},
   249  	{AMOVW, C_FCR, C_NONE, C_REG, 57, 4, 0, 0, 0, 0},
   250  	{AMOVW, C_SHIFTADDR, C_NONE, C_REG, 59, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   251  	{AMOVBU, C_SHIFTADDR, C_NONE, C_REG, 59, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   252  	{AMOVB, C_SHIFTADDR, C_NONE, C_REG, 60, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   253  	{AMOVBS, C_SHIFTADDR, C_NONE, C_REG, 60, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   254  	{AMOVH, C_SHIFTADDR, C_NONE, C_REG, 60, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   255  	{AMOVHS, C_SHIFTADDR, C_NONE, C_REG, 60, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   256  	{AMOVHU, C_SHIFTADDR, C_NONE, C_REG, 60, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   257  	{AMOVW, C_REG, C_NONE, C_SHIFTADDR, 61, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   258  	{AMOVB, C_REG, C_NONE, C_SHIFTADDR, 61, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   259  	{AMOVBS, C_REG, C_NONE, C_SHIFTADDR, 61, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   260  	{AMOVBU, C_REG, C_NONE, C_SHIFTADDR, 61, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   261  	{AMOVH, C_REG, C_NONE, C_SHIFTADDR, 62, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   262  	{AMOVHS, C_REG, C_NONE, C_SHIFTADDR, 62, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   263  	{AMOVHU, C_REG, C_NONE, C_SHIFTADDR, 62, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   264  	{AMOVH, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   265  	{AMOVH, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   266  	{AMOVHS, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   267  	{AMOVHS, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   268  	{AMOVHU, C_REG, C_NONE, C_HAUTO, 70, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   269  	{AMOVHU, C_REG, C_NONE, C_HOREG, 70, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   270  	{AMOVB, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   271  	{AMOVB, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   272  	{AMOVBS, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   273  	{AMOVBS, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   274  	{AMOVH, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   275  	{AMOVH, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   276  	{AMOVHS, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   277  	{AMOVHS, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   278  	{AMOVHU, C_HAUTO, C_NONE, C_REG, 71, 4, REGSP, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   279  	{AMOVHU, C_HOREG, C_NONE, C_REG, 71, 4, 0, 0, 0, C_PBIT | C_WBIT | C_UBIT},
   280  	{AMOVH, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   281  	{AMOVH, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   282  	{AMOVH, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   283  	{AMOVHS, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   284  	{AMOVHS, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   285  	{AMOVHS, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   286  	{AMOVHU, C_REG, C_NONE, C_LAUTO, 72, 8, REGSP, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   287  	{AMOVHU, C_REG, C_NONE, C_LOREG, 72, 8, 0, LTO, 0, C_PBIT | C_WBIT | C_UBIT},
   288  	{AMOVHU, C_REG, C_NONE, C_ADDR, 94, 8, 0, LTO | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   289  	{AMOVB, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   290  	{AMOVB, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   291  	{AMOVB, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   292  	{AMOVBS, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   293  	{AMOVBS, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   294  	{AMOVBS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   295  	{AMOVH, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   296  	{AMOVH, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   297  	{AMOVH, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   298  	{AMOVHS, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   299  	{AMOVHS, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   300  	{AMOVHS, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   301  	{AMOVHU, C_LAUTO, C_NONE, C_REG, 73, 8, REGSP, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   302  	{AMOVHU, C_LOREG, C_NONE, C_REG, 73, 8, 0, LFROM, 0, C_PBIT | C_WBIT | C_UBIT},
   303  	{AMOVHU, C_ADDR, C_NONE, C_REG, 93, 8, 0, LFROM | LPCREL, 4, C_PBIT | C_WBIT | C_UBIT},
   304  	{ALDREX, C_SOREG, C_NONE, C_REG, 77, 4, 0, 0, 0, 0},
   305  	{ASTREX, C_SOREG, C_REG, C_REG, 78, 4, 0, 0, 0, 0},
   306  	{ADMB, C_NONE, C_NONE, C_NONE, 110, 4, 0, 0, 0, 0},
   307  	{ADMB, C_LCON, C_NONE, C_NONE, 110, 4, 0, 0, 0, 0},
   308  	{ADMB, C_SPR, C_NONE, C_NONE, 110, 4, 0, 0, 0, 0},
   309  	{AMOVF, C_ZFCON, C_NONE, C_FREG, 80, 8, 0, 0, 0, 0},
   310  	{AMOVF, C_SFCON, C_NONE, C_FREG, 81, 4, 0, 0, 0, 0},
   311  	{ACMPF, C_FREG, C_FREG, C_NONE, 82, 8, 0, 0, 0, 0},
   312  	{ACMPF, C_FREG, C_NONE, C_NONE, 83, 8, 0, 0, 0, 0},
   313  	{AMOVFW, C_FREG, C_NONE, C_FREG, 84, 4, 0, 0, 0, C_UBIT},
   314  	{AMOVWF, C_FREG, C_NONE, C_FREG, 85, 4, 0, 0, 0, C_UBIT},
   315  	{AMOVFW, C_FREG, C_NONE, C_REG, 86, 8, 0, 0, 0, C_UBIT},
   316  	{AMOVWF, C_REG, C_NONE, C_FREG, 87, 8, 0, 0, 0, C_UBIT},
   317  	{AMOVW, C_REG, C_NONE, C_FREG, 88, 4, 0, 0, 0, 0},
   318  	{AMOVW, C_FREG, C_NONE, C_REG, 89, 4, 0, 0, 0, 0},
   319  	{ALDREXD, C_SOREG, C_NONE, C_REG, 91, 4, 0, 0, 0, 0},
   320  	{ASTREXD, C_SOREG, C_REG, C_REG, 92, 4, 0, 0, 0, 0},
   321  	{APLD, C_SOREG, C_NONE, C_NONE, 95, 4, 0, 0, 0, 0},
   322  	{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 96, 4, 0, 0, 0, 0},
   323  	{ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0, 0, 0, 0},
   324  	{AMULWT, C_REG, C_REG, C_REG, 98, 4, 0, 0, 0, 0},
   325  	{AMULA, C_REG, C_REG, C_REGREG2, 99, 4, 0, 0, 0, C_SBIT},
   326  	{AMULAWT, C_REG, C_REG, C_REGREG2, 99, 4, 0, 0, 0, 0},
   327  	{obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0, 0, 0},
   328  	{obj.AFUNCDATA, C_LCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0, 0},
   329  	{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0, 0},
   330  	{obj.ANOP, C_LCON, C_NONE, C_NONE, 0, 0, 0, 0, 0, 0}, 
   331  	{obj.ANOP, C_REG, C_NONE, C_NONE, 0, 0, 0, 0, 0, 0},
   332  	{obj.ANOP, C_FREG, C_NONE, C_NONE, 0, 0, 0, 0, 0, 0},
   333  	{obj.ADUFFZERO, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0, 0}, 
   334  	{obj.ADUFFCOPY, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0, 0}, 
   335  	{obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0, 0},
   336  }
   337  
   338  var mbOp = []struct {
   339  	reg int16
   340  	enc uint32
   341  }{
   342  	{REG_MB_SY, 15},
   343  	{REG_MB_ST, 14},
   344  	{REG_MB_ISH, 11},
   345  	{REG_MB_ISHST, 10},
   346  	{REG_MB_NSH, 7},
   347  	{REG_MB_NSHST, 6},
   348  	{REG_MB_OSH, 3},
   349  	{REG_MB_OSHST, 2},
   350  }
   351  
   352  var oprange [ALAST & obj.AMask][]Optab
   353  
   354  var xcmp [C_GOK + 1][C_GOK + 1]bool
   355  
   356  var (
   357  	symdiv  *obj.LSym
   358  	symdivu *obj.LSym
   359  	symmod  *obj.LSym
   360  	symmodu *obj.LSym
   361  )
   362  
   363  
   364  
   365  
   366  
   367  
   368  func checkSuffix(c *ctxt5, p *obj.Prog, o *Optab) {
   369  	if p.Scond&C_SBIT != 0 && o.scond&C_SBIT == 0 {
   370  		c.ctxt.Diag("invalid .S suffix: %v", p)
   371  	}
   372  	if p.Scond&C_PBIT != 0 && o.scond&C_PBIT == 0 {
   373  		c.ctxt.Diag("invalid .P suffix: %v", p)
   374  	}
   375  	if p.Scond&C_WBIT != 0 && o.scond&C_WBIT == 0 {
   376  		c.ctxt.Diag("invalid .W suffix: %v", p)
   377  	}
   378  	if p.Scond&C_UBIT != 0 && o.scond&C_UBIT == 0 {
   379  		c.ctxt.Diag("invalid .U suffix: %v", p)
   380  	}
   381  }
   382  
   383  func span5(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
   384  	if ctxt.Retpoline {
   385  		ctxt.Diag("-spectre=ret not supported on arm")
   386  		ctxt.Retpoline = false 
   387  	}
   388  
   389  	var p *obj.Prog
   390  	var op *obj.Prog
   391  
   392  	p = cursym.Func().Text
   393  	if p == nil || p.Link == nil { 
   394  		return
   395  	}
   396  
   397  	if oprange[AAND&obj.AMask] == nil {
   398  		ctxt.Diag("arm ops not initialized, call arm.buildop first")
   399  	}
   400  
   401  	c := ctxt5{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: p.To.Offset + 4}
   402  	pc := int32(0)
   403  
   404  	op = p
   405  	p = p.Link
   406  	var m int
   407  	var o *Optab
   408  	for ; p != nil || c.blitrl != nil; op, p = p, p.Link {
   409  		if p == nil {
   410  			if c.checkpool(op, pc) {
   411  				p = op
   412  				continue
   413  			}
   414  
   415  			
   416  			ctxt.Diag("internal inconsistency")
   417  
   418  			break
   419  		}
   420  
   421  		p.Pc = int64(pc)
   422  		o = c.oplook(p)
   423  		m = int(o.size)
   424  
   425  		if m%4 != 0 || p.Pc%4 != 0 {
   426  			ctxt.Diag("!pc invalid: %v size=%d", p, m)
   427  		}
   428  
   429  		
   430  		if c.blitrl != nil {
   431  			
   432  			
   433  			if c.checkpool(op, pc+int32(m)) {
   434  				
   435  				
   436  				
   437  				p = op
   438  				continue
   439  			}
   440  		}
   441  
   442  		if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.ANOP) {
   443  			ctxt.Diag("zero-width instruction\n%v", p)
   444  			continue
   445  		}
   446  
   447  		switch o.flag & (LFROM | LTO | LPOOL) {
   448  		case LFROM:
   449  			c.addpool(p, &p.From)
   450  
   451  		case LTO:
   452  			c.addpool(p, &p.To)
   453  
   454  		case LPOOL:
   455  			if p.Scond&C_SCOND == C_SCOND_NONE {
   456  				c.flushpool(p, 0, 0)
   457  			}
   458  		}
   459  
   460  		if p.As == AMOVW && p.To.Type == obj.TYPE_REG && p.To.Reg == REGPC && p.Scond&C_SCOND == C_SCOND_NONE {
   461  			c.flushpool(p, 0, 0)
   462  		}
   463  
   464  		pc += int32(m)
   465  	}
   466  
   467  	c.cursym.Size = int64(pc)
   468  
   469  	
   470  	times := 0
   471  
   472  	var bflag int
   473  	var opc int32
   474  	var out [6 + 3]uint32
   475  	for {
   476  		bflag = 0
   477  		pc = 0
   478  		times++
   479  		c.cursym.Func().Text.Pc = 0 
   480  		for p = c.cursym.Func().Text; p != nil; p = p.Link {
   481  			o = c.oplook(p)
   482  			if int64(pc) > p.Pc {
   483  				p.Pc = int64(pc)
   484  			}
   485  
   486  			
   487  			opc = int32(p.Pc)
   488  			m = int(o.size)
   489  			if p.Pc != int64(opc) {
   490  				bflag = 1
   491  			}
   492  
   493  			
   494  			pc = int32(p.Pc + int64(m))
   495  
   496  			if m%4 != 0 || p.Pc%4 != 0 {
   497  				ctxt.Diag("pc invalid: %v size=%d", p, m)
   498  			}
   499  
   500  			if m/4 > len(out) {
   501  				ctxt.Diag("instruction size too large: %d > %d", m/4, len(out))
   502  			}
   503  			if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.ANOP) {
   504  				if p.As == obj.ATEXT {
   505  					c.autosize = p.To.Offset + 4
   506  					continue
   507  				}
   508  
   509  				ctxt.Diag("zero-width instruction\n%v", p)
   510  				continue
   511  			}
   512  		}
   513  
   514  		c.cursym.Size = int64(pc)
   515  		if bflag == 0 {
   516  			break
   517  		}
   518  	}
   519  
   520  	if pc%4 != 0 {
   521  		ctxt.Diag("sym->size=%d, invalid", pc)
   522  	}
   523  
   524  	
   525  
   526  	p = c.cursym.Func().Text
   527  	c.autosize = p.To.Offset + 4
   528  	c.cursym.Grow(c.cursym.Size)
   529  
   530  	bp := c.cursym.P
   531  	pc = int32(p.Pc) 
   532  	var v int
   533  	for p = p.Link; p != nil; p = p.Link {
   534  		c.pc = p.Pc
   535  		o = c.oplook(p)
   536  		opc = int32(p.Pc)
   537  		c.asmout(p, o, out[:])
   538  		m = int(o.size)
   539  
   540  		if m%4 != 0 || p.Pc%4 != 0 {
   541  			ctxt.Diag("final stage: pc invalid: %v size=%d", p, m)
   542  		}
   543  
   544  		if int64(pc) > p.Pc {
   545  			ctxt.Diag("PC padding invalid: want %#d, has %#d: %v", p.Pc, pc, p)
   546  		}
   547  		for int64(pc) != p.Pc {
   548  			
   549  			bp[0] = 0x00
   550  			bp = bp[1:]
   551  
   552  			bp[0] = 0x00
   553  			bp = bp[1:]
   554  			bp[0] = 0xa0
   555  			bp = bp[1:]
   556  			bp[0] = 0xe1
   557  			bp = bp[1:]
   558  			pc += 4
   559  		}
   560  
   561  		for i := 0; i < m/4; i++ {
   562  			v = int(out[i])
   563  			bp[0] = byte(v)
   564  			bp = bp[1:]
   565  			bp[0] = byte(v >> 8)
   566  			bp = bp[1:]
   567  			bp[0] = byte(v >> 16)
   568  			bp = bp[1:]
   569  			bp[0] = byte(v >> 24)
   570  			bp = bp[1:]
   571  		}
   572  
   573  		pc += int32(m)
   574  	}
   575  }
   576  
   577  
   578  
   579  
   580  
   581  
   582  
   583  
   584  
   585  
   586  func (c *ctxt5) checkpool(p *obj.Prog, nextpc int32) bool {
   587  	poolLast := nextpc
   588  	poolLast += 4                      
   589  	poolLast += int32(c.pool.size) - 4 
   590  
   591  	refPC := int32(c.pool.start) 
   592  
   593  	v := poolLast - refPC - 8 
   594  
   595  	if c.pool.size >= 0xff0 || immaddr(v) == 0 {
   596  		return c.flushpool(p, 1, 0)
   597  	} else if p.Link == nil {
   598  		return c.flushpool(p, 2, 0)
   599  	}
   600  	return false
   601  }
   602  
   603  func (c *ctxt5) flushpool(p *obj.Prog, skip int, force int) bool {
   604  	if c.blitrl != nil {
   605  		if skip != 0 {
   606  			if false && skip == 1 {
   607  				fmt.Printf("note: flush literal pool at %x: len=%d ref=%x\n", uint64(p.Pc+4), c.pool.size, c.pool.start)
   608  			}
   609  			q := c.newprog()
   610  			q.As = AB
   611  			q.To.Type = obj.TYPE_BRANCH
   612  			q.To.SetTarget(p.Link)
   613  			q.Link = c.blitrl
   614  			q.Pos = p.Pos
   615  			c.blitrl = q
   616  		} else if force == 0 && (p.Pc+int64(c.pool.size)-int64(c.pool.start) < 2048) {
   617  			return false
   618  		}
   619  
   620  		
   621  		
   622  		
   623  		for q := c.blitrl; q != nil; q = q.Link {
   624  			q.Pos = p.Pos
   625  		}
   626  
   627  		c.elitrl.Link = p.Link
   628  		p.Link = c.blitrl
   629  
   630  		c.blitrl = nil 
   631  		c.elitrl = nil
   632  		c.pool.size = 0
   633  		c.pool.start = 0
   634  		c.pool.extra = 0
   635  		return true
   636  	}
   637  
   638  	return false
   639  }
   640  
   641  func (c *ctxt5) addpool(p *obj.Prog, a *obj.Addr) {
   642  	t := c.newprog()
   643  	t.As = AWORD
   644  
   645  	switch c.aclass(a) {
   646  	default:
   647  		t.To.Offset = a.Offset
   648  		t.To.Sym = a.Sym
   649  		t.To.Type = a.Type
   650  		t.To.Name = a.Name
   651  
   652  		if c.ctxt.Flag_shared && t.To.Sym != nil {
   653  			t.Rel = p
   654  		}
   655  
   656  	case C_SROREG,
   657  		C_LOREG,
   658  		C_ROREG,
   659  		C_FOREG,
   660  		C_SOREG,
   661  		C_HOREG,
   662  		C_FAUTO,
   663  		C_SAUTO,
   664  		C_LAUTO,
   665  		C_LACON:
   666  		t.To.Type = obj.TYPE_CONST
   667  		t.To.Offset = c.instoffset
   668  	}
   669  
   670  	if t.Rel == nil {
   671  		for q := c.blitrl; q != nil; q = q.Link { 
   672  			if q.Rel == nil && q.To == t.To {
   673  				p.Pool = q
   674  				return
   675  			}
   676  		}
   677  	}
   678  
   679  	q := c.newprog()
   680  	*q = *t
   681  	q.Pc = int64(c.pool.size)
   682  
   683  	if c.blitrl == nil {
   684  		c.blitrl = q
   685  		c.pool.start = uint32(p.Pc)
   686  	} else {
   687  		c.elitrl.Link = q
   688  	}
   689  	c.elitrl = q
   690  	c.pool.size += 4
   691  
   692  	
   693  	p.Pool = q
   694  }
   695  
   696  func (c *ctxt5) regoff(a *obj.Addr) int32 {
   697  	c.instoffset = 0
   698  	c.aclass(a)
   699  	return int32(c.instoffset)
   700  }
   701  
   702  func immrot(v uint32) int32 {
   703  	for i := 0; i < 16; i++ {
   704  		if v&^0xff == 0 {
   705  			return int32(uint32(int32(i)<<8) | v | 1<<25)
   706  		}
   707  		v = v<<2 | v>>30
   708  	}
   709  
   710  	return 0
   711  }
   712  
   713  
   714  
   715  
   716  func immrot2a(v uint32) (uint32, uint32) {
   717  	for i := uint(1); i < 32; i++ {
   718  		m := uint32(1<<i - 1)
   719  		if x, y := immrot(v&m), immrot(v&^m); x != 0 && y != 0 {
   720  			return uint32(x), uint32(y)
   721  		}
   722  	}
   723  	
   724  	
   725  	return 0, 0
   726  }
   727  
   728  
   729  
   730  
   731  func immrot2s(v uint32) (uint32, uint32) {
   732  	if immrot(v) != 0 {
   733  		return v, 0
   734  	}
   735  	
   736  	
   737  	var i uint32
   738  	for i = 2; i < 32; i += 2 {
   739  		if v&(1<<i-1) != 0 {
   740  			break
   741  		}
   742  	}
   743  	
   744  	i += 6
   745  	
   746  	x := 1<<i - v&(1<<i-1)
   747  	y := v + x
   748  	if y, x = uint32(immrot(y)), uint32(immrot(x)); y != 0 && x != 0 {
   749  		return y, x
   750  	}
   751  	return 0, 0
   752  }
   753  
   754  func immaddr(v int32) int32 {
   755  	if v >= 0 && v <= 0xfff {
   756  		return v&0xfff | 1<<24 | 1<<23  
   757  	}
   758  	if v >= -0xfff && v < 0 {
   759  		return -v&0xfff | 1<<24 
   760  	}
   761  	return 0
   762  }
   763  
   764  func immfloat(v int32) bool {
   765  	return v&0xC03 == 0 
   766  }
   767  
   768  func immhalf(v int32) bool {
   769  	if v >= 0 && v <= 0xff {
   770  		return v|1<<24|1<<23 != 0  
   771  	}
   772  	if v >= -0xff && v < 0 {
   773  		return -v&0xff|1<<24 != 0 
   774  	}
   775  	return false
   776  }
   777  
   778  func (c *ctxt5) aclass(a *obj.Addr) int {
   779  	switch a.Type {
   780  	case obj.TYPE_NONE:
   781  		return C_NONE
   782  
   783  	case obj.TYPE_REG:
   784  		c.instoffset = 0
   785  		if REG_R0 <= a.Reg && a.Reg <= REG_R15 {
   786  			return C_REG
   787  		}
   788  		if REG_F0 <= a.Reg && a.Reg <= REG_F15 {
   789  			return C_FREG
   790  		}
   791  		if a.Reg == REG_FPSR || a.Reg == REG_FPCR {
   792  			return C_FCR
   793  		}
   794  		if a.Reg == REG_CPSR || a.Reg == REG_SPSR {
   795  			return C_PSR
   796  		}
   797  		if a.Reg >= REG_SPECIAL {
   798  			return C_SPR
   799  		}
   800  		return C_GOK
   801  
   802  	case obj.TYPE_REGREG:
   803  		return C_REGREG
   804  
   805  	case obj.TYPE_REGREG2:
   806  		return C_REGREG2
   807  
   808  	case obj.TYPE_REGLIST:
   809  		return C_REGLIST
   810  
   811  	case obj.TYPE_SHIFT:
   812  		if a.Reg == 0 {
   813  			
   814  			return C_SHIFT
   815  		} else {
   816  			
   817  			return C_SHIFTADDR
   818  		}
   819  
   820  	case obj.TYPE_MEM:
   821  		switch a.Name {
   822  		case obj.NAME_EXTERN,
   823  			obj.NAME_GOTREF,
   824  			obj.NAME_STATIC:
   825  			if a.Sym == nil || a.Sym.Name == "" {
   826  				fmt.Printf("null sym external\n")
   827  				return C_GOK
   828  			}
   829  
   830  			c.instoffset = 0 
   831  			if a.Sym.Type == objabi.STLSBSS {
   832  				if c.ctxt.Flag_shared {
   833  					return C_TLS_IE
   834  				} else {
   835  					return C_TLS_LE
   836  				}
   837  			}
   838  
   839  			return C_ADDR
   840  
   841  		case obj.NAME_AUTO:
   842  			if a.Reg == REGSP {
   843  				
   844  				
   845  				a.Reg = obj.REG_NONE
   846  			}
   847  			c.instoffset = c.autosize + a.Offset
   848  			if t := immaddr(int32(c.instoffset)); t != 0 {
   849  				if immhalf(int32(c.instoffset)) {
   850  					if immfloat(t) {
   851  						return C_HFAUTO
   852  					}
   853  					return C_HAUTO
   854  				}
   855  
   856  				if immfloat(t) {
   857  					return C_FAUTO
   858  				}
   859  				return C_SAUTO
   860  			}
   861  
   862  			return C_LAUTO
   863  
   864  		case obj.NAME_PARAM:
   865  			if a.Reg == REGSP {
   866  				
   867  				
   868  				a.Reg = obj.REG_NONE
   869  			}
   870  			c.instoffset = c.autosize + a.Offset + 4
   871  			if t := immaddr(int32(c.instoffset)); t != 0 {
   872  				if immhalf(int32(c.instoffset)) {
   873  					if immfloat(t) {
   874  						return C_HFAUTO
   875  					}
   876  					return C_HAUTO
   877  				}
   878  
   879  				if immfloat(t) {
   880  					return C_FAUTO
   881  				}
   882  				return C_SAUTO
   883  			}
   884  
   885  			return C_LAUTO
   886  
   887  		case obj.NAME_NONE:
   888  			c.instoffset = a.Offset
   889  			if t := immaddr(int32(c.instoffset)); t != 0 {
   890  				if immhalf(int32(c.instoffset)) { 
   891  					if immfloat(t) {
   892  						return C_HFOREG
   893  					}
   894  					return C_HOREG
   895  				}
   896  
   897  				if immfloat(t) {
   898  					return C_FOREG 
   899  				}
   900  				if immrot(uint32(c.instoffset)) != 0 {
   901  					return C_SROREG
   902  				}
   903  				if immhalf(int32(c.instoffset)) {
   904  					return C_HOREG
   905  				}
   906  				return C_SOREG
   907  			}
   908  
   909  			if immrot(uint32(c.instoffset)) != 0 {
   910  				return C_ROREG
   911  			}
   912  			return C_LOREG
   913  		}
   914  
   915  		return C_GOK
   916  
   917  	case obj.TYPE_FCONST:
   918  		if c.chipzero5(a.Val.(float64)) >= 0 {
   919  			return C_ZFCON
   920  		}
   921  		if c.chipfloat5(a.Val.(float64)) >= 0 {
   922  			return C_SFCON
   923  		}
   924  		return C_LFCON
   925  
   926  	case obj.TYPE_TEXTSIZE:
   927  		return C_TEXTSIZE
   928  
   929  	case obj.TYPE_CONST,
   930  		obj.TYPE_ADDR:
   931  		switch a.Name {
   932  		case obj.NAME_NONE:
   933  			c.instoffset = a.Offset
   934  			if a.Reg != 0 {
   935  				return c.aconsize()
   936  			}
   937  
   938  			if immrot(uint32(c.instoffset)) != 0 {
   939  				return C_RCON
   940  			}
   941  			if immrot(^uint32(c.instoffset)) != 0 {
   942  				return C_NCON
   943  			}
   944  			if uint32(c.instoffset) <= 0xffff && buildcfg.GOARM == 7 {
   945  				return C_SCON
   946  			}
   947  			if x, y := immrot2a(uint32(c.instoffset)); x != 0 && y != 0 {
   948  				return C_RCON2A
   949  			}
   950  			if y, x := immrot2s(uint32(c.instoffset)); x != 0 && y != 0 {
   951  				return C_RCON2S
   952  			}
   953  			return C_LCON
   954  
   955  		case obj.NAME_EXTERN,
   956  			obj.NAME_GOTREF,
   957  			obj.NAME_STATIC:
   958  			s := a.Sym
   959  			if s == nil {
   960  				break
   961  			}
   962  			c.instoffset = 0 
   963  			return C_LCONADDR
   964  
   965  		case obj.NAME_AUTO:
   966  			if a.Reg == REGSP {
   967  				
   968  				
   969  				a.Reg = obj.REG_NONE
   970  			}
   971  			c.instoffset = c.autosize + a.Offset
   972  			return c.aconsize()
   973  
   974  		case obj.NAME_PARAM:
   975  			if a.Reg == REGSP {
   976  				
   977  				
   978  				a.Reg = obj.REG_NONE
   979  			}
   980  			c.instoffset = c.autosize + a.Offset + 4
   981  			return c.aconsize()
   982  		}
   983  
   984  		return C_GOK
   985  
   986  	case obj.TYPE_BRANCH:
   987  		return C_SBRA
   988  	}
   989  
   990  	return C_GOK
   991  }
   992  
   993  func (c *ctxt5) aconsize() int {
   994  	if immrot(uint32(c.instoffset)) != 0 {
   995  		return C_RACON
   996  	}
   997  	if immrot(uint32(-c.instoffset)) != 0 {
   998  		return C_RACON
   999  	}
  1000  	return C_LACON
  1001  }
  1002  
  1003  func (c *ctxt5) oplook(p *obj.Prog) *Optab {
  1004  	a1 := int(p.Optab)
  1005  	if a1 != 0 {
  1006  		return &optab[a1-1]
  1007  	}
  1008  	a1 = int(p.From.Class)
  1009  	if a1 == 0 {
  1010  		a1 = c.aclass(&p.From) + 1
  1011  		p.From.Class = int8(a1)
  1012  	}
  1013  
  1014  	a1--
  1015  	a3 := int(p.To.Class)
  1016  	if a3 == 0 {
  1017  		a3 = c.aclass(&p.To) + 1
  1018  		p.To.Class = int8(a3)
  1019  	}
  1020  
  1021  	a3--
  1022  	a2 := C_NONE
  1023  	if p.Reg != 0 {
  1024  		switch {
  1025  		case REG_F0 <= p.Reg && p.Reg <= REG_F15:
  1026  			a2 = C_FREG
  1027  		case REG_R0 <= p.Reg && p.Reg <= REG_R15:
  1028  			a2 = C_REG
  1029  		default:
  1030  			c.ctxt.Diag("invalid register in %v", p)
  1031  		}
  1032  	}
  1033  
  1034  	
  1035  	switch a1 {
  1036  	case C_SOREG, C_LOREG, C_HOREG, C_FOREG, C_ROREG, C_HFOREG, C_SROREG, C_SHIFTADDR:
  1037  		if p.From.Reg < REG_R0 || REG_R15 < p.From.Reg {
  1038  			c.ctxt.Diag("illegal base register: %v", p)
  1039  		}
  1040  	default:
  1041  	}
  1042  	switch a3 {
  1043  	case C_SOREG, C_LOREG, C_HOREG, C_FOREG, C_ROREG, C_HFOREG, C_SROREG, C_SHIFTADDR:
  1044  		if p.To.Reg < REG_R0 || REG_R15 < p.To.Reg {
  1045  			c.ctxt.Diag("illegal base register: %v", p)
  1046  		}
  1047  	default:
  1048  	}
  1049  
  1050  	
  1051  	
  1052  	if (a1 == C_RCON2A || a1 == C_RCON2S) && p.Scond&C_SBIT != 0 {
  1053  		a1 = C_LCON
  1054  	}
  1055  	if (a3 == C_RCON2A || a3 == C_RCON2S) && p.Scond&C_SBIT != 0 {
  1056  		a3 = C_LCON
  1057  	}
  1058  
  1059  	if false { 
  1060  		fmt.Printf("oplook %v %v %v %v\n", p.As, DRconv(a1), DRconv(a2), DRconv(a3))
  1061  		fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type)
  1062  	}
  1063  
  1064  	ops := oprange[p.As&obj.AMask]
  1065  	c1 := &xcmp[a1]
  1066  	c3 := &xcmp[a3]
  1067  	for i := range ops {
  1068  		op := &ops[i]
  1069  		if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] {
  1070  			p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
  1071  			checkSuffix(c, p, op)
  1072  			return op
  1073  		}
  1074  	}
  1075  
  1076  	c.ctxt.Diag("illegal combination %v; %v %v %v; from %d %d; to %d %d", p, DRconv(a1), DRconv(a2), DRconv(a3), p.From.Type, p.From.Name, p.To.Type, p.To.Name)
  1077  	if ops == nil {
  1078  		ops = optab
  1079  	}
  1080  	return &ops[0]
  1081  }
  1082  
  1083  func cmp(a int, b int) bool {
  1084  	if a == b {
  1085  		return true
  1086  	}
  1087  	switch a {
  1088  	case C_LCON:
  1089  		if b == C_RCON || b == C_NCON || b == C_SCON || b == C_RCON2A || b == C_RCON2S {
  1090  			return true
  1091  		}
  1092  
  1093  	case C_LACON:
  1094  		if b == C_RACON {
  1095  			return true
  1096  		}
  1097  
  1098  	case C_LFCON:
  1099  		if b == C_ZFCON || b == C_SFCON {
  1100  			return true
  1101  		}
  1102  
  1103  	case C_HFAUTO:
  1104  		return b == C_HAUTO || b == C_FAUTO
  1105  
  1106  	case C_FAUTO, C_HAUTO:
  1107  		return b == C_HFAUTO
  1108  
  1109  	case C_SAUTO:
  1110  		return cmp(C_HFAUTO, b)
  1111  
  1112  	case C_LAUTO:
  1113  		return cmp(C_SAUTO, b)
  1114  
  1115  	case C_HFOREG:
  1116  		return b == C_HOREG || b == C_FOREG
  1117  
  1118  	case C_FOREG, C_HOREG:
  1119  		return b == C_HFOREG
  1120  
  1121  	case C_SROREG:
  1122  		return cmp(C_SOREG, b) || cmp(C_ROREG, b)
  1123  
  1124  	case C_SOREG, C_ROREG:
  1125  		return b == C_SROREG || cmp(C_HFOREG, b)
  1126  
  1127  	case C_LOREG:
  1128  		return cmp(C_SROREG, b)
  1129  
  1130  	case C_LBRA:
  1131  		if b == C_SBRA {
  1132  			return true
  1133  		}
  1134  
  1135  	case C_HREG:
  1136  		return cmp(C_SP, b) || cmp(C_PC, b)
  1137  	}
  1138  
  1139  	return false
  1140  }
  1141  
  1142  type ocmp []Optab
  1143  
  1144  func (x ocmp) Len() int {
  1145  	return len(x)
  1146  }
  1147  
  1148  func (x ocmp) Swap(i, j int) {
  1149  	x[i], x[j] = x[j], x[i]
  1150  }
  1151  
  1152  func (x ocmp) Less(i, j int) bool {
  1153  	p1 := &x[i]
  1154  	p2 := &x[j]
  1155  	n := int(p1.as) - int(p2.as)
  1156  	if n != 0 {
  1157  		return n < 0
  1158  	}
  1159  	n = int(p1.a1) - int(p2.a1)
  1160  	if n != 0 {
  1161  		return n < 0
  1162  	}
  1163  	n = int(p1.a2) - int(p2.a2)
  1164  	if n != 0 {
  1165  		return n < 0
  1166  	}
  1167  	n = int(p1.a3) - int(p2.a3)
  1168  	if n != 0 {
  1169  		return n < 0
  1170  	}
  1171  	return false
  1172  }
  1173  
  1174  func opset(a, b0 obj.As) {
  1175  	oprange[a&obj.AMask] = oprange[b0]
  1176  }
  1177  
  1178  func buildop(ctxt *obj.Link) {
  1179  	if oprange[AAND&obj.AMask] != nil {
  1180  		
  1181  		
  1182  		
  1183  		return
  1184  	}
  1185  
  1186  	symdiv = ctxt.Lookup("runtime._div")
  1187  	symdivu = ctxt.Lookup("runtime._divu")
  1188  	symmod = ctxt.Lookup("runtime._mod")
  1189  	symmodu = ctxt.Lookup("runtime._modu")
  1190  
  1191  	var n int
  1192  
  1193  	for i := 0; i < C_GOK; i++ {
  1194  		for n = 0; n < C_GOK; n++ {
  1195  			if cmp(n, i) {
  1196  				xcmp[i][n] = true
  1197  			}
  1198  		}
  1199  	}
  1200  	for n = 0; optab[n].as != obj.AXXX; n++ {
  1201  		if optab[n].flag&LPCREL != 0 {
  1202  			if ctxt.Flag_shared {
  1203  				optab[n].size += int8(optab[n].pcrelsiz)
  1204  			} else {
  1205  				optab[n].flag &^= LPCREL
  1206  			}
  1207  		}
  1208  	}
  1209  
  1210  	sort.Sort(ocmp(optab[:n]))
  1211  	for i := 0; i < n; i++ {
  1212  		r := optab[i].as
  1213  		r0 := r & obj.AMask
  1214  		start := i
  1215  		for optab[i].as == r {
  1216  			i++
  1217  		}
  1218  		oprange[r0] = optab[start:i]
  1219  		i--
  1220  
  1221  		switch r {
  1222  		default:
  1223  			ctxt.Diag("unknown op in build: %v", r)
  1224  			ctxt.DiagFlush()
  1225  			log.Fatalf("bad code")
  1226  
  1227  		case AADD:
  1228  			opset(ASUB, r0)
  1229  			opset(ARSB, r0)
  1230  			opset(AADC, r0)
  1231  			opset(ASBC, r0)
  1232  			opset(ARSC, r0)
  1233  
  1234  		case AORR:
  1235  			opset(AEOR, r0)
  1236  			opset(ABIC, r0)
  1237  
  1238  		case ACMP:
  1239  			opset(ATEQ, r0)
  1240  			opset(ACMN, r0)
  1241  			opset(ATST, r0)
  1242  
  1243  		case AMVN:
  1244  			break
  1245  
  1246  		case ABEQ:
  1247  			opset(ABNE, r0)
  1248  			opset(ABCS, r0)
  1249  			opset(ABHS, r0)
  1250  			opset(ABCC, r0)
  1251  			opset(ABLO, r0)
  1252  			opset(ABMI, r0)
  1253  			opset(ABPL, r0)
  1254  			opset(ABVS, r0)
  1255  			opset(ABVC, r0)
  1256  			opset(ABHI, r0)
  1257  			opset(ABLS, r0)
  1258  			opset(ABGE, r0)
  1259  			opset(ABLT, r0)
  1260  			opset(ABGT, r0)
  1261  			opset(ABLE, r0)
  1262  
  1263  		case ASLL:
  1264  			opset(ASRL, r0)
  1265  			opset(ASRA, r0)
  1266  
  1267  		case AMUL:
  1268  			opset(AMULU, r0)
  1269  
  1270  		case ADIV:
  1271  			opset(AMOD, r0)
  1272  			opset(AMODU, r0)
  1273  			opset(ADIVU, r0)
  1274  
  1275  		case ADIVHW:
  1276  			opset(ADIVUHW, r0)
  1277  
  1278  		case AMOVW,
  1279  			AMOVB,
  1280  			AMOVBS,
  1281  			AMOVBU,
  1282  			AMOVH,
  1283  			AMOVHS,
  1284  			AMOVHU:
  1285  			break
  1286  
  1287  		case ASWPW:
  1288  			opset(ASWPBU, r0)
  1289  
  1290  		case AB,
  1291  			ABL,
  1292  			ABX,
  1293  			ABXRET,
  1294  			obj.ADUFFZERO,
  1295  			obj.ADUFFCOPY,
  1296  			ASWI,
  1297  			AWORD,
  1298  			AMOVM,
  1299  			ARFE,
  1300  			obj.ATEXT:
  1301  			break
  1302  
  1303  		case AADDF:
  1304  			opset(AADDD, r0)
  1305  			opset(ASUBF, r0)
  1306  			opset(ASUBD, r0)
  1307  			opset(AMULF, r0)
  1308  			opset(AMULD, r0)
  1309  			opset(ANMULF, r0)
  1310  			opset(ANMULD, r0)
  1311  			opset(AMULAF, r0)
  1312  			opset(AMULAD, r0)
  1313  			opset(AMULSF, r0)
  1314  			opset(AMULSD, r0)
  1315  			opset(ANMULAF, r0)
  1316  			opset(ANMULAD, r0)
  1317  			opset(ANMULSF, r0)
  1318  			opset(ANMULSD, r0)
  1319  			opset(AFMULAF, r0)
  1320  			opset(AFMULAD, r0)
  1321  			opset(AFMULSF, r0)
  1322  			opset(AFMULSD, r0)
  1323  			opset(AFNMULAF, r0)
  1324  			opset(AFNMULAD, r0)
  1325  			opset(AFNMULSF, r0)
  1326  			opset(AFNMULSD, r0)
  1327  			opset(ADIVF, r0)
  1328  			opset(ADIVD, r0)
  1329  
  1330  		case ANEGF:
  1331  			opset(ANEGD, r0)
  1332  			opset(ASQRTF, r0)
  1333  			opset(ASQRTD, r0)
  1334  			opset(AMOVFD, r0)
  1335  			opset(AMOVDF, r0)
  1336  			opset(AABSF, r0)
  1337  			opset(AABSD, r0)
  1338  
  1339  		case ACMPF:
  1340  			opset(ACMPD, r0)
  1341  
  1342  		case AMOVF:
  1343  			opset(AMOVD, r0)
  1344  
  1345  		case AMOVFW:
  1346  			opset(AMOVDW, r0)
  1347  
  1348  		case AMOVWF:
  1349  			opset(AMOVWD, r0)
  1350  
  1351  		case AMULL:
  1352  			opset(AMULAL, r0)
  1353  			opset(AMULLU, r0)
  1354  			opset(AMULALU, r0)
  1355  
  1356  		case AMULWT:
  1357  			opset(AMULWB, r0)
  1358  			opset(AMULBB, r0)
  1359  			opset(AMMUL, r0)
  1360  
  1361  		case AMULAWT:
  1362  			opset(AMULAWB, r0)
  1363  			opset(AMULABB, r0)
  1364  			opset(AMULS, r0)
  1365  			opset(AMMULA, r0)
  1366  			opset(AMMULS, r0)
  1367  
  1368  		case ABFX:
  1369  			opset(ABFXU, r0)
  1370  			opset(ABFC, r0)
  1371  			opset(ABFI, r0)
  1372  
  1373  		case ACLZ:
  1374  			opset(AREV, r0)
  1375  			opset(AREV16, r0)
  1376  			opset(AREVSH, r0)
  1377  			opset(ARBIT, r0)
  1378  
  1379  		case AXTAB:
  1380  			opset(AXTAH, r0)
  1381  			opset(AXTABU, r0)
  1382  			opset(AXTAHU, r0)
  1383  
  1384  		case ALDREX,
  1385  			ASTREX,
  1386  			ALDREXD,
  1387  			ASTREXD,
  1388  			ADMB,
  1389  			APLD,
  1390  			AAND,
  1391  			AMULA,
  1392  			obj.AUNDEF,
  1393  			obj.AFUNCDATA,
  1394  			obj.APCDATA,
  1395  			obj.ANOP:
  1396  			break
  1397  		}
  1398  	}
  1399  }
  1400  
  1401  func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
  1402  	c.printp = p
  1403  	o1 := uint32(0)
  1404  	o2 := uint32(0)
  1405  	o3 := uint32(0)
  1406  	o4 := uint32(0)
  1407  	o5 := uint32(0)
  1408  	o6 := uint32(0)
  1409  	if false { 
  1410  		fmt.Printf("%x: %v\ttype %d\n", uint32(p.Pc), p, o.type_)
  1411  	}
  1412  	switch o.type_ {
  1413  	default:
  1414  		c.ctxt.Diag("%v: unknown asm %d", p, o.type_)
  1415  
  1416  	case 0: 
  1417  		if false { 
  1418  			fmt.Printf("%x: %s: arm\n", uint32(p.Pc), p.From.Sym.Name)
  1419  		}
  1420  
  1421  	case 1: 
  1422  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1423  
  1424  		rf := int(p.From.Reg)
  1425  		rt := int(p.To.Reg)
  1426  		r := int(p.Reg)
  1427  		if p.To.Type == obj.TYPE_NONE {
  1428  			rt = 0
  1429  		}
  1430  		if p.As == AMOVB || p.As == AMOVH || p.As == AMOVW || p.As == AMVN {
  1431  			r = 0
  1432  		} else if r == 0 {
  1433  			r = rt
  1434  		}
  1435  		o1 |= (uint32(rf)&15)<<0 | (uint32(r)&15)<<16 | (uint32(rt)&15)<<12
  1436  
  1437  	case 2: 
  1438  		c.aclass(&p.From)
  1439  
  1440  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1441  		o1 |= uint32(immrot(uint32(c.instoffset)))
  1442  		rt := int(p.To.Reg)
  1443  		r := int(p.Reg)
  1444  		if p.To.Type == obj.TYPE_NONE {
  1445  			rt = 0
  1446  		}
  1447  		if p.As == AMOVW || p.As == AMVN {
  1448  			r = 0
  1449  		} else if r == 0 {
  1450  			r = rt
  1451  		}
  1452  		o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12
  1453  
  1454  	case 106: 
  1455  		c.aclass(&p.From)
  1456  		r := int(p.Reg)
  1457  		rt := int(p.To.Reg)
  1458  		if r == 0 {
  1459  			r = rt
  1460  		}
  1461  		x, y := immrot2a(uint32(c.instoffset))
  1462  		var as2 obj.As
  1463  		switch p.As {
  1464  		case AADD, ASUB, AORR, AEOR, ABIC:
  1465  			as2 = p.As 
  1466  		case ARSB:
  1467  			as2 = AADD 
  1468  		case AADC:
  1469  			as2 = AADD 
  1470  		case ASBC:
  1471  			as2 = ASUB 
  1472  		case ARSC:
  1473  			as2 = AADD 
  1474  		default:
  1475  			c.ctxt.Diag("unknown second op for %v", p)
  1476  		}
  1477  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1478  		o2 = c.oprrr(p, as2, int(p.Scond))
  1479  		o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12
  1480  		o2 |= (uint32(rt)&15)<<16 | (uint32(rt)&15)<<12
  1481  		o1 |= x
  1482  		o2 |= y
  1483  
  1484  	case 107: 
  1485  		c.aclass(&p.From)
  1486  		r := int(p.Reg)
  1487  		rt := int(p.To.Reg)
  1488  		if r == 0 {
  1489  			r = rt
  1490  		}
  1491  		y, x := immrot2s(uint32(c.instoffset))
  1492  		var as2 obj.As
  1493  		switch p.As {
  1494  		case AADD:
  1495  			as2 = ASUB 
  1496  		case ASUB:
  1497  			as2 = AADD 
  1498  		case ARSB:
  1499  			as2 = ASUB 
  1500  		case AADC:
  1501  			as2 = ASUB 
  1502  		case ASBC:
  1503  			as2 = AADD 
  1504  		case ARSC:
  1505  			as2 = ASUB 
  1506  		default:
  1507  			c.ctxt.Diag("unknown second op for %v", p)
  1508  		}
  1509  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1510  		o2 = c.oprrr(p, as2, int(p.Scond))
  1511  		o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12
  1512  		o2 |= (uint32(rt)&15)<<16 | (uint32(rt)&15)<<12
  1513  		o1 |= y
  1514  		o2 |= x
  1515  
  1516  	case 3: 
  1517  		o1 = c.mov(p)
  1518  
  1519  	case 4: 
  1520  		c.aclass(&p.From)
  1521  		if c.instoffset < 0 {
  1522  			o1 = c.oprrr(p, ASUB, int(p.Scond))
  1523  			o1 |= uint32(immrot(uint32(-c.instoffset)))
  1524  		} else {
  1525  			o1 = c.oprrr(p, AADD, int(p.Scond))
  1526  			o1 |= uint32(immrot(uint32(c.instoffset)))
  1527  		}
  1528  		r := int(p.From.Reg)
  1529  		if r == 0 {
  1530  			r = int(o.param)
  1531  		}
  1532  		o1 |= (uint32(r) & 15) << 16
  1533  		o1 |= (uint32(p.To.Reg) & 15) << 12
  1534  
  1535  	case 5: 
  1536  		o1 = c.opbra(p, p.As, int(p.Scond))
  1537  
  1538  		v := int32(-8)
  1539  		if p.To.Sym != nil {
  1540  			rel := obj.Addrel(c.cursym)
  1541  			rel.Off = int32(c.pc)
  1542  			rel.Siz = 4
  1543  			rel.Sym = p.To.Sym
  1544  			v += int32(p.To.Offset)
  1545  			rel.Add = int64(o1) | (int64(v)>>2)&0xffffff
  1546  			rel.Type = objabi.R_CALLARM
  1547  			break
  1548  		}
  1549  
  1550  		if p.To.Target() != nil {
  1551  			v = int32((p.To.Target().Pc - c.pc) - 8)
  1552  		}
  1553  		o1 |= (uint32(v) >> 2) & 0xffffff
  1554  
  1555  	case 6: 
  1556  		c.aclass(&p.To)
  1557  
  1558  		o1 = c.oprrr(p, AADD, int(p.Scond))
  1559  		o1 |= uint32(immrot(uint32(c.instoffset)))
  1560  		o1 |= (uint32(p.To.Reg) & 15) << 16
  1561  		o1 |= (REGPC & 15) << 12
  1562  
  1563  	case 7: 
  1564  		c.aclass(&p.To)
  1565  
  1566  		if c.instoffset != 0 {
  1567  			c.ctxt.Diag("%v: doesn't support BL offset(REG) with non-zero offset %d", p, c.instoffset)
  1568  		}
  1569  		o1 = c.oprrr(p, ABL, int(p.Scond))
  1570  		o1 |= (uint32(p.To.Reg) & 15) << 0
  1571  		rel := obj.Addrel(c.cursym)
  1572  		rel.Off = int32(c.pc)
  1573  		rel.Siz = 0
  1574  		rel.Type = objabi.R_CALLIND
  1575  
  1576  	case 8: 
  1577  		c.aclass(&p.From)
  1578  
  1579  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1580  		r := int(p.Reg)
  1581  		if r == 0 {
  1582  			r = int(p.To.Reg)
  1583  		}
  1584  		o1 |= (uint32(r) & 15) << 0
  1585  		o1 |= uint32((c.instoffset & 31) << 7)
  1586  		o1 |= (uint32(p.To.Reg) & 15) << 12
  1587  
  1588  	case 9: 
  1589  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1590  
  1591  		r := int(p.Reg)
  1592  		if r == 0 {
  1593  			r = int(p.To.Reg)
  1594  		}
  1595  		o1 |= (uint32(r) & 15) << 0
  1596  		o1 |= (uint32(p.From.Reg)&15)<<8 | 1<<4
  1597  		o1 |= (uint32(p.To.Reg) & 15) << 12
  1598  
  1599  	case 10: 
  1600  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1601  
  1602  		if p.To.Type != obj.TYPE_NONE {
  1603  			c.aclass(&p.To)
  1604  			o1 |= uint32(c.instoffset & 0xffffff)
  1605  		}
  1606  
  1607  	case 11: 
  1608  		c.aclass(&p.To)
  1609  
  1610  		o1 = uint32(c.instoffset)
  1611  		if p.To.Sym != nil {
  1612  			
  1613  			
  1614  			rel := obj.Addrel(c.cursym)
  1615  
  1616  			rel.Off = int32(c.pc)
  1617  			rel.Siz = 4
  1618  			rel.Sym = p.To.Sym
  1619  			rel.Add = p.To.Offset
  1620  
  1621  			if c.ctxt.Flag_shared {
  1622  				if p.To.Name == obj.NAME_GOTREF {
  1623  					rel.Type = objabi.R_GOTPCREL
  1624  				} else {
  1625  					rel.Type = objabi.R_PCREL
  1626  				}
  1627  				rel.Add += c.pc - p.Rel.Pc - 8
  1628  			} else {
  1629  				rel.Type = objabi.R_ADDR
  1630  			}
  1631  			o1 = 0
  1632  		}
  1633  
  1634  	case 12: 
  1635  		if o.a1 == C_SCON {
  1636  			o1 = c.omvs(p, &p.From, int(p.To.Reg))
  1637  		} else if p.As == AMVN {
  1638  			o1 = c.omvr(p, &p.From, int(p.To.Reg))
  1639  		} else {
  1640  			o1 = c.omvl(p, &p.From, int(p.To.Reg))
  1641  		}
  1642  
  1643  		if o.flag&LPCREL != 0 {
  1644  			o2 = c.oprrr(p, AADD, int(p.Scond)) | (uint32(p.To.Reg)&15)<<0 | (REGPC&15)<<16 | (uint32(p.To.Reg)&15)<<12
  1645  		}
  1646  
  1647  	case 13: 
  1648  		if o.a1 == C_SCON {
  1649  			o1 = c.omvs(p, &p.From, REGTMP)
  1650  		} else {
  1651  			o1 = c.omvl(p, &p.From, REGTMP)
  1652  		}
  1653  
  1654  		if o1 == 0 {
  1655  			break
  1656  		}
  1657  		o2 = c.oprrr(p, p.As, int(p.Scond))
  1658  		o2 |= REGTMP & 15
  1659  		r := int(p.Reg)
  1660  		if p.As == AMVN {
  1661  			r = 0
  1662  		} else if r == 0 {
  1663  			r = int(p.To.Reg)
  1664  		}
  1665  		o2 |= (uint32(r) & 15) << 16
  1666  		if p.To.Type != obj.TYPE_NONE {
  1667  			o2 |= (uint32(p.To.Reg) & 15) << 12
  1668  		}
  1669  
  1670  	case 14: 
  1671  		o1 = c.oprrr(p, ASLL, int(p.Scond))
  1672  
  1673  		if p.As == AMOVBU || p.As == AMOVHU {
  1674  			o2 = c.oprrr(p, ASRL, int(p.Scond))
  1675  		} else {
  1676  			o2 = c.oprrr(p, ASRA, int(p.Scond))
  1677  		}
  1678  
  1679  		r := int(p.To.Reg)
  1680  		o1 |= (uint32(p.From.Reg)&15)<<0 | (uint32(r)&15)<<12
  1681  		o2 |= uint32(r)&15 | (uint32(r)&15)<<12
  1682  		if p.As == AMOVB || p.As == AMOVBS || p.As == AMOVBU {
  1683  			o1 |= 24 << 7
  1684  			o2 |= 24 << 7
  1685  		} else {
  1686  			o1 |= 16 << 7
  1687  			o2 |= 16 << 7
  1688  		}
  1689  
  1690  	case 15: 
  1691  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1692  
  1693  		rf := int(p.From.Reg)
  1694  		rt := int(p.To.Reg)
  1695  		r := int(p.Reg)
  1696  		if r == 0 {
  1697  			r = rt
  1698  		}
  1699  
  1700  		o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16
  1701  
  1702  	case 16: 
  1703  		o1 = 0xf << 28
  1704  
  1705  		o2 = 0
  1706  
  1707  	case 17:
  1708  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1709  		rf := int(p.From.Reg)
  1710  		rt := int(p.To.Reg)
  1711  		rt2 := int(p.To.Offset)
  1712  		r := int(p.Reg)
  1713  		o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16 | (uint32(rt2)&15)<<12
  1714  
  1715  	case 18: 
  1716  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1717  		rt := int(p.To.Reg)
  1718  		r := int(p.Reg)
  1719  		if r == 0 {
  1720  			r = rt
  1721  		} else if p.As == ABFC { 
  1722  			c.ctxt.Diag("illegal combination: %v", p)
  1723  		}
  1724  		if p.GetFrom3() == nil || p.GetFrom3().Type != obj.TYPE_CONST {
  1725  			c.ctxt.Diag("%v: missing or wrong LSB", p)
  1726  			break
  1727  		}
  1728  		lsb := p.GetFrom3().Offset
  1729  		width := p.From.Offset
  1730  		if lsb < 0 || lsb > 31 || width <= 0 || (lsb+width) > 32 {
  1731  			c.ctxt.Diag("%v: wrong width or LSB", p)
  1732  		}
  1733  		switch p.As {
  1734  		case ABFX, ABFXU: 
  1735  			o1 |= (uint32(r)&15)<<0 | (uint32(rt)&15)<<12 | uint32(lsb)<<7 | uint32(width-1)<<16
  1736  		case ABFC, ABFI: 
  1737  			o1 |= (uint32(r)&15)<<0 | (uint32(rt)&15)<<12 | uint32(lsb)<<7 | uint32(lsb+width-1)<<16
  1738  		default:
  1739  			c.ctxt.Diag("illegal combination: %v", p)
  1740  		}
  1741  
  1742  	case 20: 
  1743  		c.aclass(&p.To)
  1744  
  1745  		r := int(p.To.Reg)
  1746  		if r == 0 {
  1747  			r = int(o.param)
  1748  		}
  1749  		o1 = c.osr(p.As, int(p.From.Reg), int32(c.instoffset), r, int(p.Scond))
  1750  
  1751  	case 21: 
  1752  		c.aclass(&p.From)
  1753  
  1754  		r := int(p.From.Reg)
  1755  		if r == 0 {
  1756  			r = int(o.param)
  1757  		}
  1758  		o1 = c.olr(int32(c.instoffset), r, int(p.To.Reg), int(p.Scond))
  1759  		if p.As != AMOVW {
  1760  			o1 |= 1 << 22
  1761  		}
  1762  
  1763  	case 22: 
  1764  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1765  		switch p.From.Offset &^ 0xf {
  1766  		
  1767  		case SHIFT_RR, SHIFT_RR | 8<<7, SHIFT_RR | 16<<7, SHIFT_RR | 24<<7:
  1768  			o1 |= uint32(p.From.Offset) & 0xc0f
  1769  		default:
  1770  			c.ctxt.Diag("illegal shift: %v", p)
  1771  		}
  1772  		rt := p.To.Reg
  1773  		r := p.Reg
  1774  		if r == 0 {
  1775  			r = rt
  1776  		}
  1777  		o1 |= (uint32(rt)&15)<<12 | (uint32(r)&15)<<16
  1778  
  1779  	case 23: 
  1780  		switch p.As {
  1781  		case AMOVW:
  1782  			o1 = c.mov(p)
  1783  		case AMOVBU, AMOVBS, AMOVB, AMOVHU, AMOVHS, AMOVH:
  1784  			o1 = c.movxt(p)
  1785  		default:
  1786  			c.ctxt.Diag("illegal combination: %v", p)
  1787  		}
  1788  
  1789  	case 30: 
  1790  		o1 = c.omvl(p, &p.To, REGTMP)
  1791  
  1792  		if o1 == 0 {
  1793  			break
  1794  		}
  1795  		r := int(p.To.Reg)
  1796  		if r == 0 {
  1797  			r = int(o.param)
  1798  		}
  1799  		o2 = c.osrr(int(p.From.Reg), REGTMP&15, r, int(p.Scond))
  1800  		if p.As != AMOVW {
  1801  			o2 |= 1 << 22
  1802  		}
  1803  
  1804  	case 31: 
  1805  		o1 = c.omvl(p, &p.From, REGTMP)
  1806  
  1807  		if o1 == 0 {
  1808  			break
  1809  		}
  1810  		r := int(p.From.Reg)
  1811  		if r == 0 {
  1812  			r = int(o.param)
  1813  		}
  1814  		o2 = c.olrr(REGTMP&15, r, int(p.To.Reg), int(p.Scond))
  1815  		if p.As == AMOVBU || p.As == AMOVBS || p.As == AMOVB {
  1816  			o2 |= 1 << 22
  1817  		}
  1818  
  1819  	case 34: 
  1820  		o1 = c.omvl(p, &p.From, REGTMP)
  1821  
  1822  		if o1 == 0 {
  1823  			break
  1824  		}
  1825  
  1826  		o2 = c.oprrr(p, AADD, int(p.Scond))
  1827  		o2 |= REGTMP & 15
  1828  		r := int(p.From.Reg)
  1829  		if r == 0 {
  1830  			r = int(o.param)
  1831  		}
  1832  		o2 |= (uint32(r) & 15) << 16
  1833  		if p.To.Type != obj.TYPE_NONE {
  1834  			o2 |= (uint32(p.To.Reg) & 15) << 12
  1835  		}
  1836  
  1837  	case 35: 
  1838  		o1 = 2<<23 | 0xf<<16 | 0<<0
  1839  
  1840  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  1841  		o1 |= (uint32(p.From.Reg) & 1) << 22
  1842  		o1 |= (uint32(p.To.Reg) & 15) << 12
  1843  
  1844  	case 36: 
  1845  		o1 = 2<<23 | 0x2cf<<12 | 0<<4
  1846  
  1847  		if p.Scond&C_FBIT != 0 {
  1848  			o1 ^= 0x010 << 12
  1849  		}
  1850  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  1851  		o1 |= (uint32(p.To.Reg) & 1) << 22
  1852  		o1 |= (uint32(p.From.Reg) & 15) << 0
  1853  
  1854  	case 37: 
  1855  		c.aclass(&p.From)
  1856  
  1857  		o1 = 2<<23 | 0x2cf<<12 | 0<<4
  1858  		if p.Scond&C_FBIT != 0 {
  1859  			o1 ^= 0x010 << 12
  1860  		}
  1861  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  1862  		o1 |= uint32(immrot(uint32(c.instoffset)))
  1863  		o1 |= (uint32(p.To.Reg) & 1) << 22
  1864  		o1 |= (uint32(p.From.Reg) & 15) << 0
  1865  
  1866  	case 38, 39:
  1867  		switch o.type_ {
  1868  		case 38: 
  1869  			o1 = 0x4 << 25
  1870  
  1871  			o1 |= uint32(p.From.Offset & 0xffff)
  1872  			o1 |= (uint32(p.To.Reg) & 15) << 16
  1873  			c.aclass(&p.To)
  1874  
  1875  		case 39: 
  1876  			o1 = 0x4<<25 | 1<<20
  1877  
  1878  			o1 |= uint32(p.To.Offset & 0xffff)
  1879  			o1 |= (uint32(p.From.Reg) & 15) << 16
  1880  			c.aclass(&p.From)
  1881  		}
  1882  
  1883  		if c.instoffset != 0 {
  1884  			c.ctxt.Diag("offset must be zero in MOVM; %v", p)
  1885  		}
  1886  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  1887  		if p.Scond&C_PBIT != 0 {
  1888  			o1 |= 1 << 24
  1889  		}
  1890  		if p.Scond&C_UBIT != 0 {
  1891  			o1 |= 1 << 23
  1892  		}
  1893  		if p.Scond&C_WBIT != 0 {
  1894  			o1 |= 1 << 21
  1895  		}
  1896  
  1897  	case 40: 
  1898  		c.aclass(&p.From)
  1899  
  1900  		if c.instoffset != 0 {
  1901  			c.ctxt.Diag("offset must be zero in SWP")
  1902  		}
  1903  		o1 = 0x2<<23 | 0x9<<4
  1904  		if p.As != ASWPW {
  1905  			o1 |= 1 << 22
  1906  		}
  1907  		o1 |= (uint32(p.From.Reg) & 15) << 16
  1908  		o1 |= (uint32(p.Reg) & 15) << 0
  1909  		o1 |= (uint32(p.To.Reg) & 15) << 12
  1910  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  1911  
  1912  	case 41: 
  1913  		o1 = 0xe8fd8000
  1914  
  1915  	case 50: 
  1916  		v := c.regoff(&p.To)
  1917  
  1918  		r := int(p.To.Reg)
  1919  		if r == 0 {
  1920  			r = int(o.param)
  1921  		}
  1922  		o1 = c.ofsr(p.As, int(p.From.Reg), v, r, int(p.Scond), p)
  1923  
  1924  	case 51: 
  1925  		v := c.regoff(&p.From)
  1926  
  1927  		r := int(p.From.Reg)
  1928  		if r == 0 {
  1929  			r = int(o.param)
  1930  		}
  1931  		o1 = c.ofsr(p.As, int(p.To.Reg), v, r, int(p.Scond), p) | 1<<20
  1932  
  1933  	case 52: 
  1934  		o1 = c.omvl(p, &p.To, REGTMP)
  1935  
  1936  		if o1 == 0 {
  1937  			break
  1938  		}
  1939  		r := int(p.To.Reg)
  1940  		if r == 0 {
  1941  			r = int(o.param)
  1942  		}
  1943  		o2 = c.oprrr(p, AADD, int(p.Scond)) | (REGTMP&15)<<12 | (REGTMP&15)<<16 | (uint32(r)&15)<<0
  1944  		o3 = c.ofsr(p.As, int(p.From.Reg), 0, REGTMP, int(p.Scond), p)
  1945  
  1946  	case 53: 
  1947  		o1 = c.omvl(p, &p.From, REGTMP)
  1948  
  1949  		if o1 == 0 {
  1950  			break
  1951  		}
  1952  		r := int(p.From.Reg)
  1953  		if r == 0 {
  1954  			r = int(o.param)
  1955  		}
  1956  		o2 = c.oprrr(p, AADD, int(p.Scond)) | (REGTMP&15)<<12 | (REGTMP&15)<<16 | (uint32(r)&15)<<0
  1957  		o3 = c.ofsr(p.As, int(p.To.Reg), 0, (REGTMP&15), int(p.Scond), p) | 1<<20
  1958  
  1959  	case 54: 
  1960  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1961  
  1962  		rf := int(p.From.Reg)
  1963  		rt := int(p.To.Reg)
  1964  		r := int(p.Reg)
  1965  		if r == 0 {
  1966  			switch p.As {
  1967  			case AMULAD, AMULAF, AMULSF, AMULSD, ANMULAF, ANMULAD, ANMULSF, ANMULSD,
  1968  				AFMULAD, AFMULAF, AFMULSF, AFMULSD, AFNMULAF, AFNMULAD, AFNMULSF, AFNMULSD:
  1969  				c.ctxt.Diag("illegal combination: %v", p)
  1970  			default:
  1971  				r = rt
  1972  			}
  1973  		}
  1974  
  1975  		o1 |= (uint32(rf)&15)<<0 | (uint32(r)&15)<<16 | (uint32(rt)&15)<<12
  1976  
  1977  	case 55: 
  1978  		o1 = c.oprrr(p, p.As, int(p.Scond))
  1979  
  1980  		rf := int(p.From.Reg)
  1981  		rt := int(p.To.Reg)
  1982  
  1983  		o1 |= (uint32(rf)&15)<<0 | (uint32(rt)&15)<<12
  1984  
  1985  	case 56: 
  1986  		o1 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0xee1<<16 | 0xa1<<4
  1987  
  1988  		o1 |= (uint32(p.From.Reg) & 15) << 12
  1989  
  1990  	case 57: 
  1991  		o1 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0xef1<<16 | 0xa1<<4
  1992  
  1993  		o1 |= (uint32(p.To.Reg) & 15) << 12
  1994  
  1995  	case 58: 
  1996  		o1 = c.oprrr(p, AAND, int(p.Scond))
  1997  
  1998  		o1 |= uint32(immrot(0xff))
  1999  		rt := int(p.To.Reg)
  2000  		r := int(p.From.Reg)
  2001  		if p.To.Type == obj.TYPE_NONE {
  2002  			rt = 0
  2003  		}
  2004  		if r == 0 {
  2005  			r = rt
  2006  		}
  2007  		o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12
  2008  
  2009  	case 59: 
  2010  		if p.From.Reg == 0 {
  2011  			c.ctxt.Diag("source operand is not a memory address: %v", p)
  2012  			break
  2013  		}
  2014  		if p.From.Offset&(1<<4) != 0 {
  2015  			c.ctxt.Diag("bad shift in LDR")
  2016  			break
  2017  		}
  2018  		o1 = c.olrr(int(p.From.Offset), int(p.From.Reg), int(p.To.Reg), int(p.Scond))
  2019  		if p.As == AMOVBU {
  2020  			o1 |= 1 << 22
  2021  		}
  2022  
  2023  	case 60: 
  2024  		if p.From.Reg == 0 {
  2025  			c.ctxt.Diag("source operand is not a memory address: %v", p)
  2026  			break
  2027  		}
  2028  		if p.From.Offset&(^0xf) != 0 {
  2029  			c.ctxt.Diag("bad shift: %v", p)
  2030  			break
  2031  		}
  2032  		o1 = c.olhrr(int(p.From.Offset), int(p.From.Reg), int(p.To.Reg), int(p.Scond))
  2033  		switch p.As {
  2034  		case AMOVB, AMOVBS:
  2035  			o1 ^= 1<<5 | 1<<6
  2036  		case AMOVH, AMOVHS:
  2037  			o1 ^= 1 << 6
  2038  		default:
  2039  		}
  2040  		if p.Scond&C_UBIT != 0 {
  2041  			o1 &^= 1 << 23
  2042  		}
  2043  
  2044  	case 61: 
  2045  		if p.To.Reg == 0 {
  2046  			c.ctxt.Diag("MOV to shifter operand")
  2047  		}
  2048  		o1 = c.osrr(int(p.From.Reg), int(p.To.Offset), int(p.To.Reg), int(p.Scond))
  2049  		if p.As == AMOVB || p.As == AMOVBS || p.As == AMOVBU {
  2050  			o1 |= 1 << 22
  2051  		}
  2052  
  2053  	case 62: 
  2054  		if p.To.Reg == 0 {
  2055  			c.ctxt.Diag("MOV to shifter operand")
  2056  		}
  2057  		if p.To.Offset&(^0xf) != 0 {
  2058  			c.ctxt.Diag("bad shift: %v", p)
  2059  		}
  2060  		o1 = c.olhrr(int(p.To.Offset), int(p.To.Reg), int(p.From.Reg), int(p.Scond))
  2061  		o1 ^= 1 << 20
  2062  		if p.Scond&C_UBIT != 0 {
  2063  			o1 &^= 1 << 23
  2064  		}
  2065  
  2066  		
  2067  	case 64: 
  2068  		o1 = c.omvl(p, &p.To, REGTMP)
  2069  
  2070  		if o1 == 0 {
  2071  			break
  2072  		}
  2073  		o2 = c.osr(p.As, int(p.From.Reg), 0, REGTMP, int(p.Scond))
  2074  		if o.flag&LPCREL != 0 {
  2075  			o3 = o2
  2076  			o2 = c.oprrr(p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
  2077  		}
  2078  
  2079  	case 65: 
  2080  		o1 = c.omvl(p, &p.From, REGTMP)
  2081  
  2082  		if o1 == 0 {
  2083  			break
  2084  		}
  2085  		o2 = c.olr(0, REGTMP, int(p.To.Reg), int(p.Scond))
  2086  		if p.As == AMOVBU || p.As == AMOVBS || p.As == AMOVB {
  2087  			o2 |= 1 << 22
  2088  		}
  2089  		if o.flag&LPCREL != 0 {
  2090  			o3 = o2
  2091  			o2 = c.oprrr(p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
  2092  		}
  2093  
  2094  	case 101: 
  2095  		o1 = c.omvl(p, &p.From, int(p.To.Reg))
  2096  
  2097  	case 102: 
  2098  		o1 = c.omvl(p, &p.From, int(p.To.Reg))
  2099  		o2 = c.olrr(int(p.To.Reg)&15, (REGPC & 15), int(p.To.Reg), int(p.Scond))
  2100  
  2101  	case 103: 
  2102  		if p.To.Sym == nil {
  2103  			c.ctxt.Diag("nil sym in tls %v", p)
  2104  		}
  2105  		if p.To.Offset != 0 {
  2106  			c.ctxt.Diag("offset against tls var in %v", p)
  2107  		}
  2108  		
  2109  		
  2110  		rel := obj.Addrel(c.cursym)
  2111  
  2112  		rel.Off = int32(c.pc)
  2113  		rel.Siz = 4
  2114  		rel.Sym = p.To.Sym
  2115  		rel.Type = objabi.R_TLS_LE
  2116  		o1 = 0
  2117  
  2118  	case 104: 
  2119  		if p.To.Sym == nil {
  2120  			c.ctxt.Diag("nil sym in tls %v", p)
  2121  		}
  2122  		if p.To.Offset != 0 {
  2123  			c.ctxt.Diag("offset against tls var in %v", p)
  2124  		}
  2125  		rel := obj.Addrel(c.cursym)
  2126  		rel.Off = int32(c.pc)
  2127  		rel.Siz = 4
  2128  		rel.Sym = p.To.Sym
  2129  		rel.Type = objabi.R_TLS_IE
  2130  		rel.Add = c.pc - p.Rel.Pc - 8 - int64(rel.Siz)
  2131  
  2132  	case 68: 
  2133  		o1 = c.omvl(p, &p.To, REGTMP)
  2134  
  2135  		if o1 == 0 {
  2136  			break
  2137  		}
  2138  		o2 = c.ofsr(p.As, int(p.From.Reg), 0, REGTMP, int(p.Scond), p)
  2139  		if o.flag&LPCREL != 0 {
  2140  			o3 = o2
  2141  			o2 = c.oprrr(p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
  2142  		}
  2143  
  2144  	case 69: 
  2145  		o1 = c.omvl(p, &p.From, REGTMP)
  2146  
  2147  		if o1 == 0 {
  2148  			break
  2149  		}
  2150  		o2 = c.ofsr(p.As, int(p.To.Reg), 0, (REGTMP&15), int(p.Scond), p) | 1<<20
  2151  		if o.flag&LPCREL != 0 {
  2152  			o3 = o2
  2153  			o2 = c.oprrr(p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
  2154  		}
  2155  
  2156  		
  2157  	case 70: 
  2158  		c.aclass(&p.To)
  2159  
  2160  		r := int(p.To.Reg)
  2161  		if r == 0 {
  2162  			r = int(o.param)
  2163  		}
  2164  		o1 = c.oshr(int(p.From.Reg), int32(c.instoffset), r, int(p.Scond))
  2165  
  2166  	case 71: 
  2167  		c.aclass(&p.From)
  2168  
  2169  		r := int(p.From.Reg)
  2170  		if r == 0 {
  2171  			r = int(o.param)
  2172  		}
  2173  		o1 = c.olhr(int32(c.instoffset), r, int(p.To.Reg), int(p.Scond))
  2174  		if p.As == AMOVB || p.As == AMOVBS {
  2175  			o1 ^= 1<<5 | 1<<6
  2176  		} else if p.As == AMOVH || p.As == AMOVHS {
  2177  			o1 ^= (1 << 6)
  2178  		}
  2179  
  2180  	case 72: 
  2181  		o1 = c.omvl(p, &p.To, REGTMP)
  2182  
  2183  		if o1 == 0 {
  2184  			break
  2185  		}
  2186  		r := int(p.To.Reg)
  2187  		if r == 0 {
  2188  			r = int(o.param)
  2189  		}
  2190  		o2 = c.oshrr(int(p.From.Reg), REGTMP&15, r, int(p.Scond))
  2191  
  2192  	case 73: 
  2193  		o1 = c.omvl(p, &p.From, REGTMP)
  2194  
  2195  		if o1 == 0 {
  2196  			break
  2197  		}
  2198  		r := int(p.From.Reg)
  2199  		if r == 0 {
  2200  			r = int(o.param)
  2201  		}
  2202  		o2 = c.olhrr(REGTMP&15, r, int(p.To.Reg), int(p.Scond))
  2203  		if p.As == AMOVB || p.As == AMOVBS {
  2204  			o2 ^= 1<<5 | 1<<6
  2205  		} else if p.As == AMOVH || p.As == AMOVHS {
  2206  			o2 ^= (1 << 6)
  2207  		}
  2208  
  2209  	case 74: 
  2210  		c.ctxt.Diag("ABX $I")
  2211  
  2212  	case 75: 
  2213  		c.aclass(&p.To)
  2214  
  2215  		if c.instoffset != 0 {
  2216  			c.ctxt.Diag("non-zero offset in ABX")
  2217  		}
  2218  
  2219  		
  2220  		
  2221  		o1 = c.oprrr(p, AADD, int(p.Scond))
  2222  
  2223  		o1 |= uint32(immrot(uint32(c.instoffset)))
  2224  		o1 |= (uint32(p.To.Reg) & 15) << 16
  2225  		o1 |= (REGTMP & 15) << 12
  2226  		o2 = c.oprrr(p, AADD, int(p.Scond)) | uint32(immrot(0)) | (REGPC&15)<<16 | (REGLINK&15)<<12 
  2227  		o3 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x12fff<<8 | 1<<4 | REGTMP&15            
  2228  
  2229  	case 76: 
  2230  		c.ctxt.Diag("ABXRET")
  2231  
  2232  	case 77: 
  2233  		c.aclass(&p.From)
  2234  
  2235  		if c.instoffset != 0 {
  2236  			c.ctxt.Diag("offset must be zero in LDREX")
  2237  		}
  2238  		o1 = 0x19<<20 | 0xf9f
  2239  		o1 |= (uint32(p.From.Reg) & 15) << 16
  2240  		o1 |= (uint32(p.To.Reg) & 15) << 12
  2241  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  2242  
  2243  	case 78: 
  2244  		c.aclass(&p.From)
  2245  
  2246  		if c.instoffset != 0 {
  2247  			c.ctxt.Diag("offset must be zero in STREX")
  2248  		}
  2249  		if p.To.Reg == p.From.Reg || p.To.Reg == p.Reg {
  2250  			c.ctxt.Diag("cannot use same register as both source and destination: %v", p)
  2251  		}
  2252  		o1 = 0x18<<20 | 0xf90
  2253  		o1 |= (uint32(p.From.Reg) & 15) << 16
  2254  		o1 |= (uint32(p.Reg) & 15) << 0
  2255  		o1 |= (uint32(p.To.Reg) & 15) << 12
  2256  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  2257  
  2258  	case 80: 
  2259  		if p.As == AMOVD {
  2260  			o1 = 0xeeb00b00 
  2261  			o2 = c.oprrr(p, ASUBD, int(p.Scond))
  2262  		} else {
  2263  			o1 = 0x0eb00a00 
  2264  			o2 = c.oprrr(p, ASUBF, int(p.Scond))
  2265  		}
  2266  
  2267  		v := int32(0x70) 
  2268  		r := (int(p.To.Reg) & 15) << 0
  2269  
  2270  		
  2271  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  2272  
  2273  		o1 |= (uint32(r) & 15) << 12
  2274  		o1 |= (uint32(v) & 0xf) << 0
  2275  		o1 |= (uint32(v) & 0xf0) << 12
  2276  
  2277  		
  2278  		o2 |= (uint32(r)&15)<<0 | (uint32(r)&15)<<16 | (uint32(r)&15)<<12
  2279  
  2280  	case 81: 
  2281  		o1 = 0x0eb00a00 
  2282  		if p.As == AMOVD {
  2283  			o1 = 0xeeb00b00 
  2284  		}
  2285  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  2286  		o1 |= (uint32(p.To.Reg) & 15) << 12
  2287  		v := int32(c.chipfloat5(p.From.Val.(float64)))
  2288  		o1 |= (uint32(v) & 0xf) << 0
  2289  		o1 |= (uint32(v) & 0xf0) << 12
  2290  
  2291  	case 82: 
  2292  		o1 = c.oprrr(p, p.As, int(p.Scond))
  2293  
  2294  		o1 |= (uint32(p.Reg)&15)<<12 | (uint32(p.From.Reg)&15)<<0
  2295  		o2 = 0x0ef1fa10 
  2296  		o2 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  2297  
  2298  	case 83: 
  2299  		o1 = c.oprrr(p, p.As, int(p.Scond))
  2300  
  2301  		o1 |= (uint32(p.From.Reg)&15)<<12 | 1<<16
  2302  		o2 = 0x0ef1fa10 
  2303  		o2 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  2304  
  2305  	case 84: 
  2306  		o1 = c.oprrr(p, p.As, int(p.Scond))
  2307  
  2308  		o1 |= (uint32(p.From.Reg) & 15) << 0
  2309  		o1 |= (uint32(p.To.Reg) & 15) << 12
  2310  
  2311  	case 85: 
  2312  		o1 = c.oprrr(p, p.As, int(p.Scond))
  2313  
  2314  		o1 |= (uint32(p.From.Reg) & 15) << 0
  2315  		o1 |= (uint32(p.To.Reg) & 15) << 12
  2316  
  2317  		
  2318  	case 86: 
  2319  		o1 = c.oprrr(p, p.As, int(p.Scond))
  2320  
  2321  		o1 |= (uint32(p.From.Reg) & 15) << 0
  2322  		o1 |= (FREGTMP & 15) << 12
  2323  		o2 = c.oprrr(p, -AMOVFW, int(p.Scond))
  2324  		o2 |= (FREGTMP & 15) << 16
  2325  		o2 |= (uint32(p.To.Reg) & 15) << 12
  2326  
  2327  		
  2328  	case 87: 
  2329  		o1 = c.oprrr(p, -AMOVWF, int(p.Scond))
  2330  
  2331  		o1 |= (uint32(p.From.Reg) & 15) << 12
  2332  		o1 |= (FREGTMP & 15) << 16
  2333  		o2 = c.oprrr(p, p.As, int(p.Scond))
  2334  		o2 |= (FREGTMP & 15) << 0
  2335  		o2 |= (uint32(p.To.Reg) & 15) << 12
  2336  
  2337  	case 88: 
  2338  		o1 = c.oprrr(p, -AMOVWF, int(p.Scond))
  2339  
  2340  		o1 |= (uint32(p.From.Reg) & 15) << 12
  2341  		o1 |= (uint32(p.To.Reg) & 15) << 16
  2342  
  2343  	case 89: 
  2344  		o1 = c.oprrr(p, -AMOVFW, int(p.Scond))
  2345  
  2346  		o1 |= (uint32(p.From.Reg) & 15) << 16
  2347  		o1 |= (uint32(p.To.Reg) & 15) << 12
  2348  
  2349  	case 91: 
  2350  		c.aclass(&p.From)
  2351  
  2352  		if c.instoffset != 0 {
  2353  			c.ctxt.Diag("offset must be zero in LDREX")
  2354  		}
  2355  		o1 = 0x1b<<20 | 0xf9f
  2356  		o1 |= (uint32(p.From.Reg) & 15) << 16
  2357  		o1 |= (uint32(p.To.Reg) & 15) << 12
  2358  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  2359  
  2360  	case 92: 
  2361  		c.aclass(&p.From)
  2362  
  2363  		if c.instoffset != 0 {
  2364  			c.ctxt.Diag("offset must be zero in STREX")
  2365  		}
  2366  		if p.Reg&1 != 0 {
  2367  			c.ctxt.Diag("source register must be even in STREXD: %v", p)
  2368  		}
  2369  		if p.To.Reg == p.From.Reg || p.To.Reg == p.Reg || p.To.Reg == p.Reg+1 {
  2370  			c.ctxt.Diag("cannot use same register as both source and destination: %v", p)
  2371  		}
  2372  		o1 = 0x1a<<20 | 0xf90
  2373  		o1 |= (uint32(p.From.Reg) & 15) << 16
  2374  		o1 |= (uint32(p.Reg) & 15) << 0
  2375  		o1 |= (uint32(p.To.Reg) & 15) << 12
  2376  		o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  2377  
  2378  	case 93: 
  2379  		o1 = c.omvl(p, &p.From, REGTMP)
  2380  
  2381  		if o1 == 0 {
  2382  			break
  2383  		}
  2384  		o2 = c.olhr(0, REGTMP, int(p.To.Reg), int(p.Scond))
  2385  		if p.As == AMOVB || p.As == AMOVBS {
  2386  			o2 ^= 1<<5 | 1<<6
  2387  		} else if p.As == AMOVH || p.As == AMOVHS {
  2388  			o2 ^= (1 << 6)
  2389  		}
  2390  		if o.flag&LPCREL != 0 {
  2391  			o3 = o2
  2392  			o2 = c.oprrr(p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
  2393  		}
  2394  
  2395  	case 94: 
  2396  		o1 = c.omvl(p, &p.To, REGTMP)
  2397  
  2398  		if o1 == 0 {
  2399  			break
  2400  		}
  2401  		o2 = c.oshr(int(p.From.Reg), 0, REGTMP, int(p.Scond))
  2402  		if o.flag&LPCREL != 0 {
  2403  			o3 = o2
  2404  			o2 = c.oprrr(p, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12
  2405  		}
  2406  
  2407  	case 95: 
  2408  		o1 = 0xf5d0f000
  2409  
  2410  		o1 |= (uint32(p.From.Reg) & 15) << 16
  2411  		if p.From.Offset < 0 {
  2412  			o1 &^= (1 << 23)
  2413  			o1 |= uint32((-p.From.Offset) & 0xfff)
  2414  		} else {
  2415  			o1 |= uint32(p.From.Offset & 0xfff)
  2416  		}
  2417  
  2418  	
  2419  	
  2420  	
  2421  	
  2422  	
  2423  	case 96: 
  2424  		o1 = 0xf7fabcfd
  2425  
  2426  	case 97: 
  2427  		o1 = c.oprrr(p, p.As, int(p.Scond))
  2428  
  2429  		o1 |= (uint32(p.To.Reg) & 15) << 12
  2430  		o1 |= (uint32(p.From.Reg) & 15) << 0
  2431  
  2432  	case 98: 
  2433  		o1 = c.oprrr(p, p.As, int(p.Scond))
  2434  
  2435  		o1 |= (uint32(p.To.Reg) & 15) << 16
  2436  		o1 |= (uint32(p.From.Reg) & 15) << 8
  2437  		o1 |= (uint32(p.Reg) & 15) << 0
  2438  
  2439  	case 99: 
  2440  		o1 = c.oprrr(p, p.As, int(p.Scond))
  2441  
  2442  		o1 |= (uint32(p.To.Reg) & 15) << 16
  2443  		o1 |= (uint32(p.From.Reg) & 15) << 8
  2444  		o1 |= (uint32(p.Reg) & 15) << 0
  2445  		o1 |= uint32((p.To.Offset & 15) << 12)
  2446  
  2447  	case 105: 
  2448  		o1 = c.oprrr(p, p.As, int(p.Scond))
  2449  		rf := int(p.From.Reg)
  2450  		rt := int(p.To.Reg)
  2451  		r := int(p.Reg)
  2452  		if r == 0 {
  2453  			r = rt
  2454  		}
  2455  		o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16
  2456  
  2457  	case 110: 
  2458  		o1 = 0xf57ff050
  2459  		mbop := uint32(0)
  2460  
  2461  		switch c.aclass(&p.From) {
  2462  		case C_SPR:
  2463  			for _, f := range mbOp {
  2464  				if f.reg == p.From.Reg {
  2465  					mbop = f.enc
  2466  					break
  2467  				}
  2468  			}
  2469  		case C_RCON:
  2470  			for _, f := range mbOp {
  2471  				enc := uint32(c.instoffset)
  2472  				if f.enc == enc {
  2473  					mbop = enc
  2474  					break
  2475  				}
  2476  			}
  2477  		case C_NONE:
  2478  			mbop = 0xf
  2479  		}
  2480  
  2481  		if mbop == 0 {
  2482  			c.ctxt.Diag("illegal mb option:\n%v", p)
  2483  		}
  2484  		o1 |= mbop
  2485  	}
  2486  
  2487  	out[0] = o1
  2488  	out[1] = o2
  2489  	out[2] = o3
  2490  	out[3] = o4
  2491  	out[4] = o5
  2492  	out[5] = o6
  2493  }
  2494  
  2495  func (c *ctxt5) movxt(p *obj.Prog) uint32 {
  2496  	o1 := ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  2497  	switch p.As {
  2498  	case AMOVB, AMOVBS:
  2499  		o1 |= 0x6af<<16 | 0x7<<4
  2500  	case AMOVH, AMOVHS:
  2501  		o1 |= 0x6bf<<16 | 0x7<<4
  2502  	case AMOVBU:
  2503  		o1 |= 0x6ef<<16 | 0x7<<4
  2504  	case AMOVHU:
  2505  		o1 |= 0x6ff<<16 | 0x7<<4
  2506  	default:
  2507  		c.ctxt.Diag("illegal combination: %v", p)
  2508  	}
  2509  	switch p.From.Offset &^ 0xf {
  2510  	
  2511  	case SHIFT_RR, SHIFT_RR | 8<<7, SHIFT_RR | 16<<7, SHIFT_RR | 24<<7:
  2512  		o1 |= uint32(p.From.Offset) & 0xc0f
  2513  	default:
  2514  		c.ctxt.Diag("illegal shift: %v", p)
  2515  	}
  2516  	o1 |= (uint32(p.To.Reg) & 15) << 12
  2517  	return o1
  2518  }
  2519  
  2520  func (c *ctxt5) mov(p *obj.Prog) uint32 {
  2521  	c.aclass(&p.From)
  2522  	o1 := c.oprrr(p, p.As, int(p.Scond))
  2523  	o1 |= uint32(p.From.Offset)
  2524  	rt := int(p.To.Reg)
  2525  	if p.To.Type == obj.TYPE_NONE {
  2526  		rt = 0
  2527  	}
  2528  	r := int(p.Reg)
  2529  	if p.As == AMOVW || p.As == AMVN {
  2530  		r = 0
  2531  	} else if r == 0 {
  2532  		r = rt
  2533  	}
  2534  	o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12
  2535  	return o1
  2536  }
  2537  
  2538  func (c *ctxt5) oprrr(p *obj.Prog, a obj.As, sc int) uint32 {
  2539  	o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
  2540  	if sc&C_SBIT != 0 {
  2541  		o |= 1 << 20
  2542  	}
  2543  	switch a {
  2544  	case ADIVHW:
  2545  		return o | 0x71<<20 | 0xf<<12 | 0x1<<4
  2546  	case ADIVUHW:
  2547  		return o | 0x73<<20 | 0xf<<12 | 0x1<<4
  2548  	case AMMUL:
  2549  		return o | 0x75<<20 | 0xf<<12 | 0x1<<4
  2550  	case AMULS:
  2551  		return o | 0x6<<20 | 0x9<<4
  2552  	case AMMULA:
  2553  		return o | 0x75<<20 | 0x1<<4
  2554  	case AMMULS:
  2555  		return o | 0x75<<20 | 0xd<<4
  2556  	case AMULU, AMUL:
  2557  		return o | 0x0<<21 | 0x9<<4
  2558  	case AMULA:
  2559  		return o | 0x1<<21 | 0x9<<4
  2560  	case AMULLU:
  2561  		return o | 0x4<<21 | 0x9<<4
  2562  	case AMULL:
  2563  		return o | 0x6<<21 | 0x9<<4
  2564  	case AMULALU:
  2565  		return o | 0x5<<21 | 0x9<<4
  2566  	case AMULAL:
  2567  		return o | 0x7<<21 | 0x9<<4
  2568  	case AAND:
  2569  		return o | 0x0<<21
  2570  	case AEOR:
  2571  		return o | 0x1<<21
  2572  	case ASUB:
  2573  		return o | 0x2<<21
  2574  	case ARSB:
  2575  		return o | 0x3<<21
  2576  	case AADD:
  2577  		return o | 0x4<<21
  2578  	case AADC:
  2579  		return o | 0x5<<21
  2580  	case ASBC:
  2581  		return o | 0x6<<21
  2582  	case ARSC:
  2583  		return o | 0x7<<21
  2584  	case ATST:
  2585  		return o | 0x8<<21 | 1<<20
  2586  	case ATEQ:
  2587  		return o | 0x9<<21 | 1<<20
  2588  	case ACMP:
  2589  		return o | 0xa<<21 | 1<<20
  2590  	case ACMN:
  2591  		return o | 0xb<<21 | 1<<20
  2592  	case AORR:
  2593  		return o | 0xc<<21
  2594  
  2595  	case AMOVB, AMOVH, AMOVW:
  2596  		if sc&(C_PBIT|C_WBIT) != 0 {
  2597  			c.ctxt.Diag("invalid .P/.W suffix: %v", p)
  2598  		}
  2599  		return o | 0xd<<21
  2600  	case ABIC:
  2601  		return o | 0xe<<21
  2602  	case AMVN:
  2603  		return o | 0xf<<21
  2604  	case ASLL:
  2605  		return o | 0xd<<21 | 0<<5
  2606  	case ASRL:
  2607  		return o | 0xd<<21 | 1<<5
  2608  	case ASRA:
  2609  		return o | 0xd<<21 | 2<<5
  2610  	case ASWI:
  2611  		return o | 0xf<<24
  2612  
  2613  	case AADDD:
  2614  		return o | 0xe<<24 | 0x3<<20 | 0xb<<8 | 0<<4
  2615  	case AADDF:
  2616  		return o | 0xe<<24 | 0x3<<20 | 0xa<<8 | 0<<4
  2617  	case ASUBD:
  2618  		return o | 0xe<<24 | 0x3<<20 | 0xb<<8 | 4<<4
  2619  	case ASUBF:
  2620  		return o | 0xe<<24 | 0x3<<20 | 0xa<<8 | 4<<4
  2621  	case AMULD:
  2622  		return o | 0xe<<24 | 0x2<<20 | 0xb<<8 | 0<<4
  2623  	case AMULF:
  2624  		return o | 0xe<<24 | 0x2<<20 | 0xa<<8 | 0<<4
  2625  	case ANMULD:
  2626  		return o | 0xe<<24 | 0x2<<20 | 0xb<<8 | 0x4<<4
  2627  	case ANMULF:
  2628  		return o | 0xe<<24 | 0x2<<20 | 0xa<<8 | 0x4<<4
  2629  	case AMULAD:
  2630  		return o | 0xe<<24 | 0xb<<8
  2631  	case AMULAF:
  2632  		return o | 0xe<<24 | 0xa<<8
  2633  	case AMULSD:
  2634  		return o | 0xe<<24 | 0xb<<8 | 0x4<<4
  2635  	case AMULSF:
  2636  		return o | 0xe<<24 | 0xa<<8 | 0x4<<4
  2637  	case ANMULAD:
  2638  		return o | 0xe<<24 | 0x1<<20 | 0xb<<8 | 0x4<<4
  2639  	case ANMULAF:
  2640  		return o | 0xe<<24 | 0x1<<20 | 0xa<<8 | 0x4<<4
  2641  	case ANMULSD:
  2642  		return o | 0xe<<24 | 0x1<<20 | 0xb<<8
  2643  	case ANMULSF:
  2644  		return o | 0xe<<24 | 0x1<<20 | 0xa<<8
  2645  	case AFMULAD:
  2646  		return o | 0xe<<24 | 0xa<<20 | 0xb<<8
  2647  	case AFMULAF:
  2648  		return o | 0xe<<24 | 0xa<<20 | 0xa<<8
  2649  	case AFMULSD:
  2650  		return o | 0xe<<24 | 0xa<<20 | 0xb<<8 | 0x4<<4
  2651  	case AFMULSF:
  2652  		return o | 0xe<<24 | 0xa<<20 | 0xa<<8 | 0x4<<4
  2653  	case AFNMULAD:
  2654  		return o | 0xe<<24 | 0x9<<20 | 0xb<<8 | 0x4<<4
  2655  	case AFNMULAF:
  2656  		return o | 0xe<<24 | 0x9<<20 | 0xa<<8 | 0x4<<4
  2657  	case AFNMULSD:
  2658  		return o | 0xe<<24 | 0x9<<20 | 0xb<<8
  2659  	case AFNMULSF:
  2660  		return o | 0xe<<24 | 0x9<<20 | 0xa<<8
  2661  	case ADIVD:
  2662  		return o | 0xe<<24 | 0x8<<20 | 0xb<<8 | 0<<4
  2663  	case ADIVF:
  2664  		return o | 0xe<<24 | 0x8<<20 | 0xa<<8 | 0<<4
  2665  	case ASQRTD:
  2666  		return o | 0xe<<24 | 0xb<<20 | 1<<16 | 0xb<<8 | 0xc<<4
  2667  	case ASQRTF:
  2668  		return o | 0xe<<24 | 0xb<<20 | 1<<16 | 0xa<<8 | 0xc<<4
  2669  	case AABSD:
  2670  		return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xb<<8 | 0xc<<4
  2671  	case AABSF:
  2672  		return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xa<<8 | 0xc<<4
  2673  	case ANEGD:
  2674  		return o | 0xe<<24 | 0xb<<20 | 1<<16 | 0xb<<8 | 0x4<<4
  2675  	case ANEGF:
  2676  		return o | 0xe<<24 | 0xb<<20 | 1<<16 | 0xa<<8 | 0x4<<4
  2677  	case ACMPD:
  2678  		return o | 0xe<<24 | 0xb<<20 | 4<<16 | 0xb<<8 | 0xc<<4
  2679  	case ACMPF:
  2680  		return o | 0xe<<24 | 0xb<<20 | 4<<16 | 0xa<<8 | 0xc<<4
  2681  
  2682  	case AMOVF:
  2683  		return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xa<<8 | 4<<4
  2684  	case AMOVD:
  2685  		return o | 0xe<<24 | 0xb<<20 | 0<<16 | 0xb<<8 | 4<<4
  2686  
  2687  	case AMOVDF:
  2688  		return o | 0xe<<24 | 0xb<<20 | 7<<16 | 0xa<<8 | 0xc<<4 | 1<<8 
  2689  	case AMOVFD:
  2690  		return o | 0xe<<24 | 0xb<<20 | 7<<16 | 0xa<<8 | 0xc<<4 | 0<<8 
  2691  
  2692  	case AMOVWF:
  2693  		if sc&C_UBIT == 0 {
  2694  			o |= 1 << 7 
  2695  		}
  2696  		return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 0<<18 | 0<<8 
  2697  
  2698  	case AMOVWD:
  2699  		if sc&C_UBIT == 0 {
  2700  			o |= 1 << 7 
  2701  		}
  2702  		return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 0<<18 | 1<<8 
  2703  
  2704  	case AMOVFW:
  2705  		if sc&C_UBIT == 0 {
  2706  			o |= 1 << 16 
  2707  		}
  2708  		return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 1<<18 | 0<<8 | 1<<7 
  2709  
  2710  	case AMOVDW:
  2711  		if sc&C_UBIT == 0 {
  2712  			o |= 1 << 16 
  2713  		}
  2714  		return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 1<<18 | 1<<8 | 1<<7 
  2715  
  2716  	case -AMOVWF: 
  2717  		return o | 0xe<<24 | 0x0<<20 | 0xb<<8 | 1<<4
  2718  
  2719  	case -AMOVFW: 
  2720  		return o | 0xe<<24 | 0x1<<20 | 0xb<<8 | 1<<4
  2721  
  2722  	case -ACMP: 
  2723  		return o | 0x3<<24 | 0x5<<20
  2724  
  2725  	case ABFX:
  2726  		return o | 0x3d<<21 | 0x5<<4
  2727  
  2728  	case ABFXU:
  2729  		return o | 0x3f<<21 | 0x5<<4
  2730  
  2731  	case ABFC:
  2732  		return o | 0x3e<<21 | 0x1f
  2733  
  2734  	case ABFI:
  2735  		return o | 0x3e<<21 | 0x1<<4
  2736  
  2737  	case AXTAB:
  2738  		return o | 0x6a<<20 | 0x7<<4
  2739  
  2740  	case AXTAH:
  2741  		return o | 0x6b<<20 | 0x7<<4
  2742  
  2743  	case AXTABU:
  2744  		return o | 0x6e<<20 | 0x7<<4
  2745  
  2746  	case AXTAHU:
  2747  		return o | 0x6f<<20 | 0x7<<4
  2748  
  2749  		
  2750  	case ACLZ:
  2751  		return o&(0xf<<28) | 0x16f<<16 | 0xf1<<4
  2752  
  2753  	case AREV:
  2754  		return o&(0xf<<28) | 0x6bf<<16 | 0xf3<<4
  2755  
  2756  	case AREV16:
  2757  		return o&(0xf<<28) | 0x6bf<<16 | 0xfb<<4
  2758  
  2759  	case AREVSH:
  2760  		return o&(0xf<<28) | 0x6ff<<16 | 0xfb<<4
  2761  
  2762  	case ARBIT:
  2763  		return o&(0xf<<28) | 0x6ff<<16 | 0xf3<<4
  2764  
  2765  	case AMULWT:
  2766  		return o&(0xf<<28) | 0x12<<20 | 0xe<<4
  2767  
  2768  	case AMULWB:
  2769  		return o&(0xf<<28) | 0x12<<20 | 0xa<<4
  2770  
  2771  	case AMULBB:
  2772  		return o&(0xf<<28) | 0x16<<20 | 0x8<<4
  2773  
  2774  	case AMULAWT:
  2775  		return o&(0xf<<28) | 0x12<<20 | 0xc<<4
  2776  
  2777  	case AMULAWB:
  2778  		return o&(0xf<<28) | 0x12<<20 | 0x8<<4
  2779  
  2780  	case AMULABB:
  2781  		return o&(0xf<<28) | 0x10<<20 | 0x8<<4
  2782  
  2783  	case ABL: 
  2784  		return o&(0xf<<28) | 0x12fff3<<4
  2785  	}
  2786  
  2787  	c.ctxt.Diag("%v: bad rrr %d", p, a)
  2788  	return 0
  2789  }
  2790  
  2791  func (c *ctxt5) opbra(p *obj.Prog, a obj.As, sc int) uint32 {
  2792  	sc &= C_SCOND
  2793  	sc ^= C_SCOND_XOR
  2794  	if a == ABL || a == obj.ADUFFZERO || a == obj.ADUFFCOPY {
  2795  		return uint32(sc)<<28 | 0x5<<25 | 0x1<<24
  2796  	}
  2797  	if sc != 0xe {
  2798  		c.ctxt.Diag("%v: .COND on bcond instruction", p)
  2799  	}
  2800  	switch a {
  2801  	case ABEQ:
  2802  		return 0x0<<28 | 0x5<<25
  2803  	case ABNE:
  2804  		return 0x1<<28 | 0x5<<25
  2805  	case ABCS:
  2806  		return 0x2<<28 | 0x5<<25
  2807  	case ABHS:
  2808  		return 0x2<<28 | 0x5<<25
  2809  	case ABCC:
  2810  		return 0x3<<28 | 0x5<<25
  2811  	case ABLO:
  2812  		return 0x3<<28 | 0x5<<25
  2813  	case ABMI:
  2814  		return 0x4<<28 | 0x5<<25
  2815  	case ABPL:
  2816  		return 0x5<<28 | 0x5<<25
  2817  	case ABVS:
  2818  		return 0x6<<28 | 0x5<<25
  2819  	case ABVC:
  2820  		return 0x7<<28 | 0x5<<25
  2821  	case ABHI:
  2822  		return 0x8<<28 | 0x5<<25
  2823  	case ABLS:
  2824  		return 0x9<<28 | 0x5<<25
  2825  	case ABGE:
  2826  		return 0xa<<28 | 0x5<<25
  2827  	case ABLT:
  2828  		return 0xb<<28 | 0x5<<25
  2829  	case ABGT:
  2830  		return 0xc<<28 | 0x5<<25
  2831  	case ABLE:
  2832  		return 0xd<<28 | 0x5<<25
  2833  	case AB:
  2834  		return 0xe<<28 | 0x5<<25
  2835  	}
  2836  
  2837  	c.ctxt.Diag("%v: bad bra %v", p, a)
  2838  	return 0
  2839  }
  2840  
  2841  func (c *ctxt5) olr(v int32, b int, r int, sc int) uint32 {
  2842  	o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
  2843  	if sc&C_PBIT == 0 {
  2844  		o |= 1 << 24
  2845  	}
  2846  	if sc&C_UBIT == 0 {
  2847  		o |= 1 << 23
  2848  	}
  2849  	if sc&C_WBIT != 0 {
  2850  		o |= 1 << 21
  2851  	}
  2852  	o |= 1<<26 | 1<<20
  2853  	if v < 0 {
  2854  		if sc&C_UBIT != 0 {
  2855  			c.ctxt.Diag(".U on neg offset")
  2856  		}
  2857  		v = -v
  2858  		o ^= 1 << 23
  2859  	}
  2860  
  2861  	if v >= 1<<12 || v < 0 {
  2862  		c.ctxt.Diag("literal span too large: %d (R%d)\n%v", v, b, c.printp)
  2863  	}
  2864  	o |= uint32(v)
  2865  	o |= (uint32(b) & 15) << 16
  2866  	o |= (uint32(r) & 15) << 12
  2867  	return o
  2868  }
  2869  
  2870  func (c *ctxt5) olhr(v int32, b int, r int, sc int) uint32 {
  2871  	o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
  2872  	if sc&C_PBIT == 0 {
  2873  		o |= 1 << 24
  2874  	}
  2875  	if sc&C_WBIT != 0 {
  2876  		o |= 1 << 21
  2877  	}
  2878  	o |= 1<<23 | 1<<20 | 0xb<<4
  2879  	if v < 0 {
  2880  		v = -v
  2881  		o ^= 1 << 23
  2882  	}
  2883  
  2884  	if v >= 1<<8 || v < 0 {
  2885  		c.ctxt.Diag("literal span too large: %d (R%d)\n%v", v, b, c.printp)
  2886  	}
  2887  	o |= uint32(v)&0xf | (uint32(v)>>4)<<8 | 1<<22
  2888  	o |= (uint32(b) & 15) << 16
  2889  	o |= (uint32(r) & 15) << 12
  2890  	return o
  2891  }
  2892  
  2893  func (c *ctxt5) osr(a obj.As, r int, v int32, b int, sc int) uint32 {
  2894  	o := c.olr(v, b, r, sc) ^ (1 << 20)
  2895  	if a != AMOVW {
  2896  		o |= 1 << 22
  2897  	}
  2898  	return o
  2899  }
  2900  
  2901  func (c *ctxt5) oshr(r int, v int32, b int, sc int) uint32 {
  2902  	o := c.olhr(v, b, r, sc) ^ (1 << 20)
  2903  	return o
  2904  }
  2905  
  2906  func (c *ctxt5) osrr(r int, i int, b int, sc int) uint32 {
  2907  	return c.olr(int32(i), b, r, sc) ^ (1<<25 | 1<<20)
  2908  }
  2909  
  2910  func (c *ctxt5) oshrr(r int, i int, b int, sc int) uint32 {
  2911  	return c.olhr(int32(i), b, r, sc) ^ (1<<22 | 1<<20)
  2912  }
  2913  
  2914  func (c *ctxt5) olrr(i int, b int, r int, sc int) uint32 {
  2915  	return c.olr(int32(i), b, r, sc) ^ (1 << 25)
  2916  }
  2917  
  2918  func (c *ctxt5) olhrr(i int, b int, r int, sc int) uint32 {
  2919  	return c.olhr(int32(i), b, r, sc) ^ (1 << 22)
  2920  }
  2921  
  2922  func (c *ctxt5) ofsr(a obj.As, r int, v int32, b int, sc int, p *obj.Prog) uint32 {
  2923  	o := ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28
  2924  	if sc&C_PBIT == 0 {
  2925  		o |= 1 << 24
  2926  	}
  2927  	if sc&C_WBIT != 0 {
  2928  		o |= 1 << 21
  2929  	}
  2930  	o |= 6<<25 | 1<<24 | 1<<23 | 10<<8
  2931  	if v < 0 {
  2932  		v = -v
  2933  		o ^= 1 << 23
  2934  	}
  2935  
  2936  	if v&3 != 0 {
  2937  		c.ctxt.Diag("odd offset for floating point op: %d\n%v", v, p)
  2938  	} else if v >= 1<<10 || v < 0 {
  2939  		c.ctxt.Diag("literal span too large: %d\n%v", v, p)
  2940  	}
  2941  	o |= (uint32(v) >> 2) & 0xFF
  2942  	o |= (uint32(b) & 15) << 16
  2943  	o |= (uint32(r) & 15) << 12
  2944  
  2945  	switch a {
  2946  	default:
  2947  		c.ctxt.Diag("bad fst %v", a)
  2948  		fallthrough
  2949  
  2950  	case AMOVD:
  2951  		o |= 1 << 8
  2952  		fallthrough
  2953  
  2954  	case AMOVF:
  2955  		break
  2956  	}
  2957  
  2958  	return o
  2959  }
  2960  
  2961  
  2962  func (c *ctxt5) omvs(p *obj.Prog, a *obj.Addr, dr int) uint32 {
  2963  	o1 := ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28
  2964  	o1 |= 0x30 << 20
  2965  	o1 |= (uint32(dr) & 15) << 12
  2966  	o1 |= uint32(a.Offset) & 0x0fff
  2967  	o1 |= (uint32(a.Offset) & 0xf000) << 4
  2968  	return o1
  2969  }
  2970  
  2971  
  2972  func (c *ctxt5) omvr(p *obj.Prog, a *obj.Addr, dr int) uint32 {
  2973  	o1 := c.oprrr(p, AMOVW, int(p.Scond))
  2974  	o1 |= (uint32(dr) & 15) << 12
  2975  	v := immrot(^uint32(a.Offset))
  2976  	if v == 0 {
  2977  		c.ctxt.Diag("%v: missing literal", p)
  2978  		return 0
  2979  	}
  2980  	o1 |= uint32(v)
  2981  	return o1
  2982  }
  2983  
  2984  func (c *ctxt5) omvl(p *obj.Prog, a *obj.Addr, dr int) uint32 {
  2985  	var o1 uint32
  2986  	if p.Pool == nil {
  2987  		c.aclass(a)
  2988  		v := immrot(^uint32(c.instoffset))
  2989  		if v == 0 {
  2990  			c.ctxt.Diag("%v: missing literal", p)
  2991  			return 0
  2992  		}
  2993  
  2994  		o1 = c.oprrr(p, AMVN, int(p.Scond)&C_SCOND)
  2995  		o1 |= uint32(v)
  2996  		o1 |= (uint32(dr) & 15) << 12
  2997  	} else {
  2998  		v := int32(p.Pool.Pc - p.Pc - 8)
  2999  		o1 = c.olr(v, REGPC, dr, int(p.Scond)&C_SCOND)
  3000  	}
  3001  
  3002  	return o1
  3003  }
  3004  
  3005  func (c *ctxt5) chipzero5(e float64) int {
  3006  	
  3007  	if buildcfg.GOARM < 7 || math.Float64bits(e) != 0 {
  3008  		return -1
  3009  	}
  3010  	return 0
  3011  }
  3012  
  3013  func (c *ctxt5) chipfloat5(e float64) int {
  3014  	
  3015  	if buildcfg.GOARM < 7 {
  3016  		return -1
  3017  	}
  3018  
  3019  	ei := math.Float64bits(e)
  3020  	l := uint32(ei)
  3021  	h := uint32(ei >> 32)
  3022  
  3023  	if l != 0 || h&0xffff != 0 {
  3024  		return -1
  3025  	}
  3026  	h1 := h & 0x7fc00000
  3027  	if h1 != 0x40000000 && h1 != 0x3fc00000 {
  3028  		return -1
  3029  	}
  3030  	n := 0
  3031  
  3032  	
  3033  	if h&0x80000000 != 0 {
  3034  		n |= 1 << 7
  3035  	}
  3036  
  3037  	
  3038  	if h1 == 0x3fc00000 {
  3039  		n |= 1 << 6
  3040  	}
  3041  
  3042  	
  3043  	n |= int((h >> 16) & 0x3f)
  3044  
  3045  	
  3046  	return n
  3047  }
  3048  
  3049  func nocache(p *obj.Prog) {
  3050  	p.Optab = 0
  3051  	p.From.Class = 0
  3052  	if p.GetFrom3() != nil {
  3053  		p.GetFrom3().Class = 0
  3054  	}
  3055  	p.To.Class = 0
  3056  }