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