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