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

View as plain text