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 {AMTFSB0, C_SCON, C_NONE, C_NONE, C_NONE, 52, 4, 0},
382 {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_FREG, 53, 4, 0},
383 {AMOVFL, C_FREG, C_NONE, C_NONE, C_FPSCR, 64, 4, 0},
384 {AMOVFL, C_FREG, C_NONE, C_LCON, C_FPSCR, 64, 4, 0},
385 {AMOVFL, C_LCON, C_NONE, C_NONE, C_FPSCR, 65, 4, 0},
386 {AMOVD, C_MSR, C_NONE, C_NONE, C_REG, 54, 4, 0}, /* mfmsr */
387 {AMOVD, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsrd */
388 {AMOVWZ, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsr */
390 /* Other ISA 2.05+ instructions */
391 {APOPCNTD, C_REG, C_NONE, C_NONE, C_REG, 93, 4, 0}, /* population count, x-form */
392 {ACMPB, C_REG, C_REG, C_NONE, C_REG, 92, 4, 0}, /* compare byte, x-form */
393 {ACMPEQB, C_REG, C_REG, C_NONE, C_CREG, 92, 4, 0}, /* compare equal byte, x-form, ISA 3.0 */
394 {ACMPEQB, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
395 {AFTDIV, C_FREG, C_FREG, C_NONE, C_SCON, 92, 4, 0}, /* floating test for sw divide, x-form */
396 {AFTSQRT, C_FREG, C_NONE, C_NONE, C_SCON, 93, 4, 0}, /* floating test for sw square root, x-form */
397 {ACOPY, C_REG, C_NONE, C_NONE, C_REG, 92, 4, 0}, /* copy/paste facility, x-form */
398 {ADARN, C_SCON, C_NONE, C_NONE, C_REG, 92, 4, 0}, /* deliver random number, x-form */
399 {ALDMX, C_SOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, /* load doubleword monitored, x-form */
400 {AMADDHD, C_REG, C_REG, C_REG, C_REG, 83, 4, 0}, /* multiply-add high/low doubleword, va-form */
401 {AADDEX, C_REG, C_REG, C_SCON, C_REG, 94, 4, 0}, /* add extended using alternate carry, z23-form */
402 {ACRAND, C_CREG, C_NONE, C_NONE, C_CREG, 2, 4, 0}, /* logical ops for condition registers xl-form */
404 /* Vector instructions */
407 {ALV, C_SOREG, C_NONE, C_NONE, C_VREG, 45, 4, 0}, /* vector load, x-form */
410 {ASTV, C_VREG, C_NONE, C_NONE, C_SOREG, 44, 4, 0}, /* vector store, x-form */
413 {AVAND, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector and, vx-form */
414 {AVOR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector or, vx-form */
417 {AVADDUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned modulo, vx-form */
418 {AVADDCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add & write carry unsigned, vx-form */
419 {AVADDUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned saturate, vx-form */
420 {AVADDSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add signed saturate, vx-form */
421 {AVADDE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector add extended, va-form */
423 /* Vector subtract */
424 {AVSUBUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned modulo, vx-form */
425 {AVSUBCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract & write carry unsigned, vx-form */
426 {AVSUBUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned saturate, vx-form */
427 {AVSUBSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract signed saturate, vx-form */
428 {AVSUBE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector subtract extended, va-form */
430 /* Vector multiply */
431 {AVMULESB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 9}, /* vector multiply, vx-form */
432 {AVPMSUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector polynomial multiply & sum, vx-form */
433 {AVMSUMUDM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector multiply-sum, va-form */
436 {AVR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector rotate, vx-form */
439 {AVS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector shift, vx-form */
440 {AVSA, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector shift algebraic, vx-form */
441 {AVSOI, C_ANDCON, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector shift by octet immediate, va-form */
444 {AVCLZ, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector count leading zeros, vx-form */
445 {AVPOPCNT, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector population count, vx-form */
448 {AVCMPEQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare equal, vc-form */
449 {AVCMPGT, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare greater than, vc-form */
450 {AVCMPNEZB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare not equal, vx-form */
453 {AVMRGOW, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector merge odd word, vx-form */
456 {AVPERM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector permute, va-form */
458 /* Vector bit permute */
459 {AVBPERMQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector bit permute, vx-form */
462 {AVSEL, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector select, va-form */
465 {AVSPLTB, C_SCON, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector splat, vx-form */
466 {AVSPLTB, C_ADDCON, C_VREG, C_NONE, C_VREG, 82, 4, 0},
467 {AVSPLTISB, C_SCON, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector splat immediate, vx-form */
468 {AVSPLTISB, C_ADDCON, C_NONE, C_NONE, C_VREG, 82, 4, 0},
471 {AVCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES cipher, vx-form */
472 {AVNCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES inverse cipher, vx-form */
473 {AVSBOX, C_VREG, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector AES subbytes, vx-form */
476 {AVSHASIGMA, C_ANDCON, C_VREG, C_ANDCON, C_VREG, 82, 4, 0}, /* vector SHA sigma, vx-form */
478 /* VSX vector load */
479 {ALXVD2X, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx vector load, xx1-form */
480 {ALXV, C_SOREG, C_NONE, C_NONE, C_VSREG, 96, 4, 0}, /* vsx vector load, dq-form */
481 {ALXVL, C_REG, C_REG, C_NONE, C_VSREG, 98, 4, 0}, /* vsx vector load length */
483 /* VSX vector store */
484 {ASTXVD2X, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx vector store, xx1-form */
485 {ASTXV, C_VSREG, C_NONE, C_NONE, C_SOREG, 97, 4, 0}, /* vsx vector store, dq-form */
486 {ASTXVL, C_VSREG, C_REG, C_NONE, C_REG, 99, 4, 0}, /* vsx vector store with length x-form */
488 /* VSX scalar load */
489 {ALXSDX, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar load, xx1-form */
491 /* VSX scalar store */
492 {ASTXSDX, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar store, xx1-form */
494 /* VSX scalar as integer load */
495 {ALXSIWAX, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar as integer load, xx1-form */
497 /* VSX scalar store as integer */
498 {ASTXSIWX, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar as integer store, xx1-form */
500 /* VSX move from VSR */
501 {AMFVSRD, C_VSREG, C_NONE, C_NONE, C_REG, 88, 4, 0}, /* vsx move from vsr, xx1-form */
502 {AMFVSRD, C_FREG, C_NONE, C_NONE, C_REG, 88, 4, 0},
503 {AMFVSRD, C_VREG, C_NONE, C_NONE, C_REG, 88, 4, 0},
505 /* VSX move to VSR */
506 {AMTVSRD, C_REG, C_NONE, C_NONE, C_VSREG, 88, 4, 0}, /* vsx move to vsr, xx1-form */
507 {AMTVSRD, C_REG, C_REG, C_NONE, C_VSREG, 88, 4, 0},
508 {AMTVSRD, C_REG, C_NONE, C_NONE, C_FREG, 88, 4, 0},
509 {AMTVSRD, C_REG, C_NONE, C_NONE, C_VREG, 88, 4, 0},
512 {AXXLAND, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx and, xx3-form */
513 {AXXLOR, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx or, xx3-form */
516 {AXXSEL, C_VSREG, C_VSREG, C_VSREG, C_VSREG, 91, 4, 0}, /* vsx select, xx4-form */
519 {AXXMRGHW, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx merge, xx3-form */
522 {AXXSPLTW, C_VSREG, C_NONE, C_SCON, C_VSREG, 89, 4, 0}, /* vsx splat, xx2-form */
523 {AXXSPLTIB, C_SCON, C_NONE, C_NONE, C_VSREG, 100, 4, 0}, /* vsx splat, xx2-form */
526 {AXXPERM, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx permute, xx3-form */
529 {AXXSLDWI, C_VSREG, C_VSREG, C_SCON, C_VSREG, 90, 4, 0}, /* vsx shift immediate, xx3-form */
531 /* VSX reverse bytes */
532 {AXXBRQ, C_VSREG, C_NONE, C_NONE, C_VSREG, 101, 4, 0}, /* vsx reverse bytes */
534 /* VSX scalar FP-FP conversion */
535 {AXSCVDPSP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-fp conversion, xx2-form */
537 /* VSX vector FP-FP conversion */
538 {AXVCVDPSP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-fp conversion, xx2-form */
540 /* VSX scalar FP-integer conversion */
541 {AXSCVDPSXDS, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-integer conversion, xx2-form */
543 /* VSX scalar integer-FP conversion */
544 {AXSCVSXDDP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar integer-fp conversion, xx2-form */
546 /* VSX vector FP-integer conversion */
547 {AXVCVDPSXDS, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-integer conversion, xx2-form */
549 /* VSX vector integer-FP conversion */
550 {AXVCVSXDDP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector integer-fp conversion, xx2-form */
552 /* 64-bit special registers */
553 {AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
554 {AMOVD, C_REG, C_NONE, C_NONE, C_LR, 66, 4, 0},
555 {AMOVD, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
556 {AMOVD, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
557 {AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
558 {AMOVD, C_LR, C_NONE, C_NONE, C_REG, 66, 4, 0},
559 {AMOVD, C_CTR, C_NONE, C_NONE, C_REG, 66, 4, 0},
560 {AMOVD, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
562 /* 32-bit special registers (gloss over sign-extension or not?) */
563 {AMOVW, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
564 {AMOVW, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
565 {AMOVW, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
566 {AMOVW, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
567 {AMOVW, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
568 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
569 {AMOVWZ, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
570 {AMOVWZ, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
571 {AMOVWZ, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
572 {AMOVWZ, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
573 {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_CREG, 73, 4, 0},
574 {AMOVFL, C_CREG, C_NONE, C_NONE, C_CREG, 67, 4, 0},
575 {AMOVW, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
576 {AMOVWZ, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
577 {AMOVFL, C_REG, C_NONE, C_NONE, C_LCON, 69, 4, 0},
578 {AMOVFL, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
579 {AMOVW, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
580 {AMOVWZ, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
581 {ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
582 {ACMP, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
583 {ACMP, C_REG, C_NONE, C_NONE, C_ADDCON, 71, 4, 0},
584 {ACMP, C_REG, C_REG, C_NONE, C_ADDCON, 71, 4, 0},
585 {ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
586 {ACMPU, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
587 {ACMPU, C_REG, C_NONE, C_NONE, C_ANDCON, 71, 4, 0},
588 {ACMPU, C_REG, C_REG, C_NONE, C_ANDCON, 71, 4, 0},
589 {AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 4, 0},
590 {AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 4, 0},
591 {ATW, C_LCON, C_REG, C_NONE, C_REG, 60, 4, 0},
592 {ATW, C_LCON, C_REG, C_NONE, C_ADDCON, 61, 4, 0},
593 {ADCBF, C_ZOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
594 {ADCBF, C_SOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
595 {ADCBF, C_ZOREG, C_REG, C_NONE, C_SCON, 43, 4, 0},
596 {ADCBF, C_SOREG, C_NONE, C_NONE, C_SCON, 43, 4, 0},
597 {AECOWX, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
598 {AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
599 {AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
600 {AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
601 {ALDAR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
602 {ALDAR, C_ZOREG, C_NONE, C_ANDCON, C_REG, 45, 4, 0},
603 {AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
604 {ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},
605 {ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0},
606 {ASLBMFEE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
607 {ASLBMTE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
608 {ASTSW, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
609 {ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},
610 {ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
611 {ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
612 {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
613 {obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
614 {obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
615 {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
616 {obj.ANOP, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0}, // NOP operand variations added for #40689
617 {obj.ANOP, C_REG, C_NONE, C_NONE, C_NONE, 0, 0, 0}, // to preserve previous behavior
618 {obj.ANOP, C_FREG, C_NONE, C_NONE, C_NONE, 0, 0, 0},
619 {obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
620 {obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
621 {obj.APCALIGN, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0}, // align code
623 {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},
626 var oprange [ALAST & obj.AMask][]Optab
628 var xcmp [C_NCLASS][C_NCLASS]bool
630 // padding bytes to add to align code as requested
631 func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int {
632 // For 16 and 32 byte alignment, there is a tradeoff
633 // between aligning the code and adding too many NOPs.
640 // Align to 16 bytes if possible but add at
649 // Align to 32 bytes if possible but add at
659 // When 32 byte alignment is requested on Linux,
660 // promote the function's alignment to 32. On AIX
661 // the function alignment is not changed which might
662 // result in 16 byte alignment but that is still fine.
663 // TODO: alignment on AIX
664 if ctxt.Headtype != objabi.Haix && cursym.Func.Align < 32 {
665 cursym.Func.Align = 32
668 ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a)
673 func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
674 p := cursym.Func.Text
675 if p == nil || p.Link == nil { // handle external functions and ELF section symbols
679 if oprange[AANDN&obj.AMask] == nil {
680 ctxt.Diag("ppc64 ops not initialized, call ppc64.buildop first")
683 c := ctxt9{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset)}
690 for p = p.Link; p != nil; p = p.Link {
695 if p.As == obj.APCALIGN {
696 a := c.vregoff(&p.From)
697 m = addpad(pc, a, ctxt, cursym)
699 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
700 ctxt.Diag("zero-width instruction\n%v", p)
711 * if any procedure is large enough to
712 * generate a large SBRA branch, then
713 * generate extra passes putting branches
714 * around jmps to fix. this is rare.
723 for p = c.cursym.Func.Text.Link; p != nil; p = p.Link {
727 // very large conditional branches
728 if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
729 otxt = p.Pcond.Pc - pc
730 if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
735 q.To.Type = obj.TYPE_BRANCH
742 q.To.Type = obj.TYPE_BRANCH
743 q.Pcond = q.Link.Link
753 if p.As == obj.APCALIGN {
754 a := c.vregoff(&p.From)
755 m = addpad(pc, a, ctxt, cursym)
757 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
758 ctxt.Diag("zero-width instruction\n%v", p)
770 if r := pc & funcAlignMask; r != 0 {
777 * lay out the code, emitting code and data relocations.
780 c.cursym.Grow(c.cursym.Size)
785 for p := c.cursym.Func.Text.Link; p != nil; p = p.Link {
788 if int(o.size) > 4*len(out) {
789 log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)
791 // asmout is not set up to add large amounts of padding
792 if o.type_ == 0 && p.As == obj.APCALIGN {
793 pad := LOP_RRR(OP_OR, REGZERO, REGZERO, REGZERO)
794 aln := c.vregoff(&p.From)
795 v := addpad(p.Pc, aln, c.ctxt, c.cursym)
797 // Same padding instruction for all
798 for i = 0; i < int32(v/4); i++ {
799 c.ctxt.Arch.ByteOrder.PutUint32(bp, pad)
804 c.asmout(p, o, out[:])
805 for i = 0; i < int32(o.size/4); i++ {
806 c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
813 func isint32(v int64) bool {
814 return int64(int32(v)) == v
817 func isuint32(v uint64) bool {
818 return uint64(uint32(v)) == v
821 func (c *ctxt9) aclass(a *obj.Addr) int {
827 if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
830 if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
833 if REG_V0 <= a.Reg && a.Reg <= REG_V31 {
836 if REG_VS0 <= a.Reg && a.Reg <= REG_VS63 {
839 if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR {
842 if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
857 if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
860 if a.Reg == REG_FPSCR {
863 if a.Reg == REG_MSR {
870 case obj.NAME_EXTERN,
875 c.instoffset = a.Offset
876 if a.Sym != nil { // use relocation
877 if a.Sym.Type == objabi.STLSBSS {
878 if c.ctxt.Flag_shared {
888 case obj.NAME_GOTREF:
891 case obj.NAME_TOCREF:
895 c.instoffset = int64(c.autosize) + a.Offset
896 if c.instoffset >= -BIG && c.instoffset < BIG {
902 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
903 if c.instoffset >= -BIG && c.instoffset < BIG {
909 c.instoffset = a.Offset
910 if c.instoffset == 0 {
913 if c.instoffset >= -BIG && c.instoffset < BIG {
921 case obj.TYPE_TEXTSIZE:
924 case obj.TYPE_FCONST:
925 // The only cases where FCONST will occur are with float64 +/- 0.
926 // All other float constants are generated in memory.
927 f64 := a.Val.(float64)
929 if math.Signbit(f64) {
934 log.Fatalf("Unexpected nonzero FCONST operand %v", a)
940 c.instoffset = a.Offset
942 if -BIG <= c.instoffset && c.instoffset <= BIG {
945 if isint32(c.instoffset) {
951 case obj.NAME_EXTERN,
958 c.instoffset = a.Offset
960 /* not sure why this barfs */
964 c.instoffset = int64(c.autosize) + a.Offset
965 if c.instoffset >= -BIG && c.instoffset < BIG {
971 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
972 if c.instoffset >= -BIG && c.instoffset < BIG {
981 if c.instoffset >= 0 {
982 if c.instoffset == 0 {
985 if c.instoffset <= 0x7fff {
988 if c.instoffset <= 0xffff {
991 if c.instoffset&0xffff == 0 && isuint32(uint64(c.instoffset)) { /* && (instoffset & (1<<31)) == 0) */
994 if isint32(c.instoffset) || isuint32(uint64(c.instoffset)) {
1000 if c.instoffset >= -0x8000 {
1003 if c.instoffset&0xffff == 0 && isint32(c.instoffset) {
1006 if isint32(c.instoffset) {
1011 case obj.TYPE_BRANCH:
1012 if a.Sym != nil && c.ctxt.Flag_dynlink {
1021 func prasm(p *obj.Prog) {
1022 fmt.Printf("%v\n", p)
1025 func (c *ctxt9) oplook(p *obj.Prog) *Optab {
1030 a1 = int(p.From.Class)
1032 a1 = c.aclass(&p.From) + 1
1033 p.From.Class = int8(a1)
1038 if p.GetFrom3() != nil {
1039 a3 = int(p.GetFrom3().Class)
1041 a3 = c.aclass(p.GetFrom3()) + 1
1042 p.GetFrom3().Class = int8(a3)
1047 a4 := int(p.To.Class)
1049 a4 = c.aclass(&p.To) + 1
1050 p.To.Class = int8(a4)
1056 if REG_R0 <= p.Reg && p.Reg <= REG_R31 {
1058 } else if REG_V0 <= p.Reg && p.Reg <= REG_V31 {
1060 } else if REG_VS0 <= p.Reg && p.Reg <= REG_VS63 {
1062 } else if REG_F0 <= p.Reg && p.Reg <= REG_F31 {
1067 // c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4)
1068 ops := oprange[p.As&obj.AMask]
1072 for i := range ops {
1074 if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] {
1075 p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
1080 c.ctxt.Diag("illegal combination %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4))
1088 func cmp(a int, b int) bool {
1094 if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {
1099 if b == C_ZCON || b == C_SCON {
1104 if b == C_ZCON || b == C_SCON {
1109 if b == C_LR || b == C_XER || b == C_CTR {
1145 return r0iszero != 0 /*TypeKind(100016)*/
1149 if b == C_ZOREG || b == C_SOREG {
1167 func (x ocmp) Len() int {
1171 func (x ocmp) Swap(i, j int) {
1172 x[i], x[j] = x[j], x[i]
1175 // Used when sorting the optab. Sorting is
1176 // done in a way so that the best choice of
1177 // opcode/operand combination is considered first.
1178 func (x ocmp) Less(i, j int) bool {
1181 n := int(p1.as) - int(p2.as)
1186 // Consider those that generate fewer
1187 // instructions first.
1188 n = int(p1.size) - int(p2.size)
1192 // operand order should match
1193 // better choices first
1194 n = int(p1.a1) - int(p2.a1)
1198 n = int(p1.a2) - int(p2.a2)
1202 n = int(p1.a3) - int(p2.a3)
1206 n = int(p1.a4) - int(p2.a4)
1213 // Add an entry to the opcode table for
1214 // a new opcode b0 with the same operand combinations
1216 func opset(a, b0 obj.As) {
1217 oprange[a&obj.AMask] = oprange[b0]
1220 // Build the opcode table
1221 func buildop(ctxt *obj.Link) {
1222 if oprange[AANDN&obj.AMask] != nil {
1223 // Already initialized; stop now.
1224 // This happens in the cmd/asm tests,
1225 // each of which re-initializes the arch.
1231 for i := 0; i < C_NCLASS; i++ {
1232 for n = 0; n < C_NCLASS; n++ {
1238 for n = 0; optab[n].as != obj.AXXX; n++ {
1240 sort.Sort(ocmp(optab[:n]))
1241 for i := 0; i < n; i++ {
1245 for optab[i].as == r {
1248 oprange[r0] = optab[start:i]
1253 ctxt.Diag("unknown op in build: %v", r)
1254 log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r)
1256 case ADCBF: /* unary indexed: op (b+a); op (b) */
1265 case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
1271 case AREM: /* macro */
1280 case ADIVW: /* op Rb[,Ra],Rd */
1285 opset(AMULHWUCC, r0)
1287 opset(AMULLWVCC, r0)
1295 opset(ADIVWUVCC, r0)
1312 opset(AMULHDUCC, r0)
1315 opset(AMULLDVCC, r0)
1322 opset(ADIVDEUCC, r0)
1327 opset(ADIVDUVCC, r0)
1339 case APOPCNTD: /* popcntd, popcntw, popcntb, cnttzw, cnttzd */
1343 opset(ACNTTZWCC, r0)
1345 opset(ACNTTZDCC, r0)
1347 case ACOPY: /* copy, paste. */
1350 case AMADDHD: /* maddhd, maddhdu, maddld */
1354 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
1358 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
1367 case ALV: /* lvebx, lvehx, lvewx, lvx, lvxl, lvsl, lvsr */
1376 case ASTV: /* stvebx, stvehx, stvewx, stvx, stvxl */
1383 case AVAND: /* vand, vandc, vnand */
1388 case AVMRGOW: /* vmrgew, vmrgow */
1391 case AVOR: /* vor, vorc, vxor, vnor, veqv */
1398 case AVADDUM: /* vaddubm, vadduhm, vadduwm, vaddudm, vadduqm */
1405 case AVADDCU: /* vaddcuq, vaddcuw */
1409 case AVADDUS: /* vaddubs, vadduhs, vadduws */
1414 case AVADDSS: /* vaddsbs, vaddshs, vaddsws */
1419 case AVADDE: /* vaddeuqm, vaddecuq */
1420 opset(AVADDEUQM, r0)
1421 opset(AVADDECUQ, r0)
1423 case AVSUBUM: /* vsububm, vsubuhm, vsubuwm, vsubudm, vsubuqm */
1430 case AVSUBCU: /* vsubcuq, vsubcuw */
1434 case AVSUBUS: /* vsububs, vsubuhs, vsubuws */
1439 case AVSUBSS: /* vsubsbs, vsubshs, vsubsws */
1444 case AVSUBE: /* vsubeuqm, vsubecuq */
1445 opset(AVSUBEUQM, r0)
1446 opset(AVSUBECUQ, r0)
1448 case AVMULESB: /* vmulesb, vmulosb, vmuleub, vmuloub, vmulosh, vmulouh, vmulesw, vmulosw, vmuleuw, vmulouw, vmuluwm */
1461 case AVPMSUM: /* vpmsumb, vpmsumh, vpmsumw, vpmsumd */
1467 case AVR: /* vrlb, vrlh, vrlw, vrld */
1473 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 */
1487 case AVSA: /* vsrab, vsrah, vsraw, vsrad */
1493 case AVSOI: /* vsldoi */
1496 case AVCLZ: /* vclzb, vclzh, vclzw, vclzd */
1502 case AVPOPCNT: /* vpopcntb, vpopcnth, vpopcntw, vpopcntd */
1503 opset(AVPOPCNTB, r0)
1504 opset(AVPOPCNTH, r0)
1505 opset(AVPOPCNTW, r0)
1506 opset(AVPOPCNTD, r0)
1508 case AVCMPEQ: /* vcmpequb[.], vcmpequh[.], vcmpequw[.], vcmpequd[.] */
1509 opset(AVCMPEQUB, r0)
1510 opset(AVCMPEQUBCC, r0)
1511 opset(AVCMPEQUH, r0)
1512 opset(AVCMPEQUHCC, r0)
1513 opset(AVCMPEQUW, r0)
1514 opset(AVCMPEQUWCC, r0)
1515 opset(AVCMPEQUD, r0)
1516 opset(AVCMPEQUDCC, r0)
1518 case AVCMPGT: /* vcmpgt[u,s]b[.], vcmpgt[u,s]h[.], vcmpgt[u,s]w[.], vcmpgt[u,s]d[.] */
1519 opset(AVCMPGTUB, r0)
1520 opset(AVCMPGTUBCC, r0)
1521 opset(AVCMPGTUH, r0)
1522 opset(AVCMPGTUHCC, r0)
1523 opset(AVCMPGTUW, r0)
1524 opset(AVCMPGTUWCC, r0)
1525 opset(AVCMPGTUD, r0)
1526 opset(AVCMPGTUDCC, r0)
1527 opset(AVCMPGTSB, r0)
1528 opset(AVCMPGTSBCC, r0)
1529 opset(AVCMPGTSH, r0)
1530 opset(AVCMPGTSHCC, r0)
1531 opset(AVCMPGTSW, r0)
1532 opset(AVCMPGTSWCC, r0)
1533 opset(AVCMPGTSD, r0)
1534 opset(AVCMPGTSDCC, r0)
1536 case AVCMPNEZB: /* vcmpnezb[.] */
1537 opset(AVCMPNEZBCC, r0)
1539 opset(AVCMPNEBCC, r0)
1541 opset(AVCMPNEHCC, r0)
1543 opset(AVCMPNEWCC, r0)
1545 case AVPERM: /* vperm */
1546 opset(AVPERMXOR, r0)
1549 case AVBPERMQ: /* vbpermq, vbpermd */
1552 case AVSEL: /* vsel */
1555 case AVSPLTB: /* vspltb, vsplth, vspltw */
1559 case AVSPLTISB: /* vspltisb, vspltish, vspltisw */
1560 opset(AVSPLTISH, r0)
1561 opset(AVSPLTISW, r0)
1563 case AVCIPH: /* vcipher, vcipherlast */
1565 opset(AVCIPHERLAST, r0)
1567 case AVNCIPH: /* vncipher, vncipherlast */
1568 opset(AVNCIPHER, r0)
1569 opset(AVNCIPHERLAST, r0)
1571 case AVSBOX: /* vsbox */
1574 case AVSHASIGMA: /* vshasigmaw, vshasigmad */
1575 opset(AVSHASIGMAW, r0)
1576 opset(AVSHASIGMAD, r0)
1578 case ALXVD2X: /* lxvd2x, lxvdsx, lxvw4x, lxvh8x, lxvb16x */
1584 case ALXV: /* lxv */
1587 case ALXVL: /* lxvl, lxvll, lxvx */
1591 case ASTXVD2X: /* stxvd2x, stxvdsx, stxvw4x, stxvh8x, stxvb16x */
1594 opset(ASTXVB16X, r0)
1596 case ASTXV: /* stxv */
1599 case ASTXVL: /* stxvl, stxvll, stvx */
1603 case ALXSDX: /* lxsdx */
1606 case ASTXSDX: /* stxsdx */
1609 case ALXSIWAX: /* lxsiwax, lxsiwzx */
1612 case ASTXSIWX: /* stxsiwx */
1615 case AMFVSRD: /* mfvsrd, mfvsrwz (and extended mnemonics), mfvsrld */
1621 case AMTVSRD: /* mtvsrd, mtvsrwa, mtvsrwz (and extended mnemonics), mtvsrdd, mtvsrws */
1629 case AXXLAND: /* xxland, xxlandc, xxleqv, xxlnand */
1634 case AXXLOR: /* xxlorc, xxlnor, xxlor, xxlxor */
1640 case AXXSEL: /* xxsel */
1643 case AXXMRGHW: /* xxmrghw, xxmrglw */
1646 case AXXSPLTW: /* xxspltw */
1649 case AXXSPLTIB: /* xxspltib */
1650 opset(AXXSPLTIB, r0)
1652 case AXXPERM: /* xxpermdi */
1655 case AXXSLDWI: /* xxsldwi */
1656 opset(AXXPERMDI, r0)
1659 case AXXBRQ: /* xxbrq, xxbrd, xxbrw, xxbrh */
1664 case AXSCVDPSP: /* xscvdpsp, xscvspdp, xscvdpspn, xscvspdpn */
1665 opset(AXSCVSPDP, r0)
1666 opset(AXSCVDPSPN, r0)
1667 opset(AXSCVSPDPN, r0)
1669 case AXVCVDPSP: /* xvcvdpsp, xvcvspdp */
1670 opset(AXVCVSPDP, r0)
1672 case AXSCVDPSXDS: /* xscvdpsxds, xscvdpsxws, xscvdpuxds, xscvdpuxws */
1673 opset(AXSCVDPSXWS, r0)
1674 opset(AXSCVDPUXDS, r0)
1675 opset(AXSCVDPUXWS, r0)
1677 case AXSCVSXDDP: /* xscvsxddp, xscvuxddp, xscvsxdsp, xscvuxdsp */
1678 opset(AXSCVUXDDP, r0)
1679 opset(AXSCVSXDSP, r0)
1680 opset(AXSCVUXDSP, r0)
1682 case AXVCVDPSXDS: /* xvcvdpsxds, xvcvdpsxws, xvcvdpuxds, xvcvdpuxws, xvcvspsxds, xvcvspsxws, xvcvspuxds, xvcvspuxws */
1683 opset(AXVCVDPSXDS, r0)
1684 opset(AXVCVDPSXWS, r0)
1685 opset(AXVCVDPUXDS, r0)
1686 opset(AXVCVDPUXWS, r0)
1687 opset(AXVCVSPSXDS, r0)
1688 opset(AXVCVSPSXWS, r0)
1689 opset(AXVCVSPUXDS, r0)
1690 opset(AXVCVSPUXWS, r0)
1692 case AXVCVSXDDP: /* xvcvsxddp, xvcvsxwdp, xvcvuxddp, xvcvuxwdp, xvcvsxdsp, xvcvsxwsp, xvcvuxdsp, xvcvuxwsp */
1693 opset(AXVCVSXWDP, r0)
1694 opset(AXVCVUXDDP, r0)
1695 opset(AXVCVUXWDP, r0)
1696 opset(AXVCVSXDSP, r0)
1697 opset(AXVCVSXWSP, r0)
1698 opset(AXVCVUXDSP, r0)
1699 opset(AXVCVUXWSP, r0)
1701 case AAND: /* logical op Rb,Rs,Ra; no literal */
1715 case AADDME: /* op Ra, Rd */
1719 opset(AADDMEVCC, r0)
1723 opset(AADDZEVCC, r0)
1727 opset(ASUBMEVCC, r0)
1731 opset(ASUBZEVCC, r0)
1751 case AEXTSB: /* op Rs, Ra */
1757 opset(ACNTLZWCC, r0)
1761 opset(ACNTLZDCC, r0)
1763 case AFABS: /* fop [s,]d */
1775 opset(AFCTIWZCC, r0)
1779 opset(AFCTIDZCC, r0)
1783 opset(AFCFIDUCC, r0)
1785 opset(AFCFIDSCC, r0)
1797 opset(AFRSQRTECC, r0)
1801 opset(AFSQRTSCC, r0)
1808 opset(AFCPSGNCC, r0)
1821 opset(AFMADDSCC, r0)
1825 opset(AFMSUBSCC, r0)
1827 opset(AFNMADDCC, r0)
1829 opset(AFNMADDSCC, r0)
1831 opset(AFNMSUBCC, r0)
1833 opset(AFNMSUBSCC, r0)
1849 opset(AMTFSB0CC, r0)
1851 opset(AMTFSB1CC, r0)
1853 case ANEG: /* op [Ra,] Rd */
1859 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,R */
1862 case AORIS: /* oris/xoris $uimm,Rs,Ra */
1877 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1880 case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1883 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
1911 opset(ARLDIMICC, r0)
1922 opset(ARLDICLCC, r0)
1924 opset(ARLDICRCC, r0)
1937 case ASYSCALL: /* just the op; flow of control */
1978 AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */
1984 /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
1985 AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals */
1986 AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
1987 AMOVB, /* macro: move byte with sign extension */
1988 AMOVBU, /* macro: move byte with sign extension & update */
1991 /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
1992 ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */
2016 func OPVXX1(o uint32, xo uint32, oe uint32) uint32 {
2017 return o<<26 | xo<<1 | oe<<11
2020 func OPVXX2(o uint32, xo uint32, oe uint32) uint32 {
2021 return o<<26 | xo<<2 | oe<<11
2024 func OPVXX2VA(o uint32, xo uint32, oe uint32) uint32 {
2025 return o<<26 | xo<<2 | oe<<16
2028 func OPVXX3(o uint32, xo uint32, oe uint32) uint32 {
2029 return o<<26 | xo<<3 | oe<<11
2032 func OPVXX4(o uint32, xo uint32, oe uint32) uint32 {
2033 return o<<26 | xo<<4 | oe<<11
2036 func OPDQ(o uint32, xo uint32, oe uint32) uint32 {
2037 return o<<26 | xo | oe<<4
2040 func OPVX(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2041 return o<<26 | xo | oe<<11 | rc&1
2044 func OPVC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2045 return o<<26 | xo | oe<<11 | (rc&1)<<10
2048 func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2049 return o<<26 | xo<<1 | oe<<10 | rc&1
2052 func OPCC(o uint32, xo uint32, rc uint32) uint32 {
2053 return OPVCC(o, xo, 0, rc)
2056 /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
2057 func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
2058 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
2061 /* VX-form 2-register operands, r/none/r */
2062 func AOP_RR(op uint32, d uint32, a uint32) uint32 {
2063 return op | (d&31)<<21 | (a&31)<<11
2066 /* VA-form 4-register operands */
2067 func AOP_RRRR(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2068 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&31)<<6
2071 func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2072 return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF
2075 /* VX-form 2-register + UIM operands */
2076 func AOP_VIRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2077 return op | (d&31)<<21 | (simm&0xFFFF)<<16 | (a&31)<<11
2080 /* VX-form 2-register + ST + SIX operands */
2081 func AOP_IIRR(op uint32, d uint32, a uint32, sbit uint32, simm uint32) uint32 {
2082 return op | (d&31)<<21 | (a&31)<<16 | (sbit&1)<<15 | (simm&0xF)<<11
2085 /* VA-form 3-register + SHB operands */
2086 func AOP_IRRR(op uint32, d uint32, a uint32, b uint32, simm uint32) uint32 {
2087 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (simm&0xF)<<6
2090 /* VX-form 1-register + SIM operands */
2091 func AOP_IR(op uint32, d uint32, simm uint32) uint32 {
2092 return op | (d&31)<<21 | (simm&31)<<16
2095 /* XX1-form 3-register operands, 1 VSR operand */
2096 func AOP_XX1(op uint32, d uint32, a uint32, b uint32) uint32 {
2097 /* For the XX-form encodings, we need the VSX register number to be exactly */
2098 /* between 0-63, so we can properly set the rightmost bits. */
2100 return op | (r&31)<<21 | (a&31)<<16 | (b&31)<<11 | (r&32)>>5
2103 /* XX2-form 3-register operands, 2 VSR operands */
2104 func AOP_XX2(op uint32, d uint32, a uint32, b uint32) uint32 {
2107 return op | (xt&31)<<21 | (a&3)<<16 | (xb&31)<<11 | (xb&32)>>4 | (xt&32)>>5
2110 /* XX3-form 3 VSR operands */
2111 func AOP_XX3(op uint32, d uint32, a uint32, b uint32) uint32 {
2115 return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2118 /* XX3-form 3 VSR operands + immediate */
2119 func AOP_XX3I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2123 return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (c&3)<<8 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2126 /* XX4-form, 4 VSR operands */
2127 func AOP_XX4(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2132 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
2135 /* DQ-form, VSR register, register + offset operands */
2136 func AOP_DQ(op uint32, d uint32, a uint32, b uint32) uint32 {
2137 /* For the DQ-form encodings, we need the VSX register number to be exactly */
2138 /* between 0-63, so we can properly set the SX bit. */
2140 /* The EA for this instruction form is (RA) + DQ << 4, where DQ is a 12-bit signed integer. */
2141 /* In order to match the output of the GNU objdump (and make the usage in Go asm easier), the */
2142 /* instruction is called using the sign extended value (i.e. a valid offset would be -32752 or 32752, */
2143 /* not -2047 or 2047), so 'b' needs to be adjusted to the expected 12-bit DQ value. Bear in mind that */
2144 /* bits 0 to 3 in 'dq' need to be zero, otherwise this will generate an illegal instruction. */
2145 /* If in doubt how this instruction form is encoded, refer to ISA 3.0b, pages 492 and 507. */
2147 return op | (r&31)<<21 | (a&31)<<16 | (dq&4095)<<4 | (r&32)>>2
2150 /* Z23-form, 3-register operands + CY field */
2151 func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2152 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<7
2155 /* X-form, 3-register operands + EH field */
2156 func AOP_RRRI(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2157 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c & 1)
2160 func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
2161 return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
2164 func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 {
2165 return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF
2168 func OP_BR(op uint32, li uint32, aa uint32) uint32 {
2169 return op | li&0x03FFFFFC | aa<<1
2172 func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 {
2173 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1
2176 func OP_BCR(op uint32, bo uint32, bi uint32) uint32 {
2177 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16
2180 func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 {
2181 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1
2184 func AOP_RLDIC(op uint32, a uint32, s uint32, sh uint32, m uint32) uint32 {
2185 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1 | (m&31)<<6 | ((m&32)>>5)<<5
2188 func AOP_ISEL(op uint32, t uint32, a uint32, b uint32, bc uint32) uint32 {
2189 return op | (t&31)<<21 | (a&31)<<16 | (b&31)<<11 | (bc&0x1F)<<6
2193 /* each rhs is OPVCC(_, _, _, _) */
2194 OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0
2195 OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0
2196 OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0
2197 OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 0
2198 OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0
2199 OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0
2200 OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0
2201 OP_ISEL = 31<<26 | 15<<1 | 0<<10 | 0
2202 OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0
2203 OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0
2204 OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0
2205 OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 0
2206 OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 0
2207 OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0
2208 OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0
2209 OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 0
2210 OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0
2211 OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0
2212 OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0
2213 OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0
2214 OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0
2215 OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0
2216 OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0
2217 OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 0
2218 OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0
2219 OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0
2220 OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0
2221 OP_OR = 31<<26 | 444<<1 | 0<<10 | 0
2222 OP_ORI = 24<<26 | 0<<1 | 0<<10 | 0
2223 OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 0
2224 OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0
2225 OP_RLWNM = 23<<26 | 0<<1 | 0<<10 | 0
2226 OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 0
2227 OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 0
2228 OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0
2229 OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0
2230 OP_RLDCL = 30<<26 | 8<<1 | 0<<10 | 0
2233 func oclass(a *obj.Addr) int {
2234 return int(a.Class) - 1
2242 // This function determines when a non-indexed load or store is D or
2243 // DS form for use in finding the size of the offset field in the instruction.
2244 // The size is needed when setting the offset value in the instruction
2245 // and when generating relocation for that field.
2246 // DS form instructions include: ld, ldu, lwa, std, stdu. All other
2247 // loads and stores with an offset field are D form. This function should
2248 // only be called with the same opcodes as are handled by opstore and opload.
2249 func (c *ctxt9) opform(insn uint32) int {
2252 c.ctxt.Diag("bad insn in loadform: %x", insn)
2253 case OPVCC(58, 0, 0, 0), // ld
2254 OPVCC(58, 0, 0, 1), // ldu
2255 OPVCC(58, 0, 0, 0) | 1<<1, // lwa
2256 OPVCC(62, 0, 0, 0), // std
2257 OPVCC(62, 0, 0, 1): //stdu
2259 case OP_ADDI, // add
2260 OPVCC(32, 0, 0, 0), // lwz
2261 OPVCC(33, 0, 0, 0), // lwzu
2262 OPVCC(34, 0, 0, 0), // lbz
2263 OPVCC(35, 0, 0, 0), // lbzu
2264 OPVCC(40, 0, 0, 0), // lhz
2265 OPVCC(41, 0, 0, 0), // lhzu
2266 OPVCC(42, 0, 0, 0), // lha
2267 OPVCC(43, 0, 0, 0), // lhau
2268 OPVCC(46, 0, 0, 0), // lmw
2269 OPVCC(48, 0, 0, 0), // lfs
2270 OPVCC(49, 0, 0, 0), // lfsu
2271 OPVCC(50, 0, 0, 0), // lfd
2272 OPVCC(51, 0, 0, 0), // lfdu
2273 OPVCC(36, 0, 0, 0), // stw
2274 OPVCC(37, 0, 0, 0), // stwu
2275 OPVCC(38, 0, 0, 0), // stb
2276 OPVCC(39, 0, 0, 0), // stbu
2277 OPVCC(44, 0, 0, 0), // sth
2278 OPVCC(45, 0, 0, 0), // sthu
2279 OPVCC(47, 0, 0, 0), // stmw
2280 OPVCC(52, 0, 0, 0), // stfs
2281 OPVCC(53, 0, 0, 0), // stfsu
2282 OPVCC(54, 0, 0, 0), // stfd
2283 OPVCC(55, 0, 0, 0): // stfdu
2289 // Encode instructions and create relocation for accessing s+d according to the
2290 // instruction op with source or destination (as appropriate) register reg.
2291 func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) {
2292 if c.ctxt.Headtype == objabi.Haix {
2293 // Every symbol access must be made via a TOC anchor.
2294 c.ctxt.Diag("symbolAccess called for %s", s.Name)
2297 form := c.opform(op)
2298 if c.ctxt.Flag_shared {
2303 o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)
2304 o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)
2305 rel := obj.Addrel(c.cursym)
2306 rel.Off = int32(c.pc)
2310 if c.ctxt.Flag_shared {
2313 rel.Type = objabi.R_ADDRPOWER_TOCREL
2315 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
2321 rel.Type = objabi.R_ADDRPOWER
2323 rel.Type = objabi.R_ADDRPOWER_DS
2332 func getmask(m []byte, v uint32) bool {
2335 if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
2346 for i := 0; i < 32; i++ {
2347 if v&(1<<uint(31-i)) != 0 {
2352 if i >= 32 || v&(1<<uint(31-i)) == 0 {
2358 if v&(1<<uint(31-i)) != 0 {
2369 func (c *ctxt9) maskgen(p *obj.Prog, m []byte, v uint32) {
2371 c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
2376 * 64-bit masks (rldic etc)
2378 func getmask64(m []byte, v uint64) bool {
2381 for i := 0; i < 64; i++ {
2382 if v&(uint64(1)<<uint(63-i)) != 0 {
2387 if i >= 64 || v&(uint64(1)<<uint(63-i)) == 0 {
2393 if v&(uint64(1)<<uint(63-i)) != 0 {
2404 func (c *ctxt9) maskgen64(p *obj.Prog, m []byte, v uint64) {
2405 if !getmask64(m, v) {
2406 c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
2410 func loadu32(r int, d int64) uint32 {
2412 if isuint32(uint64(d)) {
2413 return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
2415 return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v))
2418 func high16adjusted(d int32) uint16 {
2420 return uint16((d >> 16) + 1)
2422 return uint16(d >> 16)
2425 func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
2432 //print("%v => case %d\n", p, o->type);
2435 c.ctxt.Diag("unknown type %d", o.type_)
2438 case 0: /* pseudo ops */
2441 case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
2442 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
2443 v := c.regoff(&p.From)
2444 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
2446 c.ctxt.Diag("literal operation on R0\n%v", p)
2449 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
2453 o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
2455 case 2: /* int/cr/fp op Rb,[Ra],Rd */
2461 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2463 case 3: /* mov $soreg/addcon/andcon/ucon, r ==> addis/oris/addi/ori $i,reg',r */
2464 d := c.vregoff(&p.From)
2467 r := int(p.From.Reg)
2471 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
2472 c.ctxt.Diag("literal operation on R0\n%v", p)
2477 log.Fatalf("invalid handling of %v", p)
2479 // For UCON operands the value is right shifted 16, using ADDIS if the
2480 // value should be signed, ORIS if unsigned.
2482 if r == REGZERO && isuint32(uint64(d)) {
2483 o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v))
2488 } else if int64(int16(d)) != d {
2489 // Operand is 16 bit value with sign bit set
2490 if o.a1 == C_ANDCON {
2491 // Needs unsigned 16 bit so use ORI
2492 if r == 0 || r == REGZERO {
2493 o1 = LOP_IRR(uint32(OP_ORI), uint32(p.To.Reg), uint32(0), uint32(v))
2496 // With ADDCON, needs signed 16 bit value, fall through to use ADDI
2497 } else if o.a1 != C_ADDCON {
2498 log.Fatalf("invalid handling of %v", p)
2502 o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
2504 case 4: /* add/mul $scon,[r1],r2 */
2505 v := c.regoff(&p.From)
2511 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
2512 c.ctxt.Diag("literal operation on R0\n%v", p)
2514 if int32(int16(v)) != v {
2515 log.Fatalf("mishandled instruction %v", p)
2517 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2519 case 5: /* syscall */
2522 case 6: /* logical op Rb,[Rs,]Ra; no literal */
2528 // AROTL and AROTLW are extended mnemonics, which map to RLDCL and RLWNM.
2531 o1 = AOP_RLDIC(OP_RLDCL, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), uint32(0))
2533 o1 = OP_RLW(OP_RLWNM, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), 0, 31)
2535 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2538 case 7: /* mov r, soreg ==> stw o(r) */
2544 v := c.regoff(&p.To)
2545 if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
2547 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2549 if c.ctxt.Flag_shared && r == REG_R13 {
2550 rel := obj.Addrel(c.cursym)
2551 rel.Off = int32(c.pc)
2553 // This (and the matching part in the load case
2554 // below) are the only places in the ppc64 toolchain
2555 // that knows the name of the tls variable. Possibly
2556 // we could add some assembly syntax so that the name
2557 // of the variable does not have to be assumed.
2558 rel.Sym = c.ctxt.Lookup("runtime.tls_g")
2559 rel.Type = objabi.R_POWER_TLS
2561 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
2563 if int32(int16(v)) != v {
2564 log.Fatalf("mishandled instruction %v", p)
2566 // Offsets in DS form stores must be a multiple of 4
2567 inst := c.opstore(p.As)
2568 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2569 log.Fatalf("invalid offset for DS form load/store %v", p)
2571 o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
2574 case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
2575 r := int(p.From.Reg)
2580 v := c.regoff(&p.From)
2581 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
2583 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2585 if c.ctxt.Flag_shared && r == REG_R13 {
2586 rel := obj.Addrel(c.cursym)
2587 rel.Off = int32(c.pc)
2589 rel.Sym = c.ctxt.Lookup("runtime.tls_g")
2590 rel.Type = objabi.R_POWER_TLS
2592 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
2594 if int32(int16(v)) != v {
2595 log.Fatalf("mishandled instruction %v", p)
2597 // Offsets in DS form loads must be a multiple of 4
2598 inst := c.opload(p.As)
2599 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2600 log.Fatalf("invalid offset for DS form load/store %v", p)
2602 o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
2605 case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
2606 r := int(p.From.Reg)
2611 v := c.regoff(&p.From)
2612 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
2614 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2616 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
2618 o1 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2620 o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
2622 case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
2628 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
2630 case 11: /* br/bl lbra */
2634 v = int32(p.Pcond.Pc - p.Pc)
2636 c.ctxt.Diag("odd branch target address\n%v", p)
2640 if v < -(1<<25) || v >= 1<<24 {
2641 c.ctxt.Diag("branch too far\n%v", p)
2645 o1 = OP_BR(c.opirr(p.As), uint32(v), 0)
2646 if p.To.Sym != nil {
2647 rel := obj.Addrel(c.cursym)
2648 rel.Off = int32(c.pc)
2651 v += int32(p.To.Offset)
2653 c.ctxt.Diag("odd branch target address\n%v", p)
2658 rel.Type = objabi.R_CALLPOWER
2660 o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
2662 case 12: /* movb r,r (extsb); movw r,r (extsw) */
2663 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
2664 v := c.regoff(&p.From)
2665 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
2666 c.ctxt.Diag("literal operation on R0\n%v", p)
2669 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
2674 o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2676 o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2679 case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
2681 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
2682 } else if p.As == AMOVH {
2683 o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2684 } else if p.As == AMOVHZ {
2685 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
2686 } else if p.As == AMOVWZ {
2687 o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
2689 c.ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
2692 case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
2698 d := c.vregoff(p.GetFrom3())
2702 // These opcodes expect a mask operand that has to be converted into the
2703 // appropriate operand. The way these were defined, not all valid masks are possible.
2704 // Left here for compatibility in case they were used or generated.
2705 case ARLDCL, ARLDCLCC:
2707 c.maskgen64(p, mask[:], uint64(d))
2709 a = int(mask[0]) /* MB */
2711 c.ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)
2713 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2714 o1 |= (uint32(a) & 31) << 6
2716 o1 |= 1 << 5 /* mb[5] is top bit */
2719 case ARLDCR, ARLDCRCC:
2721 c.maskgen64(p, mask[:], uint64(d))
2723 a = int(mask[1]) /* ME */
2725 c.ctxt.Diag("invalid mask for rotate: %x %x (start != 0)\n%v", uint64(d), mask[0], p)
2727 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2728 o1 |= (uint32(a) & 31) << 6
2730 o1 |= 1 << 5 /* mb[5] is top bit */
2733 // These opcodes use a shift count like the ppc64 asm, no mask conversion done
2734 case ARLDICR, ARLDICRCC:
2736 sh := c.regoff(&p.From)
2737 o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(me))
2739 case ARLDICL, ARLDICLCC:
2741 sh := c.regoff(&p.From)
2742 o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(mb))
2745 c.ctxt.Diag("unexpected op in rldc case\n%v", p)
2749 case 17, /* bc bo,bi,lbra (same for now) */
2750 16: /* bc bo,bi,sbra */
2755 if p.From.Type == obj.TYPE_CONST {
2756 a = int(c.regoff(&p.From))
2757 } else if p.From.Type == obj.TYPE_REG {
2759 c.ctxt.Diag("unexpected register setting for branch with CR: %d\n", r)
2761 // BI values for the CR
2780 c.ctxt.Diag("unrecognized register: expecting CR\n")
2785 v = int32(p.Pcond.Pc - p.Pc)
2788 c.ctxt.Diag("odd branch target address\n%v", p)
2792 if v < -(1<<16) || v >= 1<<15 {
2793 c.ctxt.Diag("branch too far\n%v", p)
2795 o1 = OP_BC(c.opirr(p.As), uint32(a), uint32(r), uint32(v), 0)
2797 case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
2799 if p.As == ABC || p.As == ABCL {
2800 v = c.regoff(&p.To) & 31
2802 v = 20 /* unconditional */
2804 o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
2805 o2 = OPVCC(19, 16, 0, 0)
2806 if p.As == ABL || p.As == ABCL {
2809 o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index))
2811 case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
2813 if p.As == ABC || p.As == ABCL {
2814 v = c.regoff(&p.From) & 31
2816 v = 20 /* unconditional */
2822 switch oclass(&p.To) {
2824 o1 = OPVCC(19, 528, 0, 0)
2827 o1 = OPVCC(19, 16, 0, 0)
2830 c.ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p)
2834 if p.As == ABL || p.As == ABCL {
2837 o1 = OP_BCR(o1, uint32(v), uint32(r))
2839 case 19: /* mov $lcon,r ==> cau+or */
2840 d := c.vregoff(&p.From)
2842 if p.From.Sym == nil {
2843 o1 = loadu32(int(p.To.Reg), d)
2844 o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
2846 o1, o2 = c.symbolAccess(p.From.Sym, d, p.To.Reg, OP_ADDI)
2849 case 20: /* add $ucon,,r | addis $addcon,r,r */
2850 v := c.regoff(&p.From)
2856 if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
2857 c.ctxt.Diag("literal operation on R0\n%v", p)
2860 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2862 o1 = AOP_IRR(c.opirr(AADDIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
2865 case 22: /* add $lcon/$andcon,r1,r2 ==> oris+ori+add/ori+add */
2866 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2867 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2869 d := c.vregoff(&p.From)
2874 if p.From.Sym != nil {
2875 c.ctxt.Diag("%v is not supported", p)
2877 // If operand is ANDCON, generate 2 instructions using
2878 // ORI for unsigned value; with LCON 3 instructions.
2880 o1 = LOP_IRR(OP_ORI, REGTMP, REGZERO, uint32(int32(d)))
2881 o2 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2883 o1 = loadu32(REGTMP, d)
2884 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2885 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2888 case 23: /* and $lcon/$addcon,r1,r2 ==> oris+ori+and/addi+and */
2889 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2890 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2892 d := c.vregoff(&p.From)
2898 // With ADDCON operand, generate 2 instructions using ADDI for signed value,
2899 // with LCON operand generate 3 instructions.
2901 o1 = LOP_IRR(OP_ADDI, REGZERO, REGTMP, uint32(int32(d)))
2902 o2 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2904 o1 = loadu32(REGTMP, d)
2905 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2906 o3 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2908 if p.From.Sym != nil {
2909 c.ctxt.Diag("%v is not supported", p)
2912 case 24: /* lfd fA,float64(0) -> xxlxor xsA,xsaA,xsaA + fneg for -0 */
2913 o1 = AOP_XX3I(c.oprrr(AXXLXOR), uint32(p.To.Reg), uint32(p.To.Reg), uint32(p.To.Reg), uint32(0))
2914 // This is needed for -0.
2916 o2 = AOP_RRR(c.oprrr(AFNEG), uint32(p.To.Reg), 0, uint32(p.To.Reg))
2920 /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
2921 v := c.regoff(&p.From)
2947 c.ctxt.Diag("unexpected op in sldi case\n%v", p)
2952 o1 = AOP_RLDIC(op, uint32(p.To.Reg), uint32(r), uint32(v), uint32(a))
2953 if p.As == ASLDCC || p.As == ASRDCC {
2954 o1 |= 1 // Set the condition code bit
2957 case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
2958 if p.To.Reg == REGTMP {
2959 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2961 v := c.regoff(&p.From)
2962 r := int(p.From.Reg)
2966 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
2967 o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
2969 case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
2970 v := c.regoff(p.GetFrom3())
2972 r := int(p.From.Reg)
2973 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2975 case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
2976 if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
2977 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2979 v := c.regoff(p.GetFrom3())
2980 o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
2981 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
2982 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
2983 if p.From.Sym != nil {
2984 c.ctxt.Diag("%v is not supported", p)
2987 case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
2988 v := c.regoff(&p.From)
2990 d := c.vregoff(p.GetFrom3())
2992 c.maskgen64(p, mask[:], uint64(d))
2995 case ARLDC, ARLDCCC:
2996 a = int(mask[0]) /* MB */
2997 if int32(mask[1]) != (63 - v) {
2998 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[1], v, p)
3001 case ARLDCL, ARLDCLCC:
3002 a = int(mask[0]) /* MB */
3004 c.ctxt.Diag("invalid mask for shift: %x %s (shift %d)\n%v", uint64(d), mask[1], v, p)
3007 case ARLDCR, ARLDCRCC:
3008 a = int(mask[1]) /* ME */
3010 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[0], v, p)
3014 c.ctxt.Diag("unexpected op in rldic case\n%v", p)
3018 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3019 o1 |= (uint32(a) & 31) << 6
3024 o1 |= 1 << 5 /* mb[5] is top bit */
3027 case 30: /* rldimi $sh,s,$mask,a */
3028 v := c.regoff(&p.From)
3030 d := c.vregoff(p.GetFrom3())
3032 // Original opcodes had mask operands which had to be converted to a shift count as expected by
3035 case ARLDMI, ARLDMICC:
3037 c.maskgen64(p, mask[:], uint64(d))
3038 if int32(mask[1]) != (63 - v) {
3039 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[1], v, p)
3041 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3042 o1 |= (uint32(mask[0]) & 31) << 6
3046 if mask[0]&0x20 != 0 {
3047 o1 |= 1 << 5 /* mb[5] is top bit */
3050 // Opcodes with shift count operands.
3051 case ARLDIMI, ARLDIMICC:
3052 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3053 o1 |= (uint32(d) & 31) << 6
3062 case 31: /* dword */
3063 d := c.vregoff(&p.From)
3065 if c.ctxt.Arch.ByteOrder == binary.BigEndian {
3066 o1 = uint32(d >> 32)
3070 o2 = uint32(d >> 32)
3073 if p.From.Sym != nil {
3074 rel := obj.Addrel(c.cursym)
3075 rel.Off = int32(c.pc)
3077 rel.Sym = p.From.Sym
3078 rel.Add = p.From.Offset
3079 rel.Type = objabi.R_ADDR
3084 case 32: /* fmul frc,fra,frd */
3090 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
3092 case 33: /* fabs [frb,]frd; fmr. frb,frd */
3093 r := int(p.From.Reg)
3095 if oclass(&p.From) == C_NONE {
3098 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(r))
3100 case 34: /* FMADDx fra,frb,frc,frt (t=a*c±b) */
3101 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.GetFrom3().Reg)&31)<<6
3103 case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
3104 v := c.regoff(&p.To)
3110 // Offsets in DS form stores must be a multiple of 4
3111 inst := c.opstore(p.As)
3112 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3113 log.Fatalf("invalid offset for DS form load/store %v", p)
3115 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3116 o2 = AOP_IRR(inst, uint32(p.From.Reg), REGTMP, uint32(v))
3118 case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
3119 v := c.regoff(&p.From)
3121 r := int(p.From.Reg)
3125 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3126 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
3128 case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
3129 v := c.regoff(&p.From)
3131 r := int(p.From.Reg)
3135 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3136 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
3137 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3140 o1 = uint32(c.regoff(&p.From))
3142 case 41: /* stswi */
3143 o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3146 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3148 case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */
3149 /* TH field for dcbt/dcbtst: */
3150 /* 0 = Block access - program will soon access EA. */
3151 /* 8-15 = Stream access - sequence of access (data stream). See section 4.3.2 of the ISA for details. */
3152 /* 16 = Block access - program will soon make a transient access to EA. */
3153 /* 17 = Block access - program will not access EA for a long time. */
3155 /* L field for dcbf: */
3156 /* 0 = invalidates the block containing EA in all processors. */
3157 /* 1 = same as 0, but with limited scope (i.e. block in the current processor will not be reused soon). */
3158 /* 3 = same as 1, but with even more limited scope (i.e. block in the current processor primary cache will not be reused soon). */
3159 if p.To.Type == obj.TYPE_NONE {
3160 o1 = AOP_RRR(c.oprrr(p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))
3162 th := c.regoff(&p.To)
3163 o1 = AOP_RRR(c.oprrr(p.As), uint32(th), uint32(p.From.Index), uint32(p.From.Reg))
3166 case 44: /* indexed store */
3167 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3169 case 45: /* indexed load */
3171 /* The assembler accepts a 4-operand l*arx instruction. The fourth operand is an Exclusive Access Hint (EH) */
3172 /* The EH field can be used as a lock acquire/release hint as follows: */
3173 /* 0 = Atomic Update (fetch-and-operate or similar algorithm) */
3174 /* 1 = Exclusive Access (lock acquire and release) */
3175 case ALBAR, ALHAR, ALWAR, ALDAR:
3176 if p.From3Type() != obj.TYPE_NONE {
3177 eh := int(c.regoff(p.GetFrom3()))
3179 c.ctxt.Diag("illegal EH field\n%v", p)
3181 o1 = AOP_RRRI(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg), uint32(eh))
3183 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3186 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3188 case 46: /* plain op */
3191 case 47: /* op Ra, Rd; also op [Ra,] Rd */
3192 r := int(p.From.Reg)
3197 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3199 case 48: /* op Rs, Ra */
3200 r := int(p.From.Reg)
3205 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3207 case 49: /* op Rb; op $n, Rb */
3208 if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
3209 v := c.regoff(&p.From) & 1
3210 o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
3212 o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.From.Reg))
3215 case 50: /* rem[u] r1[,r2],r3 */
3222 t := v & (1<<10 | 1) /* OE|Rc */
3223 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3224 o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
3225 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3229 /* Clear top 32 bits */
3230 o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5
3233 case 51: /* remd[u] r1[,r2],r3 */
3240 t := v & (1<<10 | 1) /* OE|Rc */
3241 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3242 o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
3243 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3244 /* cases 50,51: removed; can be reused. */
3246 /* cases 50,51: removed; can be reused. */
3248 case 52: /* mtfsbNx cr(n) */
3249 v := c.regoff(&p.From) & 31
3251 o1 = AOP_RRR(c.oprrr(p.As), uint32(v), 0, 0)
3253 case 53: /* mffsX ,fr1 */
3254 o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)
3256 case 54: /* mov msr,r1; mov r1, msr*/
3257 if oclass(&p.From) == C_REG {
3259 o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
3261 o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
3264 o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
3267 case 55: /* op Rb, Rd */
3268 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg))
3270 case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
3271 v := c.regoff(&p.From)
3277 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31)
3278 if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) {
3279 o1 |= 1 << 1 /* mb[5] */
3282 case 57: /* slw $sh,[s,]a -> rlwinm ... */
3283 v := c.regoff(&p.From)
3291 * Let user (gs) shoot himself in the foot.
3292 * qc has already complained.
3295 ctxt->diag("illegal shift %ld\n%v", v, p);
3305 mask[0], mask[1] = 0, 31
3307 mask[0], mask[1] = uint8(v), 31
3310 mask[0], mask[1] = 0, uint8(31-v)
3312 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1]))
3313 if p.As == ASLWCC || p.As == ASRWCC {
3314 o1 |= 1 // set the condition code
3317 case 58: /* logical $andcon,[s],a */
3318 v := c.regoff(&p.From)
3324 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3326 case 59: /* or/xor/and $ucon,,r | oris/xoris/andis $addcon,r,r */
3327 v := c.regoff(&p.From)
3335 o1 = LOP_IRR(c.opirr(AORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis. */
3337 o1 = LOP_IRR(c.opirr(AXORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3339 o1 = LOP_IRR(c.opirr(AANDISCC), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3341 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3344 case 60: /* tw to,a,b */
3345 r := int(c.regoff(&p.From) & 31)
3347 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
3349 case 61: /* tw to,a,$simm */
3350 r := int(c.regoff(&p.From) & 31)
3352 v := c.regoff(&p.To)
3353 o1 = AOP_IRR(c.opirr(p.As), uint32(r), uint32(p.Reg), uint32(v))
3355 case 62: /* rlwmi $sh,s,$mask,a */
3356 v := c.regoff(&p.From)
3359 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
3360 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
3361 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
3363 case 63: /* rlwmi b,s,$mask,a */
3365 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
3367 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
3368 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
3370 case 64: /* mtfsf fr[, $m] {,fpcsr} */
3372 if p.From3Type() != obj.TYPE_NONE {
3373 v = c.regoff(p.GetFrom3()) & 255
3377 o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
3379 case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
3381 c.ctxt.Diag("must specify FPSCR(n)\n%v", p)
3383 o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(c.regoff(&p.From))&31)<<12
3385 case 66: /* mov spr,r1; mov r1,spr, also dcr */
3388 if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
3391 if REG_DCR0 <= v && v <= REG_DCR0+1023 {
3392 o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
3394 o1 = OPVCC(31, 467, 0, 0) /* mtspr */
3398 v = int32(p.From.Reg)
3399 if REG_DCR0 <= v && v <= REG_DCR0+1023 {
3400 o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
3402 o1 = OPVCC(31, 339, 0, 0) /* mfspr */
3406 o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
3408 case 67: /* mcrf crfD,crfS */
3409 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 {
3410 c.ctxt.Diag("illegal CR field number\n%v", p)
3412 o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
3414 case 68: /* mfcr rD; mfocrf CRM,rD */
3415 if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
3416 v := int32(1 << uint(7-(p.To.Reg&7))) /* CR(n) */
3417 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
3419 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
3422 case 69: /* mtcrf CRM,rS */
3424 if p.From3Type() != obj.TYPE_NONE {
3426 c.ctxt.Diag("can't use both mask and CR(n)\n%v", p)
3428 v = c.regoff(p.GetFrom3()) & 0xff
3433 v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
3437 o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
3439 case 70: /* [f]cmp r,r,cr*/
3444 r = (int(p.Reg) & 7) << 2
3446 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
3448 case 71: /* cmp[l] r,i,cr*/
3453 r = (int(p.Reg) & 7) << 2
3455 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(c.regoff(&p.To))&0xffff
3457 case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
3458 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg))
3460 case 73: /* mcrfs crfD,crfS */
3461 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 {
3462 c.ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
3464 o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
3466 case 77: /* syscall $scon, syscall Rx */
3467 if p.From.Type == obj.TYPE_CONST {
3468 if p.From.Offset > BIG || p.From.Offset < -BIG {
3469 c.ctxt.Diag("illegal syscall, sysnum too large: %v", p)
3471 o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
3472 } else if p.From.Type == obj.TYPE_REG {
3473 o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
3475 c.ctxt.Diag("illegal syscall: %v", p)
3476 o1 = 0x7fe00008 // trap always
3480 o3 = AOP_RRR(c.oprrr(AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R0
3482 case 78: /* undef */
3483 o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed
3484 always to be an illegal instruction." */
3486 /* relocation operations */
3488 v := c.vregoff(&p.To)
3489 // Offsets in DS form stores must be a multiple of 4
3490 inst := c.opstore(p.As)
3491 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3492 log.Fatalf("invalid offset for DS form load/store %v", p)
3494 o1, o2 = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst)
3496 //if(dlm) reloc(&p->to, p->pc, 1);
3499 v := c.vregoff(&p.From)
3500 // Offsets in DS form loads must be a multiple of 4
3501 inst := c.opload(p.As)
3502 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3503 log.Fatalf("invalid offset for DS form load/store %v", p)
3505 o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
3507 //if(dlm) reloc(&p->from, p->pc, 1);
3510 v := c.vregoff(&p.From)
3511 // Offsets in DS form loads must be a multiple of 4
3512 inst := c.opload(p.As)
3513 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3514 log.Fatalf("invalid offset for DS form load/store %v", p)
3516 o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
3517 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3519 //if(dlm) reloc(&p->from, p->pc, 1);
3522 if p.From.Offset != 0 {
3523 c.ctxt.Diag("invalid offset against tls var %v", p)
3525 o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0)
3526 rel := obj.Addrel(c.cursym)
3527 rel.Off = int32(c.pc)
3529 rel.Sym = p.From.Sym
3530 rel.Type = objabi.R_POWER_TLS_LE
3533 if p.From.Offset != 0 {
3534 c.ctxt.Diag("invalid offset against tls var %v", p)
3536 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3537 o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3538 rel := obj.Addrel(c.cursym)
3539 rel.Off = int32(c.pc)
3541 rel.Sym = p.From.Sym
3542 rel.Type = objabi.R_POWER_TLS_IE
3545 v := c.vregoff(&p.To)
3547 c.ctxt.Diag("invalid offset against GOT slot %v", p)
3550 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3551 o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3552 rel := obj.Addrel(c.cursym)
3553 rel.Off = int32(c.pc)
3555 rel.Sym = p.From.Sym
3556 rel.Type = objabi.R_ADDRPOWER_GOT
3557 case 82: /* vector instructions, VX-form and VC-form */
3558 if p.From.Type == obj.TYPE_REG {
3559 /* reg reg none OR reg reg reg */
3560 /* 3-register operand order: VRA, VRB, VRT */
3561 /* 2-register operand order: VRA, VRT */
3562 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3563 } else if p.From3Type() == obj.TYPE_CONST {
3564 /* imm imm reg reg */
3565 /* operand order: SIX, VRA, ST, VRT */
3566 six := int(c.regoff(&p.From))
3567 st := int(c.regoff(p.GetFrom3()))
3568 o1 = AOP_IIRR(c.opiirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(st), uint32(six))
3569 } else if p.From3Type() == obj.TYPE_NONE && p.Reg != 0 {
3571 /* operand order: UIM, VRB, VRT */
3572 uim := int(c.regoff(&p.From))
3573 o1 = AOP_VIRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(uim))
3576 /* operand order: SIM, VRT */
3577 sim := int(c.regoff(&p.From))
3578 o1 = AOP_IR(c.opirr(p.As), uint32(p.To.Reg), uint32(sim))
3581 case 83: /* vector instructions, VA-form */
3582 if p.From.Type == obj.TYPE_REG {
3583 /* reg reg reg reg */
3584 /* 4-register operand order: VRA, VRB, VRC, VRT */
3585 o1 = AOP_RRRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3586 } else if p.From.Type == obj.TYPE_CONST {
3587 /* imm reg reg reg */
3588 /* operand order: SHB, VRA, VRB, VRT */
3589 shb := int(c.regoff(&p.From))
3590 o1 = AOP_IRRR(c.opirrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(shb))
3593 case 84: // ISEL BC,RA,RB,RT -> isel rt,ra,rb,bc
3594 bc := c.vregoff(&p.From)
3596 // rt = To.Reg, ra = p.Reg, rb = p.From3.Reg
3597 o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(bc))
3599 case 85: /* vector instructions, VX-form */
3601 /* 2-register operand order: VRB, VRT */
3602 o1 = AOP_RR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg))
3604 case 86: /* VSX indexed store, XX1-form */
3606 /* 3-register operand order: XT, (RB)(RA*1) */
3607 o1 = AOP_XX1(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3609 case 87: /* VSX indexed load, XX1-form */
3611 /* 3-register operand order: (RB)(RA*1), XT */
3612 o1 = AOP_XX1(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3614 case 88: /* VSX instructions, XX1-form */
3615 /* reg reg none OR reg reg reg */
3616 /* 3-register operand order: RA, RB, XT */
3617 /* 2-register operand order: XS, RA or RA, XT */
3618 xt := int32(p.To.Reg)
3619 xs := int32(p.From.Reg)
3620 /* We need to treat the special case of extended mnemonics that may have a FREG/VREG as an argument */
3621 if REG_V0 <= xt && xt <= REG_V31 {
3622 /* Convert V0-V31 to VS32-VS63 */
3624 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3625 } else if REG_F0 <= xt && xt <= REG_F31 {
3626 /* Convert F0-F31 to VS0-VS31 */
3628 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3629 } else if REG_VS0 <= xt && xt <= REG_VS63 {
3630 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3631 } else if REG_V0 <= xs && xs <= REG_V31 {
3632 /* Likewise for XS */
3634 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3635 } else if REG_F0 <= xs && xs <= REG_F31 {
3637 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3638 } else if REG_VS0 <= xs && xs <= REG_VS63 {
3639 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3642 case 89: /* VSX instructions, XX2-form */
3643 /* reg none reg OR reg imm reg */
3644 /* 2-register operand order: XB, XT or XB, UIM, XT*/
3645 uim := int(c.regoff(p.GetFrom3()))
3646 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(uim), uint32(p.From.Reg))
3648 case 90: /* VSX instructions, XX3-form */
3649 if p.From3Type() == obj.TYPE_NONE {
3651 /* 3-register operand order: XA, XB, XT */
3652 o1 = AOP_XX3(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3653 } else if p.From3Type() == obj.TYPE_CONST {
3654 /* reg reg reg imm */
3655 /* operand order: XA, XB, DM, XT */
3656 dm := int(c.regoff(p.GetFrom3()))
3657 o1 = AOP_XX3I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(dm))
3660 case 91: /* VSX instructions, XX4-form */
3661 /* reg reg reg reg */
3662 /* 3-register operand order: XA, XB, XC, XT */
3663 o1 = AOP_XX4(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3665 case 92: /* X-form instructions, 3-operands */
3666 if p.To.Type == obj.TYPE_CONST {
3668 xf := int32(p.From.Reg)
3669 if REG_F0 <= xf && xf <= REG_F31 {
3670 /* operand order: FRA, FRB, BF */
3671 bf := int(c.regoff(&p.To)) << 2
3672 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3674 /* operand order: RA, RB, L */
3675 l := int(c.regoff(&p.To))
3676 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.From.Reg), uint32(p.Reg))
3678 } else if p.From3Type() == obj.TYPE_CONST {
3680 /* operand order: RB, L, RA */
3681 l := int(c.regoff(p.GetFrom3()))
3682 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.To.Reg), uint32(p.From.Reg))
3683 } else if p.To.Type == obj.TYPE_REG {
3684 cr := int32(p.To.Reg)
3685 if REG_CR0 <= cr && cr <= REG_CR7 {
3687 /* operand order: RA, RB, BF */
3688 bf := (int(p.To.Reg) & 7) << 2
3689 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3690 } else if p.From.Type == obj.TYPE_CONST {
3692 /* operand order: L, RT */
3693 l := int(c.regoff(&p.From))
3694 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(l), uint32(p.Reg))
3697 case ACOPY, APASTECC:
3698 o1 = AOP_RRR(c.opirr(p.As), uint32(1), uint32(p.From.Reg), uint32(p.To.Reg))
3701 /* operand order: RS, RB, RA */
3702 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3707 case 93: /* X-form instructions, 2-operands */
3708 if p.To.Type == obj.TYPE_CONST {
3710 /* operand order: FRB, BF */
3711 bf := int(c.regoff(&p.To)) << 2
3712 o1 = AOP_RR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg))
3713 } else if p.Reg == 0 {
3714 /* popcnt* r,r, X-form */
3715 /* operand order: RS, RA */
3716 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3719 case 94: /* Z23-form instructions, 4-operands */
3720 /* reg reg reg imm */
3721 /* operand order: RA, RB, CY, RT */
3722 cy := int(c.regoff(p.GetFrom3()))
3723 o1 = AOP_Z23I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(cy))
3725 case 95: /* Retrieve TOC relative symbol */
3726 /* This code is for AIX only */
3727 v := c.vregoff(&p.From)
3729 c.ctxt.Diag("invalid offset against TOC slot %v", p)
3732 inst := c.opload(p.As)
3733 if c.opform(inst) != DS_FORM {
3734 c.ctxt.Diag("invalid form for a TOC access in %v", p)
3737 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3738 o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3739 rel := obj.Addrel(c.cursym)
3740 rel.Off = int32(c.pc)
3742 rel.Sym = p.From.Sym
3743 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
3745 case 96: /* VSX load, DQ-form */
3747 /* operand order: (RA)(DQ), XT */
3748 dq := int16(c.regoff(&p.From))
3750 c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3752 o1 = AOP_DQ(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(dq))
3754 case 97: /* VSX store, DQ-form */
3756 /* operand order: XT, (RA)(DQ) */
3757 dq := int16(c.regoff(&p.To))
3759 c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3761 o1 = AOP_DQ(c.opstore(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(dq))
3762 case 98: /* VSX indexed load or load with length (also left-justified), x-form */
3763 /* vsreg, reg, reg */
3764 o1 = AOP_XX1(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3765 case 99: /* VSX store with length (also left-justified) x-form */
3766 /* reg, reg, vsreg */
3767 o1 = AOP_XX1(c.opstore(p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(p.To.Reg))
3768 case 100: /* VSX X-form XXSPLTIB */
3769 if p.From.Type == obj.TYPE_CONST {
3771 uim := int(c.regoff(&p.From))
3773 /* Use AOP_XX1 form with 0 for one of the registers. */
3774 o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(uim))
3776 c.ctxt.Diag("invalid ops for %v", p.As)
3779 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
3789 func (c *ctxt9) vregoff(a *obj.Addr) int64 {
3797 func (c *ctxt9) regoff(a *obj.Addr) int32 {
3798 return int32(c.vregoff(a))
3801 func (c *ctxt9) oprrr(a obj.As) uint32 {
3804 return OPVCC(31, 266, 0, 0)
3806 return OPVCC(31, 266, 0, 1)
3808 return OPVCC(31, 266, 1, 0)
3810 return OPVCC(31, 266, 1, 1)
3812 return OPVCC(31, 10, 0, 0)
3814 return OPVCC(31, 10, 0, 1)
3816 return OPVCC(31, 10, 1, 0)
3818 return OPVCC(31, 10, 1, 1)
3820 return OPVCC(31, 138, 0, 0)
3822 return OPVCC(31, 138, 0, 1)
3824 return OPVCC(31, 138, 1, 0)
3826 return OPVCC(31, 138, 1, 1)
3828 return OPVCC(31, 234, 0, 0)
3830 return OPVCC(31, 234, 0, 1)
3832 return OPVCC(31, 234, 1, 0)
3834 return OPVCC(31, 234, 1, 1)
3836 return OPVCC(31, 202, 0, 0)
3838 return OPVCC(31, 202, 0, 1)
3840 return OPVCC(31, 202, 1, 0)
3842 return OPVCC(31, 202, 1, 1)
3844 return OPVCC(31, 170, 0, 0) /* addex - v3.0b */
3847 return OPVCC(31, 28, 0, 0)
3849 return OPVCC(31, 28, 0, 1)
3851 return OPVCC(31, 60, 0, 0)
3853 return OPVCC(31, 60, 0, 1)
3856 return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */
3858 return OPVCC(31, 32, 0, 0) | 1<<21
3860 return OPVCC(31, 0, 0, 0) /* L=0 */
3862 return OPVCC(31, 32, 0, 0)
3864 return OPVCC(31, 508, 0, 0) /* cmpb - v2.05 */
3866 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
3869 return OPVCC(31, 26, 0, 0)
3871 return OPVCC(31, 26, 0, 1)
3873 return OPVCC(31, 58, 0, 0)
3875 return OPVCC(31, 58, 0, 1)
3878 return OPVCC(19, 257, 0, 0)
3880 return OPVCC(19, 129, 0, 0)
3882 return OPVCC(19, 289, 0, 0)
3884 return OPVCC(19, 225, 0, 0)
3886 return OPVCC(19, 33, 0, 0)
3888 return OPVCC(19, 449, 0, 0)
3890 return OPVCC(19, 417, 0, 0)
3892 return OPVCC(19, 193, 0, 0)
3895 return OPVCC(31, 86, 0, 0)
3897 return OPVCC(31, 470, 0, 0)
3899 return OPVCC(31, 54, 0, 0)
3901 return OPVCC(31, 278, 0, 0)
3903 return OPVCC(31, 246, 0, 0)
3905 return OPVCC(31, 1014, 0, 0)
3908 return OPVCC(31, 265, 0, 0) /* modud - v3.0 */
3910 return OPVCC(31, 267, 0, 0) /* moduw - v3.0 */
3912 return OPVCC(31, 777, 0, 0) /* modsd - v3.0 */
3914 return OPVCC(31, 779, 0, 0) /* modsw - v3.0 */
3917 return OPVCC(31, 491, 0, 0)
3920 return OPVCC(31, 491, 0, 1)
3923 return OPVCC(31, 491, 1, 0)
3926 return OPVCC(31, 491, 1, 1)
3929 return OPVCC(31, 459, 0, 0)
3932 return OPVCC(31, 459, 0, 1)
3935 return OPVCC(31, 459, 1, 0)
3938 return OPVCC(31, 459, 1, 1)
3941 return OPVCC(31, 489, 0, 0)
3944 return OPVCC(31, 489, 0, 1)
3947 return OPVCC(31, 425, 0, 0)
3950 return OPVCC(31, 425, 0, 1)
3953 return OPVCC(31, 393, 0, 0)
3956 return OPVCC(31, 393, 0, 1)
3959 return OPVCC(31, 489, 1, 0)
3962 return OPVCC(31, 489, 1, 1)
3964 case ADIVDU, AREMDU:
3965 return OPVCC(31, 457, 0, 0)
3968 return OPVCC(31, 457, 0, 1)
3971 return OPVCC(31, 457, 1, 0)
3974 return OPVCC(31, 457, 1, 1)
3977 return OPVCC(31, 854, 0, 0)
3980 return OPVCC(31, 284, 0, 0)
3982 return OPVCC(31, 284, 0, 1)
3985 return OPVCC(31, 954, 0, 0)
3987 return OPVCC(31, 954, 0, 1)
3989 return OPVCC(31, 922, 0, 0)
3991 return OPVCC(31, 922, 0, 1)
3993 return OPVCC(31, 986, 0, 0)
3995 return OPVCC(31, 986, 0, 1)
3998 return OPVCC(63, 264, 0, 0)
4000 return OPVCC(63, 264, 0, 1)
4002 return OPVCC(63, 21, 0, 0)
4004 return OPVCC(63, 21, 0, 1)
4006 return OPVCC(59, 21, 0, 0)
4008 return OPVCC(59, 21, 0, 1)
4010 return OPVCC(63, 32, 0, 0)
4012 return OPVCC(63, 0, 0, 0)
4014 return OPVCC(63, 846, 0, 0)
4016 return OPVCC(63, 846, 0, 1)
4018 return OPVCC(63, 974, 0, 0)
4020 return OPVCC(63, 974, 0, 1)
4022 return OPVCC(59, 846, 0, 0)
4024 return OPVCC(59, 846, 0, 1)
4026 return OPVCC(63, 14, 0, 0)
4028 return OPVCC(63, 14, 0, 1)
4030 return OPVCC(63, 15, 0, 0)
4032 return OPVCC(63, 15, 0, 1)
4034 return OPVCC(63, 814, 0, 0)
4036 return OPVCC(63, 814, 0, 1)
4038 return OPVCC(63, 815, 0, 0)
4040 return OPVCC(63, 815, 0, 1)
4042 return OPVCC(63, 18, 0, 0)
4044 return OPVCC(63, 18, 0, 1)
4046 return OPVCC(59, 18, 0, 0)
4048 return OPVCC(59, 18, 0, 1)
4050 return OPVCC(63, 29, 0, 0)
4052 return OPVCC(63, 29, 0, 1)
4054 return OPVCC(59, 29, 0, 0)
4056 return OPVCC(59, 29, 0, 1)
4058 case AFMOVS, AFMOVD:
4059 return OPVCC(63, 72, 0, 0) /* load */
4061 return OPVCC(63, 72, 0, 1)
4063 return OPVCC(63, 28, 0, 0)
4065 return OPVCC(63, 28, 0, 1)
4067 return OPVCC(59, 28, 0, 0)
4069 return OPVCC(59, 28, 0, 1)
4071 return OPVCC(63, 25, 0, 0)
4073 return OPVCC(63, 25, 0, 1)
4075 return OPVCC(59, 25, 0, 0)
4077 return OPVCC(59, 25, 0, 1)
4079 return OPVCC(63, 136, 0, 0)
4081 return OPVCC(63, 136, 0, 1)
4083 return OPVCC(63, 40, 0, 0)
4085 return OPVCC(63, 40, 0, 1)
4087 return OPVCC(63, 31, 0, 0)
4089 return OPVCC(63, 31, 0, 1)
4091 return OPVCC(59, 31, 0, 0)
4093 return OPVCC(59, 31, 0, 1)
4095 return OPVCC(63, 30, 0, 0)
4097 return OPVCC(63, 30, 0, 1)
4099 return OPVCC(59, 30, 0, 0)
4101 return OPVCC(59, 30, 0, 1)
4103 return OPVCC(63, 8, 0, 0)
4105 return OPVCC(63, 8, 0, 1)
4107 return OPVCC(59, 24, 0, 0)
4109 return OPVCC(59, 24, 0, 1)
4111 return OPVCC(63, 488, 0, 0)
4113 return OPVCC(63, 488, 0, 1)
4115 return OPVCC(63, 456, 0, 0)
4117 return OPVCC(63, 456, 0, 1)
4119 return OPVCC(63, 424, 0, 0)
4121 return OPVCC(63, 424, 0, 1)
4123 return OPVCC(63, 392, 0, 0)
4125 return OPVCC(63, 392, 0, 1)
4127 return OPVCC(63, 12, 0, 0)
4129 return OPVCC(63, 12, 0, 1)
4131 return OPVCC(63, 26, 0, 0)
4133 return OPVCC(63, 26, 0, 1)
4135 return OPVCC(63, 23, 0, 0)
4137 return OPVCC(63, 23, 0, 1)
4139 return OPVCC(63, 22, 0, 0)
4141 return OPVCC(63, 22, 0, 1)
4143 return OPVCC(59, 22, 0, 0)
4145 return OPVCC(59, 22, 0, 1)
4147 return OPVCC(63, 20, 0, 0)
4149 return OPVCC(63, 20, 0, 1)
4151 return OPVCC(59, 20, 0, 0)
4153 return OPVCC(59, 20, 0, 1)
4156 return OPVCC(31, 982, 0, 0)
4158 return OPVCC(19, 150, 0, 0)
4161 return OPVCC(63, 70, 0, 0)
4163 return OPVCC(63, 70, 0, 1)
4165 return OPVCC(63, 38, 0, 0)
4167 return OPVCC(63, 38, 0, 1)
4170 return OPVCC(31, 75, 0, 0)
4172 return OPVCC(31, 75, 0, 1)
4174 return OPVCC(31, 11, 0, 0)
4176 return OPVCC(31, 11, 0, 1)
4178 return OPVCC(31, 235, 0, 0)
4180 return OPVCC(31, 235, 0, 1)
4182 return OPVCC(31, 235, 1, 0)
4184 return OPVCC(31, 235, 1, 1)
4187 return OPVCC(31, 73, 0, 0)
4189 return OPVCC(31, 73, 0, 1)
4191 return OPVCC(31, 9, 0, 0)
4193 return OPVCC(31, 9, 0, 1)
4195 return OPVCC(31, 233, 0, 0)
4197 return OPVCC(31, 233, 0, 1)
4199 return OPVCC(31, 233, 1, 0)
4201 return OPVCC(31, 233, 1, 1)
4204 return OPVCC(31, 476, 0, 0)
4206 return OPVCC(31, 476, 0, 1)
4208 return OPVCC(31, 104, 0, 0)
4210 return OPVCC(31, 104, 0, 1)
4212 return OPVCC(31, 104, 1, 0)
4214 return OPVCC(31, 104, 1, 1)
4216 return OPVCC(31, 124, 0, 0)
4218 return OPVCC(31, 124, 0, 1)
4220 return OPVCC(31, 444, 0, 0)
4222 return OPVCC(31, 444, 0, 1)
4224 return OPVCC(31, 412, 0, 0)
4226 return OPVCC(31, 412, 0, 1)
4229 return OPVCC(31, 506, 0, 0) /* popcntd - v2.06 */
4231 return OPVCC(31, 378, 0, 0) /* popcntw - v2.06 */
4233 return OPVCC(31, 122, 0, 0) /* popcntb - v2.02 */
4235 return OPVCC(31, 538, 0, 0) /* cnttzw - v3.00 */
4237 return OPVCC(31, 538, 0, 1) /* cnttzw. - v3.00 */
4239 return OPVCC(31, 570, 0, 0) /* cnttzd - v3.00 */
4241 return OPVCC(31, 570, 0, 1) /* cnttzd. - v3.00 */
4244 return OPVCC(19, 50, 0, 0)
4246 return OPVCC(19, 51, 0, 0)
4248 return OPVCC(19, 18, 0, 0)
4250 return OPVCC(19, 274, 0, 0)
4253 return OPVCC(20, 0, 0, 0)
4255 return OPVCC(20, 0, 0, 1)
4257 return OPVCC(23, 0, 0, 0)
4259 return OPVCC(23, 0, 0, 1)
4262 return OPVCC(30, 8, 0, 0)
4264 return OPVCC(30, 0, 0, 1)
4267 return OPVCC(30, 9, 0, 0)
4269 return OPVCC(30, 9, 0, 1)
4272 return OPVCC(30, 0, 0, 0)
4274 return OPVCC(30, 0, 0, 1)
4276 return OPVCC(30, 0, 0, 0) | 2<<1 // rldicr
4278 return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr.
4281 return OPVCC(17, 1, 0, 0)
4284 return OPVCC(31, 24, 0, 0)
4286 return OPVCC(31, 24, 0, 1)
4288 return OPVCC(31, 27, 0, 0)
4290 return OPVCC(31, 27, 0, 1)
4293 return OPVCC(31, 792, 0, 0)
4295 return OPVCC(31, 792, 0, 1)
4297 return OPVCC(31, 794, 0, 0)
4299 return OPVCC(31, 794, 0, 1)
4302 return OPVCC(31, 536, 0, 0)
4304 return OPVCC(31, 536, 0, 1)
4306 return OPVCC(31, 539, 0, 0)
4308 return OPVCC(31, 539, 0, 1)
4311 return OPVCC(31, 40, 0, 0)
4313 return OPVCC(31, 40, 0, 1)
4315 return OPVCC(31, 40, 1, 0)
4317 return OPVCC(31, 40, 1, 1)
4319 return OPVCC(31, 8, 0, 0)
4321 return OPVCC(31, 8, 0, 1)
4323 return OPVCC(31, 8, 1, 0)
4325 return OPVCC(31, 8, 1, 1)
4327 return OPVCC(31, 136, 0, 0)
4329 return OPVCC(31, 136, 0, 1)
4331 return OPVCC(31, 136, 1, 0)
4333 return OPVCC(31, 136, 1, 1)
4335 return OPVCC(31, 232, 0, 0)
4337 return OPVCC(31, 232, 0, 1)
4339 return OPVCC(31, 232, 1, 0)
4341 return OPVCC(31, 232, 1, 1)
4343 return OPVCC(31, 200, 0, 0)
4345 return OPVCC(31, 200, 0, 1)
4347 return OPVCC(31, 200, 1, 0)
4349 return OPVCC(31, 200, 1, 1)
4352 return OPVCC(31, 598, 0, 0)
4354 return OPVCC(31, 598, 0, 0) | 1<<21
4357 return OPVCC(31, 598, 0, 0) | 2<<21
4360 return OPVCC(31, 306, 0, 0)
4362 return OPVCC(31, 274, 0, 0)
4364 return OPVCC(31, 566, 0, 0)
4366 return OPVCC(31, 498, 0, 0)
4368 return OPVCC(31, 434, 0, 0)
4370 return OPVCC(31, 915, 0, 0)
4372 return OPVCC(31, 851, 0, 0)
4374 return OPVCC(31, 402, 0, 0)
4377 return OPVCC(31, 4, 0, 0)
4379 return OPVCC(31, 68, 0, 0)
4381 /* Vector (VMX/Altivec) instructions */
4382 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4383 /* are enabled starting at POWER6 (ISA 2.05). */
4385 return OPVX(4, 1028, 0, 0) /* vand - v2.03 */
4387 return OPVX(4, 1092, 0, 0) /* vandc - v2.03 */
4389 return OPVX(4, 1412, 0, 0) /* vnand - v2.07 */
4392 return OPVX(4, 1156, 0, 0) /* vor - v2.03 */
4394 return OPVX(4, 1348, 0, 0) /* vorc - v2.07 */
4396 return OPVX(4, 1284, 0, 0) /* vnor - v2.03 */
4398 return OPVX(4, 1220, 0, 0) /* vxor - v2.03 */
4400 return OPVX(4, 1668, 0, 0) /* veqv - v2.07 */
4403 return OPVX(4, 0, 0, 0) /* vaddubm - v2.03 */
4405 return OPVX(4, 64, 0, 0) /* vadduhm - v2.03 */
4407 return OPVX(4, 128, 0, 0) /* vadduwm - v2.03 */
4409 return OPVX(4, 192, 0, 0) /* vaddudm - v2.07 */
4411 return OPVX(4, 256, 0, 0) /* vadduqm - v2.07 */
4414 return OPVX(4, 320, 0, 0) /* vaddcuq - v2.07 */
4416 return OPVX(4, 384, 0, 0) /* vaddcuw - v2.03 */
4419 return OPVX(4, 512, 0, 0) /* vaddubs - v2.03 */
4421 return OPVX(4, 576, 0, 0) /* vadduhs - v2.03 */
4423 return OPVX(4, 640, 0, 0) /* vadduws - v2.03 */
4426 return OPVX(4, 768, 0, 0) /* vaddsbs - v2.03 */
4428 return OPVX(4, 832, 0, 0) /* vaddshs - v2.03 */
4430 return OPVX(4, 896, 0, 0) /* vaddsws - v2.03 */
4433 return OPVX(4, 60, 0, 0) /* vaddeuqm - v2.07 */
4435 return OPVX(4, 61, 0, 0) /* vaddecuq - v2.07 */
4438 return OPVX(4, 776, 0, 0) /* vmulesb - v2.03 */
4440 return OPVX(4, 264, 0, 0) /* vmulosb - v2.03 */
4442 return OPVX(4, 520, 0, 0) /* vmuleub - v2.03 */
4444 return OPVX(4, 8, 0, 0) /* vmuloub - v2.03 */
4446 return OPVX(4, 840, 0, 0) /* vmulesh - v2.03 */
4448 return OPVX(4, 328, 0, 0) /* vmulosh - v2.03 */
4450 return OPVX(4, 584, 0, 0) /* vmuleuh - v2.03 */
4452 return OPVX(4, 72, 0, 0) /* vmulouh - v2.03 */
4454 return OPVX(4, 904, 0, 0) /* vmulesw - v2.07 */
4456 return OPVX(4, 392, 0, 0) /* vmulosw - v2.07 */
4458 return OPVX(4, 648, 0, 0) /* vmuleuw - v2.07 */
4460 return OPVX(4, 136, 0, 0) /* vmulouw - v2.07 */
4462 return OPVX(4, 137, 0, 0) /* vmuluwm - v2.07 */
4465 return OPVX(4, 1032, 0, 0) /* vpmsumb - v2.07 */
4467 return OPVX(4, 1096, 0, 0) /* vpmsumh - v2.07 */
4469 return OPVX(4, 1160, 0, 0) /* vpmsumw - v2.07 */
4471 return OPVX(4, 1224, 0, 0) /* vpmsumd - v2.07 */
4474 return OPVX(4, 35, 0, 0) /* vmsumudm - v3.00b */
4477 return OPVX(4, 1024, 0, 0) /* vsububm - v2.03 */
4479 return OPVX(4, 1088, 0, 0) /* vsubuhm - v2.03 */
4481 return OPVX(4, 1152, 0, 0) /* vsubuwm - v2.03 */
4483 return OPVX(4, 1216, 0, 0) /* vsubudm - v2.07 */
4485 return OPVX(4, 1280, 0, 0) /* vsubuqm - v2.07 */
4488 return OPVX(4, 1344, 0, 0) /* vsubcuq - v2.07 */
4490 return OPVX(4, 1408, 0, 0) /* vsubcuw - v2.03 */
4493 return OPVX(4, 1536, 0, 0) /* vsububs - v2.03 */
4495 return OPVX(4, 1600, 0, 0) /* vsubuhs - v2.03 */
4497 return OPVX(4, 1664, 0, 0) /* vsubuws - v2.03 */
4500 return OPVX(4, 1792, 0, 0) /* vsubsbs - v2.03 */
4502 return OPVX(4, 1856, 0, 0) /* vsubshs - v2.03 */
4504 return OPVX(4, 1920, 0, 0) /* vsubsws - v2.03 */
4507 return OPVX(4, 62, 0, 0) /* vsubeuqm - v2.07 */
4509 return OPVX(4, 63, 0, 0) /* vsubecuq - v2.07 */
4512 return OPVX(4, 4, 0, 0) /* vrlb - v2.03 */
4514 return OPVX(4, 68, 0, 0) /* vrlh - v2.03 */
4516 return OPVX(4, 132, 0, 0) /* vrlw - v2.03 */
4518 return OPVX(4, 196, 0, 0) /* vrld - v2.07 */
4521 return OPVX(4, 1676, 0, 0) /* vmrgow - v2.07 */
4523 return OPVX(4, 1932, 0, 0) /* vmrgew - v2.07 */
4526 return OPVX(4, 260, 0, 0) /* vslh - v2.03 */
4528 return OPVX(4, 324, 0, 0) /* vslh - v2.03 */
4530 return OPVX(4, 388, 0, 0) /* vslw - v2.03 */
4532 return OPVX(4, 452, 0, 0) /* vsl - v2.03 */
4534 return OPVX(4, 1036, 0, 0) /* vsl - v2.03 */
4536 return OPVX(4, 516, 0, 0) /* vsrb - v2.03 */
4538 return OPVX(4, 580, 0, 0) /* vsrh - v2.03 */
4540 return OPVX(4, 644, 0, 0) /* vsrw - v2.03 */
4542 return OPVX(4, 708, 0, 0) /* vsr - v2.03 */
4544 return OPVX(4, 1100, 0, 0) /* vsro - v2.03 */
4546 return OPVX(4, 1476, 0, 0) /* vsld - v2.07 */
4548 return OPVX(4, 1732, 0, 0) /* vsrd - v2.07 */
4551 return OPVX(4, 772, 0, 0) /* vsrab - v2.03 */
4553 return OPVX(4, 836, 0, 0) /* vsrah - v2.03 */
4555 return OPVX(4, 900, 0, 0) /* vsraw - v2.03 */
4557 return OPVX(4, 964, 0, 0) /* vsrad - v2.07 */
4560 return OPVC(4, 1356, 0, 0) /* vbpermq - v2.07 */
4562 return OPVC(4, 1484, 0, 0) /* vbpermd - v3.00 */
4565 return OPVX(4, 1794, 0, 0) /* vclzb - v2.07 */
4567 return OPVX(4, 1858, 0, 0) /* vclzh - v2.07 */
4569 return OPVX(4, 1922, 0, 0) /* vclzw - v2.07 */
4571 return OPVX(4, 1986, 0, 0) /* vclzd - v2.07 */
4574 return OPVX(4, 1795, 0, 0) /* vpopcntb - v2.07 */
4576 return OPVX(4, 1859, 0, 0) /* vpopcnth - v2.07 */
4578 return OPVX(4, 1923, 0, 0) /* vpopcntw - v2.07 */
4580 return OPVX(4, 1987, 0, 0) /* vpopcntd - v2.07 */
4583 return OPVC(4, 6, 0, 0) /* vcmpequb - v2.03 */
4585 return OPVC(4, 6, 0, 1) /* vcmpequb. - v2.03 */
4587 return OPVC(4, 70, 0, 0) /* vcmpequh - v2.03 */
4589 return OPVC(4, 70, 0, 1) /* vcmpequh. - v2.03 */
4591 return OPVC(4, 134, 0, 0) /* vcmpequw - v2.03 */
4593 return OPVC(4, 134, 0, 1) /* vcmpequw. - v2.03 */
4595 return OPVC(4, 199, 0, 0) /* vcmpequd - v2.07 */
4597 return OPVC(4, 199, 0, 1) /* vcmpequd. - v2.07 */
4600 return OPVC(4, 518, 0, 0) /* vcmpgtub - v2.03 */
4602 return OPVC(4, 518, 0, 1) /* vcmpgtub. - v2.03 */
4604 return OPVC(4, 582, 0, 0) /* vcmpgtuh - v2.03 */
4606 return OPVC(4, 582, 0, 1) /* vcmpgtuh. - v2.03 */
4608 return OPVC(4, 646, 0, 0) /* vcmpgtuw - v2.03 */
4610 return OPVC(4, 646, 0, 1) /* vcmpgtuw. - v2.03 */
4612 return OPVC(4, 711, 0, 0) /* vcmpgtud - v2.07 */
4614 return OPVC(4, 711, 0, 1) /* vcmpgtud. v2.07 */
4616 return OPVC(4, 774, 0, 0) /* vcmpgtsb - v2.03 */
4618 return OPVC(4, 774, 0, 1) /* vcmpgtsb. - v2.03 */
4620 return OPVC(4, 838, 0, 0) /* vcmpgtsh - v2.03 */
4622 return OPVC(4, 838, 0, 1) /* vcmpgtsh. - v2.03 */
4624 return OPVC(4, 902, 0, 0) /* vcmpgtsw - v2.03 */
4626 return OPVC(4, 902, 0, 1) /* vcmpgtsw. - v2.03 */
4628 return OPVC(4, 967, 0, 0) /* vcmpgtsd - v2.07 */
4630 return OPVC(4, 967, 0, 1) /* vcmpgtsd. - v2.07 */
4633 return OPVC(4, 263, 0, 0) /* vcmpnezb - v3.00 */
4635 return OPVC(4, 263, 0, 1) /* vcmpnezb. - v3.00 */
4637 return OPVC(4, 7, 0, 0) /* vcmpneb - v3.00 */
4639 return OPVC(4, 7, 0, 1) /* vcmpneb. - v3.00 */
4641 return OPVC(4, 71, 0, 0) /* vcmpneh - v3.00 */
4643 return OPVC(4, 71, 0, 1) /* vcmpneh. - v3.00 */
4645 return OPVC(4, 135, 0, 0) /* vcmpnew - v3.00 */
4647 return OPVC(4, 135, 0, 1) /* vcmpnew. - v3.00 */
4650 return OPVX(4, 43, 0, 0) /* vperm - v2.03 */
4652 return OPVX(4, 45, 0, 0) /* vpermxor - v2.03 */
4654 return OPVX(4, 59, 0, 0) /* vpermr - v3.0 */
4657 return OPVX(4, 42, 0, 0) /* vsel - v2.03 */
4660 return OPVX(4, 1288, 0, 0) /* vcipher - v2.07 */
4662 return OPVX(4, 1289, 0, 0) /* vcipherlast - v2.07 */
4664 return OPVX(4, 1352, 0, 0) /* vncipher - v2.07 */
4666 return OPVX(4, 1353, 0, 0) /* vncipherlast - v2.07 */
4668 return OPVX(4, 1480, 0, 0) /* vsbox - v2.07 */
4669 /* End of vector instructions */
4671 /* Vector scalar (VSX) instructions */
4672 /* ISA 2.06 enables these for POWER7. */
4673 case AMFVSRD, AMFVRD, AMFFPRD:
4674 return OPVXX1(31, 51, 0) /* mfvsrd - v2.07 */
4676 return OPVXX1(31, 115, 0) /* mfvsrwz - v2.07 */
4678 return OPVXX1(31, 307, 0) /* mfvsrld - v3.00 */
4680 case AMTVSRD, AMTFPRD, AMTVRD:
4681 return OPVXX1(31, 179, 0) /* mtvsrd - v2.07 */
4683 return OPVXX1(31, 211, 0) /* mtvsrwa - v2.07 */
4685 return OPVXX1(31, 243, 0) /* mtvsrwz - v2.07 */
4687 return OPVXX1(31, 435, 0) /* mtvsrdd - v3.00 */
4689 return OPVXX1(31, 403, 0) /* mtvsrws - v3.00 */
4692 return OPVXX3(60, 130, 0) /* xxland - v2.06 */
4694 return OPVXX3(60, 138, 0) /* xxlandc - v2.06 */
4696 return OPVXX3(60, 186, 0) /* xxleqv - v2.07 */
4698 return OPVXX3(60, 178, 0) /* xxlnand - v2.07 */
4701 return OPVXX3(60, 170, 0) /* xxlorc - v2.07 */
4703 return OPVXX3(60, 162, 0) /* xxlnor - v2.06 */
4704 case AXXLOR, AXXLORQ:
4705 return OPVXX3(60, 146, 0) /* xxlor - v2.06 */
4707 return OPVXX3(60, 154, 0) /* xxlxor - v2.06 */
4710 return OPVXX4(60, 3, 0) /* xxsel - v2.06 */
4713 return OPVXX3(60, 18, 0) /* xxmrghw - v2.06 */
4715 return OPVXX3(60, 50, 0) /* xxmrglw - v2.06 */
4718 return OPVXX2(60, 164, 0) /* xxspltw - v2.06 */
4721 return OPVCC(60, 360, 0, 0) /* xxspltib - v3.0 */
4724 return OPVXX3(60, 26, 0) /* xxperm - v2.06 */
4726 return OPVXX3(60, 10, 0) /* xxpermdi - v2.06 */
4729 return OPVXX3(60, 2, 0) /* xxsldwi - v2.06 */
4732 return OPVXX2VA(60, 475, 31) /* xxbrq - v3.0 */
4734 return OPVXX2VA(60, 475, 23) /* xxbrd - v3.0 */
4736 return OPVXX2VA(60, 475, 15) /* xxbrw - v3.0 */
4738 return OPVXX2VA(60, 475, 7) /* xxbrh - v3.0 */
4741 return OPVXX2(60, 265, 0) /* xscvdpsp - v2.06 */
4743 return OPVXX2(60, 329, 0) /* xscvspdp - v2.06 */
4745 return OPVXX2(60, 267, 0) /* xscvdpspn - v2.07 */
4747 return OPVXX2(60, 331, 0) /* xscvspdpn - v2.07 */
4750 return OPVXX2(60, 393, 0) /* xvcvdpsp - v2.06 */
4752 return OPVXX2(60, 457, 0) /* xvcvspdp - v2.06 */
4755 return OPVXX2(60, 344, 0) /* xscvdpsxds - v2.06 */
4757 return OPVXX2(60, 88, 0) /* xscvdpsxws - v2.06 */
4759 return OPVXX2(60, 328, 0) /* xscvdpuxds - v2.06 */
4761 return OPVXX2(60, 72, 0) /* xscvdpuxws - v2.06 */
4764 return OPVXX2(60, 376, 0) /* xscvsxddp - v2.06 */
4766 return OPVXX2(60, 360, 0) /* xscvuxddp - v2.06 */
4768 return OPVXX2(60, 312, 0) /* xscvsxdsp - v2.06 */
4770 return OPVXX2(60, 296, 0) /* xscvuxdsp - v2.06 */
4773 return OPVXX2(60, 472, 0) /* xvcvdpsxds - v2.06 */
4775 return OPVXX2(60, 216, 0) /* xvcvdpsxws - v2.06 */
4777 return OPVXX2(60, 456, 0) /* xvcvdpuxds - v2.06 */
4779 return OPVXX2(60, 200, 0) /* xvcvdpuxws - v2.06 */
4781 return OPVXX2(60, 408, 0) /* xvcvspsxds - v2.07 */
4783 return OPVXX2(60, 152, 0) /* xvcvspsxws - v2.07 */
4785 return OPVXX2(60, 392, 0) /* xvcvspuxds - v2.07 */
4787 return OPVXX2(60, 136, 0) /* xvcvspuxws - v2.07 */
4790 return OPVXX2(60, 504, 0) /* xvcvsxddp - v2.06 */
4792 return OPVXX2(60, 248, 0) /* xvcvsxwdp - v2.06 */
4794 return OPVXX2(60, 488, 0) /* xvcvuxddp - v2.06 */
4796 return OPVXX2(60, 232, 0) /* xvcvuxwdp - v2.06 */
4798 return OPVXX2(60, 440, 0) /* xvcvsxdsp - v2.06 */
4800 return OPVXX2(60, 184, 0) /* xvcvsxwsp - v2.06 */
4802 return OPVXX2(60, 424, 0) /* xvcvuxdsp - v2.06 */
4804 return OPVXX2(60, 168, 0) /* xvcvuxwsp - v2.06 */
4805 /* End of VSX instructions */
4808 return OPVX(4, 48, 0, 0) /* maddhd - v3.00 */
4810 return OPVX(4, 49, 0, 0) /* maddhdu - v3.00 */
4812 return OPVX(4, 51, 0, 0) /* maddld - v3.00 */
4815 return OPVCC(31, 316, 0, 0)
4817 return OPVCC(31, 316, 0, 1)
4820 c.ctxt.Diag("bad r/r, r/r/r or r/r/r/r opcode %v", a)
4824 func (c *ctxt9) opirrr(a obj.As) uint32 {
4826 /* Vector (VMX/Altivec) instructions */
4827 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4828 /* are enabled starting at POWER6 (ISA 2.05). */
4830 return OPVX(4, 44, 0, 0) /* vsldoi - v2.03 */
4833 c.ctxt.Diag("bad i/r/r/r opcode %v", a)
4837 func (c *ctxt9) opiirr(a obj.As) uint32 {
4839 /* Vector (VMX/Altivec) instructions */
4840 /* ISA 2.07 enables these for POWER8 and beyond. */
4842 return OPVX(4, 1666, 0, 0) /* vshasigmaw - v2.07 */
4844 return OPVX(4, 1730, 0, 0) /* vshasigmad - v2.07 */
4847 c.ctxt.Diag("bad i/i/r/r opcode %v", a)
4851 func (c *ctxt9) opirr(a obj.As) uint32 {
4854 return OPVCC(14, 0, 0, 0)
4856 return OPVCC(12, 0, 0, 0)
4858 return OPVCC(13, 0, 0, 0)
4860 return OPVCC(15, 0, 0, 0) /* ADDIS */
4863 return OPVCC(28, 0, 0, 0)
4865 return OPVCC(29, 0, 0, 0) /* ANDIS. */
4868 return OPVCC(18, 0, 0, 0)
4870 return OPVCC(18, 0, 0, 0) | 1
4872 return OPVCC(18, 0, 0, 0) | 1
4874 return OPVCC(18, 0, 0, 0) | 1
4876 return OPVCC(16, 0, 0, 0)
4878 return OPVCC(16, 0, 0, 0) | 1
4881 return AOP_RRR(16<<26, 12, 2, 0)
4883 return AOP_RRR(16<<26, 4, 0, 0)
4885 return AOP_RRR(16<<26, 12, 1, 0)
4887 return AOP_RRR(16<<26, 4, 1, 0)
4889 return AOP_RRR(16<<26, 12, 0, 0)
4891 return AOP_RRR(16<<26, 4, 2, 0)
4893 return AOP_RRR(16<<26, 4, 3, 0) // apparently unordered-clear
4895 return AOP_RRR(16<<26, 12, 3, 0) // apparently unordered-set
4898 return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */
4900 return OPVCC(10, 0, 0, 0) | 1<<21
4902 return OPVCC(11, 0, 0, 0) /* L=0 */
4904 return OPVCC(10, 0, 0, 0)
4906 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
4909 return OPVCC(31, 597, 0, 0)
4912 return OPVCC(31, 774, 0, 0) /* copy - v3.00 */
4914 return OPVCC(31, 902, 0, 1) /* paste. - v3.00 */
4916 return OPVCC(31, 755, 0, 0) /* darn - v3.00 */
4919 return OPVCC(7, 0, 0, 0)
4922 return OPVCC(24, 0, 0, 0)
4924 return OPVCC(25, 0, 0, 0) /* ORIS */
4927 return OPVCC(20, 0, 0, 0) /* rlwimi */
4929 return OPVCC(20, 0, 0, 1)
4931 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
4933 return OPVCC(30, 0, 0, 1) | 3<<2
4935 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
4937 return OPVCC(30, 0, 0, 1) | 3<<2
4939 return OPVCC(21, 0, 0, 0) /* rlwinm */
4941 return OPVCC(21, 0, 0, 1)
4944 return OPVCC(30, 0, 0, 0) /* rldicl */
4946 return OPVCC(30, 0, 0, 1)
4948 return OPVCC(30, 1, 0, 0) /* rldicr */
4950 return OPVCC(30, 1, 0, 1)
4952 return OPVCC(30, 0, 0, 0) | 2<<2
4954 return OPVCC(30, 0, 0, 1) | 2<<2
4957 return OPVCC(31, 824, 0, 0)
4959 return OPVCC(31, 824, 0, 1)
4961 return OPVCC(31, (413 << 1), 0, 0)
4963 return OPVCC(31, (413 << 1), 0, 1)
4966 return OPVCC(31, 725, 0, 0)
4969 return OPVCC(8, 0, 0, 0)
4972 return OPVCC(3, 0, 0, 0)
4974 return OPVCC(2, 0, 0, 0)
4976 /* Vector (VMX/Altivec) instructions */
4977 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4978 /* are enabled starting at POWER6 (ISA 2.05). */
4980 return OPVX(4, 524, 0, 0) /* vspltb - v2.03 */
4982 return OPVX(4, 588, 0, 0) /* vsplth - v2.03 */
4984 return OPVX(4, 652, 0, 0) /* vspltw - v2.03 */
4987 return OPVX(4, 780, 0, 0) /* vspltisb - v2.03 */
4989 return OPVX(4, 844, 0, 0) /* vspltish - v2.03 */
4991 return OPVX(4, 908, 0, 0) /* vspltisw - v2.03 */
4992 /* End of vector instructions */
4995 return OPVCC(63, 128, 0, 0) /* ftdiv - v2.06 */
4997 return OPVCC(63, 160, 0, 0) /* ftsqrt - v2.06 */
5000 return OPVCC(26, 0, 0, 0) /* XORIL */
5002 return OPVCC(27, 0, 0, 0) /* XORIS */
5005 c.ctxt.Diag("bad opcode i/r or i/r/r %v", a)
5012 func (c *ctxt9) opload(a obj.As) uint32 {
5015 return OPVCC(58, 0, 0, 0) /* ld */
5017 return OPVCC(58, 0, 0, 1) /* ldu */
5019 return OPVCC(32, 0, 0, 0) /* lwz */
5021 return OPVCC(33, 0, 0, 0) /* lwzu */
5023 return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */
5025 return OPDQ(61, 1, 0) /* lxv - ISA v3.0 */
5027 return OPVXX1(31, 269, 0) /* lxvl - ISA v3.0 */
5029 return OPVXX1(31, 301, 0) /* lxvll - ISA v3.0 */
5031 return OPVXX1(31, 268, 0) /* lxvx - ISA v3.0 */
5035 return OPVCC(34, 0, 0, 0)
5038 case AMOVBU, AMOVBZU:
5039 return OPVCC(35, 0, 0, 0)
5041 return OPVCC(50, 0, 0, 0)
5043 return OPVCC(51, 0, 0, 0)
5045 return OPVCC(48, 0, 0, 0)
5047 return OPVCC(49, 0, 0, 0)
5049 return OPVCC(42, 0, 0, 0)
5051 return OPVCC(43, 0, 0, 0)
5053 return OPVCC(40, 0, 0, 0)
5055 return OPVCC(41, 0, 0, 0)
5057 return OPVCC(46, 0, 0, 0) /* lmw */
5060 c.ctxt.Diag("bad load opcode %v", a)
5065 * indexed load a(b),d
5067 func (c *ctxt9) oploadx(a obj.As) uint32 {
5070 return OPVCC(31, 23, 0, 0) /* lwzx */
5072 return OPVCC(31, 55, 0, 0) /* lwzux */
5074 return OPVCC(31, 341, 0, 0) /* lwax */
5076 return OPVCC(31, 373, 0, 0) /* lwaux */
5079 return OPVCC(31, 87, 0, 0) /* lbzx */
5081 case AMOVBU, AMOVBZU:
5082 return OPVCC(31, 119, 0, 0) /* lbzux */
5084 return OPVCC(31, 599, 0, 0) /* lfdx */
5086 return OPVCC(31, 631, 0, 0) /* lfdux */
5088 return OPVCC(31, 535, 0, 0) /* lfsx */
5090 return OPVCC(31, 567, 0, 0) /* lfsux */
5092 return OPVCC(31, 855, 0, 0) /* lfiwax - power6, isa 2.05 */
5094 return OPVCC(31, 887, 0, 0) /* lfiwzx - power7, isa 2.06 */
5096 return OPVCC(31, 343, 0, 0) /* lhax */
5098 return OPVCC(31, 375, 0, 0) /* lhaux */
5100 return OPVCC(31, 790, 0, 0) /* lhbrx */
5102 return OPVCC(31, 534, 0, 0) /* lwbrx */
5104 return OPVCC(31, 532, 0, 0) /* ldbrx */
5106 return OPVCC(31, 279, 0, 0) /* lhzx */
5108 return OPVCC(31, 311, 0, 0) /* lhzux */
5110 return OPVCC(31, 310, 0, 0) /* eciwx */
5112 return OPVCC(31, 52, 0, 0) /* lbarx */
5114 return OPVCC(31, 116, 0, 0) /* lharx */
5116 return OPVCC(31, 20, 0, 0) /* lwarx */
5118 return OPVCC(31, 84, 0, 0) /* ldarx */
5120 return OPVCC(31, 533, 0, 0) /* lswx */
5122 return OPVCC(31, 21, 0, 0) /* ldx */
5124 return OPVCC(31, 53, 0, 0) /* ldux */
5126 return OPVCC(31, 309, 0, 0) /* ldmx */
5128 /* Vector (VMX/Altivec) instructions */
5130 return OPVCC(31, 7, 0, 0) /* lvebx - v2.03 */
5132 return OPVCC(31, 39, 0, 0) /* lvehx - v2.03 */
5134 return OPVCC(31, 71, 0, 0) /* lvewx - v2.03 */
5136 return OPVCC(31, 103, 0, 0) /* lvx - v2.03 */
5138 return OPVCC(31, 359, 0, 0) /* lvxl - v2.03 */
5140 return OPVCC(31, 6, 0, 0) /* lvsl - v2.03 */
5142 return OPVCC(31, 38, 0, 0) /* lvsr - v2.03 */
5143 /* End of vector instructions */
5145 /* Vector scalar (VSX) instructions */
5147 return OPVXX1(31, 268, 0) /* lxvx - ISA v3.0 */
5149 return OPVXX1(31, 844, 0) /* lxvd2x - v2.06 */
5151 return OPVXX1(31, 780, 0) /* lxvw4x - v2.06 */
5153 return OPVXX1(31, 812, 0) /* lxvh8x - v3.00 */
5155 return OPVXX1(31, 876, 0) /* lxvb16x - v3.00 */
5157 return OPVXX1(31, 332, 0) /* lxvdsx - v2.06 */
5159 return OPVXX1(31, 588, 0) /* lxsdx - v2.06 */
5161 return OPVXX1(31, 76, 0) /* lxsiwax - v2.07 */
5163 return OPVXX1(31, 12, 0) /* lxsiwzx - v2.07 */
5166 c.ctxt.Diag("bad loadx opcode %v", a)
5173 func (c *ctxt9) opstore(a obj.As) uint32 {
5176 return OPVCC(38, 0, 0, 0) /* stb */
5178 case AMOVBU, AMOVBZU:
5179 return OPVCC(39, 0, 0, 0) /* stbu */
5181 return OPVCC(54, 0, 0, 0) /* stfd */
5183 return OPVCC(55, 0, 0, 0) /* stfdu */
5185 return OPVCC(52, 0, 0, 0) /* stfs */
5187 return OPVCC(53, 0, 0, 0) /* stfsu */
5190 return OPVCC(44, 0, 0, 0) /* sth */
5192 case AMOVHZU, AMOVHU:
5193 return OPVCC(45, 0, 0, 0) /* sthu */
5195 return OPVCC(47, 0, 0, 0) /* stmw */
5197 return OPVCC(31, 725, 0, 0) /* stswi */
5200 return OPVCC(36, 0, 0, 0) /* stw */
5202 case AMOVWZU, AMOVWU:
5203 return OPVCC(37, 0, 0, 0) /* stwu */
5205 return OPVCC(62, 0, 0, 0) /* std */
5207 return OPVCC(62, 0, 0, 1) /* stdu */
5209 return OPDQ(61, 5, 0) /* stxv ISA 3.0 */
5211 return OPVXX1(31, 397, 0) /* stxvl ISA 3.0 */
5213 return OPVXX1(31, 429, 0) /* stxvll ISA 3.0 */
5215 return OPVXX1(31, 396, 0) /* stxvx - ISA v3.0 */
5219 c.ctxt.Diag("unknown store opcode %v", a)
5224 * indexed store s,a(b)
5226 func (c *ctxt9) opstorex(a obj.As) uint32 {
5229 return OPVCC(31, 215, 0, 0) /* stbx */
5231 case AMOVBU, AMOVBZU:
5232 return OPVCC(31, 247, 0, 0) /* stbux */
5234 return OPVCC(31, 727, 0, 0) /* stfdx */
5236 return OPVCC(31, 759, 0, 0) /* stfdux */
5238 return OPVCC(31, 663, 0, 0) /* stfsx */
5240 return OPVCC(31, 695, 0, 0) /* stfsux */
5242 return OPVCC(31, 983, 0, 0) /* stfiwx */
5245 return OPVCC(31, 407, 0, 0) /* sthx */
5247 return OPVCC(31, 918, 0, 0) /* sthbrx */
5249 case AMOVHZU, AMOVHU:
5250 return OPVCC(31, 439, 0, 0) /* sthux */
5253 return OPVCC(31, 151, 0, 0) /* stwx */
5255 case AMOVWZU, AMOVWU:
5256 return OPVCC(31, 183, 0, 0) /* stwux */
5258 return OPVCC(31, 661, 0, 0) /* stswx */
5260 return OPVCC(31, 662, 0, 0) /* stwbrx */
5262 return OPVCC(31, 660, 0, 0) /* stdbrx */
5264 return OPVCC(31, 694, 0, 1) /* stbcx. */
5266 return OPVCC(31, 726, 0, 1) /* sthcx. */
5268 return OPVCC(31, 150, 0, 1) /* stwcx. */
5270 return OPVCC(31, 214, 0, 1) /* stwdx. */
5272 return OPVCC(31, 438, 0, 0) /* ecowx */
5274 return OPVCC(31, 149, 0, 0) /* stdx */
5276 return OPVCC(31, 181, 0, 0) /* stdux */
5278 /* Vector (VMX/Altivec) instructions */
5280 return OPVCC(31, 135, 0, 0) /* stvebx - v2.03 */
5282 return OPVCC(31, 167, 0, 0) /* stvehx - v2.03 */
5284 return OPVCC(31, 199, 0, 0) /* stvewx - v2.03 */
5286 return OPVCC(31, 231, 0, 0) /* stvx - v2.03 */
5288 return OPVCC(31, 487, 0, 0) /* stvxl - v2.03 */
5289 /* End of vector instructions */
5291 /* Vector scalar (VSX) instructions */
5293 return OPVXX1(31, 396, 0) /* stxvx - v3.0 */
5295 return OPVXX1(31, 972, 0) /* stxvd2x - v2.06 */
5297 return OPVXX1(31, 908, 0) /* stxvw4x - v2.06 */
5299 return OPVXX1(31, 940, 0) /* stxvh8x - v3.0 */
5301 return OPVXX1(31, 1004, 0) /* stxvb16x - v3.0 */
5304 return OPVXX1(31, 716, 0) /* stxsdx - v2.06 */
5307 return OPVXX1(31, 140, 0) /* stxsiwx - v2.07 */
5309 /* End of vector scalar instructions */
5313 c.ctxt.Diag("unknown storex opcode %v", a)