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