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
67 a1 uint8 // p.From argument (obj.Addr). p is of type obj.Prog.
68 a2 uint8 // p.Reg argument (int16 Register)
69 a3 uint8 // p.RestArgs[0] (obj.AddrPos)
70 a4 uint8 // p.RestArgs[1]
71 a5 uint8 // p.RestARgs[2]
72 a6 uint8 // p.To (obj.Addr)
73 type_ int8 // cases in asmout below. E.g., 44 = st r,(ra+rb); 45 = ld (ra+rb), r
74 size int8 // Text space in bytes to lay operation
77 // optab contains an array to be sliced of accepted operand combinations for an
78 // instruction. Unused arguments and fields are not explicitly enumerated, and
79 // should not be listed for clarity. Unused arguments and values should always
80 // assume the default value for the given type.
82 // optab does not list every valid ppc64 opcode, it enumerates representative
83 // operand combinations for a class of instruction. The variable oprange indexes
84 // all valid ppc64 opcodes.
86 // oprange is initialized to point a slice within optab which contains the valid
87 // operand combinations for a given instruction. This is initialized from buildop.
89 // Likewise, each slice of optab is dynamically sorted using the ocmp Sort interface
90 // to arrange entries to minimize text size of each opcode.
92 {as: obj.ATEXT, a1: C_LOREG, a6: C_TEXTSIZE, type_: 0, size: 0},
93 {as: obj.ATEXT, a1: C_LOREG, a3: C_LCON, a6: C_TEXTSIZE, type_: 0, size: 0},
94 {as: obj.ATEXT, a1: C_ADDR, a6: C_TEXTSIZE, type_: 0, size: 0},
95 {as: obj.ATEXT, a1: C_ADDR, a3: C_LCON, a6: C_TEXTSIZE, type_: 0, size: 0},
97 {as: AADD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4},
98 {as: AADD, a1: C_REG, a6: C_REG, type_: 2, size: 4},
99 {as: AADD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
100 {as: AADD, a1: C_SCON, a6: C_REG, type_: 4, size: 4},
101 {as: AADD, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
102 {as: AADD, a1: C_ADDCON, a6: C_REG, type_: 4, size: 4},
103 {as: AADD, a1: C_UCON, a2: C_REG, a6: C_REG, type_: 20, size: 4},
104 {as: AADD, a1: C_UCON, a6: C_REG, type_: 20, size: 4},
105 {as: AADD, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 22, size: 8},
106 {as: AADD, a1: C_ANDCON, a6: C_REG, type_: 22, size: 8},
107 {as: AADD, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 22, size: 12},
108 {as: AADD, a1: C_LCON, a6: C_REG, type_: 22, size: 12},
109 {as: AADDIS, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 20, size: 4},
110 {as: AADDIS, a1: C_ADDCON, a6: C_REG, type_: 20, size: 4},
111 {as: AADDC, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4},
112 {as: AADDC, a1: C_REG, a6: C_REG, type_: 2, size: 4},
113 {as: AADDC, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
114 {as: AADDC, a1: C_ADDCON, a6: C_REG, type_: 4, size: 4},
115 {as: AADDC, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 22, size: 12},
116 {as: AADDC, a1: C_LCON, a6: C_REG, type_: 22, size: 12},
117 {as: AAND, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4}, /* logical, no literal */
118 {as: AAND, a1: C_REG, a6: C_REG, type_: 6, size: 4},
119 {as: AANDCC, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
120 {as: AANDCC, a1: C_REG, a6: C_REG, type_: 6, size: 4},
121 {as: AANDCC, a1: C_ANDCON, a6: C_REG, type_: 58, size: 4},
122 {as: AANDCC, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 58, size: 4},
123 {as: AANDCC, a1: C_UCON, a6: C_REG, type_: 59, size: 4},
124 {as: AANDCC, a1: C_UCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
125 {as: AANDCC, a1: C_ADDCON, a6: C_REG, type_: 23, size: 8},
126 {as: AANDCC, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 23, size: 8},
127 {as: AANDCC, a1: C_LCON, a6: C_REG, type_: 23, size: 12},
128 {as: AANDCC, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 23, size: 12},
129 {as: AANDISCC, a1: C_ANDCON, a6: C_REG, type_: 59, size: 4},
130 {as: AANDISCC, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
131 {as: AMULLW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4},
132 {as: AMULLW, a1: C_REG, a6: C_REG, type_: 2, size: 4},
133 {as: AMULLW, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
134 {as: AMULLW, a1: C_ADDCON, a6: C_REG, type_: 4, size: 4},
135 {as: AMULLW, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 4, size: 4},
136 {as: AMULLW, a1: C_ANDCON, a6: C_REG, type_: 4, size: 4},
137 {as: AMULLW, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 22, size: 12},
138 {as: AMULLW, a1: C_LCON, a6: C_REG, type_: 22, size: 12},
139 {as: ASUBC, a1: C_REG, a2: C_REG, a6: C_REG, type_: 10, size: 4},
140 {as: ASUBC, a1: C_REG, a6: C_REG, type_: 10, size: 4},
141 {as: ASUBC, a1: C_REG, a3: C_ADDCON, a6: C_REG, type_: 27, size: 4},
142 {as: ASUBC, a1: C_REG, a3: C_LCON, a6: C_REG, type_: 28, size: 12},
143 {as: AOR, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4}, /* logical, literal not cc (or/xor) */
144 {as: AOR, a1: C_REG, a6: C_REG, type_: 6, size: 4},
145 {as: AOR, a1: C_ANDCON, a6: C_REG, type_: 58, size: 4},
146 {as: AOR, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 58, size: 4},
147 {as: AOR, a1: C_UCON, a6: C_REG, type_: 59, size: 4},
148 {as: AOR, a1: C_UCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
149 {as: AOR, a1: C_ADDCON, a6: C_REG, type_: 23, size: 8},
150 {as: AOR, a1: C_ADDCON, a2: C_REG, a6: C_REG, type_: 23, size: 8},
151 {as: AOR, a1: C_LCON, a6: C_REG, type_: 23, size: 12},
152 {as: AOR, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 23, size: 12},
153 {as: AORIS, a1: C_ANDCON, a6: C_REG, type_: 59, size: 4},
154 {as: AORIS, a1: C_ANDCON, a2: C_REG, a6: C_REG, type_: 59, size: 4},
155 {as: ADIVW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 2, size: 4}, /* op r1[,r2],r3 */
156 {as: ADIVW, a1: C_REG, a6: C_REG, type_: 2, size: 4},
157 {as: ASUB, a1: C_REG, a2: C_REG, a6: C_REG, type_: 10, size: 4}, /* op r2[,r1],r3 */
158 {as: ASUB, a1: C_REG, a6: C_REG, type_: 10, size: 4},
159 {as: ASLW, a1: C_REG, a6: C_REG, type_: 6, size: 4},
160 {as: ASLW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
161 {as: ASLD, a1: C_REG, a6: C_REG, type_: 6, size: 4},
162 {as: ASLD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
163 {as: ASLD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 25, size: 4},
164 {as: ASLD, a1: C_SCON, a6: C_REG, type_: 25, size: 4},
165 {as: AEXTSWSLI, a1: C_SCON, a6: C_REG, type_: 25, size: 4},
166 {as: AEXTSWSLI, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 25, size: 4},
167 {as: ASLW, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 57, size: 4},
168 {as: ASLW, a1: C_SCON, a6: C_REG, type_: 57, size: 4},
169 {as: ASRAW, a1: C_REG, a6: C_REG, type_: 6, size: 4},
170 {as: ASRAW, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
171 {as: ASRAW, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 56, size: 4},
172 {as: ASRAW, a1: C_SCON, a6: C_REG, type_: 56, size: 4},
173 {as: ASRAD, a1: C_REG, a6: C_REG, type_: 6, size: 4},
174 {as: ASRAD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 6, size: 4},
175 {as: ASRAD, a1: C_SCON, a2: C_REG, a6: C_REG, type_: 56, size: 4},
176 {as: ASRAD, a1: C_SCON, a6: C_REG, type_: 56, size: 4},
177 {as: ARLWMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
178 {as: ARLWMI, a1: C_SCON, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 102, size: 4},
179 {as: ARLWMI, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 63, size: 4},
180 {as: ARLWMI, a1: C_REG, a2: C_REG, a3: C_SCON, a4: C_SCON, a6: C_REG, type_: 103, size: 4},
181 {as: ACLRLSLWI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
182 {as: ARLDMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 30, size: 4},
183 {as: ARLDC, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
184 {as: ARLDCL, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
185 {as: ARLDCL, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
186 {as: ARLDICL, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
187 {as: ARLDICL, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
188 {as: ARLDCL, a1: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
189 {as: AFADD, a1: C_FREG, a6: C_FREG, type_: 2, size: 4},
190 {as: AFADD, a1: C_FREG, a2: C_FREG, a6: C_FREG, type_: 2, size: 4},
191 {as: AFABS, a1: C_FREG, a6: C_FREG, type_: 33, size: 4},
192 {as: AFABS, a6: C_FREG, type_: 33, size: 4},
193 {as: AFMADD, a1: C_FREG, a2: C_FREG, a3: C_FREG, a6: C_FREG, type_: 34, size: 4},
194 {as: AFMUL, a1: C_FREG, a6: C_FREG, type_: 32, size: 4},
195 {as: AFMUL, a1: C_FREG, a2: C_FREG, a6: C_FREG, type_: 32, size: 4},
197 {as: AMOVBU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
198 {as: AMOVBU, a1: C_SOREG, a6: C_REG, type_: 9, size: 8},
200 {as: AMOVBZU, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
201 {as: AMOVBZU, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
203 {as: AMOVHBR, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
204 {as: AMOVHBR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
206 {as: AMOVB, a1: C_ADDR, a6: C_REG, type_: 76, size: 12},
207 {as: AMOVB, a1: C_LOREG, a6: C_REG, type_: 37, size: 12},
208 {as: AMOVB, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
209 {as: AMOVB, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
210 {as: AMOVB, a1: C_REG, a6: C_REG, type_: 12, size: 4},
211 {as: AMOVB, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
212 {as: AMOVB, a1: C_SOREG, a6: C_REG, type_: 9, size: 8},
214 {as: AMOVBZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
215 {as: AMOVBZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
216 {as: AMOVBZ, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
217 {as: AMOVBZ, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
218 {as: AMOVBZ, a1: C_REG, a6: C_REG, type_: 13, size: 4},
219 {as: AMOVBZ, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
220 {as: AMOVBZ, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
222 {as: AMOVD, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
223 {as: AMOVD, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
224 {as: AMOVD, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
225 {as: AMOVD, a1: C_CTR, a6: C_REG, type_: 66, size: 4},
226 {as: AMOVD, a1: C_GOTADDR, a6: C_REG, type_: 81, size: 8},
227 {as: AMOVD, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
228 {as: AMOVD, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
229 {as: AMOVD, a1: C_LECON, a6: C_REG, type_: 26, size: 8},
230 {as: AMOVD, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
231 {as: AMOVD, a1: C_LR, a6: C_REG, type_: 66, size: 4},
232 {as: AMOVD, a1: C_MSR, a6: C_REG, type_: 54, size: 4}, /* mfmsr */
233 {as: AMOVD, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
234 {as: AMOVD, a1: C_REG, a6: C_CTR, type_: 66, size: 4},
235 {as: AMOVD, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
236 {as: AMOVD, a1: C_REG, a6: C_LR, type_: 66, size: 4},
237 {as: AMOVD, a1: C_REG, a6: C_MSR, type_: 54, size: 4}, /* mtmsrd */
238 {as: AMOVD, a1: C_REG, a6: C_REG, type_: 1, size: 4},
239 {as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
240 {as: AMOVD, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
241 {as: AMOVD, a1: C_REG, a6: C_XER, type_: 66, size: 4},
242 {as: AMOVD, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
243 {as: AMOVD, a1: C_SECON, a6: C_REG, type_: 3, size: 4},
244 {as: AMOVD, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
245 {as: AMOVD, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
246 {as: AMOVD, a1: C_TLS_IE, a6: C_REG, type_: 80, size: 8},
247 {as: AMOVD, a1: C_TLS_LE, a6: C_REG, type_: 79, size: 4},
248 {as: AMOVD, a1: C_TOCADDR, a6: C_REG, type_: 95, size: 8},
249 {as: AMOVD, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
250 {as: AMOVD, a1: C_XER, a6: C_REG, type_: 66, size: 4},
252 {as: AMOVW, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
253 {as: AMOVW, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
254 {as: AMOVW, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
255 {as: AMOVW, a1: C_CREG, a6: C_REG, type_: 68, size: 4},
256 {as: AMOVW, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
257 {as: AMOVW, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
258 {as: AMOVW, a1: C_LECON, a6: C_REG, type_: 26, size: 8},
259 {as: AMOVW, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
260 {as: AMOVW, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
261 {as: AMOVW, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
262 {as: AMOVW, a1: C_REG, a6: C_CTR, type_: 66, size: 4},
263 {as: AMOVW, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
264 {as: AMOVW, a1: C_REG, a6: C_REG, type_: 12, size: 4},
265 {as: AMOVW, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
266 {as: AMOVW, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
267 {as: AMOVW, a1: C_REG, a6: C_XER, type_: 66, size: 4},
268 {as: AMOVW, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
269 {as: AMOVW, a1: C_SECON, a6: C_REG, type_: 3, size: 4}, /* TO DO: check */
270 {as: AMOVW, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
271 {as: AMOVW, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
272 {as: AMOVW, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
273 {as: AMOVW, a1: C_XER, a6: C_REG, type_: 66, size: 4},
275 {as: AMOVWZ, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
276 {as: AMOVWZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
277 {as: AMOVWZ, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
278 {as: AMOVWZ, a1: C_CREG, a6: C_REG, type_: 68, size: 4},
279 {as: AMOVWZ, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
280 {as: AMOVWZ, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
281 {as: AMOVWZ, a1: C_LECON, a6: C_REG, type_: 26, size: 8},
282 {as: AMOVWZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
283 {as: AMOVWZ, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
284 {as: AMOVWZ, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
285 {as: AMOVWZ, a1: C_REG, a6: C_CTR, type_: 66, size: 4},
286 {as: AMOVWZ, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
287 {as: AMOVWZ, a1: C_REG, a6: C_MSR, type_: 54, size: 4}, /* mtmsr */
288 {as: AMOVWZ, a1: C_REG, a6: C_REG, type_: 13, size: 4},
289 {as: AMOVWZ, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
290 {as: AMOVWZ, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
291 {as: AMOVWZ, a1: C_REG, a6: C_XER, type_: 66, size: 4},
292 {as: AMOVWZ, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
293 {as: AMOVWZ, a1: C_SECON, a6: C_REG, type_: 3, size: 4}, /* TO DO: check */
294 {as: AMOVWZ, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
295 {as: AMOVWZ, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
296 {as: AMOVWZ, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
297 {as: AMOVWZ, a1: C_XER, a6: C_REG, type_: 66, size: 4},
299 {as: AMOVFL, a1: C_CREG, a6: C_CREG, type_: 67, size: 4},
300 {as: AMOVFL, a1: C_FPSCR, a6: C_CREG, type_: 73, size: 4},
301 {as: AMOVFL, a1: C_FPSCR, a6: C_FREG, type_: 53, size: 4},
302 {as: AMOVFL, a1: C_FREG, a3: C_LCON, a6: C_FPSCR, type_: 64, size: 4},
303 {as: AMOVFL, a1: C_FREG, a6: C_FPSCR, type_: 64, size: 4},
304 {as: AMOVFL, a1: C_LCON, a6: C_FPSCR, type_: 65, size: 4},
305 {as: AMOVFL, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
306 {as: AMOVFL, a1: C_REG, a6: C_LCON, type_: 69, size: 4},
308 {as: ASYSCALL, type_: 5, size: 4},
309 {as: ASYSCALL, a1: C_REG, type_: 77, size: 12},
310 {as: ASYSCALL, a1: C_SCON, type_: 77, size: 12},
311 {as: ABEQ, a6: C_SBRA, type_: 16, size: 4},
312 {as: ABEQ, a1: C_CREG, a6: C_SBRA, type_: 16, size: 4},
313 {as: ABR, a6: C_LBRA, type_: 11, size: 4},
314 {as: ABR, a6: C_LBRAPIC, type_: 11, size: 8},
315 {as: ABC, a1: C_SCON, a2: C_REG, a6: C_SBRA, type_: 16, size: 4},
316 {as: ABC, a1: C_SCON, a2: C_REG, a6: C_LBRA, type_: 17, size: 4},
317 {as: ABR, a6: C_LR, type_: 18, size: 4},
318 {as: ABR, a3: C_SCON, a6: C_LR, type_: 18, size: 4},
319 {as: ABR, a6: C_CTR, type_: 18, size: 4},
320 {as: ABR, a1: C_REG, a6: C_CTR, type_: 18, size: 4},
321 {as: ABR, a6: C_ZOREG, type_: 15, size: 8},
322 {as: ABC, a2: C_REG, a6: C_LR, type_: 18, size: 4},
323 {as: ABC, a2: C_REG, a6: C_CTR, type_: 18, size: 4},
324 {as: ABC, a1: C_SCON, a2: C_REG, a6: C_LR, type_: 18, size: 4},
325 {as: ABC, a1: C_SCON, a2: C_REG, a6: C_CTR, type_: 18, size: 4},
326 {as: ABC, a6: C_ZOREG, type_: 15, size: 8},
327 {as: AFMOVD, a1: C_FREG, a6: C_FREG, type_: 33, size: 4},
328 {as: AFMOVD, a1: C_SOREG, a6: C_FREG, type_: 8, size: 4},
329 {as: AFMOVD, a1: C_LOREG, a6: C_FREG, type_: 36, size: 8},
330 {as: AFMOVD, a1: C_ZCON, a6: C_FREG, type_: 24, size: 4},
331 {as: AFMOVD, a1: C_ADDCON, a6: C_FREG, type_: 24, size: 8},
332 {as: AFMOVD, a1: C_ADDR, a6: C_FREG, type_: 75, size: 8},
333 {as: AFMOVD, a1: C_FREG, a6: C_SOREG, type_: 7, size: 4},
334 {as: AFMOVD, a1: C_FREG, a6: C_LOREG, type_: 35, size: 8},
335 {as: AFMOVD, a1: C_FREG, a6: C_ADDR, type_: 74, size: 8},
336 {as: AFMOVSX, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
337 {as: AFMOVSX, a1: C_FREG, a6: C_ZOREG, type_: 44, size: 4},
338 {as: AFMOVSZ, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
339 {as: ASYNC, type_: 46, size: 4},
340 {as: AWORD, a1: C_LCON, type_: 40, size: 4},
341 {as: ADWORD, a1: C_LCON, type_: 31, size: 8},
342 {as: ADWORD, a1: C_DCON, type_: 31, size: 8},
343 {as: AADDME, a1: C_REG, a6: C_REG, type_: 47, size: 4},
344 {as: AEXTSB, a1: C_REG, a6: C_REG, type_: 48, size: 4},
345 {as: AEXTSB, a6: C_REG, type_: 48, size: 4},
346 {as: AISEL, a1: C_LCON, a2: C_REG, a3: C_REG, a6: C_REG, type_: 84, size: 4},
347 {as: AISEL, a1: C_ZCON, a2: C_REG, a3: C_REG, a6: C_REG, type_: 84, size: 4},
348 {as: ANEG, a1: C_REG, a6: C_REG, type_: 47, size: 4},
349 {as: ANEG, a6: C_REG, type_: 47, size: 4},
350 {as: AREM, a1: C_REG, a6: C_REG, type_: 50, size: 12},
351 {as: AREM, a1: C_REG, a2: C_REG, a6: C_REG, type_: 50, size: 12},
352 {as: AREMU, a1: C_REG, a6: C_REG, type_: 50, size: 16},
353 {as: AREMU, a1: C_REG, a2: C_REG, a6: C_REG, type_: 50, size: 16},
354 {as: AREMD, a1: C_REG, a6: C_REG, type_: 51, size: 12},
355 {as: AREMD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 51, size: 12},
356 {as: AMTFSB0, a1: C_SCON, type_: 52, size: 4},
357 /* Other ISA 2.05+ instructions */
358 {as: APOPCNTD, a1: C_REG, a6: C_REG, type_: 93, size: 4}, /* population count, x-form */
359 {as: ACMPB, a1: C_REG, a2: C_REG, a6: C_REG, type_: 92, size: 4}, /* compare byte, x-form */
360 {as: ACMPEQB, a1: C_REG, a2: C_REG, a6: C_CREG, type_: 92, size: 4}, /* compare equal byte, x-form, ISA 3.0 */
361 {as: ACMPEQB, a1: C_REG, a6: C_REG, type_: 70, size: 4},
362 {as: AFTDIV, a1: C_FREG, a2: C_FREG, a6: C_SCON, type_: 92, size: 4}, /* floating test for sw divide, x-form */
363 {as: AFTSQRT, a1: C_FREG, a6: C_SCON, type_: 93, size: 4}, /* floating test for sw square root, x-form */
364 {as: ACOPY, a1: C_REG, a6: C_REG, type_: 92, size: 4}, /* copy/paste facility, x-form */
365 {as: ADARN, a1: C_SCON, a6: C_REG, type_: 92, size: 4}, /* deliver random number, x-form */
366 {as: ALDMX, a1: C_SOREG, a6: C_REG, type_: 45, size: 4}, /* load doubleword monitored, x-form */
367 {as: AMADDHD, a1: C_REG, a2: C_REG, a3: C_REG, a6: C_REG, type_: 83, size: 4}, /* multiply-add high/low doubleword, va-form */
368 {as: AADDEX, a1: C_REG, a2: C_REG, a3: C_SCON, a6: C_REG, type_: 94, size: 4}, /* add extended using alternate carry, z23-form */
369 {as: ACRAND, a1: C_CREG, a6: C_CREG, type_: 2, size: 4}, /* logical ops for condition registers xl-form */
371 /* Vector instructions */
374 {as: ALV, a1: C_SOREG, a6: C_VREG, type_: 45, size: 4}, /* vector load, x-form */
377 {as: ASTV, a1: C_VREG, a6: C_SOREG, type_: 44, size: 4}, /* vector store, x-form */
380 {as: AVAND, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector and, vx-form */
381 {as: AVOR, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector or, vx-form */
384 {as: AVADDUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector add unsigned modulo, vx-form */
385 {as: AVADDCU, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector add & write carry unsigned, vx-form */
386 {as: AVADDUS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector add unsigned saturate, vx-form */
387 {as: AVADDSS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector add signed saturate, vx-form */
388 {as: AVADDE, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector add extended, va-form */
390 /* Vector subtract */
391 {as: AVSUBUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector subtract unsigned modulo, vx-form */
392 {as: AVSUBCU, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector subtract & write carry unsigned, vx-form */
393 {as: AVSUBUS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector subtract unsigned saturate, vx-form */
394 {as: AVSUBSS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector subtract signed saturate, vx-form */
395 {as: AVSUBE, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector subtract extended, va-form */
397 /* Vector multiply */
398 {as: AVMULESB, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector multiply, vx-form */
399 {as: AVPMSUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector polynomial multiply & sum, vx-form */
400 {as: AVMSUMUDM, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector multiply-sum, va-form */
403 {as: AVR, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector rotate, vx-form */
406 {as: AVS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector shift, vx-form */
407 {as: AVSA, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector shift algebraic, vx-form */
408 {as: AVSOI, a1: C_ANDCON, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector shift by octet immediate, va-form */
411 {as: AVCLZ, a1: C_VREG, a6: C_VREG, type_: 85, size: 4}, /* vector count leading zeros, vx-form */
412 {as: AVPOPCNT, a1: C_VREG, a6: C_VREG, type_: 85, size: 4}, /* vector population count, vx-form */
415 {as: AVCMPEQ, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector compare equal, vc-form */
416 {as: AVCMPGT, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector compare greater than, vc-form */
417 {as: AVCMPNEZB, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector compare not equal, vx-form */
420 {as: AVMRGOW, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector merge odd word, vx-form */
423 {as: AVPERM, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector permute, va-form */
425 /* Vector bit permute */
426 {as: AVBPERMQ, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector bit permute, vx-form */
429 {as: AVSEL, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector select, va-form */
432 {as: AVSPLTB, a1: C_SCON, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector splat, vx-form */
433 {as: AVSPLTB, a1: C_ADDCON, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},
434 {as: AVSPLTISB, a1: C_SCON, a6: C_VREG, type_: 82, size: 4}, /* vector splat immediate, vx-form */
435 {as: AVSPLTISB, a1: C_ADDCON, a6: C_VREG, type_: 82, size: 4},
438 {as: AVCIPH, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector AES cipher, vx-form */
439 {as: AVNCIPH, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector AES inverse cipher, vx-form */
440 {as: AVSBOX, a1: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector AES subbytes, vx-form */
443 {as: AVSHASIGMA, a1: C_ANDCON, a2: C_VREG, a3: C_ANDCON, a6: C_VREG, type_: 82, size: 4}, /* vector SHA sigma, vx-form */
445 /* VSX vector load */
446 {as: ALXVD2X, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx vector load, xx1-form */
447 {as: ALXV, a1: C_SOREG, a6: C_VSREG, type_: 96, size: 4}, /* vsx vector load, dq-form */
448 {as: ALXVL, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 98, size: 4}, /* vsx vector load length */
450 /* VSX vector store */
451 {as: ASTXVD2X, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx vector store, xx1-form */
452 {as: ASTXV, a1: C_VSREG, a6: C_SOREG, type_: 97, size: 4}, /* vsx vector store, dq-form */
453 {as: ASTXVL, a1: C_VSREG, a2: C_REG, a6: C_REG, type_: 99, size: 4}, /* vsx vector store with length x-form */
455 /* VSX scalar load */
456 {as: ALXSDX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar load, xx1-form */
458 /* VSX scalar store */
459 {as: ASTXSDX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar store, xx1-form */
461 /* VSX scalar as integer load */
462 {as: ALXSIWAX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar as integer load, xx1-form */
464 /* VSX scalar store as integer */
465 {as: ASTXSIWX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */
467 /* VSX move from VSR */
468 {as: AMFVSRD, a1: C_VSREG, a6: C_REG, type_: 88, size: 4}, /* vsx move from vsr, xx1-form */
469 {as: AMFVSRD, a1: C_FREG, a6: C_REG, type_: 88, size: 4},
470 {as: AMFVSRD, a1: C_VREG, a6: C_REG, type_: 88, size: 4},
472 /* VSX move to VSR */
473 {as: AMTVSRD, a1: C_REG, a6: C_VSREG, type_: 88, size: 4}, /* vsx move to vsr, xx1-form */
474 {as: AMTVSRD, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 88, size: 4},
475 {as: AMTVSRD, a1: C_REG, a6: C_FREG, type_: 88, size: 4},
476 {as: AMTVSRD, a1: C_REG, a6: C_VREG, type_: 88, size: 4},
479 {as: AXXLAND, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx and, xx3-form */
480 {as: AXXLOR, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx or, xx3-form */
483 {as: AXXSEL, a1: C_VSREG, a2: C_VSREG, a3: C_VSREG, a6: C_VSREG, type_: 91, size: 4}, /* vsx select, xx4-form */
486 {as: AXXMRGHW, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx merge, xx3-form */
489 {as: AXXSPLTW, a1: C_VSREG, a3: C_SCON, a6: C_VSREG, type_: 89, size: 4}, /* vsx splat, xx2-form */
490 {as: AXXSPLTIB, a1: C_SCON, a6: C_VSREG, type_: 100, size: 4}, /* vsx splat, xx2-form */
493 {as: AXXPERM, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx permute, xx3-form */
496 {as: AXXSLDWI, a1: C_VSREG, a2: C_VSREG, a3: C_SCON, a6: C_VSREG, type_: 90, size: 4}, /* vsx shift immediate, xx3-form */
498 /* VSX reverse bytes */
499 {as: AXXBRQ, a1: C_VSREG, a6: C_VSREG, type_: 101, size: 4}, /* vsx reverse bytes */
501 /* VSX scalar FP-FP conversion */
502 {as: AXSCVDPSP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar fp-fp conversion, xx2-form */
504 /* VSX vector FP-FP conversion */
505 {as: AXVCVDPSP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector fp-fp conversion, xx2-form */
507 /* VSX scalar FP-integer conversion */
508 {as: AXSCVDPSXDS, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar fp-integer conversion, xx2-form */
510 /* VSX scalar integer-FP conversion */
511 {as: AXSCVSXDDP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar integer-fp conversion, xx2-form */
513 /* VSX vector FP-integer conversion */
514 {as: AXVCVDPSXDS, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector fp-integer conversion, xx2-form */
516 /* VSX vector integer-FP conversion */
517 {as: AXVCVSXDDP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector integer-fp conversion, xx2-form */
519 {as: ACMP, a1: C_REG, a6: C_REG, type_: 70, size: 4},
520 {as: ACMP, a1: C_REG, a2: C_REG, a6: C_REG, type_: 70, size: 4},
521 {as: ACMP, a1: C_REG, a6: C_ADDCON, type_: 71, size: 4},
522 {as: ACMP, a1: C_REG, a2: C_REG, a6: C_ADDCON, type_: 71, size: 4},
523 {as: ACMPU, a1: C_REG, a6: C_REG, type_: 70, size: 4},
524 {as: ACMPU, a1: C_REG, a2: C_REG, a6: C_REG, type_: 70, size: 4},
525 {as: ACMPU, a1: C_REG, a6: C_ANDCON, type_: 71, size: 4},
526 {as: ACMPU, a1: C_REG, a2: C_REG, a6: C_ANDCON, type_: 71, size: 4},
527 {as: AFCMPO, a1: C_FREG, a6: C_FREG, type_: 70, size: 4},
528 {as: AFCMPO, a1: C_FREG, a2: C_REG, a6: C_FREG, type_: 70, size: 4},
529 {as: ATW, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 60, size: 4},
530 {as: ATW, a1: C_LCON, a2: C_REG, a6: C_ADDCON, type_: 61, size: 4},
531 {as: ADCBF, a1: C_ZOREG, type_: 43, size: 4},
532 {as: ADCBF, a1: C_SOREG, type_: 43, size: 4},
533 {as: ADCBF, a1: C_ZOREG, a2: C_REG, a6: C_SCON, type_: 43, size: 4},
534 {as: ADCBF, a1: C_SOREG, a6: C_SCON, type_: 43, size: 4},
535 {as: AECOWX, a1: C_REG, a2: C_REG, a6: C_ZOREG, type_: 44, size: 4},
536 {as: AECIWX, a1: C_ZOREG, a2: C_REG, a6: C_REG, type_: 45, size: 4},
537 {as: AECOWX, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
538 {as: AECIWX, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
539 {as: ALDAR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
540 {as: ALDAR, a1: C_ZOREG, a3: C_ANDCON, a6: C_REG, type_: 45, size: 4},
541 {as: AEIEIO, type_: 46, size: 4},
542 {as: ATLBIE, a1: C_REG, type_: 49, size: 4},
543 {as: ATLBIE, a1: C_SCON, a6: C_REG, type_: 49, size: 4},
544 {as: ASLBMFEE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
545 {as: ASLBMTE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
546 {as: ASTSW, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
547 {as: ASTSW, a1: C_REG, a3: C_LCON, a6: C_ZOREG, type_: 41, size: 4},
548 {as: ALSW, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
549 {as: ALSW, a1: C_ZOREG, a3: C_LCON, a6: C_REG, type_: 42, size: 4},
550 {as: obj.AUNDEF, type_: 78, size: 4},
551 {as: obj.APCDATA, a1: C_LCON, a6: C_LCON, type_: 0, size: 0},
552 {as: obj.AFUNCDATA, a1: C_SCON, a6: C_ADDR, type_: 0, size: 0},
553 {as: obj.ANOP, type_: 0, size: 0},
554 {as: obj.ANOP, a1: C_LCON, type_: 0, size: 0}, // NOP operand variations added for #40689
555 {as: obj.ANOP, a1: C_REG, type_: 0, size: 0}, // to preserve previous behavior
556 {as: obj.ANOP, a1: C_FREG, type_: 0, size: 0},
557 {as: obj.ADUFFZERO, a6: C_LBRA, type_: 11, size: 4}, // same as ABR/ABL
558 {as: obj.ADUFFCOPY, a6: C_LBRA, type_: 11, size: 4}, // same as ABR/ABL
559 {as: obj.APCALIGN, a1: C_LCON, type_: 0, size: 0}, // align code
561 {as: obj.AXXX, type_: 0, size: 4},
564 var oprange [ALAST & obj.AMask][]Optab
566 var xcmp [C_NCLASS][C_NCLASS]bool
568 // padding bytes to add to align code as requested
569 func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int {
570 // For 16 and 32 byte alignment, there is a tradeoff
571 // between aligning the code and adding too many NOPs.
578 // Align to 16 bytes if possible but add at
587 // Align to 32 bytes if possible but add at
597 // When 32 byte alignment is requested on Linux,
598 // promote the function's alignment to 32. On AIX
599 // the function alignment is not changed which might
600 // result in 16 byte alignment but that is still fine.
601 // TODO: alignment on AIX
602 if ctxt.Headtype != objabi.Haix && cursym.Func().Align < 32 {
603 cursym.Func().Align = 32
606 ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a)
611 // Get the implied register of a operand which doesn't specify one. These show up
612 // in handwritten asm like "MOVD R5, foosymbol" where a base register is not supplied,
613 // or "MOVD R5, foo+10(SP) or pseudo-register is used. The other common case is when
614 // generating constants in register like "MOVD $constant, Rx".
615 func (c *ctxt9) getimpliedreg(a *obj.Addr, p *obj.Prog) int {
617 case C_ADDCON, C_ANDCON, C_UCON, C_LCON, C_SCON, C_ZCON:
619 case C_SECON, C_LECON:
621 case C_SACON, C_LACON:
623 case C_LOREG, C_SOREG, C_ZOREG:
625 case obj.NAME_EXTERN, obj.NAME_STATIC:
627 case obj.NAME_AUTO, obj.NAME_PARAM:
633 c.ctxt.Diag("failed to determine implied reg for class %v (%v)", DRconv(oclass(a)), p)
637 func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
638 p := cursym.Func().Text
639 if p == nil || p.Link == nil { // handle external functions and ELF section symbols
643 if oprange[AANDN&obj.AMask] == nil {
644 ctxt.Diag("ppc64 ops not initialized, call ppc64.buildop first")
647 c := ctxt9{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset)}
654 for p = p.Link; p != nil; p = p.Link {
659 if p.As == obj.APCALIGN {
660 a := c.vregoff(&p.From)
661 m = addpad(pc, a, ctxt, cursym)
663 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
664 ctxt.Diag("zero-width instruction\n%v", p)
675 * if any procedure is large enough to
676 * generate a large SBRA branch, then
677 * generate extra passes putting branches
678 * around jmps to fix. this is rare.
687 for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
691 // very large conditional branches
692 if (o.type_ == 16 || o.type_ == 17) && p.To.Target() != nil {
693 otxt = p.To.Target().Pc - pc
694 if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
699 q.To.Type = obj.TYPE_BRANCH
700 q.To.SetTarget(p.To.Target())
706 q.To.Type = obj.TYPE_BRANCH
707 q.To.SetTarget(q.Link.Link)
717 if p.As == obj.APCALIGN {
718 a := c.vregoff(&p.From)
719 m = addpad(pc, a, ctxt, cursym)
721 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
722 ctxt.Diag("zero-width instruction\n%v", p)
734 if r := pc & funcAlignMask; r != 0 {
741 * lay out the code, emitting code and data relocations.
744 c.cursym.Grow(c.cursym.Size)
749 for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
752 if int(o.size) > 4*len(out) {
753 log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)
755 // asmout is not set up to add large amounts of padding
756 if o.type_ == 0 && p.As == obj.APCALIGN {
757 pad := LOP_RRR(OP_OR, REGZERO, REGZERO, REGZERO)
758 aln := c.vregoff(&p.From)
759 v := addpad(p.Pc, aln, c.ctxt, c.cursym)
761 // Same padding instruction for all
762 for i = 0; i < int32(v/4); i++ {
763 c.ctxt.Arch.ByteOrder.PutUint32(bp, pad)
768 c.asmout(p, o, out[:])
769 for i = 0; i < int32(o.size/4); i++ {
770 c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
777 func isint32(v int64) bool {
778 return int64(int32(v)) == v
781 func isuint32(v uint64) bool {
782 return uint64(uint32(v)) == v
785 func (c *ctxt9) aclass(a *obj.Addr) int {
791 if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
794 if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
797 if REG_V0 <= a.Reg && a.Reg <= REG_V31 {
800 if REG_VS0 <= a.Reg && a.Reg <= REG_VS63 {
803 if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR {
806 if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
821 if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
824 if a.Reg == REG_FPSCR {
827 if a.Reg == REG_MSR {
834 case obj.NAME_EXTERN,
839 c.instoffset = a.Offset
840 if a.Sym != nil { // use relocation
841 if a.Sym.Type == objabi.STLSBSS {
842 if c.ctxt.Flag_shared {
852 case obj.NAME_GOTREF:
855 case obj.NAME_TOCREF:
859 c.instoffset = int64(c.autosize) + a.Offset
860 if c.instoffset >= -BIG && c.instoffset < BIG {
866 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
867 if c.instoffset >= -BIG && c.instoffset < BIG {
873 c.instoffset = a.Offset
874 if c.instoffset == 0 {
877 if c.instoffset >= -BIG && c.instoffset < BIG {
885 case obj.TYPE_TEXTSIZE:
888 case obj.TYPE_FCONST:
889 // The only cases where FCONST will occur are with float64 +/- 0.
890 // All other float constants are generated in memory.
891 f64 := a.Val.(float64)
893 if math.Signbit(f64) {
898 log.Fatalf("Unexpected nonzero FCONST operand %v", a)
904 c.instoffset = a.Offset
906 if -BIG <= c.instoffset && c.instoffset <= BIG {
909 if isint32(c.instoffset) {
915 case obj.NAME_EXTERN,
922 c.instoffset = a.Offset
924 /* not sure why this barfs */
928 c.instoffset = int64(c.autosize) + a.Offset
929 if c.instoffset >= -BIG && c.instoffset < BIG {
935 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
936 if c.instoffset >= -BIG && c.instoffset < BIG {
945 if c.instoffset >= 0 {
946 if c.instoffset == 0 {
949 if c.instoffset <= 0x7fff {
952 if c.instoffset <= 0xffff {
955 if c.instoffset&0xffff == 0 && isuint32(uint64(c.instoffset)) { /* && (instoffset & (1<<31)) == 0) */
958 if isint32(c.instoffset) || isuint32(uint64(c.instoffset)) {
964 if c.instoffset >= -0x8000 {
967 if c.instoffset&0xffff == 0 && isint32(c.instoffset) {
970 if isint32(c.instoffset) {
975 case obj.TYPE_BRANCH:
976 if a.Sym != nil && c.ctxt.Flag_dynlink {
985 func prasm(p *obj.Prog) {
986 fmt.Printf("%v\n", p)
989 func (c *ctxt9) oplook(p *obj.Prog) *Optab {
994 a1 = int(p.From.Class)
996 a1 = c.aclass(&p.From) + 1
997 p.From.Class = int8(a1)
1001 argsv := [3]int{C_NONE + 1, C_NONE + 1, C_NONE + 1}
1002 for i, ap := range p.RestArgs {
1003 argsv[i] = int(ap.Addr.Class)
1005 argsv[i] = c.aclass(&ap.Addr) + 1
1006 ap.Addr.Class = int8(argsv[i])
1014 a6 := int(p.To.Class)
1016 a6 = c.aclass(&p.To) + 1
1017 p.To.Class = int8(a6)
1023 if REG_R0 <= p.Reg && p.Reg <= REG_R31 {
1025 } else if REG_V0 <= p.Reg && p.Reg <= REG_V31 {
1027 } else if REG_VS0 <= p.Reg && p.Reg <= REG_VS63 {
1029 } else if REG_F0 <= p.Reg && p.Reg <= REG_F31 {
1034 // c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4, a5, a6)
1035 ops := oprange[p.As&obj.AMask]
1041 for i := range ops {
1043 if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] && c5[op.a5] && c6[op.a6] {
1044 p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
1049 c.ctxt.Diag("illegal combination %v %v %v %v %v %v %v", p.As, DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4), DRconv(a5), DRconv(a6))
1057 func cmp(a int, b int) bool {
1063 if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {
1068 if b == C_ZCON || b == C_SCON {
1073 if b == C_ZCON || b == C_SCON {
1078 if b == C_LR || b == C_XER || b == C_CTR {
1108 if b == C_SOREG || b == C_ZOREG {
1114 return r0iszero != 0 /*TypeKind(100016)*/
1126 func (x ocmp) Len() int {
1130 func (x ocmp) Swap(i, j int) {
1131 x[i], x[j] = x[j], x[i]
1134 // Used when sorting the optab. Sorting is
1135 // done in a way so that the best choice of
1136 // opcode/operand combination is considered first.
1137 func (x ocmp) Less(i, j int) bool {
1140 n := int(p1.as) - int(p2.as)
1145 // Consider those that generate fewer
1146 // instructions first.
1147 n = int(p1.size) - int(p2.size)
1151 // operand order should match
1152 // better choices first
1153 n = int(p1.a1) - int(p2.a1)
1157 n = int(p1.a2) - int(p2.a2)
1161 n = int(p1.a3) - int(p2.a3)
1165 n = int(p1.a4) - int(p2.a4)
1169 n = int(p1.a5) - int(p2.a5)
1173 n = int(p1.a6) - int(p2.a6)
1180 // Add an entry to the opcode table for
1181 // a new opcode b0 with the same operand combinations
1183 func opset(a, b0 obj.As) {
1184 oprange[a&obj.AMask] = oprange[b0]
1187 // Build the opcode table
1188 func buildop(ctxt *obj.Link) {
1189 if oprange[AANDN&obj.AMask] != nil {
1190 // Already initialized; stop now.
1191 // This happens in the cmd/asm tests,
1192 // each of which re-initializes the arch.
1198 for i := 0; i < C_NCLASS; i++ {
1199 for n = 0; n < C_NCLASS; n++ {
1205 for n = 0; optab[n].as != obj.AXXX; n++ {
1207 sort.Sort(ocmp(optab[:n]))
1208 for i := 0; i < n; i++ {
1212 for optab[i].as == r {
1215 oprange[r0] = optab[start:i]
1220 ctxt.Diag("unknown op in build: %v", r)
1221 log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r)
1223 case ADCBF: /* unary indexed: op (b+a); op (b) */
1232 case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
1238 case AREM: /* macro */
1250 case ADIVW: /* op Rb[,Ra],Rd */
1255 opset(AMULHWUCC, r0)
1257 opset(AMULLWVCC, r0)
1265 opset(ADIVWUVCC, r0)
1282 opset(AMULHDUCC, r0)
1284 opset(AMULLDVCC, r0)
1291 opset(ADIVDEUCC, r0)
1296 opset(ADIVDUVCC, r0)
1308 case APOPCNTD: /* popcntd, popcntw, popcntb, cnttzw, cnttzd */
1312 opset(ACNTTZWCC, r0)
1314 opset(ACNTTZDCC, r0)
1316 case ACOPY: /* copy, paste. */
1319 case AMADDHD: /* maddhd, maddhdu, maddld */
1323 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
1327 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
1336 case ALV: /* lvebx, lvehx, lvewx, lvx, lvxl, lvsl, lvsr */
1345 case ASTV: /* stvebx, stvehx, stvewx, stvx, stvxl */
1352 case AVAND: /* vand, vandc, vnand */
1357 case AVMRGOW: /* vmrgew, vmrgow */
1360 case AVOR: /* vor, vorc, vxor, vnor, veqv */
1367 case AVADDUM: /* vaddubm, vadduhm, vadduwm, vaddudm, vadduqm */
1374 case AVADDCU: /* vaddcuq, vaddcuw */
1378 case AVADDUS: /* vaddubs, vadduhs, vadduws */
1383 case AVADDSS: /* vaddsbs, vaddshs, vaddsws */
1388 case AVADDE: /* vaddeuqm, vaddecuq */
1389 opset(AVADDEUQM, r0)
1390 opset(AVADDECUQ, r0)
1392 case AVSUBUM: /* vsububm, vsubuhm, vsubuwm, vsubudm, vsubuqm */
1399 case AVSUBCU: /* vsubcuq, vsubcuw */
1403 case AVSUBUS: /* vsububs, vsubuhs, vsubuws */
1408 case AVSUBSS: /* vsubsbs, vsubshs, vsubsws */
1413 case AVSUBE: /* vsubeuqm, vsubecuq */
1414 opset(AVSUBEUQM, r0)
1415 opset(AVSUBECUQ, r0)
1417 case AVMULESB: /* vmulesb, vmulosb, vmuleub, vmuloub, vmulosh, vmulouh, vmulesw, vmulosw, vmuleuw, vmulouw, vmuluwm */
1430 case AVPMSUM: /* vpmsumb, vpmsumh, vpmsumw, vpmsumd */
1436 case AVR: /* vrlb, vrlh, vrlw, vrld */
1442 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 */
1456 case AVSA: /* vsrab, vsrah, vsraw, vsrad */
1462 case AVSOI: /* vsldoi */
1465 case AVCLZ: /* vclzb, vclzh, vclzw, vclzd */
1471 case AVPOPCNT: /* vpopcntb, vpopcnth, vpopcntw, vpopcntd */
1472 opset(AVPOPCNTB, r0)
1473 opset(AVPOPCNTH, r0)
1474 opset(AVPOPCNTW, r0)
1475 opset(AVPOPCNTD, r0)
1477 case AVCMPEQ: /* vcmpequb[.], vcmpequh[.], vcmpequw[.], vcmpequd[.] */
1478 opset(AVCMPEQUB, r0)
1479 opset(AVCMPEQUBCC, r0)
1480 opset(AVCMPEQUH, r0)
1481 opset(AVCMPEQUHCC, r0)
1482 opset(AVCMPEQUW, r0)
1483 opset(AVCMPEQUWCC, r0)
1484 opset(AVCMPEQUD, r0)
1485 opset(AVCMPEQUDCC, r0)
1487 case AVCMPGT: /* vcmpgt[u,s]b[.], vcmpgt[u,s]h[.], vcmpgt[u,s]w[.], vcmpgt[u,s]d[.] */
1488 opset(AVCMPGTUB, r0)
1489 opset(AVCMPGTUBCC, r0)
1490 opset(AVCMPGTUH, r0)
1491 opset(AVCMPGTUHCC, r0)
1492 opset(AVCMPGTUW, r0)
1493 opset(AVCMPGTUWCC, r0)
1494 opset(AVCMPGTUD, r0)
1495 opset(AVCMPGTUDCC, r0)
1496 opset(AVCMPGTSB, r0)
1497 opset(AVCMPGTSBCC, r0)
1498 opset(AVCMPGTSH, r0)
1499 opset(AVCMPGTSHCC, r0)
1500 opset(AVCMPGTSW, r0)
1501 opset(AVCMPGTSWCC, r0)
1502 opset(AVCMPGTSD, r0)
1503 opset(AVCMPGTSDCC, r0)
1505 case AVCMPNEZB: /* vcmpnezb[.] */
1506 opset(AVCMPNEZBCC, r0)
1508 opset(AVCMPNEBCC, r0)
1510 opset(AVCMPNEHCC, r0)
1512 opset(AVCMPNEWCC, r0)
1514 case AVPERM: /* vperm */
1515 opset(AVPERMXOR, r0)
1518 case AVBPERMQ: /* vbpermq, vbpermd */
1521 case AVSEL: /* vsel */
1524 case AVSPLTB: /* vspltb, vsplth, vspltw */
1528 case AVSPLTISB: /* vspltisb, vspltish, vspltisw */
1529 opset(AVSPLTISH, r0)
1530 opset(AVSPLTISW, r0)
1532 case AVCIPH: /* vcipher, vcipherlast */
1534 opset(AVCIPHERLAST, r0)
1536 case AVNCIPH: /* vncipher, vncipherlast */
1537 opset(AVNCIPHER, r0)
1538 opset(AVNCIPHERLAST, r0)
1540 case AVSBOX: /* vsbox */
1543 case AVSHASIGMA: /* vshasigmaw, vshasigmad */
1544 opset(AVSHASIGMAW, r0)
1545 opset(AVSHASIGMAD, r0)
1547 case ALXVD2X: /* lxvd2x, lxvdsx, lxvw4x, lxvh8x, lxvb16x */
1553 case ALXV: /* lxv */
1556 case ALXVL: /* lxvl, lxvll, lxvx */
1560 case ASTXVD2X: /* stxvd2x, stxvdsx, stxvw4x, stxvh8x, stxvb16x */
1563 opset(ASTXVB16X, r0)
1565 case ASTXV: /* stxv */
1568 case ASTXVL: /* stxvl, stxvll, stvx */
1572 case ALXSDX: /* lxsdx */
1575 case ASTXSDX: /* stxsdx */
1578 case ALXSIWAX: /* lxsiwax, lxsiwzx */
1581 case ASTXSIWX: /* stxsiwx */
1584 case AMFVSRD: /* mfvsrd, mfvsrwz (and extended mnemonics), mfvsrld */
1590 case AMTVSRD: /* mtvsrd, mtvsrwa, mtvsrwz (and extended mnemonics), mtvsrdd, mtvsrws */
1598 case AXXLAND: /* xxland, xxlandc, xxleqv, xxlnand */
1603 case AXXLOR: /* xxlorc, xxlnor, xxlor, xxlxor */
1609 case AXXSEL: /* xxsel */
1612 case AXXMRGHW: /* xxmrghw, xxmrglw */
1615 case AXXSPLTW: /* xxspltw */
1618 case AXXSPLTIB: /* xxspltib */
1619 opset(AXXSPLTIB, r0)
1621 case AXXPERM: /* xxpermdi */
1624 case AXXSLDWI: /* xxsldwi */
1625 opset(AXXPERMDI, r0)
1628 case AXXBRQ: /* xxbrq, xxbrd, xxbrw, xxbrh */
1633 case AXSCVDPSP: /* xscvdpsp, xscvspdp, xscvdpspn, xscvspdpn */
1634 opset(AXSCVSPDP, r0)
1635 opset(AXSCVDPSPN, r0)
1636 opset(AXSCVSPDPN, r0)
1638 case AXVCVDPSP: /* xvcvdpsp, xvcvspdp */
1639 opset(AXVCVSPDP, r0)
1641 case AXSCVDPSXDS: /* xscvdpsxds, xscvdpsxws, xscvdpuxds, xscvdpuxws */
1642 opset(AXSCVDPSXWS, r0)
1643 opset(AXSCVDPUXDS, r0)
1644 opset(AXSCVDPUXWS, r0)
1646 case AXSCVSXDDP: /* xscvsxddp, xscvuxddp, xscvsxdsp, xscvuxdsp */
1647 opset(AXSCVUXDDP, r0)
1648 opset(AXSCVSXDSP, r0)
1649 opset(AXSCVUXDSP, r0)
1651 case AXVCVDPSXDS: /* xvcvdpsxds, xvcvdpsxws, xvcvdpuxds, xvcvdpuxws, xvcvspsxds, xvcvspsxws, xvcvspuxds, xvcvspuxws */
1652 opset(AXVCVDPSXDS, r0)
1653 opset(AXVCVDPSXWS, r0)
1654 opset(AXVCVDPUXDS, r0)
1655 opset(AXVCVDPUXWS, r0)
1656 opset(AXVCVSPSXDS, r0)
1657 opset(AXVCVSPSXWS, r0)
1658 opset(AXVCVSPUXDS, r0)
1659 opset(AXVCVSPUXWS, r0)
1661 case AXVCVSXDDP: /* xvcvsxddp, xvcvsxwdp, xvcvuxddp, xvcvuxwdp, xvcvsxdsp, xvcvsxwsp, xvcvuxdsp, xvcvuxwsp */
1662 opset(AXVCVSXWDP, r0)
1663 opset(AXVCVUXDDP, r0)
1664 opset(AXVCVUXWDP, r0)
1665 opset(AXVCVSXDSP, r0)
1666 opset(AXVCVSXWSP, r0)
1667 opset(AXVCVUXDSP, r0)
1668 opset(AXVCVUXWSP, r0)
1670 case AAND: /* logical op Rb,Rs,Ra; no literal */
1684 case AADDME: /* op Ra, Rd */
1688 opset(AADDMEVCC, r0)
1692 opset(AADDZEVCC, r0)
1696 opset(ASUBMEVCC, r0)
1700 opset(ASUBZEVCC, r0)
1720 case AEXTSB: /* op Rs, Ra */
1726 opset(ACNTLZWCC, r0)
1730 opset(ACNTLZDCC, r0)
1732 case AFABS: /* fop [s,]d */
1744 opset(AFCTIWZCC, r0)
1748 opset(AFCTIDZCC, r0)
1752 opset(AFCFIDUCC, r0)
1754 opset(AFCFIDSCC, r0)
1766 opset(AFRSQRTECC, r0)
1770 opset(AFSQRTSCC, r0)
1777 opset(AFCPSGNCC, r0)
1790 opset(AFMADDSCC, r0)
1794 opset(AFMSUBSCC, r0)
1796 opset(AFNMADDCC, r0)
1798 opset(AFNMADDSCC, r0)
1800 opset(AFNMSUBCC, r0)
1802 opset(AFNMSUBSCC, r0)
1818 opset(AMTFSB0CC, r0)
1820 opset(AMTFSB1CC, r0)
1822 case ANEG: /* op [Ra,] Rd */
1828 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,R */
1831 case AORIS: /* oris/xoris $uimm,Rs,Ra */
1846 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1850 opset(AEXTSWSLICC, r0)
1852 case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1855 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
1883 opset(ARLDIMICC, r0)
1894 opset(ARLDICLCC, r0)
1896 opset(ARLDICRCC, r0)
1899 opset(ACLRLSLDI, r0)
1912 case ASYSCALL: /* just the op; flow of control */
1953 AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */
1959 /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
1960 AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals */
1961 AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
1962 AMOVB, /* macro: move byte with sign extension */
1963 AMOVBU, /* macro: move byte with sign extension & update */
1965 /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
1966 ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */
1991 func OPVXX1(o uint32, xo uint32, oe uint32) uint32 {
1992 return o<<26 | xo<<1 | oe<<11
1995 func OPVXX2(o uint32, xo uint32, oe uint32) uint32 {
1996 return o<<26 | xo<<2 | oe<<11
1999 func OPVXX2VA(o uint32, xo uint32, oe uint32) uint32 {
2000 return o<<26 | xo<<2 | oe<<16
2003 func OPVXX3(o uint32, xo uint32, oe uint32) uint32 {
2004 return o<<26 | xo<<3 | oe<<11
2007 func OPVXX4(o uint32, xo uint32, oe uint32) uint32 {
2008 return o<<26 | xo<<4 | oe<<11
2011 func OPDQ(o uint32, xo uint32, oe uint32) uint32 {
2012 return o<<26 | xo | oe<<4
2015 func OPVX(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2016 return o<<26 | xo | oe<<11 | rc&1
2019 func OPVC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2020 return o<<26 | xo | oe<<11 | (rc&1)<<10
2023 func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2024 return o<<26 | xo<<1 | oe<<10 | rc&1
2027 func OPCC(o uint32, xo uint32, rc uint32) uint32 {
2028 return OPVCC(o, xo, 0, rc)
2031 /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
2032 func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
2033 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
2036 /* VX-form 2-register operands, r/none/r */
2037 func AOP_RR(op uint32, d uint32, a uint32) uint32 {
2038 return op | (d&31)<<21 | (a&31)<<11
2041 /* VA-form 4-register operands */
2042 func AOP_RRRR(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2043 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&31)<<6
2046 func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2047 return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF
2050 /* VX-form 2-register + UIM operands */
2051 func AOP_VIRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2052 return op | (d&31)<<21 | (simm&0xFFFF)<<16 | (a&31)<<11
2055 /* VX-form 2-register + ST + SIX operands */
2056 func AOP_IIRR(op uint32, d uint32, a uint32, sbit uint32, simm uint32) uint32 {
2057 return op | (d&31)<<21 | (a&31)<<16 | (sbit&1)<<15 | (simm&0xF)<<11
2060 /* VA-form 3-register + SHB operands */
2061 func AOP_IRRR(op uint32, d uint32, a uint32, b uint32, simm uint32) uint32 {
2062 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (simm&0xF)<<6
2065 /* VX-form 1-register + SIM operands */
2066 func AOP_IR(op uint32, d uint32, simm uint32) uint32 {
2067 return op | (d&31)<<21 | (simm&31)<<16
2070 /* XX1-form 3-register operands, 1 VSR operand */
2071 func AOP_XX1(op uint32, d uint32, a uint32, b uint32) uint32 {
2072 /* For the XX-form encodings, we need the VSX register number to be exactly */
2073 /* between 0-63, so we can properly set the rightmost bits. */
2075 return op | (r&31)<<21 | (a&31)<<16 | (b&31)<<11 | (r&32)>>5
2078 /* XX2-form 3-register operands, 2 VSR operands */
2079 func AOP_XX2(op uint32, d uint32, a uint32, b uint32) uint32 {
2082 return op | (xt&31)<<21 | (a&3)<<16 | (xb&31)<<11 | (xb&32)>>4 | (xt&32)>>5
2085 /* XX3-form 3 VSR operands */
2086 func AOP_XX3(op uint32, d uint32, a uint32, b uint32) uint32 {
2090 return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2093 /* XX3-form 3 VSR operands + immediate */
2094 func AOP_XX3I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2098 return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (c&3)<<8 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2101 /* XX4-form, 4 VSR operands */
2102 func AOP_XX4(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2107 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
2110 /* DQ-form, VSR register, register + offset operands */
2111 func AOP_DQ(op uint32, d uint32, a uint32, b uint32) uint32 {
2112 /* For the DQ-form encodings, we need the VSX register number to be exactly */
2113 /* between 0-63, so we can properly set the SX bit. */
2115 /* The EA for this instruction form is (RA) + DQ << 4, where DQ is a 12-bit signed integer. */
2116 /* In order to match the output of the GNU objdump (and make the usage in Go asm easier), the */
2117 /* instruction is called using the sign extended value (i.e. a valid offset would be -32752 or 32752, */
2118 /* not -2047 or 2047), so 'b' needs to be adjusted to the expected 12-bit DQ value. Bear in mind that */
2119 /* bits 0 to 3 in 'dq' need to be zero, otherwise this will generate an illegal instruction. */
2120 /* If in doubt how this instruction form is encoded, refer to ISA 3.0b, pages 492 and 507. */
2122 return op | (r&31)<<21 | (a&31)<<16 | (dq&4095)<<4 | (r&32)>>2
2125 /* Z23-form, 3-register operands + CY field */
2126 func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2127 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<9
2130 /* X-form, 3-register operands + EH field */
2131 func AOP_RRRI(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2132 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c & 1)
2135 func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
2136 return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
2139 func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 {
2140 return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF
2143 func OP_BR(op uint32, li uint32, aa uint32) uint32 {
2144 return op | li&0x03FFFFFC | aa<<1
2147 func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 {
2148 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1
2151 func OP_BCR(op uint32, bo uint32, bi uint32) uint32 {
2152 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16
2155 func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 {
2156 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1
2159 func AOP_RLDIC(op uint32, a uint32, s uint32, sh uint32, m uint32) uint32 {
2160 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1 | (m&31)<<6 | ((m&32)>>5)<<5
2163 func AOP_EXTSWSLI(op uint32, a uint32, s uint32, sh uint32) uint32 {
2164 return op | (a&31)<<21 | (s&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1
2167 func AOP_ISEL(op uint32, t uint32, a uint32, b uint32, bc uint32) uint32 {
2168 return op | (t&31)<<21 | (a&31)<<16 | (b&31)<<11 | (bc&0x1F)<<6
2172 /* each rhs is OPVCC(_, _, _, _) */
2173 OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0
2174 OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0
2175 OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0
2176 OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 0
2177 OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0
2178 OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0
2179 OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0
2180 OP_ISEL = 31<<26 | 15<<1 | 0<<10 | 0
2181 OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0
2182 OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0
2183 OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0
2184 OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 0
2185 OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 0
2186 OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0
2187 OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0
2188 OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 0
2189 OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0
2190 OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0
2191 OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0
2192 OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0
2193 OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0
2194 OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0
2195 OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0
2196 OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 0
2197 OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0
2198 OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0
2199 OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0
2200 OP_OR = 31<<26 | 444<<1 | 0<<10 | 0
2201 OP_ORI = 24<<26 | 0<<1 | 0<<10 | 0
2202 OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 0
2203 OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0
2204 OP_RLWNM = 23<<26 | 0<<1 | 0<<10 | 0
2205 OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 0
2206 OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 0
2207 OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0
2208 OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0
2209 OP_RLDCL = 30<<26 | 8<<1 | 0<<10 | 0
2210 OP_EXTSWSLI = 31<<26 | 445<<2
2213 func oclass(a *obj.Addr) int {
2214 return int(a.Class) - 1
2222 // This function determines when a non-indexed load or store is D or
2223 // DS form for use in finding the size of the offset field in the instruction.
2224 // The size is needed when setting the offset value in the instruction
2225 // and when generating relocation for that field.
2226 // DS form instructions include: ld, ldu, lwa, std, stdu. All other
2227 // loads and stores with an offset field are D form. This function should
2228 // only be called with the same opcodes as are handled by opstore and opload.
2229 func (c *ctxt9) opform(insn uint32) int {
2232 c.ctxt.Diag("bad insn in loadform: %x", insn)
2233 case OPVCC(58, 0, 0, 0), // ld
2234 OPVCC(58, 0, 0, 1), // ldu
2235 OPVCC(58, 0, 0, 0) | 1<<1, // lwa
2236 OPVCC(62, 0, 0, 0), // std
2237 OPVCC(62, 0, 0, 1): //stdu
2239 case OP_ADDI, // add
2240 OPVCC(32, 0, 0, 0), // lwz
2241 OPVCC(33, 0, 0, 0), // lwzu
2242 OPVCC(34, 0, 0, 0), // lbz
2243 OPVCC(35, 0, 0, 0), // lbzu
2244 OPVCC(40, 0, 0, 0), // lhz
2245 OPVCC(41, 0, 0, 0), // lhzu
2246 OPVCC(42, 0, 0, 0), // lha
2247 OPVCC(43, 0, 0, 0), // lhau
2248 OPVCC(46, 0, 0, 0), // lmw
2249 OPVCC(48, 0, 0, 0), // lfs
2250 OPVCC(49, 0, 0, 0), // lfsu
2251 OPVCC(50, 0, 0, 0), // lfd
2252 OPVCC(51, 0, 0, 0), // lfdu
2253 OPVCC(36, 0, 0, 0), // stw
2254 OPVCC(37, 0, 0, 0), // stwu
2255 OPVCC(38, 0, 0, 0), // stb
2256 OPVCC(39, 0, 0, 0), // stbu
2257 OPVCC(44, 0, 0, 0), // sth
2258 OPVCC(45, 0, 0, 0), // sthu
2259 OPVCC(47, 0, 0, 0), // stmw
2260 OPVCC(52, 0, 0, 0), // stfs
2261 OPVCC(53, 0, 0, 0), // stfsu
2262 OPVCC(54, 0, 0, 0), // stfd
2263 OPVCC(55, 0, 0, 0): // stfdu
2269 // Encode instructions and create relocation for accessing s+d according to the
2270 // instruction op with source or destination (as appropriate) register reg.
2271 func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) {
2272 if c.ctxt.Headtype == objabi.Haix {
2273 // Every symbol access must be made via a TOC anchor.
2274 c.ctxt.Diag("symbolAccess called for %s", s.Name)
2277 form := c.opform(op)
2278 if c.ctxt.Flag_shared {
2283 o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)
2284 o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)
2285 rel := obj.Addrel(c.cursym)
2286 rel.Off = int32(c.pc)
2290 if c.ctxt.Flag_shared {
2293 rel.Type = objabi.R_ADDRPOWER_TOCREL
2295 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
2301 rel.Type = objabi.R_ADDRPOWER
2303 rel.Type = objabi.R_ADDRPOWER_DS
2312 func getmask(m []byte, v uint32) bool {
2315 if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
2326 for i := 0; i < 32; i++ {
2327 if v&(1<<uint(31-i)) != 0 {
2332 if i >= 32 || v&(1<<uint(31-i)) == 0 {
2338 if v&(1<<uint(31-i)) != 0 {
2349 func (c *ctxt9) maskgen(p *obj.Prog, m []byte, v uint32) {
2351 c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
2356 * 64-bit masks (rldic etc)
2358 func getmask64(m []byte, v uint64) bool {
2361 for i := 0; i < 64; i++ {
2362 if v&(uint64(1)<<uint(63-i)) != 0 {
2367 if i >= 64 || v&(uint64(1)<<uint(63-i)) == 0 {
2373 if v&(uint64(1)<<uint(63-i)) != 0 {
2384 func (c *ctxt9) maskgen64(p *obj.Prog, m []byte, v uint64) {
2385 if !getmask64(m, v) {
2386 c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
2390 func loadu32(r int, d int64) uint32 {
2392 if isuint32(uint64(d)) {
2393 return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
2395 return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v))
2398 func high16adjusted(d int32) uint16 {
2400 return uint16((d >> 16) + 1)
2402 return uint16(d >> 16)
2405 func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
2412 //print("%v => case %d\n", p, o->type);
2415 c.ctxt.Diag("unknown type %d", o.type_)
2418 case 0: /* pseudo ops */
2421 case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
2422 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
2423 v := c.regoff(&p.From)
2424 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
2426 c.ctxt.Diag("literal operation on R0\n%v", p)
2429 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
2433 o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
2435 case 2: /* int/cr/fp op Rb,[Ra],Rd */
2441 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2443 case 3: /* mov $soreg/addcon/andcon/ucon, r ==> addis/oris/addi/ori $i,reg',r */
2444 d := c.vregoff(&p.From)
2447 r := int(p.From.Reg)
2449 r = c.getimpliedreg(&p.From, p)
2451 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
2452 c.ctxt.Diag("literal operation on R0\n%v", p)
2457 log.Fatalf("invalid handling of %v", p)
2459 // For UCON operands the value is right shifted 16, using ADDIS if the
2460 // value should be signed, ORIS if unsigned.
2462 if r == REGZERO && isuint32(uint64(d)) {
2463 o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v))
2468 } else if int64(int16(d)) != d {
2469 // Operand is 16 bit value with sign bit set
2470 if o.a1 == C_ANDCON {
2471 // Needs unsigned 16 bit so use ORI
2472 if r == 0 || r == REGZERO {
2473 o1 = LOP_IRR(uint32(OP_ORI), uint32(p.To.Reg), uint32(0), uint32(v))
2476 // With ADDCON, needs signed 16 bit value, fall through to use ADDI
2477 } else if o.a1 != C_ADDCON {
2478 log.Fatalf("invalid handling of %v", p)
2482 o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
2484 case 4: /* add/mul $scon,[r1],r2 */
2485 v := c.regoff(&p.From)
2491 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
2492 c.ctxt.Diag("literal operation on R0\n%v", p)
2494 if int32(int16(v)) != v {
2495 log.Fatalf("mishandled instruction %v", p)
2497 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2499 case 5: /* syscall */
2502 case 6: /* logical op Rb,[Rs,]Ra; no literal */
2508 // AROTL and AROTLW are extended mnemonics, which map to RLDCL and RLWNM.
2511 o1 = AOP_RLDIC(OP_RLDCL, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), uint32(0))
2513 o1 = OP_RLW(OP_RLWNM, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), 0, 31)
2515 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2518 case 7: /* mov r, soreg ==> stw o(r) */
2522 r = c.getimpliedreg(&p.To, p)
2524 v := c.regoff(&p.To)
2525 if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
2527 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2529 if c.ctxt.Flag_shared && r == REG_R13 {
2530 rel := obj.Addrel(c.cursym)
2531 rel.Off = int32(c.pc)
2533 // This (and the matching part in the load case
2534 // below) are the only places in the ppc64 toolchain
2535 // that knows the name of the tls variable. Possibly
2536 // we could add some assembly syntax so that the name
2537 // of the variable does not have to be assumed.
2538 rel.Sym = c.ctxt.Lookup("runtime.tls_g")
2539 rel.Type = objabi.R_POWER_TLS
2541 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
2543 if int32(int16(v)) != v {
2544 log.Fatalf("mishandled instruction %v", p)
2546 // Offsets in DS form stores must be a multiple of 4
2547 inst := c.opstore(p.As)
2548 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2549 log.Fatalf("invalid offset for DS form load/store %v", p)
2551 o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
2554 case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
2555 r := int(p.From.Reg)
2558 r = c.getimpliedreg(&p.From, p)
2560 v := c.regoff(&p.From)
2561 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
2563 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2565 if c.ctxt.Flag_shared && r == REG_R13 {
2566 rel := obj.Addrel(c.cursym)
2567 rel.Off = int32(c.pc)
2569 rel.Sym = c.ctxt.Lookup("runtime.tls_g")
2570 rel.Type = objabi.R_POWER_TLS
2572 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
2574 if int32(int16(v)) != v {
2575 log.Fatalf("mishandled instruction %v", p)
2577 // Offsets in DS form loads must be a multiple of 4
2578 inst := c.opload(p.As)
2579 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2580 log.Fatalf("invalid offset for DS form load/store %v", p)
2582 o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
2585 case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
2586 r := int(p.From.Reg)
2589 r = c.getimpliedreg(&p.From, p)
2591 v := c.regoff(&p.From)
2592 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
2594 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2596 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
2598 o1 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2600 o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
2602 case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
2608 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
2610 case 11: /* br/bl lbra */
2613 if p.To.Target() != nil {
2614 v = int32(p.To.Target().Pc - p.Pc)
2616 c.ctxt.Diag("odd branch target address\n%v", p)
2620 if v < -(1<<25) || v >= 1<<24 {
2621 c.ctxt.Diag("branch too far\n%v", p)
2625 o1 = OP_BR(c.opirr(p.As), uint32(v), 0)
2626 if p.To.Sym != nil {
2627 rel := obj.Addrel(c.cursym)
2628 rel.Off = int32(c.pc)
2631 v += int32(p.To.Offset)
2633 c.ctxt.Diag("odd branch target address\n%v", p)
2638 rel.Type = objabi.R_CALLPOWER
2640 o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
2642 case 12: /* movb r,r (extsb); movw r,r (extsw) */
2643 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
2644 v := c.regoff(&p.From)
2645 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
2646 c.ctxt.Diag("literal operation on R0\n%v", p)
2649 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
2654 o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2656 o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2659 case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
2661 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
2662 } else if p.As == AMOVH {
2663 o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2664 } else if p.As == AMOVHZ {
2665 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
2666 } else if p.As == AMOVWZ {
2667 o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
2669 c.ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
2672 case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
2678 d := c.vregoff(p.GetFrom3())
2682 // These opcodes expect a mask operand that has to be converted into the
2683 // appropriate operand. The way these were defined, not all valid masks are possible.
2684 // Left here for compatibility in case they were used or generated.
2685 case ARLDCL, ARLDCLCC:
2687 c.maskgen64(p, mask[:], uint64(d))
2689 a = int(mask[0]) /* MB */
2691 c.ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)
2693 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2694 o1 |= (uint32(a) & 31) << 6
2696 o1 |= 1 << 5 /* mb[5] is top bit */
2699 case ARLDCR, ARLDCRCC:
2701 c.maskgen64(p, mask[:], uint64(d))
2703 a = int(mask[1]) /* ME */
2705 c.ctxt.Diag("invalid mask for rotate: %x %x (start != 0)\n%v", uint64(d), mask[0], p)
2707 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2708 o1 |= (uint32(a) & 31) << 6
2710 o1 |= 1 << 5 /* mb[5] is top bit */
2713 // These opcodes use a shift count like the ppc64 asm, no mask conversion done
2714 case ARLDICR, ARLDICRCC:
2716 sh := c.regoff(&p.From)
2717 if me < 0 || me > 63 || sh > 63 {
2718 c.ctxt.Diag("Invalid me or sh for RLDICR: %x %x\n%v", int(d), sh, p)
2720 o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(me))
2722 case ARLDICL, ARLDICLCC, ARLDIC, ARLDICCC:
2724 sh := c.regoff(&p.From)
2725 if mb < 0 || mb > 63 || sh > 63 {
2726 c.ctxt.Diag("Invalid mb or sh for RLDIC, RLDICL: %x %x\n%v", mb, sh, p)
2728 o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(mb))
2731 // This is an extended mnemonic defined in the ISA section C.8.1
2732 // clrlsldi ra,rs,b,n --> rldic ra,rs,n,b-n
2733 // It maps onto RLDIC so is directly generated here based on the operands from
2736 b := c.regoff(&p.From)
2737 if n > b || b > 63 {
2738 c.ctxt.Diag("Invalid n or b for CLRLSLDI: %x %x\n%v", n, b, p)
2740 o1 = AOP_RLDIC(OP_RLDIC, uint32(p.To.Reg), uint32(r), uint32(n), uint32(b)-uint32(n))
2743 c.ctxt.Diag("unexpected op in rldc case\n%v", p)
2747 case 17, /* bc bo,bi,lbra (same for now) */
2748 16: /* bc bo,bi,sbra */
2753 if p.From.Type == obj.TYPE_CONST {
2754 a = int(c.regoff(&p.From))
2755 } else if p.From.Type == obj.TYPE_REG {
2757 c.ctxt.Diag("unexpected register setting for branch with CR: %d\n", r)
2759 // BI values for the CR
2778 c.ctxt.Diag("unrecognized register: expecting CR\n")
2782 if p.To.Target() != nil {
2783 v = int32(p.To.Target().Pc - p.Pc)
2786 c.ctxt.Diag("odd branch target address\n%v", p)
2790 if v < -(1<<16) || v >= 1<<15 {
2791 c.ctxt.Diag("branch too far\n%v", p)
2793 o1 = OP_BC(c.opirr(p.As), uint32(a), uint32(r), uint32(v), 0)
2795 case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
2797 if p.As == ABC || p.As == ABCL {
2798 v = c.regoff(&p.To) & 31
2800 v = 20 /* unconditional */
2802 o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
2803 o2 = OPVCC(19, 16, 0, 0)
2804 if p.As == ABL || p.As == ABCL {
2807 o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index))
2809 case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
2812 if p.As == ABC || p.As == ABCL {
2813 v = c.regoff(&p.From) & 31
2815 v = 20 /* unconditional */
2821 switch oclass(&p.To) {
2823 o1 = OPVCC(19, 528, 0, 0)
2826 o1 = OPVCC(19, 16, 0, 0)
2829 c.ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p)
2833 // Insert optional branch hint for bclr[l]/bcctr[l]
2834 if p.From3Type() != obj.TYPE_NONE {
2835 bh = uint32(p.GetFrom3().Offset)
2836 if bh == 2 || bh > 3 {
2837 log.Fatalf("BH must be 0,1,3 for %v", p)
2842 if p.As == ABL || p.As == ABCL {
2845 o1 = OP_BCR(o1, uint32(v), uint32(r))
2847 case 19: /* mov $lcon,r ==> cau+or */
2848 d := c.vregoff(&p.From)
2850 if p.From.Sym == nil {
2851 o1 = loadu32(int(p.To.Reg), d)
2852 o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
2854 o1, o2 = c.symbolAccess(p.From.Sym, d, p.To.Reg, OP_ADDI)
2857 case 20: /* add $ucon,,r | addis $addcon,r,r */
2858 v := c.regoff(&p.From)
2864 if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
2865 c.ctxt.Diag("literal operation on R0\n%v", p)
2868 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2870 o1 = AOP_IRR(c.opirr(AADDIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
2873 case 22: /* add $lcon/$andcon,r1,r2 ==> oris+ori+add/ori+add */
2874 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2875 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2877 d := c.vregoff(&p.From)
2882 if p.From.Sym != nil {
2883 c.ctxt.Diag("%v is not supported", p)
2885 // If operand is ANDCON, generate 2 instructions using
2886 // ORI for unsigned value; with LCON 3 instructions.
2888 o1 = LOP_IRR(OP_ORI, REGTMP, REGZERO, uint32(int32(d)))
2889 o2 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2891 o1 = loadu32(REGTMP, d)
2892 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2893 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2896 case 23: /* and $lcon/$addcon,r1,r2 ==> oris+ori+and/addi+and */
2897 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2898 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2900 d := c.vregoff(&p.From)
2906 // With ADDCON operand, generate 2 instructions using ADDI for signed value,
2907 // with LCON operand generate 3 instructions.
2909 o1 = LOP_IRR(OP_ADDI, REGZERO, REGTMP, uint32(int32(d)))
2910 o2 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2912 o1 = loadu32(REGTMP, d)
2913 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2914 o3 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2916 if p.From.Sym != nil {
2917 c.ctxt.Diag("%v is not supported", p)
2920 case 24: /* lfd fA,float64(0) -> xxlxor xsA,xsaA,xsaA + fneg for -0 */
2921 o1 = AOP_XX3I(c.oprrr(AXXLXOR), uint32(p.To.Reg), uint32(p.To.Reg), uint32(p.To.Reg), uint32(0))
2922 // This is needed for -0.
2924 o2 = AOP_RRR(c.oprrr(AFNEG), uint32(p.To.Reg), 0, uint32(p.To.Reg))
2928 /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
2929 v := c.regoff(&p.From)
2957 c.ctxt.Diag("unexpected op in sldi case\n%v", p)
2962 if p.As == AEXTSWSLI || p.As == AEXTSWSLICC {
2963 o1 = AOP_EXTSWSLI(OP_EXTSWSLI, uint32(r), uint32(p.To.Reg), uint32(v))
2966 o1 = AOP_RLDIC(op, uint32(p.To.Reg), uint32(r), uint32(v), uint32(a))
2968 if p.As == ASLDCC || p.As == ASRDCC || p.As == AEXTSWSLICC {
2969 o1 |= 1 // Set the condition code bit
2972 case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
2973 if p.To.Reg == REGTMP {
2974 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2976 v := c.regoff(&p.From)
2977 r := int(p.From.Reg)
2979 r = c.getimpliedreg(&p.From, p)
2981 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
2982 o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
2984 case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
2985 v := c.regoff(p.GetFrom3())
2987 r := int(p.From.Reg)
2988 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2990 case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
2991 if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
2992 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2994 v := c.regoff(p.GetFrom3())
2995 o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
2996 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
2997 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
2998 if p.From.Sym != nil {
2999 c.ctxt.Diag("%v is not supported", p)
3002 case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
3003 v := c.regoff(&p.From)
3005 d := c.vregoff(p.GetFrom3())
3007 c.maskgen64(p, mask[:], uint64(d))
3010 case ARLDC, ARLDCCC:
3011 a = int(mask[0]) /* MB */
3012 if int32(mask[1]) != (63 - v) {
3013 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[1], v, p)
3016 case ARLDCL, ARLDCLCC:
3017 a = int(mask[0]) /* MB */
3019 c.ctxt.Diag("invalid mask for shift: %x %s (shift %d)\n%v", uint64(d), mask[1], v, p)
3022 case ARLDCR, ARLDCRCC:
3023 a = int(mask[1]) /* ME */
3025 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[0], v, p)
3029 c.ctxt.Diag("unexpected op in rldic case\n%v", p)
3033 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3034 o1 |= (uint32(a) & 31) << 6
3039 o1 |= 1 << 5 /* mb[5] is top bit */
3042 case 30: /* rldimi $sh,s,$mask,a */
3043 v := c.regoff(&p.From)
3045 d := c.vregoff(p.GetFrom3())
3047 // Original opcodes had mask operands which had to be converted to a shift count as expected by
3050 case ARLDMI, ARLDMICC:
3052 c.maskgen64(p, mask[:], uint64(d))
3053 if int32(mask[1]) != (63 - v) {
3054 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[1], v, p)
3056 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3057 o1 |= (uint32(mask[0]) & 31) << 6
3061 if mask[0]&0x20 != 0 {
3062 o1 |= 1 << 5 /* mb[5] is top bit */
3065 // Opcodes with shift count operands.
3066 case ARLDIMI, ARLDIMICC:
3067 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3068 o1 |= (uint32(d) & 31) << 6
3077 case 31: /* dword */
3078 d := c.vregoff(&p.From)
3080 if c.ctxt.Arch.ByteOrder == binary.BigEndian {
3081 o1 = uint32(d >> 32)
3085 o2 = uint32(d >> 32)
3088 if p.From.Sym != nil {
3089 rel := obj.Addrel(c.cursym)
3090 rel.Off = int32(c.pc)
3092 rel.Sym = p.From.Sym
3093 rel.Add = p.From.Offset
3094 rel.Type = objabi.R_ADDR
3099 case 32: /* fmul frc,fra,frd */
3105 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
3107 case 33: /* fabs [frb,]frd; fmr. frb,frd */
3108 r := int(p.From.Reg)
3110 if oclass(&p.From) == C_NONE {
3113 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(r))
3115 case 34: /* FMADDx fra,frb,frc,frt (t=a*c±b) */
3116 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.GetFrom3().Reg)&31)<<6
3118 case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
3119 v := c.regoff(&p.To)
3123 r = c.getimpliedreg(&p.To, p)
3125 // Offsets in DS form stores must be a multiple of 4
3126 inst := c.opstore(p.As)
3127 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3128 log.Fatalf("invalid offset for DS form load/store %v", p)
3130 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3131 o2 = AOP_IRR(inst, uint32(p.From.Reg), REGTMP, uint32(v))
3133 case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
3134 v := c.regoff(&p.From)
3136 r := int(p.From.Reg)
3138 r = c.getimpliedreg(&p.From, p)
3140 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3141 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
3143 case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
3144 v := c.regoff(&p.From)
3146 r := int(p.From.Reg)
3148 r = c.getimpliedreg(&p.From, p)
3150 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3151 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
3152 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3155 o1 = uint32(c.regoff(&p.From))
3157 case 41: /* stswi */
3158 o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3161 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3163 case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */
3164 /* TH field for dcbt/dcbtst: */
3165 /* 0 = Block access - program will soon access EA. */
3166 /* 8-15 = Stream access - sequence of access (data stream). See section 4.3.2 of the ISA for details. */
3167 /* 16 = Block access - program will soon make a transient access to EA. */
3168 /* 17 = Block access - program will not access EA for a long time. */
3170 /* L field for dcbf: */
3171 /* 0 = invalidates the block containing EA in all processors. */
3172 /* 1 = same as 0, but with limited scope (i.e. block in the current processor will not be reused soon). */
3173 /* 3 = same as 1, but with even more limited scope (i.e. block in the current processor primary cache will not be reused soon). */
3174 if p.To.Type == obj.TYPE_NONE {
3175 o1 = AOP_RRR(c.oprrr(p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))
3177 th := c.regoff(&p.To)
3178 o1 = AOP_RRR(c.oprrr(p.As), uint32(th), uint32(p.From.Index), uint32(p.From.Reg))
3181 case 44: /* indexed store */
3182 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3184 case 45: /* indexed load */
3186 /* The assembler accepts a 4-operand l*arx instruction. The fourth operand is an Exclusive Access Hint (EH) */
3187 /* The EH field can be used as a lock acquire/release hint as follows: */
3188 /* 0 = Atomic Update (fetch-and-operate or similar algorithm) */
3189 /* 1 = Exclusive Access (lock acquire and release) */
3190 case ALBAR, ALHAR, ALWAR, ALDAR:
3191 if p.From3Type() != obj.TYPE_NONE {
3192 eh := int(c.regoff(p.GetFrom3()))
3194 c.ctxt.Diag("illegal EH field\n%v", p)
3196 o1 = AOP_RRRI(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg), uint32(eh))
3198 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3201 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3203 case 46: /* plain op */
3206 case 47: /* op Ra, Rd; also op [Ra,] Rd */
3207 r := int(p.From.Reg)
3212 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3214 case 48: /* op Rs, Ra */
3215 r := int(p.From.Reg)
3220 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3222 case 49: /* op Rb; op $n, Rb */
3223 if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
3224 v := c.regoff(&p.From) & 1
3225 o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
3227 o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.From.Reg))
3230 case 50: /* rem[u] r1[,r2],r3 */
3237 t := v & (1<<10 | 1) /* OE|Rc */
3238 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3239 o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
3240 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3244 /* Clear top 32 bits */
3245 o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5
3248 case 51: /* remd[u] r1[,r2],r3 */
3255 t := v & (1<<10 | 1) /* OE|Rc */
3256 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3257 o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
3258 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3259 /* cases 50,51: removed; can be reused. */
3261 /* cases 50,51: removed; can be reused. */
3263 case 52: /* mtfsbNx cr(n) */
3264 v := c.regoff(&p.From) & 31
3266 o1 = AOP_RRR(c.oprrr(p.As), uint32(v), 0, 0)
3268 case 53: /* mffsX ,fr1 */
3269 o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)
3271 case 54: /* mov msr,r1; mov r1, msr*/
3272 if oclass(&p.From) == C_REG {
3274 o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
3276 o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
3279 o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
3282 case 55: /* op Rb, Rd */
3283 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg))
3285 case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
3286 v := c.regoff(&p.From)
3292 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31)
3293 if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) {
3294 o1 |= 1 << 1 /* mb[5] */
3297 case 57: /* slw $sh,[s,]a -> rlwinm ... */
3298 v := c.regoff(&p.From)
3306 * Let user (gs) shoot himself in the foot.
3307 * qc has already complained.
3310 ctxt->diag("illegal shift %ld\n%v", v, p);
3320 mask[0], mask[1] = 0, 31
3322 mask[0], mask[1] = uint8(v), 31
3325 mask[0], mask[1] = 0, uint8(31-v)
3327 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1]))
3328 if p.As == ASLWCC || p.As == ASRWCC {
3329 o1 |= 1 // set the condition code
3332 case 58: /* logical $andcon,[s],a */
3333 v := c.regoff(&p.From)
3339 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3341 case 59: /* or/xor/and $ucon,,r | oris/xoris/andis $addcon,r,r */
3342 v := c.regoff(&p.From)
3350 o1 = LOP_IRR(c.opirr(AORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis. */
3352 o1 = LOP_IRR(c.opirr(AXORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3354 o1 = LOP_IRR(c.opirr(AANDISCC), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3356 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3359 case 60: /* tw to,a,b */
3360 r := int(c.regoff(&p.From) & 31)
3362 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
3364 case 61: /* tw to,a,$simm */
3365 r := int(c.regoff(&p.From) & 31)
3367 v := c.regoff(&p.To)
3368 o1 = AOP_IRR(c.opirr(p.As), uint32(r), uint32(p.Reg), uint32(v))
3370 case 62: /* rlwmi $sh,s,$mask,a */
3371 v := c.regoff(&p.From)
3374 n := c.regoff(p.GetFrom3())
3375 // This is an extended mnemonic described in the ISA C.8.2
3376 // clrlslwi ra,rs,b,n -> rlwinm ra,rs,n,b-n,31-n
3377 // It maps onto rlwinm which is directly generated here.
3378 if n > v || v >= 32 {
3379 c.ctxt.Diag("Invalid n or b for CLRLSLWI: %x %x\n%v", v, n, p)
3382 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.Reg), uint32(n), uint32(v-n), uint32(31-n))
3385 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
3386 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
3387 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
3390 case 63: /* rlwmi b,s,$mask,a */
3392 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
3393 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
3394 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
3396 case 64: /* mtfsf fr[, $m] {,fpcsr} */
3398 if p.From3Type() != obj.TYPE_NONE {
3399 v = c.regoff(p.GetFrom3()) & 255
3403 o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
3405 case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
3407 c.ctxt.Diag("must specify FPSCR(n)\n%v", p)
3409 o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(c.regoff(&p.From))&31)<<12
3411 case 66: /* mov spr,r1; mov r1,spr, also dcr */
3414 if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
3417 if REG_DCR0 <= v && v <= REG_DCR0+1023 {
3418 o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
3420 o1 = OPVCC(31, 467, 0, 0) /* mtspr */
3424 v = int32(p.From.Reg)
3425 if REG_DCR0 <= v && v <= REG_DCR0+1023 {
3426 o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
3428 o1 = OPVCC(31, 339, 0, 0) /* mfspr */
3432 o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
3434 case 67: /* mcrf crfD,crfS */
3435 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 {
3436 c.ctxt.Diag("illegal CR field number\n%v", p)
3438 o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
3440 case 68: /* mfcr rD; mfocrf CRM,rD */
3441 if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
3442 v := int32(1 << uint(7-(p.To.Reg&7))) /* CR(n) */
3443 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
3445 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
3448 case 69: /* mtcrf CRM,rS */
3450 if p.From3Type() != obj.TYPE_NONE {
3452 c.ctxt.Diag("can't use both mask and CR(n)\n%v", p)
3454 v = c.regoff(p.GetFrom3()) & 0xff
3459 v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
3463 o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
3465 case 70: /* [f]cmp r,r,cr*/
3470 r = (int(p.Reg) & 7) << 2
3472 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
3474 case 71: /* cmp[l] r,i,cr*/
3479 r = (int(p.Reg) & 7) << 2
3481 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(c.regoff(&p.To))&0xffff
3483 case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
3484 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg))
3486 case 73: /* mcrfs crfD,crfS */
3487 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 {
3488 c.ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
3490 o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
3492 case 77: /* syscall $scon, syscall Rx */
3493 if p.From.Type == obj.TYPE_CONST {
3494 if p.From.Offset > BIG || p.From.Offset < -BIG {
3495 c.ctxt.Diag("illegal syscall, sysnum too large: %v", p)
3497 o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
3498 } else if p.From.Type == obj.TYPE_REG {
3499 o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
3501 c.ctxt.Diag("illegal syscall: %v", p)
3502 o1 = 0x7fe00008 // trap always
3506 o3 = AOP_RRR(c.oprrr(AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R0
3508 case 78: /* undef */
3509 o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed
3510 always to be an illegal instruction." */
3512 /* relocation operations */
3514 v := c.vregoff(&p.To)
3515 // Offsets in DS form stores must be a multiple of 4
3516 inst := c.opstore(p.As)
3517 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3518 log.Fatalf("invalid offset for DS form load/store %v", p)
3520 o1, o2 = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst)
3522 //if(dlm) reloc(&p->to, p->pc, 1);
3525 v := c.vregoff(&p.From)
3526 // Offsets in DS form loads must be a multiple of 4
3527 inst := c.opload(p.As)
3528 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3529 log.Fatalf("invalid offset for DS form load/store %v", p)
3531 o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
3533 //if(dlm) reloc(&p->from, p->pc, 1);
3536 v := c.vregoff(&p.From)
3537 // Offsets in DS form loads must be a multiple of 4
3538 inst := c.opload(p.As)
3539 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3540 log.Fatalf("invalid offset for DS form load/store %v", p)
3542 o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
3543 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3545 //if(dlm) reloc(&p->from, p->pc, 1);
3548 if p.From.Offset != 0 {
3549 c.ctxt.Diag("invalid offset against tls var %v", p)
3551 o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0)
3552 rel := obj.Addrel(c.cursym)
3553 rel.Off = int32(c.pc)
3555 rel.Sym = p.From.Sym
3556 rel.Type = objabi.R_POWER_TLS_LE
3559 if p.From.Offset != 0 {
3560 c.ctxt.Diag("invalid offset against tls var %v", p)
3562 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3563 o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3564 rel := obj.Addrel(c.cursym)
3565 rel.Off = int32(c.pc)
3567 rel.Sym = p.From.Sym
3568 rel.Type = objabi.R_POWER_TLS_IE
3571 v := c.vregoff(&p.To)
3573 c.ctxt.Diag("invalid offset against GOT slot %v", p)
3576 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3577 o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3578 rel := obj.Addrel(c.cursym)
3579 rel.Off = int32(c.pc)
3581 rel.Sym = p.From.Sym
3582 rel.Type = objabi.R_ADDRPOWER_GOT
3583 case 82: /* vector instructions, VX-form and VC-form */
3584 if p.From.Type == obj.TYPE_REG {
3585 /* reg reg none OR reg reg reg */
3586 /* 3-register operand order: VRA, VRB, VRT */
3587 /* 2-register operand order: VRA, VRT */
3588 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3589 } else if p.From3Type() == obj.TYPE_CONST {
3590 /* imm imm reg reg */
3591 /* operand order: SIX, VRA, ST, VRT */
3592 six := int(c.regoff(&p.From))
3593 st := int(c.regoff(p.GetFrom3()))
3594 o1 = AOP_IIRR(c.opiirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(st), uint32(six))
3595 } else if p.From3Type() == obj.TYPE_NONE && p.Reg != 0 {
3597 /* operand order: UIM, VRB, VRT */
3598 uim := int(c.regoff(&p.From))
3599 o1 = AOP_VIRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(uim))
3602 /* operand order: SIM, VRT */
3603 sim := int(c.regoff(&p.From))
3604 o1 = AOP_IR(c.opirr(p.As), uint32(p.To.Reg), uint32(sim))
3607 case 83: /* vector instructions, VA-form */
3608 if p.From.Type == obj.TYPE_REG {
3609 /* reg reg reg reg */
3610 /* 4-register operand order: VRA, VRB, VRC, VRT */
3611 o1 = AOP_RRRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3612 } else if p.From.Type == obj.TYPE_CONST {
3613 /* imm reg reg reg */
3614 /* operand order: SHB, VRA, VRB, VRT */
3615 shb := int(c.regoff(&p.From))
3616 o1 = AOP_IRRR(c.opirrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(shb))
3619 case 84: // ISEL BC,RA,RB,RT -> isel rt,ra,rb,bc
3620 bc := c.vregoff(&p.From)
3622 // rt = To.Reg, ra = p.Reg, rb = p.From3.Reg
3623 o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(bc))
3625 case 85: /* vector instructions, VX-form */
3627 /* 2-register operand order: VRB, VRT */
3628 o1 = AOP_RR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg))
3630 case 86: /* VSX indexed store, XX1-form */
3632 /* 3-register operand order: XT, (RB)(RA*1) */
3633 o1 = AOP_XX1(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3635 case 87: /* VSX indexed load, XX1-form */
3637 /* 3-register operand order: (RB)(RA*1), XT */
3638 o1 = AOP_XX1(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3640 case 88: /* VSX instructions, XX1-form */
3641 /* reg reg none OR reg reg reg */
3642 /* 3-register operand order: RA, RB, XT */
3643 /* 2-register operand order: XS, RA or RA, XT */
3644 xt := int32(p.To.Reg)
3645 xs := int32(p.From.Reg)
3646 /* We need to treat the special case of extended mnemonics that may have a FREG/VREG as an argument */
3647 if REG_V0 <= xt && xt <= REG_V31 {
3648 /* Convert V0-V31 to VS32-VS63 */
3650 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3651 } else if REG_F0 <= xt && xt <= REG_F31 {
3652 /* Convert F0-F31 to VS0-VS31 */
3654 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3655 } else if REG_VS0 <= xt && xt <= REG_VS63 {
3656 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3657 } else if REG_V0 <= xs && xs <= REG_V31 {
3658 /* Likewise for XS */
3660 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3661 } else if REG_F0 <= xs && xs <= REG_F31 {
3663 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3664 } else if REG_VS0 <= xs && xs <= REG_VS63 {
3665 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3668 case 89: /* VSX instructions, XX2-form */
3669 /* reg none reg OR reg imm reg */
3670 /* 2-register operand order: XB, XT or XB, UIM, XT*/
3671 uim := int(c.regoff(p.GetFrom3()))
3672 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(uim), uint32(p.From.Reg))
3674 case 90: /* VSX instructions, XX3-form */
3675 if p.From3Type() == obj.TYPE_NONE {
3677 /* 3-register operand order: XA, XB, XT */
3678 o1 = AOP_XX3(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3679 } else if p.From3Type() == obj.TYPE_CONST {
3680 /* reg reg reg imm */
3681 /* operand order: XA, XB, DM, XT */
3682 dm := int(c.regoff(p.GetFrom3()))
3683 o1 = AOP_XX3I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(dm))
3686 case 91: /* VSX instructions, XX4-form */
3687 /* reg reg reg reg */
3688 /* 3-register operand order: XA, XB, XC, XT */
3689 o1 = AOP_XX4(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3691 case 92: /* X-form instructions, 3-operands */
3692 if p.To.Type == obj.TYPE_CONST {
3694 xf := int32(p.From.Reg)
3695 if REG_F0 <= xf && xf <= REG_F31 {
3696 /* operand order: FRA, FRB, BF */
3697 bf := int(c.regoff(&p.To)) << 2
3698 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3700 /* operand order: RA, RB, L */
3701 l := int(c.regoff(&p.To))
3702 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.From.Reg), uint32(p.Reg))
3704 } else if p.From3Type() == obj.TYPE_CONST {
3706 /* operand order: RB, L, RA */
3707 l := int(c.regoff(p.GetFrom3()))
3708 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.To.Reg), uint32(p.From.Reg))
3709 } else if p.To.Type == obj.TYPE_REG {
3710 cr := int32(p.To.Reg)
3711 if REG_CR0 <= cr && cr <= REG_CR7 {
3713 /* operand order: RA, RB, BF */
3714 bf := (int(p.To.Reg) & 7) << 2
3715 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3716 } else if p.From.Type == obj.TYPE_CONST {
3718 /* operand order: L, RT */
3719 l := int(c.regoff(&p.From))
3720 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(l), uint32(p.Reg))
3723 case ACOPY, APASTECC:
3724 o1 = AOP_RRR(c.opirr(p.As), uint32(1), uint32(p.From.Reg), uint32(p.To.Reg))
3727 /* operand order: RS, RB, RA */
3728 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3733 case 93: /* X-form instructions, 2-operands */
3734 if p.To.Type == obj.TYPE_CONST {
3736 /* operand order: FRB, BF */
3737 bf := int(c.regoff(&p.To)) << 2
3738 o1 = AOP_RR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg))
3739 } else if p.Reg == 0 {
3740 /* popcnt* r,r, X-form */
3741 /* operand order: RS, RA */
3742 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3745 case 94: /* Z23-form instructions, 4-operands */
3746 /* reg reg reg imm */
3747 /* operand order: RA, RB, CY, RT */
3748 cy := int(c.regoff(p.GetFrom3()))
3749 o1 = AOP_Z23I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(cy))
3751 case 95: /* Retrieve TOC relative symbol */
3752 /* This code is for AIX only */
3753 v := c.vregoff(&p.From)
3755 c.ctxt.Diag("invalid offset against TOC slot %v", p)
3758 inst := c.opload(p.As)
3759 if c.opform(inst) != DS_FORM {
3760 c.ctxt.Diag("invalid form for a TOC access in %v", p)
3763 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3764 o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3765 rel := obj.Addrel(c.cursym)
3766 rel.Off = int32(c.pc)
3768 rel.Sym = p.From.Sym
3769 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
3771 case 96: /* VSX load, DQ-form */
3773 /* operand order: (RA)(DQ), XT */
3774 dq := int16(c.regoff(&p.From))
3776 c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3778 o1 = AOP_DQ(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(dq))
3780 case 97: /* VSX store, DQ-form */
3782 /* operand order: XT, (RA)(DQ) */
3783 dq := int16(c.regoff(&p.To))
3785 c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3787 o1 = AOP_DQ(c.opstore(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(dq))
3788 case 98: /* VSX indexed load or load with length (also left-justified), x-form */
3789 /* vsreg, reg, reg */
3790 o1 = AOP_XX1(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3791 case 99: /* VSX store with length (also left-justified) x-form */
3792 /* reg, reg, vsreg */
3793 o1 = AOP_XX1(c.opstore(p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(p.To.Reg))
3794 case 100: /* VSX X-form XXSPLTIB */
3795 if p.From.Type == obj.TYPE_CONST {
3797 uim := int(c.regoff(&p.From))
3799 /* Use AOP_XX1 form with 0 for one of the registers. */
3800 o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(uim))
3802 c.ctxt.Diag("invalid ops for %v", p.As)
3805 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
3807 case 102: /* RLWMI $sh,rs,$mb,$me,rt (M-form opcode)*/
3808 mb := uint32(c.regoff(&p.RestArgs[0].Addr))
3809 me := uint32(c.regoff(&p.RestArgs[1].Addr))
3810 sh := uint32(c.regoff(&p.From))
3811 o1 = OP_RLW(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), sh, mb, me)
3813 case 103: /* RLWMI rb,rs,$mb,$me,rt (M-form opcode)*/
3814 mb := uint32(c.regoff(&p.RestArgs[0].Addr))
3815 me := uint32(c.regoff(&p.RestArgs[1].Addr))
3816 o1 = OP_RLW(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), mb, me)
3826 func (c *ctxt9) vregoff(a *obj.Addr) int64 {
3834 func (c *ctxt9) regoff(a *obj.Addr) int32 {
3835 return int32(c.vregoff(a))
3838 func (c *ctxt9) oprrr(a obj.As) uint32 {
3841 return OPVCC(31, 266, 0, 0)
3843 return OPVCC(31, 266, 0, 1)
3845 return OPVCC(31, 266, 1, 0)
3847 return OPVCC(31, 266, 1, 1)
3849 return OPVCC(31, 10, 0, 0)
3851 return OPVCC(31, 10, 0, 1)
3853 return OPVCC(31, 10, 1, 0)
3855 return OPVCC(31, 10, 1, 1)
3857 return OPVCC(31, 138, 0, 0)
3859 return OPVCC(31, 138, 0, 1)
3861 return OPVCC(31, 138, 1, 0)
3863 return OPVCC(31, 138, 1, 1)
3865 return OPVCC(31, 234, 0, 0)
3867 return OPVCC(31, 234, 0, 1)
3869 return OPVCC(31, 234, 1, 0)
3871 return OPVCC(31, 234, 1, 1)
3873 return OPVCC(31, 202, 0, 0)
3875 return OPVCC(31, 202, 0, 1)
3877 return OPVCC(31, 202, 1, 0)
3879 return OPVCC(31, 202, 1, 1)
3881 return OPVCC(31, 170, 0, 0) /* addex - v3.0b */
3884 return OPVCC(31, 28, 0, 0)
3886 return OPVCC(31, 28, 0, 1)
3888 return OPVCC(31, 60, 0, 0)
3890 return OPVCC(31, 60, 0, 1)
3893 return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */
3895 return OPVCC(31, 32, 0, 0) | 1<<21
3897 return OPVCC(31, 0, 0, 0) /* L=0 */
3899 return OPVCC(31, 32, 0, 0)
3901 return OPVCC(31, 508, 0, 0) /* cmpb - v2.05 */
3903 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
3906 return OPVCC(31, 26, 0, 0)
3908 return OPVCC(31, 26, 0, 1)
3910 return OPVCC(31, 58, 0, 0)
3912 return OPVCC(31, 58, 0, 1)
3915 return OPVCC(19, 257, 0, 0)
3917 return OPVCC(19, 129, 0, 0)
3919 return OPVCC(19, 289, 0, 0)
3921 return OPVCC(19, 225, 0, 0)
3923 return OPVCC(19, 33, 0, 0)
3925 return OPVCC(19, 449, 0, 0)
3927 return OPVCC(19, 417, 0, 0)
3929 return OPVCC(19, 193, 0, 0)
3932 return OPVCC(31, 86, 0, 0)
3934 return OPVCC(31, 470, 0, 0)
3936 return OPVCC(31, 54, 0, 0)
3938 return OPVCC(31, 278, 0, 0)
3940 return OPVCC(31, 246, 0, 0)
3942 return OPVCC(31, 1014, 0, 0)
3945 return OPVCC(31, 265, 0, 0) /* modud - v3.0 */
3947 return OPVCC(31, 267, 0, 0) /* moduw - v3.0 */
3949 return OPVCC(31, 777, 0, 0) /* modsd - v3.0 */
3951 return OPVCC(31, 779, 0, 0) /* modsw - v3.0 */
3954 return OPVCC(31, 491, 0, 0)
3957 return OPVCC(31, 491, 0, 1)
3960 return OPVCC(31, 491, 1, 0)
3963 return OPVCC(31, 491, 1, 1)
3966 return OPVCC(31, 459, 0, 0)
3969 return OPVCC(31, 459, 0, 1)
3972 return OPVCC(31, 459, 1, 0)
3975 return OPVCC(31, 459, 1, 1)
3978 return OPVCC(31, 489, 0, 0)
3981 return OPVCC(31, 489, 0, 1)
3984 return OPVCC(31, 425, 0, 0)
3987 return OPVCC(31, 425, 0, 1)
3990 return OPVCC(31, 393, 0, 0)
3993 return OPVCC(31, 393, 0, 1)
3996 return OPVCC(31, 489, 1, 0)
3999 return OPVCC(31, 489, 1, 1)
4001 case ADIVDU, AREMDU:
4002 return OPVCC(31, 457, 0, 0)
4005 return OPVCC(31, 457, 0, 1)
4008 return OPVCC(31, 457, 1, 0)
4011 return OPVCC(31, 457, 1, 1)
4014 return OPVCC(31, 854, 0, 0)
4017 return OPVCC(31, 284, 0, 0)
4019 return OPVCC(31, 284, 0, 1)
4022 return OPVCC(31, 954, 0, 0)
4024 return OPVCC(31, 954, 0, 1)
4026 return OPVCC(31, 922, 0, 0)
4028 return OPVCC(31, 922, 0, 1)
4030 return OPVCC(31, 986, 0, 0)
4032 return OPVCC(31, 986, 0, 1)
4035 return OPVCC(63, 264, 0, 0)
4037 return OPVCC(63, 264, 0, 1)
4039 return OPVCC(63, 21, 0, 0)
4041 return OPVCC(63, 21, 0, 1)
4043 return OPVCC(59, 21, 0, 0)
4045 return OPVCC(59, 21, 0, 1)
4047 return OPVCC(63, 32, 0, 0)
4049 return OPVCC(63, 0, 0, 0)
4051 return OPVCC(63, 846, 0, 0)
4053 return OPVCC(63, 846, 0, 1)
4055 return OPVCC(63, 974, 0, 0)
4057 return OPVCC(63, 974, 0, 1)
4059 return OPVCC(59, 846, 0, 0)
4061 return OPVCC(59, 846, 0, 1)
4063 return OPVCC(63, 14, 0, 0)
4065 return OPVCC(63, 14, 0, 1)
4067 return OPVCC(63, 15, 0, 0)
4069 return OPVCC(63, 15, 0, 1)
4071 return OPVCC(63, 814, 0, 0)
4073 return OPVCC(63, 814, 0, 1)
4075 return OPVCC(63, 815, 0, 0)
4077 return OPVCC(63, 815, 0, 1)
4079 return OPVCC(63, 18, 0, 0)
4081 return OPVCC(63, 18, 0, 1)
4083 return OPVCC(59, 18, 0, 0)
4085 return OPVCC(59, 18, 0, 1)
4087 return OPVCC(63, 29, 0, 0)
4089 return OPVCC(63, 29, 0, 1)
4091 return OPVCC(59, 29, 0, 0)
4093 return OPVCC(59, 29, 0, 1)
4095 case AFMOVS, AFMOVD:
4096 return OPVCC(63, 72, 0, 0) /* load */
4098 return OPVCC(63, 72, 0, 1)
4100 return OPVCC(63, 28, 0, 0)
4102 return OPVCC(63, 28, 0, 1)
4104 return OPVCC(59, 28, 0, 0)
4106 return OPVCC(59, 28, 0, 1)
4108 return OPVCC(63, 25, 0, 0)
4110 return OPVCC(63, 25, 0, 1)
4112 return OPVCC(59, 25, 0, 0)
4114 return OPVCC(59, 25, 0, 1)
4116 return OPVCC(63, 136, 0, 0)
4118 return OPVCC(63, 136, 0, 1)
4120 return OPVCC(63, 40, 0, 0)
4122 return OPVCC(63, 40, 0, 1)
4124 return OPVCC(63, 31, 0, 0)
4126 return OPVCC(63, 31, 0, 1)
4128 return OPVCC(59, 31, 0, 0)
4130 return OPVCC(59, 31, 0, 1)
4132 return OPVCC(63, 30, 0, 0)
4134 return OPVCC(63, 30, 0, 1)
4136 return OPVCC(59, 30, 0, 0)
4138 return OPVCC(59, 30, 0, 1)
4140 return OPVCC(63, 8, 0, 0)
4142 return OPVCC(63, 8, 0, 1)
4144 return OPVCC(59, 24, 0, 0)
4146 return OPVCC(59, 24, 0, 1)
4148 return OPVCC(63, 488, 0, 0)
4150 return OPVCC(63, 488, 0, 1)
4152 return OPVCC(63, 456, 0, 0)
4154 return OPVCC(63, 456, 0, 1)
4156 return OPVCC(63, 424, 0, 0)
4158 return OPVCC(63, 424, 0, 1)
4160 return OPVCC(63, 392, 0, 0)
4162 return OPVCC(63, 392, 0, 1)
4164 return OPVCC(63, 12, 0, 0)
4166 return OPVCC(63, 12, 0, 1)
4168 return OPVCC(63, 26, 0, 0)
4170 return OPVCC(63, 26, 0, 1)
4172 return OPVCC(63, 23, 0, 0)
4174 return OPVCC(63, 23, 0, 1)
4176 return OPVCC(63, 22, 0, 0)
4178 return OPVCC(63, 22, 0, 1)
4180 return OPVCC(59, 22, 0, 0)
4182 return OPVCC(59, 22, 0, 1)
4184 return OPVCC(63, 20, 0, 0)
4186 return OPVCC(63, 20, 0, 1)
4188 return OPVCC(59, 20, 0, 0)
4190 return OPVCC(59, 20, 0, 1)
4193 return OPVCC(31, 982, 0, 0)
4195 return OPVCC(19, 150, 0, 0)
4198 return OPVCC(63, 70, 0, 0)
4200 return OPVCC(63, 70, 0, 1)
4202 return OPVCC(63, 38, 0, 0)
4204 return OPVCC(63, 38, 0, 1)
4207 return OPVCC(31, 75, 0, 0)
4209 return OPVCC(31, 75, 0, 1)
4211 return OPVCC(31, 11, 0, 0)
4213 return OPVCC(31, 11, 0, 1)
4215 return OPVCC(31, 235, 0, 0)
4217 return OPVCC(31, 235, 0, 1)
4219 return OPVCC(31, 235, 1, 0)
4221 return OPVCC(31, 235, 1, 1)
4224 return OPVCC(31, 73, 0, 0)
4226 return OPVCC(31, 73, 0, 1)
4228 return OPVCC(31, 9, 0, 0)
4230 return OPVCC(31, 9, 0, 1)
4232 return OPVCC(31, 233, 0, 0)
4234 return OPVCC(31, 233, 0, 1)
4236 return OPVCC(31, 233, 1, 0)
4238 return OPVCC(31, 233, 1, 1)
4241 return OPVCC(31, 476, 0, 0)
4243 return OPVCC(31, 476, 0, 1)
4245 return OPVCC(31, 104, 0, 0)
4247 return OPVCC(31, 104, 0, 1)
4249 return OPVCC(31, 104, 1, 0)
4251 return OPVCC(31, 104, 1, 1)
4253 return OPVCC(31, 124, 0, 0)
4255 return OPVCC(31, 124, 0, 1)
4257 return OPVCC(31, 444, 0, 0)
4259 return OPVCC(31, 444, 0, 1)
4261 return OPVCC(31, 412, 0, 0)
4263 return OPVCC(31, 412, 0, 1)
4266 return OPVCC(31, 506, 0, 0) /* popcntd - v2.06 */
4268 return OPVCC(31, 378, 0, 0) /* popcntw - v2.06 */
4270 return OPVCC(31, 122, 0, 0) /* popcntb - v2.02 */
4272 return OPVCC(31, 538, 0, 0) /* cnttzw - v3.00 */
4274 return OPVCC(31, 538, 0, 1) /* cnttzw. - v3.00 */
4276 return OPVCC(31, 570, 0, 0) /* cnttzd - v3.00 */
4278 return OPVCC(31, 570, 0, 1) /* cnttzd. - v3.00 */
4281 return OPVCC(19, 50, 0, 0)
4283 return OPVCC(19, 51, 0, 0)
4285 return OPVCC(19, 18, 0, 0)
4287 return OPVCC(19, 274, 0, 0)
4290 return OPVCC(20, 0, 0, 0)
4292 return OPVCC(20, 0, 0, 1)
4294 return OPVCC(23, 0, 0, 0)
4296 return OPVCC(23, 0, 0, 1)
4299 return OPVCC(30, 8, 0, 0)
4301 return OPVCC(30, 0, 0, 1)
4304 return OPVCC(30, 9, 0, 0)
4306 return OPVCC(30, 9, 0, 1)
4309 return OPVCC(30, 0, 0, 0)
4311 return OPVCC(30, 0, 0, 1)
4313 return OPVCC(30, 0, 0, 0) | 2<<1 // rldicr
4315 return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr.
4318 return OPVCC(30, 0, 0, 0) | 4<<1 // rldic
4320 return OPVCC(30, 0, 0, 1) | 4<<1 // rldic.
4323 return OPVCC(17, 1, 0, 0)
4326 return OPVCC(31, 24, 0, 0)
4328 return OPVCC(31, 24, 0, 1)
4330 return OPVCC(31, 27, 0, 0)
4332 return OPVCC(31, 27, 0, 1)
4335 return OPVCC(31, 792, 0, 0)
4337 return OPVCC(31, 792, 0, 1)
4339 return OPVCC(31, 794, 0, 0)
4341 return OPVCC(31, 794, 0, 1)
4344 return OPVCC(31, 445, 0, 0)
4346 return OPVCC(31, 445, 0, 1)
4349 return OPVCC(31, 536, 0, 0)
4351 return OPVCC(31, 536, 0, 1)
4353 return OPVCC(31, 539, 0, 0)
4355 return OPVCC(31, 539, 0, 1)
4358 return OPVCC(31, 40, 0, 0)
4360 return OPVCC(31, 40, 0, 1)
4362 return OPVCC(31, 40, 1, 0)
4364 return OPVCC(31, 40, 1, 1)
4366 return OPVCC(31, 8, 0, 0)
4368 return OPVCC(31, 8, 0, 1)
4370 return OPVCC(31, 8, 1, 0)
4372 return OPVCC(31, 8, 1, 1)
4374 return OPVCC(31, 136, 0, 0)
4376 return OPVCC(31, 136, 0, 1)
4378 return OPVCC(31, 136, 1, 0)
4380 return OPVCC(31, 136, 1, 1)
4382 return OPVCC(31, 232, 0, 0)
4384 return OPVCC(31, 232, 0, 1)
4386 return OPVCC(31, 232, 1, 0)
4388 return OPVCC(31, 232, 1, 1)
4390 return OPVCC(31, 200, 0, 0)
4392 return OPVCC(31, 200, 0, 1)
4394 return OPVCC(31, 200, 1, 0)
4396 return OPVCC(31, 200, 1, 1)
4399 return OPVCC(31, 598, 0, 0)
4401 return OPVCC(31, 598, 0, 0) | 1<<21
4404 return OPVCC(31, 598, 0, 0) | 2<<21
4407 return OPVCC(31, 306, 0, 0)
4409 return OPVCC(31, 274, 0, 0)
4411 return OPVCC(31, 566, 0, 0)
4413 return OPVCC(31, 498, 0, 0)
4415 return OPVCC(31, 434, 0, 0)
4417 return OPVCC(31, 915, 0, 0)
4419 return OPVCC(31, 851, 0, 0)
4421 return OPVCC(31, 402, 0, 0)
4424 return OPVCC(31, 4, 0, 0)
4426 return OPVCC(31, 68, 0, 0)
4428 /* Vector (VMX/Altivec) instructions */
4429 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4430 /* are enabled starting at POWER6 (ISA 2.05). */
4432 return OPVX(4, 1028, 0, 0) /* vand - v2.03 */
4434 return OPVX(4, 1092, 0, 0) /* vandc - v2.03 */
4436 return OPVX(4, 1412, 0, 0) /* vnand - v2.07 */
4439 return OPVX(4, 1156, 0, 0) /* vor - v2.03 */
4441 return OPVX(4, 1348, 0, 0) /* vorc - v2.07 */
4443 return OPVX(4, 1284, 0, 0) /* vnor - v2.03 */
4445 return OPVX(4, 1220, 0, 0) /* vxor - v2.03 */
4447 return OPVX(4, 1668, 0, 0) /* veqv - v2.07 */
4450 return OPVX(4, 0, 0, 0) /* vaddubm - v2.03 */
4452 return OPVX(4, 64, 0, 0) /* vadduhm - v2.03 */
4454 return OPVX(4, 128, 0, 0) /* vadduwm - v2.03 */
4456 return OPVX(4, 192, 0, 0) /* vaddudm - v2.07 */
4458 return OPVX(4, 256, 0, 0) /* vadduqm - v2.07 */
4461 return OPVX(4, 320, 0, 0) /* vaddcuq - v2.07 */
4463 return OPVX(4, 384, 0, 0) /* vaddcuw - v2.03 */
4466 return OPVX(4, 512, 0, 0) /* vaddubs - v2.03 */
4468 return OPVX(4, 576, 0, 0) /* vadduhs - v2.03 */
4470 return OPVX(4, 640, 0, 0) /* vadduws - v2.03 */
4473 return OPVX(4, 768, 0, 0) /* vaddsbs - v2.03 */
4475 return OPVX(4, 832, 0, 0) /* vaddshs - v2.03 */
4477 return OPVX(4, 896, 0, 0) /* vaddsws - v2.03 */
4480 return OPVX(4, 60, 0, 0) /* vaddeuqm - v2.07 */
4482 return OPVX(4, 61, 0, 0) /* vaddecuq - v2.07 */
4485 return OPVX(4, 776, 0, 0) /* vmulesb - v2.03 */
4487 return OPVX(4, 264, 0, 0) /* vmulosb - v2.03 */
4489 return OPVX(4, 520, 0, 0) /* vmuleub - v2.03 */
4491 return OPVX(4, 8, 0, 0) /* vmuloub - v2.03 */
4493 return OPVX(4, 840, 0, 0) /* vmulesh - v2.03 */
4495 return OPVX(4, 328, 0, 0) /* vmulosh - v2.03 */
4497 return OPVX(4, 584, 0, 0) /* vmuleuh - v2.03 */
4499 return OPVX(4, 72, 0, 0) /* vmulouh - v2.03 */
4501 return OPVX(4, 904, 0, 0) /* vmulesw - v2.07 */
4503 return OPVX(4, 392, 0, 0) /* vmulosw - v2.07 */
4505 return OPVX(4, 648, 0, 0) /* vmuleuw - v2.07 */
4507 return OPVX(4, 136, 0, 0) /* vmulouw - v2.07 */
4509 return OPVX(4, 137, 0, 0) /* vmuluwm - v2.07 */
4512 return OPVX(4, 1032, 0, 0) /* vpmsumb - v2.07 */
4514 return OPVX(4, 1096, 0, 0) /* vpmsumh - v2.07 */
4516 return OPVX(4, 1160, 0, 0) /* vpmsumw - v2.07 */
4518 return OPVX(4, 1224, 0, 0) /* vpmsumd - v2.07 */
4521 return OPVX(4, 35, 0, 0) /* vmsumudm - v3.00b */
4524 return OPVX(4, 1024, 0, 0) /* vsububm - v2.03 */
4526 return OPVX(4, 1088, 0, 0) /* vsubuhm - v2.03 */
4528 return OPVX(4, 1152, 0, 0) /* vsubuwm - v2.03 */
4530 return OPVX(4, 1216, 0, 0) /* vsubudm - v2.07 */
4532 return OPVX(4, 1280, 0, 0) /* vsubuqm - v2.07 */
4535 return OPVX(4, 1344, 0, 0) /* vsubcuq - v2.07 */
4537 return OPVX(4, 1408, 0, 0) /* vsubcuw - v2.03 */
4540 return OPVX(4, 1536, 0, 0) /* vsububs - v2.03 */
4542 return OPVX(4, 1600, 0, 0) /* vsubuhs - v2.03 */
4544 return OPVX(4, 1664, 0, 0) /* vsubuws - v2.03 */
4547 return OPVX(4, 1792, 0, 0) /* vsubsbs - v2.03 */
4549 return OPVX(4, 1856, 0, 0) /* vsubshs - v2.03 */
4551 return OPVX(4, 1920, 0, 0) /* vsubsws - v2.03 */
4554 return OPVX(4, 62, 0, 0) /* vsubeuqm - v2.07 */
4556 return OPVX(4, 63, 0, 0) /* vsubecuq - v2.07 */
4559 return OPVX(4, 4, 0, 0) /* vrlb - v2.03 */
4561 return OPVX(4, 68, 0, 0) /* vrlh - v2.03 */
4563 return OPVX(4, 132, 0, 0) /* vrlw - v2.03 */
4565 return OPVX(4, 196, 0, 0) /* vrld - v2.07 */
4568 return OPVX(4, 1676, 0, 0) /* vmrgow - v2.07 */
4570 return OPVX(4, 1932, 0, 0) /* vmrgew - v2.07 */
4573 return OPVX(4, 260, 0, 0) /* vslh - v2.03 */
4575 return OPVX(4, 324, 0, 0) /* vslh - v2.03 */
4577 return OPVX(4, 388, 0, 0) /* vslw - v2.03 */
4579 return OPVX(4, 452, 0, 0) /* vsl - v2.03 */
4581 return OPVX(4, 1036, 0, 0) /* vsl - v2.03 */
4583 return OPVX(4, 516, 0, 0) /* vsrb - v2.03 */
4585 return OPVX(4, 580, 0, 0) /* vsrh - v2.03 */
4587 return OPVX(4, 644, 0, 0) /* vsrw - v2.03 */
4589 return OPVX(4, 708, 0, 0) /* vsr - v2.03 */
4591 return OPVX(4, 1100, 0, 0) /* vsro - v2.03 */
4593 return OPVX(4, 1476, 0, 0) /* vsld - v2.07 */
4595 return OPVX(4, 1732, 0, 0) /* vsrd - v2.07 */
4598 return OPVX(4, 772, 0, 0) /* vsrab - v2.03 */
4600 return OPVX(4, 836, 0, 0) /* vsrah - v2.03 */
4602 return OPVX(4, 900, 0, 0) /* vsraw - v2.03 */
4604 return OPVX(4, 964, 0, 0) /* vsrad - v2.07 */
4607 return OPVC(4, 1356, 0, 0) /* vbpermq - v2.07 */
4609 return OPVC(4, 1484, 0, 0) /* vbpermd - v3.00 */
4612 return OPVX(4, 1794, 0, 0) /* vclzb - v2.07 */
4614 return OPVX(4, 1858, 0, 0) /* vclzh - v2.07 */
4616 return OPVX(4, 1922, 0, 0) /* vclzw - v2.07 */
4618 return OPVX(4, 1986, 0, 0) /* vclzd - v2.07 */
4621 return OPVX(4, 1795, 0, 0) /* vpopcntb - v2.07 */
4623 return OPVX(4, 1859, 0, 0) /* vpopcnth - v2.07 */
4625 return OPVX(4, 1923, 0, 0) /* vpopcntw - v2.07 */
4627 return OPVX(4, 1987, 0, 0) /* vpopcntd - v2.07 */
4630 return OPVC(4, 6, 0, 0) /* vcmpequb - v2.03 */
4632 return OPVC(4, 6, 0, 1) /* vcmpequb. - v2.03 */
4634 return OPVC(4, 70, 0, 0) /* vcmpequh - v2.03 */
4636 return OPVC(4, 70, 0, 1) /* vcmpequh. - v2.03 */
4638 return OPVC(4, 134, 0, 0) /* vcmpequw - v2.03 */
4640 return OPVC(4, 134, 0, 1) /* vcmpequw. - v2.03 */
4642 return OPVC(4, 199, 0, 0) /* vcmpequd - v2.07 */
4644 return OPVC(4, 199, 0, 1) /* vcmpequd. - v2.07 */
4647 return OPVC(4, 518, 0, 0) /* vcmpgtub - v2.03 */
4649 return OPVC(4, 518, 0, 1) /* vcmpgtub. - v2.03 */
4651 return OPVC(4, 582, 0, 0) /* vcmpgtuh - v2.03 */
4653 return OPVC(4, 582, 0, 1) /* vcmpgtuh. - v2.03 */
4655 return OPVC(4, 646, 0, 0) /* vcmpgtuw - v2.03 */
4657 return OPVC(4, 646, 0, 1) /* vcmpgtuw. - v2.03 */
4659 return OPVC(4, 711, 0, 0) /* vcmpgtud - v2.07 */
4661 return OPVC(4, 711, 0, 1) /* vcmpgtud. v2.07 */
4663 return OPVC(4, 774, 0, 0) /* vcmpgtsb - v2.03 */
4665 return OPVC(4, 774, 0, 1) /* vcmpgtsb. - v2.03 */
4667 return OPVC(4, 838, 0, 0) /* vcmpgtsh - v2.03 */
4669 return OPVC(4, 838, 0, 1) /* vcmpgtsh. - v2.03 */
4671 return OPVC(4, 902, 0, 0) /* vcmpgtsw - v2.03 */
4673 return OPVC(4, 902, 0, 1) /* vcmpgtsw. - v2.03 */
4675 return OPVC(4, 967, 0, 0) /* vcmpgtsd - v2.07 */
4677 return OPVC(4, 967, 0, 1) /* vcmpgtsd. - v2.07 */
4680 return OPVC(4, 263, 0, 0) /* vcmpnezb - v3.00 */
4682 return OPVC(4, 263, 0, 1) /* vcmpnezb. - v3.00 */
4684 return OPVC(4, 7, 0, 0) /* vcmpneb - v3.00 */
4686 return OPVC(4, 7, 0, 1) /* vcmpneb. - v3.00 */
4688 return OPVC(4, 71, 0, 0) /* vcmpneh - v3.00 */
4690 return OPVC(4, 71, 0, 1) /* vcmpneh. - v3.00 */
4692 return OPVC(4, 135, 0, 0) /* vcmpnew - v3.00 */
4694 return OPVC(4, 135, 0, 1) /* vcmpnew. - v3.00 */
4697 return OPVX(4, 43, 0, 0) /* vperm - v2.03 */
4699 return OPVX(4, 45, 0, 0) /* vpermxor - v2.03 */
4701 return OPVX(4, 59, 0, 0) /* vpermr - v3.0 */
4704 return OPVX(4, 42, 0, 0) /* vsel - v2.03 */
4707 return OPVX(4, 1288, 0, 0) /* vcipher - v2.07 */
4709 return OPVX(4, 1289, 0, 0) /* vcipherlast - v2.07 */
4711 return OPVX(4, 1352, 0, 0) /* vncipher - v2.07 */
4713 return OPVX(4, 1353, 0, 0) /* vncipherlast - v2.07 */
4715 return OPVX(4, 1480, 0, 0) /* vsbox - v2.07 */
4716 /* End of vector instructions */
4718 /* Vector scalar (VSX) instructions */
4719 /* ISA 2.06 enables these for POWER7. */
4720 case AMFVSRD, AMFVRD, AMFFPRD:
4721 return OPVXX1(31, 51, 0) /* mfvsrd - v2.07 */
4723 return OPVXX1(31, 115, 0) /* mfvsrwz - v2.07 */
4725 return OPVXX1(31, 307, 0) /* mfvsrld - v3.00 */
4727 case AMTVSRD, AMTFPRD, AMTVRD:
4728 return OPVXX1(31, 179, 0) /* mtvsrd - v2.07 */
4730 return OPVXX1(31, 211, 0) /* mtvsrwa - v2.07 */
4732 return OPVXX1(31, 243, 0) /* mtvsrwz - v2.07 */
4734 return OPVXX1(31, 435, 0) /* mtvsrdd - v3.00 */
4736 return OPVXX1(31, 403, 0) /* mtvsrws - v3.00 */
4739 return OPVXX3(60, 130, 0) /* xxland - v2.06 */
4741 return OPVXX3(60, 138, 0) /* xxlandc - v2.06 */
4743 return OPVXX3(60, 186, 0) /* xxleqv - v2.07 */
4745 return OPVXX3(60, 178, 0) /* xxlnand - v2.07 */
4748 return OPVXX3(60, 170, 0) /* xxlorc - v2.07 */
4750 return OPVXX3(60, 162, 0) /* xxlnor - v2.06 */
4751 case AXXLOR, AXXLORQ:
4752 return OPVXX3(60, 146, 0) /* xxlor - v2.06 */
4754 return OPVXX3(60, 154, 0) /* xxlxor - v2.06 */
4757 return OPVXX4(60, 3, 0) /* xxsel - v2.06 */
4760 return OPVXX3(60, 18, 0) /* xxmrghw - v2.06 */
4762 return OPVXX3(60, 50, 0) /* xxmrglw - v2.06 */
4765 return OPVXX2(60, 164, 0) /* xxspltw - v2.06 */
4768 return OPVCC(60, 360, 0, 0) /* xxspltib - v3.0 */
4771 return OPVXX3(60, 26, 0) /* xxperm - v2.06 */
4773 return OPVXX3(60, 10, 0) /* xxpermdi - v2.06 */
4776 return OPVXX3(60, 2, 0) /* xxsldwi - v2.06 */
4779 return OPVXX2VA(60, 475, 31) /* xxbrq - v3.0 */
4781 return OPVXX2VA(60, 475, 23) /* xxbrd - v3.0 */
4783 return OPVXX2VA(60, 475, 15) /* xxbrw - v3.0 */
4785 return OPVXX2VA(60, 475, 7) /* xxbrh - v3.0 */
4788 return OPVXX2(60, 265, 0) /* xscvdpsp - v2.06 */
4790 return OPVXX2(60, 329, 0) /* xscvspdp - v2.06 */
4792 return OPVXX2(60, 267, 0) /* xscvdpspn - v2.07 */
4794 return OPVXX2(60, 331, 0) /* xscvspdpn - v2.07 */
4797 return OPVXX2(60, 393, 0) /* xvcvdpsp - v2.06 */
4799 return OPVXX2(60, 457, 0) /* xvcvspdp - v2.06 */
4802 return OPVXX2(60, 344, 0) /* xscvdpsxds - v2.06 */
4804 return OPVXX2(60, 88, 0) /* xscvdpsxws - v2.06 */
4806 return OPVXX2(60, 328, 0) /* xscvdpuxds - v2.06 */
4808 return OPVXX2(60, 72, 0) /* xscvdpuxws - v2.06 */
4811 return OPVXX2(60, 376, 0) /* xscvsxddp - v2.06 */
4813 return OPVXX2(60, 360, 0) /* xscvuxddp - v2.06 */
4815 return OPVXX2(60, 312, 0) /* xscvsxdsp - v2.06 */
4817 return OPVXX2(60, 296, 0) /* xscvuxdsp - v2.06 */
4820 return OPVXX2(60, 472, 0) /* xvcvdpsxds - v2.06 */
4822 return OPVXX2(60, 216, 0) /* xvcvdpsxws - v2.06 */
4824 return OPVXX2(60, 456, 0) /* xvcvdpuxds - v2.06 */
4826 return OPVXX2(60, 200, 0) /* xvcvdpuxws - v2.06 */
4828 return OPVXX2(60, 408, 0) /* xvcvspsxds - v2.07 */
4830 return OPVXX2(60, 152, 0) /* xvcvspsxws - v2.07 */
4832 return OPVXX2(60, 392, 0) /* xvcvspuxds - v2.07 */
4834 return OPVXX2(60, 136, 0) /* xvcvspuxws - v2.07 */
4837 return OPVXX2(60, 504, 0) /* xvcvsxddp - v2.06 */
4839 return OPVXX2(60, 248, 0) /* xvcvsxwdp - v2.06 */
4841 return OPVXX2(60, 488, 0) /* xvcvuxddp - v2.06 */
4843 return OPVXX2(60, 232, 0) /* xvcvuxwdp - v2.06 */
4845 return OPVXX2(60, 440, 0) /* xvcvsxdsp - v2.06 */
4847 return OPVXX2(60, 184, 0) /* xvcvsxwsp - v2.06 */
4849 return OPVXX2(60, 424, 0) /* xvcvuxdsp - v2.06 */
4851 return OPVXX2(60, 168, 0) /* xvcvuxwsp - v2.06 */
4852 /* End of VSX instructions */
4855 return OPVX(4, 48, 0, 0) /* maddhd - v3.00 */
4857 return OPVX(4, 49, 0, 0) /* maddhdu - v3.00 */
4859 return OPVX(4, 51, 0, 0) /* maddld - v3.00 */
4862 return OPVCC(31, 316, 0, 0)
4864 return OPVCC(31, 316, 0, 1)
4867 c.ctxt.Diag("bad r/r, r/r/r or r/r/r/r opcode %v", a)
4871 func (c *ctxt9) opirrr(a obj.As) uint32 {
4873 /* Vector (VMX/Altivec) instructions */
4874 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4875 /* are enabled starting at POWER6 (ISA 2.05). */
4877 return OPVX(4, 44, 0, 0) /* vsldoi - v2.03 */
4880 c.ctxt.Diag("bad i/r/r/r opcode %v", a)
4884 func (c *ctxt9) opiirr(a obj.As) uint32 {
4886 /* Vector (VMX/Altivec) instructions */
4887 /* ISA 2.07 enables these for POWER8 and beyond. */
4889 return OPVX(4, 1666, 0, 0) /* vshasigmaw - v2.07 */
4891 return OPVX(4, 1730, 0, 0) /* vshasigmad - v2.07 */
4894 c.ctxt.Diag("bad i/i/r/r opcode %v", a)
4898 func (c *ctxt9) opirr(a obj.As) uint32 {
4901 return OPVCC(14, 0, 0, 0)
4903 return OPVCC(12, 0, 0, 0)
4905 return OPVCC(13, 0, 0, 0)
4907 return OPVCC(15, 0, 0, 0) /* ADDIS */
4910 return OPVCC(28, 0, 0, 0)
4912 return OPVCC(29, 0, 0, 0) /* ANDIS. */
4915 return OPVCC(18, 0, 0, 0)
4917 return OPVCC(18, 0, 0, 0) | 1
4919 return OPVCC(18, 0, 0, 0) | 1
4921 return OPVCC(18, 0, 0, 0) | 1
4923 return OPVCC(16, 0, 0, 0)
4925 return OPVCC(16, 0, 0, 0) | 1
4928 return AOP_RRR(16<<26, 12, 2, 0)
4930 return AOP_RRR(16<<26, 4, 0, 0)
4932 return AOP_RRR(16<<26, 12, 1, 0)
4934 return AOP_RRR(16<<26, 4, 1, 0)
4936 return AOP_RRR(16<<26, 12, 0, 0)
4938 return AOP_RRR(16<<26, 4, 2, 0)
4940 return AOP_RRR(16<<26, 4, 3, 0) // apparently unordered-clear
4942 return AOP_RRR(16<<26, 12, 3, 0) // apparently unordered-set
4945 return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */
4947 return OPVCC(10, 0, 0, 0) | 1<<21
4949 return OPVCC(11, 0, 0, 0) /* L=0 */
4951 return OPVCC(10, 0, 0, 0)
4953 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
4956 return OPVCC(31, 597, 0, 0)
4959 return OPVCC(31, 774, 0, 0) /* copy - v3.00 */
4961 return OPVCC(31, 902, 0, 1) /* paste. - v3.00 */
4963 return OPVCC(31, 755, 0, 0) /* darn - v3.00 */
4965 case AMULLW, AMULLD:
4966 return OPVCC(7, 0, 0, 0) /* mulli works with MULLW or MULLD */
4969 return OPVCC(24, 0, 0, 0)
4971 return OPVCC(25, 0, 0, 0) /* ORIS */
4974 return OPVCC(20, 0, 0, 0) /* rlwimi */
4976 return OPVCC(20, 0, 0, 1)
4978 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
4980 return OPVCC(30, 0, 0, 1) | 3<<2
4982 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
4984 return OPVCC(30, 0, 0, 1) | 3<<2
4986 return OPVCC(21, 0, 0, 0) /* rlwinm */
4988 return OPVCC(21, 0, 0, 1)
4991 return OPVCC(30, 0, 0, 0) /* rldicl */
4993 return OPVCC(30, 0, 0, 1)
4995 return OPVCC(30, 1, 0, 0) /* rldicr */
4997 return OPVCC(30, 1, 0, 1)
4999 return OPVCC(30, 0, 0, 0) | 2<<2
5001 return OPVCC(30, 0, 0, 1) | 2<<2
5004 return OPVCC(31, 824, 0, 0)
5006 return OPVCC(31, 824, 0, 1)
5008 return OPVCC(31, (413 << 1), 0, 0)
5010 return OPVCC(31, (413 << 1), 0, 1)
5012 return OPVCC(31, 445, 0, 0)
5014 return OPVCC(31, 445, 0, 1)
5017 return OPVCC(31, 725, 0, 0)
5020 return OPVCC(8, 0, 0, 0)
5023 return OPVCC(3, 0, 0, 0)
5025 return OPVCC(2, 0, 0, 0)
5027 /* Vector (VMX/Altivec) instructions */
5028 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
5029 /* are enabled starting at POWER6 (ISA 2.05). */
5031 return OPVX(4, 524, 0, 0) /* vspltb - v2.03 */
5033 return OPVX(4, 588, 0, 0) /* vsplth - v2.03 */
5035 return OPVX(4, 652, 0, 0) /* vspltw - v2.03 */
5038 return OPVX(4, 780, 0, 0) /* vspltisb - v2.03 */
5040 return OPVX(4, 844, 0, 0) /* vspltish - v2.03 */
5042 return OPVX(4, 908, 0, 0) /* vspltisw - v2.03 */
5043 /* End of vector instructions */
5046 return OPVCC(63, 128, 0, 0) /* ftdiv - v2.06 */
5048 return OPVCC(63, 160, 0, 0) /* ftsqrt - v2.06 */
5051 return OPVCC(26, 0, 0, 0) /* XORIL */
5053 return OPVCC(27, 0, 0, 0) /* XORIS */
5056 c.ctxt.Diag("bad opcode i/r or i/r/r %v", a)
5063 func (c *ctxt9) opload(a obj.As) uint32 {
5066 return OPVCC(58, 0, 0, 0) /* ld */
5068 return OPVCC(58, 0, 0, 1) /* ldu */
5070 return OPVCC(32, 0, 0, 0) /* lwz */
5072 return OPVCC(33, 0, 0, 0) /* lwzu */
5074 return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */
5076 return OPDQ(61, 1, 0) /* lxv - ISA v3.0 */
5078 return OPVXX1(31, 269, 0) /* lxvl - ISA v3.0 */
5080 return OPVXX1(31, 301, 0) /* lxvll - ISA v3.0 */
5082 return OPVXX1(31, 268, 0) /* lxvx - ISA v3.0 */
5086 return OPVCC(34, 0, 0, 0)
5089 case AMOVBU, AMOVBZU:
5090 return OPVCC(35, 0, 0, 0)
5092 return OPVCC(50, 0, 0, 0)
5094 return OPVCC(51, 0, 0, 0)
5096 return OPVCC(48, 0, 0, 0)
5098 return OPVCC(49, 0, 0, 0)
5100 return OPVCC(42, 0, 0, 0)
5102 return OPVCC(43, 0, 0, 0)
5104 return OPVCC(40, 0, 0, 0)
5106 return OPVCC(41, 0, 0, 0)
5108 return OPVCC(46, 0, 0, 0) /* lmw */
5111 c.ctxt.Diag("bad load opcode %v", a)
5116 * indexed load a(b),d
5118 func (c *ctxt9) oploadx(a obj.As) uint32 {
5121 return OPVCC(31, 23, 0, 0) /* lwzx */
5123 return OPVCC(31, 55, 0, 0) /* lwzux */
5125 return OPVCC(31, 341, 0, 0) /* lwax */
5127 return OPVCC(31, 373, 0, 0) /* lwaux */
5130 return OPVCC(31, 87, 0, 0) /* lbzx */
5132 case AMOVBU, AMOVBZU:
5133 return OPVCC(31, 119, 0, 0) /* lbzux */
5135 return OPVCC(31, 599, 0, 0) /* lfdx */
5137 return OPVCC(31, 631, 0, 0) /* lfdux */
5139 return OPVCC(31, 535, 0, 0) /* lfsx */
5141 return OPVCC(31, 567, 0, 0) /* lfsux */
5143 return OPVCC(31, 855, 0, 0) /* lfiwax - power6, isa 2.05 */
5145 return OPVCC(31, 887, 0, 0) /* lfiwzx - power7, isa 2.06 */
5147 return OPVCC(31, 343, 0, 0) /* lhax */
5149 return OPVCC(31, 375, 0, 0) /* lhaux */
5151 return OPVCC(31, 790, 0, 0) /* lhbrx */
5153 return OPVCC(31, 534, 0, 0) /* lwbrx */
5155 return OPVCC(31, 532, 0, 0) /* ldbrx */
5157 return OPVCC(31, 279, 0, 0) /* lhzx */
5159 return OPVCC(31, 311, 0, 0) /* lhzux */
5161 return OPVCC(31, 310, 0, 0) /* eciwx */
5163 return OPVCC(31, 52, 0, 0) /* lbarx */
5165 return OPVCC(31, 116, 0, 0) /* lharx */
5167 return OPVCC(31, 20, 0, 0) /* lwarx */
5169 return OPVCC(31, 84, 0, 0) /* ldarx */
5171 return OPVCC(31, 533, 0, 0) /* lswx */
5173 return OPVCC(31, 21, 0, 0) /* ldx */
5175 return OPVCC(31, 53, 0, 0) /* ldux */
5177 return OPVCC(31, 309, 0, 0) /* ldmx */
5179 /* Vector (VMX/Altivec) instructions */
5181 return OPVCC(31, 7, 0, 0) /* lvebx - v2.03 */
5183 return OPVCC(31, 39, 0, 0) /* lvehx - v2.03 */
5185 return OPVCC(31, 71, 0, 0) /* lvewx - v2.03 */
5187 return OPVCC(31, 103, 0, 0) /* lvx - v2.03 */
5189 return OPVCC(31, 359, 0, 0) /* lvxl - v2.03 */
5191 return OPVCC(31, 6, 0, 0) /* lvsl - v2.03 */
5193 return OPVCC(31, 38, 0, 0) /* lvsr - v2.03 */
5194 /* End of vector instructions */
5196 /* Vector scalar (VSX) instructions */
5198 return OPVXX1(31, 268, 0) /* lxvx - ISA v3.0 */
5200 return OPVXX1(31, 844, 0) /* lxvd2x - v2.06 */
5202 return OPVXX1(31, 780, 0) /* lxvw4x - v2.06 */
5204 return OPVXX1(31, 812, 0) /* lxvh8x - v3.00 */
5206 return OPVXX1(31, 876, 0) /* lxvb16x - v3.00 */
5208 return OPVXX1(31, 332, 0) /* lxvdsx - v2.06 */
5210 return OPVXX1(31, 588, 0) /* lxsdx - v2.06 */
5212 return OPVXX1(31, 76, 0) /* lxsiwax - v2.07 */
5214 return OPVXX1(31, 12, 0) /* lxsiwzx - v2.07 */
5217 c.ctxt.Diag("bad loadx opcode %v", a)
5224 func (c *ctxt9) opstore(a obj.As) uint32 {
5227 return OPVCC(38, 0, 0, 0) /* stb */
5229 case AMOVBU, AMOVBZU:
5230 return OPVCC(39, 0, 0, 0) /* stbu */
5232 return OPVCC(54, 0, 0, 0) /* stfd */
5234 return OPVCC(55, 0, 0, 0) /* stfdu */
5236 return OPVCC(52, 0, 0, 0) /* stfs */
5238 return OPVCC(53, 0, 0, 0) /* stfsu */
5241 return OPVCC(44, 0, 0, 0) /* sth */
5243 case AMOVHZU, AMOVHU:
5244 return OPVCC(45, 0, 0, 0) /* sthu */
5246 return OPVCC(47, 0, 0, 0) /* stmw */
5248 return OPVCC(31, 725, 0, 0) /* stswi */
5251 return OPVCC(36, 0, 0, 0) /* stw */
5253 case AMOVWZU, AMOVWU:
5254 return OPVCC(37, 0, 0, 0) /* stwu */
5256 return OPVCC(62, 0, 0, 0) /* std */
5258 return OPVCC(62, 0, 0, 1) /* stdu */
5260 return OPDQ(61, 5, 0) /* stxv ISA 3.0 */
5262 return OPVXX1(31, 397, 0) /* stxvl ISA 3.0 */
5264 return OPVXX1(31, 429, 0) /* stxvll ISA 3.0 */
5266 return OPVXX1(31, 396, 0) /* stxvx - ISA v3.0 */
5270 c.ctxt.Diag("unknown store opcode %v", a)
5275 * indexed store s,a(b)
5277 func (c *ctxt9) opstorex(a obj.As) uint32 {
5280 return OPVCC(31, 215, 0, 0) /* stbx */
5282 case AMOVBU, AMOVBZU:
5283 return OPVCC(31, 247, 0, 0) /* stbux */
5285 return OPVCC(31, 727, 0, 0) /* stfdx */
5287 return OPVCC(31, 759, 0, 0) /* stfdux */
5289 return OPVCC(31, 663, 0, 0) /* stfsx */
5291 return OPVCC(31, 695, 0, 0) /* stfsux */
5293 return OPVCC(31, 983, 0, 0) /* stfiwx */
5296 return OPVCC(31, 407, 0, 0) /* sthx */
5298 return OPVCC(31, 918, 0, 0) /* sthbrx */
5300 case AMOVHZU, AMOVHU:
5301 return OPVCC(31, 439, 0, 0) /* sthux */
5304 return OPVCC(31, 151, 0, 0) /* stwx */
5306 case AMOVWZU, AMOVWU:
5307 return OPVCC(31, 183, 0, 0) /* stwux */
5309 return OPVCC(31, 661, 0, 0) /* stswx */
5311 return OPVCC(31, 662, 0, 0) /* stwbrx */
5313 return OPVCC(31, 660, 0, 0) /* stdbrx */
5315 return OPVCC(31, 694, 0, 1) /* stbcx. */
5317 return OPVCC(31, 726, 0, 1) /* sthcx. */
5319 return OPVCC(31, 150, 0, 1) /* stwcx. */
5321 return OPVCC(31, 214, 0, 1) /* stwdx. */
5323 return OPVCC(31, 438, 0, 0) /* ecowx */
5325 return OPVCC(31, 149, 0, 0) /* stdx */
5327 return OPVCC(31, 181, 0, 0) /* stdux */
5329 /* Vector (VMX/Altivec) instructions */
5331 return OPVCC(31, 135, 0, 0) /* stvebx - v2.03 */
5333 return OPVCC(31, 167, 0, 0) /* stvehx - v2.03 */
5335 return OPVCC(31, 199, 0, 0) /* stvewx - v2.03 */
5337 return OPVCC(31, 231, 0, 0) /* stvx - v2.03 */
5339 return OPVCC(31, 487, 0, 0) /* stvxl - v2.03 */
5340 /* End of vector instructions */
5342 /* Vector scalar (VSX) instructions */
5344 return OPVXX1(31, 396, 0) /* stxvx - v3.0 */
5346 return OPVXX1(31, 972, 0) /* stxvd2x - v2.06 */
5348 return OPVXX1(31, 908, 0) /* stxvw4x - v2.06 */
5350 return OPVXX1(31, 940, 0) /* stxvh8x - v3.0 */
5352 return OPVXX1(31, 1004, 0) /* stxvb16x - v3.0 */
5355 return OPVXX1(31, 716, 0) /* stxsdx - v2.06 */
5358 return OPVXX1(31, 140, 0) /* stxsiwx - v2.07 */
5360 /* End of vector scalar instructions */
5364 c.ctxt.Diag("unknown storex opcode %v", a)