Source file src/cmd/internal/obj/loong64/asm.go

     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  	"cmd/internal/obj"
     9  	"cmd/internal/objabi"
    10  	"fmt"
    11  	"log"
    12  	"math/bits"
    13  	"slices"
    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  	loopAlign = 16
    33  )
    34  
    35  type Optab struct {
    36  	as    obj.As
    37  	from1 uint8
    38  	reg   uint8
    39  	from3 uint8
    40  	to1   uint8
    41  	to2   uint8
    42  	type_ int8
    43  	size  int8
    44  	param int16
    45  	flag  uint8
    46  }
    47  
    48  const (
    49  	NOTUSETMP = 1 << iota // p expands to multiple instructions, but does NOT use REGTMP
    50  
    51  	// branchLoopHead marks loop entry.
    52  	// Used to insert padding for under-aligned loops.
    53  	branchLoopHead
    54  )
    55  
    56  var optab = []Optab{
    57  	{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, C_NONE, 0, 0, 0, 0},
    58  
    59  	{AMOVW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 1, 4, 0, 0},
    60  	{AMOVV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 1, 4, 0, 0},
    61  	{AMOVB, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 12, 4, 0, 0},
    62  	{AMOVBU, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 12, 4, 0, 0},
    63  	{AMOVWU, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 12, 4, 0, 0},
    64  
    65  	{ASUB, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    66  	{ASUBV, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    67  	{AADD, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    68  	{AADDV, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    69  	{AAND, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    70  	{ASUB, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    71  	{ASUBV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    72  	{AADD, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    73  	{AADDV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    74  	{AAND, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    75  	{ANEGW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    76  	{ANEGV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    77  	{AMASKEQZ, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    78  	{ASLL, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    79  	{ASLL, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    80  	{ASLLV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    81  	{ASLLV, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    82  	{AMUL, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    83  	{AMUL, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    84  	{AMULV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    85  	{AMULV, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    86  	{AADDF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 2, 4, 0, 0},
    87  	{AADDF, C_FREG, C_FREG, C_NONE, C_FREG, C_NONE, 2, 4, 0, 0},
    88  	{ACMPEQF, C_FREG, C_FREG, C_NONE, C_FCCREG, C_NONE, 2, 4, 0, 0},
    89  
    90  	{AVSEQB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
    91  	{AXVSEQB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
    92  	{AVSEQB, C_S5CON, C_VREG, C_NONE, C_VREG, C_NONE, 22, 4, 0, 0},
    93  	{AXVSEQB, C_S5CON, C_XREG, C_NONE, C_XREG, C_NONE, 22, 4, 0, 0},
    94  	{AVANDV, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
    95  	{AXVANDV, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
    96  	{AVANDB, C_U8CON, C_VREG, C_NONE, C_VREG, C_NONE, 23, 4, 0, 0},
    97  	{AXVANDB, C_U8CON, C_XREG, C_NONE, C_XREG, C_NONE, 23, 4, 0, 0},
    98  
    99  	{AVADDB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   100  	{AVADDB, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   101  	{AXVADDB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   102  	{AXVADDB, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   103  
   104  	{AVSLLB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   105  	{AVSLLB, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   106  	{AXVSLLB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   107  	{AXVSLLB, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   108  	{AVSLLB, C_U3CON, C_VREG, C_NONE, C_VREG, C_NONE, 13, 4, 0, 0},
   109  	{AXVSLLB, C_U3CON, C_XREG, C_NONE, C_XREG, C_NONE, 13, 4, 0, 0},
   110  	{AVSLLB, C_U3CON, C_NONE, C_NONE, C_VREG, C_NONE, 13, 4, 0, 0},
   111  	{AXVSLLB, C_U3CON, C_NONE, C_NONE, C_XREG, C_NONE, 13, 4, 0, 0},
   112  
   113  	{AVSLLH, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   114  	{AVSLLH, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   115  	{AXVSLLH, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   116  	{AXVSLLH, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   117  	{AVSLLH, C_U4CON, C_VREG, C_NONE, C_VREG, C_NONE, 14, 4, 0, 0},
   118  	{AXVSLLH, C_U4CON, C_XREG, C_NONE, C_XREG, C_NONE, 14, 4, 0, 0},
   119  	{AVSLLH, C_U4CON, C_NONE, C_NONE, C_VREG, C_NONE, 14, 4, 0, 0},
   120  	{AXVSLLH, C_U4CON, C_NONE, C_NONE, C_XREG, C_NONE, 14, 4, 0, 0},
   121  
   122  	{AVSLLW, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   123  	{AVSLLW, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   124  	{AXVSLLW, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   125  	{AXVSLLW, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   126  	{AVSLLW, C_U5CON, C_VREG, C_NONE, C_VREG, C_NONE, 31, 4, 0, 0},
   127  	{AXVSLLW, C_U5CON, C_XREG, C_NONE, C_XREG, C_NONE, 31, 4, 0, 0},
   128  	{AVSLLW, C_U5CON, C_NONE, C_NONE, C_VREG, C_NONE, 31, 4, 0, 0},
   129  	{AXVSLLW, C_U5CON, C_NONE, C_NONE, C_XREG, C_NONE, 31, 4, 0, 0},
   130  
   131  	{AVSLLV, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   132  	{AVSLLV, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   133  	{AXVSLLV, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   134  	{AXVSLLV, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   135  	{AVSLLV, C_U6CON, C_VREG, C_NONE, C_VREG, C_NONE, 32, 4, 0, 0},
   136  	{AXVSLLV, C_U6CON, C_XREG, C_NONE, C_XREG, C_NONE, 32, 4, 0, 0},
   137  	{AVSLLV, C_U6CON, C_NONE, C_NONE, C_VREG, C_NONE, 32, 4, 0, 0},
   138  	{AXVSLLV, C_U6CON, C_NONE, C_NONE, C_XREG, C_NONE, 32, 4, 0, 0},
   139  
   140  	{ACLOW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 9, 4, 0, 0},
   141  	{AABSF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0},
   142  	{AMOVVF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0},
   143  	{AMOVF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0},
   144  	{AMOVD, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0},
   145  	{AVPCNTB, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 9, 4, 0, 0},
   146  	{AXVPCNTB, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 9, 4, 0, 0},
   147  	{AVSETEQV, C_VREG, C_NONE, C_NONE, C_FCCREG, C_NONE, 9, 4, 0, 0},
   148  	{AXVSETEQV, C_XREG, C_NONE, C_NONE, C_FCCREG, C_NONE, 9, 4, 0, 0},
   149  
   150  	{AFMADDF, C_FREG, C_FREG, C_NONE, C_FREG, C_NONE, 37, 4, 0, 0},
   151  	{AFMADDF, C_FREG, C_FREG, C_FREG, C_FREG, C_NONE, 37, 4, 0, 0},
   152  
   153  	{AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
   154  	{AMOVWU, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
   155  	{AMOVV, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
   156  	{AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
   157  	{AMOVBU, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
   158  	{AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
   159  	{AMOVWU, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
   160  	{AMOVV, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
   161  	{AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
   162  	{AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
   163  	{AVMOVQ, C_VREG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
   164  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
   165  	{AVMOVQ, C_VREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGZERO, 0},
   166  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGZERO, 0},
   167  	{ASC, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
   168  	{ASCV, C_REG, C_NONE, C_NONE, C_SOREG, C_NONE, 7, 4, REGZERO, 0},
   169  
   170  	{AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
   171  	{AMOVWU, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
   172  	{AMOVV, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
   173  	{AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
   174  	{AMOVBU, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
   175  	{AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   176  	{AMOVWU, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   177  	{AMOVV, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   178  	{AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   179  	{AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   180  	{AVMOVQ, C_SOREG, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0},
   181  	{AXVMOVQ, C_SOREG, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0},
   182  	{AVMOVQ, C_SAUTO, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0},
   183  	{AXVMOVQ, C_SAUTO, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0},
   184  	{ALL, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   185  	{ALLV, C_SOREG, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   186  
   187  	{AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
   188  	{AMOVWU, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
   189  	{AMOVV, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
   190  	{AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
   191  	{AMOVBU, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
   192  	{AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
   193  	{AMOVWU, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
   194  	{AMOVV, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
   195  	{AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
   196  	{AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
   197  	{ASC, C_REG, C_NONE, C_NONE, C_LOREG, C_NONE, 35, 12, REGZERO, 0},
   198  	{AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   199  	{AMOVWU, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   200  	{AMOVV, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   201  	{AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   202  	{AMOVBU, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   203  	{AMOVW, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
   204  	{AMOVWU, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
   205  	{AMOVV, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
   206  	{AMOVB, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
   207  	{AMOVBU, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
   208  
   209  	{AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
   210  	{AMOVWU, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
   211  	{AMOVV, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
   212  	{AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
   213  	{AMOVBU, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
   214  	{AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
   215  	{AMOVWU, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
   216  	{AMOVV, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
   217  	{AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
   218  	{AMOVBU, C_LOREG, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
   219  	{AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
   220  	{AMOVWU, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
   221  	{AMOVV, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
   222  	{AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
   223  	{AMOVBU, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
   224  	{AMOVW, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
   225  	{AMOVWU, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
   226  	{AMOVV, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
   227  	{AMOVB, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
   228  	{AMOVBU, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
   229  
   230  	{AMOVW, C_SACON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGSP, 0},
   231  	{AMOVV, C_SACON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGSP, 0},
   232  	{AMOVW, C_EXTADDR, C_NONE, C_NONE, C_REG, C_NONE, 52, 8, 0, NOTUSETMP},
   233  	{AMOVV, C_EXTADDR, C_NONE, C_NONE, C_REG, C_NONE, 52, 8, 0, NOTUSETMP},
   234  
   235  	{AMOVW, C_LACON, C_NONE, C_NONE, C_REG, C_NONE, 27, 12, REGSP, 0},
   236  	{AMOVV, C_LACON, C_NONE, C_NONE, C_REG, C_NONE, 27, 12, REGSP, 0},
   237  	{AMOVW, C_12CON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0},
   238  	{AMOVV, C_12CON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0},
   239  
   240  	{AMOVW, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 25, 4, 0, 0},
   241  	{AMOVV, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 25, 4, 0, 0},
   242  	{AMOVW, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP},
   243  	{AMOVV, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP},
   244  	{AMOVV, C_DCON12_0, C_NONE, C_NONE, C_REG, C_NONE, 67, 4, 0, NOTUSETMP},
   245  	{AMOVV, C_DCON12_20S, C_NONE, C_NONE, C_REG, C_NONE, 68, 8, 0, NOTUSETMP},
   246  	{AMOVV, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 69, 12, 0, NOTUSETMP},
   247  	{AMOVV, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 59, 16, 0, NOTUSETMP},
   248  
   249  	{AADD, C_US12CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
   250  	{AADD, C_US12CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
   251  	{AADD, C_U12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
   252  	{AADD, C_U12CON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
   253  
   254  	{AADDV, C_US12CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
   255  	{AADDV, C_US12CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
   256  	{AADDV, C_U12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
   257  	{AADDV, C_U12CON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
   258  
   259  	{AAND, C_UU12CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
   260  	{AAND, C_UU12CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
   261  	{AAND, C_S12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
   262  	{AAND, C_S12CON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
   263  
   264  	{AADD, C_32CON20_0, C_REG, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
   265  	{AADD, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
   266  	{AADDV, C_32CON20_0, C_REG, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
   267  	{AADDV, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
   268  	{AAND, C_32CON20_0, C_REG, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
   269  	{AAND, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
   270  
   271  	{AADD, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
   272  	{AADDV, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
   273  	{AAND, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
   274  	{AADD, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
   275  	{AADDV, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
   276  	{AAND, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
   277  
   278  	{AADDV, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 60, 20, 0, 0},
   279  	{AADDV, C_DCON, C_REG, C_NONE, C_REG, C_NONE, 60, 20, 0, 0},
   280  	{AAND, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 60, 20, 0, 0},
   281  	{AAND, C_DCON, C_REG, C_NONE, C_REG, C_NONE, 60, 20, 0, 0},
   282  	{AADDV, C_DCON12_0, C_NONE, C_NONE, C_REG, C_NONE, 70, 8, 0, 0},
   283  	{AADDV, C_DCON12_0, C_REG, C_NONE, C_REG, C_NONE, 70, 8, 0, 0},
   284  	{AAND, C_DCON12_0, C_NONE, C_NONE, C_REG, C_NONE, 70, 8, 0, 0},
   285  	{AAND, C_DCON12_0, C_REG, C_NONE, C_REG, C_NONE, 70, 8, 0, 0},
   286  	{AADDV, C_DCON12_20S, C_NONE, C_NONE, C_REG, C_NONE, 71, 12, 0, 0},
   287  	{AADDV, C_DCON12_20S, C_REG, C_NONE, C_REG, C_NONE, 71, 12, 0, 0},
   288  	{AAND, C_DCON12_20S, C_NONE, C_NONE, C_REG, C_NONE, 71, 12, 0, 0},
   289  	{AAND, C_DCON12_20S, C_REG, C_NONE, C_REG, C_NONE, 71, 12, 0, 0},
   290  	{AADDV, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 72, 16, 0, 0},
   291  	{AADDV, C_DCON32_12S, C_REG, C_NONE, C_REG, C_NONE, 72, 16, 0, 0},
   292  	{AAND, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 72, 16, 0, 0},
   293  	{AAND, C_DCON32_12S, C_REG, C_NONE, C_REG, C_NONE, 72, 16, 0, 0},
   294  
   295  	{ASLL, C_U5CON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
   296  	{ASLL, C_U5CON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
   297  
   298  	{ASLLV, C_U6CON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
   299  	{ASLLV, C_U6CON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
   300  
   301  	{ABSTRPICKW, C_U6CON, C_REG, C_U6CON, C_REG, C_NONE, 17, 4, 0, 0},
   302  	{ABSTRPICKW, C_U6CON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0},
   303  	{ABSTRPICKW, C_ZCON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0},
   304  
   305  	{ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
   306  	{ASYSCALL, C_U15CON, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
   307  
   308  	{ABEQ, C_REG, C_REG, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
   309  	{ABEQ, C_REG, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
   310  	{ABLEZ, C_REG, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
   311  	{ABFPT, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
   312  	{ABFPT, C_FCCREG, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
   313  
   314  	{AJMP, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 11, 4, 0, 0}, // b
   315  	{AJAL, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 11, 4, 0, 0}, // bl
   316  
   317  	{AJMP, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 18, 4, REGZERO, 0}, // jirl r0, rj, 0
   318  	{AJAL, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 18, 4, REGLINK, 0}, // jirl r1, rj, 0
   319  
   320  	{AMOVF, C_SAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGSP, 0},
   321  	{AMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGSP, 0},
   322  	{AMOVF, C_SOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0},
   323  	{AMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0},
   324  
   325  	{AMOVF, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGSP, 0},
   326  	{AMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGSP, 0},
   327  	{AMOVF, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0},
   328  	{AMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0},
   329  	{AMOVF, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 51, 8, 0, 0},
   330  	{AMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 51, 8, 0, 0},
   331  
   332  	{AMOVF, C_FREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 29, 4, REGSP, 0},
   333  	{AMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 29, 4, REGSP, 0},
   334  	{AMOVF, C_FREG, C_NONE, C_NONE, C_SOREG, C_NONE, 29, 4, REGZERO, 0},
   335  	{AMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, C_NONE, 29, 4, REGZERO, 0},
   336  
   337  	{AMOVF, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 29, 12, REGSP, 0},
   338  	{AMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 29, 12, REGSP, 0},
   339  	{AMOVF, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 29, 12, REGZERO, 0},
   340  	{AMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, C_NONE, 29, 12, REGZERO, 0},
   341  	{AMOVF, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   342  	{AMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   343  
   344  	{AMOVW, C_REG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
   345  	{AMOVV, C_REG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
   346  	{AMOVW, C_FREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
   347  	{AMOVV, C_FREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
   348  	{AMOVV, C_FCCREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
   349  	{AMOVV, C_FCSRREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
   350  	{AMOVV, C_REG, C_NONE, C_NONE, C_FCCREG, C_NONE, 30, 4, 0, 0},
   351  	{AMOVV, C_REG, C_NONE, C_NONE, C_FCSRREG, C_NONE, 30, 4, 0, 0},
   352  	{AMOVV, C_FREG, C_NONE, C_NONE, C_FCCREG, C_NONE, 30, 4, 0, 0},
   353  	{AMOVV, C_FCCREG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
   354  
   355  	{AMOVW, C_12CON, C_NONE, C_NONE, C_FREG, C_NONE, 34, 8, 0, 0},
   356  
   357  	{AMOVB, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
   358  	{AMOVW, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
   359  	{AMOVV, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
   360  	{AMOVBU, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
   361  	{AMOVWU, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
   362  
   363  	{AMOVB, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
   364  	{AMOVW, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
   365  	{AMOVV, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
   366  	{AMOVBU, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
   367  	{AMOVWU, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
   368  
   369  	{AWORD, C_32CON, C_NONE, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0},
   370  	{AWORD, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 61, 4, 0, 0},
   371  
   372  	{AMOVV, C_GOTADDR, C_NONE, C_NONE, C_REG, C_NONE, 65, 8, 0, 0},
   373  
   374  	{ATEQ, C_US12CON, C_REG, C_NONE, C_REG, C_NONE, 15, 8, 0, 0},
   375  	{ATEQ, C_US12CON, C_NONE, C_NONE, C_REG, C_NONE, 15, 8, 0, 0},
   376  
   377  	{ARDTIMELW, C_NONE, C_NONE, C_NONE, C_REG, C_REG, 62, 4, 0, 0},
   378  	{AAMSWAPW, C_REG, C_NONE, C_NONE, C_ZOREG, C_REG, 66, 4, 0, 0},
   379  	{ANOOP, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0},
   380  
   381  	/* store with extended register offset */
   382  	{AMOVB, C_REG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   383  	{AMOVW, C_REG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   384  	{AMOVV, C_REG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   385  	{AMOVF, C_FREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   386  	{AMOVD, C_FREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   387  	{AVMOVQ, C_VREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   388  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   389  
   390  	/* load with extended register offset */
   391  	{AMOVB, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
   392  	{AMOVBU, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
   393  	{AMOVW, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
   394  	{AMOVWU, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
   395  	{AMOVV, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
   396  	{AMOVF, C_ROFF, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0},
   397  	{AMOVD, C_ROFF, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0},
   398  	{AVMOVQ, C_ROFF, C_NONE, C_NONE, C_VREG, C_NONE, 21, 4, 0, 0},
   399  	{AXVMOVQ, C_ROFF, C_NONE, C_NONE, C_XREG, C_NONE, 21, 4, 0, 0},
   400  
   401  	{AVMOVQ, C_REG, C_NONE, C_NONE, C_ELEM, C_NONE, 39, 4, 0, 0},
   402  	{AVMOVQ, C_ELEM, C_NONE, C_NONE, C_REG, C_NONE, 40, 4, 0, 0},
   403  	{AXVMOVQ, C_REG, C_NONE, C_NONE, C_ELEM, C_NONE, 39, 4, 0, 0},
   404  	{AXVMOVQ, C_ELEM, C_NONE, C_NONE, C_REG, C_NONE, 40, 4, 0, 0},
   405  
   406  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_ELEM, C_NONE, 43, 4, 0, 0},
   407  	{AXVMOVQ, C_ELEM, C_NONE, C_NONE, C_XREG, C_NONE, 44, 4, 0, 0},
   408  
   409  	{AVMOVQ, C_REG, C_NONE, C_NONE, C_ARNG, C_NONE, 41, 4, 0, 0},
   410  	{AXVMOVQ, C_REG, C_NONE, C_NONE, C_ARNG, C_NONE, 41, 4, 0, 0},
   411  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_ARNG, C_NONE, 42, 4, 0, 0},
   412  
   413  	{AVMOVQ, C_ELEM, C_NONE, C_NONE, C_ARNG, C_NONE, 45, 4, 0, 0},
   414  
   415  	{obj.APCALIGN, C_U12CON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
   416  	{obj.APCDATA, C_32CON, C_NONE, C_NONE, C_32CON, C_NONE, 0, 0, 0, 0},
   417  	{obj.APCDATA, C_DCON, C_NONE, C_NONE, C_DCON, C_NONE, 0, 0, 0, 0},
   418  	{obj.AFUNCDATA, C_U12CON, C_NONE, C_NONE, C_ADDR, C_NONE, 0, 0, 0, 0},
   419  	{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
   420  	{obj.ANOP, C_32CON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, // nop variants, see #40689
   421  	{obj.ANOP, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},  // nop variants, see #40689
   422  	{obj.ANOP, C_REG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
   423  	{obj.ANOP, C_FREG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
   424  	{obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 11, 4, 0, 0}, // same as AJMP
   425  	{obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 11, 4, 0, 0}, // same as AJMP
   426  
   427  	{obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0},
   428  }
   429  
   430  var atomicInst = map[obj.As]uint32{
   431  	AAMSWAPB:   0x070B8 << 15, // amswap.b
   432  	AAMSWAPH:   0x070B9 << 15, // amswap.h
   433  	AAMSWAPW:   0x070C0 << 15, // amswap.w
   434  	AAMSWAPV:   0x070C1 << 15, // amswap.d
   435  	AAMCASB:    0x070B0 << 15, // amcas.b
   436  	AAMCASH:    0x070B1 << 15, // amcas.h
   437  	AAMCASW:    0x070B2 << 15, // amcas.w
   438  	AAMCASV:    0x070B3 << 15, // amcas.d
   439  	AAMADDW:    0x070C2 << 15, // amadd.w
   440  	AAMADDV:    0x070C3 << 15, // amadd.d
   441  	AAMANDW:    0x070C4 << 15, // amand.w
   442  	AAMANDV:    0x070C5 << 15, // amand.d
   443  	AAMORW:     0x070C6 << 15, // amor.w
   444  	AAMORV:     0x070C7 << 15, // amor.d
   445  	AAMXORW:    0x070C8 << 15, // amxor.w
   446  	AAMXORV:    0x070C9 << 15, // amxor.d
   447  	AAMMAXW:    0x070CA << 15, // ammax.w
   448  	AAMMAXV:    0x070CB << 15, // ammax.d
   449  	AAMMINW:    0x070CC << 15, // ammin.w
   450  	AAMMINV:    0x070CD << 15, // ammin.d
   451  	AAMMAXWU:   0x070CE << 15, // ammax.wu
   452  	AAMMAXVU:   0x070CF << 15, // ammax.du
   453  	AAMMINWU:   0x070D0 << 15, // ammin.wu
   454  	AAMMINVU:   0x070D1 << 15, // ammin.du
   455  	AAMSWAPDBB: 0x070BC << 15, // amswap_db.b
   456  	AAMSWAPDBH: 0x070BD << 15, // amswap_db.h
   457  	AAMSWAPDBW: 0x070D2 << 15, // amswap_db.w
   458  	AAMSWAPDBV: 0x070D3 << 15, // amswap_db.d
   459  	AAMCASDBB:  0x070B4 << 15, // amcas_db.b
   460  	AAMCASDBH:  0x070B5 << 15, // amcas_db.h
   461  	AAMCASDBW:  0x070B6 << 15, // amcas_db.w
   462  	AAMCASDBV:  0x070B7 << 15, // amcas_db.d
   463  	AAMADDDBW:  0x070D4 << 15, // amadd_db.w
   464  	AAMADDDBV:  0x070D5 << 15, // amadd_db.d
   465  	AAMANDDBW:  0x070D6 << 15, // amand_db.w
   466  	AAMANDDBV:  0x070D7 << 15, // amand_db.d
   467  	AAMORDBW:   0x070D8 << 15, // amor_db.w
   468  	AAMORDBV:   0x070D9 << 15, // amor_db.d
   469  	AAMXORDBW:  0x070DA << 15, // amxor_db.w
   470  	AAMXORDBV:  0x070DB << 15, // amxor_db.d
   471  	AAMMAXDBW:  0x070DC << 15, // ammax_db.w
   472  	AAMMAXDBV:  0x070DD << 15, // ammax_db.d
   473  	AAMMINDBW:  0x070DE << 15, // ammin_db.w
   474  	AAMMINDBV:  0x070DF << 15, // ammin_db.d
   475  	AAMMAXDBWU: 0x070E0 << 15, // ammax_db.wu
   476  	AAMMAXDBVU: 0x070E1 << 15, // ammax_db.du
   477  	AAMMINDBWU: 0x070E2 << 15, // ammin_db.wu
   478  	AAMMINDBVU: 0x070E3 << 15, // ammin_db.du
   479  }
   480  
   481  func IsAtomicInst(as obj.As) bool {
   482  	_, ok := atomicInst[as]
   483  
   484  	return ok
   485  }
   486  
   487  // pcAlignPadLength returns the number of bytes required to align pc to alignedValue,
   488  // reporting an error if alignedValue is not a power of two or is out of range.
   489  func pcAlignPadLength(ctxt *obj.Link, pc int64, alignedValue int64) int {
   490  	if !((alignedValue&(alignedValue-1) == 0) && 8 <= alignedValue && alignedValue <= 2048) {
   491  		ctxt.Diag("alignment value of an instruction must be a power of two and in the range [8, 2048], got %d\n", alignedValue)
   492  	}
   493  	return int(-pc & (alignedValue - 1))
   494  }
   495  
   496  var oprange [ALAST & obj.AMask][]Optab
   497  
   498  var xcmp [C_NCLASS][C_NCLASS]bool
   499  
   500  func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
   501  	if ctxt.Retpoline {
   502  		ctxt.Diag("-spectre=ret not supported on loong64")
   503  		ctxt.Retpoline = false // don't keep printing
   504  	}
   505  
   506  	p := cursym.Func().Text
   507  	if p == nil || p.Link == nil { // handle external functions and ELF section symbols
   508  		return
   509  	}
   510  
   511  	c := ctxt0{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset + ctxt.Arch.FixedFrameSize)}
   512  
   513  	if oprange[AOR&obj.AMask] == nil {
   514  		c.ctxt.Diag("loong64 ops not initialized, call loong64.buildop first")
   515  	}
   516  
   517  	pc := int64(0)
   518  	p.Pc = pc
   519  
   520  	var m int
   521  	var o *Optab
   522  	for p = p.Link; p != nil; p = p.Link {
   523  		p.Pc = pc
   524  		o = c.oplook(p)
   525  		m = int(o.size)
   526  		if m == 0 {
   527  			switch p.As {
   528  			case obj.APCALIGN:
   529  				alignedValue := p.From.Offset
   530  				m = pcAlignPadLength(ctxt, pc, alignedValue)
   531  				// Update the current text symbol alignment value.
   532  				if int32(alignedValue) > cursym.Func().Align {
   533  					cursym.Func().Align = int32(alignedValue)
   534  				}
   535  				break
   536  			case obj.ANOP, obj.AFUNCDATA, obj.APCDATA:
   537  				continue
   538  			default:
   539  				c.ctxt.Diag("zero-width instruction\n%v", p)
   540  			}
   541  		}
   542  
   543  		pc += int64(m)
   544  	}
   545  
   546  	c.cursym.Size = pc
   547  
   548  	// mark loop entry instructions for padding
   549  	// loop entrances are defined as targets of backward branches
   550  	for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
   551  		if q := p.To.Target(); q != nil && q.Pc < p.Pc {
   552  			q.Mark |= branchLoopHead
   553  		}
   554  	}
   555  
   556  	// Run these passes until convergence.
   557  	for {
   558  		rescan := false
   559  		pc = 0
   560  		prev := c.cursym.Func().Text
   561  		for p = prev.Link; p != nil; prev, p = p, p.Link {
   562  			p.Pc = pc
   563  			o = c.oplook(p)
   564  
   565  			// Prepend a PCALIGN $loopAlign to each of the loop heads
   566  			// that need padding, if not already done so (because this
   567  			// pass may execute more than once).
   568  			//
   569  			// This needs to come before any pass that look at pc,
   570  			// because pc will be adjusted if padding happens.
   571  			if p.Mark&branchLoopHead != 0 && pc&(loopAlign-1) != 0 &&
   572  				!(prev.As == obj.APCALIGN && prev.From.Offset >= loopAlign) {
   573  				q := c.newprog()
   574  				prev.Link = q
   575  				q.Link = p
   576  				q.Pc = pc
   577  				q.As = obj.APCALIGN
   578  				q.From.Type = obj.TYPE_CONST
   579  				q.From.Offset = loopAlign
   580  				// Don't associate the synthesized PCALIGN with
   581  				// the original source position, for deterministic
   582  				// mapping between source and corresponding asm.
   583  				// q.Pos = p.Pos
   584  
   585  				// Manually make the PCALIGN come into effect,
   586  				// since this loop iteration is for p.
   587  				pc += int64(pcAlignPadLength(ctxt, pc, loopAlign))
   588  				p.Pc = pc
   589  				rescan = true
   590  			}
   591  
   592  			// very large conditional branches
   593  			//
   594  			// if any procedure is large enough to generate a large SBRA branch, then
   595  			// generate extra passes putting branches around jmps to fix. this is rare.
   596  			if o.type_ == 6 && p.To.Target() != nil {
   597  				otxt := p.To.Target().Pc - pc
   598  
   599  				// On loong64, the immediate value field of the conditional branch instructions
   600  				// BFPT and BFPT is 21 bits, and the others are 16 bits. The jump target address
   601  				// is to logically shift the immediate value in the instruction code to the left
   602  				// by 2 bits and then sign extend.
   603  				bound := int64(1 << (18 - 1))
   604  
   605  				switch p.As {
   606  				case ABFPT, ABFPF:
   607  					bound = int64(1 << (23 - 1))
   608  				}
   609  
   610  				if otxt < -bound || otxt >= bound {
   611  					q := c.newprog()
   612  					q.Link = p.Link
   613  					p.Link = q
   614  					q.As = AJMP
   615  					q.Pos = p.Pos
   616  					q.To.Type = obj.TYPE_BRANCH
   617  					q.To.SetTarget(p.To.Target())
   618  					p.To.SetTarget(q)
   619  					q = c.newprog()
   620  					q.Link = p.Link
   621  					p.Link = q
   622  					q.As = AJMP
   623  					q.Pos = p.Pos
   624  					q.To.Type = obj.TYPE_BRANCH
   625  					q.To.SetTarget(q.Link.Link)
   626  					rescan = true
   627  				}
   628  			}
   629  
   630  			m = int(o.size)
   631  			if m == 0 {
   632  				switch p.As {
   633  				case obj.APCALIGN:
   634  					alignedValue := p.From.Offset
   635  					m = pcAlignPadLength(ctxt, pc, alignedValue)
   636  					break
   637  				case obj.ANOP, obj.AFUNCDATA, obj.APCDATA:
   638  					continue
   639  				default:
   640  					c.ctxt.Diag("zero-width instruction\n%v", p)
   641  				}
   642  			}
   643  
   644  			pc += int64(m)
   645  		}
   646  
   647  		c.cursym.Size = pc
   648  
   649  		if !rescan {
   650  			break
   651  		}
   652  	}
   653  
   654  	pc += -pc & (FuncAlign - 1)
   655  	c.cursym.Size = pc
   656  
   657  	// lay out the code, emitting code and data relocations.
   658  
   659  	c.cursym.Grow(c.cursym.Size)
   660  
   661  	bp := c.cursym.P
   662  	var i int32
   663  	var out [5]uint32
   664  	for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
   665  		c.pc = p.Pc
   666  		o = c.oplook(p)
   667  		if int(o.size) > 4*len(out) {
   668  			log.Fatalf("out array in span0 is too small, need at least %d for %v", o.size/4, p)
   669  		}
   670  		if p.As == obj.APCALIGN {
   671  			alignedValue := p.From.Offset
   672  			v := pcAlignPadLength(c.ctxt, p.Pc, alignedValue)
   673  			for i = 0; i < int32(v/4); i++ {
   674  				// emit ANOOP instruction by the padding size
   675  				c.ctxt.Arch.ByteOrder.PutUint32(bp, OP_12IRR(c.opirr(AAND), 0, 0, 0))
   676  				bp = bp[4:]
   677  			}
   678  			continue
   679  		}
   680  		c.asmout(p, o, out[:])
   681  		for i = 0; i < int32(o.size/4); i++ {
   682  			c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
   683  			bp = bp[4:]
   684  		}
   685  	}
   686  
   687  	// Mark nonpreemptible instruction sequences.
   688  	// We use REGTMP as a scratch register during call injection,
   689  	// so instruction sequences that use REGTMP are unsafe to
   690  	// preempt asynchronously.
   691  	obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable)
   692  }
   693  
   694  // isUnsafePoint returns whether p is an unsafe point.
   695  func (c *ctxt0) isUnsafePoint(p *obj.Prog) bool {
   696  	// If p explicitly uses REGTMP, it's unsafe to preempt, because the
   697  	// preemption sequence clobbers REGTMP.
   698  	return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP
   699  }
   700  
   701  // isRestartable returns whether p is a multi-instruction sequence that,
   702  // if preempted, can be restarted.
   703  func (c *ctxt0) isRestartable(p *obj.Prog) bool {
   704  	if c.isUnsafePoint(p) {
   705  		return false
   706  	}
   707  	// If p is a multi-instruction sequence with uses REGTMP inserted by
   708  	// the assembler in order to materialize a large constant/offset, we
   709  	// can restart p (at the start of the instruction sequence), recompute
   710  	// the content of REGTMP, upon async preemption. Currently, all cases
   711  	// of assembler-inserted REGTMP fall into this category.
   712  	// If p doesn't use REGTMP, it can be simply preempted, so we don't
   713  	// mark it.
   714  	o := c.oplook(p)
   715  	return o.size > 4 && o.flag&NOTUSETMP == 0
   716  }
   717  
   718  func isint32(v int64) bool {
   719  	return int64(int32(v)) == v
   720  }
   721  
   722  func isuint32(v uint64) bool {
   723  	return uint64(uint32(v)) == v
   724  }
   725  
   726  func (c *ctxt0) aclass(a *obj.Addr) int {
   727  	switch a.Type {
   728  	case obj.TYPE_NONE:
   729  		return C_NONE
   730  
   731  	case obj.TYPE_REG:
   732  		return c.rclass(a.Reg)
   733  
   734  	case obj.TYPE_MEM:
   735  		switch a.Name {
   736  		case obj.NAME_EXTERN,
   737  			obj.NAME_STATIC:
   738  			if a.Sym == nil {
   739  				break
   740  			}
   741  			c.instoffset = a.Offset
   742  			if a.Sym.Type == objabi.STLSBSS {
   743  				if c.ctxt.Flag_shared {
   744  					return C_TLS_IE
   745  				} else {
   746  					return C_TLS_LE
   747  				}
   748  			}
   749  			return C_ADDR
   750  
   751  		case obj.NAME_AUTO:
   752  			if a.Reg == REGSP {
   753  				// unset base register for better printing, since
   754  				// a.Offset is still relative to pseudo-SP.
   755  				a.Reg = obj.REG_NONE
   756  			}
   757  			c.instoffset = int64(c.autosize) + a.Offset
   758  			if c.instoffset >= -BIG && c.instoffset < BIG {
   759  				return C_SAUTO
   760  			}
   761  			return C_LAUTO
   762  
   763  		case obj.NAME_PARAM:
   764  			if a.Reg == REGSP {
   765  				// unset base register for better printing, since
   766  				// a.Offset is still relative to pseudo-FP.
   767  				a.Reg = obj.REG_NONE
   768  			}
   769  			c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
   770  			if c.instoffset >= -BIG && c.instoffset < BIG {
   771  				return C_SAUTO
   772  			}
   773  			return C_LAUTO
   774  
   775  		case obj.NAME_NONE:
   776  			if a.Index != 0 {
   777  				if a.Offset != 0 {
   778  					return C_GOK
   779  				}
   780  				// register offset
   781  				return C_ROFF
   782  			}
   783  
   784  			c.instoffset = a.Offset
   785  			if c.instoffset == 0 {
   786  				return C_ZOREG
   787  			}
   788  			if c.instoffset >= -BIG && c.instoffset < BIG {
   789  				return C_SOREG
   790  			}
   791  			return C_LOREG
   792  
   793  		case obj.NAME_GOTREF:
   794  			return C_GOTADDR
   795  		}
   796  
   797  		return C_GOK
   798  
   799  	case obj.TYPE_TEXTSIZE:
   800  		return C_TEXTSIZE
   801  
   802  	case obj.TYPE_CONST,
   803  		obj.TYPE_ADDR:
   804  		switch a.Name {
   805  		case obj.NAME_NONE:
   806  			c.instoffset = a.Offset
   807  			if a.Reg != 0 {
   808  				if -BIG <= c.instoffset && c.instoffset <= BIG {
   809  					return C_SACON
   810  				}
   811  				if isint32(c.instoffset) {
   812  					return C_LACON
   813  				}
   814  				return C_DACON
   815  			}
   816  
   817  		case obj.NAME_EXTERN,
   818  			obj.NAME_STATIC:
   819  			s := a.Sym
   820  			if s == nil {
   821  				return C_GOK
   822  			}
   823  
   824  			c.instoffset = a.Offset
   825  			if s.Type == objabi.STLSBSS {
   826  				c.ctxt.Diag("taking address of TLS variable is not supported")
   827  			}
   828  			return C_EXTADDR
   829  
   830  		case obj.NAME_AUTO:
   831  			if a.Reg == REGSP {
   832  				// unset base register for better printing, since
   833  				// a.Offset is still relative to pseudo-SP.
   834  				a.Reg = obj.REG_NONE
   835  			}
   836  			c.instoffset = int64(c.autosize) + a.Offset
   837  			if c.instoffset >= -BIG && c.instoffset < BIG {
   838  				return C_SACON
   839  			}
   840  			return C_LACON
   841  
   842  		case obj.NAME_PARAM:
   843  			if a.Reg == REGSP {
   844  				// unset base register for better printing, since
   845  				// a.Offset is still relative to pseudo-FP.
   846  				a.Reg = obj.REG_NONE
   847  			}
   848  			c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
   849  			if c.instoffset >= -BIG && c.instoffset < BIG {
   850  				return C_SACON
   851  			}
   852  			return C_LACON
   853  
   854  		default:
   855  			return C_GOK
   856  		}
   857  
   858  		if c.instoffset != int64(int32(c.instoffset)) {
   859  			return dconClass(c.instoffset)
   860  		}
   861  
   862  		if c.instoffset >= 0 {
   863  			sbits := bits.Len64(uint64(c.instoffset))
   864  			switch {
   865  			case sbits <= 8:
   866  				return C_ZCON + sbits
   867  			case sbits <= 12:
   868  				if c.instoffset <= 0x7ff {
   869  					return C_US12CON
   870  				}
   871  				return C_U12CON
   872  			case sbits <= 13:
   873  				if c.instoffset&0xfff == 0 {
   874  					return C_U13CON20_0
   875  				}
   876  				return C_U13CON
   877  			case sbits <= 15:
   878  				if c.instoffset&0xfff == 0 {
   879  					return C_U15CON20_0
   880  				}
   881  				return C_U15CON
   882  			}
   883  		} else {
   884  			sbits := bits.Len64(uint64(^c.instoffset))
   885  			switch {
   886  			case sbits < 5:
   887  				return C_S5CON
   888  			case sbits < 12:
   889  				return C_S12CON
   890  			case sbits < 13:
   891  				if c.instoffset&0xfff == 0 {
   892  					return C_S13CON20_0
   893  				}
   894  				return C_S13CON
   895  			}
   896  		}
   897  
   898  		if c.instoffset&0xfff == 0 {
   899  			return C_32CON20_0
   900  		}
   901  		return C_32CON
   902  
   903  	case obj.TYPE_BRANCH:
   904  		return C_BRAN
   905  	}
   906  
   907  	return C_GOK
   908  }
   909  
   910  // The constants here define the data characteristics within the bit field range.
   911  //
   912  //	ALL1: The data in the bit field is all 1
   913  //	ALL0: The data in the bit field is all 0
   914  //	ST1: The data in the bit field starts with 1, but not all 1
   915  //	ST0: The data in the bit field starts with 0, but not all 0
   916  const (
   917  	ALL1 = iota
   918  	ALL0
   919  	ST1
   920  	ST0
   921  )
   922  
   923  // mask returns the mask of the specified bit field, which is used to help determine
   924  // the data characteristics of the immediate value at the specified bit.
   925  func mask(suf int8, len int8) (uint64, uint64) {
   926  	if len == 12 {
   927  		if suf == 0 {
   928  			return 0xfff, 0x800
   929  		} else { // suf == 52
   930  			return 0xfff0000000000000, 0x8000000000000000
   931  		}
   932  	} else { // len == 20
   933  		if suf == 12 {
   934  			return 0xfffff000, 0x80000000
   935  		} else { // suf == 32
   936  			return 0xfffff00000000, 0x8000000000000
   937  		}
   938  	}
   939  }
   940  
   941  // bitField return a number represent status of val in bit field
   942  //
   943  //	suf: The starting bit of the bit field
   944  //	len: The length of the bit field
   945  func bitField(val int64, suf int8, len int8) int8 {
   946  	mask1, mask2 := mask(suf, len)
   947  	if uint64(val)&mask1 == mask1 {
   948  		return ALL1
   949  	} else if uint64(val)&mask1 == 0x0 {
   950  		return ALL0
   951  	} else if uint64(val)&mask2 == mask2 {
   952  		return ST1
   953  	} else {
   954  		return ST0
   955  	}
   956  }
   957  
   958  // Loading an immediate value larger than 32 bits requires four instructions
   959  // on loong64 (lu12i.w + ori + lu32i.d + lu52i.d), but in some special cases,
   960  // we can use the sign extension and zero extension features of the instruction
   961  // to fill in the high-order data (all 0 or all 1), which can save one to
   962  // three instructions.
   963  //
   964  //	| 63 ~ 52 | 51 ~ 32 | 31 ~ 12 | 11 ~ 0 |
   965  //	| lu52i.d | lu32i.d | lu12i.w |   ori  |
   966  func dconClass(offset int64) int {
   967  	tzb := bits.TrailingZeros64(uint64(offset))
   968  	hi12 := bitField(offset, 52, 12)
   969  	hi20 := bitField(offset, 32, 20)
   970  	lo20 := bitField(offset, 12, 20)
   971  	lo12 := bitField(offset, 0, 12)
   972  	if tzb >= 52 {
   973  		return C_DCON12_0 // lu52i.d
   974  	}
   975  	if tzb >= 32 {
   976  		if ((hi20 == ALL1 || hi20 == ST1) && hi12 == ALL1) || ((hi20 == ALL0 || hi20 == ST0) && hi12 == ALL0) {
   977  			return C_DCON20S_0 // addi.w + lu32i.d
   978  		}
   979  		return C_DCON32_0 // addi.w + lu32i.d + lu52i.d
   980  	}
   981  	if tzb >= 12 {
   982  		if lo20 == ST1 || lo20 == ALL1 {
   983  			if hi20 == ALL1 {
   984  				return C_DCON12_20S // lu12i.w + lu52i.d
   985  			}
   986  			if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) {
   987  				return C_DCON20S_20 // lu12i.w + lu32i.d
   988  			}
   989  			return C_DCON32_20 // lu12i.w + lu32i.d + lu52i.d
   990  		}
   991  		if hi20 == ALL0 {
   992  			return C_DCON12_20S // lu12i.w + lu52i.d
   993  		}
   994  		if (hi20 == ST0 && hi12 == ALL0) || ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) {
   995  			return C_DCON20S_20 // lu12i.w + lu32i.d
   996  		}
   997  		return C_DCON32_20 // lu12i.w + lu32i.d + lu52i.d
   998  	}
   999  	if lo12 == ST1 || lo12 == ALL1 {
  1000  		if lo20 == ALL1 {
  1001  			if hi20 == ALL1 {
  1002  				return C_DCON12_12S // addi.d + lu52i.d
  1003  			}
  1004  			if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) {
  1005  				return C_DCON20S_12S // addi.w + lu32i.d
  1006  			}
  1007  			return C_DCON32_12S // addi.w + lu32i.d + lu52i.d
  1008  		}
  1009  		if lo20 == ST1 {
  1010  			if hi20 == ALL1 {
  1011  
  1012  				return C_DCON12_32S // lu12i.w + ori + lu52i.d
  1013  			}
  1014  			if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) {
  1015  				return C_DCON20S_32 // lu12i.w + ori + lu32i.d
  1016  			}
  1017  			return C_DCON // lu12i.w + ori + lu32i.d + lu52i.d
  1018  		}
  1019  		if lo20 == ALL0 {
  1020  			if hi20 == ALL0 {
  1021  				return C_DCON12_12U // ori + lu52i.d
  1022  			}
  1023  			if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) {
  1024  				return C_DCON20S_12U // ori + lu32i.d
  1025  			}
  1026  			return C_DCON32_12U // ori + lu32i.d + lu52i.d
  1027  		}
  1028  		if hi20 == ALL0 {
  1029  			return C_DCON12_32S // lu12i.w + ori + lu52i.d
  1030  		}
  1031  		if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) {
  1032  			return C_DCON20S_32 // lu12i.w + ori + lu32i.d
  1033  		}
  1034  		return C_DCON // lu12i.w + ori + lu32i.d + lu52i.d
  1035  	}
  1036  	if lo20 == ALL0 {
  1037  		if hi20 == ALL0 {
  1038  			return C_DCON12_12U // ori + lu52i.d
  1039  		}
  1040  		if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) {
  1041  			return C_DCON20S_12U // ori + lu32i.d
  1042  		}
  1043  		return C_DCON32_12U // ori + lu32i.d + lu52i.d
  1044  	}
  1045  	if lo20 == ST1 || lo20 == ALL1 {
  1046  		if hi20 == ALL1 {
  1047  			return C_DCON12_32S // lu12i.w + ori + lu52i.d
  1048  		}
  1049  		if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) {
  1050  			return C_DCON20S_32 // lu12i.w + ori + lu32i.d
  1051  		}
  1052  		return C_DCON
  1053  	}
  1054  	if hi20 == ALL0 {
  1055  		return C_DCON12_32S // lu12i.w + ori + lu52i.d
  1056  	}
  1057  	if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) {
  1058  		return C_DCON20S_32 // lu12i.w + ori + lu32i.d
  1059  	}
  1060  	return C_DCON
  1061  }
  1062  
  1063  // In Loong64,there are 8 CFRs, denoted as fcc0-fcc7.
  1064  // There are 4 FCSRs, denoted as fcsr0-fcsr3.
  1065  func (c *ctxt0) rclass(r int16) int {
  1066  	switch {
  1067  	case REG_R0 <= r && r <= REG_R31:
  1068  		return C_REG
  1069  	case REG_F0 <= r && r <= REG_F31:
  1070  		return C_FREG
  1071  	case REG_FCC0 <= r && r <= REG_FCC7:
  1072  		return C_FCCREG
  1073  	case REG_FCSR0 <= r && r <= REG_FCSR3:
  1074  		return C_FCSRREG
  1075  	case REG_V0 <= r && r <= REG_V31:
  1076  		return C_VREG
  1077  	case REG_X0 <= r && r <= REG_X31:
  1078  		return C_XREG
  1079  	case r >= REG_ARNG && r < REG_ELEM:
  1080  		return C_ARNG
  1081  	case r >= REG_ELEM && r < REG_ELEM_END:
  1082  		return C_ELEM
  1083  	}
  1084  
  1085  	return C_GOK
  1086  }
  1087  
  1088  func oclass(a *obj.Addr) int {
  1089  	return int(a.Class) - 1
  1090  }
  1091  
  1092  func prasm(p *obj.Prog) {
  1093  	fmt.Printf("%v\n", p)
  1094  }
  1095  
  1096  func (c *ctxt0) oplook(p *obj.Prog) *Optab {
  1097  	if oprange[AOR&obj.AMask] == nil {
  1098  		c.ctxt.Diag("loong64 ops not initialized, call loong64.buildop first")
  1099  	}
  1100  
  1101  	a1 := int(p.Optab)
  1102  	if a1 != 0 {
  1103  		return &optab[a1-1]
  1104  	}
  1105  
  1106  	// first source operand
  1107  	a1 = int(p.From.Class)
  1108  	if a1 == 0 {
  1109  		a1 = c.aclass(&p.From) + 1
  1110  		p.From.Class = int8(a1)
  1111  	}
  1112  	a1--
  1113  
  1114  	// first destination operand
  1115  	a4 := int(p.To.Class)
  1116  	if a4 == 0 {
  1117  		a4 = c.aclass(&p.To) + 1
  1118  		p.To.Class = int8(a4)
  1119  	}
  1120  	a4--
  1121  
  1122  	// 2nd source operand
  1123  	a2 := C_NONE
  1124  	if p.Reg != 0 {
  1125  		a2 = c.rclass(p.Reg)
  1126  	}
  1127  
  1128  	// 2nd destination operand
  1129  	a5 := C_NONE
  1130  	if p.RegTo2 != 0 {
  1131  		a5 = C_REG
  1132  	}
  1133  
  1134  	// 3rd source operand
  1135  	a3 := C_NONE
  1136  	if len(p.RestArgs) > 0 {
  1137  		a3 = int(p.RestArgs[0].Class)
  1138  		if a3 == 0 {
  1139  			a3 = c.aclass(&p.RestArgs[0].Addr) + 1
  1140  			p.RestArgs[0].Class = int8(a3)
  1141  		}
  1142  		a3--
  1143  	}
  1144  
  1145  	ops := oprange[p.As&obj.AMask]
  1146  	c1 := &xcmp[a1]
  1147  	c3 := &xcmp[a3]
  1148  	c4 := &xcmp[a4]
  1149  	for i := range ops {
  1150  		op := &ops[i]
  1151  		if (int(op.reg) == a2) && c3[op.from3] && c1[op.from1] && c4[op.to1] && (int(op.to2) == a5) {
  1152  			p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
  1153  			return op
  1154  		}
  1155  	}
  1156  
  1157  	c.ctxt.Diag("illegal combination %v %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4), DRconv(a5))
  1158  	prasm(p)
  1159  	// Turn illegal instruction into an UNDEF, avoid crashing in asmout.
  1160  	return &Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0}
  1161  }
  1162  
  1163  func cmp(a int, b int) bool {
  1164  	if a == b {
  1165  		return true
  1166  	}
  1167  	switch a {
  1168  	case C_DCON:
  1169  		return cmp(C_32CON, b) || cmp(C_DCON12_20S, b) || cmp(C_DCON32_12S, b) || b == C_DCON12_0
  1170  	case C_32CON:
  1171  		return cmp(C_32CON20_0, b) || cmp(C_U15CON, b) || cmp(C_13CON, b) || cmp(C_12CON, b)
  1172  	case C_32CON20_0:
  1173  		return b == C_U15CON20_0 || b == C_U13CON20_0 || b == C_S13CON20_0 || b == C_ZCON
  1174  	case C_U15CON:
  1175  		return cmp(C_U12CON, b) || b == C_U15CON20_0 || b == C_U13CON20_0 || b == C_U13CON
  1176  	case C_13CON:
  1177  		return cmp(C_U13CON, b) || cmp(C_S13CON, b)
  1178  	case C_U13CON:
  1179  		return cmp(C_12CON, b) || b == C_U13CON20_0
  1180  	case C_S13CON:
  1181  		return cmp(C_12CON, b) || b == C_S13CON20_0
  1182  	case C_12CON:
  1183  		return cmp(C_U12CON, b) || cmp(C_S12CON, b)
  1184  	case C_UU12CON:
  1185  		return cmp(C_U12CON, b)
  1186  	case C_U12CON:
  1187  		return cmp(C_U8CON, b) || b == C_US12CON
  1188  	case C_U8CON:
  1189  		return cmp(C_U7CON, b)
  1190  	case C_U7CON:
  1191  		return cmp(C_U6CON, b)
  1192  	case C_U6CON:
  1193  		return cmp(C_U5CON, b)
  1194  	case C_U5CON:
  1195  		return cmp(C_U4CON, b)
  1196  	case C_U4CON:
  1197  		return cmp(C_U3CON, b)
  1198  	case C_U3CON:
  1199  		return cmp(C_U2CON, b)
  1200  	case C_U2CON:
  1201  		return cmp(C_U1CON, b)
  1202  	case C_U1CON:
  1203  		return cmp(C_ZCON, b)
  1204  	case C_US12CON:
  1205  		return cmp(C_S12CON, b)
  1206  	case C_S12CON:
  1207  		return cmp(C_S5CON, b) || cmp(C_U8CON, b) || b == C_US12CON
  1208  	case C_S5CON:
  1209  		return cmp(C_ZCON, b) || cmp(C_U4CON, b)
  1210  
  1211  	case C_DCON12_20S:
  1212  		if b == C_DCON20S_20 || b == C_DCON12_12S ||
  1213  			b == C_DCON20S_12S || b == C_DCON12_12U ||
  1214  			b == C_DCON20S_12U || b == C_DCON20S_0 {
  1215  			return true
  1216  		}
  1217  
  1218  	case C_DCON32_12S:
  1219  		if b == C_DCON32_20 || b == C_DCON12_32S ||
  1220  			b == C_DCON20S_32 || b == C_DCON32_12U ||
  1221  			b == C_DCON32_0 {
  1222  			return true
  1223  		}
  1224  
  1225  	case C_LACON:
  1226  		return b == C_SACON
  1227  
  1228  	case C_LAUTO:
  1229  		return b == C_SAUTO
  1230  
  1231  	case C_REG:
  1232  		return b == C_ZCON
  1233  
  1234  	case C_LOREG:
  1235  		return b == C_ZOREG || b == C_SOREG
  1236  
  1237  	case C_SOREG:
  1238  		return b == C_ZOREG
  1239  	}
  1240  
  1241  	return false
  1242  }
  1243  
  1244  func ocmp(p1, p2 Optab) int {
  1245  	if p1.as != p2.as {
  1246  		return int(p1.as) - int(p2.as)
  1247  	}
  1248  	if p1.from1 != p2.from1 {
  1249  		return int(p1.from1) - int(p2.from1)
  1250  	}
  1251  	if p1.reg != p2.reg {
  1252  		return int(p1.reg) - int(p2.reg)
  1253  	}
  1254  	if p1.to1 != p2.to1 {
  1255  		return int(p1.to1) - int(p2.to1)
  1256  	}
  1257  	return 0
  1258  }
  1259  
  1260  func opset(a, b0 obj.As) {
  1261  	oprange[a&obj.AMask] = oprange[b0]
  1262  }
  1263  
  1264  func buildop(ctxt *obj.Link) {
  1265  	if ctxt.DiagFunc == nil {
  1266  		ctxt.DiagFunc = func(format string, args ...interface{}) {
  1267  			log.Printf(format, args...)
  1268  		}
  1269  	}
  1270  
  1271  	if oprange[AOR&obj.AMask] != nil {
  1272  		// Already initialized; stop now.
  1273  		// This happens in the cmd/asm tests,
  1274  		// each of which re-initializes the arch.
  1275  		return
  1276  	}
  1277  
  1278  	var n int
  1279  
  1280  	for i := 0; i < C_NCLASS; i++ {
  1281  		for n = 0; n < C_NCLASS; n++ {
  1282  			if cmp(n, i) {
  1283  				xcmp[i][n] = true
  1284  			}
  1285  		}
  1286  	}
  1287  	for n = 0; optab[n].as != obj.AXXX; n++ {
  1288  	}
  1289  	slices.SortFunc(optab[:n], ocmp)
  1290  	for i := 0; i < n; i++ {
  1291  		r := optab[i].as
  1292  		r0 := r & obj.AMask
  1293  		start := i
  1294  		for optab[i].as == r {
  1295  			i++
  1296  		}
  1297  		oprange[r0] = optab[start:i]
  1298  		i--
  1299  
  1300  		switch r {
  1301  		default:
  1302  			ctxt.Diag("unknown op in build: %v", r)
  1303  			ctxt.DiagFlush()
  1304  			log.Fatalf("bad code")
  1305  
  1306  		case AABSF:
  1307  			opset(AMOVFD, r0)
  1308  			opset(AMOVDF, r0)
  1309  			opset(AMOVWF, r0)
  1310  			opset(AMOVFW, r0)
  1311  			opset(AMOVWD, r0)
  1312  			opset(AMOVDW, r0)
  1313  			opset(ANEGF, r0)
  1314  			opset(ANEGD, r0)
  1315  			opset(AABSD, r0)
  1316  			opset(ATRUNCDW, r0)
  1317  			opset(ATRUNCFW, r0)
  1318  			opset(ASQRTF, r0)
  1319  			opset(ASQRTD, r0)
  1320  			opset(AFCLASSF, r0)
  1321  			opset(AFCLASSD, r0)
  1322  			opset(AFLOGBF, r0)
  1323  			opset(AFLOGBD, r0)
  1324  
  1325  		case AMOVVF:
  1326  			opset(AMOVVD, r0)
  1327  			opset(AMOVFV, r0)
  1328  			opset(AMOVDV, r0)
  1329  			opset(ATRUNCDV, r0)
  1330  			opset(ATRUNCFV, r0)
  1331  			opset(AFFINTFW, r0)
  1332  			opset(AFFINTFV, r0)
  1333  			opset(AFFINTDW, r0)
  1334  			opset(AFFINTDV, r0)
  1335  			opset(AFTINTWF, r0)
  1336  			opset(AFTINTWD, r0)
  1337  			opset(AFTINTVF, r0)
  1338  			opset(AFTINTVD, r0)
  1339  			opset(AFTINTRPWF, r0)
  1340  			opset(AFTINTRPWD, r0)
  1341  			opset(AFTINTRPVF, r0)
  1342  			opset(AFTINTRPVD, r0)
  1343  			opset(AFTINTRMWF, r0)
  1344  			opset(AFTINTRMWD, r0)
  1345  			opset(AFTINTRMVF, r0)
  1346  			opset(AFTINTRMVD, r0)
  1347  			opset(AFTINTRZWF, r0)
  1348  			opset(AFTINTRZWD, r0)
  1349  			opset(AFTINTRZVF, r0)
  1350  			opset(AFTINTRZVD, r0)
  1351  			opset(AFTINTRNEWF, r0)
  1352  			opset(AFTINTRNEWD, r0)
  1353  			opset(AFTINTRNEVF, r0)
  1354  			opset(AFTINTRNEVD, r0)
  1355  
  1356  		case AADD:
  1357  			opset(ASGT, r0)
  1358  			opset(ASGTU, r0)
  1359  			opset(AADDU, r0)
  1360  
  1361  		case AADDV:
  1362  			opset(AADDVU, r0)
  1363  
  1364  		case AADDF:
  1365  			opset(ADIVF, r0)
  1366  			opset(ADIVD, r0)
  1367  			opset(AMULF, r0)
  1368  			opset(AMULD, r0)
  1369  			opset(ASUBF, r0)
  1370  			opset(ASUBD, r0)
  1371  			opset(AADDD, r0)
  1372  			opset(AFMINF, r0)
  1373  			opset(AFMIND, r0)
  1374  			opset(AFMAXF, r0)
  1375  			opset(AFMAXD, r0)
  1376  			opset(AFCOPYSGF, r0)
  1377  			opset(AFCOPYSGD, r0)
  1378  			opset(AFSCALEBF, r0)
  1379  			opset(AFSCALEBD, r0)
  1380  			opset(AFMAXAF, r0)
  1381  			opset(AFMAXAD, r0)
  1382  			opset(AFMINAF, r0)
  1383  			opset(AFMINAD, r0)
  1384  
  1385  		case AFMADDF:
  1386  			opset(AFMADDD, r0)
  1387  			opset(AFMSUBF, r0)
  1388  			opset(AFMSUBD, r0)
  1389  			opset(AFNMADDF, r0)
  1390  			opset(AFNMADDD, r0)
  1391  			opset(AFNMSUBF, r0)
  1392  			opset(AFNMSUBD, r0)
  1393  
  1394  		case AAND:
  1395  			opset(AOR, r0)
  1396  			opset(AXOR, r0)
  1397  			opset(AORN, r0)
  1398  			opset(AANDN, r0)
  1399  
  1400  		case ABEQ:
  1401  			opset(ABNE, r0)
  1402  			opset(ABLT, r0)
  1403  			opset(ABGE, r0)
  1404  			opset(ABGEU, r0)
  1405  			opset(ABLTU, r0)
  1406  
  1407  		case ABLEZ:
  1408  			opset(ABGEZ, r0)
  1409  			opset(ABLTZ, r0)
  1410  			opset(ABGTZ, r0)
  1411  
  1412  		case AMOVB:
  1413  			opset(AMOVH, r0)
  1414  
  1415  		case AMOVBU:
  1416  			opset(AMOVHU, r0)
  1417  
  1418  		case AMUL:
  1419  			opset(AMULU, r0)
  1420  			opset(AMULH, r0)
  1421  			opset(AMULHU, r0)
  1422  			opset(AREM, r0)
  1423  			opset(AREMU, r0)
  1424  			opset(ADIV, r0)
  1425  			opset(ADIVU, r0)
  1426  
  1427  		case AMULV:
  1428  			opset(AMULVU, r0)
  1429  			opset(AMULHV, r0)
  1430  			opset(AMULHVU, r0)
  1431  			opset(AREMV, r0)
  1432  			opset(AREMVU, r0)
  1433  			opset(ADIVV, r0)
  1434  			opset(ADIVVU, r0)
  1435  
  1436  		case ASLL:
  1437  			opset(ASRL, r0)
  1438  			opset(ASRA, r0)
  1439  			opset(AROTR, r0)
  1440  
  1441  		case ASLLV:
  1442  			opset(ASRAV, r0)
  1443  			opset(ASRLV, r0)
  1444  			opset(AROTRV, r0)
  1445  
  1446  		case ABSTRPICKW:
  1447  			opset(ABSTRPICKV, r0)
  1448  			opset(ABSTRINSW, r0)
  1449  			opset(ABSTRINSV, r0)
  1450  
  1451  		case ASUB:
  1452  			opset(ASUBU, r0)
  1453  			opset(ANOR, r0)
  1454  
  1455  		case ASUBV:
  1456  			opset(ASUBVU, r0)
  1457  
  1458  		case ASYSCALL:
  1459  			opset(ADBAR, r0)
  1460  			opset(ABREAK, r0)
  1461  
  1462  		case ACMPEQF:
  1463  			opset(ACMPGTF, r0)
  1464  			opset(ACMPGTD, r0)
  1465  			opset(ACMPGEF, r0)
  1466  			opset(ACMPGED, r0)
  1467  			opset(ACMPEQD, r0)
  1468  
  1469  		case ABFPT:
  1470  			opset(ABFPF, r0)
  1471  
  1472  		case AMOVW,
  1473  			AMOVD,
  1474  			AMOVF,
  1475  			AMOVV,
  1476  			ARFE,
  1477  			AJAL,
  1478  			AJMP,
  1479  			AMOVWU,
  1480  			AVMOVQ,
  1481  			AXVMOVQ,
  1482  			ALL,
  1483  			ALLV,
  1484  			ASC,
  1485  			ASCV,
  1486  			ANEGW,
  1487  			ANEGV,
  1488  			AWORD,
  1489  			obj.ANOP,
  1490  			obj.ATEXT,
  1491  			obj.AFUNCDATA,
  1492  			obj.APCALIGN,
  1493  			obj.APCDATA,
  1494  			obj.ADUFFZERO,
  1495  			obj.ADUFFCOPY:
  1496  			break
  1497  
  1498  		case ARDTIMELW:
  1499  			opset(ARDTIMEHW, r0)
  1500  			opset(ARDTIMED, r0)
  1501  
  1502  		case ACLOW:
  1503  			opset(ACLZW, r0)
  1504  			opset(ACTOW, r0)
  1505  			opset(ACTZW, r0)
  1506  			opset(ACLOV, r0)
  1507  			opset(ACLZV, r0)
  1508  			opset(ACTOV, r0)
  1509  			opset(ACTZV, r0)
  1510  			opset(AREVB2H, r0)
  1511  			opset(AREVB4H, r0)
  1512  			opset(AREVB2W, r0)
  1513  			opset(AREVBV, r0)
  1514  			opset(AREVH2W, r0)
  1515  			opset(AREVHV, r0)
  1516  			opset(ABITREV4B, r0)
  1517  			opset(ABITREV8B, r0)
  1518  			opset(ABITREVW, r0)
  1519  			opset(ABITREVV, r0)
  1520  			opset(AEXTWB, r0)
  1521  			opset(AEXTWH, r0)
  1522  			opset(ACPUCFG, r0)
  1523  
  1524  		case ATEQ:
  1525  			opset(ATNE, r0)
  1526  
  1527  		case AMASKEQZ:
  1528  			opset(AMASKNEZ, r0)
  1529  			opset(ACRCWBW, r0)
  1530  			opset(ACRCWHW, r0)
  1531  			opset(ACRCWWW, r0)
  1532  			opset(ACRCWVW, r0)
  1533  			opset(ACRCCWBW, r0)
  1534  			opset(ACRCCWHW, r0)
  1535  			opset(ACRCCWWW, r0)
  1536  			opset(ACRCCWVW, r0)
  1537  
  1538  		case ANOOP:
  1539  			opset(obj.AUNDEF, r0)
  1540  
  1541  		case AAMSWAPW:
  1542  			for i := range atomicInst {
  1543  				if i == AAMSWAPW {
  1544  					continue
  1545  				}
  1546  				opset(i, r0)
  1547  			}
  1548  
  1549  		case AVSEQB:
  1550  			opset(AVSEQH, r0)
  1551  			opset(AVSEQW, r0)
  1552  			opset(AVSEQV, r0)
  1553  			opset(AVILVLB, r0)
  1554  			opset(AVILVLH, r0)
  1555  			opset(AVILVLW, r0)
  1556  			opset(AVILVLV, r0)
  1557  			opset(AVILVHB, r0)
  1558  			opset(AVILVHH, r0)
  1559  			opset(AVILVHW, r0)
  1560  			opset(AVILVHV, r0)
  1561  			opset(AVMULB, r0)
  1562  			opset(AVMULH, r0)
  1563  			opset(AVMULW, r0)
  1564  			opset(AVMULV, r0)
  1565  			opset(AVMUHB, r0)
  1566  			opset(AVMUHH, r0)
  1567  			opset(AVMUHW, r0)
  1568  			opset(AVMUHV, r0)
  1569  			opset(AVMUHBU, r0)
  1570  			opset(AVMUHHU, r0)
  1571  			opset(AVMUHWU, r0)
  1572  			opset(AVMUHVU, r0)
  1573  			opset(AVDIVB, r0)
  1574  			opset(AVDIVH, r0)
  1575  			opset(AVDIVW, r0)
  1576  			opset(AVDIVV, r0)
  1577  			opset(AVMODB, r0)
  1578  			opset(AVMODH, r0)
  1579  			opset(AVMODW, r0)
  1580  			opset(AVMODV, r0)
  1581  			opset(AVDIVBU, r0)
  1582  			opset(AVDIVHU, r0)
  1583  			opset(AVDIVWU, r0)
  1584  			opset(AVDIVVU, r0)
  1585  			opset(AVMODBU, r0)
  1586  			opset(AVMODHU, r0)
  1587  			opset(AVMODWU, r0)
  1588  			opset(AVMODVU, r0)
  1589  			opset(AVMULWEVHB, r0)
  1590  			opset(AVMULWEVWH, r0)
  1591  			opset(AVMULWEVVW, r0)
  1592  			opset(AVMULWEVQV, r0)
  1593  			opset(AVMULWODHB, r0)
  1594  			opset(AVMULWODWH, r0)
  1595  			opset(AVMULWODVW, r0)
  1596  			opset(AVMULWODQV, r0)
  1597  			opset(AVMULWEVHBU, r0)
  1598  			opset(AVMULWEVWHU, r0)
  1599  			opset(AVMULWEVVWU, r0)
  1600  			opset(AVMULWEVQVU, r0)
  1601  			opset(AVMULWODHBU, r0)
  1602  			opset(AVMULWODWHU, r0)
  1603  			opset(AVMULWODVWU, r0)
  1604  			opset(AVMULWODQVU, r0)
  1605  			opset(AVMULWEVHBUB, r0)
  1606  			opset(AVMULWEVWHUH, r0)
  1607  			opset(AVMULWEVVWUW, r0)
  1608  			opset(AVMULWEVQVUV, r0)
  1609  			opset(AVMULWODHBUB, r0)
  1610  			opset(AVMULWODWHUH, r0)
  1611  			opset(AVMULWODVWUW, r0)
  1612  			opset(AVMULWODQVUV, r0)
  1613  
  1614  		case AXVSEQB:
  1615  			opset(AXVSEQH, r0)
  1616  			opset(AXVSEQW, r0)
  1617  			opset(AXVSEQV, r0)
  1618  			opset(AXVILVLB, r0)
  1619  			opset(AXVILVLH, r0)
  1620  			opset(AXVILVLW, r0)
  1621  			opset(AXVILVLV, r0)
  1622  			opset(AXVILVHB, r0)
  1623  			opset(AXVILVHH, r0)
  1624  			opset(AXVILVHW, r0)
  1625  			opset(AXVILVHV, r0)
  1626  			opset(AXVMULB, r0)
  1627  			opset(AXVMULH, r0)
  1628  			opset(AXVMULW, r0)
  1629  			opset(AXVMULV, r0)
  1630  			opset(AXVMUHB, r0)
  1631  			opset(AXVMUHH, r0)
  1632  			opset(AXVMUHW, r0)
  1633  			opset(AXVMUHV, r0)
  1634  			opset(AXVMUHBU, r0)
  1635  			opset(AXVMUHHU, r0)
  1636  			opset(AXVMUHWU, r0)
  1637  			opset(AXVMUHVU, r0)
  1638  			opset(AXVDIVB, r0)
  1639  			opset(AXVDIVH, r0)
  1640  			opset(AXVDIVW, r0)
  1641  			opset(AXVDIVV, r0)
  1642  			opset(AXVMODB, r0)
  1643  			opset(AXVMODH, r0)
  1644  			opset(AXVMODW, r0)
  1645  			opset(AXVMODV, r0)
  1646  			opset(AXVDIVBU, r0)
  1647  			opset(AXVDIVHU, r0)
  1648  			opset(AXVDIVWU, r0)
  1649  			opset(AXVDIVVU, r0)
  1650  			opset(AXVMODBU, r0)
  1651  			opset(AXVMODHU, r0)
  1652  			opset(AXVMODWU, r0)
  1653  			opset(AXVMODVU, r0)
  1654  			opset(AXVMULWEVHB, r0)
  1655  			opset(AXVMULWEVWH, r0)
  1656  			opset(AXVMULWEVVW, r0)
  1657  			opset(AXVMULWEVQV, r0)
  1658  			opset(AXVMULWODHB, r0)
  1659  			opset(AXVMULWODWH, r0)
  1660  			opset(AXVMULWODVW, r0)
  1661  			opset(AXVMULWODQV, r0)
  1662  			opset(AXVMULWEVHBU, r0)
  1663  			opset(AXVMULWEVWHU, r0)
  1664  			opset(AXVMULWEVVWU, r0)
  1665  			opset(AXVMULWEVQVU, r0)
  1666  			opset(AXVMULWODHBU, r0)
  1667  			opset(AXVMULWODWHU, r0)
  1668  			opset(AXVMULWODVWU, r0)
  1669  			opset(AXVMULWODQVU, r0)
  1670  			opset(AXVMULWEVHBUB, r0)
  1671  			opset(AXVMULWEVWHUH, r0)
  1672  			opset(AXVMULWEVVWUW, r0)
  1673  			opset(AXVMULWEVQVUV, r0)
  1674  			opset(AXVMULWODHBUB, r0)
  1675  			opset(AXVMULWODWHUH, r0)
  1676  			opset(AXVMULWODVWUW, r0)
  1677  			opset(AXVMULWODQVUV, r0)
  1678  
  1679  		case AVANDB:
  1680  			opset(AVORB, r0)
  1681  			opset(AVXORB, r0)
  1682  			opset(AVNORB, r0)
  1683  			opset(AVSHUF4IB, r0)
  1684  			opset(AVSHUF4IH, r0)
  1685  			opset(AVSHUF4IW, r0)
  1686  			opset(AVSHUF4IV, r0)
  1687  
  1688  		case AXVANDB:
  1689  			opset(AXVORB, r0)
  1690  			opset(AXVXORB, r0)
  1691  			opset(AXVNORB, r0)
  1692  			opset(AXVSHUF4IB, r0)
  1693  			opset(AXVSHUF4IH, r0)
  1694  			opset(AXVSHUF4IW, r0)
  1695  			opset(AXVSHUF4IV, r0)
  1696  
  1697  		case AVANDV:
  1698  			opset(AVORV, r0)
  1699  			opset(AVXORV, r0)
  1700  			opset(AVNORV, r0)
  1701  			opset(AVANDNV, r0)
  1702  			opset(AVORNV, r0)
  1703  
  1704  		case AXVANDV:
  1705  			opset(AXVORV, r0)
  1706  			opset(AXVXORV, r0)
  1707  			opset(AXVNORV, r0)
  1708  			opset(AXVANDNV, r0)
  1709  			opset(AXVORNV, r0)
  1710  
  1711  		case AVPCNTB:
  1712  			opset(AVPCNTH, r0)
  1713  			opset(AVPCNTW, r0)
  1714  			opset(AVPCNTV, r0)
  1715  			opset(AVFSQRTF, r0)
  1716  			opset(AVFSQRTD, r0)
  1717  			opset(AVFRECIPF, r0)
  1718  			opset(AVFRECIPD, r0)
  1719  			opset(AVFRSQRTF, r0)
  1720  			opset(AVFRSQRTD, r0)
  1721  			opset(AVNEGB, r0)
  1722  			opset(AVNEGH, r0)
  1723  			opset(AVNEGW, r0)
  1724  			opset(AVNEGV, r0)
  1725  
  1726  		case AXVPCNTB:
  1727  			opset(AXVPCNTH, r0)
  1728  			opset(AXVPCNTW, r0)
  1729  			opset(AXVPCNTV, r0)
  1730  			opset(AXVFSQRTF, r0)
  1731  			opset(AXVFSQRTD, r0)
  1732  			opset(AXVFRECIPF, r0)
  1733  			opset(AXVFRECIPD, r0)
  1734  			opset(AXVFRSQRTF, r0)
  1735  			opset(AXVFRSQRTD, r0)
  1736  			opset(AXVNEGB, r0)
  1737  			opset(AXVNEGH, r0)
  1738  			opset(AXVNEGW, r0)
  1739  			opset(AXVNEGV, r0)
  1740  
  1741  		case AVADDB:
  1742  			opset(AVADDH, r0)
  1743  			opset(AVADDW, r0)
  1744  			opset(AVADDV, r0)
  1745  			opset(AVADDQ, r0)
  1746  			opset(AVSUBB, r0)
  1747  			opset(AVSUBH, r0)
  1748  			opset(AVSUBW, r0)
  1749  			opset(AVSUBV, r0)
  1750  			opset(AVSUBQ, r0)
  1751  
  1752  		case AXVADDB:
  1753  			opset(AXVADDH, r0)
  1754  			opset(AXVADDW, r0)
  1755  			opset(AXVADDV, r0)
  1756  			opset(AXVADDQ, r0)
  1757  			opset(AXVSUBB, r0)
  1758  			opset(AXVSUBH, r0)
  1759  			opset(AXVSUBW, r0)
  1760  			opset(AXVSUBV, r0)
  1761  			opset(AXVSUBQ, r0)
  1762  
  1763  		case AVSLLB:
  1764  			opset(AVSRLB, r0)
  1765  			opset(AVSRAB, r0)
  1766  			opset(AVROTRB, r0)
  1767  
  1768  		case AXVSLLB:
  1769  			opset(AXVSRLB, r0)
  1770  			opset(AXVSRAB, r0)
  1771  			opset(AXVROTRB, r0)
  1772  
  1773  		case AVSLLH:
  1774  			opset(AVSRLH, r0)
  1775  			opset(AVSRAH, r0)
  1776  			opset(AVROTRH, r0)
  1777  
  1778  		case AXVSLLH:
  1779  			opset(AXVSRLH, r0)
  1780  			opset(AXVSRAH, r0)
  1781  			opset(AXVROTRH, r0)
  1782  
  1783  		case AVSLLW:
  1784  			opset(AVSRLW, r0)
  1785  			opset(AVSRAW, r0)
  1786  			opset(AVROTRW, r0)
  1787  			opset(AVADDBU, r0)
  1788  			opset(AVADDHU, r0)
  1789  			opset(AVADDWU, r0)
  1790  			opset(AVADDVU, r0)
  1791  			opset(AVSUBBU, r0)
  1792  			opset(AVSUBHU, r0)
  1793  			opset(AVSUBWU, r0)
  1794  			opset(AVSUBVU, r0)
  1795  
  1796  		case AXVSLLW:
  1797  			opset(AXVSRLW, r0)
  1798  			opset(AXVSRAW, r0)
  1799  			opset(AXVROTRW, r0)
  1800  			opset(AXVADDBU, r0)
  1801  			opset(AXVADDHU, r0)
  1802  			opset(AXVADDWU, r0)
  1803  			opset(AXVADDVU, r0)
  1804  			opset(AXVSUBBU, r0)
  1805  			opset(AXVSUBHU, r0)
  1806  			opset(AXVSUBWU, r0)
  1807  			opset(AXVSUBVU, r0)
  1808  
  1809  		case AVSLLV:
  1810  			opset(AVSRLV, r0)
  1811  			opset(AVSRAV, r0)
  1812  			opset(AVROTRV, r0)
  1813  
  1814  		case AXVSLLV:
  1815  			opset(AXVSRLV, r0)
  1816  			opset(AXVSRAV, r0)
  1817  			opset(AXVROTRV, r0)
  1818  
  1819  		case AVSETEQV:
  1820  			opset(AVSETNEV, r0)
  1821  			opset(AVSETANYEQB, r0)
  1822  			opset(AVSETANYEQH, r0)
  1823  			opset(AVSETANYEQW, r0)
  1824  			opset(AVSETANYEQV, r0)
  1825  			opset(AVSETALLNEB, r0)
  1826  			opset(AVSETALLNEH, r0)
  1827  			opset(AVSETALLNEW, r0)
  1828  			opset(AVSETALLNEV, r0)
  1829  
  1830  		case AXVSETEQV:
  1831  			opset(AXVSETNEV, r0)
  1832  			opset(AXVSETANYEQB, r0)
  1833  			opset(AXVSETANYEQH, r0)
  1834  			opset(AXVSETANYEQW, r0)
  1835  			opset(AXVSETANYEQV, r0)
  1836  			opset(AXVSETALLNEB, r0)
  1837  			opset(AXVSETALLNEH, r0)
  1838  			opset(AXVSETALLNEW, r0)
  1839  			opset(AXVSETALLNEV, r0)
  1840  
  1841  		}
  1842  	}
  1843  }
  1844  
  1845  func OP_RRRR(op uint32, r1 uint32, r2 uint32, r3 uint32, r4 uint32) uint32 {
  1846  	return op | (r1&0x1F)<<15 | (r2&0x1F)<<10 | (r3&0x1F)<<5 | (r4 & 0x1F)
  1847  }
  1848  
  1849  // r1 -> rk
  1850  // r2 -> rj
  1851  // r3 -> rd
  1852  func OP_RRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 {
  1853  	return op | (r1&0x1F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1854  }
  1855  
  1856  // r2 -> rj
  1857  // r3 -> rd
  1858  func OP_RR(op uint32, r2 uint32, r3 uint32) uint32 {
  1859  	return op | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1860  }
  1861  
  1862  func OP_16IR_5I(op uint32, i uint32, r2 uint32) uint32 {
  1863  	return op | (i&0xFFFF)<<10 | (r2&0x1F)<<5 | ((i >> 16) & 0x1F)
  1864  }
  1865  
  1866  func OP_16IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  1867  	return op | (i&0xFFFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1868  }
  1869  
  1870  func OP_12IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  1871  	return op | (i&0xFFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1872  }
  1873  
  1874  func OP_8IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  1875  	return op | (i&0xFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1876  }
  1877  
  1878  func OP_6IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  1879  	return op | (i&0x3F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1880  }
  1881  
  1882  func OP_5IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  1883  	return op | (i&0x1F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1884  }
  1885  
  1886  func OP_4IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  1887  	return op | (i&0xF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1888  }
  1889  
  1890  func OP_3IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  1891  	return op | (i&0x7)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  1892  }
  1893  
  1894  func OP_IR(op uint32, i uint32, r2 uint32) uint32 {
  1895  	return op | (i&0xFFFFF)<<5 | (r2&0x1F)<<0 // ui20, rd5
  1896  }
  1897  
  1898  func OP_15I(op uint32, i uint32) uint32 {
  1899  	return op | (i&0x7FFF)<<0
  1900  }
  1901  
  1902  // i1 -> msb
  1903  // r2 -> rj
  1904  // i3 -> lsb
  1905  // r4 -> rd
  1906  func OP_IRIR(op uint32, i1 uint32, r2 uint32, i3 uint32, r4 uint32) uint32 {
  1907  	return op | (i1 << 16) | (r2&0x1F)<<5 | (i3 << 10) | (r4&0x1F)<<0
  1908  }
  1909  
  1910  // Encoding for the 'b' or 'bl' instruction.
  1911  func OP_B_BL(op uint32, i uint32) uint32 {
  1912  	return op | ((i & 0xFFFF) << 10) | ((i >> 16) & 0x3FF)
  1913  }
  1914  
  1915  func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
  1916  	o1 := uint32(0)
  1917  	o2 := uint32(0)
  1918  	o3 := uint32(0)
  1919  	o4 := uint32(0)
  1920  	o5 := uint32(0)
  1921  
  1922  	add := AADDU
  1923  	add = AADDVU
  1924  
  1925  	switch o.type_ {
  1926  	default:
  1927  		c.ctxt.Diag("unknown type %d %v", o.type_)
  1928  		prasm(p)
  1929  
  1930  	case 0: // pseudo ops
  1931  		break
  1932  
  1933  	case 1: // mov r1,r2 ==> OR r1,r0,r2
  1934  		a := AOR
  1935  		if p.As == AMOVW {
  1936  			a = ASLL
  1937  		}
  1938  		o1 = OP_RRR(c.oprrr(a), uint32(REGZERO), uint32(p.From.Reg), uint32(p.To.Reg))
  1939  
  1940  	case 2: // add/sub r1,[r2],r3
  1941  		r := int(p.Reg)
  1942  		if p.As == ANEGW || p.As == ANEGV {
  1943  			r = REGZERO
  1944  		}
  1945  		if r == 0 {
  1946  			r = int(p.To.Reg)
  1947  		}
  1948  		o1 = OP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
  1949  
  1950  	case 3: // mov $soreg, r ==> or/add $i,o,r
  1951  		v := c.regoff(&p.From)
  1952  
  1953  		r := int(p.From.Reg)
  1954  		if r == 0 {
  1955  			r = int(o.param)
  1956  		}
  1957  		a := add
  1958  		if o.from1 == C_12CON && v > 0 {
  1959  			a = AOR
  1960  		}
  1961  
  1962  		o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(r), uint32(p.To.Reg))
  1963  
  1964  	case 4: // add $scon,[r1],r2
  1965  		v := c.regoff(&p.From)
  1966  		r := int(p.Reg)
  1967  		if r == 0 {
  1968  			r = int(p.To.Reg)
  1969  		}
  1970  		o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  1971  
  1972  	case 5: // syscall
  1973  		v := c.regoff(&p.From)
  1974  		o1 = OP_15I(c.opi(p.As), uint32(v))
  1975  
  1976  	case 6: // beq r1,[r2],sbra
  1977  		v := int32(0)
  1978  		if p.To.Target() != nil {
  1979  			v = int32(p.To.Target().Pc-p.Pc) >> 2
  1980  		}
  1981  		as, rd, rj, width := p.As, p.Reg, p.From.Reg, 16
  1982  		switch as {
  1983  		case ABGTZ, ABLEZ:
  1984  			rd, rj = rj, rd
  1985  		case ABFPT, ABFPF:
  1986  			width = 21
  1987  			// FCC0 is the implicit source operand, now that we
  1988  			// don't register-allocate from the FCC bank.
  1989  			if rj == 0 {
  1990  				rj = REG_FCC0
  1991  			}
  1992  		case ABEQ, ABNE:
  1993  			if rd == 0 || rd == REGZERO || rj == REGZERO {
  1994  				// BEQZ/BNEZ can be encoded with 21-bit offsets.
  1995  				width = 21
  1996  				as = -as
  1997  				if rj == 0 || rj == REGZERO {
  1998  					rj = rd
  1999  				}
  2000  			}
  2001  		}
  2002  		switch width {
  2003  		case 21:
  2004  			if (v<<11)>>11 != v {
  2005  				c.ctxt.Diag("21 bit-width, short branch too far\n%v", p)
  2006  			}
  2007  			o1 = OP_16IR_5I(c.opirr(as), uint32(v), uint32(rj))
  2008  		case 16:
  2009  			if (v<<16)>>16 != v {
  2010  				c.ctxt.Diag("16 bit-width, short branch too far\n%v", p)
  2011  			}
  2012  			o1 = OP_16IRR(c.opirr(as), uint32(v), uint32(rj), uint32(rd))
  2013  		default:
  2014  			c.ctxt.Diag("unexpected branch encoding\n%v", p)
  2015  		}
  2016  
  2017  	case 7: // mov r, soreg
  2018  		r := int(p.To.Reg)
  2019  		if r == 0 {
  2020  			r = int(o.param)
  2021  		}
  2022  		v := c.regoff(&p.To)
  2023  		o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.From.Reg))
  2024  
  2025  	case 8: // mov soreg, r
  2026  		r := int(p.From.Reg)
  2027  		if r == 0 {
  2028  			r = int(o.param)
  2029  		}
  2030  		v := c.regoff(&p.From)
  2031  		o1 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2032  
  2033  	case 9: // sll r1,[r2],r3
  2034  		o1 = OP_RR(c.oprr(p.As), uint32(p.From.Reg), uint32(p.To.Reg))
  2035  
  2036  	case 10: // add $con,[r1],r2 ==> mov $con, t; add t,[r1],r2
  2037  		v := c.regoff(&p.From)
  2038  		a := AOR
  2039  		if v < 0 {
  2040  			a = AADDU
  2041  		}
  2042  		o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
  2043  		r := int(p.Reg)
  2044  		if r == 0 {
  2045  			r = int(p.To.Reg)
  2046  		}
  2047  		o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2048  
  2049  	case 11: // jmp lbra
  2050  		v := int32(0)
  2051  		if p.To.Target() != nil {
  2052  			v = int32(p.To.Target().Pc-p.Pc) >> 2
  2053  		}
  2054  		o1 = OP_B_BL(c.opirr(p.As), uint32(v))
  2055  		if p.To.Sym != nil {
  2056  			c.cursym.AddRel(c.ctxt, obj.Reloc{
  2057  				Type: objabi.R_CALLLOONG64,
  2058  				Off:  int32(c.pc),
  2059  				Siz:  4,
  2060  				Sym:  p.To.Sym,
  2061  				Add:  p.To.Offset,
  2062  			})
  2063  		}
  2064  
  2065  	case 12: // movbs r,r
  2066  		switch p.As {
  2067  		case AMOVB:
  2068  			o1 = OP_RR(c.oprr(AEXTWB), uint32(p.From.Reg), uint32(p.To.Reg))
  2069  		case AMOVH:
  2070  			o1 = OP_RR(c.oprr(AEXTWH), uint32(p.From.Reg), uint32(p.To.Reg))
  2071  		case AMOVBU:
  2072  			o1 = OP_12IRR(c.opirr(AAND), uint32(0xff), uint32(p.From.Reg), uint32(p.To.Reg))
  2073  		case AMOVHU:
  2074  			o1 = OP_IRIR(c.opirir(ABSTRPICKV), 15, uint32(p.From.Reg), 0, uint32(p.To.Reg))
  2075  		case AMOVWU:
  2076  			o1 = OP_IRIR(c.opirir(ABSTRPICKV), 31, uint32(p.From.Reg), 0, uint32(p.To.Reg))
  2077  		default:
  2078  			c.ctxt.Diag("unexpected encoding\n%v", p)
  2079  		}
  2080  
  2081  	case 13: // vsll $ui3, [vr1], vr2
  2082  		v := c.regoff(&p.From)
  2083  		r := int(p.Reg)
  2084  		if r == 0 {
  2085  			r = int(p.To.Reg)
  2086  		}
  2087  		o1 = OP_3IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2088  
  2089  	case 14: // vsll $ui4, [vr1], vr2
  2090  		v := c.regoff(&p.From)
  2091  		r := int(p.Reg)
  2092  		if r == 0 {
  2093  			r = int(p.To.Reg)
  2094  		}
  2095  		o1 = OP_4IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2096  
  2097  	case 15: // teq $c r,r
  2098  		v := c.regoff(&p.From)
  2099  		r := int(p.Reg)
  2100  		if r == 0 {
  2101  			r = REGZERO
  2102  		}
  2103  		/*
  2104  			teq c, r1, r2
  2105  			fallthrough
  2106  			==>
  2107  			bne r1, r2, 2
  2108  			break c
  2109  			fallthrough
  2110  		*/
  2111  		if p.As == ATEQ {
  2112  			o1 = OP_16IRR(c.opirr(ABNE), uint32(2), uint32(r), uint32(p.To.Reg))
  2113  		} else { // ATNE
  2114  			o1 = OP_16IRR(c.opirr(ABEQ), uint32(2), uint32(r), uint32(p.To.Reg))
  2115  		}
  2116  		o2 = OP_15I(c.opi(ABREAK), uint32(v))
  2117  
  2118  	case 16: // sll $c,[r1],r2
  2119  		v := c.regoff(&p.From)
  2120  		r := int(p.Reg)
  2121  		if r == 0 {
  2122  			r = int(p.To.Reg)
  2123  		}
  2124  
  2125  		// instruction ending with V:6-digit immediate, others:5-digit immediate
  2126  		if v >= 32 && vshift(p.As) {
  2127  			o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x3f, uint32(r), uint32(p.To.Reg))
  2128  		} else {
  2129  			o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x1f, uint32(r), uint32(p.To.Reg))
  2130  		}
  2131  
  2132  	case 17: // bstrpickw $msbw, r1, $lsbw, r2
  2133  		rd, rj := p.To.Reg, p.Reg
  2134  		if rj == obj.REG_NONE {
  2135  			rj = rd
  2136  		}
  2137  		msb, lsb := p.From.Offset, p.GetFrom3().Offset
  2138  
  2139  		// check the range of msb and lsb
  2140  		var b uint32
  2141  		if p.As == ABSTRPICKW || p.As == ABSTRINSW {
  2142  			b = 32
  2143  		} else {
  2144  			b = 64
  2145  		}
  2146  		if lsb < 0 || uint32(lsb) >= b || msb < 0 || uint32(msb) >= b || uint32(lsb) > uint32(msb) {
  2147  			c.ctxt.Diag("illegal bit number\n%v", p)
  2148  		}
  2149  
  2150  		o1 = OP_IRIR(c.opirir(p.As), uint32(msb), uint32(rj), uint32(lsb), uint32(rd))
  2151  
  2152  	case 18: // jmp [r1],0(r2)
  2153  		r := int(p.Reg)
  2154  		if r == 0 {
  2155  			r = int(o.param)
  2156  		}
  2157  		o1 = OP_RRR(c.oprrr(p.As), uint32(0), uint32(p.To.Reg), uint32(r))
  2158  		if p.As == obj.ACALL {
  2159  			c.cursym.AddRel(c.ctxt, obj.Reloc{
  2160  				Type: objabi.R_CALLIND,
  2161  				Off:  int32(c.pc),
  2162  			})
  2163  		}
  2164  
  2165  	case 19: // mov $lcon,r
  2166  		// NOTE: this case does not use REGTMP. If it ever does,
  2167  		// remove the NOTUSETMP flag in optab.
  2168  		v := c.regoff(&p.From)
  2169  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2170  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  2171  
  2172  	case 20: // mov Rsrc, (Rbase)(Roff)
  2173  		o1 = OP_RRR(c.oprrr(p.As), uint32(p.To.Index), uint32(p.To.Reg), uint32(p.From.Reg))
  2174  
  2175  	case 21: // mov (Rbase)(Roff), Rdst
  2176  		o1 = OP_RRR(c.oprrr(-p.As), uint32(p.From.Index), uint32(p.From.Reg), uint32(p.To.Reg))
  2177  
  2178  	case 22: // add $si5,[r1],r2
  2179  		v := c.regoff(&p.From)
  2180  		r := int(p.Reg)
  2181  		if r == 0 {
  2182  			r = int(p.To.Reg)
  2183  		}
  2184  
  2185  		o1 = OP_5IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2186  
  2187  	case 23: // add $ui8,[r1],r2
  2188  		v := c.regoff(&p.From)
  2189  		r := int(p.Reg)
  2190  		if r == 0 {
  2191  			r = int(p.To.Reg)
  2192  		}
  2193  
  2194  		// the operand range available for instructions VSHUF4IV and XVSHUF4IV is [0, 15]
  2195  		if p.As == AVSHUF4IV || p.As == AXVSHUF4IV {
  2196  			operand := uint32(v)
  2197  			c.checkoperand(p, operand, 15)
  2198  		}
  2199  
  2200  		o1 = OP_8IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2201  
  2202  	case 24: // add $lcon,r1,r2
  2203  		v := c.regoff(&p.From)
  2204  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2205  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  2206  		r := int(p.Reg)
  2207  		if r == 0 {
  2208  			r = int(p.To.Reg)
  2209  		}
  2210  		o3 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2211  
  2212  	case 25: // mov $ucon,r
  2213  		v := c.regoff(&p.From)
  2214  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2215  
  2216  	case 26: // add/and $ucon,[r1],r2
  2217  		v := c.regoff(&p.From)
  2218  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2219  		r := int(p.Reg)
  2220  		if r == 0 {
  2221  			r = int(p.To.Reg)
  2222  		}
  2223  		o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2224  
  2225  	case 27: // mov $lsext/auto/oreg,r
  2226  		v := c.regoff(&p.From)
  2227  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2228  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  2229  		r := int(p.From.Reg)
  2230  		if r == 0 {
  2231  			r = int(o.param)
  2232  		}
  2233  		o3 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2234  
  2235  	case 28: // mov [sl]ext/auto/oreg,fr
  2236  		v := c.regoff(&p.From)
  2237  		r := int(p.From.Reg)
  2238  		if r == 0 {
  2239  			r = int(o.param)
  2240  		}
  2241  		switch o.size {
  2242  		case 12:
  2243  			o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  2244  			o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  2245  			o3 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
  2246  
  2247  		case 4:
  2248  			o1 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2249  		}
  2250  
  2251  	case 29: // mov fr,[sl]ext/auto/oreg
  2252  		v := c.regoff(&p.To)
  2253  		r := int(p.To.Reg)
  2254  		if r == 0 {
  2255  			r = int(o.param)
  2256  		}
  2257  		switch o.size {
  2258  		case 12:
  2259  			o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  2260  			o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  2261  			o3 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
  2262  
  2263  		case 4:
  2264  			o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.From.Reg))
  2265  		}
  2266  
  2267  	case 30: // mov gr/fr/fcc/fcsr, fr/fcc/fcsr/gr
  2268  		a := c.specialFpMovInst(p.As, oclass(&p.From), oclass(&p.To))
  2269  		o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
  2270  
  2271  	case 31: // vsll $ui5, [vr1], vr2
  2272  		v := c.regoff(&p.From)
  2273  		r := int(p.Reg)
  2274  		if r == 0 {
  2275  			r = int(p.To.Reg)
  2276  		}
  2277  		o1 = OP_5IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2278  
  2279  	case 32: // vsll $ui6, [vr1], vr2
  2280  		v := c.regoff(&p.From)
  2281  		r := int(p.Reg)
  2282  		if r == 0 {
  2283  			r = int(p.To.Reg)
  2284  		}
  2285  		o1 = OP_6IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2286  
  2287  	case 34: // mov $con,fr
  2288  		v := c.regoff(&p.From)
  2289  		a := AADDU
  2290  		if v > 0 {
  2291  			a = AOR
  2292  		}
  2293  		a2 := c.specialFpMovInst(p.As, C_REG, oclass(&p.To))
  2294  		o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
  2295  		o2 = OP_RR(a2, uint32(REGTMP), uint32(p.To.Reg))
  2296  
  2297  	case 35: // mov r,lext/auto/oreg
  2298  		v := c.regoff(&p.To)
  2299  		r := int(p.To.Reg)
  2300  		if r == 0 {
  2301  			r = int(o.param)
  2302  		}
  2303  		o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  2304  		o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  2305  		o3 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
  2306  
  2307  	case 36: // mov lext/auto/oreg,r
  2308  		v := c.regoff(&p.From)
  2309  		r := int(p.From.Reg)
  2310  		if r == 0 {
  2311  			r = int(o.param)
  2312  		}
  2313  		o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  2314  		o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  2315  		o3 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
  2316  
  2317  	case 37: // fmadd r1, r2, [r3], r4
  2318  		r := int(p.To.Reg)
  2319  		if len(p.RestArgs) > 0 {
  2320  			r = int(p.GetFrom3().Reg)
  2321  		}
  2322  		o1 = OP_RRRR(c.oprrrr(p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(r), uint32(p.To.Reg))
  2323  
  2324  	case 38: // word
  2325  		o1 = uint32(c.regoff(&p.From))
  2326  
  2327  	case 39: // vmov Rn, Vd.<T>[index]
  2328  		v, m := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg)
  2329  		if v == 0 {
  2330  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2331  		}
  2332  
  2333  		Rj := uint32(p.From.Reg & EXT_REG_MASK)
  2334  		Vd := uint32(p.To.Reg & EXT_REG_MASK)
  2335  		index := uint32(p.To.Index)
  2336  		c.checkindex(p, index, m)
  2337  		o1 = v | (index << 10) | (Rj << 5) | Vd
  2338  
  2339  	case 40: // vmov Vd.<T>[index], Rn
  2340  		v, m := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg)
  2341  		if v == 0 {
  2342  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2343  		}
  2344  
  2345  		Vj := uint32(p.From.Reg & EXT_REG_MASK)
  2346  		Rd := uint32(p.To.Reg & EXT_REG_MASK)
  2347  		index := uint32(p.From.Index)
  2348  		c.checkindex(p, index, m)
  2349  		o1 = v | (index << 10) | (Vj << 5) | Rd
  2350  
  2351  	case 41: // vmov Rn, Vd.<T>
  2352  		v, _ := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg)
  2353  		if v == 0 {
  2354  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2355  		}
  2356  
  2357  		Rj := uint32(p.From.Reg & EXT_REG_MASK)
  2358  		Vd := uint32(p.To.Reg & EXT_REG_MASK)
  2359  		o1 = v | (Rj << 5) | Vd
  2360  
  2361  	case 42: // vmov  xj, xd.<T>
  2362  		v, _ := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg)
  2363  		if v == 0 {
  2364  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2365  		}
  2366  
  2367  		Xj := uint32(p.From.Reg & EXT_REG_MASK)
  2368  		Xd := uint32(p.To.Reg & EXT_REG_MASK)
  2369  		o1 = v | (Xj << 5) | Xd
  2370  
  2371  	case 43: // vmov  xj, xd.<T>[index]
  2372  		v, m := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg)
  2373  		if v == 0 {
  2374  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2375  		}
  2376  
  2377  		Xj := uint32(p.From.Reg & EXT_REG_MASK)
  2378  		Xd := uint32(p.To.Reg & EXT_REG_MASK)
  2379  		index := uint32(p.To.Index)
  2380  		c.checkindex(p, index, m)
  2381  		o1 = v | (index << 10) | (Xj << 5) | Xd
  2382  
  2383  	case 44: // vmov  xj.<T>[index], xd
  2384  		v, m := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg)
  2385  		if v == 0 {
  2386  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2387  		}
  2388  
  2389  		Xj := uint32(p.From.Reg & EXT_REG_MASK)
  2390  		Xd := uint32(p.To.Reg & EXT_REG_MASK)
  2391  		index := uint32(p.From.Index)
  2392  		c.checkindex(p, index, m)
  2393  		o1 = v | (index << 10) | (Xj << 5) | Xd
  2394  
  2395  	case 45: // vmov  vj.<T>[index], vd.<T>
  2396  		v, m := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg)
  2397  		if v == 0 {
  2398  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2399  		}
  2400  
  2401  		vj := uint32(p.From.Reg & EXT_REG_MASK)
  2402  		vd := uint32(p.To.Reg & EXT_REG_MASK)
  2403  		index := uint32(p.From.Index)
  2404  		c.checkindex(p, index, m)
  2405  		o1 = v | (index << 10) | (vj << 5) | vd
  2406  
  2407  	case 49:
  2408  		if p.As == ANOOP {
  2409  			// andi r0, r0, 0
  2410  			o1 = OP_12IRR(c.opirr(AAND), 0, 0, 0)
  2411  		} else {
  2412  			// undef
  2413  			o1 = OP_15I(c.opi(ABREAK), 0)
  2414  		}
  2415  
  2416  	// relocation operations
  2417  	case 50: // mov r,addr ==> pcalau12i + sw
  2418  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
  2419  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2420  			Type: objabi.R_LOONG64_ADDR_HI,
  2421  			Off:  int32(c.pc),
  2422  			Siz:  4,
  2423  			Sym:  p.To.Sym,
  2424  			Add:  p.To.Offset,
  2425  		})
  2426  		o2 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
  2427  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2428  			Type: objabi.R_LOONG64_ADDR_LO,
  2429  			Off:  int32(c.pc + 4),
  2430  			Siz:  4,
  2431  			Sym:  p.To.Sym,
  2432  			Add:  p.To.Offset,
  2433  		})
  2434  
  2435  	case 51: // mov addr,r ==> pcalau12i + lw
  2436  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
  2437  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2438  			Type: objabi.R_LOONG64_ADDR_HI,
  2439  			Off:  int32(c.pc),
  2440  			Siz:  4,
  2441  			Sym:  p.From.Sym,
  2442  			Add:  p.From.Offset,
  2443  		})
  2444  		o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
  2445  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2446  			Type: objabi.R_LOONG64_ADDR_LO,
  2447  			Off:  int32(c.pc + 4),
  2448  			Siz:  4,
  2449  			Sym:  p.From.Sym,
  2450  			Add:  p.From.Offset,
  2451  		})
  2452  
  2453  	case 52: // mov $ext, r
  2454  		// NOTE: this case does not use REGTMP. If it ever does,
  2455  		// remove the NOTUSETMP flag in optab.
  2456  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
  2457  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2458  			Type: objabi.R_LOONG64_ADDR_HI,
  2459  			Off:  int32(c.pc),
  2460  			Siz:  4,
  2461  			Sym:  p.From.Sym,
  2462  			Add:  p.From.Offset,
  2463  		})
  2464  		o2 = OP_12IRR(c.opirr(add), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
  2465  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2466  			Type: objabi.R_LOONG64_ADDR_LO,
  2467  			Off:  int32(c.pc + 4),
  2468  			Siz:  4,
  2469  			Sym:  p.From.Sym,
  2470  			Add:  p.From.Offset,
  2471  		})
  2472  
  2473  	case 53: // mov r, tlsvar ==>  lu12i.w + ori + add r2, regtmp + sw o(regtmp)
  2474  		// NOTE: this case does not use REGTMP. If it ever does,
  2475  		// remove the NOTUSETMP flag in optab.
  2476  		o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
  2477  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2478  			Type: objabi.R_LOONG64_TLS_LE_HI,
  2479  			Off:  int32(c.pc),
  2480  			Siz:  4,
  2481  			Sym:  p.To.Sym,
  2482  			Add:  p.To.Offset,
  2483  		})
  2484  		o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
  2485  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2486  			Type: objabi.R_LOONG64_TLS_LE_LO,
  2487  			Off:  int32(c.pc + 4),
  2488  			Siz:  4,
  2489  			Sym:  p.To.Sym,
  2490  			Add:  p.To.Offset,
  2491  		})
  2492  		o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP))
  2493  		o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
  2494  
  2495  	case 54: // lu12i.w + ori + add r2, regtmp + lw o(regtmp)
  2496  		// NOTE: this case does not use REGTMP. If it ever does,
  2497  		// remove the NOTUSETMP flag in optab.
  2498  		o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
  2499  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2500  			Type: objabi.R_LOONG64_TLS_LE_HI,
  2501  			Off:  int32(c.pc),
  2502  			Siz:  4,
  2503  			Sym:  p.From.Sym,
  2504  			Add:  p.From.Offset,
  2505  		})
  2506  		o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
  2507  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2508  			Type: objabi.R_LOONG64_TLS_LE_LO,
  2509  			Off:  int32(c.pc + 4),
  2510  			Siz:  4,
  2511  			Sym:  p.From.Sym,
  2512  			Add:  p.From.Offset,
  2513  		})
  2514  		o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP))
  2515  		o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
  2516  
  2517  	case 56: // mov r, tlsvar IE model ==> (pcalau12i + ld.d)tlsvar@got + add.d + st.d
  2518  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
  2519  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2520  			Type: objabi.R_LOONG64_TLS_IE_HI,
  2521  			Off:  int32(c.pc),
  2522  			Siz:  4,
  2523  			Sym:  p.To.Sym,
  2524  		})
  2525  		o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP))
  2526  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2527  			Type: objabi.R_LOONG64_TLS_IE_LO,
  2528  			Off:  int32(c.pc + 4),
  2529  			Siz:  4,
  2530  			Sym:  p.To.Sym,
  2531  		})
  2532  		o3 = OP_RRR(c.oprrr(AADDVU), uint32(REGTMP), uint32(REG_R2), uint32(REGTMP))
  2533  		o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
  2534  
  2535  	case 57: // mov tlsvar, r IE model ==> (pcalau12i + ld.d)tlsvar@got + add.d + ld.d
  2536  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
  2537  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2538  			Type: objabi.R_LOONG64_TLS_IE_HI,
  2539  			Off:  int32(c.pc),
  2540  			Siz:  4,
  2541  			Sym:  p.From.Sym,
  2542  		})
  2543  		o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP))
  2544  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2545  			Type: objabi.R_LOONG64_TLS_IE_LO,
  2546  			Off:  int32(c.pc + 4),
  2547  			Siz:  4,
  2548  			Sym:  p.From.Sym,
  2549  		})
  2550  		o3 = OP_RRR(c.oprrr(AADDVU), uint32(REGTMP), uint32(REG_R2), uint32(REGTMP))
  2551  		o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
  2552  
  2553  	case 59: // mov $dcon,r
  2554  		// NOTE: this case does not use REGTMP. If it ever does,
  2555  		// remove the NOTUSETMP flag in optab.
  2556  		v := c.vregoff(&p.From)
  2557  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2558  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  2559  		o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  2560  		o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  2561  
  2562  	case 60: // add $dcon,r1,r2
  2563  		v := c.vregoff(&p.From)
  2564  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2565  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  2566  		o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  2567  		o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  2568  		r := int(p.Reg)
  2569  		if r == 0 {
  2570  			r = int(p.To.Reg)
  2571  		}
  2572  		o5 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2573  
  2574  	case 61: // word C_DCON
  2575  		o1 = uint32(c.vregoff(&p.From))
  2576  		o2 = uint32(c.vregoff(&p.From) >> 32)
  2577  
  2578  	case 62: // rdtimex rd, rj
  2579  		o1 = OP_RR(c.oprr(p.As), uint32(p.To.Reg), uint32(p.RegTo2))
  2580  
  2581  	case 65: // mov sym@GOT, r ==> pcalau12i + ld.d
  2582  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
  2583  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2584  			Type: objabi.R_LOONG64_GOT_HI,
  2585  			Off:  int32(c.pc),
  2586  			Siz:  4,
  2587  			Sym:  p.From.Sym,
  2588  		})
  2589  		o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
  2590  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2591  			Type: objabi.R_LOONG64_GOT_LO,
  2592  			Off:  int32(c.pc + 4),
  2593  			Siz:  4,
  2594  			Sym:  p.From.Sym,
  2595  		})
  2596  
  2597  	case 66: // am* From, To, RegTo2 ==> am* RegTo2, From, To
  2598  		rk := p.From.Reg
  2599  		rj := p.To.Reg
  2600  		rd := p.RegTo2
  2601  
  2602  		// See section 2.2.7.1 of https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html
  2603  		// for the register usage constraints.
  2604  		if rd == rj || rd == rk {
  2605  			c.ctxt.Diag("illegal register combination: %v\n", p)
  2606  		}
  2607  		o1 = OP_RRR(atomicInst[p.As], uint32(rk), uint32(rj), uint32(rd))
  2608  
  2609  	case 67: // mov $dcon12_0, r
  2610  		v := c.vregoff(&p.From)
  2611  		o1 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(0), uint32(p.To.Reg))
  2612  
  2613  	case 68: // mov $dcon12_20S, r
  2614  		v := c.vregoff(&p.From)
  2615  		contype := c.aclass(&p.From)
  2616  		switch contype {
  2617  		default: // C_DCON12_20S
  2618  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2619  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  2620  		case C_DCON20S_20:
  2621  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2622  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  2623  		case C_DCON12_12S:
  2624  			o1 = OP_12IRR(c.opirr(AADDV), uint32(v), uint32(0), uint32(p.To.Reg))
  2625  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  2626  		case C_DCON20S_12S, C_DCON20S_0:
  2627  			o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(p.To.Reg))
  2628  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  2629  		case C_DCON12_12U:
  2630  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(p.To.Reg))
  2631  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  2632  		case C_DCON20S_12U:
  2633  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(p.To.Reg))
  2634  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  2635  		}
  2636  
  2637  	case 69: // mov $dcon32_12S, r
  2638  		v := c.vregoff(&p.From)
  2639  		contype := c.aclass(&p.From)
  2640  		switch contype {
  2641  		default: // C_DCON32_12S, C_DCON32_0
  2642  			o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(p.To.Reg))
  2643  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  2644  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  2645  		case C_DCON32_20:
  2646  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2647  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  2648  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  2649  		case C_DCON12_32S:
  2650  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2651  			o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  2652  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  2653  		case C_DCON20S_32:
  2654  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2655  			o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  2656  			o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  2657  		case C_DCON32_12U:
  2658  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(p.To.Reg))
  2659  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  2660  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  2661  		}
  2662  
  2663  	case 70: // add $dcon12_0,[r1],r2
  2664  		v := c.vregoff(&p.From)
  2665  		r := int(p.Reg)
  2666  		if r == 0 {
  2667  			r = int(p.To.Reg)
  2668  		}
  2669  		o1 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(0), uint32(REGTMP))
  2670  		o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2671  
  2672  	case 71: // add $dcon12_20S,[r1],r2
  2673  		v := c.vregoff(&p.From)
  2674  		r := int(p.Reg)
  2675  		if r == 0 {
  2676  			r = int(p.To.Reg)
  2677  		}
  2678  		contype := c.aclass(&p.From)
  2679  		switch contype {
  2680  		default: // C_DCON12_20S
  2681  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2682  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  2683  		case C_DCON20S_20:
  2684  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2685  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  2686  		case C_DCON12_12S:
  2687  			o1 = OP_12IRR(c.opirr(AADDV), uint32(v), uint32(0), uint32(REGTMP))
  2688  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  2689  		case C_DCON20S_12S, C_DCON20S_0:
  2690  			o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(REGTMP))
  2691  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  2692  		case C_DCON12_12U:
  2693  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(REGTMP))
  2694  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  2695  		case C_DCON20S_12U:
  2696  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(REGTMP))
  2697  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  2698  		}
  2699  		o3 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2700  
  2701  	case 72: // add $dcon32_12S,[r1],r2
  2702  		v := c.vregoff(&p.From)
  2703  		r := int(p.Reg)
  2704  		if r == 0 {
  2705  			r = int(p.To.Reg)
  2706  		}
  2707  		contype := c.aclass(&p.From)
  2708  		switch contype {
  2709  		default: // C_DCON32_12S, C_DCON32_0
  2710  			o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(REGTMP))
  2711  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  2712  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  2713  		case C_DCON32_20:
  2714  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2715  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  2716  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  2717  		case C_DCON12_32S:
  2718  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2719  			o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  2720  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  2721  		case C_DCON20S_32:
  2722  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2723  			o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  2724  			o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  2725  		case C_DCON32_12U:
  2726  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(REGTMP))
  2727  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  2728  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  2729  		}
  2730  		o4 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2731  	}
  2732  
  2733  	out[0] = o1
  2734  	out[1] = o2
  2735  	out[2] = o3
  2736  	out[3] = o4
  2737  	out[4] = o5
  2738  }
  2739  
  2740  // checkoperand checks if operand >= 0 && operand <= maxoperand
  2741  func (c *ctxt0) checkoperand(p *obj.Prog, operand uint32, mask uint32) {
  2742  	if (operand & ^mask) != 0 {
  2743  		c.ctxt.Diag("operand out of range 0 to %d: %v", mask, p)
  2744  	}
  2745  }
  2746  
  2747  // checkindex checks if index >= 0 && index <= maxindex
  2748  func (c *ctxt0) checkindex(p *obj.Prog, index uint32, mask uint32) {
  2749  	if (index & ^mask) != 0 {
  2750  		c.ctxt.Diag("register element index out of range 0 to %d: %v", mask, p)
  2751  	}
  2752  }
  2753  
  2754  func (c *ctxt0) vregoff(a *obj.Addr) int64 {
  2755  	c.instoffset = 0
  2756  	c.aclass(a)
  2757  	return c.instoffset
  2758  }
  2759  
  2760  func (c *ctxt0) regoff(a *obj.Addr) int32 {
  2761  	return int32(c.vregoff(a))
  2762  }
  2763  
  2764  func (c *ctxt0) oprrrr(a obj.As) uint32 {
  2765  	switch a {
  2766  	case AFMADDF:
  2767  		return 0x81 << 20 // fmadd.s
  2768  	case AFMADDD:
  2769  		return 0x82 << 20 // fmadd.d
  2770  	case AFMSUBF:
  2771  		return 0x85 << 20 // fmsub.s
  2772  	case AFMSUBD:
  2773  		return 0x86 << 20 // fmsub.d
  2774  	case AFNMADDF:
  2775  		return 0x89 << 20 // fnmadd.f
  2776  	case AFNMADDD:
  2777  		return 0x8a << 20 // fnmadd.d
  2778  	case AFNMSUBF:
  2779  		return 0x8d << 20 // fnmsub.s
  2780  	case AFNMSUBD:
  2781  		return 0x8e << 20 // fnmsub.d
  2782  	}
  2783  
  2784  	c.ctxt.Diag("bad rrrr opcode %v", a)
  2785  	return 0
  2786  }
  2787  
  2788  func (c *ctxt0) oprrr(a obj.As) uint32 {
  2789  	switch a {
  2790  	case AADD:
  2791  		return 0x20 << 15
  2792  	case AADDU:
  2793  		return 0x20 << 15
  2794  	case ASGT:
  2795  		return 0x24 << 15 // SLT
  2796  	case ASGTU:
  2797  		return 0x25 << 15 // SLTU
  2798  	case AMASKEQZ:
  2799  		return 0x26 << 15
  2800  	case AMASKNEZ:
  2801  		return 0x27 << 15
  2802  	case AAND:
  2803  		return 0x29 << 15
  2804  	case AOR:
  2805  		return 0x2a << 15
  2806  	case AXOR:
  2807  		return 0x2b << 15
  2808  	case AORN:
  2809  		return 0x2c << 15 // orn
  2810  	case AANDN:
  2811  		return 0x2d << 15 // andn
  2812  	case ASUB:
  2813  		return 0x22 << 15
  2814  	case ASUBU, ANEGW:
  2815  		return 0x22 << 15
  2816  	case ANOR:
  2817  		return 0x28 << 15
  2818  	case ASLL:
  2819  		return 0x2e << 15
  2820  	case ASRL:
  2821  		return 0x2f << 15
  2822  	case ASRA:
  2823  		return 0x30 << 15
  2824  	case AROTR:
  2825  		return 0x36 << 15
  2826  	case ASLLV:
  2827  		return 0x31 << 15
  2828  	case ASRLV:
  2829  		return 0x32 << 15
  2830  	case ASRAV:
  2831  		return 0x33 << 15
  2832  	case AROTRV:
  2833  		return 0x37 << 15
  2834  	case AADDV:
  2835  		return 0x21 << 15
  2836  	case AADDVU:
  2837  		return 0x21 << 15
  2838  	case ASUBV:
  2839  		return 0x23 << 15
  2840  	case ASUBVU, ANEGV:
  2841  		return 0x23 << 15
  2842  
  2843  	case AMUL:
  2844  		return 0x38 << 15 // mul.w
  2845  	case AMULU:
  2846  		return 0x38 << 15 // mul.w
  2847  	case AMULH:
  2848  		return 0x39 << 15 // mulh.w
  2849  	case AMULHU:
  2850  		return 0x3a << 15 // mulhu.w
  2851  	case AMULV:
  2852  		return 0x3b << 15 // mul.d
  2853  	case AMULVU:
  2854  		return 0x3b << 15 // mul.d
  2855  	case AMULHV:
  2856  		return 0x3c << 15 // mulh.d
  2857  	case AMULHVU:
  2858  		return 0x3d << 15 // mulhu.d
  2859  	case ADIV:
  2860  		return 0x40 << 15 // div.w
  2861  	case ADIVU:
  2862  		return 0x42 << 15 // div.wu
  2863  	case ADIVV:
  2864  		return 0x44 << 15 // div.d
  2865  	case ADIVVU:
  2866  		return 0x46 << 15 // div.du
  2867  	case AREM:
  2868  		return 0x41 << 15 // mod.w
  2869  	case AREMU:
  2870  		return 0x43 << 15 // mod.wu
  2871  	case AREMV:
  2872  		return 0x45 << 15 // mod.d
  2873  	case AREMVU:
  2874  		return 0x47 << 15 // mod.du
  2875  	case ACRCWBW:
  2876  		return 0x48 << 15 // crc.w.b.w
  2877  	case ACRCWHW:
  2878  		return 0x49 << 15 // crc.w.h.w
  2879  	case ACRCWWW:
  2880  		return 0x4a << 15 // crc.w.w.w
  2881  	case ACRCWVW:
  2882  		return 0x4b << 15 // crc.w.d.w
  2883  	case ACRCCWBW:
  2884  		return 0x4c << 15 // crcc.w.b.w
  2885  	case ACRCCWHW:
  2886  		return 0x4d << 15 // crcc.w.h.w
  2887  	case ACRCCWWW:
  2888  		return 0x4e << 15 // crcc.w.w.w
  2889  	case ACRCCWVW:
  2890  		return 0x4f << 15 // crcc.w.d.w
  2891  	case AJMP:
  2892  		return 0x13 << 26 // jirl r0, rj, 0
  2893  	case AJAL:
  2894  		return (0x13 << 26) | 1 // jirl r1, rj, 0
  2895  
  2896  	case ADIVF:
  2897  		return 0x20d << 15
  2898  	case ADIVD:
  2899  		return 0x20e << 15
  2900  	case AMULF:
  2901  		return 0x209 << 15
  2902  	case AMULD:
  2903  		return 0x20a << 15
  2904  	case ASUBF:
  2905  		return 0x205 << 15
  2906  	case ASUBD:
  2907  		return 0x206 << 15
  2908  	case AADDF:
  2909  		return 0x201 << 15
  2910  	case AADDD:
  2911  		return 0x202 << 15
  2912  	case ACMPEQF:
  2913  		return 0x0c1<<20 | 0x4<<15 // FCMP.CEQ.S
  2914  	case ACMPEQD:
  2915  		return 0x0c2<<20 | 0x4<<15 // FCMP.CEQ.D
  2916  	case ACMPGED:
  2917  		return 0x0c2<<20 | 0x7<<15 // FCMP.SLE.D
  2918  	case ACMPGEF:
  2919  		return 0x0c1<<20 | 0x7<<15 // FCMP.SLE.S
  2920  	case ACMPGTD:
  2921  		return 0x0c2<<20 | 0x3<<15 // FCMP.SLT.D
  2922  	case ACMPGTF:
  2923  		return 0x0c1<<20 | 0x3<<15 // FCMP.SLT.S
  2924  	case AFMINF:
  2925  		return 0x215 << 15 // fmin.s
  2926  	case AFMIND:
  2927  		return 0x216 << 15 // fmin.d
  2928  	case AFMAXF:
  2929  		return 0x211 << 15 // fmax.s
  2930  	case AFMAXD:
  2931  		return 0x212 << 15 // fmax.d
  2932  	case AFMAXAF:
  2933  		return 0x219 << 15 // fmaxa.s
  2934  	case AFMAXAD:
  2935  		return 0x21a << 15 // fmaxa.d
  2936  	case AFMINAF:
  2937  		return 0x21d << 15 // fmina.s
  2938  	case AFMINAD:
  2939  		return 0x21e << 15 // fmina.d
  2940  	case AFSCALEBF:
  2941  		return 0x221 << 15 // fscaleb.s
  2942  	case AFSCALEBD:
  2943  		return 0x222 << 15 // fscaleb.d
  2944  	case AFCOPYSGF:
  2945  		return 0x225 << 15 // fcopysign.s
  2946  	case AFCOPYSGD:
  2947  		return 0x226 << 15 // fcopysign.d
  2948  	case -AMOVB:
  2949  		return 0x07000 << 15 // ldx.b
  2950  	case -AMOVH:
  2951  		return 0x07008 << 15 // ldx.h
  2952  	case -AMOVW:
  2953  		return 0x07010 << 15 // ldx.w
  2954  	case -AMOVV:
  2955  		return 0x07018 << 15 // ldx.d
  2956  	case -AMOVBU:
  2957  		return 0x07040 << 15 // ldx.bu
  2958  	case -AMOVHU:
  2959  		return 0x07048 << 15 // ldx.hu
  2960  	case -AMOVWU:
  2961  		return 0x07050 << 15 // ldx.wu
  2962  	case AMOVB:
  2963  		return 0x07020 << 15 // stx.b
  2964  	case AMOVH:
  2965  		return 0x07028 << 15 // stx.h
  2966  	case AMOVW:
  2967  		return 0x07030 << 15 // stx.w
  2968  	case AMOVV:
  2969  		return 0x07038 << 15 // stx.d
  2970  	case -AMOVF:
  2971  		return 0x07060 << 15 // fldx.s
  2972  	case -AMOVD:
  2973  		return 0x07068 << 15 // fldx.d
  2974  	case AMOVF:
  2975  		return 0x07070 << 15 // fstx.s
  2976  	case AMOVD:
  2977  		return 0x07078 << 15 // fstx.d
  2978  	case -AVMOVQ:
  2979  		return 0x07080 << 15 // vldx
  2980  	case -AXVMOVQ:
  2981  		return 0x07090 << 15 // xvldx
  2982  	case AVMOVQ:
  2983  		return 0x07088 << 15 // vstx
  2984  	case AXVMOVQ:
  2985  		return 0x07098 << 15 // xvstx
  2986  	case AVSEQB:
  2987  		return 0x0e000 << 15 // vseq.b
  2988  	case AXVSEQB:
  2989  		return 0x0e800 << 15 // xvseq.b
  2990  	case AVSEQH:
  2991  		return 0x0e001 << 15 // vseq.h
  2992  	case AXVSEQH:
  2993  		return 0x0e801 << 15 // xvseq.h
  2994  	case AVSEQW:
  2995  		return 0x0e002 << 15 // vseq.w
  2996  	case AXVSEQW:
  2997  		return 0x0e802 << 15 // xvseq.w
  2998  	case AVSEQV:
  2999  		return 0x0e003 << 15 // vseq.d
  3000  	case AXVSEQV:
  3001  		return 0x0e803 << 15 // xvseq.d
  3002  	case AVANDV:
  3003  		return 0x0E24C << 15 // vand.v
  3004  	case AVORV:
  3005  		return 0x0E24D << 15 // vor.v
  3006  	case AVXORV:
  3007  		return 0x0E24E << 15 // vxor.v
  3008  	case AVNORV:
  3009  		return 0x0E24F << 15 // vnor.v
  3010  	case AVANDNV:
  3011  		return 0x0E250 << 15 // vandn.v
  3012  	case AVORNV:
  3013  		return 0x0E251 << 15 // vorn.v
  3014  	case AXVANDV:
  3015  		return 0x0EA4C << 15 // xvand.v
  3016  	case AXVORV:
  3017  		return 0x0EA4D << 15 // xvor.v
  3018  	case AXVXORV:
  3019  		return 0x0EA4E << 15 // xvxor.v
  3020  	case AXVNORV:
  3021  		return 0x0EA4F << 15 // xvnor.v
  3022  	case AXVANDNV:
  3023  		return 0x0EA50 << 15 // xvandn.v
  3024  	case AXVORNV:
  3025  		return 0x0EA51 << 15 // xvorn.v
  3026  	case AVDIVB:
  3027  		return 0xe1c0 << 15 // vdiv.b
  3028  	case AVDIVH:
  3029  		return 0xe1c1 << 15 // vdiv.h
  3030  	case AVDIVW:
  3031  		return 0xe1c2 << 15 // vdiv.w
  3032  	case AVDIVV:
  3033  		return 0xe1c3 << 15 // vdiv.d
  3034  	case AVMODB:
  3035  		return 0xe1c4 << 15 // vmod.b
  3036  	case AVMODH:
  3037  		return 0xe1c5 << 15 // vmod.h
  3038  	case AVMODW:
  3039  		return 0xe1c6 << 15 // vmod.w
  3040  	case AVMODV:
  3041  		return 0xe1c7 << 15 // vmod.d
  3042  	case AVDIVBU:
  3043  		return 0xe1c8 << 15 // vdiv.bu
  3044  	case AVDIVHU:
  3045  		return 0xe1c9 << 15 // vdiv.hu
  3046  	case AVDIVWU:
  3047  		return 0xe1ca << 15 // vdiv.wu
  3048  	case AVDIVVU:
  3049  		return 0xe1cb << 15 // vdiv.du
  3050  	case AVMODBU:
  3051  		return 0xe1cc << 15 // vmod.bu
  3052  	case AVMODHU:
  3053  		return 0xe1cd << 15 // vmod.hu
  3054  	case AVMODWU:
  3055  		return 0xe1ce << 15 // vmod.wu
  3056  	case AVMODVU:
  3057  		return 0xe1cf << 15 // vmod.du
  3058  	case AXVDIVB:
  3059  		return 0xe9c0 << 15 // xvdiv.b
  3060  	case AXVDIVH:
  3061  		return 0xe9c1 << 15 // xvdiv.h
  3062  	case AXVDIVW:
  3063  		return 0xe9c2 << 15 // xvdiv.w
  3064  	case AXVDIVV:
  3065  		return 0xe9c3 << 15 // xvdiv.d
  3066  	case AXVMODB:
  3067  		return 0xe9c4 << 15 // xvmod.b
  3068  	case AXVMODH:
  3069  		return 0xe9c5 << 15 // xvmod.h
  3070  	case AXVMODW:
  3071  		return 0xe9c6 << 15 // xvmod.w
  3072  	case AXVMODV:
  3073  		return 0xe9c7 << 15 // xvmod.d
  3074  	case AXVDIVBU:
  3075  		return 0xe9c8 << 15 // xvdiv.bu
  3076  	case AXVDIVHU:
  3077  		return 0xe9c9 << 15 // xvdiv.hu
  3078  	case AXVDIVWU:
  3079  		return 0xe9ca << 15 // xvdiv.wu
  3080  	case AXVDIVVU:
  3081  		return 0xe9cb << 15 // xvdiv.du
  3082  	case AXVMODBU:
  3083  		return 0xe9cc << 15 // xvmod.bu
  3084  	case AXVMODHU:
  3085  		return 0xe9cd << 15 // xvmod.hu
  3086  	case AXVMODWU:
  3087  		return 0xe9ce << 15 // xvmod.wu
  3088  	case AXVMODVU:
  3089  		return 0xe9cf << 15 // xvmod.du
  3090  	case AVMULWEVHB:
  3091  		return 0xe120 << 15 // vmulwev.h.b
  3092  	case AVMULWEVWH:
  3093  		return 0xe121 << 15 // vmulwev.w.h
  3094  	case AVMULWEVVW:
  3095  		return 0xe122 << 15 // vmulwev.d.w
  3096  	case AVMULWEVQV:
  3097  		return 0xe123 << 15 // vmulwev.q.d
  3098  	case AVMULWODHB:
  3099  		return 0xe124 << 15 // vmulwod.h.b
  3100  	case AVMULWODWH:
  3101  		return 0xe125 << 15 // vmulwod.w.h
  3102  	case AVMULWODVW:
  3103  		return 0xe126 << 15 // vmulwod.d.w
  3104  	case AVMULWODQV:
  3105  		return 0xe127 << 15 // vmulwod.q.d
  3106  	case AVMULWEVHBU:
  3107  		return 0xe130 << 15 // vmulwev.h.bu
  3108  	case AVMULWEVWHU:
  3109  		return 0xe131 << 15 // vmulwev.w.hu
  3110  	case AVMULWEVVWU:
  3111  		return 0xe132 << 15 // vmulwev.d.wu
  3112  	case AVMULWEVQVU:
  3113  		return 0xe133 << 15 // vmulwev.q.du
  3114  	case AVMULWODHBU:
  3115  		return 0xe134 << 15 // vmulwod.h.bu
  3116  	case AVMULWODWHU:
  3117  		return 0xe135 << 15 // vmulwod.w.hu
  3118  	case AVMULWODVWU:
  3119  		return 0xe136 << 15 // vmulwod.d.wu
  3120  	case AVMULWODQVU:
  3121  		return 0xe137 << 15 // vmulwod.q.du
  3122  	case AVMULWEVHBUB:
  3123  		return 0xe140 << 15 // vmulwev.h.bu.b
  3124  	case AVMULWEVWHUH:
  3125  		return 0xe141 << 15 // vmulwev.w.hu.h
  3126  	case AVMULWEVVWUW:
  3127  		return 0xe142 << 15 // vmulwev.d.wu.w
  3128  	case AVMULWEVQVUV:
  3129  		return 0xe143 << 15 // vmulwev.q.du.d
  3130  	case AVMULWODHBUB:
  3131  		return 0xe144 << 15 // vmulwod.h.bu.b
  3132  	case AVMULWODWHUH:
  3133  		return 0xe145 << 15 // vmulwod.w.hu.h
  3134  	case AVMULWODVWUW:
  3135  		return 0xe146 << 15 // vmulwod.d.wu.w
  3136  	case AVMULWODQVUV:
  3137  		return 0xe147 << 15 // vmulwod.q.du.d
  3138  	case AXVMULWEVHB:
  3139  		return 0xe920 << 15 // xvmulwev.h.b
  3140  	case AXVMULWEVWH:
  3141  		return 0xe921 << 15 // xvmulwev.w.h
  3142  	case AXVMULWEVVW:
  3143  		return 0xe922 << 15 // xvmulwev.d.w
  3144  	case AXVMULWEVQV:
  3145  		return 0xe923 << 15 // xvmulwev.q.d
  3146  	case AXVMULWODHB:
  3147  		return 0xe924 << 15 // xvmulwod.h.b
  3148  	case AXVMULWODWH:
  3149  		return 0xe925 << 15 // xvmulwod.w.h
  3150  	case AXVMULWODVW:
  3151  		return 0xe926 << 15 // xvmulwod.d.w
  3152  	case AXVMULWODQV:
  3153  		return 0xe927 << 15 // xvmulwod.q.d
  3154  	case AXVMULWEVHBU:
  3155  		return 0xe930 << 15 // xvmulwev.h.bu
  3156  	case AXVMULWEVWHU:
  3157  		return 0xe931 << 15 // xvmulwev.w.hu
  3158  	case AXVMULWEVVWU:
  3159  		return 0xe932 << 15 // xvmulwev.d.wu
  3160  	case AXVMULWEVQVU:
  3161  		return 0xe933 << 15 // xvmulwev.q.du
  3162  	case AXVMULWODHBU:
  3163  		return 0xe934 << 15 // xvmulwod.h.bu
  3164  	case AXVMULWODWHU:
  3165  		return 0xe935 << 15 // xvmulwod.w.hu
  3166  	case AXVMULWODVWU:
  3167  		return 0xe936 << 15 // xvmulwod.d.wu
  3168  	case AXVMULWODQVU:
  3169  		return 0xe937 << 15 // xvmulwod.q.du
  3170  	case AXVMULWEVHBUB:
  3171  		return 0xe940 << 15 // xvmulwev.h.bu.b
  3172  	case AXVMULWEVWHUH:
  3173  		return 0xe941 << 15 // xvmulwev.w.hu.h
  3174  	case AXVMULWEVVWUW:
  3175  		return 0xe942 << 15 // xvmulwev.d.wu.w
  3176  	case AXVMULWEVQVUV:
  3177  		return 0xe943 << 15 // xvmulwev.q.du.d
  3178  	case AXVMULWODHBUB:
  3179  		return 0xe944 << 15 // xvmulwod.h.bu.b
  3180  	case AXVMULWODWHUH:
  3181  		return 0xe945 << 15 // xvmulwod.w.hu.h
  3182  	case AXVMULWODVWUW:
  3183  		return 0xe946 << 15 // xvmulwod.d.wu.w
  3184  	case AXVMULWODQVUV:
  3185  		return 0xe947 << 15 // xvmulwod.q.du.d
  3186  	case AVSLLB:
  3187  		return 0xe1d0 << 15 // vsll.b
  3188  	case AVSLLH:
  3189  		return 0xe1d1 << 15 // vsll.h
  3190  	case AVSLLW:
  3191  		return 0xe1d2 << 15 // vsll.w
  3192  	case AVSLLV:
  3193  		return 0xe1d3 << 15 // vsll.d
  3194  	case AVSRLB:
  3195  		return 0xe1d4 << 15 // vsrl.b
  3196  	case AVSRLH:
  3197  		return 0xe1d5 << 15 // vsrl.h
  3198  	case AVSRLW:
  3199  		return 0xe1d6 << 15 // vsrl.w
  3200  	case AVSRLV:
  3201  		return 0xe1d7 << 15 // vsrl.d
  3202  	case AVSRAB:
  3203  		return 0xe1d8 << 15 // vsra.b
  3204  	case AVSRAH:
  3205  		return 0xe1d9 << 15 // vsra.h
  3206  	case AVSRAW:
  3207  		return 0xe1da << 15 // vsra.w
  3208  	case AVSRAV:
  3209  		return 0xe1db << 15 // vsra.d
  3210  	case AVROTRB:
  3211  		return 0xe1dc << 15 // vrotr.b
  3212  	case AVROTRH:
  3213  		return 0xe1dd << 15 // vrotr.h
  3214  	case AVROTRW:
  3215  		return 0xe1de << 15 // vrotr.w
  3216  	case AVROTRV:
  3217  		return 0xe1df << 15 // vrotr.d
  3218  	case AXVSLLB:
  3219  		return 0xe9d0 << 15 // xvsll.b
  3220  	case AXVSLLH:
  3221  		return 0xe9d1 << 15 // xvsll.h
  3222  	case AXVSLLW:
  3223  		return 0xe9d2 << 15 // xvsll.w
  3224  	case AXVSLLV:
  3225  		return 0xe9d3 << 15 // xvsll.d
  3226  	case AXVSRLB:
  3227  		return 0xe9d4 << 15 // xvsrl.b
  3228  	case AXVSRLH:
  3229  		return 0xe9d5 << 15 // xvsrl.h
  3230  	case AXVSRLW:
  3231  		return 0xe9d6 << 15 // xvsrl.w
  3232  	case AXVSRLV:
  3233  		return 0xe9d7 << 15 // xvsrl.d
  3234  	case AXVSRAB:
  3235  		return 0xe9d8 << 15 // xvsra.b
  3236  	case AXVSRAH:
  3237  		return 0xe9d9 << 15 // xvsra.h
  3238  	case AXVSRAW:
  3239  		return 0xe9da << 15 // xvsra.w
  3240  	case AXVSRAV:
  3241  		return 0xe9db << 15 // xvsra.d
  3242  	case AXVROTRB:
  3243  		return 0xe9dc << 15 // xvrotr.b
  3244  	case AXVROTRH:
  3245  		return 0xe9dd << 15 // xvrotr.h
  3246  	case AXVROTRW:
  3247  		return 0xe9de << 15 // xvrotr.w
  3248  	case AXVROTRV:
  3249  		return 0xe9df << 15 // xvrotr.d
  3250  	case AVADDB:
  3251  		return 0xe014 << 15 // vadd.b
  3252  	case AVADDH:
  3253  		return 0xe015 << 15 // vadd.h
  3254  	case AVADDW:
  3255  		return 0xe016 << 15 // vadd.w
  3256  	case AVADDV:
  3257  		return 0xe017 << 15 // vadd.d
  3258  	case AVADDQ:
  3259  		return 0xe25a << 15 // vadd.q
  3260  	case AVSUBB:
  3261  		return 0xe018 << 15 // vsub.b
  3262  	case AVSUBH:
  3263  		return 0xe019 << 15 // vsub.h
  3264  	case AVSUBW:
  3265  		return 0xe01a << 15 // vsub.w
  3266  	case AVSUBV:
  3267  		return 0xe01b << 15 // vsub.d
  3268  	case AVSUBQ:
  3269  		return 0xe25b << 15 // vsub.q
  3270  	case AXVADDB:
  3271  		return 0xe814 << 15 // xvadd.b
  3272  	case AXVADDH:
  3273  		return 0xe815 << 15 // xvadd.h
  3274  	case AXVADDW:
  3275  		return 0xe816 << 15 // xvadd.w
  3276  	case AXVADDV:
  3277  		return 0xe817 << 15 // xvadd.d
  3278  	case AXVADDQ:
  3279  		return 0xea5a << 15 // xvadd.q
  3280  	case AXVSUBB:
  3281  		return 0xe818 << 15 // xvsub.b
  3282  	case AXVSUBH:
  3283  		return 0xe819 << 15 // xvsub.h
  3284  	case AXVSUBW:
  3285  		return 0xe81a << 15 // xvsub.w
  3286  	case AXVSUBV:
  3287  		return 0xe81b << 15 // xvsub.d
  3288  	case AXVSUBQ:
  3289  		return 0xea5b << 15 // xvsub.q
  3290  	case AVILVLB:
  3291  		return 0xe234 << 15 // vilvl.b
  3292  	case AVILVLH:
  3293  		return 0xe235 << 15 // vilvl.h
  3294  	case AVILVLW:
  3295  		return 0xe236 << 15 // vilvl.w
  3296  	case AVILVLV:
  3297  		return 0xe237 << 15 // vilvl.d
  3298  	case AVILVHB:
  3299  		return 0xe238 << 15 // vilvh.b
  3300  	case AVILVHH:
  3301  		return 0xe239 << 15 // vilvh.h
  3302  	case AVILVHW:
  3303  		return 0xe23a << 15 // vilvh.w
  3304  	case AVILVHV:
  3305  		return 0xe23b << 15 // vilvh.d
  3306  	case AXVILVLB:
  3307  		return 0xea34 << 15 // xvilvl.b
  3308  	case AXVILVLH:
  3309  		return 0xea35 << 15 // xvilvl.h
  3310  	case AXVILVLW:
  3311  		return 0xea36 << 15 // xvilvl.w
  3312  	case AXVILVLV:
  3313  		return 0xea37 << 15 // xvilvl.d
  3314  	case AXVILVHB:
  3315  		return 0xea38 << 15 // xvilvh.b
  3316  	case AXVILVHH:
  3317  		return 0xea39 << 15 // xvilvh.h
  3318  	case AXVILVHW:
  3319  		return 0xea3a << 15 // xvilvh.w
  3320  	case AXVILVHV:
  3321  		return 0xea3b << 15 // xvilvh.d
  3322  	case AVMULB:
  3323  		return 0xe108 << 15 // vmul.b
  3324  	case AVMULH:
  3325  		return 0xe109 << 15 // vmul.h
  3326  	case AVMULW:
  3327  		return 0xe10a << 15 // vmul.w
  3328  	case AVMULV:
  3329  		return 0xe10b << 15 // vmul.d
  3330  	case AVMUHB:
  3331  		return 0xe10c << 15 // vmuh.b
  3332  	case AVMUHH:
  3333  		return 0xe10d << 15 // vmuh.h
  3334  	case AVMUHW:
  3335  		return 0xe10e << 15 // vmuh.w
  3336  	case AVMUHV:
  3337  		return 0xe10f << 15 // vmuh.d
  3338  	case AVMUHBU:
  3339  		return 0xe110 << 15 // vmuh.bu
  3340  	case AVMUHHU:
  3341  		return 0xe111 << 15 // vmuh.hu
  3342  	case AVMUHWU:
  3343  		return 0xe112 << 15 // vmuh.wu
  3344  	case AVMUHVU:
  3345  		return 0xe113 << 15 // vmuh.du
  3346  	case AXVMULB:
  3347  		return 0xe908 << 15 // xvmul.b
  3348  	case AXVMULH:
  3349  		return 0xe909 << 15 // xvmul.h
  3350  	case AXVMULW:
  3351  		return 0xe90a << 15 // xvmul.w
  3352  	case AXVMULV:
  3353  		return 0xe90b << 15 // xvmul.d
  3354  	case AXVMUHB:
  3355  		return 0xe90c << 15 // xvmuh.b
  3356  	case AXVMUHH:
  3357  		return 0xe90d << 15 // xvmuh.h
  3358  	case AXVMUHW:
  3359  		return 0xe90e << 15 // xvmuh.w
  3360  	case AXVMUHV:
  3361  		return 0xe90f << 15 // xvmuh.d
  3362  	case AXVMUHBU:
  3363  		return 0xe910 << 15 // xvmuh.bu
  3364  	case AXVMUHHU:
  3365  		return 0xe911 << 15 // xvmuh.hu
  3366  	case AXVMUHWU:
  3367  		return 0xe912 << 15 // xvmuh.wu
  3368  	case AXVMUHVU:
  3369  		return 0xe913 << 15 // xvmuh.du
  3370  	}
  3371  
  3372  	if a < 0 {
  3373  		c.ctxt.Diag("bad rrr opcode -%v", -a)
  3374  	} else {
  3375  		c.ctxt.Diag("bad rrr opcode %v", a)
  3376  	}
  3377  	return 0
  3378  }
  3379  
  3380  func (c *ctxt0) oprr(a obj.As) uint32 {
  3381  	switch a {
  3382  	case ACLOW:
  3383  		return 0x4 << 10 // clo.w
  3384  	case ACLZW:
  3385  		return 0x5 << 10 // clz.w
  3386  	case ACTOW:
  3387  		return 0x6 << 10 // cto.w
  3388  	case ACTZW:
  3389  		return 0x7 << 10 // ctz.w
  3390  	case ACLOV:
  3391  		return 0x8 << 10 // clo.d
  3392  	case ACLZV:
  3393  		return 0x9 << 10 // clz.d
  3394  	case ACTOV:
  3395  		return 0xa << 10 // cto.d
  3396  	case ACTZV:
  3397  		return 0xb << 10 // ctz.d
  3398  	case AREVB2H:
  3399  		return 0xc << 10 // revb.2h
  3400  	case AREVB4H:
  3401  		return 0xd << 10 // revb.4h
  3402  	case AREVB2W:
  3403  		return 0xe << 10 // revb.2w
  3404  	case AREVBV:
  3405  		return 0xf << 10 // revb.d
  3406  	case AREVH2W:
  3407  		return 0x10 << 10 // revh.2w
  3408  	case AREVHV:
  3409  		return 0x11 << 10 // revh.d
  3410  	case ABITREV4B:
  3411  		return 0x12 << 10 // bitrev.4b
  3412  	case ABITREV8B:
  3413  		return 0x13 << 10 // bitrev.8b
  3414  	case ABITREVW:
  3415  		return 0x14 << 10 // bitrev.w
  3416  	case ABITREVV:
  3417  		return 0x15 << 10 // bitrev.d
  3418  	case AEXTWH:
  3419  		return 0x16 << 10 // ext.w.h
  3420  	case AEXTWB:
  3421  		return 0x17 << 10 // ext.w.h
  3422  	case ACPUCFG:
  3423  		return 0x1b << 10
  3424  	case ARDTIMELW:
  3425  		return 0x18 << 10
  3426  	case ARDTIMEHW:
  3427  		return 0x19 << 10
  3428  	case ARDTIMED:
  3429  		return 0x1a << 10
  3430  	case ATRUNCFV:
  3431  		return 0x46a9 << 10
  3432  	case ATRUNCDV:
  3433  		return 0x46aa << 10
  3434  	case ATRUNCFW:
  3435  		return 0x46a1 << 10
  3436  	case ATRUNCDW:
  3437  		return 0x46a2 << 10
  3438  	case AMOVFV:
  3439  		return 0x46c9 << 10
  3440  	case AMOVDV:
  3441  		return 0x46ca << 10
  3442  	case AMOVVF:
  3443  		return 0x4746 << 10
  3444  	case AMOVVD:
  3445  		return 0x474a << 10
  3446  	case AMOVFW:
  3447  		return 0x46c1 << 10
  3448  	case AMOVDW:
  3449  		return 0x46c2 << 10
  3450  	case AMOVWF:
  3451  		return 0x4744 << 10
  3452  	case AMOVDF:
  3453  		return 0x4646 << 10
  3454  	case AMOVWD:
  3455  		return 0x4748 << 10
  3456  	case AMOVFD:
  3457  		return 0x4649 << 10
  3458  	case AABSF:
  3459  		return 0x4501 << 10
  3460  	case AABSD:
  3461  		return 0x4502 << 10
  3462  	case AMOVF:
  3463  		return 0x4525 << 10
  3464  	case AMOVD:
  3465  		return 0x4526 << 10
  3466  	case ANEGF:
  3467  		return 0x4505 << 10
  3468  	case ANEGD:
  3469  		return 0x4506 << 10
  3470  	case ASQRTF:
  3471  		return 0x4511 << 10
  3472  	case ASQRTD:
  3473  		return 0x4512 << 10
  3474  	case AFLOGBF:
  3475  		return 0x4509 << 10 // flogb.s
  3476  	case AFLOGBD:
  3477  		return 0x450a << 10 // flogb.d
  3478  	case AFCLASSF:
  3479  		return 0x450d << 10 // fclass.s
  3480  	case AFCLASSD:
  3481  		return 0x450e << 10 // fclass.d
  3482  	case AFFINTFW:
  3483  		return 0x4744 << 10 // ffint.s.w
  3484  	case AFFINTFV:
  3485  		return 0x4746 << 10 // ffint.s.l
  3486  	case AFFINTDW:
  3487  		return 0x4748 << 10 // ffint.d.w
  3488  	case AFFINTDV:
  3489  		return 0x474a << 10 // ffint.d.l
  3490  	case AFTINTWF:
  3491  		return 0x46c1 << 10 // ftint.w.s
  3492  	case AFTINTWD:
  3493  		return 0x46c2 << 10 // ftint.w.d
  3494  	case AFTINTVF:
  3495  		return 0x46c9 << 10 // ftint.l.s
  3496  	case AFTINTVD:
  3497  		return 0x46ca << 10 // ftint.l.d
  3498  	case AFTINTRMWF:
  3499  		return 0x4681 << 10 // ftintrm.w.s
  3500  	case AFTINTRMWD:
  3501  		return 0x4682 << 10 // ftintrm.w.d
  3502  	case AFTINTRMVF:
  3503  		return 0x4689 << 10 // ftintrm.l.s
  3504  	case AFTINTRMVD:
  3505  		return 0x468a << 10 // ftintrm.l.d
  3506  	case AFTINTRPWF:
  3507  		return 0x4691 << 10 // ftintrp.w.s
  3508  	case AFTINTRPWD:
  3509  		return 0x4692 << 10 // ftintrp.w.d
  3510  	case AFTINTRPVF:
  3511  		return 0x4699 << 10 // ftintrp.l.s
  3512  	case AFTINTRPVD:
  3513  		return 0x469a << 10 // ftintrp.l.d
  3514  	case AFTINTRZWF:
  3515  		return 0x46a1 << 10 // ftintrz.w.s
  3516  	case AFTINTRZWD:
  3517  		return 0x46a2 << 10 // ftintrz.w.d
  3518  	case AFTINTRZVF:
  3519  		return 0x46a9 << 10 // ftintrz.l.s
  3520  	case AFTINTRZVD:
  3521  		return 0x46aa << 10 // ftintrz.l.d
  3522  	case AFTINTRNEWF:
  3523  		return 0x46b1 << 10 // ftintrne.w.s
  3524  	case AFTINTRNEWD:
  3525  		return 0x46b2 << 10 // ftintrne.w.d
  3526  	case AFTINTRNEVF:
  3527  		return 0x46b9 << 10 // ftintrne.l.s
  3528  	case AFTINTRNEVD:
  3529  		return 0x46ba << 10 // ftintrne.l.d
  3530  	case AVPCNTB:
  3531  		return 0x1ca708 << 10 // vpcnt.b
  3532  	case AVPCNTH:
  3533  		return 0x1ca709 << 10 // vpcnt.h
  3534  	case AVPCNTW:
  3535  		return 0x1ca70a << 10 // vpcnt.w
  3536  	case AVPCNTV:
  3537  		return 0x1ca70b << 10 // vpcnt.v
  3538  	case AXVPCNTB:
  3539  		return 0x1da708 << 10 // xvpcnt.b
  3540  	case AXVPCNTH:
  3541  		return 0x1da709 << 10 // xvpcnt.h
  3542  	case AXVPCNTW:
  3543  		return 0x1da70a << 10 // xvpcnt.w
  3544  	case AXVPCNTV:
  3545  		return 0x1da70b << 10 // xvpcnt.v
  3546  	case AVFSQRTF:
  3547  		return 0x1ca739 << 10 // vfsqrt.s
  3548  	case AVFSQRTD:
  3549  		return 0x1ca73a << 10 // vfsqrt.d
  3550  	case AVFRECIPF:
  3551  		return 0x1ca73d << 10 // vfrecip.s
  3552  	case AVFRECIPD:
  3553  		return 0x1ca73e << 10 // vfrecip.d
  3554  	case AVFRSQRTF:
  3555  		return 0x1ca741 << 10 // vfrsqrt.s
  3556  	case AVFRSQRTD:
  3557  		return 0x1ca742 << 10 // vfrsqrt.d
  3558  	case AXVFSQRTF:
  3559  		return 0x1da739 << 10 // xvfsqrt.s
  3560  	case AXVFSQRTD:
  3561  		return 0x1da73a << 10 // xvfsqrt.d
  3562  	case AXVFRECIPF:
  3563  		return 0x1da73d << 10 // xvfrecip.s
  3564  	case AXVFRECIPD:
  3565  		return 0x1da73e << 10 // xvfrecip.d
  3566  	case AXVFRSQRTF:
  3567  		return 0x1da741 << 10 // xvfrsqrt.s
  3568  	case AXVFRSQRTD:
  3569  		return 0x1da742 << 10 // xvfrsqrt.d
  3570  	case AVNEGB:
  3571  		return 0x1ca70c << 10 // vneg.b
  3572  	case AVNEGH:
  3573  		return 0x1ca70d << 10 // vneg.h
  3574  	case AVNEGW:
  3575  		return 0x1ca70e << 10 // vneg.w
  3576  	case AVNEGV:
  3577  		return 0x1ca70f << 10 // vneg.d
  3578  	case AXVNEGB:
  3579  		return 0x1da70c << 10 // xvneg.b
  3580  	case AXVNEGH:
  3581  		return 0x1da70d << 10 // xvneg.h
  3582  	case AXVNEGW:
  3583  		return 0x1da70e << 10 // xvneg.w
  3584  	case AXVNEGV:
  3585  		return 0x1da70f << 10 // xvneg.d
  3586  	case AVSETEQV:
  3587  		return 0x1ca726<<10 | 0x0<<3 // vseteqz.v
  3588  	case AVSETNEV:
  3589  		return 0x1ca727<<10 | 0x0<<3 // vsetnez.v
  3590  	case AVSETANYEQB:
  3591  		return 0x1ca728<<10 | 0x0<<3 // vsetanyeqz.b
  3592  	case AVSETANYEQH:
  3593  		return 0x1ca729<<10 | 0x0<<3 // vsetanyeqz.h
  3594  	case AVSETANYEQW:
  3595  		return 0x1ca72a<<10 | 0x0<<3 // vsetanyeqz.w
  3596  	case AVSETANYEQV:
  3597  		return 0x1ca72b<<10 | 0x0<<3 // vsetanyeqz.d
  3598  	case AVSETALLNEB:
  3599  		return 0x1ca72c<<10 | 0x0<<3 // vsetallnez.b
  3600  	case AVSETALLNEH:
  3601  		return 0x1ca72d<<10 | 0x0<<3 // vsetallnez.h
  3602  	case AVSETALLNEW:
  3603  		return 0x1ca72e<<10 | 0x0<<3 // vsetallnez.w
  3604  	case AVSETALLNEV:
  3605  		return 0x1ca72f<<10 | 0x0<<3 // vsetallnez.d
  3606  	case AXVSETEQV:
  3607  		return 0x1da726<<10 | 0x0<<3 // xvseteqz.v
  3608  	case AXVSETNEV:
  3609  		return 0x1da727<<10 | 0x0<<3 // xvsetnez.v
  3610  	case AXVSETANYEQB:
  3611  		return 0x1da728<<10 | 0x0<<3 // xvsetanyeqz.b
  3612  	case AXVSETANYEQH:
  3613  		return 0x1da729<<10 | 0x0<<3 // xvsetanyeqz.h
  3614  	case AXVSETANYEQW:
  3615  		return 0x1da72a<<10 | 0x0<<3 // xvsetanyeqz.w
  3616  	case AXVSETANYEQV:
  3617  		return 0x1da72b<<10 | 0x0<<3 // xvsetanyeqz.d
  3618  	case AXVSETALLNEB:
  3619  		return 0x1da72c<<10 | 0x0<<3 // xvsetallnez.b
  3620  	case AXVSETALLNEH:
  3621  		return 0x1da72d<<10 | 0x0<<3 // xvsetallnez.h
  3622  	case AXVSETALLNEW:
  3623  		return 0x1da72e<<10 | 0x0<<3 // xvsetallnez.w
  3624  	case AXVSETALLNEV:
  3625  		return 0x1da72f<<10 | 0x0<<3 // xvsetallnez.d
  3626  	}
  3627  
  3628  	c.ctxt.Diag("bad rr opcode %v", a)
  3629  	return 0
  3630  }
  3631  
  3632  func (c *ctxt0) opi(a obj.As) uint32 {
  3633  	switch a {
  3634  	case ASYSCALL:
  3635  		return 0x56 << 15
  3636  	case ABREAK:
  3637  		return 0x54 << 15
  3638  	case ADBAR:
  3639  		return 0x70e4 << 15
  3640  	}
  3641  
  3642  	c.ctxt.Diag("bad ic opcode %v", a)
  3643  
  3644  	return 0
  3645  }
  3646  
  3647  func (c *ctxt0) opir(a obj.As) uint32 {
  3648  	switch a {
  3649  	case ALU12IW:
  3650  		return 0x0a << 25
  3651  	case ALU32ID:
  3652  		return 0x0b << 25
  3653  	case APCALAU12I:
  3654  		return 0x0d << 25
  3655  	case APCADDU12I:
  3656  		return 0x0e << 25
  3657  	}
  3658  	return 0
  3659  }
  3660  
  3661  func (c *ctxt0) opirr(a obj.As) uint32 {
  3662  	switch a {
  3663  	case AADD, AADDU:
  3664  		return 0x00a << 22
  3665  	case ASGT:
  3666  		return 0x008 << 22
  3667  	case ASGTU:
  3668  		return 0x009 << 22
  3669  	case AAND:
  3670  		return 0x00d << 22
  3671  	case AOR:
  3672  		return 0x00e << 22
  3673  	case ALU52ID:
  3674  		return 0x00c << 22
  3675  	case AXOR:
  3676  		return 0x00f << 22
  3677  	case ASLL:
  3678  		return 0x00081 << 15
  3679  	case ASRL:
  3680  		return 0x00089 << 15
  3681  	case ASRA:
  3682  		return 0x00091 << 15
  3683  	case AROTR:
  3684  		return 0x00099 << 15
  3685  	case AADDV:
  3686  		return 0x00b << 22
  3687  	case AADDVU:
  3688  		return 0x00b << 22
  3689  
  3690  	case AJMP:
  3691  		return 0x14 << 26
  3692  	case AJAL,
  3693  		obj.ADUFFZERO,
  3694  		obj.ADUFFCOPY:
  3695  		return 0x15 << 26
  3696  
  3697  	case AJIRL:
  3698  		return 0x13 << 26
  3699  	case ABLTU:
  3700  		return 0x1a << 26
  3701  	case ABLT, ABLTZ, ABGTZ:
  3702  		return 0x18 << 26
  3703  	case ABGEU:
  3704  		return 0x1b << 26
  3705  	case ABGE, ABGEZ, ABLEZ:
  3706  		return 0x19 << 26
  3707  	case -ABEQ: // beqz
  3708  		return 0x10 << 26
  3709  	case -ABNE: // bnez
  3710  		return 0x11 << 26
  3711  	case ABEQ:
  3712  		return 0x16 << 26
  3713  	case ABNE:
  3714  		return 0x17 << 26
  3715  	case ABFPT:
  3716  		return 0x12<<26 | 0x1<<8
  3717  	case ABFPF:
  3718  		return 0x12<<26 | 0x0<<8
  3719  
  3720  	case AMOVB,
  3721  		AMOVBU:
  3722  		return 0x0a4 << 22
  3723  	case AMOVH,
  3724  		AMOVHU:
  3725  		return 0x0a5 << 22
  3726  	case AMOVW,
  3727  		AMOVWU:
  3728  		return 0x0a6 << 22
  3729  	case AMOVV:
  3730  		return 0x0a7 << 22
  3731  	case AMOVF:
  3732  		return 0x0ad << 22
  3733  	case AMOVD:
  3734  		return 0x0af << 22
  3735  	case -AMOVB:
  3736  		return 0x0a0 << 22
  3737  	case -AMOVBU:
  3738  		return 0x0a8 << 22
  3739  	case -AMOVH:
  3740  		return 0x0a1 << 22
  3741  	case -AMOVHU:
  3742  		return 0x0a9 << 22
  3743  	case -AMOVW:
  3744  		return 0x0a2 << 22
  3745  	case -AMOVWU:
  3746  		return 0x0aa << 22
  3747  	case -AMOVV:
  3748  		return 0x0a3 << 22
  3749  	case -AMOVF:
  3750  		return 0x0ac << 22
  3751  	case -AMOVD:
  3752  		return 0x0ae << 22
  3753  	case -AVMOVQ:
  3754  		return 0x0b0 << 22 // vld
  3755  	case -AXVMOVQ:
  3756  		return 0x0b2 << 22 // xvld
  3757  	case AVMOVQ:
  3758  		return 0x0b1 << 22 // vst
  3759  	case AXVMOVQ:
  3760  		return 0x0b3 << 22 // xvst
  3761  	case ASLLV:
  3762  		return 0x0041 << 16
  3763  	case ASRLV:
  3764  		return 0x0045 << 16
  3765  	case ASRAV:
  3766  		return 0x0049 << 16
  3767  	case AROTRV:
  3768  		return 0x004d << 16
  3769  	case -ALL:
  3770  		return 0x020 << 24
  3771  	case -ALLV:
  3772  		return 0x022 << 24
  3773  	case ASC:
  3774  		return 0x021 << 24
  3775  	case ASCV:
  3776  		return 0x023 << 24
  3777  	case AVANDB:
  3778  		return 0x1CF4 << 18 // vandi.b
  3779  	case AVORB:
  3780  		return 0x1CF5 << 18 // vori.b
  3781  	case AVXORB:
  3782  		return 0x1CF6 << 18 // xori.b
  3783  	case AVNORB:
  3784  		return 0x1CF7 << 18 // xnori.b
  3785  	case AXVANDB:
  3786  		return 0x1DF4 << 18 // xvandi.b
  3787  	case AXVORB:
  3788  		return 0x1DF5 << 18 // xvori.b
  3789  	case AXVXORB:
  3790  		return 0x1DF6 << 18 // xvxori.b
  3791  	case AXVNORB:
  3792  		return 0x1DF7 << 18 // xvnor.b
  3793  	case AVSEQB:
  3794  		return 0x0E500 << 15 //vseqi.b
  3795  	case AVSEQH:
  3796  		return 0x0E501 << 15 // vseqi.h
  3797  	case AVSEQW:
  3798  		return 0x0E502 << 15 //vseqi.w
  3799  	case AVSEQV:
  3800  		return 0x0E503 << 15 //vseqi.d
  3801  	case AXVSEQB:
  3802  		return 0x0ED00 << 15 //xvseqi.b
  3803  	case AXVSEQH:
  3804  		return 0x0ED01 << 15 // xvseqi.h
  3805  	case AXVSEQW:
  3806  		return 0x0ED02 << 15 // xvseqi.w
  3807  	case AXVSEQV:
  3808  		return 0x0ED03 << 15 // xvseqi.d
  3809  	case AVROTRB:
  3810  		return 0x1ca8<<18 | 0x1<<13 // vrotri.b
  3811  	case AVROTRH:
  3812  		return 0x1ca8<<18 | 0x1<<14 // vrotri.h
  3813  	case AVROTRW:
  3814  		return 0x1ca8<<18 | 0x1<<15 // vrotri.w
  3815  	case AVROTRV:
  3816  		return 0x1ca8<<18 | 0x1<<16 // vrotri.d
  3817  	case AXVROTRB:
  3818  		return 0x1da8<<18 | 0x1<<13 // xvrotri.b
  3819  	case AXVROTRH:
  3820  		return 0x1da8<<18 | 0x1<<14 // xvrotri.h
  3821  	case AXVROTRW:
  3822  		return 0x1da8<<18 | 0x1<<15 // xvrotri.w
  3823  	case AXVROTRV:
  3824  		return 0x1da8<<18 | 0x1<<16 // xvrotri.d
  3825  	case AVSLLB:
  3826  		return 0x1ccb<<18 | 0x1<<13 // vslli.b
  3827  	case AVSLLH:
  3828  		return 0x1ccb<<18 | 0x1<<14 // vslli.h
  3829  	case AVSLLW:
  3830  		return 0x1ccb<<18 | 0x1<<15 // vslli.w
  3831  	case AVSLLV:
  3832  		return 0x1ccb<<18 | 0x1<<16 // vslli.d
  3833  	case AVSRLB:
  3834  		return 0x1ccc<<18 | 0x1<<13 // vsrli.b
  3835  	case AVSRLH:
  3836  		return 0x1ccc<<18 | 0x1<<14 // vsrli.h
  3837  	case AVSRLW:
  3838  		return 0x1ccc<<18 | 0x1<<15 // vsrli.w
  3839  	case AVSRLV:
  3840  		return 0x1ccc<<18 | 0x1<<16 // vsrli.d
  3841  	case AVSRAB:
  3842  		return 0x1ccd<<18 | 0x1<<13 // vsrai.b
  3843  	case AVSRAH:
  3844  		return 0x1ccd<<18 | 0x1<<14 // vsrai.h
  3845  	case AVSRAW:
  3846  		return 0x1ccd<<18 | 0x1<<15 // vsrai.w
  3847  	case AVSRAV:
  3848  		return 0x1ccd<<18 | 0x1<<16 // vsrai.d
  3849  	case AXVSLLB:
  3850  		return 0x1dcb<<18 | 0x1<<13 // xvslli.b
  3851  	case AXVSLLH:
  3852  		return 0x1dcb<<18 | 0x1<<14 // xvslli.h
  3853  	case AXVSLLW:
  3854  		return 0x1dcb<<18 | 0x1<<15 // xvslli.w
  3855  	case AXVSLLV:
  3856  		return 0x1dcb<<18 | 0x1<<16 // xvslli.d
  3857  	case AXVSRLB:
  3858  		return 0x1dcc<<18 | 0x1<<13 // xvsrli.b
  3859  	case AXVSRLH:
  3860  		return 0x1dcc<<18 | 0x1<<14 // xvsrli.h
  3861  	case AXVSRLW:
  3862  		return 0x1dcc<<18 | 0x1<<15 // xvsrli.w
  3863  	case AXVSRLV:
  3864  		return 0x1dcc<<18 | 0x1<<16 // xvsrli.d
  3865  	case AXVSRAB:
  3866  		return 0x1dcd<<18 | 0x1<<13 // xvsrai.b
  3867  	case AXVSRAH:
  3868  		return 0x1dcd<<18 | 0x1<<14 // xvsrai.h
  3869  	case AXVSRAW:
  3870  		return 0x1dcd<<18 | 0x1<<15 // xvsrai.w
  3871  	case AXVSRAV:
  3872  		return 0x1dcd<<18 | 0x1<<16 // xvsrai.d
  3873  	case AVADDBU:
  3874  		return 0xe514 << 15 // vaddi.bu
  3875  	case AVADDHU:
  3876  		return 0xe515 << 15 // vaddi.hu
  3877  	case AVADDWU:
  3878  		return 0xe516 << 15 // vaddi.wu
  3879  	case AVADDVU:
  3880  		return 0xe517 << 15 // vaddi.du
  3881  	case AVSUBBU:
  3882  		return 0xe518 << 15 // vsubi.bu
  3883  	case AVSUBHU:
  3884  		return 0xe519 << 15 // vsubi.hu
  3885  	case AVSUBWU:
  3886  		return 0xe51a << 15 // vsubi.wu
  3887  	case AVSUBVU:
  3888  		return 0xe51b << 15 // vsubi.du
  3889  	case AXVADDBU:
  3890  		return 0xed14 << 15 // xvaddi.bu
  3891  	case AXVADDHU:
  3892  		return 0xed15 << 15 // xvaddi.hu
  3893  	case AXVADDWU:
  3894  		return 0xed16 << 15 // xvaddi.wu
  3895  	case AXVADDVU:
  3896  		return 0xed17 << 15 // xvaddi.du
  3897  	case AXVSUBBU:
  3898  		return 0xed18 << 15 // xvsubi.bu
  3899  	case AXVSUBHU:
  3900  		return 0xed19 << 15 // xvsubi.hu
  3901  	case AXVSUBWU:
  3902  		return 0xed1a << 15 // xvsubi.wu
  3903  	case AXVSUBVU:
  3904  		return 0xed1b << 15 // xvsubi.du
  3905  	case AVSHUF4IB:
  3906  		return 0x1ce4 << 18 // vshuf4i.b
  3907  	case AVSHUF4IH:
  3908  		return 0x1ce5 << 18 // vshuf4i.h
  3909  	case AVSHUF4IW:
  3910  		return 0x1ce6 << 18 // vshuf4i.w
  3911  	case AVSHUF4IV:
  3912  		return 0x1ce7 << 18 // vshuf4i.d
  3913  	case AXVSHUF4IB:
  3914  		return 0x1de4 << 18 // xvshuf4i.b
  3915  	case AXVSHUF4IH:
  3916  		return 0x1de5 << 18 // xvshuf4i.h
  3917  	case AXVSHUF4IW:
  3918  		return 0x1de6 << 18 // xvshuf4i.w
  3919  	case AXVSHUF4IV:
  3920  		return 0x1de7 << 18 // xvshuf4i.d
  3921  	}
  3922  
  3923  	if a < 0 {
  3924  		c.ctxt.Diag("bad irr opcode -%v", -a)
  3925  	} else {
  3926  		c.ctxt.Diag("bad irr opcode %v", a)
  3927  	}
  3928  	return 0
  3929  }
  3930  
  3931  func (c *ctxt0) opirir(a obj.As) uint32 {
  3932  	switch a {
  3933  	case ABSTRINSW:
  3934  		return 0x3<<21 | 0x0<<15 // bstrins.w
  3935  	case ABSTRINSV:
  3936  		return 0x2 << 22 // bstrins.d
  3937  	case ABSTRPICKW:
  3938  		return 0x3<<21 | 0x1<<15 // bstrpick.w
  3939  	case ABSTRPICKV:
  3940  		return 0x3 << 22 // bstrpick.d
  3941  	}
  3942  
  3943  	return 0
  3944  }
  3945  
  3946  func (c *ctxt0) specialFpMovInst(a obj.As, fclass int, tclass int) uint32 {
  3947  	switch a {
  3948  	case AMOVV:
  3949  		switch fclass {
  3950  		case C_REG:
  3951  			switch tclass {
  3952  			case C_FREG:
  3953  				return 0x452a << 10 // movgr2fr.d
  3954  			case C_FCCREG:
  3955  				return 0x4536 << 10 // movgr2cf
  3956  			case C_FCSRREG:
  3957  				return 0x4530 << 10 // movgr2fcsr
  3958  			}
  3959  		case C_FREG:
  3960  			switch tclass {
  3961  			case C_REG:
  3962  				return 0x452e << 10 // movfr2gr.d
  3963  			case C_FCCREG:
  3964  				return 0x4534 << 10 // movfr2cf
  3965  			}
  3966  		case C_FCCREG:
  3967  			switch tclass {
  3968  			case C_REG:
  3969  				return 0x4537 << 10 // movcf2gr
  3970  			case C_FREG:
  3971  				return 0x4535 << 10 // movcf2fr
  3972  			}
  3973  		case C_FCSRREG:
  3974  			switch tclass {
  3975  			case C_REG:
  3976  				return 0x4532 << 10 // movfcsr2gr
  3977  			}
  3978  		}
  3979  
  3980  	case AMOVW:
  3981  		switch fclass {
  3982  		case C_REG:
  3983  			switch tclass {
  3984  			case C_FREG:
  3985  				return 0x4529 << 10 // movgr2fr.w
  3986  			}
  3987  		case C_FREG:
  3988  			switch tclass {
  3989  			case C_REG:
  3990  				return 0x452d << 10 // movfr2gr.s
  3991  			}
  3992  		}
  3993  	}
  3994  
  3995  	c.ctxt.Diag("bad class combination: %s %s,%s\n", a, fclass, tclass)
  3996  
  3997  	return 0
  3998  }
  3999  
  4000  func (c *ctxt0) specialLsxMovInst(a obj.As, fReg, tReg int16) (op_code, index_mask uint32) {
  4001  	farng := (fReg >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK
  4002  	tarng := (tReg >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK
  4003  	fclass := c.rclass(fReg)
  4004  	tclass := c.rclass(tReg)
  4005  
  4006  	switch fclass | (tclass << 16) {
  4007  	case C_REG | (C_ELEM << 16):
  4008  		// vmov Rn, Vd.<T>[index]
  4009  		switch a {
  4010  		case AVMOVQ:
  4011  			switch tarng {
  4012  			case ARNG_B:
  4013  				return (0x01CBAE << 14), 0xf // vinsgr2vr.b
  4014  			case ARNG_H:
  4015  				return (0x03975E << 13), 0x7 // vinsgr2vr.h
  4016  			case ARNG_W:
  4017  				return (0x072EBE << 12), 0x3 // vinsgr2vr.w
  4018  			case ARNG_V:
  4019  				return (0x0E5D7E << 11), 0x1 // vinsgr2vr.d
  4020  			}
  4021  		case AXVMOVQ:
  4022  			switch tarng {
  4023  			case ARNG_W:
  4024  				return (0x03B75E << 13), 0x7 // xvinsgr2vr.w
  4025  			case ARNG_V:
  4026  				return (0x076EBE << 12), 0x3 // xvinsgr2vr.d
  4027  			}
  4028  		}
  4029  
  4030  	case C_ELEM | (C_REG << 16):
  4031  		// vmov Vd.<T>[index], Rn
  4032  		switch a {
  4033  		case AVMOVQ:
  4034  			switch farng {
  4035  			case ARNG_B:
  4036  				return (0x01CBBE << 14), 0xf // vpickve2gr.b
  4037  			case ARNG_H:
  4038  				return (0x03977E << 13), 0x7 // vpickve2gr.h
  4039  			case ARNG_W:
  4040  				return (0x072EFE << 12), 0x3 // vpickve2gr.w
  4041  			case ARNG_V:
  4042  				return (0x0E5DFE << 11), 0x1 // vpickve2gr.d
  4043  			case ARNG_BU:
  4044  				return (0x01CBCE << 14), 0xf // vpickve2gr.bu
  4045  			case ARNG_HU:
  4046  				return (0x03979E << 13), 0x7 // vpickve2gr.hu
  4047  			case ARNG_WU:
  4048  				return (0x072F3E << 12), 0x3 // vpickve2gr.wu
  4049  			case ARNG_VU:
  4050  				return (0x0E5E7E << 11), 0x1 // vpickve2gr.du
  4051  			}
  4052  		case AXVMOVQ:
  4053  			switch farng {
  4054  			case ARNG_W:
  4055  				return (0x03B77E << 13), 0x7 // xvpickve2gr.w
  4056  			case ARNG_V:
  4057  				return (0x076EFE << 12), 0x3 // xvpickve2gr.d
  4058  			case ARNG_WU:
  4059  				return (0x03B79E << 13), 0x7 // xvpickve2gr.wu
  4060  			case ARNG_VU:
  4061  				return (0x076F3E << 12), 0x3 // xvpickve2gr.du
  4062  			}
  4063  		}
  4064  
  4065  	case C_REG | (C_ARNG << 16):
  4066  		// vmov Rn, Vd.<T>
  4067  		switch a {
  4068  		case AVMOVQ:
  4069  			switch tarng {
  4070  			case ARNG_16B:
  4071  				return (0x1CA7C0 << 10), 0x0 // vreplgr2vr.b
  4072  			case ARNG_8H:
  4073  				return (0x1CA7C1 << 10), 0x0 // vreplgr2vr.h
  4074  			case ARNG_4W:
  4075  				return (0x1CA7C2 << 10), 0x0 // vreplgr2vr.w
  4076  			case ARNG_2V:
  4077  				return (0x1CA7C3 << 10), 0x0 // vreplgr2vr.d
  4078  			}
  4079  		case AXVMOVQ:
  4080  			switch tarng {
  4081  			case ARNG_32B:
  4082  				return (0x1DA7C0 << 10), 0x0 // xvreplgr2vr.b
  4083  			case ARNG_16H:
  4084  				return (0x1DA7C1 << 10), 0x0 // xvreplgr2vr.h
  4085  			case ARNG_8W:
  4086  				return (0x1DA7C2 << 10), 0x0 // xvreplgr2vr.w
  4087  			case ARNG_4V:
  4088  				return (0x1DA7C3 << 10), 0x0 // xvreplgr2vr.d
  4089  			}
  4090  		}
  4091  
  4092  	case C_XREG | (C_ARNG << 16):
  4093  		// vmov  xj, xd.<T>
  4094  		switch a {
  4095  		case AVMOVQ:
  4096  			return 0, 0 // unsupported op
  4097  		case AXVMOVQ:
  4098  			switch tarng {
  4099  			case ARNG_32B:
  4100  				return (0x1DC1C0 << 10), 0x0 // xvreplve0.b
  4101  			case ARNG_16H:
  4102  				return (0x1DC1E0 << 10), 0x0 // xvreplve0.h
  4103  			case ARNG_8W:
  4104  				return (0x1DC1F0 << 10), 0x0 // xvreplve0.w
  4105  			case ARNG_4V:
  4106  				return (0x1DC1F8 << 10), 0x0 // xvreplve0.d
  4107  			case ARNG_2Q:
  4108  				return (0x1DC1FC << 10), 0x0 // xvreplve0.q
  4109  			}
  4110  		}
  4111  
  4112  	case C_XREG | (C_ELEM << 16):
  4113  		// vmov  xj, xd.<T>[index]
  4114  		switch a {
  4115  		case AVMOVQ:
  4116  			return 0, 0 // unsupported op
  4117  		case AXVMOVQ:
  4118  			switch tarng {
  4119  			case ARNG_W:
  4120  				return (0x03B7FE << 13), 0x7 // xvinsve0.w
  4121  			case ARNG_V:
  4122  				return (0x076FFE << 12), 0x3 // xvinsve0.d
  4123  			}
  4124  		}
  4125  
  4126  	case C_ELEM | (C_XREG << 16):
  4127  		// vmov  xj.<T>[index], xd
  4128  		switch a {
  4129  		case AVMOVQ:
  4130  			return 0, 0 // unsupported op
  4131  		case AXVMOVQ:
  4132  			switch farng {
  4133  			case ARNG_W:
  4134  				return (0x03B81E << 13), 0x7 // xvpickve.w
  4135  			case ARNG_V:
  4136  				return (0x07703E << 12), 0x3 // xvpickve.d
  4137  			}
  4138  		}
  4139  
  4140  	case C_ELEM | (C_ARNG << 16):
  4141  		// vmov  vj.<T>[index], vd.<T>
  4142  		switch a {
  4143  		case AVMOVQ:
  4144  			switch int32(farng) | (int32(tarng) << 16) {
  4145  			case int32(ARNG_B) | (int32(ARNG_16B) << 16):
  4146  				return (0x01CBDE << 14), 0xf // vreplvei.b
  4147  			case int32(ARNG_H) | (int32(ARNG_8H) << 16):
  4148  				return (0x0397BE << 13), 0x7 // vreplvei.h
  4149  			case int32(ARNG_W) | (int32(ARNG_4W) << 16):
  4150  				return (0x072F7E << 12), 0x3 // vreplvei.w
  4151  			case int32(ARNG_V) | (int32(ARNG_2V) << 16):
  4152  				return (0x0E5EFE << 11), 0x1 // vreplvei.d
  4153  			}
  4154  		case AXVMOVQ:
  4155  			return 0, 0 // unsupported op
  4156  		}
  4157  	}
  4158  
  4159  	return 0, 0
  4160  }
  4161  
  4162  func vshift(a obj.As) bool {
  4163  	switch a {
  4164  	case ASLLV,
  4165  		ASRLV,
  4166  		ASRAV,
  4167  		AROTRV:
  4168  		return true
  4169  	}
  4170  	return false
  4171  }
  4172  

View as plain text