]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/internal/obj/ppc64/asm9.go
cmd/internal/obj/ppc64: refactor maskgen
[gostls13.git] / src / cmd / internal / obj / ppc64 / asm9.go
1 // cmd/9l/optab.c, cmd/9l/asmout.c from Vita Nuova.
2 //
3 //      Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
4 //      Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
5 //      Portions Copyright © 1997-1999 Vita Nuova Limited
6 //      Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
7 //      Portions Copyright © 2004,2006 Bruce Ellis
8 //      Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
9 //      Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
10 //      Portions Copyright © 2009 The Go Authors. All rights reserved.
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // of this software and associated documentation files (the "Software"), to deal
14 // in the Software without restriction, including without limitation the rights
15 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 // copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be included in
20 // all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 // THE SOFTWARE.
29
30 package ppc64
31
32 import (
33         "cmd/internal/obj"
34         "cmd/internal/objabi"
35         "encoding/binary"
36         "fmt"
37         "internal/buildcfg"
38         "log"
39         "math"
40         "math/bits"
41         "sort"
42 )
43
44 // ctxt9 holds state while assembling a single function.
45 // Each function gets a fresh ctxt9.
46 // This allows for multiple functions to be safely concurrently assembled.
47 type ctxt9 struct {
48         ctxt       *obj.Link
49         newprog    obj.ProgAlloc
50         cursym     *obj.LSym
51         autosize   int32
52         instoffset int64
53         pc         int64
54 }
55
56 // Instruction layout.
57
58 const (
59         r0iszero = 1
60 )
61
62 const (
63         // R bit option in prefixed load/store/add D-form operations
64         PFX_R_ABS   = 0 // Offset is absolute
65         PFX_R_PCREL = 1 // Offset is relative to PC, RA should be 0
66 )
67
68 type Optab struct {
69         as    obj.As // Opcode
70         a1    uint8  // p.From argument (obj.Addr). p is of type obj.Prog.
71         a2    uint8  // p.Reg argument (int16 Register)
72         a3    uint8  // p.RestArgs[0]  (obj.AddrPos)
73         a4    uint8  // p.RestArgs[1]
74         a5    uint8  // p.RestARgs[2]
75         a6    uint8  // p.To (obj.Addr)
76         type_ int8   // cases in asmout below. E.g., 44 = st r,(ra+rb); 45 = ld (ra+rb), r
77         size  int8   // Text space in bytes to lay operation
78
79         // A prefixed instruction is generated by this opcode. This cannot be placed
80         // across a 64B PC address. Opcodes should not translate to more than one
81         // prefixed instruction. The prefixed instruction should be written first
82         // (e.g when Optab.size > 8).
83         ispfx bool
84
85         asmout func(*ctxt9, *obj.Prog, *Optab, *[5]uint32)
86 }
87
88 // optab contains an array to be sliced of accepted operand combinations for an
89 // instruction. Unused arguments and fields are not explicitly enumerated, and
90 // should not be listed for clarity. Unused arguments and values should always
91 // assume the default value for the given type.
92 //
93 // optab does not list every valid ppc64 opcode, it enumerates representative
94 // operand combinations for a class of instruction.  The variable oprange indexes
95 // all valid ppc64 opcodes.
96 //
97 // oprange is initialized to point a slice within optab which contains the valid
98 // operand combinations for a given instruction.  This is initialized from buildop.
99 //
100 // Likewise, each slice of optab is dynamically sorted using the ocmp Sort interface
101 // to arrange entries to minimize text size of each opcode.
102 //
103 // optab is the sorted result of combining optabBase, optabGen, and prefixableOptab.
104 var optab []Optab
105
106 var optabBase = []Optab{
107         {as: obj.ATEXT, a1: C_LOREG, a6: C_TEXTSIZE, type_: 0, size: 0},
108         {as: obj.ATEXT, a1: C_LOREG, a3: C_LCON, a6: C_TEXTSIZE, type_: 0, size: 0},
109         {as: obj.ATEXT, a1: C_ADDR, a6: C_TEXTSIZE, type_: 0, size: 0},
110         {as: obj.ATEXT, a1: C_ADDR, a3: C_LCON, a6: C_TEXTSIZE, type_: 0, size: 0},
111         /* move register */
112         {as: AADD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4},
113         {as: AADD, a1: C_REG, a6: C_REG, type_: 2, size: 4},
114         {as: AADD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
115         {as: AADD, a1: C_SCON, a6: C_REG, type_: 4, size: 4},
116         {as: AADD, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
117         {as: AADD, a1: C_ADDCON, a6: C_REG, type_: 4, size: 4},
118         {as: AADD, a1: C_UCON, a2: C_REG, a6: C_REG, type_: 20, size: 4},
119         {as: AADD, a1: C_UCON, a6: C_REG, type_: 20, size: 4},
120         {as: AADD, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 22, size: 8},
121         {as: AADD, a1: C_ANDCON, a6: C_REG, type_: 22, size: 8},
122         {as: AADDIS, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 20, size: 4},
123         {as: AADDIS, a1: C_ADDCON, a6: C_REG, type_: 20, size: 4},
124         {as: AADDC, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4},
125         {as: AADDC, a1: C_REG, a6: C_REG, type_: 2, size: 4},
126         {as: AADDC, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
127         {as: AADDC, a1: C_ADDCON, a6: C_REG, type_: 4, size: 4},
128         {as: AADDC, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 22, size: 12},
129         {as: AADDC, a1: C_LCON, a6: C_REG, type_: 22, size: 12},
130         {as: AAND, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4}, /* logical, no literal */
131         {as: AAND, a1: C_REG, a6: C_REG, type_: 6, size: 4},
132         {as: AANDCC, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
133         {as: AANDCC, a1: C_REG, a6: C_REG, type_: 6, size: 4},
134         {as: AANDCC, a1: C_ANDCON, a6: C_REG, type_: 58, size: 4},
135         {as: AANDCC, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 58, size: 4},
136         {as: AANDCC, a1: C_UCON, a6: C_REG, type_: 59, size: 4},
137         {as: AANDCC, a1: C_UCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
138         {as: AANDCC, a1: C_ADDCON, a6: C_REG, type_: 23, size: 8},
139         {as: AANDCC, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 23, size: 8},
140         {as: AANDCC, a1: C_LCON, a6: C_REG, type_: 23, size: 12},
141         {as: AANDCC, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 23, size: 12},
142         {as: AANDISCC, a1: C_ANDCON, a6: C_REG, type_: 59, size: 4},
143         {as: AANDISCC, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
144         {as: AMULLW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4},
145         {as: AMULLW, a1: C_REG, a6: C_REG, type_: 2, size: 4},
146         {as: AMULLW, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
147         {as: AMULLW, a1: C_ADDCON, a6: C_REG, type_: 4, size: 4},
148         {as: AMULLW, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
149         {as: AMULLW, a1: C_ANDCON, a6: C_REG, type_: 4, size: 4},
150         {as: AMULLW, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 22, size: 12},
151         {as: AMULLW, a1: C_LCON, a6: C_REG, type_: 22, size: 12},
152         {as: ASUBC, a1: C_REG, a2: C_REG, a6: C_REG, type_: 10, size: 4},
153         {as: ASUBC, a1: C_REG, a6: C_REG, type_: 10, size: 4},
154         {as: ASUBC, a1: C_REG, a3: C_ADDCON, a6: C_REG, type_: 27, size: 4},
155         {as: ASUBC, a1: C_REG, a3: C_LCON, a6: C_REG, type_: 28, size: 12},
156         {as: AOR, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4}, /* logical, literal not cc (or/xor) */
157         {as: AOR, a1: C_REG, a6: C_REG, type_: 6, size: 4},
158         {as: AOR, a1: C_ANDCON, a6: C_REG, type_: 58, size: 4},
159         {as: AOR, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 58, size: 4},
160         {as: AOR, a1: C_UCON, a6: C_REG, type_: 59, size: 4},
161         {as: AOR, a1: C_UCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
162         {as: AOR, a1: C_ADDCON, a6: C_REG, type_: 23, size: 8},
163         {as: AOR, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 23, size: 8},
164         {as: AOR, a1: C_LCON, a6: C_REG, type_: 23, size: 12},
165         {as: AOR, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 23, size: 12},
166         {as: AORIS, a1: C_ANDCON, a6: C_REG, type_: 59, size: 4},
167         {as: AORIS, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
168         {as: ADIVW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4}, /* op r1[,r2],r3 */
169         {as: ADIVW, a1: C_REG, a6: C_REG, type_: 2, size: 4},
170         {as: ASUB, a1: C_REG, a2: C_REG, a6: C_REG, type_: 10, size: 4}, /* op r2[,r1],r3 */
171         {as: ASUB, a1: C_REG, a6: C_REG, type_: 10, size: 4},
172         {as: ASLW, a1: C_REG, a6: C_REG, type_: 6, size: 4},
173         {as: ASLW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
174         {as: ASLD, a1: C_REG, a6: C_REG, type_: 6, size: 4},
175         {as: ASLD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
176         {as: ASLD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 25, size: 4},
177         {as: ASLD, a1: C_SCON, a6: C_REG, type_: 25, size: 4},
178         {as: AEXTSWSLI, a1: C_SCON, a6: C_REG, type_: 25, size: 4},
179         {as: AEXTSWSLI, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 25, size: 4},
180         {as: ASLW, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 57, size: 4},
181         {as: ASLW, a1: C_SCON, a6: C_REG, type_: 57, size: 4},
182         {as: ASRAW, a1: C_REG, a6: C_REG, type_: 6, size: 4},
183         {as: ASRAW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
184         {as: ASRAW, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 56, size: 4},
185         {as: ASRAW, a1: C_SCON, a6: C_REG, type_: 56, size: 4},
186         {as: ASRAD, a1: C_REG, a6: C_REG, type_: 6, size: 4},
187         {as: ASRAD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
188         {as: ASRAD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 56, size: 4},
189         {as: ASRAD, a1: C_SCON, a6: C_REG, type_: 56, size: 4},
190         {as: ARLWNM, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 63, size: 4},
191         {as: ARLWNM, a1: C_SCON, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 63, size: 4},
192         {as: ARLWNM, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 63, size: 4},
193         {as: ARLWNM, a1: C_REG, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 63, size: 4},
194         {as: ACLRLSLWI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
195         {as: ARLDMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 30, size: 4},
196         {as: ARLDC, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
197         {as: ARLDC, a1: C_REG, a3: C_U8CON, a4: C_U8CON, a6: C_REG, type_: 9, size: 4},
198         {as: ARLDCL, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
199         {as: ARLDCL, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
200         {as: ARLDICL, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
201         {as: ARLDICL, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
202         {as: ARLDCL, a1: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
203         {as: AFADD, a1: C_FREG, a6: C_FREG, type_: 2, size: 4},
204         {as: AFADD, a1: C_FREG, a2: C_FREG, a6: C_FREG, type_: 2, size: 4},
205         {as: AFABS, a1: C_FREG, a6: C_FREG, type_: 33, size: 4},
206         {as: AFABS, a6: C_FREG, type_: 33, size: 4},
207         {as: AFMADD, a1: C_FREG, a2: C_FREG, a3: C_FREG, a6: C_FREG, type_: 34, size: 4},
208         {as: AFMUL, a1: C_FREG, a6: C_FREG, type_: 32, size: 4},
209         {as: AFMUL, a1: C_FREG, a2: C_FREG, a6: C_FREG, type_: 32, size: 4},
210
211         {as: AMOVBU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
212         {as: AMOVBU, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
213         {as: AMOVBU, a1: C_SOREG, a6: C_REG, type_: 8, size: 8},
214         {as: AMOVBU, a1: C_XOREG, a6: C_REG, type_: 109, size: 8},
215
216         {as: AMOVBZU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
217         {as: AMOVBZU, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
218         {as: AMOVBZU, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
219         {as: AMOVBZU, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
220
221         {as: AMOVHBR, a1: C_REG, a6: C_XOREG, type_: 44, size: 4},
222         {as: AMOVHBR, a1: C_XOREG, a6: C_REG, type_: 45, size: 4},
223
224         {as: AMOVB, a1: C_SOREG, a6: C_REG, type_: 8, size: 8},
225         {as: AMOVB, a1: C_XOREG, a6: C_REG, type_: 109, size: 8},
226         {as: AMOVB, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
227         {as: AMOVB, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
228         {as: AMOVB, a1: C_REG, a6: C_REG, type_: 13, size: 4},
229
230         {as: AMOVBZ, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
231         {as: AMOVBZ, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
232         {as: AMOVBZ, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
233         {as: AMOVBZ, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
234         {as: AMOVBZ, a1: C_REG, a6: C_REG, type_: 13, size: 4},
235
236         {as: AMOVD, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
237         {as: AMOVD, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
238         {as: AMOVD, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
239         {as: AMOVD, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
240         {as: AMOVD, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
241         {as: AMOVD, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
242         {as: AMOVD, a1: C_SOREG, a6: C_SPR, type_: 107, size: 8},
243         {as: AMOVD, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
244         {as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
245         {as: AMOVD, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
246         {as: AMOVD, a1: C_SPR, a6: C_SOREG, type_: 106, size: 8},
247         {as: AMOVD, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
248         {as: AMOVD, a1: C_REG, a6: C_REG, type_: 13, size: 4},
249
250         {as: AMOVW, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
251         {as: AMOVW, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
252         {as: AMOVW, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
253         {as: AMOVW, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
254         {as: AMOVW, a1: C_CREG, a6: C_REG, type_: 68, size: 4},
255         {as: AMOVW, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
256         {as: AMOVW, a1: C_XOREG, a6: C_REG, type_: 109, size: 4},
257         {as: AMOVW, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
258         {as: AMOVW, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
259         {as: AMOVW, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
260         {as: AMOVW, a1: C_REG, a6: C_XOREG, type_: 108, size: 4},
261         {as: AMOVW, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
262         {as: AMOVW, a1: C_REG, a6: C_REG, type_: 13, size: 4},
263
264         {as: AFMOVD, a1: C_ADDCON, a6: C_FREG, type_: 24, size: 8},
265         {as: AFMOVD, a1: C_SOREG, a6: C_FREG, type_: 8, size: 4},
266         {as: AFMOVD, a1: C_XOREG, a6: C_FREG, type_: 109, size: 4},
267         {as: AFMOVD, a1: C_ZCON, a6: C_FREG, type_: 24, size: 4},
268         {as: AFMOVD, a1: C_FREG, a6: C_FREG, type_: 33, size: 4},
269         {as: AFMOVD, a1: C_FREG, a6: C_SOREG, type_: 7, size: 4},
270         {as: AFMOVD, a1: C_FREG, a6: C_XOREG, type_: 108, size: 4},
271
272         {as: AFMOVSX, a1: C_XOREG, a6: C_FREG, type_: 45, size: 4},
273         {as: AFMOVSX, a1: C_FREG, a6: C_XOREG, type_: 44, size: 4},
274
275         {as: AFMOVSZ, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
276         {as: AFMOVSZ, a1: C_XOREG, a6: C_FREG, type_: 45, size: 4},
277
278         {as: AMOVFL, a1: C_CREG, a6: C_CREG, type_: 67, size: 4},
279         {as: AMOVFL, a1: C_FPSCR, a6: C_CREG, type_: 73, size: 4},
280         {as: AMOVFL, a1: C_FPSCR, a6: C_FREG, type_: 53, size: 4},
281         {as: AMOVFL, a1: C_FREG, a3: C_LCON, a6: C_FPSCR, type_: 64, size: 4},
282         {as: AMOVFL, a1: C_FREG, a6: C_FPSCR, type_: 64, size: 4},
283         {as: AMOVFL, a1: C_LCON, a6: C_FPSCR, type_: 65, size: 4},
284         {as: AMOVFL, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
285         {as: AMOVFL, a1: C_REG, a6: C_LCON, type_: 69, size: 4},
286
287         {as: ASYSCALL, type_: 5, size: 4},
288         {as: ASYSCALL, a1: C_REG, type_: 77, size: 12},
289         {as: ASYSCALL, a1: C_SCON, type_: 77, size: 12},
290         {as: ABEQ, a6: C_SBRA, type_: 16, size: 4},
291         {as: ABEQ, a1: C_CREG, a6: C_SBRA, type_: 16, size: 4},
292         {as: ABR, a6: C_LBRA, type_: 11, size: 4},                                    // b label
293         {as: ABR, a6: C_LBRAPIC, type_: 11, size: 8},                                 // b label; nop
294         {as: ABR, a6: C_LR, type_: 18, size: 4},                                      // blr
295         {as: ABR, a6: C_CTR, type_: 18, size: 4},                                     // bctr
296         {as: ABC, a1: C_SCON, a2: C_CRBIT, a6: C_SBRA, type_: 16, size: 4},           // bc bo, bi, label
297         {as: ABC, a1: C_SCON, a2: C_CRBIT, a6: C_LBRA, type_: 17, size: 4},           // bc bo, bi, label
298         {as: ABC, a1: C_SCON, a2: C_CRBIT, a6: C_LR, type_: 18, size: 4},             // bclr bo, bi
299         {as: ABC, a1: C_SCON, a2: C_CRBIT, a3: C_SCON, a6: C_LR, type_: 18, size: 4}, // bclr bo, bi, bh
300         {as: ABC, a1: C_SCON, a2: C_CRBIT, a6: C_CTR, type_: 18, size: 4},            // bcctr bo, bi
301         {as: ABDNZ, a6: C_SBRA, type_: 16, size: 4},
302         {as: ASYNC, type_: 46, size: 4},
303         {as: AWORD, a1: C_LCON, type_: 40, size: 4},
304         {as: ADWORD, a1: C_64CON, type_: 31, size: 8},
305         {as: ADWORD, a1: C_LACON, type_: 31, size: 8},
306         {as: AADDME, a1: C_REG, a6: C_REG, type_: 47, size: 4},
307         {as: AEXTSB, a1: C_REG, a6: C_REG, type_: 48, size: 4},
308         {as: AEXTSB, a6: C_REG, type_: 48, size: 4},
309         {as: AISEL, a1: C_U5CON, a2: C_REG, a3: C_REG, a6: C_REG, type_: 84, size: 4},
310         {as: AISEL, a1: C_CRBIT, a2: C_REG, a3: C_REG, a6: C_REG, type_: 84, size: 4},
311         {as: ANEG, a1: C_REG, a6: C_REG, type_: 47, size: 4},
312         {as: ANEG, a6: C_REG, type_: 47, size: 4},
313         {as: AREM, a1: C_REG, a6: C_REG, type_: 50, size: 12},
314         {as: AREM, a1: C_REG, a2: C_REG, a6: C_REG, type_: 50, size: 12},
315         {as: AREMU, a1: C_REG, a6: C_REG, type_: 50, size: 16},
316         {as: AREMU, a1: C_REG, a2: C_REG, a6: C_REG, type_: 50, size: 16},
317         {as: AREMD, a1: C_REG, a6: C_REG, type_: 51, size: 12},
318         {as: AREMD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 51, size: 12},
319         {as: AMTFSB0, a1: C_SCON, type_: 52, size: 4},
320         /* Other ISA 2.05+ instructions */
321         {as: APOPCNTD, a1: C_REG, a6: C_REG, type_: 93, size: 4},            /* population count, x-form */
322         {as: ACMPB, a1: C_REG, a2: C_REG, a6: C_REG, type_: 92, size: 4},    /* compare byte, x-form */
323         {as: ACMPEQB, a1: C_REG, a2: C_REG, a6: C_CREG, type_: 92, size: 4}, /* compare equal byte, x-form, ISA 3.0 */
324         {as: ACMPEQB, a1: C_REG, a6: C_REG, type_: 70, size: 4},
325         {as: AFTDIV, a1: C_FREG, a2: C_FREG, a6: C_SCON, type_: 92, size: 4},          /* floating test for sw divide, x-form */
326         {as: AFTSQRT, a1: C_FREG, a6: C_SCON, type_: 93, size: 4},                     /* floating test for sw square root, x-form */
327         {as: ACOPY, a1: C_REG, a6: C_REG, type_: 92, size: 4},                         /* copy/paste facility, x-form */
328         {as: ADARN, a1: C_SCON, a6: C_REG, type_: 92, size: 4},                        /* deliver random number, x-form */
329         {as: AMADDHD, a1: C_REG, a2: C_REG, a3: C_REG, a6: C_REG, type_: 83, size: 4}, /* multiply-add high/low doubleword, va-form */
330         {as: AADDEX, a1: C_REG, a2: C_REG, a3: C_SCON, a6: C_REG, type_: 94, size: 4}, /* add extended using alternate carry, z23-form */
331         {as: ACRAND, a1: C_CRBIT, a2: C_CRBIT, a6: C_CRBIT, type_: 2, size: 4},        /* logical ops for condition register bits xl-form */
332
333         /* Misc ISA 3.0 instructions */
334         {as: ASETB, a1: C_CREG, a6: C_REG, type_: 110, size: 4},
335         {as: AVCLZLSBB, a1: C_VREG, a6: C_REG, type_: 85, size: 4},
336
337         /* Vector instructions */
338
339         /* Vector load */
340         {as: ALVEBX, a1: C_XOREG, a6: C_VREG, type_: 45, size: 4}, /* vector load, x-form */
341
342         /* Vector store */
343         {as: ASTVEBX, a1: C_VREG, a6: C_XOREG, type_: 44, size: 4}, /* vector store, x-form */
344
345         /* Vector logical */
346         {as: AVAND, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector and, vx-form */
347         {as: AVOR, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},  /* vector or, vx-form */
348
349         /* Vector add */
350         {as: AVADDUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector add unsigned modulo, vx-form */
351         {as: AVADDCU, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector add & write carry unsigned, vx-form */
352         {as: AVADDUS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector add unsigned saturate, vx-form */
353         {as: AVADDSS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector add signed saturate, vx-form */
354         {as: AVADDE, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector add extended, va-form */
355
356         /* Vector subtract */
357         {as: AVSUBUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector subtract unsigned modulo, vx-form */
358         {as: AVSUBCU, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector subtract & write carry unsigned, vx-form */
359         {as: AVSUBUS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector subtract unsigned saturate, vx-form */
360         {as: AVSUBSS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},            /* vector subtract signed saturate, vx-form */
361         {as: AVSUBE, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector subtract extended, va-form */
362
363         /* Vector multiply */
364         {as: AVMULESB, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},              /* vector multiply, vx-form */
365         {as: AVPMSUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},               /* vector polynomial multiply & sum, vx-form */
366         {as: AVMSUMUDM, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector multiply-sum, va-form */
367
368         /* Vector rotate */
369         {as: AVR, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector rotate, vx-form */
370
371         /* Vector shift */
372         {as: AVS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},                 /* vector shift, vx-form */
373         {as: AVSA, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},                /* vector shift algebraic, vx-form */
374         {as: AVSOI, a1: C_ANDCON, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector shift by octet immediate, va-form */
375
376         /* Vector count */
377         {as: AVCLZ, a1: C_VREG, a6: C_VREG, type_: 85, size: 4},    /* vector count leading zeros, vx-form */
378         {as: AVPOPCNT, a1: C_VREG, a6: C_VREG, type_: 85, size: 4}, /* vector population count, vx-form */
379
380         /* Vector compare */
381         {as: AVCMPEQ, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},   /* vector compare equal, vc-form */
382         {as: AVCMPGT, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},   /* vector compare greater than, vc-form */
383         {as: AVCMPNEZB, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector compare not equal, vx-form */
384
385         /* Vector merge */
386         {as: AVMRGOW, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector merge odd word, vx-form */
387
388         /* Vector permute */
389         {as: AVPERM, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector permute, va-form */
390
391         /* Vector bit permute */
392         {as: AVBPERMQ, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector bit permute, vx-form */
393
394         /* Vector select */
395         {as: AVSEL, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector select, va-form */
396
397         /* Vector splat */
398         {as: AVSPLTB, a1: C_SCON, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector splat, vx-form */
399         {as: AVSPLTB, a1: C_ADDCON, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},
400         {as: AVSPLTISB, a1: C_SCON, a6: C_VREG, type_: 82, size: 4}, /* vector splat immediate, vx-form */
401         {as: AVSPLTISB, a1: C_ADDCON, a6: C_VREG, type_: 82, size: 4},
402
403         /* Vector AES */
404         {as: AVCIPH, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},  /* vector AES cipher, vx-form */
405         {as: AVNCIPH, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector AES inverse cipher, vx-form */
406         {as: AVSBOX, a1: C_VREG, a6: C_VREG, type_: 82, size: 4},              /* vector AES subbytes, vx-form */
407
408         /* Vector SHA */
409         {as: AVSHASIGMA, a1: C_ANDCON, a2: C_VREG, a3: C_ANDCON, a6: C_VREG, type_: 82, size: 4}, /* vector SHA sigma, vx-form */
410
411         /* VSX vector load */
412         {as: ALXVD2X, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4},        /* vsx vector load, xx1-form */
413         {as: ALXV, a1: C_SOREG, a6: C_VSREG, type_: 96, size: 4},           /* vsx vector load, dq-form */
414         {as: ALXVL, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 98, size: 4}, /* vsx vector load length */
415
416         /* VSX vector store */
417         {as: ASTXVD2X, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4},        /* vsx vector store, xx1-form */
418         {as: ASTXV, a1: C_VSREG, a6: C_SOREG, type_: 97, size: 4},           /* vsx vector store, dq-form */
419         {as: ASTXVL, a1: C_VSREG, a2: C_REG, a6: C_REG, type_: 99, size: 4}, /* vsx vector store with length x-form */
420
421         /* VSX scalar load */
422         {as: ALXSDX, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar load, xx1-form */
423
424         /* VSX scalar store */
425         {as: ASTXSDX, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4}, /* vsx scalar store, xx1-form */
426
427         /* VSX scalar as integer load */
428         {as: ALXSIWAX, a1: C_XOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar as integer load, xx1-form */
429
430         /* VSX scalar store as integer */
431         {as: ASTXSIWX, a1: C_VSREG, a6: C_XOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */
432
433         /* VSX move from VSR */
434         {as: AMFVSRD, a1: C_VSREG, a6: C_REG, type_: 88, size: 4},
435         {as: AMFVSRD, a1: C_FREG, a6: C_REG, type_: 88, size: 4},
436
437         /* VSX move to VSR */
438         {as: AMTVSRD, a1: C_REG, a6: C_VSREG, type_: 104, size: 4},
439         {as: AMTVSRD, a1: C_REG, a6: C_FREG, type_: 104, size: 4},
440         {as: AMTVSRDD, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 104, size: 4},
441
442         /* VSX logical */
443         {as: AXXLAND, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx and, xx3-form */
444         {as: AXXLOR, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4},  /* vsx or, xx3-form */
445
446         /* VSX select */
447         {as: AXXSEL, a1: C_VSREG, a2: C_VSREG, a3: C_VSREG, a6: C_VSREG, type_: 91, size: 4}, /* vsx select, xx4-form */
448
449         /* VSX merge */
450         {as: AXXMRGHW, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx merge, xx3-form */
451
452         /* VSX splat */
453         {as: AXXSPLTW, a1: C_VSREG, a3: C_SCON, a6: C_VSREG, type_: 89, size: 4}, /* vsx splat, xx2-form */
454         {as: AXXSPLTIB, a1: C_SCON, a6: C_VSREG, type_: 100, size: 4},            /* vsx splat, xx2-form */
455
456         /* VSX permute */
457         {as: AXXPERM, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx permute, xx3-form */
458
459         /* VSX shift */
460         {as: AXXSLDWI, a1: C_VSREG, a2: C_VSREG, a3: C_SCON, a6: C_VSREG, type_: 90, size: 4}, /* vsx shift immediate, xx3-form */
461
462         /* VSX reverse bytes */
463         {as: AXXBRQ, a1: C_VSREG, a6: C_VSREG, type_: 101, size: 4}, /* vsx reverse bytes */
464
465         /* VSX scalar FP-FP conversion */
466         {as: AXSCVDPSP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar fp-fp conversion, xx2-form */
467
468         /* VSX vector FP-FP conversion */
469         {as: AXVCVDPSP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector fp-fp conversion, xx2-form */
470
471         /* VSX scalar FP-integer conversion */
472         {as: AXSCVDPSXDS, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar fp-integer conversion, xx2-form */
473
474         /* VSX scalar integer-FP conversion */
475         {as: AXSCVSXDDP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar integer-fp conversion, xx2-form */
476
477         /* VSX vector FP-integer conversion */
478         {as: AXVCVDPSXDS, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector fp-integer conversion, xx2-form */
479
480         /* VSX vector integer-FP conversion */
481         {as: AXVCVSXDDP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector integer-fp conversion, xx2-form */
482
483         {as: ACMP, a1: C_REG, a6: C_REG, type_: 70, size: 4},
484         {as: ACMP, a1: C_REG, a2: C_CREG, a6: C_REG, type_: 70, size: 4},
485         {as: ACMP, a1: C_REG, a6: C_ADDCON, type_: 71, size: 4},
486         {as: ACMP, a1: C_REG, a2: C_CREG, a6: C_ADDCON, type_: 71, size: 4},
487         {as: ACMPU, a1: C_REG, a6: C_REG, type_: 70, size: 4},
488         {as: ACMPU, a1: C_REG, a2: C_CREG, a6: C_REG, type_: 70, size: 4},
489         {as: ACMPU, a1: C_REG, a6: C_ANDCON, type_: 71, size: 4},
490         {as: ACMPU, a1: C_REG, a2: C_CREG, a6: C_ANDCON, type_: 71, size: 4},
491         {as: AFCMPO, a1: C_FREG, a6: C_FREG, type_: 70, size: 4},
492         {as: AFCMPO, a1: C_FREG, a2: C_CREG, a6: C_FREG, type_: 70, size: 4},
493         {as: ATW, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 60, size: 4},
494         {as: ATW, a1: C_LCON, a2: C_REG, a6: C_ADDCON, type_: 61, size: 4},
495         {as: ADCBF, a1: C_SOREG, type_: 43, size: 4},
496         {as: ADCBF, a1: C_XOREG, type_: 43, size: 4},
497         {as: ADCBF, a1: C_XOREG, a2: C_REG, a6: C_SCON, type_: 43, size: 4},
498         {as: ADCBF, a1: C_SOREG, a6: C_SCON, type_: 43, size: 4},
499         {as: ADCBF, a1: C_XOREG, a6: C_SCON, type_: 43, size: 4},
500         {as: ASTDCCC, a1: C_REG, a2: C_REG, a6: C_XOREG, type_: 44, size: 4},
501         {as: ASTDCCC, a1: C_REG, a6: C_XOREG, type_: 44, size: 4},
502         {as: ALDAR, a1: C_XOREG, a6: C_REG, type_: 45, size: 4},
503         {as: ALDAR, a1: C_XOREG, a3: C_ANDCON, a6: C_REG, type_: 45, size: 4},
504         {as: AEIEIO, type_: 46, size: 4},
505         {as: ATLBIE, a1: C_REG, type_: 49, size: 4},
506         {as: ATLBIE, a1: C_SCON, a6: C_REG, type_: 49, size: 4},
507         {as: ASLBMFEE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
508         {as: ASLBMTE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
509         {as: ASTSW, a1: C_REG, a6: C_XOREG, type_: 44, size: 4},
510         {as: ASTSW, a1: C_REG, a3: C_LCON, a6: C_ZOREG, type_: 41, size: 4},
511         {as: ALSW, a1: C_XOREG, a6: C_REG, type_: 45, size: 4},
512         {as: ALSW, a1: C_ZOREG, a3: C_LCON, a6: C_REG, type_: 42, size: 4},
513
514         {as: obj.AUNDEF, type_: 78, size: 4},
515         {as: obj.APCDATA, a1: C_LCON, a6: C_LCON, type_: 0, size: 0},
516         {as: obj.AFUNCDATA, a1: C_SCON, a6: C_ADDR, type_: 0, size: 0},
517         {as: obj.ANOP, type_: 0, size: 0},
518         {as: obj.ANOP, a1: C_LCON, type_: 0, size: 0}, // NOP operand variations added for #40689
519         {as: obj.ANOP, a1: C_REG, type_: 0, size: 0},  // to preserve previous behavior
520         {as: obj.ANOP, a1: C_FREG, type_: 0, size: 0},
521         {as: obj.ADUFFZERO, a6: C_LBRA, type_: 11, size: 4}, // same as ABR/ABL
522         {as: obj.ADUFFCOPY, a6: C_LBRA, type_: 11, size: 4}, // same as ABR/ABL
523         {as: obj.APCALIGN, a1: C_LCON, type_: 0, size: 0},   // align code
524 }
525
526 // These are opcodes above which may generate different sequences depending on whether prefix opcode support
527 // is available
528 type PrefixableOptab struct {
529         Optab
530         minGOPPC64 int  // Minimum GOPPC64 required to support this.
531         pfxsize    int8 // Instruction sequence size when prefixed opcodes are used
532 }
533
534 // The prefixable optab entry contains the pseudo-opcodes which generate relocations, or may generate
535 // a more efficient sequence of instructions if a prefixed version exists (ex. paddi instead of oris/ori/add).
536 //
537 // This table is meant to transform all sequences which might be TOC-relative into an equivalent PC-relative
538 // sequence. It also encompasses several transformations which do not involve relocations, those could be
539 // separated and applied to AIX and other non-ELF targets. Likewise, the prefixed forms do not have encoding
540 // restrictions on the offset, so they are also used for static binary to allow better code generation. e.x
541 //
542 //      MOVD something-byte-aligned(Rx), Ry
543 //      MOVD 3(Rx), Ry
544 //
545 // is allowed when the prefixed forms are used.
546 //
547 // This requires an ISA 3.1 compatible cpu (e.g Power10), and when linking externally an ELFv2 1.5 compliant.
548 var prefixableOptab = []PrefixableOptab{
549         {Optab: Optab{as: AMOVD, a1: C_S34CON, a6: C_REG, type_: 19, size: 8}, minGOPPC64: 10, pfxsize: 8},
550         {Optab: Optab{as: AMOVD, a1: C_ADDR, a6: C_REG, type_: 75, size: 8}, minGOPPC64: 10, pfxsize: 8},
551         {Optab: Optab{as: AMOVD, a1: C_TLS_LE, a6: C_REG, type_: 79, size: 8}, minGOPPC64: 10, pfxsize: 8},
552         {Optab: Optab{as: AMOVD, a1: C_TLS_IE, a6: C_REG, type_: 80, size: 12}, minGOPPC64: 10, pfxsize: 12},
553         {Optab: Optab{as: AMOVD, a1: C_LACON, a6: C_REG, type_: 26, size: 8}, minGOPPC64: 10, pfxsize: 8},
554         {Optab: Optab{as: AMOVD, a1: C_LOREG, a6: C_REG, type_: 36, size: 8}, minGOPPC64: 10, pfxsize: 8},
555         {Optab: Optab{as: AMOVD, a1: C_REG, a6: C_LOREG, type_: 35, size: 8}, minGOPPC64: 10, pfxsize: 8},
556         {Optab: Optab{as: AMOVD, a1: C_REG, a6: C_ADDR, type_: 74, size: 8}, minGOPPC64: 10, pfxsize: 8},
557
558         {Optab: Optab{as: AMOVW, a1: C_LCON, a6: C_REG, type_: 19, size: 8}, minGOPPC64: 10, pfxsize: 8},
559         {Optab: Optab{as: AMOVW, a1: C_LACON, a6: C_REG, type_: 26, size: 8}, minGOPPC64: 10, pfxsize: 8},
560         {Optab: Optab{as: AMOVW, a1: C_LOREG, a6: C_REG, type_: 36, size: 8}, minGOPPC64: 10, pfxsize: 8},
561         {Optab: Optab{as: AMOVW, a1: C_ADDR, a6: C_REG, type_: 75, size: 8}, minGOPPC64: 10, pfxsize: 8},
562         {Optab: Optab{as: AMOVW, a1: C_REG, a6: C_LOREG, type_: 35, size: 8}, minGOPPC64: 10, pfxsize: 8},
563         {Optab: Optab{as: AMOVW, a1: C_REG, a6: C_ADDR, type_: 74, size: 8}, minGOPPC64: 10, pfxsize: 8},
564
565         {Optab: Optab{as: AMOVB, a1: C_REG, a6: C_LOREG, type_: 35, size: 8}, minGOPPC64: 10, pfxsize: 8},
566         {Optab: Optab{as: AMOVB, a1: C_LOREG, a6: C_REG, type_: 36, size: 12}, minGOPPC64: 10, pfxsize: 12},
567         {Optab: Optab{as: AMOVB, a1: C_ADDR, a6: C_REG, type_: 75, size: 12}, minGOPPC64: 10, pfxsize: 12},
568         {Optab: Optab{as: AMOVB, a1: C_REG, a6: C_ADDR, type_: 74, size: 8}, minGOPPC64: 10, pfxsize: 8},
569
570         {Optab: Optab{as: AMOVBZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8}, minGOPPC64: 10, pfxsize: 8},
571         {Optab: Optab{as: AMOVBZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8}, minGOPPC64: 10, pfxsize: 8},
572         {Optab: Optab{as: AMOVBZ, a1: C_REG, a6: C_LOREG, type_: 35, size: 8}, minGOPPC64: 10, pfxsize: 8},
573         {Optab: Optab{as: AMOVBZ, a1: C_REG, a6: C_ADDR, type_: 74, size: 8}, minGOPPC64: 10, pfxsize: 8},
574
575         {Optab: Optab{as: AFMOVD, a1: C_LOREG, a6: C_FREG, type_: 36, size: 8}, minGOPPC64: 10, pfxsize: 8},
576         {Optab: Optab{as: AFMOVD, a1: C_ADDR, a6: C_FREG, type_: 75, size: 8}, minGOPPC64: 10, pfxsize: 8},
577         {Optab: Optab{as: AFMOVD, a1: C_FREG, a6: C_LOREG, type_: 35, size: 8}, minGOPPC64: 10, pfxsize: 8},
578         {Optab: Optab{as: AFMOVD, a1: C_FREG, a6: C_ADDR, type_: 74, size: 8}, minGOPPC64: 10, pfxsize: 8},
579
580         {Optab: Optab{as: AADD, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 22, size: 12}, minGOPPC64: 10, pfxsize: 8},
581         {Optab: Optab{as: AADD, a1: C_LCON, a6: C_REG, type_: 22, size: 12}, minGOPPC64: 10, pfxsize: 8},
582         {Optab: Optab{as: AADD, a1: C_S34CON, a2: C_REG, a6: C_REG, type_: 22, size: 20}, minGOPPC64: 10, pfxsize: 8},
583         {Optab: Optab{as: AADD, a1: C_S34CON, a6: C_REG, type_: 22, size: 20}, minGOPPC64: 10, pfxsize: 8},
584 }
585
586 var oprange [ALAST & obj.AMask][]Optab
587
588 var xcmp [C_NCLASS][C_NCLASS]bool
589
590 var pfxEnabled = false // ISA 3.1 prefixed instructions are supported.
591 var buildOpCfg = ""    // Save the os/cpu/arch tuple used to configure the assembler in buildop
592
593 // padding bytes to add to align code as requested.
594 func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int {
595         switch a {
596         case 8, 16, 32, 64:
597                 // By default function alignment is 16. If an alignment > 16 is
598                 // requested then the function alignment must also be promoted.
599                 // The function alignment is not promoted on AIX at this time.
600                 // TODO: Investigate AIX function alignment.
601                 if ctxt.Headtype != objabi.Haix && cursym.Func().Align < int32(a) {
602                         cursym.Func().Align = int32(a)
603                 }
604                 if pc&(a-1) != 0 {
605                         return int(a - (pc & (a - 1)))
606                 }
607         default:
608                 ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a)
609         }
610         return 0
611 }
612
613 // Get the implied register of an operand which doesn't specify one.  These show up
614 // in handwritten asm like "MOVD R5, foosymbol" where a base register is not supplied,
615 // or "MOVD R5, foo+10(SP) or pseudo-register is used.  The other common case is when
616 // generating constants in register like "MOVD $constant, Rx".
617 func (c *ctxt9) getimpliedreg(a *obj.Addr, p *obj.Prog) int {
618         class := oclass(a)
619         if class >= C_ZCON && class <= C_64CON {
620                 return REGZERO
621         }
622         switch class {
623         case C_SACON, C_LACON:
624                 return REGSP
625         case C_LOREG, C_SOREG, C_ZOREG, C_XOREG:
626                 switch a.Name {
627                 case obj.NAME_EXTERN, obj.NAME_STATIC:
628                         return REGSB
629                 case obj.NAME_AUTO, obj.NAME_PARAM:
630                         return REGSP
631                 case obj.NAME_NONE:
632                         return REGZERO
633                 }
634         }
635         c.ctxt.Diag("failed to determine implied reg for class %v (%v)", DRconv(oclass(a)), p)
636         return 0
637 }
638
639 func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
640         p := cursym.Func().Text
641         if p == nil || p.Link == nil { // handle external functions and ELF section symbols
642                 return
643         }
644
645         if oprange[AANDN&obj.AMask] == nil {
646                 ctxt.Diag("ppc64 ops not initialized, call ppc64.buildop first")
647         }
648
649         c := ctxt9{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset)}
650
651         pc := int64(0)
652         p.Pc = pc
653
654         var m int
655         var o *Optab
656         for p = p.Link; p != nil; p = p.Link {
657                 p.Pc = pc
658                 o = c.oplook(p)
659                 m = int(o.size)
660                 if m == 0 {
661                         if p.As == obj.APCALIGN {
662                                 a := c.vregoff(&p.From)
663                                 m = addpad(pc, a, ctxt, cursym)
664                         } else {
665                                 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
666                                         ctxt.Diag("zero-width instruction\n%v", p)
667                                 }
668                                 continue
669                         }
670                 }
671                 pc += int64(m)
672         }
673
674         c.cursym.Size = pc
675
676         /*
677          * if any procedure is large enough to
678          * generate a large SBRA branch, then
679          * generate extra passes putting branches
680          * around jmps to fix. this is rare.
681          */
682         bflag := 1
683
684         var otxt int64
685         var q *obj.Prog
686         var out [5]uint32
687         var falign int32 // Track increased alignment requirements for prefix.
688         for bflag != 0 {
689                 bflag = 0
690                 pc = 0
691                 falign = 0 // Note, linker bumps function symbols to funcAlign.
692                 for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
693                         p.Pc = pc
694                         o = c.oplook(p)
695
696                         // very large conditional branches
697                         if (o.type_ == 16 || o.type_ == 17) && p.To.Target() != nil {
698                                 otxt = p.To.Target().Pc - pc
699                                 if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
700                                         // Assemble the instruction with a target not too far to figure out BI and BO fields.
701                                         // If only the CTR or BI (the CR bit) are tested, the conditional branch can be inverted,
702                                         // and only one extra branch is needed to reach the target.
703                                         tgt := p.To.Target()
704                                         p.To.SetTarget(p.Link)
705                                         o.asmout(&c, p, o, &out)
706                                         p.To.SetTarget(tgt)
707
708                                         bo := int64(out[0]>>21) & 31
709                                         bi := int16((out[0] >> 16) & 31)
710                                         invertible := false
711
712                                         if bo&0x14 == 0x14 {
713                                                 // A conditional branch that is unconditionally taken. This cannot be inverted.
714                                         } else if bo&0x10 == 0x10 {
715                                                 // A branch based on the value of CTR. Invert the CTR comparison against zero bit.
716                                                 bo ^= 0x2
717                                                 invertible = true
718                                         } else if bo&0x04 == 0x04 {
719                                                 // A branch based on CR bit. Invert the BI comparison bit.
720                                                 bo ^= 0x8
721                                                 invertible = true
722                                         }
723
724                                         if invertible {
725                                                 // Rewrite
726                                                 //     BC bo,...,far_away_target
727                                                 //     NEXT_INSN
728                                                 // to:
729                                                 //     BC invert(bo),next_insn
730                                                 //     JMP far_away_target
731                                                 //   next_insn:
732                                                 //     NEXT_INSN
733                                                 p.As = ABC
734                                                 p.From = obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: bo}
735                                                 q = c.newprog()
736                                                 q.As = ABR
737                                                 q.To.Type = obj.TYPE_BRANCH
738                                                 q.To.SetTarget(p.To.Target())
739                                                 q.Link = p.Link
740                                                 p.To.SetTarget(p.Link)
741                                                 p.Link = q
742                                                 p.Reg = REG_CRBIT0 + bi
743                                         } else {
744                                                 // Rewrite
745                                                 //     BC ...,far_away_target
746                                                 //     NEXT_INSN
747                                                 // to
748                                                 //     BC ...,tmp
749                                                 //     JMP next_insn
750                                                 //   tmp:
751                                                 //     JMP far_away_target
752                                                 //   next_insn:
753                                                 //     NEXT_INSN
754                                                 q = c.newprog()
755                                                 q.Link = p.Link
756                                                 p.Link = q
757                                                 q.As = ABR
758                                                 q.To.Type = obj.TYPE_BRANCH
759                                                 q.To.SetTarget(p.To.Target())
760                                                 p.To.SetTarget(q)
761                                                 q = c.newprog()
762                                                 q.Link = p.Link
763                                                 p.Link = q
764                                                 q.As = ABR
765                                                 q.To.Type = obj.TYPE_BRANCH
766                                                 q.To.SetTarget(q.Link.Link)
767                                         }
768                                         bflag = 1
769                                 }
770                         }
771
772                         m = int(o.size)
773                         if m == 0 {
774                                 if p.As == obj.APCALIGN {
775                                         a := c.vregoff(&p.From)
776                                         m = addpad(pc, a, ctxt, cursym)
777                                 } else {
778                                         if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
779                                                 ctxt.Diag("zero-width instruction\n%v", p)
780                                         }
781                                         continue
782                                 }
783                         }
784
785                         // Prefixed instructions cannot be placed across a 64B boundary.
786                         // Mark and adjust the PC of those which do. A nop will be
787                         // inserted during final assembly.
788                         if o.ispfx {
789                                 mark := p.Mark &^ PFX_X64B
790                                 if pc&63 == 60 {
791                                         p.Pc += 4
792                                         m += 4
793                                         mark |= PFX_X64B
794                                 }
795
796                                 // Marks may be adjusted if a too-far conditional branch is
797                                 // fixed up above. Likewise, inserting a NOP may cause a
798                                 // branch target to become too far away.  We need to run
799                                 // another iteration and verify no additional changes
800                                 // are needed.
801                                 if mark != p.Mark {
802                                         bflag = 1
803                                         p.Mark = mark
804                                 }
805
806                                 // Check for 16 or 32B crossing of this prefixed insn.
807                                 // These do no require padding, but do require increasing
808                                 // the function alignment to prevent them from potentially
809                                 // crossing a 64B boundary when the linker assigns the final
810                                 // PC.
811                                 switch p.Pc & 31 {
812                                 case 28: // 32B crossing
813                                         falign = 64
814                                 case 12: // 16B crossing
815                                         if falign < 64 {
816                                                 falign = 32
817                                         }
818                                 }
819                         }
820
821                         pc += int64(m)
822                 }
823
824                 c.cursym.Size = pc
825         }
826
827         c.cursym.Size = pc
828         c.cursym.Func().Align = falign
829         c.cursym.Grow(c.cursym.Size)
830
831         // lay out the code, emitting code and data relocations.
832
833         bp := c.cursym.P
834         nop := LOP_IRR(OP_ORI, REGZERO, REGZERO, 0)
835         var i int32
836         for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
837                 c.pc = p.Pc
838                 o = c.oplook(p)
839                 if int(o.size) > 4*len(out) {
840                         log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)
841                 }
842                 // asmout is not set up to add large amounts of padding
843                 if o.type_ == 0 && p.As == obj.APCALIGN {
844                         aln := c.vregoff(&p.From)
845                         v := addpad(p.Pc, aln, c.ctxt, c.cursym)
846                         if v > 0 {
847                                 // Same padding instruction for all
848                                 for i = 0; i < int32(v/4); i++ {
849                                         c.ctxt.Arch.ByteOrder.PutUint32(bp, nop)
850                                         bp = bp[4:]
851                                 }
852                         }
853                 } else {
854                         if p.Mark&PFX_X64B != 0 {
855                                 c.ctxt.Arch.ByteOrder.PutUint32(bp, nop)
856                                 bp = bp[4:]
857                         }
858                         o.asmout(&c, p, o, &out)
859                         for i = 0; i < int32(o.size/4); i++ {
860                                 c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
861                                 bp = bp[4:]
862                         }
863                 }
864         }
865 }
866
867 func isint32(v int64) bool {
868         return int64(int32(v)) == v
869 }
870
871 func isuint32(v uint64) bool {
872         return uint64(uint32(v)) == v
873 }
874
875 func (c *ctxt9) aclassreg(reg int16) int {
876         if REG_R0 <= reg && reg <= REG_R31 {
877                 return C_REGP + int(reg&1)
878         }
879         if REG_F0 <= reg && reg <= REG_F31 {
880                 return C_FREGP + int(reg&1)
881         }
882         if REG_V0 <= reg && reg <= REG_V31 {
883                 return C_VREG
884         }
885         if REG_VS0 <= reg && reg <= REG_VS63 {
886                 return C_VSREGP + int(reg&1)
887         }
888         if REG_CR0 <= reg && reg <= REG_CR7 || reg == REG_CR {
889                 return C_CREG
890         }
891         if REG_CR0LT <= reg && reg <= REG_CR7SO {
892                 return C_CRBIT
893         }
894         if REG_SPR0 <= reg && reg <= REG_SPR0+1023 {
895                 switch reg {
896                 case REG_LR:
897                         return C_LR
898
899                 case REG_XER:
900                         return C_XER
901
902                 case REG_CTR:
903                         return C_CTR
904                 }
905
906                 return C_SPR
907         }
908         if REG_A0 <= reg && reg <= REG_A7 {
909                 return C_AREG
910         }
911         if reg == REG_FPSCR {
912                 return C_FPSCR
913         }
914         return C_GOK
915 }
916
917 func (c *ctxt9) aclass(a *obj.Addr) int {
918         switch a.Type {
919         case obj.TYPE_NONE:
920                 return C_NONE
921
922         case obj.TYPE_REG:
923                 return c.aclassreg(a.Reg)
924
925         case obj.TYPE_MEM:
926                 if a.Index != 0 {
927                         if a.Name != obj.NAME_NONE || a.Offset != 0 {
928                                 c.ctxt.Logf("Unexpected Instruction operand index %d offset %d class %d \n", a.Index, a.Offset, a.Class)
929
930                         }
931                         return C_XOREG
932                 }
933                 switch a.Name {
934                 case obj.NAME_GOTREF, obj.NAME_TOCREF:
935                         return C_ADDR
936
937                 case obj.NAME_EXTERN,
938                         obj.NAME_STATIC:
939                         c.instoffset = a.Offset
940                         if a.Sym == nil {
941                                 break
942                         } else if a.Sym.Type == objabi.STLSBSS {
943                                 // For PIC builds, use 12 byte got initial-exec TLS accesses.
944                                 if c.ctxt.Flag_shared {
945                                         return C_TLS_IE
946                                 }
947                                 // Otherwise, use 8 byte local-exec TLS accesses.
948                                 return C_TLS_LE
949                         } else {
950                                 return C_ADDR
951                         }
952
953                 case obj.NAME_AUTO:
954                         c.instoffset = int64(c.autosize) + a.Offset
955
956                         if c.instoffset >= -BIG && c.instoffset < BIG {
957                                 return C_SOREG
958                         }
959                         return C_LOREG
960
961                 case obj.NAME_PARAM:
962                         c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
963                         if c.instoffset >= -BIG && c.instoffset < BIG {
964                                 return C_SOREG
965                         }
966                         return C_LOREG
967
968                 case obj.NAME_NONE:
969                         c.instoffset = a.Offset
970                         if a.Offset == 0 && a.Index == 0 {
971                                 return C_ZOREG
972                         } else if c.instoffset >= -BIG && c.instoffset < BIG {
973                                 return C_SOREG
974                         } else {
975                                 return C_LOREG
976                         }
977                 }
978
979                 return C_GOK
980
981         case obj.TYPE_TEXTSIZE:
982                 return C_TEXTSIZE
983
984         case obj.TYPE_FCONST:
985                 // The only cases where FCONST will occur are with float64 +/- 0.
986                 // All other float constants are generated in memory.
987                 f64 := a.Val.(float64)
988                 if f64 == 0 {
989                         if math.Signbit(f64) {
990                                 return C_ADDCON
991                         }
992                         return C_ZCON
993                 }
994                 log.Fatalf("Unexpected nonzero FCONST operand %v", a)
995
996         case obj.TYPE_CONST,
997                 obj.TYPE_ADDR:
998                 switch a.Name {
999                 case obj.NAME_NONE:
1000                         c.instoffset = a.Offset
1001                         if a.Reg != 0 {
1002                                 if -BIG <= c.instoffset && c.instoffset < BIG {
1003                                         return C_SACON
1004                                 }
1005                                 if isint32(c.instoffset) {
1006                                         return C_LACON
1007                                 }
1008                                 return C_DACON
1009                         }
1010
1011                 case obj.NAME_EXTERN,
1012                         obj.NAME_STATIC:
1013                         s := a.Sym
1014                         if s == nil {
1015                                 return C_GOK
1016                         }
1017                         c.instoffset = a.Offset
1018                         return C_LACON
1019
1020                 case obj.NAME_AUTO:
1021                         c.instoffset = int64(c.autosize) + a.Offset
1022                         if c.instoffset >= -BIG && c.instoffset < BIG {
1023                                 return C_SACON
1024                         }
1025                         return C_LACON
1026
1027                 case obj.NAME_PARAM:
1028                         c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
1029                         if c.instoffset >= -BIG && c.instoffset < BIG {
1030                                 return C_SACON
1031                         }
1032                         return C_LACON
1033
1034                 default:
1035                         return C_GOK
1036                 }
1037
1038                 if c.instoffset >= 0 {
1039                         sbits := bits.Len64(uint64(c.instoffset))
1040                         switch {
1041                         case sbits <= 5:
1042                                 return C_ZCON + sbits
1043                         case sbits <= 8:
1044                                 return C_U8CON
1045                         case sbits <= 15:
1046                                 return C_U15CON
1047                         case sbits <= 16:
1048                                 return C_U16CON
1049                         case sbits <= 31:
1050                                 // Special case, a positive int32 value which is a multiple of 2^16
1051                                 if c.instoffset&0xFFFF == 0 {
1052                                         return C_U3216CON
1053                                 }
1054                                 return C_U32CON
1055                         case sbits <= 32:
1056                                 return C_U32CON
1057                         case sbits <= 33:
1058                                 return C_S34CON
1059                         default:
1060                                 return C_64CON
1061                         }
1062                 } else {
1063                         sbits := bits.Len64(uint64(^c.instoffset))
1064                         switch {
1065                         case sbits <= 15:
1066                                 return C_S16CON
1067                         case sbits <= 31:
1068                                 // Special case, a negative int32 value which is a multiple of 2^16
1069                                 if c.instoffset&0xFFFF == 0 {
1070                                         return C_S3216CON
1071                                 }
1072                                 return C_S32CON
1073                         case sbits <= 33:
1074                                 return C_S34CON
1075                         default:
1076                                 return C_64CON
1077                         }
1078                 }
1079
1080         case obj.TYPE_BRANCH:
1081                 if a.Sym != nil && c.ctxt.Flag_dynlink && !pfxEnabled {
1082                         return C_LBRAPIC
1083                 }
1084                 return C_SBRA
1085         }
1086
1087         return C_GOK
1088 }
1089
1090 func prasm(p *obj.Prog) {
1091         fmt.Printf("%v\n", p)
1092 }
1093
1094 func (c *ctxt9) oplook(p *obj.Prog) *Optab {
1095         a1 := int(p.Optab)
1096         if a1 != 0 {
1097                 return &optab[a1-1]
1098         }
1099         a1 = int(p.From.Class)
1100         if a1 == 0 {
1101                 a1 = c.aclass(&p.From) + 1
1102                 p.From.Class = int8(a1)
1103         }
1104         a1--
1105
1106         argsv := [3]int{C_NONE + 1, C_NONE + 1, C_NONE + 1}
1107         for i, ap := range p.RestArgs {
1108                 argsv[i] = int(ap.Addr.Class)
1109                 if argsv[i] == 0 {
1110                         argsv[i] = c.aclass(&ap.Addr) + 1
1111                         ap.Addr.Class = int8(argsv[i])
1112                 }
1113
1114         }
1115         a3 := argsv[0] - 1
1116         a4 := argsv[1] - 1
1117         a5 := argsv[2] - 1
1118
1119         a6 := int(p.To.Class)
1120         if a6 == 0 {
1121                 a6 = c.aclass(&p.To) + 1
1122                 p.To.Class = int8(a6)
1123         }
1124         a6--
1125
1126         a2 := C_NONE
1127         if p.Reg != 0 {
1128                 a2 = c.aclassreg(p.Reg)
1129         }
1130
1131         // c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4, a5, a6)
1132         ops := oprange[p.As&obj.AMask]
1133         c1 := &xcmp[a1]
1134         c2 := &xcmp[a2]
1135         c3 := &xcmp[a3]
1136         c4 := &xcmp[a4]
1137         c5 := &xcmp[a5]
1138         c6 := &xcmp[a6]
1139         for i := range ops {
1140                 op := &ops[i]
1141                 if c1[op.a1] && c2[op.a2] && c3[op.a3] && c4[op.a4] && c5[op.a5] && c6[op.a6] {
1142                         p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
1143                         return op
1144                 }
1145         }
1146
1147         c.ctxt.Diag("illegal combination %v %v %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4), DRconv(a5), DRconv(a6))
1148         prasm(p)
1149         if ops == nil {
1150                 ops = optab
1151         }
1152         return &ops[0]
1153 }
1154
1155 // Compare two operand types (ex C_REG, or C_SCON)
1156 // and return true if b is compatible with a.
1157 //
1158 // Argument comparison isn't reflexitive, so care must be taken.
1159 // a is the argument type as found in optab, b is the argument as
1160 // fitted by aclass.
1161 func cmp(a int, b int) bool {
1162         if a == b {
1163                 return true
1164         }
1165         switch a {
1166
1167         case C_SPR:
1168                 if b == C_LR || b == C_XER || b == C_CTR {
1169                         return true
1170                 }
1171
1172         case C_U1CON:
1173                 return cmp(C_ZCON, b)
1174         case C_U2CON:
1175                 return cmp(C_U1CON, b)
1176         case C_U3CON:
1177                 return cmp(C_U2CON, b)
1178         case C_U4CON:
1179                 return cmp(C_U3CON, b)
1180         case C_U5CON:
1181                 return cmp(C_U4CON, b)
1182         case C_U8CON:
1183                 return cmp(C_U5CON, b)
1184         case C_U15CON:
1185                 return cmp(C_U8CON, b)
1186         case C_U16CON:
1187                 return cmp(C_U15CON, b)
1188
1189         case C_S16CON:
1190                 return cmp(C_U15CON, b)
1191         case C_32CON:
1192                 return cmp(C_S16CON, b) || cmp(C_U16CON, b) || cmp(C_32S16CON, b)
1193         case C_S34CON:
1194                 return cmp(C_32CON, b)
1195         case C_64CON:
1196                 return cmp(C_S34CON, b)
1197
1198         case C_32S16CON:
1199                 return cmp(C_ZCON, b)
1200
1201         case C_LACON:
1202                 return cmp(C_SACON, b)
1203
1204         case C_LBRA:
1205                 return cmp(C_SBRA, b)
1206
1207         case C_SOREG:
1208                 return cmp(C_ZOREG, b)
1209
1210         case C_LOREG:
1211                 return cmp(C_SOREG, b)
1212
1213         case C_XOREG:
1214                 return cmp(C_REG, b) || cmp(C_ZOREG, b)
1215
1216         // An even/odd register input always matches the regular register types.
1217         case C_REG:
1218                 return cmp(C_REGP, b) || (b == C_ZCON && r0iszero != 0)
1219         case C_FREG:
1220                 return cmp(C_FREGP, b)
1221         case C_VSREG:
1222                 /* Allow any VR argument as a VSR operand. */
1223                 return cmp(C_VSREGP, b) || cmp(C_VREG, b)
1224
1225         case C_ANY:
1226                 return true
1227         }
1228
1229         return false
1230 }
1231
1232 // Used when sorting the optab. Sorting is
1233 // done in a way so that the best choice of
1234 // opcode/operand combination is considered first.
1235 func optabLess(i, j int) bool {
1236         p1 := &optab[i]
1237         p2 := &optab[j]
1238         n := int(p1.as) - int(p2.as)
1239         // same opcode
1240         if n != 0 {
1241                 return n < 0
1242         }
1243         // Consider those that generate fewer
1244         // instructions first.
1245         n = int(p1.size) - int(p2.size)
1246         if n != 0 {
1247                 return n < 0
1248         }
1249         // operand order should match
1250         // better choices first
1251         n = int(p1.a1) - int(p2.a1)
1252         if n != 0 {
1253                 return n < 0
1254         }
1255         n = int(p1.a2) - int(p2.a2)
1256         if n != 0 {
1257                 return n < 0
1258         }
1259         n = int(p1.a3) - int(p2.a3)
1260         if n != 0 {
1261                 return n < 0
1262         }
1263         n = int(p1.a4) - int(p2.a4)
1264         if n != 0 {
1265                 return n < 0
1266         }
1267         n = int(p1.a5) - int(p2.a5)
1268         if n != 0 {
1269                 return n < 0
1270         }
1271         n = int(p1.a6) - int(p2.a6)
1272         if n != 0 {
1273                 return n < 0
1274         }
1275         return false
1276 }
1277
1278 // Add an entry to the opcode table for
1279 // a new opcode b0 with the same operand combinations
1280 // as opcode a.
1281 func opset(a, b0 obj.As) {
1282         oprange[a&obj.AMask] = oprange[b0]
1283 }
1284
1285 // Determine if the build configuration requires a TOC pointer.
1286 // It is assumed this always called after buildop.
1287 func NeedTOCpointer(ctxt *obj.Link) bool {
1288         return !pfxEnabled && ctxt.Flag_shared
1289 }
1290
1291 // Build the opcode table
1292 func buildop(ctxt *obj.Link) {
1293         // Limit PC-relative prefix instruction usage to supported and tested targets.
1294         pfxEnabled = buildcfg.GOPPC64 >= 10 && buildcfg.GOOS == "linux"
1295         cfg := fmt.Sprintf("power%d/%s/%s", buildcfg.GOPPC64, buildcfg.GOARCH, buildcfg.GOOS)
1296         if cfg == buildOpCfg {
1297                 // Already initialized to correct OS/cpu; stop now.
1298                 // This happens in the cmd/asm tests,
1299                 // each of which re-initializes the arch.
1300                 return
1301         }
1302         buildOpCfg = cfg
1303
1304         // Configure the optab entries which may generate prefix opcodes.
1305         prefixOptab := make([]Optab, 0, len(prefixableOptab))
1306         for _, entry := range prefixableOptab {
1307                 entry := entry
1308                 if pfxEnabled && buildcfg.GOPPC64 >= entry.minGOPPC64 {
1309                         // Enable prefix opcode generation and resize.
1310                         entry.ispfx = true
1311                         entry.size = entry.pfxsize
1312                 }
1313                 prefixOptab = append(prefixOptab, entry.Optab)
1314
1315         }
1316
1317         for i := 0; i < C_NCLASS; i++ {
1318                 for n := 0; n < C_NCLASS; n++ {
1319                         if cmp(n, i) {
1320                                 xcmp[i][n] = true
1321                         }
1322                 }
1323         }
1324
1325         // Append the generated entries, sort, and fill out oprange.
1326         optab = make([]Optab, 0, len(optabBase)+len(optabGen)+len(prefixOptab))
1327         optab = append(optab, optabBase...)
1328         optab = append(optab, optabGen...)
1329         optab = append(optab, prefixOptab...)
1330         sort.Slice(optab, optabLess)
1331
1332         for i := range optab {
1333                 // Use the legacy assembler function if none provided.
1334                 if optab[i].asmout == nil {
1335                         optab[i].asmout = asmout
1336                 }
1337         }
1338
1339         for i := 0; i < len(optab); {
1340                 r := optab[i].as
1341                 r0 := r & obj.AMask
1342                 start := i
1343                 for i < len(optab) && optab[i].as == r {
1344                         i++
1345                 }
1346                 oprange[r0] = optab[start:i]
1347
1348                 switch r {
1349                 default:
1350                         if !opsetGen(r) {
1351                                 ctxt.Diag("unknown op in build: %v", r)
1352                                 log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r)
1353                         }
1354
1355                 case ADCBF: /* unary indexed: op (b+a); op (b) */
1356                         opset(ADCBI, r0)
1357
1358                         opset(ADCBST, r0)
1359                         opset(ADCBT, r0)
1360                         opset(ADCBTST, r0)
1361                         opset(ADCBZ, r0)
1362                         opset(AICBI, r0)
1363
1364                 case ASTDCCC: /* indexed store: op s,(b+a); op s,(b) */
1365                         opset(ASTWCCC, r0)
1366                         opset(ASTHCCC, r0)
1367                         opset(ASTBCCC, r0)
1368
1369                 case AREM: /* macro */
1370                         opset(AREM, r0)
1371
1372                 case AREMU:
1373                         opset(AREMU, r0)
1374
1375                 case AREMD:
1376                         opset(AREMDU, r0)
1377
1378                 case AMULLW:
1379                         opset(AMULLD, r0)
1380
1381                 case ADIVW: /* op Rb[,Ra],Rd */
1382                         opset(AMULHW, r0)
1383
1384                         opset(AMULHWCC, r0)
1385                         opset(AMULHWU, r0)
1386                         opset(AMULHWUCC, r0)
1387                         opset(AMULLWCC, r0)
1388                         opset(AMULLWVCC, r0)
1389                         opset(AMULLWV, r0)
1390                         opset(ADIVWCC, r0)
1391                         opset(ADIVWV, r0)
1392                         opset(ADIVWVCC, r0)
1393                         opset(ADIVWU, r0)
1394                         opset(ADIVWUCC, r0)
1395                         opset(ADIVWUV, r0)
1396                         opset(ADIVWUVCC, r0)
1397                         opset(AMODUD, r0)
1398                         opset(AMODUW, r0)
1399                         opset(AMODSD, r0)
1400                         opset(AMODSW, r0)
1401                         opset(AADDCC, r0)
1402                         opset(AADDCV, r0)
1403                         opset(AADDCVCC, r0)
1404                         opset(AADDV, r0)
1405                         opset(AADDVCC, r0)
1406                         opset(AADDE, r0)
1407                         opset(AADDECC, r0)
1408                         opset(AADDEV, r0)
1409                         opset(AADDEVCC, r0)
1410                         opset(AMULHD, r0)
1411                         opset(AMULHDCC, r0)
1412                         opset(AMULHDU, r0)
1413                         opset(AMULHDUCC, r0)
1414                         opset(AMULLDCC, r0)
1415                         opset(AMULLDVCC, r0)
1416                         opset(AMULLDV, r0)
1417                         opset(ADIVD, r0)
1418                         opset(ADIVDCC, r0)
1419                         opset(ADIVDE, r0)
1420                         opset(ADIVDEU, r0)
1421                         opset(ADIVDECC, r0)
1422                         opset(ADIVDEUCC, r0)
1423                         opset(ADIVDVCC, r0)
1424                         opset(ADIVDV, r0)
1425                         opset(ADIVDU, r0)
1426                         opset(ADIVDUV, r0)
1427                         opset(ADIVDUVCC, r0)
1428                         opset(ADIVDUCC, r0)
1429
1430                 case ACRAND:
1431                         opset(ACRANDN, r0)
1432                         opset(ACREQV, r0)
1433                         opset(ACRNAND, r0)
1434                         opset(ACRNOR, r0)
1435                         opset(ACROR, r0)
1436                         opset(ACRORN, r0)
1437                         opset(ACRXOR, r0)
1438
1439                 case APOPCNTD: /* popcntd, popcntw, popcntb, cnttzw, cnttzd */
1440                         opset(APOPCNTW, r0)
1441                         opset(APOPCNTB, r0)
1442                         opset(ACNTTZW, r0)
1443                         opset(ACNTTZWCC, r0)
1444                         opset(ACNTTZD, r0)
1445                         opset(ACNTTZDCC, r0)
1446
1447                 case ACOPY: /* copy, paste. */
1448                         opset(APASTECC, r0)
1449
1450                 case AMADDHD: /* maddhd, maddhdu, maddld */
1451                         opset(AMADDHDU, r0)
1452                         opset(AMADDLD, r0)
1453
1454                 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
1455                         opset(AMOVH, r0)
1456                         opset(AMOVHZ, r0)
1457
1458                 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
1459                         opset(AMOVHU, r0)
1460
1461                         opset(AMOVHZU, r0)
1462                         opset(AMOVWU, r0)
1463                         opset(AMOVWZU, r0)
1464                         opset(AMOVDU, r0)
1465                         opset(AMOVMW, r0)
1466
1467                 case ALVEBX: /* lvebx, lvehx, lvewx, lvx, lvxl, lvsl, lvsr */
1468                         opset(ALVEHX, r0)
1469                         opset(ALVEWX, r0)
1470                         opset(ALVX, r0)
1471                         opset(ALVXL, r0)
1472                         opset(ALVSL, r0)
1473                         opset(ALVSR, r0)
1474
1475                 case ASTVEBX: /* stvebx, stvehx, stvewx, stvx, stvxl */
1476                         opset(ASTVEHX, r0)
1477                         opset(ASTVEWX, r0)
1478                         opset(ASTVX, r0)
1479                         opset(ASTVXL, r0)
1480
1481                 case AVAND: /* vand, vandc, vnand */
1482                         opset(AVAND, r0)
1483                         opset(AVANDC, r0)
1484                         opset(AVNAND, r0)
1485
1486                 case AVMRGOW: /* vmrgew, vmrgow */
1487                         opset(AVMRGEW, r0)
1488
1489                 case AVOR: /* vor, vorc, vxor, vnor, veqv */
1490                         opset(AVOR, r0)
1491                         opset(AVORC, r0)
1492                         opset(AVXOR, r0)
1493                         opset(AVNOR, r0)
1494                         opset(AVEQV, r0)
1495
1496                 case AVADDUM: /* vaddubm, vadduhm, vadduwm, vaddudm, vadduqm */
1497                         opset(AVADDUBM, r0)
1498                         opset(AVADDUHM, r0)
1499                         opset(AVADDUWM, r0)
1500                         opset(AVADDUDM, r0)
1501                         opset(AVADDUQM, r0)
1502
1503                 case AVADDCU: /* vaddcuq, vaddcuw */
1504                         opset(AVADDCUQ, r0)
1505                         opset(AVADDCUW, r0)
1506
1507                 case AVADDUS: /* vaddubs, vadduhs, vadduws */
1508                         opset(AVADDUBS, r0)
1509                         opset(AVADDUHS, r0)
1510                         opset(AVADDUWS, r0)
1511
1512                 case AVADDSS: /* vaddsbs, vaddshs, vaddsws */
1513                         opset(AVADDSBS, r0)
1514                         opset(AVADDSHS, r0)
1515                         opset(AVADDSWS, r0)
1516
1517                 case AVADDE: /* vaddeuqm, vaddecuq */
1518                         opset(AVADDEUQM, r0)
1519                         opset(AVADDECUQ, r0)
1520
1521                 case AVSUBUM: /* vsububm, vsubuhm, vsubuwm, vsubudm, vsubuqm */
1522                         opset(AVSUBUBM, r0)
1523                         opset(AVSUBUHM, r0)
1524                         opset(AVSUBUWM, r0)
1525                         opset(AVSUBUDM, r0)
1526                         opset(AVSUBUQM, r0)
1527
1528                 case AVSUBCU: /* vsubcuq, vsubcuw */
1529                         opset(AVSUBCUQ, r0)
1530                         opset(AVSUBCUW, r0)
1531
1532                 case AVSUBUS: /* vsububs, vsubuhs, vsubuws */
1533                         opset(AVSUBUBS, r0)
1534                         opset(AVSUBUHS, r0)
1535                         opset(AVSUBUWS, r0)
1536
1537                 case AVSUBSS: /* vsubsbs, vsubshs, vsubsws */
1538                         opset(AVSUBSBS, r0)
1539                         opset(AVSUBSHS, r0)
1540                         opset(AVSUBSWS, r0)
1541
1542                 case AVSUBE: /* vsubeuqm, vsubecuq */
1543                         opset(AVSUBEUQM, r0)
1544                         opset(AVSUBECUQ, r0)
1545
1546                 case AVMULESB: /* vmulesb, vmulosb, vmuleub, vmuloub, vmulosh, vmulouh, vmulesw, vmulosw, vmuleuw, vmulouw, vmuluwm */
1547                         opset(AVMULOSB, r0)
1548                         opset(AVMULEUB, r0)
1549                         opset(AVMULOUB, r0)
1550                         opset(AVMULESH, r0)
1551                         opset(AVMULOSH, r0)
1552                         opset(AVMULEUH, r0)
1553                         opset(AVMULOUH, r0)
1554                         opset(AVMULESW, r0)
1555                         opset(AVMULOSW, r0)
1556                         opset(AVMULEUW, r0)
1557                         opset(AVMULOUW, r0)
1558                         opset(AVMULUWM, r0)
1559                 case AVPMSUM: /* vpmsumb, vpmsumh, vpmsumw, vpmsumd */
1560                         opset(AVPMSUMB, r0)
1561                         opset(AVPMSUMH, r0)
1562                         opset(AVPMSUMW, r0)
1563                         opset(AVPMSUMD, r0)
1564
1565                 case AVR: /* vrlb, vrlh, vrlw, vrld */
1566                         opset(AVRLB, r0)
1567                         opset(AVRLH, r0)
1568                         opset(AVRLW, r0)
1569                         opset(AVRLD, r0)
1570
1571                 case AVS: /* vs[l,r], vs[l,r]o, vs[l,r]b, vs[l,r]h, vs[l,r]w, vs[l,r]d */
1572                         opset(AVSLB, r0)
1573                         opset(AVSLH, r0)
1574                         opset(AVSLW, r0)
1575                         opset(AVSL, r0)
1576                         opset(AVSLO, r0)
1577                         opset(AVSRB, r0)
1578                         opset(AVSRH, r0)
1579                         opset(AVSRW, r0)
1580                         opset(AVSR, r0)
1581                         opset(AVSRO, r0)
1582                         opset(AVSLD, r0)
1583                         opset(AVSRD, r0)
1584
1585                 case AVSA: /* vsrab, vsrah, vsraw, vsrad */
1586                         opset(AVSRAB, r0)
1587                         opset(AVSRAH, r0)
1588                         opset(AVSRAW, r0)
1589                         opset(AVSRAD, r0)
1590
1591                 case AVSOI: /* vsldoi */
1592                         opset(AVSLDOI, r0)
1593
1594                 case AVCLZ: /* vclzb, vclzh, vclzw, vclzd */
1595                         opset(AVCLZB, r0)
1596                         opset(AVCLZH, r0)
1597                         opset(AVCLZW, r0)
1598                         opset(AVCLZD, r0)
1599
1600                 case AVPOPCNT: /* vpopcntb, vpopcnth, vpopcntw, vpopcntd */
1601                         opset(AVPOPCNTB, r0)
1602                         opset(AVPOPCNTH, r0)
1603                         opset(AVPOPCNTW, r0)
1604                         opset(AVPOPCNTD, r0)
1605
1606                 case AVCMPEQ: /* vcmpequb[.], vcmpequh[.], vcmpequw[.], vcmpequd[.] */
1607                         opset(AVCMPEQUB, r0)
1608                         opset(AVCMPEQUBCC, r0)
1609                         opset(AVCMPEQUH, r0)
1610                         opset(AVCMPEQUHCC, r0)
1611                         opset(AVCMPEQUW, r0)
1612                         opset(AVCMPEQUWCC, r0)
1613                         opset(AVCMPEQUD, r0)
1614                         opset(AVCMPEQUDCC, r0)
1615
1616                 case AVCMPGT: /* vcmpgt[u,s]b[.], vcmpgt[u,s]h[.], vcmpgt[u,s]w[.], vcmpgt[u,s]d[.] */
1617                         opset(AVCMPGTUB, r0)
1618                         opset(AVCMPGTUBCC, r0)
1619                         opset(AVCMPGTUH, r0)
1620                         opset(AVCMPGTUHCC, r0)
1621                         opset(AVCMPGTUW, r0)
1622                         opset(AVCMPGTUWCC, r0)
1623                         opset(AVCMPGTUD, r0)
1624                         opset(AVCMPGTUDCC, r0)
1625                         opset(AVCMPGTSB, r0)
1626                         opset(AVCMPGTSBCC, r0)
1627                         opset(AVCMPGTSH, r0)
1628                         opset(AVCMPGTSHCC, r0)
1629                         opset(AVCMPGTSW, r0)
1630                         opset(AVCMPGTSWCC, r0)
1631                         opset(AVCMPGTSD, r0)
1632                         opset(AVCMPGTSDCC, r0)
1633
1634                 case AVCMPNEZB: /* vcmpnezb[.] */
1635                         opset(AVCMPNEZBCC, r0)
1636                         opset(AVCMPNEB, r0)
1637                         opset(AVCMPNEBCC, r0)
1638                         opset(AVCMPNEH, r0)
1639                         opset(AVCMPNEHCC, r0)
1640                         opset(AVCMPNEW, r0)
1641                         opset(AVCMPNEWCC, r0)
1642
1643                 case AVPERM: /* vperm */
1644                         opset(AVPERMXOR, r0)
1645                         opset(AVPERMR, r0)
1646
1647                 case AVBPERMQ: /* vbpermq, vbpermd */
1648                         opset(AVBPERMD, r0)
1649
1650                 case AVSEL: /* vsel */
1651                         opset(AVSEL, r0)
1652
1653                 case AVSPLTB: /* vspltb, vsplth, vspltw */
1654                         opset(AVSPLTH, r0)
1655                         opset(AVSPLTW, r0)
1656
1657                 case AVSPLTISB: /* vspltisb, vspltish, vspltisw */
1658                         opset(AVSPLTISH, r0)
1659                         opset(AVSPLTISW, r0)
1660
1661                 case AVCIPH: /* vcipher, vcipherlast */
1662                         opset(AVCIPHER, r0)
1663                         opset(AVCIPHERLAST, r0)
1664
1665                 case AVNCIPH: /* vncipher, vncipherlast */
1666                         opset(AVNCIPHER, r0)
1667                         opset(AVNCIPHERLAST, r0)
1668
1669                 case AVSBOX: /* vsbox */
1670                         opset(AVSBOX, r0)
1671
1672                 case AVSHASIGMA: /* vshasigmaw, vshasigmad */
1673                         opset(AVSHASIGMAW, r0)
1674                         opset(AVSHASIGMAD, r0)
1675
1676                 case ALXVD2X: /* lxvd2x, lxvdsx, lxvw4x, lxvh8x, lxvb16x */
1677                         opset(ALXVDSX, r0)
1678                         opset(ALXVW4X, r0)
1679                         opset(ALXVH8X, r0)
1680                         opset(ALXVB16X, r0)
1681
1682                 case ALXV: /* lxv */
1683                         opset(ALXV, r0)
1684
1685                 case ALXVL: /* lxvl, lxvll, lxvx */
1686                         opset(ALXVLL, r0)
1687                         opset(ALXVX, r0)
1688
1689                 case ASTXVD2X: /* stxvd2x, stxvdsx, stxvw4x, stxvh8x, stxvb16x */
1690                         opset(ASTXVW4X, r0)
1691                         opset(ASTXVH8X, r0)
1692                         opset(ASTXVB16X, r0)
1693
1694                 case ASTXV: /* stxv */
1695                         opset(ASTXV, r0)
1696
1697                 case ASTXVL: /* stxvl, stxvll, stvx */
1698                         opset(ASTXVLL, r0)
1699                         opset(ASTXVX, r0)
1700
1701                 case ALXSDX: /* lxsdx  */
1702                         opset(ALXSDX, r0)
1703
1704                 case ASTXSDX: /* stxsdx */
1705                         opset(ASTXSDX, r0)
1706
1707                 case ALXSIWAX: /* lxsiwax, lxsiwzx  */
1708                         opset(ALXSIWZX, r0)
1709
1710                 case ASTXSIWX: /* stxsiwx */
1711                         opset(ASTXSIWX, r0)
1712
1713                 case AMFVSRD: /* mfvsrd, mfvsrwz (and extended mnemonics), mfvsrld */
1714                         opset(AMFFPRD, r0)
1715                         opset(AMFVRD, r0)
1716                         opset(AMFVSRWZ, r0)
1717                         opset(AMFVSRLD, r0)
1718
1719                 case AMTVSRD: /* mtvsrd, mtvsrwa, mtvsrwz (and extended mnemonics), mtvsrdd, mtvsrws */
1720                         opset(AMTFPRD, r0)
1721                         opset(AMTVRD, r0)
1722                         opset(AMTVSRWA, r0)
1723                         opset(AMTVSRWZ, r0)
1724                         opset(AMTVSRWS, r0)
1725
1726                 case AXXLAND: /* xxland, xxlandc, xxleqv, xxlnand */
1727                         opset(AXXLANDC, r0)
1728                         opset(AXXLEQV, r0)
1729                         opset(AXXLNAND, r0)
1730
1731                 case AXXLOR: /* xxlorc, xxlnor, xxlor, xxlxor */
1732                         opset(AXXLORC, r0)
1733                         opset(AXXLNOR, r0)
1734                         opset(AXXLORQ, r0)
1735                         opset(AXXLXOR, r0)
1736
1737                 case AXXSEL: /* xxsel */
1738                         opset(AXXSEL, r0)
1739
1740                 case AXXMRGHW: /* xxmrghw, xxmrglw */
1741                         opset(AXXMRGLW, r0)
1742
1743                 case AXXSPLTW: /* xxspltw */
1744                         opset(AXXSPLTW, r0)
1745
1746                 case AXXSPLTIB: /* xxspltib */
1747                         opset(AXXSPLTIB, r0)
1748
1749                 case AXXPERM: /* xxpermdi */
1750                         opset(AXXPERM, r0)
1751
1752                 case AXXSLDWI: /* xxsldwi */
1753                         opset(AXXPERMDI, r0)
1754                         opset(AXXSLDWI, r0)
1755
1756                 case AXXBRQ: /* xxbrq, xxbrd, xxbrw, xxbrh */
1757                         opset(AXXBRD, r0)
1758                         opset(AXXBRW, r0)
1759                         opset(AXXBRH, r0)
1760
1761                 case AXSCVDPSP: /* xscvdpsp, xscvspdp, xscvdpspn, xscvspdpn */
1762                         opset(AXSCVSPDP, r0)
1763                         opset(AXSCVDPSPN, r0)
1764                         opset(AXSCVSPDPN, r0)
1765
1766                 case AXVCVDPSP: /* xvcvdpsp, xvcvspdp */
1767                         opset(AXVCVSPDP, r0)
1768
1769                 case AXSCVDPSXDS: /* xscvdpsxds, xscvdpsxws, xscvdpuxds, xscvdpuxws */
1770                         opset(AXSCVDPSXWS, r0)
1771                         opset(AXSCVDPUXDS, r0)
1772                         opset(AXSCVDPUXWS, r0)
1773
1774                 case AXSCVSXDDP: /* xscvsxddp, xscvuxddp, xscvsxdsp, xscvuxdsp */
1775                         opset(AXSCVUXDDP, r0)
1776                         opset(AXSCVSXDSP, r0)
1777                         opset(AXSCVUXDSP, r0)
1778
1779                 case AXVCVDPSXDS: /* xvcvdpsxds, xvcvdpsxws, xvcvdpuxds, xvcvdpuxws, xvcvspsxds, xvcvspsxws, xvcvspuxds, xvcvspuxws */
1780                         opset(AXVCVDPSXDS, r0)
1781                         opset(AXVCVDPSXWS, r0)
1782                         opset(AXVCVDPUXDS, r0)
1783                         opset(AXVCVDPUXWS, r0)
1784                         opset(AXVCVSPSXDS, r0)
1785                         opset(AXVCVSPSXWS, r0)
1786                         opset(AXVCVSPUXDS, r0)
1787                         opset(AXVCVSPUXWS, r0)
1788
1789                 case AXVCVSXDDP: /* xvcvsxddp, xvcvsxwdp, xvcvuxddp, xvcvuxwdp, xvcvsxdsp, xvcvsxwsp, xvcvuxdsp, xvcvuxwsp */
1790                         opset(AXVCVSXWDP, r0)
1791                         opset(AXVCVUXDDP, r0)
1792                         opset(AXVCVUXWDP, r0)
1793                         opset(AXVCVSXDSP, r0)
1794                         opset(AXVCVSXWSP, r0)
1795                         opset(AXVCVUXDSP, r0)
1796                         opset(AXVCVUXWSP, r0)
1797
1798                 case AAND: /* logical op Rb,Rs,Ra; no literal */
1799                         opset(AANDN, r0)
1800                         opset(AANDNCC, r0)
1801                         opset(AEQV, r0)
1802                         opset(AEQVCC, r0)
1803                         opset(ANAND, r0)
1804                         opset(ANANDCC, r0)
1805                         opset(ANOR, r0)
1806                         opset(ANORCC, r0)
1807                         opset(AORCC, r0)
1808                         opset(AORN, r0)
1809                         opset(AORNCC, r0)
1810                         opset(AXORCC, r0)
1811
1812                 case AADDME: /* op Ra, Rd */
1813                         opset(AADDMECC, r0)
1814
1815                         opset(AADDMEV, r0)
1816                         opset(AADDMEVCC, r0)
1817                         opset(AADDZE, r0)
1818                         opset(AADDZECC, r0)
1819                         opset(AADDZEV, r0)
1820                         opset(AADDZEVCC, r0)
1821                         opset(ASUBME, r0)
1822                         opset(ASUBMECC, r0)
1823                         opset(ASUBMEV, r0)
1824                         opset(ASUBMEVCC, r0)
1825                         opset(ASUBZE, r0)
1826                         opset(ASUBZECC, r0)
1827                         opset(ASUBZEV, r0)
1828                         opset(ASUBZEVCC, r0)
1829
1830                 case AADDC:
1831                         opset(AADDCCC, r0)
1832
1833                 case ABEQ:
1834                         opset(ABGE, r0)
1835                         opset(ABGT, r0)
1836                         opset(ABLE, r0)
1837                         opset(ABLT, r0)
1838                         opset(ABNE, r0)
1839                         opset(ABVC, r0)
1840                         opset(ABVS, r0)
1841
1842                 case ABR:
1843                         opset(ABL, r0)
1844
1845                 case ABC:
1846                         opset(ABCL, r0)
1847
1848                 case ABDNZ:
1849                         opset(ABDZ, r0)
1850
1851                 case AEXTSB: /* op Rs, Ra */
1852                         opset(AEXTSBCC, r0)
1853
1854                         opset(AEXTSH, r0)
1855                         opset(AEXTSHCC, r0)
1856                         opset(ACNTLZW, r0)
1857                         opset(ACNTLZWCC, r0)
1858                         opset(ACNTLZD, r0)
1859                         opset(AEXTSW, r0)
1860                         opset(AEXTSWCC, r0)
1861                         opset(ACNTLZDCC, r0)
1862
1863                 case AFABS: /* fop [s,]d */
1864                         opset(AFABSCC, r0)
1865
1866                         opset(AFNABS, r0)
1867                         opset(AFNABSCC, r0)
1868                         opset(AFNEG, r0)
1869                         opset(AFNEGCC, r0)
1870                         opset(AFRSP, r0)
1871                         opset(AFRSPCC, r0)
1872                         opset(AFCTIW, r0)
1873                         opset(AFCTIWCC, r0)
1874                         opset(AFCTIWZ, r0)
1875                         opset(AFCTIWZCC, r0)
1876                         opset(AFCTID, r0)
1877                         opset(AFCTIDCC, r0)
1878                         opset(AFCTIDZ, r0)
1879                         opset(AFCTIDZCC, r0)
1880                         opset(AFCFID, r0)
1881                         opset(AFCFIDCC, r0)
1882                         opset(AFCFIDU, r0)
1883                         opset(AFCFIDUCC, r0)
1884                         opset(AFCFIDS, r0)
1885                         opset(AFCFIDSCC, r0)
1886                         opset(AFRES, r0)
1887                         opset(AFRESCC, r0)
1888                         opset(AFRIM, r0)
1889                         opset(AFRIMCC, r0)
1890                         opset(AFRIP, r0)
1891                         opset(AFRIPCC, r0)
1892                         opset(AFRIZ, r0)
1893                         opset(AFRIZCC, r0)
1894                         opset(AFRIN, r0)
1895                         opset(AFRINCC, r0)
1896                         opset(AFRSQRTE, r0)
1897                         opset(AFRSQRTECC, r0)
1898                         opset(AFSQRT, r0)
1899                         opset(AFSQRTCC, r0)
1900                         opset(AFSQRTS, r0)
1901                         opset(AFSQRTSCC, r0)
1902
1903                 case AFADD:
1904                         opset(AFADDS, r0)
1905                         opset(AFADDCC, r0)
1906                         opset(AFADDSCC, r0)
1907                         opset(AFCPSGN, r0)
1908                         opset(AFCPSGNCC, r0)
1909                         opset(AFDIV, r0)
1910                         opset(AFDIVS, r0)
1911                         opset(AFDIVCC, r0)
1912                         opset(AFDIVSCC, r0)
1913                         opset(AFSUB, r0)
1914                         opset(AFSUBS, r0)
1915                         opset(AFSUBCC, r0)
1916                         opset(AFSUBSCC, r0)
1917
1918                 case AFMADD:
1919                         opset(AFMADDCC, r0)
1920                         opset(AFMADDS, r0)
1921                         opset(AFMADDSCC, r0)
1922                         opset(AFMSUB, r0)
1923                         opset(AFMSUBCC, r0)
1924                         opset(AFMSUBS, r0)
1925                         opset(AFMSUBSCC, r0)
1926                         opset(AFNMADD, r0)
1927                         opset(AFNMADDCC, r0)
1928                         opset(AFNMADDS, r0)
1929                         opset(AFNMADDSCC, r0)
1930                         opset(AFNMSUB, r0)
1931                         opset(AFNMSUBCC, r0)
1932                         opset(AFNMSUBS, r0)
1933                         opset(AFNMSUBSCC, r0)
1934                         opset(AFSEL, r0)
1935                         opset(AFSELCC, r0)
1936
1937                 case AFMUL:
1938                         opset(AFMULS, r0)
1939                         opset(AFMULCC, r0)
1940                         opset(AFMULSCC, r0)
1941
1942                 case AFCMPO:
1943                         opset(AFCMPU, r0)
1944
1945                 case AMTFSB0:
1946                         opset(AMTFSB0CC, r0)
1947                         opset(AMTFSB1, r0)
1948                         opset(AMTFSB1CC, r0)
1949
1950                 case ANEG: /* op [Ra,] Rd */
1951                         opset(ANEGCC, r0)
1952
1953                         opset(ANEGV, r0)
1954                         opset(ANEGVCC, r0)
1955
1956                 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,R */
1957                         opset(AXOR, r0)
1958
1959                 case AORIS: /* oris/xoris $uimm,Rs,Ra */
1960                         opset(AXORIS, r0)
1961
1962                 case ASLW:
1963                         opset(ASLWCC, r0)
1964                         opset(ASRW, r0)
1965                         opset(ASRWCC, r0)
1966                         opset(AROTLW, r0)
1967
1968                 case ASLD:
1969                         opset(ASLDCC, r0)
1970                         opset(ASRD, r0)
1971                         opset(ASRDCC, r0)
1972                         opset(AROTL, r0)
1973
1974                 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1975                         opset(ASRAWCC, r0)
1976
1977                 case AEXTSWSLI:
1978                         opset(AEXTSWSLICC, r0)
1979
1980                 case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1981                         opset(ASRADCC, r0)
1982
1983                 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
1984                         opset(ASUB, r0)
1985
1986                         opset(ASUBCC, r0)
1987                         opset(ASUBV, r0)
1988                         opset(ASUBVCC, r0)
1989                         opset(ASUBCCC, r0)
1990                         opset(ASUBCV, r0)
1991                         opset(ASUBCVCC, r0)
1992                         opset(ASUBE, r0)
1993                         opset(ASUBECC, r0)
1994                         opset(ASUBEV, r0)
1995                         opset(ASUBEVCC, r0)
1996
1997                 case ASYNC:
1998                         opset(AISYNC, r0)
1999                         opset(ALWSYNC, r0)
2000                         opset(APTESYNC, r0)
2001                         opset(ATLBSYNC, r0)
2002
2003                 case ARLWNM:
2004                         opset(ARLWNMCC, r0)
2005                         opset(ARLWMI, r0)
2006                         opset(ARLWMICC, r0)
2007
2008                 case ARLDMI:
2009                         opset(ARLDMICC, r0)
2010                         opset(ARLDIMI, r0)
2011                         opset(ARLDIMICC, r0)
2012
2013                 case ARLDC:
2014                         opset(ARLDCCC, r0)
2015
2016                 case ARLDCL:
2017                         opset(ARLDCR, r0)
2018                         opset(ARLDCLCC, r0)
2019                         opset(ARLDCRCC, r0)
2020
2021                 case ARLDICL:
2022                         opset(ARLDICLCC, r0)
2023                         opset(ARLDICR, r0)
2024                         opset(ARLDICRCC, r0)
2025                         opset(ARLDIC, r0)
2026                         opset(ARLDICCC, r0)
2027                         opset(ACLRLSLDI, r0)
2028
2029                 case AFMOVD:
2030                         opset(AFMOVDCC, r0)
2031                         opset(AFMOVDU, r0)
2032                         opset(AFMOVS, r0)
2033                         opset(AFMOVSU, r0)
2034
2035                 case ALDAR:
2036                         opset(ALBAR, r0)
2037                         opset(ALHAR, r0)
2038                         opset(ALWAR, r0)
2039
2040                 case ASYSCALL: /* just the op; flow of control */
2041                         opset(ARFI, r0)
2042
2043                         opset(ARFCI, r0)
2044                         opset(ARFID, r0)
2045                         opset(AHRFID, r0)
2046
2047                 case AMOVHBR:
2048                         opset(AMOVWBR, r0)
2049                         opset(AMOVDBR, r0)
2050
2051                 case ASLBMFEE:
2052                         opset(ASLBMFEV, r0)
2053
2054                 case ATW:
2055                         opset(ATD, r0)
2056
2057                 case ATLBIE:
2058                         opset(ASLBIE, r0)
2059                         opset(ATLBIEL, r0)
2060
2061                 case AEIEIO:
2062                         opset(ASLBIA, r0)
2063
2064                 case ACMP:
2065                         opset(ACMPW, r0)
2066
2067                 case ACMPU:
2068                         opset(ACMPWU, r0)
2069
2070                 case ACMPB:
2071                         opset(ACMPB, r0)
2072
2073                 case AFTDIV:
2074                         opset(AFTDIV, r0)
2075
2076                 case AFTSQRT:
2077                         opset(AFTSQRT, r0)
2078
2079                 case AMOVW: /* load/store/move word with sign extension; move 32-bit literals  */
2080                         opset(AMOVWZ, r0) /* Same as above, but zero extended */
2081
2082                 case AVCLZLSBB:
2083                         opset(AVCTZLSBB, r0)
2084
2085                 case AADD,
2086                         AADDIS,
2087                         AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */
2088                         AANDISCC,
2089                         AFMOVSX,
2090                         AFMOVSZ,
2091                         ALSW,
2092                         AMOVD,  /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
2093                         AMOVB,  /* macro: move byte with sign extension */
2094                         AMOVBU, /* macro: move byte with sign extension & update */
2095                         AMOVFL,
2096                         /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
2097                         ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */
2098                         ASTSW,
2099                         ASLBMTE,
2100                         AWORD,
2101                         ADWORD,
2102                         ADARN,
2103                         AVMSUMUDM,
2104                         AADDEX,
2105                         ACMPEQB,
2106                         ACLRLSLWI,
2107                         AMTVSRDD,
2108                         APNOP,
2109                         AISEL,
2110                         ASETB,
2111                         obj.ANOP,
2112                         obj.ATEXT,
2113                         obj.AUNDEF,
2114                         obj.AFUNCDATA,
2115                         obj.APCALIGN,
2116                         obj.APCDATA,
2117                         obj.ADUFFZERO,
2118                         obj.ADUFFCOPY:
2119                         break
2120                 }
2121         }
2122 }
2123
2124 func OPVXX1(o uint32, xo uint32, oe uint32) uint32 {
2125         return o<<26 | xo<<1 | oe<<11
2126 }
2127
2128 func OPVXX2(o uint32, xo uint32, oe uint32) uint32 {
2129         return o<<26 | xo<<2 | oe<<11
2130 }
2131
2132 func OPVXX2VA(o uint32, xo uint32, oe uint32) uint32 {
2133         return o<<26 | xo<<2 | oe<<16
2134 }
2135
2136 func OPVXX3(o uint32, xo uint32, oe uint32) uint32 {
2137         return o<<26 | xo<<3 | oe<<11
2138 }
2139
2140 func OPVXX4(o uint32, xo uint32, oe uint32) uint32 {
2141         return o<<26 | xo<<4 | oe<<11
2142 }
2143
2144 func OPDQ(o uint32, xo uint32, oe uint32) uint32 {
2145         return o<<26 | xo | oe<<4
2146 }
2147
2148 func OPVX(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2149         return o<<26 | xo | oe<<11 | rc&1
2150 }
2151
2152 func OPVC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2153         return o<<26 | xo | oe<<11 | (rc&1)<<10
2154 }
2155
2156 func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2157         return o<<26 | xo<<1 | oe<<10 | rc&1
2158 }
2159
2160 func OPCC(o uint32, xo uint32, rc uint32) uint32 {
2161         return OPVCC(o, xo, 0, rc)
2162 }
2163
2164 /* Generate MD-form opcode */
2165 func OPMD(o, xo, rc uint32) uint32 {
2166         return o<<26 | xo<<2 | rc&1
2167 }
2168
2169 /* the order is dest, a/s, b/imm for both arithmetic and logical operations. */
2170 func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
2171         return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
2172 }
2173
2174 /* VX-form 2-register operands, r/none/r */
2175 func AOP_RR(op uint32, d uint32, a uint32) uint32 {
2176         return op | (d&31)<<21 | (a&31)<<11
2177 }
2178
2179 /* VA-form 4-register operands */
2180 func AOP_RRRR(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2181         return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&31)<<6
2182 }
2183
2184 func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2185         return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF
2186 }
2187
2188 /* VX-form 2-register + UIM operands */
2189 func AOP_VIRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2190         return op | (d&31)<<21 | (simm&0xFFFF)<<16 | (a&31)<<11
2191 }
2192
2193 /* VX-form 2-register + ST + SIX operands */
2194 func AOP_IIRR(op uint32, d uint32, a uint32, sbit uint32, simm uint32) uint32 {
2195         return op | (d&31)<<21 | (a&31)<<16 | (sbit&1)<<15 | (simm&0xF)<<11
2196 }
2197
2198 /* VA-form 3-register + SHB operands */
2199 func AOP_IRRR(op uint32, d uint32, a uint32, b uint32, simm uint32) uint32 {
2200         return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (simm&0xF)<<6
2201 }
2202
2203 /* VX-form 1-register + SIM operands */
2204 func AOP_IR(op uint32, d uint32, simm uint32) uint32 {
2205         return op | (d&31)<<21 | (simm&31)<<16
2206 }
2207
2208 /* XX1-form 3-register operands, 1 VSR operand */
2209 func AOP_XX1(op uint32, r uint32, a uint32, b uint32) uint32 {
2210         return op | (r&31)<<21 | (a&31)<<16 | (b&31)<<11 | (r&32)>>5
2211 }
2212
2213 /* XX2-form 3-register operands, 2 VSR operands */
2214 func AOP_XX2(op uint32, xt uint32, a uint32, xb uint32) uint32 {
2215         return op | (xt&31)<<21 | (a&3)<<16 | (xb&31)<<11 | (xb&32)>>4 | (xt&32)>>5
2216 }
2217
2218 /* XX3-form 3 VSR operands */
2219 func AOP_XX3(op uint32, xt uint32, xa uint32, xb uint32) uint32 {
2220         return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2221 }
2222
2223 /* XX3-form 3 VSR operands + immediate */
2224 func AOP_XX3I(op uint32, xt uint32, xa uint32, xb uint32, c uint32) uint32 {
2225         return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (c&3)<<8 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2226 }
2227
2228 /* XX4-form, 4 VSR operands */
2229 func AOP_XX4(op uint32, xt uint32, xa uint32, xb uint32, xc uint32) uint32 {
2230         return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xc&31)<<6 | (xc&32)>>2 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2231 }
2232
2233 /* DQ-form, VSR register, register + offset operands */
2234 func AOP_DQ(op uint32, xt uint32, a uint32, b uint32) uint32 {
2235         /* The EA for this instruction form is (RA) + DQ << 4, where DQ is a 12-bit signed integer. */
2236         /* In order to match the output of the GNU objdump (and make the usage in Go asm easier), the */
2237         /* instruction is called using the sign extended value (i.e. a valid offset would be -32752 or 32752, */
2238         /* not -2047 or 2047), so 'b' needs to be adjusted to the expected 12-bit DQ value. Bear in mind that */
2239         /* bits 0 to 3 in 'dq' need to be zero, otherwise this will generate an illegal instruction. */
2240         /* If in doubt how this instruction form is encoded, refer to ISA 3.0b, pages 492 and 507. */
2241         dq := b >> 4
2242         return op | (xt&31)<<21 | (a&31)<<16 | (dq&4095)<<4 | (xt&32)>>2
2243 }
2244
2245 /* Z23-form, 3-register operands + CY field */
2246 func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2247         return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<9
2248 }
2249
2250 /* X-form, 3-register operands + EH field */
2251 func AOP_RRRI(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2252         return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c & 1)
2253 }
2254
2255 func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
2256         return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
2257 }
2258
2259 func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 {
2260         return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF
2261 }
2262
2263 func OP_BR(op uint32, li uint32, aa uint32) uint32 {
2264         return op | li&0x03FFFFFC | aa<<1
2265 }
2266
2267 func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 {
2268         return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1
2269 }
2270
2271 func OP_BCR(op uint32, bo uint32, bi uint32) uint32 {
2272         return op | (bo&0x1F)<<21 | (bi&0x1F)<<16
2273 }
2274
2275 func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 {
2276         return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1
2277 }
2278
2279 func AOP_EXTSWSLI(op uint32, a uint32, s uint32, sh uint32) uint32 {
2280         return op | (a&31)<<21 | (s&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1
2281 }
2282
2283 func AOP_ISEL(op uint32, t uint32, a uint32, b uint32, bc uint32) uint32 {
2284         return op | (t&31)<<21 | (a&31)<<16 | (b&31)<<11 | (bc&0x1F)<<6
2285 }
2286
2287 /* MD-form 2-register, 2 6-bit immediate operands */
2288 func AOP_MD(op uint32, a uint32, s uint32, sh uint32, m uint32) uint32 {
2289         return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1 | (m&31)<<6 | ((m&32)>>5)<<5
2290 }
2291
2292 /* MDS-form 3-register, 1 6-bit immediate operands. rsh argument is a register. */
2293 func AOP_MDS(op, to, from, rsh, m uint32) uint32 {
2294         return AOP_MD(op, to, from, rsh&31, m)
2295 }
2296
2297 func AOP_PFX_00_8LS(r, ie uint32) uint32 {
2298         return 1<<26 | 0<<24 | 0<<23 | (r&1)<<20 | (ie & 0x3FFFF)
2299 }
2300 func AOP_PFX_10_MLS(r, ie uint32) uint32 {
2301         return 1<<26 | 2<<24 | 0<<23 | (r&1)<<20 | (ie & 0x3FFFF)
2302 }
2303
2304 const (
2305         /* each rhs is OPVCC(_, _, _, _) */
2306         OP_ADD      = 31<<26 | 266<<1 | 0<<10 | 0
2307         OP_ADDI     = 14<<26 | 0<<1 | 0<<10 | 0
2308         OP_ADDIS    = 15<<26 | 0<<1 | 0<<10 | 0
2309         OP_ANDI     = 28<<26 | 0<<1 | 0<<10 | 0
2310         OP_EXTSB    = 31<<26 | 954<<1 | 0<<10 | 0
2311         OP_EXTSH    = 31<<26 | 922<<1 | 0<<10 | 0
2312         OP_EXTSW    = 31<<26 | 986<<1 | 0<<10 | 0
2313         OP_ISEL     = 31<<26 | 15<<1 | 0<<10 | 0
2314         OP_MCRF     = 19<<26 | 0<<1 | 0<<10 | 0
2315         OP_MCRFS    = 63<<26 | 64<<1 | 0<<10 | 0
2316         OP_MCRXR    = 31<<26 | 512<<1 | 0<<10 | 0
2317         OP_MFCR     = 31<<26 | 19<<1 | 0<<10 | 0
2318         OP_MFFS     = 63<<26 | 583<<1 | 0<<10 | 0
2319         OP_MFSPR    = 31<<26 | 339<<1 | 0<<10 | 0
2320         OP_MFSR     = 31<<26 | 595<<1 | 0<<10 | 0
2321         OP_MFSRIN   = 31<<26 | 659<<1 | 0<<10 | 0
2322         OP_MTCRF    = 31<<26 | 144<<1 | 0<<10 | 0
2323         OP_MTFSF    = 63<<26 | 711<<1 | 0<<10 | 0
2324         OP_MTFSFI   = 63<<26 | 134<<1 | 0<<10 | 0
2325         OP_MTSPR    = 31<<26 | 467<<1 | 0<<10 | 0
2326         OP_MTSR     = 31<<26 | 210<<1 | 0<<10 | 0
2327         OP_MTSRIN   = 31<<26 | 242<<1 | 0<<10 | 0
2328         OP_MULLW    = 31<<26 | 235<<1 | 0<<10 | 0
2329         OP_MULLD    = 31<<26 | 233<<1 | 0<<10 | 0
2330         OP_OR       = 31<<26 | 444<<1 | 0<<10 | 0
2331         OP_ORI      = 24<<26 | 0<<1 | 0<<10 | 0
2332         OP_ORIS     = 25<<26 | 0<<1 | 0<<10 | 0
2333         OP_RLWINM   = 21<<26 | 0<<1 | 0<<10 | 0
2334         OP_RLWNM    = 23<<26 | 0<<1 | 0<<10 | 0
2335         OP_SUBF     = 31<<26 | 40<<1 | 0<<10 | 0
2336         OP_RLDIC    = 30<<26 | 4<<1 | 0<<10 | 0
2337         OP_RLDICR   = 30<<26 | 2<<1 | 0<<10 | 0
2338         OP_RLDICL   = 30<<26 | 0<<1 | 0<<10 | 0
2339         OP_RLDCL    = 30<<26 | 8<<1 | 0<<10 | 0
2340         OP_EXTSWSLI = 31<<26 | 445<<2
2341         OP_SETB     = 31<<26 | 128<<1
2342 )
2343
2344 func pfxadd(rt, ra int16, r uint32, imm32 int64) (uint32, uint32) {
2345         return AOP_PFX_10_MLS(r, uint32(imm32>>16)), AOP_IRR(14<<26, uint32(rt), uint32(ra), uint32(imm32))
2346 }
2347
2348 func pfxload(a obj.As, reg int16, base int16, r uint32) (uint32, uint32) {
2349         switch a {
2350         case AMOVH:
2351                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(42<<26, uint32(reg), uint32(base), 0)
2352         case AMOVW:
2353                 return AOP_PFX_00_8LS(r, 0), AOP_IRR(41<<26, uint32(reg), uint32(base), 0)
2354         case AMOVD:
2355                 return AOP_PFX_00_8LS(r, 0), AOP_IRR(57<<26, uint32(reg), uint32(base), 0)
2356         case AMOVBZ, AMOVB:
2357                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(34<<26, uint32(reg), uint32(base), 0)
2358         case AMOVHZ:
2359                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(40<<26, uint32(reg), uint32(base), 0)
2360         case AMOVWZ:
2361                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(32<<26, uint32(reg), uint32(base), 0)
2362         case AFMOVS:
2363                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(48<<26, uint32(reg), uint32(base), 0)
2364         case AFMOVD:
2365                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(50<<26, uint32(reg), uint32(base), 0)
2366         }
2367         log.Fatalf("Error no pfxload for %v\n", a)
2368         return 0, 0
2369 }
2370
2371 func pfxstore(a obj.As, reg int16, base int16, r uint32) (uint32, uint32) {
2372         switch a {
2373         case AMOVD:
2374                 return AOP_PFX_00_8LS(r, 0), AOP_IRR(61<<26, uint32(reg), uint32(base), 0)
2375         case AMOVBZ, AMOVB:
2376                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(38<<26, uint32(reg), uint32(base), 0)
2377         case AMOVHZ, AMOVH:
2378                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(44<<26, uint32(reg), uint32(base), 0)
2379         case AMOVWZ, AMOVW:
2380                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(36<<26, uint32(reg), uint32(base), 0)
2381         case AFMOVS:
2382                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(52<<26, uint32(reg), uint32(base), 0)
2383         case AFMOVD:
2384                 return AOP_PFX_10_MLS(r, 0), AOP_IRR(54<<26, uint32(reg), uint32(base), 0)
2385         }
2386         log.Fatalf("Error no pfxstore for %v\n", a)
2387         return 0, 0
2388 }
2389
2390 func oclass(a *obj.Addr) int {
2391         return int(a.Class) - 1
2392 }
2393
2394 const (
2395         D_FORM = iota
2396         DS_FORM
2397 )
2398
2399 // This function determines when a non-indexed load or store is D or
2400 // DS form for use in finding the size of the offset field in the instruction.
2401 // The size is needed when setting the offset value in the instruction
2402 // and when generating relocation for that field.
2403 // DS form instructions include: ld, ldu, lwa, std, stdu.  All other
2404 // loads and stores with an offset field are D form.  This function should
2405 // only be called with the same opcodes as are handled by opstore and opload.
2406 func (c *ctxt9) opform(insn uint32) int {
2407         switch insn {
2408         default:
2409                 c.ctxt.Diag("bad insn in loadform: %x", insn)
2410         case OPVCC(58, 0, 0, 0), // ld
2411                 OPVCC(58, 0, 0, 1),        // ldu
2412                 OPVCC(58, 0, 0, 0) | 1<<1, // lwa
2413                 OPVCC(62, 0, 0, 0),        // std
2414                 OPVCC(62, 0, 0, 1):        //stdu
2415                 return DS_FORM
2416         case OP_ADDI, // add
2417                 OPVCC(32, 0, 0, 0), // lwz
2418                 OPVCC(33, 0, 0, 0), // lwzu
2419                 OPVCC(34, 0, 0, 0), // lbz
2420                 OPVCC(35, 0, 0, 0), // lbzu
2421                 OPVCC(40, 0, 0, 0), // lhz
2422                 OPVCC(41, 0, 0, 0), // lhzu
2423                 OPVCC(42, 0, 0, 0), // lha
2424                 OPVCC(43, 0, 0, 0), // lhau
2425                 OPVCC(46, 0, 0, 0), // lmw
2426                 OPVCC(48, 0, 0, 0), // lfs
2427                 OPVCC(49, 0, 0, 0), // lfsu
2428                 OPVCC(50, 0, 0, 0), // lfd
2429                 OPVCC(51, 0, 0, 0), // lfdu
2430                 OPVCC(36, 0, 0, 0), // stw
2431                 OPVCC(37, 0, 0, 0), // stwu
2432                 OPVCC(38, 0, 0, 0), // stb
2433                 OPVCC(39, 0, 0, 0), // stbu
2434                 OPVCC(44, 0, 0, 0), // sth
2435                 OPVCC(45, 0, 0, 0), // sthu
2436                 OPVCC(47, 0, 0, 0), // stmw
2437                 OPVCC(52, 0, 0, 0), // stfs
2438                 OPVCC(53, 0, 0, 0), // stfsu
2439                 OPVCC(54, 0, 0, 0), // stfd
2440                 OPVCC(55, 0, 0, 0): // stfdu
2441                 return D_FORM
2442         }
2443         return 0
2444 }
2445
2446 // Encode instructions and create relocation for accessing s+d according to the
2447 // instruction op with source or destination (as appropriate) register reg.
2448 func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32, reuse bool) (o1, o2 uint32, rel *obj.Reloc) {
2449         if c.ctxt.Headtype == objabi.Haix {
2450                 // Every symbol access must be made via a TOC anchor.
2451                 c.ctxt.Diag("symbolAccess called for %s", s.Name)
2452         }
2453         var base uint32
2454         form := c.opform(op)
2455         if c.ctxt.Flag_shared {
2456                 base = REG_R2
2457         } else {
2458                 base = REG_R0
2459         }
2460         // If reg can be reused when computing the symbol address,
2461         // use it instead of REGTMP.
2462         if !reuse {
2463                 o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)
2464                 o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)
2465         } else {
2466                 o1 = AOP_IRR(OP_ADDIS, uint32(reg), base, 0)
2467                 o2 = AOP_IRR(op, uint32(reg), uint32(reg), 0)
2468         }
2469         rel = obj.Addrel(c.cursym)
2470         rel.Off = int32(c.pc)
2471         rel.Siz = 8
2472         rel.Sym = s
2473         rel.Add = d
2474         if c.ctxt.Flag_shared {
2475                 switch form {
2476                 case D_FORM:
2477                         rel.Type = objabi.R_ADDRPOWER_TOCREL
2478                 case DS_FORM:
2479                         rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
2480                 }
2481
2482         } else {
2483                 switch form {
2484                 case D_FORM:
2485                         rel.Type = objabi.R_ADDRPOWER
2486                 case DS_FORM:
2487                         rel.Type = objabi.R_ADDRPOWER_DS
2488                 }
2489         }
2490         return
2491 }
2492
2493 // Determine the mask begin (mb) and mask end (me) values
2494 // for a valid word rotate mask. A valid 32 bit mask is of
2495 // the form 1+0*1+ or 0*1+0*.
2496 //
2497 // Note, me is inclusive.
2498 func decodeMask32(mask uint32) (mb, me uint32, valid bool) {
2499         mb = uint32(bits.LeadingZeros32(mask))
2500         me = uint32(32 - bits.TrailingZeros32(mask))
2501         mbn := uint32(bits.LeadingZeros32(^mask))
2502         men := uint32(32 - bits.TrailingZeros32(^mask))
2503         // Check for a wrapping mask (e.g bits at 0 and 31)
2504         if mb == 0 && me == 32 {
2505                 // swap the inverted values
2506                 mb, me = men, mbn
2507         }
2508
2509         // Validate mask is of the binary form 1+0*1+ or 0*1+0*
2510         // Isolate rightmost 1 (if none 0) and add.
2511         v := mask
2512         vp := (v & -v) + v
2513         // Likewise, check for the wrapping (inverted) case.
2514         vn := ^v
2515         vpn := (vn & -vn) + vn
2516         return mb, (me - 1) & 31, (v&vp == 0 || vn&vpn == 0) && v != 0
2517 }
2518
2519 // Decompose a mask of contiguous bits into a begin (mb) and
2520 // end (me) value.
2521 //
2522 // 64b mask values cannot wrap on any valid PPC64 instruction.
2523 // Only masks of the form 0*1+0* are valid.
2524 //
2525 // Note, me is inclusive.
2526 func decodeMask64(mask int64) (mb, me uint32, valid bool) {
2527         m := uint64(mask)
2528         mb = uint32(bits.LeadingZeros64(m))
2529         me = uint32(64 - bits.TrailingZeros64(m))
2530         valid = ((m&-m)+m)&m == 0 && m != 0
2531         return mb, (me - 1) & 63, valid
2532 }
2533
2534 func loadu32(r int, d int64) uint32 {
2535         v := int32(d >> 16)
2536         if isuint32(uint64(d)) {
2537                 return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
2538         }
2539         return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v))
2540 }
2541
2542 func high16adjusted(d int32) uint16 {
2543         if d&0x8000 != 0 {
2544                 return uint16((d >> 16) + 1)
2545         }
2546         return uint16(d >> 16)
2547 }
2548
2549 func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
2550         o1 := uint32(0)
2551         o2 := uint32(0)
2552         o3 := uint32(0)
2553         o4 := uint32(0)
2554         o5 := uint32(0)
2555
2556         //print("%v => case %d\n", p, o->type);
2557         switch o.type_ {
2558         default:
2559                 c.ctxt.Diag("unknown type %d", o.type_)
2560                 prasm(p)
2561
2562         case 0: /* pseudo ops */
2563                 break
2564
2565         case 2: /* int/cr/fp op Rb,[Ra],Rd */
2566                 r := int(p.Reg)
2567
2568                 if r == 0 {
2569                         r = int(p.To.Reg)
2570                 }
2571                 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2572
2573         case 3: /* mov $soreg/addcon/andcon/ucon, r ==> addis/oris/addi/ori $i,reg',r */
2574                 d := c.vregoff(&p.From)
2575
2576                 v := int32(d)
2577                 r := int(p.From.Reg)
2578                 if r == 0 {
2579                         r = c.getimpliedreg(&p.From, p)
2580                 }
2581                 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
2582                         c.ctxt.Diag("literal operation on R0\n%v", p)
2583                 }
2584                 a := OP_ADDI
2585                 if o.a1 == C_UCON {
2586                         if d&0xffff != 0 {
2587                                 log.Fatalf("invalid handling of %v", p)
2588                         }
2589                         // For UCON operands the value is right shifted 16, using ADDIS if the
2590                         // value should be signed, ORIS if unsigned.
2591                         v >>= 16
2592                         if r == REGZERO && isuint32(uint64(d)) {
2593                                 o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v))
2594                                 break
2595                         }
2596
2597                         a = OP_ADDIS
2598                 } else if int64(int16(d)) != d {
2599                         // Operand is 16 bit value with sign bit set
2600                         if o.a1 == C_ANDCON {
2601                                 // Needs unsigned 16 bit so use ORI
2602                                 if r == 0 || r == REGZERO {
2603                                         o1 = LOP_IRR(uint32(OP_ORI), uint32(p.To.Reg), uint32(0), uint32(v))
2604                                         break
2605                                 }
2606                                 // With ADDCON, needs signed 16 bit value, fall through to use ADDI
2607                         } else if o.a1 != C_ADDCON {
2608                                 log.Fatalf("invalid handling of %v", p)
2609                         }
2610                 }
2611
2612                 o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
2613
2614         case 4: /* add/mul $scon,[r1],r2 */
2615                 v := c.regoff(&p.From)
2616
2617                 r := int(p.Reg)
2618                 if r == 0 {
2619                         r = int(p.To.Reg)
2620                 }
2621                 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
2622                         c.ctxt.Diag("literal operation on R0\n%v", p)
2623                 }
2624                 if int32(int16(v)) != v {
2625                         log.Fatalf("mishandled instruction %v", p)
2626                 }
2627                 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2628
2629         case 5: /* syscall */
2630                 o1 = c.oprrr(p.As)
2631
2632         case 6: /* logical op Rb,[Rs,]Ra; no literal */
2633                 r := int(p.Reg)
2634
2635                 if r == 0 {
2636                         r = int(p.To.Reg)
2637                 }
2638                 // AROTL and AROTLW are extended mnemonics, which map to RLDCL and RLWNM.
2639                 switch p.As {
2640                 case AROTL:
2641                         o1 = AOP_MD(OP_RLDCL, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), uint32(0))
2642                 case AROTLW:
2643                         o1 = OP_RLW(OP_RLWNM, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), 0, 31)
2644                 default:
2645                         if p.As == AOR && p.From.Type == obj.TYPE_CONST && p.From.Offset == 0 {
2646                                 // Compile "OR $0, Rx, Ry" into ori. If Rx == Ry == 0, this is the preferred
2647                                 // hardware no-op. This happens because $0 matches C_REG before C_ZCON.
2648                                 o1 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(r), 0)
2649                         } else {
2650                                 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2651                         }
2652                 }
2653
2654         case 7: /* mov r, soreg ==> stw o(r) */
2655                 r := int(p.To.Reg)
2656
2657                 if r == 0 {
2658                         r = c.getimpliedreg(&p.To, p)
2659                 }
2660                 v := c.regoff(&p.To)
2661                 if int32(int16(v)) != v {
2662                         log.Fatalf("mishandled instruction %v", p)
2663                 }
2664                 // Offsets in DS form stores must be a multiple of 4
2665                 inst := c.opstore(p.As)
2666                 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2667                         log.Fatalf("invalid offset for DS form load/store %v", p)
2668                 }
2669                 o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
2670
2671         case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r), lbz o(r) + extsb r,r */
2672                 r := int(p.From.Reg)
2673
2674                 if r == 0 {
2675                         r = c.getimpliedreg(&p.From, p)
2676                 }
2677                 v := c.regoff(&p.From)
2678                 if int32(int16(v)) != v {
2679                         log.Fatalf("mishandled instruction %v", p)
2680                 }
2681                 // Offsets in DS form loads must be a multiple of 4
2682                 inst := c.opload(p.As)
2683                 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2684                         log.Fatalf("invalid offset for DS form load/store %v", p)
2685                 }
2686                 o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
2687
2688                 // Sign extend MOVB operations. This is ignored for other cases (o.size == 4).
2689                 o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
2690
2691         case 9: /* RLDC Ra, $sh, $mb, Rb */
2692                 sh := uint32(p.RestArgs[0].Addr.Offset) & 0x3F
2693                 mb := uint32(p.RestArgs[1].Addr.Offset) & 0x3F
2694                 o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), (uint32(sh) & 0x1F))
2695                 o1 |= (sh & 0x20) >> 4 // sh[5] is placed in bit 1.
2696                 o1 |= (mb & 0x1F) << 6 // mb[0:4] is placed in bits 6-10.
2697                 o1 |= (mb & 0x20)      // mb[5] is placed in bit 5
2698
2699         case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
2700                 r := int(p.Reg)
2701
2702                 if r == 0 {
2703                         r = int(p.To.Reg)
2704                 }
2705                 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
2706
2707         case 11: /* br/bl lbra */
2708                 v := int32(0)
2709
2710                 if p.To.Target() != nil {
2711                         v = int32(p.To.Target().Pc - p.Pc)
2712                         if v&03 != 0 {
2713                                 c.ctxt.Diag("odd branch target address\n%v", p)
2714                                 v &^= 03
2715                         }
2716
2717                         if v < -(1<<25) || v >= 1<<24 {
2718                                 c.ctxt.Diag("branch too far\n%v", p)
2719                         }
2720                 }
2721
2722                 o1 = OP_BR(c.opirr(p.As), uint32(v), 0)
2723                 if p.To.Sym != nil {
2724                         rel := obj.Addrel(c.cursym)
2725                         rel.Off = int32(c.pc)
2726                         rel.Siz = 4
2727                         rel.Sym = p.To.Sym
2728                         v += int32(p.To.Offset)
2729                         if v&03 != 0 {
2730                                 c.ctxt.Diag("odd branch target address\n%v", p)
2731                                 v &^= 03
2732                         }
2733
2734                         rel.Add = int64(v)
2735                         rel.Type = objabi.R_CALLPOWER
2736                 }
2737                 o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
2738
2739         case 13: /* mov[bhwd]{z,} r,r */
2740                 // This needs to handle "MOV* $0, Rx".  This shows up because $0 also
2741                 // matches C_REG if r0iszero. This happens because C_REG sorts before C_ANDCON
2742                 // TODO: fix the above behavior and cleanup this exception.
2743                 if p.From.Type == obj.TYPE_CONST {
2744                         o1 = LOP_IRR(OP_ADDI, REGZERO, uint32(p.To.Reg), 0)
2745                         break
2746                 }
2747                 if p.To.Type == obj.TYPE_CONST {
2748                         c.ctxt.Diag("cannot move into constant 0\n%v", p)
2749                 }
2750
2751                 switch p.As {
2752                 case AMOVB:
2753                         o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2754                 case AMOVBZ:
2755                         o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
2756                 case AMOVH:
2757                         o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2758                 case AMOVHZ:
2759                         o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
2760                 case AMOVW:
2761                         o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2762                 case AMOVWZ:
2763                         o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
2764                 case AMOVD:
2765                         o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
2766                 default:
2767                         c.ctxt.Diag("internal: bad register move/truncation\n%v", p)
2768                 }
2769
2770         case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
2771                 r := uint32(p.Reg)
2772
2773                 if r == 0 {
2774                         r = uint32(p.To.Reg)
2775                 }
2776                 d := c.vregoff(p.GetFrom3())
2777                 switch p.As {
2778
2779                 // These opcodes expect a mask operand that has to be converted into the
2780                 // appropriate operand.  The way these were defined, not all valid masks are possible.
2781                 // Left here for compatibility in case they were used or generated.
2782                 case ARLDCL, ARLDCLCC:
2783                         mb, me, valid := decodeMask64(d)
2784                         if me != 63 || !valid {
2785                                 c.ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)
2786                         }
2787                         o1 = AOP_MDS(c.oprrr(p.As), uint32(p.To.Reg), r, uint32(p.From.Reg), mb)
2788
2789                 case ARLDCR, ARLDCRCC:
2790                         mb, me, valid := decodeMask64(d)
2791                         if mb != 0 || !valid {
2792                                 c.ctxt.Diag("invalid mask for rotate: %x (start != 0)\n%v", uint64(d), p)
2793                         }
2794                         o1 = AOP_MDS(c.oprrr(p.As), uint32(p.To.Reg), r, uint32(p.From.Reg), me)
2795
2796                 // These opcodes use a shift count like the ppc64 asm, no mask conversion done
2797                 case ARLDICR, ARLDICRCC:
2798                         me := uint32(d)
2799                         sh := c.regoff(&p.From)
2800                         if me < 0 || me > 63 || sh > 63 {
2801                                 c.ctxt.Diag("Invalid me or sh for RLDICR: %x %x\n%v", int(d), sh, p)
2802                         }
2803                         o1 = AOP_MD(c.oprrr(p.As), uint32(p.To.Reg), r, uint32(sh), me)
2804
2805                 case ARLDICL, ARLDICLCC, ARLDIC, ARLDICCC:
2806                         mb := uint32(d)
2807                         sh := c.regoff(&p.From)
2808                         if mb < 0 || mb > 63 || sh > 63 {
2809                                 c.ctxt.Diag("Invalid mb or sh for RLDIC, RLDICL: %x %x\n%v", mb, sh, p)
2810                         }
2811                         o1 = AOP_MD(c.oprrr(p.As), uint32(p.To.Reg), r, uint32(sh), mb)
2812
2813                 case ACLRLSLDI:
2814                         // This is an extended mnemonic defined in the ISA section C.8.1
2815                         // clrlsldi ra,rs,b,n --> rldic ra,rs,n,b-n
2816                         // It maps onto RLDIC so is directly generated here based on the operands from
2817                         // the clrlsldi.
2818                         n := int32(d)
2819                         b := c.regoff(&p.From)
2820                         if n > b || b > 63 {
2821                                 c.ctxt.Diag("Invalid n or b for CLRLSLDI: %x %x\n%v", n, b, p)
2822                         }
2823                         o1 = AOP_MD(OP_RLDIC, uint32(p.To.Reg), uint32(r), uint32(n), uint32(b)-uint32(n))
2824
2825                 default:
2826                         c.ctxt.Diag("unexpected op in rldc case\n%v", p)
2827                 }
2828
2829         case 17, /* bc bo,bi,lbra (same for now) */
2830                 16: /* bc bo,bi,sbra */
2831                 a := 0
2832
2833                 r := int(p.Reg)
2834
2835                 if p.From.Type == obj.TYPE_CONST {
2836                         a = int(c.regoff(&p.From))
2837                 } else if p.From.Type == obj.TYPE_REG {
2838                         if r != 0 {
2839                                 c.ctxt.Diag("unexpected register setting for branch with CR: %d\n", r)
2840                         }
2841                         // BI values for the CR
2842                         switch p.From.Reg {
2843                         case REG_CR0:
2844                                 r = BI_CR0
2845                         case REG_CR1:
2846                                 r = BI_CR1
2847                         case REG_CR2:
2848                                 r = BI_CR2
2849                         case REG_CR3:
2850                                 r = BI_CR3
2851                         case REG_CR4:
2852                                 r = BI_CR4
2853                         case REG_CR5:
2854                                 r = BI_CR5
2855                         case REG_CR6:
2856                                 r = BI_CR6
2857                         case REG_CR7:
2858                                 r = BI_CR7
2859                         default:
2860                                 c.ctxt.Diag("unrecognized register: expecting CR\n")
2861                         }
2862                 }
2863                 v := int32(0)
2864                 if p.To.Target() != nil {
2865                         v = int32(p.To.Target().Pc - p.Pc)
2866                 }
2867                 if v&03 != 0 {
2868                         c.ctxt.Diag("odd branch target address\n%v", p)
2869                         v &^= 03
2870                 }
2871
2872                 if v < -(1<<16) || v >= 1<<15 {
2873                         c.ctxt.Diag("branch too far\n%v", p)
2874                 }
2875                 o1 = OP_BC(c.opirr(p.As), uint32(a), uint32(r), uint32(v), 0)
2876
2877         case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
2878                 var v int32
2879                 var bh uint32 = 0
2880                 if p.As == ABC || p.As == ABCL {
2881                         v = c.regoff(&p.From) & 31
2882                 } else {
2883                         v = 20 /* unconditional */
2884                 }
2885                 r := int(p.Reg)
2886                 if r == 0 {
2887                         r = 0
2888                 }
2889                 switch oclass(&p.To) {
2890                 case C_CTR:
2891                         o1 = OPVCC(19, 528, 0, 0)
2892
2893                 case C_LR:
2894                         o1 = OPVCC(19, 16, 0, 0)
2895
2896                 default:
2897                         c.ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p)
2898                         v = 0
2899                 }
2900
2901                 // Insert optional branch hint for bclr[l]/bcctr[l]
2902                 if p.From3Type() != obj.TYPE_NONE {
2903                         bh = uint32(p.GetFrom3().Offset)
2904                         if bh == 2 || bh > 3 {
2905                                 log.Fatalf("BH must be 0,1,3 for %v", p)
2906                         }
2907                         o1 |= bh << 11
2908                 }
2909
2910                 if p.As == ABL || p.As == ABCL {
2911                         o1 |= 1
2912                 }
2913                 o1 = OP_BCR(o1, uint32(v), uint32(r))
2914
2915         case 19: /* mov $lcon,r ==> cau+or */
2916                 d := c.vregoff(&p.From)
2917                 if o.ispfx {
2918                         o1, o2 = pfxadd(p.To.Reg, REG_R0, PFX_R_ABS, d)
2919                 } else {
2920                         o1 = loadu32(int(p.To.Reg), d)
2921                         o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
2922                 }
2923
2924         case 20: /* add $ucon,,r | addis $addcon,r,r */
2925                 v := c.regoff(&p.From)
2926
2927                 r := int(p.Reg)
2928                 if r == 0 {
2929                         r = int(p.To.Reg)
2930                 }
2931                 if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
2932                         c.ctxt.Diag("literal operation on R0\n%v", p)
2933                 }
2934                 if p.As == AADDIS {
2935                         o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2936                 } else {
2937                         o1 = AOP_IRR(c.opirr(AADDIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
2938                 }
2939
2940         case 22: /* add $lcon/$andcon,r1,r2 ==> oris+ori+add/ori+add, add $s34con,r1 ==> addis+ori+slw+ori+add */
2941                 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2942                         c.ctxt.Diag("can't synthesize large constant\n%v", p)
2943                 }
2944                 d := c.vregoff(&p.From)
2945                 r := int(p.Reg)
2946                 if r == 0 {
2947                         r = int(p.To.Reg)
2948                 }
2949                 if p.From.Sym != nil {
2950                         c.ctxt.Diag("%v is not supported", p)
2951                 }
2952                 if o.ispfx {
2953                         o1, o2 = pfxadd(int16(p.To.Reg), int16(r), PFX_R_ABS, d)
2954                 } else if o.size == 8 {
2955                         o1 = LOP_IRR(OP_ORI, REGTMP, REGZERO, uint32(int32(d)))          // tmp = uint16(d)
2956                         o2 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r)) // to = tmp + from
2957                 } else if o.size == 12 {
2958                         // Note, o1 is ADDIS if d is negative, ORIS otherwise.
2959                         o1 = loadu32(REGTMP, d)                                          // tmp = d & 0xFFFF0000
2960                         o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))           // tmp |= d & 0xFFFF
2961                         o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r)) // to = from + tmp
2962                 } else {
2963                         // For backwards compatibility with GOPPC64 < 10, generate 34b constants in register.
2964                         o1 = LOP_IRR(OP_ADDIS, REGZERO, REGTMP, uint32(d>>32))  // tmp = sign_extend((d>>32)&0xFFFF0000)
2965                         o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(d>>16))     // tmp |= (d>>16)&0xFFFF
2966                         o3 = AOP_MD(OP_RLDICR, REGTMP, REGTMP, 16, 63-16)       // tmp <<= 16
2967                         o4 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(uint16(d))) // tmp |= d&0xFFFF
2968                         o5 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2969                 }
2970
2971         case 23: /* and $lcon/$addcon,r1,r2 ==> oris+ori+and/addi+and */
2972                 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2973                         c.ctxt.Diag("can't synthesize large constant\n%v", p)
2974                 }
2975                 d := c.vregoff(&p.From)
2976                 r := int(p.Reg)
2977                 if r == 0 {
2978                         r = int(p.To.Reg)
2979                 }
2980
2981                 // With ADDCON operand, generate 2 instructions using ADDI for signed value,
2982                 // with LCON operand generate 3 instructions.
2983                 if o.size == 8 {
2984                         o1 = LOP_IRR(OP_ADDI, REGZERO, REGTMP, uint32(int32(d)))
2985                         o2 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2986                 } else {
2987                         o1 = loadu32(REGTMP, d)
2988                         o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2989                         o3 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2990                 }
2991                 if p.From.Sym != nil {
2992                         c.ctxt.Diag("%v is not supported", p)
2993                 }
2994
2995         case 24: /* lfd fA,float64(0) -> xxlxor xsA,xsaA,xsaA + fneg for -0 */
2996                 o1 = AOP_XX3I(c.oprrr(AXXLXOR), uint32(p.To.Reg), uint32(p.To.Reg), uint32(p.To.Reg), uint32(0))
2997                 // This is needed for -0.
2998                 if o.size == 8 {
2999                         o2 = AOP_RRR(c.oprrr(AFNEG), uint32(p.To.Reg), 0, uint32(p.To.Reg))
3000                 }
3001
3002         case 25:
3003                 /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
3004                 v := c.regoff(&p.From)
3005
3006                 if v < 0 {
3007                         v = 0
3008                 } else if v > 63 {
3009                         v = 63
3010                 }
3011                 r := int(p.Reg)
3012                 if r == 0 {
3013                         r = int(p.To.Reg)
3014                 }
3015                 var a int
3016                 op := uint32(0)
3017                 switch p.As {
3018                 case ASLD, ASLDCC:
3019                         a = int(63 - v)
3020                         op = OP_RLDICR
3021
3022                 case ASRD, ASRDCC:
3023                         a = int(v)
3024                         v = 64 - v
3025                         op = OP_RLDICL
3026                 case AROTL:
3027                         a = int(0)
3028                         op = OP_RLDICL
3029                 case AEXTSWSLI, AEXTSWSLICC:
3030                         a = int(v)
3031                 default:
3032                         c.ctxt.Diag("unexpected op in sldi case\n%v", p)
3033                         a = 0
3034                         o1 = 0
3035                 }
3036
3037                 if p.As == AEXTSWSLI || p.As == AEXTSWSLICC {
3038                         o1 = AOP_EXTSWSLI(OP_EXTSWSLI, uint32(r), uint32(p.To.Reg), uint32(v))
3039
3040                 } else {
3041                         o1 = AOP_MD(op, uint32(p.To.Reg), uint32(r), uint32(v), uint32(a))
3042                 }
3043                 if p.As == ASLDCC || p.As == ASRDCC || p.As == AEXTSWSLICC {
3044                         o1 |= 1 // Set the condition code bit
3045                 }
3046
3047         case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
3048                 v := c.vregoff(&p.From)
3049                 r := int(p.From.Reg)
3050                 var rel *obj.Reloc
3051
3052                 switch p.From.Name {
3053                 case obj.NAME_EXTERN, obj.NAME_STATIC:
3054                         // Load a 32 bit constant, or relocation depending on if a symbol is attached
3055                         o1, o2, rel = c.symbolAccess(p.From.Sym, v, p.To.Reg, OP_ADDI, true)
3056                 default:
3057                         if r == 0 {
3058                                 r = c.getimpliedreg(&p.From, p)
3059                         }
3060                         // Add a 32 bit offset to a register.
3061                         o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(int32(v))))
3062                         o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(v))
3063                 }
3064
3065                 if o.ispfx {
3066                         if rel == nil {
3067                                 o1, o2 = pfxadd(int16(p.To.Reg), int16(r), PFX_R_ABS, v)
3068                         } else {
3069                                 o1, o2 = pfxadd(int16(p.To.Reg), REG_R0, PFX_R_PCREL, 0)
3070                                 rel.Type = objabi.R_ADDRPOWER_PCREL34
3071                         }
3072                 }
3073
3074         case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
3075                 v := c.regoff(p.GetFrom3())
3076
3077                 r := int(p.From.Reg)
3078                 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3079
3080         case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
3081                 if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
3082                         c.ctxt.Diag("can't synthesize large constant\n%v", p)
3083                 }
3084                 v := c.regoff(p.GetFrom3())
3085                 o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
3086                 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
3087                 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
3088                 if p.From.Sym != nil {
3089                         c.ctxt.Diag("%v is not supported", p)
3090                 }
3091
3092         case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
3093                 sh := uint32(c.regoff(&p.From))
3094                 d := c.vregoff(p.GetFrom3())
3095                 mb, me, valid := decodeMask64(d)
3096                 var a uint32
3097                 switch p.As {
3098                 case ARLDC, ARLDCCC:
3099                         a = mb
3100                         if me != (63-sh) || !valid {
3101                                 c.ctxt.Diag("invalid mask for shift: %016x (mb=%d,me=%d) (shift %d)\n%v", uint64(d), mb, me, sh, p)
3102                         }
3103
3104                 case ARLDCL, ARLDCLCC:
3105                         a = mb
3106                         if mb != 63 || !valid {
3107                                 c.ctxt.Diag("invalid mask for shift: %016x (mb=%d,me=%d) (shift %d)\n%v", uint64(d), mb, me, sh, p)
3108                         }
3109
3110                 case ARLDCR, ARLDCRCC:
3111                         a = me
3112                         if mb != 0 || !valid {
3113                                 c.ctxt.Diag("invalid mask for shift: %016x (mb=%d,me=%d) (shift %d)\n%v", uint64(d), mb, me, sh, p)
3114                         }
3115
3116                 default:
3117                         c.ctxt.Diag("unexpected op in rldic case\n%v", p)
3118                 }
3119                 o1 = AOP_MD(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), sh, a)
3120
3121         case 30: /* rldimi $sh,s,$mask,a */
3122                 sh := uint32(c.regoff(&p.From))
3123                 d := c.vregoff(p.GetFrom3())
3124
3125                 // Original opcodes had mask operands which had to be converted to a shift count as expected by
3126                 // the ppc64 asm.
3127                 switch p.As {
3128                 case ARLDMI, ARLDMICC:
3129                         mb, me, valid := decodeMask64(d)
3130                         if me != (63-sh) || !valid {
3131                                 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), me, sh, p)
3132                         }
3133                         o1 = AOP_MD(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), sh, mb)
3134
3135                 // Opcodes with shift count operands.
3136                 case ARLDIMI, ARLDIMICC:
3137                         o1 = AOP_MD(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), sh, uint32(d))
3138                 }
3139
3140         case 31: /* dword */
3141                 d := c.vregoff(&p.From)
3142
3143                 if c.ctxt.Arch.ByteOrder == binary.BigEndian {
3144                         o1 = uint32(d >> 32)
3145                         o2 = uint32(d)
3146                 } else {
3147                         o1 = uint32(d)
3148                         o2 = uint32(d >> 32)
3149                 }
3150
3151                 if p.From.Sym != nil {
3152                         rel := obj.Addrel(c.cursym)
3153                         rel.Off = int32(c.pc)
3154                         rel.Siz = 8
3155                         rel.Sym = p.From.Sym
3156                         rel.Add = p.From.Offset
3157                         rel.Type = objabi.R_ADDR
3158                         o2 = 0
3159                         o1 = o2
3160                 }
3161
3162         case 32: /* fmul frc,fra,frd */
3163                 r := int(p.Reg)
3164
3165                 if r == 0 {
3166                         r = int(p.To.Reg)
3167                 }
3168                 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
3169
3170         case 33: /* fabs [frb,]frd; fmr. frb,frd */
3171                 r := int(p.From.Reg)
3172
3173                 if oclass(&p.From) == C_NONE {
3174                         r = int(p.To.Reg)
3175                 }
3176                 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(r))
3177
3178         case 34: /* FMADDx fra,frb,frc,frt (t=a*c±b) */
3179                 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.GetFrom3().Reg)&31)<<6
3180
3181         case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
3182                 v := c.regoff(&p.To)
3183
3184                 r := int(p.To.Reg)
3185                 if r == 0 {
3186                         r = c.getimpliedreg(&p.To, p)
3187                 }
3188                 // Offsets in DS form stores must be a multiple of 4
3189                 if o.ispfx {
3190                         o1, o2 = pfxstore(p.As, p.From.Reg, int16(r), PFX_R_ABS)
3191                         o1 |= uint32((v >> 16) & 0x3FFFF)
3192                         o2 |= uint32(v & 0xFFFF)
3193                 } else {
3194                         inst := c.opstore(p.As)
3195                         if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3196                                 log.Fatalf("invalid offset for DS form load/store %v", p)
3197                         }
3198                         o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3199                         o2 = AOP_IRR(inst, uint32(p.From.Reg), REGTMP, uint32(v))
3200                 }
3201
3202         case 36: /* mov b/bz/h/hz lext/lauto/lreg,r ==> lbz+extsb/lbz/lha/lhz etc */
3203                 v := c.regoff(&p.From)
3204
3205                 r := int(p.From.Reg)
3206                 if r == 0 {
3207                         r = c.getimpliedreg(&p.From, p)
3208                 }
3209
3210                 if o.ispfx {
3211                         o1, o2 = pfxload(p.As, p.To.Reg, int16(r), PFX_R_ABS)
3212                         o1 |= uint32((v >> 16) & 0x3FFFF)
3213                         o2 |= uint32(v & 0xFFFF)
3214                 } else {
3215                         if o.a6 == C_REG {
3216                                 // Reuse the base register when loading a GPR (C_REG) to avoid
3217                                 // using REGTMP (R31) when possible.
3218                                 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(v)))
3219                                 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(p.To.Reg), uint32(v))
3220                         } else {
3221                                 o1 = AOP_IRR(OP_ADDIS, uint32(REGTMP), uint32(r), uint32(high16adjusted(v)))
3222                                 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(REGTMP), uint32(v))
3223                         }
3224                 }
3225
3226                 // Sign extend MOVB if needed
3227                 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3228
3229         case 40: /* word */
3230                 o1 = uint32(c.regoff(&p.From))
3231
3232         case 41: /* stswi */
3233                 if p.To.Type == obj.TYPE_MEM && p.To.Index == 0 && p.To.Offset != 0 {
3234                         c.ctxt.Diag("Invalid addressing mode used in index type instruction: %v", p.As)
3235                 }
3236
3237                 o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3238
3239         case 42: /* lswi */
3240                 if p.From.Type == obj.TYPE_MEM && p.From.Index == 0 && p.From.Offset != 0 {
3241                         c.ctxt.Diag("Invalid addressing mode used in index type instruction: %v", p.As)
3242                 }
3243                 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3244
3245         case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */
3246                 /* TH field for dcbt/dcbtst: */
3247                 /* 0 = Block access - program will soon access EA. */
3248                 /* 8-15 = Stream access - sequence of access (data stream). See section 4.3.2 of the ISA for details. */
3249                 /* 16 = Block access - program will soon make a transient access to EA. */
3250                 /* 17 = Block access - program will not access EA for a long time. */
3251
3252                 /* L field for dcbf: */
3253                 /* 0 = invalidates the block containing EA in all processors. */
3254                 /* 1 = same as 0, but with limited scope (i.e. block in the current processor will not be reused soon). */
3255                 /* 3 = same as 1, but with even more limited scope (i.e. block in the current processor primary cache will not be reused soon). */
3256                 if p.To.Type == obj.TYPE_NONE {
3257                         o1 = AOP_RRR(c.oprrr(p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))
3258                 } else {
3259                         th := c.regoff(&p.To)
3260                         o1 = AOP_RRR(c.oprrr(p.As), uint32(th), uint32(p.From.Index), uint32(p.From.Reg))
3261                 }
3262
3263         case 44: /* indexed store */
3264                 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3265
3266         case 45: /* indexed load */
3267                 switch p.As {
3268                 /* The assembler accepts a 4-operand l*arx instruction. The fourth operand is an Exclusive Access Hint (EH) */
3269                 /* The EH field can be used as a lock acquire/release hint as follows: */
3270                 /* 0 = Atomic Update (fetch-and-operate or similar algorithm) */
3271                 /* 1 = Exclusive Access (lock acquire and release) */
3272                 case ALBAR, ALHAR, ALWAR, ALDAR:
3273                         if p.From3Type() != obj.TYPE_NONE {
3274                                 eh := int(c.regoff(p.GetFrom3()))
3275                                 if eh > 1 {
3276                                         c.ctxt.Diag("illegal EH field\n%v", p)
3277                                 }
3278                                 o1 = AOP_RRRI(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg), uint32(eh))
3279                         } else {
3280                                 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3281                         }
3282                 default:
3283                         o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3284                 }
3285         case 46: /* plain op */
3286                 o1 = c.oprrr(p.As)
3287
3288         case 47: /* op Ra, Rd; also op [Ra,] Rd */
3289                 r := int(p.From.Reg)
3290
3291                 if r == 0 {
3292                         r = int(p.To.Reg)
3293                 }
3294                 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3295
3296         case 48: /* op Rs, Ra */
3297                 r := int(p.From.Reg)
3298
3299                 if r == 0 {
3300                         r = int(p.To.Reg)
3301                 }
3302                 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3303
3304         case 49: /* op Rb; op $n, Rb */
3305                 if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
3306                         v := c.regoff(&p.From) & 1
3307                         o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
3308                 } else {
3309                         o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.From.Reg))
3310                 }
3311
3312         case 50: /* rem[u] r1[,r2],r3 */
3313                 r := int(p.Reg)
3314
3315                 if r == 0 {
3316                         r = int(p.To.Reg)
3317                 }
3318                 v := c.oprrr(p.As)
3319                 t := v & (1<<10 | 1) /* OE|Rc */
3320                 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3321                 o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
3322                 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3323                 if p.As == AREMU {
3324                         o4 = o3
3325
3326                         /* Clear top 32 bits */
3327                         o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5
3328                 }
3329
3330         case 51: /* remd[u] r1[,r2],r3 */
3331                 r := int(p.Reg)
3332
3333                 if r == 0 {
3334                         r = int(p.To.Reg)
3335                 }
3336                 v := c.oprrr(p.As)
3337                 t := v & (1<<10 | 1) /* OE|Rc */
3338                 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3339                 o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
3340                 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3341                 /* cases 50,51: removed; can be reused. */
3342
3343                 /* cases 50,51: removed; can be reused. */
3344
3345         case 52: /* mtfsbNx cr(n) */
3346                 v := c.regoff(&p.From) & 31
3347
3348                 o1 = AOP_RRR(c.oprrr(p.As), uint32(v), 0, 0)
3349
3350         case 53: /* mffsX ,fr1 */
3351                 o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)
3352
3353         case 55: /* op Rb, Rd */
3354                 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg))
3355
3356         case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
3357                 v := c.regoff(&p.From)
3358
3359                 r := int(p.Reg)
3360                 if r == 0 {
3361                         r = int(p.To.Reg)
3362                 }
3363                 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31)
3364                 if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) {
3365                         o1 |= 1 << 1 /* mb[5] */
3366                 }
3367
3368         case 57: /* slw $sh,[s,]a -> rlwinm ... */
3369                 v := c.regoff(&p.From)
3370
3371                 r := int(p.Reg)
3372                 if r == 0 {
3373                         r = int(p.To.Reg)
3374                 }
3375
3376                 /*
3377                          * Let user (gs) shoot himself in the foot.
3378                          * qc has already complained.
3379                          *
3380                         if(v < 0 || v > 31)
3381                                 ctxt->diag("illegal shift %ld\n%v", v, p);
3382                 */
3383                 if v < 0 {
3384                         v = 0
3385                 } else if v > 32 {
3386                         v = 32
3387                 }
3388                 var mask [2]uint8
3389                 switch p.As {
3390                 case AROTLW:
3391                         mask[0], mask[1] = 0, 31
3392                 case ASRW, ASRWCC:
3393                         mask[0], mask[1] = uint8(v), 31
3394                         v = 32 - v
3395                 default:
3396                         mask[0], mask[1] = 0, uint8(31-v)
3397                 }
3398                 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1]))
3399                 if p.As == ASLWCC || p.As == ASRWCC {
3400                         o1 |= 1 // set the condition code
3401                 }
3402
3403         case 58: /* logical $andcon,[s],a */
3404                 v := c.regoff(&p.From)
3405
3406                 r := int(p.Reg)
3407                 if r == 0 {
3408                         r = int(p.To.Reg)
3409                 }
3410                 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3411
3412         case 59: /* or/xor/and $ucon,,r | oris/xoris/andis $addcon,r,r */
3413                 v := c.regoff(&p.From)
3414
3415                 r := int(p.Reg)
3416                 if r == 0 {
3417                         r = int(p.To.Reg)
3418                 }
3419                 switch p.As {
3420                 case AOR:
3421                         o1 = LOP_IRR(c.opirr(AORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis. */
3422                 case AXOR:
3423                         o1 = LOP_IRR(c.opirr(AXORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3424                 case AANDCC:
3425                         o1 = LOP_IRR(c.opirr(AANDISCC), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3426                 default:
3427                         o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3428                 }
3429
3430         case 60: /* tw to,a,b */
3431                 r := int(c.regoff(&p.From) & 31)
3432
3433                 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
3434
3435         case 61: /* tw to,a,$simm */
3436                 r := int(c.regoff(&p.From) & 31)
3437
3438                 v := c.regoff(&p.To)
3439                 o1 = AOP_IRR(c.opirr(p.As), uint32(r), uint32(p.Reg), uint32(v))
3440
3441         case 62: /* clrlslwi $sh,s,$mask,a */
3442                 v := c.regoff(&p.From)
3443                 n := c.regoff(p.GetFrom3())
3444                 // This is an extended mnemonic described in the ISA C.8.2
3445                 // clrlslwi ra,rs,b,n -> rlwinm ra,rs,n,b-n,31-n
3446                 // It maps onto rlwinm which is directly generated here.
3447                 if n > v || v >= 32 {
3448                         c.ctxt.Diag("Invalid n or b for CLRLSLWI: %x %x\n%v", v, n, p)
3449                 }
3450
3451                 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.Reg), uint32(n), uint32(v-n), uint32(31-n))
3452
3453         case 63: /* rlwimi/rlwnm/rlwinm [$sh,b],s,[$mask or mb,me],a*/
3454                 var mb, me uint32
3455                 if len(p.RestArgs) == 1 { // Mask needs decomposed into mb and me.
3456                         var valid bool
3457                         // Note, optab rules ensure $mask is a 32b constant.
3458                         mb, me, valid = decodeMask32(uint32(p.RestArgs[0].Addr.Offset))
3459                         if !valid {
3460                                 c.ctxt.Diag("cannot generate mask #%x\n%v", uint64(p.RestArgs[0].Addr.Offset), p)
3461                         }
3462                 } else { // Otherwise, mask is already passed as mb and me in RestArgs.
3463                         mb, me = uint32(p.RestArgs[0].Addr.Offset), uint32(p.RestArgs[1].Addr.Offset)
3464                 }
3465                 if p.From.Type == obj.TYPE_CONST {
3466                         o1 = OP_RLW(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Offset), mb, me)
3467                 } else {
3468                         o1 = OP_RLW(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), mb, me)
3469                 }
3470
3471         case 64: /* mtfsf fr[, $m] {,fpcsr} */
3472                 var v int32
3473                 if p.From3Type() != obj.TYPE_NONE {
3474                         v = c.regoff(p.GetFrom3()) & 255
3475                 } else {
3476                         v = 255
3477                 }
3478                 o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
3479
3480         case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
3481                 if p.To.Reg == 0 {
3482                         c.ctxt.Diag("must specify FPSCR(n)\n%v", p)
3483                 }
3484                 o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(c.regoff(&p.From))&31)<<12
3485
3486         case 66: /* mov spr,r1; mov r1,spr */
3487                 var r int
3488                 var v int32
3489                 if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
3490                         r = int(p.From.Reg)
3491                         v = int32(p.To.Reg)
3492                         o1 = OPVCC(31, 467, 0, 0) /* mtspr */
3493                 } else {
3494                         r = int(p.To.Reg)
3495                         v = int32(p.From.Reg)
3496                         o1 = OPVCC(31, 339, 0, 0) /* mfspr */
3497                 }
3498
3499                 o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
3500
3501         case 67: /* mcrf crfD,crfS */
3502                 if p.From.Reg == REG_CR || p.To.Reg == REG_CR {
3503                         c.ctxt.Diag("CR argument must be a conditional register field (CR0-CR7)\n%v", p)
3504                 }
3505                 o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
3506
3507         case 68: /* mfcr rD; mfocrf CRM,rD */
3508                 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /*  form, whole register */
3509                 if p.From.Reg != REG_CR {
3510                         v := uint32(1) << uint(7-(p.From.Reg&7)) /* CR(n) */
3511                         o1 |= 1<<20 | v<<12                      /* new form, mfocrf */
3512                 }
3513
3514         case 69: /* mtcrf CRM,rS, mtocrf CRx,rS */
3515                 var v uint32
3516                 if p.To.Reg == REG_CR {
3517                         v = 0xff
3518                 } else if p.To.Offset != 0 { // MOVFL gpr, constant
3519                         v = uint32(p.To.Offset)
3520                 } else { // p.To.Reg == REG_CRx
3521                         v = 1 << uint(7-(p.To.Reg&7))
3522                 }
3523                 // Use mtocrf form if only one CR field moved.
3524                 if bits.OnesCount32(v) == 1 {
3525                         v |= 1 << 8
3526                 }
3527
3528                 o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
3529
3530         case 70: /* [f]cmp r,r,cr*/
3531                 var r int
3532                 if p.Reg == 0 {
3533                         r = 0
3534                 } else {
3535                         r = (int(p.Reg) & 7) << 2
3536                 }
3537                 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
3538
3539         case 71: /* cmp[l] r,i,cr*/
3540                 var r int
3541                 if p.Reg == 0 {
3542                         r = 0
3543                 } else {
3544                         r = (int(p.Reg) & 7) << 2
3545                 }
3546                 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(c.regoff(&p.To))&0xffff
3547
3548         case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
3549                 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg))
3550
3551         case 73: /* mcrfs crfD,crfS */
3552                 if p.From.Type != obj.TYPE_REG || p.From.Reg != REG_FPSCR || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg {
3553                         c.ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
3554                 }
3555                 o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
3556
3557         case 77: /* syscall $scon, syscall Rx */
3558                 if p.From.Type == obj.TYPE_CONST {
3559                         if p.From.Offset > BIG || p.From.Offset < -BIG {
3560                                 c.ctxt.Diag("illegal syscall, sysnum too large: %v", p)
3561                         }
3562                         o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
3563                 } else if p.From.Type == obj.TYPE_REG {
3564                         o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
3565                 } else {
3566                         c.ctxt.Diag("illegal syscall: %v", p)
3567                         o1 = 0x7fe00008 // trap always
3568                 }
3569
3570                 o2 = c.oprrr(p.As)
3571                 o3 = AOP_RRR(c.oprrr(AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R0
3572
3573         case 78: /* undef */
3574                 o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed
3575                    always to be an illegal instruction."  */
3576
3577         /* relocation operations */
3578         case 74:
3579                 var rel *obj.Reloc
3580                 v := c.vregoff(&p.To)
3581                 // Offsets in DS form stores must be a multiple of 4
3582                 inst := c.opstore(p.As)
3583
3584                 // Can't reuse base for store instructions.
3585                 o1, o2, rel = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst, false)
3586
3587                 // Rewrite as a prefixed store if supported.
3588                 if o.ispfx {
3589                         o1, o2 = pfxstore(p.As, p.From.Reg, REG_R0, PFX_R_PCREL)
3590                         rel.Type = objabi.R_ADDRPOWER_PCREL34
3591                 } else if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3592                         log.Fatalf("invalid offset for DS form load/store %v", p)
3593                 }
3594
3595         case 75: // 32 bit offset symbol loads (got/toc/addr)
3596                 var rel *obj.Reloc
3597                 v := p.From.Offset
3598
3599                 // Offsets in DS form loads must be a multiple of 4
3600                 inst := c.opload(p.As)
3601                 switch p.From.Name {
3602                 case obj.NAME_GOTREF, obj.NAME_TOCREF:
3603                         if v != 0 {
3604                                 c.ctxt.Diag("invalid offset for GOT/TOC access %v", p)
3605                         }
3606                         o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3607                         o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3608                         rel = obj.Addrel(c.cursym)
3609                         rel.Off = int32(c.pc)
3610                         rel.Siz = 8
3611                         rel.Sym = p.From.Sym
3612                         switch p.From.Name {
3613                         case obj.NAME_GOTREF:
3614                                 rel.Type = objabi.R_ADDRPOWER_GOT
3615                         case obj.NAME_TOCREF:
3616                                 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
3617                         }
3618                 default:
3619                         reuseBaseReg := o.a6 == C_REG
3620                         // Reuse To.Reg as base register if it is a GPR.
3621                         o1, o2, rel = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst, reuseBaseReg)
3622                 }
3623
3624                 // Convert to prefixed forms if supported.
3625                 if o.ispfx {
3626                         switch rel.Type {
3627                         case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS,
3628                                 objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS:
3629                                 o1, o2 = pfxload(p.As, p.To.Reg, REG_R0, PFX_R_PCREL)
3630                                 rel.Type = objabi.R_ADDRPOWER_PCREL34
3631                         case objabi.R_POWER_TLS_IE:
3632                                 o1, o2 = pfxload(p.As, p.To.Reg, REG_R0, PFX_R_PCREL)
3633                                 rel.Type = objabi.R_POWER_TLS_IE_PCREL34
3634                         case objabi.R_ADDRPOWER_GOT:
3635                                 o1, o2 = pfxload(p.As, p.To.Reg, REG_R0, PFX_R_PCREL)
3636                                 rel.Type = objabi.R_ADDRPOWER_GOT_PCREL34
3637                         default:
3638                                 // We've failed to convert a TOC-relative relocation to a PC-relative one.
3639                                 log.Fatalf("Unable convert TOC-relative relocation %v to PC-relative", rel.Type)
3640                         }
3641                 } else if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3642                         log.Fatalf("invalid offset for DS form load/store %v", p)
3643                 }
3644
3645                 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3646
3647         case 79:
3648                 if p.From.Offset != 0 {
3649                         c.ctxt.Diag("invalid offset against tls var %v", p)
3650                 }
3651                 rel := obj.Addrel(c.cursym)
3652                 rel.Off = int32(c.pc)
3653                 rel.Siz = 8
3654                 rel.Sym = p.From.Sym
3655                 if !o.ispfx {
3656                         o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R13, 0)
3657                         o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3658                         rel.Type = objabi.R_POWER_TLS_LE
3659                 } else {
3660                         o1, o2 = pfxadd(p.To.Reg, REG_R13, PFX_R_ABS, 0)
3661                         rel.Type = objabi.R_POWER_TLS_LE_TPREL34
3662                 }
3663
3664         case 80:
3665                 if p.From.Offset != 0 {
3666                         c.ctxt.Diag("invalid offset against tls var %v", p)
3667                 }
3668                 rel := obj.Addrel(c.cursym)
3669                 rel.Off = int32(c.pc)
3670                 rel.Siz = 8
3671                 rel.Sym = p.From.Sym
3672                 rel.Type = objabi.R_POWER_TLS_IE
3673                 if !o.ispfx {
3674                         o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3675                         o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3676                 } else {
3677                         o1, o2 = pfxload(p.As, p.To.Reg, REG_R0, PFX_R_PCREL)
3678                         rel.Type = objabi.R_POWER_TLS_IE_PCREL34
3679                 }
3680                 o3 = AOP_RRR(OP_ADD, uint32(p.To.Reg), uint32(p.To.Reg), REG_R13)
3681                 rel = obj.Addrel(c.cursym)
3682                 rel.Off = int32(c.pc) + 8
3683                 rel.Siz = 4
3684                 rel.Sym = p.From.Sym
3685                 rel.Type = objabi.R_POWER_TLS
3686
3687         case 82: /* vector instructions, VX-form and VC-form */
3688                 if p.From.Type == obj.TYPE_REG {
3689                         /* reg reg none OR reg reg reg */
3690                         /* 3-register operand order: VRA, VRB, VRT */
3691                         /* 2-register operand order: VRA, VRT */
3692                         o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3693                 } else if p.From3Type() == obj.TYPE_CONST {
3694                         /* imm imm reg reg */
3695                         /* operand order: SIX, VRA, ST, VRT */
3696                         six := int(c.regoff(&p.From))
3697                         st := int(c.regoff(p.GetFrom3()))
3698                         o1 = AOP_IIRR(c.opiirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(st), uint32(six))
3699                 } else if p.From3Type() == obj.TYPE_NONE && p.Reg != 0 {
3700                         /* imm reg reg */
3701                         /* operand order: UIM, VRB, VRT */
3702                         uim := int(c.regoff(&p.From))
3703                         o1 = AOP_VIRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(uim))
3704                 } else {
3705                         /* imm reg */
3706                         /* operand order: SIM, VRT */
3707                         sim := int(c.regoff(&p.From))
3708                         o1 = AOP_IR(c.opirr(p.As), uint32(p.To.Reg), uint32(sim))
3709                 }
3710
3711         case 83: /* vector instructions, VA-form */
3712                 if p.From.Type == obj.TYPE_REG {
3713                         /* reg reg reg reg */
3714                         /* 4-register operand order: VRA, VRB, VRC, VRT */
3715                         o1 = AOP_RRRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3716                 } else if p.From.Type == obj.TYPE_CONST {
3717                         /* imm reg reg reg */
3718                         /* operand order: SHB, VRA, VRB, VRT */
3719                         shb := int(c.regoff(&p.From))
3720                         o1 = AOP_IRRR(c.opirrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(shb))
3721                 }
3722
3723         case 84: // ISEL BC,RA,RB,RT -> isel rt,ra,rb,bc
3724                 bc := c.vregoff(&p.From)
3725                 if o.a1 == C_CRBIT {
3726                         // CR bit is encoded as a register, not a constant.
3727                         bc = int64(p.From.Reg)
3728                 }
3729
3730                 // rt = To.Reg, ra = p.Reg, rb = p.From3.Reg
3731                 o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(bc))
3732
3733         case 85: /* vector instructions, VX-form */
3734                 /* reg none reg */
3735                 /* 2-register operand order: VRB, VRT */
3736                 o1 = AOP_RR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg))
3737
3738         case 86: /* VSX indexed store, XX1-form */
3739                 /* reg reg reg */
3740                 /* 3-register operand order: XT, (RB)(RA*1) */
3741                 o1 = AOP_XX1(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3742
3743         case 87: /* VSX indexed load, XX1-form */
3744                 /* reg reg reg */
3745                 /* 3-register operand order: (RB)(RA*1), XT */
3746                 o1 = AOP_XX1(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3747
3748         case 88: /* VSX mfvsr* instructions, XX1-form XS,RA */
3749                 o1 = AOP_XX1(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3750
3751         case 89: /* VSX instructions, XX2-form */
3752                 /* reg none reg OR reg imm reg */
3753                 /* 2-register operand order: XB, XT or XB, UIM, XT*/
3754                 uim := int(c.regoff(p.GetFrom3()))
3755                 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(uim), uint32(p.From.Reg))
3756
3757         case 90: /* VSX instructions, XX3-form */
3758                 if p.From3Type() == obj.TYPE_NONE {
3759                         /* reg reg reg */
3760                         /* 3-register operand order: XA, XB, XT */
3761                         o1 = AOP_XX3(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3762                 } else if p.From3Type() == obj.TYPE_CONST {
3763                         /* reg reg reg imm */
3764                         /* operand order: XA, XB, DM, XT */
3765                         dm := int(c.regoff(p.GetFrom3()))
3766                         o1 = AOP_XX3I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(dm))
3767                 }
3768
3769         case 91: /* VSX instructions, XX4-form */
3770                 /* reg reg reg reg */
3771                 /* 3-register operand order: XA, XB, XC, XT */
3772                 o1 = AOP_XX4(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3773
3774         case 92: /* X-form instructions, 3-operands */
3775                 if p.To.Type == obj.TYPE_CONST {
3776                         /* imm reg reg */
3777                         xf := int32(p.From.Reg)
3778                         if REG_F0 <= xf && xf <= REG_F31 {
3779                                 /* operand order: FRA, FRB, BF */
3780                                 bf := int(c.regoff(&p.To)) << 2
3781                                 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3782                         } else {
3783                                 /* operand order: RA, RB, L */
3784                                 l := int(c.regoff(&p.To))
3785                                 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.From.Reg), uint32(p.Reg))
3786                         }
3787                 } else if p.From3Type() == obj.TYPE_CONST {
3788                         /* reg reg imm */
3789                         /* operand order: RB, L, RA */
3790                         l := int(c.regoff(p.GetFrom3()))
3791                         o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.To.Reg), uint32(p.From.Reg))
3792                 } else if p.To.Type == obj.TYPE_REG {
3793                         cr := int32(p.To.Reg)
3794                         if REG_CR0 <= cr && cr <= REG_CR7 {
3795                                 /* cr reg reg */
3796                                 /* operand order: RA, RB, BF */
3797                                 bf := (int(p.To.Reg) & 7) << 2
3798                                 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3799                         } else if p.From.Type == obj.TYPE_CONST {
3800                                 /* reg imm */
3801                                 /* operand order: L, RT */
3802                                 l := int(c.regoff(&p.From))
3803                                 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(l), uint32(p.Reg))
3804                         } else {
3805                                 switch p.As {
3806                                 case ACOPY, APASTECC:
3807                                         o1 = AOP_RRR(c.opirr(p.As), uint32(1), uint32(p.From.Reg), uint32(p.To.Reg))
3808                                 default:
3809                                         /* reg reg reg */
3810                                         /* operand order: RS, RB, RA */
3811                                         o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3812                                 }
3813                         }
3814                 }
3815
3816         case 93: /* X-form instructions, 2-operands */
3817                 if p.To.Type == obj.TYPE_CONST {
3818                         /* imm reg */
3819                         /* operand order: FRB, BF */
3820                         bf := int(c.regoff(&p.To)) << 2
3821                         o1 = AOP_RR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg))
3822                 } else if p.Reg == 0 {
3823                         /* popcnt* r,r, X-form */
3824                         /* operand order: RS, RA */
3825                         o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3826                 }
3827
3828         case 94: /* Z23-form instructions, 4-operands */
3829                 /* reg reg reg imm */
3830                 /* operand order: RA, RB, CY, RT */
3831                 cy := int(c.regoff(p.GetFrom3()))
3832                 o1 = AOP_Z23I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(cy))
3833
3834         case 96: /* VSX load, DQ-form */
3835                 /* reg imm reg */
3836                 /* operand order: (RA)(DQ), XT */
3837                 dq := int16(c.regoff(&p.From))
3838                 if (dq & 15) != 0 {
3839                         c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3840                 }
3841                 o1 = AOP_DQ(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(dq))
3842
3843         case 97: /* VSX store, DQ-form */
3844                 /* reg imm reg */
3845                 /* operand order: XT, (RA)(DQ) */
3846                 dq := int16(c.regoff(&p.To))
3847                 if (dq & 15) != 0 {
3848                         c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3849                 }
3850                 o1 = AOP_DQ(c.opstore(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(dq))
3851         case 98: /* VSX indexed load or load with length (also left-justified), x-form */
3852                 /* vsreg, reg, reg */
3853                 o1 = AOP_XX1(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3854         case 99: /* VSX store with length (also left-justified) x-form */
3855                 /* reg, reg, vsreg */
3856                 o1 = AOP_XX1(c.opstore(p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(p.To.Reg))
3857         case 100: /* VSX X-form XXSPLTIB */
3858                 if p.From.Type == obj.TYPE_CONST {
3859                         /* imm reg */
3860                         uim := int(c.regoff(&p.From))
3861                         /* imm reg */
3862                         /* Use AOP_XX1 form with 0 for one of the registers. */
3863                         o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(uim))
3864                 } else {
3865                         c.ctxt.Diag("invalid ops for %v", p.As)
3866                 }
3867         case 101:
3868                 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
3869
3870         case 104: /* VSX mtvsr* instructions, XX1-form RA,RB,XT */
3871                 o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3872
3873         case 106: /* MOVD spr, soreg */
3874                 v := int32(p.From.Reg)
3875                 o1 = OPVCC(31, 339, 0, 0) /* mfspr */
3876                 o1 = AOP_RRR(o1, uint32(REGTMP), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
3877                 so := c.regoff(&p.To)
3878                 o2 = AOP_IRR(c.opstore(AMOVD), uint32(REGTMP), uint32(p.To.Reg), uint32(so))
3879                 if so&0x3 != 0 {
3880                         log.Fatalf("invalid offset for DS form load/store %v", p)
3881                 }
3882                 if p.To.Reg == REGTMP {
3883                         log.Fatalf("SPR move to memory will clobber R31 %v", p)
3884                 }
3885
3886         case 107: /* MOVD soreg, spr */
3887                 v := int32(p.From.Reg)
3888                 so := c.regoff(&p.From)
3889                 o1 = AOP_IRR(c.opload(AMOVD), uint32(REGTMP), uint32(v), uint32(so))
3890                 o2 = OPVCC(31, 467, 0, 0) /* mtspr */
3891                 v = int32(p.To.Reg)
3892                 o2 = AOP_RRR(o2, uint32(REGTMP), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
3893                 if so&0x3 != 0 {
3894                         log.Fatalf("invalid offset for DS form load/store %v", p)
3895                 }
3896
3897         case 108: /* mov r, xoreg ==> stwx rx,ry */
3898                 r := int(p.To.Reg)
3899                 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
3900
3901         case 109: /* mov xoreg, r ==> lbzx/lhzx/lwzx rx,ry, lbzx rx,ry + extsb r,r */
3902                 r := int(p.From.Reg)
3903
3904                 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
3905                 // Sign extend MOVB operations. This is ignored for other cases (o.size == 4).
3906                 o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3907
3908         case 110: /* SETB creg, rt */
3909                 bfa := uint32(p.From.Reg) << 2
3910                 rt := uint32(p.To.Reg)
3911                 o1 = LOP_RRR(OP_SETB, bfa, rt, 0)
3912         }
3913
3914         out[0] = o1
3915         out[1] = o2
3916         out[2] = o3
3917         out[3] = o4
3918         out[4] = o5
3919 }
3920
3921 func (c *ctxt9) vregoff(a *obj.Addr) int64 {
3922         c.instoffset = 0
3923         if a != nil {
3924                 c.aclass(a)
3925         }
3926         return c.instoffset
3927 }
3928
3929 func (c *ctxt9) regoff(a *obj.Addr) int32 {
3930         return int32(c.vregoff(a))
3931 }
3932
3933 func (c *ctxt9) oprrr(a obj.As) uint32 {
3934         switch a {
3935         case AADD:
3936                 return OPVCC(31, 266, 0, 0)
3937         case AADDCC:
3938                 return OPVCC(31, 266, 0, 1)
3939         case AADDV:
3940                 return OPVCC(31, 266, 1, 0)
3941         case AADDVCC:
3942                 return OPVCC(31, 266, 1, 1)
3943         case AADDC:
3944                 return OPVCC(31, 10, 0, 0)
3945         case AADDCCC:
3946                 return OPVCC(31, 10, 0, 1)
3947         case AADDCV:
3948                 return OPVCC(31, 10, 1, 0)
3949         case AADDCVCC:
3950                 return OPVCC(31, 10, 1, 1)
3951         case AADDE:
3952                 return OPVCC(31, 138, 0, 0)
3953         case AADDECC:
3954                 return OPVCC(31, 138, 0, 1)
3955         case AADDEV:
3956                 return OPVCC(31, 138, 1, 0)
3957         case AADDEVCC:
3958                 return OPVCC(31, 138, 1, 1)
3959         case AADDME:
3960                 return OPVCC(31, 234, 0, 0)
3961         case AADDMECC:
3962                 return OPVCC(31, 234, 0, 1)
3963         case AADDMEV:
3964                 return OPVCC(31, 234, 1, 0)
3965         case AADDMEVCC:
3966                 return OPVCC(31, 234, 1, 1)
3967         case AADDZE:
3968                 return OPVCC(31, 202, 0, 0)
3969         case AADDZECC:
3970                 return OPVCC(31, 202, 0, 1)
3971         case AADDZEV:
3972                 return OPVCC(31, 202, 1, 0)
3973         case AADDZEVCC:
3974                 return OPVCC(31, 202, 1, 1)
3975         case AADDEX:
3976                 return OPVCC(31, 170, 0, 0) /* addex - v3.0b */
3977
3978         case AAND:
3979                 return OPVCC(31, 28, 0, 0)
3980         case AANDCC:
3981                 return OPVCC(31, 28, 0, 1)
3982         case AANDN:
3983                 return OPVCC(31, 60, 0, 0)
3984         case AANDNCC:
3985                 return OPVCC(31, 60, 0, 1)
3986
3987         case ACMP:
3988                 return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */
3989         case ACMPU:
3990                 return OPVCC(31, 32, 0, 0) | 1<<21
3991         case ACMPW:
3992                 return OPVCC(31, 0, 0, 0) /* L=0 */
3993         case ACMPWU:
3994                 return OPVCC(31, 32, 0, 0)
3995         case ACMPB:
3996                 return OPVCC(31, 508, 0, 0) /* cmpb - v2.05 */
3997         case ACMPEQB:
3998                 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
3999
4000         case ACNTLZW:
4001                 return OPVCC(31, 26, 0, 0)
4002         case ACNTLZWCC:
4003                 return OPVCC(31, 26, 0, 1)
4004         case ACNTLZD:
4005                 return OPVCC(31, 58, 0, 0)
4006         case ACNTLZDCC:
4007                 return OPVCC(31, 58, 0, 1)
4008
4009         case ACRAND:
4010                 return OPVCC(19, 257, 0, 0)
4011         case ACRANDN:
4012                 return OPVCC(19, 129, 0, 0)
4013         case ACREQV:
4014                 return OPVCC(19, 289, 0, 0)
4015         case ACRNAND:
4016                 return OPVCC(19, 225, 0, 0)
4017         case ACRNOR:
4018                 return OPVCC(19, 33, 0, 0)
4019         case ACROR:
4020                 return OPVCC(19, 449, 0, 0)
4021         case ACRORN:
4022                 return OPVCC(19, 417, 0, 0)
4023         case ACRXOR:
4024                 return OPVCC(19, 193, 0, 0)
4025
4026         case ADCBF:
4027                 return OPVCC(31, 86, 0, 0)
4028         case ADCBI:
4029                 return OPVCC(31, 470, 0, 0)
4030         case ADCBST:
4031                 return OPVCC(31, 54, 0, 0)
4032         case ADCBT:
4033                 return OPVCC(31, 278, 0, 0)
4034         case ADCBTST:
4035                 return OPVCC(31, 246, 0, 0)
4036         case ADCBZ:
4037                 return OPVCC(31, 1014, 0, 0)
4038
4039         case AMODUD:
4040                 return OPVCC(31, 265, 0, 0) /* modud - v3.0 */
4041         case AMODUW:
4042                 return OPVCC(31, 267, 0, 0) /* moduw - v3.0 */
4043         case AMODSD:
4044                 return OPVCC(31, 777, 0, 0) /* modsd - v3.0 */
4045         case AMODSW:
4046                 return OPVCC(31, 779, 0, 0) /* modsw - v3.0 */
4047
4048         case ADIVW, AREM:
4049                 return OPVCC(31, 491, 0, 0)
4050
4051         case ADIVWCC:
4052                 return OPVCC(31, 491, 0, 1)
4053
4054         case ADIVWV:
4055                 return OPVCC(31, 491, 1, 0)
4056
4057         case ADIVWVCC:
4058                 return OPVCC(31, 491, 1, 1)
4059
4060         case ADIVWU, AREMU:
4061                 return OPVCC(31, 459, 0, 0)
4062
4063         case ADIVWUCC:
4064                 return OPVCC(31, 459, 0, 1)
4065
4066         case ADIVWUV:
4067                 return OPVCC(31, 459, 1, 0)
4068
4069         case ADIVWUVCC:
4070                 return OPVCC(31, 459, 1, 1)
4071
4072         case ADIVD, AREMD:
4073                 return OPVCC(31, 489, 0, 0)
4074
4075         case ADIVDCC:
4076                 return OPVCC(31, 489, 0, 1)
4077
4078         case ADIVDE:
4079                 return OPVCC(31, 425, 0, 0)
4080
4081         case ADIVDECC:
4082                 return OPVCC(31, 425, 0, 1)
4083
4084         case ADIVDEU:
4085                 return OPVCC(31, 393, 0, 0)
4086
4087         case ADIVDEUCC:
4088                 return OPVCC(31, 393, 0, 1)
4089
4090         case ADIVDV:
4091                 return OPVCC(31, 489, 1, 0)
4092
4093         case ADIVDVCC:
4094                 return OPVCC(31, 489, 1, 1)
4095
4096         case ADIVDU, AREMDU:
4097                 return OPVCC(31, 457, 0, 0)
4098
4099         case ADIVDUCC:
4100                 return OPVCC(31, 457, 0, 1)
4101
4102         case ADIVDUV:
4103                 return OPVCC(31, 457, 1, 0)
4104
4105         case ADIVDUVCC:
4106                 return OPVCC(31, 457, 1, 1)
4107
4108         case AEIEIO:
4109                 return OPVCC(31, 854, 0, 0)
4110
4111         case AEQV:
4112                 return OPVCC(31, 284, 0, 0)
4113         case AEQVCC:
4114                 return OPVCC(31, 284, 0, 1)
4115
4116         case AEXTSB:
4117                 return OPVCC(31, 954, 0, 0)
4118         case AEXTSBCC:
4119                 return OPVCC(31, 954, 0, 1)
4120         case AEXTSH:
4121                 return OPVCC(31, 922, 0, 0)
4122         case AEXTSHCC:
4123                 return OPVCC(31, 922, 0, 1)
4124         case AEXTSW:
4125                 return OPVCC(31, 986, 0, 0)
4126         case AEXTSWCC:
4127                 return OPVCC(31, 986, 0, 1)
4128
4129         case AFABS:
4130                 return OPVCC(63, 264, 0, 0)
4131         case AFABSCC:
4132                 return OPVCC(63, 264, 0, 1)
4133         case AFADD:
4134                 return OPVCC(63, 21, 0, 0)
4135         case AFADDCC:
4136                 return OPVCC(63, 21, 0, 1)
4137         case AFADDS:
4138                 return OPVCC(59, 21, 0, 0)
4139         case AFADDSCC:
4140                 return OPVCC(59, 21, 0, 1)
4141         case AFCMPO:
4142                 return OPVCC(63, 32, 0, 0)
4143         case AFCMPU:
4144                 return OPVCC(63, 0, 0, 0)
4145         case AFCFID:
4146                 return OPVCC(63, 846, 0, 0)
4147         case AFCFIDCC:
4148                 return OPVCC(63, 846, 0, 1)
4149         case AFCFIDU:
4150                 return OPVCC(63, 974, 0, 0)
4151         case AFCFIDUCC:
4152                 return OPVCC(63, 974, 0, 1)
4153         case AFCFIDS:
4154                 return OPVCC(59, 846, 0, 0)
4155         case AFCFIDSCC:
4156                 return OPVCC(59, 846, 0, 1)
4157         case AFCTIW:
4158                 return OPVCC(63, 14, 0, 0)
4159         case AFCTIWCC:
4160                 return OPVCC(63, 14, 0, 1)
4161         case AFCTIWZ:
4162                 return OPVCC(63, 15, 0, 0)
4163         case AFCTIWZCC:
4164                 return OPVCC(63, 15, 0, 1)
4165         case AFCTID:
4166                 return OPVCC(63, 814, 0, 0)
4167         case AFCTIDCC:
4168                 return OPVCC(63, 814, 0, 1)
4169         case AFCTIDZ:
4170                 return OPVCC(63, 815, 0, 0)
4171         case AFCTIDZCC:
4172                 return OPVCC(63, 815, 0, 1)
4173         case AFDIV:
4174                 return OPVCC(63, 18, 0, 0)
4175         case AFDIVCC:
4176                 return OPVCC(63, 18, 0, 1)
4177         case AFDIVS:
4178                 return OPVCC(59, 18, 0, 0)
4179         case AFDIVSCC:
4180                 return OPVCC(59, 18, 0, 1)
4181         case AFMADD:
4182                 return OPVCC(63, 29, 0, 0)
4183         case AFMADDCC:
4184                 return OPVCC(63, 29, 0, 1)
4185         case AFMADDS:
4186                 return OPVCC(59, 29, 0, 0)
4187         case AFMADDSCC:
4188                 return OPVCC(59, 29, 0, 1)
4189
4190         case AFMOVS, AFMOVD:
4191                 return OPVCC(63, 72, 0, 0) /* load */
4192         case AFMOVDCC:
4193                 return OPVCC(63, 72, 0, 1)
4194         case AFMSUB:
4195                 return OPVCC(63, 28, 0, 0)
4196         case AFMSUBCC:
4197                 return OPVCC(63, 28, 0, 1)
4198         case AFMSUBS:
4199                 return OPVCC(59, 28, 0, 0)
4200         case AFMSUBSCC:
4201                 return OPVCC(59, 28, 0, 1)
4202         case AFMUL:
4203                 return OPVCC(63, 25, 0, 0)
4204         case AFMULCC:
4205                 return OPVCC(63, 25, 0, 1)
4206         case AFMULS:
4207                 return OPVCC(59, 25, 0, 0)
4208         case AFMULSCC:
4209                 return OPVCC(59, 25, 0, 1)
4210         case AFNABS:
4211                 return OPVCC(63, 136, 0, 0)
4212         case AFNABSCC:
4213                 return OPVCC(63, 136, 0, 1)
4214         case AFNEG:
4215                 return OPVCC(63, 40, 0, 0)
4216         case AFNEGCC:
4217                 return OPVCC(63, 40, 0, 1)
4218         case AFNMADD:
4219                 return OPVCC(63, 31, 0, 0)
4220         case AFNMADDCC:
4221                 return OPVCC(63, 31, 0, 1)
4222         case AFNMADDS:
4223                 return OPVCC(59, 31, 0, 0)
4224         case AFNMADDSCC:
4225                 return OPVCC(59, 31, 0, 1)
4226         case AFNMSUB:
4227                 return OPVCC(63, 30, 0, 0)
4228         case AFNMSUBCC:
4229                 return OPVCC(63, 30, 0, 1)
4230         case AFNMSUBS:
4231                 return OPVCC(59, 30, 0, 0)
4232         case AFNMSUBSCC:
4233                 return OPVCC(59, 30, 0, 1)
4234         case AFCPSGN:
4235                 return OPVCC(63, 8, 0, 0)
4236         case AFCPSGNCC:
4237                 return OPVCC(63, 8, 0, 1)
4238         case AFRES:
4239                 return OPVCC(59, 24, 0, 0)
4240         case AFRESCC:
4241                 return OPVCC(59, 24, 0, 1)
4242         case AFRIM:
4243                 return OPVCC(63, 488, 0, 0)
4244         case AFRIMCC:
4245                 return OPVCC(63, 488, 0, 1)
4246         case AFRIP:
4247                 return OPVCC(63, 456, 0, 0)
4248         case AFRIPCC:
4249                 return OPVCC(63, 456, 0, 1)
4250         case AFRIZ:
4251                 return OPVCC(63, 424, 0, 0)
4252         case AFRIZCC:
4253                 return OPVCC(63, 424, 0, 1)
4254         case AFRIN:
4255                 return OPVCC(63, 392, 0, 0)
4256         case AFRINCC:
4257                 return OPVCC(63, 392, 0, 1)
4258         case AFRSP:
4259                 return OPVCC(63, 12, 0, 0)
4260         case AFRSPCC:
4261                 return OPVCC(63, 12, 0, 1)
4262         case AFRSQRTE:
4263                 return OPVCC(63, 26, 0, 0)
4264         case AFRSQRTECC:
4265                 return OPVCC(63, 26, 0, 1)
4266         case AFSEL:
4267                 return OPVCC(63, 23, 0, 0)
4268         case AFSELCC:
4269                 return OPVCC(63, 23, 0, 1)
4270         case AFSQRT:
4271                 return OPVCC(63, 22, 0, 0)
4272         case AFSQRTCC:
4273                 return OPVCC(63, 22, 0, 1)
4274         case AFSQRTS:
4275                 return OPVCC(59, 22, 0, 0)
4276         case AFSQRTSCC:
4277                 return OPVCC(59, 22, 0, 1)
4278         case AFSUB:
4279                 return OPVCC(63, 20, 0, 0)
4280         case AFSUBCC:
4281                 return OPVCC(63, 20, 0, 1)
4282         case AFSUBS:
4283                 return OPVCC(59, 20, 0, 0)
4284         case AFSUBSCC:
4285                 return OPVCC(59, 20, 0, 1)
4286
4287         case AICBI:
4288                 return OPVCC(31, 982, 0, 0)
4289         case AISYNC:
4290                 return OPVCC(19, 150, 0, 0)
4291
4292         case AMTFSB0:
4293                 return OPVCC(63, 70, 0, 0)
4294         case AMTFSB0CC:
4295                 return OPVCC(63, 70, 0, 1)
4296         case AMTFSB1:
4297                 return OPVCC(63, 38, 0, 0)
4298         case AMTFSB1CC:
4299                 return OPVCC(63, 38, 0, 1)
4300
4301         case AMULHW:
4302                 return OPVCC(31, 75, 0, 0)
4303         case AMULHWCC:
4304                 return OPVCC(31, 75, 0, 1)
4305         case AMULHWU:
4306                 return OPVCC(31, 11, 0, 0)
4307         case AMULHWUCC:
4308                 return OPVCC(31, 11, 0, 1)
4309         case AMULLW:
4310                 return OPVCC(31, 235, 0, 0)
4311         case AMULLWCC:
4312                 return OPVCC(31, 235, 0, 1)
4313         case AMULLWV:
4314                 return OPVCC(31, 235, 1, 0)
4315         case AMULLWVCC:
4316                 return OPVCC(31, 235, 1, 1)
4317
4318         case AMULHD:
4319                 return OPVCC(31, 73, 0, 0)
4320         case AMULHDCC:
4321                 return OPVCC(31, 73, 0, 1)
4322         case AMULHDU:
4323                 return OPVCC(31, 9, 0, 0)
4324         case AMULHDUCC:
4325                 return OPVCC(31, 9, 0, 1)
4326         case AMULLD:
4327                 return OPVCC(31, 233, 0, 0)
4328         case AMULLDCC:
4329                 return OPVCC(31, 233, 0, 1)
4330         case AMULLDV:
4331                 return OPVCC(31, 233, 1, 0)
4332         case AMULLDVCC:
4333                 return OPVCC(31, 233, 1, 1)
4334
4335         case ANAND:
4336                 return OPVCC(31, 476, 0, 0)
4337         case ANANDCC:
4338                 return OPVCC(31, 476, 0, 1)
4339         case ANEG:
4340                 return OPVCC(31, 104, 0, 0)
4341         case ANEGCC:
4342                 return OPVCC(31, 104, 0, 1)
4343         case ANEGV:
4344                 return OPVCC(31, 104, 1, 0)
4345         case ANEGVCC:
4346                 return OPVCC(31, 104, 1, 1)
4347         case ANOR:
4348                 return OPVCC(31, 124, 0, 0)
4349         case ANORCC:
4350                 return OPVCC(31, 124, 0, 1)
4351         case AOR:
4352                 return OPVCC(31, 444, 0, 0)
4353         case AORCC:
4354                 return OPVCC(31, 444, 0, 1)
4355         case AORN:
4356                 return OPVCC(31, 412, 0, 0)
4357         case AORNCC:
4358                 return OPVCC(31, 412, 0, 1)
4359
4360         case APOPCNTD:
4361                 return OPVCC(31, 506, 0, 0) /* popcntd - v2.06 */
4362         case APOPCNTW:
4363                 return OPVCC(31, 378, 0, 0) /* popcntw - v2.06 */
4364         case APOPCNTB:
4365                 return OPVCC(31, 122, 0, 0) /* popcntb - v2.02 */
4366         case ACNTTZW:
4367                 return OPVCC(31, 538, 0, 0) /* cnttzw - v3.00 */
4368         case ACNTTZWCC:
4369                 return OPVCC(31, 538, 0, 1) /* cnttzw. - v3.00 */
4370         case ACNTTZD:
4371                 return OPVCC(31, 570, 0, 0) /* cnttzd - v3.00 */
4372         case ACNTTZDCC:
4373                 return OPVCC(31, 570, 0, 1) /* cnttzd. - v3.00 */
4374
4375         case ARFI:
4376                 return OPVCC(19, 50, 0, 0)
4377         case ARFCI:
4378                 return OPVCC(19, 51, 0, 0)
4379         case ARFID:
4380                 return OPVCC(19, 18, 0, 0)
4381         case AHRFID:
4382                 return OPVCC(19, 274, 0, 0)
4383
4384         case ARLWNM:
4385                 return OPVCC(23, 0, 0, 0)
4386         case ARLWNMCC:
4387                 return OPVCC(23, 0, 0, 1)
4388
4389         case ARLDCL:
4390                 return OPVCC(30, 8, 0, 0)
4391         case ARLDCLCC:
4392                 return OPVCC(30, 0, 0, 1)
4393
4394         case ARLDCR:
4395                 return OPVCC(30, 9, 0, 0)
4396         case ARLDCRCC:
4397                 return OPVCC(30, 9, 0, 1)
4398
4399         case ARLDICL:
4400                 return OPVCC(30, 0, 0, 0)
4401         case ARLDICLCC:
4402                 return OPVCC(30, 0, 0, 1)
4403         case ARLDICR:
4404                 return OPMD(30, 1, 0) // rldicr
4405         case ARLDICRCC:
4406                 return OPMD(30, 1, 1) // rldicr.
4407
4408         case ARLDIC:
4409                 return OPMD(30, 2, 0) // rldic
4410         case ARLDICCC:
4411                 return OPMD(30, 2, 1) // rldic.
4412
4413         case ASYSCALL:
4414                 return OPVCC(17, 1, 0, 0)
4415
4416         case ASLW:
4417                 return OPVCC(31, 24, 0, 0)
4418         case ASLWCC:
4419                 return OPVCC(31, 24, 0, 1)
4420         case ASLD:
4421                 return OPVCC(31, 27, 0, 0)
4422         case ASLDCC:
4423                 return OPVCC(31, 27, 0, 1)
4424
4425         case ASRAW:
4426                 return OPVCC(31, 792, 0, 0)
4427         case ASRAWCC:
4428                 return OPVCC(31, 792, 0, 1)
4429         case ASRAD:
4430                 return OPVCC(31, 794, 0, 0)
4431         case ASRADCC:
4432                 return OPVCC(31, 794, 0, 1)
4433
4434         case AEXTSWSLI:
4435                 return OPVCC(31, 445, 0, 0)
4436         case AEXTSWSLICC:
4437                 return OPVCC(31, 445, 0, 1)
4438
4439         case ASRW:
4440                 return OPVCC(31, 536, 0, 0)
4441         case ASRWCC:
4442                 return OPVCC(31, 536, 0, 1)
4443         case ASRD:
4444                 return OPVCC(31, 539, 0, 0)
4445         case ASRDCC:
4446                 return OPVCC(31, 539, 0, 1)
4447
4448         case ASUB:
4449                 return OPVCC(31, 40, 0, 0)
4450         case ASUBCC:
4451                 return OPVCC(31, 40, 0, 1)
4452         case ASUBV:
4453                 return OPVCC(31, 40, 1, 0)
4454         case ASUBVCC:
4455                 return OPVCC(31, 40, 1, 1)
4456         case ASUBC:
4457                 return OPVCC(31, 8, 0, 0)
4458         case ASUBCCC:
4459                 return OPVCC(31, 8, 0, 1)
4460         case ASUBCV:
4461                 return OPVCC(31, 8, 1, 0)
4462         case ASUBCVCC:
4463                 return OPVCC(31, 8, 1, 1)
4464         case ASUBE:
4465                 return OPVCC(31, 136, 0, 0)
4466         case ASUBECC:
4467                 return OPVCC(31, 136, 0, 1)
4468         case ASUBEV:
4469                 return OPVCC(31, 136, 1, 0)
4470         case ASUBEVCC:
4471                 return OPVCC(31, 136, 1, 1)
4472         case ASUBME:
4473                 return OPVCC(31, 232, 0, 0)
4474         case ASUBMECC:
4475                 return OPVCC(31, 232, 0, 1)
4476         case ASUBMEV:
4477                 return OPVCC(31, 232, 1, 0)
4478         case ASUBMEVCC:
4479                 return OPVCC(31, 232, 1, 1)
4480         case ASUBZE:
4481                 return OPVCC(31, 200, 0, 0)
4482         case ASUBZECC:
4483                 return OPVCC(31, 200, 0, 1)
4484         case ASUBZEV:
4485                 return OPVCC(31, 200, 1, 0)
4486         case ASUBZEVCC:
4487                 return OPVCC(31, 200, 1, 1)
4488
4489         case ASYNC:
4490                 return OPVCC(31, 598, 0, 0)
4491         case ALWSYNC:
4492                 return OPVCC(31, 598, 0, 0) | 1<<21
4493
4494         case APTESYNC:
4495                 return OPVCC(31, 598, 0, 0) | 2<<21
4496
4497         case ATLBIE:
4498                 return OPVCC(31, 306, 0, 0)
4499         case ATLBIEL:
4500                 return OPVCC(31, 274, 0, 0)
4501         case ATLBSYNC:
4502                 return OPVCC(31, 566, 0, 0)
4503         case ASLBIA:
4504                 return OPVCC(31, 498, 0, 0)
4505         case ASLBIE:
4506                 return OPVCC(31, 434, 0, 0)
4507         case ASLBMFEE:
4508                 return OPVCC(31, 915, 0, 0)
4509         case ASLBMFEV:
4510                 return OPVCC(31, 851, 0, 0)
4511         case ASLBMTE:
4512                 return OPVCC(31, 402, 0, 0)
4513
4514         case ATW:
4515                 return OPVCC(31, 4, 0, 0)
4516         case ATD:
4517                 return OPVCC(31, 68, 0, 0)
4518
4519         /* Vector (VMX/Altivec) instructions */
4520         /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4521         /* are enabled starting at POWER6 (ISA 2.05). */
4522         case AVAND:
4523                 return OPVX(4, 1028, 0, 0) /* vand - v2.03 */
4524         case AVANDC:
4525                 return OPVX(4, 1092, 0, 0) /* vandc - v2.03 */
4526         case AVNAND:
4527                 return OPVX(4, 1412, 0, 0) /* vnand - v2.07 */
4528
4529         case AVOR:
4530                 return OPVX(4, 1156, 0, 0) /* vor - v2.03 */
4531         case AVORC:
4532                 return OPVX(4, 1348, 0, 0) /* vorc - v2.07 */
4533         case AVNOR:
4534                 return OPVX(4, 1284, 0, 0) /* vnor - v2.03 */
4535         case AVXOR:
4536                 return OPVX(4, 1220, 0, 0) /* vxor - v2.03 */
4537         case AVEQV:
4538                 return OPVX(4, 1668, 0, 0) /* veqv - v2.07 */
4539
4540         case AVADDUBM:
4541                 return OPVX(4, 0, 0, 0) /* vaddubm - v2.03 */
4542         case AVADDUHM:
4543                 return OPVX(4, 64, 0, 0) /* vadduhm - v2.03 */
4544         case AVADDUWM:
4545                 return OPVX(4, 128, 0, 0) /* vadduwm - v2.03 */
4546         case AVADDUDM:
4547                 return OPVX(4, 192, 0, 0) /* vaddudm - v2.07 */
4548         case AVADDUQM:
4549                 return OPVX(4, 256, 0, 0) /* vadduqm - v2.07 */
4550
4551         case AVADDCUQ:
4552                 return OPVX(4, 320, 0, 0) /* vaddcuq - v2.07 */
4553         case AVADDCUW:
4554                 return OPVX(4, 384, 0, 0) /* vaddcuw - v2.03 */
4555
4556         case AVADDUBS:
4557                 return OPVX(4, 512, 0, 0) /* vaddubs - v2.03 */
4558         case AVADDUHS:
4559                 return OPVX(4, 576, 0, 0) /* vadduhs - v2.03 */
4560         case AVADDUWS:
4561                 return OPVX(4, 640, 0, 0) /* vadduws - v2.03 */
4562
4563         case AVADDSBS:
4564                 return OPVX(4, 768, 0, 0) /* vaddsbs - v2.03 */
4565         case AVADDSHS:
4566                 return OPVX(4, 832, 0, 0) /* vaddshs - v2.03 */
4567         case AVADDSWS:
4568                 return OPVX(4, 896, 0, 0) /* vaddsws - v2.03 */
4569
4570         case AVADDEUQM:
4571                 return OPVX(4, 60, 0, 0) /* vaddeuqm - v2.07 */
4572         case AVADDECUQ:
4573                 return OPVX(4, 61, 0, 0) /* vaddecuq - v2.07 */
4574
4575         case AVMULESB:
4576                 return OPVX(4, 776, 0, 0) /* vmulesb - v2.03 */
4577         case AVMULOSB:
4578                 return OPVX(4, 264, 0, 0) /* vmulosb - v2.03 */
4579         case AVMULEUB:
4580                 return OPVX(4, 520, 0, 0) /* vmuleub - v2.03 */
4581         case AVMULOUB:
4582                 return OPVX(4, 8, 0, 0) /* vmuloub - v2.03 */
4583         case AVMULESH:
4584                 return OPVX(4, 840, 0, 0) /* vmulesh - v2.03 */
4585         case AVMULOSH:
4586                 return OPVX(4, 328, 0, 0) /* vmulosh - v2.03 */
4587         case AVMULEUH:
4588                 return OPVX(4, 584, 0, 0) /* vmuleuh - v2.03 */
4589         case AVMULOUH:
4590                 return OPVX(4, 72, 0, 0) /* vmulouh - v2.03 */
4591         case AVMULESW:
4592                 return OPVX(4, 904, 0, 0) /* vmulesw - v2.07 */
4593         case AVMULOSW:
4594                 return OPVX(4, 392, 0, 0) /* vmulosw - v2.07 */
4595         case AVMULEUW:
4596                 return OPVX(4, 648, 0, 0) /* vmuleuw - v2.07 */
4597         case AVMULOUW:
4598                 return OPVX(4, 136, 0, 0) /* vmulouw - v2.07 */
4599         case AVMULUWM:
4600                 return OPVX(4, 137, 0, 0) /* vmuluwm - v2.07 */
4601
4602         case AVPMSUMB:
4603                 return OPVX(4, 1032, 0, 0) /* vpmsumb - v2.07 */
4604         case AVPMSUMH:
4605                 return OPVX(4, 1096, 0, 0) /* vpmsumh - v2.07 */
4606         case AVPMSUMW:
4607                 return OPVX(4, 1160, 0, 0) /* vpmsumw - v2.07 */
4608         case AVPMSUMD:
4609                 return OPVX(4, 1224, 0, 0) /* vpmsumd - v2.07 */
4610
4611         case AVMSUMUDM:
4612                 return OPVX(4, 35, 0, 0) /* vmsumudm - v3.00b */
4613
4614         case AVSUBUBM:
4615                 return OPVX(4, 1024, 0, 0) /* vsububm - v2.03 */
4616         case AVSUBUHM:
4617                 return OPVX(4, 1088, 0, 0) /* vsubuhm - v2.03 */
4618         case AVSUBUWM:
4619                 return OPVX(4, 1152, 0, 0) /* vsubuwm - v2.03 */
4620         case AVSUBUDM:
4621                 return OPVX(4, 1216, 0, 0) /* vsubudm - v2.07 */
4622         case AVSUBUQM:
4623                 return OPVX(4, 1280, 0, 0) /* vsubuqm - v2.07 */
4624
4625         case AVSUBCUQ:
4626                 return OPVX(4, 1344, 0, 0) /* vsubcuq - v2.07 */
4627         case AVSUBCUW:
4628                 return OPVX(4, 1408, 0, 0) /* vsubcuw - v2.03 */
4629
4630         case AVSUBUBS:
4631                 return OPVX(4, 1536, 0, 0) /* vsububs - v2.03 */
4632         case AVSUBUHS:
4633                 return OPVX(4, 1600, 0, 0) /* vsubuhs - v2.03 */
4634         case AVSUBUWS:
4635                 return OPVX(4, 1664, 0, 0) /* vsubuws - v2.03 */
4636
4637         case AVSUBSBS:
4638                 return OPVX(4, 1792, 0, 0) /* vsubsbs - v2.03 */
4639         case AVSUBSHS:
4640                 return OPVX(4, 1856, 0, 0) /* vsubshs - v2.03 */
4641         case AVSUBSWS:
4642                 return OPVX(4, 1920, 0, 0) /* vsubsws - v2.03 */
4643
4644         case AVSUBEUQM:
4645                 return OPVX(4, 62, 0, 0) /* vsubeuqm - v2.07 */
4646         case AVSUBECUQ:
4647                 return OPVX(4, 63, 0, 0) /* vsubecuq - v2.07 */
4648
4649         case AVRLB:
4650                 return OPVX(4, 4, 0, 0) /* vrlb - v2.03 */
4651         case AVRLH:
4652                 return OPVX(4, 68, 0, 0) /* vrlh - v2.03 */
4653         case AVRLW:
4654                 return OPVX(4, 132, 0, 0) /* vrlw - v2.03 */
4655         case AVRLD:
4656                 return OPVX(4, 196, 0, 0) /* vrld - v2.07 */
4657
4658         case AVMRGOW:
4659                 return OPVX(4, 1676, 0, 0) /* vmrgow - v2.07 */
4660         case AVMRGEW:
4661                 return OPVX(4, 1932, 0, 0) /* vmrgew - v2.07 */
4662
4663         case AVSLB:
4664                 return OPVX(4, 260, 0, 0) /* vslh - v2.03 */
4665         case AVSLH:
4666                 return OPVX(4, 324, 0, 0) /* vslh - v2.03 */
4667         case AVSLW:
4668                 return OPVX(4, 388, 0, 0) /* vslw - v2.03 */
4669         case AVSL:
4670                 return OPVX(4, 452, 0, 0) /* vsl - v2.03 */
4671         case AVSLO:
4672                 return OPVX(4, 1036, 0, 0) /* vsl - v2.03 */
4673         case AVSRB:
4674                 return OPVX(4, 516, 0, 0) /* vsrb - v2.03 */
4675         case AVSRH:
4676                 return OPVX(4, 580, 0, 0) /* vsrh - v2.03 */
4677         case AVSRW:
4678                 return OPVX(4, 644, 0, 0) /* vsrw - v2.03 */
4679         case AVSR:
4680                 return OPVX(4, 708, 0, 0) /* vsr - v2.03 */
4681         case AVSRO:
4682                 return OPVX(4, 1100, 0, 0) /* vsro - v2.03 */
4683         case AVSLD:
4684                 return OPVX(4, 1476, 0, 0) /* vsld - v2.07 */
4685         case AVSRD:
4686                 return OPVX(4, 1732, 0, 0) /* vsrd - v2.07 */
4687
4688         case AVSRAB:
4689                 return OPVX(4, 772, 0, 0) /* vsrab - v2.03 */
4690         case AVSRAH:
4691                 return OPVX(4, 836, 0, 0) /* vsrah - v2.03 */
4692         case AVSRAW:
4693                 return OPVX(4, 900, 0, 0) /* vsraw - v2.03 */
4694         case AVSRAD:
4695                 return OPVX(4, 964, 0, 0) /* vsrad - v2.07 */
4696
4697         case AVBPERMQ:
4698                 return OPVC(4, 1356, 0, 0) /* vbpermq - v2.07 */
4699         case AVBPERMD:
4700                 return OPVC(4, 1484, 0, 0) /* vbpermd - v3.00 */
4701
4702         case AVCLZB:
4703                 return OPVX(4, 1794, 0, 0) /* vclzb - v2.07 */
4704         case AVCLZH:
4705                 return OPVX(4, 1858, 0, 0) /* vclzh - v2.07 */
4706         case AVCLZW:
4707                 return OPVX(4, 1922, 0, 0) /* vclzw - v2.07 */
4708         case AVCLZD:
4709                 return OPVX(4, 1986, 0, 0) /* vclzd - v2.07 */
4710
4711         case AVCLZLSBB:
4712                 return OPVX(4, 1538, 0, 0) /* vclzlsbb - v3.0 */
4713         case AVCTZLSBB:
4714                 return OPVX(4, 1538, 0, 0) | 1<<16 /* vctzlsbb - v3.0 */
4715
4716         case AVPOPCNTB:
4717                 return OPVX(4, 1795, 0, 0) /* vpopcntb - v2.07 */
4718         case AVPOPCNTH:
4719                 return OPVX(4, 1859, 0, 0) /* vpopcnth - v2.07 */
4720         case AVPOPCNTW:
4721                 return OPVX(4, 1923, 0, 0) /* vpopcntw - v2.07 */
4722         case AVPOPCNTD:
4723                 return OPVX(4, 1987, 0, 0) /* vpopcntd - v2.07 */
4724
4725         case AVCMPEQUB:
4726                 return OPVC(4, 6, 0, 0) /* vcmpequb - v2.03 */
4727         case AVCMPEQUBCC:
4728                 return OPVC(4, 6, 0, 1) /* vcmpequb. - v2.03 */
4729         case AVCMPEQUH:
4730                 return OPVC(4, 70, 0, 0) /* vcmpequh - v2.03 */
4731         case AVCMPEQUHCC:
4732                 return OPVC(4, 70, 0, 1) /* vcmpequh. - v2.03 */
4733         case AVCMPEQUW:
4734                 return OPVC(4, 134, 0, 0) /* vcmpequw - v2.03 */
4735         case AVCMPEQUWCC:
4736                 return OPVC(4, 134, 0, 1) /* vcmpequw. - v2.03 */
4737         case AVCMPEQUD:
4738                 return OPVC(4, 199, 0, 0) /* vcmpequd - v2.07 */
4739         case AVCMPEQUDCC:
4740                 return OPVC(4, 199, 0, 1) /* vcmpequd. - v2.07 */
4741
4742         case AVCMPGTUB:
4743                 return OPVC(4, 518, 0, 0) /* vcmpgtub - v2.03 */
4744         case AVCMPGTUBCC:
4745                 return OPVC(4, 518, 0, 1) /* vcmpgtub. - v2.03 */
4746         case AVCMPGTUH:
4747                 return OPVC(4, 582, 0, 0) /* vcmpgtuh - v2.03 */
4748         case AVCMPGTUHCC:
4749                 return OPVC(4, 582, 0, 1) /* vcmpgtuh. - v2.03 */
4750         case AVCMPGTUW:
4751                 return OPVC(4, 646, 0, 0) /* vcmpgtuw - v2.03 */
4752         case AVCMPGTUWCC:
4753                 return OPVC(4, 646, 0, 1) /* vcmpgtuw. - v2.03 */
4754         case AVCMPGTUD:
4755                 return OPVC(4, 711, 0, 0) /* vcmpgtud - v2.07 */
4756         case AVCMPGTUDCC:
4757                 return OPVC(4, 711, 0, 1) /* vcmpgtud. v2.07 */
4758         case AVCMPGTSB:
4759                 return OPVC(4, 774, 0, 0) /* vcmpgtsb - v2.03 */
4760         case AVCMPGTSBCC:
4761                 return OPVC(4, 774, 0, 1) /* vcmpgtsb. - v2.03 */
4762         case AVCMPGTSH:
4763                 return OPVC(4, 838, 0, 0) /* vcmpgtsh - v2.03 */
4764         case AVCMPGTSHCC:
4765                 return OPVC(4, 838, 0, 1) /* vcmpgtsh. - v2.03 */
4766         case AVCMPGTSW:
4767                 return OPVC(4, 902, 0, 0) /* vcmpgtsw - v2.03 */
4768         case AVCMPGTSWCC:
4769                 return OPVC(4, 902, 0, 1) /* vcmpgtsw. - v2.03 */
4770         case AVCMPGTSD:
4771                 return OPVC(4, 967, 0, 0) /* vcmpgtsd - v2.07 */
4772         case AVCMPGTSDCC:
4773                 return OPVC(4, 967, 0, 1) /* vcmpgtsd. - v2.07 */
4774
4775         case AVCMPNEZB:
4776                 return OPVC(4, 263, 0, 0) /* vcmpnezb - v3.00 */
4777         case AVCMPNEZBCC:
4778                 return OPVC(4, 263, 0, 1) /* vcmpnezb. - v3.00 */
4779         case AVCMPNEB:
4780                 return OPVC(4, 7, 0, 0) /* vcmpneb - v3.00 */
4781         case AVCMPNEBCC:
4782                 return OPVC(4, 7, 0, 1) /* vcmpneb. - v3.00 */
4783         case AVCMPNEH:
4784                 return OPVC(4, 71, 0, 0) /* vcmpneh - v3.00 */
4785         case AVCMPNEHCC:
4786                 return OPVC(4, 71, 0, 1) /* vcmpneh. - v3.00 */
4787         case AVCMPNEW:
4788                 return OPVC(4, 135, 0, 0) /* vcmpnew - v3.00 */
4789         case AVCMPNEWCC:
4790                 return OPVC(4, 135, 0, 1) /* vcmpnew. - v3.00 */
4791
4792         case AVPERM:
4793                 return OPVX(4, 43, 0, 0) /* vperm - v2.03 */
4794         case AVPERMXOR:
4795                 return OPVX(4, 45, 0, 0) /* vpermxor - v2.03 */
4796         case AVPERMR:
4797                 return OPVX(4, 59, 0, 0) /* vpermr - v3.0 */
4798
4799         case AVSEL:
4800                 return OPVX(4, 42, 0, 0) /* vsel - v2.03 */
4801
4802         case AVCIPHER:
4803                 return OPVX(4, 1288, 0, 0) /* vcipher - v2.07 */
4804         case AVCIPHERLAST:
4805                 return OPVX(4, 1289, 0, 0) /* vcipherlast - v2.07 */
4806         case AVNCIPHER:
4807                 return OPVX(4, 1352, 0, 0) /* vncipher - v2.07 */
4808         case AVNCIPHERLAST:
4809                 return OPVX(4, 1353, 0, 0) /* vncipherlast - v2.07 */
4810         case AVSBOX:
4811                 return OPVX(4, 1480, 0, 0) /* vsbox - v2.07 */
4812         /* End of vector instructions */
4813
4814         /* Vector scalar (VSX) instructions */
4815         /* ISA 2.06 enables these for POWER7. */
4816         case AMFVSRD, AMFVRD, AMFFPRD:
4817                 return OPVXX1(31, 51, 0) /* mfvsrd - v2.07 */
4818         case AMFVSRWZ:
4819                 return OPVXX1(31, 115, 0) /* mfvsrwz - v2.07 */
4820         case AMFVSRLD:
4821                 return OPVXX1(31, 307, 0) /* mfvsrld - v3.00 */
4822
4823         case AMTVSRD, AMTFPRD, AMTVRD:
4824                 return OPVXX1(31, 179, 0) /* mtvsrd - v2.07 */
4825         case AMTVSRWA:
4826                 return OPVXX1(31, 211, 0) /* mtvsrwa - v2.07 */
4827         case AMTVSRWZ:
4828                 return OPVXX1(31, 243, 0) /* mtvsrwz - v2.07 */
4829         case AMTVSRDD:
4830                 return OPVXX1(31, 435, 0) /* mtvsrdd - v3.00 */
4831         case AMTVSRWS:
4832                 return OPVXX1(31, 403, 0) /* mtvsrws - v3.00 */
4833
4834         case AXXLAND:
4835                 return OPVXX3(60, 130, 0) /* xxland - v2.06 */
4836         case AXXLANDC:
4837                 return OPVXX3(60, 138, 0) /* xxlandc - v2.06 */
4838         case AXXLEQV:
4839                 return OPVXX3(60, 186, 0) /* xxleqv - v2.07 */
4840         case AXXLNAND:
4841                 return OPVXX3(60, 178, 0) /* xxlnand - v2.07 */
4842
4843         case AXXLORC:
4844                 return OPVXX3(60, 170, 0) /* xxlorc - v2.07 */
4845         case AXXLNOR:
4846                 return OPVXX3(60, 162, 0) /* xxlnor - v2.06 */
4847         case AXXLOR, AXXLORQ:
4848                 return OPVXX3(60, 146, 0) /* xxlor - v2.06 */
4849         case AXXLXOR:
4850                 return OPVXX3(60, 154, 0) /* xxlxor - v2.06 */
4851
4852         case AXXSEL:
4853                 return OPVXX4(60, 3, 0) /* xxsel - v2.06 */
4854
4855         case AXXMRGHW:
4856                 return OPVXX3(60, 18, 0) /* xxmrghw - v2.06 */
4857         case AXXMRGLW:
4858                 return OPVXX3(60, 50, 0) /* xxmrglw - v2.06 */
4859
4860         case AXXSPLTW:
4861                 return OPVXX2(60, 164, 0) /* xxspltw - v2.06 */
4862
4863         case AXXSPLTIB:
4864                 return OPVCC(60, 360, 0, 0) /* xxspltib - v3.0 */
4865
4866         case AXXPERM:
4867                 return OPVXX3(60, 26, 0) /* xxperm - v2.06 */
4868         case AXXPERMDI:
4869                 return OPVXX3(60, 10, 0) /* xxpermdi - v2.06 */
4870
4871         case AXXSLDWI:
4872                 return OPVXX3(60, 2, 0) /* xxsldwi - v2.06 */
4873
4874         case AXXBRQ:
4875                 return OPVXX2VA(60, 475, 31) /* xxbrq - v3.0 */
4876         case AXXBRD:
4877                 return OPVXX2VA(60, 475, 23) /* xxbrd - v3.0 */
4878         case AXXBRW:
4879                 return OPVXX2VA(60, 475, 15) /* xxbrw - v3.0 */
4880         case AXXBRH:
4881                 return OPVXX2VA(60, 475, 7) /* xxbrh - v3.0 */
4882
4883         case AXSCVDPSP:
4884                 return OPVXX2(60, 265, 0) /* xscvdpsp - v2.06 */
4885         case AXSCVSPDP:
4886                 return OPVXX2(60, 329, 0) /* xscvspdp - v2.06 */
4887         case AXSCVDPSPN:
4888                 return OPVXX2(60, 267, 0) /* xscvdpspn - v2.07 */
4889         case AXSCVSPDPN:
4890                 return OPVXX2(60, 331, 0) /* xscvspdpn - v2.07 */
4891
4892         case AXVCVDPSP:
4893                 return OPVXX2(60, 393, 0) /* xvcvdpsp - v2.06 */
4894         case AXVCVSPDP:
4895                 return OPVXX2(60, 457, 0) /* xvcvspdp - v2.06 */
4896
4897         case AXSCVDPSXDS:
4898                 return OPVXX2(60, 344, 0) /* xscvdpsxds - v2.06 */
4899         case AXSCVDPSXWS:
4900                 return OPVXX2(60, 88, 0) /* xscvdpsxws - v2.06 */
4901         case AXSCVDPUXDS:
4902                 return OPVXX2(60, 328, 0) /* xscvdpuxds - v2.06 */
4903         case AXSCVDPUXWS:
4904                 return OPVXX2(60, 72, 0) /* xscvdpuxws - v2.06 */
4905
4906         case AXSCVSXDDP:
4907                 return OPVXX2(60, 376, 0) /* xscvsxddp - v2.06 */
4908         case AXSCVUXDDP:
4909                 return OPVXX2(60, 360, 0) /* xscvuxddp - v2.06 */
4910         case AXSCVSXDSP:
4911                 return OPVXX2(60, 312, 0) /* xscvsxdsp - v2.06 */
4912         case AXSCVUXDSP:
4913                 return OPVXX2(60, 296, 0) /* xscvuxdsp - v2.06 */
4914
4915         case AXVCVDPSXDS:
4916                 return OPVXX2(60, 472, 0) /* xvcvdpsxds - v2.06 */
4917         case AXVCVDPSXWS:
4918                 return OPVXX2(60, 216, 0) /* xvcvdpsxws - v2.06 */
4919         case AXVCVDPUXDS:
4920                 return OPVXX2(60, 456, 0) /* xvcvdpuxds - v2.06 */
4921         case AXVCVDPUXWS:
4922                 return OPVXX2(60, 200, 0) /* xvcvdpuxws - v2.06 */
4923         case AXVCVSPSXDS:
4924                 return OPVXX2(60, 408, 0) /* xvcvspsxds - v2.07 */
4925         case AXVCVSPSXWS:
4926                 return OPVXX2(60, 152, 0) /* xvcvspsxws - v2.07 */
4927         case AXVCVSPUXDS:
4928                 return OPVXX2(60, 392, 0) /* xvcvspuxds - v2.07 */
4929         case AXVCVSPUXWS:
4930                 return OPVXX2(60, 136, 0) /* xvcvspuxws - v2.07 */
4931
4932         case AXVCVSXDDP:
4933                 return OPVXX2(60, 504, 0) /* xvcvsxddp - v2.06 */
4934         case AXVCVSXWDP:
4935                 return OPVXX2(60, 248, 0) /* xvcvsxwdp - v2.06 */
4936         case AXVCVUXDDP:
4937                 return OPVXX2(60, 488, 0) /* xvcvuxddp - v2.06 */
4938         case AXVCVUXWDP:
4939                 return OPVXX2(60, 232, 0) /* xvcvuxwdp - v2.06 */
4940         case AXVCVSXDSP:
4941                 return OPVXX2(60, 440, 0) /* xvcvsxdsp - v2.06 */
4942         case AXVCVSXWSP:
4943                 return OPVXX2(60, 184, 0) /* xvcvsxwsp - v2.06 */
4944         case AXVCVUXDSP:
4945                 return OPVXX2(60, 424, 0) /* xvcvuxdsp - v2.06 */
4946         case AXVCVUXWSP:
4947                 return OPVXX2(60, 168, 0) /* xvcvuxwsp - v2.06 */
4948         /* End of VSX instructions */
4949
4950         case AMADDHD:
4951                 return OPVX(4, 48, 0, 0) /* maddhd - v3.00 */
4952         case AMADDHDU:
4953                 return OPVX(4, 49, 0, 0) /* maddhdu - v3.00 */
4954         case AMADDLD:
4955                 return OPVX(4, 51, 0, 0) /* maddld - v3.00 */
4956
4957         case AXOR:
4958                 return OPVCC(31, 316, 0, 0)
4959         case AXORCC:
4960                 return OPVCC(31, 316, 0, 1)
4961         }
4962
4963         c.ctxt.Diag("bad r/r, r/r/r or r/r/r/r opcode %v", a)
4964         return 0
4965 }
4966
4967 func (c *ctxt9) opirrr(a obj.As) uint32 {
4968         switch a {
4969         /* Vector (VMX/Altivec) instructions */
4970         /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4971         /* are enabled starting at POWER6 (ISA 2.05). */
4972         case AVSLDOI:
4973                 return OPVX(4, 44, 0, 0) /* vsldoi - v2.03 */
4974         }
4975
4976         c.ctxt.Diag("bad i/r/r/r opcode %v", a)
4977         return 0
4978 }
4979
4980 func (c *ctxt9) opiirr(a obj.As) uint32 {
4981         switch a {
4982         /* Vector (VMX/Altivec) instructions */
4983         /* ISA 2.07 enables these for POWER8 and beyond. */
4984         case AVSHASIGMAW:
4985                 return OPVX(4, 1666, 0, 0) /* vshasigmaw - v2.07 */
4986         case AVSHASIGMAD:
4987                 return OPVX(4, 1730, 0, 0) /* vshasigmad - v2.07 */
4988         }
4989
4990         c.ctxt.Diag("bad i/i/r/r opcode %v", a)
4991         return 0
4992 }
4993
4994 func (c *ctxt9) opirr(a obj.As) uint32 {
4995         switch a {
4996         case AADD:
4997                 return OPVCC(14, 0, 0, 0)
4998         case AADDC:
4999                 return OPVCC(12, 0, 0, 0)
5000         case AADDCCC:
5001                 return OPVCC(13, 0, 0, 0)
5002         case AADDIS:
5003                 return OPVCC(15, 0, 0, 0) /* ADDIS */
5004
5005         case AANDCC:
5006                 return OPVCC(28, 0, 0, 0)
5007         case AANDISCC:
5008                 return OPVCC(29, 0, 0, 0) /* ANDIS. */
5009
5010         case ABR:
5011                 return OPVCC(18, 0, 0, 0)
5012         case ABL:
5013                 return OPVCC(18, 0, 0, 0) | 1
5014         case obj.ADUFFZERO:
5015                 return OPVCC(18, 0, 0, 0) | 1
5016         case obj.ADUFFCOPY:
5017                 return OPVCC(18, 0, 0, 0) | 1
5018         case ABC:
5019                 return OPVCC(16, 0, 0, 0)
5020         case ABCL:
5021                 return OPVCC(16, 0, 0, 0) | 1
5022
5023         case ABEQ:
5024                 return AOP_RRR(16<<26, BO_BCR, BI_EQ, 0)
5025         case ABGE:
5026                 return AOP_RRR(16<<26, BO_NOTBCR, BI_LT, 0)
5027         case ABGT:
5028                 return AOP_RRR(16<<26, BO_BCR, BI_GT, 0)
5029         case ABLE:
5030                 return AOP_RRR(16<<26, BO_NOTBCR, BI_GT, 0)
5031         case ABLT:
5032                 return AOP_RRR(16<<26, BO_BCR, BI_LT, 0)
5033         case ABNE:
5034                 return AOP_RRR(16<<26, BO_NOTBCR, BI_EQ, 0)
5035         case ABVC:
5036                 return AOP_RRR(16<<26, BO_NOTBCR, BI_FU, 0)
5037         case ABVS:
5038                 return AOP_RRR(16<<26, BO_BCR, BI_FU, 0)
5039         case ABDZ:
5040                 return AOP_RRR(16<<26, BO_NOTBCTR, 0, 0)
5041         case ABDNZ:
5042                 return AOP_RRR(16<<26, BO_BCTR, 0, 0)
5043
5044         case ACMP:
5045                 return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */
5046         case ACMPU:
5047                 return OPVCC(10, 0, 0, 0) | 1<<21
5048         case ACMPW:
5049                 return OPVCC(11, 0, 0, 0) /* L=0 */
5050         case ACMPWU:
5051                 return OPVCC(10, 0, 0, 0)
5052         case ACMPEQB:
5053                 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
5054
5055         case ALSW:
5056                 return OPVCC(31, 597, 0, 0)
5057
5058         case ACOPY:
5059                 return OPVCC(31, 774, 0, 0) /* copy - v3.00 */
5060         case APASTECC:
5061                 return OPVCC(31, 902, 0, 1) /* paste. - v3.00 */
5062         case ADARN:
5063                 return OPVCC(31, 755, 0, 0) /* darn - v3.00 */
5064
5065         case AMULLW, AMULLD:
5066                 return OPVCC(7, 0, 0, 0) /* mulli works with MULLW or MULLD */
5067
5068         case AOR:
5069                 return OPVCC(24, 0, 0, 0)
5070         case AORIS:
5071                 return OPVCC(25, 0, 0, 0) /* ORIS */
5072
5073         case ARLWMI:
5074                 return OPVCC(20, 0, 0, 0) /* rlwimi */
5075         case ARLWMICC:
5076                 return OPVCC(20, 0, 0, 1)
5077         case ARLDMI:
5078                 return OPMD(30, 3, 0) /* rldimi */
5079         case ARLDMICC:
5080                 return OPMD(30, 3, 1) /* rldimi. */
5081         case ARLDIMI:
5082                 return OPMD(30, 3, 0) /* rldimi */
5083         case ARLDIMICC:
5084                 return OPMD(30, 3, 1) /* rldimi. */
5085         case ARLWNM:
5086                 return OPVCC(21, 0, 0, 0) /* rlwinm */
5087         case ARLWNMCC:
5088                 return OPVCC(21, 0, 0, 1)
5089
5090         case ARLDCL:
5091                 return OPMD(30, 0, 0) /* rldicl */
5092         case ARLDCLCC:
5093                 return OPMD(30, 0, 1) /* rldicl. */
5094         case ARLDCR:
5095                 return OPMD(30, 1, 0) /* rldicr */
5096         case ARLDCRCC:
5097                 return OPMD(30, 1, 1) /* rldicr. */
5098         case ARLDC:
5099                 return OPMD(30, 2, 0) /* rldic */
5100         case ARLDCCC:
5101                 return OPMD(30, 2, 1) /* rldic. */
5102
5103         case ASRAW:
5104                 return OPVCC(31, 824, 0, 0)
5105         case ASRAWCC:
5106                 return OPVCC(31, 824, 0, 1)
5107         case ASRAD:
5108                 return OPVCC(31, (413 << 1), 0, 0)
5109         case ASRADCC:
5110                 return OPVCC(31, (413 << 1), 0, 1)
5111         case AEXTSWSLI:
5112                 return OPVCC(31, 445, 0, 0)
5113         case AEXTSWSLICC:
5114                 return OPVCC(31, 445, 0, 1)
5115
5116         case ASTSW:
5117                 return OPVCC(31, 725, 0, 0)
5118
5119         case ASUBC:
5120                 return OPVCC(8, 0, 0, 0)
5121
5122         case ATW:
5123                 return OPVCC(3, 0, 0, 0)
5124         case ATD:
5125                 return OPVCC(2, 0, 0, 0)
5126
5127         /* Vector (VMX/Altivec) instructions */
5128         /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
5129         /* are enabled starting at POWER6 (ISA 2.05). */
5130         case AVSPLTB:
5131                 return OPVX(4, 524, 0, 0) /* vspltb - v2.03 */
5132         case AVSPLTH:
5133                 return OPVX(4, 588, 0, 0) /* vsplth - v2.03 */
5134         case AVSPLTW:
5135                 return OPVX(4, 652, 0, 0) /* vspltw - v2.03 */
5136
5137         case AVSPLTISB:
5138                 return OPVX(4, 780, 0, 0) /* vspltisb - v2.03 */
5139         case AVSPLTISH:
5140                 return OPVX(4, 844, 0, 0) /* vspltish - v2.03 */
5141         case AVSPLTISW:
5142                 return OPVX(4, 908, 0, 0) /* vspltisw - v2.03 */
5143         /* End of vector instructions */
5144
5145         case AFTDIV:
5146                 return OPVCC(63, 128, 0, 0) /* ftdiv - v2.06 */
5147         case AFTSQRT:
5148                 return OPVCC(63, 160, 0, 0) /* ftsqrt - v2.06 */
5149
5150         case AXOR:
5151                 return OPVCC(26, 0, 0, 0) /* XORIL */
5152         case AXORIS:
5153                 return OPVCC(27, 0, 0, 0) /* XORIS */
5154         }
5155
5156         c.ctxt.Diag("bad opcode i/r or i/r/r %v", a)
5157         return 0
5158 }
5159
5160 /*
5161  * load o(a),d
5162  */
5163 func (c *ctxt9) opload(a obj.As) uint32 {
5164         switch a {
5165         case AMOVD:
5166                 return OPVCC(58, 0, 0, 0) /* ld */
5167         case AMOVDU:
5168                 return OPVCC(58, 0, 0, 1) /* ldu */
5169         case AMOVWZ:
5170                 return OPVCC(32, 0, 0, 0) /* lwz */
5171         case AMOVWZU:
5172                 return OPVCC(33, 0, 0, 0) /* lwzu */
5173         case AMOVW:
5174                 return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */
5175         case ALXV:
5176                 return OPDQ(61, 1, 0) /* lxv - ISA v3.0 */
5177         case ALXVL:
5178                 return OPVXX1(31, 269, 0) /* lxvl - ISA v3.0 */
5179         case ALXVLL:
5180                 return OPVXX1(31, 301, 0) /* lxvll - ISA v3.0 */
5181         case ALXVX:
5182                 return OPVXX1(31, 268, 0) /* lxvx - ISA v3.0 */
5183
5184                 /* no AMOVWU */
5185         case AMOVB, AMOVBZ:
5186                 return OPVCC(34, 0, 0, 0)
5187                 /* load */
5188
5189         case AMOVBU, AMOVBZU:
5190                 return OPVCC(35, 0, 0, 0)
5191         case AFMOVD:
5192                 return OPVCC(50, 0, 0, 0)
5193         case AFMOVDU:
5194                 return OPVCC(51, 0, 0, 0)
5195         case AFMOVS:
5196                 return OPVCC(48, 0, 0, 0)
5197         case AFMOVSU:
5198                 return OPVCC(49, 0, 0, 0)
5199         case AMOVH:
5200                 return OPVCC(42, 0, 0, 0)
5201         case AMOVHU:
5202                 return OPVCC(43, 0, 0, 0)
5203         case AMOVHZ:
5204                 return OPVCC(40, 0, 0, 0)
5205         case AMOVHZU:
5206                 return OPVCC(41, 0, 0, 0)
5207         case AMOVMW:
5208                 return OPVCC(46, 0, 0, 0) /* lmw */
5209         }
5210
5211         c.ctxt.Diag("bad load opcode %v", a)
5212         return 0
5213 }
5214
5215 /*
5216  * indexed load a(b),d
5217  */
5218 func (c *ctxt9) oploadx(a obj.As) uint32 {
5219         switch a {
5220         case AMOVWZ:
5221                 return OPVCC(31, 23, 0, 0) /* lwzx */
5222         case AMOVWZU:
5223                 return OPVCC(31, 55, 0, 0) /* lwzux */
5224         case AMOVW:
5225                 return OPVCC(31, 341, 0, 0) /* lwax */
5226         case AMOVWU:
5227                 return OPVCC(31, 373, 0, 0) /* lwaux */
5228
5229         case AMOVB, AMOVBZ:
5230                 return OPVCC(31, 87, 0, 0) /* lbzx */
5231
5232         case AMOVBU, AMOVBZU:
5233                 return OPVCC(31, 119, 0, 0) /* lbzux */
5234         case AFMOVD:
5235                 return OPVCC(31, 599, 0, 0) /* lfdx */
5236         case AFMOVDU:
5237                 return OPVCC(31, 631, 0, 0) /*  lfdux */
5238         case AFMOVS:
5239                 return OPVCC(31, 535, 0, 0) /* lfsx */
5240         case AFMOVSU:
5241                 return OPVCC(31, 567, 0, 0) /* lfsux */
5242         case AFMOVSX:
5243                 return OPVCC(31, 855, 0, 0) /* lfiwax - power6, isa 2.05 */
5244         case AFMOVSZ:
5245                 return OPVCC(31, 887, 0, 0) /* lfiwzx - power7, isa 2.06 */
5246         case AMOVH:
5247                 return OPVCC(31, 343, 0, 0) /* lhax */
5248         case AMOVHU:
5249                 return OPVCC(31, 375, 0, 0) /* lhaux */
5250         case AMOVHBR:
5251                 return OPVCC(31, 790, 0, 0) /* lhbrx */
5252         case AMOVWBR:
5253                 return OPVCC(31, 534, 0, 0) /* lwbrx */
5254         case AMOVDBR:
5255                 return OPVCC(31, 532, 0, 0) /* ldbrx */
5256         case AMOVHZ:
5257                 return OPVCC(31, 279, 0, 0) /* lhzx */
5258         case AMOVHZU:
5259                 return OPVCC(31, 311, 0, 0) /* lhzux */
5260         case ALBAR:
5261                 return OPVCC(31, 52, 0, 0) /* lbarx */
5262         case ALHAR:
5263                 return OPVCC(31, 116, 0, 0) /* lharx */
5264         case ALWAR:
5265                 return OPVCC(31, 20, 0, 0) /* lwarx */
5266         case ALDAR:
5267                 return OPVCC(31, 84, 0, 0) /* ldarx */
5268         case ALSW:
5269                 return OPVCC(31, 533, 0, 0) /* lswx */
5270         case AMOVD:
5271                 return OPVCC(31, 21, 0, 0) /* ldx */
5272         case AMOVDU:
5273                 return OPVCC(31, 53, 0, 0) /* ldux */
5274
5275         /* Vector (VMX/Altivec) instructions */
5276         case ALVEBX:
5277                 return OPVCC(31, 7, 0, 0) /* lvebx - v2.03 */
5278         case ALVEHX:
5279                 return OPVCC(31, 39, 0, 0) /* lvehx - v2.03 */
5280         case ALVEWX:
5281                 return OPVCC(31, 71, 0, 0) /* lvewx - v2.03 */
5282         case ALVX:
5283                 return OPVCC(31, 103, 0, 0) /* lvx - v2.03 */
5284         case ALVXL:
5285                 return OPVCC(31, 359, 0, 0) /* lvxl - v2.03 */
5286         case ALVSL:
5287                 return OPVCC(31, 6, 0, 0) /* lvsl - v2.03 */
5288         case ALVSR:
5289                 return OPVCC(31, 38, 0, 0) /* lvsr - v2.03 */
5290                 /* End of vector instructions */
5291
5292         /* Vector scalar (VSX) instructions */
5293         case ALXVX:
5294                 return OPVXX1(31, 268, 0) /* lxvx - ISA v3.0 */
5295         case ALXVD2X:
5296                 return OPVXX1(31, 844, 0) /* lxvd2x - v2.06 */
5297         case ALXVW4X:
5298                 return OPVXX1(31, 780, 0) /* lxvw4x - v2.06 */
5299         case ALXVH8X:
5300                 return OPVXX1(31, 812, 0) /* lxvh8x - v3.00 */
5301         case ALXVB16X:
5302                 return OPVXX1(31, 876, 0) /* lxvb16x - v3.00 */
5303         case ALXVDSX:
5304                 return OPVXX1(31, 332, 0) /* lxvdsx - v2.06 */
5305         case ALXSDX:
5306                 return OPVXX1(31, 588, 0) /* lxsdx - v2.06 */
5307         case ALXSIWAX:
5308                 return OPVXX1(31, 76, 0) /* lxsiwax - v2.07 */
5309         case ALXSIWZX:
5310                 return OPVXX1(31, 12, 0) /* lxsiwzx - v2.07 */
5311         }
5312
5313         c.ctxt.Diag("bad loadx opcode %v", a)
5314         return 0
5315 }
5316
5317 /*
5318  * store s,o(d)
5319  */
5320 func (c *ctxt9) opstore(a obj.As) uint32 {
5321         switch a {
5322         case AMOVB, AMOVBZ:
5323                 return OPVCC(38, 0, 0, 0) /* stb */
5324
5325         case AMOVBU, AMOVBZU:
5326                 return OPVCC(39, 0, 0, 0) /* stbu */
5327         case AFMOVD:
5328                 return OPVCC(54, 0, 0, 0) /* stfd */
5329         case AFMOVDU:
5330                 return OPVCC(55, 0, 0, 0) /* stfdu */
5331         case AFMOVS:
5332                 return OPVCC(52, 0, 0, 0) /* stfs */
5333         case AFMOVSU:
5334                 return OPVCC(53, 0, 0, 0) /* stfsu */
5335
5336         case AMOVHZ, AMOVH:
5337                 return OPVCC(44, 0, 0, 0) /* sth */
5338
5339         case AMOVHZU, AMOVHU:
5340                 return OPVCC(45, 0, 0, 0) /* sthu */
5341         case AMOVMW:
5342                 return OPVCC(47, 0, 0, 0) /* stmw */
5343         case ASTSW:
5344                 return OPVCC(31, 725, 0, 0) /* stswi */
5345
5346         case AMOVWZ, AMOVW:
5347                 return OPVCC(36, 0, 0, 0) /* stw */
5348
5349         case AMOVWZU, AMOVWU:
5350                 return OPVCC(37, 0, 0, 0) /* stwu */
5351         case AMOVD:
5352                 return OPVCC(62, 0, 0, 0) /* std */
5353         case AMOVDU:
5354                 return OPVCC(62, 0, 0, 1) /* stdu */
5355         case ASTXV:
5356                 return OPDQ(61, 5, 0) /* stxv ISA 3.0 */
5357         case ASTXVL:
5358                 return OPVXX1(31, 397, 0) /* stxvl ISA 3.0 */
5359         case ASTXVLL:
5360                 return OPVXX1(31, 429, 0) /* stxvll ISA 3.0 */
5361         case ASTXVX:
5362                 return OPVXX1(31, 396, 0) /* stxvx - ISA v3.0 */
5363
5364         }
5365
5366         c.ctxt.Diag("unknown store opcode %v", a)
5367         return 0
5368 }
5369
5370 /*
5371  * indexed store s,a(b)
5372  */
5373 func (c *ctxt9) opstorex(a obj.As) uint32 {
5374         switch a {
5375         case AMOVB, AMOVBZ:
5376                 return OPVCC(31, 215, 0, 0) /* stbx */
5377
5378         case AMOVBU, AMOVBZU:
5379                 return OPVCC(31, 247, 0, 0) /* stbux */
5380         case AFMOVD:
5381                 return OPVCC(31, 727, 0, 0) /* stfdx */
5382         case AFMOVDU:
5383                 return OPVCC(31, 759, 0, 0) /* stfdux */
5384         case AFMOVS:
5385                 return OPVCC(31, 663, 0, 0) /* stfsx */
5386         case AFMOVSU:
5387                 return OPVCC(31, 695, 0, 0) /* stfsux */
5388         case AFMOVSX:
5389                 return OPVCC(31, 983, 0, 0) /* stfiwx */
5390
5391         case AMOVHZ, AMOVH:
5392                 return OPVCC(31, 407, 0, 0) /* sthx */
5393         case AMOVHBR:
5394                 return OPVCC(31, 918, 0, 0) /* sthbrx */
5395
5396         case AMOVHZU, AMOVHU:
5397                 return OPVCC(31, 439, 0, 0) /* sthux */
5398
5399         case AMOVWZ, AMOVW:
5400                 return OPVCC(31, 151, 0, 0) /* stwx */
5401
5402         case AMOVWZU, AMOVWU:
5403                 return OPVCC(31, 183, 0, 0) /* stwux */
5404         case ASTSW:
5405                 return OPVCC(31, 661, 0, 0) /* stswx */
5406         case AMOVWBR:
5407                 return OPVCC(31, 662, 0, 0) /* stwbrx */
5408         case AMOVDBR:
5409                 return OPVCC(31, 660, 0, 0) /* stdbrx */
5410         case ASTBCCC:
5411                 return OPVCC(31, 694, 0, 1) /* stbcx. */
5412         case ASTHCCC:
5413                 return OPVCC(31, 726, 0, 1) /* sthcx. */
5414         case ASTWCCC:
5415                 return OPVCC(31, 150, 0, 1) /* stwcx. */
5416         case ASTDCCC:
5417                 return OPVCC(31, 214, 0, 1) /* stwdx. */
5418         case AMOVD:
5419                 return OPVCC(31, 149, 0, 0) /* stdx */
5420         case AMOVDU:
5421                 return OPVCC(31, 181, 0, 0) /* stdux */
5422
5423         /* Vector (VMX/Altivec) instructions */
5424         case ASTVEBX:
5425                 return OPVCC(31, 135, 0, 0) /* stvebx - v2.03 */
5426         case ASTVEHX:
5427                 return OPVCC(31, 167, 0, 0) /* stvehx - v2.03 */
5428         case ASTVEWX:
5429                 return OPVCC(31, 199, 0, 0) /* stvewx - v2.03 */
5430         case ASTVX:
5431                 return OPVCC(31, 231, 0, 0) /* stvx - v2.03 */
5432         case ASTVXL:
5433                 return OPVCC(31, 487, 0, 0) /* stvxl - v2.03 */
5434                 /* End of vector instructions */
5435
5436         /* Vector scalar (VSX) instructions */
5437         case ASTXVX:
5438                 return OPVXX1(31, 396, 0) /* stxvx - v3.0 */
5439         case ASTXVD2X:
5440                 return OPVXX1(31, 972, 0) /* stxvd2x - v2.06 */
5441         case ASTXVW4X:
5442                 return OPVXX1(31, 908, 0) /* stxvw4x - v2.06 */
5443         case ASTXVH8X:
5444                 return OPVXX1(31, 940, 0) /* stxvh8x - v3.0 */
5445         case ASTXVB16X:
5446                 return OPVXX1(31, 1004, 0) /* stxvb16x - v3.0 */
5447
5448         case ASTXSDX:
5449                 return OPVXX1(31, 716, 0) /* stxsdx - v2.06 */
5450
5451         case ASTXSIWX:
5452                 return OPVXX1(31, 140, 0) /* stxsiwx - v2.07 */
5453
5454                 /* End of vector scalar instructions */
5455
5456         }
5457
5458         c.ctxt.Diag("unknown storex opcode %v", a)
5459         return 0
5460 }