1 // cmd/9l/optab.c, cmd/9l/asmout.c from Vita Nuova.
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.
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:
19 // The above copyright notice and this permission notice shall be included in
20 // all copies or substantial portions of the Software.
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
42 // ctxt9 holds state while assembling a single function.
43 // Each function gets a fresh ctxt9.
44 // This allows for multiple functions to be safely concurrently assembled.
54 // Instruction layout.
58 funcAlignMask = funcAlign - 1
71 type_ int8 // cases in asmout below. E.g., 44 = st r,(ra+rb); 45 = ld (ra+rb), r
76 // This optab contains a list of opcodes with the operand
77 // combinations that are implemented. Not all opcodes are in this
78 // table, but are added later in buildop by calling opset for those
79 // opcodes which allow the same operand combinations as an opcode
80 // already in the table.
82 // The type field in the Optabl identifies the case in asmout where
83 // the instruction word is assembled.
85 {obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
86 {obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
87 {obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
88 {obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
90 {AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0},
91 {AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
92 {AMOVBZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
93 {AMOVW, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
94 {AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
95 {AADD, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
96 {AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
97 {AADD, C_SCON, C_REG, C_NONE, C_REG, 4, 4, 0},
98 {AADD, C_SCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
99 {AADD, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
100 {AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
101 {AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0},
102 {AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
103 {AADD, C_ANDCON, C_REG, C_NONE, C_REG, 22, 8, 0},
104 {AADD, C_ANDCON, C_NONE, C_NONE, C_REG, 22, 8, 0},
105 {AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
106 {AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
107 {AADDIS, C_ADDCON, C_REG, C_NONE, C_REG, 20, 4, 0},
108 {AADDIS, C_ADDCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
109 {AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
110 {AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
111 {AADDC, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
112 {AADDC, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
113 {AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
114 {AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
115 {AAND, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, no literal */
116 {AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
117 {AANDCC, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
118 {AANDCC, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
119 {AANDCC, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
120 {AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
121 {AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
122 {AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
123 {AANDCC, C_ADDCON, C_NONE, C_NONE, C_REG, 23, 8, 0},
124 {AANDCC, C_ADDCON, C_REG, C_NONE, C_REG, 23, 8, 0},
125 {AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
126 {AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
127 {AANDISCC, C_ANDCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
128 {AANDISCC, C_ANDCON, C_REG, C_NONE, C_REG, 59, 4, 0},
129 {AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
130 {AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
131 {AMULLW, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
132 {AMULLW, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
133 {AMULLW, C_ANDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
134 {AMULLW, C_ANDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
135 {AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
136 {AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
137 {ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0},
138 {ASUBC, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
139 {ASUBC, C_REG, C_NONE, C_ADDCON, C_REG, 27, 4, 0},
140 {ASUBC, C_REG, C_NONE, C_LCON, C_REG, 28, 12, 0},
141 {AOR, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, literal not cc (or/xor) */
142 {AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
143 {AOR, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
144 {AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
145 {AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
146 {AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
147 {AOR, C_ADDCON, C_NONE, C_NONE, C_REG, 23, 8, 0},
148 {AOR, C_ADDCON, C_REG, C_NONE, C_REG, 23, 8, 0},
149 {AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
150 {AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
151 {AORIS, C_ANDCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
152 {AORIS, C_ANDCON, C_REG, C_NONE, C_REG, 59, 4, 0},
153 {ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */
154 {ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
155 {ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, /* op r2[,r1],r3 */
156 {ASUB, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
157 {ASLW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
158 {ASLW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
159 {ASLD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
160 {ASLD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
161 {ASLD, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0},
162 {ASLD, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0},
163 {ASLW, C_SCON, C_REG, C_NONE, C_REG, 57, 4, 0},
164 {ASLW, C_SCON, C_NONE, C_NONE, C_REG, 57, 4, 0},
165 {ASRAW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
166 {ASRAW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
167 {ASRAW, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
168 {ASRAW, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
169 {ASRAD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
170 {ASRAD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
171 {ASRAD, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
172 {ASRAD, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
173 {ARLWMI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0},
174 {ARLWMI, C_REG, C_REG, C_LCON, C_REG, 63, 4, 0},
175 {ARLDMI, C_SCON, C_REG, C_LCON, C_REG, 30, 4, 0},
176 {ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
177 {ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
178 {ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
179 {ARLDICL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
180 {ARLDICL, C_SCON, C_REG, C_LCON, C_REG, 14, 4, 0},
181 {ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 4, 0},
182 {AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 4, 0},
183 {AFADD, C_FREG, C_FREG, C_NONE, C_FREG, 2, 4, 0},
184 {AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
185 {AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 4, 0},
186 {AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
187 {AFMADD, C_FREG, C_FREG, C_FREG, C_FREG, 34, 4, 0},
188 {AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 4, 0},
189 {AFMUL, C_FREG, C_FREG, C_NONE, C_FREG, 32, 4, 0},
191 /* store, short offset */
192 {AMOVD, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
193 {AMOVW, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
194 {AMOVWZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
195 {AMOVBZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
196 {AMOVBZU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
197 {AMOVB, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
198 {AMOVBU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
199 {AMOVD, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
200 {AMOVW, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
201 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
202 {AMOVBZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
203 {AMOVB, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
204 {AMOVD, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
205 {AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
206 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
207 {AMOVBZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
208 {AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
209 {AMOVD, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
210 {AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
211 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
212 {AMOVBZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
213 {AMOVBZU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
214 {AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
215 {AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
217 /* load, short offset */
218 {AMOVD, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
219 {AMOVW, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
220 {AMOVWZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
221 {AMOVBZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
222 {AMOVBZU, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
223 {AMOVB, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
224 {AMOVBU, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
225 {AMOVD, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
226 {AMOVW, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
227 {AMOVWZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
228 {AMOVBZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
229 {AMOVB, C_SEXT, C_NONE, C_NONE, C_REG, 9, 8, REGSB},
230 {AMOVD, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
231 {AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
232 {AMOVWZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
233 {AMOVBZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
234 {AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, 9, 8, REGSP},
235 {AMOVD, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
236 {AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
237 {AMOVWZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
238 {AMOVBZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
239 {AMOVBZU, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
240 {AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
241 {AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
243 /* store, long offset */
244 {AMOVD, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
245 {AMOVW, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
246 {AMOVWZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
247 {AMOVBZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
248 {AMOVB, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
249 {AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
250 {AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
251 {AMOVWZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
252 {AMOVBZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
253 {AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
254 {AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
255 {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
256 {AMOVWZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
257 {AMOVBZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
258 {AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
259 {AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
260 {AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
261 {AMOVWZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
262 {AMOVBZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
263 {AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
265 /* load, long offset */
266 {AMOVD, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
267 {AMOVW, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
268 {AMOVWZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
269 {AMOVBZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
270 {AMOVB, C_LEXT, C_NONE, C_NONE, C_REG, 37, 12, REGSB},
271 {AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
272 {AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
273 {AMOVWZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
274 {AMOVBZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
275 {AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 37, 12, REGSP},
276 {AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
277 {AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
278 {AMOVWZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
279 {AMOVBZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
280 {AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 37, 12, REGZERO},
281 {AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
282 {AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
283 {AMOVWZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
284 {AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
285 {AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 12, 0},
287 {AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 79, 4, 0},
288 {AMOVD, C_TLS_IE, C_NONE, C_NONE, C_REG, 80, 8, 0},
290 {AMOVD, C_GOTADDR, C_NONE, C_NONE, C_REG, 81, 8, 0},
291 {AMOVD, C_TOCADDR, C_NONE, C_NONE, C_REG, 95, 8, 0},
294 {AMOVD, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB},
295 {AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
296 {AMOVD, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
297 {AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
298 {AMOVD, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
299 {AMOVD, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
300 {AMOVW, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
301 {AMOVW, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
302 {AMOVW, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
303 {AMOVW, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
304 {AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
305 {AMOVW, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
306 {AMOVWZ, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
307 {AMOVWZ, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
308 {AMOVWZ, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
309 {AMOVWZ, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
310 {AMOVWZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
311 {AMOVWZ, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
313 /* load unsigned/long constants (TO DO: check) */
314 {AMOVD, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
315 {AMOVD, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
316 {AMOVW, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
317 {AMOVW, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
318 {AMOVWZ, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
319 {AMOVWZ, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
320 {AMOVHBR, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
321 {AMOVHBR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
322 {AMOVHBR, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
323 {AMOVHBR, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
324 {ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0},
325 {ASYSCALL, C_REG, C_NONE, C_NONE, C_NONE, 77, 12, 0},
326 {ASYSCALL, C_SCON, C_NONE, C_NONE, C_NONE, 77, 12, 0},
327 {ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
328 {ABEQ, C_CREG, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
329 {ABR, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0},
330 {ABR, C_NONE, C_NONE, C_NONE, C_LBRAPIC, 11, 8, 0},
331 {ABC, C_SCON, C_REG, C_NONE, C_SBRA, 16, 4, 0},
332 {ABC, C_SCON, C_REG, C_NONE, C_LBRA, 17, 4, 0},
333 {ABR, C_NONE, C_NONE, C_NONE, C_LR, 18, 4, 0},
334 {ABR, C_NONE, C_NONE, C_NONE, C_CTR, 18, 4, 0},
335 {ABR, C_REG, C_NONE, C_NONE, C_CTR, 18, 4, 0},
336 {ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
337 {ABC, C_NONE, C_REG, C_NONE, C_LR, 18, 4, 0},
338 {ABC, C_NONE, C_REG, C_NONE, C_CTR, 18, 4, 0},
339 {ABC, C_SCON, C_REG, C_NONE, C_LR, 18, 4, 0},
340 {ABC, C_SCON, C_REG, C_NONE, C_CTR, 18, 4, 0},
341 {ABC, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
342 {AFMOVD, C_SEXT, C_NONE, C_NONE, C_FREG, 8, 4, REGSB},
343 {AFMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, 8, 4, REGSP},
344 {AFMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, 8, 4, REGZERO},
345 {AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB},
346 {AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP},
347 {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO},
348 {AFMOVD, C_ZCON, C_NONE, C_NONE, C_FREG, 24, 4, 0},
349 {AFMOVD, C_ADDCON, C_NONE, C_NONE, C_FREG, 24, 8, 0},
350 {AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0},
351 {AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
352 {AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
353 {AFMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
354 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
355 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
356 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
357 {AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
358 {AFMOVSX, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0},
359 {AFMOVSX, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0},
360 {AFMOVSX, C_FREG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
361 {AFMOVSX, C_FREG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
362 {AFMOVSZ, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0},
363 {AFMOVSZ, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0},
364 {ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
365 {AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 4, 0},
366 {ADWORD, C_LCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
367 {ADWORD, C_DCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
368 {AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
369 {AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0},
370 {AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0},
371 {AISEL, C_LCON, C_REG, C_REG, C_REG, 84, 4, 0},
372 {AISEL, C_ZCON, C_REG, C_REG, C_REG, 84, 4, 0},
373 {ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
374 {ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0},
375 {AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0},
376 {AREM, C_REG, C_REG, C_NONE, C_REG, 50, 12, 0},
377 {AREMU, C_REG, C_NONE, C_NONE, C_REG, 50, 16, 0},
378 {AREMU, C_REG, C_REG, C_NONE, C_REG, 50, 16, 0},
379 {AREMD, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
380 {AREMD, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
381 {AREMDU, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
382 {AREMDU, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
383 {AMTFSB0, C_SCON, C_NONE, C_NONE, C_NONE, 52, 4, 0},
384 {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_FREG, 53, 4, 0},
385 {AMOVFL, C_FREG, C_NONE, C_NONE, C_FPSCR, 64, 4, 0},
386 {AMOVFL, C_FREG, C_NONE, C_LCON, C_FPSCR, 64, 4, 0},
387 {AMOVFL, C_LCON, C_NONE, C_NONE, C_FPSCR, 65, 4, 0},
388 {AMOVD, C_MSR, C_NONE, C_NONE, C_REG, 54, 4, 0}, /* mfmsr */
389 {AMOVD, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsrd */
390 {AMOVWZ, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsr */
392 /* Other ISA 2.05+ instructions */
393 {APOPCNTD, C_REG, C_NONE, C_NONE, C_REG, 93, 4, 0}, /* population count, x-form */
394 {ACMPB, C_REG, C_REG, C_NONE, C_REG, 92, 4, 0}, /* compare byte, x-form */
395 {ACMPEQB, C_REG, C_REG, C_NONE, C_CREG, 92, 4, 0}, /* compare equal byte, x-form, ISA 3.0 */
396 {ACMPEQB, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
397 {AFTDIV, C_FREG, C_FREG, C_NONE, C_SCON, 92, 4, 0}, /* floating test for sw divide, x-form */
398 {AFTSQRT, C_FREG, C_NONE, C_NONE, C_SCON, 93, 4, 0}, /* floating test for sw square root, x-form */
399 {ACOPY, C_REG, C_NONE, C_NONE, C_REG, 92, 4, 0}, /* copy/paste facility, x-form */
400 {ADARN, C_SCON, C_NONE, C_NONE, C_REG, 92, 4, 0}, /* deliver random number, x-form */
401 {ALDMX, C_SOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, /* load doubleword monitored, x-form */
402 {AMADDHD, C_REG, C_REG, C_REG, C_REG, 83, 4, 0}, /* multiply-add high/low doubleword, va-form */
403 {AADDEX, C_REG, C_REG, C_SCON, C_REG, 94, 4, 0}, /* add extended using alternate carry, z23-form */
405 /* Vector instructions */
408 {ALV, C_SOREG, C_NONE, C_NONE, C_VREG, 45, 4, 0}, /* vector load, x-form */
411 {ASTV, C_VREG, C_NONE, C_NONE, C_SOREG, 44, 4, 0}, /* vector store, x-form */
414 {AVAND, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector and, vx-form */
415 {AVOR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector or, vx-form */
418 {AVADDUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned modulo, vx-form */
419 {AVADDCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add & write carry unsigned, vx-form */
420 {AVADDUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned saturate, vx-form */
421 {AVADDSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add signed saturate, vx-form */
422 {AVADDE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector add extended, va-form */
424 /* Vector subtract */
425 {AVSUBUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned modulo, vx-form */
426 {AVSUBCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract & write carry unsigned, vx-form */
427 {AVSUBUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned saturate, vx-form */
428 {AVSUBSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract signed saturate, vx-form */
429 {AVSUBE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector subtract extended, va-form */
431 /* Vector multiply */
432 {AVMULESB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 9}, /* vector multiply, vx-form */
433 {AVPMSUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector polynomial multiply & sum, vx-form */
434 {AVMSUMUDM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector multiply-sum, va-form */
437 {AVR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector rotate, vx-form */
440 {AVS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector shift, vx-form */
441 {AVSA, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector shift algebraic, vx-form */
442 {AVSOI, C_ANDCON, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector shift by octet immediate, va-form */
445 {AVCLZ, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector count leading zeros, vx-form */
446 {AVPOPCNT, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector population count, vx-form */
449 {AVCMPEQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare equal, vc-form */
450 {AVCMPGT, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare greater than, vc-form */
451 {AVCMPNEZB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare not equal, vx-form */
454 {AVMRGOW, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector merge odd word, vx-form */
457 {AVPERM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector permute, va-form */
459 /* Vector bit permute */
460 {AVBPERMQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector bit permute, vx-form */
463 {AVSEL, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector select, va-form */
466 {AVSPLTB, C_SCON, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector splat, vx-form */
467 {AVSPLTB, C_ADDCON, C_VREG, C_NONE, C_VREG, 82, 4, 0},
468 {AVSPLTISB, C_SCON, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector splat immediate, vx-form */
469 {AVSPLTISB, C_ADDCON, C_NONE, C_NONE, C_VREG, 82, 4, 0},
472 {AVCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES cipher, vx-form */
473 {AVNCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES inverse cipher, vx-form */
474 {AVSBOX, C_VREG, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector AES subbytes, vx-form */
477 {AVSHASIGMA, C_ANDCON, C_VREG, C_ANDCON, C_VREG, 82, 4, 0}, /* vector SHA sigma, vx-form */
479 /* VSX vector load */
480 {ALXVD2X, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx vector load, xx1-form */
481 {ALXV, C_SOREG, C_NONE, C_NONE, C_VSREG, 96, 4, 0}, /* vsx vector load, dq-form */
483 /* VSX vector store */
484 {ASTXVD2X, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx vector store, xx1-form */
485 {ASTXV, C_VSREG, C_NONE, C_NONE, C_SOREG, 97, 4, 0}, /* vsx vector store, dq-form */
487 /* VSX scalar load */
488 {ALXSDX, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar load, xx1-form */
490 /* VSX scalar store */
491 {ASTXSDX, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar store, xx1-form */
493 /* VSX scalar as integer load */
494 {ALXSIWAX, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar as integer load, xx1-form */
496 /* VSX scalar store as integer */
497 {ASTXSIWX, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar as integer store, xx1-form */
499 /* VSX move from VSR */
500 {AMFVSRD, C_VSREG, C_NONE, C_NONE, C_REG, 88, 4, 0}, /* vsx move from vsr, xx1-form */
501 {AMFVSRD, C_FREG, C_NONE, C_NONE, C_REG, 88, 4, 0},
502 {AMFVSRD, C_VREG, C_NONE, C_NONE, C_REG, 88, 4, 0},
504 /* VSX move to VSR */
505 {AMTVSRD, C_REG, C_NONE, C_NONE, C_VSREG, 88, 4, 0}, /* vsx move to vsr, xx1-form */
506 {AMTVSRD, C_REG, C_REG, C_NONE, C_VSREG, 88, 4, 0},
507 {AMTVSRD, C_REG, C_NONE, C_NONE, C_FREG, 88, 4, 0},
508 {AMTVSRD, C_REG, C_NONE, C_NONE, C_VREG, 88, 4, 0},
511 {AXXLAND, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx and, xx3-form */
512 {AXXLOR, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx or, xx3-form */
515 {AXXSEL, C_VSREG, C_VSREG, C_VSREG, C_VSREG, 91, 4, 0}, /* vsx select, xx4-form */
518 {AXXMRGHW, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx merge, xx3-form */
521 {AXXSPLTW, C_VSREG, C_NONE, C_SCON, C_VSREG, 89, 4, 0}, /* vsx splat, xx2-form */
524 {AXXPERM, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx permute, xx3-form */
527 {AXXSLDWI, C_VSREG, C_VSREG, C_SCON, C_VSREG, 90, 4, 0}, /* vsx shift immediate, xx3-form */
529 /* VSX scalar FP-FP conversion */
530 {AXSCVDPSP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-fp conversion, xx2-form */
532 /* VSX vector FP-FP conversion */
533 {AXVCVDPSP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-fp conversion, xx2-form */
535 /* VSX scalar FP-integer conversion */
536 {AXSCVDPSXDS, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-integer conversion, xx2-form */
538 /* VSX scalar integer-FP conversion */
539 {AXSCVSXDDP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar integer-fp conversion, xx2-form */
541 /* VSX vector FP-integer conversion */
542 {AXVCVDPSXDS, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-integer conversion, xx2-form */
544 /* VSX vector integer-FP conversion */
545 {AXVCVSXDDP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector integer-fp conversion, xx2-form */
547 /* 64-bit special registers */
548 {AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
549 {AMOVD, C_REG, C_NONE, C_NONE, C_LR, 66, 4, 0},
550 {AMOVD, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
551 {AMOVD, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
552 {AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
553 {AMOVD, C_LR, C_NONE, C_NONE, C_REG, 66, 4, 0},
554 {AMOVD, C_CTR, C_NONE, C_NONE, C_REG, 66, 4, 0},
555 {AMOVD, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
557 /* 32-bit special registers (gloss over sign-extension or not?) */
558 {AMOVW, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
559 {AMOVW, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
560 {AMOVW, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
561 {AMOVW, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
562 {AMOVW, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
563 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
564 {AMOVWZ, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
565 {AMOVWZ, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
566 {AMOVWZ, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
567 {AMOVWZ, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
568 {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_CREG, 73, 4, 0},
569 {AMOVFL, C_CREG, C_NONE, C_NONE, C_CREG, 67, 4, 0},
570 {AMOVW, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
571 {AMOVWZ, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
572 {AMOVFL, C_REG, C_NONE, C_NONE, C_LCON, 69, 4, 0},
573 {AMOVFL, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
574 {AMOVW, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
575 {AMOVWZ, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
576 {ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
577 {ACMP, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
578 {ACMP, C_REG, C_NONE, C_NONE, C_ADDCON, 71, 4, 0},
579 {ACMP, C_REG, C_REG, C_NONE, C_ADDCON, 71, 4, 0},
580 {ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
581 {ACMPU, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
582 {ACMPU, C_REG, C_NONE, C_NONE, C_ANDCON, 71, 4, 0},
583 {ACMPU, C_REG, C_REG, C_NONE, C_ANDCON, 71, 4, 0},
584 {AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 4, 0},
585 {AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 4, 0},
586 {ATW, C_LCON, C_REG, C_NONE, C_REG, 60, 4, 0},
587 {ATW, C_LCON, C_REG, C_NONE, C_ADDCON, 61, 4, 0},
588 {ADCBF, C_ZOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
589 {ADCBF, C_SOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
590 {ADCBF, C_ZOREG, C_REG, C_NONE, C_SCON, 43, 4, 0},
591 {ADCBF, C_SOREG, C_NONE, C_NONE, C_SCON, 43, 4, 0},
592 {AECOWX, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
593 {AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
594 {AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
595 {AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
596 {ALDAR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
597 {ALDAR, C_ZOREG, C_NONE, C_ANDCON, C_REG, 45, 4, 0},
598 {AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
599 {ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},
600 {ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0},
601 {ASLBMFEE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
602 {ASLBMTE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
603 {ASTSW, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
604 {ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},
605 {ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
606 {ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
607 {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
608 {obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
609 {obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
610 {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
611 {obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
612 {obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
613 {obj.APCALIGN, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0}, // align code
615 {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},
618 var oprange [ALAST & obj.AMask][]Optab
620 var xcmp [C_NCLASS][C_NCLASS]bool
622 // padding bytes to add to align code as requested
623 func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int {
645 // The default function alignment is 16, but
646 // if 32 byte alignment is requested then the
647 // function needs to be aligned to 32.
648 if cursym.Func.Align < 32 {
649 cursym.Func.Align = 32
652 ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a)
657 func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
658 p := cursym.Func.Text
659 if p == nil || p.Link == nil { // handle external functions and ELF section symbols
663 if oprange[AANDN&obj.AMask] == nil {
664 ctxt.Diag("ppc64 ops not initialized, call ppc64.buildop first")
667 c := ctxt9{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset)}
674 for p = p.Link; p != nil; p = p.Link {
679 if p.As == obj.APCALIGN {
680 a := c.vregoff(&p.From)
681 m = addpad(pc, a, ctxt, cursym)
683 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
684 ctxt.Diag("zero-width instruction\n%v", p)
695 * if any procedure is large enough to
696 * generate a large SBRA branch, then
697 * generate extra passes putting branches
698 * around jmps to fix. this is rare.
707 for p = c.cursym.Func.Text.Link; p != nil; p = p.Link {
711 // very large conditional branches
712 if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
713 otxt = p.Pcond.Pc - pc
714 if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
719 q.To.Type = obj.TYPE_BRANCH
726 q.To.Type = obj.TYPE_BRANCH
727 q.Pcond = q.Link.Link
737 if p.As == obj.APCALIGN {
738 a := c.vregoff(&p.From)
739 m = addpad(pc, a, ctxt, cursym)
741 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
742 ctxt.Diag("zero-width instruction\n%v", p)
757 * lay out the code, emitting code and data relocations.
760 c.cursym.Grow(c.cursym.Size)
765 for p := c.cursym.Func.Text.Link; p != nil; p = p.Link {
768 if int(o.size) > 4*len(out) {
769 log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)
771 // asmout is not set up to add large amounts of padding
772 if o.type_ == 0 && p.As == obj.APCALIGN {
773 pad := LOP_RRR(OP_OR, REGZERO, REGZERO, REGZERO)
774 aln := c.vregoff(&p.From)
775 v := addpad(p.Pc, aln, c.ctxt, c.cursym)
777 // Same padding instruction for all
778 for i = 0; i < int32(v/4); i++ {
779 c.ctxt.Arch.ByteOrder.PutUint32(bp, pad)
784 c.asmout(p, o, out[:])
785 for i = 0; i < int32(o.size/4); i++ {
786 c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
793 func isint32(v int64) bool {
794 return int64(int32(v)) == v
797 func isuint32(v uint64) bool {
798 return uint64(uint32(v)) == v
801 func (c *ctxt9) aclass(a *obj.Addr) int {
807 if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
810 if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
813 if REG_V0 <= a.Reg && a.Reg <= REG_V31 {
816 if REG_VS0 <= a.Reg && a.Reg <= REG_VS63 {
819 if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR {
822 if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
837 if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
840 if a.Reg == REG_FPSCR {
843 if a.Reg == REG_MSR {
850 case obj.NAME_EXTERN,
855 c.instoffset = a.Offset
856 if a.Sym != nil { // use relocation
857 if a.Sym.Type == objabi.STLSBSS {
858 if c.ctxt.Flag_shared {
868 case obj.NAME_GOTREF:
871 case obj.NAME_TOCREF:
875 c.instoffset = int64(c.autosize) + a.Offset
876 if c.instoffset >= -BIG && c.instoffset < BIG {
882 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
883 if c.instoffset >= -BIG && c.instoffset < BIG {
889 c.instoffset = a.Offset
890 if c.instoffset == 0 {
893 if c.instoffset >= -BIG && c.instoffset < BIG {
901 case obj.TYPE_TEXTSIZE:
904 case obj.TYPE_FCONST:
905 // The only cases where FCONST will occur are with float64 +/- 0.
906 // All other float constants are generated in memory.
907 f64 := a.Val.(float64)
909 if math.Signbit(f64) {
914 log.Fatalf("Unexpected nonzero FCONST operand %v", a)
920 c.instoffset = a.Offset
922 if -BIG <= c.instoffset && c.instoffset <= BIG {
925 if isint32(c.instoffset) {
931 case obj.NAME_EXTERN,
938 c.instoffset = a.Offset
940 /* not sure why this barfs */
944 c.instoffset = int64(c.autosize) + a.Offset
945 if c.instoffset >= -BIG && c.instoffset < BIG {
951 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
952 if c.instoffset >= -BIG && c.instoffset < BIG {
961 if c.instoffset >= 0 {
962 if c.instoffset == 0 {
965 if c.instoffset <= 0x7fff {
968 if c.instoffset <= 0xffff {
971 if c.instoffset&0xffff == 0 && isuint32(uint64(c.instoffset)) { /* && (instoffset & (1<<31)) == 0) */
974 if isint32(c.instoffset) || isuint32(uint64(c.instoffset)) {
980 if c.instoffset >= -0x8000 {
983 if c.instoffset&0xffff == 0 && isint32(c.instoffset) {
986 if isint32(c.instoffset) {
991 case obj.TYPE_BRANCH:
992 if a.Sym != nil && c.ctxt.Flag_dynlink {
1001 func prasm(p *obj.Prog) {
1002 fmt.Printf("%v\n", p)
1005 func (c *ctxt9) oplook(p *obj.Prog) *Optab {
1010 a1 = int(p.From.Class)
1012 a1 = c.aclass(&p.From) + 1
1013 p.From.Class = int8(a1)
1018 if p.GetFrom3() != nil {
1019 a3 = int(p.GetFrom3().Class)
1021 a3 = c.aclass(p.GetFrom3()) + 1
1022 p.GetFrom3().Class = int8(a3)
1027 a4 := int(p.To.Class)
1029 a4 = c.aclass(&p.To) + 1
1030 p.To.Class = int8(a4)
1036 if REG_R0 <= p.Reg && p.Reg <= REG_R31 {
1038 } else if REG_V0 <= p.Reg && p.Reg <= REG_V31 {
1040 } else if REG_VS0 <= p.Reg && p.Reg <= REG_VS63 {
1042 } else if REG_F0 <= p.Reg && p.Reg <= REG_F31 {
1047 // c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4)
1048 ops := oprange[p.As&obj.AMask]
1052 for i := range ops {
1054 if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] {
1055 p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
1060 c.ctxt.Diag("illegal combination %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4))
1068 func cmp(a int, b int) bool {
1074 if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {
1079 if b == C_ZCON || b == C_SCON {
1084 if b == C_ZCON || b == C_SCON {
1089 if b == C_LR || b == C_XER || b == C_CTR {
1125 return r0iszero != 0 /*TypeKind(100016)*/
1129 if b == C_ZOREG || b == C_SOREG {
1147 func (x ocmp) Len() int {
1151 func (x ocmp) Swap(i, j int) {
1152 x[i], x[j] = x[j], x[i]
1155 // Used when sorting the optab. Sorting is
1156 // done in a way so that the best choice of
1157 // opcode/operand combination is considered first.
1158 func (x ocmp) Less(i, j int) bool {
1161 n := int(p1.as) - int(p2.as)
1166 // Consider those that generate fewer
1167 // instructions first.
1168 n = int(p1.size) - int(p2.size)
1172 // operand order should match
1173 // better choices first
1174 n = int(p1.a1) - int(p2.a1)
1178 n = int(p1.a2) - int(p2.a2)
1182 n = int(p1.a3) - int(p2.a3)
1186 n = int(p1.a4) - int(p2.a4)
1193 // Add an entry to the opcode table for
1194 // a new opcode b0 with the same operand combinations
1196 func opset(a, b0 obj.As) {
1197 oprange[a&obj.AMask] = oprange[b0]
1200 // Build the opcode table
1201 func buildop(ctxt *obj.Link) {
1202 if oprange[AANDN&obj.AMask] != nil {
1203 // Already initialized; stop now.
1204 // This happens in the cmd/asm tests,
1205 // each of which re-initializes the arch.
1211 for i := 0; i < C_NCLASS; i++ {
1212 for n = 0; n < C_NCLASS; n++ {
1218 for n = 0; optab[n].as != obj.AXXX; n++ {
1220 sort.Sort(ocmp(optab[:n]))
1221 for i := 0; i < n; i++ {
1225 for optab[i].as == r {
1228 oprange[r0] = optab[start:i]
1233 ctxt.Diag("unknown op in build: %v", r)
1234 log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r)
1236 case ADCBF: /* unary indexed: op (b+a); op (b) */
1245 case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
1251 case AREM: /* macro */
1272 opset(AREMDUVCC, r0)
1274 case ADIVW: /* op Rb[,Ra],Rd */
1279 opset(AMULHWUCC, r0)
1281 opset(AMULLWVCC, r0)
1289 opset(ADIVWUVCC, r0)
1310 opset(AMULHDUCC, r0)
1313 opset(AMULLDVCC, r0)
1320 opset(ADIVDEUCC, r0)
1325 opset(ADIVDUVCC, r0)
1328 case APOPCNTD: /* popcntd, popcntw, popcntb, cnttzw, cnttzd */
1332 opset(ACNTTZWCC, r0)
1334 opset(ACNTTZDCC, r0)
1336 case ACOPY: /* copy, paste. */
1339 case AMADDHD: /* maddhd, maddhdu, maddld */
1343 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
1347 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
1356 case ALV: /* lvebx, lvehx, lvewx, lvx, lvxl, lvsl, lvsr */
1365 case ASTV: /* stvebx, stvehx, stvewx, stvx, stvxl */
1372 case AVAND: /* vand, vandc, vnand */
1377 case AVMRGOW: /* vmrgew, vmrgow */
1380 case AVOR: /* vor, vorc, vxor, vnor, veqv */
1387 case AVADDUM: /* vaddubm, vadduhm, vadduwm, vaddudm, vadduqm */
1394 case AVADDCU: /* vaddcuq, vaddcuw */
1398 case AVADDUS: /* vaddubs, vadduhs, vadduws */
1403 case AVADDSS: /* vaddsbs, vaddshs, vaddsws */
1408 case AVADDE: /* vaddeuqm, vaddecuq */
1409 opset(AVADDEUQM, r0)
1410 opset(AVADDECUQ, r0)
1412 case AVSUBUM: /* vsububm, vsubuhm, vsubuwm, vsubudm, vsubuqm */
1419 case AVSUBCU: /* vsubcuq, vsubcuw */
1423 case AVSUBUS: /* vsububs, vsubuhs, vsubuws */
1428 case AVSUBSS: /* vsubsbs, vsubshs, vsubsws */
1433 case AVSUBE: /* vsubeuqm, vsubecuq */
1434 opset(AVSUBEUQM, r0)
1435 opset(AVSUBECUQ, r0)
1437 case AVMULESB: /* vmulesb, vmulosb, vmuleub, vmuloub, vmulosh, vmulouh, vmulesw, vmulosw, vmuleuw, vmulouw, vmuluwm */
1450 case AVPMSUM: /* vpmsumb, vpmsumh, vpmsumw, vpmsumd */
1456 case AVR: /* vrlb, vrlh, vrlw, vrld */
1462 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 */
1476 case AVSA: /* vsrab, vsrah, vsraw, vsrad */
1482 case AVSOI: /* vsldoi */
1485 case AVCLZ: /* vclzb, vclzh, vclzw, vclzd */
1491 case AVPOPCNT: /* vpopcntb, vpopcnth, vpopcntw, vpopcntd */
1492 opset(AVPOPCNTB, r0)
1493 opset(AVPOPCNTH, r0)
1494 opset(AVPOPCNTW, r0)
1495 opset(AVPOPCNTD, r0)
1497 case AVCMPEQ: /* vcmpequb[.], vcmpequh[.], vcmpequw[.], vcmpequd[.] */
1498 opset(AVCMPEQUB, r0)
1499 opset(AVCMPEQUBCC, r0)
1500 opset(AVCMPEQUH, r0)
1501 opset(AVCMPEQUHCC, r0)
1502 opset(AVCMPEQUW, r0)
1503 opset(AVCMPEQUWCC, r0)
1504 opset(AVCMPEQUD, r0)
1505 opset(AVCMPEQUDCC, r0)
1507 case AVCMPGT: /* vcmpgt[u,s]b[.], vcmpgt[u,s]h[.], vcmpgt[u,s]w[.], vcmpgt[u,s]d[.] */
1508 opset(AVCMPGTUB, r0)
1509 opset(AVCMPGTUBCC, r0)
1510 opset(AVCMPGTUH, r0)
1511 opset(AVCMPGTUHCC, r0)
1512 opset(AVCMPGTUW, r0)
1513 opset(AVCMPGTUWCC, r0)
1514 opset(AVCMPGTUD, r0)
1515 opset(AVCMPGTUDCC, r0)
1516 opset(AVCMPGTSB, r0)
1517 opset(AVCMPGTSBCC, r0)
1518 opset(AVCMPGTSH, r0)
1519 opset(AVCMPGTSHCC, r0)
1520 opset(AVCMPGTSW, r0)
1521 opset(AVCMPGTSWCC, r0)
1522 opset(AVCMPGTSD, r0)
1523 opset(AVCMPGTSDCC, r0)
1525 case AVCMPNEZB: /* vcmpnezb[.] */
1526 opset(AVCMPNEZBCC, r0)
1528 case AVPERM: /* vperm */
1529 opset(AVPERMXOR, r0)
1531 case AVBPERMQ: /* vbpermq, vbpermd */
1534 case AVSEL: /* vsel */
1537 case AVSPLTB: /* vspltb, vsplth, vspltw */
1541 case AVSPLTISB: /* vspltisb, vspltish, vspltisw */
1542 opset(AVSPLTISH, r0)
1543 opset(AVSPLTISW, r0)
1545 case AVCIPH: /* vcipher, vcipherlast */
1547 opset(AVCIPHERLAST, r0)
1549 case AVNCIPH: /* vncipher, vncipherlast */
1550 opset(AVNCIPHER, r0)
1551 opset(AVNCIPHERLAST, r0)
1553 case AVSBOX: /* vsbox */
1556 case AVSHASIGMA: /* vshasigmaw, vshasigmad */
1557 opset(AVSHASIGMAW, r0)
1558 opset(AVSHASIGMAD, r0)
1560 case ALXVD2X: /* lxvd2x, lxvdsx, lxvw4x, lxvh8x, lxvb16x */
1566 case ALXV: /* lxv */
1569 case ASTXVD2X: /* stxvd2x, stxvdsx, stxvw4x, stxvh8x, stxvb16x */
1572 opset(ASTXVB16X, r0)
1574 case ASTXV: /* stxv */
1577 case ALXSDX: /* lxsdx */
1580 case ASTXSDX: /* stxsdx */
1583 case ALXSIWAX: /* lxsiwax, lxsiwzx */
1586 case ASTXSIWX: /* stxsiwx */
1589 case AMFVSRD: /* mfvsrd, mfvsrwz (and extended mnemonics), mfvsrld */
1595 case AMTVSRD: /* mtvsrd, mtvsrwa, mtvsrwz (and extended mnemonics), mtvsrdd, mtvsrws */
1603 case AXXLAND: /* xxland, xxlandc, xxleqv, xxlnand */
1608 case AXXLOR: /* xxlorc, xxlnor, xxlor, xxlxor */
1614 case AXXSEL: /* xxsel */
1617 case AXXMRGHW: /* xxmrghw, xxmrglw */
1620 case AXXSPLTW: /* xxspltw */
1623 case AXXPERM: /* xxpermdi */
1626 case AXXSLDWI: /* xxsldwi */
1627 opset(AXXPERMDI, r0)
1630 case AXSCVDPSP: /* xscvdpsp, xscvspdp, xscvdpspn, xscvspdpn */
1631 opset(AXSCVSPDP, r0)
1632 opset(AXSCVDPSPN, r0)
1633 opset(AXSCVSPDPN, r0)
1635 case AXVCVDPSP: /* xvcvdpsp, xvcvspdp */
1636 opset(AXVCVSPDP, r0)
1638 case AXSCVDPSXDS: /* xscvdpsxds, xscvdpsxws, xscvdpuxds, xscvdpuxws */
1639 opset(AXSCVDPSXWS, r0)
1640 opset(AXSCVDPUXDS, r0)
1641 opset(AXSCVDPUXWS, r0)
1643 case AXSCVSXDDP: /* xscvsxddp, xscvuxddp, xscvsxdsp, xscvuxdsp */
1644 opset(AXSCVUXDDP, r0)
1645 opset(AXSCVSXDSP, r0)
1646 opset(AXSCVUXDSP, r0)
1648 case AXVCVDPSXDS: /* xvcvdpsxds, xvcvdpsxws, xvcvdpuxds, xvcvdpuxws, xvcvspsxds, xvcvspsxws, xvcvspuxds, xvcvspuxws */
1649 opset(AXVCVDPSXDS, r0)
1650 opset(AXVCVDPSXWS, r0)
1651 opset(AXVCVDPUXDS, r0)
1652 opset(AXVCVDPUXWS, r0)
1653 opset(AXVCVSPSXDS, r0)
1654 opset(AXVCVSPSXWS, r0)
1655 opset(AXVCVSPUXDS, r0)
1656 opset(AXVCVSPUXWS, r0)
1658 case AXVCVSXDDP: /* xvcvsxddp, xvcvsxwdp, xvcvuxddp, xvcvuxwdp, xvcvsxdsp, xvcvsxwsp, xvcvuxdsp, xvcvuxwsp */
1659 opset(AXVCVSXWDP, r0)
1660 opset(AXVCVUXDDP, r0)
1661 opset(AXVCVUXWDP, r0)
1662 opset(AXVCVSXDSP, r0)
1663 opset(AXVCVSXWSP, r0)
1664 opset(AXVCVUXDSP, r0)
1665 opset(AXVCVUXWSP, r0)
1667 case AAND: /* logical op Rb,Rs,Ra; no literal */
1681 case AADDME: /* op Ra, Rd */
1685 opset(AADDMEVCC, r0)
1689 opset(AADDZEVCC, r0)
1693 opset(ASUBMEVCC, r0)
1697 opset(ASUBZEVCC, r0)
1717 case AEXTSB: /* op Rs, Ra */
1723 opset(ACNTLZWCC, r0)
1727 opset(ACNTLZDCC, r0)
1729 case AFABS: /* fop [s,]d */
1741 opset(AFCTIWZCC, r0)
1745 opset(AFCTIDZCC, r0)
1749 opset(AFCFIDUCC, r0)
1751 opset(AFCFIDSCC, r0)
1763 opset(AFRSQRTECC, r0)
1767 opset(AFSQRTSCC, r0)
1774 opset(AFCPSGNCC, r0)
1787 opset(AFMADDSCC, r0)
1791 opset(AFMSUBSCC, r0)
1793 opset(AFNMADDCC, r0)
1795 opset(AFNMADDSCC, r0)
1797 opset(AFNMSUBCC, r0)
1799 opset(AFNMSUBSCC, r0)
1815 opset(AMTFSB0CC, r0)
1817 opset(AMTFSB1CC, r0)
1819 case ANEG: /* op [Ra,] Rd */
1825 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,R */
1828 case AORIS: /* oris/xoris $uimm,Rs,Ra */
1843 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1846 case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1849 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
1877 opset(ARLDIMICC, r0)
1888 opset(ARLDICLCC, r0)
1890 opset(ARLDICRCC, r0)
1903 case ASYSCALL: /* just the op; flow of control */
1944 AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */
1950 /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
1951 AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals */
1952 AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
1953 AMOVB, /* macro: move byte with sign extension */
1954 AMOVBU, /* macro: move byte with sign extension & update */
1957 /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
1958 ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */
1982 func OPVXX1(o uint32, xo uint32, oe uint32) uint32 {
1983 return o<<26 | xo<<1 | oe<<11
1986 func OPVXX2(o uint32, xo uint32, oe uint32) uint32 {
1987 return o<<26 | xo<<2 | oe<<11
1990 func OPVXX3(o uint32, xo uint32, oe uint32) uint32 {
1991 return o<<26 | xo<<3 | oe<<11
1994 func OPVXX4(o uint32, xo uint32, oe uint32) uint32 {
1995 return o<<26 | xo<<4 | oe<<11
1998 func OPDQ(o uint32, xo uint32, oe uint32) uint32 {
1999 return o<<26 | xo | oe<<4
2002 func OPVX(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2003 return o<<26 | xo | oe<<11 | rc&1
2006 func OPVC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2007 return o<<26 | xo | oe<<11 | (rc&1)<<10
2010 func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2011 return o<<26 | xo<<1 | oe<<10 | rc&1
2014 func OPCC(o uint32, xo uint32, rc uint32) uint32 {
2015 return OPVCC(o, xo, 0, rc)
2018 func OP(o uint32, xo uint32) uint32 {
2019 return OPVCC(o, xo, 0, 0)
2022 /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
2023 func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
2024 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
2027 /* VX-form 2-register operands, r/none/r */
2028 func AOP_RR(op uint32, d uint32, a uint32) uint32 {
2029 return op | (d&31)<<21 | (a&31)<<11
2032 /* VA-form 4-register operands */
2033 func AOP_RRRR(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2034 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&31)<<6
2037 func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2038 return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF
2041 /* VX-form 2-register + UIM operands */
2042 func AOP_VIRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2043 return op | (d&31)<<21 | (simm&0xFFFF)<<16 | (a&31)<<11
2046 /* VX-form 2-register + ST + SIX operands */
2047 func AOP_IIRR(op uint32, d uint32, a uint32, sbit uint32, simm uint32) uint32 {
2048 return op | (d&31)<<21 | (a&31)<<16 | (sbit&1)<<15 | (simm&0xF)<<11
2051 /* VA-form 3-register + SHB operands */
2052 func AOP_IRRR(op uint32, d uint32, a uint32, b uint32, simm uint32) uint32 {
2053 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (simm&0xF)<<6
2056 /* VX-form 1-register + SIM operands */
2057 func AOP_IR(op uint32, d uint32, simm uint32) uint32 {
2058 return op | (d&31)<<21 | (simm&31)<<16
2061 /* XX1-form 3-register operands, 1 VSR operand */
2062 func AOP_XX1(op uint32, d uint32, a uint32, b uint32) uint32 {
2063 /* For the XX-form encodings, we need the VSX register number to be exactly */
2064 /* between 0-63, so we can properly set the rightmost bits. */
2066 return op | (r&31)<<21 | (a&31)<<16 | (b&31)<<11 | (r&32)>>5
2069 /* XX2-form 3-register operands, 2 VSR operands */
2070 func AOP_XX2(op uint32, d uint32, a uint32, b uint32) uint32 {
2073 return op | (xt&31)<<21 | (a&3)<<16 | (xb&31)<<11 | (xb&32)>>4 | (xt&32)>>5
2076 /* XX3-form 3 VSR operands */
2077 func AOP_XX3(op uint32, d uint32, a uint32, b uint32) uint32 {
2081 return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2084 /* XX3-form 3 VSR operands + immediate */
2085 func AOP_XX3I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2089 return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (c&3)<<8 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2092 /* XX4-form, 4 VSR operands */
2093 func AOP_XX4(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2098 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
2101 /* DQ-form, VSR register, register + offset operands */
2102 func AOP_DQ(op uint32, d uint32, a uint32, b uint32) uint32 {
2103 /* For the DQ-form encodings, we need the VSX register number to be exactly */
2104 /* between 0-63, so we can properly set the SX bit. */
2106 /* The EA for this instruction form is (RA) + DQ << 4, where DQ is a 12-bit signed integer. */
2107 /* In order to match the output of the GNU objdump (and make the usage in Go asm easier), the */
2108 /* instruction is called using the sign extended value (i.e. a valid offset would be -32752 or 32752, */
2109 /* not -2047 or 2047), so 'b' needs to be adjusted to the expected 12-bit DQ value. Bear in mind that */
2110 /* bits 0 to 3 in 'dq' need to be zero, otherwise this will generate an illegal instruction. */
2111 /* If in doubt how this instruction form is encoded, refer to ISA 3.0b, pages 492 and 507. */
2113 return op | (r&31)<<21 | (a&31)<<16 | (dq&4095)<<4 | (r&32)>>2
2116 /* Z23-form, 3-register operands + CY field */
2117 func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2118 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<7
2121 /* X-form, 3-register operands + EH field */
2122 func AOP_RRRI(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2123 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c & 1)
2126 func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
2127 return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
2130 func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 {
2131 return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF
2134 func OP_BR(op uint32, li uint32, aa uint32) uint32 {
2135 return op | li&0x03FFFFFC | aa<<1
2138 func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 {
2139 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1
2142 func OP_BCR(op uint32, bo uint32, bi uint32) uint32 {
2143 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16
2146 func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 {
2147 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1
2150 func AOP_RLDIC(op uint32, a uint32, s uint32, sh uint32, m uint32) uint32 {
2151 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1 | (m&31)<<6 | ((m&32)>>5)<<5
2154 func AOP_ISEL(op uint32, t uint32, a uint32, b uint32, bc uint32) uint32 {
2155 return op | (t&31)<<21 | (a&31)<<16 | (b&31)<<11 | (bc&0x1F)<<6
2159 /* each rhs is OPVCC(_, _, _, _) */
2160 OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0
2161 OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0
2162 OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0
2163 OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 0
2164 OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0
2165 OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0
2166 OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0
2167 OP_ISEL = 31<<26 | 15<<1 | 0<<10 | 0
2168 OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0
2169 OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0
2170 OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0
2171 OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 0
2172 OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 0
2173 OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0
2174 OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0
2175 OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 0
2176 OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0
2177 OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0
2178 OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0
2179 OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0
2180 OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0
2181 OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0
2182 OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0
2183 OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 0
2184 OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0
2185 OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0
2186 OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0
2187 OP_OR = 31<<26 | 444<<1 | 0<<10 | 0
2188 OP_ORI = 24<<26 | 0<<1 | 0<<10 | 0
2189 OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 0
2190 OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0
2191 OP_RLWNM = 23<<26 | 0<<1 | 0<<10 | 0
2192 OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 0
2193 OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 0
2194 OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0
2195 OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0
2196 OP_RLDCL = 30<<26 | 8<<1 | 0<<10 | 0
2199 func oclass(a *obj.Addr) int {
2200 return int(a.Class) - 1
2208 // This function determines when a non-indexed load or store is D or
2209 // DS form for use in finding the size of the offset field in the instruction.
2210 // The size is needed when setting the offset value in the instruction
2211 // and when generating relocation for that field.
2212 // DS form instructions include: ld, ldu, lwa, std, stdu. All other
2213 // loads and stores with an offset field are D form. This function should
2214 // only be called with the same opcodes as are handled by opstore and opload.
2215 func (c *ctxt9) opform(insn uint32) int {
2218 c.ctxt.Diag("bad insn in loadform: %x", insn)
2219 case OPVCC(58, 0, 0, 0), // ld
2220 OPVCC(58, 0, 0, 1), // ldu
2221 OPVCC(58, 0, 0, 0) | 1<<1, // lwa
2222 OPVCC(62, 0, 0, 0), // std
2223 OPVCC(62, 0, 0, 1): //stdu
2225 case OP_ADDI, // add
2226 OPVCC(32, 0, 0, 0), // lwz
2227 OPVCC(33, 0, 0, 0), // lwzu
2228 OPVCC(34, 0, 0, 0), // lbz
2229 OPVCC(35, 0, 0, 0), // lbzu
2230 OPVCC(40, 0, 0, 0), // lhz
2231 OPVCC(41, 0, 0, 0), // lhzu
2232 OPVCC(42, 0, 0, 0), // lha
2233 OPVCC(43, 0, 0, 0), // lhau
2234 OPVCC(46, 0, 0, 0), // lmw
2235 OPVCC(48, 0, 0, 0), // lfs
2236 OPVCC(49, 0, 0, 0), // lfsu
2237 OPVCC(50, 0, 0, 0), // lfd
2238 OPVCC(51, 0, 0, 0), // lfdu
2239 OPVCC(36, 0, 0, 0), // stw
2240 OPVCC(37, 0, 0, 0), // stwu
2241 OPVCC(38, 0, 0, 0), // stb
2242 OPVCC(39, 0, 0, 0), // stbu
2243 OPVCC(44, 0, 0, 0), // sth
2244 OPVCC(45, 0, 0, 0), // sthu
2245 OPVCC(47, 0, 0, 0), // stmw
2246 OPVCC(52, 0, 0, 0), // stfs
2247 OPVCC(53, 0, 0, 0), // stfsu
2248 OPVCC(54, 0, 0, 0), // stfd
2249 OPVCC(55, 0, 0, 0): // stfdu
2255 // Encode instructions and create relocation for accessing s+d according to the
2256 // instruction op with source or destination (as appropriate) register reg.
2257 func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) {
2258 if c.ctxt.Headtype == objabi.Haix {
2259 // Every symbol access must be made via a TOC anchor.
2260 c.ctxt.Diag("symbolAccess called for %s", s.Name)
2263 form := c.opform(op)
2264 if c.ctxt.Flag_shared {
2269 o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)
2270 o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)
2271 rel := obj.Addrel(c.cursym)
2272 rel.Off = int32(c.pc)
2276 if c.ctxt.Flag_shared {
2279 rel.Type = objabi.R_ADDRPOWER_TOCREL
2281 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
2287 rel.Type = objabi.R_ADDRPOWER
2289 rel.Type = objabi.R_ADDRPOWER_DS
2298 func getmask(m []byte, v uint32) bool {
2301 if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
2312 for i := 0; i < 32; i++ {
2313 if v&(1<<uint(31-i)) != 0 {
2318 if i >= 32 || v&(1<<uint(31-i)) == 0 {
2324 if v&(1<<uint(31-i)) != 0 {
2335 func (c *ctxt9) maskgen(p *obj.Prog, m []byte, v uint32) {
2337 c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
2342 * 64-bit masks (rldic etc)
2344 func getmask64(m []byte, v uint64) bool {
2347 for i := 0; i < 64; i++ {
2348 if v&(uint64(1)<<uint(63-i)) != 0 {
2353 if i >= 64 || v&(uint64(1)<<uint(63-i)) == 0 {
2359 if v&(uint64(1)<<uint(63-i)) != 0 {
2370 func (c *ctxt9) maskgen64(p *obj.Prog, m []byte, v uint64) {
2371 if !getmask64(m, v) {
2372 c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
2376 func loadu32(r int, d int64) uint32 {
2378 if isuint32(uint64(d)) {
2379 return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
2381 return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v))
2384 func high16adjusted(d int32) uint16 {
2386 return uint16((d >> 16) + 1)
2388 return uint16(d >> 16)
2391 func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
2398 //print("%v => case %d\n", p, o->type);
2401 c.ctxt.Diag("unknown type %d", o.type_)
2404 case 0: /* pseudo ops */
2407 case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
2408 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
2409 v := c.regoff(&p.From)
2410 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
2412 c.ctxt.Diag("literal operation on R0\n%v", p)
2415 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
2419 o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
2421 case 2: /* int/cr/fp op Rb,[Ra],Rd */
2427 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2429 case 3: /* mov $soreg/addcon/andcon/ucon, r ==> addis/oris/addi/ori $i,reg',r */
2430 d := c.vregoff(&p.From)
2433 r := int(p.From.Reg)
2437 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
2438 c.ctxt.Diag("literal operation on R0\n%v", p)
2443 log.Fatalf("invalid handling of %v", p)
2445 // For UCON operands the value is right shifted 16, using ADDIS if the
2446 // value should be signed, ORIS if unsigned.
2448 if r == REGZERO && isuint32(uint64(d)) {
2449 o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v))
2454 } else if int64(int16(d)) != d {
2455 // Operand is 16 bit value with sign bit set
2456 if o.a1 == C_ANDCON {
2457 // Needs unsigned 16 bit so use ORI
2458 if r == 0 || r == REGZERO {
2459 o1 = LOP_IRR(uint32(OP_ORI), uint32(p.To.Reg), uint32(0), uint32(v))
2462 // With ADDCON, needs signed 16 bit value, fall through to use ADDI
2463 } else if o.a1 != C_ADDCON {
2464 log.Fatalf("invalid handling of %v", p)
2468 o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
2470 case 4: /* add/mul $scon,[r1],r2 */
2471 v := c.regoff(&p.From)
2477 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
2478 c.ctxt.Diag("literal operation on R0\n%v", p)
2480 if int32(int16(v)) != v {
2481 log.Fatalf("mishandled instruction %v", p)
2483 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2485 case 5: /* syscall */
2488 case 6: /* logical op Rb,[Rs,]Ra; no literal */
2494 // AROTL and AROTLW are extended mnemonics, which map to RLDCL and RLWNM.
2497 o1 = AOP_RLDIC(OP_RLDCL, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), uint32(0))
2499 o1 = OP_RLW(OP_RLWNM, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), 0, 31)
2501 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2504 case 7: /* mov r, soreg ==> stw o(r) */
2510 v := c.regoff(&p.To)
2511 if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
2513 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2515 if c.ctxt.Flag_shared && r == REG_R13 {
2516 rel := obj.Addrel(c.cursym)
2517 rel.Off = int32(c.pc)
2519 // This (and the matching part in the load case
2520 // below) are the only places in the ppc64 toolchain
2521 // that knows the name of the tls variable. Possibly
2522 // we could add some assembly syntax so that the name
2523 // of the variable does not have to be assumed.
2524 rel.Sym = c.ctxt.Lookup("runtime.tls_g")
2525 rel.Type = objabi.R_POWER_TLS
2527 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
2529 if int32(int16(v)) != v {
2530 log.Fatalf("mishandled instruction %v", p)
2532 // Offsets in DS form stores must be a multiple of 4
2533 inst := c.opstore(p.As)
2534 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2535 log.Fatalf("invalid offset for DS form load/store %v", p)
2537 o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
2540 case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
2541 r := int(p.From.Reg)
2546 v := c.regoff(&p.From)
2547 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
2549 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2551 if c.ctxt.Flag_shared && r == REG_R13 {
2552 rel := obj.Addrel(c.cursym)
2553 rel.Off = int32(c.pc)
2555 rel.Sym = c.ctxt.Lookup("runtime.tls_g")
2556 rel.Type = objabi.R_POWER_TLS
2558 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
2560 if int32(int16(v)) != v {
2561 log.Fatalf("mishandled instruction %v", p)
2563 // Offsets in DS form loads must be a multiple of 4
2564 inst := c.opload(p.As)
2565 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2566 log.Fatalf("invalid offset for DS form load/store %v", p)
2568 o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
2571 case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
2572 r := int(p.From.Reg)
2577 v := c.regoff(&p.From)
2578 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
2580 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2582 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
2584 o1 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2586 o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
2588 case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
2594 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
2596 case 11: /* br/bl lbra */
2600 v = int32(p.Pcond.Pc - p.Pc)
2602 c.ctxt.Diag("odd branch target address\n%v", p)
2606 if v < -(1<<25) || v >= 1<<24 {
2607 c.ctxt.Diag("branch too far\n%v", p)
2611 o1 = OP_BR(c.opirr(p.As), uint32(v), 0)
2612 if p.To.Sym != nil {
2613 rel := obj.Addrel(c.cursym)
2614 rel.Off = int32(c.pc)
2617 v += int32(p.To.Offset)
2619 c.ctxt.Diag("odd branch target address\n%v", p)
2624 rel.Type = objabi.R_CALLPOWER
2626 o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
2628 case 12: /* movb r,r (extsb); movw r,r (extsw) */
2629 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
2630 v := c.regoff(&p.From)
2631 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
2632 c.ctxt.Diag("literal operation on R0\n%v", p)
2635 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
2640 o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2642 o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2645 case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
2647 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
2648 } else if p.As == AMOVH {
2649 o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2650 } else if p.As == AMOVHZ {
2651 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
2652 } else if p.As == AMOVWZ {
2653 o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
2655 c.ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
2658 case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
2664 d := c.vregoff(p.GetFrom3())
2668 // These opcodes expect a mask operand that has to be converted into the
2669 // appropriate operand. The way these were defined, not all valid masks are possible.
2670 // Left here for compatibility in case they were used or generated.
2671 case ARLDCL, ARLDCLCC:
2673 c.maskgen64(p, mask[:], uint64(d))
2675 a = int(mask[0]) /* MB */
2677 c.ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)
2679 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2680 o1 |= (uint32(a) & 31) << 6
2682 o1 |= 1 << 5 /* mb[5] is top bit */
2685 case ARLDCR, ARLDCRCC:
2687 c.maskgen64(p, mask[:], uint64(d))
2689 a = int(mask[1]) /* ME */
2691 c.ctxt.Diag("invalid mask for rotate: %x (start != 0)\n%v", uint64(d), p)
2693 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2694 o1 |= (uint32(a) & 31) << 6
2696 o1 |= 1 << 5 /* mb[5] is top bit */
2699 // These opcodes use a shift count like the ppc64 asm, no mask conversion done
2700 case ARLDICR, ARLDICRCC:
2702 sh := c.regoff(&p.From)
2703 o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(me))
2705 case ARLDICL, ARLDICLCC:
2707 sh := c.regoff(&p.From)
2708 o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(mb))
2711 c.ctxt.Diag("unexpected op in rldc case\n%v", p)
2715 case 17, /* bc bo,bi,lbra (same for now) */
2716 16: /* bc bo,bi,sbra */
2721 if p.From.Type == obj.TYPE_CONST {
2722 a = int(c.regoff(&p.From))
2723 } else if p.From.Type == obj.TYPE_REG {
2725 c.ctxt.Diag("unexpected register setting for branch with CR: %d\n", r)
2727 // BI values for the CR
2746 c.ctxt.Diag("unrecognized register: expecting CR\n")
2751 v = int32(p.Pcond.Pc - p.Pc)
2754 c.ctxt.Diag("odd branch target address\n%v", p)
2758 if v < -(1<<16) || v >= 1<<15 {
2759 c.ctxt.Diag("branch too far\n%v", p)
2761 o1 = OP_BC(c.opirr(p.As), uint32(a), uint32(r), uint32(v), 0)
2763 case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
2765 if p.As == ABC || p.As == ABCL {
2766 v = c.regoff(&p.To) & 31
2768 v = 20 /* unconditional */
2770 o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
2771 o2 = OPVCC(19, 16, 0, 0)
2772 if p.As == ABL || p.As == ABCL {
2775 o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index))
2777 case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
2779 if p.As == ABC || p.As == ABCL {
2780 v = c.regoff(&p.From) & 31
2782 v = 20 /* unconditional */
2788 switch oclass(&p.To) {
2790 o1 = OPVCC(19, 528, 0, 0)
2793 o1 = OPVCC(19, 16, 0, 0)
2796 c.ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p)
2800 if p.As == ABL || p.As == ABCL {
2803 o1 = OP_BCR(o1, uint32(v), uint32(r))
2805 case 19: /* mov $lcon,r ==> cau+or */
2806 d := c.vregoff(&p.From)
2808 if p.From.Sym == nil {
2809 o1 = loadu32(int(p.To.Reg), d)
2810 o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
2812 o1, o2 = c.symbolAccess(p.From.Sym, d, p.To.Reg, OP_ADDI)
2815 case 20: /* add $ucon,,r | addis $addcon,r,r */
2816 v := c.regoff(&p.From)
2822 if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
2823 c.ctxt.Diag("literal operation on R0\n%v", p)
2826 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2828 o1 = AOP_IRR(c.opirr(AADDIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
2831 case 22: /* add $lcon/$andcon,r1,r2 ==> oris+ori+add/ori+add */
2832 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2833 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2835 d := c.vregoff(&p.From)
2840 if p.From.Sym != nil {
2841 c.ctxt.Diag("%v is not supported", p)
2843 // If operand is ANDCON, generate 2 instructions using
2844 // ORI for unsigned value; with LCON 3 instructions.
2846 o1 = LOP_IRR(OP_ORI, REGTMP, REGZERO, uint32(int32(d)))
2847 o2 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2849 o1 = loadu32(REGTMP, d)
2850 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2851 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2854 case 23: /* and $lcon/$addcon,r1,r2 ==> oris+ori+and/addi+and */
2855 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2856 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2858 d := c.vregoff(&p.From)
2864 // With ADDCON operand, generate 2 instructions using ADDI for signed value,
2865 // with LCON operand generate 3 instructions.
2867 o1 = LOP_IRR(OP_ADDI, REGZERO, REGTMP, uint32(int32(d)))
2868 o2 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2870 o1 = loadu32(REGTMP, d)
2871 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2872 o3 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2874 if p.From.Sym != nil {
2875 c.ctxt.Diag("%v is not supported", p)
2878 case 24: /* lfd fA,float64(0) -> xxlxor xsA,xsaA,xsaA + fneg for -0 */
2879 o1 = AOP_XX3I(c.oprrr(AXXLXOR), uint32(p.To.Reg), uint32(p.To.Reg), uint32(p.To.Reg), uint32(0))
2880 // This is needed for -0.
2882 o2 = AOP_RRR(c.oprrr(AFNEG), uint32(p.To.Reg), 0, uint32(p.To.Reg))
2886 /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
2887 v := c.regoff(&p.From)
2913 c.ctxt.Diag("unexpected op in sldi case\n%v", p)
2918 o1 = AOP_RLDIC(op, uint32(p.To.Reg), uint32(r), uint32(v), uint32(a))
2919 if p.As == ASLDCC || p.As == ASRDCC {
2920 o1 |= 1 // Set the condition code bit
2923 case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
2924 if p.To.Reg == REGTMP {
2925 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2927 v := c.regoff(&p.From)
2928 r := int(p.From.Reg)
2932 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
2933 o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
2935 case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
2936 v := c.regoff(p.GetFrom3())
2938 r := int(p.From.Reg)
2939 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2941 case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
2942 if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
2943 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2945 v := c.regoff(p.GetFrom3())
2946 o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
2947 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
2948 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
2949 if p.From.Sym != nil {
2950 c.ctxt.Diag("%v is not supported", p)
2953 //if(dlm) reloc(&p->from3, p->pc, 0);
2955 case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
2956 v := c.regoff(&p.From)
2958 d := c.vregoff(p.GetFrom3())
2960 c.maskgen64(p, mask[:], uint64(d))
2963 case ARLDC, ARLDCCC:
2964 a = int(mask[0]) /* MB */
2965 if int32(mask[1]) != (63 - v) {
2966 c.ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
2969 case ARLDCL, ARLDCLCC:
2970 a = int(mask[0]) /* MB */
2972 c.ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
2975 case ARLDCR, ARLDCRCC:
2976 a = int(mask[1]) /* ME */
2978 c.ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
2982 c.ctxt.Diag("unexpected op in rldic case\n%v", p)
2986 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
2987 o1 |= (uint32(a) & 31) << 6
2992 o1 |= 1 << 5 /* mb[5] is top bit */
2995 case 30: /* rldimi $sh,s,$mask,a */
2996 v := c.regoff(&p.From)
2998 d := c.vregoff(p.GetFrom3())
3000 // Original opcodes had mask operands which had to be converted to a shift count as expected by
3003 case ARLDMI, ARLDMICC:
3005 c.maskgen64(p, mask[:], uint64(d))
3006 if int32(mask[1]) != (63 - v) {
3007 c.ctxt.Diag("invalid mask for shift: %x (shift %d)\n%v", uint64(d), v, p)
3009 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3010 o1 |= (uint32(mask[0]) & 31) << 6
3014 if mask[0]&0x20 != 0 {
3015 o1 |= 1 << 5 /* mb[5] is top bit */
3018 // Opcodes with shift count operands.
3019 case ARLDIMI, ARLDIMICC:
3020 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3021 o1 |= (uint32(d) & 31) << 6
3030 case 31: /* dword */
3031 d := c.vregoff(&p.From)
3033 if c.ctxt.Arch.ByteOrder == binary.BigEndian {
3034 o1 = uint32(d >> 32)
3038 o2 = uint32(d >> 32)
3041 if p.From.Sym != nil {
3042 rel := obj.Addrel(c.cursym)
3043 rel.Off = int32(c.pc)
3045 rel.Sym = p.From.Sym
3046 rel.Add = p.From.Offset
3047 rel.Type = objabi.R_ADDR
3052 case 32: /* fmul frc,fra,frd */
3058 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
3060 case 33: /* fabs [frb,]frd; fmr. frb,frd */
3061 r := int(p.From.Reg)
3063 if oclass(&p.From) == C_NONE {
3066 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(r))
3068 case 34: /* FMADDx fra,frb,frc,frt (t=a*c±b) */
3069 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.GetFrom3().Reg)&31)<<6
3071 case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
3072 v := c.regoff(&p.To)
3078 // Offsets in DS form stores must be a multiple of 4
3079 inst := c.opstore(p.As)
3080 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3081 log.Fatalf("invalid offset for DS form load/store %v", p)
3083 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3084 o2 = AOP_IRR(inst, uint32(p.From.Reg), REGTMP, uint32(v))
3086 case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
3087 v := c.regoff(&p.From)
3089 r := int(p.From.Reg)
3093 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3094 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
3096 case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
3097 v := c.regoff(&p.From)
3099 r := int(p.From.Reg)
3103 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3104 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
3105 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3108 o1 = uint32(c.regoff(&p.From))
3110 case 41: /* stswi */
3111 o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3114 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3116 case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */
3117 /* TH field for dcbt/dcbtst: */
3118 /* 0 = Block access - program will soon access EA. */
3119 /* 8-15 = Stream access - sequence of access (data stream). See section 4.3.2 of the ISA for details. */
3120 /* 16 = Block access - program will soon make a transient access to EA. */
3121 /* 17 = Block access - program will not access EA for a long time. */
3123 /* L field for dcbf: */
3124 /* 0 = invalidates the block containing EA in all processors. */
3125 /* 1 = same as 0, but with limited scope (i.e. block in the current processor will not be reused soon). */
3126 /* 3 = same as 1, but with even more limited scope (i.e. block in the current processor primary cache will not be reused soon). */
3127 if p.To.Type == obj.TYPE_NONE {
3128 o1 = AOP_RRR(c.oprrr(p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))
3130 th := c.regoff(&p.To)
3131 o1 = AOP_RRR(c.oprrr(p.As), uint32(th), uint32(p.From.Index), uint32(p.From.Reg))
3134 case 44: /* indexed store */
3135 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3137 case 45: /* indexed load */
3139 /* The assembler accepts a 4-operand l*arx instruction. The fourth operand is an Exclusive Access Hint (EH) */
3140 /* The EH field can be used as a lock acquire/release hint as follows: */
3141 /* 0 = Atomic Update (fetch-and-operate or similar algorithm) */
3142 /* 1 = Exclusive Access (lock acquire and release) */
3143 case ALBAR, ALHAR, ALWAR, ALDAR:
3144 if p.From3Type() != obj.TYPE_NONE {
3145 eh := int(c.regoff(p.GetFrom3()))
3147 c.ctxt.Diag("illegal EH field\n%v", p)
3149 o1 = AOP_RRRI(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg), uint32(eh))
3151 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3154 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3156 case 46: /* plain op */
3159 case 47: /* op Ra, Rd; also op [Ra,] Rd */
3160 r := int(p.From.Reg)
3165 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3167 case 48: /* op Rs, Ra */
3168 r := int(p.From.Reg)
3173 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3175 case 49: /* op Rb; op $n, Rb */
3176 if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
3177 v := c.regoff(&p.From) & 1
3178 o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
3180 o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.From.Reg))
3183 case 50: /* rem[u] r1[,r2],r3 */
3190 t := v & (1<<10 | 1) /* OE|Rc */
3191 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3192 o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
3193 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3197 /* Clear top 32 bits */
3198 o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5
3201 case 51: /* remd[u] r1[,r2],r3 */
3208 t := v & (1<<10 | 1) /* OE|Rc */
3209 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3210 o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
3211 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3213 case 52: /* mtfsbNx cr(n) */
3214 v := c.regoff(&p.From) & 31
3216 o1 = AOP_RRR(c.oprrr(p.As), uint32(v), 0, 0)
3218 case 53: /* mffsX ,fr1 */
3219 o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)
3221 case 54: /* mov msr,r1; mov r1, msr*/
3222 if oclass(&p.From) == C_REG {
3224 o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
3226 o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
3229 o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
3232 case 55: /* op Rb, Rd */
3233 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg))
3235 case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
3236 v := c.regoff(&p.From)
3242 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31)
3243 if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) {
3244 o1 |= 1 << 1 /* mb[5] */
3247 case 57: /* slw $sh,[s,]a -> rlwinm ... */
3248 v := c.regoff(&p.From)
3256 * Let user (gs) shoot himself in the foot.
3257 * qc has already complained.
3260 ctxt->diag("illegal shift %ld\n%v", v, p);
3270 mask[0], mask[1] = 0, 31
3272 mask[0], mask[1] = uint8(v), 31
3275 mask[0], mask[1] = 0, uint8(31-v)
3277 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1]))
3278 if p.As == ASLWCC || p.As == ASRWCC {
3279 o1 |= 1 // set the condition code
3282 case 58: /* logical $andcon,[s],a */
3283 v := c.regoff(&p.From)
3289 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3291 case 59: /* or/xor/and $ucon,,r | oris/xoris/andis $addcon,r,r */
3292 v := c.regoff(&p.From)
3300 o1 = LOP_IRR(c.opirr(AORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis. */
3302 o1 = LOP_IRR(c.opirr(AXORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3304 o1 = LOP_IRR(c.opirr(AANDISCC), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3306 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3309 case 60: /* tw to,a,b */
3310 r := int(c.regoff(&p.From) & 31)
3312 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
3314 case 61: /* tw to,a,$simm */
3315 r := int(c.regoff(&p.From) & 31)
3317 v := c.regoff(&p.To)
3318 o1 = AOP_IRR(c.opirr(p.As), uint32(r), uint32(p.Reg), uint32(v))
3320 case 62: /* rlwmi $sh,s,$mask,a */
3321 v := c.regoff(&p.From)
3324 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
3325 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
3326 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
3328 case 63: /* rlwmi b,s,$mask,a */
3330 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
3332 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
3333 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
3335 case 64: /* mtfsf fr[, $m] {,fpcsr} */
3337 if p.From3Type() != obj.TYPE_NONE {
3338 v = c.regoff(p.GetFrom3()) & 255
3342 o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
3344 case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
3346 c.ctxt.Diag("must specify FPSCR(n)\n%v", p)
3348 o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(c.regoff(&p.From))&31)<<12
3350 case 66: /* mov spr,r1; mov r1,spr, also dcr */
3353 if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
3356 if REG_DCR0 <= v && v <= REG_DCR0+1023 {
3357 o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
3359 o1 = OPVCC(31, 467, 0, 0) /* mtspr */
3363 v = int32(p.From.Reg)
3364 if REG_DCR0 <= v && v <= REG_DCR0+1023 {
3365 o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
3367 o1 = OPVCC(31, 339, 0, 0) /* mfspr */
3371 o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
3373 case 67: /* mcrf crfD,crfS */
3374 if p.From.Type != obj.TYPE_REG || p.From.Reg < REG_CR0 || REG_CR7 < p.From.Reg || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg {
3375 c.ctxt.Diag("illegal CR field number\n%v", p)
3377 o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
3379 case 68: /* mfcr rD; mfocrf CRM,rD */
3380 if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
3381 v := int32(1 << uint(7-(p.To.Reg&7))) /* CR(n) */
3382 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
3384 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
3387 case 69: /* mtcrf CRM,rS */
3389 if p.From3Type() != obj.TYPE_NONE {
3391 c.ctxt.Diag("can't use both mask and CR(n)\n%v", p)
3393 v = c.regoff(p.GetFrom3()) & 0xff
3398 v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
3402 o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
3404 case 70: /* [f]cmp r,r,cr*/
3409 r = (int(p.Reg) & 7) << 2
3411 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
3413 case 71: /* cmp[l] r,i,cr*/
3418 r = (int(p.Reg) & 7) << 2
3420 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(c.regoff(&p.To))&0xffff
3422 case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
3423 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg))
3425 case 73: /* mcrfs crfD,crfS */
3426 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 {
3427 c.ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
3429 o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
3431 case 77: /* syscall $scon, syscall Rx */
3432 if p.From.Type == obj.TYPE_CONST {
3433 if p.From.Offset > BIG || p.From.Offset < -BIG {
3434 c.ctxt.Diag("illegal syscall, sysnum too large: %v", p)
3436 o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
3437 } else if p.From.Type == obj.TYPE_REG {
3438 o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
3440 c.ctxt.Diag("illegal syscall: %v", p)
3441 o1 = 0x7fe00008 // trap always
3445 o3 = AOP_RRR(c.oprrr(AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R0
3447 case 78: /* undef */
3448 o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed
3449 always to be an illegal instruction." */
3451 /* relocation operations */
3453 v := c.vregoff(&p.To)
3454 // Offsets in DS form stores must be a multiple of 4
3455 inst := c.opstore(p.As)
3456 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3457 log.Fatalf("invalid offset for DS form load/store %v", p)
3459 o1, o2 = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst)
3461 //if(dlm) reloc(&p->to, p->pc, 1);
3464 v := c.vregoff(&p.From)
3465 // Offsets in DS form loads must be a multiple of 4
3466 inst := c.opload(p.As)
3467 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3468 log.Fatalf("invalid offset for DS form load/store %v", p)
3470 o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
3472 //if(dlm) reloc(&p->from, p->pc, 1);
3475 v := c.vregoff(&p.From)
3476 // Offsets in DS form loads must be a multiple of 4
3477 inst := c.opload(p.As)
3478 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3479 log.Fatalf("invalid offset for DS form load/store %v", p)
3481 o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
3482 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3484 //if(dlm) reloc(&p->from, p->pc, 1);
3487 if p.From.Offset != 0 {
3488 c.ctxt.Diag("invalid offset against tls var %v", p)
3490 o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0)
3491 rel := obj.Addrel(c.cursym)
3492 rel.Off = int32(c.pc)
3494 rel.Sym = p.From.Sym
3495 rel.Type = objabi.R_POWER_TLS_LE
3498 if p.From.Offset != 0 {
3499 c.ctxt.Diag("invalid offset against tls var %v", p)
3501 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3502 o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3503 rel := obj.Addrel(c.cursym)
3504 rel.Off = int32(c.pc)
3506 rel.Sym = p.From.Sym
3507 rel.Type = objabi.R_POWER_TLS_IE
3510 v := c.vregoff(&p.To)
3512 c.ctxt.Diag("invalid offset against GOT slot %v", p)
3515 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3516 o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3517 rel := obj.Addrel(c.cursym)
3518 rel.Off = int32(c.pc)
3520 rel.Sym = p.From.Sym
3521 rel.Type = objabi.R_ADDRPOWER_GOT
3522 case 82: /* vector instructions, VX-form and VC-form */
3523 if p.From.Type == obj.TYPE_REG {
3524 /* reg reg none OR reg reg reg */
3525 /* 3-register operand order: VRA, VRB, VRT */
3526 /* 2-register operand order: VRA, VRT */
3527 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3528 } else if p.From3Type() == obj.TYPE_CONST {
3529 /* imm imm reg reg */
3530 /* operand order: SIX, VRA, ST, VRT */
3531 six := int(c.regoff(&p.From))
3532 st := int(c.regoff(p.GetFrom3()))
3533 o1 = AOP_IIRR(c.opiirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(st), uint32(six))
3534 } else if p.From3Type() == obj.TYPE_NONE && p.Reg != 0 {
3536 /* operand order: UIM, VRB, VRT */
3537 uim := int(c.regoff(&p.From))
3538 o1 = AOP_VIRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(uim))
3541 /* operand order: SIM, VRT */
3542 sim := int(c.regoff(&p.From))
3543 o1 = AOP_IR(c.opirr(p.As), uint32(p.To.Reg), uint32(sim))
3546 case 83: /* vector instructions, VA-form */
3547 if p.From.Type == obj.TYPE_REG {
3548 /* reg reg reg reg */
3549 /* 4-register operand order: VRA, VRB, VRC, VRT */
3550 o1 = AOP_RRRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3551 } else if p.From.Type == obj.TYPE_CONST {
3552 /* imm reg reg reg */
3553 /* operand order: SHB, VRA, VRB, VRT */
3554 shb := int(c.regoff(&p.From))
3555 o1 = AOP_IRRR(c.opirrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(shb))
3558 case 84: // ISEL BC,RA,RB,RT -> isel rt,ra,rb,bc
3559 bc := c.vregoff(&p.From)
3561 // rt = To.Reg, ra = p.Reg, rb = p.From3.Reg
3562 o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(bc))
3564 case 85: /* vector instructions, VX-form */
3566 /* 2-register operand order: VRB, VRT */
3567 o1 = AOP_RR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg))
3569 case 86: /* VSX indexed store, XX1-form */
3571 /* 3-register operand order: XT, (RB)(RA*1) */
3572 o1 = AOP_XX1(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3574 case 87: /* VSX indexed load, XX1-form */
3576 /* 3-register operand order: (RB)(RA*1), XT */
3577 o1 = AOP_XX1(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3579 case 88: /* VSX instructions, XX1-form */
3580 /* reg reg none OR reg reg reg */
3581 /* 3-register operand order: RA, RB, XT */
3582 /* 2-register operand order: XS, RA or RA, XT */
3583 xt := int32(p.To.Reg)
3584 xs := int32(p.From.Reg)
3585 /* We need to treat the special case of extended mnemonics that may have a FREG/VREG as an argument */
3586 if REG_V0 <= xt && xt <= REG_V31 {
3587 /* Convert V0-V31 to VS32-VS63 */
3589 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3590 } else if REG_F0 <= xt && xt <= REG_F31 {
3591 /* Convert F0-F31 to VS0-VS31 */
3593 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3594 } else if REG_VS0 <= xt && xt <= REG_VS63 {
3595 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3596 } else if REG_V0 <= xs && xs <= REG_V31 {
3597 /* Likewise for XS */
3599 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3600 } else if REG_F0 <= xs && xs <= REG_F31 {
3602 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3603 } else if REG_VS0 <= xs && xs <= REG_VS63 {
3604 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3607 case 89: /* VSX instructions, XX2-form */
3608 /* reg none reg OR reg imm reg */
3609 /* 2-register operand order: XB, XT or XB, UIM, XT*/
3610 uim := int(c.regoff(p.GetFrom3()))
3611 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(uim), uint32(p.From.Reg))
3613 case 90: /* VSX instructions, XX3-form */
3614 if p.From3Type() == obj.TYPE_NONE {
3616 /* 3-register operand order: XA, XB, XT */
3617 o1 = AOP_XX3(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3618 } else if p.From3Type() == obj.TYPE_CONST {
3619 /* reg reg reg imm */
3620 /* operand order: XA, XB, DM, XT */
3621 dm := int(c.regoff(p.GetFrom3()))
3622 o1 = AOP_XX3I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(dm))
3625 case 91: /* VSX instructions, XX4-form */
3626 /* reg reg reg reg */
3627 /* 3-register operand order: XA, XB, XC, XT */
3628 o1 = AOP_XX4(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3630 case 92: /* X-form instructions, 3-operands */
3631 if p.To.Type == obj.TYPE_CONST {
3633 xf := int32(p.From.Reg)
3634 if REG_F0 <= xf && xf <= REG_F31 {
3635 /* operand order: FRA, FRB, BF */
3636 bf := int(c.regoff(&p.To)) << 2
3637 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3639 /* operand order: RA, RB, L */
3640 l := int(c.regoff(&p.To))
3641 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.From.Reg), uint32(p.Reg))
3643 } else if p.From3Type() == obj.TYPE_CONST {
3645 /* operand order: RB, L, RA */
3646 l := int(c.regoff(p.GetFrom3()))
3647 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.To.Reg), uint32(p.From.Reg))
3648 } else if p.To.Type == obj.TYPE_REG {
3649 cr := int32(p.To.Reg)
3650 if REG_CR0 <= cr && cr <= REG_CR7 {
3652 /* operand order: RA, RB, BF */
3653 bf := (int(p.To.Reg) & 7) << 2
3654 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3655 } else if p.From.Type == obj.TYPE_CONST {
3657 /* operand order: L, RT */
3658 l := int(c.regoff(&p.From))
3659 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(l), uint32(p.Reg))
3662 case ACOPY, APASTECC:
3663 o1 = AOP_RRR(c.opirr(p.As), uint32(1), uint32(p.From.Reg), uint32(p.To.Reg))
3666 /* operand order: RS, RB, RA */
3667 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3672 case 93: /* X-form instructions, 2-operands */
3673 if p.To.Type == obj.TYPE_CONST {
3675 /* operand order: FRB, BF */
3676 bf := int(c.regoff(&p.To)) << 2
3677 o1 = AOP_RR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg))
3678 } else if p.Reg == 0 {
3679 /* popcnt* r,r, X-form */
3680 /* operand order: RS, RA */
3681 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3684 case 94: /* Z23-form instructions, 4-operands */
3685 /* reg reg reg imm */
3686 /* operand order: RA, RB, CY, RT */
3687 cy := int(c.regoff(p.GetFrom3()))
3688 o1 = AOP_Z23I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(cy))
3690 case 95: /* Retrieve TOC relative symbol */
3691 /* This code is for AIX only */
3692 v := c.vregoff(&p.From)
3694 c.ctxt.Diag("invalid offset against TOC slot %v", p)
3697 inst := c.opload(p.As)
3698 if c.opform(inst) != DS_FORM {
3699 c.ctxt.Diag("invalid form for a TOC access in %v", p)
3702 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3703 o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3704 rel := obj.Addrel(c.cursym)
3705 rel.Off = int32(c.pc)
3707 rel.Sym = p.From.Sym
3708 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
3710 case 96: /* VSX load, DQ-form */
3712 /* operand order: (RA)(DQ), XT */
3713 dq := int16(c.regoff(&p.From))
3715 c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3717 o1 = AOP_DQ(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(dq))
3719 case 97: /* VSX store, DQ-form */
3721 /* operand order: XT, (RA)(DQ) */
3722 dq := int16(c.regoff(&p.To))
3724 c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3726 o1 = AOP_DQ(c.opstore(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(dq))
3736 func (c *ctxt9) vregoff(a *obj.Addr) int64 {
3744 func (c *ctxt9) regoff(a *obj.Addr) int32 {
3745 return int32(c.vregoff(a))
3748 func (c *ctxt9) oprrr(a obj.As) uint32 {
3751 return OPVCC(31, 266, 0, 0)
3753 return OPVCC(31, 266, 0, 1)
3755 return OPVCC(31, 266, 1, 0)
3757 return OPVCC(31, 266, 1, 1)
3759 return OPVCC(31, 10, 0, 0)
3761 return OPVCC(31, 10, 0, 1)
3763 return OPVCC(31, 10, 1, 0)
3765 return OPVCC(31, 10, 1, 1)
3767 return OPVCC(31, 138, 0, 0)
3769 return OPVCC(31, 138, 0, 1)
3771 return OPVCC(31, 138, 1, 0)
3773 return OPVCC(31, 138, 1, 1)
3775 return OPVCC(31, 234, 0, 0)
3777 return OPVCC(31, 234, 0, 1)
3779 return OPVCC(31, 234, 1, 0)
3781 return OPVCC(31, 234, 1, 1)
3783 return OPVCC(31, 202, 0, 0)
3785 return OPVCC(31, 202, 0, 1)
3787 return OPVCC(31, 202, 1, 0)
3789 return OPVCC(31, 202, 1, 1)
3791 return OPVCC(31, 170, 0, 0) /* addex - v3.0b */
3794 return OPVCC(31, 28, 0, 0)
3796 return OPVCC(31, 28, 0, 1)
3798 return OPVCC(31, 60, 0, 0)
3800 return OPVCC(31, 60, 0, 1)
3803 return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */
3805 return OPVCC(31, 32, 0, 0) | 1<<21
3807 return OPVCC(31, 0, 0, 0) /* L=0 */
3809 return OPVCC(31, 32, 0, 0)
3811 return OPVCC(31, 508, 0, 0) /* cmpb - v2.05 */
3813 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
3816 return OPVCC(31, 26, 0, 0)
3818 return OPVCC(31, 26, 0, 1)
3820 return OPVCC(31, 58, 0, 0)
3822 return OPVCC(31, 58, 0, 1)
3825 return OPVCC(19, 257, 0, 0)
3827 return OPVCC(19, 129, 0, 0)
3829 return OPVCC(19, 289, 0, 0)
3831 return OPVCC(19, 225, 0, 0)
3833 return OPVCC(19, 33, 0, 0)
3835 return OPVCC(19, 449, 0, 0)
3837 return OPVCC(19, 417, 0, 0)
3839 return OPVCC(19, 193, 0, 0)
3842 return OPVCC(31, 86, 0, 0)
3844 return OPVCC(31, 470, 0, 0)
3846 return OPVCC(31, 54, 0, 0)
3848 return OPVCC(31, 278, 0, 0)
3850 return OPVCC(31, 246, 0, 0)
3852 return OPVCC(31, 1014, 0, 0)
3855 return OPVCC(31, 491, 0, 0)
3857 case AREMCC, ADIVWCC:
3858 return OPVCC(31, 491, 0, 1)
3861 return OPVCC(31, 491, 1, 0)
3863 case AREMVCC, ADIVWVCC:
3864 return OPVCC(31, 491, 1, 1)
3867 return OPVCC(31, 459, 0, 0)
3869 case AREMUCC, ADIVWUCC:
3870 return OPVCC(31, 459, 0, 1)
3872 case AREMUV, ADIVWUV:
3873 return OPVCC(31, 459, 1, 0)
3875 case AREMUVCC, ADIVWUVCC:
3876 return OPVCC(31, 459, 1, 1)
3879 return OPVCC(31, 489, 0, 0)
3881 case AREMDCC, ADIVDCC:
3882 return OPVCC(31, 489, 0, 1)
3885 return OPVCC(31, 425, 0, 0)
3888 return OPVCC(31, 425, 0, 1)
3891 return OPVCC(31, 393, 0, 0)
3894 return OPVCC(31, 393, 0, 1)
3896 case AREMDV, ADIVDV:
3897 return OPVCC(31, 489, 1, 0)
3899 case AREMDVCC, ADIVDVCC:
3900 return OPVCC(31, 489, 1, 1)
3902 case AREMDU, ADIVDU:
3903 return OPVCC(31, 457, 0, 0)
3905 case AREMDUCC, ADIVDUCC:
3906 return OPVCC(31, 457, 0, 1)
3908 case AREMDUV, ADIVDUV:
3909 return OPVCC(31, 457, 1, 0)
3911 case AREMDUVCC, ADIVDUVCC:
3912 return OPVCC(31, 457, 1, 1)
3915 return OPVCC(31, 854, 0, 0)
3918 return OPVCC(31, 284, 0, 0)
3920 return OPVCC(31, 284, 0, 1)
3923 return OPVCC(31, 954, 0, 0)
3925 return OPVCC(31, 954, 0, 1)
3927 return OPVCC(31, 922, 0, 0)
3929 return OPVCC(31, 922, 0, 1)
3931 return OPVCC(31, 986, 0, 0)
3933 return OPVCC(31, 986, 0, 1)
3936 return OPVCC(63, 264, 0, 0)
3938 return OPVCC(63, 264, 0, 1)
3940 return OPVCC(63, 21, 0, 0)
3942 return OPVCC(63, 21, 0, 1)
3944 return OPVCC(59, 21, 0, 0)
3946 return OPVCC(59, 21, 0, 1)
3948 return OPVCC(63, 32, 0, 0)
3950 return OPVCC(63, 0, 0, 0)
3952 return OPVCC(63, 846, 0, 0)
3954 return OPVCC(63, 846, 0, 1)
3956 return OPVCC(63, 974, 0, 0)
3958 return OPVCC(63, 974, 0, 1)
3960 return OPVCC(59, 846, 0, 0)
3962 return OPVCC(59, 846, 0, 1)
3964 return OPVCC(63, 14, 0, 0)
3966 return OPVCC(63, 14, 0, 1)
3968 return OPVCC(63, 15, 0, 0)
3970 return OPVCC(63, 15, 0, 1)
3972 return OPVCC(63, 814, 0, 0)
3974 return OPVCC(63, 814, 0, 1)
3976 return OPVCC(63, 815, 0, 0)
3978 return OPVCC(63, 815, 0, 1)
3980 return OPVCC(63, 18, 0, 0)
3982 return OPVCC(63, 18, 0, 1)
3984 return OPVCC(59, 18, 0, 0)
3986 return OPVCC(59, 18, 0, 1)
3988 return OPVCC(63, 29, 0, 0)
3990 return OPVCC(63, 29, 0, 1)
3992 return OPVCC(59, 29, 0, 0)
3994 return OPVCC(59, 29, 0, 1)
3996 case AFMOVS, AFMOVD:
3997 return OPVCC(63, 72, 0, 0) /* load */
3999 return OPVCC(63, 72, 0, 1)
4001 return OPVCC(63, 28, 0, 0)
4003 return OPVCC(63, 28, 0, 1)
4005 return OPVCC(59, 28, 0, 0)
4007 return OPVCC(59, 28, 0, 1)
4009 return OPVCC(63, 25, 0, 0)
4011 return OPVCC(63, 25, 0, 1)
4013 return OPVCC(59, 25, 0, 0)
4015 return OPVCC(59, 25, 0, 1)
4017 return OPVCC(63, 136, 0, 0)
4019 return OPVCC(63, 136, 0, 1)
4021 return OPVCC(63, 40, 0, 0)
4023 return OPVCC(63, 40, 0, 1)
4025 return OPVCC(63, 31, 0, 0)
4027 return OPVCC(63, 31, 0, 1)
4029 return OPVCC(59, 31, 0, 0)
4031 return OPVCC(59, 31, 0, 1)
4033 return OPVCC(63, 30, 0, 0)
4035 return OPVCC(63, 30, 0, 1)
4037 return OPVCC(59, 30, 0, 0)
4039 return OPVCC(59, 30, 0, 1)
4041 return OPVCC(63, 8, 0, 0)
4043 return OPVCC(63, 8, 0, 1)
4045 return OPVCC(59, 24, 0, 0)
4047 return OPVCC(59, 24, 0, 1)
4049 return OPVCC(63, 488, 0, 0)
4051 return OPVCC(63, 488, 0, 1)
4053 return OPVCC(63, 456, 0, 0)
4055 return OPVCC(63, 456, 0, 1)
4057 return OPVCC(63, 424, 0, 0)
4059 return OPVCC(63, 424, 0, 1)
4061 return OPVCC(63, 392, 0, 0)
4063 return OPVCC(63, 392, 0, 1)
4065 return OPVCC(63, 12, 0, 0)
4067 return OPVCC(63, 12, 0, 1)
4069 return OPVCC(63, 26, 0, 0)
4071 return OPVCC(63, 26, 0, 1)
4073 return OPVCC(63, 23, 0, 0)
4075 return OPVCC(63, 23, 0, 1)
4077 return OPVCC(63, 22, 0, 0)
4079 return OPVCC(63, 22, 0, 1)
4081 return OPVCC(59, 22, 0, 0)
4083 return OPVCC(59, 22, 0, 1)
4085 return OPVCC(63, 20, 0, 0)
4087 return OPVCC(63, 20, 0, 1)
4089 return OPVCC(59, 20, 0, 0)
4091 return OPVCC(59, 20, 0, 1)
4094 return OPVCC(31, 982, 0, 0)
4096 return OPVCC(19, 150, 0, 0)
4099 return OPVCC(63, 70, 0, 0)
4101 return OPVCC(63, 70, 0, 1)
4103 return OPVCC(63, 38, 0, 0)
4105 return OPVCC(63, 38, 0, 1)
4108 return OPVCC(31, 75, 0, 0)
4110 return OPVCC(31, 75, 0, 1)
4112 return OPVCC(31, 11, 0, 0)
4114 return OPVCC(31, 11, 0, 1)
4116 return OPVCC(31, 235, 0, 0)
4118 return OPVCC(31, 235, 0, 1)
4120 return OPVCC(31, 235, 1, 0)
4122 return OPVCC(31, 235, 1, 1)
4125 return OPVCC(31, 73, 0, 0)
4127 return OPVCC(31, 73, 0, 1)
4129 return OPVCC(31, 9, 0, 0)
4131 return OPVCC(31, 9, 0, 1)
4133 return OPVCC(31, 233, 0, 0)
4135 return OPVCC(31, 233, 0, 1)
4137 return OPVCC(31, 233, 1, 0)
4139 return OPVCC(31, 233, 1, 1)
4142 return OPVCC(31, 476, 0, 0)
4144 return OPVCC(31, 476, 0, 1)
4146 return OPVCC(31, 104, 0, 0)
4148 return OPVCC(31, 104, 0, 1)
4150 return OPVCC(31, 104, 1, 0)
4152 return OPVCC(31, 104, 1, 1)
4154 return OPVCC(31, 124, 0, 0)
4156 return OPVCC(31, 124, 0, 1)
4158 return OPVCC(31, 444, 0, 0)
4160 return OPVCC(31, 444, 0, 1)
4162 return OPVCC(31, 412, 0, 0)
4164 return OPVCC(31, 412, 0, 1)
4167 return OPVCC(31, 506, 0, 0) /* popcntd - v2.06 */
4169 return OPVCC(31, 378, 0, 0) /* popcntw - v2.06 */
4171 return OPVCC(31, 122, 0, 0) /* popcntb - v2.02 */
4173 return OPVCC(31, 538, 0, 0) /* cnttzw - v3.00 */
4175 return OPVCC(31, 538, 0, 1) /* cnttzw. - v3.00 */
4177 return OPVCC(31, 570, 0, 0) /* cnttzd - v3.00 */
4179 return OPVCC(31, 570, 0, 1) /* cnttzd. - v3.00 */
4182 return OPVCC(19, 50, 0, 0)
4184 return OPVCC(19, 51, 0, 0)
4186 return OPVCC(19, 18, 0, 0)
4188 return OPVCC(19, 274, 0, 0)
4191 return OPVCC(20, 0, 0, 0)
4193 return OPVCC(20, 0, 0, 1)
4195 return OPVCC(23, 0, 0, 0)
4197 return OPVCC(23, 0, 0, 1)
4200 return OPVCC(30, 8, 0, 0)
4202 return OPVCC(30, 9, 0, 0)
4205 return OPVCC(30, 0, 0, 0)
4207 return OPVCC(30, 0, 0, 1)
4209 return OPVCC(30, 0, 0, 0) | 2<<1 // rldicr
4211 return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr.
4214 return OPVCC(17, 1, 0, 0)
4217 return OPVCC(31, 24, 0, 0)
4219 return OPVCC(31, 24, 0, 1)
4221 return OPVCC(31, 27, 0, 0)
4223 return OPVCC(31, 27, 0, 1)
4226 return OPVCC(31, 792, 0, 0)
4228 return OPVCC(31, 792, 0, 1)
4230 return OPVCC(31, 794, 0, 0)
4232 return OPVCC(31, 794, 0, 1)
4235 return OPVCC(31, 536, 0, 0)
4237 return OPVCC(31, 536, 0, 1)
4239 return OPVCC(31, 539, 0, 0)
4241 return OPVCC(31, 539, 0, 1)
4244 return OPVCC(31, 40, 0, 0)
4246 return OPVCC(31, 40, 0, 1)
4248 return OPVCC(31, 40, 1, 0)
4250 return OPVCC(31, 40, 1, 1)
4252 return OPVCC(31, 8, 0, 0)
4254 return OPVCC(31, 8, 0, 1)
4256 return OPVCC(31, 8, 1, 0)
4258 return OPVCC(31, 8, 1, 1)
4260 return OPVCC(31, 136, 0, 0)
4262 return OPVCC(31, 136, 0, 1)
4264 return OPVCC(31, 136, 1, 0)
4266 return OPVCC(31, 136, 1, 1)
4268 return OPVCC(31, 232, 0, 0)
4270 return OPVCC(31, 232, 0, 1)
4272 return OPVCC(31, 232, 1, 0)
4274 return OPVCC(31, 232, 1, 1)
4276 return OPVCC(31, 200, 0, 0)
4278 return OPVCC(31, 200, 0, 1)
4280 return OPVCC(31, 200, 1, 0)
4282 return OPVCC(31, 200, 1, 1)
4285 return OPVCC(31, 598, 0, 0)
4287 return OPVCC(31, 598, 0, 0) | 1<<21
4290 return OPVCC(31, 598, 0, 0) | 2<<21
4293 return OPVCC(31, 306, 0, 0)
4295 return OPVCC(31, 274, 0, 0)
4297 return OPVCC(31, 566, 0, 0)
4299 return OPVCC(31, 498, 0, 0)
4301 return OPVCC(31, 434, 0, 0)
4303 return OPVCC(31, 915, 0, 0)
4305 return OPVCC(31, 851, 0, 0)
4307 return OPVCC(31, 402, 0, 0)
4310 return OPVCC(31, 4, 0, 0)
4312 return OPVCC(31, 68, 0, 0)
4314 /* Vector (VMX/Altivec) instructions */
4315 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4316 /* are enabled starting at POWER6 (ISA 2.05). */
4318 return OPVX(4, 1028, 0, 0) /* vand - v2.03 */
4320 return OPVX(4, 1092, 0, 0) /* vandc - v2.03 */
4322 return OPVX(4, 1412, 0, 0) /* vnand - v2.07 */
4325 return OPVX(4, 1156, 0, 0) /* vor - v2.03 */
4327 return OPVX(4, 1348, 0, 0) /* vorc - v2.07 */
4329 return OPVX(4, 1284, 0, 0) /* vnor - v2.03 */
4331 return OPVX(4, 1220, 0, 0) /* vxor - v2.03 */
4333 return OPVX(4, 1668, 0, 0) /* veqv - v2.07 */
4336 return OPVX(4, 0, 0, 0) /* vaddubm - v2.03 */
4338 return OPVX(4, 64, 0, 0) /* vadduhm - v2.03 */
4340 return OPVX(4, 128, 0, 0) /* vadduwm - v2.03 */
4342 return OPVX(4, 192, 0, 0) /* vaddudm - v2.07 */
4344 return OPVX(4, 256, 0, 0) /* vadduqm - v2.07 */
4347 return OPVX(4, 320, 0, 0) /* vaddcuq - v2.07 */
4349 return OPVX(4, 384, 0, 0) /* vaddcuw - v2.03 */
4352 return OPVX(4, 512, 0, 0) /* vaddubs - v2.03 */
4354 return OPVX(4, 576, 0, 0) /* vadduhs - v2.03 */
4356 return OPVX(4, 640, 0, 0) /* vadduws - v2.03 */
4359 return OPVX(4, 768, 0, 0) /* vaddsbs - v2.03 */
4361 return OPVX(4, 832, 0, 0) /* vaddshs - v2.03 */
4363 return OPVX(4, 896, 0, 0) /* vaddsws - v2.03 */
4366 return OPVX(4, 60, 0, 0) /* vaddeuqm - v2.07 */
4368 return OPVX(4, 61, 0, 0) /* vaddecuq - v2.07 */
4371 return OPVX(4, 776, 0, 0) /* vmulesb - v2.03 */
4373 return OPVX(4, 264, 0, 0) /* vmulosb - v2.03 */
4375 return OPVX(4, 520, 0, 0) /* vmuleub - v2.03 */
4377 return OPVX(4, 8, 0, 0) /* vmuloub - v2.03 */
4379 return OPVX(4, 840, 0, 0) /* vmulesh - v2.03 */
4381 return OPVX(4, 328, 0, 0) /* vmulosh - v2.03 */
4383 return OPVX(4, 584, 0, 0) /* vmuleuh - v2.03 */
4385 return OPVX(4, 72, 0, 0) /* vmulouh - v2.03 */
4387 return OPVX(4, 904, 0, 0) /* vmulesw - v2.07 */
4389 return OPVX(4, 392, 0, 0) /* vmulosw - v2.07 */
4391 return OPVX(4, 648, 0, 0) /* vmuleuw - v2.07 */
4393 return OPVX(4, 136, 0, 0) /* vmulouw - v2.07 */
4395 return OPVX(4, 137, 0, 0) /* vmuluwm - v2.07 */
4398 return OPVX(4, 1032, 0, 0) /* vpmsumb - v2.07 */
4400 return OPVX(4, 1096, 0, 0) /* vpmsumh - v2.07 */
4402 return OPVX(4, 1160, 0, 0) /* vpmsumw - v2.07 */
4404 return OPVX(4, 1224, 0, 0) /* vpmsumd - v2.07 */
4407 return OPVX(4, 35, 0, 0) /* vmsumudm - v3.00b */
4410 return OPVX(4, 1024, 0, 0) /* vsububm - v2.03 */
4412 return OPVX(4, 1088, 0, 0) /* vsubuhm - v2.03 */
4414 return OPVX(4, 1152, 0, 0) /* vsubuwm - v2.03 */
4416 return OPVX(4, 1216, 0, 0) /* vsubudm - v2.07 */
4418 return OPVX(4, 1280, 0, 0) /* vsubuqm - v2.07 */
4421 return OPVX(4, 1344, 0, 0) /* vsubcuq - v2.07 */
4423 return OPVX(4, 1408, 0, 0) /* vsubcuw - v2.03 */
4426 return OPVX(4, 1536, 0, 0) /* vsububs - v2.03 */
4428 return OPVX(4, 1600, 0, 0) /* vsubuhs - v2.03 */
4430 return OPVX(4, 1664, 0, 0) /* vsubuws - v2.03 */
4433 return OPVX(4, 1792, 0, 0) /* vsubsbs - v2.03 */
4435 return OPVX(4, 1856, 0, 0) /* vsubshs - v2.03 */
4437 return OPVX(4, 1920, 0, 0) /* vsubsws - v2.03 */
4440 return OPVX(4, 62, 0, 0) /* vsubeuqm - v2.07 */
4442 return OPVX(4, 63, 0, 0) /* vsubecuq - v2.07 */
4445 return OPVX(4, 4, 0, 0) /* vrlb - v2.03 */
4447 return OPVX(4, 68, 0, 0) /* vrlh - v2.03 */
4449 return OPVX(4, 132, 0, 0) /* vrlw - v2.03 */
4451 return OPVX(4, 196, 0, 0) /* vrld - v2.07 */
4454 return OPVX(4, 1676, 0, 0) /* vmrgow - v2.07 */
4456 return OPVX(4, 1932, 0, 0) /* vmrgew - v2.07 */
4459 return OPVX(4, 260, 0, 0) /* vslh - v2.03 */
4461 return OPVX(4, 324, 0, 0) /* vslh - v2.03 */
4463 return OPVX(4, 388, 0, 0) /* vslw - v2.03 */
4465 return OPVX(4, 452, 0, 0) /* vsl - v2.03 */
4467 return OPVX(4, 1036, 0, 0) /* vsl - v2.03 */
4469 return OPVX(4, 516, 0, 0) /* vsrb - v2.03 */
4471 return OPVX(4, 580, 0, 0) /* vsrh - v2.03 */
4473 return OPVX(4, 644, 0, 0) /* vsrw - v2.03 */
4475 return OPVX(4, 708, 0, 0) /* vsr - v2.03 */
4477 return OPVX(4, 1100, 0, 0) /* vsro - v2.03 */
4479 return OPVX(4, 1476, 0, 0) /* vsld - v2.07 */
4481 return OPVX(4, 1732, 0, 0) /* vsrd - v2.07 */
4484 return OPVX(4, 772, 0, 0) /* vsrab - v2.03 */
4486 return OPVX(4, 836, 0, 0) /* vsrah - v2.03 */
4488 return OPVX(4, 900, 0, 0) /* vsraw - v2.03 */
4490 return OPVX(4, 964, 0, 0) /* vsrad - v2.07 */
4493 return OPVC(4, 1356, 0, 0) /* vbpermq - v2.07 */
4495 return OPVC(4, 1484, 0, 0) /* vbpermd - v3.00 */
4498 return OPVX(4, 1794, 0, 0) /* vclzb - v2.07 */
4500 return OPVX(4, 1858, 0, 0) /* vclzh - v2.07 */
4502 return OPVX(4, 1922, 0, 0) /* vclzw - v2.07 */
4504 return OPVX(4, 1986, 0, 0) /* vclzd - v2.07 */
4507 return OPVX(4, 1795, 0, 0) /* vpopcntb - v2.07 */
4509 return OPVX(4, 1859, 0, 0) /* vpopcnth - v2.07 */
4511 return OPVX(4, 1923, 0, 0) /* vpopcntw - v2.07 */
4513 return OPVX(4, 1987, 0, 0) /* vpopcntd - v2.07 */
4516 return OPVC(4, 6, 0, 0) /* vcmpequb - v2.03 */
4518 return OPVC(4, 6, 0, 1) /* vcmpequb. - v2.03 */
4520 return OPVC(4, 70, 0, 0) /* vcmpequh - v2.03 */
4522 return OPVC(4, 70, 0, 1) /* vcmpequh. - v2.03 */
4524 return OPVC(4, 134, 0, 0) /* vcmpequw - v2.03 */
4526 return OPVC(4, 134, 0, 1) /* vcmpequw. - v2.03 */
4528 return OPVC(4, 199, 0, 0) /* vcmpequd - v2.07 */
4530 return OPVC(4, 199, 0, 1) /* vcmpequd. - v2.07 */
4533 return OPVC(4, 518, 0, 0) /* vcmpgtub - v2.03 */
4535 return OPVC(4, 518, 0, 1) /* vcmpgtub. - v2.03 */
4537 return OPVC(4, 582, 0, 0) /* vcmpgtuh - v2.03 */
4539 return OPVC(4, 582, 0, 1) /* vcmpgtuh. - v2.03 */
4541 return OPVC(4, 646, 0, 0) /* vcmpgtuw - v2.03 */
4543 return OPVC(4, 646, 0, 1) /* vcmpgtuw. - v2.03 */
4545 return OPVC(4, 711, 0, 0) /* vcmpgtud - v2.07 */
4547 return OPVC(4, 711, 0, 1) /* vcmpgtud. v2.07 */
4549 return OPVC(4, 774, 0, 0) /* vcmpgtsb - v2.03 */
4551 return OPVC(4, 774, 0, 1) /* vcmpgtsb. - v2.03 */
4553 return OPVC(4, 838, 0, 0) /* vcmpgtsh - v2.03 */
4555 return OPVC(4, 838, 0, 1) /* vcmpgtsh. - v2.03 */
4557 return OPVC(4, 902, 0, 0) /* vcmpgtsw - v2.03 */
4559 return OPVC(4, 902, 0, 1) /* vcmpgtsw. - v2.03 */
4561 return OPVC(4, 967, 0, 0) /* vcmpgtsd - v2.07 */
4563 return OPVC(4, 967, 0, 1) /* vcmpgtsd. - v2.07 */
4566 return OPVC(4, 263, 0, 0) /* vcmpnezb - v3.00 */
4568 return OPVC(4, 263, 0, 1) /* vcmpnezb. - v3.00 */
4571 return OPVX(4, 43, 0, 0) /* vperm - v2.03 */
4573 return OPVX(4, 45, 0, 0) /* vpermxor - v2.03 */
4576 return OPVX(4, 42, 0, 0) /* vsel - v2.03 */
4579 return OPVX(4, 1288, 0, 0) /* vcipher - v2.07 */
4581 return OPVX(4, 1289, 0, 0) /* vcipherlast - v2.07 */
4583 return OPVX(4, 1352, 0, 0) /* vncipher - v2.07 */
4585 return OPVX(4, 1353, 0, 0) /* vncipherlast - v2.07 */
4587 return OPVX(4, 1480, 0, 0) /* vsbox - v2.07 */
4588 /* End of vector instructions */
4590 /* Vector scalar (VSX) instructions */
4591 /* ISA 2.06 enables these for POWER7. */
4592 case AMFVSRD, AMFVRD, AMFFPRD:
4593 return OPVXX1(31, 51, 0) /* mfvsrd - v2.07 */
4595 return OPVXX1(31, 115, 0) /* mfvsrwz - v2.07 */
4597 return OPVXX1(31, 307, 0) /* mfvsrld - v3.00 */
4599 case AMTVSRD, AMTFPRD, AMTVRD:
4600 return OPVXX1(31, 179, 0) /* mtvsrd - v2.07 */
4602 return OPVXX1(31, 211, 0) /* mtvsrwa - v2.07 */
4604 return OPVXX1(31, 243, 0) /* mtvsrwz - v2.07 */
4606 return OPVXX1(31, 435, 0) /* mtvsrdd - v3.00 */
4608 return OPVXX1(31, 403, 0) /* mtvsrws - v3.00 */
4611 return OPVXX3(60, 130, 0) /* xxland - v2.06 */
4613 return OPVXX3(60, 138, 0) /* xxlandc - v2.06 */
4615 return OPVXX3(60, 186, 0) /* xxleqv - v2.07 */
4617 return OPVXX3(60, 178, 0) /* xxlnand - v2.07 */
4620 return OPVXX3(60, 170, 0) /* xxlorc - v2.07 */
4622 return OPVXX3(60, 162, 0) /* xxlnor - v2.06 */
4624 return OPVXX3(60, 146, 0) /* xxlor - v2.06 */
4626 return OPVXX3(60, 154, 0) /* xxlxor - v2.06 */
4629 return OPVXX4(60, 3, 0) /* xxsel - v2.06 */
4632 return OPVXX3(60, 18, 0) /* xxmrghw - v2.06 */
4634 return OPVXX3(60, 50, 0) /* xxmrglw - v2.06 */
4637 return OPVXX2(60, 164, 0) /* xxspltw - v2.06 */
4640 return OPVXX3(60, 26, 0) /* xxperm - v2.06 */
4642 return OPVXX3(60, 10, 0) /* xxpermdi - v2.06 */
4645 return OPVXX3(60, 2, 0) /* xxsldwi - v2.06 */
4648 return OPVXX2(60, 265, 0) /* xscvdpsp - v2.06 */
4650 return OPVXX2(60, 329, 0) /* xscvspdp - v2.06 */
4652 return OPVXX2(60, 267, 0) /* xscvdpspn - v2.07 */
4654 return OPVXX2(60, 331, 0) /* xscvspdpn - v2.07 */
4657 return OPVXX2(60, 393, 0) /* xvcvdpsp - v2.06 */
4659 return OPVXX2(60, 457, 0) /* xvcvspdp - v2.06 */
4662 return OPVXX2(60, 344, 0) /* xscvdpsxds - v2.06 */
4664 return OPVXX2(60, 88, 0) /* xscvdpsxws - v2.06 */
4666 return OPVXX2(60, 328, 0) /* xscvdpuxds - v2.06 */
4668 return OPVXX2(60, 72, 0) /* xscvdpuxws - v2.06 */
4671 return OPVXX2(60, 376, 0) /* xscvsxddp - v2.06 */
4673 return OPVXX2(60, 360, 0) /* xscvuxddp - v2.06 */
4675 return OPVXX2(60, 312, 0) /* xscvsxdsp - v2.06 */
4677 return OPVXX2(60, 296, 0) /* xscvuxdsp - v2.06 */
4680 return OPVXX2(60, 472, 0) /* xvcvdpsxds - v2.06 */
4682 return OPVXX2(60, 216, 0) /* xvcvdpsxws - v2.06 */
4684 return OPVXX2(60, 456, 0) /* xvcvdpuxds - v2.06 */
4686 return OPVXX2(60, 200, 0) /* xvcvdpuxws - v2.06 */
4688 return OPVXX2(60, 408, 0) /* xvcvspsxds - v2.07 */
4690 return OPVXX2(60, 152, 0) /* xvcvspsxws - v2.07 */
4692 return OPVXX2(60, 392, 0) /* xvcvspuxds - v2.07 */
4694 return OPVXX2(60, 136, 0) /* xvcvspuxws - v2.07 */
4697 return OPVXX2(60, 504, 0) /* xvcvsxddp - v2.06 */
4699 return OPVXX2(60, 248, 0) /* xvcvsxwdp - v2.06 */
4701 return OPVXX2(60, 488, 0) /* xvcvuxddp - v2.06 */
4703 return OPVXX2(60, 232, 0) /* xvcvuxwdp - v2.06 */
4705 return OPVXX2(60, 440, 0) /* xvcvsxdsp - v2.06 */
4707 return OPVXX2(60, 184, 0) /* xvcvsxwsp - v2.06 */
4709 return OPVXX2(60, 424, 0) /* xvcvuxdsp - v2.06 */
4711 return OPVXX2(60, 168, 0) /* xvcvuxwsp - v2.06 */
4712 /* End of VSX instructions */
4715 return OPVX(4, 48, 0, 0) /* maddhd - v3.00 */
4717 return OPVX(4, 49, 0, 0) /* maddhdu - v3.00 */
4719 return OPVX(4, 51, 0, 0) /* maddld - v3.00 */
4722 return OPVCC(31, 316, 0, 0)
4724 return OPVCC(31, 316, 0, 1)
4727 c.ctxt.Diag("bad r/r, r/r/r or r/r/r/r opcode %v", a)
4731 func (c *ctxt9) opirrr(a obj.As) uint32 {
4733 /* Vector (VMX/Altivec) instructions */
4734 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4735 /* are enabled starting at POWER6 (ISA 2.05). */
4737 return OPVX(4, 44, 0, 0) /* vsldoi - v2.03 */
4740 c.ctxt.Diag("bad i/r/r/r opcode %v", a)
4744 func (c *ctxt9) opiirr(a obj.As) uint32 {
4746 /* Vector (VMX/Altivec) instructions */
4747 /* ISA 2.07 enables these for POWER8 and beyond. */
4749 return OPVX(4, 1666, 0, 0) /* vshasigmaw - v2.07 */
4751 return OPVX(4, 1730, 0, 0) /* vshasigmad - v2.07 */
4754 c.ctxt.Diag("bad i/i/r/r opcode %v", a)
4758 func (c *ctxt9) opirr(a obj.As) uint32 {
4761 return OPVCC(14, 0, 0, 0)
4763 return OPVCC(12, 0, 0, 0)
4765 return OPVCC(13, 0, 0, 0)
4767 return OPVCC(15, 0, 0, 0) /* ADDIS */
4770 return OPVCC(28, 0, 0, 0)
4772 return OPVCC(29, 0, 0, 0) /* ANDIS. */
4775 return OPVCC(18, 0, 0, 0)
4777 return OPVCC(18, 0, 0, 0) | 1
4779 return OPVCC(18, 0, 0, 0) | 1
4781 return OPVCC(18, 0, 0, 0) | 1
4783 return OPVCC(16, 0, 0, 0)
4785 return OPVCC(16, 0, 0, 0) | 1
4788 return AOP_RRR(16<<26, 12, 2, 0)
4790 return AOP_RRR(16<<26, 4, 0, 0)
4792 return AOP_RRR(16<<26, 12, 1, 0)
4794 return AOP_RRR(16<<26, 4, 1, 0)
4796 return AOP_RRR(16<<26, 12, 0, 0)
4798 return AOP_RRR(16<<26, 4, 2, 0)
4800 return AOP_RRR(16<<26, 4, 3, 0) // apparently unordered-clear
4802 return AOP_RRR(16<<26, 12, 3, 0) // apparently unordered-set
4805 return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */
4807 return OPVCC(10, 0, 0, 0) | 1<<21
4809 return OPVCC(11, 0, 0, 0) /* L=0 */
4811 return OPVCC(10, 0, 0, 0)
4813 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
4816 return OPVCC(31, 597, 0, 0)
4819 return OPVCC(31, 774, 0, 0) /* copy - v3.00 */
4821 return OPVCC(31, 902, 0, 1) /* paste. - v3.00 */
4823 return OPVCC(31, 755, 0, 0) /* darn - v3.00 */
4826 return OPVCC(7, 0, 0, 0)
4829 return OPVCC(24, 0, 0, 0)
4831 return OPVCC(25, 0, 0, 0) /* ORIS */
4834 return OPVCC(20, 0, 0, 0) /* rlwimi */
4836 return OPVCC(20, 0, 0, 1)
4838 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
4840 return OPVCC(30, 0, 0, 1) | 3<<2
4842 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
4844 return OPVCC(30, 0, 0, 1) | 3<<2
4846 return OPVCC(21, 0, 0, 0) /* rlwinm */
4848 return OPVCC(21, 0, 0, 1)
4851 return OPVCC(30, 0, 0, 0) /* rldicl */
4853 return OPVCC(30, 0, 0, 1)
4855 return OPVCC(30, 1, 0, 0) /* rldicr */
4857 return OPVCC(30, 1, 0, 1)
4859 return OPVCC(30, 0, 0, 0) | 2<<2
4861 return OPVCC(30, 0, 0, 1) | 2<<2
4864 return OPVCC(31, 824, 0, 0)
4866 return OPVCC(31, 824, 0, 1)
4868 return OPVCC(31, (413 << 1), 0, 0)
4870 return OPVCC(31, (413 << 1), 0, 1)
4873 return OPVCC(31, 725, 0, 0)
4876 return OPVCC(8, 0, 0, 0)
4879 return OPVCC(3, 0, 0, 0)
4881 return OPVCC(2, 0, 0, 0)
4883 /* Vector (VMX/Altivec) instructions */
4884 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4885 /* are enabled starting at POWER6 (ISA 2.05). */
4887 return OPVX(4, 524, 0, 0) /* vspltb - v2.03 */
4889 return OPVX(4, 588, 0, 0) /* vsplth - v2.03 */
4891 return OPVX(4, 652, 0, 0) /* vspltw - v2.03 */
4894 return OPVX(4, 780, 0, 0) /* vspltisb - v2.03 */
4896 return OPVX(4, 844, 0, 0) /* vspltish - v2.03 */
4898 return OPVX(4, 908, 0, 0) /* vspltisw - v2.03 */
4899 /* End of vector instructions */
4902 return OPVCC(63, 128, 0, 0) /* ftdiv - v2.06 */
4904 return OPVCC(63, 160, 0, 0) /* ftsqrt - v2.06 */
4907 return OPVCC(26, 0, 0, 0) /* XORIL */
4909 return OPVCC(27, 0, 0, 0) /* XORIS */
4912 c.ctxt.Diag("bad opcode i/r or i/r/r %v", a)
4919 func (c *ctxt9) opload(a obj.As) uint32 {
4922 return OPVCC(58, 0, 0, 0) /* ld */
4924 return OPVCC(58, 0, 0, 1) /* ldu */
4926 return OPVCC(32, 0, 0, 0) /* lwz */
4928 return OPVCC(33, 0, 0, 0) /* lwzu */
4930 return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */
4932 return OPDQ(61, 1, 0) /* lxv - ISA v3.00 */
4936 return OPVCC(34, 0, 0, 0)
4939 case AMOVBU, AMOVBZU:
4940 return OPVCC(35, 0, 0, 0)
4942 return OPVCC(50, 0, 0, 0)
4944 return OPVCC(51, 0, 0, 0)
4946 return OPVCC(48, 0, 0, 0)
4948 return OPVCC(49, 0, 0, 0)
4950 return OPVCC(42, 0, 0, 0)
4952 return OPVCC(43, 0, 0, 0)
4954 return OPVCC(40, 0, 0, 0)
4956 return OPVCC(41, 0, 0, 0)
4958 return OPVCC(46, 0, 0, 0) /* lmw */
4961 c.ctxt.Diag("bad load opcode %v", a)
4966 * indexed load a(b),d
4968 func (c *ctxt9) oploadx(a obj.As) uint32 {
4971 return OPVCC(31, 23, 0, 0) /* lwzx */
4973 return OPVCC(31, 55, 0, 0) /* lwzux */
4975 return OPVCC(31, 341, 0, 0) /* lwax */
4977 return OPVCC(31, 373, 0, 0) /* lwaux */
4980 return OPVCC(31, 87, 0, 0) /* lbzx */
4982 case AMOVBU, AMOVBZU:
4983 return OPVCC(31, 119, 0, 0) /* lbzux */
4985 return OPVCC(31, 599, 0, 0) /* lfdx */
4987 return OPVCC(31, 631, 0, 0) /* lfdux */
4989 return OPVCC(31, 535, 0, 0) /* lfsx */
4991 return OPVCC(31, 567, 0, 0) /* lfsux */
4993 return OPVCC(31, 855, 0, 0) /* lfiwax - power6, isa 2.05 */
4995 return OPVCC(31, 887, 0, 0) /* lfiwzx - power7, isa 2.06 */
4997 return OPVCC(31, 343, 0, 0) /* lhax */
4999 return OPVCC(31, 375, 0, 0) /* lhaux */
5001 return OPVCC(31, 790, 0, 0) /* lhbrx */
5003 return OPVCC(31, 534, 0, 0) /* lwbrx */
5005 return OPVCC(31, 532, 0, 0) /* ldbrx */
5007 return OPVCC(31, 279, 0, 0) /* lhzx */
5009 return OPVCC(31, 311, 0, 0) /* lhzux */
5011 return OPVCC(31, 310, 0, 0) /* eciwx */
5013 return OPVCC(31, 52, 0, 0) /* lbarx */
5015 return OPVCC(31, 116, 0, 0) /* lharx */
5017 return OPVCC(31, 20, 0, 0) /* lwarx */
5019 return OPVCC(31, 84, 0, 0) /* ldarx */
5021 return OPVCC(31, 533, 0, 0) /* lswx */
5023 return OPVCC(31, 21, 0, 0) /* ldx */
5025 return OPVCC(31, 53, 0, 0) /* ldux */
5027 return OPVCC(31, 309, 0, 0) /* ldmx */
5029 /* Vector (VMX/Altivec) instructions */
5030 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
5031 /* are enabled starting at POWER6 (ISA 2.05). */
5033 return OPVCC(31, 7, 0, 0) /* lvebx - v2.03 */
5035 return OPVCC(31, 39, 0, 0) /* lvehx - v2.03 */
5037 return OPVCC(31, 71, 0, 0) /* lvewx - v2.03 */
5039 return OPVCC(31, 103, 0, 0) /* lvx - v2.03 */
5041 return OPVCC(31, 359, 0, 0) /* lvxl - v2.03 */
5043 return OPVCC(31, 6, 0, 0) /* lvsl - v2.03 */
5045 return OPVCC(31, 38, 0, 0) /* lvsr - v2.03 */
5046 /* End of vector instructions */
5048 /* Vector scalar (VSX) instructions */
5049 /* ISA 2.06 enables these for POWER7. */
5051 return OPVXX1(31, 844, 0) /* lxvd2x - v2.06 */
5053 return OPVXX1(31, 780, 0) /* lxvw4x - v2.06 */
5055 return OPVXX1(31, 812, 0) /* lxvh8x - v3.00 */
5057 return OPVXX1(31, 876, 0) /* lxvb16x - v3.00 */
5059 return OPVXX1(31, 332, 0) /* lxvdsx - v2.06 */
5061 return OPVXX1(31, 588, 0) /* lxsdx - v2.06 */
5063 return OPVXX1(31, 76, 0) /* lxsiwax - v2.07 */
5065 return OPVXX1(31, 12, 0) /* lxsiwzx - v2.07 */
5066 /* End of vector scalar instructions */
5070 c.ctxt.Diag("bad loadx opcode %v", a)
5077 func (c *ctxt9) opstore(a obj.As) uint32 {
5080 return OPVCC(38, 0, 0, 0) /* stb */
5082 case AMOVBU, AMOVBZU:
5083 return OPVCC(39, 0, 0, 0) /* stbu */
5085 return OPVCC(54, 0, 0, 0) /* stfd */
5087 return OPVCC(55, 0, 0, 0) /* stfdu */
5089 return OPVCC(52, 0, 0, 0) /* stfs */
5091 return OPVCC(53, 0, 0, 0) /* stfsu */
5094 return OPVCC(44, 0, 0, 0) /* sth */
5096 case AMOVHZU, AMOVHU:
5097 return OPVCC(45, 0, 0, 0) /* sthu */
5099 return OPVCC(47, 0, 0, 0) /* stmw */
5101 return OPVCC(31, 725, 0, 0) /* stswi */
5104 return OPVCC(36, 0, 0, 0) /* stw */
5106 case AMOVWZU, AMOVWU:
5107 return OPVCC(37, 0, 0, 0) /* stwu */
5109 return OPVCC(62, 0, 0, 0) /* std */
5111 return OPVCC(62, 0, 0, 1) /* stdu */
5113 return OPDQ(61, 5, 0) /* stxv */
5116 c.ctxt.Diag("unknown store opcode %v", a)
5121 * indexed store s,a(b)
5123 func (c *ctxt9) opstorex(a obj.As) uint32 {
5126 return OPVCC(31, 215, 0, 0) /* stbx */
5128 case AMOVBU, AMOVBZU:
5129 return OPVCC(31, 247, 0, 0) /* stbux */
5131 return OPVCC(31, 727, 0, 0) /* stfdx */
5133 return OPVCC(31, 759, 0, 0) /* stfdux */
5135 return OPVCC(31, 663, 0, 0) /* stfsx */
5137 return OPVCC(31, 695, 0, 0) /* stfsux */
5139 return OPVCC(31, 983, 0, 0) /* stfiwx */
5142 return OPVCC(31, 407, 0, 0) /* sthx */
5144 return OPVCC(31, 918, 0, 0) /* sthbrx */
5146 case AMOVHZU, AMOVHU:
5147 return OPVCC(31, 439, 0, 0) /* sthux */
5150 return OPVCC(31, 151, 0, 0) /* stwx */
5152 case AMOVWZU, AMOVWU:
5153 return OPVCC(31, 183, 0, 0) /* stwux */
5155 return OPVCC(31, 661, 0, 0) /* stswx */
5157 return OPVCC(31, 662, 0, 0) /* stwbrx */
5159 return OPVCC(31, 660, 0, 0) /* stdbrx */
5161 return OPVCC(31, 694, 0, 1) /* stbcx. */
5163 return OPVCC(31, 150, 0, 1) /* stwcx. */
5165 return OPVCC(31, 214, 0, 1) /* stwdx. */
5167 return OPVCC(31, 438, 0, 0) /* ecowx */
5169 return OPVCC(31, 149, 0, 0) /* stdx */
5171 return OPVCC(31, 181, 0, 0) /* stdux */
5173 /* Vector (VMX/Altivec) instructions */
5174 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
5175 /* are enabled starting at POWER6 (ISA 2.05). */
5177 return OPVCC(31, 135, 0, 0) /* stvebx - v2.03 */
5179 return OPVCC(31, 167, 0, 0) /* stvehx - v2.03 */
5181 return OPVCC(31, 199, 0, 0) /* stvewx - v2.03 */
5183 return OPVCC(31, 231, 0, 0) /* stvx - v2.03 */
5185 return OPVCC(31, 487, 0, 0) /* stvxl - v2.03 */
5186 /* End of vector instructions */
5188 /* Vector scalar (VSX) instructions */
5189 /* ISA 2.06 enables these for POWER7. */
5191 return OPVXX1(31, 972, 0) /* stxvd2x - v2.06 */
5193 return OPVXX1(31, 908, 0) /* stxvw4x - v2.06 */
5195 return OPVXX1(31, 940, 0) /* stxvh8x - v3.00 */
5197 return OPVXX1(31, 1004, 0) /* stxvb16x - v3.00 */
5200 return OPVXX1(31, 716, 0) /* stxsdx - v2.06 */
5203 return OPVXX1(31, 140, 0) /* stxsiwx - v2.07 */
5205 /* End of vector scalar instructions */
5209 c.ctxt.Diag("unknown storex opcode %v", a)