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