1 // cmd/9l/optab.c, cmd/9l/asmout.c from Vita Nuova.
3 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
4 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
5 // Portions Copyright © 1997-1999 Vita Nuova Limited
6 // Portions Copyright © 2000-2008 Vita Nuova Holdings Limited (www.vitanuova.com)
7 // Portions Copyright © 2004,2006 Bruce Ellis
8 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
9 // Revisions Copyright © 2000-2008 Lucent Technologies Inc. and others
10 // Portions Copyright © 2009 The Go Authors. All rights reserved.
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // of this software and associated documentation files (the "Software"), to deal
14 // in the Software without restriction, including without limitation the rights
15 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 // copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
19 // The above copyright notice and this permission notice shall be included in
20 // all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
42 // ctxt9 holds state while assembling a single function.
43 // Each function gets a fresh ctxt9.
44 // This allows for multiple functions to be safely concurrently assembled.
54 // Instruction layout.
58 funcAlignMask = funcAlign - 1
71 type_ int8 // cases in asmout below. E.g., 44 = st r,(ra+rb); 45 = ld (ra+rb), r
76 // This optab contains a list of opcodes with the operand
77 // combinations that are implemented. Not all opcodes are in this
78 // table, but are added later in buildop by calling opset for those
79 // opcodes which allow the same operand combinations as an opcode
80 // already in the table.
82 // The type field in the Optabl identifies the case in asmout where
83 // the instruction word is assembled.
85 {obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
86 {obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
87 {obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0},
88 {obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0},
90 {AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0},
91 {AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
92 {AMOVBZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
93 {AMOVW, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0},
94 {AMOVWZ, C_REG, C_NONE, C_NONE, C_REG, 13, 4, 0},
95 {AADD, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
96 {AADD, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
97 {AADD, C_SCON, C_REG, C_NONE, C_REG, 4, 4, 0},
98 {AADD, C_SCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
99 {AADD, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
100 {AADD, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
101 {AADD, C_UCON, C_REG, C_NONE, C_REG, 20, 4, 0},
102 {AADD, C_UCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
103 {AADD, C_ANDCON, C_REG, C_NONE, C_REG, 22, 8, 0},
104 {AADD, C_ANDCON, C_NONE, C_NONE, C_REG, 22, 8, 0},
105 {AADD, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
106 {AADD, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
107 {AADDIS, C_ADDCON, C_REG, C_NONE, C_REG, 20, 4, 0},
108 {AADDIS, C_ADDCON, C_NONE, C_NONE, C_REG, 20, 4, 0},
109 {AADDC, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
110 {AADDC, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
111 {AADDC, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
112 {AADDC, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
113 {AADDC, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
114 {AADDC, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
115 {AAND, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, no literal */
116 {AAND, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
117 {AANDCC, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
118 {AANDCC, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
119 {AANDCC, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
120 {AANDCC, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
121 {AANDCC, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
122 {AANDCC, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
123 {AANDCC, C_ADDCON, C_NONE, C_NONE, C_REG, 23, 8, 0},
124 {AANDCC, C_ADDCON, C_REG, C_NONE, C_REG, 23, 8, 0},
125 {AANDCC, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
126 {AANDCC, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
127 {AANDISCC, C_ANDCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
128 {AANDISCC, C_ANDCON, C_REG, C_NONE, C_REG, 59, 4, 0},
129 {AMULLW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0},
130 {AMULLW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
131 {AMULLW, C_ADDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
132 {AMULLW, C_ADDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
133 {AMULLW, C_ANDCON, C_REG, C_NONE, C_REG, 4, 4, 0},
134 {AMULLW, C_ANDCON, C_NONE, C_NONE, C_REG, 4, 4, 0},
135 {AMULLW, C_LCON, C_REG, C_NONE, C_REG, 22, 12, 0},
136 {AMULLW, C_LCON, C_NONE, C_NONE, C_REG, 22, 12, 0},
137 {ASUBC, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0},
138 {ASUBC, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
139 {ASUBC, C_REG, C_NONE, C_ADDCON, C_REG, 27, 4, 0},
140 {ASUBC, C_REG, C_NONE, C_LCON, C_REG, 28, 12, 0},
141 {AOR, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0}, /* logical, literal not cc (or/xor) */
142 {AOR, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
143 {AOR, C_ANDCON, C_NONE, C_NONE, C_REG, 58, 4, 0},
144 {AOR, C_ANDCON, C_REG, C_NONE, C_REG, 58, 4, 0},
145 {AOR, C_UCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
146 {AOR, C_UCON, C_REG, C_NONE, C_REG, 59, 4, 0},
147 {AOR, C_ADDCON, C_NONE, C_NONE, C_REG, 23, 8, 0},
148 {AOR, C_ADDCON, C_REG, C_NONE, C_REG, 23, 8, 0},
149 {AOR, C_LCON, C_NONE, C_NONE, C_REG, 23, 12, 0},
150 {AOR, C_LCON, C_REG, C_NONE, C_REG, 23, 12, 0},
151 {AORIS, C_ANDCON, C_NONE, C_NONE, C_REG, 59, 4, 0},
152 {AORIS, C_ANDCON, C_REG, C_NONE, C_REG, 59, 4, 0},
153 {ADIVW, C_REG, C_REG, C_NONE, C_REG, 2, 4, 0}, /* op r1[,r2],r3 */
154 {ADIVW, C_REG, C_NONE, C_NONE, C_REG, 2, 4, 0},
155 {ASUB, C_REG, C_REG, C_NONE, C_REG, 10, 4, 0}, /* op r2[,r1],r3 */
156 {ASUB, C_REG, C_NONE, C_NONE, C_REG, 10, 4, 0},
157 {ASLW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
158 {ASLW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
159 {ASLD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
160 {ASLD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
161 {ASLD, C_SCON, C_REG, C_NONE, C_REG, 25, 4, 0},
162 {ASLD, C_SCON, C_NONE, C_NONE, C_REG, 25, 4, 0},
163 {ASLW, C_SCON, C_REG, C_NONE, C_REG, 57, 4, 0},
164 {ASLW, C_SCON, C_NONE, C_NONE, C_REG, 57, 4, 0},
165 {ASRAW, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
166 {ASRAW, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
167 {ASRAW, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
168 {ASRAW, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
169 {ASRAD, C_REG, C_NONE, C_NONE, C_REG, 6, 4, 0},
170 {ASRAD, C_REG, C_REG, C_NONE, C_REG, 6, 4, 0},
171 {ASRAD, C_SCON, C_REG, C_NONE, C_REG, 56, 4, 0},
172 {ASRAD, C_SCON, C_NONE, C_NONE, C_REG, 56, 4, 0},
173 {ARLWMI, C_SCON, C_REG, C_LCON, C_REG, 62, 4, 0},
174 {ARLWMI, C_REG, C_REG, C_LCON, C_REG, 63, 4, 0},
175 {ARLDMI, C_SCON, C_REG, C_LCON, C_REG, 30, 4, 0},
176 {ARLDC, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
177 {ARLDCL, C_SCON, C_REG, C_LCON, C_REG, 29, 4, 0},
178 {ARLDCL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
179 {ARLDICL, C_REG, C_REG, C_LCON, C_REG, 14, 4, 0},
180 {ARLDICL, C_SCON, C_REG, C_LCON, C_REG, 14, 4, 0},
181 {ARLDCL, C_REG, C_NONE, C_LCON, C_REG, 14, 4, 0},
182 {AFADD, C_FREG, C_NONE, C_NONE, C_FREG, 2, 4, 0},
183 {AFADD, C_FREG, C_FREG, C_NONE, C_FREG, 2, 4, 0},
184 {AFABS, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
185 {AFABS, C_NONE, C_NONE, C_NONE, C_FREG, 33, 4, 0},
186 {AFMOVD, C_FREG, C_NONE, C_NONE, C_FREG, 33, 4, 0},
187 {AFMADD, C_FREG, C_FREG, C_FREG, C_FREG, 34, 4, 0},
188 {AFMUL, C_FREG, C_NONE, C_NONE, C_FREG, 32, 4, 0},
189 {AFMUL, C_FREG, C_FREG, C_NONE, C_FREG, 32, 4, 0},
191 /* store, short offset */
192 {AMOVD, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
193 {AMOVW, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
194 {AMOVWZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
195 {AMOVBZ, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
196 {AMOVBZU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
197 {AMOVB, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
198 {AMOVBU, C_REG, C_REG, C_NONE, C_ZOREG, 7, 4, REGZERO},
199 {AMOVD, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
200 {AMOVW, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
201 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
202 {AMOVBZ, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
203 {AMOVB, C_REG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
204 {AMOVD, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
205 {AMOVW, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
206 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
207 {AMOVBZ, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
208 {AMOVB, C_REG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
209 {AMOVD, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
210 {AMOVW, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
211 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
212 {AMOVBZ, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
213 {AMOVBZU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
214 {AMOVB, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
215 {AMOVBU, C_REG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
217 /* load, short offset */
218 {AMOVD, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
219 {AMOVW, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
220 {AMOVWZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
221 {AMOVBZ, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
222 {AMOVBZU, C_ZOREG, C_REG, C_NONE, C_REG, 8, 4, REGZERO},
223 {AMOVB, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
224 {AMOVBU, C_ZOREG, C_REG, C_NONE, C_REG, 9, 8, REGZERO},
225 {AMOVD, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
226 {AMOVW, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
227 {AMOVWZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
228 {AMOVBZ, C_SEXT, C_NONE, C_NONE, C_REG, 8, 4, REGSB},
229 {AMOVB, C_SEXT, C_NONE, C_NONE, C_REG, 9, 8, REGSB},
230 {AMOVD, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
231 {AMOVW, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
232 {AMOVWZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
233 {AMOVBZ, C_SAUTO, C_NONE, C_NONE, C_REG, 8, 4, REGSP},
234 {AMOVB, C_SAUTO, C_NONE, C_NONE, C_REG, 9, 8, REGSP},
235 {AMOVD, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
236 {AMOVW, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
237 {AMOVWZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
238 {AMOVBZ, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
239 {AMOVBZU, C_SOREG, C_NONE, C_NONE, C_REG, 8, 4, REGZERO},
240 {AMOVB, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
241 {AMOVBU, C_SOREG, C_NONE, C_NONE, C_REG, 9, 8, REGZERO},
243 /* store, long offset */
244 {AMOVD, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
245 {AMOVW, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
246 {AMOVWZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
247 {AMOVBZ, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
248 {AMOVB, C_REG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
249 {AMOVD, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
250 {AMOVW, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
251 {AMOVWZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
252 {AMOVBZ, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
253 {AMOVB, C_REG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
254 {AMOVD, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
255 {AMOVW, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
256 {AMOVWZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
257 {AMOVBZ, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
258 {AMOVB, C_REG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
259 {AMOVD, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
260 {AMOVW, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
261 {AMOVWZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
262 {AMOVBZ, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
263 {AMOVB, C_REG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
265 /* load, long offset */
266 {AMOVD, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
267 {AMOVW, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
268 {AMOVWZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
269 {AMOVBZ, C_LEXT, C_NONE, C_NONE, C_REG, 36, 8, REGSB},
270 {AMOVB, C_LEXT, C_NONE, C_NONE, C_REG, 37, 12, REGSB},
271 {AMOVD, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
272 {AMOVW, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
273 {AMOVWZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
274 {AMOVBZ, C_LAUTO, C_NONE, C_NONE, C_REG, 36, 8, REGSP},
275 {AMOVB, C_LAUTO, C_NONE, C_NONE, C_REG, 37, 12, REGSP},
276 {AMOVD, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
277 {AMOVW, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
278 {AMOVWZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
279 {AMOVBZ, C_LOREG, C_NONE, C_NONE, C_REG, 36, 8, REGZERO},
280 {AMOVB, C_LOREG, C_NONE, C_NONE, C_REG, 37, 12, REGZERO},
281 {AMOVD, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
282 {AMOVW, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
283 {AMOVWZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
284 {AMOVBZ, C_ADDR, C_NONE, C_NONE, C_REG, 75, 8, 0},
285 {AMOVB, C_ADDR, C_NONE, C_NONE, C_REG, 76, 12, 0},
287 {AMOVD, C_TLS_LE, C_NONE, C_NONE, C_REG, 79, 4, 0},
288 {AMOVD, C_TLS_IE, C_NONE, C_NONE, C_REG, 80, 8, 0},
290 {AMOVD, C_GOTADDR, C_NONE, C_NONE, C_REG, 81, 8, 0},
291 {AMOVD, C_TOCADDR, C_NONE, C_NONE, C_REG, 95, 8, 0},
294 {AMOVD, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB},
295 {AMOVD, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
296 {AMOVD, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
297 {AMOVD, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
298 {AMOVD, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
299 {AMOVD, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
300 {AMOVW, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
301 {AMOVW, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
302 {AMOVW, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
303 {AMOVW, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
304 {AMOVW, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
305 {AMOVW, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
306 {AMOVWZ, C_SECON, C_NONE, C_NONE, C_REG, 3, 4, REGSB}, /* TO DO: check */
307 {AMOVWZ, C_SACON, C_NONE, C_NONE, C_REG, 3, 4, REGSP},
308 {AMOVWZ, C_LECON, C_NONE, C_NONE, C_REG, 26, 8, REGSB},
309 {AMOVWZ, C_LACON, C_NONE, C_NONE, C_REG, 26, 8, REGSP},
310 {AMOVWZ, C_ADDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
311 {AMOVWZ, C_ANDCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
313 /* load unsigned/long constants (TO DO: check) */
314 {AMOVD, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
315 {AMOVD, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
316 {AMOVW, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
317 {AMOVW, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
318 {AMOVWZ, C_UCON, C_NONE, C_NONE, C_REG, 3, 4, REGZERO},
319 {AMOVWZ, C_LCON, C_NONE, C_NONE, C_REG, 19, 8, 0},
320 {AMOVHBR, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
321 {AMOVHBR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
322 {AMOVHBR, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
323 {AMOVHBR, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
324 {ASYSCALL, C_NONE, C_NONE, C_NONE, C_NONE, 5, 4, 0},
325 {ASYSCALL, C_REG, C_NONE, C_NONE, C_NONE, 77, 12, 0},
326 {ASYSCALL, C_SCON, C_NONE, C_NONE, C_NONE, 77, 12, 0},
327 {ABEQ, C_NONE, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
328 {ABEQ, C_CREG, C_NONE, C_NONE, C_SBRA, 16, 4, 0},
329 {ABR, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0},
330 {ABR, C_NONE, C_NONE, C_NONE, C_LBRAPIC, 11, 8, 0},
331 {ABC, C_SCON, C_REG, C_NONE, C_SBRA, 16, 4, 0},
332 {ABC, C_SCON, C_REG, C_NONE, C_LBRA, 17, 4, 0},
333 {ABR, C_NONE, C_NONE, C_NONE, C_LR, 18, 4, 0},
334 {ABR, C_NONE, C_NONE, C_NONE, C_CTR, 18, 4, 0},
335 {ABR, C_REG, C_NONE, C_NONE, C_CTR, 18, 4, 0},
336 {ABR, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
337 {ABC, C_NONE, C_REG, C_NONE, C_LR, 18, 4, 0},
338 {ABC, C_NONE, C_REG, C_NONE, C_CTR, 18, 4, 0},
339 {ABC, C_SCON, C_REG, C_NONE, C_LR, 18, 4, 0},
340 {ABC, C_SCON, C_REG, C_NONE, C_CTR, 18, 4, 0},
341 {ABC, C_NONE, C_NONE, C_NONE, C_ZOREG, 15, 8, 0},
342 {AFMOVD, C_SEXT, C_NONE, C_NONE, C_FREG, 8, 4, REGSB},
343 {AFMOVD, C_SAUTO, C_NONE, C_NONE, C_FREG, 8, 4, REGSP},
344 {AFMOVD, C_SOREG, C_NONE, C_NONE, C_FREG, 8, 4, REGZERO},
345 {AFMOVD, C_LEXT, C_NONE, C_NONE, C_FREG, 36, 8, REGSB},
346 {AFMOVD, C_LAUTO, C_NONE, C_NONE, C_FREG, 36, 8, REGSP},
347 {AFMOVD, C_LOREG, C_NONE, C_NONE, C_FREG, 36, 8, REGZERO},
348 {AFMOVD, C_ZCON, C_NONE, C_NONE, C_FREG, 24, 4, 0},
349 {AFMOVD, C_ADDCON, C_NONE, C_NONE, C_FREG, 24, 8, 0},
350 {AFMOVD, C_ADDR, C_NONE, C_NONE, C_FREG, 75, 8, 0},
351 {AFMOVD, C_FREG, C_NONE, C_NONE, C_SEXT, 7, 4, REGSB},
352 {AFMOVD, C_FREG, C_NONE, C_NONE, C_SAUTO, 7, 4, REGSP},
353 {AFMOVD, C_FREG, C_NONE, C_NONE, C_SOREG, 7, 4, REGZERO},
354 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LEXT, 35, 8, REGSB},
355 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LAUTO, 35, 8, REGSP},
356 {AFMOVD, C_FREG, C_NONE, C_NONE, C_LOREG, 35, 8, REGZERO},
357 {AFMOVD, C_FREG, C_NONE, C_NONE, C_ADDR, 74, 8, 0},
358 {AFMOVSX, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0},
359 {AFMOVSX, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0},
360 {AFMOVSX, C_FREG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
361 {AFMOVSX, C_FREG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
362 {AFMOVSZ, C_ZOREG, C_REG, C_NONE, C_FREG, 45, 4, 0},
363 {AFMOVSZ, C_ZOREG, C_NONE, C_NONE, C_FREG, 45, 4, 0},
364 {ASYNC, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
365 {AWORD, C_LCON, C_NONE, C_NONE, C_NONE, 40, 4, 0},
366 {ADWORD, C_LCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
367 {ADWORD, C_DCON, C_NONE, C_NONE, C_NONE, 31, 8, 0},
368 {AADDME, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
369 {AEXTSB, C_REG, C_NONE, C_NONE, C_REG, 48, 4, 0},
370 {AEXTSB, C_NONE, C_NONE, C_NONE, C_REG, 48, 4, 0},
371 {AISEL, C_LCON, C_REG, C_REG, C_REG, 84, 4, 0},
372 {AISEL, C_ZCON, C_REG, C_REG, C_REG, 84, 4, 0},
373 {ANEG, C_REG, C_NONE, C_NONE, C_REG, 47, 4, 0},
374 {ANEG, C_NONE, C_NONE, C_NONE, C_REG, 47, 4, 0},
375 {AREM, C_REG, C_NONE, C_NONE, C_REG, 50, 12, 0},
376 {AREM, C_REG, C_REG, C_NONE, C_REG, 50, 12, 0},
377 {AREMU, C_REG, C_NONE, C_NONE, C_REG, 50, 16, 0},
378 {AREMU, C_REG, C_REG, C_NONE, C_REG, 50, 16, 0},
379 {AREMD, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
380 {AREMD, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
381 {AREMDU, C_REG, C_NONE, C_NONE, C_REG, 51, 12, 0},
382 {AREMDU, C_REG, C_REG, C_NONE, C_REG, 51, 12, 0},
383 {AMTFSB0, C_SCON, C_NONE, C_NONE, C_NONE, 52, 4, 0},
384 {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_FREG, 53, 4, 0},
385 {AMOVFL, C_FREG, C_NONE, C_NONE, C_FPSCR, 64, 4, 0},
386 {AMOVFL, C_FREG, C_NONE, C_LCON, C_FPSCR, 64, 4, 0},
387 {AMOVFL, C_LCON, C_NONE, C_NONE, C_FPSCR, 65, 4, 0},
388 {AMOVD, C_MSR, C_NONE, C_NONE, C_REG, 54, 4, 0}, /* mfmsr */
389 {AMOVD, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsrd */
390 {AMOVWZ, C_REG, C_NONE, C_NONE, C_MSR, 54, 4, 0}, /* mtmsr */
392 /* Other ISA 2.05+ instructions */
393 {APOPCNTD, C_REG, C_NONE, C_NONE, C_REG, 93, 4, 0}, /* population count, x-form */
394 {ACMPB, C_REG, C_REG, C_NONE, C_REG, 92, 4, 0}, /* compare byte, x-form */
395 {ACMPEQB, C_REG, C_REG, C_NONE, C_CREG, 92, 4, 0}, /* compare equal byte, x-form, ISA 3.0 */
396 {ACMPEQB, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
397 {AFTDIV, C_FREG, C_FREG, C_NONE, C_SCON, 92, 4, 0}, /* floating test for sw divide, x-form */
398 {AFTSQRT, C_FREG, C_NONE, C_NONE, C_SCON, 93, 4, 0}, /* floating test for sw square root, x-form */
399 {ACOPY, C_REG, C_NONE, C_NONE, C_REG, 92, 4, 0}, /* copy/paste facility, x-form */
400 {ADARN, C_SCON, C_NONE, C_NONE, C_REG, 92, 4, 0}, /* deliver random number, x-form */
401 {ALDMX, C_SOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, /* load doubleword monitored, x-form */
402 {AMADDHD, C_REG, C_REG, C_REG, C_REG, 83, 4, 0}, /* multiply-add high/low doubleword, va-form */
403 {AADDEX, C_REG, C_REG, C_SCON, C_REG, 94, 4, 0}, /* add extended using alternate carry, z23-form */
404 {ACRAND, C_CREG, C_NONE, C_NONE, C_CREG, 2, 4, 0}, /* logical ops for condition registers xl-form */
406 /* Vector instructions */
409 {ALV, C_SOREG, C_NONE, C_NONE, C_VREG, 45, 4, 0}, /* vector load, x-form */
412 {ASTV, C_VREG, C_NONE, C_NONE, C_SOREG, 44, 4, 0}, /* vector store, x-form */
415 {AVAND, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector and, vx-form */
416 {AVOR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector or, vx-form */
419 {AVADDUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned modulo, vx-form */
420 {AVADDCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add & write carry unsigned, vx-form */
421 {AVADDUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add unsigned saturate, vx-form */
422 {AVADDSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector add signed saturate, vx-form */
423 {AVADDE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector add extended, va-form */
425 /* Vector subtract */
426 {AVSUBUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned modulo, vx-form */
427 {AVSUBCU, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract & write carry unsigned, vx-form */
428 {AVSUBUS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract unsigned saturate, vx-form */
429 {AVSUBSS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector subtract signed saturate, vx-form */
430 {AVSUBE, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector subtract extended, va-form */
432 /* Vector multiply */
433 {AVMULESB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 9}, /* vector multiply, vx-form */
434 {AVPMSUM, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector polynomial multiply & sum, vx-form */
435 {AVMSUMUDM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector multiply-sum, va-form */
438 {AVR, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector rotate, vx-form */
441 {AVS, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector shift, vx-form */
442 {AVSA, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector shift algebraic, vx-form */
443 {AVSOI, C_ANDCON, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector shift by octet immediate, va-form */
446 {AVCLZ, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector count leading zeros, vx-form */
447 {AVPOPCNT, C_VREG, C_NONE, C_NONE, C_VREG, 85, 4, 0}, /* vector population count, vx-form */
450 {AVCMPEQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare equal, vc-form */
451 {AVCMPGT, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare greater than, vc-form */
452 {AVCMPNEZB, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector compare not equal, vx-form */
455 {AVMRGOW, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector merge odd word, vx-form */
458 {AVPERM, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector permute, va-form */
460 /* Vector bit permute */
461 {AVBPERMQ, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector bit permute, vx-form */
464 {AVSEL, C_VREG, C_VREG, C_VREG, C_VREG, 83, 4, 0}, /* vector select, va-form */
467 {AVSPLTB, C_SCON, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector splat, vx-form */
468 {AVSPLTB, C_ADDCON, C_VREG, C_NONE, C_VREG, 82, 4, 0},
469 {AVSPLTISB, C_SCON, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector splat immediate, vx-form */
470 {AVSPLTISB, C_ADDCON, C_NONE, C_NONE, C_VREG, 82, 4, 0},
473 {AVCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES cipher, vx-form */
474 {AVNCIPH, C_VREG, C_VREG, C_NONE, C_VREG, 82, 4, 0}, /* vector AES inverse cipher, vx-form */
475 {AVSBOX, C_VREG, C_NONE, C_NONE, C_VREG, 82, 4, 0}, /* vector AES subbytes, vx-form */
478 {AVSHASIGMA, C_ANDCON, C_VREG, C_ANDCON, C_VREG, 82, 4, 0}, /* vector SHA sigma, vx-form */
480 /* VSX vector load */
481 {ALXVD2X, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx vector load, xx1-form */
482 {ALXV, C_SOREG, C_NONE, C_NONE, C_VSREG, 96, 4, 0}, /* vsx vector load, dq-form */
483 {ALXVL, C_REG, C_REG, C_NONE, C_VSREG, 98, 4, 0}, /* vsx vector load length */
485 /* VSX vector store */
486 {ASTXVD2X, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx vector store, xx1-form */
487 {ASTXV, C_VSREG, C_NONE, C_NONE, C_SOREG, 97, 4, 0}, /* vsx vector store, dq-form */
488 {ASTXVL, C_VSREG, C_REG, C_NONE, C_REG, 99, 4, 0}, /* vsx vector store with length x-form */
490 /* VSX scalar load */
491 {ALXSDX, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar load, xx1-form */
493 /* VSX scalar store */
494 {ASTXSDX, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar store, xx1-form */
496 /* VSX scalar as integer load */
497 {ALXSIWAX, C_SOREG, C_NONE, C_NONE, C_VSREG, 87, 4, 0}, /* vsx scalar as integer load, xx1-form */
499 /* VSX scalar store as integer */
500 {ASTXSIWX, C_VSREG, C_NONE, C_NONE, C_SOREG, 86, 4, 0}, /* vsx scalar as integer store, xx1-form */
502 /* VSX move from VSR */
503 {AMFVSRD, C_VSREG, C_NONE, C_NONE, C_REG, 88, 4, 0}, /* vsx move from vsr, xx1-form */
504 {AMFVSRD, C_FREG, C_NONE, C_NONE, C_REG, 88, 4, 0},
505 {AMFVSRD, C_VREG, C_NONE, C_NONE, C_REG, 88, 4, 0},
507 /* VSX move to VSR */
508 {AMTVSRD, C_REG, C_NONE, C_NONE, C_VSREG, 88, 4, 0}, /* vsx move to vsr, xx1-form */
509 {AMTVSRD, C_REG, C_REG, C_NONE, C_VSREG, 88, 4, 0},
510 {AMTVSRD, C_REG, C_NONE, C_NONE, C_FREG, 88, 4, 0},
511 {AMTVSRD, C_REG, C_NONE, C_NONE, C_VREG, 88, 4, 0},
514 {AXXLAND, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx and, xx3-form */
515 {AXXLOR, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx or, xx3-form */
518 {AXXSEL, C_VSREG, C_VSREG, C_VSREG, C_VSREG, 91, 4, 0}, /* vsx select, xx4-form */
521 {AXXMRGHW, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx merge, xx3-form */
524 {AXXSPLTW, C_VSREG, C_NONE, C_SCON, C_VSREG, 89, 4, 0}, /* vsx splat, xx2-form */
525 {AXXSPLTIB, C_SCON, C_NONE, C_NONE, C_VSREG, 100, 4, 0}, /* vsx splat, xx2-form */
528 {AXXPERM, C_VSREG, C_VSREG, C_NONE, C_VSREG, 90, 4, 0}, /* vsx permute, xx3-form */
531 {AXXSLDWI, C_VSREG, C_VSREG, C_SCON, C_VSREG, 90, 4, 0}, /* vsx shift immediate, xx3-form */
533 /* VSX reverse bytes */
534 {AXXBRQ, C_VSREG, C_NONE, C_NONE, C_VSREG, 101, 4, 0}, /* vsx reverse bytes */
536 /* VSX scalar FP-FP conversion */
537 {AXSCVDPSP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-fp conversion, xx2-form */
539 /* VSX vector FP-FP conversion */
540 {AXVCVDPSP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-fp conversion, xx2-form */
542 /* VSX scalar FP-integer conversion */
543 {AXSCVDPSXDS, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar fp-integer conversion, xx2-form */
545 /* VSX scalar integer-FP conversion */
546 {AXSCVSXDDP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx scalar integer-fp conversion, xx2-form */
548 /* VSX vector FP-integer conversion */
549 {AXVCVDPSXDS, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector fp-integer conversion, xx2-form */
551 /* VSX vector integer-FP conversion */
552 {AXVCVSXDDP, C_VSREG, C_NONE, C_NONE, C_VSREG, 89, 4, 0}, /* vsx vector integer-fp conversion, xx2-form */
554 /* 64-bit special registers */
555 {AMOVD, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
556 {AMOVD, C_REG, C_NONE, C_NONE, C_LR, 66, 4, 0},
557 {AMOVD, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
558 {AMOVD, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
559 {AMOVD, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
560 {AMOVD, C_LR, C_NONE, C_NONE, C_REG, 66, 4, 0},
561 {AMOVD, C_CTR, C_NONE, C_NONE, C_REG, 66, 4, 0},
562 {AMOVD, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
564 /* 32-bit special registers (gloss over sign-extension or not?) */
565 {AMOVW, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
566 {AMOVW, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
567 {AMOVW, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
568 {AMOVW, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
569 {AMOVW, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
570 {AMOVWZ, C_REG, C_NONE, C_NONE, C_SPR, 66, 4, 0},
571 {AMOVWZ, C_REG, C_NONE, C_NONE, C_CTR, 66, 4, 0},
572 {AMOVWZ, C_REG, C_NONE, C_NONE, C_XER, 66, 4, 0},
573 {AMOVWZ, C_SPR, C_NONE, C_NONE, C_REG, 66, 4, 0},
574 {AMOVWZ, C_XER, C_NONE, C_NONE, C_REG, 66, 4, 0},
575 {AMOVFL, C_FPSCR, C_NONE, C_NONE, C_CREG, 73, 4, 0},
576 {AMOVFL, C_CREG, C_NONE, C_NONE, C_CREG, 67, 4, 0},
577 {AMOVW, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
578 {AMOVWZ, C_CREG, C_NONE, C_NONE, C_REG, 68, 4, 0},
579 {AMOVFL, C_REG, C_NONE, C_NONE, C_LCON, 69, 4, 0},
580 {AMOVFL, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
581 {AMOVW, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
582 {AMOVWZ, C_REG, C_NONE, C_NONE, C_CREG, 69, 4, 0},
583 {ACMP, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
584 {ACMP, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
585 {ACMP, C_REG, C_NONE, C_NONE, C_ADDCON, 71, 4, 0},
586 {ACMP, C_REG, C_REG, C_NONE, C_ADDCON, 71, 4, 0},
587 {ACMPU, C_REG, C_NONE, C_NONE, C_REG, 70, 4, 0},
588 {ACMPU, C_REG, C_REG, C_NONE, C_REG, 70, 4, 0},
589 {ACMPU, C_REG, C_NONE, C_NONE, C_ANDCON, 71, 4, 0},
590 {ACMPU, C_REG, C_REG, C_NONE, C_ANDCON, 71, 4, 0},
591 {AFCMPO, C_FREG, C_NONE, C_NONE, C_FREG, 70, 4, 0},
592 {AFCMPO, C_FREG, C_REG, C_NONE, C_FREG, 70, 4, 0},
593 {ATW, C_LCON, C_REG, C_NONE, C_REG, 60, 4, 0},
594 {ATW, C_LCON, C_REG, C_NONE, C_ADDCON, 61, 4, 0},
595 {ADCBF, C_ZOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
596 {ADCBF, C_SOREG, C_NONE, C_NONE, C_NONE, 43, 4, 0},
597 {ADCBF, C_ZOREG, C_REG, C_NONE, C_SCON, 43, 4, 0},
598 {ADCBF, C_SOREG, C_NONE, C_NONE, C_SCON, 43, 4, 0},
599 {AECOWX, C_REG, C_REG, C_NONE, C_ZOREG, 44, 4, 0},
600 {AECIWX, C_ZOREG, C_REG, C_NONE, C_REG, 45, 4, 0},
601 {AECOWX, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
602 {AECIWX, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
603 {ALDAR, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
604 {ALDAR, C_ZOREG, C_NONE, C_ANDCON, C_REG, 45, 4, 0},
605 {AEIEIO, C_NONE, C_NONE, C_NONE, C_NONE, 46, 4, 0},
606 {ATLBIE, C_REG, C_NONE, C_NONE, C_NONE, 49, 4, 0},
607 {ATLBIE, C_SCON, C_NONE, C_NONE, C_REG, 49, 4, 0},
608 {ASLBMFEE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
609 {ASLBMTE, C_REG, C_NONE, C_NONE, C_REG, 55, 4, 0},
610 {ASTSW, C_REG, C_NONE, C_NONE, C_ZOREG, 44, 4, 0},
611 {ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0},
612 {ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0},
613 {ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0},
614 {obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0},
615 {obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0},
616 {obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0},
617 {obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0},
618 {obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
619 {obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL
620 {obj.APCALIGN, C_LCON, C_NONE, C_NONE, C_NONE, 0, 0, 0}, // align code
622 {obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0},
625 var oprange [ALAST & obj.AMask][]Optab
627 var xcmp [C_NCLASS][C_NCLASS]bool
629 // padding bytes to add to align code as requested
630 func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int {
631 // For 16 and 32 byte alignment, there is a tradeoff
632 // between aligning the code and adding too many NOPs.
639 // Align to 16 bytes if possible but add at
648 // Align to 32 bytes if possible but add at
658 // When 32 byte alignment is requested on Linux,
659 // promote the function's alignment to 32. On AIX
660 // the function alignment is not changed which might
661 // result in 16 byte alignment but that is still fine.
662 // TODO: alignment on AIX
663 if ctxt.Headtype != objabi.Haix && cursym.Func.Align < 32 {
664 cursym.Func.Align = 32
667 ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a)
672 func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
673 p := cursym.Func.Text
674 if p == nil || p.Link == nil { // handle external functions and ELF section symbols
678 if oprange[AANDN&obj.AMask] == nil {
679 ctxt.Diag("ppc64 ops not initialized, call ppc64.buildop first")
682 c := ctxt9{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset)}
689 for p = p.Link; p != nil; p = p.Link {
694 if p.As == obj.APCALIGN {
695 a := c.vregoff(&p.From)
696 m = addpad(pc, a, ctxt, cursym)
698 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
699 ctxt.Diag("zero-width instruction\n%v", p)
710 * if any procedure is large enough to
711 * generate a large SBRA branch, then
712 * generate extra passes putting branches
713 * around jmps to fix. this is rare.
722 for p = c.cursym.Func.Text.Link; p != nil; p = p.Link {
726 // very large conditional branches
727 if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
728 otxt = p.Pcond.Pc - pc
729 if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
734 q.To.Type = obj.TYPE_BRANCH
741 q.To.Type = obj.TYPE_BRANCH
742 q.Pcond = q.Link.Link
752 if p.As == obj.APCALIGN {
753 a := c.vregoff(&p.From)
754 m = addpad(pc, a, ctxt, cursym)
756 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
757 ctxt.Diag("zero-width instruction\n%v", p)
769 if r := pc & funcAlignMask; r != 0 {
776 * lay out the code, emitting code and data relocations.
779 c.cursym.Grow(c.cursym.Size)
784 for p := c.cursym.Func.Text.Link; p != nil; p = p.Link {
787 if int(o.size) > 4*len(out) {
788 log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)
790 // asmout is not set up to add large amounts of padding
791 if o.type_ == 0 && p.As == obj.APCALIGN {
792 pad := LOP_RRR(OP_OR, REGZERO, REGZERO, REGZERO)
793 aln := c.vregoff(&p.From)
794 v := addpad(p.Pc, aln, c.ctxt, c.cursym)
796 // Same padding instruction for all
797 for i = 0; i < int32(v/4); i++ {
798 c.ctxt.Arch.ByteOrder.PutUint32(bp, pad)
803 c.asmout(p, o, out[:])
804 for i = 0; i < int32(o.size/4); i++ {
805 c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
812 func isint32(v int64) bool {
813 return int64(int32(v)) == v
816 func isuint32(v uint64) bool {
817 return uint64(uint32(v)) == v
820 func (c *ctxt9) aclass(a *obj.Addr) int {
826 if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
829 if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
832 if REG_V0 <= a.Reg && a.Reg <= REG_V31 {
835 if REG_VS0 <= a.Reg && a.Reg <= REG_VS63 {
838 if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR {
841 if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
856 if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
859 if a.Reg == REG_FPSCR {
862 if a.Reg == REG_MSR {
869 case obj.NAME_EXTERN,
874 c.instoffset = a.Offset
875 if a.Sym != nil { // use relocation
876 if a.Sym.Type == objabi.STLSBSS {
877 if c.ctxt.Flag_shared {
887 case obj.NAME_GOTREF:
890 case obj.NAME_TOCREF:
894 c.instoffset = int64(c.autosize) + a.Offset
895 if c.instoffset >= -BIG && c.instoffset < BIG {
901 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
902 if c.instoffset >= -BIG && c.instoffset < BIG {
908 c.instoffset = a.Offset
909 if c.instoffset == 0 {
912 if c.instoffset >= -BIG && c.instoffset < BIG {
920 case obj.TYPE_TEXTSIZE:
923 case obj.TYPE_FCONST:
924 // The only cases where FCONST will occur are with float64 +/- 0.
925 // All other float constants are generated in memory.
926 f64 := a.Val.(float64)
928 if math.Signbit(f64) {
933 log.Fatalf("Unexpected nonzero FCONST operand %v", a)
939 c.instoffset = a.Offset
941 if -BIG <= c.instoffset && c.instoffset <= BIG {
944 if isint32(c.instoffset) {
950 case obj.NAME_EXTERN,
957 c.instoffset = a.Offset
959 /* not sure why this barfs */
963 c.instoffset = int64(c.autosize) + a.Offset
964 if c.instoffset >= -BIG && c.instoffset < BIG {
970 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
971 if c.instoffset >= -BIG && c.instoffset < BIG {
980 if c.instoffset >= 0 {
981 if c.instoffset == 0 {
984 if c.instoffset <= 0x7fff {
987 if c.instoffset <= 0xffff {
990 if c.instoffset&0xffff == 0 && isuint32(uint64(c.instoffset)) { /* && (instoffset & (1<<31)) == 0) */
993 if isint32(c.instoffset) || isuint32(uint64(c.instoffset)) {
999 if c.instoffset >= -0x8000 {
1002 if c.instoffset&0xffff == 0 && isint32(c.instoffset) {
1005 if isint32(c.instoffset) {
1010 case obj.TYPE_BRANCH:
1011 if a.Sym != nil && c.ctxt.Flag_dynlink {
1020 func prasm(p *obj.Prog) {
1021 fmt.Printf("%v\n", p)
1024 func (c *ctxt9) oplook(p *obj.Prog) *Optab {
1029 a1 = int(p.From.Class)
1031 a1 = c.aclass(&p.From) + 1
1032 p.From.Class = int8(a1)
1037 if p.GetFrom3() != nil {
1038 a3 = int(p.GetFrom3().Class)
1040 a3 = c.aclass(p.GetFrom3()) + 1
1041 p.GetFrom3().Class = int8(a3)
1046 a4 := int(p.To.Class)
1048 a4 = c.aclass(&p.To) + 1
1049 p.To.Class = int8(a4)
1055 if REG_R0 <= p.Reg && p.Reg <= REG_R31 {
1057 } else if REG_V0 <= p.Reg && p.Reg <= REG_V31 {
1059 } else if REG_VS0 <= p.Reg && p.Reg <= REG_VS63 {
1061 } else if REG_F0 <= p.Reg && p.Reg <= REG_F31 {
1066 // c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4)
1067 ops := oprange[p.As&obj.AMask]
1071 for i := range ops {
1073 if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] {
1074 p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
1079 c.ctxt.Diag("illegal combination %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4))
1087 func cmp(a int, b int) bool {
1093 if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {
1098 if b == C_ZCON || b == C_SCON {
1103 if b == C_ZCON || b == C_SCON {
1108 if b == C_LR || b == C_XER || b == C_CTR {
1144 return r0iszero != 0 /*TypeKind(100016)*/
1148 if b == C_ZOREG || b == C_SOREG {
1166 func (x ocmp) Len() int {
1170 func (x ocmp) Swap(i, j int) {
1171 x[i], x[j] = x[j], x[i]
1174 // Used when sorting the optab. Sorting is
1175 // done in a way so that the best choice of
1176 // opcode/operand combination is considered first.
1177 func (x ocmp) Less(i, j int) bool {
1180 n := int(p1.as) - int(p2.as)
1185 // Consider those that generate fewer
1186 // instructions first.
1187 n = int(p1.size) - int(p2.size)
1191 // operand order should match
1192 // better choices first
1193 n = int(p1.a1) - int(p2.a1)
1197 n = int(p1.a2) - int(p2.a2)
1201 n = int(p1.a3) - int(p2.a3)
1205 n = int(p1.a4) - int(p2.a4)
1212 // Add an entry to the opcode table for
1213 // a new opcode b0 with the same operand combinations
1215 func opset(a, b0 obj.As) {
1216 oprange[a&obj.AMask] = oprange[b0]
1219 // Build the opcode table
1220 func buildop(ctxt *obj.Link) {
1221 if oprange[AANDN&obj.AMask] != nil {
1222 // Already initialized; stop now.
1223 // This happens in the cmd/asm tests,
1224 // each of which re-initializes the arch.
1230 for i := 0; i < C_NCLASS; i++ {
1231 for n = 0; n < C_NCLASS; n++ {
1237 for n = 0; optab[n].as != obj.AXXX; n++ {
1239 sort.Sort(ocmp(optab[:n]))
1240 for i := 0; i < n; i++ {
1244 for optab[i].as == r {
1247 oprange[r0] = optab[start:i]
1252 ctxt.Diag("unknown op in build: %v", r)
1253 log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r)
1255 case ADCBF: /* unary indexed: op (b+a); op (b) */
1264 case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
1271 case AREM: /* macro */
1292 opset(AREMDUVCC, r0)
1294 case ADIVW: /* op Rb[,Ra],Rd */
1299 opset(AMULHWUCC, r0)
1301 opset(AMULLWVCC, r0)
1309 opset(ADIVWUVCC, r0)
1326 opset(AMULHDUCC, r0)
1329 opset(AMULLDVCC, r0)
1336 opset(ADIVDEUCC, r0)
1341 opset(ADIVDUVCC, r0)
1353 case APOPCNTD: /* popcntd, popcntw, popcntb, cnttzw, cnttzd */
1357 opset(ACNTTZWCC, r0)
1359 opset(ACNTTZDCC, r0)
1361 case ACOPY: /* copy, paste. */
1364 case AMADDHD: /* maddhd, maddhdu, maddld */
1368 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
1372 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
1381 case ALV: /* lvebx, lvehx, lvewx, lvx, lvxl, lvsl, lvsr */
1390 case ASTV: /* stvebx, stvehx, stvewx, stvx, stvxl */
1397 case AVAND: /* vand, vandc, vnand */
1402 case AVMRGOW: /* vmrgew, vmrgow */
1405 case AVOR: /* vor, vorc, vxor, vnor, veqv */
1412 case AVADDUM: /* vaddubm, vadduhm, vadduwm, vaddudm, vadduqm */
1419 case AVADDCU: /* vaddcuq, vaddcuw */
1423 case AVADDUS: /* vaddubs, vadduhs, vadduws */
1428 case AVADDSS: /* vaddsbs, vaddshs, vaddsws */
1433 case AVADDE: /* vaddeuqm, vaddecuq */
1434 opset(AVADDEUQM, r0)
1435 opset(AVADDECUQ, r0)
1437 case AVSUBUM: /* vsububm, vsubuhm, vsubuwm, vsubudm, vsubuqm */
1444 case AVSUBCU: /* vsubcuq, vsubcuw */
1448 case AVSUBUS: /* vsububs, vsubuhs, vsubuws */
1453 case AVSUBSS: /* vsubsbs, vsubshs, vsubsws */
1458 case AVSUBE: /* vsubeuqm, vsubecuq */
1459 opset(AVSUBEUQM, r0)
1460 opset(AVSUBECUQ, r0)
1462 case AVMULESB: /* vmulesb, vmulosb, vmuleub, vmuloub, vmulosh, vmulouh, vmulesw, vmulosw, vmuleuw, vmulouw, vmuluwm */
1475 case AVPMSUM: /* vpmsumb, vpmsumh, vpmsumw, vpmsumd */
1481 case AVR: /* vrlb, vrlh, vrlw, vrld */
1487 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 */
1501 case AVSA: /* vsrab, vsrah, vsraw, vsrad */
1507 case AVSOI: /* vsldoi */
1510 case AVCLZ: /* vclzb, vclzh, vclzw, vclzd */
1516 case AVPOPCNT: /* vpopcntb, vpopcnth, vpopcntw, vpopcntd */
1517 opset(AVPOPCNTB, r0)
1518 opset(AVPOPCNTH, r0)
1519 opset(AVPOPCNTW, r0)
1520 opset(AVPOPCNTD, r0)
1522 case AVCMPEQ: /* vcmpequb[.], vcmpequh[.], vcmpequw[.], vcmpequd[.] */
1523 opset(AVCMPEQUB, r0)
1524 opset(AVCMPEQUBCC, r0)
1525 opset(AVCMPEQUH, r0)
1526 opset(AVCMPEQUHCC, r0)
1527 opset(AVCMPEQUW, r0)
1528 opset(AVCMPEQUWCC, r0)
1529 opset(AVCMPEQUD, r0)
1530 opset(AVCMPEQUDCC, r0)
1532 case AVCMPGT: /* vcmpgt[u,s]b[.], vcmpgt[u,s]h[.], vcmpgt[u,s]w[.], vcmpgt[u,s]d[.] */
1533 opset(AVCMPGTUB, r0)
1534 opset(AVCMPGTUBCC, r0)
1535 opset(AVCMPGTUH, r0)
1536 opset(AVCMPGTUHCC, r0)
1537 opset(AVCMPGTUW, r0)
1538 opset(AVCMPGTUWCC, r0)
1539 opset(AVCMPGTUD, r0)
1540 opset(AVCMPGTUDCC, r0)
1541 opset(AVCMPGTSB, r0)
1542 opset(AVCMPGTSBCC, r0)
1543 opset(AVCMPGTSH, r0)
1544 opset(AVCMPGTSHCC, r0)
1545 opset(AVCMPGTSW, r0)
1546 opset(AVCMPGTSWCC, r0)
1547 opset(AVCMPGTSD, r0)
1548 opset(AVCMPGTSDCC, r0)
1550 case AVCMPNEZB: /* vcmpnezb[.] */
1551 opset(AVCMPNEZBCC, r0)
1553 opset(AVCMPNEBCC, r0)
1555 opset(AVCMPNEHCC, r0)
1557 opset(AVCMPNEWCC, r0)
1559 case AVPERM: /* vperm */
1560 opset(AVPERMXOR, r0)
1563 case AVBPERMQ: /* vbpermq, vbpermd */
1566 case AVSEL: /* vsel */
1569 case AVSPLTB: /* vspltb, vsplth, vspltw */
1573 case AVSPLTISB: /* vspltisb, vspltish, vspltisw */
1574 opset(AVSPLTISH, r0)
1575 opset(AVSPLTISW, r0)
1577 case AVCIPH: /* vcipher, vcipherlast */
1579 opset(AVCIPHERLAST, r0)
1581 case AVNCIPH: /* vncipher, vncipherlast */
1582 opset(AVNCIPHER, r0)
1583 opset(AVNCIPHERLAST, r0)
1585 case AVSBOX: /* vsbox */
1588 case AVSHASIGMA: /* vshasigmaw, vshasigmad */
1589 opset(AVSHASIGMAW, r0)
1590 opset(AVSHASIGMAD, r0)
1592 case ALXVD2X: /* lxvd2x, lxvdsx, lxvw4x, lxvh8x, lxvb16x */
1598 case ALXV: /* lxv */
1601 case ALXVL: /* lxvl */
1604 case ASTXVD2X: /* stxvd2x, stxvdsx, stxvw4x, stxvh8x, stxvb16x */
1607 opset(ASTXVB16X, r0)
1609 case ASTXV: /* stxv */
1612 case ASTXVL: /* stxvl, stxvll */
1615 case ALXSDX: /* lxsdx */
1618 case ASTXSDX: /* stxsdx */
1621 case ALXSIWAX: /* lxsiwax, lxsiwzx */
1624 case ASTXSIWX: /* stxsiwx */
1627 case AMFVSRD: /* mfvsrd, mfvsrwz (and extended mnemonics), mfvsrld */
1633 case AMTVSRD: /* mtvsrd, mtvsrwa, mtvsrwz (and extended mnemonics), mtvsrdd, mtvsrws */
1641 case AXXLAND: /* xxland, xxlandc, xxleqv, xxlnand */
1646 case AXXLOR: /* xxlorc, xxlnor, xxlor, xxlxor */
1652 case AXXSEL: /* xxsel */
1655 case AXXMRGHW: /* xxmrghw, xxmrglw */
1658 case AXXSPLTW: /* xxspltw */
1661 case AXXSPLTIB: /* xxspltib */
1662 opset(AXXSPLTIB, r0)
1664 case AXXPERM: /* xxpermdi */
1667 case AXXSLDWI: /* xxsldwi */
1668 opset(AXXPERMDI, r0)
1671 case AXXBRQ: /* xxbrq, xxbrd, xxbrw, xxbrh */
1676 case AXSCVDPSP: /* xscvdpsp, xscvspdp, xscvdpspn, xscvspdpn */
1677 opset(AXSCVSPDP, r0)
1678 opset(AXSCVDPSPN, r0)
1679 opset(AXSCVSPDPN, r0)
1681 case AXVCVDPSP: /* xvcvdpsp, xvcvspdp */
1682 opset(AXVCVSPDP, r0)
1684 case AXSCVDPSXDS: /* xscvdpsxds, xscvdpsxws, xscvdpuxds, xscvdpuxws */
1685 opset(AXSCVDPSXWS, r0)
1686 opset(AXSCVDPUXDS, r0)
1687 opset(AXSCVDPUXWS, r0)
1689 case AXSCVSXDDP: /* xscvsxddp, xscvuxddp, xscvsxdsp, xscvuxdsp */
1690 opset(AXSCVUXDDP, r0)
1691 opset(AXSCVSXDSP, r0)
1692 opset(AXSCVUXDSP, r0)
1694 case AXVCVDPSXDS: /* xvcvdpsxds, xvcvdpsxws, xvcvdpuxds, xvcvdpuxws, xvcvspsxds, xvcvspsxws, xvcvspuxds, xvcvspuxws */
1695 opset(AXVCVDPSXDS, r0)
1696 opset(AXVCVDPSXWS, r0)
1697 opset(AXVCVDPUXDS, r0)
1698 opset(AXVCVDPUXWS, r0)
1699 opset(AXVCVSPSXDS, r0)
1700 opset(AXVCVSPSXWS, r0)
1701 opset(AXVCVSPUXDS, r0)
1702 opset(AXVCVSPUXWS, r0)
1704 case AXVCVSXDDP: /* xvcvsxddp, xvcvsxwdp, xvcvuxddp, xvcvuxwdp, xvcvsxdsp, xvcvsxwsp, xvcvuxdsp, xvcvuxwsp */
1705 opset(AXVCVSXWDP, r0)
1706 opset(AXVCVUXDDP, r0)
1707 opset(AXVCVUXWDP, r0)
1708 opset(AXVCVSXDSP, r0)
1709 opset(AXVCVSXWSP, r0)
1710 opset(AXVCVUXDSP, r0)
1711 opset(AXVCVUXWSP, r0)
1713 case AAND: /* logical op Rb,Rs,Ra; no literal */
1727 case AADDME: /* op Ra, Rd */
1731 opset(AADDMEVCC, r0)
1735 opset(AADDZEVCC, r0)
1739 opset(ASUBMEVCC, r0)
1743 opset(ASUBZEVCC, r0)
1763 case AEXTSB: /* op Rs, Ra */
1769 opset(ACNTLZWCC, r0)
1773 opset(ACNTLZDCC, r0)
1775 case AFABS: /* fop [s,]d */
1787 opset(AFCTIWZCC, r0)
1791 opset(AFCTIDZCC, r0)
1795 opset(AFCFIDUCC, r0)
1797 opset(AFCFIDSCC, r0)
1809 opset(AFRSQRTECC, r0)
1813 opset(AFSQRTSCC, r0)
1820 opset(AFCPSGNCC, r0)
1833 opset(AFMADDSCC, r0)
1837 opset(AFMSUBSCC, r0)
1839 opset(AFNMADDCC, r0)
1841 opset(AFNMADDSCC, r0)
1843 opset(AFNMSUBCC, r0)
1845 opset(AFNMSUBSCC, r0)
1861 opset(AMTFSB0CC, r0)
1863 opset(AMTFSB1CC, r0)
1865 case ANEG: /* op [Ra,] Rd */
1871 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,R */
1874 case AORIS: /* oris/xoris $uimm,Rs,Ra */
1889 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1892 case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1895 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
1923 opset(ARLDIMICC, r0)
1934 opset(ARLDICLCC, r0)
1936 opset(ARLDICRCC, r0)
1949 case ASYSCALL: /* just the op; flow of control */
1990 AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */
1996 /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
1997 AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals */
1998 AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
1999 AMOVB, /* macro: move byte with sign extension */
2000 AMOVBU, /* macro: move byte with sign extension & update */
2003 /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
2004 ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */
2028 func OPVXX1(o uint32, xo uint32, oe uint32) uint32 {
2029 return o<<26 | xo<<1 | oe<<11
2032 func OPVXX2(o uint32, xo uint32, oe uint32) uint32 {
2033 return o<<26 | xo<<2 | oe<<11
2036 func OPVXX2VA(o uint32, xo uint32, oe uint32) uint32 {
2037 return o<<26 | xo<<2 | oe<<16
2040 func OPVXX3(o uint32, xo uint32, oe uint32) uint32 {
2041 return o<<26 | xo<<3 | oe<<11
2044 func OPVXX4(o uint32, xo uint32, oe uint32) uint32 {
2045 return o<<26 | xo<<4 | oe<<11
2048 func OPDQ(o uint32, xo uint32, oe uint32) uint32 {
2049 return o<<26 | xo | oe<<4
2052 func OPVX(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2053 return o<<26 | xo | oe<<11 | rc&1
2056 func OPVC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2057 return o<<26 | xo | oe<<11 | (rc&1)<<10
2060 func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2061 return o<<26 | xo<<1 | oe<<10 | rc&1
2064 func OPCC(o uint32, xo uint32, rc uint32) uint32 {
2065 return OPVCC(o, xo, 0, rc)
2068 /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
2069 func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
2070 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
2073 /* VX-form 2-register operands, r/none/r */
2074 func AOP_RR(op uint32, d uint32, a uint32) uint32 {
2075 return op | (d&31)<<21 | (a&31)<<11
2078 /* VA-form 4-register operands */
2079 func AOP_RRRR(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2080 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&31)<<6
2083 func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2084 return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF
2087 /* VX-form 2-register + UIM operands */
2088 func AOP_VIRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2089 return op | (d&31)<<21 | (simm&0xFFFF)<<16 | (a&31)<<11
2092 /* VX-form 2-register + ST + SIX operands */
2093 func AOP_IIRR(op uint32, d uint32, a uint32, sbit uint32, simm uint32) uint32 {
2094 return op | (d&31)<<21 | (a&31)<<16 | (sbit&1)<<15 | (simm&0xF)<<11
2097 /* VA-form 3-register + SHB operands */
2098 func AOP_IRRR(op uint32, d uint32, a uint32, b uint32, simm uint32) uint32 {
2099 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (simm&0xF)<<6
2102 /* VX-form 1-register + SIM operands */
2103 func AOP_IR(op uint32, d uint32, simm uint32) uint32 {
2104 return op | (d&31)<<21 | (simm&31)<<16
2107 /* XX1-form 3-register operands, 1 VSR operand */
2108 func AOP_XX1(op uint32, d uint32, a uint32, b uint32) uint32 {
2109 /* For the XX-form encodings, we need the VSX register number to be exactly */
2110 /* between 0-63, so we can properly set the rightmost bits. */
2112 return op | (r&31)<<21 | (a&31)<<16 | (b&31)<<11 | (r&32)>>5
2115 /* XX2-form 3-register operands, 2 VSR operands */
2116 func AOP_XX2(op uint32, d uint32, a uint32, b uint32) uint32 {
2119 return op | (xt&31)<<21 | (a&3)<<16 | (xb&31)<<11 | (xb&32)>>4 | (xt&32)>>5
2122 /* XX3-form 3 VSR operands */
2123 func AOP_XX3(op uint32, d uint32, a uint32, b uint32) uint32 {
2127 return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2130 /* XX3-form 3 VSR operands + immediate */
2131 func AOP_XX3I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2135 return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (c&3)<<8 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2138 /* XX4-form, 4 VSR operands */
2139 func AOP_XX4(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2144 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
2147 /* DQ-form, VSR register, register + offset operands */
2148 func AOP_DQ(op uint32, d uint32, a uint32, b uint32) uint32 {
2149 /* For the DQ-form encodings, we need the VSX register number to be exactly */
2150 /* between 0-63, so we can properly set the SX bit. */
2152 /* The EA for this instruction form is (RA) + DQ << 4, where DQ is a 12-bit signed integer. */
2153 /* In order to match the output of the GNU objdump (and make the usage in Go asm easier), the */
2154 /* instruction is called using the sign extended value (i.e. a valid offset would be -32752 or 32752, */
2155 /* not -2047 or 2047), so 'b' needs to be adjusted to the expected 12-bit DQ value. Bear in mind that */
2156 /* bits 0 to 3 in 'dq' need to be zero, otherwise this will generate an illegal instruction. */
2157 /* If in doubt how this instruction form is encoded, refer to ISA 3.0b, pages 492 and 507. */
2159 return op | (r&31)<<21 | (a&31)<<16 | (dq&4095)<<4 | (r&32)>>2
2162 /* Z23-form, 3-register operands + CY field */
2163 func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2164 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<7
2167 /* X-form, 3-register operands + EH field */
2168 func AOP_RRRI(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2169 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c & 1)
2172 func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
2173 return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
2176 func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 {
2177 return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF
2180 func OP_BR(op uint32, li uint32, aa uint32) uint32 {
2181 return op | li&0x03FFFFFC | aa<<1
2184 func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 {
2185 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1
2188 func OP_BCR(op uint32, bo uint32, bi uint32) uint32 {
2189 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16
2192 func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 {
2193 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1
2196 func AOP_RLDIC(op uint32, a uint32, s uint32, sh uint32, m uint32) uint32 {
2197 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1 | (m&31)<<6 | ((m&32)>>5)<<5
2200 func AOP_ISEL(op uint32, t uint32, a uint32, b uint32, bc uint32) uint32 {
2201 return op | (t&31)<<21 | (a&31)<<16 | (b&31)<<11 | (bc&0x1F)<<6
2205 /* each rhs is OPVCC(_, _, _, _) */
2206 OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0
2207 OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0
2208 OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0
2209 OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 0
2210 OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0
2211 OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0
2212 OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0
2213 OP_ISEL = 31<<26 | 15<<1 | 0<<10 | 0
2214 OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0
2215 OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0
2216 OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0
2217 OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 0
2218 OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 0
2219 OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0
2220 OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0
2221 OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 0
2222 OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0
2223 OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0
2224 OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0
2225 OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0
2226 OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0
2227 OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0
2228 OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0
2229 OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 0
2230 OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0
2231 OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0
2232 OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0
2233 OP_OR = 31<<26 | 444<<1 | 0<<10 | 0
2234 OP_ORI = 24<<26 | 0<<1 | 0<<10 | 0
2235 OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 0
2236 OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0
2237 OP_RLWNM = 23<<26 | 0<<1 | 0<<10 | 0
2238 OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 0
2239 OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 0
2240 OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0
2241 OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0
2242 OP_RLDCL = 30<<26 | 8<<1 | 0<<10 | 0
2245 func oclass(a *obj.Addr) int {
2246 return int(a.Class) - 1
2254 // This function determines when a non-indexed load or store is D or
2255 // DS form for use in finding the size of the offset field in the instruction.
2256 // The size is needed when setting the offset value in the instruction
2257 // and when generating relocation for that field.
2258 // DS form instructions include: ld, ldu, lwa, std, stdu. All other
2259 // loads and stores with an offset field are D form. This function should
2260 // only be called with the same opcodes as are handled by opstore and opload.
2261 func (c *ctxt9) opform(insn uint32) int {
2264 c.ctxt.Diag("bad insn in loadform: %x", insn)
2265 case OPVCC(58, 0, 0, 0), // ld
2266 OPVCC(58, 0, 0, 1), // ldu
2267 OPVCC(58, 0, 0, 0) | 1<<1, // lwa
2268 OPVCC(62, 0, 0, 0), // std
2269 OPVCC(62, 0, 0, 1): //stdu
2271 case OP_ADDI, // add
2272 OPVCC(32, 0, 0, 0), // lwz
2273 OPVCC(33, 0, 0, 0), // lwzu
2274 OPVCC(34, 0, 0, 0), // lbz
2275 OPVCC(35, 0, 0, 0), // lbzu
2276 OPVCC(40, 0, 0, 0), // lhz
2277 OPVCC(41, 0, 0, 0), // lhzu
2278 OPVCC(42, 0, 0, 0), // lha
2279 OPVCC(43, 0, 0, 0), // lhau
2280 OPVCC(46, 0, 0, 0), // lmw
2281 OPVCC(48, 0, 0, 0), // lfs
2282 OPVCC(49, 0, 0, 0), // lfsu
2283 OPVCC(50, 0, 0, 0), // lfd
2284 OPVCC(51, 0, 0, 0), // lfdu
2285 OPVCC(36, 0, 0, 0), // stw
2286 OPVCC(37, 0, 0, 0), // stwu
2287 OPVCC(38, 0, 0, 0), // stb
2288 OPVCC(39, 0, 0, 0), // stbu
2289 OPVCC(44, 0, 0, 0), // sth
2290 OPVCC(45, 0, 0, 0), // sthu
2291 OPVCC(47, 0, 0, 0), // stmw
2292 OPVCC(52, 0, 0, 0), // stfs
2293 OPVCC(53, 0, 0, 0), // stfsu
2294 OPVCC(54, 0, 0, 0), // stfd
2295 OPVCC(55, 0, 0, 0): // stfdu
2301 // Encode instructions and create relocation for accessing s+d according to the
2302 // instruction op with source or destination (as appropriate) register reg.
2303 func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) {
2304 if c.ctxt.Headtype == objabi.Haix {
2305 // Every symbol access must be made via a TOC anchor.
2306 c.ctxt.Diag("symbolAccess called for %s", s.Name)
2309 form := c.opform(op)
2310 if c.ctxt.Flag_shared {
2315 o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)
2316 o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)
2317 rel := obj.Addrel(c.cursym)
2318 rel.Off = int32(c.pc)
2322 if c.ctxt.Flag_shared {
2325 rel.Type = objabi.R_ADDRPOWER_TOCREL
2327 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
2333 rel.Type = objabi.R_ADDRPOWER
2335 rel.Type = objabi.R_ADDRPOWER_DS
2344 func getmask(m []byte, v uint32) bool {
2347 if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
2358 for i := 0; i < 32; i++ {
2359 if v&(1<<uint(31-i)) != 0 {
2364 if i >= 32 || v&(1<<uint(31-i)) == 0 {
2370 if v&(1<<uint(31-i)) != 0 {
2381 func (c *ctxt9) maskgen(p *obj.Prog, m []byte, v uint32) {
2383 c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
2388 * 64-bit masks (rldic etc)
2390 func getmask64(m []byte, v uint64) bool {
2393 for i := 0; i < 64; i++ {
2394 if v&(uint64(1)<<uint(63-i)) != 0 {
2399 if i >= 64 || v&(uint64(1)<<uint(63-i)) == 0 {
2405 if v&(uint64(1)<<uint(63-i)) != 0 {
2416 func (c *ctxt9) maskgen64(p *obj.Prog, m []byte, v uint64) {
2417 if !getmask64(m, v) {
2418 c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
2422 func loadu32(r int, d int64) uint32 {
2424 if isuint32(uint64(d)) {
2425 return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
2427 return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v))
2430 func high16adjusted(d int32) uint16 {
2432 return uint16((d >> 16) + 1)
2434 return uint16(d >> 16)
2437 func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
2444 //print("%v => case %d\n", p, o->type);
2447 c.ctxt.Diag("unknown type %d", o.type_)
2450 case 0: /* pseudo ops */
2453 case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
2454 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
2455 v := c.regoff(&p.From)
2456 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
2458 c.ctxt.Diag("literal operation on R0\n%v", p)
2461 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
2465 o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
2467 case 2: /* int/cr/fp op Rb,[Ra],Rd */
2473 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2475 case 3: /* mov $soreg/addcon/andcon/ucon, r ==> addis/oris/addi/ori $i,reg',r */
2476 d := c.vregoff(&p.From)
2479 r := int(p.From.Reg)
2483 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
2484 c.ctxt.Diag("literal operation on R0\n%v", p)
2489 log.Fatalf("invalid handling of %v", p)
2491 // For UCON operands the value is right shifted 16, using ADDIS if the
2492 // value should be signed, ORIS if unsigned.
2494 if r == REGZERO && isuint32(uint64(d)) {
2495 o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v))
2500 } else if int64(int16(d)) != d {
2501 // Operand is 16 bit value with sign bit set
2502 if o.a1 == C_ANDCON {
2503 // Needs unsigned 16 bit so use ORI
2504 if r == 0 || r == REGZERO {
2505 o1 = LOP_IRR(uint32(OP_ORI), uint32(p.To.Reg), uint32(0), uint32(v))
2508 // With ADDCON, needs signed 16 bit value, fall through to use ADDI
2509 } else if o.a1 != C_ADDCON {
2510 log.Fatalf("invalid handling of %v", p)
2514 o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
2516 case 4: /* add/mul $scon,[r1],r2 */
2517 v := c.regoff(&p.From)
2523 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
2524 c.ctxt.Diag("literal operation on R0\n%v", p)
2526 if int32(int16(v)) != v {
2527 log.Fatalf("mishandled instruction %v", p)
2529 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2531 case 5: /* syscall */
2534 case 6: /* logical op Rb,[Rs,]Ra; no literal */
2540 // AROTL and AROTLW are extended mnemonics, which map to RLDCL and RLWNM.
2543 o1 = AOP_RLDIC(OP_RLDCL, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), uint32(0))
2545 o1 = OP_RLW(OP_RLWNM, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), 0, 31)
2547 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2550 case 7: /* mov r, soreg ==> stw o(r) */
2556 v := c.regoff(&p.To)
2557 if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
2559 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2561 if c.ctxt.Flag_shared && r == REG_R13 {
2562 rel := obj.Addrel(c.cursym)
2563 rel.Off = int32(c.pc)
2565 // This (and the matching part in the load case
2566 // below) are the only places in the ppc64 toolchain
2567 // that knows the name of the tls variable. Possibly
2568 // we could add some assembly syntax so that the name
2569 // of the variable does not have to be assumed.
2570 rel.Sym = c.ctxt.Lookup("runtime.tls_g")
2571 rel.Type = objabi.R_POWER_TLS
2573 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
2575 if int32(int16(v)) != v {
2576 log.Fatalf("mishandled instruction %v", p)
2578 // Offsets in DS form stores must be a multiple of 4
2579 inst := c.opstore(p.As)
2580 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2581 log.Fatalf("invalid offset for DS form load/store %v", p)
2583 o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
2586 case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
2587 r := int(p.From.Reg)
2592 v := c.regoff(&p.From)
2593 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
2595 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2597 if c.ctxt.Flag_shared && r == REG_R13 {
2598 rel := obj.Addrel(c.cursym)
2599 rel.Off = int32(c.pc)
2601 rel.Sym = c.ctxt.Lookup("runtime.tls_g")
2602 rel.Type = objabi.R_POWER_TLS
2604 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
2606 if int32(int16(v)) != v {
2607 log.Fatalf("mishandled instruction %v", p)
2609 // Offsets in DS form loads must be a multiple of 4
2610 inst := c.opload(p.As)
2611 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2612 log.Fatalf("invalid offset for DS form load/store %v", p)
2614 o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
2617 case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
2618 r := int(p.From.Reg)
2623 v := c.regoff(&p.From)
2624 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
2626 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2628 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
2630 o1 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2632 o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
2634 case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
2640 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
2642 case 11: /* br/bl lbra */
2646 v = int32(p.Pcond.Pc - p.Pc)
2648 c.ctxt.Diag("odd branch target address\n%v", p)
2652 if v < -(1<<25) || v >= 1<<24 {
2653 c.ctxt.Diag("branch too far\n%v", p)
2657 o1 = OP_BR(c.opirr(p.As), uint32(v), 0)
2658 if p.To.Sym != nil {
2659 rel := obj.Addrel(c.cursym)
2660 rel.Off = int32(c.pc)
2663 v += int32(p.To.Offset)
2665 c.ctxt.Diag("odd branch target address\n%v", p)
2670 rel.Type = objabi.R_CALLPOWER
2672 o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
2674 case 12: /* movb r,r (extsb); movw r,r (extsw) */
2675 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
2676 v := c.regoff(&p.From)
2677 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
2678 c.ctxt.Diag("literal operation on R0\n%v", p)
2681 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
2686 o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2688 o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2691 case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
2693 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
2694 } else if p.As == AMOVH {
2695 o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2696 } else if p.As == AMOVHZ {
2697 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
2698 } else if p.As == AMOVWZ {
2699 o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
2701 c.ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
2704 case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
2710 d := c.vregoff(p.GetFrom3())
2714 // These opcodes expect a mask operand that has to be converted into the
2715 // appropriate operand. The way these were defined, not all valid masks are possible.
2716 // Left here for compatibility in case they were used or generated.
2717 case ARLDCL, ARLDCLCC:
2719 c.maskgen64(p, mask[:], uint64(d))
2721 a = int(mask[0]) /* MB */
2723 c.ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)
2725 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2726 o1 |= (uint32(a) & 31) << 6
2728 o1 |= 1 << 5 /* mb[5] is top bit */
2731 case ARLDCR, ARLDCRCC:
2733 c.maskgen64(p, mask[:], uint64(d))
2735 a = int(mask[1]) /* ME */
2737 c.ctxt.Diag("invalid mask for rotate: %x %x (start != 0)\n%v", uint64(d), mask[0], p)
2739 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2740 o1 |= (uint32(a) & 31) << 6
2742 o1 |= 1 << 5 /* mb[5] is top bit */
2745 // These opcodes use a shift count like the ppc64 asm, no mask conversion done
2746 case ARLDICR, ARLDICRCC:
2748 sh := c.regoff(&p.From)
2749 o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(me))
2751 case ARLDICL, ARLDICLCC:
2753 sh := c.regoff(&p.From)
2754 o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(mb))
2757 c.ctxt.Diag("unexpected op in rldc case\n%v", p)
2761 case 17, /* bc bo,bi,lbra (same for now) */
2762 16: /* bc bo,bi,sbra */
2767 if p.From.Type == obj.TYPE_CONST {
2768 a = int(c.regoff(&p.From))
2769 } else if p.From.Type == obj.TYPE_REG {
2771 c.ctxt.Diag("unexpected register setting for branch with CR: %d\n", r)
2773 // BI values for the CR
2792 c.ctxt.Diag("unrecognized register: expecting CR\n")
2797 v = int32(p.Pcond.Pc - p.Pc)
2800 c.ctxt.Diag("odd branch target address\n%v", p)
2804 if v < -(1<<16) || v >= 1<<15 {
2805 c.ctxt.Diag("branch too far\n%v", p)
2807 o1 = OP_BC(c.opirr(p.As), uint32(a), uint32(r), uint32(v), 0)
2809 case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
2811 if p.As == ABC || p.As == ABCL {
2812 v = c.regoff(&p.To) & 31
2814 v = 20 /* unconditional */
2816 o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
2817 o2 = OPVCC(19, 16, 0, 0)
2818 if p.As == ABL || p.As == ABCL {
2821 o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index))
2823 case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
2825 if p.As == ABC || p.As == ABCL {
2826 v = c.regoff(&p.From) & 31
2828 v = 20 /* unconditional */
2834 switch oclass(&p.To) {
2836 o1 = OPVCC(19, 528, 0, 0)
2839 o1 = OPVCC(19, 16, 0, 0)
2842 c.ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p)
2846 if p.As == ABL || p.As == ABCL {
2849 o1 = OP_BCR(o1, uint32(v), uint32(r))
2851 case 19: /* mov $lcon,r ==> cau+or */
2852 d := c.vregoff(&p.From)
2854 if p.From.Sym == nil {
2855 o1 = loadu32(int(p.To.Reg), d)
2856 o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
2858 o1, o2 = c.symbolAccess(p.From.Sym, d, p.To.Reg, OP_ADDI)
2861 case 20: /* add $ucon,,r | addis $addcon,r,r */
2862 v := c.regoff(&p.From)
2868 if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
2869 c.ctxt.Diag("literal operation on R0\n%v", p)
2872 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2874 o1 = AOP_IRR(c.opirr(AADDIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
2877 case 22: /* add $lcon/$andcon,r1,r2 ==> oris+ori+add/ori+add */
2878 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2879 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2881 d := c.vregoff(&p.From)
2886 if p.From.Sym != nil {
2887 c.ctxt.Diag("%v is not supported", p)
2889 // If operand is ANDCON, generate 2 instructions using
2890 // ORI for unsigned value; with LCON 3 instructions.
2892 o1 = LOP_IRR(OP_ORI, REGTMP, REGZERO, uint32(int32(d)))
2893 o2 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2895 o1 = loadu32(REGTMP, d)
2896 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2897 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2900 case 23: /* and $lcon/$addcon,r1,r2 ==> oris+ori+and/addi+and */
2901 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2902 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2904 d := c.vregoff(&p.From)
2910 // With ADDCON operand, generate 2 instructions using ADDI for signed value,
2911 // with LCON operand generate 3 instructions.
2913 o1 = LOP_IRR(OP_ADDI, REGZERO, REGTMP, uint32(int32(d)))
2914 o2 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2916 o1 = loadu32(REGTMP, d)
2917 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2918 o3 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2920 if p.From.Sym != nil {
2921 c.ctxt.Diag("%v is not supported", p)
2924 case 24: /* lfd fA,float64(0) -> xxlxor xsA,xsaA,xsaA + fneg for -0 */
2925 o1 = AOP_XX3I(c.oprrr(AXXLXOR), uint32(p.To.Reg), uint32(p.To.Reg), uint32(p.To.Reg), uint32(0))
2926 // This is needed for -0.
2928 o2 = AOP_RRR(c.oprrr(AFNEG), uint32(p.To.Reg), 0, uint32(p.To.Reg))
2932 /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
2933 v := c.regoff(&p.From)
2959 c.ctxt.Diag("unexpected op in sldi case\n%v", p)
2964 o1 = AOP_RLDIC(op, uint32(p.To.Reg), uint32(r), uint32(v), uint32(a))
2965 if p.As == ASLDCC || p.As == ASRDCC {
2966 o1 |= 1 // Set the condition code bit
2969 case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
2970 if p.To.Reg == REGTMP {
2971 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2973 v := c.regoff(&p.From)
2974 r := int(p.From.Reg)
2978 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
2979 o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
2981 case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
2982 v := c.regoff(p.GetFrom3())
2984 r := int(p.From.Reg)
2985 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2987 case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
2988 if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
2989 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2991 v := c.regoff(p.GetFrom3())
2992 o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
2993 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
2994 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
2995 if p.From.Sym != nil {
2996 c.ctxt.Diag("%v is not supported", p)
2999 case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
3000 v := c.regoff(&p.From)
3002 d := c.vregoff(p.GetFrom3())
3004 c.maskgen64(p, mask[:], uint64(d))
3007 case ARLDC, ARLDCCC:
3008 a = int(mask[0]) /* MB */
3009 if int32(mask[1]) != (63 - v) {
3010 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[1], v, p)
3013 case ARLDCL, ARLDCLCC:
3014 a = int(mask[0]) /* MB */
3016 c.ctxt.Diag("invalid mask for shift: %x %s (shift %d)\n%v", uint64(d), mask[1], v, p)
3019 case ARLDCR, ARLDCRCC:
3020 a = int(mask[1]) /* ME */
3022 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[0], v, p)
3026 c.ctxt.Diag("unexpected op in rldic case\n%v", p)
3030 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3031 o1 |= (uint32(a) & 31) << 6
3036 o1 |= 1 << 5 /* mb[5] is top bit */
3039 case 30: /* rldimi $sh,s,$mask,a */
3040 v := c.regoff(&p.From)
3042 d := c.vregoff(p.GetFrom3())
3044 // Original opcodes had mask operands which had to be converted to a shift count as expected by
3047 case ARLDMI, ARLDMICC:
3049 c.maskgen64(p, mask[:], uint64(d))
3050 if int32(mask[1]) != (63 - v) {
3051 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[1], v, p)
3053 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3054 o1 |= (uint32(mask[0]) & 31) << 6
3058 if mask[0]&0x20 != 0 {
3059 o1 |= 1 << 5 /* mb[5] is top bit */
3062 // Opcodes with shift count operands.
3063 case ARLDIMI, ARLDIMICC:
3064 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3065 o1 |= (uint32(d) & 31) << 6
3074 case 31: /* dword */
3075 d := c.vregoff(&p.From)
3077 if c.ctxt.Arch.ByteOrder == binary.BigEndian {
3078 o1 = uint32(d >> 32)
3082 o2 = uint32(d >> 32)
3085 if p.From.Sym != nil {
3086 rel := obj.Addrel(c.cursym)
3087 rel.Off = int32(c.pc)
3089 rel.Sym = p.From.Sym
3090 rel.Add = p.From.Offset
3091 rel.Type = objabi.R_ADDR
3096 case 32: /* fmul frc,fra,frd */
3102 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
3104 case 33: /* fabs [frb,]frd; fmr. frb,frd */
3105 r := int(p.From.Reg)
3107 if oclass(&p.From) == C_NONE {
3110 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(r))
3112 case 34: /* FMADDx fra,frb,frc,frt (t=a*c±b) */
3113 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.GetFrom3().Reg)&31)<<6
3115 case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
3116 v := c.regoff(&p.To)
3122 // Offsets in DS form stores must be a multiple of 4
3123 inst := c.opstore(p.As)
3124 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3125 log.Fatalf("invalid offset for DS form load/store %v", p)
3127 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3128 o2 = AOP_IRR(inst, uint32(p.From.Reg), REGTMP, uint32(v))
3130 case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
3131 v := c.regoff(&p.From)
3133 r := int(p.From.Reg)
3137 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3138 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
3140 case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
3141 v := c.regoff(&p.From)
3143 r := int(p.From.Reg)
3147 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3148 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
3149 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3152 o1 = uint32(c.regoff(&p.From))
3154 case 41: /* stswi */
3155 o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3158 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3160 case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */
3161 /* TH field for dcbt/dcbtst: */
3162 /* 0 = Block access - program will soon access EA. */
3163 /* 8-15 = Stream access - sequence of access (data stream). See section 4.3.2 of the ISA for details. */
3164 /* 16 = Block access - program will soon make a transient access to EA. */
3165 /* 17 = Block access - program will not access EA for a long time. */
3167 /* L field for dcbf: */
3168 /* 0 = invalidates the block containing EA in all processors. */
3169 /* 1 = same as 0, but with limited scope (i.e. block in the current processor will not be reused soon). */
3170 /* 3 = same as 1, but with even more limited scope (i.e. block in the current processor primary cache will not be reused soon). */
3171 if p.To.Type == obj.TYPE_NONE {
3172 o1 = AOP_RRR(c.oprrr(p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))
3174 th := c.regoff(&p.To)
3175 o1 = AOP_RRR(c.oprrr(p.As), uint32(th), uint32(p.From.Index), uint32(p.From.Reg))
3178 case 44: /* indexed store */
3179 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3181 case 45: /* indexed load */
3183 /* The assembler accepts a 4-operand l*arx instruction. The fourth operand is an Exclusive Access Hint (EH) */
3184 /* The EH field can be used as a lock acquire/release hint as follows: */
3185 /* 0 = Atomic Update (fetch-and-operate or similar algorithm) */
3186 /* 1 = Exclusive Access (lock acquire and release) */
3187 case ALBAR, ALHAR, ALWAR, ALDAR:
3188 if p.From3Type() != obj.TYPE_NONE {
3189 eh := int(c.regoff(p.GetFrom3()))
3191 c.ctxt.Diag("illegal EH field\n%v", p)
3193 o1 = AOP_RRRI(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg), uint32(eh))
3195 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3198 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3200 case 46: /* plain op */
3203 case 47: /* op Ra, Rd; also op [Ra,] Rd */
3204 r := int(p.From.Reg)
3209 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3211 case 48: /* op Rs, Ra */
3212 r := int(p.From.Reg)
3217 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3219 case 49: /* op Rb; op $n, Rb */
3220 if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
3221 v := c.regoff(&p.From) & 1
3222 o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
3224 o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.From.Reg))
3227 case 50: /* rem[u] r1[,r2],r3 */
3234 t := v & (1<<10 | 1) /* OE|Rc */
3235 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3236 o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
3237 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3241 /* Clear top 32 bits */
3242 o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5
3245 case 51: /* remd[u] r1[,r2],r3 */
3252 t := v & (1<<10 | 1) /* OE|Rc */
3253 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3254 o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
3255 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3257 case 52: /* mtfsbNx cr(n) */
3258 v := c.regoff(&p.From) & 31
3260 o1 = AOP_RRR(c.oprrr(p.As), uint32(v), 0, 0)
3262 case 53: /* mffsX ,fr1 */
3263 o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)
3265 case 54: /* mov msr,r1; mov r1, msr*/
3266 if oclass(&p.From) == C_REG {
3268 o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
3270 o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
3273 o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
3276 case 55: /* op Rb, Rd */
3277 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg))
3279 case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
3280 v := c.regoff(&p.From)
3286 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31)
3287 if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) {
3288 o1 |= 1 << 1 /* mb[5] */
3291 case 57: /* slw $sh,[s,]a -> rlwinm ... */
3292 v := c.regoff(&p.From)
3300 * Let user (gs) shoot himself in the foot.
3301 * qc has already complained.
3304 ctxt->diag("illegal shift %ld\n%v", v, p);
3314 mask[0], mask[1] = 0, 31
3316 mask[0], mask[1] = uint8(v), 31
3319 mask[0], mask[1] = 0, uint8(31-v)
3321 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1]))
3322 if p.As == ASLWCC || p.As == ASRWCC {
3323 o1 |= 1 // set the condition code
3326 case 58: /* logical $andcon,[s],a */
3327 v := c.regoff(&p.From)
3333 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3335 case 59: /* or/xor/and $ucon,,r | oris/xoris/andis $addcon,r,r */
3336 v := c.regoff(&p.From)
3344 o1 = LOP_IRR(c.opirr(AORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis. */
3346 o1 = LOP_IRR(c.opirr(AXORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3348 o1 = LOP_IRR(c.opirr(AANDISCC), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3350 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3353 case 60: /* tw to,a,b */
3354 r := int(c.regoff(&p.From) & 31)
3356 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
3358 case 61: /* tw to,a,$simm */
3359 r := int(c.regoff(&p.From) & 31)
3361 v := c.regoff(&p.To)
3362 o1 = AOP_IRR(c.opirr(p.As), uint32(r), uint32(p.Reg), uint32(v))
3364 case 62: /* rlwmi $sh,s,$mask,a */
3365 v := c.regoff(&p.From)
3368 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
3369 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
3370 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
3372 case 63: /* rlwmi b,s,$mask,a */
3374 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
3376 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
3377 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
3379 case 64: /* mtfsf fr[, $m] {,fpcsr} */
3381 if p.From3Type() != obj.TYPE_NONE {
3382 v = c.regoff(p.GetFrom3()) & 255
3386 o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
3388 case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
3390 c.ctxt.Diag("must specify FPSCR(n)\n%v", p)
3392 o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(c.regoff(&p.From))&31)<<12
3394 case 66: /* mov spr,r1; mov r1,spr, also dcr */
3397 if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
3400 if REG_DCR0 <= v && v <= REG_DCR0+1023 {
3401 o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
3403 o1 = OPVCC(31, 467, 0, 0) /* mtspr */
3407 v = int32(p.From.Reg)
3408 if REG_DCR0 <= v && v <= REG_DCR0+1023 {
3409 o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
3411 o1 = OPVCC(31, 339, 0, 0) /* mfspr */
3415 o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
3417 case 67: /* mcrf crfD,crfS */
3418 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 {
3419 c.ctxt.Diag("illegal CR field number\n%v", p)
3421 o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
3423 case 68: /* mfcr rD; mfocrf CRM,rD */
3424 if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
3425 v := int32(1 << uint(7-(p.To.Reg&7))) /* CR(n) */
3426 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
3428 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
3431 case 69: /* mtcrf CRM,rS */
3433 if p.From3Type() != obj.TYPE_NONE {
3435 c.ctxt.Diag("can't use both mask and CR(n)\n%v", p)
3437 v = c.regoff(p.GetFrom3()) & 0xff
3442 v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
3446 o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
3448 case 70: /* [f]cmp r,r,cr*/
3453 r = (int(p.Reg) & 7) << 2
3455 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
3457 case 71: /* cmp[l] r,i,cr*/
3462 r = (int(p.Reg) & 7) << 2
3464 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(c.regoff(&p.To))&0xffff
3466 case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
3467 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg))
3469 case 73: /* mcrfs crfD,crfS */
3470 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 {
3471 c.ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
3473 o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
3475 case 77: /* syscall $scon, syscall Rx */
3476 if p.From.Type == obj.TYPE_CONST {
3477 if p.From.Offset > BIG || p.From.Offset < -BIG {
3478 c.ctxt.Diag("illegal syscall, sysnum too large: %v", p)
3480 o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
3481 } else if p.From.Type == obj.TYPE_REG {
3482 o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
3484 c.ctxt.Diag("illegal syscall: %v", p)
3485 o1 = 0x7fe00008 // trap always
3489 o3 = AOP_RRR(c.oprrr(AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R0
3491 case 78: /* undef */
3492 o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed
3493 always to be an illegal instruction." */
3495 /* relocation operations */
3497 v := c.vregoff(&p.To)
3498 // Offsets in DS form stores must be a multiple of 4
3499 inst := c.opstore(p.As)
3500 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3501 log.Fatalf("invalid offset for DS form load/store %v", p)
3503 o1, o2 = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst)
3505 //if(dlm) reloc(&p->to, p->pc, 1);
3508 v := c.vregoff(&p.From)
3509 // Offsets in DS form loads must be a multiple of 4
3510 inst := c.opload(p.As)
3511 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3512 log.Fatalf("invalid offset for DS form load/store %v", p)
3514 o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
3516 //if(dlm) reloc(&p->from, p->pc, 1);
3519 v := c.vregoff(&p.From)
3520 // Offsets in DS form loads must be a multiple of 4
3521 inst := c.opload(p.As)
3522 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3523 log.Fatalf("invalid offset for DS form load/store %v", p)
3525 o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
3526 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3528 //if(dlm) reloc(&p->from, p->pc, 1);
3531 if p.From.Offset != 0 {
3532 c.ctxt.Diag("invalid offset against tls var %v", p)
3534 o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0)
3535 rel := obj.Addrel(c.cursym)
3536 rel.Off = int32(c.pc)
3538 rel.Sym = p.From.Sym
3539 rel.Type = objabi.R_POWER_TLS_LE
3542 if p.From.Offset != 0 {
3543 c.ctxt.Diag("invalid offset against tls var %v", p)
3545 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3546 o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3547 rel := obj.Addrel(c.cursym)
3548 rel.Off = int32(c.pc)
3550 rel.Sym = p.From.Sym
3551 rel.Type = objabi.R_POWER_TLS_IE
3554 v := c.vregoff(&p.To)
3556 c.ctxt.Diag("invalid offset against GOT slot %v", p)
3559 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3560 o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3561 rel := obj.Addrel(c.cursym)
3562 rel.Off = int32(c.pc)
3564 rel.Sym = p.From.Sym
3565 rel.Type = objabi.R_ADDRPOWER_GOT
3566 case 82: /* vector instructions, VX-form and VC-form */
3567 if p.From.Type == obj.TYPE_REG {
3568 /* reg reg none OR reg reg reg */
3569 /* 3-register operand order: VRA, VRB, VRT */
3570 /* 2-register operand order: VRA, VRT */
3571 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3572 } else if p.From3Type() == obj.TYPE_CONST {
3573 /* imm imm reg reg */
3574 /* operand order: SIX, VRA, ST, VRT */
3575 six := int(c.regoff(&p.From))
3576 st := int(c.regoff(p.GetFrom3()))
3577 o1 = AOP_IIRR(c.opiirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(st), uint32(six))
3578 } else if p.From3Type() == obj.TYPE_NONE && p.Reg != 0 {
3580 /* operand order: UIM, VRB, VRT */
3581 uim := int(c.regoff(&p.From))
3582 o1 = AOP_VIRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(uim))
3585 /* operand order: SIM, VRT */
3586 sim := int(c.regoff(&p.From))
3587 o1 = AOP_IR(c.opirr(p.As), uint32(p.To.Reg), uint32(sim))
3590 case 83: /* vector instructions, VA-form */
3591 if p.From.Type == obj.TYPE_REG {
3592 /* reg reg reg reg */
3593 /* 4-register operand order: VRA, VRB, VRC, VRT */
3594 o1 = AOP_RRRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3595 } else if p.From.Type == obj.TYPE_CONST {
3596 /* imm reg reg reg */
3597 /* operand order: SHB, VRA, VRB, VRT */
3598 shb := int(c.regoff(&p.From))
3599 o1 = AOP_IRRR(c.opirrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(shb))
3602 case 84: // ISEL BC,RA,RB,RT -> isel rt,ra,rb,bc
3603 bc := c.vregoff(&p.From)
3605 // rt = To.Reg, ra = p.Reg, rb = p.From3.Reg
3606 o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(bc))
3608 case 85: /* vector instructions, VX-form */
3610 /* 2-register operand order: VRB, VRT */
3611 o1 = AOP_RR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg))
3613 case 86: /* VSX indexed store, XX1-form */
3615 /* 3-register operand order: XT, (RB)(RA*1) */
3616 o1 = AOP_XX1(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3618 case 87: /* VSX indexed load, XX1-form */
3620 /* 3-register operand order: (RB)(RA*1), XT */
3621 o1 = AOP_XX1(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3623 case 88: /* VSX instructions, XX1-form */
3624 /* reg reg none OR reg reg reg */
3625 /* 3-register operand order: RA, RB, XT */
3626 /* 2-register operand order: XS, RA or RA, XT */
3627 xt := int32(p.To.Reg)
3628 xs := int32(p.From.Reg)
3629 /* We need to treat the special case of extended mnemonics that may have a FREG/VREG as an argument */
3630 if REG_V0 <= xt && xt <= REG_V31 {
3631 /* Convert V0-V31 to VS32-VS63 */
3633 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3634 } else if REG_F0 <= xt && xt <= REG_F31 {
3635 /* Convert F0-F31 to VS0-VS31 */
3637 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3638 } else if REG_VS0 <= xt && xt <= REG_VS63 {
3639 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3640 } else if REG_V0 <= xs && xs <= REG_V31 {
3641 /* Likewise for XS */
3643 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3644 } else if REG_F0 <= xs && xs <= REG_F31 {
3646 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3647 } else if REG_VS0 <= xs && xs <= REG_VS63 {
3648 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3651 case 89: /* VSX instructions, XX2-form */
3652 /* reg none reg OR reg imm reg */
3653 /* 2-register operand order: XB, XT or XB, UIM, XT*/
3654 uim := int(c.regoff(p.GetFrom3()))
3655 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(uim), uint32(p.From.Reg))
3657 case 90: /* VSX instructions, XX3-form */
3658 if p.From3Type() == obj.TYPE_NONE {
3660 /* 3-register operand order: XA, XB, XT */
3661 o1 = AOP_XX3(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3662 } else if p.From3Type() == obj.TYPE_CONST {
3663 /* reg reg reg imm */
3664 /* operand order: XA, XB, DM, XT */
3665 dm := int(c.regoff(p.GetFrom3()))
3666 o1 = AOP_XX3I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(dm))
3669 case 91: /* VSX instructions, XX4-form */
3670 /* reg reg reg reg */
3671 /* 3-register operand order: XA, XB, XC, XT */
3672 o1 = AOP_XX4(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3674 case 92: /* X-form instructions, 3-operands */
3675 if p.To.Type == obj.TYPE_CONST {
3677 xf := int32(p.From.Reg)
3678 if REG_F0 <= xf && xf <= REG_F31 {
3679 /* operand order: FRA, FRB, BF */
3680 bf := int(c.regoff(&p.To)) << 2
3681 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3683 /* operand order: RA, RB, L */
3684 l := int(c.regoff(&p.To))
3685 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.From.Reg), uint32(p.Reg))
3687 } else if p.From3Type() == obj.TYPE_CONST {
3689 /* operand order: RB, L, RA */
3690 l := int(c.regoff(p.GetFrom3()))
3691 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.To.Reg), uint32(p.From.Reg))
3692 } else if p.To.Type == obj.TYPE_REG {
3693 cr := int32(p.To.Reg)
3694 if REG_CR0 <= cr && cr <= REG_CR7 {
3696 /* operand order: RA, RB, BF */
3697 bf := (int(p.To.Reg) & 7) << 2
3698 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3699 } else if p.From.Type == obj.TYPE_CONST {
3701 /* operand order: L, RT */
3702 l := int(c.regoff(&p.From))
3703 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(l), uint32(p.Reg))
3706 case ACOPY, APASTECC:
3707 o1 = AOP_RRR(c.opirr(p.As), uint32(1), uint32(p.From.Reg), uint32(p.To.Reg))
3710 /* operand order: RS, RB, RA */
3711 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3716 case 93: /* X-form instructions, 2-operands */
3717 if p.To.Type == obj.TYPE_CONST {
3719 /* operand order: FRB, BF */
3720 bf := int(c.regoff(&p.To)) << 2
3721 o1 = AOP_RR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg))
3722 } else if p.Reg == 0 {
3723 /* popcnt* r,r, X-form */
3724 /* operand order: RS, RA */
3725 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3728 case 94: /* Z23-form instructions, 4-operands */
3729 /* reg reg reg imm */
3730 /* operand order: RA, RB, CY, RT */
3731 cy := int(c.regoff(p.GetFrom3()))
3732 o1 = AOP_Z23I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(cy))
3734 case 95: /* Retrieve TOC relative symbol */
3735 /* This code is for AIX only */
3736 v := c.vregoff(&p.From)
3738 c.ctxt.Diag("invalid offset against TOC slot %v", p)
3741 inst := c.opload(p.As)
3742 if c.opform(inst) != DS_FORM {
3743 c.ctxt.Diag("invalid form for a TOC access in %v", p)
3746 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3747 o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3748 rel := obj.Addrel(c.cursym)
3749 rel.Off = int32(c.pc)
3751 rel.Sym = p.From.Sym
3752 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
3754 case 96: /* VSX load, DQ-form */
3756 /* operand order: (RA)(DQ), XT */
3757 dq := int16(c.regoff(&p.From))
3759 c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3761 o1 = AOP_DQ(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(dq))
3763 case 97: /* VSX store, DQ-form */
3765 /* operand order: XT, (RA)(DQ) */
3766 dq := int16(c.regoff(&p.To))
3768 c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3770 o1 = AOP_DQ(c.opstore(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(dq))
3771 case 98: /* VSX indexed load or load with length (also left-justified), x-form */
3772 /* vsreg, reg, reg */
3773 o1 = AOP_XX1(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3774 case 99: /* VSX store with length (also left-justified) x-form */
3775 /* reg, reg, vsreg */
3776 o1 = AOP_XX1(c.opstore(p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(p.To.Reg))
3777 case 100: /* VSX X-form XXSPLTIB */
3778 if p.From.Type == obj.TYPE_CONST {
3780 uim := int(c.regoff(&p.From))
3782 /* Use AOP_XX1 form with 0 for one of the registers. */
3783 o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(uim))
3785 c.ctxt.Diag("invalid ops for %v", p.As)
3788 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
3798 func (c *ctxt9) vregoff(a *obj.Addr) int64 {
3806 func (c *ctxt9) regoff(a *obj.Addr) int32 {
3807 return int32(c.vregoff(a))
3810 func (c *ctxt9) oprrr(a obj.As) uint32 {
3813 return OPVCC(31, 266, 0, 0)
3815 return OPVCC(31, 266, 0, 1)
3817 return OPVCC(31, 266, 1, 0)
3819 return OPVCC(31, 266, 1, 1)
3821 return OPVCC(31, 10, 0, 0)
3823 return OPVCC(31, 10, 0, 1)
3825 return OPVCC(31, 10, 1, 0)
3827 return OPVCC(31, 10, 1, 1)
3829 return OPVCC(31, 138, 0, 0)
3831 return OPVCC(31, 138, 0, 1)
3833 return OPVCC(31, 138, 1, 0)
3835 return OPVCC(31, 138, 1, 1)
3837 return OPVCC(31, 234, 0, 0)
3839 return OPVCC(31, 234, 0, 1)
3841 return OPVCC(31, 234, 1, 0)
3843 return OPVCC(31, 234, 1, 1)
3845 return OPVCC(31, 202, 0, 0)
3847 return OPVCC(31, 202, 0, 1)
3849 return OPVCC(31, 202, 1, 0)
3851 return OPVCC(31, 202, 1, 1)
3853 return OPVCC(31, 170, 0, 0) /* addex - v3.0b */
3856 return OPVCC(31, 28, 0, 0)
3858 return OPVCC(31, 28, 0, 1)
3860 return OPVCC(31, 60, 0, 0)
3862 return OPVCC(31, 60, 0, 1)
3865 return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */
3867 return OPVCC(31, 32, 0, 0) | 1<<21
3869 return OPVCC(31, 0, 0, 0) /* L=0 */
3871 return OPVCC(31, 32, 0, 0)
3873 return OPVCC(31, 508, 0, 0) /* cmpb - v2.05 */
3875 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
3878 return OPVCC(31, 26, 0, 0)
3880 return OPVCC(31, 26, 0, 1)
3882 return OPVCC(31, 58, 0, 0)
3884 return OPVCC(31, 58, 0, 1)
3887 return OPVCC(19, 257, 0, 0)
3889 return OPVCC(19, 129, 0, 0)
3891 return OPVCC(19, 289, 0, 0)
3893 return OPVCC(19, 225, 0, 0)
3895 return OPVCC(19, 33, 0, 0)
3897 return OPVCC(19, 449, 0, 0)
3899 return OPVCC(19, 417, 0, 0)
3901 return OPVCC(19, 193, 0, 0)
3904 return OPVCC(31, 86, 0, 0)
3906 return OPVCC(31, 470, 0, 0)
3908 return OPVCC(31, 54, 0, 0)
3910 return OPVCC(31, 278, 0, 0)
3912 return OPVCC(31, 246, 0, 0)
3914 return OPVCC(31, 1014, 0, 0)
3917 return OPVCC(31, 265, 0, 0) /* modud - v3.0 */
3919 return OPVCC(31, 267, 0, 0) /* moduw - v3.0 */
3921 return OPVCC(31, 777, 0, 0) /* modsd - v3.0 */
3923 return OPVCC(31, 779, 0, 0) /* modsw - v3.0 */
3925 // TODO: Should REMs be here?
3927 return OPVCC(31, 491, 0, 0)
3929 case AREMCC, ADIVWCC:
3930 return OPVCC(31, 491, 0, 1)
3933 return OPVCC(31, 491, 1, 0)
3935 case AREMVCC, ADIVWVCC:
3936 return OPVCC(31, 491, 1, 1)
3939 return OPVCC(31, 459, 0, 0)
3941 case AREMUCC, ADIVWUCC:
3942 return OPVCC(31, 459, 0, 1)
3944 case AREMUV, ADIVWUV:
3945 return OPVCC(31, 459, 1, 0)
3947 case AREMUVCC, ADIVWUVCC:
3948 return OPVCC(31, 459, 1, 1)
3951 return OPVCC(31, 489, 0, 0)
3953 case AREMDCC, ADIVDCC:
3954 return OPVCC(31, 489, 0, 1)
3957 return OPVCC(31, 425, 0, 0)
3960 return OPVCC(31, 425, 0, 1)
3963 return OPVCC(31, 393, 0, 0)
3966 return OPVCC(31, 393, 0, 1)
3968 case AREMDV, ADIVDV:
3969 return OPVCC(31, 489, 1, 0)
3971 case AREMDVCC, ADIVDVCC:
3972 return OPVCC(31, 489, 1, 1)
3974 case AREMDU, ADIVDU:
3975 return OPVCC(31, 457, 0, 0)
3977 case AREMDUCC, ADIVDUCC:
3978 return OPVCC(31, 457, 0, 1)
3980 case AREMDUV, ADIVDUV:
3981 return OPVCC(31, 457, 1, 0)
3983 case AREMDUVCC, ADIVDUVCC:
3984 return OPVCC(31, 457, 1, 1)
3987 return OPVCC(31, 854, 0, 0)
3990 return OPVCC(31, 284, 0, 0)
3992 return OPVCC(31, 284, 0, 1)
3995 return OPVCC(31, 954, 0, 0)
3997 return OPVCC(31, 954, 0, 1)
3999 return OPVCC(31, 922, 0, 0)
4001 return OPVCC(31, 922, 0, 1)
4003 return OPVCC(31, 986, 0, 0)
4005 return OPVCC(31, 986, 0, 1)
4008 return OPVCC(63, 264, 0, 0)
4010 return OPVCC(63, 264, 0, 1)
4012 return OPVCC(63, 21, 0, 0)
4014 return OPVCC(63, 21, 0, 1)
4016 return OPVCC(59, 21, 0, 0)
4018 return OPVCC(59, 21, 0, 1)
4020 return OPVCC(63, 32, 0, 0)
4022 return OPVCC(63, 0, 0, 0)
4024 return OPVCC(63, 846, 0, 0)
4026 return OPVCC(63, 846, 0, 1)
4028 return OPVCC(63, 974, 0, 0)
4030 return OPVCC(63, 974, 0, 1)
4032 return OPVCC(59, 846, 0, 0)
4034 return OPVCC(59, 846, 0, 1)
4036 return OPVCC(63, 14, 0, 0)
4038 return OPVCC(63, 14, 0, 1)
4040 return OPVCC(63, 15, 0, 0)
4042 return OPVCC(63, 15, 0, 1)
4044 return OPVCC(63, 814, 0, 0)
4046 return OPVCC(63, 814, 0, 1)
4048 return OPVCC(63, 815, 0, 0)
4050 return OPVCC(63, 815, 0, 1)
4052 return OPVCC(63, 18, 0, 0)
4054 return OPVCC(63, 18, 0, 1)
4056 return OPVCC(59, 18, 0, 0)
4058 return OPVCC(59, 18, 0, 1)
4060 return OPVCC(63, 29, 0, 0)
4062 return OPVCC(63, 29, 0, 1)
4064 return OPVCC(59, 29, 0, 0)
4066 return OPVCC(59, 29, 0, 1)
4068 case AFMOVS, AFMOVD:
4069 return OPVCC(63, 72, 0, 0) /* load */
4071 return OPVCC(63, 72, 0, 1)
4073 return OPVCC(63, 28, 0, 0)
4075 return OPVCC(63, 28, 0, 1)
4077 return OPVCC(59, 28, 0, 0)
4079 return OPVCC(59, 28, 0, 1)
4081 return OPVCC(63, 25, 0, 0)
4083 return OPVCC(63, 25, 0, 1)
4085 return OPVCC(59, 25, 0, 0)
4087 return OPVCC(59, 25, 0, 1)
4089 return OPVCC(63, 136, 0, 0)
4091 return OPVCC(63, 136, 0, 1)
4093 return OPVCC(63, 40, 0, 0)
4095 return OPVCC(63, 40, 0, 1)
4097 return OPVCC(63, 31, 0, 0)
4099 return OPVCC(63, 31, 0, 1)
4101 return OPVCC(59, 31, 0, 0)
4103 return OPVCC(59, 31, 0, 1)
4105 return OPVCC(63, 30, 0, 0)
4107 return OPVCC(63, 30, 0, 1)
4109 return OPVCC(59, 30, 0, 0)
4111 return OPVCC(59, 30, 0, 1)
4113 return OPVCC(63, 8, 0, 0)
4115 return OPVCC(63, 8, 0, 1)
4117 return OPVCC(59, 24, 0, 0)
4119 return OPVCC(59, 24, 0, 1)
4121 return OPVCC(63, 488, 0, 0)
4123 return OPVCC(63, 488, 0, 1)
4125 return OPVCC(63, 456, 0, 0)
4127 return OPVCC(63, 456, 0, 1)
4129 return OPVCC(63, 424, 0, 0)
4131 return OPVCC(63, 424, 0, 1)
4133 return OPVCC(63, 392, 0, 0)
4135 return OPVCC(63, 392, 0, 1)
4137 return OPVCC(63, 12, 0, 0)
4139 return OPVCC(63, 12, 0, 1)
4141 return OPVCC(63, 26, 0, 0)
4143 return OPVCC(63, 26, 0, 1)
4145 return OPVCC(63, 23, 0, 0)
4147 return OPVCC(63, 23, 0, 1)
4149 return OPVCC(63, 22, 0, 0)
4151 return OPVCC(63, 22, 0, 1)
4153 return OPVCC(59, 22, 0, 0)
4155 return OPVCC(59, 22, 0, 1)
4157 return OPVCC(63, 20, 0, 0)
4159 return OPVCC(63, 20, 0, 1)
4161 return OPVCC(59, 20, 0, 0)
4163 return OPVCC(59, 20, 0, 1)
4166 return OPVCC(31, 982, 0, 0)
4168 return OPVCC(19, 150, 0, 0)
4171 return OPVCC(63, 70, 0, 0)
4173 return OPVCC(63, 70, 0, 1)
4175 return OPVCC(63, 38, 0, 0)
4177 return OPVCC(63, 38, 0, 1)
4180 return OPVCC(31, 75, 0, 0)
4182 return OPVCC(31, 75, 0, 1)
4184 return OPVCC(31, 11, 0, 0)
4186 return OPVCC(31, 11, 0, 1)
4188 return OPVCC(31, 235, 0, 0)
4190 return OPVCC(31, 235, 0, 1)
4192 return OPVCC(31, 235, 1, 0)
4194 return OPVCC(31, 235, 1, 1)
4197 return OPVCC(31, 73, 0, 0)
4199 return OPVCC(31, 73, 0, 1)
4201 return OPVCC(31, 9, 0, 0)
4203 return OPVCC(31, 9, 0, 1)
4205 return OPVCC(31, 233, 0, 0)
4207 return OPVCC(31, 233, 0, 1)
4209 return OPVCC(31, 233, 1, 0)
4211 return OPVCC(31, 233, 1, 1)
4214 return OPVCC(31, 476, 0, 0)
4216 return OPVCC(31, 476, 0, 1)
4218 return OPVCC(31, 104, 0, 0)
4220 return OPVCC(31, 104, 0, 1)
4222 return OPVCC(31, 104, 1, 0)
4224 return OPVCC(31, 104, 1, 1)
4226 return OPVCC(31, 124, 0, 0)
4228 return OPVCC(31, 124, 0, 1)
4230 return OPVCC(31, 444, 0, 0)
4232 return OPVCC(31, 444, 0, 1)
4234 return OPVCC(31, 412, 0, 0)
4236 return OPVCC(31, 412, 0, 1)
4239 return OPVCC(31, 506, 0, 0) /* popcntd - v2.06 */
4241 return OPVCC(31, 378, 0, 0) /* popcntw - v2.06 */
4243 return OPVCC(31, 122, 0, 0) /* popcntb - v2.02 */
4245 return OPVCC(31, 538, 0, 0) /* cnttzw - v3.00 */
4247 return OPVCC(31, 538, 0, 1) /* cnttzw. - v3.00 */
4249 return OPVCC(31, 570, 0, 0) /* cnttzd - v3.00 */
4251 return OPVCC(31, 570, 0, 1) /* cnttzd. - v3.00 */
4254 return OPVCC(19, 50, 0, 0)
4256 return OPVCC(19, 51, 0, 0)
4258 return OPVCC(19, 18, 0, 0)
4260 return OPVCC(19, 274, 0, 0)
4263 return OPVCC(20, 0, 0, 0)
4265 return OPVCC(20, 0, 0, 1)
4267 return OPVCC(23, 0, 0, 0)
4269 return OPVCC(23, 0, 0, 1)
4272 return OPVCC(30, 8, 0, 0)
4274 return OPVCC(30, 0, 0, 1)
4277 return OPVCC(30, 9, 0, 0)
4279 return OPVCC(30, 9, 0, 1)
4282 return OPVCC(30, 0, 0, 0)
4284 return OPVCC(30, 0, 0, 1)
4286 return OPVCC(30, 0, 0, 0) | 2<<1 // rldicr
4288 return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr.
4291 return OPVCC(17, 1, 0, 0)
4294 return OPVCC(31, 24, 0, 0)
4296 return OPVCC(31, 24, 0, 1)
4298 return OPVCC(31, 27, 0, 0)
4300 return OPVCC(31, 27, 0, 1)
4303 return OPVCC(31, 792, 0, 0)
4305 return OPVCC(31, 792, 0, 1)
4307 return OPVCC(31, 794, 0, 0)
4309 return OPVCC(31, 794, 0, 1)
4312 return OPVCC(31, 536, 0, 0)
4314 return OPVCC(31, 536, 0, 1)
4316 return OPVCC(31, 539, 0, 0)
4318 return OPVCC(31, 539, 0, 1)
4321 return OPVCC(31, 40, 0, 0)
4323 return OPVCC(31, 40, 0, 1)
4325 return OPVCC(31, 40, 1, 0)
4327 return OPVCC(31, 40, 1, 1)
4329 return OPVCC(31, 8, 0, 0)
4331 return OPVCC(31, 8, 0, 1)
4333 return OPVCC(31, 8, 1, 0)
4335 return OPVCC(31, 8, 1, 1)
4337 return OPVCC(31, 136, 0, 0)
4339 return OPVCC(31, 136, 0, 1)
4341 return OPVCC(31, 136, 1, 0)
4343 return OPVCC(31, 136, 1, 1)
4345 return OPVCC(31, 232, 0, 0)
4347 return OPVCC(31, 232, 0, 1)
4349 return OPVCC(31, 232, 1, 0)
4351 return OPVCC(31, 232, 1, 1)
4353 return OPVCC(31, 200, 0, 0)
4355 return OPVCC(31, 200, 0, 1)
4357 return OPVCC(31, 200, 1, 0)
4359 return OPVCC(31, 200, 1, 1)
4362 return OPVCC(31, 598, 0, 0)
4364 return OPVCC(31, 598, 0, 0) | 1<<21
4367 return OPVCC(31, 598, 0, 0) | 2<<21
4370 return OPVCC(31, 306, 0, 0)
4372 return OPVCC(31, 274, 0, 0)
4374 return OPVCC(31, 566, 0, 0)
4376 return OPVCC(31, 498, 0, 0)
4378 return OPVCC(31, 434, 0, 0)
4380 return OPVCC(31, 915, 0, 0)
4382 return OPVCC(31, 851, 0, 0)
4384 return OPVCC(31, 402, 0, 0)
4387 return OPVCC(31, 4, 0, 0)
4389 return OPVCC(31, 68, 0, 0)
4391 /* Vector (VMX/Altivec) instructions */
4392 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4393 /* are enabled starting at POWER6 (ISA 2.05). */
4395 return OPVX(4, 1028, 0, 0) /* vand - v2.03 */
4397 return OPVX(4, 1092, 0, 0) /* vandc - v2.03 */
4399 return OPVX(4, 1412, 0, 0) /* vnand - v2.07 */
4402 return OPVX(4, 1156, 0, 0) /* vor - v2.03 */
4404 return OPVX(4, 1348, 0, 0) /* vorc - v2.07 */
4406 return OPVX(4, 1284, 0, 0) /* vnor - v2.03 */
4408 return OPVX(4, 1220, 0, 0) /* vxor - v2.03 */
4410 return OPVX(4, 1668, 0, 0) /* veqv - v2.07 */
4413 return OPVX(4, 0, 0, 0) /* vaddubm - v2.03 */
4415 return OPVX(4, 64, 0, 0) /* vadduhm - v2.03 */
4417 return OPVX(4, 128, 0, 0) /* vadduwm - v2.03 */
4419 return OPVX(4, 192, 0, 0) /* vaddudm - v2.07 */
4421 return OPVX(4, 256, 0, 0) /* vadduqm - v2.07 */
4424 return OPVX(4, 320, 0, 0) /* vaddcuq - v2.07 */
4426 return OPVX(4, 384, 0, 0) /* vaddcuw - v2.03 */
4429 return OPVX(4, 512, 0, 0) /* vaddubs - v2.03 */
4431 return OPVX(4, 576, 0, 0) /* vadduhs - v2.03 */
4433 return OPVX(4, 640, 0, 0) /* vadduws - v2.03 */
4436 return OPVX(4, 768, 0, 0) /* vaddsbs - v2.03 */
4438 return OPVX(4, 832, 0, 0) /* vaddshs - v2.03 */
4440 return OPVX(4, 896, 0, 0) /* vaddsws - v2.03 */
4443 return OPVX(4, 60, 0, 0) /* vaddeuqm - v2.07 */
4445 return OPVX(4, 61, 0, 0) /* vaddecuq - v2.07 */
4448 return OPVX(4, 776, 0, 0) /* vmulesb - v2.03 */
4450 return OPVX(4, 264, 0, 0) /* vmulosb - v2.03 */
4452 return OPVX(4, 520, 0, 0) /* vmuleub - v2.03 */
4454 return OPVX(4, 8, 0, 0) /* vmuloub - v2.03 */
4456 return OPVX(4, 840, 0, 0) /* vmulesh - v2.03 */
4458 return OPVX(4, 328, 0, 0) /* vmulosh - v2.03 */
4460 return OPVX(4, 584, 0, 0) /* vmuleuh - v2.03 */
4462 return OPVX(4, 72, 0, 0) /* vmulouh - v2.03 */
4464 return OPVX(4, 904, 0, 0) /* vmulesw - v2.07 */
4466 return OPVX(4, 392, 0, 0) /* vmulosw - v2.07 */
4468 return OPVX(4, 648, 0, 0) /* vmuleuw - v2.07 */
4470 return OPVX(4, 136, 0, 0) /* vmulouw - v2.07 */
4472 return OPVX(4, 137, 0, 0) /* vmuluwm - v2.07 */
4475 return OPVX(4, 1032, 0, 0) /* vpmsumb - v2.07 */
4477 return OPVX(4, 1096, 0, 0) /* vpmsumh - v2.07 */
4479 return OPVX(4, 1160, 0, 0) /* vpmsumw - v2.07 */
4481 return OPVX(4, 1224, 0, 0) /* vpmsumd - v2.07 */
4484 return OPVX(4, 35, 0, 0) /* vmsumudm - v3.00b */
4487 return OPVX(4, 1024, 0, 0) /* vsububm - v2.03 */
4489 return OPVX(4, 1088, 0, 0) /* vsubuhm - v2.03 */
4491 return OPVX(4, 1152, 0, 0) /* vsubuwm - v2.03 */
4493 return OPVX(4, 1216, 0, 0) /* vsubudm - v2.07 */
4495 return OPVX(4, 1280, 0, 0) /* vsubuqm - v2.07 */
4498 return OPVX(4, 1344, 0, 0) /* vsubcuq - v2.07 */
4500 return OPVX(4, 1408, 0, 0) /* vsubcuw - v2.03 */
4503 return OPVX(4, 1536, 0, 0) /* vsububs - v2.03 */
4505 return OPVX(4, 1600, 0, 0) /* vsubuhs - v2.03 */
4507 return OPVX(4, 1664, 0, 0) /* vsubuws - v2.03 */
4510 return OPVX(4, 1792, 0, 0) /* vsubsbs - v2.03 */
4512 return OPVX(4, 1856, 0, 0) /* vsubshs - v2.03 */
4514 return OPVX(4, 1920, 0, 0) /* vsubsws - v2.03 */
4517 return OPVX(4, 62, 0, 0) /* vsubeuqm - v2.07 */
4519 return OPVX(4, 63, 0, 0) /* vsubecuq - v2.07 */
4522 return OPVX(4, 4, 0, 0) /* vrlb - v2.03 */
4524 return OPVX(4, 68, 0, 0) /* vrlh - v2.03 */
4526 return OPVX(4, 132, 0, 0) /* vrlw - v2.03 */
4528 return OPVX(4, 196, 0, 0) /* vrld - v2.07 */
4531 return OPVX(4, 1676, 0, 0) /* vmrgow - v2.07 */
4533 return OPVX(4, 1932, 0, 0) /* vmrgew - v2.07 */
4536 return OPVX(4, 260, 0, 0) /* vslh - v2.03 */
4538 return OPVX(4, 324, 0, 0) /* vslh - v2.03 */
4540 return OPVX(4, 388, 0, 0) /* vslw - v2.03 */
4542 return OPVX(4, 452, 0, 0) /* vsl - v2.03 */
4544 return OPVX(4, 1036, 0, 0) /* vsl - v2.03 */
4546 return OPVX(4, 516, 0, 0) /* vsrb - v2.03 */
4548 return OPVX(4, 580, 0, 0) /* vsrh - v2.03 */
4550 return OPVX(4, 644, 0, 0) /* vsrw - v2.03 */
4552 return OPVX(4, 708, 0, 0) /* vsr - v2.03 */
4554 return OPVX(4, 1100, 0, 0) /* vsro - v2.03 */
4556 return OPVX(4, 1476, 0, 0) /* vsld - v2.07 */
4558 return OPVX(4, 1732, 0, 0) /* vsrd - v2.07 */
4561 return OPVX(4, 772, 0, 0) /* vsrab - v2.03 */
4563 return OPVX(4, 836, 0, 0) /* vsrah - v2.03 */
4565 return OPVX(4, 900, 0, 0) /* vsraw - v2.03 */
4567 return OPVX(4, 964, 0, 0) /* vsrad - v2.07 */
4570 return OPVC(4, 1356, 0, 0) /* vbpermq - v2.07 */
4572 return OPVC(4, 1484, 0, 0) /* vbpermd - v3.00 */
4575 return OPVX(4, 1794, 0, 0) /* vclzb - v2.07 */
4577 return OPVX(4, 1858, 0, 0) /* vclzh - v2.07 */
4579 return OPVX(4, 1922, 0, 0) /* vclzw - v2.07 */
4581 return OPVX(4, 1986, 0, 0) /* vclzd - v2.07 */
4584 return OPVX(4, 1795, 0, 0) /* vpopcntb - v2.07 */
4586 return OPVX(4, 1859, 0, 0) /* vpopcnth - v2.07 */
4588 return OPVX(4, 1923, 0, 0) /* vpopcntw - v2.07 */
4590 return OPVX(4, 1987, 0, 0) /* vpopcntd - v2.07 */
4593 return OPVC(4, 6, 0, 0) /* vcmpequb - v2.03 */
4595 return OPVC(4, 6, 0, 1) /* vcmpequb. - v2.03 */
4597 return OPVC(4, 70, 0, 0) /* vcmpequh - v2.03 */
4599 return OPVC(4, 70, 0, 1) /* vcmpequh. - v2.03 */
4601 return OPVC(4, 134, 0, 0) /* vcmpequw - v2.03 */
4603 return OPVC(4, 134, 0, 1) /* vcmpequw. - v2.03 */
4605 return OPVC(4, 199, 0, 0) /* vcmpequd - v2.07 */
4607 return OPVC(4, 199, 0, 1) /* vcmpequd. - v2.07 */
4610 return OPVC(4, 518, 0, 0) /* vcmpgtub - v2.03 */
4612 return OPVC(4, 518, 0, 1) /* vcmpgtub. - v2.03 */
4614 return OPVC(4, 582, 0, 0) /* vcmpgtuh - v2.03 */
4616 return OPVC(4, 582, 0, 1) /* vcmpgtuh. - v2.03 */
4618 return OPVC(4, 646, 0, 0) /* vcmpgtuw - v2.03 */
4620 return OPVC(4, 646, 0, 1) /* vcmpgtuw. - v2.03 */
4622 return OPVC(4, 711, 0, 0) /* vcmpgtud - v2.07 */
4624 return OPVC(4, 711, 0, 1) /* vcmpgtud. v2.07 */
4626 return OPVC(4, 774, 0, 0) /* vcmpgtsb - v2.03 */
4628 return OPVC(4, 774, 0, 1) /* vcmpgtsb. - v2.03 */
4630 return OPVC(4, 838, 0, 0) /* vcmpgtsh - v2.03 */
4632 return OPVC(4, 838, 0, 1) /* vcmpgtsh. - v2.03 */
4634 return OPVC(4, 902, 0, 0) /* vcmpgtsw - v2.03 */
4636 return OPVC(4, 902, 0, 1) /* vcmpgtsw. - v2.03 */
4638 return OPVC(4, 967, 0, 0) /* vcmpgtsd - v2.07 */
4640 return OPVC(4, 967, 0, 1) /* vcmpgtsd. - v2.07 */
4643 return OPVC(4, 263, 0, 0) /* vcmpnezb - v3.00 */
4645 return OPVC(4, 263, 0, 1) /* vcmpnezb. - v3.00 */
4647 return OPVC(4, 7, 0, 0) /* vcmpneb - v3.00 */
4649 return OPVC(4, 7, 0, 1) /* vcmpneb. - v3.00 */
4651 return OPVC(4, 71, 0, 0) /* vcmpneh - v3.00 */
4653 return OPVC(4, 71, 0, 1) /* vcmpneh. - v3.00 */
4655 return OPVC(4, 135, 0, 0) /* vcmpnew - v3.00 */
4657 return OPVC(4, 135, 0, 1) /* vcmpnew. - v3.00 */
4660 return OPVX(4, 43, 0, 0) /* vperm - v2.03 */
4662 return OPVX(4, 45, 0, 0) /* vpermxor - v2.03 */
4664 return OPVX(4, 59, 0, 0) /* vpermr - v3.0 */
4667 return OPVX(4, 42, 0, 0) /* vsel - v2.03 */
4670 return OPVX(4, 1288, 0, 0) /* vcipher - v2.07 */
4672 return OPVX(4, 1289, 0, 0) /* vcipherlast - v2.07 */
4674 return OPVX(4, 1352, 0, 0) /* vncipher - v2.07 */
4676 return OPVX(4, 1353, 0, 0) /* vncipherlast - v2.07 */
4678 return OPVX(4, 1480, 0, 0) /* vsbox - v2.07 */
4679 /* End of vector instructions */
4681 /* Vector scalar (VSX) instructions */
4682 /* ISA 2.06 enables these for POWER7. */
4683 case AMFVSRD, AMFVRD, AMFFPRD:
4684 return OPVXX1(31, 51, 0) /* mfvsrd - v2.07 */
4686 return OPVXX1(31, 115, 0) /* mfvsrwz - v2.07 */
4688 return OPVXX1(31, 307, 0) /* mfvsrld - v3.00 */
4690 case AMTVSRD, AMTFPRD, AMTVRD:
4691 return OPVXX1(31, 179, 0) /* mtvsrd - v2.07 */
4693 return OPVXX1(31, 211, 0) /* mtvsrwa - v2.07 */
4695 return OPVXX1(31, 243, 0) /* mtvsrwz - v2.07 */
4697 return OPVXX1(31, 435, 0) /* mtvsrdd - v3.00 */
4699 return OPVXX1(31, 403, 0) /* mtvsrws - v3.00 */
4702 return OPVXX3(60, 130, 0) /* xxland - v2.06 */
4704 return OPVXX3(60, 138, 0) /* xxlandc - v2.06 */
4706 return OPVXX3(60, 186, 0) /* xxleqv - v2.07 */
4708 return OPVXX3(60, 178, 0) /* xxlnand - v2.07 */
4711 return OPVXX3(60, 170, 0) /* xxlorc - v2.07 */
4713 return OPVXX3(60, 162, 0) /* xxlnor - v2.06 */
4714 case AXXLOR, AXXLORQ:
4715 return OPVXX3(60, 146, 0) /* xxlor - v2.06 */
4717 return OPVXX3(60, 154, 0) /* xxlxor - v2.06 */
4720 return OPVXX4(60, 3, 0) /* xxsel - v2.06 */
4723 return OPVXX3(60, 18, 0) /* xxmrghw - v2.06 */
4725 return OPVXX3(60, 50, 0) /* xxmrglw - v2.06 */
4728 return OPVXX2(60, 164, 0) /* xxspltw - v2.06 */
4731 return OPVCC(60, 360, 0, 0) /* xxspltib - v3.0 */
4734 return OPVXX3(60, 26, 0) /* xxperm - v2.06 */
4736 return OPVXX3(60, 10, 0) /* xxpermdi - v2.06 */
4739 return OPVXX3(60, 2, 0) /* xxsldwi - v2.06 */
4742 return OPVXX2VA(60, 475, 31) /* xxbrq - v3.0 */
4744 return OPVXX2VA(60, 475, 23) /* xxbrd - v3.0 */
4746 return OPVXX2VA(60, 475, 15) /* xxbrw - v3.0 */
4748 return OPVXX2VA(60, 475, 7) /* xxbrh - v3.0 */
4751 return OPVXX2(60, 265, 0) /* xscvdpsp - v2.06 */
4753 return OPVXX2(60, 329, 0) /* xscvspdp - v2.06 */
4755 return OPVXX2(60, 267, 0) /* xscvdpspn - v2.07 */
4757 return OPVXX2(60, 331, 0) /* xscvspdpn - v2.07 */
4760 return OPVXX2(60, 393, 0) /* xvcvdpsp - v2.06 */
4762 return OPVXX2(60, 457, 0) /* xvcvspdp - v2.06 */
4765 return OPVXX2(60, 344, 0) /* xscvdpsxds - v2.06 */
4767 return OPVXX2(60, 88, 0) /* xscvdpsxws - v2.06 */
4769 return OPVXX2(60, 328, 0) /* xscvdpuxds - v2.06 */
4771 return OPVXX2(60, 72, 0) /* xscvdpuxws - v2.06 */
4774 return OPVXX2(60, 376, 0) /* xscvsxddp - v2.06 */
4776 return OPVXX2(60, 360, 0) /* xscvuxddp - v2.06 */
4778 return OPVXX2(60, 312, 0) /* xscvsxdsp - v2.06 */
4780 return OPVXX2(60, 296, 0) /* xscvuxdsp - v2.06 */
4783 return OPVXX2(60, 472, 0) /* xvcvdpsxds - v2.06 */
4785 return OPVXX2(60, 216, 0) /* xvcvdpsxws - v2.06 */
4787 return OPVXX2(60, 456, 0) /* xvcvdpuxds - v2.06 */
4789 return OPVXX2(60, 200, 0) /* xvcvdpuxws - v2.06 */
4791 return OPVXX2(60, 408, 0) /* xvcvspsxds - v2.07 */
4793 return OPVXX2(60, 152, 0) /* xvcvspsxws - v2.07 */
4795 return OPVXX2(60, 392, 0) /* xvcvspuxds - v2.07 */
4797 return OPVXX2(60, 136, 0) /* xvcvspuxws - v2.07 */
4800 return OPVXX2(60, 504, 0) /* xvcvsxddp - v2.06 */
4802 return OPVXX2(60, 248, 0) /* xvcvsxwdp - v2.06 */
4804 return OPVXX2(60, 488, 0) /* xvcvuxddp - v2.06 */
4806 return OPVXX2(60, 232, 0) /* xvcvuxwdp - v2.06 */
4808 return OPVXX2(60, 440, 0) /* xvcvsxdsp - v2.06 */
4810 return OPVXX2(60, 184, 0) /* xvcvsxwsp - v2.06 */
4812 return OPVXX2(60, 424, 0) /* xvcvuxdsp - v2.06 */
4814 return OPVXX2(60, 168, 0) /* xvcvuxwsp - v2.06 */
4815 /* End of VSX instructions */
4818 return OPVX(4, 48, 0, 0) /* maddhd - v3.00 */
4820 return OPVX(4, 49, 0, 0) /* maddhdu - v3.00 */
4822 return OPVX(4, 51, 0, 0) /* maddld - v3.00 */
4825 return OPVCC(31, 316, 0, 0)
4827 return OPVCC(31, 316, 0, 1)
4830 c.ctxt.Diag("bad r/r, r/r/r or r/r/r/r opcode %v", a)
4834 func (c *ctxt9) opirrr(a obj.As) uint32 {
4836 /* Vector (VMX/Altivec) instructions */
4837 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4838 /* are enabled starting at POWER6 (ISA 2.05). */
4840 return OPVX(4, 44, 0, 0) /* vsldoi - v2.03 */
4843 c.ctxt.Diag("bad i/r/r/r opcode %v", a)
4847 func (c *ctxt9) opiirr(a obj.As) uint32 {
4849 /* Vector (VMX/Altivec) instructions */
4850 /* ISA 2.07 enables these for POWER8 and beyond. */
4852 return OPVX(4, 1666, 0, 0) /* vshasigmaw - v2.07 */
4854 return OPVX(4, 1730, 0, 0) /* vshasigmad - v2.07 */
4857 c.ctxt.Diag("bad i/i/r/r opcode %v", a)
4861 func (c *ctxt9) opirr(a obj.As) uint32 {
4864 return OPVCC(14, 0, 0, 0)
4866 return OPVCC(12, 0, 0, 0)
4868 return OPVCC(13, 0, 0, 0)
4870 return OPVCC(15, 0, 0, 0) /* ADDIS */
4873 return OPVCC(28, 0, 0, 0)
4875 return OPVCC(29, 0, 0, 0) /* ANDIS. */
4878 return OPVCC(18, 0, 0, 0)
4880 return OPVCC(18, 0, 0, 0) | 1
4882 return OPVCC(18, 0, 0, 0) | 1
4884 return OPVCC(18, 0, 0, 0) | 1
4886 return OPVCC(16, 0, 0, 0)
4888 return OPVCC(16, 0, 0, 0) | 1
4891 return AOP_RRR(16<<26, 12, 2, 0)
4893 return AOP_RRR(16<<26, 4, 0, 0)
4895 return AOP_RRR(16<<26, 12, 1, 0)
4897 return AOP_RRR(16<<26, 4, 1, 0)
4899 return AOP_RRR(16<<26, 12, 0, 0)
4901 return AOP_RRR(16<<26, 4, 2, 0)
4903 return AOP_RRR(16<<26, 4, 3, 0) // apparently unordered-clear
4905 return AOP_RRR(16<<26, 12, 3, 0) // apparently unordered-set
4908 return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */
4910 return OPVCC(10, 0, 0, 0) | 1<<21
4912 return OPVCC(11, 0, 0, 0) /* L=0 */
4914 return OPVCC(10, 0, 0, 0)
4916 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
4919 return OPVCC(31, 597, 0, 0)
4922 return OPVCC(31, 774, 0, 0) /* copy - v3.00 */
4924 return OPVCC(31, 902, 0, 1) /* paste. - v3.00 */
4926 return OPVCC(31, 755, 0, 0) /* darn - v3.00 */
4929 return OPVCC(7, 0, 0, 0)
4932 return OPVCC(24, 0, 0, 0)
4934 return OPVCC(25, 0, 0, 0) /* ORIS */
4937 return OPVCC(20, 0, 0, 0) /* rlwimi */
4939 return OPVCC(20, 0, 0, 1)
4941 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
4943 return OPVCC(30, 0, 0, 1) | 3<<2
4945 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
4947 return OPVCC(30, 0, 0, 1) | 3<<2
4949 return OPVCC(21, 0, 0, 0) /* rlwinm */
4951 return OPVCC(21, 0, 0, 1)
4954 return OPVCC(30, 0, 0, 0) /* rldicl */
4956 return OPVCC(30, 0, 0, 1)
4958 return OPVCC(30, 1, 0, 0) /* rldicr */
4960 return OPVCC(30, 1, 0, 1)
4962 return OPVCC(30, 0, 0, 0) | 2<<2
4964 return OPVCC(30, 0, 0, 1) | 2<<2
4967 return OPVCC(31, 824, 0, 0)
4969 return OPVCC(31, 824, 0, 1)
4971 return OPVCC(31, (413 << 1), 0, 0)
4973 return OPVCC(31, (413 << 1), 0, 1)
4976 return OPVCC(31, 725, 0, 0)
4979 return OPVCC(8, 0, 0, 0)
4982 return OPVCC(3, 0, 0, 0)
4984 return OPVCC(2, 0, 0, 0)
4986 /* Vector (VMX/Altivec) instructions */
4987 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4988 /* are enabled starting at POWER6 (ISA 2.05). */
4990 return OPVX(4, 524, 0, 0) /* vspltb - v2.03 */
4992 return OPVX(4, 588, 0, 0) /* vsplth - v2.03 */
4994 return OPVX(4, 652, 0, 0) /* vspltw - v2.03 */
4997 return OPVX(4, 780, 0, 0) /* vspltisb - v2.03 */
4999 return OPVX(4, 844, 0, 0) /* vspltish - v2.03 */
5001 return OPVX(4, 908, 0, 0) /* vspltisw - v2.03 */
5002 /* End of vector instructions */
5005 return OPVCC(63, 128, 0, 0) /* ftdiv - v2.06 */
5007 return OPVCC(63, 160, 0, 0) /* ftsqrt - v2.06 */
5010 return OPVCC(26, 0, 0, 0) /* XORIL */
5012 return OPVCC(27, 0, 0, 0) /* XORIS */
5015 c.ctxt.Diag("bad opcode i/r or i/r/r %v", a)
5022 func (c *ctxt9) opload(a obj.As) uint32 {
5025 return OPVCC(58, 0, 0, 0) /* ld */
5027 return OPVCC(58, 0, 0, 1) /* ldu */
5029 return OPVCC(32, 0, 0, 0) /* lwz */
5031 return OPVCC(33, 0, 0, 0) /* lwzu */
5033 return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */
5035 return OPDQ(61, 1, 0) /* lxv - ISA v3.00 */
5037 return OPVXX1(31, 269, 0) /* lxvl - ISA v3.00 */
5039 return OPVXX1(31, 301, 0) /* lxvll - ISA v3.00 */
5043 return OPVCC(34, 0, 0, 0)
5046 case AMOVBU, AMOVBZU:
5047 return OPVCC(35, 0, 0, 0)
5049 return OPVCC(50, 0, 0, 0)
5051 return OPVCC(51, 0, 0, 0)
5053 return OPVCC(48, 0, 0, 0)
5055 return OPVCC(49, 0, 0, 0)
5057 return OPVCC(42, 0, 0, 0)
5059 return OPVCC(43, 0, 0, 0)
5061 return OPVCC(40, 0, 0, 0)
5063 return OPVCC(41, 0, 0, 0)
5065 return OPVCC(46, 0, 0, 0) /* lmw */
5068 c.ctxt.Diag("bad load opcode %v", a)
5073 * indexed load a(b),d
5075 func (c *ctxt9) oploadx(a obj.As) uint32 {
5078 return OPVCC(31, 23, 0, 0) /* lwzx */
5080 return OPVCC(31, 55, 0, 0) /* lwzux */
5082 return OPVCC(31, 341, 0, 0) /* lwax */
5084 return OPVCC(31, 373, 0, 0) /* lwaux */
5087 return OPVCC(31, 87, 0, 0) /* lbzx */
5089 case AMOVBU, AMOVBZU:
5090 return OPVCC(31, 119, 0, 0) /* lbzux */
5092 return OPVCC(31, 599, 0, 0) /* lfdx */
5094 return OPVCC(31, 631, 0, 0) /* lfdux */
5096 return OPVCC(31, 535, 0, 0) /* lfsx */
5098 return OPVCC(31, 567, 0, 0) /* lfsux */
5100 return OPVCC(31, 855, 0, 0) /* lfiwax - power6, isa 2.05 */
5102 return OPVCC(31, 887, 0, 0) /* lfiwzx - power7, isa 2.06 */
5104 return OPVCC(31, 343, 0, 0) /* lhax */
5106 return OPVCC(31, 375, 0, 0) /* lhaux */
5108 return OPVCC(31, 790, 0, 0) /* lhbrx */
5110 return OPVCC(31, 534, 0, 0) /* lwbrx */
5112 return OPVCC(31, 532, 0, 0) /* ldbrx */
5114 return OPVCC(31, 279, 0, 0) /* lhzx */
5116 return OPVCC(31, 311, 0, 0) /* lhzux */
5118 return OPVCC(31, 310, 0, 0) /* eciwx */
5120 return OPVCC(31, 52, 0, 0) /* lbarx */
5122 return OPVCC(31, 116, 0, 0) /* lharx */
5124 return OPVCC(31, 20, 0, 0) /* lwarx */
5126 return OPVCC(31, 84, 0, 0) /* ldarx */
5128 return OPVCC(31, 533, 0, 0) /* lswx */
5130 return OPVCC(31, 21, 0, 0) /* ldx */
5132 return OPVCC(31, 53, 0, 0) /* ldux */
5134 return OPVCC(31, 309, 0, 0) /* ldmx */
5136 /* Vector (VMX/Altivec) instructions */
5137 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
5138 /* are enabled starting at POWER6 (ISA 2.05). */
5140 return OPVCC(31, 7, 0, 0) /* lvebx - v2.03 */
5142 return OPVCC(31, 39, 0, 0) /* lvehx - v2.03 */
5144 return OPVCC(31, 71, 0, 0) /* lvewx - v2.03 */
5146 return OPVCC(31, 103, 0, 0) /* lvx - v2.03 */
5148 return OPVCC(31, 359, 0, 0) /* lvxl - v2.03 */
5150 return OPVCC(31, 6, 0, 0) /* lvsl - v2.03 */
5152 return OPVCC(31, 38, 0, 0) /* lvsr - v2.03 */
5153 /* End of vector instructions */
5155 /* Vector scalar (VSX) instructions */
5156 /* ISA 2.06 enables these for POWER7. */
5158 return OPVXX1(31, 844, 0) /* lxvd2x - v2.06 */
5160 return OPVXX1(31, 780, 0) /* lxvw4x - v2.06 */
5162 return OPVXX1(31, 812, 0) /* lxvh8x - v3.00 */
5164 return OPVXX1(31, 876, 0) /* lxvb16x - v3.00 */
5166 return OPVXX1(31, 332, 0) /* lxvdsx - v2.06 */
5168 return OPVXX1(31, 588, 0) /* lxsdx - v2.06 */
5170 return OPVXX1(31, 76, 0) /* lxsiwax - v2.07 */
5172 return OPVXX1(31, 12, 0) /* lxsiwzx - v2.07 */
5175 c.ctxt.Diag("bad loadx opcode %v", a)
5182 func (c *ctxt9) opstore(a obj.As) uint32 {
5185 return OPVCC(38, 0, 0, 0) /* stb */
5187 case AMOVBU, AMOVBZU:
5188 return OPVCC(39, 0, 0, 0) /* stbu */
5190 return OPVCC(54, 0, 0, 0) /* stfd */
5192 return OPVCC(55, 0, 0, 0) /* stfdu */
5194 return OPVCC(52, 0, 0, 0) /* stfs */
5196 return OPVCC(53, 0, 0, 0) /* stfsu */
5199 return OPVCC(44, 0, 0, 0) /* sth */
5201 case AMOVHZU, AMOVHU:
5202 return OPVCC(45, 0, 0, 0) /* sthu */
5204 return OPVCC(47, 0, 0, 0) /* stmw */
5206 return OPVCC(31, 725, 0, 0) /* stswi */
5209 return OPVCC(36, 0, 0, 0) /* stw */
5211 case AMOVWZU, AMOVWU:
5212 return OPVCC(37, 0, 0, 0) /* stwu */
5214 return OPVCC(62, 0, 0, 0) /* std */
5216 return OPVCC(62, 0, 0, 1) /* stdu */
5218 return OPDQ(61, 5, 0) /* stxv ISA 3.0 */
5220 return OPVXX1(31, 397, 0) /* stxvl ISA 3.0 */
5222 return OPVXX1(31, 429, 0) /* stxvll ISA 3.0 */
5226 c.ctxt.Diag("unknown store opcode %v", a)
5231 * indexed store s,a(b)
5233 func (c *ctxt9) opstorex(a obj.As) uint32 {
5236 return OPVCC(31, 215, 0, 0) /* stbx */
5238 case AMOVBU, AMOVBZU:
5239 return OPVCC(31, 247, 0, 0) /* stbux */
5241 return OPVCC(31, 727, 0, 0) /* stfdx */
5243 return OPVCC(31, 759, 0, 0) /* stfdux */
5245 return OPVCC(31, 663, 0, 0) /* stfsx */
5247 return OPVCC(31, 695, 0, 0) /* stfsux */
5249 return OPVCC(31, 983, 0, 0) /* stfiwx */
5252 return OPVCC(31, 407, 0, 0) /* sthx */
5254 return OPVCC(31, 918, 0, 0) /* sthbrx */
5256 case AMOVHZU, AMOVHU:
5257 return OPVCC(31, 439, 0, 0) /* sthux */
5260 return OPVCC(31, 151, 0, 0) /* stwx */
5262 case AMOVWZU, AMOVWU:
5263 return OPVCC(31, 183, 0, 0) /* stwux */
5265 return OPVCC(31, 661, 0, 0) /* stswx */
5267 return OPVCC(31, 662, 0, 0) /* stwbrx */
5269 return OPVCC(31, 660, 0, 0) /* stdbrx */
5271 return OPVCC(31, 694, 0, 1) /* stbcx. */
5273 return OPVCC(31, 726, 0, 1) /* sthcx. */
5275 return OPVCC(31, 150, 0, 1) /* stwcx. */
5277 return OPVCC(31, 214, 0, 1) /* stwdx. */
5279 return OPVCC(31, 438, 0, 0) /* ecowx */
5281 return OPVCC(31, 149, 0, 0) /* stdx */
5283 return OPVCC(31, 181, 0, 0) /* stdux */
5285 /* Vector (VMX/Altivec) instructions */
5286 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
5287 /* are enabled starting at POWER6 (ISA 2.05). */
5289 return OPVCC(31, 135, 0, 0) /* stvebx - v2.03 */
5291 return OPVCC(31, 167, 0, 0) /* stvehx - v2.03 */
5293 return OPVCC(31, 199, 0, 0) /* stvewx - v2.03 */
5295 return OPVCC(31, 231, 0, 0) /* stvx - v2.03 */
5297 return OPVCC(31, 487, 0, 0) /* stvxl - v2.03 */
5298 /* End of vector instructions */
5300 /* Vector scalar (VSX) instructions */
5301 /* ISA 2.06 enables these for POWER7. */
5303 return OPVXX1(31, 972, 0) /* stxvd2x - v2.06 */
5305 return OPVXX1(31, 908, 0) /* stxvw4x - v2.06 */
5307 return OPVXX1(31, 940, 0) /* stxvh8x - v3.00 */
5309 return OPVXX1(31, 1004, 0) /* stxvb16x - v3.00 */
5312 return OPVXX1(31, 716, 0) /* stxsdx - v2.06 */
5315 return OPVXX1(31, 140, 0) /* stxsiwx - v2.07 */
5317 /* End of vector scalar instructions */
5321 c.ctxt.Diag("unknown storex opcode %v", a)