github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/internal/obj/mips/asm0.go (about)

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