github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/cmd/internal/obj/ppc64/asm9.go (about)

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