...

Source file src/pkg/cmd/internal/obj/mips/asm0.go

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

View as plain text