github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/src/cmd/internal/obj/ppc64/asm9.go (about)

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