github.com/euank/go@v0.0.0-20160829210321-495514729181/src/cmd/internal/obj/ppc64/asm9.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 ppc64
    31  
    32  import (
    33  	"cmd/internal/obj"
    34  	"encoding/binary"
    35  	"fmt"
    36  	"log"
    37  	"sort"
    38  )
    39  
    40  // Instruction layout.
    41  
    42  const (
    43  	FuncAlign = 8
    44  )
    45  
    46  const (
    47  	r0iszero = 1
    48  )
    49  
    50  type Optab struct {
    51  	as    obj.As
    52  	a1    uint8
    53  	a2    uint8
    54  	a3    uint8
    55  	a4    uint8
    56  	type_ int8 // cases in asmout below. E.g., 44 = st r,(ra+rb); 45 = ld (ra+rb), r
    57  	size  int8
    58  	param int16
    59  }
    60  
    61  var optab = []Optab{
    62  	{obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
    63  	{obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
    64  	{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
    65  	{obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
    66  	/* move register */
    67  	{AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0},
    68  	{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
    69  	{AMOVBZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
    70  	{AMOVW, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
    71  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
    72  	{AADD, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
    73  	{AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
    74  	{AADD, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
    75  	{AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
    76  	{AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0},
    77  	{AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
    78  	{AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
    79  	{AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
    80  	{AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
    81  	{AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
    82  	{AADDC, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
    83  	{AADDC, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
    84  	{AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
    85  	{AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
    86  	{AAND, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, no literal */
    87  	{AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
    88  	{AANDCC, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
    89  	{AANDCC, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
    90  	{AANDCC, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
    91  	{AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
    92  	{AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
    93  	{AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
    94  	{AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
    95  	{AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
    96  	{AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
    97  	{AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
    98  	{AMULLW, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
    99  	{AMULLW, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
   100  	{AMULLW, C_ANDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
   101  	{AMULLW, C_ANDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
   102  	{AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
   103  	{AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
   104  	{ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0},
   105  	{ASUBC, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
   106  	{ASUBC, C_REG, C_NONE, C_ADDCON, C_REG, 27, 4, 0},
   107  	{ASUBC, C_REG, C_NONE, C_LCON, C_REG, 28, 12, 0},
   108  	{AOR, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, literal not cc (or/xor) */
   109  	{AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
   110  	{AOR, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
   111  	{AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
   112  	{AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
   113  	{AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
   114  	{AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
   115  	{AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
   116  	{ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */
   117  	{ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
   118  	{ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, /* op r2[,r1],r3 */
   119  	{ASUB, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
   120  	{ASLW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
   121  	{ASLW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
   122  	{ASLD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
   123  	{ASLD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
   124  	{ASLD, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0},
   125  	{ASLD, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0},
   126  	{ASLW, C_SCON, C_REG, C_NONE, C_REG, 57, 4, 0},
   127  	{ASLW, C_SCON, C_NONE, C_NONE, C_REG, 57, 4, 0},
   128  	{ASRAW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
   129  	{ASRAW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
   130  	{ASRAW, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
   131  	{ASRAW, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
   132  	{ASRAD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
   133  	{ASRAD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
   134  	{ASRAD, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
   135  	{ASRAD, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
   136  	{ARLWMI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0},
   137  	{ARLWMI, C_REG, C_REG, C_LCON, C_REG, 63, 4, 0},
   138  	{ARLDMI, C_SCON, C_REG, C_LCON, C_REG, 30, 4, 0},
   139  	{ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
   140  	{ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
   141  	{ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
   142  	{ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 4, 0},
   143  	{AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 4, 0},
   144  	{AFADD, C_FREG, C_REG, C_NONE, C_FREG, 2, 4, 0},
   145  	{AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
   146  	{AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 4, 0},
   147  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
   148  	{AFMADD, C_FREG, C_REG, C_FREG, C_FREG, 34, 4, 0},
   149  	{AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 4, 0},
   150  	{AFMUL, C_FREG, C_REG, C_NONE, C_FREG, 32, 4, 0},
   151  
   152  	/* store, short offset */
   153  	{AMOVD, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
   154  	{AMOVW, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
   155  	{AMOVWZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
   156  	{AMOVBZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
   157  	{AMOVBZU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
   158  	{AMOVB, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
   159  	{AMOVBU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
   160  	{AMOVD, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
   161  	{AMOVW, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
   162  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
   163  	{AMOVBZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
   164  	{AMOVB, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
   165  	{AMOVD, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
   166  	{AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
   167  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
   168  	{AMOVBZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
   169  	{AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
   170  	{AMOVD, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
   171  	{AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
   172  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
   173  	{AMOVBZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
   174  	{AMOVBZU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
   175  	{AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
   176  	{AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
   177  
   178  	/* load, short offset */
   179  	{AMOVD, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
   180  	{AMOVW, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
   181  	{AMOVWZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
   182  	{AMOVBZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
   183  	{AMOVBZU, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
   184  	{AMOVB, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
   185  	{AMOVBU, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
   186  	{AMOVD, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
   187  	{AMOVW, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
   188  	{AMOVWZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
   189  	{AMOVBZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
   190  	{AMOVB, C_SEXT, C_NONE, C_NONE, C_REG, 9, 8, REGSB},
   191  	{AMOVD, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
   192  	{AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
   193  	{AMOVWZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
   194  	{AMOVBZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
   195  	{AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, 9, 8, REGSP},
   196  	{AMOVD, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
   197  	{AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
   198  	{AMOVWZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
   199  	{AMOVBZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
   200  	{AMOVBZU, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
   201  	{AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
   202  	{AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
   203  
   204  	/* store, long offset */
   205  	{AMOVD, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
   206  	{AMOVW, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
   207  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
   208  	{AMOVBZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
   209  	{AMOVB, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
   210  	{AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
   211  	{AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
   212  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
   213  	{AMOVBZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
   214  	{AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
   215  	{AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
   216  	{AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
   217  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
   218  	{AMOVBZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
   219  	{AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
   220  	{AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
   221  	{AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
   222  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
   223  	{AMOVBZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
   224  	{AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
   225  
   226  	/* load, long offset */
   227  	{AMOVD, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
   228  	{AMOVW, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
   229  	{AMOVWZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
   230  	{AMOVBZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
   231  	{AMOVB, C_LEXT, C_NONE, C_NONE, C_REG, 37, 12, REGSB},
   232  	{AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
   233  	{AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
   234  	{AMOVWZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
   235  	{AMOVBZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
   236  	{AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 37, 12, REGSP},
   237  	{AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
   238  	{AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
   239  	{AMOVWZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
   240  	{AMOVBZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
   241  	{AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 37, 12, REGZERO},
   242  	{AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
   243  	{AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
   244  	{AMOVWZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
   245  	{AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
   246  	{AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 12, 0},
   247  
   248  	{AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 79, 4, 0},
   249  	{AMOVD, C_TLS_IE, C_NONE, C_NONE, C_REG, 80, 8, 0},
   250  
   251  	{AMOVD, C_GOTADDR, C_NONE, C_NONE, C_REG, 81, 8, 0},
   252  
   253  	/* load constant */
   254  	{AMOVD, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB},
   255  	{AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
   256  	{AMOVD, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
   257  	{AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
   258  	{AMOVD, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
   259  	{AMOVW, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
   260  	{AMOVW, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
   261  	{AMOVW, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
   262  	{AMOVW, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
   263  	{AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
   264  	{AMOVWZ, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
   265  	{AMOVWZ, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
   266  	{AMOVWZ, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
   267  	{AMOVWZ, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
   268  	{AMOVWZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
   269  
   270  	/* load unsigned/long constants (TO DO: check) */
   271  	{AMOVD, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
   272  	{AMOVD, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
   273  	{AMOVW, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
   274  	{AMOVW, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
   275  	{AMOVWZ, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
   276  	{AMOVWZ, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
   277  	{AMOVHBR, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
   278  	{AMOVHBR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
   279  	{AMOVHBR, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
   280  	{AMOVHBR, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
   281  	{ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0},
   282  	{ASYSCALL, C_REG, C_NONE, C_NONE, C_NONE, 77, 12, 0},
   283  	{ASYSCALL, C_SCON, C_NONE, C_NONE, C_NONE, 77, 12, 0},
   284  	{ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
   285  	{ABEQ, C_CREG, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
   286  	{ABR, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0},
   287  	{ABR, C_NONE, C_NONE, C_NONE, C_LBRAPIC, 11, 8, 0},
   288  	{ABC, C_SCON, C_REG, C_NONE, C_SBRA, 16, 4, 0},
   289  	{ABC, C_SCON, C_REG, C_NONE, C_LBRA, 17, 4, 0},
   290  	{ABR, C_NONE, C_NONE, C_NONE, C_LR, 18, 4, 0},
   291  	{ABR, C_NONE, C_NONE, C_NONE, C_CTR, 18, 4, 0},
   292  	{ABR, C_REG, C_NONE, C_NONE, C_CTR, 18, 4, 0},
   293  	{ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
   294  	{ABC, C_NONE, C_REG, C_NONE, C_LR, 18, 4, 0},
   295  	{ABC, C_NONE, C_REG, C_NONE, C_CTR, 18, 4, 0},
   296  	{ABC, C_SCON, C_REG, C_NONE, C_LR, 18, 4, 0},
   297  	{ABC, C_SCON, C_REG, C_NONE, C_CTR, 18, 4, 0},
   298  	{ABC, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
   299  	{AFMOVD, C_SEXT, C_NONE, C_NONE, C_FREG, 8, 4, REGSB},
   300  	{AFMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, 8, 4, REGSP},
   301  	{AFMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, 8, 4, REGZERO},
   302  	{AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB},
   303  	{AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP},
   304  	{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO},
   305  	{AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0},
   306  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
   307  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
   308  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
   309  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
   310  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
   311  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
   312  	{AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
   313  	{AFMOVSX, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0},
   314  	{AFMOVSX, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0},
   315  	{AFMOVSX, C_FREG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
   316  	{AFMOVSX, C_FREG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
   317  	{AFMOVSZ, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0},
   318  	{AFMOVSZ, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0},
   319  	{ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
   320  	{AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 4, 0},
   321  	{ADWORD, C_LCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
   322  	{ADWORD, C_DCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
   323  	{AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
   324  	{AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0},
   325  	{AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0},
   326  	{ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
   327  	{ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0},
   328  	{AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0},
   329  	{AREM, C_REG, C_REG, C_NONE, C_REG, 50, 12, 0},
   330  	{AREMU, C_REG, C_NONE, C_NONE, C_REG, 50, 16, 0},
   331  	{AREMU, C_REG, C_REG, C_NONE, C_REG, 50, 16, 0},
   332  	{AREMD, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
   333  	{AREMD, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
   334  	{AREMDU, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
   335  	{AREMDU, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
   336  	{AMTFSB0, C_SCON, C_NONE, C_NONE, C_NONE, 52, 4, 0},
   337  	{AMOVFL, C_FPSCR, C_NONE, C_NONE, C_FREG, 53, 4, 0},
   338  	{AMOVFL, C_FREG, C_NONE, C_NONE, C_FPSCR, 64, 4, 0},
   339  	{AMOVFL, C_FREG, C_NONE, C_LCON, C_FPSCR, 64, 4, 0},
   340  	{AMOVFL, C_LCON, C_NONE, C_NONE, C_FPSCR, 65, 4, 0},
   341  	{AMOVD, C_MSR, C_NONE, C_NONE, C_REG, 54, 4, 0},  /* mfmsr */
   342  	{AMOVD, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0},  /* mtmsrd */
   343  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsr */
   344  
   345  	/* 64-bit special registers */
   346  	{AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
   347  	{AMOVD, C_REG, C_NONE, C_NONE, C_LR, 66, 4, 0},
   348  	{AMOVD, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
   349  	{AMOVD, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
   350  	{AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
   351  	{AMOVD, C_LR, C_NONE, C_NONE, C_REG, 66, 4, 0},
   352  	{AMOVD, C_CTR, C_NONE, C_NONE, C_REG, 66, 4, 0},
   353  	{AMOVD, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
   354  
   355  	/* 32-bit special registers (gloss over sign-extension or not?) */
   356  	{AMOVW, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
   357  	{AMOVW, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
   358  	{AMOVW, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
   359  	{AMOVW, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
   360  	{AMOVW, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
   361  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
   362  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
   363  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
   364  	{AMOVWZ, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
   365  	{AMOVWZ, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
   366  	{AMOVFL, C_FPSCR, C_NONE, C_NONE, C_CREG, 73, 4, 0},
   367  	{AMOVFL, C_CREG, C_NONE, C_NONE, C_CREG, 67, 4, 0},
   368  	{AMOVW, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
   369  	{AMOVWZ, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
   370  	{AMOVFL, C_REG, C_NONE, C_LCON, C_CREG, 69, 4, 0},
   371  	{AMOVFL, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
   372  	{AMOVW, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
   373  	{AMOVWZ, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
   374  	{ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
   375  	{ACMP, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
   376  	{ACMP, C_REG, C_NONE, C_NONE, C_ADDCON, 71, 4, 0},
   377  	{ACMP, C_REG, C_REG, C_NONE, C_ADDCON, 71, 4, 0},
   378  	{ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
   379  	{ACMPU, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
   380  	{ACMPU, C_REG, C_NONE, C_NONE, C_ANDCON, 71, 4, 0},
   381  	{ACMPU, C_REG, C_REG, C_NONE, C_ANDCON, 71, 4, 0},
   382  	{AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 4, 0},
   383  	{AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 4, 0},
   384  	{ATW, C_LCON, C_REG, C_NONE, C_REG, 60, 4, 0},
   385  	{ATW, C_LCON, C_REG, C_NONE, C_ADDCON, 61, 4, 0},
   386  	{ADCBF, C_ZOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
   387  	{ADCBF, C_ZOREG, C_REG, C_NONE, C_NONE, 43, 4, 0},
   388  	{AECOWX, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
   389  	{AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
   390  	{AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
   391  	{AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
   392  	{AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
   393  	{ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},
   394  	{ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0},
   395  	{ASLBMFEE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
   396  	{ASLBMTE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
   397  	{ASTSW, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
   398  	{ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},
   399  	{ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
   400  	{ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
   401  	{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
   402  	{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0},
   403  	{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
   404  	{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
   405  	{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
   406  	{obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
   407  	{obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
   408  
   409  	{obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},
   410  }
   411  
   412  var oprange [ALAST & obj.AMask][]Optab
   413  
   414  var xcmp [C_NCLASS][C_NCLASS]bool
   415  
   416  func span9(ctxt *obj.Link, cursym *obj.LSym) {
   417  	p := cursym.Text
   418  	if p == nil || p.Link == nil { // handle external functions and ELF section symbols
   419  		return
   420  	}
   421  	ctxt.Cursym = cursym
   422  	ctxt.Autosize = int32(p.To.Offset)
   423  
   424  	if oprange[AANDN&obj.AMask] == nil {
   425  		buildop(ctxt)
   426  	}
   427  
   428  	c := int64(0)
   429  	p.Pc = c
   430  
   431  	var m int
   432  	var o *Optab
   433  	for p = p.Link; p != nil; p = p.Link {
   434  		ctxt.Curp = p
   435  		p.Pc = c
   436  		o = oplook(ctxt, p)
   437  		m = int(o.size)
   438  		if m == 0 {
   439  			if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
   440  				ctxt.Diag("zero-width instruction\n%v", p)
   441  			}
   442  			continue
   443  		}
   444  
   445  		c += int64(m)
   446  	}
   447  
   448  	cursym.Size = c
   449  
   450  	/*
   451  	 * if any procedure is large enough to
   452  	 * generate a large SBRA branch, then
   453  	 * generate extra passes putting branches
   454  	 * around jmps to fix. this is rare.
   455  	 */
   456  	bflag := 1
   457  
   458  	var otxt int64
   459  	var q *obj.Prog
   460  	for bflag != 0 {
   461  		if ctxt.Debugvlog != 0 {
   462  			ctxt.Logf("%5.2f span1\n", obj.Cputime())
   463  		}
   464  		bflag = 0
   465  		c = 0
   466  		for p = cursym.Text.Link; p != nil; p = p.Link {
   467  			p.Pc = c
   468  			o = oplook(ctxt, p)
   469  
   470  			// very large conditional branches
   471  			if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
   472  				otxt = p.Pcond.Pc - c
   473  				if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
   474  					q = ctxt.NewProg()
   475  					q.Link = p.Link
   476  					p.Link = q
   477  					q.As = ABR
   478  					q.To.Type = obj.TYPE_BRANCH
   479  					q.Pcond = p.Pcond
   480  					p.Pcond = q
   481  					q = ctxt.NewProg()
   482  					q.Link = p.Link
   483  					p.Link = q
   484  					q.As = ABR
   485  					q.To.Type = obj.TYPE_BRANCH
   486  					q.Pcond = q.Link.Link
   487  
   488  					//addnop(p->link);
   489  					//addnop(p);
   490  					bflag = 1
   491  				}
   492  			}
   493  
   494  			m = int(o.size)
   495  			if m == 0 {
   496  				if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != obj.AUSEFIELD {
   497  					ctxt.Diag("zero-width instruction\n%v", p)
   498  				}
   499  				continue
   500  			}
   501  
   502  			c += int64(m)
   503  		}
   504  
   505  		cursym.Size = c
   506  	}
   507  
   508  	c += -c & (FuncAlign - 1)
   509  	cursym.Size = c
   510  
   511  	/*
   512  	 * lay out the code, emitting code and data relocations.
   513  	 */
   514  
   515  	cursym.Grow(cursym.Size)
   516  
   517  	bp := cursym.P
   518  	var i int32
   519  	var out [6]uint32
   520  	for p := cursym.Text.Link; p != nil; p = p.Link {
   521  		ctxt.Pc = p.Pc
   522  		ctxt.Curp = p
   523  		o = oplook(ctxt, p)
   524  		if int(o.size) > 4*len(out) {
   525  			log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)
   526  		}
   527  		asmout(ctxt, p, o, out[:])
   528  		for i = 0; i < int32(o.size/4); i++ {
   529  			ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
   530  			bp = bp[4:]
   531  		}
   532  	}
   533  }
   534  
   535  func isint32(v int64) bool {
   536  	return int64(int32(v)) == v
   537  }
   538  
   539  func isuint32(v uint64) bool {
   540  	return uint64(uint32(v)) == v
   541  }
   542  
   543  func aclass(ctxt *obj.Link, a *obj.Addr) int {
   544  	switch a.Type {
   545  	case obj.TYPE_NONE:
   546  		return C_NONE
   547  
   548  	case obj.TYPE_REG:
   549  		if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
   550  			return C_REG
   551  		}
   552  		if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
   553  			return C_FREG
   554  		}
   555  		if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR {
   556  			return C_CREG
   557  		}
   558  		if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
   559  			switch a.Reg {
   560  			case REG_LR:
   561  				return C_LR
   562  
   563  			case REG_XER:
   564  				return C_XER
   565  
   566  			case REG_CTR:
   567  				return C_CTR
   568  			}
   569  
   570  			return C_SPR
   571  		}
   572  
   573  		if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
   574  			return C_SPR
   575  		}
   576  		if a.Reg == REG_FPSCR {
   577  			return C_FPSCR
   578  		}
   579  		if a.Reg == REG_MSR {
   580  			return C_MSR
   581  		}
   582  		return C_GOK
   583  
   584  	case obj.TYPE_MEM:
   585  		switch a.Name {
   586  		case obj.NAME_EXTERN,
   587  			obj.NAME_STATIC:
   588  			if a.Sym == nil {
   589  				break
   590  			}
   591  			ctxt.Instoffset = a.Offset
   592  			if a.Sym != nil { // use relocation
   593  				if a.Sym.Type == obj.STLSBSS {
   594  					if ctxt.Flag_shared {
   595  						return C_TLS_IE
   596  					} else {
   597  						return C_TLS_LE
   598  					}
   599  				}
   600  				return C_ADDR
   601  			}
   602  			return C_LEXT
   603  
   604  		case obj.NAME_GOTREF:
   605  			return C_GOTADDR
   606  
   607  		case obj.NAME_AUTO:
   608  			ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
   609  			if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
   610  				return C_SAUTO
   611  			}
   612  			return C_LAUTO
   613  
   614  		case obj.NAME_PARAM:
   615  			ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize()
   616  			if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
   617  				return C_SAUTO
   618  			}
   619  			return C_LAUTO
   620  
   621  		case obj.NAME_NONE:
   622  			ctxt.Instoffset = a.Offset
   623  			if ctxt.Instoffset == 0 {
   624  				return C_ZOREG
   625  			}
   626  			if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
   627  				return C_SOREG
   628  			}
   629  			return C_LOREG
   630  		}
   631  
   632  		return C_GOK
   633  
   634  	case obj.TYPE_TEXTSIZE:
   635  		return C_TEXTSIZE
   636  
   637  	case obj.TYPE_CONST,
   638  		obj.TYPE_ADDR:
   639  		switch a.Name {
   640  		case obj.NAME_NONE:
   641  			ctxt.Instoffset = a.Offset
   642  			if a.Reg != 0 {
   643  				if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG {
   644  					return C_SACON
   645  				}
   646  				if isint32(ctxt.Instoffset) {
   647  					return C_LACON
   648  				}
   649  				return C_DACON
   650  			}
   651  
   652  			goto consize
   653  
   654  		case obj.NAME_EXTERN,
   655  			obj.NAME_STATIC:
   656  			s := a.Sym
   657  			if s == nil {
   658  				break
   659  			}
   660  			if s.Type == obj.SCONST {
   661  				ctxt.Instoffset = a.Offset
   662  				goto consize
   663  			}
   664  
   665  			ctxt.Instoffset = a.Offset
   666  
   667  			/* not sure why this barfs */
   668  			return C_LCON
   669  
   670  		case obj.NAME_AUTO:
   671  			ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset
   672  			if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
   673  				return C_SACON
   674  			}
   675  			return C_LACON
   676  
   677  		case obj.NAME_PARAM:
   678  			ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + ctxt.FixedFrameSize()
   679  			if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG {
   680  				return C_SACON
   681  			}
   682  			return C_LACON
   683  		}
   684  
   685  		return C_GOK
   686  
   687  	consize:
   688  		if ctxt.Instoffset >= 0 {
   689  			if ctxt.Instoffset == 0 {
   690  				return C_ZCON
   691  			}
   692  			if ctxt.Instoffset <= 0x7fff {
   693  				return C_SCON
   694  			}
   695  			if ctxt.Instoffset <= 0xffff {
   696  				return C_ANDCON
   697  			}
   698  			if ctxt.Instoffset&0xffff == 0 && isuint32(uint64(ctxt.Instoffset)) { /* && (instoffset & (1<<31)) == 0) */
   699  				return C_UCON
   700  			}
   701  			if isint32(ctxt.Instoffset) || isuint32(uint64(ctxt.Instoffset)) {
   702  				return C_LCON
   703  			}
   704  			return C_DCON
   705  		}
   706  
   707  		if ctxt.Instoffset >= -0x8000 {
   708  			return C_ADDCON
   709  		}
   710  		if ctxt.Instoffset&0xffff == 0 && isint32(ctxt.Instoffset) {
   711  			return C_UCON
   712  		}
   713  		if isint32(ctxt.Instoffset) {
   714  			return C_LCON
   715  		}
   716  		return C_DCON
   717  
   718  	case obj.TYPE_BRANCH:
   719  		if a.Sym != nil && ctxt.Flag_dynlink {
   720  			return C_LBRAPIC
   721  		}
   722  		return C_SBRA
   723  	}
   724  
   725  	return C_GOK
   726  }
   727  
   728  func prasm(p *obj.Prog) {
   729  	fmt.Printf("%v\n", p)
   730  }
   731  
   732  func oplook(ctxt *obj.Link, p *obj.Prog) *Optab {
   733  	a1 := int(p.Optab)
   734  	if a1 != 0 {
   735  		return &optab[a1-1]
   736  	}
   737  	a1 = int(p.From.Class)
   738  	if a1 == 0 {
   739  		a1 = aclass(ctxt, &p.From) + 1
   740  		p.From.Class = int8(a1)
   741  	}
   742  
   743  	a1--
   744  	a3 := C_NONE + 1
   745  	if p.From3 != nil {
   746  		a3 = int(p.From3.Class)
   747  		if a3 == 0 {
   748  			a3 = aclass(ctxt, p.From3) + 1
   749  			p.From3.Class = int8(a3)
   750  		}
   751  	}
   752  
   753  	a3--
   754  	a4 := int(p.To.Class)
   755  	if a4 == 0 {
   756  		a4 = aclass(ctxt, &p.To) + 1
   757  		p.To.Class = int8(a4)
   758  	}
   759  
   760  	a4--
   761  	a2 := C_NONE
   762  	if p.Reg != 0 {
   763  		a2 = C_REG
   764  	}
   765  
   766  	//print("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4);
   767  	ops := oprange[p.As&obj.AMask]
   768  	c1 := &xcmp[a1]
   769  	c3 := &xcmp[a3]
   770  	c4 := &xcmp[a4]
   771  	for i := range ops {
   772  		op := &ops[i]
   773  		if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] {
   774  			p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
   775  			return op
   776  		}
   777  	}
   778  
   779  	ctxt.Diag("illegal combination %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4))
   780  	prasm(p)
   781  	if ops == nil {
   782  		ops = optab
   783  	}
   784  	return &ops[0]
   785  }
   786  
   787  func cmp(a int, b int) bool {
   788  	if a == b {
   789  		return true
   790  	}
   791  	switch a {
   792  	case C_LCON:
   793  		if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {
   794  			return true
   795  		}
   796  
   797  	case C_ADDCON:
   798  		if b == C_ZCON || b == C_SCON {
   799  			return true
   800  		}
   801  
   802  	case C_ANDCON:
   803  		if b == C_ZCON || b == C_SCON {
   804  			return true
   805  		}
   806  
   807  	case C_SPR:
   808  		if b == C_LR || b == C_XER || b == C_CTR {
   809  			return true
   810  		}
   811  
   812  	case C_UCON:
   813  		if b == C_ZCON {
   814  			return true
   815  		}
   816  
   817  	case C_SCON:
   818  		if b == C_ZCON {
   819  			return true
   820  		}
   821  
   822  	case C_LACON:
   823  		if b == C_SACON {
   824  			return true
   825  		}
   826  
   827  	case C_LBRA:
   828  		if b == C_SBRA {
   829  			return true
   830  		}
   831  
   832  	case C_LEXT:
   833  		if b == C_SEXT {
   834  			return true
   835  		}
   836  
   837  	case C_LAUTO:
   838  		if b == C_SAUTO {
   839  			return true
   840  		}
   841  
   842  	case C_REG:
   843  		if b == C_ZCON {
   844  			return r0iszero != 0 /*TypeKind(100016)*/
   845  		}
   846  
   847  	case C_LOREG:
   848  		if b == C_ZOREG || b == C_SOREG {
   849  			return true
   850  		}
   851  
   852  	case C_SOREG:
   853  		if b == C_ZOREG {
   854  			return true
   855  		}
   856  
   857  	case C_ANY:
   858  		return true
   859  	}
   860  
   861  	return false
   862  }
   863  
   864  type ocmp []Optab
   865  
   866  func (x ocmp) Len() int {
   867  	return len(x)
   868  }
   869  
   870  func (x ocmp) Swap(i, j int) {
   871  	x[i], x[j] = x[j], x[i]
   872  }
   873  
   874  func (x ocmp) Less(i, j int) bool {
   875  	p1 := &x[i]
   876  	p2 := &x[j]
   877  	n := int(p1.as) - int(p2.as)
   878  	if n != 0 {
   879  		return n < 0
   880  	}
   881  	n = int(p1.a1) - int(p2.a1)
   882  	if n != 0 {
   883  		return n < 0
   884  	}
   885  	n = int(p1.a2) - int(p2.a2)
   886  	if n != 0 {
   887  		return n < 0
   888  	}
   889  	n = int(p1.a3) - int(p2.a3)
   890  	if n != 0 {
   891  		return n < 0
   892  	}
   893  	n = int(p1.a4) - int(p2.a4)
   894  	if n != 0 {
   895  		return n < 0
   896  	}
   897  	return false
   898  }
   899  func opset(a, b0 obj.As) {
   900  	oprange[a&obj.AMask] = oprange[b0]
   901  }
   902  
   903  func buildop(ctxt *obj.Link) {
   904  	var n int
   905  
   906  	for i := 0; i < C_NCLASS; i++ {
   907  		for n = 0; n < C_NCLASS; n++ {
   908  			if cmp(n, i) {
   909  				xcmp[i][n] = true
   910  			}
   911  		}
   912  	}
   913  	for n = 0; optab[n].as != obj.AXXX; n++ {
   914  	}
   915  	sort.Sort(ocmp(optab[:n]))
   916  	for i := 0; i < n; i++ {
   917  		r := optab[i].as
   918  		r0 := r & obj.AMask
   919  		start := i
   920  		for optab[i].as == r {
   921  			i++
   922  		}
   923  		oprange[r0] = optab[start:i]
   924  		i--
   925  
   926  		switch r {
   927  		default:
   928  			ctxt.Diag("unknown op in build: %v", r)
   929  			log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r)
   930  
   931  		case ADCBF: /* unary indexed: op (b+a); op (b) */
   932  			opset(ADCBI, r0)
   933  
   934  			opset(ADCBST, r0)
   935  			opset(ADCBT, r0)
   936  			opset(ADCBTST, r0)
   937  			opset(ADCBZ, r0)
   938  			opset(AICBI, r0)
   939  
   940  		case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
   941  			opset(ASTWCCC, r0)
   942  			opset(ASTBCCC, r0)
   943  
   944  			opset(ASTDCCC, r0)
   945  
   946  		case AREM: /* macro */
   947  			opset(AREMCC, r0)
   948  
   949  			opset(AREMV, r0)
   950  			opset(AREMVCC, r0)
   951  
   952  		case AREMU:
   953  			opset(AREMU, r0)
   954  			opset(AREMUCC, r0)
   955  			opset(AREMUV, r0)
   956  			opset(AREMUVCC, r0)
   957  
   958  		case AREMD:
   959  			opset(AREMDCC, r0)
   960  			opset(AREMDV, r0)
   961  			opset(AREMDVCC, r0)
   962  
   963  		case AREMDU:
   964  			opset(AREMDU, r0)
   965  			opset(AREMDUCC, r0)
   966  			opset(AREMDUV, r0)
   967  			opset(AREMDUVCC, r0)
   968  
   969  		case ADIVW: /* op Rb[,Ra],Rd */
   970  			opset(AMULHW, r0)
   971  
   972  			opset(AMULHWCC, r0)
   973  			opset(AMULHWU, r0)
   974  			opset(AMULHWUCC, r0)
   975  			opset(AMULLWCC, r0)
   976  			opset(AMULLWVCC, r0)
   977  			opset(AMULLWV, r0)
   978  			opset(ADIVWCC, r0)
   979  			opset(ADIVWV, r0)
   980  			opset(ADIVWVCC, r0)
   981  			opset(ADIVWU, r0)
   982  			opset(ADIVWUCC, r0)
   983  			opset(ADIVWUV, r0)
   984  			opset(ADIVWUVCC, r0)
   985  			opset(AADDCC, r0)
   986  			opset(AADDCV, r0)
   987  			opset(AADDCVCC, r0)
   988  			opset(AADDV, r0)
   989  			opset(AADDVCC, r0)
   990  			opset(AADDE, r0)
   991  			opset(AADDECC, r0)
   992  			opset(AADDEV, r0)
   993  			opset(AADDEVCC, r0)
   994  			opset(ACRAND, r0)
   995  			opset(ACRANDN, r0)
   996  			opset(ACREQV, r0)
   997  			opset(ACRNAND, r0)
   998  			opset(ACRNOR, r0)
   999  			opset(ACROR, r0)
  1000  			opset(ACRORN, r0)
  1001  			opset(ACRXOR, r0)
  1002  			opset(AMULHD, r0)
  1003  			opset(AMULHDCC, r0)
  1004  			opset(AMULHDU, r0)
  1005  			opset(AMULHDUCC, r0)
  1006  			opset(AMULLD, r0)
  1007  			opset(AMULLDCC, r0)
  1008  			opset(AMULLDVCC, r0)
  1009  			opset(AMULLDV, r0)
  1010  			opset(ADIVD, r0)
  1011  			opset(ADIVDCC, r0)
  1012  			opset(ADIVDE, r0)
  1013  			opset(ADIVDEU, r0)
  1014  			opset(ADIVDECC, r0)
  1015  			opset(ADIVDEUCC, r0)
  1016  			opset(ADIVDVCC, r0)
  1017  			opset(ADIVDV, r0)
  1018  			opset(ADIVDU, r0)
  1019  			opset(ADIVDUCC, r0)
  1020  			opset(ADIVDUVCC, r0)
  1021  			opset(ADIVDUCC, r0)
  1022  
  1023  		case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
  1024  			opset(AMOVH, r0)
  1025  
  1026  			opset(AMOVHZ, r0)
  1027  
  1028  		case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
  1029  			opset(AMOVHU, r0)
  1030  
  1031  			opset(AMOVHZU, r0)
  1032  			opset(AMOVWU, r0)
  1033  			opset(AMOVWZU, r0)
  1034  			opset(AMOVDU, r0)
  1035  			opset(AMOVMW, r0)
  1036  
  1037  		case AAND: /* logical op Rb,Rs,Ra; no literal */
  1038  			opset(AANDN, r0)
  1039  
  1040  			opset(AANDNCC, r0)
  1041  			opset(AEQV, r0)
  1042  			opset(AEQVCC, r0)
  1043  			opset(ANAND, r0)
  1044  			opset(ANANDCC, r0)
  1045  			opset(ANOR, r0)
  1046  			opset(ANORCC, r0)
  1047  			opset(AORCC, r0)
  1048  			opset(AORN, r0)
  1049  			opset(AORNCC, r0)
  1050  			opset(AXORCC, r0)
  1051  
  1052  		case AADDME: /* op Ra, Rd */
  1053  			opset(AADDMECC, r0)
  1054  
  1055  			opset(AADDMEV, r0)
  1056  			opset(AADDMEVCC, r0)
  1057  			opset(AADDZE, r0)
  1058  			opset(AADDZECC, r0)
  1059  			opset(AADDZEV, r0)
  1060  			opset(AADDZEVCC, r0)
  1061  			opset(ASUBME, r0)
  1062  			opset(ASUBMECC, r0)
  1063  			opset(ASUBMEV, r0)
  1064  			opset(ASUBMEVCC, r0)
  1065  			opset(ASUBZE, r0)
  1066  			opset(ASUBZECC, r0)
  1067  			opset(ASUBZEV, r0)
  1068  			opset(ASUBZEVCC, r0)
  1069  
  1070  		case AADDC:
  1071  			opset(AADDCCC, r0)
  1072  
  1073  		case ABEQ:
  1074  			opset(ABGE, r0)
  1075  			opset(ABGT, r0)
  1076  			opset(ABLE, r0)
  1077  			opset(ABLT, r0)
  1078  			opset(ABNE, r0)
  1079  			opset(ABVC, r0)
  1080  			opset(ABVS, r0)
  1081  
  1082  		case ABR:
  1083  			opset(ABL, r0)
  1084  
  1085  		case ABC:
  1086  			opset(ABCL, r0)
  1087  
  1088  		case AEXTSB: /* op Rs, Ra */
  1089  			opset(AEXTSBCC, r0)
  1090  
  1091  			opset(AEXTSH, r0)
  1092  			opset(AEXTSHCC, r0)
  1093  			opset(ACNTLZW, r0)
  1094  			opset(ACNTLZWCC, r0)
  1095  			opset(ACNTLZD, r0)
  1096  			opset(AEXTSW, r0)
  1097  			opset(AEXTSWCC, r0)
  1098  			opset(ACNTLZDCC, r0)
  1099  
  1100  		case AFABS: /* fop [s,]d */
  1101  			opset(AFABSCC, r0)
  1102  
  1103  			opset(AFNABS, r0)
  1104  			opset(AFNABSCC, r0)
  1105  			opset(AFNEG, r0)
  1106  			opset(AFNEGCC, r0)
  1107  			opset(AFRSP, r0)
  1108  			opset(AFRSPCC, r0)
  1109  			opset(AFCTIW, r0)
  1110  			opset(AFCTIWCC, r0)
  1111  			opset(AFCTIWZ, r0)
  1112  			opset(AFCTIWZCC, r0)
  1113  			opset(AFCTID, r0)
  1114  			opset(AFCTIDCC, r0)
  1115  			opset(AFCTIDZ, r0)
  1116  			opset(AFCTIDZCC, r0)
  1117  			opset(AFCFID, r0)
  1118  			opset(AFCFIDCC, r0)
  1119  			opset(AFCFIDU, r0)
  1120  			opset(AFCFIDUCC, r0)
  1121  			opset(AFRES, r0)
  1122  			opset(AFRESCC, r0)
  1123  			opset(AFRSQRTE, r0)
  1124  			opset(AFRSQRTECC, r0)
  1125  			opset(AFSQRT, r0)
  1126  			opset(AFSQRTCC, r0)
  1127  			opset(AFSQRTS, r0)
  1128  			opset(AFSQRTSCC, r0)
  1129  
  1130  		case AFADD:
  1131  			opset(AFADDS, r0)
  1132  			opset(AFADDCC, r0)
  1133  			opset(AFADDSCC, r0)
  1134  			opset(AFDIV, r0)
  1135  			opset(AFDIVS, r0)
  1136  			opset(AFDIVCC, r0)
  1137  			opset(AFDIVSCC, r0)
  1138  			opset(AFSUB, r0)
  1139  			opset(AFSUBS, r0)
  1140  			opset(AFSUBCC, r0)
  1141  			opset(AFSUBSCC, r0)
  1142  
  1143  		case AFMADD:
  1144  			opset(AFMADDCC, r0)
  1145  			opset(AFMADDS, r0)
  1146  			opset(AFMADDSCC, r0)
  1147  			opset(AFMSUB, r0)
  1148  			opset(AFMSUBCC, r0)
  1149  			opset(AFMSUBS, r0)
  1150  			opset(AFMSUBSCC, r0)
  1151  			opset(AFNMADD, r0)
  1152  			opset(AFNMADDCC, r0)
  1153  			opset(AFNMADDS, r0)
  1154  			opset(AFNMADDSCC, r0)
  1155  			opset(AFNMSUB, r0)
  1156  			opset(AFNMSUBCC, r0)
  1157  			opset(AFNMSUBS, r0)
  1158  			opset(AFNMSUBSCC, r0)
  1159  			opset(AFSEL, r0)
  1160  			opset(AFSELCC, r0)
  1161  
  1162  		case AFMUL:
  1163  			opset(AFMULS, r0)
  1164  			opset(AFMULCC, r0)
  1165  			opset(AFMULSCC, r0)
  1166  
  1167  		case AFCMPO:
  1168  			opset(AFCMPU, r0)
  1169  
  1170  		case AMTFSB0:
  1171  			opset(AMTFSB0CC, r0)
  1172  			opset(AMTFSB1, r0)
  1173  			opset(AMTFSB1CC, r0)
  1174  
  1175  		case ANEG: /* op [Ra,] Rd */
  1176  			opset(ANEGCC, r0)
  1177  
  1178  			opset(ANEGV, r0)
  1179  			opset(ANEGVCC, r0)
  1180  
  1181  		case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
  1182  			opset(AXOR, r0)
  1183  
  1184  		case ASLW:
  1185  			opset(ASLWCC, r0)
  1186  			opset(ASRW, r0)
  1187  			opset(ASRWCC, r0)
  1188  
  1189  		case ASLD:
  1190  			opset(ASLDCC, r0)
  1191  			opset(ASRD, r0)
  1192  			opset(ASRDCC, r0)
  1193  
  1194  		case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
  1195  			opset(ASRAWCC, r0)
  1196  
  1197  		case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
  1198  			opset(ASRADCC, r0)
  1199  
  1200  		case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
  1201  			opset(ASUB, r0)
  1202  
  1203  			opset(ASUBCC, r0)
  1204  			opset(ASUBV, r0)
  1205  			opset(ASUBVCC, r0)
  1206  			opset(ASUBCCC, r0)
  1207  			opset(ASUBCV, r0)
  1208  			opset(ASUBCVCC, r0)
  1209  			opset(ASUBE, r0)
  1210  			opset(ASUBECC, r0)
  1211  			opset(ASUBEV, r0)
  1212  			opset(ASUBEVCC, r0)
  1213  
  1214  		case ASYNC:
  1215  			opset(AISYNC, r0)
  1216  			opset(ALWSYNC, r0)
  1217  			opset(APTESYNC, r0)
  1218  			opset(ATLBSYNC, r0)
  1219  
  1220  		case ARLWMI:
  1221  			opset(ARLWMICC, r0)
  1222  			opset(ARLWNM, r0)
  1223  			opset(ARLWNMCC, r0)
  1224  
  1225  		case ARLDMI:
  1226  			opset(ARLDMICC, r0)
  1227  
  1228  		case ARLDC:
  1229  			opset(ARLDCCC, r0)
  1230  
  1231  		case ARLDCL:
  1232  			opset(ARLDCR, r0)
  1233  			opset(ARLDCLCC, r0)
  1234  			opset(ARLDCRCC, r0)
  1235  
  1236  		case AFMOVD:
  1237  			opset(AFMOVDCC, r0)
  1238  			opset(AFMOVDU, r0)
  1239  			opset(AFMOVS, r0)
  1240  			opset(AFMOVSU, r0)
  1241  
  1242  		case AECIWX:
  1243  			opset(ALBAR, r0)
  1244  			opset(ALWAR, r0)
  1245  			opset(ALDAR, r0)
  1246  
  1247  		case ASYSCALL: /* just the op; flow of control */
  1248  			opset(ARFI, r0)
  1249  
  1250  			opset(ARFCI, r0)
  1251  			opset(ARFID, r0)
  1252  			opset(AHRFID, r0)
  1253  
  1254  		case AMOVHBR:
  1255  			opset(AMOVWBR, r0)
  1256  
  1257  		case ASLBMFEE:
  1258  			opset(ASLBMFEV, r0)
  1259  
  1260  		case ATW:
  1261  			opset(ATD, r0)
  1262  
  1263  		case ATLBIE:
  1264  			opset(ASLBIE, r0)
  1265  			opset(ATLBIEL, r0)
  1266  
  1267  		case AEIEIO:
  1268  			opset(ASLBIA, r0)
  1269  
  1270  		case ACMP:
  1271  			opset(ACMPW, r0)
  1272  
  1273  		case ACMPU:
  1274  			opset(ACMPWU, r0)
  1275  
  1276  		case AADD,
  1277  			AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
  1278  			AFMOVSX,
  1279  			AFMOVSZ,
  1280  			ALSW,
  1281  			AMOVW,
  1282  			/* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
  1283  			AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals  */
  1284  			AMOVD,  /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
  1285  			AMOVB,  /* macro: move byte with sign extension */
  1286  			AMOVBU, /* macro: move byte with sign extension & update */
  1287  			AMOVFL,
  1288  			AMULLW,
  1289  			/* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
  1290  			ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */
  1291  			ASTSW,
  1292  			ASLBMTE,
  1293  			AWORD,
  1294  			ADWORD,
  1295  			obj.ANOP,
  1296  			obj.ATEXT,
  1297  			obj.AUNDEF,
  1298  			obj.AUSEFIELD,
  1299  			obj.AFUNCDATA,
  1300  			obj.APCDATA,
  1301  			obj.ADUFFZERO,
  1302  			obj.ADUFFCOPY:
  1303  			break
  1304  		}
  1305  	}
  1306  }
  1307  
  1308  func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
  1309  	return o<<26 | xo<<1 | oe<<10 | rc&1
  1310  }
  1311  
  1312  func OPCC(o uint32, xo uint32, rc uint32) uint32 {
  1313  	return OPVCC(o, xo, 0, rc)
  1314  }
  1315  
  1316  func OP(o uint32, xo uint32) uint32 {
  1317  	return OPVCC(o, xo, 0, 0)
  1318  }
  1319  
  1320  /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
  1321  func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
  1322  	return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
  1323  }
  1324  
  1325  func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
  1326  	return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF
  1327  }
  1328  
  1329  func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
  1330  	return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
  1331  }
  1332  
  1333  func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 {
  1334  	return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF
  1335  }
  1336  
  1337  func OP_BR(op uint32, li uint32, aa uint32) uint32 {
  1338  	return op | li&0x03FFFFFC | aa<<1
  1339  }
  1340  
  1341  func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 {
  1342  	return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1
  1343  }
  1344  
  1345  func OP_BCR(op uint32, bo uint32, bi uint32) uint32 {
  1346  	return op | (bo&0x1F)<<21 | (bi&0x1F)<<16
  1347  }
  1348  
  1349  func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 {
  1350  	return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1
  1351  }
  1352  
  1353  const (
  1354  	/* each rhs is OPVCC(_, _, _, _) */
  1355  	OP_ADD    = 31<<26 | 266<<1 | 0<<10 | 0
  1356  	OP_ADDI   = 14<<26 | 0<<1 | 0<<10 | 0
  1357  	OP_ADDIS  = 15<<26 | 0<<1 | 0<<10 | 0
  1358  	OP_ANDI   = 28<<26 | 0<<1 | 0<<10 | 0
  1359  	OP_EXTSB  = 31<<26 | 954<<1 | 0<<10 | 0
  1360  	OP_EXTSH  = 31<<26 | 922<<1 | 0<<10 | 0
  1361  	OP_EXTSW  = 31<<26 | 986<<1 | 0<<10 | 0
  1362  	OP_MCRF   = 19<<26 | 0<<1 | 0<<10 | 0
  1363  	OP_MCRFS  = 63<<26 | 64<<1 | 0<<10 | 0
  1364  	OP_MCRXR  = 31<<26 | 512<<1 | 0<<10 | 0
  1365  	OP_MFCR   = 31<<26 | 19<<1 | 0<<10 | 0
  1366  	OP_MFFS   = 63<<26 | 583<<1 | 0<<10 | 0
  1367  	OP_MFMSR  = 31<<26 | 83<<1 | 0<<10 | 0
  1368  	OP_MFSPR  = 31<<26 | 339<<1 | 0<<10 | 0
  1369  	OP_MFSR   = 31<<26 | 595<<1 | 0<<10 | 0
  1370  	OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0
  1371  	OP_MTCRF  = 31<<26 | 144<<1 | 0<<10 | 0
  1372  	OP_MTFSF  = 63<<26 | 711<<1 | 0<<10 | 0
  1373  	OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0
  1374  	OP_MTMSR  = 31<<26 | 146<<1 | 0<<10 | 0
  1375  	OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0
  1376  	OP_MTSPR  = 31<<26 | 467<<1 | 0<<10 | 0
  1377  	OP_MTSR   = 31<<26 | 210<<1 | 0<<10 | 0
  1378  	OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0
  1379  	OP_MULLW  = 31<<26 | 235<<1 | 0<<10 | 0
  1380  	OP_MULLD  = 31<<26 | 233<<1 | 0<<10 | 0
  1381  	OP_OR     = 31<<26 | 444<<1 | 0<<10 | 0
  1382  	OP_ORI    = 24<<26 | 0<<1 | 0<<10 | 0
  1383  	OP_ORIS   = 25<<26 | 0<<1 | 0<<10 | 0
  1384  	OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0
  1385  	OP_SUBF   = 31<<26 | 40<<1 | 0<<10 | 0
  1386  	OP_RLDIC  = 30<<26 | 4<<1 | 0<<10 | 0
  1387  	OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0
  1388  	OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0
  1389  )
  1390  
  1391  func oclass(a *obj.Addr) int {
  1392  	return int(a.Class) - 1
  1393  }
  1394  
  1395  const (
  1396  	D_FORM = iota
  1397  	DS_FORM
  1398  )
  1399  
  1400  // opform returns the form (D_FORM or DS_FORM) of an instruction. Used to decide on
  1401  // which relocation to use with a load or store and only supports the needed
  1402  // instructions.
  1403  func opform(ctxt *obj.Link, insn uint32) int {
  1404  	switch insn {
  1405  	default:
  1406  		ctxt.Diag("bad insn in loadform: %x", insn)
  1407  	case OPVCC(58, 0, 0, 0), // ld
  1408  		OPVCC(58, 0, 0, 0) | 1<<1, // lwa
  1409  		OPVCC(62, 0, 0, 0):        // std
  1410  		return DS_FORM
  1411  	case OP_ADDI, // add
  1412  		OPVCC(32, 0, 0, 0), // lwz
  1413  		OPVCC(42, 0, 0, 0), // lha
  1414  		OPVCC(40, 0, 0, 0), // lhz
  1415  		OPVCC(34, 0, 0, 0), // lbz
  1416  		OPVCC(50, 0, 0, 0), // lfd
  1417  		OPVCC(48, 0, 0, 0), // lfs
  1418  		OPVCC(36, 0, 0, 0), // stw
  1419  		OPVCC(44, 0, 0, 0), // sth
  1420  		OPVCC(38, 0, 0, 0), // stb
  1421  		OPVCC(54, 0, 0, 0), // stfd
  1422  		OPVCC(52, 0, 0, 0): // stfs
  1423  		return D_FORM
  1424  	}
  1425  	return 0
  1426  }
  1427  
  1428  // Encode instructions and create relocation for accessing s+d according to the
  1429  // instruction op with source or destination (as appropriate) register reg.
  1430  func symbolAccess(ctxt *obj.Link, s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) {
  1431  	var base uint32
  1432  	form := opform(ctxt, op)
  1433  	if ctxt.Flag_shared {
  1434  		base = REG_R2
  1435  	} else {
  1436  		base = REG_R0
  1437  	}
  1438  	o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)
  1439  	o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)
  1440  	rel := obj.Addrel(ctxt.Cursym)
  1441  	rel.Off = int32(ctxt.Pc)
  1442  	rel.Siz = 8
  1443  	rel.Sym = s
  1444  	rel.Add = d
  1445  	if ctxt.Flag_shared {
  1446  		switch form {
  1447  		case D_FORM:
  1448  			rel.Type = obj.R_ADDRPOWER_TOCREL
  1449  		case DS_FORM:
  1450  			rel.Type = obj.R_ADDRPOWER_TOCREL_DS
  1451  		}
  1452  
  1453  	} else {
  1454  		switch form {
  1455  		case D_FORM:
  1456  			rel.Type = obj.R_ADDRPOWER
  1457  		case DS_FORM:
  1458  			rel.Type = obj.R_ADDRPOWER_DS
  1459  		}
  1460  	}
  1461  	return
  1462  }
  1463  
  1464  /*
  1465   * 32-bit masks
  1466   */
  1467  func getmask(m []byte, v uint32) bool {
  1468  	m[1] = 0
  1469  	m[0] = m[1]
  1470  	if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
  1471  		if getmask(m, ^v) {
  1472  			i := int(m[0])
  1473  			m[0] = m[1] + 1
  1474  			m[1] = byte(i - 1)
  1475  			return true
  1476  		}
  1477  
  1478  		return false
  1479  	}
  1480  
  1481  	for i := 0; i < 32; i++ {
  1482  		if v&(1<<uint(31-i)) != 0 {
  1483  			m[0] = byte(i)
  1484  			for {
  1485  				m[1] = byte(i)
  1486  				i++
  1487  				if i >= 32 || v&(1<<uint(31-i)) == 0 {
  1488  					break
  1489  				}
  1490  			}
  1491  
  1492  			for ; i < 32; i++ {
  1493  				if v&(1<<uint(31-i)) != 0 {
  1494  					return false
  1495  				}
  1496  			}
  1497  			return true
  1498  		}
  1499  	}
  1500  
  1501  	return false
  1502  }
  1503  
  1504  func maskgen(ctxt *obj.Link, p *obj.Prog, m []byte, v uint32) {
  1505  	if !getmask(m, v) {
  1506  		ctxt.Diag("cannot generate mask #%x\n%v", v, p)
  1507  	}
  1508  }
  1509  
  1510  /*
  1511   * 64-bit masks (rldic etc)
  1512   */
  1513  func getmask64(m []byte, v uint64) bool {
  1514  	m[1] = 0
  1515  	m[0] = m[1]
  1516  	for i := 0; i < 64; i++ {
  1517  		if v&(uint64(1)<<uint(63-i)) != 0 {
  1518  			m[0] = byte(i)
  1519  			for {
  1520  				m[1] = byte(i)
  1521  				i++
  1522  				if i >= 64 || v&(uint64(1)<<uint(63-i)) == 0 {
  1523  					break
  1524  				}
  1525  			}
  1526  
  1527  			for ; i < 64; i++ {
  1528  				if v&(uint64(1)<<uint(63-i)) != 0 {
  1529  					return false
  1530  				}
  1531  			}
  1532  			return true
  1533  		}
  1534  	}
  1535  
  1536  	return false
  1537  }
  1538  
  1539  func maskgen64(ctxt *obj.Link, p *obj.Prog, m []byte, v uint64) {
  1540  	if !getmask64(m, v) {
  1541  		ctxt.Diag("cannot generate mask #%x\n%v", v, p)
  1542  	}
  1543  }
  1544  
  1545  func loadu32(r int, d int64) uint32 {
  1546  	v := int32(d >> 16)
  1547  	if isuint32(uint64(d)) {
  1548  		return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
  1549  	}
  1550  	return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v))
  1551  }
  1552  
  1553  func high16adjusted(d int32) uint16 {
  1554  	if d&0x8000 != 0 {
  1555  		return uint16((d >> 16) + 1)
  1556  	}
  1557  	return uint16(d >> 16)
  1558  }
  1559  
  1560  func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) {
  1561  	o1 := uint32(0)
  1562  	o2 := uint32(0)
  1563  	o3 := uint32(0)
  1564  	o4 := uint32(0)
  1565  	o5 := uint32(0)
  1566  
  1567  	//print("%v => case %d\n", p, o->type);
  1568  	switch o.type_ {
  1569  	default:
  1570  		ctxt.Diag("unknown type %d", o.type_)
  1571  		prasm(p)
  1572  
  1573  	case 0: /* pseudo ops */
  1574  		break
  1575  
  1576  	case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
  1577  		if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
  1578  			v := regoff(ctxt, &p.From)
  1579  			if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
  1580  				//nerrors--;
  1581  				ctxt.Diag("literal operation on R0\n%v", p)
  1582  			}
  1583  
  1584  			o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
  1585  			break
  1586  		}
  1587  
  1588  		o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
  1589  
  1590  	case 2: /* int/cr/fp op Rb,[Ra],Rd */
  1591  		r := int(p.Reg)
  1592  
  1593  		if r == 0 {
  1594  			r = int(p.To.Reg)
  1595  		}
  1596  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
  1597  
  1598  	case 3: /* mov $soreg/addcon/ucon, r ==> addis/addi $i,reg',r */
  1599  		d := vregoff(ctxt, &p.From)
  1600  
  1601  		v := int32(d)
  1602  		r := int(p.From.Reg)
  1603  		if r == 0 {
  1604  			r = int(o.param)
  1605  		}
  1606  		if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
  1607  			ctxt.Diag("literal operation on R0\n%v", p)
  1608  		}
  1609  		a := OP_ADDI
  1610  		if o.a1 == C_UCON {
  1611  			if d&0xffff != 0 {
  1612  				log.Fatalf("invalid handling of %v", p)
  1613  			}
  1614  			v >>= 16
  1615  			if r == REGZERO && isuint32(uint64(d)) {
  1616  				o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v))
  1617  				break
  1618  			}
  1619  
  1620  			a = OP_ADDIS
  1621  		} else {
  1622  			if int64(int16(d)) != d {
  1623  				log.Fatalf("invalid handling of %v", p)
  1624  			}
  1625  		}
  1626  
  1627  		o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
  1628  
  1629  	case 4: /* add/mul $scon,[r1],r2 */
  1630  		v := regoff(ctxt, &p.From)
  1631  
  1632  		r := int(p.Reg)
  1633  		if r == 0 {
  1634  			r = int(p.To.Reg)
  1635  		}
  1636  		if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
  1637  			ctxt.Diag("literal operation on R0\n%v", p)
  1638  		}
  1639  		if int32(int16(v)) != v {
  1640  			log.Fatalf("mishandled instruction %v", p)
  1641  		}
  1642  		o1 = AOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v))
  1643  
  1644  	case 5: /* syscall */
  1645  		o1 = oprrr(ctxt, p.As)
  1646  
  1647  	case 6: /* logical op Rb,[Rs,]Ra; no literal */
  1648  		r := int(p.Reg)
  1649  
  1650  		if r == 0 {
  1651  			r = int(p.To.Reg)
  1652  		}
  1653  		o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
  1654  
  1655  	case 7: /* mov r, soreg ==> stw o(r) */
  1656  		r := int(p.To.Reg)
  1657  
  1658  		if r == 0 {
  1659  			r = int(o.param)
  1660  		}
  1661  		v := regoff(ctxt, &p.To)
  1662  		if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
  1663  			if v != 0 {
  1664  				ctxt.Diag("illegal indexed instruction\n%v", p)
  1665  			}
  1666  			if ctxt.Flag_shared && r == REG_R13 {
  1667  				rel := obj.Addrel(ctxt.Cursym)
  1668  				rel.Off = int32(ctxt.Pc)
  1669  				rel.Siz = 4
  1670  				// This (and the matching part in the load case
  1671  				// below) are the only places in the ppc64 toolchain
  1672  				// that knows the name of the tls variable. Possibly
  1673  				// we could add some assembly syntax so that the name
  1674  				// of the variable does not have to be assumed.
  1675  				rel.Sym = obj.Linklookup(ctxt, "runtime.tls_g", 0)
  1676  				rel.Type = obj.R_POWER_TLS
  1677  			}
  1678  			o1 = AOP_RRR(opstorex(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
  1679  		} else {
  1680  			if int32(int16(v)) != v {
  1681  				log.Fatalf("mishandled instruction %v", p)
  1682  			}
  1683  			o1 = AOP_IRR(opstore(ctxt, p.As), uint32(p.From.Reg), uint32(r), uint32(v))
  1684  		}
  1685  
  1686  	case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
  1687  		r := int(p.From.Reg)
  1688  
  1689  		if r == 0 {
  1690  			r = int(o.param)
  1691  		}
  1692  		v := regoff(ctxt, &p.From)
  1693  		if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
  1694  			if v != 0 {
  1695  				ctxt.Diag("illegal indexed instruction\n%v", p)
  1696  			}
  1697  			if ctxt.Flag_shared && r == REG_R13 {
  1698  				rel := obj.Addrel(ctxt.Cursym)
  1699  				rel.Off = int32(ctxt.Pc)
  1700  				rel.Siz = 4
  1701  				rel.Sym = obj.Linklookup(ctxt, "runtime.tls_g", 0)
  1702  				rel.Type = obj.R_POWER_TLS
  1703  			}
  1704  			o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
  1705  		} else {
  1706  			if int32(int16(v)) != v {
  1707  				log.Fatalf("mishandled instruction %v", p)
  1708  			}
  1709  			o1 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v))
  1710  		}
  1711  
  1712  	case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
  1713  		r := int(p.From.Reg)
  1714  
  1715  		if r == 0 {
  1716  			r = int(o.param)
  1717  		}
  1718  		v := regoff(ctxt, &p.From)
  1719  		if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
  1720  			if v != 0 {
  1721  				ctxt.Diag("illegal indexed instruction\n%v", p)
  1722  			}
  1723  			o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
  1724  		} else {
  1725  			o1 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v))
  1726  		}
  1727  		o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
  1728  
  1729  	case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
  1730  		r := int(p.Reg)
  1731  
  1732  		if r == 0 {
  1733  			r = int(p.To.Reg)
  1734  		}
  1735  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
  1736  
  1737  	case 11: /* br/bl lbra */
  1738  		v := int32(0)
  1739  
  1740  		if p.Pcond != nil {
  1741  			v = int32(p.Pcond.Pc - p.Pc)
  1742  			if v&03 != 0 {
  1743  				ctxt.Diag("odd branch target address\n%v", p)
  1744  				v &^= 03
  1745  			}
  1746  
  1747  			if v < -(1<<25) || v >= 1<<24 {
  1748  				ctxt.Diag("branch too far\n%v", p)
  1749  			}
  1750  		}
  1751  
  1752  		o1 = OP_BR(opirr(ctxt, p.As), uint32(v), 0)
  1753  		if p.To.Sym != nil {
  1754  			rel := obj.Addrel(ctxt.Cursym)
  1755  			rel.Off = int32(ctxt.Pc)
  1756  			rel.Siz = 4
  1757  			rel.Sym = p.To.Sym
  1758  			v += int32(p.To.Offset)
  1759  			if v&03 != 0 {
  1760  				ctxt.Diag("odd branch target address\n%v", p)
  1761  				v &^= 03
  1762  			}
  1763  
  1764  			rel.Add = int64(v)
  1765  			rel.Type = obj.R_CALLPOWER
  1766  		}
  1767  		o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
  1768  
  1769  	case 12: /* movb r,r (extsb); movw r,r (extsw) */
  1770  		if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
  1771  			v := regoff(ctxt, &p.From)
  1772  			if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
  1773  				ctxt.Diag("literal operation on R0\n%v", p)
  1774  			}
  1775  
  1776  			o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
  1777  			break
  1778  		}
  1779  
  1780  		if p.As == AMOVW {
  1781  			o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
  1782  		} else {
  1783  			o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
  1784  		}
  1785  
  1786  	case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
  1787  		if p.As == AMOVBZ {
  1788  			o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
  1789  		} else if p.As == AMOVH {
  1790  			o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
  1791  		} else if p.As == AMOVHZ {
  1792  			o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
  1793  		} else if p.As == AMOVWZ {
  1794  			o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
  1795  		} else {
  1796  			ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
  1797  		}
  1798  
  1799  	case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
  1800  		r := int(p.Reg)
  1801  
  1802  		if r == 0 {
  1803  			r = int(p.To.Reg)
  1804  		}
  1805  		d := vregoff(ctxt, p.From3)
  1806  		var mask [2]uint8
  1807  		maskgen64(ctxt, p, mask[:], uint64(d))
  1808  		var a int
  1809  		switch p.As {
  1810  		case ARLDCL, ARLDCLCC:
  1811  			a = int(mask[0]) /* MB */
  1812  			if mask[1] != 63 {
  1813  				ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)
  1814  			}
  1815  
  1816  		case ARLDCR, ARLDCRCC:
  1817  			a = int(mask[1]) /* ME */
  1818  			if mask[0] != 0 {
  1819  				ctxt.Diag("invalid mask for rotate: %x (start != 0)\n%v", uint64(d), p)
  1820  			}
  1821  
  1822  		default:
  1823  			ctxt.Diag("unexpected op in rldc case\n%v", p)
  1824  			a = 0
  1825  		}
  1826  
  1827  		o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
  1828  		o1 |= (uint32(a) & 31) << 6
  1829  		if a&0x20 != 0 {
  1830  			o1 |= 1 << 5 /* mb[5] is top bit */
  1831  		}
  1832  
  1833  	case 17, /* bc bo,bi,lbra (same for now) */
  1834  		16: /* bc bo,bi,sbra */
  1835  		a := 0
  1836  
  1837  		if p.From.Type == obj.TYPE_CONST {
  1838  			a = int(regoff(ctxt, &p.From))
  1839  		}
  1840  		r := int(p.Reg)
  1841  		if r == 0 {
  1842  			r = 0
  1843  		}
  1844  		v := int32(0)
  1845  		if p.Pcond != nil {
  1846  			v = int32(p.Pcond.Pc - p.Pc)
  1847  		}
  1848  		if v&03 != 0 {
  1849  			ctxt.Diag("odd branch target address\n%v", p)
  1850  			v &^= 03
  1851  		}
  1852  
  1853  		if v < -(1<<16) || v >= 1<<15 {
  1854  			ctxt.Diag("branch too far\n%v", p)
  1855  		}
  1856  		o1 = OP_BC(opirr(ctxt, p.As), uint32(a), uint32(r), uint32(v), 0)
  1857  
  1858  	case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
  1859  		var v int32
  1860  		if p.As == ABC || p.As == ABCL {
  1861  			v = regoff(ctxt, &p.To) & 31
  1862  		} else {
  1863  			v = 20 /* unconditional */
  1864  		}
  1865  		o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
  1866  		o2 = OPVCC(19, 16, 0, 0)
  1867  		if p.As == ABL || p.As == ABCL {
  1868  			o2 |= 1
  1869  		}
  1870  		o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index))
  1871  
  1872  	case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
  1873  		var v int32
  1874  		if p.As == ABC || p.As == ABCL {
  1875  			v = regoff(ctxt, &p.From) & 31
  1876  		} else {
  1877  			v = 20 /* unconditional */
  1878  		}
  1879  		r := int(p.Reg)
  1880  		if r == 0 {
  1881  			r = 0
  1882  		}
  1883  		switch oclass(&p.To) {
  1884  		case C_CTR:
  1885  			o1 = OPVCC(19, 528, 0, 0)
  1886  
  1887  		case C_LR:
  1888  			o1 = OPVCC(19, 16, 0, 0)
  1889  
  1890  		default:
  1891  			ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p)
  1892  			v = 0
  1893  		}
  1894  
  1895  		if p.As == ABL || p.As == ABCL {
  1896  			o1 |= 1
  1897  		}
  1898  		o1 = OP_BCR(o1, uint32(v), uint32(r))
  1899  
  1900  	case 19: /* mov $lcon,r ==> cau+or */
  1901  		d := vregoff(ctxt, &p.From)
  1902  
  1903  		if p.From.Sym == nil {
  1904  			o1 = loadu32(int(p.To.Reg), d)
  1905  			o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
  1906  		} else {
  1907  			o1, o2 = symbolAccess(ctxt, p.From.Sym, d, p.To.Reg, OP_ADDI)
  1908  		}
  1909  
  1910  	//if(dlm) reloc(&p->from, p->pc, 0);
  1911  
  1912  	case 20: /* add $ucon,,r */
  1913  		v := regoff(ctxt, &p.From)
  1914  
  1915  		r := int(p.Reg)
  1916  		if r == 0 {
  1917  			r = int(p.To.Reg)
  1918  		}
  1919  		if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
  1920  			ctxt.Diag("literal operation on R0\n%v", p)
  1921  		}
  1922  		o1 = AOP_IRR(opirr(ctxt, -p.As), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
  1923  
  1924  	case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */
  1925  		if p.To.Reg == REGTMP || p.Reg == REGTMP {
  1926  			ctxt.Diag("can't synthesize large constant\n%v", p)
  1927  		}
  1928  		d := vregoff(ctxt, &p.From)
  1929  		o1 = loadu32(REGTMP, d)
  1930  		o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
  1931  		r := int(p.Reg)
  1932  		if r == 0 {
  1933  			r = int(p.To.Reg)
  1934  		}
  1935  		o3 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(r))
  1936  		if p.From.Sym != nil {
  1937  			ctxt.Diag("%v is not supported", p)
  1938  		}
  1939  
  1940  	//if(dlm) reloc(&p->from, p->pc, 0);
  1941  
  1942  	case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */
  1943  		if p.To.Reg == REGTMP || p.Reg == REGTMP {
  1944  			ctxt.Diag("can't synthesize large constant\n%v", p)
  1945  		}
  1946  		d := vregoff(ctxt, &p.From)
  1947  		o1 = loadu32(REGTMP, d)
  1948  		o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
  1949  		r := int(p.Reg)
  1950  		if r == 0 {
  1951  			r = int(p.To.Reg)
  1952  		}
  1953  		o3 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(r))
  1954  		if p.From.Sym != nil {
  1955  			ctxt.Diag("%v is not supported", p)
  1956  		}
  1957  
  1958  		//if(dlm) reloc(&p->from, p->pc, 0);
  1959  
  1960  		/*24*/
  1961  	case 25:
  1962  		/* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
  1963  		v := regoff(ctxt, &p.From)
  1964  
  1965  		if v < 0 {
  1966  			v = 0
  1967  		} else if v > 63 {
  1968  			v = 63
  1969  		}
  1970  		r := int(p.Reg)
  1971  		if r == 0 {
  1972  			r = int(p.To.Reg)
  1973  		}
  1974  		var a int
  1975  		switch p.As {
  1976  		case ASLD, ASLDCC:
  1977  			a = int(63 - v)
  1978  			o1 = OP_RLDICR
  1979  
  1980  		case ASRD, ASRDCC:
  1981  			a = int(v)
  1982  			v = 64 - v
  1983  			o1 = OP_RLDICL
  1984  
  1985  		default:
  1986  			ctxt.Diag("unexpected op in sldi case\n%v", p)
  1987  			a = 0
  1988  			o1 = 0
  1989  		}
  1990  
  1991  		o1 = AOP_RRR(o1, uint32(r), uint32(p.To.Reg), (uint32(v) & 0x1F))
  1992  		o1 |= (uint32(a) & 31) << 6
  1993  		if v&0x20 != 0 {
  1994  			o1 |= 1 << 1
  1995  		}
  1996  		if a&0x20 != 0 {
  1997  			o1 |= 1 << 5 /* mb[5] is top bit */
  1998  		}
  1999  		if p.As == ASLDCC || p.As == ASRDCC {
  2000  			o1 |= 1 /* Rc */
  2001  		}
  2002  
  2003  	case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
  2004  		if p.To.Reg == REGTMP {
  2005  			ctxt.Diag("can't synthesize large constant\n%v", p)
  2006  		}
  2007  		v := regoff(ctxt, &p.From)
  2008  		r := int(p.From.Reg)
  2009  		if r == 0 {
  2010  			r = int(o.param)
  2011  		}
  2012  		o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
  2013  		o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
  2014  
  2015  	case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
  2016  		v := regoff(ctxt, p.From3)
  2017  
  2018  		r := int(p.From.Reg)
  2019  		o1 = AOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v))
  2020  
  2021  	case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
  2022  		if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
  2023  			ctxt.Diag("can't synthesize large constant\n%v", p)
  2024  		}
  2025  		v := regoff(ctxt, p.From3)
  2026  		o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
  2027  		o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
  2028  		o3 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
  2029  		if p.From.Sym != nil {
  2030  			ctxt.Diag("%v is not supported", p)
  2031  		}
  2032  
  2033  	//if(dlm) reloc(&p->from3, p->pc, 0);
  2034  
  2035  	case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
  2036  		v := regoff(ctxt, &p.From)
  2037  
  2038  		d := vregoff(ctxt, p.From3)
  2039  		var mask [2]uint8
  2040  		maskgen64(ctxt, p, mask[:], uint64(d))
  2041  		var a int
  2042  		switch p.As {
  2043  		case ARLDC, ARLDCCC:
  2044  			a = int(mask[0]) /* MB */
  2045  			if int32(mask[1]) != (63 - v) {
  2046  				ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
  2047  			}
  2048  
  2049  		case ARLDCL, ARLDCLCC:
  2050  			a = int(mask[0]) /* MB */
  2051  			if mask[1] != 63 {
  2052  				ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
  2053  			}
  2054  
  2055  		case ARLDCR, ARLDCRCC:
  2056  			a = int(mask[1]) /* ME */
  2057  			if mask[0] != 0 {
  2058  				ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
  2059  			}
  2060  
  2061  		default:
  2062  			ctxt.Diag("unexpected op in rldic case\n%v", p)
  2063  			a = 0
  2064  		}
  2065  
  2066  		o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
  2067  		o1 |= (uint32(a) & 31) << 6
  2068  		if v&0x20 != 0 {
  2069  			o1 |= 1 << 1
  2070  		}
  2071  		if a&0x20 != 0 {
  2072  			o1 |= 1 << 5 /* mb[5] is top bit */
  2073  		}
  2074  
  2075  	case 30: /* rldimi $sh,s,$mask,a */
  2076  		v := regoff(ctxt, &p.From)
  2077  
  2078  		d := vregoff(ctxt, p.From3)
  2079  		var mask [2]uint8
  2080  		maskgen64(ctxt, p, mask[:], uint64(d))
  2081  		if int32(mask[1]) != (63 - v) {
  2082  			ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
  2083  		}
  2084  		o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
  2085  		o1 |= (uint32(mask[0]) & 31) << 6
  2086  		if v&0x20 != 0 {
  2087  			o1 |= 1 << 1
  2088  		}
  2089  		if mask[0]&0x20 != 0 {
  2090  			o1 |= 1 << 5 /* mb[5] is top bit */
  2091  		}
  2092  
  2093  	case 31: /* dword */
  2094  		d := vregoff(ctxt, &p.From)
  2095  
  2096  		if ctxt.Arch.ByteOrder == binary.BigEndian {
  2097  			o1 = uint32(d >> 32)
  2098  			o2 = uint32(d)
  2099  		} else {
  2100  			o1 = uint32(d)
  2101  			o2 = uint32(d >> 32)
  2102  		}
  2103  
  2104  		if p.From.Sym != nil {
  2105  			rel := obj.Addrel(ctxt.Cursym)
  2106  			rel.Off = int32(ctxt.Pc)
  2107  			rel.Siz = 8
  2108  			rel.Sym = p.From.Sym
  2109  			rel.Add = p.From.Offset
  2110  			rel.Type = obj.R_ADDR
  2111  			o2 = 0
  2112  			o1 = o2
  2113  		}
  2114  
  2115  	case 32: /* fmul frc,fra,frd */
  2116  		r := int(p.Reg)
  2117  
  2118  		if r == 0 {
  2119  			r = int(p.To.Reg)
  2120  		}
  2121  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
  2122  
  2123  	case 33: /* fabs [frb,]frd; fmr. frb,frd */
  2124  		r := int(p.From.Reg)
  2125  
  2126  		if oclass(&p.From) == C_NONE {
  2127  			r = int(p.To.Reg)
  2128  		}
  2129  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), 0, uint32(r))
  2130  
  2131  	case 34: /* FMADDx fra,frb,frc,frd (d=a*b+c); FSELx a<0? (d=b): (d=c) */
  2132  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.From3.Reg)&31)<<6
  2133  
  2134  	case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
  2135  		v := regoff(ctxt, &p.To)
  2136  
  2137  		r := int(p.To.Reg)
  2138  		if r == 0 {
  2139  			r = int(o.param)
  2140  		}
  2141  		o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
  2142  		o2 = AOP_IRR(opstore(ctxt, p.As), uint32(p.From.Reg), REGTMP, uint32(v))
  2143  
  2144  	case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
  2145  		v := regoff(ctxt, &p.From)
  2146  
  2147  		r := int(p.From.Reg)
  2148  		if r == 0 {
  2149  			r = int(o.param)
  2150  		}
  2151  		o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
  2152  		o2 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(v))
  2153  
  2154  	case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
  2155  		v := regoff(ctxt, &p.From)
  2156  
  2157  		r := int(p.From.Reg)
  2158  		if r == 0 {
  2159  			r = int(o.param)
  2160  		}
  2161  		o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
  2162  		o2 = AOP_IRR(opload(ctxt, p.As), uint32(p.To.Reg), REGTMP, uint32(v))
  2163  		o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
  2164  
  2165  	case 40: /* word */
  2166  		o1 = uint32(regoff(ctxt, &p.From))
  2167  
  2168  	case 41: /* stswi */
  2169  		o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11
  2170  
  2171  	case 42: /* lswi */
  2172  		o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(regoff(ctxt, p.From3))&0x7F)<<11
  2173  
  2174  	case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */
  2175  		o1 = AOP_RRR(oprrr(ctxt, p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))
  2176  
  2177  	case 44: /* indexed store */
  2178  		o1 = AOP_RRR(opstorex(ctxt, p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
  2179  
  2180  	case 45: /* indexed load */
  2181  		o1 = AOP_RRR(oploadx(ctxt, p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
  2182  
  2183  	case 46: /* plain op */
  2184  		o1 = oprrr(ctxt, p.As)
  2185  
  2186  	case 47: /* op Ra, Rd; also op [Ra,] Rd */
  2187  		r := int(p.From.Reg)
  2188  
  2189  		if r == 0 {
  2190  			r = int(p.To.Reg)
  2191  		}
  2192  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0)
  2193  
  2194  	case 48: /* op Rs, Ra */
  2195  		r := int(p.From.Reg)
  2196  
  2197  		if r == 0 {
  2198  			r = int(p.To.Reg)
  2199  		}
  2200  		o1 = LOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), uint32(r), 0)
  2201  
  2202  	case 49: /* op Rb; op $n, Rb */
  2203  		if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
  2204  			v := regoff(ctxt, &p.From) & 1
  2205  			o1 = AOP_RRR(oprrr(ctxt, p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
  2206  		} else {
  2207  			o1 = AOP_RRR(oprrr(ctxt, p.As), 0, 0, uint32(p.From.Reg))
  2208  		}
  2209  
  2210  	case 50: /* rem[u] r1[,r2],r3 */
  2211  		r := int(p.Reg)
  2212  
  2213  		if r == 0 {
  2214  			r = int(p.To.Reg)
  2215  		}
  2216  		v := oprrr(ctxt, p.As)
  2217  		t := v & (1<<10 | 1) /* OE|Rc */
  2218  		o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
  2219  		o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
  2220  		o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
  2221  		if p.As == AREMU {
  2222  			o4 = o3
  2223  
  2224  			/* Clear top 32 bits */
  2225  			o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5
  2226  		}
  2227  
  2228  	case 51: /* remd[u] r1[,r2],r3 */
  2229  		r := int(p.Reg)
  2230  
  2231  		if r == 0 {
  2232  			r = int(p.To.Reg)
  2233  		}
  2234  		v := oprrr(ctxt, p.As)
  2235  		t := v & (1<<10 | 1) /* OE|Rc */
  2236  		o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
  2237  		o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
  2238  		o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
  2239  
  2240  	case 52: /* mtfsbNx cr(n) */
  2241  		v := regoff(ctxt, &p.From) & 31
  2242  
  2243  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(v), 0, 0)
  2244  
  2245  	case 53: /* mffsX ,fr1 */
  2246  		o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)
  2247  
  2248  	case 54: /* mov msr,r1; mov r1, msr*/
  2249  		if oclass(&p.From) == C_REG {
  2250  			if p.As == AMOVD {
  2251  				o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
  2252  			} else {
  2253  				o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
  2254  			}
  2255  		} else {
  2256  			o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
  2257  		}
  2258  
  2259  	case 55: /* op Rb, Rd */
  2260  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg))
  2261  
  2262  	case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
  2263  		v := regoff(ctxt, &p.From)
  2264  
  2265  		r := int(p.Reg)
  2266  		if r == 0 {
  2267  			r = int(p.To.Reg)
  2268  		}
  2269  		o1 = AOP_RRR(opirr(ctxt, p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31)
  2270  		if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) {
  2271  			o1 |= 1 << 1 /* mb[5] */
  2272  		}
  2273  
  2274  	case 57: /* slw $sh,[s,]a -> rlwinm ... */
  2275  		v := regoff(ctxt, &p.From)
  2276  
  2277  		r := int(p.Reg)
  2278  		if r == 0 {
  2279  			r = int(p.To.Reg)
  2280  		}
  2281  
  2282  		/*
  2283  			 * Let user (gs) shoot himself in the foot.
  2284  			 * qc has already complained.
  2285  			 *
  2286  			if(v < 0 || v > 31)
  2287  				ctxt->diag("illegal shift %ld\n%v", v, p);
  2288  		*/
  2289  		if v < 0 {
  2290  			v = 0
  2291  		} else if v > 32 {
  2292  			v = 32
  2293  		}
  2294  		var mask [2]uint8
  2295  		if p.As == ASRW || p.As == ASRWCC { /* shift right */
  2296  			mask[0] = uint8(v)
  2297  			mask[1] = 31
  2298  			v = 32 - v
  2299  		} else {
  2300  			mask[0] = 0
  2301  			mask[1] = uint8(31 - v)
  2302  		}
  2303  
  2304  		o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1]))
  2305  		if p.As == ASLWCC || p.As == ASRWCC {
  2306  			o1 |= 1 /* Rc */
  2307  		}
  2308  
  2309  	case 58: /* logical $andcon,[s],a */
  2310  		v := regoff(ctxt, &p.From)
  2311  
  2312  		r := int(p.Reg)
  2313  		if r == 0 {
  2314  			r = int(p.To.Reg)
  2315  		}
  2316  		o1 = LOP_IRR(opirr(ctxt, p.As), uint32(p.To.Reg), uint32(r), uint32(v))
  2317  
  2318  	case 59: /* or/and $ucon,,r */
  2319  		v := regoff(ctxt, &p.From)
  2320  
  2321  		r := int(p.Reg)
  2322  		if r == 0 {
  2323  			r = int(p.To.Reg)
  2324  		}
  2325  		o1 = LOP_IRR(opirr(ctxt, -p.As), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */
  2326  
  2327  	case 60: /* tw to,a,b */
  2328  		r := int(regoff(ctxt, &p.From) & 31)
  2329  
  2330  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
  2331  
  2332  	case 61: /* tw to,a,$simm */
  2333  		r := int(regoff(ctxt, &p.From) & 31)
  2334  
  2335  		v := regoff(ctxt, &p.To)
  2336  		o1 = AOP_IRR(opirr(ctxt, p.As), uint32(r), uint32(p.Reg), uint32(v))
  2337  
  2338  	case 62: /* rlwmi $sh,s,$mask,a */
  2339  		v := regoff(ctxt, &p.From)
  2340  
  2341  		var mask [2]uint8
  2342  		maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3)))
  2343  		o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
  2344  		o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
  2345  
  2346  	case 63: /* rlwmi b,s,$mask,a */
  2347  		var mask [2]uint8
  2348  		maskgen(ctxt, p, mask[:], uint32(regoff(ctxt, p.From3)))
  2349  
  2350  		o1 = AOP_RRR(opirr(ctxt, p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
  2351  		o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
  2352  
  2353  	case 64: /* mtfsf fr[, $m] {,fpcsr} */
  2354  		var v int32
  2355  		if p.From3Type() != obj.TYPE_NONE {
  2356  			v = regoff(ctxt, p.From3) & 255
  2357  		} else {
  2358  			v = 255
  2359  		}
  2360  		o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
  2361  
  2362  	case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
  2363  		if p.To.Reg == 0 {
  2364  			ctxt.Diag("must specify FPSCR(n)\n%v", p)
  2365  		}
  2366  		o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12
  2367  
  2368  	case 66: /* mov spr,r1; mov r1,spr, also dcr */
  2369  		var r int
  2370  		var v int32
  2371  		if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
  2372  			r = int(p.From.Reg)
  2373  			v = int32(p.To.Reg)
  2374  			if REG_DCR0 <= v && v <= REG_DCR0+1023 {
  2375  				o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
  2376  			} else {
  2377  				o1 = OPVCC(31, 467, 0, 0) /* mtspr */
  2378  			}
  2379  		} else {
  2380  			r = int(p.To.Reg)
  2381  			v = int32(p.From.Reg)
  2382  			if REG_DCR0 <= v && v <= REG_DCR0+1023 {
  2383  				o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
  2384  			} else {
  2385  				o1 = OPVCC(31, 339, 0, 0) /* mfspr */
  2386  			}
  2387  		}
  2388  
  2389  		o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
  2390  
  2391  	case 67: /* mcrf crfD,crfS */
  2392  		if p.From.Type != obj.TYPE_REG || p.From.Reg < REG_CR0 || REG_CR7 < p.From.Reg || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg {
  2393  			ctxt.Diag("illegal CR field number\n%v", p)
  2394  		}
  2395  		o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
  2396  
  2397  	case 68: /* mfcr rD; mfocrf CRM,rD */
  2398  		if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
  2399  			v := int32(1 << uint(7-(p.To.Reg&7)))                                 /* CR(n) */
  2400  			o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
  2401  		} else {
  2402  			o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
  2403  		}
  2404  
  2405  	case 69: /* mtcrf CRM,rS */
  2406  		var v int32
  2407  		if p.From3Type() != obj.TYPE_NONE {
  2408  			if p.To.Reg != 0 {
  2409  				ctxt.Diag("can't use both mask and CR(n)\n%v", p)
  2410  			}
  2411  			v = regoff(ctxt, p.From3) & 0xff
  2412  		} else {
  2413  			if p.To.Reg == 0 {
  2414  				v = 0xff /* CR */
  2415  			} else {
  2416  				v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
  2417  			}
  2418  		}
  2419  
  2420  		o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
  2421  
  2422  	case 70: /* [f]cmp r,r,cr*/
  2423  		var r int
  2424  		if p.Reg == 0 {
  2425  			r = 0
  2426  		} else {
  2427  			r = (int(p.Reg) & 7) << 2
  2428  		}
  2429  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
  2430  
  2431  	case 71: /* cmp[l] r,i,cr*/
  2432  		var r int
  2433  		if p.Reg == 0 {
  2434  			r = 0
  2435  		} else {
  2436  			r = (int(p.Reg) & 7) << 2
  2437  		}
  2438  		o1 = AOP_RRR(opirr(ctxt, p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(regoff(ctxt, &p.To))&0xffff
  2439  
  2440  	case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
  2441  		o1 = AOP_RRR(oprrr(ctxt, p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg))
  2442  
  2443  	case 73: /* mcrfs crfD,crfS */
  2444  		if p.From.Type != obj.TYPE_REG || p.From.Reg != REG_FPSCR || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg {
  2445  			ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
  2446  		}
  2447  		o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
  2448  
  2449  	case 77: /* syscall $scon, syscall Rx */
  2450  		if p.From.Type == obj.TYPE_CONST {
  2451  			if p.From.Offset > BIG || p.From.Offset < -BIG {
  2452  				ctxt.Diag("illegal syscall, sysnum too large: %v", p)
  2453  			}
  2454  			o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
  2455  		} else if p.From.Type == obj.TYPE_REG {
  2456  			o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
  2457  		} else {
  2458  			ctxt.Diag("illegal syscall: %v", p)
  2459  			o1 = 0x7fe00008 // trap always
  2460  		}
  2461  
  2462  		o2 = oprrr(ctxt, p.As)
  2463  		o3 = AOP_RRR(oprrr(ctxt, AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R0
  2464  
  2465  	case 78: /* undef */
  2466  		o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed
  2467  		   always to be an illegal instruction."  */
  2468  
  2469  	/* relocation operations */
  2470  	case 74:
  2471  		v := vregoff(ctxt, &p.To)
  2472  		o1, o2 = symbolAccess(ctxt, p.To.Sym, v, p.From.Reg, opstore(ctxt, p.As))
  2473  
  2474  	//if(dlm) reloc(&p->to, p->pc, 1);
  2475  
  2476  	case 75:
  2477  		v := vregoff(ctxt, &p.From)
  2478  		o1, o2 = symbolAccess(ctxt, p.From.Sym, v, p.To.Reg, opload(ctxt, p.As))
  2479  
  2480  	//if(dlm) reloc(&p->from, p->pc, 1);
  2481  
  2482  	case 76:
  2483  		v := vregoff(ctxt, &p.From)
  2484  		o1, o2 = symbolAccess(ctxt, p.From.Sym, v, p.To.Reg, opload(ctxt, p.As))
  2485  		o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
  2486  
  2487  		//if(dlm) reloc(&p->from, p->pc, 1);
  2488  
  2489  	case 79:
  2490  		if p.From.Offset != 0 {
  2491  			ctxt.Diag("invalid offset against tls var %v", p)
  2492  		}
  2493  		o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0)
  2494  		rel := obj.Addrel(ctxt.Cursym)
  2495  		rel.Off = int32(ctxt.Pc)
  2496  		rel.Siz = 4
  2497  		rel.Sym = p.From.Sym
  2498  		rel.Type = obj.R_POWER_TLS_LE
  2499  
  2500  	case 80:
  2501  		if p.From.Offset != 0 {
  2502  			ctxt.Diag("invalid offset against tls var %v", p)
  2503  		}
  2504  		o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
  2505  		o2 = AOP_IRR(opload(ctxt, AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
  2506  		rel := obj.Addrel(ctxt.Cursym)
  2507  		rel.Off = int32(ctxt.Pc)
  2508  		rel.Siz = 8
  2509  		rel.Sym = p.From.Sym
  2510  		rel.Type = obj.R_POWER_TLS_IE
  2511  
  2512  	case 81:
  2513  		v := vregoff(ctxt, &p.To)
  2514  		if v != 0 {
  2515  			ctxt.Diag("invalid offset against GOT slot %v", p)
  2516  		}
  2517  
  2518  		o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
  2519  		o2 = AOP_IRR(opload(ctxt, AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
  2520  		rel := obj.Addrel(ctxt.Cursym)
  2521  		rel.Off = int32(ctxt.Pc)
  2522  		rel.Siz = 8
  2523  		rel.Sym = p.From.Sym
  2524  		rel.Type = obj.R_ADDRPOWER_GOT
  2525  	}
  2526  
  2527  	out[0] = o1
  2528  	out[1] = o2
  2529  	out[2] = o3
  2530  	out[3] = o4
  2531  	out[4] = o5
  2532  	return
  2533  }
  2534  
  2535  func vregoff(ctxt *obj.Link, a *obj.Addr) int64 {
  2536  	ctxt.Instoffset = 0
  2537  	if a != nil {
  2538  		aclass(ctxt, a)
  2539  	}
  2540  	return ctxt.Instoffset
  2541  }
  2542  
  2543  func regoff(ctxt *obj.Link, a *obj.Addr) int32 {
  2544  	return int32(vregoff(ctxt, a))
  2545  }
  2546  
  2547  func oprrr(ctxt *obj.Link, a obj.As) uint32 {
  2548  	switch a {
  2549  	case AADD:
  2550  		return OPVCC(31, 266, 0, 0)
  2551  	case AADDCC:
  2552  		return OPVCC(31, 266, 0, 1)
  2553  	case AADDV:
  2554  		return OPVCC(31, 266, 1, 0)
  2555  	case AADDVCC:
  2556  		return OPVCC(31, 266, 1, 1)
  2557  	case AADDC:
  2558  		return OPVCC(31, 10, 0, 0)
  2559  	case AADDCCC:
  2560  		return OPVCC(31, 10, 0, 1)
  2561  	case AADDCV:
  2562  		return OPVCC(31, 10, 1, 0)
  2563  	case AADDCVCC:
  2564  		return OPVCC(31, 10, 1, 1)
  2565  	case AADDE:
  2566  		return OPVCC(31, 138, 0, 0)
  2567  	case AADDECC:
  2568  		return OPVCC(31, 138, 0, 1)
  2569  	case AADDEV:
  2570  		return OPVCC(31, 138, 1, 0)
  2571  	case AADDEVCC:
  2572  		return OPVCC(31, 138, 1, 1)
  2573  	case AADDME:
  2574  		return OPVCC(31, 234, 0, 0)
  2575  	case AADDMECC:
  2576  		return OPVCC(31, 234, 0, 1)
  2577  	case AADDMEV:
  2578  		return OPVCC(31, 234, 1, 0)
  2579  	case AADDMEVCC:
  2580  		return OPVCC(31, 234, 1, 1)
  2581  	case AADDZE:
  2582  		return OPVCC(31, 202, 0, 0)
  2583  	case AADDZECC:
  2584  		return OPVCC(31, 202, 0, 1)
  2585  	case AADDZEV:
  2586  		return OPVCC(31, 202, 1, 0)
  2587  	case AADDZEVCC:
  2588  		return OPVCC(31, 202, 1, 1)
  2589  
  2590  	case AAND:
  2591  		return OPVCC(31, 28, 0, 0)
  2592  	case AANDCC:
  2593  		return OPVCC(31, 28, 0, 1)
  2594  	case AANDN:
  2595  		return OPVCC(31, 60, 0, 0)
  2596  	case AANDNCC:
  2597  		return OPVCC(31, 60, 0, 1)
  2598  
  2599  	case ACMP:
  2600  		return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */
  2601  	case ACMPU:
  2602  		return OPVCC(31, 32, 0, 0) | 1<<21
  2603  	case ACMPW:
  2604  		return OPVCC(31, 0, 0, 0) /* L=0 */
  2605  	case ACMPWU:
  2606  		return OPVCC(31, 32, 0, 0)
  2607  
  2608  	case ACNTLZW:
  2609  		return OPVCC(31, 26, 0, 0)
  2610  	case ACNTLZWCC:
  2611  		return OPVCC(31, 26, 0, 1)
  2612  	case ACNTLZD:
  2613  		return OPVCC(31, 58, 0, 0)
  2614  	case ACNTLZDCC:
  2615  		return OPVCC(31, 58, 0, 1)
  2616  
  2617  	case ACRAND:
  2618  		return OPVCC(19, 257, 0, 0)
  2619  	case ACRANDN:
  2620  		return OPVCC(19, 129, 0, 0)
  2621  	case ACREQV:
  2622  		return OPVCC(19, 289, 0, 0)
  2623  	case ACRNAND:
  2624  		return OPVCC(19, 225, 0, 0)
  2625  	case ACRNOR:
  2626  		return OPVCC(19, 33, 0, 0)
  2627  	case ACROR:
  2628  		return OPVCC(19, 449, 0, 0)
  2629  	case ACRORN:
  2630  		return OPVCC(19, 417, 0, 0)
  2631  	case ACRXOR:
  2632  		return OPVCC(19, 193, 0, 0)
  2633  
  2634  	case ADCBF:
  2635  		return OPVCC(31, 86, 0, 0)
  2636  	case ADCBI:
  2637  		return OPVCC(31, 470, 0, 0)
  2638  	case ADCBST:
  2639  		return OPVCC(31, 54, 0, 0)
  2640  	case ADCBT:
  2641  		return OPVCC(31, 278, 0, 0)
  2642  	case ADCBTST:
  2643  		return OPVCC(31, 246, 0, 0)
  2644  	case ADCBZ:
  2645  		return OPVCC(31, 1014, 0, 0)
  2646  
  2647  	case AREM, ADIVW:
  2648  		return OPVCC(31, 491, 0, 0)
  2649  
  2650  	case AREMCC, ADIVWCC:
  2651  		return OPVCC(31, 491, 0, 1)
  2652  
  2653  	case AREMV, ADIVWV:
  2654  		return OPVCC(31, 491, 1, 0)
  2655  
  2656  	case AREMVCC, ADIVWVCC:
  2657  		return OPVCC(31, 491, 1, 1)
  2658  
  2659  	case AREMU, ADIVWU:
  2660  		return OPVCC(31, 459, 0, 0)
  2661  
  2662  	case AREMUCC, ADIVWUCC:
  2663  		return OPVCC(31, 459, 0, 1)
  2664  
  2665  	case AREMUV, ADIVWUV:
  2666  		return OPVCC(31, 459, 1, 0)
  2667  
  2668  	case AREMUVCC, ADIVWUVCC:
  2669  		return OPVCC(31, 459, 1, 1)
  2670  
  2671  	case AREMD, ADIVD:
  2672  		return OPVCC(31, 489, 0, 0)
  2673  
  2674  	case AREMDCC, ADIVDCC:
  2675  		return OPVCC(31, 489, 0, 1)
  2676  
  2677  	case ADIVDE:
  2678  		return OPVCC(31, 425, 0, 0)
  2679  
  2680  	case ADIVDECC:
  2681  		return OPVCC(31, 425, 0, 1)
  2682  
  2683  	case ADIVDEU:
  2684  		return OPVCC(31, 393, 0, 0)
  2685  
  2686  	case ADIVDEUCC:
  2687  		return OPVCC(31, 393, 0, 1)
  2688  
  2689  	case AREMDV, ADIVDV:
  2690  		return OPVCC(31, 489, 1, 0)
  2691  
  2692  	case AREMDVCC, ADIVDVCC:
  2693  		return OPVCC(31, 489, 1, 1)
  2694  
  2695  	case AREMDU, ADIVDU:
  2696  		return OPVCC(31, 457, 0, 0)
  2697  
  2698  	case AREMDUCC, ADIVDUCC:
  2699  		return OPVCC(31, 457, 0, 1)
  2700  
  2701  	case AREMDUV, ADIVDUV:
  2702  		return OPVCC(31, 457, 1, 0)
  2703  
  2704  	case AREMDUVCC, ADIVDUVCC:
  2705  		return OPVCC(31, 457, 1, 1)
  2706  
  2707  	case AEIEIO:
  2708  		return OPVCC(31, 854, 0, 0)
  2709  
  2710  	case AEQV:
  2711  		return OPVCC(31, 284, 0, 0)
  2712  	case AEQVCC:
  2713  		return OPVCC(31, 284, 0, 1)
  2714  
  2715  	case AEXTSB:
  2716  		return OPVCC(31, 954, 0, 0)
  2717  	case AEXTSBCC:
  2718  		return OPVCC(31, 954, 0, 1)
  2719  	case AEXTSH:
  2720  		return OPVCC(31, 922, 0, 0)
  2721  	case AEXTSHCC:
  2722  		return OPVCC(31, 922, 0, 1)
  2723  	case AEXTSW:
  2724  		return OPVCC(31, 986, 0, 0)
  2725  	case AEXTSWCC:
  2726  		return OPVCC(31, 986, 0, 1)
  2727  
  2728  	case AFABS:
  2729  		return OPVCC(63, 264, 0, 0)
  2730  	case AFABSCC:
  2731  		return OPVCC(63, 264, 0, 1)
  2732  	case AFADD:
  2733  		return OPVCC(63, 21, 0, 0)
  2734  	case AFADDCC:
  2735  		return OPVCC(63, 21, 0, 1)
  2736  	case AFADDS:
  2737  		return OPVCC(59, 21, 0, 0)
  2738  	case AFADDSCC:
  2739  		return OPVCC(59, 21, 0, 1)
  2740  	case AFCMPO:
  2741  		return OPVCC(63, 32, 0, 0)
  2742  	case AFCMPU:
  2743  		return OPVCC(63, 0, 0, 0)
  2744  	case AFCFID:
  2745  		return OPVCC(63, 846, 0, 0)
  2746  	case AFCFIDCC:
  2747  		return OPVCC(63, 846, 0, 1)
  2748  	case AFCFIDU:
  2749  		return OPVCC(63, 974, 0, 0)
  2750  	case AFCFIDUCC:
  2751  		return OPVCC(63, 974, 0, 1)
  2752  	case AFCTIW:
  2753  		return OPVCC(63, 14, 0, 0)
  2754  	case AFCTIWCC:
  2755  		return OPVCC(63, 14, 0, 1)
  2756  	case AFCTIWZ:
  2757  		return OPVCC(63, 15, 0, 0)
  2758  	case AFCTIWZCC:
  2759  		return OPVCC(63, 15, 0, 1)
  2760  	case AFCTID:
  2761  		return OPVCC(63, 814, 0, 0)
  2762  	case AFCTIDCC:
  2763  		return OPVCC(63, 814, 0, 1)
  2764  	case AFCTIDZ:
  2765  		return OPVCC(63, 815, 0, 0)
  2766  	case AFCTIDZCC:
  2767  		return OPVCC(63, 815, 0, 1)
  2768  	case AFDIV:
  2769  		return OPVCC(63, 18, 0, 0)
  2770  	case AFDIVCC:
  2771  		return OPVCC(63, 18, 0, 1)
  2772  	case AFDIVS:
  2773  		return OPVCC(59, 18, 0, 0)
  2774  	case AFDIVSCC:
  2775  		return OPVCC(59, 18, 0, 1)
  2776  	case AFMADD:
  2777  		return OPVCC(63, 29, 0, 0)
  2778  	case AFMADDCC:
  2779  		return OPVCC(63, 29, 0, 1)
  2780  	case AFMADDS:
  2781  		return OPVCC(59, 29, 0, 0)
  2782  	case AFMADDSCC:
  2783  		return OPVCC(59, 29, 0, 1)
  2784  
  2785  	case AFMOVS, AFMOVD:
  2786  		return OPVCC(63, 72, 0, 0) /* load */
  2787  	case AFMOVDCC:
  2788  		return OPVCC(63, 72, 0, 1)
  2789  	case AFMSUB:
  2790  		return OPVCC(63, 28, 0, 0)
  2791  	case AFMSUBCC:
  2792  		return OPVCC(63, 28, 0, 1)
  2793  	case AFMSUBS:
  2794  		return OPVCC(59, 28, 0, 0)
  2795  	case AFMSUBSCC:
  2796  		return OPVCC(59, 28, 0, 1)
  2797  	case AFMUL:
  2798  		return OPVCC(63, 25, 0, 0)
  2799  	case AFMULCC:
  2800  		return OPVCC(63, 25, 0, 1)
  2801  	case AFMULS:
  2802  		return OPVCC(59, 25, 0, 0)
  2803  	case AFMULSCC:
  2804  		return OPVCC(59, 25, 0, 1)
  2805  	case AFNABS:
  2806  		return OPVCC(63, 136, 0, 0)
  2807  	case AFNABSCC:
  2808  		return OPVCC(63, 136, 0, 1)
  2809  	case AFNEG:
  2810  		return OPVCC(63, 40, 0, 0)
  2811  	case AFNEGCC:
  2812  		return OPVCC(63, 40, 0, 1)
  2813  	case AFNMADD:
  2814  		return OPVCC(63, 31, 0, 0)
  2815  	case AFNMADDCC:
  2816  		return OPVCC(63, 31, 0, 1)
  2817  	case AFNMADDS:
  2818  		return OPVCC(59, 31, 0, 0)
  2819  	case AFNMADDSCC:
  2820  		return OPVCC(59, 31, 0, 1)
  2821  	case AFNMSUB:
  2822  		return OPVCC(63, 30, 0, 0)
  2823  	case AFNMSUBCC:
  2824  		return OPVCC(63, 30, 0, 1)
  2825  	case AFNMSUBS:
  2826  		return OPVCC(59, 30, 0, 0)
  2827  	case AFNMSUBSCC:
  2828  		return OPVCC(59, 30, 0, 1)
  2829  	case AFRES:
  2830  		return OPVCC(59, 24, 0, 0)
  2831  	case AFRESCC:
  2832  		return OPVCC(59, 24, 0, 1)
  2833  	case AFRSP:
  2834  		return OPVCC(63, 12, 0, 0)
  2835  	case AFRSPCC:
  2836  		return OPVCC(63, 12, 0, 1)
  2837  	case AFRSQRTE:
  2838  		return OPVCC(63, 26, 0, 0)
  2839  	case AFRSQRTECC:
  2840  		return OPVCC(63, 26, 0, 1)
  2841  	case AFSEL:
  2842  		return OPVCC(63, 23, 0, 0)
  2843  	case AFSELCC:
  2844  		return OPVCC(63, 23, 0, 1)
  2845  	case AFSQRT:
  2846  		return OPVCC(63, 22, 0, 0)
  2847  	case AFSQRTCC:
  2848  		return OPVCC(63, 22, 0, 1)
  2849  	case AFSQRTS:
  2850  		return OPVCC(59, 22, 0, 0)
  2851  	case AFSQRTSCC:
  2852  		return OPVCC(59, 22, 0, 1)
  2853  	case AFSUB:
  2854  		return OPVCC(63, 20, 0, 0)
  2855  	case AFSUBCC:
  2856  		return OPVCC(63, 20, 0, 1)
  2857  	case AFSUBS:
  2858  		return OPVCC(59, 20, 0, 0)
  2859  	case AFSUBSCC:
  2860  		return OPVCC(59, 20, 0, 1)
  2861  
  2862  	case AICBI:
  2863  		return OPVCC(31, 982, 0, 0)
  2864  	case AISYNC:
  2865  		return OPVCC(19, 150, 0, 0)
  2866  
  2867  	case AMTFSB0:
  2868  		return OPVCC(63, 70, 0, 0)
  2869  	case AMTFSB0CC:
  2870  		return OPVCC(63, 70, 0, 1)
  2871  	case AMTFSB1:
  2872  		return OPVCC(63, 38, 0, 0)
  2873  	case AMTFSB1CC:
  2874  		return OPVCC(63, 38, 0, 1)
  2875  
  2876  	case AMULHW:
  2877  		return OPVCC(31, 75, 0, 0)
  2878  	case AMULHWCC:
  2879  		return OPVCC(31, 75, 0, 1)
  2880  	case AMULHWU:
  2881  		return OPVCC(31, 11, 0, 0)
  2882  	case AMULHWUCC:
  2883  		return OPVCC(31, 11, 0, 1)
  2884  	case AMULLW:
  2885  		return OPVCC(31, 235, 0, 0)
  2886  	case AMULLWCC:
  2887  		return OPVCC(31, 235, 0, 1)
  2888  	case AMULLWV:
  2889  		return OPVCC(31, 235, 1, 0)
  2890  	case AMULLWVCC:
  2891  		return OPVCC(31, 235, 1, 1)
  2892  
  2893  	case AMULHD:
  2894  		return OPVCC(31, 73, 0, 0)
  2895  	case AMULHDCC:
  2896  		return OPVCC(31, 73, 0, 1)
  2897  	case AMULHDU:
  2898  		return OPVCC(31, 9, 0, 0)
  2899  	case AMULHDUCC:
  2900  		return OPVCC(31, 9, 0, 1)
  2901  	case AMULLD:
  2902  		return OPVCC(31, 233, 0, 0)
  2903  	case AMULLDCC:
  2904  		return OPVCC(31, 233, 0, 1)
  2905  	case AMULLDV:
  2906  		return OPVCC(31, 233, 1, 0)
  2907  	case AMULLDVCC:
  2908  		return OPVCC(31, 233, 1, 1)
  2909  
  2910  	case ANAND:
  2911  		return OPVCC(31, 476, 0, 0)
  2912  	case ANANDCC:
  2913  		return OPVCC(31, 476, 0, 1)
  2914  	case ANEG:
  2915  		return OPVCC(31, 104, 0, 0)
  2916  	case ANEGCC:
  2917  		return OPVCC(31, 104, 0, 1)
  2918  	case ANEGV:
  2919  		return OPVCC(31, 104, 1, 0)
  2920  	case ANEGVCC:
  2921  		return OPVCC(31, 104, 1, 1)
  2922  	case ANOR:
  2923  		return OPVCC(31, 124, 0, 0)
  2924  	case ANORCC:
  2925  		return OPVCC(31, 124, 0, 1)
  2926  	case AOR:
  2927  		return OPVCC(31, 444, 0, 0)
  2928  	case AORCC:
  2929  		return OPVCC(31, 444, 0, 1)
  2930  	case AORN:
  2931  		return OPVCC(31, 412, 0, 0)
  2932  	case AORNCC:
  2933  		return OPVCC(31, 412, 0, 1)
  2934  
  2935  	case ARFI:
  2936  		return OPVCC(19, 50, 0, 0)
  2937  	case ARFCI:
  2938  		return OPVCC(19, 51, 0, 0)
  2939  	case ARFID:
  2940  		return OPVCC(19, 18, 0, 0)
  2941  	case AHRFID:
  2942  		return OPVCC(19, 274, 0, 0)
  2943  
  2944  	case ARLWMI:
  2945  		return OPVCC(20, 0, 0, 0)
  2946  	case ARLWMICC:
  2947  		return OPVCC(20, 0, 0, 1)
  2948  	case ARLWNM:
  2949  		return OPVCC(23, 0, 0, 0)
  2950  	case ARLWNMCC:
  2951  		return OPVCC(23, 0, 0, 1)
  2952  
  2953  	case ARLDCL:
  2954  		return OPVCC(30, 8, 0, 0)
  2955  	case ARLDCR:
  2956  		return OPVCC(30, 9, 0, 0)
  2957  
  2958  	case ASYSCALL:
  2959  		return OPVCC(17, 1, 0, 0)
  2960  
  2961  	case ASLW:
  2962  		return OPVCC(31, 24, 0, 0)
  2963  	case ASLWCC:
  2964  		return OPVCC(31, 24, 0, 1)
  2965  	case ASLD:
  2966  		return OPVCC(31, 27, 0, 0)
  2967  	case ASLDCC:
  2968  		return OPVCC(31, 27, 0, 1)
  2969  
  2970  	case ASRAW:
  2971  		return OPVCC(31, 792, 0, 0)
  2972  	case ASRAWCC:
  2973  		return OPVCC(31, 792, 0, 1)
  2974  	case ASRAD:
  2975  		return OPVCC(31, 794, 0, 0)
  2976  	case ASRADCC:
  2977  		return OPVCC(31, 794, 0, 1)
  2978  
  2979  	case ASRW:
  2980  		return OPVCC(31, 536, 0, 0)
  2981  	case ASRWCC:
  2982  		return OPVCC(31, 536, 0, 1)
  2983  	case ASRD:
  2984  		return OPVCC(31, 539, 0, 0)
  2985  	case ASRDCC:
  2986  		return OPVCC(31, 539, 0, 1)
  2987  
  2988  	case ASUB:
  2989  		return OPVCC(31, 40, 0, 0)
  2990  	case ASUBCC:
  2991  		return OPVCC(31, 40, 0, 1)
  2992  	case ASUBV:
  2993  		return OPVCC(31, 40, 1, 0)
  2994  	case ASUBVCC:
  2995  		return OPVCC(31, 40, 1, 1)
  2996  	case ASUBC:
  2997  		return OPVCC(31, 8, 0, 0)
  2998  	case ASUBCCC:
  2999  		return OPVCC(31, 8, 0, 1)
  3000  	case ASUBCV:
  3001  		return OPVCC(31, 8, 1, 0)
  3002  	case ASUBCVCC:
  3003  		return OPVCC(31, 8, 1, 1)
  3004  	case ASUBE:
  3005  		return OPVCC(31, 136, 0, 0)
  3006  	case ASUBECC:
  3007  		return OPVCC(31, 136, 0, 1)
  3008  	case ASUBEV:
  3009  		return OPVCC(31, 136, 1, 0)
  3010  	case ASUBEVCC:
  3011  		return OPVCC(31, 136, 1, 1)
  3012  	case ASUBME:
  3013  		return OPVCC(31, 232, 0, 0)
  3014  	case ASUBMECC:
  3015  		return OPVCC(31, 232, 0, 1)
  3016  	case ASUBMEV:
  3017  		return OPVCC(31, 232, 1, 0)
  3018  	case ASUBMEVCC:
  3019  		return OPVCC(31, 232, 1, 1)
  3020  	case ASUBZE:
  3021  		return OPVCC(31, 200, 0, 0)
  3022  	case ASUBZECC:
  3023  		return OPVCC(31, 200, 0, 1)
  3024  	case ASUBZEV:
  3025  		return OPVCC(31, 200, 1, 0)
  3026  	case ASUBZEVCC:
  3027  		return OPVCC(31, 200, 1, 1)
  3028  
  3029  	case ASYNC:
  3030  		return OPVCC(31, 598, 0, 0)
  3031  	case ALWSYNC:
  3032  		return OPVCC(31, 598, 0, 0) | 1<<21
  3033  
  3034  	case APTESYNC:
  3035  		return OPVCC(31, 598, 0, 0) | 2<<21
  3036  
  3037  	case ATLBIE:
  3038  		return OPVCC(31, 306, 0, 0)
  3039  	case ATLBIEL:
  3040  		return OPVCC(31, 274, 0, 0)
  3041  	case ATLBSYNC:
  3042  		return OPVCC(31, 566, 0, 0)
  3043  	case ASLBIA:
  3044  		return OPVCC(31, 498, 0, 0)
  3045  	case ASLBIE:
  3046  		return OPVCC(31, 434, 0, 0)
  3047  	case ASLBMFEE:
  3048  		return OPVCC(31, 915, 0, 0)
  3049  	case ASLBMFEV:
  3050  		return OPVCC(31, 851, 0, 0)
  3051  	case ASLBMTE:
  3052  		return OPVCC(31, 402, 0, 0)
  3053  
  3054  	case ATW:
  3055  		return OPVCC(31, 4, 0, 0)
  3056  	case ATD:
  3057  		return OPVCC(31, 68, 0, 0)
  3058  
  3059  	case AXOR:
  3060  		return OPVCC(31, 316, 0, 0)
  3061  	case AXORCC:
  3062  		return OPVCC(31, 316, 0, 1)
  3063  	}
  3064  
  3065  	ctxt.Diag("bad r/r opcode %v", a)
  3066  	return 0
  3067  }
  3068  
  3069  func opirr(ctxt *obj.Link, a obj.As) uint32 {
  3070  	switch a {
  3071  	case AADD:
  3072  		return OPVCC(14, 0, 0, 0)
  3073  	case AADDC:
  3074  		return OPVCC(12, 0, 0, 0)
  3075  	case AADDCCC:
  3076  		return OPVCC(13, 0, 0, 0)
  3077  	case -AADD:
  3078  		return OPVCC(15, 0, 0, 0) /* ADDIS/CAU */
  3079  
  3080  	case AANDCC:
  3081  		return OPVCC(28, 0, 0, 0)
  3082  	case -AANDCC:
  3083  		return OPVCC(29, 0, 0, 0) /* ANDIS./ANDIU. */
  3084  
  3085  	case ABR:
  3086  		return OPVCC(18, 0, 0, 0)
  3087  	case ABL:
  3088  		return OPVCC(18, 0, 0, 0) | 1
  3089  	case obj.ADUFFZERO:
  3090  		return OPVCC(18, 0, 0, 0) | 1
  3091  	case obj.ADUFFCOPY:
  3092  		return OPVCC(18, 0, 0, 0) | 1
  3093  	case ABC:
  3094  		return OPVCC(16, 0, 0, 0)
  3095  	case ABCL:
  3096  		return OPVCC(16, 0, 0, 0) | 1
  3097  
  3098  	case ABEQ:
  3099  		return AOP_RRR(16<<26, 12, 2, 0)
  3100  	case ABGE:
  3101  		return AOP_RRR(16<<26, 4, 0, 0)
  3102  	case ABGT:
  3103  		return AOP_RRR(16<<26, 12, 1, 0)
  3104  	case ABLE:
  3105  		return AOP_RRR(16<<26, 4, 1, 0)
  3106  	case ABLT:
  3107  		return AOP_RRR(16<<26, 12, 0, 0)
  3108  	case ABNE:
  3109  		return AOP_RRR(16<<26, 4, 2, 0)
  3110  	case ABVC:
  3111  		return AOP_RRR(16<<26, 4, 3, 0) // apparently unordered-clear
  3112  	case ABVS:
  3113  		return AOP_RRR(16<<26, 12, 3, 0) // apparently unordered-set
  3114  
  3115  	case ACMP:
  3116  		return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */
  3117  	case ACMPU:
  3118  		return OPVCC(10, 0, 0, 0) | 1<<21
  3119  	case ACMPW:
  3120  		return OPVCC(11, 0, 0, 0) /* L=0 */
  3121  	case ACMPWU:
  3122  		return OPVCC(10, 0, 0, 0)
  3123  	case ALSW:
  3124  		return OPVCC(31, 597, 0, 0)
  3125  
  3126  	case AMULLW:
  3127  		return OPVCC(7, 0, 0, 0)
  3128  
  3129  	case AOR:
  3130  		return OPVCC(24, 0, 0, 0)
  3131  	case -AOR:
  3132  		return OPVCC(25, 0, 0, 0) /* ORIS/ORIU */
  3133  
  3134  	case ARLWMI:
  3135  		return OPVCC(20, 0, 0, 0) /* rlwimi */
  3136  	case ARLWMICC:
  3137  		return OPVCC(20, 0, 0, 1)
  3138  	case ARLDMI:
  3139  		return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
  3140  	case ARLDMICC:
  3141  		return OPVCC(30, 0, 0, 1) | 3<<2
  3142  
  3143  	case ARLWNM:
  3144  		return OPVCC(21, 0, 0, 0) /* rlwinm */
  3145  	case ARLWNMCC:
  3146  		return OPVCC(21, 0, 0, 1)
  3147  
  3148  	case ARLDCL:
  3149  		return OPVCC(30, 0, 0, 0) /* rldicl */
  3150  	case ARLDCLCC:
  3151  		return OPVCC(30, 0, 0, 1)
  3152  	case ARLDCR:
  3153  		return OPVCC(30, 1, 0, 0) /* rldicr */
  3154  	case ARLDCRCC:
  3155  		return OPVCC(30, 1, 0, 1)
  3156  	case ARLDC:
  3157  		return OPVCC(30, 0, 0, 0) | 2<<2
  3158  	case ARLDCCC:
  3159  		return OPVCC(30, 0, 0, 1) | 2<<2
  3160  
  3161  	case ASRAW:
  3162  		return OPVCC(31, 824, 0, 0)
  3163  	case ASRAWCC:
  3164  		return OPVCC(31, 824, 0, 1)
  3165  	case ASRAD:
  3166  		return OPVCC(31, (413 << 1), 0, 0)
  3167  	case ASRADCC:
  3168  		return OPVCC(31, (413 << 1), 0, 1)
  3169  
  3170  	case ASTSW:
  3171  		return OPVCC(31, 725, 0, 0)
  3172  
  3173  	case ASUBC:
  3174  		return OPVCC(8, 0, 0, 0)
  3175  
  3176  	case ATW:
  3177  		return OPVCC(3, 0, 0, 0)
  3178  	case ATD:
  3179  		return OPVCC(2, 0, 0, 0)
  3180  
  3181  	case AXOR:
  3182  		return OPVCC(26, 0, 0, 0) /* XORIL */
  3183  	case -AXOR:
  3184  		return OPVCC(27, 0, 0, 0) /* XORIU */
  3185  	}
  3186  
  3187  	ctxt.Diag("bad opcode i/r %v", a)
  3188  	return 0
  3189  }
  3190  
  3191  /*
  3192   * load o(a),d
  3193   */
  3194  func opload(ctxt *obj.Link, a obj.As) uint32 {
  3195  	switch a {
  3196  	case AMOVD:
  3197  		return OPVCC(58, 0, 0, 0) /* ld */
  3198  	case AMOVDU:
  3199  		return OPVCC(58, 0, 0, 1) /* ldu */
  3200  	case AMOVWZ:
  3201  		return OPVCC(32, 0, 0, 0) /* lwz */
  3202  	case AMOVWZU:
  3203  		return OPVCC(33, 0, 0, 0) /* lwzu */
  3204  	case AMOVW:
  3205  		return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */
  3206  
  3207  		/* no AMOVWU */
  3208  	case AMOVB, AMOVBZ:
  3209  		return OPVCC(34, 0, 0, 0)
  3210  		/* load */
  3211  
  3212  	case AMOVBU, AMOVBZU:
  3213  		return OPVCC(35, 0, 0, 0)
  3214  	case AFMOVD:
  3215  		return OPVCC(50, 0, 0, 0)
  3216  	case AFMOVDU:
  3217  		return OPVCC(51, 0, 0, 0)
  3218  	case AFMOVS:
  3219  		return OPVCC(48, 0, 0, 0)
  3220  	case AFMOVSU:
  3221  		return OPVCC(49, 0, 0, 0)
  3222  	case AMOVH:
  3223  		return OPVCC(42, 0, 0, 0)
  3224  	case AMOVHU:
  3225  		return OPVCC(43, 0, 0, 0)
  3226  	case AMOVHZ:
  3227  		return OPVCC(40, 0, 0, 0)
  3228  	case AMOVHZU:
  3229  		return OPVCC(41, 0, 0, 0)
  3230  	case AMOVMW:
  3231  		return OPVCC(46, 0, 0, 0) /* lmw */
  3232  	}
  3233  
  3234  	ctxt.Diag("bad load opcode %v", a)
  3235  	return 0
  3236  }
  3237  
  3238  /*
  3239   * indexed load a(b),d
  3240   */
  3241  func oploadx(ctxt *obj.Link, a obj.As) uint32 {
  3242  	switch a {
  3243  	case AMOVWZ:
  3244  		return OPVCC(31, 23, 0, 0) /* lwzx */
  3245  	case AMOVWZU:
  3246  		return OPVCC(31, 55, 0, 0) /* lwzux */
  3247  	case AMOVW:
  3248  		return OPVCC(31, 341, 0, 0) /* lwax */
  3249  	case AMOVWU:
  3250  		return OPVCC(31, 373, 0, 0) /* lwaux */
  3251  
  3252  	case AMOVB, AMOVBZ:
  3253  		return OPVCC(31, 87, 0, 0) /* lbzx */
  3254  
  3255  	case AMOVBU, AMOVBZU:
  3256  		return OPVCC(31, 119, 0, 0) /* lbzux */
  3257  	case AFMOVD:
  3258  		return OPVCC(31, 599, 0, 0) /* lfdx */
  3259  	case AFMOVDU:
  3260  		return OPVCC(31, 631, 0, 0) /*  lfdux */
  3261  	case AFMOVS:
  3262  		return OPVCC(31, 535, 0, 0) /* lfsx */
  3263  	case AFMOVSU:
  3264  		return OPVCC(31, 567, 0, 0) /* lfsux */
  3265  	case AFMOVSX:
  3266  		return OPVCC(31, 855, 0, 0) /* lfiwax - power6, isa 2.05 */
  3267  	case AFMOVSZ:
  3268  		return OPVCC(31, 887, 0, 0) /* lfiwzx - power7, isa 2.06 */
  3269  	case AMOVH:
  3270  		return OPVCC(31, 343, 0, 0) /* lhax */
  3271  	case AMOVHU:
  3272  		return OPVCC(31, 375, 0, 0) /* lhaux */
  3273  	case AMOVHBR:
  3274  		return OPVCC(31, 790, 0, 0) /* lhbrx */
  3275  	case AMOVWBR:
  3276  		return OPVCC(31, 534, 0, 0) /* lwbrx */
  3277  	case AMOVHZ:
  3278  		return OPVCC(31, 279, 0, 0) /* lhzx */
  3279  	case AMOVHZU:
  3280  		return OPVCC(31, 311, 0, 0) /* lhzux */
  3281  	case AECIWX:
  3282  		return OPVCC(31, 310, 0, 0) /* eciwx */
  3283  	case ALBAR:
  3284  		return OPVCC(31, 52, 0, 0) /* lbarx */
  3285  	case ALWAR:
  3286  		return OPVCC(31, 20, 0, 0) /* lwarx */
  3287  	case ALDAR:
  3288  		return OPVCC(31, 84, 0, 0)
  3289  	case ALSW:
  3290  		return OPVCC(31, 533, 0, 0) /* lswx */
  3291  	case AMOVD:
  3292  		return OPVCC(31, 21, 0, 0) /* ldx */
  3293  	case AMOVDU:
  3294  		return OPVCC(31, 53, 0, 0) /* ldux */
  3295  	}
  3296  
  3297  	ctxt.Diag("bad loadx opcode %v", a)
  3298  	return 0
  3299  }
  3300  
  3301  /*
  3302   * store s,o(d)
  3303   */
  3304  func opstore(ctxt *obj.Link, a obj.As) uint32 {
  3305  	switch a {
  3306  	case AMOVB, AMOVBZ:
  3307  		return OPVCC(38, 0, 0, 0) /* stb */
  3308  
  3309  	case AMOVBU, AMOVBZU:
  3310  		return OPVCC(39, 0, 0, 0) /* stbu */
  3311  	case AFMOVD:
  3312  		return OPVCC(54, 0, 0, 0) /* stfd */
  3313  	case AFMOVDU:
  3314  		return OPVCC(55, 0, 0, 0) /* stfdu */
  3315  	case AFMOVS:
  3316  		return OPVCC(52, 0, 0, 0) /* stfs */
  3317  	case AFMOVSU:
  3318  		return OPVCC(53, 0, 0, 0) /* stfsu */
  3319  
  3320  	case AMOVHZ, AMOVH:
  3321  		return OPVCC(44, 0, 0, 0) /* sth */
  3322  
  3323  	case AMOVHZU, AMOVHU:
  3324  		return OPVCC(45, 0, 0, 0) /* sthu */
  3325  	case AMOVMW:
  3326  		return OPVCC(47, 0, 0, 0) /* stmw */
  3327  	case ASTSW:
  3328  		return OPVCC(31, 725, 0, 0) /* stswi */
  3329  
  3330  	case AMOVWZ, AMOVW:
  3331  		return OPVCC(36, 0, 0, 0) /* stw */
  3332  
  3333  	case AMOVWZU, AMOVWU:
  3334  		return OPVCC(37, 0, 0, 0) /* stwu */
  3335  	case AMOVD:
  3336  		return OPVCC(62, 0, 0, 0) /* std */
  3337  	case AMOVDU:
  3338  		return OPVCC(62, 0, 0, 1) /* stdu */
  3339  	}
  3340  
  3341  	ctxt.Diag("unknown store opcode %v", a)
  3342  	return 0
  3343  }
  3344  
  3345  /*
  3346   * indexed store s,a(b)
  3347   */
  3348  func opstorex(ctxt *obj.Link, a obj.As) uint32 {
  3349  	switch a {
  3350  	case AMOVB, AMOVBZ:
  3351  		return OPVCC(31, 215, 0, 0) /* stbx */
  3352  
  3353  	case AMOVBU, AMOVBZU:
  3354  		return OPVCC(31, 247, 0, 0) /* stbux */
  3355  	case AFMOVD:
  3356  		return OPVCC(31, 727, 0, 0) /* stfdx */
  3357  	case AFMOVDU:
  3358  		return OPVCC(31, 759, 0, 0) /* stfdux */
  3359  	case AFMOVS:
  3360  		return OPVCC(31, 663, 0, 0) /* stfsx */
  3361  	case AFMOVSU:
  3362  		return OPVCC(31, 695, 0, 0) /* stfsux */
  3363  	case AFMOVSX:
  3364  		return OPVCC(31, 983, 0, 0) /* stfiwx */
  3365  
  3366  	case AMOVHZ, AMOVH:
  3367  		return OPVCC(31, 407, 0, 0) /* sthx */
  3368  	case AMOVHBR:
  3369  		return OPVCC(31, 918, 0, 0) /* sthbrx */
  3370  
  3371  	case AMOVHZU, AMOVHU:
  3372  		return OPVCC(31, 439, 0, 0) /* sthux */
  3373  
  3374  	case AMOVWZ, AMOVW:
  3375  		return OPVCC(31, 151, 0, 0) /* stwx */
  3376  
  3377  	case AMOVWZU, AMOVWU:
  3378  		return OPVCC(31, 183, 0, 0) /* stwux */
  3379  	case ASTSW:
  3380  		return OPVCC(31, 661, 0, 0) /* stswx */
  3381  	case AMOVWBR:
  3382  		return OPVCC(31, 662, 0, 0) /* stwbrx */
  3383  	case ASTBCCC:
  3384  		return OPVCC(31, 694, 0, 1) /* stbcx. */
  3385  	case ASTWCCC:
  3386  		return OPVCC(31, 150, 0, 1) /* stwcx. */
  3387  	case ASTDCCC:
  3388  		return OPVCC(31, 214, 0, 1) /* stwdx. */
  3389  	case AECOWX:
  3390  		return OPVCC(31, 438, 0, 0) /* ecowx */
  3391  	case AMOVD:
  3392  		return OPVCC(31, 149, 0, 0) /* stdx */
  3393  	case AMOVDU:
  3394  		return OPVCC(31, 181, 0, 0) /* stdux */
  3395  	}
  3396  
  3397  	ctxt.Diag("unknown storex opcode %v", a)
  3398  	return 0
  3399  }