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  	{ASUB, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    60  	{ASUB, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    61  
    62  	{AADD, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    63  	{AADD, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    64  	{AADD, C_US12CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
    65  	{AADD, C_US12CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
    66  	{AADD, C_U12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
    67  	{AADD, C_U12CON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
    68  	{AADD, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
    69  	{AADD, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
    70  	{AADD, C_32CON20_0, C_REG, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
    71  	{AADD, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
    72  
    73  	{AADDV, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    74  	{AADDV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    75  	{AADDV, C_US12CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
    76  	{AADDV, C_US12CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
    77  	{AADDV, C_U12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
    78  	{AADDV, C_U12CON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
    79  	{AADDV, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
    80  	{AADDV, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
    81  	{AADDV, C_32CON20_0, C_REG, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
    82  	{AADDV, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
    83  	{AADDV, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 60, 20, 0, 0},
    84  	{AADDV, C_DCON, C_REG, C_NONE, C_REG, C_NONE, 60, 20, 0, 0},
    85  	{AADDV, C_DCON12_0, C_NONE, C_NONE, C_REG, C_NONE, 70, 8, 0, 0},
    86  	{AADDV, C_DCON12_0, C_REG, C_NONE, C_REG, C_NONE, 70, 8, 0, 0},
    87  	{AADDV, C_DCON12_20S, C_NONE, C_NONE, C_REG, C_NONE, 71, 12, 0, 0},
    88  	{AADDV, C_DCON12_20S, C_REG, C_NONE, C_REG, C_NONE, 71, 12, 0, 0},
    89  	{AADDV, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 72, 16, 0, 0},
    90  	{AADDV, C_DCON32_12S, C_REG, C_NONE, C_REG, C_NONE, 72, 16, 0, 0},
    91  
    92  	{AAND, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    93  	{AAND, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
    94  	{AAND, C_UU12CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
    95  	{AAND, C_UU12CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
    96  	{AAND, C_S12CON, C_REG, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
    97  	{AAND, C_S12CON, C_NONE, C_NONE, C_REG, C_NONE, 10, 8, 0, 0},
    98  	{AAND, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
    99  	{AAND, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 24, 12, 0, 0},
   100  	{AAND, C_32CON20_0, C_REG, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
   101  	{AAND, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 26, 8, 0, 0},
   102  	{AAND, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 60, 20, 0, 0},
   103  	{AAND, C_DCON, C_REG, C_NONE, C_REG, C_NONE, 60, 20, 0, 0},
   104  	{AAND, C_DCON12_0, C_NONE, C_NONE, C_REG, C_NONE, 70, 8, 0, 0},
   105  	{AAND, C_DCON12_0, C_REG, C_NONE, C_REG, C_NONE, 70, 8, 0, 0},
   106  	{AAND, C_DCON12_20S, C_NONE, C_NONE, C_REG, C_NONE, 71, 12, 0, 0},
   107  	{AAND, C_DCON12_20S, C_REG, C_NONE, C_REG, C_NONE, 71, 12, 0, 0},
   108  	{AAND, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 72, 16, 0, 0},
   109  	{AAND, C_DCON32_12S, C_REG, C_NONE, C_REG, C_NONE, 72, 16, 0, 0},
   110  
   111  	{ASLL, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
   112  	{ASLL, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
   113  	{ASLL, C_U5CON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
   114  	{ASLL, C_U5CON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
   115  	{ASLLV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
   116  	{ASLLV, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
   117  	{ASLLV, C_U6CON, C_REG, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
   118  	{ASLLV, C_U6CON, C_NONE, C_NONE, C_REG, C_NONE, 16, 4, 0, 0},
   119  
   120  	{AADDV16, C_32CON, C_REG, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
   121  	{AADDV16, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 4, 4, 0, 0},
   122  
   123  	// memory access
   124  	{AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
   125  	{AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
   126  	{AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
   127  	{AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
   128  	{AMOVB, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0},
   129  	{AMOVB, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0},
   130  	{AMOVB, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   131  	{AMOVB, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
   132  	{AMOVB, C_REG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   133  	{AMOVB, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
   134  	// variable access
   135  	{AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   136  	{AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
   137  	// TLS access
   138  	{AMOVB, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
   139  	{AMOVB, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
   140  	{AMOVB, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
   141  	{AMOVB, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
   142  	// moving data between registers
   143  	{AMOVB, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 1, 4, 0, 0},
   144  
   145  	// memory access
   146  	{AMOVBU, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
   147  	{AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0},
   148  	{AMOVBU, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
   149  	{AMOVBU, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   150  	{AMOVBU, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
   151  	{AMOVBU, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0},
   152  	{AMOVBU, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
   153  	{AMOVBU, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
   154  	{AMOVBU, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
   155  	// variable access
   156  	{AMOVBU, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   157  	{AMOVBU, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
   158  	// TLS access
   159  	{AMOVBU, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
   160  	{AMOVBU, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
   161  	{AMOVBU, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
   162  	{AMOVBU, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
   163  	// moving data between registers
   164  	{AMOVBU, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 1, 4, 0, 0},
   165  
   166  	// memory access
   167  	{AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
   168  	{AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
   169  	{AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
   170  	{AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
   171  	{AMOVW, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0},
   172  	{AMOVW, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0},
   173  	{AMOVW, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   174  	{AMOVW, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
   175  	{AMOVW, C_REG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   176  	{AMOVW, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
   177  	// variable access
   178  	{AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   179  	{AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
   180  	// TLS access
   181  	{AMOVW, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
   182  	{AMOVW, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
   183  	{AMOVW, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
   184  	{AMOVW, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
   185  	// moving data between registers
   186  	{AMOVW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 1, 4, 0, 0},
   187  	{AMOVW, C_REG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
   188  	{AMOVW, C_FREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
   189  	// immediate load
   190  	{AMOVW, C_12CON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0},
   191  	{AMOVW, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP},
   192  	{AMOVW, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 25, 4, 0, 0},
   193  	{AMOVW, C_12CON, C_NONE, C_NONE, C_FREG, C_NONE, 34, 8, 0, 0},
   194  	// get a stack address
   195  	{AMOVW, C_SACON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGSP, 0},
   196  	{AMOVW, C_LACON, C_NONE, C_NONE, C_REG, C_NONE, 27, 12, REGSP, 0},
   197  
   198  	// memory access
   199  	{AMOVV, C_REG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGSP, 0},
   200  	{AMOVV, C_REG, C_NONE, C_NONE, C_LAUTO, C_NONE, 35, 12, REGSP, 0},
   201  	{AMOVV, C_SAUTO, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGSP, 0},
   202  	{AMOVV, C_LAUTO, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGSP, 0},
   203  	{AMOVV, C_REG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0},
   204  	{AMOVV, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 35, 12, REGZERO, 0},
   205  	{AMOVV, C_SOREG_12, C_NONE, C_NONE, C_REG, C_NONE, 8, 4, REGZERO, 0},
   206  	{AMOVV, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 36, 12, REGZERO, 0},
   207  	{AMOVV, C_REG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   208  	{AMOVV, C_ROFF, C_NONE, C_NONE, C_REG, C_NONE, 21, 4, 0, 0},
   209  	// variable access, need relocation
   210  	{AMOVV, C_REG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   211  	{AMOVV, C_ADDR, C_NONE, C_NONE, C_REG, C_NONE, 51, 8, 0, 0},
   212  	// TLS access
   213  	{AMOVV, C_REG, C_NONE, C_NONE, C_TLS_LE, C_NONE, 53, 16, 0, 0},
   214  	{AMOVV, C_TLS_LE, C_NONE, C_NONE, C_REG, C_NONE, 54, 16, 0, 0},
   215  	{AMOVV, C_REG, C_NONE, C_NONE, C_TLS_IE, C_NONE, 56, 16, 0, 0},
   216  	{AMOVV, C_TLS_IE, C_NONE, C_NONE, C_REG, C_NONE, 57, 16, 0, 0},
   217  	// moving data between registers
   218  	{AMOVV, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 1, 4, 0, 0},
   219  	{AMOVV, C_FCCREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
   220  	{AMOVV, C_FCSRREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
   221  	{AMOVV, C_REG, C_NONE, C_NONE, C_FCCREG, C_NONE, 30, 4, 0, 0},
   222  	{AMOVV, C_REG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
   223  	{AMOVV, C_FREG, C_NONE, C_NONE, C_REG, C_NONE, 30, 4, 0, 0},
   224  	{AMOVV, C_REG, C_NONE, C_NONE, C_FCSRREG, C_NONE, 30, 4, 0, 0},
   225  	{AMOVV, C_FREG, C_NONE, C_NONE, C_FCCREG, C_NONE, 30, 4, 0, 0},
   226  	{AMOVV, C_FCCREG, C_NONE, C_NONE, C_FREG, C_NONE, 30, 4, 0, 0},
   227  	// immediate load
   228  	{AMOVV, C_12CON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGZERO, 0},
   229  	{AMOVV, C_32CON, C_NONE, C_NONE, C_REG, C_NONE, 19, 8, 0, NOTUSETMP},
   230  	{AMOVV, C_32CON20_0, C_NONE, C_NONE, C_REG, C_NONE, 25, 4, 0, 0},
   231  	{AMOVV, C_DCON12_0, C_NONE, C_NONE, C_REG, C_NONE, 67, 4, 0, NOTUSETMP},
   232  	{AMOVV, C_DCON12_20S, C_NONE, C_NONE, C_REG, C_NONE, 68, 8, 0, NOTUSETMP},
   233  	{AMOVV, C_DCON32_12S, C_NONE, C_NONE, C_REG, C_NONE, 69, 12, 0, NOTUSETMP},
   234  	{AMOVV, C_DCON, C_NONE, C_NONE, C_REG, C_NONE, 59, 16, 0, NOTUSETMP},
   235  	// get a stack address
   236  	{AMOVV, C_SACON, C_NONE, C_NONE, C_REG, C_NONE, 3, 4, REGSP, 0},
   237  	{AMOVV, C_LACON, C_NONE, C_NONE, C_REG, C_NONE, 27, 12, REGSP, 0},
   238  	// get an external address, need relocation
   239  	{AMOVV, C_EXTADDR, C_NONE, C_NONE, C_REG, C_NONE, 52, 8, 0, NOTUSETMP},
   240  	// get a got address, need relocation
   241  	{AMOVV, C_GOTADDR, C_NONE, C_NONE, C_REG, C_NONE, 65, 8, 0, 0},
   242  
   243  	// memory access
   244  	{AVMOVQ, C_VREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGZERO, 0},
   245  	{AVMOVQ, C_VREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0},
   246  	{AVMOVQ, C_SAUTO, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0},
   247  	{AVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_VREG, C_NONE, 8, 4, REGZERO, 0},
   248  	{AVMOVQ, C_VREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   249  	{AVMOVQ, C_ROFF, C_NONE, C_NONE, C_VREG, C_NONE, 21, 4, 0, 0},
   250  	{AVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, // vldrepl.{b/h/w/d}
   251  	// moving data between registers
   252  	{AVMOVQ, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 1, 4, 0, 0},
   253  	{AVMOVQ, C_REG, C_NONE, C_NONE, C_ELEM, C_NONE, 39, 4, 0, 0},  // vinsgr2vr.{b/h/w/d}
   254  	{AVMOVQ, C_ELEM, C_NONE, C_NONE, C_REG, C_NONE, 40, 4, 0, 0},  // vpickve2gr.{b/h/w/d}
   255  	{AVMOVQ, C_REG, C_NONE, C_NONE, C_ARNG, C_NONE, 41, 4, 0, 0},  // vreplgr2vr.{b/h/w/d}
   256  	{AVMOVQ, C_ELEM, C_NONE, C_NONE, C_ARNG, C_NONE, 45, 4, 0, 0}, // vreplvei.{b/h/w/d}
   257  
   258  	// memory access
   259  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 7, 4, REGZERO, 0},
   260  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 7, 4, REGZERO, 0},
   261  	{AXVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0},
   262  	{AXVMOVQ, C_SAUTO, C_NONE, C_NONE, C_XREG, C_NONE, 8, 4, REGZERO, 0},
   263  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   264  	{AXVMOVQ, C_ROFF, C_NONE, C_NONE, C_XREG, C_NONE, 21, 4, 0, 0},
   265  	{AXVMOVQ, C_SOREG_12, C_NONE, C_NONE, C_ARNG, C_NONE, 46, 4, 0, 0}, // xvldrepl.{b/h/w/d}
   266  	// moving data between registers
   267  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 1, 4, 0, 0},
   268  	{AXVMOVQ, C_REG, C_NONE, C_NONE, C_ELEM, C_NONE, 39, 4, 0, 0},  // vinsgr2vr.{b/h/w/d}
   269  	{AXVMOVQ, C_ELEM, C_NONE, C_NONE, C_REG, C_NONE, 40, 4, 0, 0},  // vpickve2gr.{b/h/w/d}
   270  	{AXVMOVQ, C_REG, C_NONE, C_NONE, C_ARNG, C_NONE, 41, 4, 0, 0},  // xvreplgr2vr.{b/h/w/d}
   271  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_ARNG, C_NONE, 42, 4, 0, 0}, // xvreplve0.{b/h/w/d/q}
   272  	{AXVMOVQ, C_XREG, C_NONE, C_NONE, C_ELEM, C_NONE, 43, 4, 0, 0}, // xvinsve0.{w/d}
   273  	{AXVMOVQ, C_ELEM, C_NONE, C_NONE, C_XREG, C_NONE, 44, 4, 0, 0}, // xvpickve.{w/d}
   274  
   275  	// memory access
   276  	{AMOVWP, C_REG, C_NONE, C_NONE, C_SOREG_16, C_NONE, 73, 4, 0, 0},
   277  	{AMOVWP, C_REG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 73, 12, 0, 0},
   278  	{AMOVWP, C_REG, C_NONE, C_NONE, C_LOREG_64, C_NONE, 73, 24, 0, 0},
   279  	{AMOVWP, C_SOREG_16, C_NONE, C_NONE, C_REG, C_NONE, 74, 4, 0, 0},
   280  	{AMOVWP, C_LOREG_32, C_NONE, C_NONE, C_REG, C_NONE, 74, 12, 0, 0},
   281  	{AMOVWP, C_LOREG_64, C_NONE, C_NONE, C_REG, C_NONE, 74, 24, 0, 0},
   282  
   283  	// condition branch
   284  	{ABEQ, C_REG, C_REG, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
   285  	{ABEQ, C_REG, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
   286  	{ABLEZ, C_REG, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
   287  	{ABFPT, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
   288  	{ABFPT, C_FCCREG, C_NONE, C_NONE, C_BRAN, C_NONE, 6, 4, 0, 0},
   289  	// jmp and call
   290  	{AJMP, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 11, 4, 0, 0},        // b
   291  	{AJAL, C_NONE, C_NONE, C_NONE, C_BRAN, C_NONE, 11, 4, 0, 0},        // bl
   292  	{AJMP, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 18, 4, REGZERO, 0}, // jirl r0, rj, 0
   293  	{AJAL, C_NONE, C_NONE, C_NONE, C_ZOREG, C_NONE, 18, 4, REGLINK, 0}, // jirl r1, rj, 0
   294  
   295  	{ABSTRPICKW, C_U6CON, C_REG, C_U6CON, C_REG, C_NONE, 17, 4, 0, 0},
   296  	{ABSTRPICKW, C_U6CON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0},
   297  	{ABSTRPICKW, C_ZCON, C_REG, C_ZCON, C_REG, C_NONE, 17, 4, 0, 0},
   298  
   299  	// preload
   300  	{APRELD, C_SOREG_12, C_U5CON, C_NONE, C_NONE, C_NONE, 47, 4, 0, 0},
   301  	{APRELDX, C_SOREG_16, C_DCON, C_U5CON, C_NONE, C_NONE, 48, 20, 0, 0},
   302  
   303  	{AMASKEQZ, C_REG, C_REG, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
   304  
   305  	{ACMPEQF, C_FREG, C_FREG, C_NONE, C_FCCREG, C_NONE, 2, 4, 0, 0},
   306  
   307  	{ARDTIMELW, C_NONE, C_NONE, C_NONE, C_REG, C_REG, 62, 4, 0, 0},
   308  
   309  	{AALSLV, C_U3CON, C_REG, C_REG, C_REG, C_NONE, 64, 4, 0, 0},
   310  
   311  	{AAMSWAPW, C_REG, C_NONE, C_NONE, C_ZOREG, C_REG, 66, 4, 0, 0},
   312  
   313  	{ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
   314  	{ASYSCALL, C_U15CON, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0, 0},
   315  
   316  	{AFMADDF, C_FREG, C_FREG, C_NONE, C_FREG, C_NONE, 37, 4, 0, 0},
   317  	{AFMADDF, C_FREG, C_FREG, C_FREG, C_FREG, C_NONE, 37, 4, 0, 0},
   318  
   319  	{AADDF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 2, 4, 0, 0},
   320  	{AADDF, C_FREG, C_FREG, C_NONE, C_FREG, C_NONE, 2, 4, 0, 0},
   321  
   322  	{AFSEL, C_FCCREG, C_FREG, C_FREG, C_FREG, C_NONE, 33, 4, 0, 0},
   323  	{AFSEL, C_FCCREG, C_FREG, C_NONE, C_FREG, C_NONE, 33, 4, 0, 0},
   324  
   325  	{ACLOW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 9, 4, 0, 0},
   326  	{AABSF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0},
   327  
   328  	{AVSETEQV, C_VREG, C_NONE, C_NONE, C_FCCREG, C_NONE, 9, 4, 0, 0},
   329  	{AXVSETEQV, C_XREG, C_NONE, C_NONE, C_FCCREG, C_NONE, 9, 4, 0, 0},
   330  
   331  	{AVPCNTB, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 9, 4, 0, 0},
   332  	{AXVPCNTB, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 9, 4, 0, 0},
   333  
   334  	// memory access
   335  	{AMOVF, C_SOREG_12, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGZERO, 0},
   336  	{AMOVF, C_LOREG_32, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGZERO, 0},
   337  	{AMOVF, C_FREG, C_NONE, C_NONE, C_SOREG_12, C_NONE, 29, 4, REGZERO, 0},
   338  	{AMOVF, C_FREG, C_NONE, C_NONE, C_LOREG_32, C_NONE, 29, 12, REGZERO, 0},
   339  	{AMOVF, C_FREG, C_NONE, C_NONE, C_ROFF, C_NONE, 20, 4, 0, 0},
   340  	{AMOVF, C_ROFF, C_NONE, C_NONE, C_FREG, C_NONE, 21, 4, 0, 0},
   341  	// variable access
   342  	{AMOVF, C_FREG, C_NONE, C_NONE, C_ADDR, C_NONE, 50, 8, 0, 0},
   343  	{AMOVF, C_ADDR, C_NONE, C_NONE, C_FREG, C_NONE, 51, 8, 0, 0},
   344  	// moving data between registers
   345  	{AMOVF, C_FREG, C_NONE, C_NONE, C_FREG, C_NONE, 9, 4, 0, 0},
   346  	// load data from stack
   347  	{AMOVF, C_SAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 4, REGSP, 0},
   348  	{AMOVF, C_LAUTO, C_NONE, C_NONE, C_FREG, C_NONE, 28, 12, REGSP, 0},
   349  	// store data to stack
   350  	{AMOVF, C_FREG, C_NONE, C_NONE, C_SAUTO, C_NONE, 29, 4, REGSP, 0},
   351  	{AMOVF, C_FREG, C_NONE, C_NONE, C_LAUTO, C_NONE, 29, 12, REGSP, 0},
   352  
   353  	{AVSHUFB, C_VREG, C_VREG, C_VREG, C_VREG, C_NONE, 37, 4, 0, 0},
   354  	{AXVSHUFB, C_XREG, C_XREG, C_XREG, C_XREG, C_NONE, 37, 4, 0, 0},
   355  
   356  	{AVSEQB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   357  	{AVSEQB, C_S5CON, C_VREG, C_NONE, C_VREG, C_NONE, 22, 4, 0, 0},
   358  	{AXVSEQB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   359  	{AXVSEQB, C_S5CON, C_XREG, C_NONE, C_XREG, C_NONE, 22, 4, 0, 0},
   360  
   361  	{AVSLTB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   362  	{AVSLTB, C_S5CON, C_VREG, C_NONE, C_VREG, C_NONE, 22, 4, 0, 0},
   363  	{AVSLTB, C_U5CON, C_VREG, C_NONE, C_VREG, C_NONE, 31, 4, 0, 0},
   364  	{AXVSLTB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   365  	{AXVSLTB, C_S5CON, C_XREG, C_NONE, C_XREG, C_NONE, 22, 4, 0, 0},
   366  	{AXVSLTB, C_U5CON, C_XREG, C_NONE, C_XREG, C_NONE, 31, 4, 0, 0},
   367  
   368  	{AVANDB, C_U8CON, C_VREG, C_NONE, C_VREG, C_NONE, 23, 4, 0, 0},
   369  	{AVANDB, C_U8CON, C_NONE, C_NONE, C_VREG, C_NONE, 23, 4, 0, 0},
   370  	{AXVANDB, C_U8CON, C_XREG, C_NONE, C_XREG, C_NONE, 23, 4, 0, 0},
   371  	{AXVANDB, C_U8CON, C_NONE, C_NONE, C_XREG, C_NONE, 23, 4, 0, 0},
   372  
   373  	{AVANDV, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   374  	{AVANDV, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   375  	{AXVANDV, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   376  	{AXVANDV, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   377  
   378  	{AVADDB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   379  	{AVADDB, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   380  	{AXVADDB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   381  	{AXVADDB, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   382  
   383  	{AVSLLB, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   384  	{AVSLLB, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   385  	{AVSLLB, C_U3CON, C_VREG, C_NONE, C_VREG, C_NONE, 13, 4, 0, 0},
   386  	{AVSLLB, C_U3CON, C_NONE, C_NONE, C_VREG, C_NONE, 13, 4, 0, 0},
   387  	{AXVSLLB, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   388  	{AXVSLLB, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   389  	{AXVSLLB, C_U3CON, C_XREG, C_NONE, C_XREG, C_NONE, 13, 4, 0, 0},
   390  	{AXVSLLB, C_U3CON, C_NONE, C_NONE, C_XREG, C_NONE, 13, 4, 0, 0},
   391  
   392  	{AVSLLH, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   393  	{AVSLLH, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   394  	{AVSLLH, C_U4CON, C_VREG, C_NONE, C_VREG, C_NONE, 14, 4, 0, 0},
   395  	{AVSLLH, C_U4CON, C_NONE, C_NONE, C_VREG, C_NONE, 14, 4, 0, 0},
   396  	{AXVSLLH, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   397  	{AXVSLLH, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   398  	{AXVSLLH, C_U4CON, C_XREG, C_NONE, C_XREG, C_NONE, 14, 4, 0, 0},
   399  	{AXVSLLH, C_U4CON, C_NONE, C_NONE, C_XREG, C_NONE, 14, 4, 0, 0},
   400  
   401  	{AVSLLW, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   402  	{AVSLLW, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   403  	{AVSLLW, C_U5CON, C_VREG, C_NONE, C_VREG, C_NONE, 31, 4, 0, 0},
   404  	{AVSLLW, C_U5CON, C_NONE, C_NONE, C_VREG, C_NONE, 31, 4, 0, 0},
   405  	{AXVSLLW, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   406  	{AXVSLLW, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   407  	{AXVSLLW, C_U5CON, C_XREG, C_NONE, C_XREG, C_NONE, 31, 4, 0, 0},
   408  	{AXVSLLW, C_U5CON, C_NONE, C_NONE, C_XREG, C_NONE, 31, 4, 0, 0},
   409  
   410  	{AVSLLV, C_VREG, C_VREG, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   411  	{AVSLLV, C_VREG, C_NONE, C_NONE, C_VREG, C_NONE, 2, 4, 0, 0},
   412  	{AVSLLV, C_U6CON, C_VREG, C_NONE, C_VREG, C_NONE, 32, 4, 0, 0},
   413  	{AVSLLV, C_U6CON, C_NONE, C_NONE, C_VREG, C_NONE, 32, 4, 0, 0},
   414  	{AXVSLLV, C_XREG, C_XREG, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   415  	{AXVSLLV, C_XREG, C_NONE, C_NONE, C_XREG, C_NONE, 2, 4, 0, 0},
   416  	{AXVSLLV, C_U6CON, C_XREG, C_NONE, C_XREG, C_NONE, 32, 4, 0, 0},
   417  	{AXVSLLV, C_U6CON, C_NONE, C_NONE, C_XREG, C_NONE, 32, 4, 0, 0},
   418  
   419  	{AWORD, C_32CON, C_NONE, C_NONE, C_NONE, C_NONE, 38, 4, 0, 0},
   420  	{AWORD, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 61, 4, 0, 0},
   421  
   422  	{ANOOP, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0},
   423  
   424  	{ANEGW, C_REG, C_NONE, C_NONE, C_REG, C_NONE, 2, 4, 0, 0},
   425  	{ATEQ, C_US12CON, C_REG, C_NONE, C_REG, C_NONE, 15, 8, 0, 0},
   426  	{ATEQ, C_US12CON, C_NONE, C_NONE, C_REG, C_NONE, 15, 8, 0, 0},
   427  
   428  	{obj.APCALIGN, C_U12CON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
   429  	{obj.APCDATA, C_32CON, C_NONE, C_NONE, C_32CON, C_NONE, 0, 0, 0, 0},
   430  	{obj.APCDATA, C_DCON, C_NONE, C_NONE, C_DCON, C_NONE, 0, 0, 0, 0},
   431  	{obj.AFUNCDATA, C_U12CON, C_NONE, C_NONE, C_ADDR, C_NONE, 0, 0, 0, 0},
   432  	{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
   433  	{obj.ANOP, C_32CON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0}, // nop variants, see #40689
   434  	{obj.ANOP, C_DCON, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},  // nop variants, see #40689
   435  	{obj.ANOP, C_REG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
   436  	{obj.ANOP, C_FREG, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0},
   437  }
   438  
   439  func IsAtomicInst(as obj.As) bool {
   440  	_, ok := atomicInst[as]
   441  
   442  	return ok
   443  }
   444  
   445  // pcAlignPadLength returns the number of bytes required to align pc to alignedValue,
   446  // reporting an error if alignedValue is not a power of two or is out of range.
   447  func pcAlignPadLength(ctxt *obj.Link, pc int64, alignedValue int64) int {
   448  	if !((alignedValue&(alignedValue-1) == 0) && 8 <= alignedValue && alignedValue <= 2048) {
   449  		ctxt.Diag("alignment value of an instruction must be a power of two and in the range [8, 2048], got %d\n", alignedValue)
   450  	}
   451  	return int(-pc & (alignedValue - 1))
   452  }
   453  
   454  var oprange [ALAST & obj.AMask][]Optab
   455  
   456  var xcmp [C_NCLASS][C_NCLASS]bool
   457  
   458  func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
   459  	if ctxt.Retpoline {
   460  		ctxt.Diag("-spectre=ret not supported on loong64")
   461  		ctxt.Retpoline = false // don't keep printing
   462  	}
   463  
   464  	p := cursym.Func().Text
   465  	if p == nil || p.Link == nil { // handle external functions and ELF section symbols
   466  		return
   467  	}
   468  
   469  	c := ctxt0{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset + ctxt.Arch.FixedFrameSize)}
   470  
   471  	if oprange[AOR&obj.AMask] == nil {
   472  		c.ctxt.Diag("loong64 ops not initialized, call loong64.buildop first")
   473  	}
   474  
   475  	pc := int64(0)
   476  	p.Pc = pc
   477  
   478  	var m int
   479  	var o *Optab
   480  	for p = p.Link; p != nil; p = p.Link {
   481  		p.Pc = pc
   482  		o = c.oplook(p)
   483  		m = int(o.size)
   484  		if m == 0 {
   485  			switch p.As {
   486  			case obj.APCALIGN:
   487  				alignedValue := p.From.Offset
   488  				m = pcAlignPadLength(ctxt, pc, alignedValue)
   489  				// Update the current text symbol alignment value.
   490  				if int16(alignedValue) > cursym.Align {
   491  					cursym.Align = int16(alignedValue)
   492  				}
   493  				break
   494  			case obj.ANOP, obj.AFUNCDATA, obj.APCDATA:
   495  				continue
   496  			default:
   497  				c.ctxt.Diag("zero-width instruction\n%v", p)
   498  			}
   499  		}
   500  
   501  		pc += int64(m)
   502  	}
   503  
   504  	c.cursym.Size = pc
   505  
   506  	// mark loop entry instructions for padding
   507  	// loop entrances are defined as targets of backward branches
   508  	for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
   509  		if q := p.To.Target(); q != nil && q.Pc < p.Pc {
   510  			q.Mark |= branchLoopHead
   511  		}
   512  	}
   513  
   514  	// Run these passes until convergence.
   515  	for {
   516  		rescan := false
   517  		pc = 0
   518  		prev := c.cursym.Func().Text
   519  		for p = prev.Link; p != nil; prev, p = p, p.Link {
   520  			p.Pc = pc
   521  			o = c.oplook(p)
   522  
   523  			// Prepend a PCALIGN $loopAlign to each of the loop heads
   524  			// that need padding, if not already done so (because this
   525  			// pass may execute more than once).
   526  			//
   527  			// This needs to come before any pass that look at pc,
   528  			// because pc will be adjusted if padding happens.
   529  			if p.Mark&branchLoopHead != 0 && pc&(loopAlign-1) != 0 &&
   530  				!(prev.As == obj.APCALIGN && prev.From.Offset >= loopAlign) {
   531  				q := c.newprog()
   532  				prev.Link = q
   533  				q.Link = p
   534  				q.Pc = pc
   535  				q.As = obj.APCALIGN
   536  				q.From.Type = obj.TYPE_CONST
   537  				q.From.Offset = loopAlign
   538  				// Don't associate the synthesized PCALIGN with
   539  				// the original source position, for deterministic
   540  				// mapping between source and corresponding asm.
   541  				// q.Pos = p.Pos
   542  
   543  				// Manually make the PCALIGN come into effect,
   544  				// since this loop iteration is for p.
   545  				pc += int64(pcAlignPadLength(ctxt, pc, loopAlign))
   546  				p.Pc = pc
   547  				rescan = true
   548  			}
   549  
   550  			// very large conditional branches
   551  			//
   552  			// if any procedure is large enough to generate a large SBRA branch, then
   553  			// generate extra passes putting branches around jmps to fix. this is rare.
   554  			if o.type_ == 6 && p.To.Target() != nil {
   555  				otxt := p.To.Target().Pc - pc
   556  
   557  				// On loong64, the immediate value field of the conditional branch instructions
   558  				// BFPT and BFPT is 21 bits, and the others are 16 bits. The jump target address
   559  				// is to logically shift the immediate value in the instruction code to the left
   560  				// by 2 bits and then sign extend.
   561  				bound := int64(1 << (18 - 1))
   562  
   563  				switch p.As {
   564  				case ABFPT, ABFPF:
   565  					bound = int64(1 << (23 - 1))
   566  				}
   567  
   568  				if otxt < -bound || otxt >= bound {
   569  					q := c.newprog()
   570  					q.Link = p.Link
   571  					p.Link = q
   572  					q.As = AJMP
   573  					q.Pos = p.Pos
   574  					q.To.Type = obj.TYPE_BRANCH
   575  					q.To.SetTarget(p.To.Target())
   576  					p.To.SetTarget(q)
   577  					q = c.newprog()
   578  					q.Link = p.Link
   579  					p.Link = q
   580  					q.As = AJMP
   581  					q.Pos = p.Pos
   582  					q.To.Type = obj.TYPE_BRANCH
   583  					q.To.SetTarget(q.Link.Link)
   584  					rescan = true
   585  				}
   586  			}
   587  
   588  			m = int(o.size)
   589  			if m == 0 {
   590  				switch p.As {
   591  				case obj.APCALIGN:
   592  					alignedValue := p.From.Offset
   593  					m = pcAlignPadLength(ctxt, pc, alignedValue)
   594  					break
   595  				case obj.ANOP, obj.AFUNCDATA, obj.APCDATA:
   596  					continue
   597  				default:
   598  					c.ctxt.Diag("zero-width instruction\n%v", p)
   599  				}
   600  			}
   601  
   602  			pc += int64(m)
   603  		}
   604  
   605  		c.cursym.Size = pc
   606  
   607  		if !rescan {
   608  			break
   609  		}
   610  	}
   611  
   612  	pc += -pc & (FuncAlign - 1)
   613  	c.cursym.Size = pc
   614  
   615  	// lay out the code, emitting code and data relocations.
   616  
   617  	c.cursym.Grow(c.cursym.Size)
   618  
   619  	bp := c.cursym.P
   620  	var i int32
   621  	var out [6]uint32
   622  	for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
   623  		c.pc = p.Pc
   624  		o = c.oplook(p)
   625  		if int(o.size) > 4*len(out) {
   626  			log.Fatalf("out array in span0 is too small, need at least %d for %v", o.size/4, p)
   627  		}
   628  		if p.As == obj.APCALIGN {
   629  			alignedValue := p.From.Offset
   630  			v := pcAlignPadLength(c.ctxt, p.Pc, alignedValue)
   631  			for i = 0; i < int32(v/4); i++ {
   632  				// emit ANOOP instruction by the padding size
   633  				c.ctxt.Arch.ByteOrder.PutUint32(bp, OP_12IRR(c.opirr(AAND), 0, 0, 0))
   634  				bp = bp[4:]
   635  			}
   636  			continue
   637  		}
   638  		c.asmout(p, o, out[:])
   639  		for i = 0; i < int32(o.size/4); i++ {
   640  			c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
   641  			bp = bp[4:]
   642  		}
   643  	}
   644  
   645  	// Mark nonpreemptible instruction sequences.
   646  	// We use REGTMP as a scratch register during call injection,
   647  	// so instruction sequences that use REGTMP are unsafe to
   648  	// preempt asynchronously.
   649  	obj.MarkUnsafePoints(c.ctxt, c.cursym.Func().Text, c.newprog, c.isUnsafePoint, c.isRestartable)
   650  
   651  	// Now that we know byte offsets, we can generate jump table entries.
   652  	for _, jt := range cursym.Func().JumpTables {
   653  		for i, p := range jt.Targets {
   654  			// The ith jumptable entry points to the p.Pc'th
   655  			// byte in the function symbol s.
   656  			jt.Sym.WriteAddr(ctxt, int64(i)*8, 8, cursym, p.Pc)
   657  		}
   658  	}
   659  }
   660  
   661  // isUnsafePoint returns whether p is an unsafe point.
   662  func (c *ctxt0) isUnsafePoint(p *obj.Prog) bool {
   663  	// If p explicitly uses REGTMP, it's unsafe to preempt, because the
   664  	// preemption sequence clobbers REGTMP.
   665  	return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP
   666  }
   667  
   668  // isRestartable returns whether p is a multi-instruction sequence that,
   669  // if preempted, can be restarted.
   670  func (c *ctxt0) isRestartable(p *obj.Prog) bool {
   671  	if c.isUnsafePoint(p) {
   672  		return false
   673  	}
   674  	// If p is a multi-instruction sequence with uses REGTMP inserted by
   675  	// the assembler in order to materialize a large constant/offset, we
   676  	// can restart p (at the start of the instruction sequence), recompute
   677  	// the content of REGTMP, upon async preemption. Currently, all cases
   678  	// of assembler-inserted REGTMP fall into this category.
   679  	// If p doesn't use REGTMP, it can be simply preempted, so we don't
   680  	// mark it.
   681  	o := c.oplook(p)
   682  	return o.size > 4 && o.flag&NOTUSETMP == 0
   683  }
   684  
   685  func isint32(v int64) bool {
   686  	return int64(int32(v)) == v
   687  }
   688  
   689  func (c *ctxt0) aclass(a *obj.Addr) int {
   690  	switch a.Type {
   691  	case obj.TYPE_NONE:
   692  		return C_NONE
   693  
   694  	case obj.TYPE_REG:
   695  		return c.rclass(a.Reg)
   696  
   697  	case obj.TYPE_MEM:
   698  		switch a.Name {
   699  		case obj.NAME_EXTERN,
   700  			obj.NAME_STATIC:
   701  			if a.Sym == nil {
   702  				break
   703  			}
   704  			c.instoffset = a.Offset
   705  			if a.Sym.Type == objabi.STLSBSS {
   706  				if c.ctxt.Flag_shared {
   707  					return C_TLS_IE
   708  				} else {
   709  					return C_TLS_LE
   710  				}
   711  			}
   712  			return C_ADDR
   713  
   714  		case obj.NAME_AUTO:
   715  			if a.Reg == REGSP {
   716  				// unset base register for better printing, since
   717  				// a.Offset is still relative to pseudo-SP.
   718  				a.Reg = obj.REG_NONE
   719  			}
   720  			c.instoffset = int64(c.autosize) + a.Offset
   721  			if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 {
   722  				return C_SAUTO
   723  			}
   724  			return C_LAUTO
   725  
   726  		case obj.NAME_PARAM:
   727  			if a.Reg == REGSP {
   728  				// unset base register for better printing, since
   729  				// a.Offset is still relative to pseudo-FP.
   730  				a.Reg = obj.REG_NONE
   731  			}
   732  			c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
   733  			if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 {
   734  				return C_SAUTO
   735  			}
   736  			return C_LAUTO
   737  
   738  		case obj.NAME_NONE:
   739  			if a.Index != 0 {
   740  				if a.Offset != 0 {
   741  					return C_GOK
   742  				}
   743  				// register offset
   744  				return C_ROFF
   745  			}
   746  
   747  			c.instoffset = a.Offset
   748  			if c.instoffset == 0 {
   749  				return C_ZOREG
   750  			}
   751  			if c.instoffset >= -BIG_8 && c.instoffset < BIG_8 {
   752  				return C_SOREG_8
   753  			} else if c.instoffset >= -BIG_9 && c.instoffset < BIG_9 {
   754  				return C_SOREG_9
   755  			} else if c.instoffset >= -BIG_10 && c.instoffset < BIG_10 {
   756  				return C_SOREG_10
   757  			} else if c.instoffset >= -BIG_11 && c.instoffset < BIG_11 {
   758  				return C_SOREG_11
   759  			} else if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 {
   760  				return C_SOREG_12
   761  			} else if c.instoffset >= -BIG_16 && c.instoffset < BIG_16 {
   762  				return C_SOREG_16
   763  			} else if c.instoffset >= -BIG_32 && c.instoffset < BIG_32 {
   764  				return C_LOREG_32
   765  			} else {
   766  				return C_LOREG_64
   767  			}
   768  
   769  		case obj.NAME_GOTREF:
   770  			return C_GOTADDR
   771  		}
   772  
   773  		return C_GOK
   774  
   775  	case obj.TYPE_TEXTSIZE:
   776  		return C_TEXTSIZE
   777  
   778  	case obj.TYPE_CONST,
   779  		obj.TYPE_ADDR:
   780  		switch a.Name {
   781  		case obj.NAME_NONE:
   782  			c.instoffset = a.Offset
   783  			if a.Reg != 0 {
   784  				if -BIG_12 <= c.instoffset && c.instoffset <= BIG_12 {
   785  					return C_SACON
   786  				}
   787  				if isint32(c.instoffset) {
   788  					return C_LACON
   789  				}
   790  				return C_DACON
   791  			}
   792  
   793  		case obj.NAME_EXTERN,
   794  			obj.NAME_STATIC:
   795  			s := a.Sym
   796  			if s == nil {
   797  				return C_GOK
   798  			}
   799  
   800  			c.instoffset = a.Offset
   801  			if s.Type == objabi.STLSBSS {
   802  				c.ctxt.Diag("taking address of TLS variable is not supported")
   803  			}
   804  			return C_EXTADDR
   805  
   806  		case obj.NAME_AUTO:
   807  			if a.Reg == REGSP {
   808  				// unset base register for better printing, since
   809  				// a.Offset is still relative to pseudo-SP.
   810  				a.Reg = obj.REG_NONE
   811  			}
   812  			c.instoffset = int64(c.autosize) + a.Offset
   813  			if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 {
   814  				return C_SACON
   815  			}
   816  			return C_LACON
   817  
   818  		case obj.NAME_PARAM:
   819  			if a.Reg == REGSP {
   820  				// unset base register for better printing, since
   821  				// a.Offset is still relative to pseudo-FP.
   822  				a.Reg = obj.REG_NONE
   823  			}
   824  			c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
   825  			if c.instoffset >= -BIG_12 && c.instoffset < BIG_12 {
   826  				return C_SACON
   827  			}
   828  			return C_LACON
   829  
   830  		default:
   831  			return C_GOK
   832  		}
   833  
   834  		if c.instoffset != int64(int32(c.instoffset)) {
   835  			return dconClass(c.instoffset)
   836  		}
   837  
   838  		if c.instoffset >= 0 {
   839  			sbits := bits.Len64(uint64(c.instoffset))
   840  			switch {
   841  			case sbits <= 8:
   842  				return C_ZCON + sbits
   843  			case sbits <= 12:
   844  				if c.instoffset <= 0x7ff {
   845  					return C_US12CON
   846  				}
   847  				return C_U12CON
   848  			case sbits <= 13:
   849  				if c.instoffset&0xfff == 0 {
   850  					return C_U13CON20_0
   851  				}
   852  				return C_U13CON
   853  			case sbits <= 15:
   854  				if c.instoffset&0xfff == 0 {
   855  					return C_U15CON20_0
   856  				}
   857  				return C_U15CON
   858  			}
   859  		} else {
   860  			sbits := bits.Len64(uint64(^c.instoffset))
   861  			switch {
   862  			case sbits < 5:
   863  				return C_S5CON
   864  			case sbits < 12:
   865  				return C_S12CON
   866  			case sbits < 13:
   867  				if c.instoffset&0xfff == 0 {
   868  					return C_S13CON20_0
   869  				}
   870  				return C_S13CON
   871  			}
   872  		}
   873  
   874  		if c.instoffset&0xfff == 0 {
   875  			return C_32CON20_0
   876  		}
   877  		return C_32CON
   878  
   879  	case obj.TYPE_BRANCH:
   880  		return C_BRAN
   881  	}
   882  
   883  	return C_GOK
   884  }
   885  
   886  // The constants here define the data characteristics within the bit field range.
   887  //
   888  //	ALL1: The data in the bit field is all 1
   889  //	ALL0: The data in the bit field is all 0
   890  //	ST1: The data in the bit field starts with 1, but not all 1
   891  //	ST0: The data in the bit field starts with 0, but not all 0
   892  const (
   893  	ALL1 = iota
   894  	ALL0
   895  	ST1
   896  	ST0
   897  )
   898  
   899  // mask returns the mask of the specified bit field, which is used to help determine
   900  // the data characteristics of the immediate value at the specified bit.
   901  func mask(suf int8, len int8) (uint64, uint64) {
   902  	if len == 12 {
   903  		if suf == 0 {
   904  			return 0xfff, 0x800
   905  		} else { // suf == 52
   906  			return 0xfff0000000000000, 0x8000000000000000
   907  		}
   908  	} else { // len == 20
   909  		if suf == 12 {
   910  			return 0xfffff000, 0x80000000
   911  		} else { // suf == 32
   912  			return 0xfffff00000000, 0x8000000000000
   913  		}
   914  	}
   915  }
   916  
   917  // bitField return a number represent status of val in bit field
   918  //
   919  //	suf: The starting bit of the bit field
   920  //	len: The length of the bit field
   921  func bitField(val int64, suf int8, len int8) int8 {
   922  	mask1, mask2 := mask(suf, len)
   923  	if uint64(val)&mask1 == mask1 {
   924  		return ALL1
   925  	} else if uint64(val)&mask1 == 0x0 {
   926  		return ALL0
   927  	} else if uint64(val)&mask2 == mask2 {
   928  		return ST1
   929  	} else {
   930  		return ST0
   931  	}
   932  }
   933  
   934  // Loading an immediate value larger than 32 bits requires four instructions
   935  // on loong64 (lu12i.w + ori + lu32i.d + lu52i.d), but in some special cases,
   936  // we can use the sign extension and zero extension features of the instruction
   937  // to fill in the high-order data (all 0 or all 1), which can save one to
   938  // three instructions.
   939  //
   940  //	| 63 ~ 52 | 51 ~ 32 | 31 ~ 12 | 11 ~ 0 |
   941  //	| lu52i.d | lu32i.d | lu12i.w |   ori  |
   942  func dconClass(offset int64) int {
   943  	tzb := bits.TrailingZeros64(uint64(offset))
   944  	hi12 := bitField(offset, 52, 12)
   945  	hi20 := bitField(offset, 32, 20)
   946  	lo20 := bitField(offset, 12, 20)
   947  	lo12 := bitField(offset, 0, 12)
   948  	if tzb >= 52 {
   949  		return C_DCON12_0 // lu52i.d
   950  	}
   951  	if tzb >= 32 {
   952  		if ((hi20 == ALL1 || hi20 == ST1) && hi12 == ALL1) || ((hi20 == ALL0 || hi20 == ST0) && hi12 == ALL0) {
   953  			return C_DCON20S_0 // addi.w + lu32i.d
   954  		}
   955  		return C_DCON32_0 // addi.w + lu32i.d + lu52i.d
   956  	}
   957  	if tzb >= 12 {
   958  		if lo20 == ST1 || lo20 == ALL1 {
   959  			if hi20 == ALL1 {
   960  				return C_DCON12_20S // lu12i.w + lu52i.d
   961  			}
   962  			if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) {
   963  				return C_DCON20S_20 // lu12i.w + lu32i.d
   964  			}
   965  			return C_DCON32_20 // lu12i.w + lu32i.d + lu52i.d
   966  		}
   967  		if hi20 == ALL0 {
   968  			return C_DCON12_20S // lu12i.w + lu52i.d
   969  		}
   970  		if (hi20 == ST0 && hi12 == ALL0) || ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) {
   971  			return C_DCON20S_20 // lu12i.w + lu32i.d
   972  		}
   973  		return C_DCON32_20 // lu12i.w + lu32i.d + lu52i.d
   974  	}
   975  	if lo12 == ST1 || lo12 == ALL1 {
   976  		if lo20 == ALL1 {
   977  			if hi20 == ALL1 {
   978  				return C_DCON12_12S // addi.d + lu52i.d
   979  			}
   980  			if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) {
   981  				return C_DCON20S_12S // addi.w + lu32i.d
   982  			}
   983  			return C_DCON32_12S // addi.w + lu32i.d + lu52i.d
   984  		}
   985  		if lo20 == ST1 {
   986  			if hi20 == ALL1 {
   987  
   988  				return C_DCON12_32S // lu12i.w + ori + lu52i.d
   989  			}
   990  			if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) {
   991  				return C_DCON20S_32 // lu12i.w + ori + lu32i.d
   992  			}
   993  			return C_DCON // lu12i.w + ori + lu32i.d + lu52i.d
   994  		}
   995  		if lo20 == ALL0 {
   996  			if hi20 == ALL0 {
   997  				return C_DCON12_12U // ori + lu52i.d
   998  			}
   999  			if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) {
  1000  				return C_DCON20S_12U // ori + lu32i.d
  1001  			}
  1002  			return C_DCON32_12U // ori + lu32i.d + lu52i.d
  1003  		}
  1004  		if hi20 == ALL0 {
  1005  			return C_DCON12_32S // lu12i.w + ori + lu52i.d
  1006  		}
  1007  		if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) {
  1008  			return C_DCON20S_32 // lu12i.w + ori + lu32i.d
  1009  		}
  1010  		return C_DCON // lu12i.w + ori + lu32i.d + lu52i.d
  1011  	}
  1012  	if lo20 == ALL0 {
  1013  		if hi20 == ALL0 {
  1014  			return C_DCON12_12U // ori + lu52i.d
  1015  		}
  1016  		if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) {
  1017  			return C_DCON20S_12U // ori + lu32i.d
  1018  		}
  1019  		return C_DCON32_12U // ori + lu32i.d + lu52i.d
  1020  	}
  1021  	if lo20 == ST1 || lo20 == ALL1 {
  1022  		if hi20 == ALL1 {
  1023  			return C_DCON12_32S // lu12i.w + ori + lu52i.d
  1024  		}
  1025  		if (hi20 == ST1 && hi12 == ALL1) || ((hi20 == ST0 || hi20 == ALL0) && hi12 == ALL0) {
  1026  			return C_DCON20S_32 // lu12i.w + ori + lu32i.d
  1027  		}
  1028  		return C_DCON
  1029  	}
  1030  	if hi20 == ALL0 {
  1031  		return C_DCON12_32S // lu12i.w + ori + lu52i.d
  1032  	}
  1033  	if ((hi20 == ST1 || hi20 == ALL1) && hi12 == ALL1) || (hi20 == ST0 && hi12 == ALL0) {
  1034  		return C_DCON20S_32 // lu12i.w + ori + lu32i.d
  1035  	}
  1036  	return C_DCON
  1037  }
  1038  
  1039  // In Loong64,there are 8 CFRs, denoted as fcc0-fcc7.
  1040  // There are 4 FCSRs, denoted as fcsr0-fcsr3.
  1041  func (c *ctxt0) rclass(r int16) int {
  1042  	switch {
  1043  	case REG_R0 <= r && r <= REG_R31:
  1044  		return C_REG
  1045  	case REG_F0 <= r && r <= REG_F31:
  1046  		return C_FREG
  1047  	case REG_FCC0 <= r && r <= REG_FCC7:
  1048  		return C_FCCREG
  1049  	case REG_FCSR0 <= r && r <= REG_FCSR3:
  1050  		return C_FCSRREG
  1051  	case REG_V0 <= r && r <= REG_V31:
  1052  		return C_VREG
  1053  	case REG_X0 <= r && r <= REG_X31:
  1054  		return C_XREG
  1055  	case r >= REG_ARNG && r < REG_ELEM:
  1056  		return C_ARNG
  1057  	case r >= REG_ELEM && r < REG_ELEM_END:
  1058  		return C_ELEM
  1059  	}
  1060  
  1061  	return C_GOK
  1062  }
  1063  
  1064  func oclass(a *obj.Addr) int {
  1065  	return int(a.Class) - 1
  1066  }
  1067  
  1068  func prasm(p *obj.Prog) {
  1069  	fmt.Printf("%v\n", p)
  1070  }
  1071  
  1072  func (c *ctxt0) oplook(p *obj.Prog) *Optab {
  1073  	if oprange[AOR&obj.AMask] == nil {
  1074  		c.ctxt.Diag("loong64 ops not initialized, call loong64.buildop first")
  1075  	}
  1076  
  1077  	restArgsIndex := 0
  1078  	restArgsLen := len(p.RestArgs)
  1079  	if restArgsLen > 2 {
  1080  		c.ctxt.Diag("too many RestArgs: got %v, maximum is 2\n", restArgsLen)
  1081  		return nil
  1082  	}
  1083  
  1084  	restArgsv := [2]int{C_NONE + 1, C_NONE + 1}
  1085  	for i, ap := range p.RestArgs {
  1086  		restArgsv[i] = int(ap.Addr.Class)
  1087  		if restArgsv[i] == 0 {
  1088  			restArgsv[i] = c.aclass(&ap.Addr) + 1
  1089  			ap.Addr.Class = int8(restArgsv[i])
  1090  		}
  1091  	}
  1092  
  1093  	a1 := int(p.Optab)
  1094  	if a1 != 0 {
  1095  		return &optab[a1-1]
  1096  	}
  1097  
  1098  	// first source operand
  1099  	a1 = int(p.From.Class)
  1100  	if a1 == 0 {
  1101  		a1 = c.aclass(&p.From) + 1
  1102  		p.From.Class = int8(a1)
  1103  	}
  1104  	a1--
  1105  
  1106  	// first destination operand
  1107  	a4 := int(p.To.Class)
  1108  	if a4 == 0 {
  1109  		a4 = c.aclass(&p.To) + 1
  1110  		p.To.Class = int8(a4)
  1111  	}
  1112  	a4--
  1113  
  1114  	// 2nd source operand
  1115  	a2 := C_NONE
  1116  	if p.Reg != 0 {
  1117  		a2 = c.rclass(p.Reg)
  1118  	} else if restArgsLen > 0 {
  1119  		a2 = restArgsv[restArgsIndex] - 1
  1120  		restArgsIndex++
  1121  	}
  1122  
  1123  	// 2nd destination operand
  1124  	a5 := C_NONE
  1125  	if p.RegTo2 != 0 {
  1126  		a5 = C_REG
  1127  	}
  1128  
  1129  	// 3rd source operand
  1130  	a3 := C_NONE
  1131  	if restArgsLen > 0 && restArgsIndex < restArgsLen {
  1132  		a3 = restArgsv[restArgsIndex] - 1
  1133  		restArgsIndex++
  1134  	}
  1135  
  1136  	ops := oprange[p.As&obj.AMask]
  1137  	c1 := &xcmp[a1]
  1138  	c2 := &xcmp[a2]
  1139  	c3 := &xcmp[a3]
  1140  	c4 := &xcmp[a4]
  1141  	c5 := &xcmp[a5]
  1142  	for i := range ops {
  1143  		op := &ops[i]
  1144  		if c1[op.from1] && c2[op.reg] && c3[op.from3] && c4[op.to1] && c5[op.to2] {
  1145  			p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
  1146  			return op
  1147  		}
  1148  	}
  1149  
  1150  	c.ctxt.Diag("illegal combination %v %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4), DRconv(a5))
  1151  	prasm(p)
  1152  	// Turn illegal instruction into an UNDEF, avoid crashing in asmout.
  1153  	return &Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, C_NONE, 49, 4, 0, 0}
  1154  }
  1155  
  1156  func cmp(a int, b int) bool {
  1157  	if a == b {
  1158  		return true
  1159  	}
  1160  	switch a {
  1161  	case C_DCON:
  1162  		return cmp(C_32CON, b) || cmp(C_DCON12_20S, b) || cmp(C_DCON32_12S, b) || b == C_DCON12_0
  1163  	case C_32CON:
  1164  		return cmp(C_32CON20_0, b) || cmp(C_U15CON, b) || cmp(C_13CON, b) || cmp(C_12CON, b)
  1165  	case C_32CON20_0:
  1166  		return b == C_U15CON20_0 || b == C_U13CON20_0 || b == C_S13CON20_0 || b == C_ZCON
  1167  	case C_U15CON:
  1168  		return cmp(C_U12CON, b) || b == C_U15CON20_0 || b == C_U13CON20_0 || b == C_U13CON
  1169  	case C_13CON:
  1170  		return cmp(C_U13CON, b) || cmp(C_S13CON, b)
  1171  	case C_U13CON:
  1172  		return cmp(C_12CON, b) || b == C_U13CON20_0
  1173  	case C_S13CON:
  1174  		return cmp(C_12CON, b) || b == C_S13CON20_0
  1175  	case C_12CON:
  1176  		return cmp(C_U12CON, b) || cmp(C_S12CON, b)
  1177  	case C_UU12CON:
  1178  		return cmp(C_U12CON, b)
  1179  	case C_U12CON:
  1180  		return cmp(C_U8CON, b) || b == C_US12CON
  1181  	case C_U8CON:
  1182  		return cmp(C_U7CON, b)
  1183  	case C_U7CON:
  1184  		return cmp(C_U6CON, b)
  1185  	case C_U6CON:
  1186  		return cmp(C_U5CON, b)
  1187  	case C_U5CON:
  1188  		return cmp(C_U4CON, b)
  1189  	case C_U4CON:
  1190  		return cmp(C_U3CON, b)
  1191  	case C_U3CON:
  1192  		return cmp(C_U2CON, b)
  1193  	case C_U2CON:
  1194  		return cmp(C_U1CON, b)
  1195  	case C_U1CON:
  1196  		return cmp(C_ZCON, b)
  1197  	case C_US12CON:
  1198  		return cmp(C_S12CON, b)
  1199  	case C_S12CON:
  1200  		return cmp(C_S5CON, b) || cmp(C_U8CON, b) || b == C_US12CON
  1201  	case C_S5CON:
  1202  		return cmp(C_ZCON, b) || cmp(C_U4CON, b)
  1203  
  1204  	case C_DCON12_20S:
  1205  		if b == C_DCON20S_20 || b == C_DCON12_12S ||
  1206  			b == C_DCON20S_12S || b == C_DCON12_12U ||
  1207  			b == C_DCON20S_12U || b == C_DCON20S_0 {
  1208  			return true
  1209  		}
  1210  
  1211  	case C_DCON32_12S:
  1212  		if b == C_DCON32_20 || b == C_DCON12_32S ||
  1213  			b == C_DCON20S_32 || b == C_DCON32_12U ||
  1214  			b == C_DCON32_0 {
  1215  			return true
  1216  		}
  1217  
  1218  	case C_LACON:
  1219  		return b == C_SACON
  1220  
  1221  	case C_LAUTO:
  1222  		return b == C_SAUTO
  1223  
  1224  	case C_REG:
  1225  		return b == C_ZCON
  1226  
  1227  	case C_LOREG_64:
  1228  		if b == C_ZOREG || b == C_SOREG_8 ||
  1229  			b == C_SOREG_9 || b == C_SOREG_10 ||
  1230  			b == C_SOREG_11 || b == C_SOREG_12 ||
  1231  			b == C_SOREG_16 || b == C_LOREG_32 {
  1232  			return true
  1233  		}
  1234  
  1235  	case C_LOREG_32:
  1236  		return cmp(C_SOREG_16, b)
  1237  
  1238  	case C_SOREG_16:
  1239  		return cmp(C_SOREG_12, b)
  1240  
  1241  	case C_SOREG_12:
  1242  		return cmp(C_SOREG_11, b)
  1243  
  1244  	case C_SOREG_11:
  1245  		return cmp(C_SOREG_10, b)
  1246  
  1247  	case C_SOREG_10:
  1248  		return cmp(C_SOREG_9, b)
  1249  
  1250  	case C_SOREG_9:
  1251  		return cmp(C_SOREG_8, b)
  1252  
  1253  	case C_SOREG_8:
  1254  		return b == C_ZOREG
  1255  	}
  1256  
  1257  	return false
  1258  }
  1259  
  1260  func ocmp(p1, p2 Optab) int {
  1261  	if p1.as != p2.as {
  1262  		return int(p1.as) - int(p2.as)
  1263  	}
  1264  	if p1.from1 != p2.from1 {
  1265  		return int(p1.from1) - int(p2.from1)
  1266  	}
  1267  	if p1.reg != p2.reg {
  1268  		return int(p1.reg) - int(p2.reg)
  1269  	}
  1270  	if p1.to1 != p2.to1 {
  1271  		return int(p1.to1) - int(p2.to1)
  1272  	}
  1273  	return 0
  1274  }
  1275  
  1276  func opset(a, b0 obj.As) {
  1277  	oprange[a&obj.AMask] = oprange[b0]
  1278  }
  1279  
  1280  func buildop(ctxt *obj.Link) {
  1281  	if ctxt.DiagFunc == nil {
  1282  		ctxt.DiagFunc = func(format string, args ...any) {
  1283  			log.Printf(format, args...)
  1284  		}
  1285  	}
  1286  
  1287  	if oprange[AOR&obj.AMask] != nil {
  1288  		// Already initialized; stop now.
  1289  		// This happens in the cmd/asm tests,
  1290  		// each of which re-initializes the arch.
  1291  		return
  1292  	}
  1293  
  1294  	for i := range C_NCLASS {
  1295  		for j := range C_NCLASS {
  1296  			if cmp(j, i) {
  1297  				xcmp[i][j] = true
  1298  			}
  1299  		}
  1300  	}
  1301  
  1302  	slices.SortFunc(optab, ocmp)
  1303  	for i := 0; i < len(optab); i++ {
  1304  		as, start := optab[i].as, i
  1305  		for ; i < len(optab)-1; i++ {
  1306  			if optab[i+1].as != as {
  1307  				break
  1308  			}
  1309  		}
  1310  		r0 := as & obj.AMask
  1311  		oprange[r0] = optab[start : i+1]
  1312  		switch as {
  1313  		default:
  1314  			ctxt.Diag("unknown op in build: %v", as)
  1315  			ctxt.DiagFlush()
  1316  			log.Fatalf("bad code")
  1317  
  1318  		case AABSF:
  1319  			opset(AMOVFD, r0)
  1320  			opset(AMOVDF, r0)
  1321  			opset(AMOVWF, r0)
  1322  			opset(AMOVFW, r0)
  1323  			opset(AMOVWD, r0)
  1324  			opset(AMOVDW, r0)
  1325  			opset(AMOVVF, r0)
  1326  			opset(AMOVVD, r0)
  1327  			opset(AMOVFV, r0)
  1328  			opset(AMOVDV, r0)
  1329  			opset(AFFINTFW, r0)
  1330  			opset(AFFINTFV, r0)
  1331  			opset(AFFINTDW, r0)
  1332  			opset(AFFINTDV, r0)
  1333  			opset(AFTINTWF, r0)
  1334  			opset(AFTINTWD, r0)
  1335  			opset(AFTINTVF, r0)
  1336  			opset(AFTINTVD, r0)
  1337  			opset(ANEGF, r0)
  1338  			opset(ANEGD, r0)
  1339  			opset(AABSD, r0)
  1340  			opset(ATRUNCDW, r0)
  1341  			opset(ATRUNCFW, r0)
  1342  			opset(ASQRTF, r0)
  1343  			opset(ASQRTD, r0)
  1344  			opset(AFCLASSF, r0)
  1345  			opset(AFCLASSD, r0)
  1346  			opset(AFLOGBF, r0)
  1347  			opset(AFLOGBD, r0)
  1348  			opset(ATRUNCDV, r0)
  1349  			opset(ATRUNCFV, r0)
  1350  			opset(AFTINTRPWF, r0)
  1351  			opset(AFTINTRPWD, r0)
  1352  			opset(AFTINTRPVF, r0)
  1353  			opset(AFTINTRPVD, r0)
  1354  			opset(AFTINTRMWF, r0)
  1355  			opset(AFTINTRMWD, r0)
  1356  			opset(AFTINTRMVF, r0)
  1357  			opset(AFTINTRMVD, r0)
  1358  			opset(AFTINTRZWF, r0)
  1359  			opset(AFTINTRZWD, r0)
  1360  			opset(AFTINTRZVF, r0)
  1361  			opset(AFTINTRZVD, r0)
  1362  			opset(AFTINTRNEWF, r0)
  1363  			opset(AFTINTRNEWD, r0)
  1364  			opset(AFTINTRNEVF, r0)
  1365  			opset(AFTINTRNEVD, r0)
  1366  
  1367  		case AADD:
  1368  			opset(AADDW, r0)
  1369  			opset(ASGT, r0)
  1370  			opset(ASGTU, r0)
  1371  
  1372  		case AADDV:
  1373  			opset(AADDVU, r0)
  1374  
  1375  		case AADDF:
  1376  			opset(ADIVF, r0)
  1377  			opset(ADIVD, r0)
  1378  			opset(AMULF, r0)
  1379  			opset(AMULD, r0)
  1380  			opset(ASUBF, r0)
  1381  			opset(ASUBD, r0)
  1382  			opset(AADDD, r0)
  1383  			opset(AFMINF, r0)
  1384  			opset(AFMIND, r0)
  1385  			opset(AFMAXF, r0)
  1386  			opset(AFMAXD, r0)
  1387  			opset(AFCOPYSGF, r0)
  1388  			opset(AFCOPYSGD, r0)
  1389  			opset(AFSCALEBF, r0)
  1390  			opset(AFSCALEBD, r0)
  1391  			opset(AFMAXAF, r0)
  1392  			opset(AFMAXAD, r0)
  1393  			opset(AFMINAF, r0)
  1394  			opset(AFMINAD, r0)
  1395  
  1396  		case AFMADDF:
  1397  			opset(AFMADDD, r0)
  1398  			opset(AFMSUBF, r0)
  1399  			opset(AFMSUBD, r0)
  1400  			opset(AFNMADDF, r0)
  1401  			opset(AFNMADDD, r0)
  1402  			opset(AFNMSUBF, r0)
  1403  			opset(AFNMSUBD, r0)
  1404  
  1405  		case AAND:
  1406  			opset(AOR, r0)
  1407  			opset(AXOR, r0)
  1408  			opset(AORN, r0)
  1409  			opset(AANDN, r0)
  1410  
  1411  		case ABEQ:
  1412  			opset(ABNE, r0)
  1413  			opset(ABLT, r0)
  1414  			opset(ABGE, r0)
  1415  			opset(ABGEU, r0)
  1416  			opset(ABLTU, r0)
  1417  
  1418  		case ABLEZ:
  1419  			opset(ABGEZ, r0)
  1420  			opset(ABLTZ, r0)
  1421  			opset(ABGTZ, r0)
  1422  
  1423  		case AMOVB:
  1424  			opset(AMOVH, r0)
  1425  
  1426  		case AMOVBU:
  1427  			opset(AMOVHU, r0)
  1428  			opset(AMOVWU, r0)
  1429  
  1430  		case AMOVWP:
  1431  			opset(AMOVVP, r0)
  1432  			opset(ASC, r0)
  1433  			opset(ASCV, r0)
  1434  			opset(ALL, r0)
  1435  			opset(ALLV, r0)
  1436  
  1437  		case ASLL:
  1438  			opset(ASRL, r0)
  1439  			opset(ASRA, r0)
  1440  			opset(AROTR, r0)
  1441  
  1442  		case ASLLV:
  1443  			opset(ASRAV, r0)
  1444  			opset(ASRLV, r0)
  1445  			opset(AROTRV, r0)
  1446  
  1447  		case ABSTRPICKW:
  1448  			opset(ABSTRPICKV, r0)
  1449  			opset(ABSTRINSW, r0)
  1450  			opset(ABSTRINSV, r0)
  1451  
  1452  		case ASUB:
  1453  			opset(ASUBW, r0)
  1454  			opset(ANOR, r0)
  1455  			opset(ASUBV, r0)
  1456  			opset(ASUBVU, r0)
  1457  			opset(AMUL, r0)
  1458  			opset(AMULW, r0)
  1459  			opset(AMULH, r0)
  1460  			opset(AMULHU, r0)
  1461  			opset(AREM, r0)
  1462  			opset(AREMW, r0)
  1463  			opset(AREMU, r0)
  1464  			opset(AREMWU, r0)
  1465  			opset(ADIV, r0)
  1466  			opset(ADIVW, r0)
  1467  			opset(ADIVU, r0)
  1468  			opset(ADIVWU, r0)
  1469  			opset(AMULV, r0)
  1470  			opset(AMULVU, r0)
  1471  			opset(AMULHV, r0)
  1472  			opset(AMULHVU, r0)
  1473  			opset(AREMV, r0)
  1474  			opset(AREMVU, r0)
  1475  			opset(ADIVV, r0)
  1476  			opset(ADIVVU, r0)
  1477  			opset(AMULWVW, r0)
  1478  			opset(AMULWVWU, r0)
  1479  
  1480  		case ASYSCALL:
  1481  			opset(ADBAR, r0)
  1482  			opset(ABREAK, r0)
  1483  
  1484  		case ACMPEQF:
  1485  			opset(ACMPGTF, r0)
  1486  			opset(ACMPGTD, r0)
  1487  			opset(ACMPGEF, r0)
  1488  			opset(ACMPGED, r0)
  1489  			opset(ACMPEQD, r0)
  1490  
  1491  		case ABFPT:
  1492  			opset(ABFPF, r0)
  1493  
  1494  		case AALSLV:
  1495  			opset(AALSLW, r0)
  1496  			opset(AALSLWU, r0)
  1497  
  1498  		case ANEGW:
  1499  			opset(ANEGV, r0)
  1500  
  1501  		case AMOVF:
  1502  			opset(AMOVD, r0)
  1503  
  1504  		case AMOVW,
  1505  			AMOVV,
  1506  			ARFE,
  1507  			AJAL,
  1508  			AJMP,
  1509  			AVMOVQ,
  1510  			AXVMOVQ,
  1511  			AVSHUFB,
  1512  			AXVSHUFB,
  1513  			AWORD,
  1514  			APRELD,
  1515  			APRELDX,
  1516  			AFSEL,
  1517  			AADDV16,
  1518  			obj.ANOP,
  1519  			obj.ATEXT,
  1520  			obj.AFUNCDATA,
  1521  			obj.APCALIGN,
  1522  			obj.APCDATA:
  1523  			break
  1524  
  1525  		case ARDTIMELW:
  1526  			opset(ARDTIMEHW, r0)
  1527  			opset(ARDTIMED, r0)
  1528  
  1529  		case ACLOW:
  1530  			opset(ACLZW, r0)
  1531  			opset(ACTOW, r0)
  1532  			opset(ACTZW, r0)
  1533  			opset(ACLOV, r0)
  1534  			opset(ACLZV, r0)
  1535  			opset(ACTOV, r0)
  1536  			opset(ACTZV, r0)
  1537  			opset(AREVB2H, r0)
  1538  			opset(AREVB4H, r0)
  1539  			opset(AREVB2W, r0)
  1540  			opset(AREVBV, r0)
  1541  			opset(AREVH2W, r0)
  1542  			opset(AREVHV, r0)
  1543  			opset(ABITREV4B, r0)
  1544  			opset(ABITREV8B, r0)
  1545  			opset(ABITREVW, r0)
  1546  			opset(ABITREVV, r0)
  1547  			opset(AEXTWB, r0)
  1548  			opset(AEXTWH, r0)
  1549  			opset(ACPUCFG, r0)
  1550  
  1551  		case ATEQ:
  1552  			opset(ATNE, r0)
  1553  
  1554  		case AMASKEQZ:
  1555  			opset(AMASKNEZ, r0)
  1556  			opset(ACRCWBW, r0)
  1557  			opset(ACRCWHW, r0)
  1558  			opset(ACRCWWW, r0)
  1559  			opset(ACRCWVW, r0)
  1560  			opset(ACRCCWBW, r0)
  1561  			opset(ACRCCWHW, r0)
  1562  			opset(ACRCCWWW, r0)
  1563  			opset(ACRCCWVW, r0)
  1564  
  1565  		case ANOOP:
  1566  			opset(obj.AUNDEF, r0)
  1567  
  1568  		case AAMSWAPW:
  1569  			for i := range atomicInst {
  1570  				if i == AAMSWAPW {
  1571  					continue
  1572  				}
  1573  				opset(i, r0)
  1574  			}
  1575  
  1576  		case AVSEQB:
  1577  			opset(AVSEQH, r0)
  1578  			opset(AVSEQW, r0)
  1579  			opset(AVSEQV, r0)
  1580  			opset(AVILVLB, r0)
  1581  			opset(AVILVLH, r0)
  1582  			opset(AVILVLW, r0)
  1583  			opset(AVILVLV, r0)
  1584  			opset(AVILVHB, r0)
  1585  			opset(AVILVHH, r0)
  1586  			opset(AVILVHW, r0)
  1587  			opset(AVILVHV, r0)
  1588  			opset(AVMULB, r0)
  1589  			opset(AVMULH, r0)
  1590  			opset(AVMULW, r0)
  1591  			opset(AVMULV, r0)
  1592  			opset(AVMUHB, r0)
  1593  			opset(AVMUHH, r0)
  1594  			opset(AVMUHW, r0)
  1595  			opset(AVMUHV, r0)
  1596  			opset(AVMUHBU, r0)
  1597  			opset(AVMUHHU, r0)
  1598  			opset(AVMUHWU, r0)
  1599  			opset(AVMUHVU, r0)
  1600  			opset(AVDIVB, r0)
  1601  			opset(AVDIVH, r0)
  1602  			opset(AVDIVW, r0)
  1603  			opset(AVDIVV, r0)
  1604  			opset(AVMODB, r0)
  1605  			opset(AVMODH, r0)
  1606  			opset(AVMODW, r0)
  1607  			opset(AVMODV, r0)
  1608  			opset(AVDIVBU, r0)
  1609  			opset(AVDIVHU, r0)
  1610  			opset(AVDIVWU, r0)
  1611  			opset(AVDIVVU, r0)
  1612  			opset(AVMODBU, r0)
  1613  			opset(AVMODHU, r0)
  1614  			opset(AVMODWU, r0)
  1615  			opset(AVMODVU, r0)
  1616  			opset(AVMULWEVHB, r0)
  1617  			opset(AVMULWEVWH, r0)
  1618  			opset(AVMULWEVVW, r0)
  1619  			opset(AVMULWEVQV, r0)
  1620  			opset(AVMULWODHB, r0)
  1621  			opset(AVMULWODWH, r0)
  1622  			opset(AVMULWODVW, r0)
  1623  			opset(AVMULWODQV, r0)
  1624  			opset(AVMULWEVHBU, r0)
  1625  			opset(AVMULWEVWHU, r0)
  1626  			opset(AVMULWEVVWU, r0)
  1627  			opset(AVMULWEVQVU, r0)
  1628  			opset(AVMULWODHBU, r0)
  1629  			opset(AVMULWODWHU, r0)
  1630  			opset(AVMULWODVWU, r0)
  1631  			opset(AVMULWODQVU, r0)
  1632  			opset(AVMULWEVHBUB, r0)
  1633  			opset(AVMULWEVWHUH, r0)
  1634  			opset(AVMULWEVVWUW, r0)
  1635  			opset(AVMULWEVQVUV, r0)
  1636  			opset(AVMULWODHBUB, r0)
  1637  			opset(AVMULWODWHUH, r0)
  1638  			opset(AVMULWODVWUW, r0)
  1639  			opset(AVMULWODQVUV, r0)
  1640  			opset(AVADDF, r0)
  1641  			opset(AVADDD, r0)
  1642  			opset(AVSUBF, r0)
  1643  			opset(AVSUBD, r0)
  1644  			opset(AVMULF, r0)
  1645  			opset(AVMULD, r0)
  1646  			opset(AVDIVF, r0)
  1647  			opset(AVDIVD, r0)
  1648  			opset(AVSHUFH, r0)
  1649  			opset(AVSHUFW, r0)
  1650  			opset(AVSHUFV, r0)
  1651  
  1652  		case AXVSEQB:
  1653  			opset(AXVSEQH, r0)
  1654  			opset(AXVSEQW, r0)
  1655  			opset(AXVSEQV, r0)
  1656  			opset(AXVILVLB, r0)
  1657  			opset(AXVILVLH, r0)
  1658  			opset(AXVILVLW, r0)
  1659  			opset(AXVILVLV, r0)
  1660  			opset(AXVILVHB, r0)
  1661  			opset(AXVILVHH, r0)
  1662  			opset(AXVILVHW, r0)
  1663  			opset(AXVILVHV, r0)
  1664  			opset(AXVMULB, r0)
  1665  			opset(AXVMULH, r0)
  1666  			opset(AXVMULW, r0)
  1667  			opset(AXVMULV, r0)
  1668  			opset(AXVMUHB, r0)
  1669  			opset(AXVMUHH, r0)
  1670  			opset(AXVMUHW, r0)
  1671  			opset(AXVMUHV, r0)
  1672  			opset(AXVMUHBU, r0)
  1673  			opset(AXVMUHHU, r0)
  1674  			opset(AXVMUHWU, r0)
  1675  			opset(AXVMUHVU, r0)
  1676  			opset(AXVDIVB, r0)
  1677  			opset(AXVDIVH, r0)
  1678  			opset(AXVDIVW, r0)
  1679  			opset(AXVDIVV, r0)
  1680  			opset(AXVMODB, r0)
  1681  			opset(AXVMODH, r0)
  1682  			opset(AXVMODW, r0)
  1683  			opset(AXVMODV, r0)
  1684  			opset(AXVDIVBU, r0)
  1685  			opset(AXVDIVHU, r0)
  1686  			opset(AXVDIVWU, r0)
  1687  			opset(AXVDIVVU, r0)
  1688  			opset(AXVMODBU, r0)
  1689  			opset(AXVMODHU, r0)
  1690  			opset(AXVMODWU, r0)
  1691  			opset(AXVMODVU, r0)
  1692  			opset(AXVMULWEVHB, r0)
  1693  			opset(AXVMULWEVWH, r0)
  1694  			opset(AXVMULWEVVW, r0)
  1695  			opset(AXVMULWEVQV, r0)
  1696  			opset(AXVMULWODHB, r0)
  1697  			opset(AXVMULWODWH, r0)
  1698  			opset(AXVMULWODVW, r0)
  1699  			opset(AXVMULWODQV, r0)
  1700  			opset(AXVMULWEVHBU, r0)
  1701  			opset(AXVMULWEVWHU, r0)
  1702  			opset(AXVMULWEVVWU, r0)
  1703  			opset(AXVMULWEVQVU, r0)
  1704  			opset(AXVMULWODHBU, r0)
  1705  			opset(AXVMULWODWHU, r0)
  1706  			opset(AXVMULWODVWU, r0)
  1707  			opset(AXVMULWODQVU, r0)
  1708  			opset(AXVMULWEVHBUB, r0)
  1709  			opset(AXVMULWEVWHUH, r0)
  1710  			opset(AXVMULWEVVWUW, r0)
  1711  			opset(AXVMULWEVQVUV, r0)
  1712  			opset(AXVMULWODHBUB, r0)
  1713  			opset(AXVMULWODWHUH, r0)
  1714  			opset(AXVMULWODVWUW, r0)
  1715  			opset(AXVMULWODQVUV, r0)
  1716  			opset(AXVADDF, r0)
  1717  			opset(AXVADDD, r0)
  1718  			opset(AXVSUBF, r0)
  1719  			opset(AXVSUBD, r0)
  1720  			opset(AXVMULF, r0)
  1721  			opset(AXVMULD, r0)
  1722  			opset(AXVDIVF, r0)
  1723  			opset(AXVDIVD, r0)
  1724  			opset(AXVSHUFH, r0)
  1725  			opset(AXVSHUFW, r0)
  1726  			opset(AXVSHUFV, r0)
  1727  
  1728  		case AVSLTB:
  1729  			opset(AVSLTH, r0)
  1730  			opset(AVSLTW, r0)
  1731  			opset(AVSLTV, r0)
  1732  			opset(AVSLTBU, r0)
  1733  			opset(AVSLTHU, r0)
  1734  			opset(AVSLTWU, r0)
  1735  			opset(AVSLTVU, r0)
  1736  			opset(AVADDWEVHB, r0)
  1737  			opset(AVADDWEVWH, r0)
  1738  			opset(AVADDWEVVW, r0)
  1739  			opset(AVADDWEVQV, r0)
  1740  			opset(AVSUBWEVHB, r0)
  1741  			opset(AVSUBWEVWH, r0)
  1742  			opset(AVSUBWEVVW, r0)
  1743  			opset(AVSUBWEVQV, r0)
  1744  			opset(AVADDWODHB, r0)
  1745  			opset(AVADDWODWH, r0)
  1746  			opset(AVADDWODVW, r0)
  1747  			opset(AVADDWODQV, r0)
  1748  			opset(AVSUBWODHB, r0)
  1749  			opset(AVSUBWODWH, r0)
  1750  			opset(AVSUBWODVW, r0)
  1751  			opset(AVSUBWODQV, r0)
  1752  			opset(AVADDWEVHBU, r0)
  1753  			opset(AVADDWEVWHU, r0)
  1754  			opset(AVADDWEVVWU, r0)
  1755  			opset(AVADDWEVQVU, r0)
  1756  			opset(AVSUBWEVHBU, r0)
  1757  			opset(AVSUBWEVWHU, r0)
  1758  			opset(AVSUBWEVVWU, r0)
  1759  			opset(AVSUBWEVQVU, r0)
  1760  			opset(AVADDWODHBU, r0)
  1761  			opset(AVADDWODWHU, r0)
  1762  			opset(AVADDWODVWU, r0)
  1763  			opset(AVADDWODQVU, r0)
  1764  			opset(AVSUBWODHBU, r0)
  1765  			opset(AVSUBWODWHU, r0)
  1766  			opset(AVSUBWODVWU, r0)
  1767  			opset(AVSUBWODQVU, r0)
  1768  			opset(AVMADDB, r0)
  1769  			opset(AVMADDH, r0)
  1770  			opset(AVMADDW, r0)
  1771  			opset(AVMADDV, r0)
  1772  			opset(AVMSUBB, r0)
  1773  			opset(AVMSUBH, r0)
  1774  			opset(AVMSUBW, r0)
  1775  			opset(AVMSUBV, r0)
  1776  			opset(AVMADDWEVHB, r0)
  1777  			opset(AVMADDWEVWH, r0)
  1778  			opset(AVMADDWEVVW, r0)
  1779  			opset(AVMADDWEVQV, r0)
  1780  			opset(AVMADDWODHB, r0)
  1781  			opset(AVMADDWODWH, r0)
  1782  			opset(AVMADDWODVW, r0)
  1783  			opset(AVMADDWODQV, r0)
  1784  			opset(AVMADDWEVHBU, r0)
  1785  			opset(AVMADDWEVWHU, r0)
  1786  			opset(AVMADDWEVVWU, r0)
  1787  			opset(AVMADDWEVQVU, r0)
  1788  			opset(AVMADDWODHBU, r0)
  1789  			opset(AVMADDWODWHU, r0)
  1790  			opset(AVMADDWODVWU, r0)
  1791  			opset(AVMADDWODQVU, r0)
  1792  			opset(AVMADDWEVHBUB, r0)
  1793  			opset(AVMADDWEVWHUH, r0)
  1794  			opset(AVMADDWEVVWUW, r0)
  1795  			opset(AVMADDWEVQVUV, r0)
  1796  			opset(AVMADDWODHBUB, r0)
  1797  			opset(AVMADDWODWHUH, r0)
  1798  			opset(AVMADDWODVWUW, r0)
  1799  			opset(AVMADDWODQVUV, r0)
  1800  
  1801  		case AXVSLTB:
  1802  			opset(AXVSLTH, r0)
  1803  			opset(AXVSLTW, r0)
  1804  			opset(AXVSLTV, r0)
  1805  			opset(AXVSLTBU, r0)
  1806  			opset(AXVSLTHU, r0)
  1807  			opset(AXVSLTWU, r0)
  1808  			opset(AXVSLTVU, r0)
  1809  			opset(AXVADDWEVHB, r0)
  1810  			opset(AXVADDWEVWH, r0)
  1811  			opset(AXVADDWEVVW, r0)
  1812  			opset(AXVADDWEVQV, r0)
  1813  			opset(AXVSUBWEVHB, r0)
  1814  			opset(AXVSUBWEVWH, r0)
  1815  			opset(AXVSUBWEVVW, r0)
  1816  			opset(AXVSUBWEVQV, r0)
  1817  			opset(AXVADDWODHB, r0)
  1818  			opset(AXVADDWODWH, r0)
  1819  			opset(AXVADDWODVW, r0)
  1820  			opset(AXVADDWODQV, r0)
  1821  			opset(AXVSUBWODHB, r0)
  1822  			opset(AXVSUBWODWH, r0)
  1823  			opset(AXVSUBWODVW, r0)
  1824  			opset(AXVSUBWODQV, r0)
  1825  			opset(AXVADDWEVHBU, r0)
  1826  			opset(AXVADDWEVWHU, r0)
  1827  			opset(AXVADDWEVVWU, r0)
  1828  			opset(AXVADDWEVQVU, r0)
  1829  			opset(AXVSUBWEVHBU, r0)
  1830  			opset(AXVSUBWEVWHU, r0)
  1831  			opset(AXVSUBWEVVWU, r0)
  1832  			opset(AXVSUBWEVQVU, r0)
  1833  			opset(AXVADDWODHBU, r0)
  1834  			opset(AXVADDWODWHU, r0)
  1835  			opset(AXVADDWODVWU, r0)
  1836  			opset(AXVADDWODQVU, r0)
  1837  			opset(AXVSUBWODHBU, r0)
  1838  			opset(AXVSUBWODWHU, r0)
  1839  			opset(AXVSUBWODVWU, r0)
  1840  			opset(AXVSUBWODQVU, r0)
  1841  			opset(AXVMADDB, r0)
  1842  			opset(AXVMADDH, r0)
  1843  			opset(AXVMADDW, r0)
  1844  			opset(AXVMADDV, r0)
  1845  			opset(AXVMSUBB, r0)
  1846  			opset(AXVMSUBH, r0)
  1847  			opset(AXVMSUBW, r0)
  1848  			opset(AXVMSUBV, r0)
  1849  			opset(AXVMADDWEVHB, r0)
  1850  			opset(AXVMADDWEVWH, r0)
  1851  			opset(AXVMADDWEVVW, r0)
  1852  			opset(AXVMADDWEVQV, r0)
  1853  			opset(AXVMADDWODHB, r0)
  1854  			opset(AXVMADDWODWH, r0)
  1855  			opset(AXVMADDWODVW, r0)
  1856  			opset(AXVMADDWODQV, r0)
  1857  			opset(AXVMADDWEVHBU, r0)
  1858  			opset(AXVMADDWEVWHU, r0)
  1859  			opset(AXVMADDWEVVWU, r0)
  1860  			opset(AXVMADDWEVQVU, r0)
  1861  			opset(AXVMADDWODHBU, r0)
  1862  			opset(AXVMADDWODWHU, r0)
  1863  			opset(AXVMADDWODVWU, r0)
  1864  			opset(AXVMADDWODQVU, r0)
  1865  			opset(AXVMADDWEVHBUB, r0)
  1866  			opset(AXVMADDWEVWHUH, r0)
  1867  			opset(AXVMADDWEVVWUW, r0)
  1868  			opset(AXVMADDWEVQVUV, r0)
  1869  			opset(AXVMADDWODHBUB, r0)
  1870  			opset(AXVMADDWODWHUH, r0)
  1871  			opset(AXVMADDWODVWUW, r0)
  1872  			opset(AXVMADDWODQVUV, r0)
  1873  
  1874  		case AVANDB:
  1875  			opset(AVORB, r0)
  1876  			opset(AVXORB, r0)
  1877  			opset(AVNORB, r0)
  1878  			opset(AVSHUF4IB, r0)
  1879  			opset(AVSHUF4IH, r0)
  1880  			opset(AVSHUF4IW, r0)
  1881  			opset(AVSHUF4IV, r0)
  1882  			opset(AVPERMIW, r0)
  1883  			opset(AVEXTRINSB, r0)
  1884  			opset(AVEXTRINSH, r0)
  1885  			opset(AVEXTRINSW, r0)
  1886  			opset(AVEXTRINSV, r0)
  1887  
  1888  		case AXVANDB:
  1889  			opset(AXVORB, r0)
  1890  			opset(AXVXORB, r0)
  1891  			opset(AXVNORB, r0)
  1892  			opset(AXVSHUF4IB, r0)
  1893  			opset(AXVSHUF4IH, r0)
  1894  			opset(AXVSHUF4IW, r0)
  1895  			opset(AXVSHUF4IV, r0)
  1896  			opset(AXVPERMIW, r0)
  1897  			opset(AXVPERMIV, r0)
  1898  			opset(AXVPERMIQ, r0)
  1899  			opset(AXVEXTRINSB, r0)
  1900  			opset(AXVEXTRINSH, r0)
  1901  			opset(AXVEXTRINSW, r0)
  1902  			opset(AXVEXTRINSV, r0)
  1903  
  1904  		case AVANDV:
  1905  			opset(AVORV, r0)
  1906  			opset(AVXORV, r0)
  1907  			opset(AVNORV, r0)
  1908  			opset(AVANDNV, r0)
  1909  			opset(AVORNV, r0)
  1910  
  1911  		case AXVANDV:
  1912  			opset(AXVORV, r0)
  1913  			opset(AXVXORV, r0)
  1914  			opset(AXVNORV, r0)
  1915  			opset(AXVANDNV, r0)
  1916  			opset(AXVORNV, r0)
  1917  
  1918  		case AVPCNTB:
  1919  			opset(AVPCNTH, r0)
  1920  			opset(AVPCNTW, r0)
  1921  			opset(AVPCNTV, r0)
  1922  			opset(AVFSQRTF, r0)
  1923  			opset(AVFSQRTD, r0)
  1924  			opset(AVFRECIPF, r0)
  1925  			opset(AVFRECIPD, r0)
  1926  			opset(AVFRSQRTF, r0)
  1927  			opset(AVFRSQRTD, r0)
  1928  			opset(AVNEGB, r0)
  1929  			opset(AVNEGH, r0)
  1930  			opset(AVNEGW, r0)
  1931  			opset(AVNEGV, r0)
  1932  			opset(AVFRINTRNEF, r0)
  1933  			opset(AVFRINTRNED, r0)
  1934  			opset(AVFRINTRZF, r0)
  1935  			opset(AVFRINTRZD, r0)
  1936  			opset(AVFRINTRPF, r0)
  1937  			opset(AVFRINTRPD, r0)
  1938  			opset(AVFRINTRMF, r0)
  1939  			opset(AVFRINTRMD, r0)
  1940  			opset(AVFRINTF, r0)
  1941  			opset(AVFRINTD, r0)
  1942  			opset(AVFCLASSF, r0)
  1943  			opset(AVFCLASSD, r0)
  1944  
  1945  		case AXVPCNTB:
  1946  			opset(AXVPCNTH, r0)
  1947  			opset(AXVPCNTW, r0)
  1948  			opset(AXVPCNTV, r0)
  1949  			opset(AXVFSQRTF, r0)
  1950  			opset(AXVFSQRTD, r0)
  1951  			opset(AXVFRECIPF, r0)
  1952  			opset(AXVFRECIPD, r0)
  1953  			opset(AXVFRSQRTF, r0)
  1954  			opset(AXVFRSQRTD, r0)
  1955  			opset(AXVNEGB, r0)
  1956  			opset(AXVNEGH, r0)
  1957  			opset(AXVNEGW, r0)
  1958  			opset(AXVNEGV, r0)
  1959  			opset(AXVFRINTRNEF, r0)
  1960  			opset(AXVFRINTRNED, r0)
  1961  			opset(AXVFRINTRZF, r0)
  1962  			opset(AXVFRINTRZD, r0)
  1963  			opset(AXVFRINTRPF, r0)
  1964  			opset(AXVFRINTRPD, r0)
  1965  			opset(AXVFRINTRMF, r0)
  1966  			opset(AXVFRINTRMD, r0)
  1967  			opset(AXVFRINTF, r0)
  1968  			opset(AXVFRINTD, r0)
  1969  			opset(AXVFCLASSF, r0)
  1970  			opset(AXVFCLASSD, r0)
  1971  
  1972  		case AVADDB:
  1973  			opset(AVADDH, r0)
  1974  			opset(AVADDW, r0)
  1975  			opset(AVADDV, r0)
  1976  			opset(AVADDQ, r0)
  1977  			opset(AVSUBB, r0)
  1978  			opset(AVSUBH, r0)
  1979  			opset(AVSUBW, r0)
  1980  			opset(AVSUBV, r0)
  1981  			opset(AVSUBQ, r0)
  1982  			opset(AVSADDB, r0)
  1983  			opset(AVSADDH, r0)
  1984  			opset(AVSADDW, r0)
  1985  			opset(AVSADDV, r0)
  1986  			opset(AVSSUBB, r0)
  1987  			opset(AVSSUBH, r0)
  1988  			opset(AVSSUBW, r0)
  1989  			opset(AVSSUBV, r0)
  1990  			opset(AVSADDBU, r0)
  1991  			opset(AVSADDHU, r0)
  1992  			opset(AVSADDWU, r0)
  1993  			opset(AVSADDVU, r0)
  1994  			opset(AVSSUBBU, r0)
  1995  			opset(AVSSUBHU, r0)
  1996  			opset(AVSSUBWU, r0)
  1997  			opset(AVSSUBVU, r0)
  1998  
  1999  		case AXVADDB:
  2000  			opset(AXVADDH, r0)
  2001  			opset(AXVADDW, r0)
  2002  			opset(AXVADDV, r0)
  2003  			opset(AXVADDQ, r0)
  2004  			opset(AXVSUBB, r0)
  2005  			opset(AXVSUBH, r0)
  2006  			opset(AXVSUBW, r0)
  2007  			opset(AXVSUBV, r0)
  2008  			opset(AXVSUBQ, r0)
  2009  			opset(AXVSADDB, r0)
  2010  			opset(AXVSADDH, r0)
  2011  			opset(AXVSADDW, r0)
  2012  			opset(AXVSADDV, r0)
  2013  			opset(AXVSSUBB, r0)
  2014  			opset(AXVSSUBH, r0)
  2015  			opset(AXVSSUBW, r0)
  2016  			opset(AXVSSUBV, r0)
  2017  			opset(AXVSADDBU, r0)
  2018  			opset(AXVSADDHU, r0)
  2019  			opset(AXVSADDWU, r0)
  2020  			opset(AXVSADDVU, r0)
  2021  			opset(AXVSSUBBU, r0)
  2022  			opset(AXVSSUBHU, r0)
  2023  			opset(AXVSSUBWU, r0)
  2024  			opset(AXVSSUBVU, r0)
  2025  
  2026  		case AVSLLB:
  2027  			opset(AVSRLB, r0)
  2028  			opset(AVSRAB, r0)
  2029  			opset(AVROTRB, r0)
  2030  			opset(AVBITCLRB, r0)
  2031  			opset(AVBITSETB, r0)
  2032  			opset(AVBITREVB, r0)
  2033  
  2034  		case AXVSLLB:
  2035  			opset(AXVSRLB, r0)
  2036  			opset(AXVSRAB, r0)
  2037  			opset(AXVROTRB, r0)
  2038  			opset(AXVBITCLRB, r0)
  2039  			opset(AXVBITSETB, r0)
  2040  			opset(AXVBITREVB, r0)
  2041  
  2042  		case AVSLLH:
  2043  			opset(AVSRLH, r0)
  2044  			opset(AVSRAH, r0)
  2045  			opset(AVROTRH, r0)
  2046  			opset(AVBITCLRH, r0)
  2047  			opset(AVBITSETH, r0)
  2048  			opset(AVBITREVH, r0)
  2049  
  2050  		case AXVSLLH:
  2051  			opset(AXVSRLH, r0)
  2052  			opset(AXVSRAH, r0)
  2053  			opset(AXVROTRH, r0)
  2054  			opset(AXVBITCLRH, r0)
  2055  			opset(AXVBITSETH, r0)
  2056  			opset(AXVBITREVH, r0)
  2057  
  2058  		case AVSLLW:
  2059  			opset(AVSRLW, r0)
  2060  			opset(AVSRAW, r0)
  2061  			opset(AVROTRW, r0)
  2062  			opset(AVADDBU, r0)
  2063  			opset(AVADDHU, r0)
  2064  			opset(AVADDWU, r0)
  2065  			opset(AVADDVU, r0)
  2066  			opset(AVSUBBU, r0)
  2067  			opset(AVSUBHU, r0)
  2068  			opset(AVSUBWU, r0)
  2069  			opset(AVSUBVU, r0)
  2070  			opset(AVBITCLRW, r0)
  2071  			opset(AVBITSETW, r0)
  2072  			opset(AVBITREVW, r0)
  2073  
  2074  		case AXVSLLW:
  2075  			opset(AXVSRLW, r0)
  2076  			opset(AXVSRAW, r0)
  2077  			opset(AXVROTRW, r0)
  2078  			opset(AXVADDBU, r0)
  2079  			opset(AXVADDHU, r0)
  2080  			opset(AXVADDWU, r0)
  2081  			opset(AXVADDVU, r0)
  2082  			opset(AXVSUBBU, r0)
  2083  			opset(AXVSUBHU, r0)
  2084  			opset(AXVSUBWU, r0)
  2085  			opset(AXVSUBVU, r0)
  2086  			opset(AXVBITCLRW, r0)
  2087  			opset(AXVBITSETW, r0)
  2088  			opset(AXVBITREVW, r0)
  2089  
  2090  		case AVSLLV:
  2091  			opset(AVSRLV, r0)
  2092  			opset(AVSRAV, r0)
  2093  			opset(AVROTRV, r0)
  2094  			opset(AVBITCLRV, r0)
  2095  			opset(AVBITSETV, r0)
  2096  			opset(AVBITREVV, r0)
  2097  
  2098  		case AXVSLLV:
  2099  			opset(AXVSRLV, r0)
  2100  			opset(AXVSRAV, r0)
  2101  			opset(AXVROTRV, r0)
  2102  			opset(AXVBITCLRV, r0)
  2103  			opset(AXVBITSETV, r0)
  2104  			opset(AXVBITREVV, r0)
  2105  
  2106  		case AVSETEQV:
  2107  			opset(AVSETNEV, r0)
  2108  			opset(AVSETANYEQB, r0)
  2109  			opset(AVSETANYEQH, r0)
  2110  			opset(AVSETANYEQW, r0)
  2111  			opset(AVSETANYEQV, r0)
  2112  			opset(AVSETALLNEB, r0)
  2113  			opset(AVSETALLNEH, r0)
  2114  			opset(AVSETALLNEW, r0)
  2115  			opset(AVSETALLNEV, r0)
  2116  
  2117  		case AXVSETEQV:
  2118  			opset(AXVSETNEV, r0)
  2119  			opset(AXVSETANYEQB, r0)
  2120  			opset(AXVSETANYEQH, r0)
  2121  			opset(AXVSETANYEQW, r0)
  2122  			opset(AXVSETANYEQV, r0)
  2123  			opset(AXVSETALLNEB, r0)
  2124  			opset(AXVSETALLNEH, r0)
  2125  			opset(AXVSETALLNEW, r0)
  2126  			opset(AXVSETALLNEV, r0)
  2127  
  2128  		}
  2129  	}
  2130  }
  2131  
  2132  func OP_RRRR(op uint32, r1 uint32, r2 uint32, r3 uint32, r4 uint32) uint32 {
  2133  	return op | (r1&0x1F)<<15 | (r2&0x1F)<<10 | (r3&0x1F)<<5 | (r4 & 0x1F)
  2134  }
  2135  
  2136  // r1 -> rk
  2137  // r2 -> rj
  2138  // r3 -> rd
  2139  func OP_RRR(op uint32, r1 uint32, r2 uint32, r3 uint32) uint32 {
  2140  	return op | (r1&0x1F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2141  }
  2142  
  2143  // r2 -> rj
  2144  // r3 -> rd
  2145  func OP_RR(op uint32, r2 uint32, r3 uint32) uint32 {
  2146  	return op | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2147  }
  2148  
  2149  func OP_2IRRR(op uint32, i uint32, r2 uint32, r3 uint32, r4 uint32) uint32 {
  2150  	return op | (i&0x3)<<15 | (r2&0x1F)<<10 | (r3&0x1F)<<5 | (r4&0x1F)<<0
  2151  }
  2152  
  2153  func OP_16IR_5I(op uint32, i uint32, r2 uint32) uint32 {
  2154  	return op | (i&0xFFFF)<<10 | (r2&0x1F)<<5 | ((i >> 16) & 0x1F)
  2155  }
  2156  
  2157  func OP_16IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2158  	return op | (i&0xFFFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2159  }
  2160  
  2161  func OP_14IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2162  	return op | (i&0x3FFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2163  }
  2164  
  2165  func OP_12IR_5I(op uint32, i1 uint32, r2 uint32, i2 uint32) uint32 {
  2166  	return op | (i1&0xFFF)<<10 | (r2&0x1F)<<5 | (i2&0x1F)<<0
  2167  }
  2168  
  2169  func OP_12IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2170  	return op | (i&0xFFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2171  }
  2172  
  2173  func OP_11IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2174  	return op | (i&0x7FF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2175  }
  2176  
  2177  func OP_10IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2178  	return op | (i&0x3FF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2179  }
  2180  
  2181  func OP_9IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2182  	return op | (i&0x1FF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2183  }
  2184  
  2185  func OP_8IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2186  	return op | (i&0xFF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2187  }
  2188  
  2189  func OP_6IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2190  	return op | (i&0x3F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2191  }
  2192  
  2193  func OP_5IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2194  	return op | (i&0x1F)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2195  }
  2196  
  2197  func OP_4IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2198  	return op | (i&0xF)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2199  }
  2200  
  2201  func OP_3IRR(op uint32, i uint32, r2 uint32, r3 uint32) uint32 {
  2202  	return op | (i&0x7)<<10 | (r2&0x1F)<<5 | (r3&0x1F)<<0
  2203  }
  2204  
  2205  func OP_IR(op uint32, i uint32, r2 uint32) uint32 {
  2206  	return op | (i&0xFFFFF)<<5 | (r2&0x1F)<<0 // ui20, rd5
  2207  }
  2208  
  2209  func OP_15I(op uint32, i uint32) uint32 {
  2210  	return op | (i&0x7FFF)<<0
  2211  }
  2212  
  2213  // i1 -> msb
  2214  // r2 -> rj
  2215  // i3 -> lsb
  2216  // r4 -> rd
  2217  func OP_IRIR(op uint32, i1 uint32, r2 uint32, i3 uint32, r4 uint32) uint32 {
  2218  	return op | (i1 << 16) | (r2&0x1F)<<5 | (i3 << 10) | (r4&0x1F)<<0
  2219  }
  2220  
  2221  // Encoding for the 'b' or 'bl' instruction.
  2222  func OP_B_BL(op uint32, i uint32) uint32 {
  2223  	return op | ((i & 0xFFFF) << 10) | ((i >> 16) & 0x3FF)
  2224  }
  2225  
  2226  func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
  2227  	o1 := uint32(0)
  2228  	o2 := uint32(0)
  2229  	o3 := uint32(0)
  2230  	o4 := uint32(0)
  2231  	o5 := uint32(0)
  2232  	o6 := uint32(0)
  2233  
  2234  	add := AADDVU
  2235  
  2236  	switch o.type_ {
  2237  	default:
  2238  		c.ctxt.Diag("unknown type %d", o.type_)
  2239  		prasm(p)
  2240  
  2241  	case 0: // pseudo ops
  2242  		break
  2243  
  2244  	case 1: // mov rj, rd
  2245  		switch p.As {
  2246  		case AMOVB:
  2247  			o1 = OP_RR(c.oprr(AEXTWB), uint32(p.From.Reg), uint32(p.To.Reg))
  2248  		case AMOVH:
  2249  			o1 = OP_RR(c.oprr(AEXTWH), uint32(p.From.Reg), uint32(p.To.Reg))
  2250  		case AMOVW:
  2251  			o1 = OP_RRR(c.oprrr(ASLL), uint32(REGZERO), uint32(p.From.Reg), uint32(p.To.Reg))
  2252  		case AMOVV:
  2253  			o1 = OP_RRR(c.oprrr(AOR), uint32(REGZERO), uint32(p.From.Reg), uint32(p.To.Reg))
  2254  		case AMOVBU:
  2255  			o1 = OP_12IRR(c.opirr(AAND), uint32(0xff), uint32(p.From.Reg), uint32(p.To.Reg))
  2256  		case AMOVHU:
  2257  			o1 = OP_IRIR(c.opirir(ABSTRPICKV), 15, uint32(p.From.Reg), 0, uint32(p.To.Reg))
  2258  		case AMOVWU:
  2259  			o1 = OP_IRIR(c.opirir(ABSTRPICKV), 31, uint32(p.From.Reg), 0, uint32(p.To.Reg))
  2260  		case AVMOVQ:
  2261  			o1 = OP_6IRR(c.opirr(AVSLLV), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
  2262  		case AXVMOVQ:
  2263  			o1 = OP_6IRR(c.opirr(AXVSLLV), uint32(0), uint32(p.From.Reg), uint32(p.To.Reg))
  2264  		default:
  2265  			c.ctxt.Diag("unexpected encoding\n%v", p)
  2266  		}
  2267  
  2268  	case 2: // add/sub r1,[r2],r3
  2269  		r := int(p.Reg)
  2270  		if p.As == ANEGW || p.As == ANEGV {
  2271  			r = REGZERO
  2272  		}
  2273  		if r == 0 {
  2274  			r = int(p.To.Reg)
  2275  		}
  2276  		o1 = OP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg))
  2277  
  2278  	case 3: // mov $soreg, r ==> or/add $i,o,r
  2279  		v := c.regoff(&p.From)
  2280  
  2281  		r := int(p.From.Reg)
  2282  		if r == 0 {
  2283  			r = int(o.param)
  2284  		}
  2285  		a := add
  2286  		if o.from1 == C_12CON && v > 0 {
  2287  			a = AOR
  2288  		}
  2289  
  2290  		o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(r), uint32(p.To.Reg))
  2291  
  2292  	case 4: // add $scon,[r1],r2
  2293  		v := c.regoff(&p.From)
  2294  		r := int(p.Reg)
  2295  		if r == 0 {
  2296  			r = int(p.To.Reg)
  2297  		}
  2298  		if p.As == AADDV16 {
  2299  			if v&65535 != 0 {
  2300  				c.ctxt.Diag("%v: the constant must be a multiple of 65536.\n", p)
  2301  			}
  2302  			o1 = OP_16IRR(c.opirr(p.As), uint32(v>>16), uint32(r), uint32(p.To.Reg))
  2303  		} else {
  2304  			o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2305  		}
  2306  
  2307  	case 5: // syscall
  2308  		v := c.regoff(&p.From)
  2309  		o1 = OP_15I(c.opi(p.As), uint32(v))
  2310  
  2311  	case 6: // beq r1,[r2],sbra
  2312  		v := int32(0)
  2313  		if p.To.Target() != nil {
  2314  			v = int32(p.To.Target().Pc-p.Pc) >> 2
  2315  		}
  2316  		as, rd, rj, width := p.As, p.Reg, p.From.Reg, 16
  2317  		switch as {
  2318  		case ABGTZ, ABLEZ:
  2319  			rd, rj = rj, rd
  2320  		case ABFPT, ABFPF:
  2321  			width = 21
  2322  			// FCC0 is the implicit source operand, now that we
  2323  			// don't register-allocate from the FCC bank.
  2324  			if rj == 0 {
  2325  				rj = REG_FCC0
  2326  			}
  2327  		case ABEQ, ABNE:
  2328  			if rd == 0 || rd == REGZERO || rj == REGZERO {
  2329  				// BEQZ/BNEZ can be encoded with 21-bit offsets.
  2330  				width = 21
  2331  				as = -as
  2332  				if rj == 0 || rj == REGZERO {
  2333  					rj = rd
  2334  				}
  2335  			}
  2336  		}
  2337  		switch width {
  2338  		case 21:
  2339  			if (v<<11)>>11 != v {
  2340  				c.ctxt.Diag("21 bit-width, short branch too far\n%v", p)
  2341  			}
  2342  			o1 = OP_16IR_5I(c.opirr(as), uint32(v), uint32(rj))
  2343  		case 16:
  2344  			if (v<<16)>>16 != v {
  2345  				c.ctxt.Diag("16 bit-width, short branch too far\n%v", p)
  2346  			}
  2347  			o1 = OP_16IRR(c.opirr(as), uint32(v), uint32(rj), uint32(rd))
  2348  		default:
  2349  			c.ctxt.Diag("unexpected branch encoding\n%v", p)
  2350  		}
  2351  
  2352  	case 7: // mov r, soreg
  2353  		r := int(p.To.Reg)
  2354  		if r == 0 {
  2355  			r = int(o.param)
  2356  		}
  2357  		v := c.regoff(&p.To)
  2358  		o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.From.Reg))
  2359  
  2360  	case 8: // mov soreg, r
  2361  		r := int(p.From.Reg)
  2362  		if r == 0 {
  2363  			r = int(o.param)
  2364  		}
  2365  		v := c.regoff(&p.From)
  2366  		o1 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2367  
  2368  	case 9: // sll r1,[r2],r3
  2369  		o1 = OP_RR(c.oprr(p.As), uint32(p.From.Reg), uint32(p.To.Reg))
  2370  
  2371  	case 10: // add $con,[r1],r2 ==> mov $con, t; add t,[r1],r2
  2372  		v := c.regoff(&p.From)
  2373  		a := AOR
  2374  		if v < 0 {
  2375  			a = AADD
  2376  		}
  2377  		o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
  2378  		r := int(p.Reg)
  2379  		if r == 0 {
  2380  			r = int(p.To.Reg)
  2381  		}
  2382  		o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2383  
  2384  	case 11: // jmp lbra
  2385  		v := int32(0)
  2386  		if p.To.Target() != nil {
  2387  			v = int32(p.To.Target().Pc-p.Pc) >> 2
  2388  			if v < -1<<25 || v >= 1<<25 {
  2389  				c.ctxt.Diag("branch too far \n%v", p)
  2390  			}
  2391  		}
  2392  		o1 = OP_B_BL(c.opirr(p.As), uint32(v))
  2393  		if p.To.Sym != nil {
  2394  			c.cursym.AddRel(c.ctxt, obj.Reloc{
  2395  				Type: objabi.R_CALLLOONG64,
  2396  				Off:  int32(c.pc),
  2397  				Siz:  4,
  2398  				Sym:  p.To.Sym,
  2399  				Add:  p.To.Offset,
  2400  			})
  2401  		}
  2402  
  2403  	case 13: // vsll $ui3, [vr1], vr2
  2404  		v := c.regoff(&p.From)
  2405  		r := int(p.Reg)
  2406  		if r == 0 {
  2407  			r = int(p.To.Reg)
  2408  		}
  2409  		o1 = OP_3IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2410  
  2411  	case 14: // vsll $ui4, [vr1], vr2
  2412  		v := c.regoff(&p.From)
  2413  		r := int(p.Reg)
  2414  		if r == 0 {
  2415  			r = int(p.To.Reg)
  2416  		}
  2417  		o1 = OP_4IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2418  
  2419  	case 15: // teq $c r,r
  2420  		v := c.regoff(&p.From)
  2421  		r := int(p.Reg)
  2422  		if r == 0 {
  2423  			r = REGZERO
  2424  		}
  2425  		/*
  2426  			teq c, r1, r2
  2427  			fallthrough
  2428  			==>
  2429  			bne r1, r2, 2
  2430  			break c
  2431  			fallthrough
  2432  		*/
  2433  		if p.As == ATEQ {
  2434  			o1 = OP_16IRR(c.opirr(ABNE), uint32(2), uint32(r), uint32(p.To.Reg))
  2435  		} else { // ATNE
  2436  			o1 = OP_16IRR(c.opirr(ABEQ), uint32(2), uint32(r), uint32(p.To.Reg))
  2437  		}
  2438  		o2 = OP_15I(c.opi(ABREAK), uint32(v))
  2439  
  2440  	case 16: // sll $c,[r1],r2
  2441  		v := c.regoff(&p.From)
  2442  		r := int(p.Reg)
  2443  		if r == 0 {
  2444  			r = int(p.To.Reg)
  2445  		}
  2446  
  2447  		// instruction ending with V:6-digit immediate, others:5-digit immediate
  2448  		if v >= 32 && vshift(p.As) {
  2449  			o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x3f, uint32(r), uint32(p.To.Reg))
  2450  		} else {
  2451  			o1 = OP_16IRR(c.opirr(p.As), uint32(v)&0x1f, uint32(r), uint32(p.To.Reg))
  2452  		}
  2453  
  2454  	case 17: // bstrpickw $msbw, r1, $lsbw, r2
  2455  		rd, rj := p.To.Reg, p.Reg
  2456  		if rj == obj.REG_NONE {
  2457  			rj = rd
  2458  		}
  2459  		msb, lsb := p.From.Offset, p.GetFrom3().Offset
  2460  
  2461  		// check the range of msb and lsb
  2462  		var b uint32
  2463  		if p.As == ABSTRPICKW || p.As == ABSTRINSW {
  2464  			b = 32
  2465  		} else {
  2466  			b = 64
  2467  		}
  2468  		if lsb < 0 || uint32(lsb) >= b || msb < 0 || uint32(msb) >= b || uint32(lsb) > uint32(msb) {
  2469  			c.ctxt.Diag("illegal bit number\n%v", p)
  2470  		}
  2471  
  2472  		o1 = OP_IRIR(c.opirir(p.As), uint32(msb), uint32(rj), uint32(lsb), uint32(rd))
  2473  
  2474  	case 18: // jmp [r1],0(r2)
  2475  		r := int(p.Reg)
  2476  		if r == 0 {
  2477  			r = int(o.param)
  2478  		}
  2479  		o1 = OP_RRR(c.oprrr(p.As), uint32(0), uint32(p.To.Reg), uint32(r))
  2480  		if p.As == obj.ACALL {
  2481  			c.cursym.AddRel(c.ctxt, obj.Reloc{
  2482  				Type: objabi.R_CALLIND,
  2483  				Off:  int32(c.pc),
  2484  			})
  2485  		}
  2486  
  2487  	case 19: // mov $lcon,r
  2488  		// NOTE: this case does not use REGTMP. If it ever does,
  2489  		// remove the NOTUSETMP flag in optab.
  2490  		v := c.regoff(&p.From)
  2491  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2492  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  2493  
  2494  	case 20: // mov Rsrc, (Rbase)(Roff)
  2495  		o1 = OP_RRR(c.oprrr(p.As), uint32(p.To.Index), uint32(p.To.Reg), uint32(p.From.Reg))
  2496  
  2497  	case 21: // mov (Rbase)(Roff), Rdst
  2498  		o1 = OP_RRR(c.oprrr(-p.As), uint32(p.From.Index), uint32(p.From.Reg), uint32(p.To.Reg))
  2499  
  2500  	case 22: // add $si5,[r1],r2
  2501  		v := c.regoff(&p.From)
  2502  		r := int(p.Reg)
  2503  		if r == 0 {
  2504  			r = int(p.To.Reg)
  2505  		}
  2506  
  2507  		o1 = OP_5IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2508  
  2509  	case 23: // add $ui8,[r1],r2
  2510  		v := c.regoff(&p.From)
  2511  		r := int(p.Reg)
  2512  		if r == 0 {
  2513  			r = int(p.To.Reg)
  2514  		}
  2515  
  2516  		// the operand range available for instructions VSHUF4IV and XVSHUF4IV is [0, 15]
  2517  		if p.As == AVSHUF4IV || p.As == AXVSHUF4IV {
  2518  			operand := uint32(v)
  2519  			c.checkoperand(p, operand, 15)
  2520  		}
  2521  
  2522  		o1 = OP_8IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2523  
  2524  	case 24: // add $lcon,r1,r2
  2525  		v := c.regoff(&p.From)
  2526  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2527  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  2528  		r := int(p.Reg)
  2529  		if r == 0 {
  2530  			r = int(p.To.Reg)
  2531  		}
  2532  		o3 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2533  
  2534  	case 25: // mov $ucon,r
  2535  		v := c.regoff(&p.From)
  2536  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2537  
  2538  	case 26: // add/and $ucon,[r1],r2
  2539  		v := c.regoff(&p.From)
  2540  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2541  		r := int(p.Reg)
  2542  		if r == 0 {
  2543  			r = int(p.To.Reg)
  2544  		}
  2545  		o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2546  
  2547  	case 27: // mov $lsext/auto/oreg,r
  2548  		v := c.regoff(&p.From)
  2549  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2550  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  2551  		r := int(p.From.Reg)
  2552  		if r == 0 {
  2553  			r = int(o.param)
  2554  		}
  2555  		o3 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2556  
  2557  	case 28: // mov [sl]ext/auto/oreg,fr
  2558  		v := c.regoff(&p.From)
  2559  		r := int(p.From.Reg)
  2560  		if r == 0 {
  2561  			r = int(o.param)
  2562  		}
  2563  		switch o.size {
  2564  		case 12:
  2565  			o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  2566  			o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  2567  			o3 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
  2568  
  2569  		case 4:
  2570  			o1 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2571  		}
  2572  
  2573  	case 29: // mov fr,[sl]ext/auto/oreg
  2574  		v := c.regoff(&p.To)
  2575  		r := int(p.To.Reg)
  2576  		if r == 0 {
  2577  			r = int(o.param)
  2578  		}
  2579  		switch o.size {
  2580  		case 12:
  2581  			o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  2582  			o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  2583  			o3 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
  2584  
  2585  		case 4:
  2586  			o1 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.From.Reg))
  2587  		}
  2588  
  2589  	case 30: // mov gr/fr/fcc/fcsr, fr/fcc/fcsr/gr
  2590  		a := c.specialFpMovInst(p.As, oclass(&p.From), oclass(&p.To))
  2591  		o1 = OP_RR(a, uint32(p.From.Reg), uint32(p.To.Reg))
  2592  
  2593  	case 31: // vsll $ui5, [vr1], vr2
  2594  		v := c.regoff(&p.From)
  2595  		r := int(p.Reg)
  2596  		if r == 0 {
  2597  			r = int(p.To.Reg)
  2598  		}
  2599  		o1 = OP_5IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2600  
  2601  	case 32: // vsll $ui6, [vr1], vr2
  2602  		v := c.regoff(&p.From)
  2603  		r := int(p.Reg)
  2604  		if r == 0 {
  2605  			r = int(p.To.Reg)
  2606  		}
  2607  		o1 = OP_6IRR(c.opirr(p.As), uint32(v), uint32(r), uint32(p.To.Reg))
  2608  
  2609  	case 33: // fsel ca, fk, [fj], fd
  2610  		ca := uint32(p.From.Reg)
  2611  		fk := uint32(p.Reg)
  2612  		fd := uint32(p.To.Reg)
  2613  		fj := fd
  2614  		if len(p.RestArgs) > 0 {
  2615  			fj = uint32(p.GetFrom3().Reg)
  2616  		}
  2617  		o1 = 0x340<<18 | (ca&0x7)<<15 | (fk&0x1F)<<10 | (fj&0x1F)<<5 | (fd & 0x1F)
  2618  
  2619  	case 34: // mov $con,fr
  2620  		v := c.regoff(&p.From)
  2621  		a := AADD
  2622  		if v > 0 {
  2623  			a = AOR
  2624  		}
  2625  		a2 := c.specialFpMovInst(p.As, C_REG, oclass(&p.To))
  2626  		o1 = OP_12IRR(c.opirr(a), uint32(v), uint32(0), uint32(REGTMP))
  2627  		o2 = OP_RR(a2, uint32(REGTMP), uint32(p.To.Reg))
  2628  
  2629  	case 35: // mov r,lext/auto/oreg
  2630  		v := c.regoff(&p.To)
  2631  		r := int(p.To.Reg)
  2632  		if r == 0 {
  2633  			r = int(o.param)
  2634  		}
  2635  		o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  2636  		o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  2637  		o3 = OP_12IRR(c.opirr(p.As), uint32(v), uint32(REGTMP), uint32(p.From.Reg))
  2638  
  2639  	case 36: // mov lext/auto/oreg,r
  2640  		v := c.regoff(&p.From)
  2641  		r := int(p.From.Reg)
  2642  		if r == 0 {
  2643  			r = int(o.param)
  2644  		}
  2645  		o1 = OP_IR(c.opir(ALU12IW), uint32((v+1<<11)>>12), uint32(REGTMP))
  2646  		o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  2647  		o3 = OP_12IRR(c.opirr(-p.As), uint32(v), uint32(REGTMP), uint32(p.To.Reg))
  2648  
  2649  	case 37: // fmadd r1, r2, [r3], r4
  2650  		r := int(p.To.Reg)
  2651  		if len(p.RestArgs) > 0 {
  2652  			r = int(p.GetFrom3().Reg)
  2653  		}
  2654  		o1 = OP_RRRR(c.oprrrr(p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(r), uint32(p.To.Reg))
  2655  
  2656  	case 38: // word
  2657  		o1 = uint32(c.regoff(&p.From))
  2658  
  2659  	case 39: // vmov Rn, Vd.<T>[index]
  2660  		v, m := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg, false)
  2661  		if v == 0 {
  2662  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2663  		}
  2664  
  2665  		Rj := uint32(p.From.Reg & EXT_REG_MASK)
  2666  		Vd := uint32(p.To.Reg & EXT_REG_MASK)
  2667  		index := uint32(p.To.Index)
  2668  		c.checkindex(p, index, m)
  2669  		o1 = v | (index << 10) | (Rj << 5) | Vd
  2670  
  2671  	case 40: // vmov Vd.<T>[index], Rn
  2672  		v, m := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg, false)
  2673  		if v == 0 {
  2674  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2675  		}
  2676  
  2677  		Vj := uint32(p.From.Reg & EXT_REG_MASK)
  2678  		Rd := uint32(p.To.Reg & EXT_REG_MASK)
  2679  		index := uint32(p.From.Index)
  2680  		c.checkindex(p, index, m)
  2681  		o1 = v | (index << 10) | (Vj << 5) | Rd
  2682  
  2683  	case 41: // vmov Rn, Vd.<T>
  2684  		v, _ := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg, false)
  2685  		if v == 0 {
  2686  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2687  		}
  2688  
  2689  		Rj := uint32(p.From.Reg & EXT_REG_MASK)
  2690  		Vd := uint32(p.To.Reg & EXT_REG_MASK)
  2691  		o1 = v | (Rj << 5) | Vd
  2692  
  2693  	case 42: // vmov  xj, xd.<T>
  2694  		v, _ := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg, false)
  2695  		if v == 0 {
  2696  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2697  		}
  2698  
  2699  		Xj := uint32(p.From.Reg & EXT_REG_MASK)
  2700  		Xd := uint32(p.To.Reg & EXT_REG_MASK)
  2701  		o1 = v | (Xj << 5) | Xd
  2702  
  2703  	case 43: // vmov  xj, xd.<T>[index]
  2704  		v, m := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg, false)
  2705  		if v == 0 {
  2706  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2707  		}
  2708  
  2709  		Xj := uint32(p.From.Reg & EXT_REG_MASK)
  2710  		Xd := uint32(p.To.Reg & EXT_REG_MASK)
  2711  		index := uint32(p.To.Index)
  2712  		c.checkindex(p, index, m)
  2713  		o1 = v | (index << 10) | (Xj << 5) | Xd
  2714  
  2715  	case 44: // vmov  xj.<T>[index], xd
  2716  		v, m := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg, false)
  2717  		if v == 0 {
  2718  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2719  		}
  2720  
  2721  		Xj := uint32(p.From.Reg & EXT_REG_MASK)
  2722  		Xd := uint32(p.To.Reg & EXT_REG_MASK)
  2723  		index := uint32(p.From.Index)
  2724  		c.checkindex(p, index, m)
  2725  		o1 = v | (index << 10) | (Xj << 5) | Xd
  2726  
  2727  	case 45: // vmov  vj.<T>[index], vd.<T>
  2728  		v, m := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg, false)
  2729  		if v == 0 {
  2730  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2731  		}
  2732  
  2733  		vj := uint32(p.From.Reg & EXT_REG_MASK)
  2734  		vd := uint32(p.To.Reg & EXT_REG_MASK)
  2735  		index := uint32(p.From.Index)
  2736  		c.checkindex(p, index, m)
  2737  		o1 = v | (index << 10) | (vj << 5) | vd
  2738  
  2739  	case 46: // vmov offset(vj), vd.<T>
  2740  		v, _ := c.specialLsxMovInst(p.As, p.From.Reg, p.To.Reg, true)
  2741  		if v == 0 {
  2742  			c.ctxt.Diag("illegal arng type combination: %v\n", p)
  2743  		}
  2744  
  2745  		si := c.regoff(&p.From)
  2746  		Rj := uint32(p.From.Reg & EXT_REG_MASK)
  2747  		Vd := uint32(p.To.Reg & EXT_REG_MASK)
  2748  		switch v & 0xc00000 {
  2749  		case 0x800000: // [x]vldrepl.b
  2750  			o1 = OP_12IRR(v, uint32(si), Rj, Vd)
  2751  		case 0x400000: // [x]vldrepl.h
  2752  			if si&1 != 0 {
  2753  				c.ctxt.Diag("%v: offset must be a multiple of 2.\n", p)
  2754  			}
  2755  			o1 = OP_11IRR(v, uint32(si>>1), Rj, Vd)
  2756  		case 0x0:
  2757  			switch v & 0x300000 {
  2758  			case 0x200000: // [x]vldrepl.w
  2759  				if si&3 != 0 {
  2760  					c.ctxt.Diag("%v: offset must be a multiple of 4.\n", p)
  2761  				}
  2762  				o1 = OP_10IRR(v, uint32(si>>2), Rj, Vd)
  2763  			case 0x100000: // [x]vldrepl.d
  2764  				if si&7 != 0 {
  2765  					c.ctxt.Diag("%v: offset must be a multiple of 8.\n", p)
  2766  				}
  2767  				o1 = OP_9IRR(v, uint32(si>>3), Rj, Vd)
  2768  			}
  2769  		}
  2770  
  2771  	case 47: // preld  offset(Rbase), $hint
  2772  		offs := c.regoff(&p.From)
  2773  		hint := p.GetFrom3().Offset
  2774  		o1 = OP_12IR_5I(c.opiir(p.As), uint32(offs), uint32(p.From.Reg), uint32(hint))
  2775  
  2776  	case 48: // preldx offset(Rbase), $n, $hint
  2777  		offs := c.regoff(&p.From)
  2778  		hint := p.RestArgs[1].Offset
  2779  		n := uint64(p.GetFrom3().Offset)
  2780  
  2781  		addrSeq := (n >> 0) & 0x1
  2782  		blkSize := (n >> 1) & 0x7ff
  2783  		blkNums := (n >> 12) & 0x1ff
  2784  		stride := (n >> 21) & 0xffff
  2785  
  2786  		if blkSize > 1024 {
  2787  			c.ctxt.Diag("%v: block_size amount out of range[16, 1024]: %v\n", p, blkSize)
  2788  		}
  2789  
  2790  		if blkNums > 256 {
  2791  			c.ctxt.Diag("%v: block_nums amount out of range[1, 256]: %v\n", p, blkSize)
  2792  		}
  2793  
  2794  		v := (uint64(offs) & 0xffff)
  2795  		v += addrSeq << 16
  2796  		v += ((blkSize / 16) - 1) << 20
  2797  		v += (blkNums - 1) << 32
  2798  		v += stride << 44
  2799  
  2800  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2801  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  2802  		o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  2803  		o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  2804  		o5 = OP_5IRR(c.opirr(p.As), uint32(REGTMP), uint32(p.From.Reg), uint32(hint))
  2805  
  2806  	case 49:
  2807  		if p.As == ANOOP {
  2808  			// andi r0, r0, 0
  2809  			o1 = OP_12IRR(c.opirr(AAND), 0, 0, 0)
  2810  		} else {
  2811  			// undef
  2812  			o1 = OP_15I(c.opi(ABREAK), 0)
  2813  		}
  2814  
  2815  	// relocation operations
  2816  	case 50: // mov r,addr ==> pcalau12i + sw
  2817  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
  2818  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2819  			Type: objabi.R_LOONG64_ADDR_HI,
  2820  			Off:  int32(c.pc),
  2821  			Siz:  4,
  2822  			Sym:  p.To.Sym,
  2823  			Add:  p.To.Offset,
  2824  		})
  2825  		o2 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
  2826  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2827  			Type: objabi.R_LOONG64_ADDR_LO,
  2828  			Off:  int32(c.pc + 4),
  2829  			Siz:  4,
  2830  			Sym:  p.To.Sym,
  2831  			Add:  p.To.Offset,
  2832  		})
  2833  
  2834  	case 51: // mov addr,r ==> pcalau12i + lw
  2835  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
  2836  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2837  			Type: objabi.R_LOONG64_ADDR_HI,
  2838  			Off:  int32(c.pc),
  2839  			Siz:  4,
  2840  			Sym:  p.From.Sym,
  2841  			Add:  p.From.Offset,
  2842  		})
  2843  		o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
  2844  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2845  			Type: objabi.R_LOONG64_ADDR_LO,
  2846  			Off:  int32(c.pc + 4),
  2847  			Siz:  4,
  2848  			Sym:  p.From.Sym,
  2849  			Add:  p.From.Offset,
  2850  		})
  2851  
  2852  	case 52: // mov $ext, r
  2853  		// NOTE: this case does not use REGTMP. If it ever does,
  2854  		// remove the NOTUSETMP flag in optab.
  2855  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
  2856  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2857  			Type: objabi.R_LOONG64_ADDR_HI,
  2858  			Off:  int32(c.pc),
  2859  			Siz:  4,
  2860  			Sym:  p.From.Sym,
  2861  			Add:  p.From.Offset,
  2862  		})
  2863  		o2 = OP_12IRR(c.opirr(add), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
  2864  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2865  			Type: objabi.R_LOONG64_ADDR_LO,
  2866  			Off:  int32(c.pc + 4),
  2867  			Siz:  4,
  2868  			Sym:  p.From.Sym,
  2869  			Add:  p.From.Offset,
  2870  		})
  2871  
  2872  	case 53: // mov r, tlsvar ==>  lu12i.w + ori + add r2, regtmp + sw o(regtmp)
  2873  		// NOTE: this case does not use REGTMP. If it ever does,
  2874  		// remove the NOTUSETMP flag in optab.
  2875  		o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
  2876  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2877  			Type: objabi.R_LOONG64_TLS_LE_HI,
  2878  			Off:  int32(c.pc),
  2879  			Siz:  4,
  2880  			Sym:  p.To.Sym,
  2881  			Add:  p.To.Offset,
  2882  		})
  2883  		o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
  2884  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2885  			Type: objabi.R_LOONG64_TLS_LE_LO,
  2886  			Off:  int32(c.pc + 4),
  2887  			Siz:  4,
  2888  			Sym:  p.To.Sym,
  2889  			Add:  p.To.Offset,
  2890  		})
  2891  		o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP))
  2892  		o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
  2893  
  2894  	case 54: // lu12i.w + ori + add r2, regtmp + lw o(regtmp)
  2895  		// NOTE: this case does not use REGTMP. If it ever does,
  2896  		// remove the NOTUSETMP flag in optab.
  2897  		o1 = OP_IR(c.opir(ALU12IW), uint32(0), uint32(REGTMP))
  2898  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2899  			Type: objabi.R_LOONG64_TLS_LE_HI,
  2900  			Off:  int32(c.pc),
  2901  			Siz:  4,
  2902  			Sym:  p.From.Sym,
  2903  			Add:  p.From.Offset,
  2904  		})
  2905  		o2 = OP_12IRR(c.opirr(AOR), uint32(0), uint32(REGTMP), uint32(REGTMP))
  2906  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2907  			Type: objabi.R_LOONG64_TLS_LE_LO,
  2908  			Off:  int32(c.pc + 4),
  2909  			Siz:  4,
  2910  			Sym:  p.From.Sym,
  2911  			Add:  p.From.Offset,
  2912  		})
  2913  		o3 = OP_RRR(c.oprrr(AADDV), uint32(REG_R2), uint32(REGTMP), uint32(REGTMP))
  2914  		o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
  2915  
  2916  	case 56: // mov r, tlsvar IE model ==> (pcalau12i + ld.d)tlsvar@got + add.d + st.d
  2917  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
  2918  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2919  			Type: objabi.R_LOONG64_TLS_IE_HI,
  2920  			Off:  int32(c.pc),
  2921  			Siz:  4,
  2922  			Sym:  p.To.Sym,
  2923  		})
  2924  		o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP))
  2925  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2926  			Type: objabi.R_LOONG64_TLS_IE_LO,
  2927  			Off:  int32(c.pc + 4),
  2928  			Siz:  4,
  2929  			Sym:  p.To.Sym,
  2930  		})
  2931  		o3 = OP_RRR(c.oprrr(AADDVU), uint32(REGTMP), uint32(REG_R2), uint32(REGTMP))
  2932  		o4 = OP_12IRR(c.opirr(p.As), uint32(0), uint32(REGTMP), uint32(p.From.Reg))
  2933  
  2934  	case 57: // mov tlsvar, r IE model ==> (pcalau12i + ld.d)tlsvar@got + add.d + ld.d
  2935  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(REGTMP))
  2936  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2937  			Type: objabi.R_LOONG64_TLS_IE_HI,
  2938  			Off:  int32(c.pc),
  2939  			Siz:  4,
  2940  			Sym:  p.From.Sym,
  2941  		})
  2942  		o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(REGTMP))
  2943  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2944  			Type: objabi.R_LOONG64_TLS_IE_LO,
  2945  			Off:  int32(c.pc + 4),
  2946  			Siz:  4,
  2947  			Sym:  p.From.Sym,
  2948  		})
  2949  		o3 = OP_RRR(c.oprrr(AADDVU), uint32(REGTMP), uint32(REG_R2), uint32(REGTMP))
  2950  		o4 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(REGTMP), uint32(p.To.Reg))
  2951  
  2952  	case 59: // mov $dcon,r
  2953  		// NOTE: this case does not use REGTMP. If it ever does,
  2954  		// remove the NOTUSETMP flag in optab.
  2955  		v := c.vregoff(&p.From)
  2956  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  2957  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  2958  		o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  2959  		o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  2960  
  2961  	case 60: // add $dcon,r1,r2
  2962  		v := c.vregoff(&p.From)
  2963  		o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  2964  		o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  2965  		o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  2966  		o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  2967  		r := int(p.Reg)
  2968  		if r == 0 {
  2969  			r = int(p.To.Reg)
  2970  		}
  2971  		o5 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  2972  
  2973  	case 61: // word C_DCON
  2974  		o1 = uint32(c.vregoff(&p.From))
  2975  		o2 = uint32(c.vregoff(&p.From) >> 32)
  2976  
  2977  	case 62: // rdtimex rd, rj
  2978  		o1 = OP_RR(c.oprr(p.As), uint32(p.To.Reg), uint32(p.RegTo2))
  2979  
  2980  	case 64: // alsl rd, rj, rk, sa2
  2981  		sa := p.From.Offset - 1
  2982  		if sa < 0 || sa > 3 {
  2983  			c.ctxt.Diag("%v: shift amount out of range[1, 4].\n", p)
  2984  		}
  2985  		r := p.GetFrom3().Reg
  2986  		o1 = OP_2IRRR(c.opirrr(p.As), uint32(sa), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
  2987  
  2988  	case 65: // mov sym@GOT, r ==> pcalau12i + ld.d
  2989  		o1 = OP_IR(c.opir(APCALAU12I), uint32(0), uint32(p.To.Reg))
  2990  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2991  			Type: objabi.R_LOONG64_GOT_HI,
  2992  			Off:  int32(c.pc),
  2993  			Siz:  4,
  2994  			Sym:  p.From.Sym,
  2995  		})
  2996  		o2 = OP_12IRR(c.opirr(-p.As), uint32(0), uint32(p.To.Reg), uint32(p.To.Reg))
  2997  		c.cursym.AddRel(c.ctxt, obj.Reloc{
  2998  			Type: objabi.R_LOONG64_GOT_LO,
  2999  			Off:  int32(c.pc + 4),
  3000  			Siz:  4,
  3001  			Sym:  p.From.Sym,
  3002  		})
  3003  
  3004  	case 66: // am* From, To, RegTo2 ==> am* RegTo2, From, To
  3005  		rk := p.From.Reg
  3006  		rj := p.To.Reg
  3007  		rd := p.RegTo2
  3008  
  3009  		// See section 2.2.7.1 of https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html
  3010  		// for the register usage constraints.
  3011  		if rd == rj || rd == rk {
  3012  			c.ctxt.Diag("illegal register combination: %v\n", p)
  3013  		}
  3014  		o1 = OP_RRR(atomicInst[p.As], uint32(rk), uint32(rj), uint32(rd))
  3015  
  3016  	case 67: // mov $dcon12_0, r
  3017  		v := c.vregoff(&p.From)
  3018  		o1 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(0), uint32(p.To.Reg))
  3019  
  3020  	case 68: // mov $dcon12_20S, r
  3021  		v := c.vregoff(&p.From)
  3022  		contype := c.aclass(&p.From)
  3023  		switch contype {
  3024  		default: // C_DCON12_20S
  3025  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  3026  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  3027  		case C_DCON20S_20:
  3028  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  3029  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  3030  		case C_DCON12_12S:
  3031  			o1 = OP_12IRR(c.opirr(AADDV), uint32(v), uint32(0), uint32(p.To.Reg))
  3032  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  3033  		case C_DCON20S_12S, C_DCON20S_0:
  3034  			o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(p.To.Reg))
  3035  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  3036  		case C_DCON12_12U:
  3037  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(p.To.Reg))
  3038  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  3039  		case C_DCON20S_12U:
  3040  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(p.To.Reg))
  3041  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  3042  		}
  3043  
  3044  	case 69: // mov $dcon32_12S, r
  3045  		v := c.vregoff(&p.From)
  3046  		contype := c.aclass(&p.From)
  3047  		switch contype {
  3048  		default: // C_DCON32_12S, C_DCON32_0
  3049  			o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(p.To.Reg))
  3050  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  3051  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  3052  		case C_DCON32_20:
  3053  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  3054  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  3055  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  3056  		case C_DCON12_32S:
  3057  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  3058  			o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  3059  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  3060  		case C_DCON20S_32:
  3061  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(p.To.Reg))
  3062  			o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(p.To.Reg), uint32(p.To.Reg))
  3063  			o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  3064  		case C_DCON32_12U:
  3065  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(p.To.Reg))
  3066  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(p.To.Reg))
  3067  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(p.To.Reg), uint32(p.To.Reg))
  3068  		}
  3069  
  3070  	case 70: // add $dcon12_0,[r1],r2
  3071  		v := c.vregoff(&p.From)
  3072  		r := int(p.Reg)
  3073  		if r == 0 {
  3074  			r = int(p.To.Reg)
  3075  		}
  3076  		o1 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(0), uint32(REGTMP))
  3077  		o2 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  3078  
  3079  	case 71: // add $dcon12_20S,[r1],r2
  3080  		v := c.vregoff(&p.From)
  3081  		r := int(p.Reg)
  3082  		if r == 0 {
  3083  			r = int(p.To.Reg)
  3084  		}
  3085  		contype := c.aclass(&p.From)
  3086  		switch contype {
  3087  		default: // C_DCON12_20S
  3088  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  3089  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  3090  		case C_DCON20S_20:
  3091  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  3092  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  3093  		case C_DCON12_12S:
  3094  			o1 = OP_12IRR(c.opirr(AADDV), uint32(v), uint32(0), uint32(REGTMP))
  3095  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  3096  		case C_DCON20S_12S, C_DCON20S_0:
  3097  			o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(REGTMP))
  3098  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  3099  		case C_DCON12_12U:
  3100  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(REGTMP))
  3101  			o2 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  3102  		case C_DCON20S_12U:
  3103  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(REGTMP))
  3104  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  3105  		}
  3106  		o3 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  3107  
  3108  	case 72: // add $dcon32_12S,[r1],r2
  3109  		v := c.vregoff(&p.From)
  3110  		r := int(p.Reg)
  3111  		if r == 0 {
  3112  			r = int(p.To.Reg)
  3113  		}
  3114  		contype := c.aclass(&p.From)
  3115  		switch contype {
  3116  		default: // C_DCON32_12S, C_DCON32_0
  3117  			o1 = OP_12IRR(c.opirr(AADD), uint32(v), uint32(0), uint32(REGTMP))
  3118  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  3119  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  3120  		case C_DCON32_20:
  3121  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  3122  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  3123  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  3124  		case C_DCON12_32S:
  3125  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  3126  			o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  3127  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  3128  		case C_DCON20S_32:
  3129  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  3130  			o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  3131  			o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  3132  		case C_DCON32_12U:
  3133  			o1 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(0), uint32(REGTMP))
  3134  			o2 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  3135  			o3 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  3136  		}
  3137  		o4 = OP_RRR(c.oprrr(p.As), uint32(REGTMP), uint32(r), uint32(p.To.Reg))
  3138  
  3139  	case 73:
  3140  		v := c.vregoff(&p.To)
  3141  		r := p.To.Reg
  3142  		if v&3 != 0 {
  3143  			c.ctxt.Diag("%v: offset must be a multiple of 4.\n", p)
  3144  		}
  3145  
  3146  		switch o.size {
  3147  		case 4: // 16 bit
  3148  			o1 = OP_14IRR(c.opirr(p.As), uint32(v>>2), uint32(r), uint32(p.From.Reg))
  3149  		case 12: // 32 bit
  3150  			o1 = OP_16IRR(c.opirr(AADDV16), uint32(v>>16), uint32(REG_R0), uint32(REGTMP))
  3151  			o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  3152  			o3 = OP_14IRR(c.opirr(p.As), uint32(v>>2), uint32(REGTMP), uint32(p.From.Reg))
  3153  		case 24: // 64 bit
  3154  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  3155  			o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  3156  			o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  3157  			o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  3158  			o5 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(r))
  3159  			o6 = OP_14IRR(c.opirr(p.As), uint32(0), uint32(r), uint32(p.From.Reg))
  3160  		}
  3161  
  3162  	case 74:
  3163  		v := c.vregoff(&p.From)
  3164  		r := p.From.Reg
  3165  		if v&3 != 0 {
  3166  			c.ctxt.Diag("%v: offset must be a multiple of 4.\n", p)
  3167  		}
  3168  
  3169  		switch o.size {
  3170  		case 4: // 16 bit
  3171  			o1 = OP_14IRR(c.opirr(-p.As), uint32(v>>2), uint32(r), uint32(p.To.Reg))
  3172  		case 12: // 32 bit
  3173  			o1 = OP_16IRR(c.opirr(AADDV16), uint32(v>>16), uint32(REG_R0), uint32(REGTMP))
  3174  			o2 = OP_RRR(c.oprrr(add), uint32(r), uint32(REGTMP), uint32(REGTMP))
  3175  			o3 = OP_14IRR(c.opirr(-p.As), uint32(v>>2), uint32(REGTMP), uint32(p.To.Reg))
  3176  		case 24: // 64 bit
  3177  			o1 = OP_IR(c.opir(ALU12IW), uint32(v>>12), uint32(REGTMP))
  3178  			o2 = OP_12IRR(c.opirr(AOR), uint32(v), uint32(REGTMP), uint32(REGTMP))
  3179  			o3 = OP_IR(c.opir(ALU32ID), uint32(v>>32), uint32(REGTMP))
  3180  			o4 = OP_12IRR(c.opirr(ALU52ID), uint32(v>>52), uint32(REGTMP), uint32(REGTMP))
  3181  			o5 = OP_RRR(c.oprrr(add), uint32(REGTMP), uint32(r), uint32(r))
  3182  			o6 = OP_14IRR(c.opirr(p.As), uint32(0), uint32(r), uint32(p.To.Reg))
  3183  		}
  3184  
  3185  	}
  3186  
  3187  	out[0] = o1
  3188  	out[1] = o2
  3189  	out[2] = o3
  3190  	out[3] = o4
  3191  	out[4] = o5
  3192  	out[5] = o6
  3193  }
  3194  
  3195  // checkoperand checks if operand >= 0 && operand <= maxoperand
  3196  func (c *ctxt0) checkoperand(p *obj.Prog, operand uint32, mask uint32) {
  3197  	if (operand & ^mask) != 0 {
  3198  		c.ctxt.Diag("operand out of range 0 to %d: %v", mask, p)
  3199  	}
  3200  }
  3201  
  3202  // checkindex checks if index >= 0 && index <= maxindex
  3203  func (c *ctxt0) checkindex(p *obj.Prog, index uint32, mask uint32) {
  3204  	if (index & ^mask) != 0 {
  3205  		c.ctxt.Diag("register element index out of range 0 to %d: %v", mask, p)
  3206  	}
  3207  }
  3208  
  3209  func (c *ctxt0) vregoff(a *obj.Addr) int64 {
  3210  	c.instoffset = 0
  3211  	c.aclass(a)
  3212  	return c.instoffset
  3213  }
  3214  
  3215  func (c *ctxt0) regoff(a *obj.Addr) int32 {
  3216  	return int32(c.vregoff(a))
  3217  }
  3218  
  3219  func (c *ctxt0) oprrrr(a obj.As) uint32 {
  3220  	op, ok := oprrrr[a]
  3221  	if ok {
  3222  		return op
  3223  	}
  3224  	c.ctxt.Diag("bad rrrr opcode %v", a)
  3225  	return 0
  3226  }
  3227  
  3228  func (c *ctxt0) oprrr(a obj.As) uint32 {
  3229  	op, ok := oprrr[a]
  3230  	if ok {
  3231  		return op
  3232  	}
  3233  	c.ctxt.Diag("bad rrr opcode %v", a)
  3234  	return 0
  3235  }
  3236  
  3237  func (c *ctxt0) oprr(a obj.As) uint32 {
  3238  	op, ok := oprr[a]
  3239  	if ok {
  3240  		return op
  3241  	}
  3242  	c.ctxt.Diag("bad rr opcode %v", a)
  3243  	return 0
  3244  }
  3245  
  3246  func (c *ctxt0) opi(a obj.As) uint32 {
  3247  	op, ok := opi[a]
  3248  	if ok {
  3249  		return op
  3250  	}
  3251  	c.ctxt.Diag("bad i opcode %v", a)
  3252  	return 0
  3253  }
  3254  
  3255  func (c *ctxt0) opir(a obj.As) uint32 {
  3256  	op, ok := opir[a]
  3257  	if ok {
  3258  		return op
  3259  	}
  3260  	c.ctxt.Diag("bad ir opcode %v", a)
  3261  	return 0
  3262  }
  3263  
  3264  func (c *ctxt0) opirr(a obj.As) uint32 {
  3265  	op, ok := opirr[a]
  3266  	if ok {
  3267  		return op
  3268  	}
  3269  	c.ctxt.Diag("bad irr opcode %v", a)
  3270  	return 0
  3271  }
  3272  
  3273  func (c *ctxt0) opirrr(a obj.As) uint32 {
  3274  	op, ok := opirrr[a]
  3275  	if ok {
  3276  		return op
  3277  	}
  3278  	c.ctxt.Diag("bad irrr opcode %v", a)
  3279  	return 0
  3280  }
  3281  
  3282  func (c *ctxt0) opirir(a obj.As) uint32 {
  3283  	op, ok := opirir[a]
  3284  	if ok {
  3285  		return op
  3286  	}
  3287  	c.ctxt.Diag("bad irir opcode %v", a)
  3288  	return 0
  3289  }
  3290  
  3291  func (c *ctxt0) opiir(a obj.As) uint32 {
  3292  	op, ok := opiir[a]
  3293  	if ok {
  3294  		return op
  3295  	}
  3296  	c.ctxt.Diag("bad iir opcode %v", a)
  3297  	return 0
  3298  }
  3299  
  3300  func vshift(a obj.As) bool {
  3301  	switch a {
  3302  	case ASLLV,
  3303  		ASRLV,
  3304  		ASRAV,
  3305  		AROTRV:
  3306  		return true
  3307  	}
  3308  	return false
  3309  }
  3310  

View as plain text