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