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