Help us shape the future of Go! Take the 2026 Go Developer Survey

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

View as plain text