github.com/bir3/gocompiler@v0.3.205/src/cmd/internal/obj/loong64/asm.go (about)

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package loong64
     6  
     7  import (
     8  	"github.com/bir3/gocompiler/src/cmd/internal/obj"
     9  	"github.com/bir3/gocompiler/src/cmd/internal/objabi"
    10  	"github.com/bir3/gocompiler/src/cmd/internal/sys"
    11  	"fmt"
    12  	"log"
    13  	"sort"
    14  )
    15  
    16  // ctxt0 holds state while assembling a single function.
    17  // Each function gets a fresh ctxt0.
    18  // This allows for multiple functions to be safely concurrently assembled.
    19  type ctxt0 struct {
    20  	ctxt       *obj.Link
    21  	newprog    obj.ProgAlloc
    22  	cursym     *obj.LSym
    23  	autosize   int32
    24  	instoffset int64
    25  	pc         int64
    26  }
    27  
    28  // Instruction layout.
    29  
    30  const (
    31  	FuncAlign = 4
    32  )
    33  
    34  type Optab struct {
    35  	as     obj.As
    36  	a1     uint8
    37  	a2     uint8
    38  	a3     uint8
    39  	type_  int8
    40  	size   int8
    41  	param  int16
    42  	family sys.ArchFamily
    43  	flag   uint8
    44  }
    45  
    46  const (
    47  	NOTUSETMP = 1 << iota // p expands to multiple instructions, but does NOT use REGTMP
    48  )
    49  
    50  var optab = []Optab{
    51  	{obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0},
    52  
    53  	{AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0},
    54  	{AMOVV, C_REG, C_NONE, C_REG, 1, 4, 0, sys.Loong64, 0},
    55  	{AMOVB, C_REG, C_NONE, C_REG, 12, 8, 0, 0, NOTUSETMP},
    56  	{AMOVBU, C_REG, C_NONE, C_REG, 13, 4, 0, 0, 0},
    57  	{AMOVWU, C_REG, C_NONE, C_REG, 14, 8, 0, sys.Loong64, NOTUSETMP},
    58  
    59  	{ASUB, C_REG, C_REG, C_REG, 2, 4, 0, 0, 0},
    60  	{ASUBV, C_REG, C_REG, C_REG, 2, 4, 0, sys.Loong64, 0},
    61  	{AADD, C_REG, C_REG, C_REG, 2, 4, 0, 0, 0},
    62  	{AADDV, C_REG, C_REG, C_REG, 2, 4, 0, sys.Loong64, 0},
    63  	{AAND, C_REG, C_REG, C_REG, 2, 4, 0, 0, 0},
    64  	{ASUB, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
    65  	{ASUBV, C_REG, C_NONE, C_REG, 2, 4, 0, sys.Loong64, 0},
    66  	{AADD, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
    67  	{AADDV, C_REG, C_NONE, C_REG, 2, 4, 0, sys.Loong64, 0},
    68  	{AAND, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
    69  	{ANEGW, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
    70  	{ANEGV, C_REG, C_NONE, C_REG, 2, 4, 0, sys.Loong64, 0},
    71  	{AMASKEQZ, C_REG, C_REG, C_REG, 2, 4, 0, 0, 0},
    72  
    73  	{ASLL, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0},
    74  	{ASLL, C_REG, C_REG, C_REG, 9, 4, 0, 0, 0},
    75  	{ASLLV, C_REG, C_NONE, C_REG, 9, 4, 0, sys.Loong64, 0},
    76  	{ASLLV, C_REG, C_REG, C_REG, 9, 4, 0, sys.Loong64, 0},
    77  	{ACLO, C_REG, C_NONE, C_REG, 9, 4, 0, 0, 0},
    78  
    79  	{AADDF, C_FREG, C_NONE, C_FREG, 32, 4, 0, 0, 0},
    80  	{AADDF, C_FREG, C_REG, C_FREG, 32, 4, 0, 0, 0},
    81  	{ACMPEQF, C_FREG, C_REG, C_NONE, 32, 4, 0, 0, 0},
    82  	{AABSF, C_FREG, C_NONE, C_FREG, 33, 4, 0, 0, 0},
    83  	{AMOVVF, C_FREG, C_NONE, C_FREG, 33, 4, 0, sys.Loong64, 0},
    84  	{AMOVF, C_FREG, C_NONE, C_FREG, 33, 4, 0, 0, 0},
    85  	{AMOVD, C_FREG, C_NONE, C_FREG, 33, 4, 0, 0, 0},
    86  
    87  	{AMOVW, C_REG, C_NONE, C_SEXT, 7, 4, 0, sys.Loong64, 0},
    88  	{AMOVWU, C_REG, C_NONE, C_SEXT, 7, 4, 0, sys.Loong64, 0},
    89  	{AMOVV, C_REG, C_NONE, C_SEXT, 7, 4, 0, sys.Loong64, 0},
    90  	{AMOVB, C_REG, C_NONE, C_SEXT, 7, 4, 0, sys.Loong64, 0},
    91  	{AMOVBU, C_REG, C_NONE, C_SEXT, 7, 4, 0, sys.Loong64, 0},
    92  	{AMOVWL, C_REG, C_NONE, C_SEXT, 7, 4, 0, sys.Loong64, 0},
    93  	{AMOVVL, C_REG, C_NONE, C_SEXT, 7, 4, 0, sys.Loong64, 0},
    94  	{AMOVW, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0, 0},
    95  	{AMOVWU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, sys.Loong64, 0},
    96  	{AMOVV, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, sys.Loong64, 0},
    97  	{AMOVB, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0, 0},
    98  	{AMOVBU, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0, 0},
    99  	{AMOVWL, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, 0, 0},
   100  	{AMOVVL, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, sys.Loong64, 0},
   101  	{AMOVW, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0, 0},
   102  	{AMOVWU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.Loong64, 0},
   103  	{AMOVV, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.Loong64, 0},
   104  	{AMOVB, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0, 0},
   105  	{AMOVBU, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0, 0},
   106  	{AMOVWL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0, 0},
   107  	{AMOVVL, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.Loong64, 0},
   108  	{ASC, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, 0, 0},
   109  	{ASCV, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.Loong64, 0},
   110  
   111  	{AMOVW, C_SEXT, C_NONE, C_REG, 8, 4, 0, sys.Loong64, 0},
   112  	{AMOVWU, C_SEXT, C_NONE, C_REG, 8, 4, 0, sys.Loong64, 0},
   113  	{AMOVV, C_SEXT, C_NONE, C_REG, 8, 4, 0, sys.Loong64, 0},
   114  	{AMOVB, C_SEXT, C_NONE, C_REG, 8, 4, 0, sys.Loong64, 0},
   115  	{AMOVBU, C_SEXT, C_NONE, C_REG, 8, 4, 0, sys.Loong64, 0},
   116  	{AMOVWL, C_SEXT, C_NONE, C_REG, 8, 4, 0, sys.Loong64, 0},
   117  	{AMOVVL, C_SEXT, C_NONE, C_REG, 8, 4, 0, sys.Loong64, 0},
   118  	{AMOVW, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0, 0},
   119  	{AMOVWU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, sys.Loong64, 0},
   120  	{AMOVV, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, sys.Loong64, 0},
   121  	{AMOVB, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0, 0},
   122  	{AMOVBU, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0, 0},
   123  	{AMOVWL, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, 0, 0},
   124  	{AMOVVL, C_SAUTO, C_NONE, C_REG, 8, 4, REGSP, sys.Loong64, 0},
   125  	{AMOVW, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0, 0},
   126  	{AMOVWU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, sys.Loong64, 0},
   127  	{AMOVV, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, sys.Loong64, 0},
   128  	{AMOVB, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0, 0},
   129  	{AMOVBU, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0, 0},
   130  	{AMOVWL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0, 0},
   131  	{AMOVVL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, sys.Loong64, 0},
   132  	{ALL, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, 0, 0},
   133  	{ALLV, C_SOREG, C_NONE, C_REG, 8, 4, REGZERO, sys.Loong64, 0},
   134  
   135  	{AMOVW, C_REG, C_NONE, C_LEXT, 35, 12, 0, sys.Loong64, 0},
   136  	{AMOVWU, C_REG, C_NONE, C_LEXT, 35, 12, 0, sys.Loong64, 0},
   137  	{AMOVV, C_REG, C_NONE, C_LEXT, 35, 12, 0, sys.Loong64, 0},
   138  	{AMOVB, C_REG, C_NONE, C_LEXT, 35, 12, 0, sys.Loong64, 0},
   139  	{AMOVBU, C_REG, C_NONE, C_LEXT, 35, 12, 0, sys.Loong64, 0},
   140  	{AMOVW, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, 0, 0},
   141  	{AMOVWU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, sys.Loong64, 0},
   142  	{AMOVV, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, sys.Loong64, 0},
   143  	{AMOVB, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, 0, 0},
   144  	{AMOVBU, C_REG, C_NONE, C_LAUTO, 35, 12, REGSP, 0, 0},
   145  	{AMOVW, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0, 0},
   146  	{AMOVWU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, sys.Loong64, 0},
   147  	{AMOVV, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, sys.Loong64, 0},
   148  	{AMOVB, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0, 0},
   149  	{AMOVBU, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0, 0},
   150  	{ASC, C_REG, C_NONE, C_LOREG, 35, 12, REGZERO, 0, 0},
   151  	{AMOVW, C_REG, C_NONE, C_ADDR, 50, 8, 0, 0, 0},
   152  	{AMOVW, C_REG, C_NONE, C_ADDR, 50, 8, 0, sys.Loong64, 0},
   153  	{AMOVWU, C_REG, C_NONE, C_ADDR, 50, 8, 0, sys.Loong64, 0},
   154  	{AMOVV, C_REG, C_NONE, C_ADDR, 50, 8, 0, sys.Loong64, 0},
   155  	{AMOVB, C_REG, C_NONE, C_ADDR, 50, 8, 0, 0, 0},
   156  	{AMOVB, C_REG, C_NONE, C_ADDR, 50, 8, 0, sys.Loong64, 0},
   157  	{AMOVBU, C_REG, C_NONE, C_ADDR, 50, 8, 0, 0, 0},
   158  	{AMOVBU, C_REG, C_NONE, C_ADDR, 50, 8, 0, sys.Loong64, 0},
   159  	{AMOVW, C_REG, C_NONE, C_TLS, 53, 16, 0, 0, 0},
   160  	{AMOVWU, C_REG, C_NONE, C_TLS, 53, 16, 0, sys.Loong64, 0},
   161  	{AMOVV, C_REG, C_NONE, C_TLS, 53, 16, 0, sys.Loong64, 0},
   162  	{AMOVB, C_REG, C_NONE, C_TLS, 53, 16, 0, 0, 0},
   163  	{AMOVBU, C_REG, C_NONE, C_TLS, 53, 16, 0, 0, 0},
   164  
   165  	{AMOVW, C_LEXT, C_NONE, C_REG, 36, 12, 0, sys.Loong64, 0},
   166  	{AMOVWU, C_LEXT, C_NONE, C_REG, 36, 12, 0, sys.Loong64, 0},
   167  	{AMOVV, C_LEXT, C_NONE, C_REG, 36, 12, 0, sys.Loong64, 0},
   168  	{AMOVB, C_LEXT, C_NONE, C_REG, 36, 12, 0, sys.Loong64, 0},
   169  	{AMOVBU, C_LEXT, C_NONE, C_REG, 36, 12, 0, sys.Loong64, 0},
   170  	{AMOVW, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, 0, 0},
   171  	{AMOVWU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, sys.Loong64, 0},
   172  	{AMOVV, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, sys.Loong64, 0},
   173  	{AMOVB, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, 0, 0},
   174  	{AMOVBU, C_LAUTO, C_NONE, C_REG, 36, 12, REGSP, 0, 0},
   175  	{AMOVW, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, 0, 0},
   176  	{AMOVWU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, sys.Loong64, 0},
   177  	{AMOVV, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, sys.Loong64, 0},
   178  	{AMOVB, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, 0, 0},
   179  	{AMOVBU, C_LOREG, C_NONE, C_REG, 36, 12, REGZERO, 0, 0},
   180  	{AMOVW, C_ADDR, C_NONE, C_REG, 51, 8, 0, 0, 0},
   181  	{AMOVW, C_ADDR, C_NONE, C_REG, 51, 8, 0, sys.Loong64, 0},
   182  	{AMOVWU, C_ADDR, C_NONE, C_REG, 51, 8, 0, sys.Loong64, 0},
   183  	{AMOVV, C_ADDR, C_NONE, C_REG, 51, 8, 0, sys.Loong64, 0},
   184  	{AMOVB, C_ADDR, C_NONE, C_REG, 51, 8, 0, 0, 0},
   185  	{AMOVB, C_ADDR, C_NONE, C_REG, 51, 8, 0, sys.Loong64, 0},
   186  	{AMOVBU, C_ADDR, C_NONE, C_REG, 51, 8, 0, 0, 0},
   187  	{AMOVBU, C_ADDR, C_NONE, C_REG, 51, 8, 0, sys.Loong64, 0},
   188  	{AMOVW, C_TLS, C_NONE, C_REG, 54, 16, 0, 0, 0},
   189  	{AMOVWU, C_TLS, C_NONE, C_REG, 54, 16, 0, sys.Loong64, 0},
   190  	{AMOVV, C_TLS, C_NONE, C_REG, 54, 16, 0, sys.Loong64, 0},
   191  	{AMOVB, C_TLS, C_NONE, C_REG, 54, 16, 0, 0, 0},
   192  	{AMOVBU, C_TLS, C_NONE, C_REG, 54, 16, 0, 0, 0},
   193  
   194  	{AMOVW, C_SECON, C_NONE, C_REG, 3, 4, 0, sys.Loong64, 0},
   195  	{AMOVV, C_SECON, C_NONE, C_REG, 3, 4, 0, sys.Loong64, 0},
   196  	{AMOVW, C_SACON, C_NONE, C_REG, 3, 4, REGSP, 0, 0},
   197  	{AMOVV, C_SACON, C_NONE, C_REG, 3, 4, REGSP, sys.Loong64, 0},
   198  	{AMOVW, C_LECON, C_NONE, C_REG, 52, 8, 0, 0, NOTUSETMP},
   199  	{AMOVW, C_LECON, C_NONE, C_REG, 52, 8, 0, sys.Loong64, NOTUSETMP},
   200  	{AMOVV, C_LECON, C_NONE, C_REG, 52, 8, 0, sys.Loong64, NOTUSETMP},
   201  
   202  	{AMOVW, C_LACON, C_NONE, C_REG, 26, 12, REGSP, 0, 0},
   203  	{AMOVV, C_LACON, C_NONE, C_REG, 26, 12, REGSP, sys.Loong64, 0},
   204  	{AMOVW, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO, 0, 0},
   205  	{AMOVV, C_ADDCON, C_NONE, C_REG, 3, 4, REGZERO, sys.Loong64, 0},
   206  	{AMOVW, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO, 0, 0},
   207  	{AMOVV, C_ANDCON, C_NONE, C_REG, 3, 4, REGZERO, sys.Loong64, 0},
   208  	{AMOVW, C_STCON, C_NONE, C_REG, 55, 12, 0, 0, 0},
   209  	{AMOVV, C_STCON, C_NONE, C_REG, 55, 12, 0, sys.Loong64, 0},
   210  
   211  	{AMOVW, C_UCON, C_NONE, C_REG, 24, 4, 0, 0, 0},
   212  	{AMOVV, C_UCON, C_NONE, C_REG, 24, 4, 0, sys.Loong64, 0},
   213  	{AMOVW, C_LCON, C_NONE, C_REG, 19, 8, 0, 0, NOTUSETMP},
   214  	{AMOVV, C_LCON, C_NONE, C_REG, 19, 8, 0, sys.Loong64, NOTUSETMP},
   215  	{AMOVV, C_DCON, C_NONE, C_REG, 59, 16, 0, sys.Loong64, NOTUSETMP},
   216  
   217  	{AMUL, C_REG, C_NONE, C_REG, 2, 4, 0, 0, 0},
   218  	{AMUL, C_REG, C_REG, C_REG, 2, 4, 0, 0, 0},
   219  	{AMULV, C_REG, C_NONE, C_REG, 2, 4, 0, sys.Loong64, 0},
   220  	{AMULV, C_REG, C_REG, C_REG, 2, 4, 0, sys.Loong64, 0},
   221  
   222  	{AADD, C_ADD0CON, C_REG, C_REG, 4, 4, 0, 0, 0},
   223  	{AADD, C_ADD0CON, C_NONE, C_REG, 4, 4, 0, 0, 0},
   224  	{AADD, C_ANDCON, C_REG, C_REG, 10, 8, 0, 0, 0},
   225  	{AADD, C_ANDCON, C_NONE, C_REG, 10, 8, 0, 0, 0},
   226  
   227  	{AADDV, C_ADD0CON, C_REG, C_REG, 4, 4, 0, sys.Loong64, 0},
   228  	{AADDV, C_ADD0CON, C_NONE, C_REG, 4, 4, 0, sys.Loong64, 0},
   229  	{AADDV, C_ANDCON, C_REG, C_REG, 10, 8, 0, sys.Loong64, 0},
   230  	{AADDV, C_ANDCON, C_NONE, C_REG, 10, 8, 0, sys.Loong64, 0},
   231  
   232  	{AAND, C_AND0CON, C_REG, C_REG, 4, 4, 0, 0, 0},
   233  	{AAND, C_AND0CON, C_NONE, C_REG, 4, 4, 0, 0, 0},
   234  	{AAND, C_ADDCON, C_REG, C_REG, 10, 8, 0, 0, 0},
   235  	{AAND, C_ADDCON, C_NONE, C_REG, 10, 8, 0, 0, 0},
   236  
   237  	{AADD, C_UCON, C_REG, C_REG, 25, 8, 0, 0, 0},
   238  	{AADD, C_UCON, C_NONE, C_REG, 25, 8, 0, 0, 0},
   239  	{AADDV, C_UCON, C_REG, C_REG, 25, 8, 0, sys.Loong64, 0},
   240  	{AADDV, C_UCON, C_NONE, C_REG, 25, 8, 0, sys.Loong64, 0},
   241  	{AAND, C_UCON, C_REG, C_REG, 25, 8, 0, 0, 0},
   242  	{AAND, C_UCON, C_NONE, C_REG, 25, 8, 0, 0, 0},
   243  
   244  	{AADD, C_LCON, C_NONE, C_REG, 23, 12, 0, 0, 0},
   245  	{AADDV, C_LCON, C_NONE, C_REG, 23, 12, 0, sys.Loong64, 0},
   246  	{AAND, C_LCON, C_NONE, C_REG, 23, 12, 0, 0, 0},
   247  	{AADD, C_LCON, C_REG, C_REG, 23, 12, 0, 0, 0},
   248  	{AADDV, C_LCON, C_REG, C_REG, 23, 12, 0, sys.Loong64, 0},
   249  	{AAND, C_LCON, C_REG, C_REG, 23, 12, 0, 0, 0},
   250  
   251  	{AADDV, C_DCON, C_NONE, C_REG, 60, 20, 0, sys.Loong64, 0},
   252  	{AADDV, C_DCON, C_REG, C_REG, 60, 20, 0, sys.Loong64, 0},
   253  
   254  	{ASLL, C_SCON, C_REG, C_REG, 16, 4, 0, 0, 0},
   255  	{ASLL, C_SCON, C_NONE, C_REG, 16, 4, 0, 0, 0},
   256  
   257  	{ASLLV, C_SCON, C_REG, C_REG, 16, 4, 0, sys.Loong64, 0},
   258  	{ASLLV, C_SCON, C_NONE, C_REG, 16, 4, 0, sys.Loong64, 0},
   259  
   260  	{ASYSCALL, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0, 0},
   261  
   262  	{ABEQ, C_REG, C_REG, C_SBRA, 6, 4, 0, 0, 0},
   263  	{ABEQ, C_REG, C_NONE, C_SBRA, 6, 4, 0, 0, 0},
   264  	{ABLEZ, C_REG, C_NONE, C_SBRA, 6, 4, 0, 0, 0},
   265  	{ABFPT, C_NONE, C_NONE, C_SBRA, 6, 4, 0, 0, NOTUSETMP},
   266  
   267  	{AJMP, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0, 0}, // b
   268  	{AJAL, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0, 0}, // bl
   269  
   270  	{AJMP, C_NONE, C_NONE, C_ZOREG, 18, 4, REGZERO, 0, 0}, // jirl r0, rj, 0
   271  	{AJAL, C_NONE, C_NONE, C_ZOREG, 18, 4, REGLINK, 0, 0}, // jirl r1, rj, 0
   272  
   273  	{AMOVW, C_SEXT, C_NONE, C_FREG, 27, 4, 0, sys.Loong64, 0},
   274  	{AMOVF, C_SEXT, C_NONE, C_FREG, 27, 4, 0, sys.Loong64, 0},
   275  	{AMOVD, C_SEXT, C_NONE, C_FREG, 27, 4, 0, sys.Loong64, 0},
   276  	{AMOVW, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP, sys.Loong64, 0},
   277  	{AMOVF, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP, 0, 0},
   278  	{AMOVD, C_SAUTO, C_NONE, C_FREG, 27, 4, REGSP, 0, 0},
   279  	{AMOVW, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO, sys.Loong64, 0},
   280  	{AMOVF, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO, 0, 0},
   281  	{AMOVD, C_SOREG, C_NONE, C_FREG, 27, 4, REGZERO, 0, 0},
   282  
   283  	{AMOVW, C_LEXT, C_NONE, C_FREG, 27, 12, 0, sys.Loong64, 0},
   284  	{AMOVF, C_LEXT, C_NONE, C_FREG, 27, 12, 0, sys.Loong64, 0},
   285  	{AMOVD, C_LEXT, C_NONE, C_FREG, 27, 12, 0, sys.Loong64, 0},
   286  	{AMOVW, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP, sys.Loong64, 0},
   287  	{AMOVF, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP, 0, 0},
   288  	{AMOVD, C_LAUTO, C_NONE, C_FREG, 27, 12, REGSP, 0, 0},
   289  	{AMOVW, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO, sys.Loong64, 0},
   290  	{AMOVF, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO, 0, 0},
   291  	{AMOVD, C_LOREG, C_NONE, C_FREG, 27, 12, REGZERO, 0, 0},
   292  	{AMOVF, C_ADDR, C_NONE, C_FREG, 51, 8, 0, 0, 0},
   293  	{AMOVF, C_ADDR, C_NONE, C_FREG, 51, 8, 0, sys.Loong64, 0},
   294  	{AMOVD, C_ADDR, C_NONE, C_FREG, 51, 8, 0, 0, 0},
   295  	{AMOVD, C_ADDR, C_NONE, C_FREG, 51, 8, 0, sys.Loong64, 0},
   296  
   297  	{AMOVW, C_FREG, C_NONE, C_SEXT, 28, 4, 0, sys.Loong64, 0},
   298  	{AMOVF, C_FREG, C_NONE, C_SEXT, 28, 4, 0, sys.Loong64, 0},
   299  	{AMOVD, C_FREG, C_NONE, C_SEXT, 28, 4, 0, sys.Loong64, 0},
   300  	{AMOVW, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP, sys.Loong64, 0},
   301  	{AMOVF, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP, 0, 0},
   302  	{AMOVD, C_FREG, C_NONE, C_SAUTO, 28, 4, REGSP, 0, 0},
   303  	{AMOVW, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO, sys.Loong64, 0},
   304  	{AMOVF, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO, 0, 0},
   305  	{AMOVD, C_FREG, C_NONE, C_SOREG, 28, 4, REGZERO, 0, 0},
   306  
   307  	{AMOVW, C_FREG, C_NONE, C_LEXT, 28, 12, 0, sys.Loong64, 0},
   308  	{AMOVF, C_FREG, C_NONE, C_LEXT, 28, 12, 0, sys.Loong64, 0},
   309  	{AMOVD, C_FREG, C_NONE, C_LEXT, 28, 12, 0, sys.Loong64, 0},
   310  	{AMOVW, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP, sys.Loong64, 0},
   311  	{AMOVF, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP, 0, 0},
   312  	{AMOVD, C_FREG, C_NONE, C_LAUTO, 28, 12, REGSP, 0, 0},
   313  	{AMOVW, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO, sys.Loong64, 0},
   314  	{AMOVF, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO, 0, 0},
   315  	{AMOVD, C_FREG, C_NONE, C_LOREG, 28, 12, REGZERO, 0, 0},
   316  	{AMOVF, C_FREG, C_NONE, C_ADDR, 50, 8, 0, 0, 0},
   317  	{AMOVF, C_FREG, C_NONE, C_ADDR, 50, 8, 0, sys.Loong64, 0},
   318  	{AMOVD, C_FREG, C_NONE, C_ADDR, 50, 8, 0, 0, 0},
   319  	{AMOVD, C_FREG, C_NONE, C_ADDR, 50, 8, 0, sys.Loong64, 0},
   320  
   321  	{AMOVW, C_REG, C_NONE, C_FREG, 30, 4, 0, 0, 0},
   322  	{AMOVW, C_FREG, C_NONE, C_REG, 31, 4, 0, 0, 0},
   323  	{AMOVV, C_REG, C_NONE, C_FREG, 47, 4, 0, sys.Loong64, 0},
   324  	{AMOVV, C_FREG, C_NONE, C_REG, 48, 4, 0, sys.Loong64, 0},
   325  
   326  	{AMOVW, C_ADDCON, C_NONE, C_FREG, 34, 8, 0, sys.Loong64, 0},
   327  	{AMOVW, C_ANDCON, C_NONE, C_FREG, 34, 8, 0, sys.Loong64, 0},
   328  
   329  	{AWORD, C_LCON, C_NONE, C_NONE, 40, 4, 0, 0, 0},
   330  	{AWORD, C_DCON, C_NONE, C_NONE, 61, 4, 0, 0, 0},
   331  
   332  	{ATEQ, C_SCON, C_REG, C_REG, 15, 8, 0, 0, 0},
   333  	{ATEQ, C_SCON, C_NONE, C_REG, 15, 8, 0, 0, 0},
   334  
   335  	{ABREAK, C_REG, C_NONE, C_SEXT, 7, 4, 0, sys.Loong64, 0}, // really CACHE instruction
   336  	{ABREAK, C_REG, C_NONE, C_SAUTO, 7, 4, REGSP, sys.Loong64, 0},
   337  	{ABREAK, C_REG, C_NONE, C_SOREG, 7, 4, REGZERO, sys.Loong64, 0},
   338  	{ABREAK, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0, 0},
   339  
   340  	{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0, 0},
   341  	{obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0, 0},
   342  	{obj.APCDATA, C_DCON, C_NONE, C_DCON, 0, 0, 0, 0, 0},
   343  	{obj.AFUNCDATA, C_SCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0},
   344  	{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0},
   345  	{obj.ANOP, C_LCON, C_NONE, C_NONE, 0, 0, 0, 0, 0}, // nop variants, see #40689
   346  	{obj.ANOP, C_DCON, C_NONE, C_NONE, 0, 0, 0, 0, 0}, // nop variants, see #40689
   347  	{obj.ANOP, C_REG, C_NONE, C_NONE, 0, 0, 0, 0, 0},
   348  	{obj.ANOP, C_FREG, C_NONE, C_NONE, 0, 0, 0, 0, 0},
   349  	{obj.ADUFFZERO, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0, 0}, // same as AJMP
   350  	{obj.ADUFFCOPY, C_NONE, C_NONE, C_LBRA, 11, 4, 0, 0, 0}, // same as AJMP
   351  
   352  	{obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0},
   353  }
   354  
   355  var oprange [ALAST & obj.AMask][]Optab
   356  
   357  var xcmp [C_NCLASS][C_NCLASS]bool
   358  
   359  func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
   360  	if ctxt.Retpoline {
   361  		ctxt.Diag("-spectre=ret not supported on loong64")
   362  		ctxt.Retpoline = false // don't keep printing
   363  	}
   364  
   365  	p := cursym.Func().Text
   366  	if p == nil || p.Link == nil { // handle external functions and ELF section symbols
   367  		return
   368  	}
   369  
   370  	c := ctxt0{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset + ctxt.Arch.FixedFrameSize)}
   371  
   372  	if oprange[AOR&obj.AMask] == nil {
   373  		c.ctxt.Diag("loong64 ops not initialized, call loong64.buildop first")
   374  	}
   375  
   376  	pc := int64(0)
   377  	p.Pc = pc
   378  
   379  	var m int
   380  	var o *Optab
   381  	for p = p.Link; p != nil; p = p.Link {
   382  		p.Pc = pc
   383  		o = c.oplook(p)
   384  		m = int(o.size)
   385  		if m == 0 {
   386  			if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
   387  				c.ctxt.Diag("zero-width instruction\n%v", p)
   388  			}
   389  			continue
   390  		}
   391  
   392  		pc += int64(m)
   393  	}
   394  
   395  	c.cursym.Size = pc
   396  
   397  	/*
   398  	 * if any procedure is large enough to
   399  	 * generate a large SBRA branch, then
   400  	 * generate extra passes putting branches
   401  	 * around jmps to fix. this is rare.
   402  	 */
   403  	bflag := 1
   404  
   405  	var otxt int64
   406  	var q *obj.Prog
   407  	for bflag != 0 {
   408  		bflag = 0
   409  		pc = 0
   410  		for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
   411  			p.Pc = pc
   412  			o = c.oplook(p)
   413  
   414  			// very large conditional branches
   415  			if o.type_ == 6 && p.To.Target() != nil {
   416  				otxt = p.To.Target().Pc - pc
   417  				if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 {
   418  					q = c.newprog()
   419  					q.Link = p.Link
   420  					p.Link = q
   421  					q.As = AJMP
   422  					q.Pos = p.Pos
   423  					q.To.Type = obj.TYPE_BRANCH
   424  					q.To.SetTarget(p.To.Target())
   425  					p.To.SetTarget(q)
   426  					q = c.newprog()
   427  					q.Link = p.Link
   428  					p.Link = q
   429  					q.As = AJMP
   430  					q.Pos = p.Pos
   431  					q.To.Type = obj.TYPE_BRANCH
   432  					q.To.SetTarget(q.Link.Link)
   433  
   434  					c.addnop(p.Link)
   435  					c.addnop(p)
   436  					bflag = 1
   437  				}
   438  			}
   439  
   440  			m = int(o.size)
   441  			if m == 0 {
   442  				if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
   443  					c.ctxt.Diag("zero-width instruction\n%v", p)
   444  				}
   445  				continue
   446  			}
   447  
   448  			pc += int64(m)
   449  		}
   450  
   451  		c.cursym.Size = pc
   452  	}
   453  	pc += -pc & (FuncAlign - 1)
   454  	c.cursym.Size = pc
   455  
   456  	// lay out the code, emitting code and data relocations.
   457  
   458  	c.cursym.Grow(c.cursym.Size)
   459  
   460  	bp := c.cursym.P
   461  	var i int32
   462  	var out [5]uint32
   463  	for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
   464  		c.pc = p.Pc
   465  		o = c.oplook(p)
   466  		if int(o.size) > 4*len(out) {
   467  			log.Fatalf("out array in span0 is too small, need at least %d for %v", o.size/4, p)
   468  		}
   469  		c.asmout(p, o, out[:])
   470  		for i = 0; i < int32(o.size/4); i++ {
   471  			c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
   472  			bp = bp[4:]
   473  		}
   474  	}
   475  
   476  	// Mark nonpreemptible instruction sequences.
   477  	// We use REGTMP as a scratch register during call injection,
   478  	// so instruction sequences that use REGTMP are unsafe to
   479  	// preempt asynchronously.
   480  	obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable)
   481  }
   482  
   483  // isUnsafePoint returns whether p is an unsafe point.
   484  func (c *ctxt0) isUnsafePoint(p *obj.Prog) bool {
   485  	// If p explicitly uses REGTMP, it's unsafe to preempt, because the
   486  	// preemption sequence clobbers REGTMP.
   487  	return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP
   488  }
   489  
   490  // isRestartable returns whether p is a multi-instruction sequence that,
   491  // if preempted, can be restarted.
   492  func (c *ctxt0) isRestartable(p *obj.Prog) bool {
   493  	if c.isUnsafePoint(p) {
   494  		return false
   495  	}
   496  	// If p is a multi-instruction sequence with uses REGTMP inserted by
   497  	// the assembler in order to materialize a large constant/offset, we
   498  	// can restart p (at the start of the instruction sequence), recompute
   499  	// the content of REGTMP, upon async preemption. Currently, all cases
   500  	// of assembler-inserted REGTMP fall into this category.
   501  	// If p doesn't use REGTMP, it can be simply preempted, so we don't
   502  	// mark it.
   503  	o := c.oplook(p)
   504  	return o.size > 4 && o.flag&NOTUSETMP == 0
   505  }
   506  
   507  func isint32(v int64) bool {
   508  	return int64(int32(v)) == v
   509  }
   510  
   511  func isuint32(v uint64) bool {
   512  	return uint64(uint32(v)) == v
   513  }
   514  
   515  func (c *ctxt0) aclass(a *obj.Addr) int {
   516  	switch a.Type {
   517  	case obj.TYPE_NONE:
   518  		return C_NONE
   519  
   520  	case obj.TYPE_REG:
   521  		if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
   522  			return C_REG
   523  		}
   524  		if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
   525  			return C_FREG
   526  		}
   527  		if REG_FCSR0 <= a.Reg && a.Reg <= REG_FCSR31 {
   528  			return C_FCSRREG
   529  		}
   530  		if REG_FCC0 <= a.Reg && a.Reg <= REG_FCC31 {
   531  			return C_FCCREG
   532  		}
   533  		return C_GOK
   534  
   535  	case obj.TYPE_MEM:
   536  		switch a.Name {
   537  		case obj.NAME_EXTERN,
   538  			obj.NAME_STATIC:
   539  			if a.Sym == nil {
   540  				break
   541  			}
   542  			c.instoffset = a.Offset
   543  			if a.Sym != nil { // use relocation
   544  				if a.Sym.Type == objabi.STLSBSS {
   545  					return C_TLS
   546  				}
   547  				return C_ADDR
   548  			}
   549  			return C_LEXT
   550  
   551  		case obj.NAME_AUTO:
   552  			if a.Reg == REGSP {
   553  				// unset base register for better printing, since
   554  				// a.Offset is still relative to pseudo-SP.
   555  				a.Reg = obj.REG_NONE
   556  			}
   557  			c.instoffset = int64(c.autosize) + a.Offset
   558  			if c.instoffset >= -BIG && c.instoffset < BIG {
   559  				return C_SAUTO
   560  			}
   561  			return C_LAUTO
   562  
   563  		case obj.NAME_PARAM:
   564  			if a.Reg == REGSP {
   565  				// unset base register for better printing, since
   566  				// a.Offset is still relative to pseudo-FP.
   567  				a.Reg = obj.REG_NONE
   568  			}
   569  			c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
   570  			if c.instoffset >= -BIG && c.instoffset < BIG {
   571  				return C_SAUTO
   572  			}
   573  			return C_LAUTO
   574  
   575  		case obj.NAME_NONE:
   576  			c.instoffset = a.Offset
   577  			if c.instoffset == 0 {
   578  				return C_ZOREG
   579  			}
   580  			if c.instoffset >= -BIG && c.instoffset < BIG {
   581  				return C_SOREG
   582  			}
   583  			return C_LOREG
   584  		}
   585  
   586  		return C_GOK
   587  
   588  	case obj.TYPE_TEXTSIZE:
   589  		return C_TEXTSIZE
   590  
   591  	case obj.TYPE_CONST,
   592  		obj.TYPE_ADDR:
   593  		switch a.Name {
   594  		case obj.NAME_NONE:
   595  			c.instoffset = a.Offset
   596  			if a.Reg != 0 {
   597  				if -BIG <= c.instoffset && c.instoffset <= BIG {
   598  					return C_SACON
   599  				}
   600  				if isint32(c.instoffset) {
   601  					return C_LACON
   602  				}
   603  				return C_DACON
   604  			}
   605  
   606  		case obj.NAME_EXTERN,
   607  			obj.NAME_STATIC:
   608  			s := a.Sym
   609  			if s == nil {
   610  				return C_GOK
   611  			}
   612  
   613  			c.instoffset = a.Offset
   614  			if s.Type == objabi.STLSBSS {
   615  				return C_STCON // address of TLS variable
   616  			}
   617  			return C_LECON
   618  
   619  		case obj.NAME_AUTO:
   620  			if a.Reg == REGSP {
   621  				// unset base register for better printing, since
   622  				// a.Offset is still relative to pseudo-SP.
   623  				a.Reg = obj.REG_NONE
   624  			}
   625  			c.instoffset = int64(c.autosize) + a.Offset
   626  			if c.instoffset >= -BIG && c.instoffset < BIG {
   627  				return C_SACON
   628  			}
   629  			return C_LACON
   630  
   631  		case obj.NAME_PARAM:
   632  			if a.Reg == REGSP {
   633  				// unset base register for better printing, since
   634  				// a.Offset is still relative to pseudo-FP.
   635  				a.Reg = obj.REG_NONE
   636  			}
   637  			c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
   638  			if c.instoffset >= -BIG && c.instoffset < BIG {
   639  				return C_SACON
   640  			}
   641  			return C_LACON
   642  
   643  		default:
   644  			return C_GOK
   645  		}
   646  
   647  		if c.instoffset != int64(int32(c.instoffset)) {
   648  			return C_DCON
   649  		}
   650  
   651  		if c.instoffset >= 0 {
   652  			if c.instoffset == 0 {
   653  				return C_ZCON
   654  			}
   655  			if c.instoffset <= 0x7ff {
   656  				return C_SCON
   657  			}
   658  			if c.instoffset <= 0xfff {
   659  				return C_ANDCON
   660  			}
   661  			if c.instoffset&0xfff == 0 && isuint32(uint64(c.instoffset)) { // && (instoffset & (1<<31)) == 0)
   662  				return C_UCON
   663  			}
   664  			if isint32(c.instoffset) || isuint32(uint64(c.instoffset)) {
   665  				return C_LCON
   666  			}
   667  			return C_LCON
   668  		}
   669  
   670  		if c.instoffset >= -0x800 {
   671  			return C_ADDCON
   672  		}
   673  		if c.instoffset&0xfff == 0 && isint32(c.instoffset) {
   674  			return C_UCON
   675  		}
   676  		if isint32(c.instoffset) {
   677  			return C_LCON
   678  		}
   679  		return C_LCON
   680  
   681  	case obj.TYPE_BRANCH:
   682  		return C_SBRA
   683  	}
   684  
   685  	return C_GOK
   686  }
   687  
   688  func prasm(p *obj.Prog) {
   689  	fmt.Printf("%v\n", p)
   690  }
   691  
   692  func (c *ctxt0) oplook(p *obj.Prog) *Optab {
   693  	if oprange[AOR&obj.AMask] == nil {
   694  		c.ctxt.Diag("loong64 ops not initialized, call loong64.buildop first")
   695  	}
   696  
   697  	a1 := int(p.Optab)
   698  	if a1 != 0 {
   699  		return &optab[a1-1]
   700  	}
   701  	a1 = int(p.From.Class)
   702  	if a1 == 0 {
   703  		a1 = c.aclass(&p.From) + 1
   704  		p.From.Class = int8(a1)
   705  	}
   706  
   707  	a1--
   708  	a3 := int(p.To.Class)
   709  	if a3 == 0 {
   710  		a3 = c.aclass(&p.To) + 1
   711  		p.To.Class = int8(a3)
   712  	}
   713  
   714  	a3--
   715  	a2 := C_NONE
   716  	if p.Reg != 0 {
   717  		a2 = C_REG
   718  	}
   719  
   720  	ops := oprange[p.As&obj.AMask]
   721  	c1 := &xcmp[a1]
   722  	c3 := &xcmp[a3]
   723  	for i := range ops {
   724  		op := &ops[i]
   725  		if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && (op.family == 0 || c.ctxt.Arch.Family == op.family) {
   726  			p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
   727  			return op
   728  		}
   729  	}
   730  
   731  	c.ctxt.Diag("illegal combination %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3))
   732  	prasm(p)
   733  	// Turn illegal instruction into an UNDEF, avoid crashing in asmout.
   734  	return &Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0, 0}
   735  }
   736  
   737  func cmp(a int, b int) bool {
   738  	if a == b {
   739  		return true
   740  	}
   741  	switch a {
   742  	case C_DCON:
   743  		if b == C_LCON {
   744  			return true
   745  		}
   746  		fallthrough
   747  	case C_LCON:
   748  		if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {
   749  			return true
   750  		}
   751  
   752  	case C_ADD0CON:
   753  		if b == C_ADDCON {
   754  			return true
   755  		}
   756  		fallthrough
   757  
   758  	case C_ADDCON:
   759  		if b == C_ZCON || b == C_SCON {
   760  			return true
   761  		}
   762  
   763  	case C_AND0CON:
   764  		if b == C_ANDCON {
   765  			return true
   766  		}
   767  		fallthrough
   768  
   769  	case C_ANDCON:
   770  		if b == C_ZCON || b == C_SCON {
   771  			return true
   772  		}
   773  
   774  	case C_UCON:
   775  		if b == C_ZCON {
   776  			return true
   777  		}
   778  
   779  	case C_SCON:
   780  		if b == C_ZCON {
   781  			return true
   782  		}
   783  
   784  	case C_LACON:
   785  		if b == C_SACON {
   786  			return true
   787  		}
   788  
   789  	case C_LBRA:
   790  		if b == C_SBRA {
   791  			return true
   792  		}
   793  
   794  	case C_LEXT:
   795  		if b == C_SEXT {
   796  			return true
   797  		}
   798  
   799  	case C_LAUTO:
   800  		if b == C_SAUTO {
   801  			return true
   802  		}
   803  
   804  	case C_REG:
   805  		if b == C_ZCON {
   806  			return true
   807  		}
   808  
   809  	case C_LOREG:
   810  		if b == C_ZOREG || b == C_SOREG {
   811  			return true
   812  		}
   813  
   814  	case C_SOREG:
   815  		if b == C_ZOREG {
   816  			return true
   817  		}
   818  	}
   819  
   820  	return false
   821  }
   822  
   823  type ocmp []Optab
   824  
   825  func (x ocmp) Len() int {
   826  	return len(x)
   827  }
   828  
   829  func (x ocmp) Swap(i, j int) {
   830  	x[i], x[j] = x[j], x[i]
   831  }
   832  
   833  func (x ocmp) Less(i, j int) bool {
   834  	p1 := &x[i]
   835  	p2 := &x[j]
   836  	n := int(p1.as) - int(p2.as)
   837  	if n != 0 {
   838  		return n < 0
   839  	}
   840  	n = int(p1.a1) - int(p2.a1)
   841  	if n != 0 {
   842  		return n < 0
   843  	}
   844  	n = int(p1.a2) - int(p2.a2)
   845  	if n != 0 {
   846  		return n < 0
   847  	}
   848  	n = int(p1.a3) - int(p2.a3)
   849  	if n != 0 {
   850  		return n < 0
   851  	}
   852  	return false
   853  }
   854  
   855  func opset(a, b0 obj.As) {
   856  	oprange[a&obj.AMask] = oprange[b0]
   857  }
   858  
   859  func buildop(ctxt *obj.Link) {
   860  	if ctxt.DiagFunc == nil {
   861  		ctxt.DiagFunc = func(format string, args ...interface{}) {
   862  			log.Printf(format, args...)
   863  		}
   864  	}
   865  
   866  	if oprange[AOR&obj.AMask] != nil {
   867  		// Already initialized; stop now.
   868  		// This happens in the cmd/asm tests,
   869  		// each of which re-initializes the arch.
   870  		return
   871  	}
   872  
   873  	var n int
   874  
   875  	for i := 0; i < C_NCLASS; i++ {
   876  		for n = 0; n < C_NCLASS; n++ {
   877  			if cmp(n, i) {
   878  				xcmp[i][n] = true
   879  			}
   880  		}
   881  	}
   882  	for n = 0; optab[n].as != obj.AXXX; n++ {
   883  	}
   884  	sort.Sort(ocmp(optab[:n]))
   885  	for i := 0; i < n; i++ {
   886  		r := optab[i].as
   887  		r0 := r & obj.AMask
   888  		start := i
   889  		for optab[i].as == r {
   890  			i++
   891  		}
   892  		oprange[r0] = optab[start:i]
   893  		i--
   894  
   895  		switch r {
   896  		default:
   897  			ctxt.Diag("unknown op in build: %v", r)
   898  			ctxt.DiagFlush()
   899  			log.Fatalf("bad code")
   900  
   901  		case AABSF:
   902  			opset(AMOVFD, r0)
   903  			opset(AMOVDF, r0)
   904  			opset(AMOVWF, r0)
   905  			opset(AMOVFW, r0)
   906  			opset(AMOVWD, r0)
   907  			opset(AMOVDW, r0)
   908  			opset(ANEGF, r0)
   909  			opset(ANEGD, r0)
   910  			opset(AABSD, r0)
   911  			opset(ATRUNCDW, r0)
   912  			opset(ATRUNCFW, r0)
   913  			opset(ASQRTF, r0)
   914  			opset(ASQRTD, r0)
   915  
   916  		case AMOVVF:
   917  			opset(AMOVVD, r0)
   918  			opset(AMOVFV, r0)
   919  			opset(AMOVDV, r0)
   920  			opset(ATRUNCDV, r0)
   921  			opset(ATRUNCFV, r0)
   922  
   923  		case AADD:
   924  			opset(ASGT, r0)
   925  			opset(ASGTU, r0)
   926  			opset(AADDU, r0)
   927  
   928  		case AADDV:
   929  			opset(AADDVU, r0)
   930  
   931  		case AADDF:
   932  			opset(ADIVF, r0)
   933  			opset(ADIVD, r0)
   934  			opset(AMULF, r0)
   935  			opset(AMULD, r0)
   936  			opset(ASUBF, r0)
   937  			opset(ASUBD, r0)
   938  			opset(AADDD, r0)
   939  
   940  		case AAND:
   941  			opset(AOR, r0)
   942  			opset(AXOR, r0)
   943  
   944  		case ABEQ:
   945  			opset(ABNE, r0)
   946  			opset(ABLT, r0)
   947  			opset(ABGE, r0)
   948  			opset(ABGEU, r0)
   949  			opset(ABLTU, r0)
   950  
   951  		case ABLEZ:
   952  			opset(ABGEZ, r0)
   953  			opset(ABLTZ, r0)
   954  			opset(ABGTZ, r0)
   955  
   956  		case AMOVB:
   957  			opset(AMOVH, r0)
   958  
   959  		case AMOVBU:
   960  			opset(AMOVHU, r0)
   961  
   962  		case AMUL:
   963  			opset(AMULU, r0)
   964  			opset(AMULH, r0)
   965  			opset(AMULHU, r0)
   966  			opset(AREM, r0)
   967  			opset(AREMU, r0)
   968  			opset(ADIV, r0)
   969  			opset(ADIVU, r0)
   970  
   971  		case AMULV:
   972  			opset(AMULVU, r0)
   973  			opset(AMULHV, r0)
   974  			opset(AMULHVU, r0)
   975  			opset(AREMV, r0)
   976  			opset(AREMVU, r0)
   977  			opset(ADIVV, r0)
   978  			opset(ADIVVU, r0)
   979  
   980  		case ASLL:
   981  			opset(ASRL, r0)
   982  			opset(ASRA, r0)
   983  			opset(AROTR, r0)
   984  
   985  		case ASLLV:
   986  			opset(ASRAV, r0)
   987  			opset(ASRLV, r0)
   988  			opset(AROTRV, r0)
   989  
   990  		case ASUB:
   991  			opset(ASUBU, r0)
   992  			opset(ANOR, r0)
   993  
   994  		case ASUBV:
   995  			opset(ASUBVU, r0)
   996  
   997  		case ASYSCALL:
   998  			opset(ADBAR, r0)
   999  			opset(ANOOP, r0)
  1000  
  1001  		case ACMPEQF:
  1002  			opset(ACMPGTF, r0)
  1003  			opset(ACMPGTD, r0)
  1004  			opset(ACMPGEF, r0)
  1005  			opset(ACMPGED, r0)
  1006  			opset(ACMPEQD, r0)
  1007  
  1008  		case ABFPT:
  1009  			opset(ABFPF, r0)
  1010  
  1011  		case AMOVWL:
  1012  			opset(AMOVWR, r0)
  1013  
  1014  		case AMOVVL:
  1015  			opset(AMOVVR, r0)
  1016  
  1017  		case AMOVW,
  1018  			AMOVD,
  1019  			AMOVF,
  1020  			AMOVV,
  1021  			ABREAK,
  1022  			ARFE,
  1023  			AJAL,
  1024  			AJMP,
  1025  			AMOVWU,
  1026  			ALL,
  1027  			ALLV,
  1028  			ASC,
  1029  			ASCV,
  1030  			ANEGW,
  1031  			ANEGV,
  1032  			AWORD,
  1033  			obj.ANOP,
  1034  			obj.ATEXT,
  1035  			obj.AUNDEF,
  1036  			obj.AFUNCDATA,
  1037  			obj.APCDATA,
  1038  			obj.ADUFFZERO,
  1039  			obj.ADUFFCOPY:
  1040  			break
  1041  
  1042  		case ACLO:
  1043  			opset(ACLZ, r0)
  1044  
  1045  		case ATEQ:
  1046  			opset(ATNE, r0)
  1047  
  1048  		case AMASKEQZ:
  1049  			opset(AMASKNEZ, r0)
  1050  		}
  1051  	}
  1052  }
  1053  
  1054  func OP(x uint32, y uint32) uint32 {
  1055  	return x<<3 | y<<0
  1056  }
  1057  
  1058  func SP(x uint32, y uint32) uint32 {
  1059  	return x<<29 | y<<26
  1060  }
  1061  
  1062  func OP_TEN(x uint32, y uint32) uint32 {
  1063  	return x<<21 | y<<10
  1064  }
  1065  
  1066  // r1 -> rk
  1067  // r2 -> rj
  1068  // r3 -> rd
  1069  func OP_RRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 {
  1070  	return op | (r1&0x1F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1071  }
  1072  
  1073  // r2 -> rj
  1074  // r3 -> rd
  1075  func OP_RR(op uint32, r2 uint32, r3 uint32) uint32 {
  1076  	return op | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1077  }
  1078  
  1079  func OP_16IR_5I(op uint32, i uint32, r2 uint32) uint32 {
  1080  	return op | (i&0xFFFF)<<10 | (r2&0x7)<<5 | ((i >> 16) & 0x1F)
  1081  }
  1082  
  1083  func OP_16IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  1084  	return op | (i&0xFFFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1085  }
  1086  
  1087  func OP_12IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  1088  	return op | (i&0xFFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1089  }
  1090  
  1091  func OP_IR(op uint32, i uint32, r2 uint32) uint32 {
  1092  	return op | (i&0xFFFFF)<<5 | (r2&0x1F)<<0 // ui20, rd5
  1093  }
  1094  
  1095  // Encoding for the 'b' or 'bl' instruction.
  1096  func OP_B_BL(op uint32, i uint32) uint32 {
  1097  	return op | ((i & 0xFFFF) << 10) | ((i >> 16) & 0x3FF)
  1098  }
  1099  
  1100  func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
  1101  	o1 := uint32(0)
  1102  	o2 := uint32(0)
  1103  	o3 := uint32(0)
  1104  	o4 := uint32(0)
  1105  	o5 := uint32(0)
  1106  
  1107  	add := AADDU
  1108  	add = AADDVU
  1109  
  1110  	switch o.type_ {
  1111  	default:
  1112  		c.ctxt.Diag("unknown type %d %v", o.type_)
  1113  		prasm(p)
  1114  
  1115  	case 0: // pseudo ops
  1116  		break
  1117  
  1118  	case 1: // mov r1,r2 ==> OR r1,r0,r2
  1119  		a := AOR
  1120  		if p.As == AMOVW {
  1121  			a = ASLL
  1122  		}
  1123  		o1 = OP_RRR(c.oprrr(a), uint32(REGZERO), uint32(p.From.Reg), uint32(p.To.Reg))
  1124  
  1125  	case 2: // add/sub r1,[r2],r3
  1126  		r := int(p.Reg)
  1127  		if p.As == ANEGW || p.As == ANEGV {
  1128  			r = REGZERO
  1129  		}
  1130  		if r == 0 {
  1131  			r = int(p.To.Reg)
  1132  		}
  1133  		o1 = OP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
  1134  
  1135  	case 3: // mov $soreg, r ==> or/add $i,o,r
  1136  		v := c.regoff(&p.From)
  1137  
  1138  		r := int(p.From.Reg)
  1139  		if r == 0 {
  1140  			r = int(o.param)
  1141  		}
  1142  		a := add
  1143  		if o.a1 == C_ANDCON {
  1144  			a = AOR
  1145  		}
  1146  
  1147  		o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(r), uint32(p.To.Reg))
  1148  
  1149  	case 4: // add $scon,[r1],r2
  1150  		v := c.regoff(&p.From)
  1151  
  1152  		r := int(p.Reg)
  1153  		if r == 0 {
  1154  			r = int(p.To.Reg)
  1155  		}
  1156  
  1157  		o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  1158  
  1159  	case 5: // syscall
  1160  		o1 = c.oprrr(p.As)
  1161  
  1162  	case 6: // beq r1,[r2],sbra
  1163  		v := int32(0)
  1164  		vcmp := int32(0)
  1165  		if p.To.Target() != nil {
  1166  			v = int32(p.To.Target().Pc-p.Pc) >> 2
  1167  		}
  1168  		if v < 0 {
  1169  			vcmp = -v
  1170  		}
  1171  		if (p.As == ABFPT || p.As == ABFPF) && ((uint32(vcmp))>>21)&0x7FF != 0 {
  1172  			c.ctxt.Diag("21 bit-width, short branch too far\n%v", p)
  1173  		} else if p.As != ABFPT && p.As != ABFPF && (v<<16)>>16 != v {
  1174  			c.ctxt.Diag("16 bit-width, short branch too far\n%v", p)
  1175  		}
  1176  		if p.As == ABGTZ || p.As == ABLEZ {
  1177  			o1 = OP_16IRR(c.opirr(p.As), uint32(v), uint32(p.Reg), uint32(p.From.Reg))
  1178  		} else if p.As == ABFPT || p.As == ABFPF {
  1179  			// BCNEZ cj offset21 ,cj = fcc0
  1180  			// BCEQZ cj offset21 ,cj = fcc0
  1181  			o1 = OP_16IR_5I(c.opirr(p.As), uint32(v), uint32(REG_FCC0))
  1182  		} else {
  1183  			o1 = OP_16IRR(c.opirr(p.As), uint32(v), uint32(p.From.Reg), uint32(p.Reg))
  1184  		}
  1185  
  1186  	case 7: // mov r, soreg
  1187  		r := int(p.To.Reg)
  1188  		if r == 0 {
  1189  			r = int(o.param)
  1190  		}
  1191  		v := c.regoff(&p.To)
  1192  		o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.From.Reg))
  1193  
  1194  	case 8: // mov soreg, r
  1195  		r := int(p.From.Reg)
  1196  		if r == 0 {
  1197  			r = int(o.param)
  1198  		}
  1199  		v := c.regoff(&p.From)
  1200  		o1 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  1201  
  1202  	case 9: // sll r1,[r2],r3
  1203  		if p.As != ACLO && p.As != ACLZ {
  1204  			r := int(p.Reg)
  1205  			if r == 0 {
  1206  				r = int(p.To.Reg)
  1207  			}
  1208  			o1 = OP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
  1209  		} else { // clo r1,r2
  1210  			o1 = OP_RR(c.oprr(p.As), uint32(p.From.Reg), uint32(p.To.Reg))
  1211  		}
  1212  
  1213  	case 10: // add $con,[r1],r2 ==> mov $con, t; add t,[r1],r2
  1214  		v := c.regoff(&p.From)
  1215  		a := AOR
  1216  		if v < 0 {
  1217  			a = AADDU
  1218  		}
  1219  		o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
  1220  		r := int(p.Reg)
  1221  		if r == 0 {
  1222  			r = int(p.To.Reg)
  1223  		}
  1224  		o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  1225  
  1226  	case 11: // jmp lbra
  1227  		v := int32(0)
  1228  		if c.aclass(&p.To) == C_SBRA && p.To.Sym == nil && p.As == AJMP {
  1229  			// use PC-relative branch for short branches
  1230  			// BEQ	R0, R0, sbra
  1231  			if p.To.Target() != nil {
  1232  				v = int32(p.To.Target().Pc-p.Pc) >> 2
  1233  			}
  1234  			if (v<<16)>>16 == v {
  1235  				o1 = OP_16IRR(c.opirr(ABEQ), uint32(v), uint32(REGZERO), uint32(REGZERO))
  1236  				break
  1237  			}
  1238  		}
  1239  		if p.To.Target() == nil {
  1240  			v = int32(p.Pc) >> 2
  1241  		} else {
  1242  			v = int32(p.To.Target().Pc) >> 2
  1243  		}
  1244  		o1 = OP_B_BL(c.opirr(p.As), uint32(v))
  1245  		if p.To.Sym == nil {
  1246  			p.To.Sym = c.cursym.Func().Text.From.Sym
  1247  			p.To.Offset = p.To.Target().Pc
  1248  		}
  1249  		rel := obj.Addrel(c.cursym)
  1250  		rel.Off = int32(c.pc)
  1251  		rel.Siz = 4
  1252  		rel.Sym = p.To.Sym
  1253  		rel.Add = p.To.Offset
  1254  		rel.Type = objabi.R_CALLLOONG64
  1255  
  1256  	case 12: // movbs r,r
  1257  		// NOTE: this case does not use REGTMP. If it ever does,
  1258  		// remove the NOTUSETMP flag in optab.
  1259  		v := 16
  1260  		if p.As == AMOVB {
  1261  			v = 24
  1262  		}
  1263  		o1 = OP_16IRR(c.opirr(ASLL), uint32(v), uint32(p.From.Reg), uint32(p.To.Reg))
  1264  		o2 = OP_16IRR(c.opirr(ASRA), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  1265  
  1266  	case 13: // movbu r,r
  1267  		if p.As == AMOVBU {
  1268  			o1 = OP_12IRR(c.opirr(AAND), uint32(0xff), uint32(p.From.Reg), uint32(p.To.Reg))
  1269  		} else {
  1270  			// bstrpick.d (msbd=15, lsbd=0)
  1271  			o1 = (0x33c0 << 10) | ((uint32(p.From.Reg) & 0x1f) << 5) | (uint32(p.To.Reg) & 0x1F)
  1272  		}
  1273  
  1274  	case 14: // movwu r,r
  1275  		// NOTE: this case does not use REGTMP. If it ever does,
  1276  		// remove the NOTUSETMP flag in optab.
  1277  		o1 = OP_16IRR(c.opirr(-ASLLV), uint32(32)&0x3f, uint32(p.From.Reg), uint32(p.To.Reg))
  1278  		o2 = OP_16IRR(c.opirr(-ASRLV), uint32(32)&0x3f, uint32(p.To.Reg), uint32(p.To.Reg))
  1279  
  1280  	case 15: // teq $c r,r
  1281  		v := c.regoff(&p.From)
  1282  		r := int(p.Reg)
  1283  		if r == 0 {
  1284  			r = REGZERO
  1285  		}
  1286  		/*
  1287  			teq c, r1, r2
  1288  			fallthrough
  1289  			==>
  1290  			bne r1, r2, 2
  1291  			break c
  1292  			fallthrough
  1293  		*/
  1294  		if p.As == ATEQ {
  1295  			o1 = OP_16IRR(c.opirr(ABNE), uint32(2), uint32(r), uint32(p.To.Reg))
  1296  		} else { // ATNE
  1297  			o1 = OP_16IRR(c.opirr(ABEQ), uint32(2), uint32(r), uint32(p.To.Reg))
  1298  		}
  1299  		o2 = c.oprrr(ABREAK) | (uint32(v) & 0x7FFF)
  1300  
  1301  	case 16: // sll $c,[r1],r2
  1302  		v := c.regoff(&p.From)
  1303  		r := int(p.Reg)
  1304  		if r == 0 {
  1305  			r = int(p.To.Reg)
  1306  		}
  1307  
  1308  		// instruction ending with V:6-digit immediate, others:5-digit immediate
  1309  		if v >= 32 && vshift(p.As) {
  1310  			o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x3f, uint32(r), uint32(p.To.Reg))
  1311  		} else {
  1312  			o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x1f, uint32(r), uint32(p.To.Reg))
  1313  		}
  1314  
  1315  	case 17:
  1316  		o1 = OP_RRR(c.oprrr(p.As), uint32(REGZERO), uint32(p.From.Reg), uint32(p.To.Reg))
  1317  
  1318  	case 18: // jmp [r1],0(r2)
  1319  		r := int(p.Reg)
  1320  		if r == 0 {
  1321  			r = int(o.param)
  1322  		}
  1323  		o1 = OP_RRR(c.oprrr(p.As), uint32(0), uint32(p.To.Reg), uint32(r))
  1324  		if p.As == obj.ACALL {
  1325  			rel := obj.Addrel(c.cursym)
  1326  			rel.Off = int32(c.pc)
  1327  			rel.Siz = 0
  1328  			rel.Type = objabi.R_CALLIND
  1329  		}
  1330  
  1331  	case 19: // mov $lcon,r
  1332  		// NOTE: this case does not use REGTMP. If it ever does,
  1333  		// remove the NOTUSETMP flag in optab.
  1334  		v := c.regoff(&p.From)
  1335  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  1336  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  1337  
  1338  	case 23: // add $lcon,r1,r2
  1339  		v := c.regoff(&p.From)
  1340  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  1341  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  1342  		r := int(p.Reg)
  1343  		if r == 0 {
  1344  			r = int(p.To.Reg)
  1345  		}
  1346  		o3 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  1347  
  1348  	case 24: // mov $ucon,r
  1349  		v := c.regoff(&p.From)
  1350  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  1351  
  1352  	case 25: // add/and $ucon,[r1],r2
  1353  		v := c.regoff(&p.From)
  1354  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  1355  		r := int(p.Reg)
  1356  		if r == 0 {
  1357  			r = int(p.To.Reg)
  1358  		}
  1359  		o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  1360  
  1361  	case 26: // mov $lsext/auto/oreg,r
  1362  		v := c.regoff(&p.From)
  1363  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  1364  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  1365  		r := int(p.From.Reg)
  1366  		if r == 0 {
  1367  			r = int(o.param)
  1368  		}
  1369  		o3 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  1370  
  1371  	case 27: // mov [sl]ext/auto/oreg,fr
  1372  		v := c.regoff(&p.From)
  1373  		r := int(p.From.Reg)
  1374  		if r == 0 {
  1375  			r = int(o.param)
  1376  		}
  1377  		a := -AMOVF
  1378  		if p.As == AMOVD {
  1379  			a = -AMOVD
  1380  		}
  1381  		switch o.size {
  1382  		case 12:
  1383  			o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  1384  			o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  1385  			o3 = OP_12IRR(c.opirr(a), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
  1386  
  1387  		case 4:
  1388  			o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(r), uint32(p.To.Reg))
  1389  		}
  1390  
  1391  	case 28: // mov fr,[sl]ext/auto/oreg
  1392  		v := c.regoff(&p.To)
  1393  		r := int(p.To.Reg)
  1394  		if r == 0 {
  1395  			r = int(o.param)
  1396  		}
  1397  		a := AMOVF
  1398  		if p.As == AMOVD {
  1399  			a = AMOVD
  1400  		}
  1401  		switch o.size {
  1402  		case 12:
  1403  			o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  1404  			o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  1405  			o3 = OP_12IRR(c.opirr(a), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
  1406  
  1407  		case 4:
  1408  			o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(r), uint32(p.From.Reg))
  1409  		}
  1410  
  1411  	case 30: // movw r,fr
  1412  		a := OP_TEN(8, 1321) // movgr2fr.w
  1413  		o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
  1414  
  1415  	case 31: // movw fr,r
  1416  		a := OP_TEN(8, 1325) // movfr2gr.s
  1417  		o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
  1418  
  1419  	case 32: // fadd fr1,[fr2],fr3
  1420  		r := int(p.Reg)
  1421  		if r == 0 {
  1422  			r = int(p.To.Reg)
  1423  		}
  1424  		o1 = OP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
  1425  
  1426  	case 33: // fabs fr1, fr3
  1427  		o1 = OP_RRR(c.oprrr(p.As), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
  1428  
  1429  	case 34: // mov $con,fr
  1430  		v := c.regoff(&p.From)
  1431  		a := AADDU
  1432  		if o.a1 == C_ANDCON {
  1433  			a = AOR
  1434  		}
  1435  		o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
  1436  		o2 = OP_RR(OP_TEN(8, 1321), uint32(REGTMP), uint32(p.To.Reg)) // movgr2fr.w
  1437  
  1438  	case 35: // mov r,lext/auto/oreg
  1439  		v := c.regoff(&p.To)
  1440  		r := int(p.To.Reg)
  1441  		if r == 0 {
  1442  			r = int(o.param)
  1443  		}
  1444  		o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  1445  		o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  1446  		o3 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
  1447  
  1448  	case 36: // mov lext/auto/oreg,r
  1449  		v := c.regoff(&p.From)
  1450  		r := int(p.From.Reg)
  1451  		if r == 0 {
  1452  			r = int(o.param)
  1453  		}
  1454  		o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  1455  		o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  1456  		o3 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
  1457  
  1458  	case 40: // word
  1459  		o1 = uint32(c.regoff(&p.From))
  1460  
  1461  	case 47: // movv r,fr
  1462  		a := OP_TEN(8, 1322) // movgr2fr.d
  1463  		o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
  1464  
  1465  	case 48: // movv fr,r
  1466  		a := OP_TEN(8, 1326) // movfr2gr.d
  1467  		o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
  1468  
  1469  	case 49: // undef
  1470  		o1 = c.oprrr(ABREAK)
  1471  
  1472  	// relocation operations
  1473  	case 50: // mov r,addr ==> pcaddu12i + sw
  1474  		o1 = OP_IR(c.opir(APCADDU12I), uint32(0), uint32(REGTMP))
  1475  		rel := obj.Addrel(c.cursym)
  1476  		rel.Off = int32(c.pc)
  1477  		rel.Siz = 4
  1478  		rel.Sym = p.To.Sym
  1479  		rel.Add = p.To.Offset
  1480  		rel.Type = objabi.R_ADDRLOONG64U
  1481  
  1482  		o2 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
  1483  		rel2 := obj.Addrel(c.cursym)
  1484  		rel2.Off = int32(c.pc + 4)
  1485  		rel2.Siz = 4
  1486  		rel2.Sym = p.To.Sym
  1487  		rel2.Add = p.To.Offset
  1488  		rel2.Type = objabi.R_ADDRLOONG64
  1489  
  1490  	case 51: // mov addr,r ==> pcaddu12i + lw
  1491  		o1 = OP_IR(c.opir(APCADDU12I), uint32(0), uint32(REGTMP))
  1492  		rel := obj.Addrel(c.cursym)
  1493  		rel.Off = int32(c.pc)
  1494  		rel.Siz = 4
  1495  		rel.Sym = p.From.Sym
  1496  		rel.Add = p.From.Offset
  1497  		rel.Type = objabi.R_ADDRLOONG64U
  1498  		o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
  1499  		rel2 := obj.Addrel(c.cursym)
  1500  		rel2.Off = int32(c.pc + 4)
  1501  		rel2.Siz = 4
  1502  		rel2.Sym = p.From.Sym
  1503  		rel2.Add = p.From.Offset
  1504  		rel2.Type = objabi.R_ADDRLOONG64
  1505  
  1506  	case 52: // mov $lext, r
  1507  		// NOTE: this case does not use REGTMP. If it ever does,
  1508  		// remove the NOTUSETMP flag in optab.
  1509  		o1 = OP_IR(c.opir(APCADDU12I), uint32(0), uint32(p.To.Reg))
  1510  		rel := obj.Addrel(c.cursym)
  1511  		rel.Off = int32(c.pc)
  1512  		rel.Siz = 4
  1513  		rel.Sym = p.From.Sym
  1514  		rel.Add = p.From.Offset
  1515  		rel.Type = objabi.R_ADDRLOONG64U
  1516  		o2 = OP_12IRR(c.opirr(add), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
  1517  		rel2 := obj.Addrel(c.cursym)
  1518  		rel2.Off = int32(c.pc + 4)
  1519  		rel2.Siz = 4
  1520  		rel2.Sym = p.From.Sym
  1521  		rel2.Add = p.From.Offset
  1522  		rel2.Type = objabi.R_ADDRLOONG64
  1523  
  1524  	case 53: // mov r, tlsvar ==>  lu12i.w + ori + add r2, regtmp + sw o(regtmp)
  1525  		// NOTE: this case does not use REGTMP. If it ever does,
  1526  		// remove the NOTUSETMP flag in optab.
  1527  		o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
  1528  		rel := obj.Addrel(c.cursym)
  1529  		rel.Off = int32(c.pc)
  1530  		rel.Siz = 4
  1531  		rel.Sym = p.To.Sym
  1532  		rel.Add = p.To.Offset
  1533  		rel.Type = objabi.R_ADDRLOONG64TLSU
  1534  		o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
  1535  		rel2 := obj.Addrel(c.cursym)
  1536  		rel2.Off = int32(c.pc + 4)
  1537  		rel2.Siz = 4
  1538  		rel2.Sym = p.To.Sym
  1539  		rel2.Add = p.To.Offset
  1540  		rel2.Type = objabi.R_ADDRLOONG64TLS
  1541  		o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP))
  1542  		o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
  1543  
  1544  	case 54: // lu12i.w + ori + add r2, regtmp + lw o(regtmp)
  1545  		// NOTE: this case does not use REGTMP. If it ever does,
  1546  		// remove the NOTUSETMP flag in optab.
  1547  		o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
  1548  		rel := obj.Addrel(c.cursym)
  1549  		rel.Off = int32(c.pc)
  1550  		rel.Siz = 4
  1551  		rel.Sym = p.From.Sym
  1552  		rel.Add = p.From.Offset
  1553  		rel.Type = objabi.R_ADDRLOONG64TLSU
  1554  		o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
  1555  		rel2 := obj.Addrel(c.cursym)
  1556  		rel2.Off = int32(c.pc + 4)
  1557  		rel2.Siz = 4
  1558  		rel2.Sym = p.From.Sym
  1559  		rel2.Add = p.From.Offset
  1560  		rel2.Type = objabi.R_ADDRLOONG64TLS
  1561  		o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP))
  1562  		o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
  1563  
  1564  	case 55: //  lu12i.w + ori + add r2, regtmp
  1565  		// NOTE: this case does not use REGTMP. If it ever does,
  1566  		// remove the NOTUSETMP flag in optab.
  1567  		o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
  1568  		rel := obj.Addrel(c.cursym)
  1569  		rel.Off = int32(c.pc)
  1570  		rel.Siz = 4
  1571  		rel.Sym = p.From.Sym
  1572  		rel.Add = p.From.Offset
  1573  		rel.Type = objabi.R_ADDRLOONG64TLSU
  1574  		o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
  1575  		rel2 := obj.Addrel(c.cursym)
  1576  		rel2.Off = int32(c.pc + 4)
  1577  		rel2.Siz = 4
  1578  		rel2.Sym = p.From.Sym
  1579  		rel2.Add = p.From.Offset
  1580  		rel2.Type = objabi.R_ADDRLOONG64TLS
  1581  		o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(p.To.Reg))
  1582  
  1583  	case 59: // mov $dcon,r
  1584  		// NOTE: this case does not use REGTMP. If it ever does,
  1585  		// remove the NOTUSETMP flag in optab.
  1586  		v := c.vregoff(&p.From)
  1587  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  1588  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  1589  		o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  1590  		o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  1591  
  1592  	case 60: // add $dcon,r1,r2
  1593  		v := c.vregoff(&p.From)
  1594  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  1595  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  1596  		o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  1597  		o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  1598  		r := int(p.Reg)
  1599  		if r == 0 {
  1600  			r = int(p.To.Reg)
  1601  		}
  1602  		o5 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  1603  
  1604  	case 61: // word C_DCON
  1605  		o1 = uint32(c.vregoff(&p.From))
  1606  		o2 = uint32(c.vregoff(&p.From) >> 32)
  1607  	}
  1608  
  1609  	out[0] = o1
  1610  	out[1] = o2
  1611  	out[2] = o3
  1612  	out[3] = o4
  1613  	out[4] = o5
  1614  }
  1615  
  1616  func (c *ctxt0) vregoff(a *obj.Addr) int64 {
  1617  	c.instoffset = 0
  1618  	c.aclass(a)
  1619  	return c.instoffset
  1620  }
  1621  
  1622  func (c *ctxt0) regoff(a *obj.Addr) int32 {
  1623  	return int32(c.vregoff(a))
  1624  }
  1625  
  1626  func (c *ctxt0) oprrr(a obj.As) uint32 {
  1627  	switch a {
  1628  	case AADD:
  1629  		return 0x20 << 15
  1630  	case AADDU:
  1631  		return 0x20 << 15
  1632  	case ASGT:
  1633  		return 0x24 << 15 // SLT
  1634  	case ASGTU:
  1635  		return 0x25 << 15 // SLTU
  1636  	case AMASKEQZ:
  1637  		return 0x26 << 15
  1638  	case AMASKNEZ:
  1639  		return 0x27 << 15
  1640  	case AAND:
  1641  		return 0x29 << 15
  1642  	case AOR:
  1643  		return 0x2a << 15
  1644  	case AXOR:
  1645  		return 0x2b << 15
  1646  	case ASUB:
  1647  		return 0x22 << 15
  1648  	case ASUBU, ANEGW:
  1649  		return 0x22 << 15
  1650  	case ANOR:
  1651  		return 0x28 << 15
  1652  	case ASLL:
  1653  		return 0x2e << 15
  1654  	case ASRL:
  1655  		return 0x2f << 15
  1656  	case ASRA:
  1657  		return 0x30 << 15
  1658  	case AROTR:
  1659  		return 0x36 << 15
  1660  	case ASLLV:
  1661  		return 0x31 << 15
  1662  	case ASRLV:
  1663  		return 0x32 << 15
  1664  	case ASRAV:
  1665  		return 0x33 << 15
  1666  	case AROTRV:
  1667  		return 0x37 << 15
  1668  	case AADDV:
  1669  		return 0x21 << 15
  1670  	case AADDVU:
  1671  		return 0x21 << 15
  1672  	case ASUBV:
  1673  		return 0x23 << 15
  1674  	case ASUBVU, ANEGV:
  1675  		return 0x23 << 15
  1676  
  1677  	case AMUL:
  1678  		return 0x38 << 15 // mul.w
  1679  	case AMULU:
  1680  		return 0x38 << 15 // mul.w
  1681  	case AMULH:
  1682  		return 0x39 << 15 // mulh.w
  1683  	case AMULHU:
  1684  		return 0x3a << 15 // mulhu.w
  1685  	case AMULV:
  1686  		return 0x3b << 15 // mul.d
  1687  	case AMULVU:
  1688  		return 0x3b << 15 // mul.d
  1689  	case AMULHV:
  1690  		return 0x3c << 15 // mulh.d
  1691  	case AMULHVU:
  1692  		return 0x3d << 15 // mulhu.d
  1693  	case ADIV:
  1694  		return 0x40 << 15 // div.w
  1695  	case ADIVU:
  1696  		return 0x42 << 15 // div.wu
  1697  	case ADIVV:
  1698  		return 0x44 << 15 // div.d
  1699  	case ADIVVU:
  1700  		return 0x46 << 15 // div.du
  1701  	case AREM:
  1702  		return 0x41 << 15 // mod.w
  1703  	case AREMU:
  1704  		return 0x43 << 15 // mod.wu
  1705  	case AREMV:
  1706  		return 0x45 << 15 // mod.d
  1707  	case AREMVU:
  1708  		return 0x47 << 15 // mod.du
  1709  
  1710  	case AJMP:
  1711  		return 0x13 << 26 // jirl r0, rj, 0
  1712  	case AJAL:
  1713  		return (0x13 << 26) | 1 // jirl r1, rj, 0
  1714  
  1715  	case ABREAK:
  1716  		return 0x54 << 15
  1717  	case ASYSCALL:
  1718  		return 0x56 << 15
  1719  	case ADIVF:
  1720  		return 0x20d << 15
  1721  	case ADIVD:
  1722  		return 0x20e << 15
  1723  	case AMULF:
  1724  		return 0x209 << 15
  1725  	case AMULD:
  1726  		return 0x20a << 15
  1727  	case ASUBF:
  1728  		return 0x205 << 15
  1729  	case ASUBD:
  1730  		return 0x206 << 15
  1731  	case AADDF:
  1732  		return 0x201 << 15
  1733  	case AADDD:
  1734  		return 0x202 << 15
  1735  	case ATRUNCFV:
  1736  		return 0x46a9 << 10
  1737  	case ATRUNCDV:
  1738  		return 0x46aa << 10
  1739  	case ATRUNCFW:
  1740  		return 0x46a1 << 10
  1741  	case ATRUNCDW:
  1742  		return 0x46a2 << 10
  1743  	case AMOVFV:
  1744  		return 0x46c9 << 10
  1745  	case AMOVDV:
  1746  		return 0x46ca << 10
  1747  	case AMOVVF:
  1748  		return 0x4746 << 10
  1749  	case AMOVVD:
  1750  		return 0x474a << 10
  1751  	case AMOVFW:
  1752  		return 0x46c1 << 10
  1753  	case AMOVDW:
  1754  		return 0x46c2 << 10
  1755  	case AMOVWF:
  1756  		return 0x4744 << 10
  1757  	case AMOVDF:
  1758  		return 0x4646 << 10
  1759  	case AMOVWD:
  1760  		return 0x4748 << 10
  1761  	case AMOVFD:
  1762  		return 0x4649 << 10
  1763  	case AABSF:
  1764  		return 0x4501 << 10
  1765  	case AABSD:
  1766  		return 0x4502 << 10
  1767  	case AMOVF:
  1768  		return 0x4525 << 10
  1769  	case AMOVD:
  1770  		return 0x4526 << 10
  1771  	case ANEGF:
  1772  		return 0x4505 << 10
  1773  	case ANEGD:
  1774  		return 0x4506 << 10
  1775  	case ACMPEQF:
  1776  		return 0x0c1<<20 | 0x4<<15 // FCMP.CEQ.S
  1777  	case ACMPEQD:
  1778  		return 0x0c2<<20 | 0x4<<15 // FCMP.CEQ.D
  1779  	case ACMPGED:
  1780  		return 0x0c2<<20 | 0x7<<15 // FCMP.SLE.D
  1781  	case ACMPGEF:
  1782  		return 0x0c1<<20 | 0x7<<15 // FCMP.SLE.S
  1783  	case ACMPGTD:
  1784  		return 0x0c2<<20 | 0x3<<15 // FCMP.SLT.D
  1785  	case ACMPGTF:
  1786  		return 0x0c1<<20 | 0x3<<15 // FCMP.SLT.S
  1787  
  1788  	case ASQRTF:
  1789  		return 0x4511 << 10
  1790  	case ASQRTD:
  1791  		return 0x4512 << 10
  1792  
  1793  	case ADBAR:
  1794  		return 0x70e4 << 15
  1795  	case ANOOP:
  1796  		// andi r0, r0, 0
  1797  		return 0x03400000
  1798  	}
  1799  
  1800  	if a < 0 {
  1801  		c.ctxt.Diag("bad rrr opcode -%v", -a)
  1802  	} else {
  1803  		c.ctxt.Diag("bad rrr opcode %v", a)
  1804  	}
  1805  	return 0
  1806  }
  1807  
  1808  func (c *ctxt0) oprr(a obj.As) uint32 {
  1809  	switch a {
  1810  	case ACLO:
  1811  		return 0x4 << 10
  1812  	case ACLZ:
  1813  		return 0x5 << 10
  1814  	}
  1815  
  1816  	c.ctxt.Diag("bad rr opcode %v", a)
  1817  	return 0
  1818  }
  1819  
  1820  func (c *ctxt0) opir(a obj.As) uint32 {
  1821  	switch a {
  1822  	case ALU12IW:
  1823  		return 0x0a << 25
  1824  	case ALU32ID:
  1825  		return 0x0b << 25
  1826  	case APCADDU12I:
  1827  		return 0x0e << 25
  1828  	}
  1829  	return 0
  1830  }
  1831  
  1832  func (c *ctxt0) opirr(a obj.As) uint32 {
  1833  	switch a {
  1834  	case AADD, AADDU:
  1835  		return 0x00a << 22
  1836  	case ASGT:
  1837  		return 0x008 << 22
  1838  	case ASGTU:
  1839  		return 0x009 << 22
  1840  	case AAND:
  1841  		return 0x00d << 22
  1842  	case AOR:
  1843  		return 0x00e << 22
  1844  	case ALU52ID:
  1845  		return 0x00c << 22
  1846  	case AXOR:
  1847  		return 0x00f << 22
  1848  	case ASLL:
  1849  		return 0x00081 << 15
  1850  	case ASRL:
  1851  		return 0x00089 << 15
  1852  	case ASRA:
  1853  		return 0x00091 << 15
  1854  	case AROTR:
  1855  		return 0x00099 << 15
  1856  	case AADDV:
  1857  		return 0x00b << 22
  1858  	case AADDVU:
  1859  		return 0x00b << 22
  1860  
  1861  	case AJMP:
  1862  		return 0x14 << 26
  1863  	case AJAL,
  1864  		obj.ADUFFZERO,
  1865  		obj.ADUFFCOPY:
  1866  		return 0x15 << 26
  1867  
  1868  	case AJIRL:
  1869  		return 0x13 << 26
  1870  	case ABLTU:
  1871  		return 0x1a << 26
  1872  	case ABLT, ABLTZ, ABGTZ:
  1873  		return 0x18 << 26
  1874  	case ABGEU:
  1875  		return 0x1b << 26
  1876  	case ABGE, ABGEZ, ABLEZ:
  1877  		return 0x19 << 26
  1878  	case ABEQ:
  1879  		return 0x16 << 26
  1880  	case ABNE:
  1881  		return 0x17 << 26
  1882  	case ABFPT:
  1883  		return 0x12<<26 | 0x1<<8
  1884  	case ABFPF:
  1885  		return 0x12<<26 | 0x0<<8
  1886  
  1887  	case AMOVB,
  1888  		AMOVBU:
  1889  		return 0x0a4 << 22
  1890  	case AMOVH,
  1891  		AMOVHU:
  1892  		return 0x0a5 << 22
  1893  	case AMOVW,
  1894  		AMOVWU:
  1895  		return 0x0a6 << 22
  1896  	case AMOVV:
  1897  		return 0x0a7 << 22
  1898  	case AMOVF:
  1899  		return 0x0ad << 22
  1900  	case AMOVD:
  1901  		return 0x0af << 22
  1902  	case AMOVWL:
  1903  		return 0x0bc << 22
  1904  	case AMOVWR:
  1905  		return 0x0bd << 22
  1906  	case AMOVVL:
  1907  		return 0x0be << 22
  1908  	case AMOVVR:
  1909  		return 0x0bf << 22
  1910  
  1911  	case ABREAK:
  1912  		return 0x018 << 22
  1913  
  1914  	case -AMOVWL:
  1915  		return 0x0b8 << 22
  1916  	case -AMOVWR:
  1917  		return 0x0b9 << 22
  1918  	case -AMOVVL:
  1919  		return 0x0ba << 22
  1920  	case -AMOVVR:
  1921  		return 0x0bb << 22
  1922  	case -AMOVB:
  1923  		return 0x0a0 << 22
  1924  	case -AMOVBU:
  1925  		return 0x0a8 << 22
  1926  	case -AMOVH:
  1927  		return 0x0a1 << 22
  1928  	case -AMOVHU:
  1929  		return 0x0a9 << 22
  1930  	case -AMOVW:
  1931  		return 0x0a2 << 22
  1932  	case -AMOVWU:
  1933  		return 0x0aa << 22
  1934  	case -AMOVV:
  1935  		return 0x0a3 << 22
  1936  	case -AMOVF:
  1937  		return 0x0ac << 22
  1938  	case -AMOVD:
  1939  		return 0x0ae << 22
  1940  
  1941  	case ASLLV,
  1942  		-ASLLV:
  1943  		return 0x0041 << 16
  1944  	case ASRLV,
  1945  		-ASRLV:
  1946  		return 0x0045 << 16
  1947  	case ASRAV,
  1948  		-ASRAV:
  1949  		return 0x0049 << 16
  1950  	case AROTRV,
  1951  		-AROTRV:
  1952  		return 0x004d << 16
  1953  	case -ALL:
  1954  		return 0x020 << 24
  1955  	case -ALLV:
  1956  		return 0x022 << 24
  1957  	case ASC:
  1958  		return 0x021 << 24
  1959  	case ASCV:
  1960  		return 0x023 << 24
  1961  	}
  1962  
  1963  	if a < 0 {
  1964  		c.ctxt.Diag("bad irr opcode -%v", -a)
  1965  	} else {
  1966  		c.ctxt.Diag("bad irr opcode %v", a)
  1967  	}
  1968  	return 0
  1969  }
  1970  
  1971  func vshift(a obj.As) bool {
  1972  	switch a {
  1973  	case ASLLV,
  1974  		ASRLV,
  1975  		ASRAV,
  1976  		AROTRV:
  1977  		return true
  1978  	}
  1979  	return false
  1980  }