podman
5367 строк · 147.5 Кб
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
30package ppc6431
32import (33"github.com/twitchyliquid64/golang-asm/obj"34"github.com/twitchyliquid64/golang-asm/objabi"35"encoding/binary"36"fmt"37"log"38"math"39"sort"40)
41
42// ctxt9 holds state while assembling a single function.
43// Each function gets a fresh ctxt9.
44// This allows for multiple functions to be safely concurrently assembled.
45type ctxt9 struct {46ctxt *obj.Link47newprog obj.ProgAlloc48cursym *obj.LSym49autosize int3250instoffset int6451pc int6452}
53
54// Instruction layout.
55
56const (57funcAlign = 1658funcAlignMask = funcAlign - 159)
60
61const (62r0iszero = 163)
64
65type Optab struct {66as obj.As // Opcode67a1 uint868a2 uint869a3 uint870a4 uint871type_ int8 // cases in asmout below. E.g., 44 = st r,(ra+rb); 45 = ld (ra+rb), r72size int873param int1674}
75
76// This optab contains a list of opcodes with the operand
77// combinations that are implemented. Not all opcodes are in this
78// table, but are added later in buildop by calling opset for those
79// opcodes which allow the same operand combinations as an opcode
80// already in the table.
81//
82// The type field in the Optabl identifies the case in asmout where
83// the instruction word is assembled.
84var optab = []Optab{85{obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},86{obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},87{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},88{obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},89/* move register */90{AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0},91{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},92{AMOVBZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},93{AMOVW, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},94{AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},95{AADD, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},96{AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},97{AADD, C_SCON, C_REG, C_NONE, C_REG, 4, 4, 0},98{AADD, C_SCON, C_NONE, C_NONE, C_REG, 4, 4, 0},99{AADD, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},100{AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},101{AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0},102{AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0},103{AADD, C_ANDCON, C_REG, C_NONE, C_REG, 22, 8, 0},104{AADD, C_ANDCON, C_NONE, C_NONE, C_REG, 22, 8, 0},105{AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},106{AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},107{AADDIS, C_ADDCON, C_REG, C_NONE, C_REG, 20, 4, 0},108{AADDIS, C_ADDCON, C_NONE, C_NONE, C_REG, 20, 4, 0},109{AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},110{AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},111{AADDC, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},112{AADDC, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},113{AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},114{AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},115{AAND, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, no literal */116{AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},117{AANDCC, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},118{AANDCC, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},119{AANDCC, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},120{AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},121{AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},122{AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},123{AANDCC, C_ADDCON, C_NONE, C_NONE, C_REG, 23, 8, 0},124{AANDCC, C_ADDCON, C_REG, C_NONE, C_REG, 23, 8, 0},125{AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},126{AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},127{AANDISCC, C_ANDCON, C_NONE, C_NONE, C_REG, 59, 4, 0},128{AANDISCC, C_ANDCON, C_REG, C_NONE, C_REG, 59, 4, 0},129{AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},130{AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},131{AMULLW, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},132{AMULLW, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},133{AMULLW, C_ANDCON, C_REG, C_NONE, C_REG, 4, 4, 0},134{AMULLW, C_ANDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},135{AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},136{AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},137{ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0},138{ASUBC, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},139{ASUBC, C_REG, C_NONE, C_ADDCON, C_REG, 27, 4, 0},140{ASUBC, C_REG, C_NONE, C_LCON, C_REG, 28, 12, 0},141{AOR, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, literal not cc (or/xor) */142{AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},143{AOR, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},144{AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},145{AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},146{AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},147{AOR, C_ADDCON, C_NONE, C_NONE, C_REG, 23, 8, 0},148{AOR, C_ADDCON, C_REG, C_NONE, C_REG, 23, 8, 0},149{AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},150{AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},151{AORIS, C_ANDCON, C_NONE, C_NONE, C_REG, 59, 4, 0},152{AORIS, C_ANDCON, C_REG, C_NONE, C_REG, 59, 4, 0},153{ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */154{ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},155{ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, /* op r2[,r1],r3 */156{ASUB, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},157{ASLW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},158{ASLW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},159{ASLD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},160{ASLD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},161{ASLD, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0},162{ASLD, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0},163{ASLW, C_SCON, C_REG, C_NONE, C_REG, 57, 4, 0},164{ASLW, C_SCON, C_NONE, C_NONE, C_REG, 57, 4, 0},165{ASRAW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},166{ASRAW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},167{ASRAW, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},168{ASRAW, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},169{ASRAD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},170{ASRAD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},171{ASRAD, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},172{ASRAD, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},173{ARLWMI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0},174{ARLWMI, C_REG, C_REG, C_LCON, C_REG, 63, 4, 0},175{ARLDMI, C_SCON, C_REG, C_LCON, C_REG, 30, 4, 0},176{ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},177{ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},178{ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},179{ARLDICL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},180{ARLDICL, C_SCON, C_REG, C_LCON, C_REG, 14, 4, 0},181{ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 4, 0},182{AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 4, 0},183{AFADD, C_FREG, C_FREG, C_NONE, C_FREG, 2, 4, 0},184{AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},185{AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 4, 0},186{AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},187{AFMADD, C_FREG, C_FREG, C_FREG, C_FREG, 34, 4, 0},188{AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 4, 0},189{AFMUL, C_FREG, C_FREG, C_NONE, C_FREG, 32, 4, 0},190
191/* store, short offset */192{AMOVD, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},193{AMOVW, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},194{AMOVWZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},195{AMOVBZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},196{AMOVBZU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},197{AMOVB, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},198{AMOVBU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},199{AMOVD, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},200{AMOVW, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},201{AMOVWZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},202{AMOVBZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},203{AMOVB, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},204{AMOVD, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},205{AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},206{AMOVWZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},207{AMOVBZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},208{AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},209{AMOVD, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},210{AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},211{AMOVWZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},212{AMOVBZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},213{AMOVBZU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},214{AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},215{AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},216
217/* load, short offset */218{AMOVD, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},219{AMOVW, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},220{AMOVWZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},221{AMOVBZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},222{AMOVBZU, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},223{AMOVB, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},224{AMOVBU, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},225{AMOVD, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},226{AMOVW, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},227{AMOVWZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},228{AMOVBZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},229{AMOVB, C_SEXT, C_NONE, C_NONE, C_REG, 9, 8, REGSB},230{AMOVD, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},231{AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},232{AMOVWZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},233{AMOVBZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},234{AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, 9, 8, REGSP},235{AMOVD, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},236{AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},237{AMOVWZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},238{AMOVBZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},239{AMOVBZU, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},240{AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},241{AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},242
243/* store, long offset */244{AMOVD, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},245{AMOVW, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},246{AMOVWZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},247{AMOVBZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},248{AMOVB, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},249{AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},250{AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},251{AMOVWZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},252{AMOVBZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},253{AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},254{AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},255{AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},256{AMOVWZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},257{AMOVBZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},258{AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},259{AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},260{AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},261{AMOVWZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},262{AMOVBZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},263{AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},264
265/* load, long offset */266{AMOVD, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},267{AMOVW, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},268{AMOVWZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},269{AMOVBZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},270{AMOVB, C_LEXT, C_NONE, C_NONE, C_REG, 37, 12, REGSB},271{AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},272{AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},273{AMOVWZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},274{AMOVBZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},275{AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 37, 12, REGSP},276{AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},277{AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},278{AMOVWZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},279{AMOVBZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},280{AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 37, 12, REGZERO},281{AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},282{AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},283{AMOVWZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},284{AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},285{AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 12, 0},286
287{AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 79, 4, 0},288{AMOVD, C_TLS_IE, C_NONE, C_NONE, C_REG, 80, 8, 0},289
290{AMOVD, C_GOTADDR, C_NONE, C_NONE, C_REG, 81, 8, 0},291{AMOVD, C_TOCADDR, C_NONE, C_NONE, C_REG, 95, 8, 0},292
293/* load constant */294{AMOVD, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB},295{AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},296{AMOVD, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},297{AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},298{AMOVD, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},299{AMOVD, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},300{AMOVW, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */301{AMOVW, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},302{AMOVW, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},303{AMOVW, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},304{AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},305{AMOVW, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},306{AMOVWZ, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */307{AMOVWZ, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},308{AMOVWZ, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},309{AMOVWZ, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},310{AMOVWZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},311{AMOVWZ, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},312
313/* load unsigned/long constants (TO DO: check) */314{AMOVD, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},315{AMOVD, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},316{AMOVW, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},317{AMOVW, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},318{AMOVWZ, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},319{AMOVWZ, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},320{AMOVHBR, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},321{AMOVHBR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},322{AMOVHBR, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},323{AMOVHBR, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},324{ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0},325{ASYSCALL, C_REG, C_NONE, C_NONE, C_NONE, 77, 12, 0},326{ASYSCALL, C_SCON, C_NONE, C_NONE, C_NONE, 77, 12, 0},327{ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 16, 4, 0},328{ABEQ, C_CREG, C_NONE, C_NONE, C_SBRA, 16, 4, 0},329{ABR, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0},330{ABR, C_NONE, C_NONE, C_NONE, C_LBRAPIC, 11, 8, 0},331{ABC, C_SCON, C_REG, C_NONE, C_SBRA, 16, 4, 0},332{ABC, C_SCON, C_REG, C_NONE, C_LBRA, 17, 4, 0},333{ABR, C_NONE, C_NONE, C_NONE, C_LR, 18, 4, 0},334{ABR, C_NONE, C_NONE, C_NONE, C_CTR, 18, 4, 0},335{ABR, C_REG, C_NONE, C_NONE, C_CTR, 18, 4, 0},336{ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},337{ABC, C_NONE, C_REG, C_NONE, C_LR, 18, 4, 0},338{ABC, C_NONE, C_REG, C_NONE, C_CTR, 18, 4, 0},339{ABC, C_SCON, C_REG, C_NONE, C_LR, 18, 4, 0},340{ABC, C_SCON, C_REG, C_NONE, C_CTR, 18, 4, 0},341{ABC, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},342{AFMOVD, C_SEXT, C_NONE, C_NONE, C_FREG, 8, 4, REGSB},343{AFMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, 8, 4, REGSP},344{AFMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, 8, 4, REGZERO},345{AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB},346{AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP},347{AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO},348{AFMOVD, C_ZCON, C_NONE, C_NONE, C_FREG, 24, 4, 0},349{AFMOVD, C_ADDCON, C_NONE, C_NONE, C_FREG, 24, 8, 0},350{AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0},351{AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},352{AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},353{AFMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},354{AFMOVD, C_FREG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},355{AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},356{AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},357{AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},358{AFMOVSX, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0},359{AFMOVSX, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0},360{AFMOVSX, C_FREG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},361{AFMOVSX, C_FREG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},362{AFMOVSZ, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0},363{AFMOVSZ, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0},364{ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},365{AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 4, 0},366{ADWORD, C_LCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},367{ADWORD, C_DCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},368{AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},369{AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0},370{AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0},371{AISEL, C_LCON, C_REG, C_REG, C_REG, 84, 4, 0},372{AISEL, C_ZCON, C_REG, C_REG, C_REG, 84, 4, 0},373{ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},374{ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0},375{AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0},376{AREM, C_REG, C_REG, C_NONE, C_REG, 50, 12, 0},377{AREMU, C_REG, C_NONE, C_NONE, C_REG, 50, 16, 0},378{AREMU, C_REG, C_REG, C_NONE, C_REG, 50, 16, 0},379{AREMD, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},380{AREMD, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},381{AMTFSB0, C_SCON, C_NONE, C_NONE, C_NONE, 52, 4, 0},382{AMOVFL, C_FPSCR, C_NONE, C_NONE, C_FREG, 53, 4, 0},383{AMOVFL, C_FREG, C_NONE, C_NONE, C_FPSCR, 64, 4, 0},384{AMOVFL, C_FREG, C_NONE, C_LCON, C_FPSCR, 64, 4, 0},385{AMOVFL, C_LCON, C_NONE, C_NONE, C_FPSCR, 65, 4, 0},386{AMOVD, C_MSR, C_NONE, C_NONE, C_REG, 54, 4, 0}, /* mfmsr */387{AMOVD, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsrd */388{AMOVWZ, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsr */389
390/* Other ISA 2.05+ instructions */391{APOPCNTD, C_REG, C_NONE, C_NONE, C_REG, 93, 4, 0}, /* population count, x-form */392{ACMPB, C_REG, C_REG, C_NONE, C_REG, 92, 4, 0}, /* compare byte, x-form */393{ACMPEQB, C_REG, C_REG, C_NONE, C_CREG, 92, 4, 0}, /* compare equal byte, x-form, ISA 3.0 */394{ACMPEQB, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},395{AFTDIV, C_FREG, C_FREG, C_NONE, C_SCON, 92, 4, 0}, /* floating test for sw divide, x-form */396{AFTSQRT, C_FREG, C_NONE, C_NONE, C_SCON, 93, 4, 0}, /* floating test for sw square root, x-form */397{ACOPY, C_REG, C_NONE, C_NONE, C_REG, 92, 4, 0}, /* copy/paste facility, x-form */398{ADARN, C_SCON, C_NONE, C_NONE, C_REG, 92, 4, 0}, /* deliver random number, x-form */399{ALDMX, C_SOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, /* load doubleword monitored, x-form */400{AMADDHD, C_REG, C_REG, C_REG, C_REG, 83, 4, 0}, /* multiply-add high/low doubleword, va-form */401{AADDEX, C_REG, C_REG, C_SCON, C_REG, 94, 4, 0}, /* add extended using alternate carry, z23-form */402{ACRAND, C_CREG, C_NONE, C_NONE, C_CREG, 2, 4, 0}, /* logical ops for condition registers xl-form */403
404/* Vector instructions */405
406/* Vector load */407{ALV, C_SOREG, C_NONE, C_NONE, C_VREG, 45, 4, 0}, /* vector load, x-form */408
409/* Vector store */410{ASTV, C_VREG, C_NONE, C_NONE, C_SOREG, 44, 4, 0}, /* vector store, x-form */411
412/* Vector logical */413{AVAND, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector and, vx-form */414{AVOR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector or, vx-form */415
416/* Vector add */417{AVADDUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned modulo, vx-form */418{AVADDCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add & write carry unsigned, vx-form */419{AVADDUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned saturate, vx-form */420{AVADDSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add signed saturate, vx-form */421{AVADDE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector add extended, va-form */422
423/* Vector subtract */424{AVSUBUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned modulo, vx-form */425{AVSUBCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract & write carry unsigned, vx-form */426{AVSUBUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned saturate, vx-form */427{AVSUBSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract signed saturate, vx-form */428{AVSUBE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector subtract extended, va-form */429
430/* Vector multiply */431{AVMULESB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 9}, /* vector multiply, vx-form */432{AVPMSUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector polynomial multiply & sum, vx-form */433{AVMSUMUDM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector multiply-sum, va-form */434
435/* Vector rotate */436{AVR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector rotate, vx-form */437
438/* Vector shift */439{AVS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector shift, vx-form */440{AVSA, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector shift algebraic, vx-form */441{AVSOI, C_ANDCON, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector shift by octet immediate, va-form */442
443/* Vector count */444{AVCLZ, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector count leading zeros, vx-form */445{AVPOPCNT, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector population count, vx-form */446
447/* Vector compare */448{AVCMPEQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare equal, vc-form */449{AVCMPGT, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare greater than, vc-form */450{AVCMPNEZB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare not equal, vx-form */451
452/* Vector merge */453{AVMRGOW, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector merge odd word, vx-form */454
455/* Vector permute */456{AVPERM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector permute, va-form */457
458/* Vector bit permute */459{AVBPERMQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector bit permute, vx-form */460
461/* Vector select */462{AVSEL, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector select, va-form */463
464/* Vector splat */465{AVSPLTB, C_SCON, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector splat, vx-form */466{AVSPLTB, C_ADDCON, C_VREG, C_NONE, C_VREG, 82, 4, 0},467{AVSPLTISB, C_SCON, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector splat immediate, vx-form */468{AVSPLTISB, C_ADDCON, C_NONE, C_NONE, C_VREG, 82, 4, 0},469
470/* Vector AES */471{AVCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES cipher, vx-form */472{AVNCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES inverse cipher, vx-form */473{AVSBOX, C_VREG, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector AES subbytes, vx-form */474
475/* Vector SHA */476{AVSHASIGMA, C_ANDCON, C_VREG, C_ANDCON, C_VREG, 82, 4, 0}, /* vector SHA sigma, vx-form */477
478/* VSX vector load */479{ALXVD2X, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx vector load, xx1-form */480{ALXV, C_SOREG, C_NONE, C_NONE, C_VSREG, 96, 4, 0}, /* vsx vector load, dq-form */481{ALXVL, C_REG, C_REG, C_NONE, C_VSREG, 98, 4, 0}, /* vsx vector load length */482
483/* VSX vector store */484{ASTXVD2X, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx vector store, xx1-form */485{ASTXV, C_VSREG, C_NONE, C_NONE, C_SOREG, 97, 4, 0}, /* vsx vector store, dq-form */486{ASTXVL, C_VSREG, C_REG, C_NONE, C_REG, 99, 4, 0}, /* vsx vector store with length x-form */487
488/* VSX scalar load */489{ALXSDX, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar load, xx1-form */490
491/* VSX scalar store */492{ASTXSDX, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar store, xx1-form */493
494/* VSX scalar as integer load */495{ALXSIWAX, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar as integer load, xx1-form */496
497/* VSX scalar store as integer */498{ASTXSIWX, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar as integer store, xx1-form */499
500/* VSX move from VSR */501{AMFVSRD, C_VSREG, C_NONE, C_NONE, C_REG, 88, 4, 0}, /* vsx move from vsr, xx1-form */502{AMFVSRD, C_FREG, C_NONE, C_NONE, C_REG, 88, 4, 0},503{AMFVSRD, C_VREG, C_NONE, C_NONE, C_REG, 88, 4, 0},504
505/* VSX move to VSR */506{AMTVSRD, C_REG, C_NONE, C_NONE, C_VSREG, 88, 4, 0}, /* vsx move to vsr, xx1-form */507{AMTVSRD, C_REG, C_REG, C_NONE, C_VSREG, 88, 4, 0},508{AMTVSRD, C_REG, C_NONE, C_NONE, C_FREG, 88, 4, 0},509{AMTVSRD, C_REG, C_NONE, C_NONE, C_VREG, 88, 4, 0},510
511/* VSX logical */512{AXXLAND, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx and, xx3-form */513{AXXLOR, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx or, xx3-form */514
515/* VSX select */516{AXXSEL, C_VSREG, C_VSREG, C_VSREG, C_VSREG, 91, 4, 0}, /* vsx select, xx4-form */517
518/* VSX merge */519{AXXMRGHW, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx merge, xx3-form */520
521/* VSX splat */522{AXXSPLTW, C_VSREG, C_NONE, C_SCON, C_VSREG, 89, 4, 0}, /* vsx splat, xx2-form */523{AXXSPLTIB, C_SCON, C_NONE, C_NONE, C_VSREG, 100, 4, 0}, /* vsx splat, xx2-form */524
525/* VSX permute */526{AXXPERM, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx permute, xx3-form */527
528/* VSX shift */529{AXXSLDWI, C_VSREG, C_VSREG, C_SCON, C_VSREG, 90, 4, 0}, /* vsx shift immediate, xx3-form */530
531/* VSX reverse bytes */532{AXXBRQ, C_VSREG, C_NONE, C_NONE, C_VSREG, 101, 4, 0}, /* vsx reverse bytes */533
534/* VSX scalar FP-FP conversion */535{AXSCVDPSP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-fp conversion, xx2-form */536
537/* VSX vector FP-FP conversion */538{AXVCVDPSP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-fp conversion, xx2-form */539
540/* VSX scalar FP-integer conversion */541{AXSCVDPSXDS, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-integer conversion, xx2-form */542
543/* VSX scalar integer-FP conversion */544{AXSCVSXDDP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar integer-fp conversion, xx2-form */545
546/* VSX vector FP-integer conversion */547{AXVCVDPSXDS, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-integer conversion, xx2-form */548
549/* VSX vector integer-FP conversion */550{AXVCVSXDDP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector integer-fp conversion, xx2-form */551
552/* 64-bit special registers */553{AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},554{AMOVD, C_REG, C_NONE, C_NONE, C_LR, 66, 4, 0},555{AMOVD, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},556{AMOVD, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},557{AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},558{AMOVD, C_LR, C_NONE, C_NONE, C_REG, 66, 4, 0},559{AMOVD, C_CTR, C_NONE, C_NONE, C_REG, 66, 4, 0},560{AMOVD, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},561
562/* 32-bit special registers (gloss over sign-extension or not?) */563{AMOVW, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},564{AMOVW, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},565{AMOVW, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},566{AMOVW, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},567{AMOVW, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},568{AMOVWZ, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},569{AMOVWZ, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},570{AMOVWZ, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},571{AMOVWZ, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},572{AMOVWZ, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},573{AMOVFL, C_FPSCR, C_NONE, C_NONE, C_CREG, 73, 4, 0},574{AMOVFL, C_CREG, C_NONE, C_NONE, C_CREG, 67, 4, 0},575{AMOVW, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},576{AMOVWZ, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},577{AMOVFL, C_REG, C_NONE, C_NONE, C_LCON, 69, 4, 0},578{AMOVFL, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},579{AMOVW, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},580{AMOVWZ, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},581{ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},582{ACMP, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},583{ACMP, C_REG, C_NONE, C_NONE, C_ADDCON, 71, 4, 0},584{ACMP, C_REG, C_REG, C_NONE, C_ADDCON, 71, 4, 0},585{ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},586{ACMPU, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},587{ACMPU, C_REG, C_NONE, C_NONE, C_ANDCON, 71, 4, 0},588{ACMPU, C_REG, C_REG, C_NONE, C_ANDCON, 71, 4, 0},589{AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 4, 0},590{AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 4, 0},591{ATW, C_LCON, C_REG, C_NONE, C_REG, 60, 4, 0},592{ATW, C_LCON, C_REG, C_NONE, C_ADDCON, 61, 4, 0},593{ADCBF, C_ZOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},594{ADCBF, C_SOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},595{ADCBF, C_ZOREG, C_REG, C_NONE, C_SCON, 43, 4, 0},596{ADCBF, C_SOREG, C_NONE, C_NONE, C_SCON, 43, 4, 0},597{AECOWX, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},598{AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},599{AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},600{AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},601{ALDAR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},602{ALDAR, C_ZOREG, C_NONE, C_ANDCON, C_REG, 45, 4, 0},603{AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},604{ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},605{ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0},606{ASLBMFEE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},607{ASLBMTE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},608{ASTSW, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},609{ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},610{ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},611{ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},612{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},613{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},614{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},615{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},616{obj.ANOP, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0}, // NOP operand variations added for #40689617{obj.ANOP, C_REG, C_NONE, C_NONE, C_NONE, 0, 0, 0}, // to preserve previous behavior618{obj.ANOP, C_FREG, C_NONE, C_NONE, C_NONE, 0, 0, 0},619{obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL620{obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL621{obj.APCALIGN, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0}, // align code622
623{obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},624}
625
626var oprange [ALAST & obj.AMask][]Optab627
628var xcmp [C_NCLASS][C_NCLASS]bool629
630// padding bytes to add to align code as requested
631func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int {632// For 16 and 32 byte alignment, there is a tradeoff633// between aligning the code and adding too many NOPs.634switch a {635case 8:636if pc&7 != 0 {637return 4638}639case 16:640// Align to 16 bytes if possible but add at641// most 2 NOPs.642switch pc & 15 {643case 4, 12:644return 4645case 8:646return 8647}648case 32:649// Align to 32 bytes if possible but add at650// most 3 NOPs.651switch pc & 31 {652case 4, 20:653return 12654case 8, 24:655return 8656case 12, 28:657return 4658}659// When 32 byte alignment is requested on Linux,660// promote the function's alignment to 32. On AIX661// the function alignment is not changed which might662// result in 16 byte alignment but that is still fine.663// TODO: alignment on AIX664if ctxt.Headtype != objabi.Haix && cursym.Func.Align < 32 {665cursym.Func.Align = 32666}667default:668ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a)669}670return 0671}
672
673func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {674p := cursym.Func.Text675if p == nil || p.Link == nil { // handle external functions and ELF section symbols676return677}678
679if oprange[AANDN&obj.AMask] == nil {680ctxt.Diag("ppc64 ops not initialized, call ppc64.buildop first")681}682
683c := ctxt9{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset)}684
685pc := int64(0)686p.Pc = pc687
688var m int689var o *Optab690for p = p.Link; p != nil; p = p.Link {691p.Pc = pc692o = c.oplook(p)693m = int(o.size)694if m == 0 {695if p.As == obj.APCALIGN {696a := c.vregoff(&p.From)697m = addpad(pc, a, ctxt, cursym)698} else {699if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {700ctxt.Diag("zero-width instruction\n%v", p)701}702continue703}704}705pc += int64(m)706}707
708c.cursym.Size = pc709
710/*711* if any procedure is large enough to
712* generate a large SBRA branch, then
713* generate extra passes putting branches
714* around jmps to fix. this is rare.
715*/
716bflag := 1717
718var otxt int64719var q *obj.Prog720for bflag != 0 {721bflag = 0722pc = 0723for p = c.cursym.Func.Text.Link; p != nil; p = p.Link {724p.Pc = pc725o = c.oplook(p)726
727// very large conditional branches728if (o.type_ == 16 || o.type_ == 17) && p.To.Target() != nil {729otxt = p.To.Target().Pc - pc730if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {731q = c.newprog()732q.Link = p.Link733p.Link = q734q.As = ABR735q.To.Type = obj.TYPE_BRANCH736q.To.SetTarget(p.To.Target())737p.To.SetTarget(q)738q = c.newprog()739q.Link = p.Link740p.Link = q741q.As = ABR742q.To.Type = obj.TYPE_BRANCH743q.To.SetTarget(q.Link.Link)744
745//addnop(p->link);746//addnop(p);747bflag = 1748}749}750
751m = int(o.size)752if m == 0 {753if p.As == obj.APCALIGN {754a := c.vregoff(&p.From)755m = addpad(pc, a, ctxt, cursym)756} else {757if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {758ctxt.Diag("zero-width instruction\n%v", p)759}760continue761}762}763
764pc += int64(m)765}766
767c.cursym.Size = pc768}769
770if r := pc & funcAlignMask; r != 0 {771pc += funcAlign - r772}773
774c.cursym.Size = pc775
776/*777* lay out the code, emitting code and data relocations.
778*/
779
780c.cursym.Grow(c.cursym.Size)781
782bp := c.cursym.P783var i int32784var out [6]uint32785for p := c.cursym.Func.Text.Link; p != nil; p = p.Link {786c.pc = p.Pc787o = c.oplook(p)788if int(o.size) > 4*len(out) {789log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)790}791// asmout is not set up to add large amounts of padding792if o.type_ == 0 && p.As == obj.APCALIGN {793pad := LOP_RRR(OP_OR, REGZERO, REGZERO, REGZERO)794aln := c.vregoff(&p.From)795v := addpad(p.Pc, aln, c.ctxt, c.cursym)796if v > 0 {797// Same padding instruction for all798for i = 0; i < int32(v/4); i++ {799c.ctxt.Arch.ByteOrder.PutUint32(bp, pad)800bp = bp[4:]801}802}803} else {804c.asmout(p, o, out[:])805for i = 0; i < int32(o.size/4); i++ {806c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])807bp = bp[4:]808}809}810}811}
812
813func isint32(v int64) bool {814return int64(int32(v)) == v815}
816
817func isuint32(v uint64) bool {818return uint64(uint32(v)) == v819}
820
821func (c *ctxt9) aclass(a *obj.Addr) int {822switch a.Type {823case obj.TYPE_NONE:824return C_NONE825
826case obj.TYPE_REG:827if REG_R0 <= a.Reg && a.Reg <= REG_R31 {828return C_REG829}830if REG_F0 <= a.Reg && a.Reg <= REG_F31 {831return C_FREG832}833if REG_V0 <= a.Reg && a.Reg <= REG_V31 {834return C_VREG835}836if REG_VS0 <= a.Reg && a.Reg <= REG_VS63 {837return C_VSREG838}839if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR {840return C_CREG841}842if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {843switch a.Reg {844case REG_LR:845return C_LR846
847case REG_XER:848return C_XER849
850case REG_CTR:851return C_CTR852}853
854return C_SPR855}856
857if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {858return C_SPR859}860if a.Reg == REG_FPSCR {861return C_FPSCR862}863if a.Reg == REG_MSR {864return C_MSR865}866return C_GOK867
868case obj.TYPE_MEM:869switch a.Name {870case obj.NAME_EXTERN,871obj.NAME_STATIC:872if a.Sym == nil {873break874}875c.instoffset = a.Offset876if a.Sym != nil { // use relocation877if a.Sym.Type == objabi.STLSBSS {878if c.ctxt.Flag_shared {879return C_TLS_IE880} else {881return C_TLS_LE882}883}884return C_ADDR885}886return C_LEXT887
888case obj.NAME_GOTREF:889return C_GOTADDR890
891case obj.NAME_TOCREF:892return C_TOCADDR893
894case obj.NAME_AUTO:895c.instoffset = int64(c.autosize) + a.Offset896if c.instoffset >= -BIG && c.instoffset < BIG {897return C_SAUTO898}899return C_LAUTO900
901case obj.NAME_PARAM:902c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()903if c.instoffset >= -BIG && c.instoffset < BIG {904return C_SAUTO905}906return C_LAUTO907
908case obj.NAME_NONE:909c.instoffset = a.Offset910if c.instoffset == 0 {911return C_ZOREG912}913if c.instoffset >= -BIG && c.instoffset < BIG {914return C_SOREG915}916return C_LOREG917}918
919return C_GOK920
921case obj.TYPE_TEXTSIZE:922return C_TEXTSIZE923
924case obj.TYPE_FCONST:925// The only cases where FCONST will occur are with float64 +/- 0.926// All other float constants are generated in memory.927f64 := a.Val.(float64)928if f64 == 0 {929if math.Signbit(f64) {930return C_ADDCON931}932return C_ZCON933}934log.Fatalf("Unexpected nonzero FCONST operand %v", a)935
936case obj.TYPE_CONST,937obj.TYPE_ADDR:938switch a.Name {939case obj.NAME_NONE:940c.instoffset = a.Offset941if a.Reg != 0 {942if -BIG <= c.instoffset && c.instoffset <= BIG {943return C_SACON944}945if isint32(c.instoffset) {946return C_LACON947}948return C_DACON949}950
951case obj.NAME_EXTERN,952obj.NAME_STATIC:953s := a.Sym954if s == nil {955return C_GOK956}957
958c.instoffset = a.Offset959
960/* not sure why this barfs */961return C_LCON962
963case obj.NAME_AUTO:964c.instoffset = int64(c.autosize) + a.Offset965if c.instoffset >= -BIG && c.instoffset < BIG {966return C_SACON967}968return C_LACON969
970case obj.NAME_PARAM:971c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()972if c.instoffset >= -BIG && c.instoffset < BIG {973return C_SACON974}975return C_LACON976
977default:978return C_GOK979}980
981if c.instoffset >= 0 {982if c.instoffset == 0 {983return C_ZCON984}985if c.instoffset <= 0x7fff {986return C_SCON987}988if c.instoffset <= 0xffff {989return C_ANDCON990}991if c.instoffset&0xffff == 0 && isuint32(uint64(c.instoffset)) { /* && (instoffset & (1<<31)) == 0) */992return C_UCON993}994if isint32(c.instoffset) || isuint32(uint64(c.instoffset)) {995return C_LCON996}997return C_DCON998}999
1000if c.instoffset >= -0x8000 {1001return C_ADDCON1002}1003if c.instoffset&0xffff == 0 && isint32(c.instoffset) {1004return C_UCON1005}1006if isint32(c.instoffset) {1007return C_LCON1008}1009return C_DCON1010
1011case obj.TYPE_BRANCH:1012if a.Sym != nil && c.ctxt.Flag_dynlink {1013return C_LBRAPIC1014}1015return C_SBRA1016}1017
1018return C_GOK1019}
1020
1021func prasm(p *obj.Prog) {1022fmt.Printf("%v\n", p)1023}
1024
1025func (c *ctxt9) oplook(p *obj.Prog) *Optab {1026a1 := int(p.Optab)1027if a1 != 0 {1028return &optab[a1-1]1029}1030a1 = int(p.From.Class)1031if a1 == 0 {1032a1 = c.aclass(&p.From) + 11033p.From.Class = int8(a1)1034}1035
1036a1--1037a3 := C_NONE + 11038if p.GetFrom3() != nil {1039a3 = int(p.GetFrom3().Class)1040if a3 == 0 {1041a3 = c.aclass(p.GetFrom3()) + 11042p.GetFrom3().Class = int8(a3)1043}1044}1045
1046a3--1047a4 := int(p.To.Class)1048if a4 == 0 {1049a4 = c.aclass(&p.To) + 11050p.To.Class = int8(a4)1051}1052
1053a4--1054a2 := C_NONE1055if p.Reg != 0 {1056if REG_R0 <= p.Reg && p.Reg <= REG_R31 {1057a2 = C_REG1058} else if REG_V0 <= p.Reg && p.Reg <= REG_V31 {1059a2 = C_VREG1060} else if REG_VS0 <= p.Reg && p.Reg <= REG_VS63 {1061a2 = C_VSREG1062} else if REG_F0 <= p.Reg && p.Reg <= REG_F31 {1063a2 = C_FREG1064}1065}1066
1067// c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4)1068ops := oprange[p.As&obj.AMask]1069c1 := &xcmp[a1]1070c3 := &xcmp[a3]1071c4 := &xcmp[a4]1072for i := range ops {1073op := &ops[i]1074if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] {1075p.Optab = uint16(cap(optab) - cap(ops) + i + 1)1076return op1077}1078}1079
1080c.ctxt.Diag("illegal combination %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4))1081prasm(p)1082if ops == nil {1083ops = optab1084}1085return &ops[0]1086}
1087
1088func cmp(a int, b int) bool {1089if a == b {1090return true1091}1092switch a {1093case C_LCON:1094if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {1095return true1096}1097
1098case C_ADDCON:1099if b == C_ZCON || b == C_SCON {1100return true1101}1102
1103case C_ANDCON:1104if b == C_ZCON || b == C_SCON {1105return true1106}1107
1108case C_SPR:1109if b == C_LR || b == C_XER || b == C_CTR {1110return true1111}1112
1113case C_UCON:1114if b == C_ZCON {1115return true1116}1117
1118case C_SCON:1119if b == C_ZCON {1120return true1121}1122
1123case C_LACON:1124if b == C_SACON {1125return true1126}1127
1128case C_LBRA:1129if b == C_SBRA {1130return true1131}1132
1133case C_LEXT:1134if b == C_SEXT {1135return true1136}1137
1138case C_LAUTO:1139if b == C_SAUTO {1140return true1141}1142
1143case C_REG:1144if b == C_ZCON {1145return r0iszero != 0 /*TypeKind(100016)*/1146}1147
1148case C_LOREG:1149if b == C_ZOREG || b == C_SOREG {1150return true1151}1152
1153case C_SOREG:1154if b == C_ZOREG {1155return true1156}1157
1158case C_ANY:1159return true1160}1161
1162return false1163}
1164
1165type ocmp []Optab1166
1167func (x ocmp) Len() int {1168return len(x)1169}
1170
1171func (x ocmp) Swap(i, j int) {1172x[i], x[j] = x[j], x[i]1173}
1174
1175// Used when sorting the optab. Sorting is
1176// done in a way so that the best choice of
1177// opcode/operand combination is considered first.
1178func (x ocmp) Less(i, j int) bool {1179p1 := &x[i]1180p2 := &x[j]1181n := int(p1.as) - int(p2.as)1182// same opcode1183if n != 0 {1184return n < 01185}1186// Consider those that generate fewer1187// instructions first.1188n = int(p1.size) - int(p2.size)1189if n != 0 {1190return n < 01191}1192// operand order should match1193// better choices first1194n = int(p1.a1) - int(p2.a1)1195if n != 0 {1196return n < 01197}1198n = int(p1.a2) - int(p2.a2)1199if n != 0 {1200return n < 01201}1202n = int(p1.a3) - int(p2.a3)1203if n != 0 {1204return n < 01205}1206n = int(p1.a4) - int(p2.a4)1207if n != 0 {1208return n < 01209}1210return false1211}
1212
1213// Add an entry to the opcode table for
1214// a new opcode b0 with the same operand combinations
1215// as opcode a.
1216func opset(a, b0 obj.As) {1217oprange[a&obj.AMask] = oprange[b0]1218}
1219
1220// Build the opcode table
1221func buildop(ctxt *obj.Link) {1222if oprange[AANDN&obj.AMask] != nil {1223// Already initialized; stop now.1224// This happens in the cmd/asm tests,1225// each of which re-initializes the arch.1226return1227}1228
1229var n int1230
1231for i := 0; i < C_NCLASS; i++ {1232for n = 0; n < C_NCLASS; n++ {1233if cmp(n, i) {1234xcmp[i][n] = true1235}1236}1237}1238for n = 0; optab[n].as != obj.AXXX; n++ {1239}1240sort.Sort(ocmp(optab[:n]))1241for i := 0; i < n; i++ {1242r := optab[i].as1243r0 := r & obj.AMask1244start := i1245for optab[i].as == r {1246i++1247}1248oprange[r0] = optab[start:i]1249i--1250
1251switch r {1252default:1253ctxt.Diag("unknown op in build: %v", r)1254log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r)1255
1256case ADCBF: /* unary indexed: op (b+a); op (b) */1257opset(ADCBI, r0)1258
1259opset(ADCBST, r0)1260opset(ADCBT, r0)1261opset(ADCBTST, r0)1262opset(ADCBZ, r0)1263opset(AICBI, r0)1264
1265case AECOWX: /* indexed store: op s,(b+a); op s,(b) */1266opset(ASTWCCC, r0)1267opset(ASTHCCC, r0)1268opset(ASTBCCC, r0)1269opset(ASTDCCC, r0)1270
1271case AREM: /* macro */1272opset(AREM, r0)1273
1274case AREMU:1275opset(AREMU, r0)1276
1277case AREMD:1278opset(AREMDU, r0)1279
1280case ADIVW: /* op Rb[,Ra],Rd */1281opset(AMULHW, r0)1282
1283opset(AMULHWCC, r0)1284opset(AMULHWU, r0)1285opset(AMULHWUCC, r0)1286opset(AMULLWCC, r0)1287opset(AMULLWVCC, r0)1288opset(AMULLWV, r0)1289opset(ADIVWCC, r0)1290opset(ADIVWV, r0)1291opset(ADIVWVCC, r0)1292opset(ADIVWU, r0)1293opset(ADIVWUCC, r0)1294opset(ADIVWUV, r0)1295opset(ADIVWUVCC, r0)1296opset(AMODUD, r0)1297opset(AMODUW, r0)1298opset(AMODSD, r0)1299opset(AMODSW, r0)1300opset(AADDCC, r0)1301opset(AADDCV, r0)1302opset(AADDCVCC, r0)1303opset(AADDV, r0)1304opset(AADDVCC, r0)1305opset(AADDE, r0)1306opset(AADDECC, r0)1307opset(AADDEV, r0)1308opset(AADDEVCC, r0)1309opset(AMULHD, r0)1310opset(AMULHDCC, r0)1311opset(AMULHDU, r0)1312opset(AMULHDUCC, r0)1313opset(AMULLD, r0)1314opset(AMULLDCC, r0)1315opset(AMULLDVCC, r0)1316opset(AMULLDV, r0)1317opset(ADIVD, r0)1318opset(ADIVDCC, r0)1319opset(ADIVDE, r0)1320opset(ADIVDEU, r0)1321opset(ADIVDECC, r0)1322opset(ADIVDEUCC, r0)1323opset(ADIVDVCC, r0)1324opset(ADIVDV, r0)1325opset(ADIVDU, r0)1326opset(ADIVDUV, r0)1327opset(ADIVDUVCC, r0)1328opset(ADIVDUCC, r0)1329
1330case ACRAND:1331opset(ACRANDN, r0)1332opset(ACREQV, r0)1333opset(ACRNAND, r0)1334opset(ACRNOR, r0)1335opset(ACROR, r0)1336opset(ACRORN, r0)1337opset(ACRXOR, r0)1338
1339case APOPCNTD: /* popcntd, popcntw, popcntb, cnttzw, cnttzd */1340opset(APOPCNTW, r0)1341opset(APOPCNTB, r0)1342opset(ACNTTZW, r0)1343opset(ACNTTZWCC, r0)1344opset(ACNTTZD, r0)1345opset(ACNTTZDCC, r0)1346
1347case ACOPY: /* copy, paste. */1348opset(APASTECC, r0)1349
1350case AMADDHD: /* maddhd, maddhdu, maddld */1351opset(AMADDHDU, r0)1352opset(AMADDLD, r0)1353
1354case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */1355opset(AMOVH, r0)1356opset(AMOVHZ, r0)1357
1358case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */1359opset(AMOVHU, r0)1360
1361opset(AMOVHZU, r0)1362opset(AMOVWU, r0)1363opset(AMOVWZU, r0)1364opset(AMOVDU, r0)1365opset(AMOVMW, r0)1366
1367case ALV: /* lvebx, lvehx, lvewx, lvx, lvxl, lvsl, lvsr */1368opset(ALVEBX, r0)1369opset(ALVEHX, r0)1370opset(ALVEWX, r0)1371opset(ALVX, r0)1372opset(ALVXL, r0)1373opset(ALVSL, r0)1374opset(ALVSR, r0)1375
1376case ASTV: /* stvebx, stvehx, stvewx, stvx, stvxl */1377opset(ASTVEBX, r0)1378opset(ASTVEHX, r0)1379opset(ASTVEWX, r0)1380opset(ASTVX, r0)1381opset(ASTVXL, r0)1382
1383case AVAND: /* vand, vandc, vnand */1384opset(AVAND, r0)1385opset(AVANDC, r0)1386opset(AVNAND, r0)1387
1388case AVMRGOW: /* vmrgew, vmrgow */1389opset(AVMRGEW, r0)1390
1391case AVOR: /* vor, vorc, vxor, vnor, veqv */1392opset(AVOR, r0)1393opset(AVORC, r0)1394opset(AVXOR, r0)1395opset(AVNOR, r0)1396opset(AVEQV, r0)1397
1398case AVADDUM: /* vaddubm, vadduhm, vadduwm, vaddudm, vadduqm */1399opset(AVADDUBM, r0)1400opset(AVADDUHM, r0)1401opset(AVADDUWM, r0)1402opset(AVADDUDM, r0)1403opset(AVADDUQM, r0)1404
1405case AVADDCU: /* vaddcuq, vaddcuw */1406opset(AVADDCUQ, r0)1407opset(AVADDCUW, r0)1408
1409case AVADDUS: /* vaddubs, vadduhs, vadduws */1410opset(AVADDUBS, r0)1411opset(AVADDUHS, r0)1412opset(AVADDUWS, r0)1413
1414case AVADDSS: /* vaddsbs, vaddshs, vaddsws */1415opset(AVADDSBS, r0)1416opset(AVADDSHS, r0)1417opset(AVADDSWS, r0)1418
1419case AVADDE: /* vaddeuqm, vaddecuq */1420opset(AVADDEUQM, r0)1421opset(AVADDECUQ, r0)1422
1423case AVSUBUM: /* vsububm, vsubuhm, vsubuwm, vsubudm, vsubuqm */1424opset(AVSUBUBM, r0)1425opset(AVSUBUHM, r0)1426opset(AVSUBUWM, r0)1427opset(AVSUBUDM, r0)1428opset(AVSUBUQM, r0)1429
1430case AVSUBCU: /* vsubcuq, vsubcuw */1431opset(AVSUBCUQ, r0)1432opset(AVSUBCUW, r0)1433
1434case AVSUBUS: /* vsububs, vsubuhs, vsubuws */1435opset(AVSUBUBS, r0)1436opset(AVSUBUHS, r0)1437opset(AVSUBUWS, r0)1438
1439case AVSUBSS: /* vsubsbs, vsubshs, vsubsws */1440opset(AVSUBSBS, r0)1441opset(AVSUBSHS, r0)1442opset(AVSUBSWS, r0)1443
1444case AVSUBE: /* vsubeuqm, vsubecuq */1445opset(AVSUBEUQM, r0)1446opset(AVSUBECUQ, r0)1447
1448case AVMULESB: /* vmulesb, vmulosb, vmuleub, vmuloub, vmulosh, vmulouh, vmulesw, vmulosw, vmuleuw, vmulouw, vmuluwm */1449opset(AVMULOSB, r0)1450opset(AVMULEUB, r0)1451opset(AVMULOUB, r0)1452opset(AVMULESH, r0)1453opset(AVMULOSH, r0)1454opset(AVMULEUH, r0)1455opset(AVMULOUH, r0)1456opset(AVMULESW, r0)1457opset(AVMULOSW, r0)1458opset(AVMULEUW, r0)1459opset(AVMULOUW, r0)1460opset(AVMULUWM, r0)1461case AVPMSUM: /* vpmsumb, vpmsumh, vpmsumw, vpmsumd */1462opset(AVPMSUMB, r0)1463opset(AVPMSUMH, r0)1464opset(AVPMSUMW, r0)1465opset(AVPMSUMD, r0)1466
1467case AVR: /* vrlb, vrlh, vrlw, vrld */1468opset(AVRLB, r0)1469opset(AVRLH, r0)1470opset(AVRLW, r0)1471opset(AVRLD, r0)1472
1473case AVS: /* vs[l,r], vs[l,r]o, vs[l,r]b, vs[l,r]h, vs[l,r]w, vs[l,r]d */1474opset(AVSLB, r0)1475opset(AVSLH, r0)1476opset(AVSLW, r0)1477opset(AVSL, r0)1478opset(AVSLO, r0)1479opset(AVSRB, r0)1480opset(AVSRH, r0)1481opset(AVSRW, r0)1482opset(AVSR, r0)1483opset(AVSRO, r0)1484opset(AVSLD, r0)1485opset(AVSRD, r0)1486
1487case AVSA: /* vsrab, vsrah, vsraw, vsrad */1488opset(AVSRAB, r0)1489opset(AVSRAH, r0)1490opset(AVSRAW, r0)1491opset(AVSRAD, r0)1492
1493case AVSOI: /* vsldoi */1494opset(AVSLDOI, r0)1495
1496case AVCLZ: /* vclzb, vclzh, vclzw, vclzd */1497opset(AVCLZB, r0)1498opset(AVCLZH, r0)1499opset(AVCLZW, r0)1500opset(AVCLZD, r0)1501
1502case AVPOPCNT: /* vpopcntb, vpopcnth, vpopcntw, vpopcntd */1503opset(AVPOPCNTB, r0)1504opset(AVPOPCNTH, r0)1505opset(AVPOPCNTW, r0)1506opset(AVPOPCNTD, r0)1507
1508case AVCMPEQ: /* vcmpequb[.], vcmpequh[.], vcmpequw[.], vcmpequd[.] */1509opset(AVCMPEQUB, r0)1510opset(AVCMPEQUBCC, r0)1511opset(AVCMPEQUH, r0)1512opset(AVCMPEQUHCC, r0)1513opset(AVCMPEQUW, r0)1514opset(AVCMPEQUWCC, r0)1515opset(AVCMPEQUD, r0)1516opset(AVCMPEQUDCC, r0)1517
1518case AVCMPGT: /* vcmpgt[u,s]b[.], vcmpgt[u,s]h[.], vcmpgt[u,s]w[.], vcmpgt[u,s]d[.] */1519opset(AVCMPGTUB, r0)1520opset(AVCMPGTUBCC, r0)1521opset(AVCMPGTUH, r0)1522opset(AVCMPGTUHCC, r0)1523opset(AVCMPGTUW, r0)1524opset(AVCMPGTUWCC, r0)1525opset(AVCMPGTUD, r0)1526opset(AVCMPGTUDCC, r0)1527opset(AVCMPGTSB, r0)1528opset(AVCMPGTSBCC, r0)1529opset(AVCMPGTSH, r0)1530opset(AVCMPGTSHCC, r0)1531opset(AVCMPGTSW, r0)1532opset(AVCMPGTSWCC, r0)1533opset(AVCMPGTSD, r0)1534opset(AVCMPGTSDCC, r0)1535
1536case AVCMPNEZB: /* vcmpnezb[.] */1537opset(AVCMPNEZBCC, r0)1538opset(AVCMPNEB, r0)1539opset(AVCMPNEBCC, r0)1540opset(AVCMPNEH, r0)1541opset(AVCMPNEHCC, r0)1542opset(AVCMPNEW, r0)1543opset(AVCMPNEWCC, r0)1544
1545case AVPERM: /* vperm */1546opset(AVPERMXOR, r0)1547opset(AVPERMR, r0)1548
1549case AVBPERMQ: /* vbpermq, vbpermd */1550opset(AVBPERMD, r0)1551
1552case AVSEL: /* vsel */1553opset(AVSEL, r0)1554
1555case AVSPLTB: /* vspltb, vsplth, vspltw */1556opset(AVSPLTH, r0)1557opset(AVSPLTW, r0)1558
1559case AVSPLTISB: /* vspltisb, vspltish, vspltisw */1560opset(AVSPLTISH, r0)1561opset(AVSPLTISW, r0)1562
1563case AVCIPH: /* vcipher, vcipherlast */1564opset(AVCIPHER, r0)1565opset(AVCIPHERLAST, r0)1566
1567case AVNCIPH: /* vncipher, vncipherlast */1568opset(AVNCIPHER, r0)1569opset(AVNCIPHERLAST, r0)1570
1571case AVSBOX: /* vsbox */1572opset(AVSBOX, r0)1573
1574case AVSHASIGMA: /* vshasigmaw, vshasigmad */1575opset(AVSHASIGMAW, r0)1576opset(AVSHASIGMAD, r0)1577
1578case ALXVD2X: /* lxvd2x, lxvdsx, lxvw4x, lxvh8x, lxvb16x */1579opset(ALXVDSX, r0)1580opset(ALXVW4X, r0)1581opset(ALXVH8X, r0)1582opset(ALXVB16X, r0)1583
1584case ALXV: /* lxv */1585opset(ALXV, r0)1586
1587case ALXVL: /* lxvl, lxvll, lxvx */1588opset(ALXVLL, r0)1589opset(ALXVX, r0)1590
1591case ASTXVD2X: /* stxvd2x, stxvdsx, stxvw4x, stxvh8x, stxvb16x */1592opset(ASTXVW4X, r0)1593opset(ASTXVH8X, r0)1594opset(ASTXVB16X, r0)1595
1596case ASTXV: /* stxv */1597opset(ASTXV, r0)1598
1599case ASTXVL: /* stxvl, stxvll, stvx */1600opset(ASTXVLL, r0)1601opset(ASTXVX, r0)1602
1603case ALXSDX: /* lxsdx */1604opset(ALXSDX, r0)1605
1606case ASTXSDX: /* stxsdx */1607opset(ASTXSDX, r0)1608
1609case ALXSIWAX: /* lxsiwax, lxsiwzx */1610opset(ALXSIWZX, r0)1611
1612case ASTXSIWX: /* stxsiwx */1613opset(ASTXSIWX, r0)1614
1615case AMFVSRD: /* mfvsrd, mfvsrwz (and extended mnemonics), mfvsrld */1616opset(AMFFPRD, r0)1617opset(AMFVRD, r0)1618opset(AMFVSRWZ, r0)1619opset(AMFVSRLD, r0)1620
1621case AMTVSRD: /* mtvsrd, mtvsrwa, mtvsrwz (and extended mnemonics), mtvsrdd, mtvsrws */1622opset(AMTFPRD, r0)1623opset(AMTVRD, r0)1624opset(AMTVSRWA, r0)1625opset(AMTVSRWZ, r0)1626opset(AMTVSRDD, r0)1627opset(AMTVSRWS, r0)1628
1629case AXXLAND: /* xxland, xxlandc, xxleqv, xxlnand */1630opset(AXXLANDC, r0)1631opset(AXXLEQV, r0)1632opset(AXXLNAND, r0)1633
1634case AXXLOR: /* xxlorc, xxlnor, xxlor, xxlxor */1635opset(AXXLORC, r0)1636opset(AXXLNOR, r0)1637opset(AXXLORQ, r0)1638opset(AXXLXOR, r0)1639
1640case AXXSEL: /* xxsel */1641opset(AXXSEL, r0)1642
1643case AXXMRGHW: /* xxmrghw, xxmrglw */1644opset(AXXMRGLW, r0)1645
1646case AXXSPLTW: /* xxspltw */1647opset(AXXSPLTW, r0)1648
1649case AXXSPLTIB: /* xxspltib */1650opset(AXXSPLTIB, r0)1651
1652case AXXPERM: /* xxpermdi */1653opset(AXXPERM, r0)1654
1655case AXXSLDWI: /* xxsldwi */1656opset(AXXPERMDI, r0)1657opset(AXXSLDWI, r0)1658
1659case AXXBRQ: /* xxbrq, xxbrd, xxbrw, xxbrh */1660opset(AXXBRD, r0)1661opset(AXXBRW, r0)1662opset(AXXBRH, r0)1663
1664case AXSCVDPSP: /* xscvdpsp, xscvspdp, xscvdpspn, xscvspdpn */1665opset(AXSCVSPDP, r0)1666opset(AXSCVDPSPN, r0)1667opset(AXSCVSPDPN, r0)1668
1669case AXVCVDPSP: /* xvcvdpsp, xvcvspdp */1670opset(AXVCVSPDP, r0)1671
1672case AXSCVDPSXDS: /* xscvdpsxds, xscvdpsxws, xscvdpuxds, xscvdpuxws */1673opset(AXSCVDPSXWS, r0)1674opset(AXSCVDPUXDS, r0)1675opset(AXSCVDPUXWS, r0)1676
1677case AXSCVSXDDP: /* xscvsxddp, xscvuxddp, xscvsxdsp, xscvuxdsp */1678opset(AXSCVUXDDP, r0)1679opset(AXSCVSXDSP, r0)1680opset(AXSCVUXDSP, r0)1681
1682case AXVCVDPSXDS: /* xvcvdpsxds, xvcvdpsxws, xvcvdpuxds, xvcvdpuxws, xvcvspsxds, xvcvspsxws, xvcvspuxds, xvcvspuxws */1683opset(AXVCVDPSXDS, r0)1684opset(AXVCVDPSXWS, r0)1685opset(AXVCVDPUXDS, r0)1686opset(AXVCVDPUXWS, r0)1687opset(AXVCVSPSXDS, r0)1688opset(AXVCVSPSXWS, r0)1689opset(AXVCVSPUXDS, r0)1690opset(AXVCVSPUXWS, r0)1691
1692case AXVCVSXDDP: /* xvcvsxddp, xvcvsxwdp, xvcvuxddp, xvcvuxwdp, xvcvsxdsp, xvcvsxwsp, xvcvuxdsp, xvcvuxwsp */1693opset(AXVCVSXWDP, r0)1694opset(AXVCVUXDDP, r0)1695opset(AXVCVUXWDP, r0)1696opset(AXVCVSXDSP, r0)1697opset(AXVCVSXWSP, r0)1698opset(AXVCVUXDSP, r0)1699opset(AXVCVUXWSP, r0)1700
1701case AAND: /* logical op Rb,Rs,Ra; no literal */1702opset(AANDN, r0)1703opset(AANDNCC, r0)1704opset(AEQV, r0)1705opset(AEQVCC, r0)1706opset(ANAND, r0)1707opset(ANANDCC, r0)1708opset(ANOR, r0)1709opset(ANORCC, r0)1710opset(AORCC, r0)1711opset(AORN, r0)1712opset(AORNCC, r0)1713opset(AXORCC, r0)1714
1715case AADDME: /* op Ra, Rd */1716opset(AADDMECC, r0)1717
1718opset(AADDMEV, r0)1719opset(AADDMEVCC, r0)1720opset(AADDZE, r0)1721opset(AADDZECC, r0)1722opset(AADDZEV, r0)1723opset(AADDZEVCC, r0)1724opset(ASUBME, r0)1725opset(ASUBMECC, r0)1726opset(ASUBMEV, r0)1727opset(ASUBMEVCC, r0)1728opset(ASUBZE, r0)1729opset(ASUBZECC, r0)1730opset(ASUBZEV, r0)1731opset(ASUBZEVCC, r0)1732
1733case AADDC:1734opset(AADDCCC, r0)1735
1736case ABEQ:1737opset(ABGE, r0)1738opset(ABGT, r0)1739opset(ABLE, r0)1740opset(ABLT, r0)1741opset(ABNE, r0)1742opset(ABVC, r0)1743opset(ABVS, r0)1744
1745case ABR:1746opset(ABL, r0)1747
1748case ABC:1749opset(ABCL, r0)1750
1751case AEXTSB: /* op Rs, Ra */1752opset(AEXTSBCC, r0)1753
1754opset(AEXTSH, r0)1755opset(AEXTSHCC, r0)1756opset(ACNTLZW, r0)1757opset(ACNTLZWCC, r0)1758opset(ACNTLZD, r0)1759opset(AEXTSW, r0)1760opset(AEXTSWCC, r0)1761opset(ACNTLZDCC, r0)1762
1763case AFABS: /* fop [s,]d */1764opset(AFABSCC, r0)1765
1766opset(AFNABS, r0)1767opset(AFNABSCC, r0)1768opset(AFNEG, r0)1769opset(AFNEGCC, r0)1770opset(AFRSP, r0)1771opset(AFRSPCC, r0)1772opset(AFCTIW, r0)1773opset(AFCTIWCC, r0)1774opset(AFCTIWZ, r0)1775opset(AFCTIWZCC, r0)1776opset(AFCTID, r0)1777opset(AFCTIDCC, r0)1778opset(AFCTIDZ, r0)1779opset(AFCTIDZCC, r0)1780opset(AFCFID, r0)1781opset(AFCFIDCC, r0)1782opset(AFCFIDU, r0)1783opset(AFCFIDUCC, r0)1784opset(AFCFIDS, r0)1785opset(AFCFIDSCC, r0)1786opset(AFRES, r0)1787opset(AFRESCC, r0)1788opset(AFRIM, r0)1789opset(AFRIMCC, r0)1790opset(AFRIP, r0)1791opset(AFRIPCC, r0)1792opset(AFRIZ, r0)1793opset(AFRIZCC, r0)1794opset(AFRIN, r0)1795opset(AFRINCC, r0)1796opset(AFRSQRTE, r0)1797opset(AFRSQRTECC, r0)1798opset(AFSQRT, r0)1799opset(AFSQRTCC, r0)1800opset(AFSQRTS, r0)1801opset(AFSQRTSCC, r0)1802
1803case AFADD:1804opset(AFADDS, r0)1805opset(AFADDCC, r0)1806opset(AFADDSCC, r0)1807opset(AFCPSGN, r0)1808opset(AFCPSGNCC, r0)1809opset(AFDIV, r0)1810opset(AFDIVS, r0)1811opset(AFDIVCC, r0)1812opset(AFDIVSCC, r0)1813opset(AFSUB, r0)1814opset(AFSUBS, r0)1815opset(AFSUBCC, r0)1816opset(AFSUBSCC, r0)1817
1818case AFMADD:1819opset(AFMADDCC, r0)1820opset(AFMADDS, r0)1821opset(AFMADDSCC, r0)1822opset(AFMSUB, r0)1823opset(AFMSUBCC, r0)1824opset(AFMSUBS, r0)1825opset(AFMSUBSCC, r0)1826opset(AFNMADD, r0)1827opset(AFNMADDCC, r0)1828opset(AFNMADDS, r0)1829opset(AFNMADDSCC, r0)1830opset(AFNMSUB, r0)1831opset(AFNMSUBCC, r0)1832opset(AFNMSUBS, r0)1833opset(AFNMSUBSCC, r0)1834opset(AFSEL, r0)1835opset(AFSELCC, r0)1836
1837case AFMUL:1838opset(AFMULS, r0)1839opset(AFMULCC, r0)1840opset(AFMULSCC, r0)1841
1842case AFCMPO:1843opset(AFCMPU, r0)1844
1845case AISEL:1846opset(AISEL, r0)1847
1848case AMTFSB0:1849opset(AMTFSB0CC, r0)1850opset(AMTFSB1, r0)1851opset(AMTFSB1CC, r0)1852
1853case ANEG: /* op [Ra,] Rd */1854opset(ANEGCC, r0)1855
1856opset(ANEGV, r0)1857opset(ANEGVCC, r0)1858
1859case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,R */1860opset(AXOR, r0)1861
1862case AORIS: /* oris/xoris $uimm,Rs,Ra */1863opset(AXORIS, r0)1864
1865case ASLW:1866opset(ASLWCC, r0)1867opset(ASRW, r0)1868opset(ASRWCC, r0)1869opset(AROTLW, r0)1870
1871case ASLD:1872opset(ASLDCC, r0)1873opset(ASRD, r0)1874opset(ASRDCC, r0)1875opset(AROTL, r0)1876
1877case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */1878opset(ASRAWCC, r0)1879
1880case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */1881opset(ASRADCC, r0)1882
1883case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */1884opset(ASUB, r0)1885
1886opset(ASUBCC, r0)1887opset(ASUBV, r0)1888opset(ASUBVCC, r0)1889opset(ASUBCCC, r0)1890opset(ASUBCV, r0)1891opset(ASUBCVCC, r0)1892opset(ASUBE, r0)1893opset(ASUBECC, r0)1894opset(ASUBEV, r0)1895opset(ASUBEVCC, r0)1896
1897case ASYNC:1898opset(AISYNC, r0)1899opset(ALWSYNC, r0)1900opset(APTESYNC, r0)1901opset(ATLBSYNC, r0)1902
1903case ARLWMI:1904opset(ARLWMICC, r0)1905opset(ARLWNM, r0)1906opset(ARLWNMCC, r0)1907opset(ACLRLSLWI, r0)1908
1909case ARLDMI:1910opset(ARLDMICC, r0)1911opset(ARLDIMI, r0)1912opset(ARLDIMICC, r0)1913
1914case ARLDC:1915opset(ARLDCCC, r0)1916
1917case ARLDCL:1918opset(ARLDCR, r0)1919opset(ARLDCLCC, r0)1920opset(ARLDCRCC, r0)1921
1922case ARLDICL:1923opset(ARLDICLCC, r0)1924opset(ARLDICR, r0)1925opset(ARLDICRCC, r0)1926opset(ARLDIC, r0)1927opset(ARLDICCC, r0)1928opset(ACLRLSLDI, r0)1929
1930case AFMOVD:1931opset(AFMOVDCC, r0)1932opset(AFMOVDU, r0)1933opset(AFMOVS, r0)1934opset(AFMOVSU, r0)1935
1936case ALDAR:1937opset(ALBAR, r0)1938opset(ALHAR, r0)1939opset(ALWAR, r0)1940
1941case ASYSCALL: /* just the op; flow of control */1942opset(ARFI, r0)1943
1944opset(ARFCI, r0)1945opset(ARFID, r0)1946opset(AHRFID, r0)1947
1948case AMOVHBR:1949opset(AMOVWBR, r0)1950opset(AMOVDBR, r0)1951
1952case ASLBMFEE:1953opset(ASLBMFEV, r0)1954
1955case ATW:1956opset(ATD, r0)1957
1958case ATLBIE:1959opset(ASLBIE, r0)1960opset(ATLBIEL, r0)1961
1962case AEIEIO:1963opset(ASLBIA, r0)1964
1965case ACMP:1966opset(ACMPW, r0)1967
1968case ACMPU:1969opset(ACMPWU, r0)1970
1971case ACMPB:1972opset(ACMPB, r0)1973
1974case AFTDIV:1975opset(AFTDIV, r0)1976
1977case AFTSQRT:1978opset(AFTSQRT, r0)1979
1980case AADD,1981AADDIS,1982AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */1983AANDISCC,1984AFMOVSX,1985AFMOVSZ,1986ALSW,1987AMOVW,1988/* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */1989AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals */1990AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */1991AMOVB, /* macro: move byte with sign extension */1992AMOVBU, /* macro: move byte with sign extension & update */1993AMOVFL,1994AMULLW,1995/* op $s[,r2],r3; op r1[,r2],r3; no cc/v */1996ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */1997ASTSW,1998ASLBMTE,1999AWORD,2000ADWORD,2001ADARN,2002ALDMX,2003AVMSUMUDM,2004AADDEX,2005ACMPEQB,2006AECIWX,2007obj.ANOP,2008obj.ATEXT,2009obj.AUNDEF,2010obj.AFUNCDATA,2011obj.APCALIGN,2012obj.APCDATA,2013obj.ADUFFZERO,2014obj.ADUFFCOPY:2015break2016}2017}2018}
2019
2020func OPVXX1(o uint32, xo uint32, oe uint32) uint32 {2021return o<<26 | xo<<1 | oe<<112022}
2023
2024func OPVXX2(o uint32, xo uint32, oe uint32) uint32 {2025return o<<26 | xo<<2 | oe<<112026}
2027
2028func OPVXX2VA(o uint32, xo uint32, oe uint32) uint32 {2029return o<<26 | xo<<2 | oe<<162030}
2031
2032func OPVXX3(o uint32, xo uint32, oe uint32) uint32 {2033return o<<26 | xo<<3 | oe<<112034}
2035
2036func OPVXX4(o uint32, xo uint32, oe uint32) uint32 {2037return o<<26 | xo<<4 | oe<<112038}
2039
2040func OPDQ(o uint32, xo uint32, oe uint32) uint32 {2041return o<<26 | xo | oe<<42042}
2043
2044func OPVX(o uint32, xo uint32, oe uint32, rc uint32) uint32 {2045return o<<26 | xo | oe<<11 | rc&12046}
2047
2048func OPVC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {2049return o<<26 | xo | oe<<11 | (rc&1)<<102050}
2051
2052func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {2053return o<<26 | xo<<1 | oe<<10 | rc&12054}
2055
2056func OPCC(o uint32, xo uint32, rc uint32) uint32 {2057return OPVCC(o, xo, 0, rc)2058}
2059
2060/* the order is dest, a/s, b/imm for both arithmetic and logical operations */
2061func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {2062return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<112063}
2064
2065/* VX-form 2-register operands, r/none/r */
2066func AOP_RR(op uint32, d uint32, a uint32) uint32 {2067return op | (d&31)<<21 | (a&31)<<112068}
2069
2070/* VA-form 4-register operands */
2071func AOP_RRRR(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {2072return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&31)<<62073}
2074
2075func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 {2076return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF2077}
2078
2079/* VX-form 2-register + UIM operands */
2080func AOP_VIRR(op uint32, d uint32, a uint32, simm uint32) uint32 {2081return op | (d&31)<<21 | (simm&0xFFFF)<<16 | (a&31)<<112082}
2083
2084/* VX-form 2-register + ST + SIX operands */
2085func AOP_IIRR(op uint32, d uint32, a uint32, sbit uint32, simm uint32) uint32 {2086return op | (d&31)<<21 | (a&31)<<16 | (sbit&1)<<15 | (simm&0xF)<<112087}
2088
2089/* VA-form 3-register + SHB operands */
2090func AOP_IRRR(op uint32, d uint32, a uint32, b uint32, simm uint32) uint32 {2091return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (simm&0xF)<<62092}
2093
2094/* VX-form 1-register + SIM operands */
2095func AOP_IR(op uint32, d uint32, simm uint32) uint32 {2096return op | (d&31)<<21 | (simm&31)<<162097}
2098
2099/* XX1-form 3-register operands, 1 VSR operand */
2100func AOP_XX1(op uint32, d uint32, a uint32, b uint32) uint32 {2101/* For the XX-form encodings, we need the VSX register number to be exactly */2102/* between 0-63, so we can properly set the rightmost bits. */2103r := d - REG_VS02104return op | (r&31)<<21 | (a&31)<<16 | (b&31)<<11 | (r&32)>>52105}
2106
2107/* XX2-form 3-register operands, 2 VSR operands */
2108func AOP_XX2(op uint32, d uint32, a uint32, b uint32) uint32 {2109xt := d - REG_VS02110xb := b - REG_VS02111return op | (xt&31)<<21 | (a&3)<<16 | (xb&31)<<11 | (xb&32)>>4 | (xt&32)>>52112}
2113
2114/* XX3-form 3 VSR operands */
2115func AOP_XX3(op uint32, d uint32, a uint32, b uint32) uint32 {2116xt := d - REG_VS02117xa := a - REG_VS02118xb := b - REG_VS02119return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>52120}
2121
2122/* XX3-form 3 VSR operands + immediate */
2123func AOP_XX3I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {2124xt := d - REG_VS02125xa := a - REG_VS02126xb := b - REG_VS02127return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (c&3)<<8 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>52128}
2129
2130/* XX4-form, 4 VSR operands */
2131func AOP_XX4(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {2132xt := d - REG_VS02133xa := a - REG_VS02134xb := b - REG_VS02135xc := c - REG_VS02136return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xc&31)<<6 | (xc&32)>>2 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>52137}
2138
2139/* DQ-form, VSR register, register + offset operands */
2140func AOP_DQ(op uint32, d uint32, a uint32, b uint32) uint32 {2141/* For the DQ-form encodings, we need the VSX register number to be exactly */2142/* between 0-63, so we can properly set the SX bit. */2143r := d - REG_VS02144/* The EA for this instruction form is (RA) + DQ << 4, where DQ is a 12-bit signed integer. */2145/* In order to match the output of the GNU objdump (and make the usage in Go asm easier), the */2146/* instruction is called using the sign extended value (i.e. a valid offset would be -32752 or 32752, */2147/* not -2047 or 2047), so 'b' needs to be adjusted to the expected 12-bit DQ value. Bear in mind that */2148/* bits 0 to 3 in 'dq' need to be zero, otherwise this will generate an illegal instruction. */2149/* If in doubt how this instruction form is encoded, refer to ISA 3.0b, pages 492 and 507. */2150dq := b >> 42151return op | (r&31)<<21 | (a&31)<<16 | (dq&4095)<<4 | (r&32)>>22152}
2153
2154/* Z23-form, 3-register operands + CY field */
2155func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {2156return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<72157}
2158
2159/* X-form, 3-register operands + EH field */
2160func AOP_RRRI(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {2161return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c & 1)2162}
2163
2164func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {2165return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<112166}
2167
2168func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 {2169return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF2170}
2171
2172func OP_BR(op uint32, li uint32, aa uint32) uint32 {2173return op | li&0x03FFFFFC | aa<<12174}
2175
2176func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 {2177return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<12178}
2179
2180func OP_BCR(op uint32, bo uint32, bi uint32) uint32 {2181return op | (bo&0x1F)<<21 | (bi&0x1F)<<162182}
2183
2184func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 {2185return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<12186}
2187
2188func AOP_RLDIC(op uint32, a uint32, s uint32, sh uint32, m uint32) uint32 {2189return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1 | (m&31)<<6 | ((m&32)>>5)<<52190}
2191
2192func AOP_ISEL(op uint32, t uint32, a uint32, b uint32, bc uint32) uint32 {2193return op | (t&31)<<21 | (a&31)<<16 | (b&31)<<11 | (bc&0x1F)<<62194}
2195
2196const (2197/* each rhs is OPVCC(_, _, _, _) */2198OP_ADD = 31<<26 | 266<<1 | 0<<10 | 02199OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 02200OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 02201OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 02202OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 02203OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 02204OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 02205OP_ISEL = 31<<26 | 15<<1 | 0<<10 | 02206OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 02207OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 02208OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 02209OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 02210OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 02211OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 02212OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 02213OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 02214OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 02215OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 02216OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 02217OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 02218OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 02219OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 02220OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 02221OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 02222OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 02223OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 02224OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 02225OP_OR = 31<<26 | 444<<1 | 0<<10 | 02226OP_ORI = 24<<26 | 0<<1 | 0<<10 | 02227OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 02228OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 02229OP_RLWNM = 23<<26 | 0<<1 | 0<<10 | 02230OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 02231OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 02232OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 02233OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 02234OP_RLDCL = 30<<26 | 8<<1 | 0<<10 | 02235)
2236
2237func oclass(a *obj.Addr) int {2238return int(a.Class) - 12239}
2240
2241const (2242D_FORM = iota2243DS_FORM
2244)
2245
2246// This function determines when a non-indexed load or store is D or
2247// DS form for use in finding the size of the offset field in the instruction.
2248// The size is needed when setting the offset value in the instruction
2249// and when generating relocation for that field.
2250// DS form instructions include: ld, ldu, lwa, std, stdu. All other
2251// loads and stores with an offset field are D form. This function should
2252// only be called with the same opcodes as are handled by opstore and opload.
2253func (c *ctxt9) opform(insn uint32) int {2254switch insn {2255default:2256c.ctxt.Diag("bad insn in loadform: %x", insn)2257case OPVCC(58, 0, 0, 0), // ld2258OPVCC(58, 0, 0, 1), // ldu2259OPVCC(58, 0, 0, 0) | 1<<1, // lwa2260OPVCC(62, 0, 0, 0), // std2261OPVCC(62, 0, 0, 1): //stdu2262return DS_FORM2263case OP_ADDI, // add2264OPVCC(32, 0, 0, 0), // lwz2265OPVCC(33, 0, 0, 0), // lwzu2266OPVCC(34, 0, 0, 0), // lbz2267OPVCC(35, 0, 0, 0), // lbzu2268OPVCC(40, 0, 0, 0), // lhz2269OPVCC(41, 0, 0, 0), // lhzu2270OPVCC(42, 0, 0, 0), // lha2271OPVCC(43, 0, 0, 0), // lhau2272OPVCC(46, 0, 0, 0), // lmw2273OPVCC(48, 0, 0, 0), // lfs2274OPVCC(49, 0, 0, 0), // lfsu2275OPVCC(50, 0, 0, 0), // lfd2276OPVCC(51, 0, 0, 0), // lfdu2277OPVCC(36, 0, 0, 0), // stw2278OPVCC(37, 0, 0, 0), // stwu2279OPVCC(38, 0, 0, 0), // stb2280OPVCC(39, 0, 0, 0), // stbu2281OPVCC(44, 0, 0, 0), // sth2282OPVCC(45, 0, 0, 0), // sthu2283OPVCC(47, 0, 0, 0), // stmw2284OPVCC(52, 0, 0, 0), // stfs2285OPVCC(53, 0, 0, 0), // stfsu2286OPVCC(54, 0, 0, 0), // stfd2287OPVCC(55, 0, 0, 0): // stfdu2288return D_FORM2289}2290return 02291}
2292
2293// Encode instructions and create relocation for accessing s+d according to the
2294// instruction op with source or destination (as appropriate) register reg.
2295func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) {2296if c.ctxt.Headtype == objabi.Haix {2297// Every symbol access must be made via a TOC anchor.2298c.ctxt.Diag("symbolAccess called for %s", s.Name)2299}2300var base uint322301form := c.opform(op)2302if c.ctxt.Flag_shared {2303base = REG_R22304} else {2305base = REG_R02306}2307o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)2308o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)2309rel := obj.Addrel(c.cursym)2310rel.Off = int32(c.pc)2311rel.Siz = 82312rel.Sym = s2313rel.Add = d2314if c.ctxt.Flag_shared {2315switch form {2316case D_FORM:2317rel.Type = objabi.R_ADDRPOWER_TOCREL2318case DS_FORM:2319rel.Type = objabi.R_ADDRPOWER_TOCREL_DS2320}2321
2322} else {2323switch form {2324case D_FORM:2325rel.Type = objabi.R_ADDRPOWER2326case DS_FORM:2327rel.Type = objabi.R_ADDRPOWER_DS2328}2329}2330return2331}
2332
2333/*
2334* 32-bit masks
2335*/
2336func getmask(m []byte, v uint32) bool {2337m[1] = 02338m[0] = m[1]2339if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */2340if getmask(m, ^v) {2341i := int(m[0])2342m[0] = m[1] + 12343m[1] = byte(i - 1)2344return true2345}2346
2347return false2348}2349
2350for i := 0; i < 32; i++ {2351if v&(1<<uint(31-i)) != 0 {2352m[0] = byte(i)2353for {2354m[1] = byte(i)2355i++2356if i >= 32 || v&(1<<uint(31-i)) == 0 {2357break2358}2359}2360
2361for ; i < 32; i++ {2362if v&(1<<uint(31-i)) != 0 {2363return false2364}2365}2366return true2367}2368}2369
2370return false2371}
2372
2373func (c *ctxt9) maskgen(p *obj.Prog, m []byte, v uint32) {2374if !getmask(m, v) {2375c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)2376}2377}
2378
2379/*
2380* 64-bit masks (rldic etc)
2381*/
2382func getmask64(m []byte, v uint64) bool {2383m[1] = 02384m[0] = m[1]2385for i := 0; i < 64; i++ {2386if v&(uint64(1)<<uint(63-i)) != 0 {2387m[0] = byte(i)2388for {2389m[1] = byte(i)2390i++2391if i >= 64 || v&(uint64(1)<<uint(63-i)) == 0 {2392break2393}2394}2395
2396for ; i < 64; i++ {2397if v&(uint64(1)<<uint(63-i)) != 0 {2398return false2399}2400}2401return true2402}2403}2404
2405return false2406}
2407
2408func (c *ctxt9) maskgen64(p *obj.Prog, m []byte, v uint64) {2409if !getmask64(m, v) {2410c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)2411}2412}
2413
2414func loadu32(r int, d int64) uint32 {2415v := int32(d >> 16)2416if isuint32(uint64(d)) {2417return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))2418}2419return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v))2420}
2421
2422func high16adjusted(d int32) uint16 {2423if d&0x8000 != 0 {2424return uint16((d >> 16) + 1)2425}2426return uint16(d >> 16)2427}
2428
2429func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {2430o1 := uint32(0)2431o2 := uint32(0)2432o3 := uint32(0)2433o4 := uint32(0)2434o5 := uint32(0)2435
2436//print("%v => case %d\n", p, o->type);2437switch o.type_ {2438default:2439c.ctxt.Diag("unknown type %d", o.type_)2440prasm(p)2441
2442case 0: /* pseudo ops */2443break2444
2445case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */2446if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {2447v := c.regoff(&p.From)2448if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {2449//nerrors--;2450c.ctxt.Diag("literal operation on R0\n%v", p)2451}2452
2453o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))2454break2455}2456
2457o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))2458
2459case 2: /* int/cr/fp op Rb,[Ra],Rd */2460r := int(p.Reg)2461
2462if r == 0 {2463r = int(p.To.Reg)2464}2465o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))2466
2467case 3: /* mov $soreg/addcon/andcon/ucon, r ==> addis/oris/addi/ori $i,reg',r */2468d := c.vregoff(&p.From)2469
2470v := int32(d)2471r := int(p.From.Reg)2472if r == 0 {2473r = int(o.param)2474}2475if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {2476c.ctxt.Diag("literal operation on R0\n%v", p)2477}2478a := OP_ADDI2479if o.a1 == C_UCON {2480if d&0xffff != 0 {2481log.Fatalf("invalid handling of %v", p)2482}2483// For UCON operands the value is right shifted 16, using ADDIS if the2484// value should be signed, ORIS if unsigned.2485v >>= 162486if r == REGZERO && isuint32(uint64(d)) {2487o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v))2488break2489}2490
2491a = OP_ADDIS2492} else if int64(int16(d)) != d {2493// Operand is 16 bit value with sign bit set2494if o.a1 == C_ANDCON {2495// Needs unsigned 16 bit so use ORI2496if r == 0 || r == REGZERO {2497o1 = LOP_IRR(uint32(OP_ORI), uint32(p.To.Reg), uint32(0), uint32(v))2498break2499}2500// With ADDCON, needs signed 16 bit value, fall through to use ADDI2501} else if o.a1 != C_ADDCON {2502log.Fatalf("invalid handling of %v", p)2503}2504}2505
2506o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))2507
2508case 4: /* add/mul $scon,[r1],r2 */2509v := c.regoff(&p.From)2510
2511r := int(p.Reg)2512if r == 0 {2513r = int(p.To.Reg)2514}2515if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {2516c.ctxt.Diag("literal operation on R0\n%v", p)2517}2518if int32(int16(v)) != v {2519log.Fatalf("mishandled instruction %v", p)2520}2521o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))2522
2523case 5: /* syscall */2524o1 = c.oprrr(p.As)2525
2526case 6: /* logical op Rb,[Rs,]Ra; no literal */2527r := int(p.Reg)2528
2529if r == 0 {2530r = int(p.To.Reg)2531}2532// AROTL and AROTLW are extended mnemonics, which map to RLDCL and RLWNM.2533switch p.As {2534case AROTL:2535o1 = AOP_RLDIC(OP_RLDCL, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), uint32(0))2536case AROTLW:2537o1 = OP_RLW(OP_RLWNM, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), 0, 31)2538default:2539o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))2540}2541
2542case 7: /* mov r, soreg ==> stw o(r) */2543r := int(p.To.Reg)2544
2545if r == 0 {2546r = int(o.param)2547}2548v := c.regoff(&p.To)2549if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {2550if v != 0 {2551c.ctxt.Diag("illegal indexed instruction\n%v", p)2552}2553if c.ctxt.Flag_shared && r == REG_R13 {2554rel := obj.Addrel(c.cursym)2555rel.Off = int32(c.pc)2556rel.Siz = 42557// This (and the matching part in the load case2558// below) are the only places in the ppc64 toolchain2559// that knows the name of the tls variable. Possibly2560// we could add some assembly syntax so that the name2561// of the variable does not have to be assumed.2562rel.Sym = c.ctxt.Lookup("runtime.tls_g")2563rel.Type = objabi.R_POWER_TLS2564}2565o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))2566} else {2567if int32(int16(v)) != v {2568log.Fatalf("mishandled instruction %v", p)2569}2570// Offsets in DS form stores must be a multiple of 42571inst := c.opstore(p.As)2572if c.opform(inst) == DS_FORM && v&0x3 != 0 {2573log.Fatalf("invalid offset for DS form load/store %v", p)2574}2575o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))2576}2577
2578case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */2579r := int(p.From.Reg)2580
2581if r == 0 {2582r = int(o.param)2583}2584v := c.regoff(&p.From)2585if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {2586if v != 0 {2587c.ctxt.Diag("illegal indexed instruction\n%v", p)2588}2589if c.ctxt.Flag_shared && r == REG_R13 {2590rel := obj.Addrel(c.cursym)2591rel.Off = int32(c.pc)2592rel.Siz = 42593rel.Sym = c.ctxt.Lookup("runtime.tls_g")2594rel.Type = objabi.R_POWER_TLS2595}2596o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))2597} else {2598if int32(int16(v)) != v {2599log.Fatalf("mishandled instruction %v", p)2600}2601// Offsets in DS form loads must be a multiple of 42602inst := c.opload(p.As)2603if c.opform(inst) == DS_FORM && v&0x3 != 0 {2604log.Fatalf("invalid offset for DS form load/store %v", p)2605}2606o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))2607}2608
2609case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */2610r := int(p.From.Reg)2611
2612if r == 0 {2613r = int(o.param)2614}2615v := c.regoff(&p.From)2616if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {2617if v != 0 {2618c.ctxt.Diag("illegal indexed instruction\n%v", p)2619}2620o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))2621} else {2622o1 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(r), uint32(v))2623}2624o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)2625
2626case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */2627r := int(p.Reg)2628
2629if r == 0 {2630r = int(p.To.Reg)2631}2632o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))2633
2634case 11: /* br/bl lbra */2635v := int32(0)2636
2637if p.To.Target() != nil {2638v = int32(p.To.Target().Pc - p.Pc)2639if v&03 != 0 {2640c.ctxt.Diag("odd branch target address\n%v", p)2641v &^= 032642}2643
2644if v < -(1<<25) || v >= 1<<24 {2645c.ctxt.Diag("branch too far\n%v", p)2646}2647}2648
2649o1 = OP_BR(c.opirr(p.As), uint32(v), 0)2650if p.To.Sym != nil {2651rel := obj.Addrel(c.cursym)2652rel.Off = int32(c.pc)2653rel.Siz = 42654rel.Sym = p.To.Sym2655v += int32(p.To.Offset)2656if v&03 != 0 {2657c.ctxt.Diag("odd branch target address\n%v", p)2658v &^= 032659}2660
2661rel.Add = int64(v)2662rel.Type = objabi.R_CALLPOWER2663}2664o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking2665
2666case 12: /* movb r,r (extsb); movw r,r (extsw) */2667if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {2668v := c.regoff(&p.From)2669if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {2670c.ctxt.Diag("literal operation on R0\n%v", p)2671}2672
2673o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))2674break2675}2676
2677if p.As == AMOVW {2678o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)2679} else {2680o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)2681}2682
2683case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */2684if p.As == AMOVBZ {2685o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)2686} else if p.As == AMOVH {2687o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)2688} else if p.As == AMOVHZ {2689o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)2690} else if p.As == AMOVWZ {2691o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */2692} else {2693c.ctxt.Diag("internal: bad mov[bhw]z\n%v", p)2694}2695
2696case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */2697r := int(p.Reg)2698
2699if r == 0 {2700r = int(p.To.Reg)2701}2702d := c.vregoff(p.GetFrom3())2703var a int2704switch p.As {2705
2706// These opcodes expect a mask operand that has to be converted into the2707// appropriate operand. The way these were defined, not all valid masks are possible.2708// Left here for compatibility in case they were used or generated.2709case ARLDCL, ARLDCLCC:2710var mask [2]uint82711c.maskgen64(p, mask[:], uint64(d))2712
2713a = int(mask[0]) /* MB */2714if mask[1] != 63 {2715c.ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)2716}2717o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))2718o1 |= (uint32(a) & 31) << 62719if a&0x20 != 0 {2720o1 |= 1 << 5 /* mb[5] is top bit */2721}2722
2723case ARLDCR, ARLDCRCC:2724var mask [2]uint82725c.maskgen64(p, mask[:], uint64(d))2726
2727a = int(mask[1]) /* ME */2728if mask[0] != 0 {2729c.ctxt.Diag("invalid mask for rotate: %x %x (start != 0)\n%v", uint64(d), mask[0], p)2730}2731o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))2732o1 |= (uint32(a) & 31) << 62733if a&0x20 != 0 {2734o1 |= 1 << 5 /* mb[5] is top bit */2735}2736
2737// These opcodes use a shift count like the ppc64 asm, no mask conversion done2738case ARLDICR, ARLDICRCC:2739me := int(d)2740sh := c.regoff(&p.From)2741if me < 0 || me > 63 || sh > 63 {2742c.ctxt.Diag("Invalid me or sh for RLDICR: %x %x\n%v", int(d), sh)2743}2744o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(me))2745
2746case ARLDICL, ARLDICLCC, ARLDIC, ARLDICCC:2747mb := int(d)2748sh := c.regoff(&p.From)2749if mb < 0 || mb > 63 || sh > 63 {2750c.ctxt.Diag("Invalid mb or sh for RLDIC, RLDICL: %x %x\n%v", mb, sh)2751}2752o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(mb))2753
2754case ACLRLSLDI:2755// This is an extended mnemonic defined in the ISA section C.8.12756// clrlsldi ra,rs,n,b --> rldic ra,rs,n,b-n2757// It maps onto RLDIC so is directly generated here based on the operands from2758// the clrlsldi.2759b := int(d)2760n := c.regoff(&p.From)2761if n > int32(b) || b > 63 {2762c.ctxt.Diag("Invalid n or b for CLRLSLDI: %x %x\n%v", n, b)2763}2764o1 = AOP_RLDIC(OP_RLDIC, uint32(p.To.Reg), uint32(r), uint32(n), uint32(b)-uint32(n))2765
2766default:2767c.ctxt.Diag("unexpected op in rldc case\n%v", p)2768a = 02769}2770
2771case 17, /* bc bo,bi,lbra (same for now) */277216: /* bc bo,bi,sbra */2773a := 02774
2775r := int(p.Reg)2776
2777if p.From.Type == obj.TYPE_CONST {2778a = int(c.regoff(&p.From))2779} else if p.From.Type == obj.TYPE_REG {2780if r != 0 {2781c.ctxt.Diag("unexpected register setting for branch with CR: %d\n", r)2782}2783// BI values for the CR2784switch p.From.Reg {2785case REG_CR0:2786r = BI_CR02787case REG_CR1:2788r = BI_CR12789case REG_CR2:2790r = BI_CR22791case REG_CR3:2792r = BI_CR32793case REG_CR4:2794r = BI_CR42795case REG_CR5:2796r = BI_CR52797case REG_CR6:2798r = BI_CR62799case REG_CR7:2800r = BI_CR72801default:2802c.ctxt.Diag("unrecognized register: expecting CR\n")2803}2804}2805v := int32(0)2806if p.To.Target() != nil {2807v = int32(p.To.Target().Pc - p.Pc)2808}2809if v&03 != 0 {2810c.ctxt.Diag("odd branch target address\n%v", p)2811v &^= 032812}2813
2814if v < -(1<<16) || v >= 1<<15 {2815c.ctxt.Diag("branch too far\n%v", p)2816}2817o1 = OP_BC(c.opirr(p.As), uint32(a), uint32(r), uint32(v), 0)2818
2819case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */2820var v int322821if p.As == ABC || p.As == ABCL {2822v = c.regoff(&p.To) & 312823} else {2824v = 20 /* unconditional */2825}2826o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<112827o2 = OPVCC(19, 16, 0, 0)2828if p.As == ABL || p.As == ABCL {2829o2 |= 12830}2831o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index))2832
2833case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */2834var v int322835if p.As == ABC || p.As == ABCL {2836v = c.regoff(&p.From) & 312837} else {2838v = 20 /* unconditional */2839}2840r := int(p.Reg)2841if r == 0 {2842r = 02843}2844switch oclass(&p.To) {2845case C_CTR:2846o1 = OPVCC(19, 528, 0, 0)2847
2848case C_LR:2849o1 = OPVCC(19, 16, 0, 0)2850
2851default:2852c.ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p)2853v = 02854}2855
2856if p.As == ABL || p.As == ABCL {2857o1 |= 12858}2859o1 = OP_BCR(o1, uint32(v), uint32(r))2860
2861case 19: /* mov $lcon,r ==> cau+or */2862d := c.vregoff(&p.From)2863
2864if p.From.Sym == nil {2865o1 = loadu32(int(p.To.Reg), d)2866o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))2867} else {2868o1, o2 = c.symbolAccess(p.From.Sym, d, p.To.Reg, OP_ADDI)2869}2870
2871case 20: /* add $ucon,,r | addis $addcon,r,r */2872v := c.regoff(&p.From)2873
2874r := int(p.Reg)2875if r == 0 {2876r = int(p.To.Reg)2877}2878if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {2879c.ctxt.Diag("literal operation on R0\n%v", p)2880}2881if p.As == AADDIS {2882o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))2883} else {2884o1 = AOP_IRR(c.opirr(AADDIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)2885}2886
2887case 22: /* add $lcon/$andcon,r1,r2 ==> oris+ori+add/ori+add */2888if p.To.Reg == REGTMP || p.Reg == REGTMP {2889c.ctxt.Diag("can't synthesize large constant\n%v", p)2890}2891d := c.vregoff(&p.From)2892r := int(p.Reg)2893if r == 0 {2894r = int(p.To.Reg)2895}2896if p.From.Sym != nil {2897c.ctxt.Diag("%v is not supported", p)2898}2899// If operand is ANDCON, generate 2 instructions using2900// ORI for unsigned value; with LCON 3 instructions.2901if o.size == 8 {2902o1 = LOP_IRR(OP_ORI, REGTMP, REGZERO, uint32(int32(d)))2903o2 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))2904} else {2905o1 = loadu32(REGTMP, d)2906o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))2907o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))2908}2909
2910case 23: /* and $lcon/$addcon,r1,r2 ==> oris+ori+and/addi+and */2911if p.To.Reg == REGTMP || p.Reg == REGTMP {2912c.ctxt.Diag("can't synthesize large constant\n%v", p)2913}2914d := c.vregoff(&p.From)2915r := int(p.Reg)2916if r == 0 {2917r = int(p.To.Reg)2918}2919
2920// With ADDCON operand, generate 2 instructions using ADDI for signed value,2921// with LCON operand generate 3 instructions.2922if o.size == 8 {2923o1 = LOP_IRR(OP_ADDI, REGZERO, REGTMP, uint32(int32(d)))2924o2 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))2925} else {2926o1 = loadu32(REGTMP, d)2927o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))2928o3 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))2929}2930if p.From.Sym != nil {2931c.ctxt.Diag("%v is not supported", p)2932}2933
2934case 24: /* lfd fA,float64(0) -> xxlxor xsA,xsaA,xsaA + fneg for -0 */2935o1 = AOP_XX3I(c.oprrr(AXXLXOR), uint32(p.To.Reg), uint32(p.To.Reg), uint32(p.To.Reg), uint32(0))2936// This is needed for -0.2937if o.size == 8 {2938o2 = AOP_RRR(c.oprrr(AFNEG), uint32(p.To.Reg), 0, uint32(p.To.Reg))2939}2940
2941case 25:2942/* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */2943v := c.regoff(&p.From)2944
2945if v < 0 {2946v = 02947} else if v > 63 {2948v = 632949}2950r := int(p.Reg)2951if r == 0 {2952r = int(p.To.Reg)2953}2954var a int2955op := uint32(0)2956switch p.As {2957case ASLD, ASLDCC:2958a = int(63 - v)2959op = OP_RLDICR2960
2961case ASRD, ASRDCC:2962a = int(v)2963v = 64 - v2964op = OP_RLDICL2965case AROTL:2966a = int(0)2967op = OP_RLDICL2968default:2969c.ctxt.Diag("unexpected op in sldi case\n%v", p)2970a = 02971o1 = 02972}2973
2974o1 = AOP_RLDIC(op, uint32(p.To.Reg), uint32(r), uint32(v), uint32(a))2975if p.As == ASLDCC || p.As == ASRDCC {2976o1 |= 1 // Set the condition code bit2977}2978
2979case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */2980if p.To.Reg == REGTMP {2981c.ctxt.Diag("can't synthesize large constant\n%v", p)2982}2983v := c.regoff(&p.From)2984r := int(p.From.Reg)2985if r == 0 {2986r = int(o.param)2987}2988o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))2989o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))2990
2991case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */2992v := c.regoff(p.GetFrom3())2993
2994r := int(p.From.Reg)2995o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))2996
2997case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */2998if p.To.Reg == REGTMP || p.From.Reg == REGTMP {2999c.ctxt.Diag("can't synthesize large constant\n%v", p)3000}3001v := c.regoff(p.GetFrom3())3002o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)3003o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))3004o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)3005if p.From.Sym != nil {3006c.ctxt.Diag("%v is not supported", p)3007}3008
3009case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */3010v := c.regoff(&p.From)3011
3012d := c.vregoff(p.GetFrom3())3013var mask [2]uint83014c.maskgen64(p, mask[:], uint64(d))3015var a int3016switch p.As {3017case ARLDC, ARLDCCC:3018a = int(mask[0]) /* MB */3019if int32(mask[1]) != (63 - v) {3020c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[1], v, p)3021}3022
3023case ARLDCL, ARLDCLCC:3024a = int(mask[0]) /* MB */3025if mask[1] != 63 {3026c.ctxt.Diag("invalid mask for shift: %x %s (shift %d)\n%v", uint64(d), mask[1], v, p)3027}3028
3029case ARLDCR, ARLDCRCC:3030a = int(mask[1]) /* ME */3031if mask[0] != 0 {3032c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[0], v, p)3033}3034
3035default:3036c.ctxt.Diag("unexpected op in rldic case\n%v", p)3037a = 03038}3039
3040o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))3041o1 |= (uint32(a) & 31) << 63042if v&0x20 != 0 {3043o1 |= 1 << 13044}3045if a&0x20 != 0 {3046o1 |= 1 << 5 /* mb[5] is top bit */3047}3048
3049case 30: /* rldimi $sh,s,$mask,a */3050v := c.regoff(&p.From)3051
3052d := c.vregoff(p.GetFrom3())3053
3054// Original opcodes had mask operands which had to be converted to a shift count as expected by3055// the ppc64 asm.3056switch p.As {3057case ARLDMI, ARLDMICC:3058var mask [2]uint83059c.maskgen64(p, mask[:], uint64(d))3060if int32(mask[1]) != (63 - v) {3061c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[1], v, p)3062}3063o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))3064o1 |= (uint32(mask[0]) & 31) << 63065if v&0x20 != 0 {3066o1 |= 1 << 13067}3068if mask[0]&0x20 != 0 {3069o1 |= 1 << 5 /* mb[5] is top bit */3070}3071
3072// Opcodes with shift count operands.3073case ARLDIMI, ARLDIMICC:3074o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))3075o1 |= (uint32(d) & 31) << 63076if d&0x20 != 0 {3077o1 |= 1 << 53078}3079if v&0x20 != 0 {3080o1 |= 1 << 13081}3082}3083
3084case 31: /* dword */3085d := c.vregoff(&p.From)3086
3087if c.ctxt.Arch.ByteOrder == binary.BigEndian {3088o1 = uint32(d >> 32)3089o2 = uint32(d)3090} else {3091o1 = uint32(d)3092o2 = uint32(d >> 32)3093}3094
3095if p.From.Sym != nil {3096rel := obj.Addrel(c.cursym)3097rel.Off = int32(c.pc)3098rel.Siz = 83099rel.Sym = p.From.Sym3100rel.Add = p.From.Offset3101rel.Type = objabi.R_ADDR3102o2 = 03103o1 = o23104}3105
3106case 32: /* fmul frc,fra,frd */3107r := int(p.Reg)3108
3109if r == 0 {3110r = int(p.To.Reg)3111}3112o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<63113
3114case 33: /* fabs [frb,]frd; fmr. frb,frd */3115r := int(p.From.Reg)3116
3117if oclass(&p.From) == C_NONE {3118r = int(p.To.Reg)3119}3120o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(r))3121
3122case 34: /* FMADDx fra,frb,frc,frt (t=a*c±b) */3123o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.GetFrom3().Reg)&31)<<63124
3125case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */3126v := c.regoff(&p.To)3127
3128r := int(p.To.Reg)3129if r == 0 {3130r = int(o.param)3131}3132// Offsets in DS form stores must be a multiple of 43133inst := c.opstore(p.As)3134if c.opform(inst) == DS_FORM && v&0x3 != 0 {3135log.Fatalf("invalid offset for DS form load/store %v", p)3136}3137o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))3138o2 = AOP_IRR(inst, uint32(p.From.Reg), REGTMP, uint32(v))3139
3140case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */3141v := c.regoff(&p.From)3142
3143r := int(p.From.Reg)3144if r == 0 {3145r = int(o.param)3146}3147o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))3148o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))3149
3150case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */3151v := c.regoff(&p.From)3152
3153r := int(p.From.Reg)3154if r == 0 {3155r = int(o.param)3156}3157o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))3158o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))3159o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)3160
3161case 40: /* word */3162o1 = uint32(c.regoff(&p.From))3163
3164case 41: /* stswi */3165o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<113166
3167case 42: /* lswi */3168o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<113169
3170case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */3171/* TH field for dcbt/dcbtst: */3172/* 0 = Block access - program will soon access EA. */3173/* 8-15 = Stream access - sequence of access (data stream). See section 4.3.2 of the ISA for details. */3174/* 16 = Block access - program will soon make a transient access to EA. */3175/* 17 = Block access - program will not access EA for a long time. */3176
3177/* L field for dcbf: */3178/* 0 = invalidates the block containing EA in all processors. */3179/* 1 = same as 0, but with limited scope (i.e. block in the current processor will not be reused soon). */3180/* 3 = same as 1, but with even more limited scope (i.e. block in the current processor primary cache will not be reused soon). */3181if p.To.Type == obj.TYPE_NONE {3182o1 = AOP_RRR(c.oprrr(p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))3183} else {3184th := c.regoff(&p.To)3185o1 = AOP_RRR(c.oprrr(p.As), uint32(th), uint32(p.From.Index), uint32(p.From.Reg))3186}3187
3188case 44: /* indexed store */3189o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))3190
3191case 45: /* indexed load */3192switch p.As {3193/* The assembler accepts a 4-operand l*arx instruction. The fourth operand is an Exclusive Access Hint (EH) */3194/* The EH field can be used as a lock acquire/release hint as follows: */3195/* 0 = Atomic Update (fetch-and-operate or similar algorithm) */3196/* 1 = Exclusive Access (lock acquire and release) */3197case ALBAR, ALHAR, ALWAR, ALDAR:3198if p.From3Type() != obj.TYPE_NONE {3199eh := int(c.regoff(p.GetFrom3()))3200if eh > 1 {3201c.ctxt.Diag("illegal EH field\n%v", p)3202}3203o1 = AOP_RRRI(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg), uint32(eh))3204} else {3205o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))3206}3207default:3208o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))3209}3210case 46: /* plain op */3211o1 = c.oprrr(p.As)3212
3213case 47: /* op Ra, Rd; also op [Ra,] Rd */3214r := int(p.From.Reg)3215
3216if r == 0 {3217r = int(p.To.Reg)3218}3219o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)3220
3221case 48: /* op Rs, Ra */3222r := int(p.From.Reg)3223
3224if r == 0 {3225r = int(p.To.Reg)3226}3227o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)3228
3229case 49: /* op Rb; op $n, Rb */3230if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */3231v := c.regoff(&p.From) & 13232o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<213233} else {3234o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.From.Reg))3235}3236
3237case 50: /* rem[u] r1[,r2],r3 */3238r := int(p.Reg)3239
3240if r == 0 {3241r = int(p.To.Reg)3242}3243v := c.oprrr(p.As)3244t := v & (1<<10 | 1) /* OE|Rc */3245o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))3246o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))3247o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))3248if p.As == AREMU {3249o4 = o33250
3251/* Clear top 32 bits */3252o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<53253}3254
3255case 51: /* remd[u] r1[,r2],r3 */3256r := int(p.Reg)3257
3258if r == 0 {3259r = int(p.To.Reg)3260}3261v := c.oprrr(p.As)3262t := v & (1<<10 | 1) /* OE|Rc */3263o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))3264o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))3265o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))3266/* cases 50,51: removed; can be reused. */3267
3268/* cases 50,51: removed; can be reused. */3269
3270case 52: /* mtfsbNx cr(n) */3271v := c.regoff(&p.From) & 313272
3273o1 = AOP_RRR(c.oprrr(p.As), uint32(v), 0, 0)3274
3275case 53: /* mffsX ,fr1 */3276o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)3277
3278case 54: /* mov msr,r1; mov r1, msr*/3279if oclass(&p.From) == C_REG {3280if p.As == AMOVD {3281o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)3282} else {3283o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)3284}3285} else {3286o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)3287}3288
3289case 55: /* op Rb, Rd */3290o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg))3291
3292case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */3293v := c.regoff(&p.From)3294
3295r := int(p.Reg)3296if r == 0 {3297r = int(p.To.Reg)3298}3299o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31)3300if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) {3301o1 |= 1 << 1 /* mb[5] */3302}3303
3304case 57: /* slw $sh,[s,]a -> rlwinm ... */3305v := c.regoff(&p.From)3306
3307r := int(p.Reg)3308if r == 0 {3309r = int(p.To.Reg)3310}3311
3312/*3313* Let user (gs) shoot himself in the foot.
3314* qc has already complained.
3315*
3316if(v < 0 || v > 31)
3317ctxt->diag("illegal shift %ld\n%v", v, p);
3318*/
3319if v < 0 {3320v = 03321} else if v > 32 {3322v = 323323}3324var mask [2]uint83325switch p.As {3326case AROTLW:3327mask[0], mask[1] = 0, 313328case ASRW, ASRWCC:3329mask[0], mask[1] = uint8(v), 313330v = 32 - v3331default:3332mask[0], mask[1] = 0, uint8(31-v)3333}3334o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1]))3335if p.As == ASLWCC || p.As == ASRWCC {3336o1 |= 1 // set the condition code3337}3338
3339case 58: /* logical $andcon,[s],a */3340v := c.regoff(&p.From)3341
3342r := int(p.Reg)3343if r == 0 {3344r = int(p.To.Reg)3345}3346o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))3347
3348case 59: /* or/xor/and $ucon,,r | oris/xoris/andis $addcon,r,r */3349v := c.regoff(&p.From)3350
3351r := int(p.Reg)3352if r == 0 {3353r = int(p.To.Reg)3354}3355switch p.As {3356case AOR:3357o1 = LOP_IRR(c.opirr(AORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis. */3358case AXOR:3359o1 = LOP_IRR(c.opirr(AXORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)3360case AANDCC:3361o1 = LOP_IRR(c.opirr(AANDISCC), uint32(p.To.Reg), uint32(r), uint32(v)>>16)3362default:3363o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))3364}3365
3366case 60: /* tw to,a,b */3367r := int(c.regoff(&p.From) & 31)3368
3369o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg))3370
3371case 61: /* tw to,a,$simm */3372r := int(c.regoff(&p.From) & 31)3373
3374v := c.regoff(&p.To)3375o1 = AOP_IRR(c.opirr(p.As), uint32(r), uint32(p.Reg), uint32(v))3376
3377case 62: /* rlwmi $sh,s,$mask,a */3378v := c.regoff(&p.From)3379switch p.As {3380case ACLRLSLWI:3381b := c.regoff(p.GetFrom3())3382// This is an extended mnemonic described in the ISA C.8.23383// clrlslwi ra,rs,n,b -> rlwinm ra,rs,n,b-n,31-n3384// It maps onto rlwinm which is directly generated here.3385if v < 0 || v > 32 || b > 32 {3386c.ctxt.Diag("Invalid n or b for CLRLSLWI: %x %x\n%v", v, b)3387}3388o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.Reg), uint32(v), uint32(b-v), uint32(31-v))3389default:3390var mask [2]uint83391c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))3392o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))3393o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<13394}3395
3396case 63: /* rlwmi b,s,$mask,a */3397v := c.regoff(&p.From)3398switch p.As {3399case ACLRLSLWI:3400b := c.regoff(p.GetFrom3())3401if v > b || b > 32 {3402// Message will match operands from the ISA even though in the3403// code it uses 'v'3404c.ctxt.Diag("Invalid n or b for CLRLSLWI: %x %x\n%v", v, b)3405}3406// This is an extended mnemonic described in the ISA C.8.23407// clrlslwi ra,rs,n,b -> rlwinm ra,rs,n,b-n,31-n3408// It generates the rlwinm directly here.3409o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.Reg), uint32(v), uint32(b-v), uint32(31-v))3410default:3411var mask [2]uint83412c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))3413o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))3414o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<13415}3416
3417case 64: /* mtfsf fr[, $m] {,fpcsr} */3418var v int323419if p.From3Type() != obj.TYPE_NONE {3420v = c.regoff(p.GetFrom3()) & 2553421} else {3422v = 2553423}3424o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<113425
3426case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */3427if p.To.Reg == 0 {3428c.ctxt.Diag("must specify FPSCR(n)\n%v", p)3429}3430o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(c.regoff(&p.From))&31)<<123431
3432case 66: /* mov spr,r1; mov r1,spr, also dcr */3433var r int3434var v int323435if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {3436r = int(p.From.Reg)3437v = int32(p.To.Reg)3438if REG_DCR0 <= v && v <= REG_DCR0+1023 {3439o1 = OPVCC(31, 451, 0, 0) /* mtdcr */3440} else {3441o1 = OPVCC(31, 467, 0, 0) /* mtspr */3442}3443} else {3444r = int(p.To.Reg)3445v = int32(p.From.Reg)3446if REG_DCR0 <= v && v <= REG_DCR0+1023 {3447o1 = OPVCC(31, 323, 0, 0) /* mfdcr */3448} else {3449o1 = OPVCC(31, 339, 0, 0) /* mfspr */3450}3451}3452
3453o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<113454
3455case 67: /* mcrf crfD,crfS */3456if 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 {3457c.ctxt.Diag("illegal CR field number\n%v", p)3458}3459o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)3460
3461case 68: /* mfcr rD; mfocrf CRM,rD */3462if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {3463v := int32(1 << uint(7-(p.To.Reg&7))) /* CR(n) */3464o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */3465} else {3466o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */3467}3468
3469case 69: /* mtcrf CRM,rS */3470var v int323471if p.From3Type() != obj.TYPE_NONE {3472if p.To.Reg != 0 {3473c.ctxt.Diag("can't use both mask and CR(n)\n%v", p)3474}3475v = c.regoff(p.GetFrom3()) & 0xff3476} else {3477if p.To.Reg == 0 {3478v = 0xff /* CR */3479} else {3480v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */3481}3482}3483
3484o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<123485
3486case 70: /* [f]cmp r,r,cr*/3487var r int3488if p.Reg == 0 {3489r = 03490} else {3491r = (int(p.Reg) & 7) << 23492}3493o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))3494
3495case 71: /* cmp[l] r,i,cr*/3496var r int3497if p.Reg == 0 {3498r = 03499} else {3500r = (int(p.Reg) & 7) << 23501}3502o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(c.regoff(&p.To))&0xffff3503
3504case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */3505o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg))3506
3507case 73: /* mcrfs crfD,crfS */3508if 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 {3509c.ctxt.Diag("illegal FPSCR/CR field number\n%v", p)3510}3511o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)3512
3513case 77: /* syscall $scon, syscall Rx */3514if p.From.Type == obj.TYPE_CONST {3515if p.From.Offset > BIG || p.From.Offset < -BIG {3516c.ctxt.Diag("illegal syscall, sysnum too large: %v", p)3517}3518o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))3519} else if p.From.Type == obj.TYPE_REG {3520o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))3521} else {3522c.ctxt.Diag("illegal syscall: %v", p)3523o1 = 0x7fe00008 // trap always3524}3525
3526o2 = c.oprrr(p.As)3527o3 = AOP_RRR(c.oprrr(AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R03528
3529case 78: /* undef */3530o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed3531always to be an illegal instruction." */
3532
3533/* relocation operations */3534case 74:3535v := c.vregoff(&p.To)3536// Offsets in DS form stores must be a multiple of 43537inst := c.opstore(p.As)3538if c.opform(inst) == DS_FORM && v&0x3 != 0 {3539log.Fatalf("invalid offset for DS form load/store %v", p)3540}3541o1, o2 = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst)3542
3543//if(dlm) reloc(&p->to, p->pc, 1);3544
3545case 75:3546v := c.vregoff(&p.From)3547// Offsets in DS form loads must be a multiple of 43548inst := c.opload(p.As)3549if c.opform(inst) == DS_FORM && v&0x3 != 0 {3550log.Fatalf("invalid offset for DS form load/store %v", p)3551}3552o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)3553
3554//if(dlm) reloc(&p->from, p->pc, 1);3555
3556case 76:3557v := c.vregoff(&p.From)3558// Offsets in DS form loads must be a multiple of 43559inst := c.opload(p.As)3560if c.opform(inst) == DS_FORM && v&0x3 != 0 {3561log.Fatalf("invalid offset for DS form load/store %v", p)3562}3563o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)3564o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)3565
3566//if(dlm) reloc(&p->from, p->pc, 1);3567
3568case 79:3569if p.From.Offset != 0 {3570c.ctxt.Diag("invalid offset against tls var %v", p)3571}3572o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0)3573rel := obj.Addrel(c.cursym)3574rel.Off = int32(c.pc)3575rel.Siz = 43576rel.Sym = p.From.Sym3577rel.Type = objabi.R_POWER_TLS_LE3578
3579case 80:3580if p.From.Offset != 0 {3581c.ctxt.Diag("invalid offset against tls var %v", p)3582}3583o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)3584o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)3585rel := obj.Addrel(c.cursym)3586rel.Off = int32(c.pc)3587rel.Siz = 83588rel.Sym = p.From.Sym3589rel.Type = objabi.R_POWER_TLS_IE3590
3591case 81:3592v := c.vregoff(&p.To)3593if v != 0 {3594c.ctxt.Diag("invalid offset against GOT slot %v", p)3595}3596
3597o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)3598o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)3599rel := obj.Addrel(c.cursym)3600rel.Off = int32(c.pc)3601rel.Siz = 83602rel.Sym = p.From.Sym3603rel.Type = objabi.R_ADDRPOWER_GOT3604case 82: /* vector instructions, VX-form and VC-form */3605if p.From.Type == obj.TYPE_REG {3606/* reg reg none OR reg reg reg */3607/* 3-register operand order: VRA, VRB, VRT */3608/* 2-register operand order: VRA, VRT */3609o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))3610} else if p.From3Type() == obj.TYPE_CONST {3611/* imm imm reg reg */3612/* operand order: SIX, VRA, ST, VRT */3613six := int(c.regoff(&p.From))3614st := int(c.regoff(p.GetFrom3()))3615o1 = AOP_IIRR(c.opiirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(st), uint32(six))3616} else if p.From3Type() == obj.TYPE_NONE && p.Reg != 0 {3617/* imm reg reg */3618/* operand order: UIM, VRB, VRT */3619uim := int(c.regoff(&p.From))3620o1 = AOP_VIRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(uim))3621} else {3622/* imm reg */3623/* operand order: SIM, VRT */3624sim := int(c.regoff(&p.From))3625o1 = AOP_IR(c.opirr(p.As), uint32(p.To.Reg), uint32(sim))3626}3627
3628case 83: /* vector instructions, VA-form */3629if p.From.Type == obj.TYPE_REG {3630/* reg reg reg reg */3631/* 4-register operand order: VRA, VRB, VRC, VRT */3632o1 = AOP_RRRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))3633} else if p.From.Type == obj.TYPE_CONST {3634/* imm reg reg reg */3635/* operand order: SHB, VRA, VRB, VRT */3636shb := int(c.regoff(&p.From))3637o1 = AOP_IRRR(c.opirrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(shb))3638}3639
3640case 84: // ISEL BC,RA,RB,RT -> isel rt,ra,rb,bc3641bc := c.vregoff(&p.From)3642
3643// rt = To.Reg, ra = p.Reg, rb = p.From3.Reg3644o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(bc))3645
3646case 85: /* vector instructions, VX-form */3647/* reg none reg */3648/* 2-register operand order: VRB, VRT */3649o1 = AOP_RR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg))3650
3651case 86: /* VSX indexed store, XX1-form */3652/* reg reg reg */3653/* 3-register operand order: XT, (RB)(RA*1) */3654o1 = AOP_XX1(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))3655
3656case 87: /* VSX indexed load, XX1-form */3657/* reg reg reg */3658/* 3-register operand order: (RB)(RA*1), XT */3659o1 = AOP_XX1(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))3660
3661case 88: /* VSX instructions, XX1-form */3662/* reg reg none OR reg reg reg */3663/* 3-register operand order: RA, RB, XT */3664/* 2-register operand order: XS, RA or RA, XT */3665xt := int32(p.To.Reg)3666xs := int32(p.From.Reg)3667/* We need to treat the special case of extended mnemonics that may have a FREG/VREG as an argument */3668if REG_V0 <= xt && xt <= REG_V31 {3669/* Convert V0-V31 to VS32-VS63 */3670xt = xt + 643671o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))3672} else if REG_F0 <= xt && xt <= REG_F31 {3673/* Convert F0-F31 to VS0-VS31 */3674xt = xt + 643675o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))3676} else if REG_VS0 <= xt && xt <= REG_VS63 {3677o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))3678} else if REG_V0 <= xs && xs <= REG_V31 {3679/* Likewise for XS */3680xs = xs + 643681o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))3682} else if REG_F0 <= xs && xs <= REG_F31 {3683xs = xs + 643684o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))3685} else if REG_VS0 <= xs && xs <= REG_VS63 {3686o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))3687}3688
3689case 89: /* VSX instructions, XX2-form */3690/* reg none reg OR reg imm reg */3691/* 2-register operand order: XB, XT or XB, UIM, XT*/3692uim := int(c.regoff(p.GetFrom3()))3693o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(uim), uint32(p.From.Reg))3694
3695case 90: /* VSX instructions, XX3-form */3696if p.From3Type() == obj.TYPE_NONE {3697/* reg reg reg */3698/* 3-register operand order: XA, XB, XT */3699o1 = AOP_XX3(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))3700} else if p.From3Type() == obj.TYPE_CONST {3701/* reg reg reg imm */3702/* operand order: XA, XB, DM, XT */3703dm := int(c.regoff(p.GetFrom3()))3704o1 = AOP_XX3I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(dm))3705}3706
3707case 91: /* VSX instructions, XX4-form */3708/* reg reg reg reg */3709/* 3-register operand order: XA, XB, XC, XT */3710o1 = AOP_XX4(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))3711
3712case 92: /* X-form instructions, 3-operands */3713if p.To.Type == obj.TYPE_CONST {3714/* imm reg reg */3715xf := int32(p.From.Reg)3716if REG_F0 <= xf && xf <= REG_F31 {3717/* operand order: FRA, FRB, BF */3718bf := int(c.regoff(&p.To)) << 23719o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))3720} else {3721/* operand order: RA, RB, L */3722l := int(c.regoff(&p.To))3723o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.From.Reg), uint32(p.Reg))3724}3725} else if p.From3Type() == obj.TYPE_CONST {3726/* reg reg imm */3727/* operand order: RB, L, RA */3728l := int(c.regoff(p.GetFrom3()))3729o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.To.Reg), uint32(p.From.Reg))3730} else if p.To.Type == obj.TYPE_REG {3731cr := int32(p.To.Reg)3732if REG_CR0 <= cr && cr <= REG_CR7 {3733/* cr reg reg */3734/* operand order: RA, RB, BF */3735bf := (int(p.To.Reg) & 7) << 23736o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))3737} else if p.From.Type == obj.TYPE_CONST {3738/* reg imm */3739/* operand order: L, RT */3740l := int(c.regoff(&p.From))3741o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(l), uint32(p.Reg))3742} else {3743switch p.As {3744case ACOPY, APASTECC:3745o1 = AOP_RRR(c.opirr(p.As), uint32(1), uint32(p.From.Reg), uint32(p.To.Reg))3746default:3747/* reg reg reg */3748/* operand order: RS, RB, RA */3749o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))3750}3751}3752}3753
3754case 93: /* X-form instructions, 2-operands */3755if p.To.Type == obj.TYPE_CONST {3756/* imm reg */3757/* operand order: FRB, BF */3758bf := int(c.regoff(&p.To)) << 23759o1 = AOP_RR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg))3760} else if p.Reg == 0 {3761/* popcnt* r,r, X-form */3762/* operand order: RS, RA */3763o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))3764}3765
3766case 94: /* Z23-form instructions, 4-operands */3767/* reg reg reg imm */3768/* operand order: RA, RB, CY, RT */3769cy := int(c.regoff(p.GetFrom3()))3770o1 = AOP_Z23I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(cy))3771
3772case 95: /* Retrieve TOC relative symbol */3773/* This code is for AIX only */3774v := c.vregoff(&p.From)3775if v != 0 {3776c.ctxt.Diag("invalid offset against TOC slot %v", p)3777}3778
3779inst := c.opload(p.As)3780if c.opform(inst) != DS_FORM {3781c.ctxt.Diag("invalid form for a TOC access in %v", p)3782}3783
3784o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)3785o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)3786rel := obj.Addrel(c.cursym)3787rel.Off = int32(c.pc)3788rel.Siz = 83789rel.Sym = p.From.Sym3790rel.Type = objabi.R_ADDRPOWER_TOCREL_DS3791
3792case 96: /* VSX load, DQ-form */3793/* reg imm reg */3794/* operand order: (RA)(DQ), XT */3795dq := int16(c.regoff(&p.From))3796if (dq & 15) != 0 {3797c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)3798}3799o1 = AOP_DQ(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(dq))3800
3801case 97: /* VSX store, DQ-form */3802/* reg imm reg */3803/* operand order: XT, (RA)(DQ) */3804dq := int16(c.regoff(&p.To))3805if (dq & 15) != 0 {3806c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)3807}3808o1 = AOP_DQ(c.opstore(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(dq))3809case 98: /* VSX indexed load or load with length (also left-justified), x-form */3810/* vsreg, reg, reg */3811o1 = AOP_XX1(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))3812case 99: /* VSX store with length (also left-justified) x-form */3813/* reg, reg, vsreg */3814o1 = AOP_XX1(c.opstore(p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(p.To.Reg))3815case 100: /* VSX X-form XXSPLTIB */3816if p.From.Type == obj.TYPE_CONST {3817/* imm reg */3818uim := int(c.regoff(&p.From))3819/* imm reg */3820/* Use AOP_XX1 form with 0 for one of the registers. */3821o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(uim))3822} else {3823c.ctxt.Diag("invalid ops for %v", p.As)3824}3825case 101:3826o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))3827}3828
3829out[0] = o13830out[1] = o23831out[2] = o33832out[3] = o43833out[4] = o53834}
3835
3836func (c *ctxt9) vregoff(a *obj.Addr) int64 {3837c.instoffset = 03838if a != nil {3839c.aclass(a)3840}3841return c.instoffset3842}
3843
3844func (c *ctxt9) regoff(a *obj.Addr) int32 {3845return int32(c.vregoff(a))3846}
3847
3848func (c *ctxt9) oprrr(a obj.As) uint32 {3849switch a {3850case AADD:3851return OPVCC(31, 266, 0, 0)3852case AADDCC:3853return OPVCC(31, 266, 0, 1)3854case AADDV:3855return OPVCC(31, 266, 1, 0)3856case AADDVCC:3857return OPVCC(31, 266, 1, 1)3858case AADDC:3859return OPVCC(31, 10, 0, 0)3860case AADDCCC:3861return OPVCC(31, 10, 0, 1)3862case AADDCV:3863return OPVCC(31, 10, 1, 0)3864case AADDCVCC:3865return OPVCC(31, 10, 1, 1)3866case AADDE:3867return OPVCC(31, 138, 0, 0)3868case AADDECC:3869return OPVCC(31, 138, 0, 1)3870case AADDEV:3871return OPVCC(31, 138, 1, 0)3872case AADDEVCC:3873return OPVCC(31, 138, 1, 1)3874case AADDME:3875return OPVCC(31, 234, 0, 0)3876case AADDMECC:3877return OPVCC(31, 234, 0, 1)3878case AADDMEV:3879return OPVCC(31, 234, 1, 0)3880case AADDMEVCC:3881return OPVCC(31, 234, 1, 1)3882case AADDZE:3883return OPVCC(31, 202, 0, 0)3884case AADDZECC:3885return OPVCC(31, 202, 0, 1)3886case AADDZEV:3887return OPVCC(31, 202, 1, 0)3888case AADDZEVCC:3889return OPVCC(31, 202, 1, 1)3890case AADDEX:3891return OPVCC(31, 170, 0, 0) /* addex - v3.0b */3892
3893case AAND:3894return OPVCC(31, 28, 0, 0)3895case AANDCC:3896return OPVCC(31, 28, 0, 1)3897case AANDN:3898return OPVCC(31, 60, 0, 0)3899case AANDNCC:3900return OPVCC(31, 60, 0, 1)3901
3902case ACMP:3903return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */3904case ACMPU:3905return OPVCC(31, 32, 0, 0) | 1<<213906case ACMPW:3907return OPVCC(31, 0, 0, 0) /* L=0 */3908case ACMPWU:3909return OPVCC(31, 32, 0, 0)3910case ACMPB:3911return OPVCC(31, 508, 0, 0) /* cmpb - v2.05 */3912case ACMPEQB:3913return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */3914
3915case ACNTLZW:3916return OPVCC(31, 26, 0, 0)3917case ACNTLZWCC:3918return OPVCC(31, 26, 0, 1)3919case ACNTLZD:3920return OPVCC(31, 58, 0, 0)3921case ACNTLZDCC:3922return OPVCC(31, 58, 0, 1)3923
3924case ACRAND:3925return OPVCC(19, 257, 0, 0)3926case ACRANDN:3927return OPVCC(19, 129, 0, 0)3928case ACREQV:3929return OPVCC(19, 289, 0, 0)3930case ACRNAND:3931return OPVCC(19, 225, 0, 0)3932case ACRNOR:3933return OPVCC(19, 33, 0, 0)3934case ACROR:3935return OPVCC(19, 449, 0, 0)3936case ACRORN:3937return OPVCC(19, 417, 0, 0)3938case ACRXOR:3939return OPVCC(19, 193, 0, 0)3940
3941case ADCBF:3942return OPVCC(31, 86, 0, 0)3943case ADCBI:3944return OPVCC(31, 470, 0, 0)3945case ADCBST:3946return OPVCC(31, 54, 0, 0)3947case ADCBT:3948return OPVCC(31, 278, 0, 0)3949case ADCBTST:3950return OPVCC(31, 246, 0, 0)3951case ADCBZ:3952return OPVCC(31, 1014, 0, 0)3953
3954case AMODUD:3955return OPVCC(31, 265, 0, 0) /* modud - v3.0 */3956case AMODUW:3957return OPVCC(31, 267, 0, 0) /* moduw - v3.0 */3958case AMODSD:3959return OPVCC(31, 777, 0, 0) /* modsd - v3.0 */3960case AMODSW:3961return OPVCC(31, 779, 0, 0) /* modsw - v3.0 */3962
3963case ADIVW, AREM:3964return OPVCC(31, 491, 0, 0)3965
3966case ADIVWCC:3967return OPVCC(31, 491, 0, 1)3968
3969case ADIVWV:3970return OPVCC(31, 491, 1, 0)3971
3972case ADIVWVCC:3973return OPVCC(31, 491, 1, 1)3974
3975case ADIVWU, AREMU:3976return OPVCC(31, 459, 0, 0)3977
3978case ADIVWUCC:3979return OPVCC(31, 459, 0, 1)3980
3981case ADIVWUV:3982return OPVCC(31, 459, 1, 0)3983
3984case ADIVWUVCC:3985return OPVCC(31, 459, 1, 1)3986
3987case ADIVD, AREMD:3988return OPVCC(31, 489, 0, 0)3989
3990case ADIVDCC:3991return OPVCC(31, 489, 0, 1)3992
3993case ADIVDE:3994return OPVCC(31, 425, 0, 0)3995
3996case ADIVDECC:3997return OPVCC(31, 425, 0, 1)3998
3999case ADIVDEU:4000return OPVCC(31, 393, 0, 0)4001
4002case ADIVDEUCC:4003return OPVCC(31, 393, 0, 1)4004
4005case ADIVDV:4006return OPVCC(31, 489, 1, 0)4007
4008case ADIVDVCC:4009return OPVCC(31, 489, 1, 1)4010
4011case ADIVDU, AREMDU:4012return OPVCC(31, 457, 0, 0)4013
4014case ADIVDUCC:4015return OPVCC(31, 457, 0, 1)4016
4017case ADIVDUV:4018return OPVCC(31, 457, 1, 0)4019
4020case ADIVDUVCC:4021return OPVCC(31, 457, 1, 1)4022
4023case AEIEIO:4024return OPVCC(31, 854, 0, 0)4025
4026case AEQV:4027return OPVCC(31, 284, 0, 0)4028case AEQVCC:4029return OPVCC(31, 284, 0, 1)4030
4031case AEXTSB:4032return OPVCC(31, 954, 0, 0)4033case AEXTSBCC:4034return OPVCC(31, 954, 0, 1)4035case AEXTSH:4036return OPVCC(31, 922, 0, 0)4037case AEXTSHCC:4038return OPVCC(31, 922, 0, 1)4039case AEXTSW:4040return OPVCC(31, 986, 0, 0)4041case AEXTSWCC:4042return OPVCC(31, 986, 0, 1)4043
4044case AFABS:4045return OPVCC(63, 264, 0, 0)4046case AFABSCC:4047return OPVCC(63, 264, 0, 1)4048case AFADD:4049return OPVCC(63, 21, 0, 0)4050case AFADDCC:4051return OPVCC(63, 21, 0, 1)4052case AFADDS:4053return OPVCC(59, 21, 0, 0)4054case AFADDSCC:4055return OPVCC(59, 21, 0, 1)4056case AFCMPO:4057return OPVCC(63, 32, 0, 0)4058case AFCMPU:4059return OPVCC(63, 0, 0, 0)4060case AFCFID:4061return OPVCC(63, 846, 0, 0)4062case AFCFIDCC:4063return OPVCC(63, 846, 0, 1)4064case AFCFIDU:4065return OPVCC(63, 974, 0, 0)4066case AFCFIDUCC:4067return OPVCC(63, 974, 0, 1)4068case AFCFIDS:4069return OPVCC(59, 846, 0, 0)4070case AFCFIDSCC:4071return OPVCC(59, 846, 0, 1)4072case AFCTIW:4073return OPVCC(63, 14, 0, 0)4074case AFCTIWCC:4075return OPVCC(63, 14, 0, 1)4076case AFCTIWZ:4077return OPVCC(63, 15, 0, 0)4078case AFCTIWZCC:4079return OPVCC(63, 15, 0, 1)4080case AFCTID:4081return OPVCC(63, 814, 0, 0)4082case AFCTIDCC:4083return OPVCC(63, 814, 0, 1)4084case AFCTIDZ:4085return OPVCC(63, 815, 0, 0)4086case AFCTIDZCC:4087return OPVCC(63, 815, 0, 1)4088case AFDIV:4089return OPVCC(63, 18, 0, 0)4090case AFDIVCC:4091return OPVCC(63, 18, 0, 1)4092case AFDIVS:4093return OPVCC(59, 18, 0, 0)4094case AFDIVSCC:4095return OPVCC(59, 18, 0, 1)4096case AFMADD:4097return OPVCC(63, 29, 0, 0)4098case AFMADDCC:4099return OPVCC(63, 29, 0, 1)4100case AFMADDS:4101return OPVCC(59, 29, 0, 0)4102case AFMADDSCC:4103return OPVCC(59, 29, 0, 1)4104
4105case AFMOVS, AFMOVD:4106return OPVCC(63, 72, 0, 0) /* load */4107case AFMOVDCC:4108return OPVCC(63, 72, 0, 1)4109case AFMSUB:4110return OPVCC(63, 28, 0, 0)4111case AFMSUBCC:4112return OPVCC(63, 28, 0, 1)4113case AFMSUBS:4114return OPVCC(59, 28, 0, 0)4115case AFMSUBSCC:4116return OPVCC(59, 28, 0, 1)4117case AFMUL:4118return OPVCC(63, 25, 0, 0)4119case AFMULCC:4120return OPVCC(63, 25, 0, 1)4121case AFMULS:4122return OPVCC(59, 25, 0, 0)4123case AFMULSCC:4124return OPVCC(59, 25, 0, 1)4125case AFNABS:4126return OPVCC(63, 136, 0, 0)4127case AFNABSCC:4128return OPVCC(63, 136, 0, 1)4129case AFNEG:4130return OPVCC(63, 40, 0, 0)4131case AFNEGCC:4132return OPVCC(63, 40, 0, 1)4133case AFNMADD:4134return OPVCC(63, 31, 0, 0)4135case AFNMADDCC:4136return OPVCC(63, 31, 0, 1)4137case AFNMADDS:4138return OPVCC(59, 31, 0, 0)4139case AFNMADDSCC:4140return OPVCC(59, 31, 0, 1)4141case AFNMSUB:4142return OPVCC(63, 30, 0, 0)4143case AFNMSUBCC:4144return OPVCC(63, 30, 0, 1)4145case AFNMSUBS:4146return OPVCC(59, 30, 0, 0)4147case AFNMSUBSCC:4148return OPVCC(59, 30, 0, 1)4149case AFCPSGN:4150return OPVCC(63, 8, 0, 0)4151case AFCPSGNCC:4152return OPVCC(63, 8, 0, 1)4153case AFRES:4154return OPVCC(59, 24, 0, 0)4155case AFRESCC:4156return OPVCC(59, 24, 0, 1)4157case AFRIM:4158return OPVCC(63, 488, 0, 0)4159case AFRIMCC:4160return OPVCC(63, 488, 0, 1)4161case AFRIP:4162return OPVCC(63, 456, 0, 0)4163case AFRIPCC:4164return OPVCC(63, 456, 0, 1)4165case AFRIZ:4166return OPVCC(63, 424, 0, 0)4167case AFRIZCC:4168return OPVCC(63, 424, 0, 1)4169case AFRIN:4170return OPVCC(63, 392, 0, 0)4171case AFRINCC:4172return OPVCC(63, 392, 0, 1)4173case AFRSP:4174return OPVCC(63, 12, 0, 0)4175case AFRSPCC:4176return OPVCC(63, 12, 0, 1)4177case AFRSQRTE:4178return OPVCC(63, 26, 0, 0)4179case AFRSQRTECC:4180return OPVCC(63, 26, 0, 1)4181case AFSEL:4182return OPVCC(63, 23, 0, 0)4183case AFSELCC:4184return OPVCC(63, 23, 0, 1)4185case AFSQRT:4186return OPVCC(63, 22, 0, 0)4187case AFSQRTCC:4188return OPVCC(63, 22, 0, 1)4189case AFSQRTS:4190return OPVCC(59, 22, 0, 0)4191case AFSQRTSCC:4192return OPVCC(59, 22, 0, 1)4193case AFSUB:4194return OPVCC(63, 20, 0, 0)4195case AFSUBCC:4196return OPVCC(63, 20, 0, 1)4197case AFSUBS:4198return OPVCC(59, 20, 0, 0)4199case AFSUBSCC:4200return OPVCC(59, 20, 0, 1)4201
4202case AICBI:4203return OPVCC(31, 982, 0, 0)4204case AISYNC:4205return OPVCC(19, 150, 0, 0)4206
4207case AMTFSB0:4208return OPVCC(63, 70, 0, 0)4209case AMTFSB0CC:4210return OPVCC(63, 70, 0, 1)4211case AMTFSB1:4212return OPVCC(63, 38, 0, 0)4213case AMTFSB1CC:4214return OPVCC(63, 38, 0, 1)4215
4216case AMULHW:4217return OPVCC(31, 75, 0, 0)4218case AMULHWCC:4219return OPVCC(31, 75, 0, 1)4220case AMULHWU:4221return OPVCC(31, 11, 0, 0)4222case AMULHWUCC:4223return OPVCC(31, 11, 0, 1)4224case AMULLW:4225return OPVCC(31, 235, 0, 0)4226case AMULLWCC:4227return OPVCC(31, 235, 0, 1)4228case AMULLWV:4229return OPVCC(31, 235, 1, 0)4230case AMULLWVCC:4231return OPVCC(31, 235, 1, 1)4232
4233case AMULHD:4234return OPVCC(31, 73, 0, 0)4235case AMULHDCC:4236return OPVCC(31, 73, 0, 1)4237case AMULHDU:4238return OPVCC(31, 9, 0, 0)4239case AMULHDUCC:4240return OPVCC(31, 9, 0, 1)4241case AMULLD:4242return OPVCC(31, 233, 0, 0)4243case AMULLDCC:4244return OPVCC(31, 233, 0, 1)4245case AMULLDV:4246return OPVCC(31, 233, 1, 0)4247case AMULLDVCC:4248return OPVCC(31, 233, 1, 1)4249
4250case ANAND:4251return OPVCC(31, 476, 0, 0)4252case ANANDCC:4253return OPVCC(31, 476, 0, 1)4254case ANEG:4255return OPVCC(31, 104, 0, 0)4256case ANEGCC:4257return OPVCC(31, 104, 0, 1)4258case ANEGV:4259return OPVCC(31, 104, 1, 0)4260case ANEGVCC:4261return OPVCC(31, 104, 1, 1)4262case ANOR:4263return OPVCC(31, 124, 0, 0)4264case ANORCC:4265return OPVCC(31, 124, 0, 1)4266case AOR:4267return OPVCC(31, 444, 0, 0)4268case AORCC:4269return OPVCC(31, 444, 0, 1)4270case AORN:4271return OPVCC(31, 412, 0, 0)4272case AORNCC:4273return OPVCC(31, 412, 0, 1)4274
4275case APOPCNTD:4276return OPVCC(31, 506, 0, 0) /* popcntd - v2.06 */4277case APOPCNTW:4278return OPVCC(31, 378, 0, 0) /* popcntw - v2.06 */4279case APOPCNTB:4280return OPVCC(31, 122, 0, 0) /* popcntb - v2.02 */4281case ACNTTZW:4282return OPVCC(31, 538, 0, 0) /* cnttzw - v3.00 */4283case ACNTTZWCC:4284return OPVCC(31, 538, 0, 1) /* cnttzw. - v3.00 */4285case ACNTTZD:4286return OPVCC(31, 570, 0, 0) /* cnttzd - v3.00 */4287case ACNTTZDCC:4288return OPVCC(31, 570, 0, 1) /* cnttzd. - v3.00 */4289
4290case ARFI:4291return OPVCC(19, 50, 0, 0)4292case ARFCI:4293return OPVCC(19, 51, 0, 0)4294case ARFID:4295return OPVCC(19, 18, 0, 0)4296case AHRFID:4297return OPVCC(19, 274, 0, 0)4298
4299case ARLWMI:4300return OPVCC(20, 0, 0, 0)4301case ARLWMICC:4302return OPVCC(20, 0, 0, 1)4303case ARLWNM:4304return OPVCC(23, 0, 0, 0)4305case ARLWNMCC:4306return OPVCC(23, 0, 0, 1)4307
4308case ARLDCL:4309return OPVCC(30, 8, 0, 0)4310case ARLDCLCC:4311return OPVCC(30, 0, 0, 1)4312
4313case ARLDCR:4314return OPVCC(30, 9, 0, 0)4315case ARLDCRCC:4316return OPVCC(30, 9, 0, 1)4317
4318case ARLDICL:4319return OPVCC(30, 0, 0, 0)4320case ARLDICLCC:4321return OPVCC(30, 0, 0, 1)4322case ARLDICR:4323return OPVCC(30, 0, 0, 0) | 2<<1 // rldicr4324case ARLDICRCC:4325return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr.4326
4327case ARLDIC:4328return OPVCC(30, 0, 0, 0) | 4<<1 // rldic4329case ARLDICCC:4330return OPVCC(30, 0, 0, 1) | 4<<1 // rldic.4331
4332case ASYSCALL:4333return OPVCC(17, 1, 0, 0)4334
4335case ASLW:4336return OPVCC(31, 24, 0, 0)4337case ASLWCC:4338return OPVCC(31, 24, 0, 1)4339case ASLD:4340return OPVCC(31, 27, 0, 0)4341case ASLDCC:4342return OPVCC(31, 27, 0, 1)4343
4344case ASRAW:4345return OPVCC(31, 792, 0, 0)4346case ASRAWCC:4347return OPVCC(31, 792, 0, 1)4348case ASRAD:4349return OPVCC(31, 794, 0, 0)4350case ASRADCC:4351return OPVCC(31, 794, 0, 1)4352
4353case ASRW:4354return OPVCC(31, 536, 0, 0)4355case ASRWCC:4356return OPVCC(31, 536, 0, 1)4357case ASRD:4358return OPVCC(31, 539, 0, 0)4359case ASRDCC:4360return OPVCC(31, 539, 0, 1)4361
4362case ASUB:4363return OPVCC(31, 40, 0, 0)4364case ASUBCC:4365return OPVCC(31, 40, 0, 1)4366case ASUBV:4367return OPVCC(31, 40, 1, 0)4368case ASUBVCC:4369return OPVCC(31, 40, 1, 1)4370case ASUBC:4371return OPVCC(31, 8, 0, 0)4372case ASUBCCC:4373return OPVCC(31, 8, 0, 1)4374case ASUBCV:4375return OPVCC(31, 8, 1, 0)4376case ASUBCVCC:4377return OPVCC(31, 8, 1, 1)4378case ASUBE:4379return OPVCC(31, 136, 0, 0)4380case ASUBECC:4381return OPVCC(31, 136, 0, 1)4382case ASUBEV:4383return OPVCC(31, 136, 1, 0)4384case ASUBEVCC:4385return OPVCC(31, 136, 1, 1)4386case ASUBME:4387return OPVCC(31, 232, 0, 0)4388case ASUBMECC:4389return OPVCC(31, 232, 0, 1)4390case ASUBMEV:4391return OPVCC(31, 232, 1, 0)4392case ASUBMEVCC:4393return OPVCC(31, 232, 1, 1)4394case ASUBZE:4395return OPVCC(31, 200, 0, 0)4396case ASUBZECC:4397return OPVCC(31, 200, 0, 1)4398case ASUBZEV:4399return OPVCC(31, 200, 1, 0)4400case ASUBZEVCC:4401return OPVCC(31, 200, 1, 1)4402
4403case ASYNC:4404return OPVCC(31, 598, 0, 0)4405case ALWSYNC:4406return OPVCC(31, 598, 0, 0) | 1<<214407
4408case APTESYNC:4409return OPVCC(31, 598, 0, 0) | 2<<214410
4411case ATLBIE:4412return OPVCC(31, 306, 0, 0)4413case ATLBIEL:4414return OPVCC(31, 274, 0, 0)4415case ATLBSYNC:4416return OPVCC(31, 566, 0, 0)4417case ASLBIA:4418return OPVCC(31, 498, 0, 0)4419case ASLBIE:4420return OPVCC(31, 434, 0, 0)4421case ASLBMFEE:4422return OPVCC(31, 915, 0, 0)4423case ASLBMFEV:4424return OPVCC(31, 851, 0, 0)4425case ASLBMTE:4426return OPVCC(31, 402, 0, 0)4427
4428case ATW:4429return OPVCC(31, 4, 0, 0)4430case ATD:4431return OPVCC(31, 68, 0, 0)4432
4433/* Vector (VMX/Altivec) instructions */4434/* ISA 2.03 enables these for PPC970. For POWERx processors, these */4435/* are enabled starting at POWER6 (ISA 2.05). */4436case AVAND:4437return OPVX(4, 1028, 0, 0) /* vand - v2.03 */4438case AVANDC:4439return OPVX(4, 1092, 0, 0) /* vandc - v2.03 */4440case AVNAND:4441return OPVX(4, 1412, 0, 0) /* vnand - v2.07 */4442
4443case AVOR:4444return OPVX(4, 1156, 0, 0) /* vor - v2.03 */4445case AVORC:4446return OPVX(4, 1348, 0, 0) /* vorc - v2.07 */4447case AVNOR:4448return OPVX(4, 1284, 0, 0) /* vnor - v2.03 */4449case AVXOR:4450return OPVX(4, 1220, 0, 0) /* vxor - v2.03 */4451case AVEQV:4452return OPVX(4, 1668, 0, 0) /* veqv - v2.07 */4453
4454case AVADDUBM:4455return OPVX(4, 0, 0, 0) /* vaddubm - v2.03 */4456case AVADDUHM:4457return OPVX(4, 64, 0, 0) /* vadduhm - v2.03 */4458case AVADDUWM:4459return OPVX(4, 128, 0, 0) /* vadduwm - v2.03 */4460case AVADDUDM:4461return OPVX(4, 192, 0, 0) /* vaddudm - v2.07 */4462case AVADDUQM:4463return OPVX(4, 256, 0, 0) /* vadduqm - v2.07 */4464
4465case AVADDCUQ:4466return OPVX(4, 320, 0, 0) /* vaddcuq - v2.07 */4467case AVADDCUW:4468return OPVX(4, 384, 0, 0) /* vaddcuw - v2.03 */4469
4470case AVADDUBS:4471return OPVX(4, 512, 0, 0) /* vaddubs - v2.03 */4472case AVADDUHS:4473return OPVX(4, 576, 0, 0) /* vadduhs - v2.03 */4474case AVADDUWS:4475return OPVX(4, 640, 0, 0) /* vadduws - v2.03 */4476
4477case AVADDSBS:4478return OPVX(4, 768, 0, 0) /* vaddsbs - v2.03 */4479case AVADDSHS:4480return OPVX(4, 832, 0, 0) /* vaddshs - v2.03 */4481case AVADDSWS:4482return OPVX(4, 896, 0, 0) /* vaddsws - v2.03 */4483
4484case AVADDEUQM:4485return OPVX(4, 60, 0, 0) /* vaddeuqm - v2.07 */4486case AVADDECUQ:4487return OPVX(4, 61, 0, 0) /* vaddecuq - v2.07 */4488
4489case AVMULESB:4490return OPVX(4, 776, 0, 0) /* vmulesb - v2.03 */4491case AVMULOSB:4492return OPVX(4, 264, 0, 0) /* vmulosb - v2.03 */4493case AVMULEUB:4494return OPVX(4, 520, 0, 0) /* vmuleub - v2.03 */4495case AVMULOUB:4496return OPVX(4, 8, 0, 0) /* vmuloub - v2.03 */4497case AVMULESH:4498return OPVX(4, 840, 0, 0) /* vmulesh - v2.03 */4499case AVMULOSH:4500return OPVX(4, 328, 0, 0) /* vmulosh - v2.03 */4501case AVMULEUH:4502return OPVX(4, 584, 0, 0) /* vmuleuh - v2.03 */4503case AVMULOUH:4504return OPVX(4, 72, 0, 0) /* vmulouh - v2.03 */4505case AVMULESW:4506return OPVX(4, 904, 0, 0) /* vmulesw - v2.07 */4507case AVMULOSW:4508return OPVX(4, 392, 0, 0) /* vmulosw - v2.07 */4509case AVMULEUW:4510return OPVX(4, 648, 0, 0) /* vmuleuw - v2.07 */4511case AVMULOUW:4512return OPVX(4, 136, 0, 0) /* vmulouw - v2.07 */4513case AVMULUWM:4514return OPVX(4, 137, 0, 0) /* vmuluwm - v2.07 */4515
4516case AVPMSUMB:4517return OPVX(4, 1032, 0, 0) /* vpmsumb - v2.07 */4518case AVPMSUMH:4519return OPVX(4, 1096, 0, 0) /* vpmsumh - v2.07 */4520case AVPMSUMW:4521return OPVX(4, 1160, 0, 0) /* vpmsumw - v2.07 */4522case AVPMSUMD:4523return OPVX(4, 1224, 0, 0) /* vpmsumd - v2.07 */4524
4525case AVMSUMUDM:4526return OPVX(4, 35, 0, 0) /* vmsumudm - v3.00b */4527
4528case AVSUBUBM:4529return OPVX(4, 1024, 0, 0) /* vsububm - v2.03 */4530case AVSUBUHM:4531return OPVX(4, 1088, 0, 0) /* vsubuhm - v2.03 */4532case AVSUBUWM:4533return OPVX(4, 1152, 0, 0) /* vsubuwm - v2.03 */4534case AVSUBUDM:4535return OPVX(4, 1216, 0, 0) /* vsubudm - v2.07 */4536case AVSUBUQM:4537return OPVX(4, 1280, 0, 0) /* vsubuqm - v2.07 */4538
4539case AVSUBCUQ:4540return OPVX(4, 1344, 0, 0) /* vsubcuq - v2.07 */4541case AVSUBCUW:4542return OPVX(4, 1408, 0, 0) /* vsubcuw - v2.03 */4543
4544case AVSUBUBS:4545return OPVX(4, 1536, 0, 0) /* vsububs - v2.03 */4546case AVSUBUHS:4547return OPVX(4, 1600, 0, 0) /* vsubuhs - v2.03 */4548case AVSUBUWS:4549return OPVX(4, 1664, 0, 0) /* vsubuws - v2.03 */4550
4551case AVSUBSBS:4552return OPVX(4, 1792, 0, 0) /* vsubsbs - v2.03 */4553case AVSUBSHS:4554return OPVX(4, 1856, 0, 0) /* vsubshs - v2.03 */4555case AVSUBSWS:4556return OPVX(4, 1920, 0, 0) /* vsubsws - v2.03 */4557
4558case AVSUBEUQM:4559return OPVX(4, 62, 0, 0) /* vsubeuqm - v2.07 */4560case AVSUBECUQ:4561return OPVX(4, 63, 0, 0) /* vsubecuq - v2.07 */4562
4563case AVRLB:4564return OPVX(4, 4, 0, 0) /* vrlb - v2.03 */4565case AVRLH:4566return OPVX(4, 68, 0, 0) /* vrlh - v2.03 */4567case AVRLW:4568return OPVX(4, 132, 0, 0) /* vrlw - v2.03 */4569case AVRLD:4570return OPVX(4, 196, 0, 0) /* vrld - v2.07 */4571
4572case AVMRGOW:4573return OPVX(4, 1676, 0, 0) /* vmrgow - v2.07 */4574case AVMRGEW:4575return OPVX(4, 1932, 0, 0) /* vmrgew - v2.07 */4576
4577case AVSLB:4578return OPVX(4, 260, 0, 0) /* vslh - v2.03 */4579case AVSLH:4580return OPVX(4, 324, 0, 0) /* vslh - v2.03 */4581case AVSLW:4582return OPVX(4, 388, 0, 0) /* vslw - v2.03 */4583case AVSL:4584return OPVX(4, 452, 0, 0) /* vsl - v2.03 */4585case AVSLO:4586return OPVX(4, 1036, 0, 0) /* vsl - v2.03 */4587case AVSRB:4588return OPVX(4, 516, 0, 0) /* vsrb - v2.03 */4589case AVSRH:4590return OPVX(4, 580, 0, 0) /* vsrh - v2.03 */4591case AVSRW:4592return OPVX(4, 644, 0, 0) /* vsrw - v2.03 */4593case AVSR:4594return OPVX(4, 708, 0, 0) /* vsr - v2.03 */4595case AVSRO:4596return OPVX(4, 1100, 0, 0) /* vsro - v2.03 */4597case AVSLD:4598return OPVX(4, 1476, 0, 0) /* vsld - v2.07 */4599case AVSRD:4600return OPVX(4, 1732, 0, 0) /* vsrd - v2.07 */4601
4602case AVSRAB:4603return OPVX(4, 772, 0, 0) /* vsrab - v2.03 */4604case AVSRAH:4605return OPVX(4, 836, 0, 0) /* vsrah - v2.03 */4606case AVSRAW:4607return OPVX(4, 900, 0, 0) /* vsraw - v2.03 */4608case AVSRAD:4609return OPVX(4, 964, 0, 0) /* vsrad - v2.07 */4610
4611case AVBPERMQ:4612return OPVC(4, 1356, 0, 0) /* vbpermq - v2.07 */4613case AVBPERMD:4614return OPVC(4, 1484, 0, 0) /* vbpermd - v3.00 */4615
4616case AVCLZB:4617return OPVX(4, 1794, 0, 0) /* vclzb - v2.07 */4618case AVCLZH:4619return OPVX(4, 1858, 0, 0) /* vclzh - v2.07 */4620case AVCLZW:4621return OPVX(4, 1922, 0, 0) /* vclzw - v2.07 */4622case AVCLZD:4623return OPVX(4, 1986, 0, 0) /* vclzd - v2.07 */4624
4625case AVPOPCNTB:4626return OPVX(4, 1795, 0, 0) /* vpopcntb - v2.07 */4627case AVPOPCNTH:4628return OPVX(4, 1859, 0, 0) /* vpopcnth - v2.07 */4629case AVPOPCNTW:4630return OPVX(4, 1923, 0, 0) /* vpopcntw - v2.07 */4631case AVPOPCNTD:4632return OPVX(4, 1987, 0, 0) /* vpopcntd - v2.07 */4633
4634case AVCMPEQUB:4635return OPVC(4, 6, 0, 0) /* vcmpequb - v2.03 */4636case AVCMPEQUBCC:4637return OPVC(4, 6, 0, 1) /* vcmpequb. - v2.03 */4638case AVCMPEQUH:4639return OPVC(4, 70, 0, 0) /* vcmpequh - v2.03 */4640case AVCMPEQUHCC:4641return OPVC(4, 70, 0, 1) /* vcmpequh. - v2.03 */4642case AVCMPEQUW:4643return OPVC(4, 134, 0, 0) /* vcmpequw - v2.03 */4644case AVCMPEQUWCC:4645return OPVC(4, 134, 0, 1) /* vcmpequw. - v2.03 */4646case AVCMPEQUD:4647return OPVC(4, 199, 0, 0) /* vcmpequd - v2.07 */4648case AVCMPEQUDCC:4649return OPVC(4, 199, 0, 1) /* vcmpequd. - v2.07 */4650
4651case AVCMPGTUB:4652return OPVC(4, 518, 0, 0) /* vcmpgtub - v2.03 */4653case AVCMPGTUBCC:4654return OPVC(4, 518, 0, 1) /* vcmpgtub. - v2.03 */4655case AVCMPGTUH:4656return OPVC(4, 582, 0, 0) /* vcmpgtuh - v2.03 */4657case AVCMPGTUHCC:4658return OPVC(4, 582, 0, 1) /* vcmpgtuh. - v2.03 */4659case AVCMPGTUW:4660return OPVC(4, 646, 0, 0) /* vcmpgtuw - v2.03 */4661case AVCMPGTUWCC:4662return OPVC(4, 646, 0, 1) /* vcmpgtuw. - v2.03 */4663case AVCMPGTUD:4664return OPVC(4, 711, 0, 0) /* vcmpgtud - v2.07 */4665case AVCMPGTUDCC:4666return OPVC(4, 711, 0, 1) /* vcmpgtud. v2.07 */4667case AVCMPGTSB:4668return OPVC(4, 774, 0, 0) /* vcmpgtsb - v2.03 */4669case AVCMPGTSBCC:4670return OPVC(4, 774, 0, 1) /* vcmpgtsb. - v2.03 */4671case AVCMPGTSH:4672return OPVC(4, 838, 0, 0) /* vcmpgtsh - v2.03 */4673case AVCMPGTSHCC:4674return OPVC(4, 838, 0, 1) /* vcmpgtsh. - v2.03 */4675case AVCMPGTSW:4676return OPVC(4, 902, 0, 0) /* vcmpgtsw - v2.03 */4677case AVCMPGTSWCC:4678return OPVC(4, 902, 0, 1) /* vcmpgtsw. - v2.03 */4679case AVCMPGTSD:4680return OPVC(4, 967, 0, 0) /* vcmpgtsd - v2.07 */4681case AVCMPGTSDCC:4682return OPVC(4, 967, 0, 1) /* vcmpgtsd. - v2.07 */4683
4684case AVCMPNEZB:4685return OPVC(4, 263, 0, 0) /* vcmpnezb - v3.00 */4686case AVCMPNEZBCC:4687return OPVC(4, 263, 0, 1) /* vcmpnezb. - v3.00 */4688case AVCMPNEB:4689return OPVC(4, 7, 0, 0) /* vcmpneb - v3.00 */4690case AVCMPNEBCC:4691return OPVC(4, 7, 0, 1) /* vcmpneb. - v3.00 */4692case AVCMPNEH:4693return OPVC(4, 71, 0, 0) /* vcmpneh - v3.00 */4694case AVCMPNEHCC:4695return OPVC(4, 71, 0, 1) /* vcmpneh. - v3.00 */4696case AVCMPNEW:4697return OPVC(4, 135, 0, 0) /* vcmpnew - v3.00 */4698case AVCMPNEWCC:4699return OPVC(4, 135, 0, 1) /* vcmpnew. - v3.00 */4700
4701case AVPERM:4702return OPVX(4, 43, 0, 0) /* vperm - v2.03 */4703case AVPERMXOR:4704return OPVX(4, 45, 0, 0) /* vpermxor - v2.03 */4705case AVPERMR:4706return OPVX(4, 59, 0, 0) /* vpermr - v3.0 */4707
4708case AVSEL:4709return OPVX(4, 42, 0, 0) /* vsel - v2.03 */4710
4711case AVCIPHER:4712return OPVX(4, 1288, 0, 0) /* vcipher - v2.07 */4713case AVCIPHERLAST:4714return OPVX(4, 1289, 0, 0) /* vcipherlast - v2.07 */4715case AVNCIPHER:4716return OPVX(4, 1352, 0, 0) /* vncipher - v2.07 */4717case AVNCIPHERLAST:4718return OPVX(4, 1353, 0, 0) /* vncipherlast - v2.07 */4719case AVSBOX:4720return OPVX(4, 1480, 0, 0) /* vsbox - v2.07 */4721/* End of vector instructions */4722
4723/* Vector scalar (VSX) instructions */4724/* ISA 2.06 enables these for POWER7. */4725case AMFVSRD, AMFVRD, AMFFPRD:4726return OPVXX1(31, 51, 0) /* mfvsrd - v2.07 */4727case AMFVSRWZ:4728return OPVXX1(31, 115, 0) /* mfvsrwz - v2.07 */4729case AMFVSRLD:4730return OPVXX1(31, 307, 0) /* mfvsrld - v3.00 */4731
4732case AMTVSRD, AMTFPRD, AMTVRD:4733return OPVXX1(31, 179, 0) /* mtvsrd - v2.07 */4734case AMTVSRWA:4735return OPVXX1(31, 211, 0) /* mtvsrwa - v2.07 */4736case AMTVSRWZ:4737return OPVXX1(31, 243, 0) /* mtvsrwz - v2.07 */4738case AMTVSRDD:4739return OPVXX1(31, 435, 0) /* mtvsrdd - v3.00 */4740case AMTVSRWS:4741return OPVXX1(31, 403, 0) /* mtvsrws - v3.00 */4742
4743case AXXLAND:4744return OPVXX3(60, 130, 0) /* xxland - v2.06 */4745case AXXLANDC:4746return OPVXX3(60, 138, 0) /* xxlandc - v2.06 */4747case AXXLEQV:4748return OPVXX3(60, 186, 0) /* xxleqv - v2.07 */4749case AXXLNAND:4750return OPVXX3(60, 178, 0) /* xxlnand - v2.07 */4751
4752case AXXLORC:4753return OPVXX3(60, 170, 0) /* xxlorc - v2.07 */4754case AXXLNOR:4755return OPVXX3(60, 162, 0) /* xxlnor - v2.06 */4756case AXXLOR, AXXLORQ:4757return OPVXX3(60, 146, 0) /* xxlor - v2.06 */4758case AXXLXOR:4759return OPVXX3(60, 154, 0) /* xxlxor - v2.06 */4760
4761case AXXSEL:4762return OPVXX4(60, 3, 0) /* xxsel - v2.06 */4763
4764case AXXMRGHW:4765return OPVXX3(60, 18, 0) /* xxmrghw - v2.06 */4766case AXXMRGLW:4767return OPVXX3(60, 50, 0) /* xxmrglw - v2.06 */4768
4769case AXXSPLTW:4770return OPVXX2(60, 164, 0) /* xxspltw - v2.06 */4771
4772case AXXSPLTIB:4773return OPVCC(60, 360, 0, 0) /* xxspltib - v3.0 */4774
4775case AXXPERM:4776return OPVXX3(60, 26, 0) /* xxperm - v2.06 */4777case AXXPERMDI:4778return OPVXX3(60, 10, 0) /* xxpermdi - v2.06 */4779
4780case AXXSLDWI:4781return OPVXX3(60, 2, 0) /* xxsldwi - v2.06 */4782
4783case AXXBRQ:4784return OPVXX2VA(60, 475, 31) /* xxbrq - v3.0 */4785case AXXBRD:4786return OPVXX2VA(60, 475, 23) /* xxbrd - v3.0 */4787case AXXBRW:4788return OPVXX2VA(60, 475, 15) /* xxbrw - v3.0 */4789case AXXBRH:4790return OPVXX2VA(60, 475, 7) /* xxbrh - v3.0 */4791
4792case AXSCVDPSP:4793return OPVXX2(60, 265, 0) /* xscvdpsp - v2.06 */4794case AXSCVSPDP:4795return OPVXX2(60, 329, 0) /* xscvspdp - v2.06 */4796case AXSCVDPSPN:4797return OPVXX2(60, 267, 0) /* xscvdpspn - v2.07 */4798case AXSCVSPDPN:4799return OPVXX2(60, 331, 0) /* xscvspdpn - v2.07 */4800
4801case AXVCVDPSP:4802return OPVXX2(60, 393, 0) /* xvcvdpsp - v2.06 */4803case AXVCVSPDP:4804return OPVXX2(60, 457, 0) /* xvcvspdp - v2.06 */4805
4806case AXSCVDPSXDS:4807return OPVXX2(60, 344, 0) /* xscvdpsxds - v2.06 */4808case AXSCVDPSXWS:4809return OPVXX2(60, 88, 0) /* xscvdpsxws - v2.06 */4810case AXSCVDPUXDS:4811return OPVXX2(60, 328, 0) /* xscvdpuxds - v2.06 */4812case AXSCVDPUXWS:4813return OPVXX2(60, 72, 0) /* xscvdpuxws - v2.06 */4814
4815case AXSCVSXDDP:4816return OPVXX2(60, 376, 0) /* xscvsxddp - v2.06 */4817case AXSCVUXDDP:4818return OPVXX2(60, 360, 0) /* xscvuxddp - v2.06 */4819case AXSCVSXDSP:4820return OPVXX2(60, 312, 0) /* xscvsxdsp - v2.06 */4821case AXSCVUXDSP:4822return OPVXX2(60, 296, 0) /* xscvuxdsp - v2.06 */4823
4824case AXVCVDPSXDS:4825return OPVXX2(60, 472, 0) /* xvcvdpsxds - v2.06 */4826case AXVCVDPSXWS:4827return OPVXX2(60, 216, 0) /* xvcvdpsxws - v2.06 */4828case AXVCVDPUXDS:4829return OPVXX2(60, 456, 0) /* xvcvdpuxds - v2.06 */4830case AXVCVDPUXWS:4831return OPVXX2(60, 200, 0) /* xvcvdpuxws - v2.06 */4832case AXVCVSPSXDS:4833return OPVXX2(60, 408, 0) /* xvcvspsxds - v2.07 */4834case AXVCVSPSXWS:4835return OPVXX2(60, 152, 0) /* xvcvspsxws - v2.07 */4836case AXVCVSPUXDS:4837return OPVXX2(60, 392, 0) /* xvcvspuxds - v2.07 */4838case AXVCVSPUXWS:4839return OPVXX2(60, 136, 0) /* xvcvspuxws - v2.07 */4840
4841case AXVCVSXDDP:4842return OPVXX2(60, 504, 0) /* xvcvsxddp - v2.06 */4843case AXVCVSXWDP:4844return OPVXX2(60, 248, 0) /* xvcvsxwdp - v2.06 */4845case AXVCVUXDDP:4846return OPVXX2(60, 488, 0) /* xvcvuxddp - v2.06 */4847case AXVCVUXWDP:4848return OPVXX2(60, 232, 0) /* xvcvuxwdp - v2.06 */4849case AXVCVSXDSP:4850return OPVXX2(60, 440, 0) /* xvcvsxdsp - v2.06 */4851case AXVCVSXWSP:4852return OPVXX2(60, 184, 0) /* xvcvsxwsp - v2.06 */4853case AXVCVUXDSP:4854return OPVXX2(60, 424, 0) /* xvcvuxdsp - v2.06 */4855case AXVCVUXWSP:4856return OPVXX2(60, 168, 0) /* xvcvuxwsp - v2.06 */4857/* End of VSX instructions */4858
4859case AMADDHD:4860return OPVX(4, 48, 0, 0) /* maddhd - v3.00 */4861case AMADDHDU:4862return OPVX(4, 49, 0, 0) /* maddhdu - v3.00 */4863case AMADDLD:4864return OPVX(4, 51, 0, 0) /* maddld - v3.00 */4865
4866case AXOR:4867return OPVCC(31, 316, 0, 0)4868case AXORCC:4869return OPVCC(31, 316, 0, 1)4870}4871
4872c.ctxt.Diag("bad r/r, r/r/r or r/r/r/r opcode %v", a)4873return 04874}
4875
4876func (c *ctxt9) opirrr(a obj.As) uint32 {4877switch a {4878/* Vector (VMX/Altivec) instructions */4879/* ISA 2.03 enables these for PPC970. For POWERx processors, these */4880/* are enabled starting at POWER6 (ISA 2.05). */4881case AVSLDOI:4882return OPVX(4, 44, 0, 0) /* vsldoi - v2.03 */4883}4884
4885c.ctxt.Diag("bad i/r/r/r opcode %v", a)4886return 04887}
4888
4889func (c *ctxt9) opiirr(a obj.As) uint32 {4890switch a {4891/* Vector (VMX/Altivec) instructions */4892/* ISA 2.07 enables these for POWER8 and beyond. */4893case AVSHASIGMAW:4894return OPVX(4, 1666, 0, 0) /* vshasigmaw - v2.07 */4895case AVSHASIGMAD:4896return OPVX(4, 1730, 0, 0) /* vshasigmad - v2.07 */4897}4898
4899c.ctxt.Diag("bad i/i/r/r opcode %v", a)4900return 04901}
4902
4903func (c *ctxt9) opirr(a obj.As) uint32 {4904switch a {4905case AADD:4906return OPVCC(14, 0, 0, 0)4907case AADDC:4908return OPVCC(12, 0, 0, 0)4909case AADDCCC:4910return OPVCC(13, 0, 0, 0)4911case AADDIS:4912return OPVCC(15, 0, 0, 0) /* ADDIS */4913
4914case AANDCC:4915return OPVCC(28, 0, 0, 0)4916case AANDISCC:4917return OPVCC(29, 0, 0, 0) /* ANDIS. */4918
4919case ABR:4920return OPVCC(18, 0, 0, 0)4921case ABL:4922return OPVCC(18, 0, 0, 0) | 14923case obj.ADUFFZERO:4924return OPVCC(18, 0, 0, 0) | 14925case obj.ADUFFCOPY:4926return OPVCC(18, 0, 0, 0) | 14927case ABC:4928return OPVCC(16, 0, 0, 0)4929case ABCL:4930return OPVCC(16, 0, 0, 0) | 14931
4932case ABEQ:4933return AOP_RRR(16<<26, 12, 2, 0)4934case ABGE:4935return AOP_RRR(16<<26, 4, 0, 0)4936case ABGT:4937return AOP_RRR(16<<26, 12, 1, 0)4938case ABLE:4939return AOP_RRR(16<<26, 4, 1, 0)4940case ABLT:4941return AOP_RRR(16<<26, 12, 0, 0)4942case ABNE:4943return AOP_RRR(16<<26, 4, 2, 0)4944case ABVC:4945return AOP_RRR(16<<26, 4, 3, 0) // apparently unordered-clear4946case ABVS:4947return AOP_RRR(16<<26, 12, 3, 0) // apparently unordered-set4948
4949case ACMP:4950return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */4951case ACMPU:4952return OPVCC(10, 0, 0, 0) | 1<<214953case ACMPW:4954return OPVCC(11, 0, 0, 0) /* L=0 */4955case ACMPWU:4956return OPVCC(10, 0, 0, 0)4957case ACMPEQB:4958return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */4959
4960case ALSW:4961return OPVCC(31, 597, 0, 0)4962
4963case ACOPY:4964return OPVCC(31, 774, 0, 0) /* copy - v3.00 */4965case APASTECC:4966return OPVCC(31, 902, 0, 1) /* paste. - v3.00 */4967case ADARN:4968return OPVCC(31, 755, 0, 0) /* darn - v3.00 */4969
4970case AMULLW:4971return OPVCC(7, 0, 0, 0)4972
4973case AOR:4974return OPVCC(24, 0, 0, 0)4975case AORIS:4976return OPVCC(25, 0, 0, 0) /* ORIS */4977
4978case ARLWMI:4979return OPVCC(20, 0, 0, 0) /* rlwimi */4980case ARLWMICC:4981return OPVCC(20, 0, 0, 1)4982case ARLDMI:4983return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */4984case ARLDMICC:4985return OPVCC(30, 0, 0, 1) | 3<<24986case ARLDIMI:4987return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */4988case ARLDIMICC:4989return OPVCC(30, 0, 0, 1) | 3<<24990case ARLWNM:4991return OPVCC(21, 0, 0, 0) /* rlwinm */4992case ARLWNMCC:4993return OPVCC(21, 0, 0, 1)4994
4995case ARLDCL:4996return OPVCC(30, 0, 0, 0) /* rldicl */4997case ARLDCLCC:4998return OPVCC(30, 0, 0, 1)4999case ARLDCR:5000return OPVCC(30, 1, 0, 0) /* rldicr */5001case ARLDCRCC:5002return OPVCC(30, 1, 0, 1)5003case ARLDC:5004return OPVCC(30, 0, 0, 0) | 2<<25005case ARLDCCC:5006return OPVCC(30, 0, 0, 1) | 2<<25007
5008case ASRAW:5009return OPVCC(31, 824, 0, 0)5010case ASRAWCC:5011return OPVCC(31, 824, 0, 1)5012case ASRAD:5013return OPVCC(31, (413 << 1), 0, 0)5014case ASRADCC:5015return OPVCC(31, (413 << 1), 0, 1)5016
5017case ASTSW:5018return OPVCC(31, 725, 0, 0)5019
5020case ASUBC:5021return OPVCC(8, 0, 0, 0)5022
5023case ATW:5024return OPVCC(3, 0, 0, 0)5025case ATD:5026return OPVCC(2, 0, 0, 0)5027
5028/* Vector (VMX/Altivec) instructions */5029/* ISA 2.03 enables these for PPC970. For POWERx processors, these */5030/* are enabled starting at POWER6 (ISA 2.05). */5031case AVSPLTB:5032return OPVX(4, 524, 0, 0) /* vspltb - v2.03 */5033case AVSPLTH:5034return OPVX(4, 588, 0, 0) /* vsplth - v2.03 */5035case AVSPLTW:5036return OPVX(4, 652, 0, 0) /* vspltw - v2.03 */5037
5038case AVSPLTISB:5039return OPVX(4, 780, 0, 0) /* vspltisb - v2.03 */5040case AVSPLTISH:5041return OPVX(4, 844, 0, 0) /* vspltish - v2.03 */5042case AVSPLTISW:5043return OPVX(4, 908, 0, 0) /* vspltisw - v2.03 */5044/* End of vector instructions */5045
5046case AFTDIV:5047return OPVCC(63, 128, 0, 0) /* ftdiv - v2.06 */5048case AFTSQRT:5049return OPVCC(63, 160, 0, 0) /* ftsqrt - v2.06 */5050
5051case AXOR:5052return OPVCC(26, 0, 0, 0) /* XORIL */5053case AXORIS:5054return OPVCC(27, 0, 0, 0) /* XORIS */5055}5056
5057c.ctxt.Diag("bad opcode i/r or i/r/r %v", a)5058return 05059}
5060
5061/*
5062* load o(a),d
5063*/
5064func (c *ctxt9) opload(a obj.As) uint32 {5065switch a {5066case AMOVD:5067return OPVCC(58, 0, 0, 0) /* ld */5068case AMOVDU:5069return OPVCC(58, 0, 0, 1) /* ldu */5070case AMOVWZ:5071return OPVCC(32, 0, 0, 0) /* lwz */5072case AMOVWZU:5073return OPVCC(33, 0, 0, 0) /* lwzu */5074case AMOVW:5075return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */5076case ALXV:5077return OPDQ(61, 1, 0) /* lxv - ISA v3.0 */5078case ALXVL:5079return OPVXX1(31, 269, 0) /* lxvl - ISA v3.0 */5080case ALXVLL:5081return OPVXX1(31, 301, 0) /* lxvll - ISA v3.0 */5082case ALXVX:5083return OPVXX1(31, 268, 0) /* lxvx - ISA v3.0 */5084
5085/* no AMOVWU */5086case AMOVB, AMOVBZ:5087return OPVCC(34, 0, 0, 0)5088/* load */5089
5090case AMOVBU, AMOVBZU:5091return OPVCC(35, 0, 0, 0)5092case AFMOVD:5093return OPVCC(50, 0, 0, 0)5094case AFMOVDU:5095return OPVCC(51, 0, 0, 0)5096case AFMOVS:5097return OPVCC(48, 0, 0, 0)5098case AFMOVSU:5099return OPVCC(49, 0, 0, 0)5100case AMOVH:5101return OPVCC(42, 0, 0, 0)5102case AMOVHU:5103return OPVCC(43, 0, 0, 0)5104case AMOVHZ:5105return OPVCC(40, 0, 0, 0)5106case AMOVHZU:5107return OPVCC(41, 0, 0, 0)5108case AMOVMW:5109return OPVCC(46, 0, 0, 0) /* lmw */5110}5111
5112c.ctxt.Diag("bad load opcode %v", a)5113return 05114}
5115
5116/*
5117* indexed load a(b),d
5118*/
5119func (c *ctxt9) oploadx(a obj.As) uint32 {5120switch a {5121case AMOVWZ:5122return OPVCC(31, 23, 0, 0) /* lwzx */5123case AMOVWZU:5124return OPVCC(31, 55, 0, 0) /* lwzux */5125case AMOVW:5126return OPVCC(31, 341, 0, 0) /* lwax */5127case AMOVWU:5128return OPVCC(31, 373, 0, 0) /* lwaux */5129
5130case AMOVB, AMOVBZ:5131return OPVCC(31, 87, 0, 0) /* lbzx */5132
5133case AMOVBU, AMOVBZU:5134return OPVCC(31, 119, 0, 0) /* lbzux */5135case AFMOVD:5136return OPVCC(31, 599, 0, 0) /* lfdx */5137case AFMOVDU:5138return OPVCC(31, 631, 0, 0) /* lfdux */5139case AFMOVS:5140return OPVCC(31, 535, 0, 0) /* lfsx */5141case AFMOVSU:5142return OPVCC(31, 567, 0, 0) /* lfsux */5143case AFMOVSX:5144return OPVCC(31, 855, 0, 0) /* lfiwax - power6, isa 2.05 */5145case AFMOVSZ:5146return OPVCC(31, 887, 0, 0) /* lfiwzx - power7, isa 2.06 */5147case AMOVH:5148return OPVCC(31, 343, 0, 0) /* lhax */5149case AMOVHU:5150return OPVCC(31, 375, 0, 0) /* lhaux */5151case AMOVHBR:5152return OPVCC(31, 790, 0, 0) /* lhbrx */5153case AMOVWBR:5154return OPVCC(31, 534, 0, 0) /* lwbrx */5155case AMOVDBR:5156return OPVCC(31, 532, 0, 0) /* ldbrx */5157case AMOVHZ:5158return OPVCC(31, 279, 0, 0) /* lhzx */5159case AMOVHZU:5160return OPVCC(31, 311, 0, 0) /* lhzux */5161case AECIWX:5162return OPVCC(31, 310, 0, 0) /* eciwx */5163case ALBAR:5164return OPVCC(31, 52, 0, 0) /* lbarx */5165case ALHAR:5166return OPVCC(31, 116, 0, 0) /* lharx */5167case ALWAR:5168return OPVCC(31, 20, 0, 0) /* lwarx */5169case ALDAR:5170return OPVCC(31, 84, 0, 0) /* ldarx */5171case ALSW:5172return OPVCC(31, 533, 0, 0) /* lswx */5173case AMOVD:5174return OPVCC(31, 21, 0, 0) /* ldx */5175case AMOVDU:5176return OPVCC(31, 53, 0, 0) /* ldux */5177case ALDMX:5178return OPVCC(31, 309, 0, 0) /* ldmx */5179
5180/* Vector (VMX/Altivec) instructions */5181case ALVEBX:5182return OPVCC(31, 7, 0, 0) /* lvebx - v2.03 */5183case ALVEHX:5184return OPVCC(31, 39, 0, 0) /* lvehx - v2.03 */5185case ALVEWX:5186return OPVCC(31, 71, 0, 0) /* lvewx - v2.03 */5187case ALVX:5188return OPVCC(31, 103, 0, 0) /* lvx - v2.03 */5189case ALVXL:5190return OPVCC(31, 359, 0, 0) /* lvxl - v2.03 */5191case ALVSL:5192return OPVCC(31, 6, 0, 0) /* lvsl - v2.03 */5193case ALVSR:5194return OPVCC(31, 38, 0, 0) /* lvsr - v2.03 */5195/* End of vector instructions */5196
5197/* Vector scalar (VSX) instructions */5198case ALXVX:5199return OPVXX1(31, 268, 0) /* lxvx - ISA v3.0 */5200case ALXVD2X:5201return OPVXX1(31, 844, 0) /* lxvd2x - v2.06 */5202case ALXVW4X:5203return OPVXX1(31, 780, 0) /* lxvw4x - v2.06 */5204case ALXVH8X:5205return OPVXX1(31, 812, 0) /* lxvh8x - v3.00 */5206case ALXVB16X:5207return OPVXX1(31, 876, 0) /* lxvb16x - v3.00 */5208case ALXVDSX:5209return OPVXX1(31, 332, 0) /* lxvdsx - v2.06 */5210case ALXSDX:5211return OPVXX1(31, 588, 0) /* lxsdx - v2.06 */5212case ALXSIWAX:5213return OPVXX1(31, 76, 0) /* lxsiwax - v2.07 */5214case ALXSIWZX:5215return OPVXX1(31, 12, 0) /* lxsiwzx - v2.07 */5216}5217
5218c.ctxt.Diag("bad loadx opcode %v", a)5219return 05220}
5221
5222/*
5223* store s,o(d)
5224*/
5225func (c *ctxt9) opstore(a obj.As) uint32 {5226switch a {5227case AMOVB, AMOVBZ:5228return OPVCC(38, 0, 0, 0) /* stb */5229
5230case AMOVBU, AMOVBZU:5231return OPVCC(39, 0, 0, 0) /* stbu */5232case AFMOVD:5233return OPVCC(54, 0, 0, 0) /* stfd */5234case AFMOVDU:5235return OPVCC(55, 0, 0, 0) /* stfdu */5236case AFMOVS:5237return OPVCC(52, 0, 0, 0) /* stfs */5238case AFMOVSU:5239return OPVCC(53, 0, 0, 0) /* stfsu */5240
5241case AMOVHZ, AMOVH:5242return OPVCC(44, 0, 0, 0) /* sth */5243
5244case AMOVHZU, AMOVHU:5245return OPVCC(45, 0, 0, 0) /* sthu */5246case AMOVMW:5247return OPVCC(47, 0, 0, 0) /* stmw */5248case ASTSW:5249return OPVCC(31, 725, 0, 0) /* stswi */5250
5251case AMOVWZ, AMOVW:5252return OPVCC(36, 0, 0, 0) /* stw */5253
5254case AMOVWZU, AMOVWU:5255return OPVCC(37, 0, 0, 0) /* stwu */5256case AMOVD:5257return OPVCC(62, 0, 0, 0) /* std */5258case AMOVDU:5259return OPVCC(62, 0, 0, 1) /* stdu */5260case ASTXV:5261return OPDQ(61, 5, 0) /* stxv ISA 3.0 */5262case ASTXVL:5263return OPVXX1(31, 397, 0) /* stxvl ISA 3.0 */5264case ASTXVLL:5265return OPVXX1(31, 429, 0) /* stxvll ISA 3.0 */5266case ASTXVX:5267return OPVXX1(31, 396, 0) /* stxvx - ISA v3.0 */5268
5269}5270
5271c.ctxt.Diag("unknown store opcode %v", a)5272return 05273}
5274
5275/*
5276* indexed store s,a(b)
5277*/
5278func (c *ctxt9) opstorex(a obj.As) uint32 {5279switch a {5280case AMOVB, AMOVBZ:5281return OPVCC(31, 215, 0, 0) /* stbx */5282
5283case AMOVBU, AMOVBZU:5284return OPVCC(31, 247, 0, 0) /* stbux */5285case AFMOVD:5286return OPVCC(31, 727, 0, 0) /* stfdx */5287case AFMOVDU:5288return OPVCC(31, 759, 0, 0) /* stfdux */5289case AFMOVS:5290return OPVCC(31, 663, 0, 0) /* stfsx */5291case AFMOVSU:5292return OPVCC(31, 695, 0, 0) /* stfsux */5293case AFMOVSX:5294return OPVCC(31, 983, 0, 0) /* stfiwx */5295
5296case AMOVHZ, AMOVH:5297return OPVCC(31, 407, 0, 0) /* sthx */5298case AMOVHBR:5299return OPVCC(31, 918, 0, 0) /* sthbrx */5300
5301case AMOVHZU, AMOVHU:5302return OPVCC(31, 439, 0, 0) /* sthux */5303
5304case AMOVWZ, AMOVW:5305return OPVCC(31, 151, 0, 0) /* stwx */5306
5307case AMOVWZU, AMOVWU:5308return OPVCC(31, 183, 0, 0) /* stwux */5309case ASTSW:5310return OPVCC(31, 661, 0, 0) /* stswx */5311case AMOVWBR:5312return OPVCC(31, 662, 0, 0) /* stwbrx */5313case AMOVDBR:5314return OPVCC(31, 660, 0, 0) /* stdbrx */5315case ASTBCCC:5316return OPVCC(31, 694, 0, 1) /* stbcx. */5317case ASTHCCC:5318return OPVCC(31, 726, 0, 1) /* sthcx. */5319case ASTWCCC:5320return OPVCC(31, 150, 0, 1) /* stwcx. */5321case ASTDCCC:5322return OPVCC(31, 214, 0, 1) /* stwdx. */5323case AECOWX:5324return OPVCC(31, 438, 0, 0) /* ecowx */5325case AMOVD:5326return OPVCC(31, 149, 0, 0) /* stdx */5327case AMOVDU:5328return OPVCC(31, 181, 0, 0) /* stdux */5329
5330/* Vector (VMX/Altivec) instructions */5331case ASTVEBX:5332return OPVCC(31, 135, 0, 0) /* stvebx - v2.03 */5333case ASTVEHX:5334return OPVCC(31, 167, 0, 0) /* stvehx - v2.03 */5335case ASTVEWX:5336return OPVCC(31, 199, 0, 0) /* stvewx - v2.03 */5337case ASTVX:5338return OPVCC(31, 231, 0, 0) /* stvx - v2.03 */5339case ASTVXL:5340return OPVCC(31, 487, 0, 0) /* stvxl - v2.03 */5341/* End of vector instructions */5342
5343/* Vector scalar (VSX) instructions */5344case ASTXVX:5345return OPVXX1(31, 396, 0) /* stxvx - v3.0 */5346case ASTXVD2X:5347return OPVXX1(31, 972, 0) /* stxvd2x - v2.06 */5348case ASTXVW4X:5349return OPVXX1(31, 908, 0) /* stxvw4x - v2.06 */5350case ASTXVH8X:5351return OPVXX1(31, 940, 0) /* stxvh8x - v3.0 */5352case ASTXVB16X:5353return OPVXX1(31, 1004, 0) /* stxvb16x - v3.0 */5354
5355case ASTXSDX:5356return OPVXX1(31, 716, 0) /* stxsdx - v2.06 */5357
5358case ASTXSIWX:5359return OPVXX1(31, 140, 0) /* stxsiwx - v2.07 */5360
5361/* End of vector scalar instructions */5362
5363}5364
5365c.ctxt.Diag("unknown storex opcode %v", a)5366return 05367}
5368