Home | History | Annotate | Download | only in ppc64
      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 (a] 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 (a] 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 }
   3248