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_GOTADDR, a6: C_REG, type_: 81, size: 8},
226 {as: AMOVD, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
227 {as: AMOVD, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
228 {as: AMOVD, a1: C_LECON, a6: C_REG, type_: 26, size: 8},
229 {as: AMOVD, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
230 {as: AMOVD, a1: C_MSR, a6: C_REG, type_: 54, size: 4}, /* mfmsr */
231 {as: AMOVD, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
232 {as: AMOVD, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
233 {as: AMOVD, a1: C_REG, a6: C_MSR, type_: 54, size: 4}, /* mtmsrd */
234 {as: AMOVD, a1: C_REG, a6: C_REG, type_: 1, size: 4},
235 {as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
236 {as: AMOVD, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
237 {as: AMOVD, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
238 {as: AMOVD, a1: C_SECON, a6: C_REG, type_: 3, size: 4},
239 {as: AMOVD, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
240 {as: AMOVD, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
241 {as: AMOVD, a1: C_TLS_IE, a6: C_REG, type_: 80, size: 8},
242 {as: AMOVD, a1: C_TLS_LE, a6: C_REG, type_: 79, size: 4},
243 {as: AMOVD, a1: C_TOCADDR, a6: C_REG, type_: 95, size: 8},
244 {as: AMOVD, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
246 {as: AMOVW, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
247 {as: AMOVW, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
248 {as: AMOVW, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
249 {as: AMOVW, a1: C_CREG, a6: C_REG, type_: 68, size: 4},
250 {as: AMOVW, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
251 {as: AMOVW, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
252 {as: AMOVW, a1: C_LECON, a6: C_REG, type_: 26, size: 8},
253 {as: AMOVW, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
254 {as: AMOVW, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
255 {as: AMOVW, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
256 {as: AMOVW, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
257 {as: AMOVW, a1: C_REG, a6: C_REG, type_: 12, size: 4},
258 {as: AMOVW, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
259 {as: AMOVW, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
260 {as: AMOVW, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
261 {as: AMOVW, a1: C_SECON, a6: C_REG, type_: 3, size: 4}, /* TO DO: check */
262 {as: AMOVW, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
263 {as: AMOVW, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
264 {as: AMOVW, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
266 {as: AMOVWZ, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
267 {as: AMOVWZ, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
268 {as: AMOVWZ, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
269 {as: AMOVWZ, a1: C_CREG, a6: C_REG, type_: 68, size: 4},
270 {as: AMOVWZ, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
271 {as: AMOVWZ, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
272 {as: AMOVWZ, a1: C_LECON, a6: C_REG, type_: 26, size: 8},
273 {as: AMOVWZ, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
274 {as: AMOVWZ, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
275 {as: AMOVWZ, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
276 {as: AMOVWZ, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
277 {as: AMOVWZ, a1: C_REG, a6: C_MSR, type_: 54, size: 4}, /* mtmsr */
278 {as: AMOVWZ, a1: C_REG, a6: C_REG, type_: 13, size: 4},
279 {as: AMOVWZ, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
280 {as: AMOVWZ, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
281 {as: AMOVWZ, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
282 {as: AMOVWZ, a1: C_SECON, a6: C_REG, type_: 3, size: 4}, /* TO DO: check */
283 {as: AMOVWZ, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
284 {as: AMOVWZ, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
285 {as: AMOVWZ, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
287 {as: AMOVFL, a1: C_CREG, a6: C_CREG, type_: 67, size: 4},
288 {as: AMOVFL, a1: C_FPSCR, a6: C_CREG, type_: 73, size: 4},
289 {as: AMOVFL, a1: C_FPSCR, a6: C_FREG, type_: 53, size: 4},
290 {as: AMOVFL, a1: C_FREG, a3: C_LCON, a6: C_FPSCR, type_: 64, size: 4},
291 {as: AMOVFL, a1: C_FREG, a6: C_FPSCR, type_: 64, size: 4},
292 {as: AMOVFL, a1: C_LCON, a6: C_FPSCR, type_: 65, size: 4},
293 {as: AMOVFL, a1: C_REG, a6: C_CREG, type_: 69, size: 4},
294 {as: AMOVFL, a1: C_REG, a6: C_LCON, type_: 69, size: 4},
296 {as: ASYSCALL, type_: 5, size: 4},
297 {as: ASYSCALL, a1: C_REG, type_: 77, size: 12},
298 {as: ASYSCALL, a1: C_SCON, type_: 77, size: 12},
299 {as: ABEQ, a6: C_SBRA, type_: 16, size: 4},
300 {as: ABEQ, a1: C_CREG, a6: C_SBRA, type_: 16, size: 4},
301 {as: ABR, a6: C_LBRA, type_: 11, size: 4},
302 {as: ABR, a6: C_LBRAPIC, type_: 11, size: 8},
303 {as: ABC, a1: C_SCON, a2: C_REG, a6: C_SBRA, type_: 16, size: 4},
304 {as: ABC, a1: C_SCON, a2: C_REG, a6: C_LBRA, type_: 17, size: 4},
305 {as: ABR, a6: C_LR, type_: 18, size: 4},
306 {as: ABR, a3: C_SCON, a6: C_LR, type_: 18, size: 4},
307 {as: ABR, a6: C_CTR, type_: 18, size: 4},
308 {as: ABR, a1: C_REG, a6: C_CTR, type_: 18, size: 4},
309 {as: ABR, a6: C_ZOREG, type_: 15, size: 8},
310 {as: ABC, a2: C_REG, a6: C_LR, type_: 18, size: 4},
311 {as: ABC, a2: C_REG, a6: C_CTR, type_: 18, size: 4},
312 {as: ABC, a1: C_SCON, a2: C_REG, a6: C_LR, type_: 18, size: 4},
313 {as: ABC, a1: C_SCON, a2: C_REG, a6: C_CTR, type_: 18, size: 4},
314 {as: ABC, a6: C_ZOREG, type_: 15, size: 8},
315 {as: AFMOVD, a1: C_FREG, a6: C_FREG, type_: 33, size: 4},
316 {as: AFMOVD, a1: C_SOREG, a6: C_FREG, type_: 8, size: 4},
317 {as: AFMOVD, a1: C_LOREG, a6: C_FREG, type_: 36, size: 8},
318 {as: AFMOVD, a1: C_ZCON, a6: C_FREG, type_: 24, size: 4},
319 {as: AFMOVD, a1: C_ADDCON, a6: C_FREG, type_: 24, size: 8},
320 {as: AFMOVD, a1: C_ADDR, a6: C_FREG, type_: 75, size: 8},
321 {as: AFMOVD, a1: C_FREG, a6: C_SOREG, type_: 7, size: 4},
322 {as: AFMOVD, a1: C_FREG, a6: C_LOREG, type_: 35, size: 8},
323 {as: AFMOVD, a1: C_FREG, a6: C_ADDR, type_: 74, size: 8},
324 {as: AFMOVSX, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
325 {as: AFMOVSX, a1: C_FREG, a6: C_ZOREG, type_: 44, size: 4},
326 {as: AFMOVSZ, a1: C_ZOREG, a6: C_FREG, type_: 45, size: 4},
327 {as: ASYNC, type_: 46, size: 4},
328 {as: AWORD, a1: C_LCON, type_: 40, size: 4},
329 {as: ADWORD, a1: C_LCON, type_: 31, size: 8},
330 {as: ADWORD, a1: C_DCON, type_: 31, size: 8},
331 {as: AADDME, a1: C_REG, a6: C_REG, type_: 47, size: 4},
332 {as: AEXTSB, a1: C_REG, a6: C_REG, type_: 48, size: 4},
333 {as: AEXTSB, a6: C_REG, type_: 48, size: 4},
334 {as: AISEL, a1: C_LCON, a2: C_REG, a3: C_REG, a6: C_REG, type_: 84, size: 4},
335 {as: AISEL, a1: C_ZCON, a2: C_REG, a3: C_REG, a6: C_REG, type_: 84, size: 4},
336 {as: ANEG, a1: C_REG, a6: C_REG, type_: 47, size: 4},
337 {as: ANEG, a6: C_REG, type_: 47, size: 4},
338 {as: AREM, a1: C_REG, a6: C_REG, type_: 50, size: 12},
339 {as: AREM, a1: C_REG, a2: C_REG, a6: C_REG, type_: 50, size: 12},
340 {as: AREMU, a1: C_REG, a6: C_REG, type_: 50, size: 16},
341 {as: AREMU, a1: C_REG, a2: C_REG, a6: C_REG, type_: 50, size: 16},
342 {as: AREMD, a1: C_REG, a6: C_REG, type_: 51, size: 12},
343 {as: AREMD, a1: C_REG, a2: C_REG, a6: C_REG, type_: 51, size: 12},
344 {as: AMTFSB0, a1: C_SCON, type_: 52, size: 4},
345 /* Other ISA 2.05+ instructions */
346 {as: APOPCNTD, a1: C_REG, a6: C_REG, type_: 93, size: 4}, /* population count, x-form */
347 {as: ACMPB, a1: C_REG, a2: C_REG, a6: C_REG, type_: 92, size: 4}, /* compare byte, x-form */
348 {as: ACMPEQB, a1: C_REG, a2: C_REG, a6: C_CREG, type_: 92, size: 4}, /* compare equal byte, x-form, ISA 3.0 */
349 {as: ACMPEQB, a1: C_REG, a6: C_REG, type_: 70, size: 4},
350 {as: AFTDIV, a1: C_FREG, a2: C_FREG, a6: C_SCON, type_: 92, size: 4}, /* floating test for sw divide, x-form */
351 {as: AFTSQRT, a1: C_FREG, a6: C_SCON, type_: 93, size: 4}, /* floating test for sw square root, x-form */
352 {as: ACOPY, a1: C_REG, a6: C_REG, type_: 92, size: 4}, /* copy/paste facility, x-form */
353 {as: ADARN, a1: C_SCON, a6: C_REG, type_: 92, size: 4}, /* deliver random number, x-form */
354 {as: ALDMX, a1: C_SOREG, a6: C_REG, type_: 45, size: 4}, /* load doubleword monitored, x-form */
355 {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 */
356 {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 */
357 {as: ACRAND, a1: C_CREG, a6: C_CREG, type_: 2, size: 4}, /* logical ops for condition registers xl-form */
359 /* Vector instructions */
362 {as: ALV, a1: C_SOREG, a6: C_VREG, type_: 45, size: 4}, /* vector load, x-form */
365 {as: ASTV, a1: C_VREG, a6: C_SOREG, type_: 44, size: 4}, /* vector store, x-form */
368 {as: AVAND, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector and, vx-form */
369 {as: AVOR, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector or, vx-form */
372 {as: AVADDUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector add unsigned modulo, vx-form */
373 {as: AVADDCU, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector add & write carry unsigned, vx-form */
374 {as: AVADDUS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector add unsigned saturate, vx-form */
375 {as: AVADDSS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector add signed saturate, vx-form */
376 {as: AVADDE, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector add extended, va-form */
378 /* Vector subtract */
379 {as: AVSUBUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector subtract unsigned modulo, vx-form */
380 {as: AVSUBCU, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector subtract & write carry unsigned, vx-form */
381 {as: AVSUBUS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector subtract unsigned saturate, vx-form */
382 {as: AVSUBSS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector subtract signed saturate, vx-form */
383 {as: AVSUBE, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector subtract extended, va-form */
385 /* Vector multiply */
386 {as: AVMULESB, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector multiply, vx-form */
387 {as: AVPMSUM, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector polynomial multiply & sum, vx-form */
388 {as: AVMSUMUDM, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector multiply-sum, va-form */
391 {as: AVR, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector rotate, vx-form */
394 {as: AVS, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector shift, vx-form */
395 {as: AVSA, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector shift algebraic, vx-form */
396 {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 */
399 {as: AVCLZ, a1: C_VREG, a6: C_VREG, type_: 85, size: 4}, /* vector count leading zeros, vx-form */
400 {as: AVPOPCNT, a1: C_VREG, a6: C_VREG, type_: 85, size: 4}, /* vector population count, vx-form */
403 {as: AVCMPEQ, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector compare equal, vc-form */
404 {as: AVCMPGT, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector compare greater than, vc-form */
405 {as: AVCMPNEZB, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector compare not equal, vx-form */
408 {as: AVMRGOW, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector merge odd word, vx-form */
411 {as: AVPERM, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector permute, va-form */
413 /* Vector bit permute */
414 {as: AVBPERMQ, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector bit permute, vx-form */
417 {as: AVSEL, a1: C_VREG, a2: C_VREG, a3: C_VREG, a6: C_VREG, type_: 83, size: 4}, /* vector select, va-form */
420 {as: AVSPLTB, a1: C_SCON, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector splat, vx-form */
421 {as: AVSPLTB, a1: C_ADDCON, a2: C_VREG, a6: C_VREG, type_: 82, size: 4},
422 {as: AVSPLTISB, a1: C_SCON, a6: C_VREG, type_: 82, size: 4}, /* vector splat immediate, vx-form */
423 {as: AVSPLTISB, a1: C_ADDCON, a6: C_VREG, type_: 82, size: 4},
426 {as: AVCIPH, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector AES cipher, vx-form */
427 {as: AVNCIPH, a1: C_VREG, a2: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector AES inverse cipher, vx-form */
428 {as: AVSBOX, a1: C_VREG, a6: C_VREG, type_: 82, size: 4}, /* vector AES subbytes, vx-form */
431 {as: AVSHASIGMA, a1: C_ANDCON, a2: C_VREG, a3: C_ANDCON, a6: C_VREG, type_: 82, size: 4}, /* vector SHA sigma, vx-form */
433 /* VSX vector load */
434 {as: ALXVD2X, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx vector load, xx1-form */
435 {as: ALXV, a1: C_SOREG, a6: C_VSREG, type_: 96, size: 4}, /* vsx vector load, dq-form */
436 {as: ALXVL, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 98, size: 4}, /* vsx vector load length */
438 /* VSX vector store */
439 {as: ASTXVD2X, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx vector store, xx1-form */
440 {as: ASTXV, a1: C_VSREG, a6: C_SOREG, type_: 97, size: 4}, /* vsx vector store, dq-form */
441 {as: ASTXVL, a1: C_VSREG, a2: C_REG, a6: C_REG, type_: 99, size: 4}, /* vsx vector store with length x-form */
443 /* VSX scalar load */
444 {as: ALXSDX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar load, xx1-form */
446 /* VSX scalar store */
447 {as: ASTXSDX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar store, xx1-form */
449 /* VSX scalar as integer load */
450 {as: ALXSIWAX, a1: C_SOREG, a6: C_VSREG, type_: 87, size: 4}, /* vsx scalar as integer load, xx1-form */
452 /* VSX scalar store as integer */
453 {as: ASTXSIWX, a1: C_VSREG, a6: C_SOREG, type_: 86, size: 4}, /* vsx scalar as integer store, xx1-form */
455 /* VSX move from VSR */
456 {as: AMFVSRD, a1: C_VSREG, a6: C_REG, type_: 88, size: 4}, /* vsx move from vsr, xx1-form */
457 {as: AMFVSRD, a1: C_FREG, a6: C_REG, type_: 88, size: 4},
458 {as: AMFVSRD, a1: C_VREG, a6: C_REG, type_: 88, size: 4},
460 /* VSX move to VSR */
461 {as: AMTVSRD, a1: C_REG, a6: C_VSREG, type_: 88, size: 4}, /* vsx move to vsr, xx1-form */
462 {as: AMTVSRD, a1: C_REG, a2: C_REG, a6: C_VSREG, type_: 88, size: 4},
463 {as: AMTVSRD, a1: C_REG, a6: C_FREG, type_: 88, size: 4},
464 {as: AMTVSRD, a1: C_REG, a6: C_VREG, type_: 88, size: 4},
467 {as: AXXLAND, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx and, xx3-form */
468 {as: AXXLOR, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx or, xx3-form */
471 {as: AXXSEL, a1: C_VSREG, a2: C_VSREG, a3: C_VSREG, a6: C_VSREG, type_: 91, size: 4}, /* vsx select, xx4-form */
474 {as: AXXMRGHW, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx merge, xx3-form */
477 {as: AXXSPLTW, a1: C_VSREG, a3: C_SCON, a6: C_VSREG, type_: 89, size: 4}, /* vsx splat, xx2-form */
478 {as: AXXSPLTIB, a1: C_SCON, a6: C_VSREG, type_: 100, size: 4}, /* vsx splat, xx2-form */
481 {as: AXXPERM, a1: C_VSREG, a2: C_VSREG, a6: C_VSREG, type_: 90, size: 4}, /* vsx permute, xx3-form */
484 {as: AXXSLDWI, a1: C_VSREG, a2: C_VSREG, a3: C_SCON, a6: C_VSREG, type_: 90, size: 4}, /* vsx shift immediate, xx3-form */
486 /* VSX reverse bytes */
487 {as: AXXBRQ, a1: C_VSREG, a6: C_VSREG, type_: 101, size: 4}, /* vsx reverse bytes */
489 /* VSX scalar FP-FP conversion */
490 {as: AXSCVDPSP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar fp-fp conversion, xx2-form */
492 /* VSX vector FP-FP conversion */
493 {as: AXVCVDPSP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector fp-fp conversion, xx2-form */
495 /* VSX scalar FP-integer conversion */
496 {as: AXSCVDPSXDS, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar fp-integer conversion, xx2-form */
498 /* VSX scalar integer-FP conversion */
499 {as: AXSCVSXDDP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx scalar integer-fp conversion, xx2-form */
501 /* VSX vector FP-integer conversion */
502 {as: AXVCVDPSXDS, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector fp-integer conversion, xx2-form */
504 /* VSX vector integer-FP conversion */
505 {as: AXVCVSXDDP, a1: C_VSREG, a6: C_VSREG, type_: 89, size: 4}, /* vsx vector integer-fp conversion, xx2-form */
507 {as: ACMP, a1: C_REG, a6: C_REG, type_: 70, size: 4},
508 {as: ACMP, a1: C_REG, a2: C_REG, a6: C_REG, type_: 70, size: 4},
509 {as: ACMP, a1: C_REG, a6: C_ADDCON, type_: 71, size: 4},
510 {as: ACMP, a1: C_REG, a2: C_REG, a6: C_ADDCON, type_: 71, size: 4},
511 {as: ACMPU, a1: C_REG, a6: C_REG, type_: 70, size: 4},
512 {as: ACMPU, a1: C_REG, a2: C_REG, a6: C_REG, type_: 70, size: 4},
513 {as: ACMPU, a1: C_REG, a6: C_ANDCON, type_: 71, size: 4},
514 {as: ACMPU, a1: C_REG, a2: C_REG, a6: C_ANDCON, type_: 71, size: 4},
515 {as: AFCMPO, a1: C_FREG, a6: C_FREG, type_: 70, size: 4},
516 {as: AFCMPO, a1: C_FREG, a2: C_REG, a6: C_FREG, type_: 70, size: 4},
517 {as: ATW, a1: C_LCON, a2: C_REG, a6: C_REG, type_: 60, size: 4},
518 {as: ATW, a1: C_LCON, a2: C_REG, a6: C_ADDCON, type_: 61, size: 4},
519 {as: ADCBF, a1: C_ZOREG, type_: 43, size: 4},
520 {as: ADCBF, a1: C_SOREG, type_: 43, size: 4},
521 {as: ADCBF, a1: C_ZOREG, a2: C_REG, a6: C_SCON, type_: 43, size: 4},
522 {as: ADCBF, a1: C_SOREG, a6: C_SCON, type_: 43, size: 4},
523 {as: AECOWX, a1: C_REG, a2: C_REG, a6: C_ZOREG, type_: 44, size: 4},
524 {as: AECIWX, a1: C_ZOREG, a2: C_REG, a6: C_REG, type_: 45, size: 4},
525 {as: AECOWX, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
526 {as: AECIWX, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
527 {as: ALDAR, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
528 {as: ALDAR, a1: C_ZOREG, a3: C_ANDCON, a6: C_REG, type_: 45, size: 4},
529 {as: AEIEIO, type_: 46, size: 4},
530 {as: ATLBIE, a1: C_REG, type_: 49, size: 4},
531 {as: ATLBIE, a1: C_SCON, a6: C_REG, type_: 49, size: 4},
532 {as: ASLBMFEE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
533 {as: ASLBMTE, a1: C_REG, a6: C_REG, type_: 55, size: 4},
534 {as: ASTSW, a1: C_REG, a6: C_ZOREG, type_: 44, size: 4},
535 {as: ASTSW, a1: C_REG, a3: C_LCON, a6: C_ZOREG, type_: 41, size: 4},
536 {as: ALSW, a1: C_ZOREG, a6: C_REG, type_: 45, size: 4},
537 {as: ALSW, a1: C_ZOREG, a3: C_LCON, a6: C_REG, type_: 42, size: 4},
538 {as: obj.AUNDEF, type_: 78, size: 4},
539 {as: obj.APCDATA, a1: C_LCON, a6: C_LCON, type_: 0, size: 0},
540 {as: obj.AFUNCDATA, a1: C_SCON, a6: C_ADDR, type_: 0, size: 0},
541 {as: obj.ANOP, type_: 0, size: 0},
542 {as: obj.ANOP, a1: C_LCON, type_: 0, size: 0}, // NOP operand variations added for #40689
543 {as: obj.ANOP, a1: C_REG, type_: 0, size: 0}, // to preserve previous behavior
544 {as: obj.ANOP, a1: C_FREG, type_: 0, size: 0},
545 {as: obj.ADUFFZERO, a6: C_LBRA, type_: 11, size: 4}, // same as ABR/ABL
546 {as: obj.ADUFFCOPY, a6: C_LBRA, type_: 11, size: 4}, // same as ABR/ABL
547 {as: obj.APCALIGN, a1: C_LCON, type_: 0, size: 0}, // align code
549 {as: obj.AXXX, type_: 0, size: 4},
552 var oprange [ALAST & obj.AMask][]Optab
554 var xcmp [C_NCLASS][C_NCLASS]bool
556 // padding bytes to add to align code as requested
557 func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int {
558 // For 16 and 32 byte alignment, there is a tradeoff
559 // between aligning the code and adding too many NOPs.
566 // Align to 16 bytes if possible but add at
575 // Align to 32 bytes if possible but add at
585 // When 32 byte alignment is requested on Linux,
586 // promote the function's alignment to 32. On AIX
587 // the function alignment is not changed which might
588 // result in 16 byte alignment but that is still fine.
589 // TODO: alignment on AIX
590 if ctxt.Headtype != objabi.Haix && cursym.Func().Align < 32 {
591 cursym.Func().Align = 32
594 ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a)
599 // Get the implied register of a operand which doesn't specify one. These show up
600 // in handwritten asm like "MOVD R5, foosymbol" where a base register is not supplied,
601 // or "MOVD R5, foo+10(SP) or pseudo-register is used. The other common case is when
602 // generating constants in register like "MOVD $constant, Rx".
603 func (c *ctxt9) getimpliedreg(a *obj.Addr, p *obj.Prog) int {
605 case C_ADDCON, C_ANDCON, C_UCON, C_LCON, C_SCON, C_ZCON:
607 case C_SECON, C_LECON:
609 case C_SACON, C_LACON:
611 case C_LOREG, C_SOREG, C_ZOREG:
613 case obj.NAME_EXTERN, obj.NAME_STATIC:
615 case obj.NAME_AUTO, obj.NAME_PARAM:
621 c.ctxt.Diag("failed to determine implied reg for class %v (%v)", DRconv(oclass(a)), p)
625 func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
626 p := cursym.Func().Text
627 if p == nil || p.Link == nil { // handle external functions and ELF section symbols
631 if oprange[AANDN&obj.AMask] == nil {
632 ctxt.Diag("ppc64 ops not initialized, call ppc64.buildop first")
635 c := ctxt9{ctxt: ctxt, newprog: newprog, cursym: cursym, autosize: int32(p.To.Offset)}
642 for p = p.Link; p != nil; p = p.Link {
647 if p.As == obj.APCALIGN {
648 a := c.vregoff(&p.From)
649 m = addpad(pc, a, ctxt, cursym)
651 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
652 ctxt.Diag("zero-width instruction\n%v", p)
663 * if any procedure is large enough to
664 * generate a large SBRA branch, then
665 * generate extra passes putting branches
666 * around jmps to fix. this is rare.
675 for p = c.cursym.Func().Text.Link; p != nil; p = p.Link {
679 // very large conditional branches
680 if (o.type_ == 16 || o.type_ == 17) && p.To.Target() != nil {
681 otxt = p.To.Target().Pc - pc
682 if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
687 q.To.Type = obj.TYPE_BRANCH
688 q.To.SetTarget(p.To.Target())
694 q.To.Type = obj.TYPE_BRANCH
695 q.To.SetTarget(q.Link.Link)
705 if p.As == obj.APCALIGN {
706 a := c.vregoff(&p.From)
707 m = addpad(pc, a, ctxt, cursym)
709 if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
710 ctxt.Diag("zero-width instruction\n%v", p)
722 if r := pc & funcAlignMask; r != 0 {
729 * lay out the code, emitting code and data relocations.
732 c.cursym.Grow(c.cursym.Size)
737 for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
740 if int(o.size) > 4*len(out) {
741 log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)
743 // asmout is not set up to add large amounts of padding
744 if o.type_ == 0 && p.As == obj.APCALIGN {
745 pad := LOP_RRR(OP_OR, REGZERO, REGZERO, REGZERO)
746 aln := c.vregoff(&p.From)
747 v := addpad(p.Pc, aln, c.ctxt, c.cursym)
749 // Same padding instruction for all
750 for i = 0; i < int32(v/4); i++ {
751 c.ctxt.Arch.ByteOrder.PutUint32(bp, pad)
756 c.asmout(p, o, out[:])
757 for i = 0; i < int32(o.size/4); i++ {
758 c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
765 func isint32(v int64) bool {
766 return int64(int32(v)) == v
769 func isuint32(v uint64) bool {
770 return uint64(uint32(v)) == v
773 func (c *ctxt9) aclass(a *obj.Addr) int {
779 if REG_R0 <= a.Reg && a.Reg <= REG_R31 {
782 if REG_F0 <= a.Reg && a.Reg <= REG_F31 {
785 if REG_V0 <= a.Reg && a.Reg <= REG_V31 {
788 if REG_VS0 <= a.Reg && a.Reg <= REG_VS63 {
791 if REG_CR0 <= a.Reg && a.Reg <= REG_CR7 || a.Reg == REG_CR {
794 if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 {
809 if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 {
812 if a.Reg == REG_FPSCR {
815 if a.Reg == REG_MSR {
822 case obj.NAME_EXTERN,
827 c.instoffset = a.Offset
828 if a.Sym != nil { // use relocation
829 if a.Sym.Type == objabi.STLSBSS {
830 if c.ctxt.Flag_shared {
840 case obj.NAME_GOTREF:
843 case obj.NAME_TOCREF:
847 c.instoffset = int64(c.autosize) + a.Offset
848 if c.instoffset >= -BIG && c.instoffset < BIG {
854 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
855 if c.instoffset >= -BIG && c.instoffset < BIG {
861 c.instoffset = a.Offset
862 if c.instoffset == 0 {
865 if c.instoffset >= -BIG && c.instoffset < BIG {
873 case obj.TYPE_TEXTSIZE:
876 case obj.TYPE_FCONST:
877 // The only cases where FCONST will occur are with float64 +/- 0.
878 // All other float constants are generated in memory.
879 f64 := a.Val.(float64)
881 if math.Signbit(f64) {
886 log.Fatalf("Unexpected nonzero FCONST operand %v", a)
892 c.instoffset = a.Offset
894 if -BIG <= c.instoffset && c.instoffset <= BIG {
897 if isint32(c.instoffset) {
903 case obj.NAME_EXTERN,
910 c.instoffset = a.Offset
912 /* not sure why this barfs */
916 c.instoffset = int64(c.autosize) + a.Offset
917 if c.instoffset >= -BIG && c.instoffset < BIG {
923 c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
924 if c.instoffset >= -BIG && c.instoffset < BIG {
933 if c.instoffset >= 0 {
934 if c.instoffset == 0 {
937 if c.instoffset <= 0x7fff {
940 if c.instoffset <= 0xffff {
943 if c.instoffset&0xffff == 0 && isuint32(uint64(c.instoffset)) { /* && (instoffset & (1<<31)) == 0) */
946 if isint32(c.instoffset) || isuint32(uint64(c.instoffset)) {
952 if c.instoffset >= -0x8000 {
955 if c.instoffset&0xffff == 0 && isint32(c.instoffset) {
958 if isint32(c.instoffset) {
963 case obj.TYPE_BRANCH:
964 if a.Sym != nil && c.ctxt.Flag_dynlink {
973 func prasm(p *obj.Prog) {
974 fmt.Printf("%v\n", p)
977 func (c *ctxt9) oplook(p *obj.Prog) *Optab {
982 a1 = int(p.From.Class)
984 a1 = c.aclass(&p.From) + 1
985 p.From.Class = int8(a1)
989 argsv := [3]int{C_NONE + 1, C_NONE + 1, C_NONE + 1}
990 for i, ap := range p.RestArgs {
991 argsv[i] = int(ap.Addr.Class)
993 argsv[i] = c.aclass(&ap.Addr) + 1
994 ap.Addr.Class = int8(argsv[i])
1002 a6 := int(p.To.Class)
1004 a6 = c.aclass(&p.To) + 1
1005 p.To.Class = int8(a6)
1011 if REG_R0 <= p.Reg && p.Reg <= REG_R31 {
1013 } else if REG_V0 <= p.Reg && p.Reg <= REG_V31 {
1015 } else if REG_VS0 <= p.Reg && p.Reg <= REG_VS63 {
1017 } else if REG_F0 <= p.Reg && p.Reg <= REG_F31 {
1022 // c.ctxt.Logf("oplook %v %d %d %d %d\n", p, a1, a2, a3, a4, a5, a6)
1023 ops := oprange[p.As&obj.AMask]
1029 for i := range ops {
1031 if int(op.a2) == a2 && c1[op.a1] && c3[op.a3] && c4[op.a4] && c5[op.a5] && c6[op.a6] {
1032 p.Optab = uint16(cap(optab) - cap(ops) + i + 1)
1037 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))
1045 func cmp(a int, b int) bool {
1051 if b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON {
1056 if b == C_ZCON || b == C_SCON {
1061 if b == C_ZCON || b == C_SCON {
1066 if b == C_LR || b == C_XER || b == C_CTR {
1096 if b == C_SOREG || b == C_ZOREG {
1102 return r0iszero != 0 /*TypeKind(100016)*/
1114 func (x ocmp) Len() int {
1118 func (x ocmp) Swap(i, j int) {
1119 x[i], x[j] = x[j], x[i]
1122 // Used when sorting the optab. Sorting is
1123 // done in a way so that the best choice of
1124 // opcode/operand combination is considered first.
1125 func (x ocmp) Less(i, j int) bool {
1128 n := int(p1.as) - int(p2.as)
1133 // Consider those that generate fewer
1134 // instructions first.
1135 n = int(p1.size) - int(p2.size)
1139 // operand order should match
1140 // better choices first
1141 n = int(p1.a1) - int(p2.a1)
1145 n = int(p1.a2) - int(p2.a2)
1149 n = int(p1.a3) - int(p2.a3)
1153 n = int(p1.a4) - int(p2.a4)
1157 n = int(p1.a5) - int(p2.a5)
1161 n = int(p1.a6) - int(p2.a6)
1168 // Add an entry to the opcode table for
1169 // a new opcode b0 with the same operand combinations
1171 func opset(a, b0 obj.As) {
1172 oprange[a&obj.AMask] = oprange[b0]
1175 // Build the opcode table
1176 func buildop(ctxt *obj.Link) {
1177 if oprange[AANDN&obj.AMask] != nil {
1178 // Already initialized; stop now.
1179 // This happens in the cmd/asm tests,
1180 // each of which re-initializes the arch.
1186 for i := 0; i < C_NCLASS; i++ {
1187 for n = 0; n < C_NCLASS; n++ {
1193 for n = 0; optab[n].as != obj.AXXX; n++ {
1195 sort.Sort(ocmp(optab[:n]))
1196 for i := 0; i < n; i++ {
1200 for optab[i].as == r {
1203 oprange[r0] = optab[start:i]
1208 ctxt.Diag("unknown op in build: %v", r)
1209 log.Fatalf("instruction missing from switch in asm9.go:buildop: %v", r)
1211 case ADCBF: /* unary indexed: op (b+a); op (b) */
1220 case AECOWX: /* indexed store: op s,(b+a); op s,(b) */
1226 case AREM: /* macro */
1238 case ADIVW: /* op Rb[,Ra],Rd */
1243 opset(AMULHWUCC, r0)
1245 opset(AMULLWVCC, r0)
1253 opset(ADIVWUVCC, r0)
1270 opset(AMULHDUCC, r0)
1272 opset(AMULLDVCC, r0)
1279 opset(ADIVDEUCC, r0)
1284 opset(ADIVDUVCC, r0)
1296 case APOPCNTD: /* popcntd, popcntw, popcntb, cnttzw, cnttzd */
1300 opset(ACNTTZWCC, r0)
1302 opset(ACNTTZDCC, r0)
1304 case ACOPY: /* copy, paste. */
1307 case AMADDHD: /* maddhd, maddhdu, maddld */
1311 case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
1315 case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */
1324 case ALV: /* lvebx, lvehx, lvewx, lvx, lvxl, lvsl, lvsr */
1333 case ASTV: /* stvebx, stvehx, stvewx, stvx, stvxl */
1340 case AVAND: /* vand, vandc, vnand */
1345 case AVMRGOW: /* vmrgew, vmrgow */
1348 case AVOR: /* vor, vorc, vxor, vnor, veqv */
1355 case AVADDUM: /* vaddubm, vadduhm, vadduwm, vaddudm, vadduqm */
1362 case AVADDCU: /* vaddcuq, vaddcuw */
1366 case AVADDUS: /* vaddubs, vadduhs, vadduws */
1371 case AVADDSS: /* vaddsbs, vaddshs, vaddsws */
1376 case AVADDE: /* vaddeuqm, vaddecuq */
1377 opset(AVADDEUQM, r0)
1378 opset(AVADDECUQ, r0)
1380 case AVSUBUM: /* vsububm, vsubuhm, vsubuwm, vsubudm, vsubuqm */
1387 case AVSUBCU: /* vsubcuq, vsubcuw */
1391 case AVSUBUS: /* vsububs, vsubuhs, vsubuws */
1396 case AVSUBSS: /* vsubsbs, vsubshs, vsubsws */
1401 case AVSUBE: /* vsubeuqm, vsubecuq */
1402 opset(AVSUBEUQM, r0)
1403 opset(AVSUBECUQ, r0)
1405 case AVMULESB: /* vmulesb, vmulosb, vmuleub, vmuloub, vmulosh, vmulouh, vmulesw, vmulosw, vmuleuw, vmulouw, vmuluwm */
1418 case AVPMSUM: /* vpmsumb, vpmsumh, vpmsumw, vpmsumd */
1424 case AVR: /* vrlb, vrlh, vrlw, vrld */
1430 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 */
1444 case AVSA: /* vsrab, vsrah, vsraw, vsrad */
1450 case AVSOI: /* vsldoi */
1453 case AVCLZ: /* vclzb, vclzh, vclzw, vclzd */
1459 case AVPOPCNT: /* vpopcntb, vpopcnth, vpopcntw, vpopcntd */
1460 opset(AVPOPCNTB, r0)
1461 opset(AVPOPCNTH, r0)
1462 opset(AVPOPCNTW, r0)
1463 opset(AVPOPCNTD, r0)
1465 case AVCMPEQ: /* vcmpequb[.], vcmpequh[.], vcmpequw[.], vcmpequd[.] */
1466 opset(AVCMPEQUB, r0)
1467 opset(AVCMPEQUBCC, r0)
1468 opset(AVCMPEQUH, r0)
1469 opset(AVCMPEQUHCC, r0)
1470 opset(AVCMPEQUW, r0)
1471 opset(AVCMPEQUWCC, r0)
1472 opset(AVCMPEQUD, r0)
1473 opset(AVCMPEQUDCC, r0)
1475 case AVCMPGT: /* vcmpgt[u,s]b[.], vcmpgt[u,s]h[.], vcmpgt[u,s]w[.], vcmpgt[u,s]d[.] */
1476 opset(AVCMPGTUB, r0)
1477 opset(AVCMPGTUBCC, r0)
1478 opset(AVCMPGTUH, r0)
1479 opset(AVCMPGTUHCC, r0)
1480 opset(AVCMPGTUW, r0)
1481 opset(AVCMPGTUWCC, r0)
1482 opset(AVCMPGTUD, r0)
1483 opset(AVCMPGTUDCC, r0)
1484 opset(AVCMPGTSB, r0)
1485 opset(AVCMPGTSBCC, r0)
1486 opset(AVCMPGTSH, r0)
1487 opset(AVCMPGTSHCC, r0)
1488 opset(AVCMPGTSW, r0)
1489 opset(AVCMPGTSWCC, r0)
1490 opset(AVCMPGTSD, r0)
1491 opset(AVCMPGTSDCC, r0)
1493 case AVCMPNEZB: /* vcmpnezb[.] */
1494 opset(AVCMPNEZBCC, r0)
1496 opset(AVCMPNEBCC, r0)
1498 opset(AVCMPNEHCC, r0)
1500 opset(AVCMPNEWCC, r0)
1502 case AVPERM: /* vperm */
1503 opset(AVPERMXOR, r0)
1506 case AVBPERMQ: /* vbpermq, vbpermd */
1509 case AVSEL: /* vsel */
1512 case AVSPLTB: /* vspltb, vsplth, vspltw */
1516 case AVSPLTISB: /* vspltisb, vspltish, vspltisw */
1517 opset(AVSPLTISH, r0)
1518 opset(AVSPLTISW, r0)
1520 case AVCIPH: /* vcipher, vcipherlast */
1522 opset(AVCIPHERLAST, r0)
1524 case AVNCIPH: /* vncipher, vncipherlast */
1525 opset(AVNCIPHER, r0)
1526 opset(AVNCIPHERLAST, r0)
1528 case AVSBOX: /* vsbox */
1531 case AVSHASIGMA: /* vshasigmaw, vshasigmad */
1532 opset(AVSHASIGMAW, r0)
1533 opset(AVSHASIGMAD, r0)
1535 case ALXVD2X: /* lxvd2x, lxvdsx, lxvw4x, lxvh8x, lxvb16x */
1541 case ALXV: /* lxv */
1544 case ALXVL: /* lxvl, lxvll, lxvx */
1548 case ASTXVD2X: /* stxvd2x, stxvdsx, stxvw4x, stxvh8x, stxvb16x */
1551 opset(ASTXVB16X, r0)
1553 case ASTXV: /* stxv */
1556 case ASTXVL: /* stxvl, stxvll, stvx */
1560 case ALXSDX: /* lxsdx */
1563 case ASTXSDX: /* stxsdx */
1566 case ALXSIWAX: /* lxsiwax, lxsiwzx */
1569 case ASTXSIWX: /* stxsiwx */
1572 case AMFVSRD: /* mfvsrd, mfvsrwz (and extended mnemonics), mfvsrld */
1578 case AMTVSRD: /* mtvsrd, mtvsrwa, mtvsrwz (and extended mnemonics), mtvsrdd, mtvsrws */
1586 case AXXLAND: /* xxland, xxlandc, xxleqv, xxlnand */
1591 case AXXLOR: /* xxlorc, xxlnor, xxlor, xxlxor */
1597 case AXXSEL: /* xxsel */
1600 case AXXMRGHW: /* xxmrghw, xxmrglw */
1603 case AXXSPLTW: /* xxspltw */
1606 case AXXSPLTIB: /* xxspltib */
1607 opset(AXXSPLTIB, r0)
1609 case AXXPERM: /* xxpermdi */
1612 case AXXSLDWI: /* xxsldwi */
1613 opset(AXXPERMDI, r0)
1616 case AXXBRQ: /* xxbrq, xxbrd, xxbrw, xxbrh */
1621 case AXSCVDPSP: /* xscvdpsp, xscvspdp, xscvdpspn, xscvspdpn */
1622 opset(AXSCVSPDP, r0)
1623 opset(AXSCVDPSPN, r0)
1624 opset(AXSCVSPDPN, r0)
1626 case AXVCVDPSP: /* xvcvdpsp, xvcvspdp */
1627 opset(AXVCVSPDP, r0)
1629 case AXSCVDPSXDS: /* xscvdpsxds, xscvdpsxws, xscvdpuxds, xscvdpuxws */
1630 opset(AXSCVDPSXWS, r0)
1631 opset(AXSCVDPUXDS, r0)
1632 opset(AXSCVDPUXWS, r0)
1634 case AXSCVSXDDP: /* xscvsxddp, xscvuxddp, xscvsxdsp, xscvuxdsp */
1635 opset(AXSCVUXDDP, r0)
1636 opset(AXSCVSXDSP, r0)
1637 opset(AXSCVUXDSP, r0)
1639 case AXVCVDPSXDS: /* xvcvdpsxds, xvcvdpsxws, xvcvdpuxds, xvcvdpuxws, xvcvspsxds, xvcvspsxws, xvcvspuxds, xvcvspuxws */
1640 opset(AXVCVDPSXDS, r0)
1641 opset(AXVCVDPSXWS, r0)
1642 opset(AXVCVDPUXDS, r0)
1643 opset(AXVCVDPUXWS, r0)
1644 opset(AXVCVSPSXDS, r0)
1645 opset(AXVCVSPSXWS, r0)
1646 opset(AXVCVSPUXDS, r0)
1647 opset(AXVCVSPUXWS, r0)
1649 case AXVCVSXDDP: /* xvcvsxddp, xvcvsxwdp, xvcvuxddp, xvcvuxwdp, xvcvsxdsp, xvcvsxwsp, xvcvuxdsp, xvcvuxwsp */
1650 opset(AXVCVSXWDP, r0)
1651 opset(AXVCVUXDDP, r0)
1652 opset(AXVCVUXWDP, r0)
1653 opset(AXVCVSXDSP, r0)
1654 opset(AXVCVSXWSP, r0)
1655 opset(AXVCVUXDSP, r0)
1656 opset(AXVCVUXWSP, r0)
1658 case AAND: /* logical op Rb,Rs,Ra; no literal */
1672 case AADDME: /* op Ra, Rd */
1676 opset(AADDMEVCC, r0)
1680 opset(AADDZEVCC, r0)
1684 opset(ASUBMEVCC, r0)
1688 opset(ASUBZEVCC, r0)
1708 case AEXTSB: /* op Rs, Ra */
1714 opset(ACNTLZWCC, r0)
1718 opset(ACNTLZDCC, r0)
1720 case AFABS: /* fop [s,]d */
1732 opset(AFCTIWZCC, r0)
1736 opset(AFCTIDZCC, r0)
1740 opset(AFCFIDUCC, r0)
1742 opset(AFCFIDSCC, r0)
1754 opset(AFRSQRTECC, r0)
1758 opset(AFSQRTSCC, r0)
1765 opset(AFCPSGNCC, r0)
1778 opset(AFMADDSCC, r0)
1782 opset(AFMSUBSCC, r0)
1784 opset(AFNMADDCC, r0)
1786 opset(AFNMADDSCC, r0)
1788 opset(AFNMSUBCC, r0)
1790 opset(AFNMSUBSCC, r0)
1806 opset(AMTFSB0CC, r0)
1808 opset(AMTFSB1CC, r0)
1810 case ANEG: /* op [Ra,] Rd */
1816 case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,R */
1819 case AORIS: /* oris/xoris $uimm,Rs,Ra */
1834 case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1838 opset(AEXTSWSLICC, r0)
1840 case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
1843 case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */
1871 opset(ARLDIMICC, r0)
1882 opset(ARLDICLCC, r0)
1884 opset(ARLDICRCC, r0)
1887 opset(ACLRLSLDI, r0)
1900 case ASYSCALL: /* just the op; flow of control */
1941 AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra */
1947 /* load/store/move word with sign extension; special 32-bit move; move 32-bit literals */
1948 AMOVWZ, /* load/store/move word with zero extension; move 32-bit literals */
1949 AMOVD, /* load/store/move 64-bit values, including 32-bit literals with/without sign-extension */
1950 AMOVB, /* macro: move byte with sign extension */
1951 AMOVBU, /* macro: move byte with sign extension & update */
1953 /* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
1954 ASUBC, /* op r1,$s,r3; op r1[,r2],r3 */
1979 func OPVXX1(o uint32, xo uint32, oe uint32) uint32 {
1980 return o<<26 | xo<<1 | oe<<11
1983 func OPVXX2(o uint32, xo uint32, oe uint32) uint32 {
1984 return o<<26 | xo<<2 | oe<<11
1987 func OPVXX2VA(o uint32, xo uint32, oe uint32) uint32 {
1988 return o<<26 | xo<<2 | oe<<16
1991 func OPVXX3(o uint32, xo uint32, oe uint32) uint32 {
1992 return o<<26 | xo<<3 | oe<<11
1995 func OPVXX4(o uint32, xo uint32, oe uint32) uint32 {
1996 return o<<26 | xo<<4 | oe<<11
1999 func OPDQ(o uint32, xo uint32, oe uint32) uint32 {
2000 return o<<26 | xo | oe<<4
2003 func OPVX(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2004 return o<<26 | xo | oe<<11 | rc&1
2007 func OPVC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2008 return o<<26 | xo | oe<<11 | (rc&1)<<10
2011 func OPVCC(o uint32, xo uint32, oe uint32, rc uint32) uint32 {
2012 return o<<26 | xo<<1 | oe<<10 | rc&1
2015 func OPCC(o uint32, xo uint32, rc uint32) uint32 {
2016 return OPVCC(o, xo, 0, rc)
2019 /* the order is dest, a/s, b/imm for both arithmetic and logical operations */
2020 func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 {
2021 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11
2024 /* VX-form 2-register operands, r/none/r */
2025 func AOP_RR(op uint32, d uint32, a uint32) uint32 {
2026 return op | (d&31)<<21 | (a&31)<<11
2029 /* VA-form 4-register operands */
2030 func AOP_RRRR(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2031 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&31)<<6
2034 func AOP_IRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2035 return op | (d&31)<<21 | (a&31)<<16 | simm&0xFFFF
2038 /* VX-form 2-register + UIM operands */
2039 func AOP_VIRR(op uint32, d uint32, a uint32, simm uint32) uint32 {
2040 return op | (d&31)<<21 | (simm&0xFFFF)<<16 | (a&31)<<11
2043 /* VX-form 2-register + ST + SIX operands */
2044 func AOP_IIRR(op uint32, d uint32, a uint32, sbit uint32, simm uint32) uint32 {
2045 return op | (d&31)<<21 | (a&31)<<16 | (sbit&1)<<15 | (simm&0xF)<<11
2048 /* VA-form 3-register + SHB operands */
2049 func AOP_IRRR(op uint32, d uint32, a uint32, b uint32, simm uint32) uint32 {
2050 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (simm&0xF)<<6
2053 /* VX-form 1-register + SIM operands */
2054 func AOP_IR(op uint32, d uint32, simm uint32) uint32 {
2055 return op | (d&31)<<21 | (simm&31)<<16
2058 /* XX1-form 3-register operands, 1 VSR operand */
2059 func AOP_XX1(op uint32, d uint32, a uint32, b uint32) uint32 {
2060 /* For the XX-form encodings, we need the VSX register number to be exactly */
2061 /* between 0-63, so we can properly set the rightmost bits. */
2063 return op | (r&31)<<21 | (a&31)<<16 | (b&31)<<11 | (r&32)>>5
2066 /* XX2-form 3-register operands, 2 VSR operands */
2067 func AOP_XX2(op uint32, d uint32, a uint32, b uint32) uint32 {
2070 return op | (xt&31)<<21 | (a&3)<<16 | (xb&31)<<11 | (xb&32)>>4 | (xt&32)>>5
2073 /* XX3-form 3 VSR operands */
2074 func AOP_XX3(op uint32, d uint32, a uint32, b uint32) uint32 {
2078 return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2081 /* XX3-form 3 VSR operands + immediate */
2082 func AOP_XX3I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2086 return op | (xt&31)<<21 | (xa&31)<<16 | (xb&31)<<11 | (c&3)<<8 | (xa&32)>>3 | (xb&32)>>4 | (xt&32)>>5
2089 /* XX4-form, 4 VSR operands */
2090 func AOP_XX4(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2095 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
2098 /* DQ-form, VSR register, register + offset operands */
2099 func AOP_DQ(op uint32, d uint32, a uint32, b uint32) uint32 {
2100 /* For the DQ-form encodings, we need the VSX register number to be exactly */
2101 /* between 0-63, so we can properly set the SX bit. */
2103 /* The EA for this instruction form is (RA) + DQ << 4, where DQ is a 12-bit signed integer. */
2104 /* In order to match the output of the GNU objdump (and make the usage in Go asm easier), the */
2105 /* instruction is called using the sign extended value (i.e. a valid offset would be -32752 or 32752, */
2106 /* not -2047 or 2047), so 'b' needs to be adjusted to the expected 12-bit DQ value. Bear in mind that */
2107 /* bits 0 to 3 in 'dq' need to be zero, otherwise this will generate an illegal instruction. */
2108 /* If in doubt how this instruction form is encoded, refer to ISA 3.0b, pages 492 and 507. */
2110 return op | (r&31)<<21 | (a&31)<<16 | (dq&4095)<<4 | (r&32)>>2
2113 /* Z23-form, 3-register operands + CY field */
2114 func AOP_Z23I(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2115 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c&3)<<9
2118 /* X-form, 3-register operands + EH field */
2119 func AOP_RRRI(op uint32, d uint32, a uint32, b uint32, c uint32) uint32 {
2120 return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 | (c & 1)
2123 func LOP_RRR(op uint32, a uint32, s uint32, b uint32) uint32 {
2124 return op | (s&31)<<21 | (a&31)<<16 | (b&31)<<11
2127 func LOP_IRR(op uint32, a uint32, s uint32, uimm uint32) uint32 {
2128 return op | (s&31)<<21 | (a&31)<<16 | uimm&0xFFFF
2131 func OP_BR(op uint32, li uint32, aa uint32) uint32 {
2132 return op | li&0x03FFFFFC | aa<<1
2135 func OP_BC(op uint32, bo uint32, bi uint32, bd uint32, aa uint32) uint32 {
2136 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16 | bd&0xFFFC | aa<<1
2139 func OP_BCR(op uint32, bo uint32, bi uint32) uint32 {
2140 return op | (bo&0x1F)<<21 | (bi&0x1F)<<16
2143 func OP_RLW(op uint32, a uint32, s uint32, sh uint32, mb uint32, me uint32) uint32 {
2144 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | (mb&31)<<6 | (me&31)<<1
2147 func AOP_RLDIC(op uint32, a uint32, s uint32, sh uint32, m uint32) uint32 {
2148 return op | (s&31)<<21 | (a&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1 | (m&31)<<6 | ((m&32)>>5)<<5
2151 func AOP_EXTSWSLI(op uint32, a uint32, s uint32, sh uint32) uint32 {
2152 return op | (a&31)<<21 | (s&31)<<16 | (sh&31)<<11 | ((sh&32)>>5)<<1
2155 func AOP_ISEL(op uint32, t uint32, a uint32, b uint32, bc uint32) uint32 {
2156 return op | (t&31)<<21 | (a&31)<<16 | (b&31)<<11 | (bc&0x1F)<<6
2160 /* each rhs is OPVCC(_, _, _, _) */
2161 OP_ADD = 31<<26 | 266<<1 | 0<<10 | 0
2162 OP_ADDI = 14<<26 | 0<<1 | 0<<10 | 0
2163 OP_ADDIS = 15<<26 | 0<<1 | 0<<10 | 0
2164 OP_ANDI = 28<<26 | 0<<1 | 0<<10 | 0
2165 OP_EXTSB = 31<<26 | 954<<1 | 0<<10 | 0
2166 OP_EXTSH = 31<<26 | 922<<1 | 0<<10 | 0
2167 OP_EXTSW = 31<<26 | 986<<1 | 0<<10 | 0
2168 OP_ISEL = 31<<26 | 15<<1 | 0<<10 | 0
2169 OP_MCRF = 19<<26 | 0<<1 | 0<<10 | 0
2170 OP_MCRFS = 63<<26 | 64<<1 | 0<<10 | 0
2171 OP_MCRXR = 31<<26 | 512<<1 | 0<<10 | 0
2172 OP_MFCR = 31<<26 | 19<<1 | 0<<10 | 0
2173 OP_MFFS = 63<<26 | 583<<1 | 0<<10 | 0
2174 OP_MFMSR = 31<<26 | 83<<1 | 0<<10 | 0
2175 OP_MFSPR = 31<<26 | 339<<1 | 0<<10 | 0
2176 OP_MFSR = 31<<26 | 595<<1 | 0<<10 | 0
2177 OP_MFSRIN = 31<<26 | 659<<1 | 0<<10 | 0
2178 OP_MTCRF = 31<<26 | 144<<1 | 0<<10 | 0
2179 OP_MTFSF = 63<<26 | 711<<1 | 0<<10 | 0
2180 OP_MTFSFI = 63<<26 | 134<<1 | 0<<10 | 0
2181 OP_MTMSR = 31<<26 | 146<<1 | 0<<10 | 0
2182 OP_MTMSRD = 31<<26 | 178<<1 | 0<<10 | 0
2183 OP_MTSPR = 31<<26 | 467<<1 | 0<<10 | 0
2184 OP_MTSR = 31<<26 | 210<<1 | 0<<10 | 0
2185 OP_MTSRIN = 31<<26 | 242<<1 | 0<<10 | 0
2186 OP_MULLW = 31<<26 | 235<<1 | 0<<10 | 0
2187 OP_MULLD = 31<<26 | 233<<1 | 0<<10 | 0
2188 OP_OR = 31<<26 | 444<<1 | 0<<10 | 0
2189 OP_ORI = 24<<26 | 0<<1 | 0<<10 | 0
2190 OP_ORIS = 25<<26 | 0<<1 | 0<<10 | 0
2191 OP_RLWINM = 21<<26 | 0<<1 | 0<<10 | 0
2192 OP_RLWNM = 23<<26 | 0<<1 | 0<<10 | 0
2193 OP_SUBF = 31<<26 | 40<<1 | 0<<10 | 0
2194 OP_RLDIC = 30<<26 | 4<<1 | 0<<10 | 0
2195 OP_RLDICR = 30<<26 | 2<<1 | 0<<10 | 0
2196 OP_RLDICL = 30<<26 | 0<<1 | 0<<10 | 0
2197 OP_RLDCL = 30<<26 | 8<<1 | 0<<10 | 0
2198 OP_EXTSWSLI = 31<<26 | 445<<2
2201 func oclass(a *obj.Addr) int {
2202 return int(a.Class) - 1
2210 // This function determines when a non-indexed load or store is D or
2211 // DS form for use in finding the size of the offset field in the instruction.
2212 // The size is needed when setting the offset value in the instruction
2213 // and when generating relocation for that field.
2214 // DS form instructions include: ld, ldu, lwa, std, stdu. All other
2215 // loads and stores with an offset field are D form. This function should
2216 // only be called with the same opcodes as are handled by opstore and opload.
2217 func (c *ctxt9) opform(insn uint32) int {
2220 c.ctxt.Diag("bad insn in loadform: %x", insn)
2221 case OPVCC(58, 0, 0, 0), // ld
2222 OPVCC(58, 0, 0, 1), // ldu
2223 OPVCC(58, 0, 0, 0) | 1<<1, // lwa
2224 OPVCC(62, 0, 0, 0), // std
2225 OPVCC(62, 0, 0, 1): //stdu
2227 case OP_ADDI, // add
2228 OPVCC(32, 0, 0, 0), // lwz
2229 OPVCC(33, 0, 0, 0), // lwzu
2230 OPVCC(34, 0, 0, 0), // lbz
2231 OPVCC(35, 0, 0, 0), // lbzu
2232 OPVCC(40, 0, 0, 0), // lhz
2233 OPVCC(41, 0, 0, 0), // lhzu
2234 OPVCC(42, 0, 0, 0), // lha
2235 OPVCC(43, 0, 0, 0), // lhau
2236 OPVCC(46, 0, 0, 0), // lmw
2237 OPVCC(48, 0, 0, 0), // lfs
2238 OPVCC(49, 0, 0, 0), // lfsu
2239 OPVCC(50, 0, 0, 0), // lfd
2240 OPVCC(51, 0, 0, 0), // lfdu
2241 OPVCC(36, 0, 0, 0), // stw
2242 OPVCC(37, 0, 0, 0), // stwu
2243 OPVCC(38, 0, 0, 0), // stb
2244 OPVCC(39, 0, 0, 0), // stbu
2245 OPVCC(44, 0, 0, 0), // sth
2246 OPVCC(45, 0, 0, 0), // sthu
2247 OPVCC(47, 0, 0, 0), // stmw
2248 OPVCC(52, 0, 0, 0), // stfs
2249 OPVCC(53, 0, 0, 0), // stfsu
2250 OPVCC(54, 0, 0, 0), // stfd
2251 OPVCC(55, 0, 0, 0): // stfdu
2257 // Encode instructions and create relocation for accessing s+d according to the
2258 // instruction op with source or destination (as appropriate) register reg.
2259 func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32) (o1, o2 uint32) {
2260 if c.ctxt.Headtype == objabi.Haix {
2261 // Every symbol access must be made via a TOC anchor.
2262 c.ctxt.Diag("symbolAccess called for %s", s.Name)
2265 form := c.opform(op)
2266 if c.ctxt.Flag_shared {
2271 o1 = AOP_IRR(OP_ADDIS, REGTMP, base, 0)
2272 o2 = AOP_IRR(op, uint32(reg), REGTMP, 0)
2273 rel := obj.Addrel(c.cursym)
2274 rel.Off = int32(c.pc)
2278 if c.ctxt.Flag_shared {
2281 rel.Type = objabi.R_ADDRPOWER_TOCREL
2283 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
2289 rel.Type = objabi.R_ADDRPOWER
2291 rel.Type = objabi.R_ADDRPOWER_DS
2300 func getmask(m []byte, v uint32) bool {
2303 if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
2314 for i := 0; i < 32; i++ {
2315 if v&(1<<uint(31-i)) != 0 {
2320 if i >= 32 || v&(1<<uint(31-i)) == 0 {
2326 if v&(1<<uint(31-i)) != 0 {
2337 func (c *ctxt9) maskgen(p *obj.Prog, m []byte, v uint32) {
2339 c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
2344 * 64-bit masks (rldic etc)
2346 func getmask64(m []byte, v uint64) bool {
2349 for i := 0; i < 64; i++ {
2350 if v&(uint64(1)<<uint(63-i)) != 0 {
2355 if i >= 64 || v&(uint64(1)<<uint(63-i)) == 0 {
2361 if v&(uint64(1)<<uint(63-i)) != 0 {
2372 func (c *ctxt9) maskgen64(p *obj.Prog, m []byte, v uint64) {
2373 if !getmask64(m, v) {
2374 c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
2378 func loadu32(r int, d int64) uint32 {
2380 if isuint32(uint64(d)) {
2381 return LOP_IRR(OP_ORIS, uint32(r), REGZERO, uint32(v))
2383 return AOP_IRR(OP_ADDIS, uint32(r), REGZERO, uint32(v))
2386 func high16adjusted(d int32) uint16 {
2388 return uint16((d >> 16) + 1)
2390 return uint16(d >> 16)
2393 func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
2400 //print("%v => case %d\n", p, o->type);
2403 c.ctxt.Diag("unknown type %d", o.type_)
2406 case 0: /* pseudo ops */
2409 case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
2410 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
2411 v := c.regoff(&p.From)
2412 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
2414 c.ctxt.Diag("literal operation on R0\n%v", p)
2417 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
2421 o1 = LOP_RRR(OP_OR, uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg))
2423 case 2: /* int/cr/fp op Rb,[Ra],Rd */
2429 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2431 case 3: /* mov $soreg/addcon/andcon/ucon, r ==> addis/oris/addi/ori $i,reg',r */
2432 d := c.vregoff(&p.From)
2435 r := int(p.From.Reg)
2437 r = c.getimpliedreg(&p.From, p)
2439 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
2440 c.ctxt.Diag("literal operation on R0\n%v", p)
2445 log.Fatalf("invalid handling of %v", p)
2447 // For UCON operands the value is right shifted 16, using ADDIS if the
2448 // value should be signed, ORIS if unsigned.
2450 if r == REGZERO && isuint32(uint64(d)) {
2451 o1 = LOP_IRR(OP_ORIS, uint32(p.To.Reg), REGZERO, uint32(v))
2456 } else if int64(int16(d)) != d {
2457 // Operand is 16 bit value with sign bit set
2458 if o.a1 == C_ANDCON {
2459 // Needs unsigned 16 bit so use ORI
2460 if r == 0 || r == REGZERO {
2461 o1 = LOP_IRR(uint32(OP_ORI), uint32(p.To.Reg), uint32(0), uint32(v))
2464 // With ADDCON, needs signed 16 bit value, fall through to use ADDI
2465 } else if o.a1 != C_ADDCON {
2466 log.Fatalf("invalid handling of %v", p)
2470 o1 = AOP_IRR(uint32(a), uint32(p.To.Reg), uint32(r), uint32(v))
2472 case 4: /* add/mul $scon,[r1],r2 */
2473 v := c.regoff(&p.From)
2479 if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 {
2480 c.ctxt.Diag("literal operation on R0\n%v", p)
2482 if int32(int16(v)) != v {
2483 log.Fatalf("mishandled instruction %v", p)
2485 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2487 case 5: /* syscall */
2490 case 6: /* logical op Rb,[Rs,]Ra; no literal */
2496 // AROTL and AROTLW are extended mnemonics, which map to RLDCL and RLWNM.
2499 o1 = AOP_RLDIC(OP_RLDCL, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), uint32(0))
2501 o1 = OP_RLW(OP_RLWNM, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), 0, 31)
2503 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2506 case 7: /* mov r, soreg ==> stw o(r) */
2510 r = c.getimpliedreg(&p.To, p)
2512 v := c.regoff(&p.To)
2513 if p.To.Type == obj.TYPE_MEM && p.To.Index != 0 {
2515 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2517 if c.ctxt.Flag_shared && r == REG_R13 {
2518 rel := obj.Addrel(c.cursym)
2519 rel.Off = int32(c.pc)
2521 // This (and the matching part in the load case
2522 // below) are the only places in the ppc64 toolchain
2523 // that knows the name of the tls variable. Possibly
2524 // we could add some assembly syntax so that the name
2525 // of the variable does not have to be assumed.
2526 rel.Sym = c.ctxt.Lookup("runtime.tls_g")
2527 rel.Type = objabi.R_POWER_TLS
2529 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(r))
2531 if int32(int16(v)) != v {
2532 log.Fatalf("mishandled instruction %v", p)
2534 // Offsets in DS form stores must be a multiple of 4
2535 inst := c.opstore(p.As)
2536 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2537 log.Fatalf("invalid offset for DS form load/store %v", p)
2539 o1 = AOP_IRR(inst, uint32(p.From.Reg), uint32(r), uint32(v))
2542 case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */
2543 r := int(p.From.Reg)
2546 r = c.getimpliedreg(&p.From, p)
2548 v := c.regoff(&p.From)
2549 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
2551 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2553 if c.ctxt.Flag_shared && r == REG_R13 {
2554 rel := obj.Addrel(c.cursym)
2555 rel.Off = int32(c.pc)
2557 rel.Sym = c.ctxt.Lookup("runtime.tls_g")
2558 rel.Type = objabi.R_POWER_TLS
2560 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
2562 if int32(int16(v)) != v {
2563 log.Fatalf("mishandled instruction %v", p)
2565 // Offsets in DS form loads must be a multiple of 4
2566 inst := c.opload(p.As)
2567 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
2568 log.Fatalf("invalid offset for DS form load/store %v", p)
2570 o1 = AOP_IRR(inst, uint32(p.To.Reg), uint32(r), uint32(v))
2573 case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */
2574 r := int(p.From.Reg)
2577 r = c.getimpliedreg(&p.From, p)
2579 v := c.regoff(&p.From)
2580 if p.From.Type == obj.TYPE_MEM && p.From.Index != 0 {
2582 c.ctxt.Diag("illegal indexed instruction\n%v", p)
2584 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(r))
2586 o1 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2588 o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
2590 case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
2596 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r))
2598 case 11: /* br/bl lbra */
2601 if p.To.Target() != nil {
2602 v = int32(p.To.Target().Pc - p.Pc)
2604 c.ctxt.Diag("odd branch target address\n%v", p)
2608 if v < -(1<<25) || v >= 1<<24 {
2609 c.ctxt.Diag("branch too far\n%v", p)
2613 o1 = OP_BR(c.opirr(p.As), uint32(v), 0)
2614 if p.To.Sym != nil {
2615 rel := obj.Addrel(c.cursym)
2616 rel.Off = int32(c.pc)
2619 v += int32(p.To.Offset)
2621 c.ctxt.Diag("odd branch target address\n%v", p)
2626 rel.Type = objabi.R_CALLPOWER
2628 o2 = 0x60000000 // nop, sometimes overwritten by ld r2, 24(r1) when dynamic linking
2630 case 12: /* movb r,r (extsb); movw r,r (extsw) */
2631 if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST {
2632 v := c.regoff(&p.From)
2633 if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 {
2634 c.ctxt.Diag("literal operation on R0\n%v", p)
2637 o1 = LOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(v))
2642 o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2644 o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2647 case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */
2649 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31)
2650 } else if p.As == AMOVH {
2651 o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0)
2652 } else if p.As == AMOVHZ {
2653 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 16, 31)
2654 } else if p.As == AMOVWZ {
2655 o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */
2657 c.ctxt.Diag("internal: bad mov[bhw]z\n%v", p)
2660 case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */
2666 d := c.vregoff(p.GetFrom3())
2670 // These opcodes expect a mask operand that has to be converted into the
2671 // appropriate operand. The way these were defined, not all valid masks are possible.
2672 // Left here for compatibility in case they were used or generated.
2673 case ARLDCL, ARLDCLCC:
2675 c.maskgen64(p, mask[:], uint64(d))
2677 a = int(mask[0]) /* MB */
2679 c.ctxt.Diag("invalid mask for rotate: %x (end != bit 63)\n%v", uint64(d), p)
2681 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2682 o1 |= (uint32(a) & 31) << 6
2684 o1 |= 1 << 5 /* mb[5] is top bit */
2687 case ARLDCR, ARLDCRCC:
2689 c.maskgen64(p, mask[:], uint64(d))
2691 a = int(mask[1]) /* ME */
2693 c.ctxt.Diag("invalid mask for rotate: %x %x (start != 0)\n%v", uint64(d), mask[0], p)
2695 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg))
2696 o1 |= (uint32(a) & 31) << 6
2698 o1 |= 1 << 5 /* mb[5] is top bit */
2701 // These opcodes use a shift count like the ppc64 asm, no mask conversion done
2702 case ARLDICR, ARLDICRCC:
2704 sh := c.regoff(&p.From)
2705 if me < 0 || me > 63 || sh > 63 {
2706 c.ctxt.Diag("Invalid me or sh for RLDICR: %x %x\n%v", int(d), sh, p)
2708 o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(me))
2710 case ARLDICL, ARLDICLCC, ARLDIC, ARLDICCC:
2712 sh := c.regoff(&p.From)
2713 if mb < 0 || mb > 63 || sh > 63 {
2714 c.ctxt.Diag("Invalid mb or sh for RLDIC, RLDICL: %x %x\n%v", mb, sh, p)
2716 o1 = AOP_RLDIC(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(sh), uint32(mb))
2719 // This is an extended mnemonic defined in the ISA section C.8.1
2720 // clrlsldi ra,rs,b,n --> rldic ra,rs,n,b-n
2721 // It maps onto RLDIC so is directly generated here based on the operands from
2724 b := c.regoff(&p.From)
2725 if n > b || b > 63 {
2726 c.ctxt.Diag("Invalid n or b for CLRLSLDI: %x %x\n%v", n, b, p)
2728 o1 = AOP_RLDIC(OP_RLDIC, uint32(p.To.Reg), uint32(r), uint32(n), uint32(b)-uint32(n))
2731 c.ctxt.Diag("unexpected op in rldc case\n%v", p)
2735 case 17, /* bc bo,bi,lbra (same for now) */
2736 16: /* bc bo,bi,sbra */
2741 if p.From.Type == obj.TYPE_CONST {
2742 a = int(c.regoff(&p.From))
2743 } else if p.From.Type == obj.TYPE_REG {
2745 c.ctxt.Diag("unexpected register setting for branch with CR: %d\n", r)
2747 // BI values for the CR
2766 c.ctxt.Diag("unrecognized register: expecting CR\n")
2770 if p.To.Target() != nil {
2771 v = int32(p.To.Target().Pc - p.Pc)
2774 c.ctxt.Diag("odd branch target address\n%v", p)
2778 if v < -(1<<16) || v >= 1<<15 {
2779 c.ctxt.Diag("branch too far\n%v", p)
2781 o1 = OP_BC(c.opirr(p.As), uint32(a), uint32(r), uint32(v), 0)
2783 case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */
2785 if p.As == ABC || p.As == ABCL {
2786 v = c.regoff(&p.To) & 31
2788 v = 20 /* unconditional */
2790 o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11
2791 o2 = OPVCC(19, 16, 0, 0)
2792 if p.As == ABL || p.As == ABCL {
2795 o2 = OP_BCR(o2, uint32(v), uint32(p.To.Index))
2797 case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */
2800 if p.As == ABC || p.As == ABCL {
2801 v = c.regoff(&p.From) & 31
2803 v = 20 /* unconditional */
2809 switch oclass(&p.To) {
2811 o1 = OPVCC(19, 528, 0, 0)
2814 o1 = OPVCC(19, 16, 0, 0)
2817 c.ctxt.Diag("bad optab entry (18): %d\n%v", p.To.Class, p)
2821 // Insert optional branch hint for bclr[l]/bcctr[l]
2822 if p.From3Type() != obj.TYPE_NONE {
2823 bh = uint32(p.GetFrom3().Offset)
2824 if bh == 2 || bh > 3 {
2825 log.Fatalf("BH must be 0,1,3 for %v", p)
2830 if p.As == ABL || p.As == ABCL {
2833 o1 = OP_BCR(o1, uint32(v), uint32(r))
2835 case 19: /* mov $lcon,r ==> cau+or */
2836 d := c.vregoff(&p.From)
2838 if p.From.Sym == nil {
2839 o1 = loadu32(int(p.To.Reg), d)
2840 o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
2842 o1, o2 = c.symbolAccess(p.From.Sym, d, p.To.Reg, OP_ADDI)
2845 case 20: /* add $ucon,,r | addis $addcon,r,r */
2846 v := c.regoff(&p.From)
2852 if p.As == AADD && (r0iszero == 0 /*TypeKind(100016)*/ && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) {
2853 c.ctxt.Diag("literal operation on R0\n%v", p)
2856 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2858 o1 = AOP_IRR(c.opirr(AADDIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
2861 case 22: /* add $lcon/$andcon,r1,r2 ==> oris+ori+add/ori+add */
2862 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2863 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2865 d := c.vregoff(&p.From)
2870 if p.From.Sym != nil {
2871 c.ctxt.Diag("%v is not supported", p)
2873 // If operand is ANDCON, generate 2 instructions using
2874 // ORI for unsigned value; with LCON 3 instructions.
2876 o1 = LOP_IRR(OP_ORI, REGTMP, REGZERO, uint32(int32(d)))
2877 o2 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2879 o1 = loadu32(REGTMP, d)
2880 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2881 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2884 case 23: /* and $lcon/$addcon,r1,r2 ==> oris+ori+and/addi+and */
2885 if p.To.Reg == REGTMP || p.Reg == REGTMP {
2886 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2888 d := c.vregoff(&p.From)
2894 // With ADDCON operand, generate 2 instructions using ADDI for signed value,
2895 // with LCON operand generate 3 instructions.
2897 o1 = LOP_IRR(OP_ADDI, REGZERO, REGTMP, uint32(int32(d)))
2898 o2 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2900 o1 = loadu32(REGTMP, d)
2901 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d)))
2902 o3 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), REGTMP, uint32(r))
2904 if p.From.Sym != nil {
2905 c.ctxt.Diag("%v is not supported", p)
2908 case 24: /* lfd fA,float64(0) -> xxlxor xsA,xsaA,xsaA + fneg for -0 */
2909 o1 = AOP_XX3I(c.oprrr(AXXLXOR), uint32(p.To.Reg), uint32(p.To.Reg), uint32(p.To.Reg), uint32(0))
2910 // This is needed for -0.
2912 o2 = AOP_RRR(c.oprrr(AFNEG), uint32(p.To.Reg), 0, uint32(p.To.Reg))
2916 /* sld[.] $sh,rS,rA -> rldicr[.] $sh,rS,mask(0,63-sh),rA; srd[.] -> rldicl */
2917 v := c.regoff(&p.From)
2945 c.ctxt.Diag("unexpected op in sldi case\n%v", p)
2950 if p.As == AEXTSWSLI || p.As == AEXTSWSLICC {
2951 o1 = AOP_EXTSWSLI(OP_EXTSWSLI, uint32(r), uint32(p.To.Reg), uint32(v))
2954 o1 = AOP_RLDIC(op, uint32(p.To.Reg), uint32(r), uint32(v), uint32(a))
2956 if p.As == ASLDCC || p.As == ASRDCC || p.As == AEXTSWSLICC {
2957 o1 |= 1 // Set the condition code bit
2960 case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
2961 if p.To.Reg == REGTMP {
2962 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2964 v := c.regoff(&p.From)
2965 r := int(p.From.Reg)
2967 r = c.getimpliedreg(&p.From, p)
2969 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
2970 o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
2972 case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
2973 v := c.regoff(p.GetFrom3())
2975 r := int(p.From.Reg)
2976 o1 = AOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
2978 case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */
2979 if p.To.Reg == REGTMP || p.From.Reg == REGTMP {
2980 c.ctxt.Diag("can't synthesize large constant\n%v", p)
2982 v := c.regoff(p.GetFrom3())
2983 o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(v)>>16)
2984 o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(v))
2985 o3 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), REGTMP)
2986 if p.From.Sym != nil {
2987 c.ctxt.Diag("%v is not supported", p)
2990 case 29: /* rldic[lr]? $sh,s,$mask,a -- left, right, plain give different masks */
2991 v := c.regoff(&p.From)
2993 d := c.vregoff(p.GetFrom3())
2995 c.maskgen64(p, mask[:], uint64(d))
2998 case ARLDC, ARLDCCC:
2999 a = int(mask[0]) /* MB */
3000 if int32(mask[1]) != (63 - v) {
3001 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[1], v, p)
3004 case ARLDCL, ARLDCLCC:
3005 a = int(mask[0]) /* MB */
3007 c.ctxt.Diag("invalid mask for shift: %x %s (shift %d)\n%v", uint64(d), mask[1], v, p)
3010 case ARLDCR, ARLDCRCC:
3011 a = int(mask[1]) /* ME */
3013 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[0], v, p)
3017 c.ctxt.Diag("unexpected op in rldic case\n%v", p)
3021 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3022 o1 |= (uint32(a) & 31) << 6
3027 o1 |= 1 << 5 /* mb[5] is top bit */
3030 case 30: /* rldimi $sh,s,$mask,a */
3031 v := c.regoff(&p.From)
3033 d := c.vregoff(p.GetFrom3())
3035 // Original opcodes had mask operands which had to be converted to a shift count as expected by
3038 case ARLDMI, ARLDMICC:
3040 c.maskgen64(p, mask[:], uint64(d))
3041 if int32(mask[1]) != (63 - v) {
3042 c.ctxt.Diag("invalid mask for shift: %x %x (shift %d)\n%v", uint64(d), mask[1], v, p)
3044 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3045 o1 |= (uint32(mask[0]) & 31) << 6
3049 if mask[0]&0x20 != 0 {
3050 o1 |= 1 << 5 /* mb[5] is top bit */
3053 // Opcodes with shift count operands.
3054 case ARLDIMI, ARLDIMICC:
3055 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), (uint32(v) & 0x1F))
3056 o1 |= (uint32(d) & 31) << 6
3065 case 31: /* dword */
3066 d := c.vregoff(&p.From)
3068 if c.ctxt.Arch.ByteOrder == binary.BigEndian {
3069 o1 = uint32(d >> 32)
3073 o2 = uint32(d >> 32)
3076 if p.From.Sym != nil {
3077 rel := obj.Addrel(c.cursym)
3078 rel.Off = int32(c.pc)
3080 rel.Sym = p.From.Sym
3081 rel.Add = p.From.Offset
3082 rel.Type = objabi.R_ADDR
3087 case 32: /* fmul frc,fra,frd */
3093 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6
3095 case 33: /* fabs [frb,]frd; fmr. frb,frd */
3096 r := int(p.From.Reg)
3098 if oclass(&p.From) == C_NONE {
3101 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(r))
3103 case 34: /* FMADDx fra,frb,frc,frt (t=a*c±b) */
3104 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg)) | (uint32(p.GetFrom3().Reg)&31)<<6
3106 case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
3107 v := c.regoff(&p.To)
3111 r = c.getimpliedreg(&p.To, p)
3113 // Offsets in DS form stores must be a multiple of 4
3114 inst := c.opstore(p.As)
3115 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3116 log.Fatalf("invalid offset for DS form load/store %v", p)
3118 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3119 o2 = AOP_IRR(inst, uint32(p.From.Reg), REGTMP, uint32(v))
3121 case 36: /* mov bz/h/hz lext/lauto/lreg,r ==> lbz/lha/lhz etc */
3122 v := c.regoff(&p.From)
3124 r := int(p.From.Reg)
3126 r = c.getimpliedreg(&p.From, p)
3128 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3129 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
3131 case 37: /* movb lext/lauto/lreg,r ==> lbz o(reg),r; extsb r */
3132 v := c.regoff(&p.From)
3134 r := int(p.From.Reg)
3136 r = c.getimpliedreg(&p.From, p)
3138 o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
3139 o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), REGTMP, uint32(v))
3140 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3143 o1 = uint32(c.regoff(&p.From))
3145 case 41: /* stswi */
3146 o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3149 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), 0) | (uint32(c.regoff(p.GetFrom3()))&0x7F)<<11
3151 case 43: /* data cache instructions: op (Ra+[Rb]), [th|l] */
3152 /* TH field for dcbt/dcbtst: */
3153 /* 0 = Block access - program will soon access EA. */
3154 /* 8-15 = Stream access - sequence of access (data stream). See section 4.3.2 of the ISA for details. */
3155 /* 16 = Block access - program will soon make a transient access to EA. */
3156 /* 17 = Block access - program will not access EA for a long time. */
3158 /* L field for dcbf: */
3159 /* 0 = invalidates the block containing EA in all processors. */
3160 /* 1 = same as 0, but with limited scope (i.e. block in the current processor will not be reused soon). */
3161 /* 3 = same as 1, but with even more limited scope (i.e. block in the current processor primary cache will not be reused soon). */
3162 if p.To.Type == obj.TYPE_NONE {
3163 o1 = AOP_RRR(c.oprrr(p.As), 0, uint32(p.From.Index), uint32(p.From.Reg))
3165 th := c.regoff(&p.To)
3166 o1 = AOP_RRR(c.oprrr(p.As), uint32(th), uint32(p.From.Index), uint32(p.From.Reg))
3169 case 44: /* indexed store */
3170 o1 = AOP_RRR(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3172 case 45: /* indexed load */
3174 /* The assembler accepts a 4-operand l*arx instruction. The fourth operand is an Exclusive Access Hint (EH) */
3175 /* The EH field can be used as a lock acquire/release hint as follows: */
3176 /* 0 = Atomic Update (fetch-and-operate or similar algorithm) */
3177 /* 1 = Exclusive Access (lock acquire and release) */
3178 case ALBAR, ALHAR, ALWAR, ALDAR:
3179 if p.From3Type() != obj.TYPE_NONE {
3180 eh := int(c.regoff(p.GetFrom3()))
3182 c.ctxt.Diag("illegal EH field\n%v", p)
3184 o1 = AOP_RRRI(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg), uint32(eh))
3186 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3189 o1 = AOP_RRR(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3191 case 46: /* plain op */
3194 case 47: /* op Ra, Rd; also op [Ra,] Rd */
3195 r := int(p.From.Reg)
3200 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3202 case 48: /* op Rs, Ra */
3203 r := int(p.From.Reg)
3208 o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), 0)
3210 case 49: /* op Rb; op $n, Rb */
3211 if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */
3212 v := c.regoff(&p.From) & 1
3213 o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21
3215 o1 = AOP_RRR(c.oprrr(p.As), 0, 0, uint32(p.From.Reg))
3218 case 50: /* rem[u] r1[,r2],r3 */
3225 t := v & (1<<10 | 1) /* OE|Rc */
3226 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3227 o2 = AOP_RRR(OP_MULLW, REGTMP, REGTMP, uint32(p.From.Reg))
3228 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3232 /* Clear top 32 bits */
3233 o3 = OP_RLW(OP_RLDIC, REGTMP, REGTMP, 0, 0, 0) | 1<<5
3236 case 51: /* remd[u] r1[,r2],r3 */
3243 t := v & (1<<10 | 1) /* OE|Rc */
3244 o1 = AOP_RRR(v&^t, REGTMP, uint32(r), uint32(p.From.Reg))
3245 o2 = AOP_RRR(OP_MULLD, REGTMP, REGTMP, uint32(p.From.Reg))
3246 o3 = AOP_RRR(OP_SUBF|t, uint32(p.To.Reg), REGTMP, uint32(r))
3247 /* cases 50,51: removed; can be reused. */
3249 /* cases 50,51: removed; can be reused. */
3251 case 52: /* mtfsbNx cr(n) */
3252 v := c.regoff(&p.From) & 31
3254 o1 = AOP_RRR(c.oprrr(p.As), uint32(v), 0, 0)
3256 case 53: /* mffsX ,fr1 */
3257 o1 = AOP_RRR(OP_MFFS, uint32(p.To.Reg), 0, 0)
3259 case 54: /* mov msr,r1; mov r1, msr*/
3260 if oclass(&p.From) == C_REG {
3262 o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0)
3264 o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0)
3267 o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0)
3270 case 55: /* op Rb, Rd */
3271 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), 0, uint32(p.From.Reg))
3273 case 56: /* sra $sh,[s,]a; srd $sh,[s,]a */
3274 v := c.regoff(&p.From)
3280 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.To.Reg), uint32(v)&31)
3281 if (p.As == ASRAD || p.As == ASRADCC) && (v&0x20 != 0) {
3282 o1 |= 1 << 1 /* mb[5] */
3285 case 57: /* slw $sh,[s,]a -> rlwinm ... */
3286 v := c.regoff(&p.From)
3294 * Let user (gs) shoot himself in the foot.
3295 * qc has already complained.
3298 ctxt->diag("illegal shift %ld\n%v", v, p);
3308 mask[0], mask[1] = 0, 31
3310 mask[0], mask[1] = uint8(v), 31
3313 mask[0], mask[1] = 0, uint8(31-v)
3315 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(r), uint32(v), uint32(mask[0]), uint32(mask[1]))
3316 if p.As == ASLWCC || p.As == ASRWCC {
3317 o1 |= 1 // set the condition code
3320 case 58: /* logical $andcon,[s],a */
3321 v := c.regoff(&p.From)
3327 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3329 case 59: /* or/xor/and $ucon,,r | oris/xoris/andis $addcon,r,r */
3330 v := c.regoff(&p.From)
3338 o1 = LOP_IRR(c.opirr(AORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis. */
3340 o1 = LOP_IRR(c.opirr(AXORIS), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3342 o1 = LOP_IRR(c.opirr(AANDISCC), uint32(p.To.Reg), uint32(r), uint32(v)>>16)
3344 o1 = LOP_IRR(c.opirr(p.As), uint32(p.To.Reg), uint32(r), uint32(v))
3347 case 60: /* tw to,a,b */
3348 r := int(c.regoff(&p.From) & 31)
3350 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.Reg), uint32(p.To.Reg))
3352 case 61: /* tw to,a,$simm */
3353 r := int(c.regoff(&p.From) & 31)
3355 v := c.regoff(&p.To)
3356 o1 = AOP_IRR(c.opirr(p.As), uint32(r), uint32(p.Reg), uint32(v))
3358 case 62: /* rlwmi $sh,s,$mask,a */
3359 v := c.regoff(&p.From)
3362 n := c.regoff(p.GetFrom3())
3363 // This is an extended mnemonic described in the ISA C.8.2
3364 // clrlslwi ra,rs,b,n -> rlwinm ra,rs,n,b-n,31-n
3365 // It maps onto rlwinm which is directly generated here.
3366 if n > v || v >= 32 {
3367 c.ctxt.Diag("Invalid n or b for CLRLSLWI: %x %x\n%v", v, n, p)
3370 o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.Reg), uint32(n), uint32(v-n), uint32(31-n))
3373 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
3374 o1 = AOP_RRR(c.opirr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(v))
3375 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
3378 case 63: /* rlwmi b,s,$mask,a */
3380 c.maskgen(p, mask[:], uint32(c.regoff(p.GetFrom3())))
3381 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.Reg), uint32(p.To.Reg), uint32(p.From.Reg))
3382 o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1
3384 case 64: /* mtfsf fr[, $m] {,fpcsr} */
3386 if p.From3Type() != obj.TYPE_NONE {
3387 v = c.regoff(p.GetFrom3()) & 255
3391 o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11
3393 case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */
3395 c.ctxt.Diag("must specify FPSCR(n)\n%v", p)
3397 o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(c.regoff(&p.From))&31)<<12
3399 case 66: /* mov spr,r1; mov r1,spr, also dcr */
3402 if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 {
3405 if REG_DCR0 <= v && v <= REG_DCR0+1023 {
3406 o1 = OPVCC(31, 451, 0, 0) /* mtdcr */
3408 o1 = OPVCC(31, 467, 0, 0) /* mtspr */
3412 v = int32(p.From.Reg)
3413 if REG_DCR0 <= v && v <= REG_DCR0+1023 {
3414 o1 = OPVCC(31, 323, 0, 0) /* mfdcr */
3416 o1 = OPVCC(31, 339, 0, 0) /* mfspr */
3420 o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
3422 case 67: /* mcrf crfD,crfS */
3423 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 {
3424 c.ctxt.Diag("illegal CR field number\n%v", p)
3426 o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
3428 case 68: /* mfcr rD; mfocrf CRM,rD */
3429 if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
3430 v := int32(1 << uint(7-(p.To.Reg&7))) /* CR(n) */
3431 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
3433 o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
3436 case 69: /* mtcrf CRM,rS */
3438 if p.From3Type() != obj.TYPE_NONE {
3440 c.ctxt.Diag("can't use both mask and CR(n)\n%v", p)
3442 v = c.regoff(p.GetFrom3()) & 0xff
3447 v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
3451 o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12
3453 case 70: /* [f]cmp r,r,cr*/
3458 r = (int(p.Reg) & 7) << 2
3460 o1 = AOP_RRR(c.oprrr(p.As), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg))
3462 case 71: /* cmp[l] r,i,cr*/
3467 r = (int(p.Reg) & 7) << 2
3469 o1 = AOP_RRR(c.opirr(p.As), uint32(r), uint32(p.From.Reg), 0) | uint32(c.regoff(&p.To))&0xffff
3471 case 72: /* slbmte (Rb+Rs -> slb[Rb]) -> Rs, Rb */
3472 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), 0, uint32(p.To.Reg))
3474 case 73: /* mcrfs crfD,crfS */
3475 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 {
3476 c.ctxt.Diag("illegal FPSCR/CR field number\n%v", p)
3478 o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0)
3480 case 77: /* syscall $scon, syscall Rx */
3481 if p.From.Type == obj.TYPE_CONST {
3482 if p.From.Offset > BIG || p.From.Offset < -BIG {
3483 c.ctxt.Diag("illegal syscall, sysnum too large: %v", p)
3485 o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset))
3486 } else if p.From.Type == obj.TYPE_REG {
3487 o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg))
3489 c.ctxt.Diag("illegal syscall: %v", p)
3490 o1 = 0x7fe00008 // trap always
3494 o3 = AOP_RRR(c.oprrr(AXOR), REGZERO, REGZERO, REGZERO) // XOR R0, R0
3496 case 78: /* undef */
3497 o1 = 0 /* "An instruction consisting entirely of binary 0s is guaranteed
3498 always to be an illegal instruction." */
3500 /* relocation operations */
3502 v := c.vregoff(&p.To)
3503 // Offsets in DS form stores must be a multiple of 4
3504 inst := c.opstore(p.As)
3505 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3506 log.Fatalf("invalid offset for DS form load/store %v", p)
3508 o1, o2 = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst)
3510 //if(dlm) reloc(&p->to, p->pc, 1);
3513 v := c.vregoff(&p.From)
3514 // Offsets in DS form loads must be a multiple of 4
3515 inst := c.opload(p.As)
3516 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3517 log.Fatalf("invalid offset for DS form load/store %v", p)
3519 o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
3521 //if(dlm) reloc(&p->from, p->pc, 1);
3524 v := c.vregoff(&p.From)
3525 // Offsets in DS form loads must be a multiple of 4
3526 inst := c.opload(p.As)
3527 if c.opform(inst) == DS_FORM && v&0x3 != 0 {
3528 log.Fatalf("invalid offset for DS form load/store %v", p)
3530 o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
3531 o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3533 //if(dlm) reloc(&p->from, p->pc, 1);
3536 if p.From.Offset != 0 {
3537 c.ctxt.Diag("invalid offset against tls var %v", p)
3539 o1 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGZERO, 0)
3540 rel := obj.Addrel(c.cursym)
3541 rel.Off = int32(c.pc)
3543 rel.Sym = p.From.Sym
3544 rel.Type = objabi.R_POWER_TLS_LE
3547 if p.From.Offset != 0 {
3548 c.ctxt.Diag("invalid offset against tls var %v", p)
3550 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3551 o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3552 rel := obj.Addrel(c.cursym)
3553 rel.Off = int32(c.pc)
3555 rel.Sym = p.From.Sym
3556 rel.Type = objabi.R_POWER_TLS_IE
3559 v := c.vregoff(&p.To)
3561 c.ctxt.Diag("invalid offset against GOT slot %v", p)
3564 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3565 o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
3566 rel := obj.Addrel(c.cursym)
3567 rel.Off = int32(c.pc)
3569 rel.Sym = p.From.Sym
3570 rel.Type = objabi.R_ADDRPOWER_GOT
3571 case 82: /* vector instructions, VX-form and VC-form */
3572 if p.From.Type == obj.TYPE_REG {
3573 /* reg reg none OR reg reg reg */
3574 /* 3-register operand order: VRA, VRB, VRT */
3575 /* 2-register operand order: VRA, VRT */
3576 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3577 } else if p.From3Type() == obj.TYPE_CONST {
3578 /* imm imm reg reg */
3579 /* operand order: SIX, VRA, ST, VRT */
3580 six := int(c.regoff(&p.From))
3581 st := int(c.regoff(p.GetFrom3()))
3582 o1 = AOP_IIRR(c.opiirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(st), uint32(six))
3583 } else if p.From3Type() == obj.TYPE_NONE && p.Reg != 0 {
3585 /* operand order: UIM, VRB, VRT */
3586 uim := int(c.regoff(&p.From))
3587 o1 = AOP_VIRR(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(uim))
3590 /* operand order: SIM, VRT */
3591 sim := int(c.regoff(&p.From))
3592 o1 = AOP_IR(c.opirr(p.As), uint32(p.To.Reg), uint32(sim))
3595 case 83: /* vector instructions, VA-form */
3596 if p.From.Type == obj.TYPE_REG {
3597 /* reg reg reg reg */
3598 /* 4-register operand order: VRA, VRB, VRC, VRT */
3599 o1 = AOP_RRRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3600 } else if p.From.Type == obj.TYPE_CONST {
3601 /* imm reg reg reg */
3602 /* operand order: SHB, VRA, VRB, VRT */
3603 shb := int(c.regoff(&p.From))
3604 o1 = AOP_IRRR(c.opirrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(shb))
3607 case 84: // ISEL BC,RA,RB,RT -> isel rt,ra,rb,bc
3608 bc := c.vregoff(&p.From)
3610 // rt = To.Reg, ra = p.Reg, rb = p.From3.Reg
3611 o1 = AOP_ISEL(OP_ISEL, uint32(p.To.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg), uint32(bc))
3613 case 85: /* vector instructions, VX-form */
3615 /* 2-register operand order: VRB, VRT */
3616 o1 = AOP_RR(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg))
3618 case 86: /* VSX indexed store, XX1-form */
3620 /* 3-register operand order: XT, (RB)(RA*1) */
3621 o1 = AOP_XX1(c.opstorex(p.As), uint32(p.From.Reg), uint32(p.To.Index), uint32(p.To.Reg))
3623 case 87: /* VSX indexed load, XX1-form */
3625 /* 3-register operand order: (RB)(RA*1), XT */
3626 o1 = AOP_XX1(c.oploadx(p.As), uint32(p.To.Reg), uint32(p.From.Index), uint32(p.From.Reg))
3628 case 88: /* VSX instructions, XX1-form */
3629 /* reg reg none OR reg reg reg */
3630 /* 3-register operand order: RA, RB, XT */
3631 /* 2-register operand order: XS, RA or RA, XT */
3632 xt := int32(p.To.Reg)
3633 xs := int32(p.From.Reg)
3634 /* We need to treat the special case of extended mnemonics that may have a FREG/VREG as an argument */
3635 if REG_V0 <= xt && xt <= REG_V31 {
3636 /* Convert V0-V31 to VS32-VS63 */
3638 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3639 } else if REG_F0 <= xt && xt <= REG_F31 {
3640 /* Convert F0-F31 to VS0-VS31 */
3642 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3643 } else if REG_VS0 <= xt && xt <= REG_VS63 {
3644 o1 = AOP_XX1(c.oprrr(p.As), uint32(xt), uint32(p.From.Reg), uint32(p.Reg))
3645 } else if REG_V0 <= xs && xs <= REG_V31 {
3646 /* Likewise for XS */
3648 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3649 } else if REG_F0 <= xs && xs <= REG_F31 {
3651 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3652 } else if REG_VS0 <= xs && xs <= REG_VS63 {
3653 o1 = AOP_XX1(c.oprrr(p.As), uint32(xs), uint32(p.To.Reg), uint32(p.Reg))
3656 case 89: /* VSX instructions, XX2-form */
3657 /* reg none reg OR reg imm reg */
3658 /* 2-register operand order: XB, XT or XB, UIM, XT*/
3659 uim := int(c.regoff(p.GetFrom3()))
3660 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(uim), uint32(p.From.Reg))
3662 case 90: /* VSX instructions, XX3-form */
3663 if p.From3Type() == obj.TYPE_NONE {
3665 /* 3-register operand order: XA, XB, XT */
3666 o1 = AOP_XX3(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3667 } else if p.From3Type() == obj.TYPE_CONST {
3668 /* reg reg reg imm */
3669 /* operand order: XA, XB, DM, XT */
3670 dm := int(c.regoff(p.GetFrom3()))
3671 o1 = AOP_XX3I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(dm))
3674 case 91: /* VSX instructions, XX4-form */
3675 /* reg reg reg reg */
3676 /* 3-register operand order: XA, XB, XC, XT */
3677 o1 = AOP_XX4(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(p.GetFrom3().Reg))
3679 case 92: /* X-form instructions, 3-operands */
3680 if p.To.Type == obj.TYPE_CONST {
3682 xf := int32(p.From.Reg)
3683 if REG_F0 <= xf && xf <= REG_F31 {
3684 /* operand order: FRA, FRB, BF */
3685 bf := int(c.regoff(&p.To)) << 2
3686 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3688 /* operand order: RA, RB, L */
3689 l := int(c.regoff(&p.To))
3690 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.From.Reg), uint32(p.Reg))
3692 } else if p.From3Type() == obj.TYPE_CONST {
3694 /* operand order: RB, L, RA */
3695 l := int(c.regoff(p.GetFrom3()))
3696 o1 = AOP_RRR(c.opirr(p.As), uint32(l), uint32(p.To.Reg), uint32(p.From.Reg))
3697 } else if p.To.Type == obj.TYPE_REG {
3698 cr := int32(p.To.Reg)
3699 if REG_CR0 <= cr && cr <= REG_CR7 {
3701 /* operand order: RA, RB, BF */
3702 bf := (int(p.To.Reg) & 7) << 2
3703 o1 = AOP_RRR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg), uint32(p.Reg))
3704 } else if p.From.Type == obj.TYPE_CONST {
3706 /* operand order: L, RT */
3707 l := int(c.regoff(&p.From))
3708 o1 = AOP_RRR(c.opirr(p.As), uint32(p.To.Reg), uint32(l), uint32(p.Reg))
3711 case ACOPY, APASTECC:
3712 o1 = AOP_RRR(c.opirr(p.As), uint32(1), uint32(p.From.Reg), uint32(p.To.Reg))
3715 /* operand order: RS, RB, RA */
3716 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3721 case 93: /* X-form instructions, 2-operands */
3722 if p.To.Type == obj.TYPE_CONST {
3724 /* operand order: FRB, BF */
3725 bf := int(c.regoff(&p.To)) << 2
3726 o1 = AOP_RR(c.opirr(p.As), uint32(bf), uint32(p.From.Reg))
3727 } else if p.Reg == 0 {
3728 /* popcnt* r,r, X-form */
3729 /* operand order: RS, RA */
3730 o1 = AOP_RRR(c.oprrr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(p.Reg))
3733 case 94: /* Z23-form instructions, 4-operands */
3734 /* reg reg reg imm */
3735 /* operand order: RA, RB, CY, RT */
3736 cy := int(c.regoff(p.GetFrom3()))
3737 o1 = AOP_Z23I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(cy))
3739 case 95: /* Retrieve TOC relative symbol */
3740 /* This code is for AIX only */
3741 v := c.vregoff(&p.From)
3743 c.ctxt.Diag("invalid offset against TOC slot %v", p)
3746 inst := c.opload(p.As)
3747 if c.opform(inst) != DS_FORM {
3748 c.ctxt.Diag("invalid form for a TOC access in %v", p)
3751 o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
3752 o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
3753 rel := obj.Addrel(c.cursym)
3754 rel.Off = int32(c.pc)
3756 rel.Sym = p.From.Sym
3757 rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
3759 case 96: /* VSX load, DQ-form */
3761 /* operand order: (RA)(DQ), XT */
3762 dq := int16(c.regoff(&p.From))
3764 c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3766 o1 = AOP_DQ(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(dq))
3768 case 97: /* VSX store, DQ-form */
3770 /* operand order: XT, (RA)(DQ) */
3771 dq := int16(c.regoff(&p.To))
3773 c.ctxt.Diag("invalid offset for DQ form load/store %v", dq)
3775 o1 = AOP_DQ(c.opstore(p.As), uint32(p.From.Reg), uint32(p.To.Reg), uint32(dq))
3776 case 98: /* VSX indexed load or load with length (also left-justified), x-form */
3777 /* vsreg, reg, reg */
3778 o1 = AOP_XX1(c.opload(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg))
3779 case 99: /* VSX store with length (also left-justified) x-form */
3780 /* reg, reg, vsreg */
3781 o1 = AOP_XX1(c.opstore(p.As), uint32(p.From.Reg), uint32(p.Reg), uint32(p.To.Reg))
3782 case 100: /* VSX X-form XXSPLTIB */
3783 if p.From.Type == obj.TYPE_CONST {
3785 uim := int(c.regoff(&p.From))
3787 /* Use AOP_XX1 form with 0 for one of the registers. */
3788 o1 = AOP_XX1(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(uim))
3790 c.ctxt.Diag("invalid ops for %v", p.As)
3793 o1 = AOP_XX2(c.oprrr(p.As), uint32(p.To.Reg), uint32(0), uint32(p.From.Reg))
3795 case 102: /* RLWMI $sh,rs,$mb,$me,rt (M-form opcode)*/
3796 mb := uint32(c.regoff(&p.RestArgs[0].Addr))
3797 me := uint32(c.regoff(&p.RestArgs[1].Addr))
3798 sh := uint32(c.regoff(&p.From))
3799 o1 = OP_RLW(c.opirr(p.As), uint32(p.To.Reg), uint32(p.Reg), sh, mb, me)
3801 case 103: /* RLWMI rb,rs,$mb,$me,rt (M-form opcode)*/
3802 mb := uint32(c.regoff(&p.RestArgs[0].Addr))
3803 me := uint32(c.regoff(&p.RestArgs[1].Addr))
3804 o1 = OP_RLW(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), mb, me)
3814 func (c *ctxt9) vregoff(a *obj.Addr) int64 {
3822 func (c *ctxt9) regoff(a *obj.Addr) int32 {
3823 return int32(c.vregoff(a))
3826 func (c *ctxt9) oprrr(a obj.As) uint32 {
3829 return OPVCC(31, 266, 0, 0)
3831 return OPVCC(31, 266, 0, 1)
3833 return OPVCC(31, 266, 1, 0)
3835 return OPVCC(31, 266, 1, 1)
3837 return OPVCC(31, 10, 0, 0)
3839 return OPVCC(31, 10, 0, 1)
3841 return OPVCC(31, 10, 1, 0)
3843 return OPVCC(31, 10, 1, 1)
3845 return OPVCC(31, 138, 0, 0)
3847 return OPVCC(31, 138, 0, 1)
3849 return OPVCC(31, 138, 1, 0)
3851 return OPVCC(31, 138, 1, 1)
3853 return OPVCC(31, 234, 0, 0)
3855 return OPVCC(31, 234, 0, 1)
3857 return OPVCC(31, 234, 1, 0)
3859 return OPVCC(31, 234, 1, 1)
3861 return OPVCC(31, 202, 0, 0)
3863 return OPVCC(31, 202, 0, 1)
3865 return OPVCC(31, 202, 1, 0)
3867 return OPVCC(31, 202, 1, 1)
3869 return OPVCC(31, 170, 0, 0) /* addex - v3.0b */
3872 return OPVCC(31, 28, 0, 0)
3874 return OPVCC(31, 28, 0, 1)
3876 return OPVCC(31, 60, 0, 0)
3878 return OPVCC(31, 60, 0, 1)
3881 return OPVCC(31, 0, 0, 0) | 1<<21 /* L=1 */
3883 return OPVCC(31, 32, 0, 0) | 1<<21
3885 return OPVCC(31, 0, 0, 0) /* L=0 */
3887 return OPVCC(31, 32, 0, 0)
3889 return OPVCC(31, 508, 0, 0) /* cmpb - v2.05 */
3891 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
3894 return OPVCC(31, 26, 0, 0)
3896 return OPVCC(31, 26, 0, 1)
3898 return OPVCC(31, 58, 0, 0)
3900 return OPVCC(31, 58, 0, 1)
3903 return OPVCC(19, 257, 0, 0)
3905 return OPVCC(19, 129, 0, 0)
3907 return OPVCC(19, 289, 0, 0)
3909 return OPVCC(19, 225, 0, 0)
3911 return OPVCC(19, 33, 0, 0)
3913 return OPVCC(19, 449, 0, 0)
3915 return OPVCC(19, 417, 0, 0)
3917 return OPVCC(19, 193, 0, 0)
3920 return OPVCC(31, 86, 0, 0)
3922 return OPVCC(31, 470, 0, 0)
3924 return OPVCC(31, 54, 0, 0)
3926 return OPVCC(31, 278, 0, 0)
3928 return OPVCC(31, 246, 0, 0)
3930 return OPVCC(31, 1014, 0, 0)
3933 return OPVCC(31, 265, 0, 0) /* modud - v3.0 */
3935 return OPVCC(31, 267, 0, 0) /* moduw - v3.0 */
3937 return OPVCC(31, 777, 0, 0) /* modsd - v3.0 */
3939 return OPVCC(31, 779, 0, 0) /* modsw - v3.0 */
3942 return OPVCC(31, 491, 0, 0)
3945 return OPVCC(31, 491, 0, 1)
3948 return OPVCC(31, 491, 1, 0)
3951 return OPVCC(31, 491, 1, 1)
3954 return OPVCC(31, 459, 0, 0)
3957 return OPVCC(31, 459, 0, 1)
3960 return OPVCC(31, 459, 1, 0)
3963 return OPVCC(31, 459, 1, 1)
3966 return OPVCC(31, 489, 0, 0)
3969 return OPVCC(31, 489, 0, 1)
3972 return OPVCC(31, 425, 0, 0)
3975 return OPVCC(31, 425, 0, 1)
3978 return OPVCC(31, 393, 0, 0)
3981 return OPVCC(31, 393, 0, 1)
3984 return OPVCC(31, 489, 1, 0)
3987 return OPVCC(31, 489, 1, 1)
3989 case ADIVDU, AREMDU:
3990 return OPVCC(31, 457, 0, 0)
3993 return OPVCC(31, 457, 0, 1)
3996 return OPVCC(31, 457, 1, 0)
3999 return OPVCC(31, 457, 1, 1)
4002 return OPVCC(31, 854, 0, 0)
4005 return OPVCC(31, 284, 0, 0)
4007 return OPVCC(31, 284, 0, 1)
4010 return OPVCC(31, 954, 0, 0)
4012 return OPVCC(31, 954, 0, 1)
4014 return OPVCC(31, 922, 0, 0)
4016 return OPVCC(31, 922, 0, 1)
4018 return OPVCC(31, 986, 0, 0)
4020 return OPVCC(31, 986, 0, 1)
4023 return OPVCC(63, 264, 0, 0)
4025 return OPVCC(63, 264, 0, 1)
4027 return OPVCC(63, 21, 0, 0)
4029 return OPVCC(63, 21, 0, 1)
4031 return OPVCC(59, 21, 0, 0)
4033 return OPVCC(59, 21, 0, 1)
4035 return OPVCC(63, 32, 0, 0)
4037 return OPVCC(63, 0, 0, 0)
4039 return OPVCC(63, 846, 0, 0)
4041 return OPVCC(63, 846, 0, 1)
4043 return OPVCC(63, 974, 0, 0)
4045 return OPVCC(63, 974, 0, 1)
4047 return OPVCC(59, 846, 0, 0)
4049 return OPVCC(59, 846, 0, 1)
4051 return OPVCC(63, 14, 0, 0)
4053 return OPVCC(63, 14, 0, 1)
4055 return OPVCC(63, 15, 0, 0)
4057 return OPVCC(63, 15, 0, 1)
4059 return OPVCC(63, 814, 0, 0)
4061 return OPVCC(63, 814, 0, 1)
4063 return OPVCC(63, 815, 0, 0)
4065 return OPVCC(63, 815, 0, 1)
4067 return OPVCC(63, 18, 0, 0)
4069 return OPVCC(63, 18, 0, 1)
4071 return OPVCC(59, 18, 0, 0)
4073 return OPVCC(59, 18, 0, 1)
4075 return OPVCC(63, 29, 0, 0)
4077 return OPVCC(63, 29, 0, 1)
4079 return OPVCC(59, 29, 0, 0)
4081 return OPVCC(59, 29, 0, 1)
4083 case AFMOVS, AFMOVD:
4084 return OPVCC(63, 72, 0, 0) /* load */
4086 return OPVCC(63, 72, 0, 1)
4088 return OPVCC(63, 28, 0, 0)
4090 return OPVCC(63, 28, 0, 1)
4092 return OPVCC(59, 28, 0, 0)
4094 return OPVCC(59, 28, 0, 1)
4096 return OPVCC(63, 25, 0, 0)
4098 return OPVCC(63, 25, 0, 1)
4100 return OPVCC(59, 25, 0, 0)
4102 return OPVCC(59, 25, 0, 1)
4104 return OPVCC(63, 136, 0, 0)
4106 return OPVCC(63, 136, 0, 1)
4108 return OPVCC(63, 40, 0, 0)
4110 return OPVCC(63, 40, 0, 1)
4112 return OPVCC(63, 31, 0, 0)
4114 return OPVCC(63, 31, 0, 1)
4116 return OPVCC(59, 31, 0, 0)
4118 return OPVCC(59, 31, 0, 1)
4120 return OPVCC(63, 30, 0, 0)
4122 return OPVCC(63, 30, 0, 1)
4124 return OPVCC(59, 30, 0, 0)
4126 return OPVCC(59, 30, 0, 1)
4128 return OPVCC(63, 8, 0, 0)
4130 return OPVCC(63, 8, 0, 1)
4132 return OPVCC(59, 24, 0, 0)
4134 return OPVCC(59, 24, 0, 1)
4136 return OPVCC(63, 488, 0, 0)
4138 return OPVCC(63, 488, 0, 1)
4140 return OPVCC(63, 456, 0, 0)
4142 return OPVCC(63, 456, 0, 1)
4144 return OPVCC(63, 424, 0, 0)
4146 return OPVCC(63, 424, 0, 1)
4148 return OPVCC(63, 392, 0, 0)
4150 return OPVCC(63, 392, 0, 1)
4152 return OPVCC(63, 12, 0, 0)
4154 return OPVCC(63, 12, 0, 1)
4156 return OPVCC(63, 26, 0, 0)
4158 return OPVCC(63, 26, 0, 1)
4160 return OPVCC(63, 23, 0, 0)
4162 return OPVCC(63, 23, 0, 1)
4164 return OPVCC(63, 22, 0, 0)
4166 return OPVCC(63, 22, 0, 1)
4168 return OPVCC(59, 22, 0, 0)
4170 return OPVCC(59, 22, 0, 1)
4172 return OPVCC(63, 20, 0, 0)
4174 return OPVCC(63, 20, 0, 1)
4176 return OPVCC(59, 20, 0, 0)
4178 return OPVCC(59, 20, 0, 1)
4181 return OPVCC(31, 982, 0, 0)
4183 return OPVCC(19, 150, 0, 0)
4186 return OPVCC(63, 70, 0, 0)
4188 return OPVCC(63, 70, 0, 1)
4190 return OPVCC(63, 38, 0, 0)
4192 return OPVCC(63, 38, 0, 1)
4195 return OPVCC(31, 75, 0, 0)
4197 return OPVCC(31, 75, 0, 1)
4199 return OPVCC(31, 11, 0, 0)
4201 return OPVCC(31, 11, 0, 1)
4203 return OPVCC(31, 235, 0, 0)
4205 return OPVCC(31, 235, 0, 1)
4207 return OPVCC(31, 235, 1, 0)
4209 return OPVCC(31, 235, 1, 1)
4212 return OPVCC(31, 73, 0, 0)
4214 return OPVCC(31, 73, 0, 1)
4216 return OPVCC(31, 9, 0, 0)
4218 return OPVCC(31, 9, 0, 1)
4220 return OPVCC(31, 233, 0, 0)
4222 return OPVCC(31, 233, 0, 1)
4224 return OPVCC(31, 233, 1, 0)
4226 return OPVCC(31, 233, 1, 1)
4229 return OPVCC(31, 476, 0, 0)
4231 return OPVCC(31, 476, 0, 1)
4233 return OPVCC(31, 104, 0, 0)
4235 return OPVCC(31, 104, 0, 1)
4237 return OPVCC(31, 104, 1, 0)
4239 return OPVCC(31, 104, 1, 1)
4241 return OPVCC(31, 124, 0, 0)
4243 return OPVCC(31, 124, 0, 1)
4245 return OPVCC(31, 444, 0, 0)
4247 return OPVCC(31, 444, 0, 1)
4249 return OPVCC(31, 412, 0, 0)
4251 return OPVCC(31, 412, 0, 1)
4254 return OPVCC(31, 506, 0, 0) /* popcntd - v2.06 */
4256 return OPVCC(31, 378, 0, 0) /* popcntw - v2.06 */
4258 return OPVCC(31, 122, 0, 0) /* popcntb - v2.02 */
4260 return OPVCC(31, 538, 0, 0) /* cnttzw - v3.00 */
4262 return OPVCC(31, 538, 0, 1) /* cnttzw. - v3.00 */
4264 return OPVCC(31, 570, 0, 0) /* cnttzd - v3.00 */
4266 return OPVCC(31, 570, 0, 1) /* cnttzd. - v3.00 */
4269 return OPVCC(19, 50, 0, 0)
4271 return OPVCC(19, 51, 0, 0)
4273 return OPVCC(19, 18, 0, 0)
4275 return OPVCC(19, 274, 0, 0)
4278 return OPVCC(20, 0, 0, 0)
4280 return OPVCC(20, 0, 0, 1)
4282 return OPVCC(23, 0, 0, 0)
4284 return OPVCC(23, 0, 0, 1)
4287 return OPVCC(30, 8, 0, 0)
4289 return OPVCC(30, 0, 0, 1)
4292 return OPVCC(30, 9, 0, 0)
4294 return OPVCC(30, 9, 0, 1)
4297 return OPVCC(30, 0, 0, 0)
4299 return OPVCC(30, 0, 0, 1)
4301 return OPVCC(30, 0, 0, 0) | 2<<1 // rldicr
4303 return OPVCC(30, 0, 0, 1) | 2<<1 // rldicr.
4306 return OPVCC(30, 0, 0, 0) | 4<<1 // rldic
4308 return OPVCC(30, 0, 0, 1) | 4<<1 // rldic.
4311 return OPVCC(17, 1, 0, 0)
4314 return OPVCC(31, 24, 0, 0)
4316 return OPVCC(31, 24, 0, 1)
4318 return OPVCC(31, 27, 0, 0)
4320 return OPVCC(31, 27, 0, 1)
4323 return OPVCC(31, 792, 0, 0)
4325 return OPVCC(31, 792, 0, 1)
4327 return OPVCC(31, 794, 0, 0)
4329 return OPVCC(31, 794, 0, 1)
4332 return OPVCC(31, 445, 0, 0)
4334 return OPVCC(31, 445, 0, 1)
4337 return OPVCC(31, 536, 0, 0)
4339 return OPVCC(31, 536, 0, 1)
4341 return OPVCC(31, 539, 0, 0)
4343 return OPVCC(31, 539, 0, 1)
4346 return OPVCC(31, 40, 0, 0)
4348 return OPVCC(31, 40, 0, 1)
4350 return OPVCC(31, 40, 1, 0)
4352 return OPVCC(31, 40, 1, 1)
4354 return OPVCC(31, 8, 0, 0)
4356 return OPVCC(31, 8, 0, 1)
4358 return OPVCC(31, 8, 1, 0)
4360 return OPVCC(31, 8, 1, 1)
4362 return OPVCC(31, 136, 0, 0)
4364 return OPVCC(31, 136, 0, 1)
4366 return OPVCC(31, 136, 1, 0)
4368 return OPVCC(31, 136, 1, 1)
4370 return OPVCC(31, 232, 0, 0)
4372 return OPVCC(31, 232, 0, 1)
4374 return OPVCC(31, 232, 1, 0)
4376 return OPVCC(31, 232, 1, 1)
4378 return OPVCC(31, 200, 0, 0)
4380 return OPVCC(31, 200, 0, 1)
4382 return OPVCC(31, 200, 1, 0)
4384 return OPVCC(31, 200, 1, 1)
4387 return OPVCC(31, 598, 0, 0)
4389 return OPVCC(31, 598, 0, 0) | 1<<21
4392 return OPVCC(31, 598, 0, 0) | 2<<21
4395 return OPVCC(31, 306, 0, 0)
4397 return OPVCC(31, 274, 0, 0)
4399 return OPVCC(31, 566, 0, 0)
4401 return OPVCC(31, 498, 0, 0)
4403 return OPVCC(31, 434, 0, 0)
4405 return OPVCC(31, 915, 0, 0)
4407 return OPVCC(31, 851, 0, 0)
4409 return OPVCC(31, 402, 0, 0)
4412 return OPVCC(31, 4, 0, 0)
4414 return OPVCC(31, 68, 0, 0)
4416 /* Vector (VMX/Altivec) instructions */
4417 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4418 /* are enabled starting at POWER6 (ISA 2.05). */
4420 return OPVX(4, 1028, 0, 0) /* vand - v2.03 */
4422 return OPVX(4, 1092, 0, 0) /* vandc - v2.03 */
4424 return OPVX(4, 1412, 0, 0) /* vnand - v2.07 */
4427 return OPVX(4, 1156, 0, 0) /* vor - v2.03 */
4429 return OPVX(4, 1348, 0, 0) /* vorc - v2.07 */
4431 return OPVX(4, 1284, 0, 0) /* vnor - v2.03 */
4433 return OPVX(4, 1220, 0, 0) /* vxor - v2.03 */
4435 return OPVX(4, 1668, 0, 0) /* veqv - v2.07 */
4438 return OPVX(4, 0, 0, 0) /* vaddubm - v2.03 */
4440 return OPVX(4, 64, 0, 0) /* vadduhm - v2.03 */
4442 return OPVX(4, 128, 0, 0) /* vadduwm - v2.03 */
4444 return OPVX(4, 192, 0, 0) /* vaddudm - v2.07 */
4446 return OPVX(4, 256, 0, 0) /* vadduqm - v2.07 */
4449 return OPVX(4, 320, 0, 0) /* vaddcuq - v2.07 */
4451 return OPVX(4, 384, 0, 0) /* vaddcuw - v2.03 */
4454 return OPVX(4, 512, 0, 0) /* vaddubs - v2.03 */
4456 return OPVX(4, 576, 0, 0) /* vadduhs - v2.03 */
4458 return OPVX(4, 640, 0, 0) /* vadduws - v2.03 */
4461 return OPVX(4, 768, 0, 0) /* vaddsbs - v2.03 */
4463 return OPVX(4, 832, 0, 0) /* vaddshs - v2.03 */
4465 return OPVX(4, 896, 0, 0) /* vaddsws - v2.03 */
4468 return OPVX(4, 60, 0, 0) /* vaddeuqm - v2.07 */
4470 return OPVX(4, 61, 0, 0) /* vaddecuq - v2.07 */
4473 return OPVX(4, 776, 0, 0) /* vmulesb - v2.03 */
4475 return OPVX(4, 264, 0, 0) /* vmulosb - v2.03 */
4477 return OPVX(4, 520, 0, 0) /* vmuleub - v2.03 */
4479 return OPVX(4, 8, 0, 0) /* vmuloub - v2.03 */
4481 return OPVX(4, 840, 0, 0) /* vmulesh - v2.03 */
4483 return OPVX(4, 328, 0, 0) /* vmulosh - v2.03 */
4485 return OPVX(4, 584, 0, 0) /* vmuleuh - v2.03 */
4487 return OPVX(4, 72, 0, 0) /* vmulouh - v2.03 */
4489 return OPVX(4, 904, 0, 0) /* vmulesw - v2.07 */
4491 return OPVX(4, 392, 0, 0) /* vmulosw - v2.07 */
4493 return OPVX(4, 648, 0, 0) /* vmuleuw - v2.07 */
4495 return OPVX(4, 136, 0, 0) /* vmulouw - v2.07 */
4497 return OPVX(4, 137, 0, 0) /* vmuluwm - v2.07 */
4500 return OPVX(4, 1032, 0, 0) /* vpmsumb - v2.07 */
4502 return OPVX(4, 1096, 0, 0) /* vpmsumh - v2.07 */
4504 return OPVX(4, 1160, 0, 0) /* vpmsumw - v2.07 */
4506 return OPVX(4, 1224, 0, 0) /* vpmsumd - v2.07 */
4509 return OPVX(4, 35, 0, 0) /* vmsumudm - v3.00b */
4512 return OPVX(4, 1024, 0, 0) /* vsububm - v2.03 */
4514 return OPVX(4, 1088, 0, 0) /* vsubuhm - v2.03 */
4516 return OPVX(4, 1152, 0, 0) /* vsubuwm - v2.03 */
4518 return OPVX(4, 1216, 0, 0) /* vsubudm - v2.07 */
4520 return OPVX(4, 1280, 0, 0) /* vsubuqm - v2.07 */
4523 return OPVX(4, 1344, 0, 0) /* vsubcuq - v2.07 */
4525 return OPVX(4, 1408, 0, 0) /* vsubcuw - v2.03 */
4528 return OPVX(4, 1536, 0, 0) /* vsububs - v2.03 */
4530 return OPVX(4, 1600, 0, 0) /* vsubuhs - v2.03 */
4532 return OPVX(4, 1664, 0, 0) /* vsubuws - v2.03 */
4535 return OPVX(4, 1792, 0, 0) /* vsubsbs - v2.03 */
4537 return OPVX(4, 1856, 0, 0) /* vsubshs - v2.03 */
4539 return OPVX(4, 1920, 0, 0) /* vsubsws - v2.03 */
4542 return OPVX(4, 62, 0, 0) /* vsubeuqm - v2.07 */
4544 return OPVX(4, 63, 0, 0) /* vsubecuq - v2.07 */
4547 return OPVX(4, 4, 0, 0) /* vrlb - v2.03 */
4549 return OPVX(4, 68, 0, 0) /* vrlh - v2.03 */
4551 return OPVX(4, 132, 0, 0) /* vrlw - v2.03 */
4553 return OPVX(4, 196, 0, 0) /* vrld - v2.07 */
4556 return OPVX(4, 1676, 0, 0) /* vmrgow - v2.07 */
4558 return OPVX(4, 1932, 0, 0) /* vmrgew - v2.07 */
4561 return OPVX(4, 260, 0, 0) /* vslh - v2.03 */
4563 return OPVX(4, 324, 0, 0) /* vslh - v2.03 */
4565 return OPVX(4, 388, 0, 0) /* vslw - v2.03 */
4567 return OPVX(4, 452, 0, 0) /* vsl - v2.03 */
4569 return OPVX(4, 1036, 0, 0) /* vsl - v2.03 */
4571 return OPVX(4, 516, 0, 0) /* vsrb - v2.03 */
4573 return OPVX(4, 580, 0, 0) /* vsrh - v2.03 */
4575 return OPVX(4, 644, 0, 0) /* vsrw - v2.03 */
4577 return OPVX(4, 708, 0, 0) /* vsr - v2.03 */
4579 return OPVX(4, 1100, 0, 0) /* vsro - v2.03 */
4581 return OPVX(4, 1476, 0, 0) /* vsld - v2.07 */
4583 return OPVX(4, 1732, 0, 0) /* vsrd - v2.07 */
4586 return OPVX(4, 772, 0, 0) /* vsrab - v2.03 */
4588 return OPVX(4, 836, 0, 0) /* vsrah - v2.03 */
4590 return OPVX(4, 900, 0, 0) /* vsraw - v2.03 */
4592 return OPVX(4, 964, 0, 0) /* vsrad - v2.07 */
4595 return OPVC(4, 1356, 0, 0) /* vbpermq - v2.07 */
4597 return OPVC(4, 1484, 0, 0) /* vbpermd - v3.00 */
4600 return OPVX(4, 1794, 0, 0) /* vclzb - v2.07 */
4602 return OPVX(4, 1858, 0, 0) /* vclzh - v2.07 */
4604 return OPVX(4, 1922, 0, 0) /* vclzw - v2.07 */
4606 return OPVX(4, 1986, 0, 0) /* vclzd - v2.07 */
4609 return OPVX(4, 1795, 0, 0) /* vpopcntb - v2.07 */
4611 return OPVX(4, 1859, 0, 0) /* vpopcnth - v2.07 */
4613 return OPVX(4, 1923, 0, 0) /* vpopcntw - v2.07 */
4615 return OPVX(4, 1987, 0, 0) /* vpopcntd - v2.07 */
4618 return OPVC(4, 6, 0, 0) /* vcmpequb - v2.03 */
4620 return OPVC(4, 6, 0, 1) /* vcmpequb. - v2.03 */
4622 return OPVC(4, 70, 0, 0) /* vcmpequh - v2.03 */
4624 return OPVC(4, 70, 0, 1) /* vcmpequh. - v2.03 */
4626 return OPVC(4, 134, 0, 0) /* vcmpequw - v2.03 */
4628 return OPVC(4, 134, 0, 1) /* vcmpequw. - v2.03 */
4630 return OPVC(4, 199, 0, 0) /* vcmpequd - v2.07 */
4632 return OPVC(4, 199, 0, 1) /* vcmpequd. - v2.07 */
4635 return OPVC(4, 518, 0, 0) /* vcmpgtub - v2.03 */
4637 return OPVC(4, 518, 0, 1) /* vcmpgtub. - v2.03 */
4639 return OPVC(4, 582, 0, 0) /* vcmpgtuh - v2.03 */
4641 return OPVC(4, 582, 0, 1) /* vcmpgtuh. - v2.03 */
4643 return OPVC(4, 646, 0, 0) /* vcmpgtuw - v2.03 */
4645 return OPVC(4, 646, 0, 1) /* vcmpgtuw. - v2.03 */
4647 return OPVC(4, 711, 0, 0) /* vcmpgtud - v2.07 */
4649 return OPVC(4, 711, 0, 1) /* vcmpgtud. v2.07 */
4651 return OPVC(4, 774, 0, 0) /* vcmpgtsb - v2.03 */
4653 return OPVC(4, 774, 0, 1) /* vcmpgtsb. - v2.03 */
4655 return OPVC(4, 838, 0, 0) /* vcmpgtsh - v2.03 */
4657 return OPVC(4, 838, 0, 1) /* vcmpgtsh. - v2.03 */
4659 return OPVC(4, 902, 0, 0) /* vcmpgtsw - v2.03 */
4661 return OPVC(4, 902, 0, 1) /* vcmpgtsw. - v2.03 */
4663 return OPVC(4, 967, 0, 0) /* vcmpgtsd - v2.07 */
4665 return OPVC(4, 967, 0, 1) /* vcmpgtsd. - v2.07 */
4668 return OPVC(4, 263, 0, 0) /* vcmpnezb - v3.00 */
4670 return OPVC(4, 263, 0, 1) /* vcmpnezb. - v3.00 */
4672 return OPVC(4, 7, 0, 0) /* vcmpneb - v3.00 */
4674 return OPVC(4, 7, 0, 1) /* vcmpneb. - v3.00 */
4676 return OPVC(4, 71, 0, 0) /* vcmpneh - v3.00 */
4678 return OPVC(4, 71, 0, 1) /* vcmpneh. - v3.00 */
4680 return OPVC(4, 135, 0, 0) /* vcmpnew - v3.00 */
4682 return OPVC(4, 135, 0, 1) /* vcmpnew. - v3.00 */
4685 return OPVX(4, 43, 0, 0) /* vperm - v2.03 */
4687 return OPVX(4, 45, 0, 0) /* vpermxor - v2.03 */
4689 return OPVX(4, 59, 0, 0) /* vpermr - v3.0 */
4692 return OPVX(4, 42, 0, 0) /* vsel - v2.03 */
4695 return OPVX(4, 1288, 0, 0) /* vcipher - v2.07 */
4697 return OPVX(4, 1289, 0, 0) /* vcipherlast - v2.07 */
4699 return OPVX(4, 1352, 0, 0) /* vncipher - v2.07 */
4701 return OPVX(4, 1353, 0, 0) /* vncipherlast - v2.07 */
4703 return OPVX(4, 1480, 0, 0) /* vsbox - v2.07 */
4704 /* End of vector instructions */
4706 /* Vector scalar (VSX) instructions */
4707 /* ISA 2.06 enables these for POWER7. */
4708 case AMFVSRD, AMFVRD, AMFFPRD:
4709 return OPVXX1(31, 51, 0) /* mfvsrd - v2.07 */
4711 return OPVXX1(31, 115, 0) /* mfvsrwz - v2.07 */
4713 return OPVXX1(31, 307, 0) /* mfvsrld - v3.00 */
4715 case AMTVSRD, AMTFPRD, AMTVRD:
4716 return OPVXX1(31, 179, 0) /* mtvsrd - v2.07 */
4718 return OPVXX1(31, 211, 0) /* mtvsrwa - v2.07 */
4720 return OPVXX1(31, 243, 0) /* mtvsrwz - v2.07 */
4722 return OPVXX1(31, 435, 0) /* mtvsrdd - v3.00 */
4724 return OPVXX1(31, 403, 0) /* mtvsrws - v3.00 */
4727 return OPVXX3(60, 130, 0) /* xxland - v2.06 */
4729 return OPVXX3(60, 138, 0) /* xxlandc - v2.06 */
4731 return OPVXX3(60, 186, 0) /* xxleqv - v2.07 */
4733 return OPVXX3(60, 178, 0) /* xxlnand - v2.07 */
4736 return OPVXX3(60, 170, 0) /* xxlorc - v2.07 */
4738 return OPVXX3(60, 162, 0) /* xxlnor - v2.06 */
4739 case AXXLOR, AXXLORQ:
4740 return OPVXX3(60, 146, 0) /* xxlor - v2.06 */
4742 return OPVXX3(60, 154, 0) /* xxlxor - v2.06 */
4745 return OPVXX4(60, 3, 0) /* xxsel - v2.06 */
4748 return OPVXX3(60, 18, 0) /* xxmrghw - v2.06 */
4750 return OPVXX3(60, 50, 0) /* xxmrglw - v2.06 */
4753 return OPVXX2(60, 164, 0) /* xxspltw - v2.06 */
4756 return OPVCC(60, 360, 0, 0) /* xxspltib - v3.0 */
4759 return OPVXX3(60, 26, 0) /* xxperm - v2.06 */
4761 return OPVXX3(60, 10, 0) /* xxpermdi - v2.06 */
4764 return OPVXX3(60, 2, 0) /* xxsldwi - v2.06 */
4767 return OPVXX2VA(60, 475, 31) /* xxbrq - v3.0 */
4769 return OPVXX2VA(60, 475, 23) /* xxbrd - v3.0 */
4771 return OPVXX2VA(60, 475, 15) /* xxbrw - v3.0 */
4773 return OPVXX2VA(60, 475, 7) /* xxbrh - v3.0 */
4776 return OPVXX2(60, 265, 0) /* xscvdpsp - v2.06 */
4778 return OPVXX2(60, 329, 0) /* xscvspdp - v2.06 */
4780 return OPVXX2(60, 267, 0) /* xscvdpspn - v2.07 */
4782 return OPVXX2(60, 331, 0) /* xscvspdpn - v2.07 */
4785 return OPVXX2(60, 393, 0) /* xvcvdpsp - v2.06 */
4787 return OPVXX2(60, 457, 0) /* xvcvspdp - v2.06 */
4790 return OPVXX2(60, 344, 0) /* xscvdpsxds - v2.06 */
4792 return OPVXX2(60, 88, 0) /* xscvdpsxws - v2.06 */
4794 return OPVXX2(60, 328, 0) /* xscvdpuxds - v2.06 */
4796 return OPVXX2(60, 72, 0) /* xscvdpuxws - v2.06 */
4799 return OPVXX2(60, 376, 0) /* xscvsxddp - v2.06 */
4801 return OPVXX2(60, 360, 0) /* xscvuxddp - v2.06 */
4803 return OPVXX2(60, 312, 0) /* xscvsxdsp - v2.06 */
4805 return OPVXX2(60, 296, 0) /* xscvuxdsp - v2.06 */
4808 return OPVXX2(60, 472, 0) /* xvcvdpsxds - v2.06 */
4810 return OPVXX2(60, 216, 0) /* xvcvdpsxws - v2.06 */
4812 return OPVXX2(60, 456, 0) /* xvcvdpuxds - v2.06 */
4814 return OPVXX2(60, 200, 0) /* xvcvdpuxws - v2.06 */
4816 return OPVXX2(60, 408, 0) /* xvcvspsxds - v2.07 */
4818 return OPVXX2(60, 152, 0) /* xvcvspsxws - v2.07 */
4820 return OPVXX2(60, 392, 0) /* xvcvspuxds - v2.07 */
4822 return OPVXX2(60, 136, 0) /* xvcvspuxws - v2.07 */
4825 return OPVXX2(60, 504, 0) /* xvcvsxddp - v2.06 */
4827 return OPVXX2(60, 248, 0) /* xvcvsxwdp - v2.06 */
4829 return OPVXX2(60, 488, 0) /* xvcvuxddp - v2.06 */
4831 return OPVXX2(60, 232, 0) /* xvcvuxwdp - v2.06 */
4833 return OPVXX2(60, 440, 0) /* xvcvsxdsp - v2.06 */
4835 return OPVXX2(60, 184, 0) /* xvcvsxwsp - v2.06 */
4837 return OPVXX2(60, 424, 0) /* xvcvuxdsp - v2.06 */
4839 return OPVXX2(60, 168, 0) /* xvcvuxwsp - v2.06 */
4840 /* End of VSX instructions */
4843 return OPVX(4, 48, 0, 0) /* maddhd - v3.00 */
4845 return OPVX(4, 49, 0, 0) /* maddhdu - v3.00 */
4847 return OPVX(4, 51, 0, 0) /* maddld - v3.00 */
4850 return OPVCC(31, 316, 0, 0)
4852 return OPVCC(31, 316, 0, 1)
4855 c.ctxt.Diag("bad r/r, r/r/r or r/r/r/r opcode %v", a)
4859 func (c *ctxt9) opirrr(a obj.As) uint32 {
4861 /* Vector (VMX/Altivec) instructions */
4862 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
4863 /* are enabled starting at POWER6 (ISA 2.05). */
4865 return OPVX(4, 44, 0, 0) /* vsldoi - v2.03 */
4868 c.ctxt.Diag("bad i/r/r/r opcode %v", a)
4872 func (c *ctxt9) opiirr(a obj.As) uint32 {
4874 /* Vector (VMX/Altivec) instructions */
4875 /* ISA 2.07 enables these for POWER8 and beyond. */
4877 return OPVX(4, 1666, 0, 0) /* vshasigmaw - v2.07 */
4879 return OPVX(4, 1730, 0, 0) /* vshasigmad - v2.07 */
4882 c.ctxt.Diag("bad i/i/r/r opcode %v", a)
4886 func (c *ctxt9) opirr(a obj.As) uint32 {
4889 return OPVCC(14, 0, 0, 0)
4891 return OPVCC(12, 0, 0, 0)
4893 return OPVCC(13, 0, 0, 0)
4895 return OPVCC(15, 0, 0, 0) /* ADDIS */
4898 return OPVCC(28, 0, 0, 0)
4900 return OPVCC(29, 0, 0, 0) /* ANDIS. */
4903 return OPVCC(18, 0, 0, 0)
4905 return OPVCC(18, 0, 0, 0) | 1
4907 return OPVCC(18, 0, 0, 0) | 1
4909 return OPVCC(18, 0, 0, 0) | 1
4911 return OPVCC(16, 0, 0, 0)
4913 return OPVCC(16, 0, 0, 0) | 1
4916 return AOP_RRR(16<<26, 12, 2, 0)
4918 return AOP_RRR(16<<26, 4, 0, 0)
4920 return AOP_RRR(16<<26, 12, 1, 0)
4922 return AOP_RRR(16<<26, 4, 1, 0)
4924 return AOP_RRR(16<<26, 12, 0, 0)
4926 return AOP_RRR(16<<26, 4, 2, 0)
4928 return AOP_RRR(16<<26, 4, 3, 0) // apparently unordered-clear
4930 return AOP_RRR(16<<26, 12, 3, 0) // apparently unordered-set
4933 return OPVCC(11, 0, 0, 0) | 1<<21 /* L=1 */
4935 return OPVCC(10, 0, 0, 0) | 1<<21
4937 return OPVCC(11, 0, 0, 0) /* L=0 */
4939 return OPVCC(10, 0, 0, 0)
4941 return OPVCC(31, 224, 0, 0) /* cmpeqb - v3.00 */
4944 return OPVCC(31, 597, 0, 0)
4947 return OPVCC(31, 774, 0, 0) /* copy - v3.00 */
4949 return OPVCC(31, 902, 0, 1) /* paste. - v3.00 */
4951 return OPVCC(31, 755, 0, 0) /* darn - v3.00 */
4953 case AMULLW, AMULLD:
4954 return OPVCC(7, 0, 0, 0) /* mulli works with MULLW or MULLD */
4957 return OPVCC(24, 0, 0, 0)
4959 return OPVCC(25, 0, 0, 0) /* ORIS */
4962 return OPVCC(20, 0, 0, 0) /* rlwimi */
4964 return OPVCC(20, 0, 0, 1)
4966 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
4968 return OPVCC(30, 0, 0, 1) | 3<<2
4970 return OPVCC(30, 0, 0, 0) | 3<<2 /* rldimi */
4972 return OPVCC(30, 0, 0, 1) | 3<<2
4974 return OPVCC(21, 0, 0, 0) /* rlwinm */
4976 return OPVCC(21, 0, 0, 1)
4979 return OPVCC(30, 0, 0, 0) /* rldicl */
4981 return OPVCC(30, 0, 0, 1)
4983 return OPVCC(30, 1, 0, 0) /* rldicr */
4985 return OPVCC(30, 1, 0, 1)
4987 return OPVCC(30, 0, 0, 0) | 2<<2
4989 return OPVCC(30, 0, 0, 1) | 2<<2
4992 return OPVCC(31, 824, 0, 0)
4994 return OPVCC(31, 824, 0, 1)
4996 return OPVCC(31, (413 << 1), 0, 0)
4998 return OPVCC(31, (413 << 1), 0, 1)
5000 return OPVCC(31, 445, 0, 0)
5002 return OPVCC(31, 445, 0, 1)
5005 return OPVCC(31, 725, 0, 0)
5008 return OPVCC(8, 0, 0, 0)
5011 return OPVCC(3, 0, 0, 0)
5013 return OPVCC(2, 0, 0, 0)
5015 /* Vector (VMX/Altivec) instructions */
5016 /* ISA 2.03 enables these for PPC970. For POWERx processors, these */
5017 /* are enabled starting at POWER6 (ISA 2.05). */
5019 return OPVX(4, 524, 0, 0) /* vspltb - v2.03 */
5021 return OPVX(4, 588, 0, 0) /* vsplth - v2.03 */
5023 return OPVX(4, 652, 0, 0) /* vspltw - v2.03 */
5026 return OPVX(4, 780, 0, 0) /* vspltisb - v2.03 */
5028 return OPVX(4, 844, 0, 0) /* vspltish - v2.03 */
5030 return OPVX(4, 908, 0, 0) /* vspltisw - v2.03 */
5031 /* End of vector instructions */
5034 return OPVCC(63, 128, 0, 0) /* ftdiv - v2.06 */
5036 return OPVCC(63, 160, 0, 0) /* ftsqrt - v2.06 */
5039 return OPVCC(26, 0, 0, 0) /* XORIL */
5041 return OPVCC(27, 0, 0, 0) /* XORIS */
5044 c.ctxt.Diag("bad opcode i/r or i/r/r %v", a)
5051 func (c *ctxt9) opload(a obj.As) uint32 {
5054 return OPVCC(58, 0, 0, 0) /* ld */
5056 return OPVCC(58, 0, 0, 1) /* ldu */
5058 return OPVCC(32, 0, 0, 0) /* lwz */
5060 return OPVCC(33, 0, 0, 0) /* lwzu */
5062 return OPVCC(58, 0, 0, 0) | 1<<1 /* lwa */
5064 return OPDQ(61, 1, 0) /* lxv - ISA v3.0 */
5066 return OPVXX1(31, 269, 0) /* lxvl - ISA v3.0 */
5068 return OPVXX1(31, 301, 0) /* lxvll - ISA v3.0 */
5070 return OPVXX1(31, 268, 0) /* lxvx - ISA v3.0 */
5074 return OPVCC(34, 0, 0, 0)
5077 case AMOVBU, AMOVBZU:
5078 return OPVCC(35, 0, 0, 0)
5080 return OPVCC(50, 0, 0, 0)
5082 return OPVCC(51, 0, 0, 0)
5084 return OPVCC(48, 0, 0, 0)
5086 return OPVCC(49, 0, 0, 0)
5088 return OPVCC(42, 0, 0, 0)
5090 return OPVCC(43, 0, 0, 0)
5092 return OPVCC(40, 0, 0, 0)
5094 return OPVCC(41, 0, 0, 0)
5096 return OPVCC(46, 0, 0, 0) /* lmw */
5099 c.ctxt.Diag("bad load opcode %v", a)
5104 * indexed load a(b),d
5106 func (c *ctxt9) oploadx(a obj.As) uint32 {
5109 return OPVCC(31, 23, 0, 0) /* lwzx */
5111 return OPVCC(31, 55, 0, 0) /* lwzux */
5113 return OPVCC(31, 341, 0, 0) /* lwax */
5115 return OPVCC(31, 373, 0, 0) /* lwaux */
5118 return OPVCC(31, 87, 0, 0) /* lbzx */
5120 case AMOVBU, AMOVBZU:
5121 return OPVCC(31, 119, 0, 0) /* lbzux */
5123 return OPVCC(31, 599, 0, 0) /* lfdx */
5125 return OPVCC(31, 631, 0, 0) /* lfdux */
5127 return OPVCC(31, 535, 0, 0) /* lfsx */
5129 return OPVCC(31, 567, 0, 0) /* lfsux */
5131 return OPVCC(31, 855, 0, 0) /* lfiwax - power6, isa 2.05 */
5133 return OPVCC(31, 887, 0, 0) /* lfiwzx - power7, isa 2.06 */
5135 return OPVCC(31, 343, 0, 0) /* lhax */
5137 return OPVCC(31, 375, 0, 0) /* lhaux */
5139 return OPVCC(31, 790, 0, 0) /* lhbrx */
5141 return OPVCC(31, 534, 0, 0) /* lwbrx */
5143 return OPVCC(31, 532, 0, 0) /* ldbrx */
5145 return OPVCC(31, 279, 0, 0) /* lhzx */
5147 return OPVCC(31, 311, 0, 0) /* lhzux */
5149 return OPVCC(31, 310, 0, 0) /* eciwx */
5151 return OPVCC(31, 52, 0, 0) /* lbarx */
5153 return OPVCC(31, 116, 0, 0) /* lharx */
5155 return OPVCC(31, 20, 0, 0) /* lwarx */
5157 return OPVCC(31, 84, 0, 0) /* ldarx */
5159 return OPVCC(31, 533, 0, 0) /* lswx */
5161 return OPVCC(31, 21, 0, 0) /* ldx */
5163 return OPVCC(31, 53, 0, 0) /* ldux */
5165 return OPVCC(31, 309, 0, 0) /* ldmx */
5167 /* Vector (VMX/Altivec) instructions */
5169 return OPVCC(31, 7, 0, 0) /* lvebx - v2.03 */
5171 return OPVCC(31, 39, 0, 0) /* lvehx - v2.03 */
5173 return OPVCC(31, 71, 0, 0) /* lvewx - v2.03 */
5175 return OPVCC(31, 103, 0, 0) /* lvx - v2.03 */
5177 return OPVCC(31, 359, 0, 0) /* lvxl - v2.03 */
5179 return OPVCC(31, 6, 0, 0) /* lvsl - v2.03 */
5181 return OPVCC(31, 38, 0, 0) /* lvsr - v2.03 */
5182 /* End of vector instructions */
5184 /* Vector scalar (VSX) instructions */
5186 return OPVXX1(31, 268, 0) /* lxvx - ISA v3.0 */
5188 return OPVXX1(31, 844, 0) /* lxvd2x - v2.06 */
5190 return OPVXX1(31, 780, 0) /* lxvw4x - v2.06 */
5192 return OPVXX1(31, 812, 0) /* lxvh8x - v3.00 */
5194 return OPVXX1(31, 876, 0) /* lxvb16x - v3.00 */
5196 return OPVXX1(31, 332, 0) /* lxvdsx - v2.06 */
5198 return OPVXX1(31, 588, 0) /* lxsdx - v2.06 */
5200 return OPVXX1(31, 76, 0) /* lxsiwax - v2.07 */
5202 return OPVXX1(31, 12, 0) /* lxsiwzx - v2.07 */
5205 c.ctxt.Diag("bad loadx opcode %v", a)
5212 func (c *ctxt9) opstore(a obj.As) uint32 {
5215 return OPVCC(38, 0, 0, 0) /* stb */
5217 case AMOVBU, AMOVBZU:
5218 return OPVCC(39, 0, 0, 0) /* stbu */
5220 return OPVCC(54, 0, 0, 0) /* stfd */
5222 return OPVCC(55, 0, 0, 0) /* stfdu */
5224 return OPVCC(52, 0, 0, 0) /* stfs */
5226 return OPVCC(53, 0, 0, 0) /* stfsu */
5229 return OPVCC(44, 0, 0, 0) /* sth */
5231 case AMOVHZU, AMOVHU:
5232 return OPVCC(45, 0, 0, 0) /* sthu */
5234 return OPVCC(47, 0, 0, 0) /* stmw */
5236 return OPVCC(31, 725, 0, 0) /* stswi */
5239 return OPVCC(36, 0, 0, 0) /* stw */
5241 case AMOVWZU, AMOVWU:
5242 return OPVCC(37, 0, 0, 0) /* stwu */
5244 return OPVCC(62, 0, 0, 0) /* std */
5246 return OPVCC(62, 0, 0, 1) /* stdu */
5248 return OPDQ(61, 5, 0) /* stxv ISA 3.0 */
5250 return OPVXX1(31, 397, 0) /* stxvl ISA 3.0 */
5252 return OPVXX1(31, 429, 0) /* stxvll ISA 3.0 */
5254 return OPVXX1(31, 396, 0) /* stxvx - ISA v3.0 */
5258 c.ctxt.Diag("unknown store opcode %v", a)
5263 * indexed store s,a(b)
5265 func (c *ctxt9) opstorex(a obj.As) uint32 {
5268 return OPVCC(31, 215, 0, 0) /* stbx */
5270 case AMOVBU, AMOVBZU:
5271 return OPVCC(31, 247, 0, 0) /* stbux */
5273 return OPVCC(31, 727, 0, 0) /* stfdx */
5275 return OPVCC(31, 759, 0, 0) /* stfdux */
5277 return OPVCC(31, 663, 0, 0) /* stfsx */
5279 return OPVCC(31, 695, 0, 0) /* stfsux */
5281 return OPVCC(31, 983, 0, 0) /* stfiwx */
5284 return OPVCC(31, 407, 0, 0) /* sthx */
5286 return OPVCC(31, 918, 0, 0) /* sthbrx */
5288 case AMOVHZU, AMOVHU:
5289 return OPVCC(31, 439, 0, 0) /* sthux */
5292 return OPVCC(31, 151, 0, 0) /* stwx */
5294 case AMOVWZU, AMOVWU:
5295 return OPVCC(31, 183, 0, 0) /* stwux */
5297 return OPVCC(31, 661, 0, 0) /* stswx */
5299 return OPVCC(31, 662, 0, 0) /* stwbrx */
5301 return OPVCC(31, 660, 0, 0) /* stdbrx */
5303 return OPVCC(31, 694, 0, 1) /* stbcx. */
5305 return OPVCC(31, 726, 0, 1) /* sthcx. */
5307 return OPVCC(31, 150, 0, 1) /* stwcx. */
5309 return OPVCC(31, 214, 0, 1) /* stwdx. */
5311 return OPVCC(31, 438, 0, 0) /* ecowx */
5313 return OPVCC(31, 149, 0, 0) /* stdx */
5315 return OPVCC(31, 181, 0, 0) /* stdux */
5317 /* Vector (VMX/Altivec) instructions */
5319 return OPVCC(31, 135, 0, 0) /* stvebx - v2.03 */
5321 return OPVCC(31, 167, 0, 0) /* stvehx - v2.03 */
5323 return OPVCC(31, 199, 0, 0) /* stvewx - v2.03 */
5325 return OPVCC(31, 231, 0, 0) /* stvx - v2.03 */
5327 return OPVCC(31, 487, 0, 0) /* stvxl - v2.03 */
5328 /* End of vector instructions */
5330 /* Vector scalar (VSX) instructions */
5332 return OPVXX1(31, 396, 0) /* stxvx - v3.0 */
5334 return OPVXX1(31, 972, 0) /* stxvd2x - v2.06 */
5336 return OPVXX1(31, 908, 0) /* stxvw4x - v2.06 */
5338 return OPVXX1(31, 940, 0) /* stxvh8x - v3.0 */
5340 return OPVXX1(31, 1004, 0) /* stxvb16x - v3.0 */
5343 return OPVXX1(31, 716, 0) /* stxsdx - v2.06 */
5346 return OPVXX1(31, 140, 0) /* stxsiwx - v2.07 */
5348 /* End of vector scalar instructions */
5352 c.ctxt.Diag("unknown storex opcode %v", a)