github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/src/cmd/internal/obj/ppc64/asm9.go (about)

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