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