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