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

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