1 /* Opcode table for the TXVU
2 Copyright 1998 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20 #include "opcode/txvu.h"
26 #if defined (__STDC__) || defined (ALMOST_STDC)
27 #define XCONCAT2(a,b) a##b
29 #define XCONCAT2(a,b) a/**/b
31 #define CONCAT2(a,b) XCONCAT2(a,b)
33 /* ??? One can argue it's preferable to have the PARSE_FN support in tc-vxvu.c
34 and the PRINT_FN support in txvu-dis.c. For this project I like having
35 them all in one place. */
37 #define PARSE_FN(fn) \
38 static long CONCAT2 (parse_,fn) \
39 PARAMS ((char **, const char **));
40 #define INSERT_FN(fn) \
41 static void CONCAT2 (insert_,fn) \
42 PARAMS ((TXVU_INSN *, const struct txvu_operand *, \
43 int, long, const char **))
44 #define EXTRACT_FN(fn) \
45 static long CONCAT2 (extract_,fn) \
46 PARAMS ((TXVU_INSN *, const struct txvu_operand *, \
48 #define PRINT_FN(fn) \
49 static void CONCAT2 (print_,fn) \
50 PARAMS ((disassemble_info *, TXVU_INSN *, long));
93 INSERT_FN (luimm12up6
);
98 /* Various types of TXVU operands, including insn suffixes.
102 BITS SHIFT FLAGS PARSE_FN INSERT_FN EXTRACT_FN PRINT_FN
104 Operand values are 128 + table index. This allows ASCII chars to be
105 included in the syntax spec. */
107 const struct txvu_operand txvu_operands
[] =
109 /* place holder (??? not sure if needed) */
113 /* Operands that exist in the same place for essentially the same purpose
114 in both upper and lower instructions. These don't have a U or L prefix.
115 Operands specific to the upper or lower instruction are so prefixed. */
117 /* Destination indicator attached to mnemonic, with leading '.' or '/'.
118 After parsing this, the value is stored in global `dest' so that the
119 register parser can verify the same choice of xyzw is used. */
120 #define DOTDEST (UNUSED + 1)
121 { 4, TXVU_SHIFT_DEST
, TXVU_OPERAND_SUFFIX
,
122 parse_dotdest
, insert_dotdest
, extract_dotdest
, print_dotdest
},
124 /* ft reg, with vector specification same as DOTDEST */
125 #define VFTREG (DOTDEST + 1)
126 { 5, TXVU_SHIFT_TREG
, 0, parse_vfreg
, 0, 0, print_vfreg
},
128 /* fs reg, with vector specification same as DOTDEST */
129 #define VFSREG (VFTREG + 1)
130 { 5, TXVU_SHIFT_SREG
, 0, parse_vfreg
, 0, 0, print_vfreg
},
132 /* fd reg, with vector specification same as DOTDEST */
133 #define VFDREG (VFSREG + 1)
134 { 5, TXVU_SHIFT_DREG
, 0, parse_vfreg
, 0, 0, print_vfreg
},
136 /* Upper word operands. */
139 #define UBC (VFDREG + 1)
140 { 2, 0, TXVU_OPERAND_SUFFIX
, parse_bc
, 0, extract_bc
, print_sdest
},
142 /* ftreg in broadcast case */
143 #define UBCFTREG (UBC + 1)
144 { 5, TXVU_SHIFT_TREG
, 0, parse_bcftreg
, 0, 0, print_bcftreg
},
146 /* accumulator dest */
147 #define UACCDEST (UBCFTREG + 1)
148 { 0, 0, 0, parse_accdest
, 0, 0, print_accdest
},
150 /* The XYZ operand is a fake one that is used to ensure only "xyz" is
151 specified. It simplifies the opmula and opmsub entries. */
152 #define UXYZ (UACCDEST + 1)
153 { 0, 0, TXVU_OPERAND_FAKE
, 0, insert_xyz
, 0, 0 },
155 /* Lower word operands. */
157 /* 5 bit signed immediate. */
158 #define LIMM5 (UXYZ + 1)
159 { 5, 6, TXVU_OPERAND_SIGNED
, 0, 0, 0, 0 },
161 /* 11 bit signed immediate. */
162 #define LIMM11 (LIMM5 + 1)
163 { 11, 0, TXVU_OPERAND_SIGNED
, 0, 0, 0, 0 },
165 /* 15 bit unsigned immediate. */
166 #define LUIMM15 (LIMM11 + 1)
167 { 15, 0, 0, 0, insert_luimm15
, extract_luimm15
, 0 },
170 #define LIDREG (LUIMM15 + 1)
171 { 5, 6, 0, parse_ireg
, 0, 0, print_ireg
},
174 #define LISREG (LIDREG + 1)
175 { 5, 11, 0, parse_ireg
, 0, 0, print_ireg
},
178 #define LITREG (LISREG + 1)
179 { 5, 16, 0, parse_ireg
, 0, 0, print_ireg
},
181 /* FS reg, with FSF field selector. */
182 #define LFSFFSREG (LITREG + 1)
183 { 5, 11, 0, parse_ffstreg
, insert_ffstreg
, extract_ffstreg
, print_ffstreg
},
185 /* FS reg, no selector (choice of x,y,z,w is provided by opcode). */
186 #define LFSREG (LFSFFSREG + 1)
187 { 5, 11, 0, parse_freg
, 0, 0, print_freg
},
189 /* FT reg, with FTF field selector. */
190 #define LFTFFTREG (LFSREG + 1)
191 { 5, 16, 0, parse_ffstreg
, insert_ffstreg
, extract_ffstreg
, print_ffstreg
},
194 #define LVI01 (LFTFFTREG + 1)
195 { 0, 0, 0, parse_vi01
, 0, 0, print_vi01
},
197 /* 24 bit unsigned immediate. */
198 #define LUIMM24 (LVI01 + 1)
199 { 24, 0, 0, 0, 0, 0, 0 },
201 /* 12 bit unsigned immediate, split into 1 and 11 bit pieces. */
202 #define LUIMM12 (LUIMM24 + 1)
203 { 12, 0, 0, 0, insert_luimm12
, extract_luimm12
, 0 },
205 /* upper 6 bits of 12 bit unsigned immediate */
206 #define LUIMM12UP6 (LUIMM12 + 1)
207 { 12, 0, 0, 0, insert_luimm12up6
, extract_luimm12
, 0 },
209 /* 11 bit pc-relative signed immediate. */
210 #define LPCREL11 (LUIMM12UP6 + 1)
211 { 11, 0, TXVU_OPERAND_SIGNED
+ TXVU_OPERAND_RELATIVE_BRANCH
, 0, 0, 0, 0 },
213 /* Destination indicator, single letter only, with leading '.'. */
214 #define LDOTDEST1 (LPCREL11 + 1)
215 { 4, TXVU_SHIFT_DEST
, TXVU_OPERAND_SUFFIX
,
216 /* Note that we borrow the insert/extract/print functions from the
218 parse_dotdest1
, insert_dotdest
, extract_dotdest
, print_dotdest
},
220 /* Destination indicator, single letter only, no leading '.'. */
221 #define LDEST1 (LDOTDEST1 + 1)
222 { 0, 0, 0, parse_dest1
, 0, 0, print_dest1
},
224 /* end of list place holder */
228 /* Macros to put a field's value into the right place. */
229 /* ??? If assembler needs these, move to opcode/txvu.h. */
231 /* value X, B bits, shift S */
232 #define V(x,b,s) (((x) & ((1 << (b)) - 1)) << (s))
234 /* Field value macros for both upper and lower instructions.
235 These shift a value into the right place in the instruction. */
237 /* [FI] T reg field (remember it's V for value, not vector, here). */
238 #define VT(x) V ((x), 5, TXVU_SHIFT_TREG)
239 /* [FI] S reg field. */
240 #define VS(x) V ((x), 5, TXVU_SHIFT_SREG)
241 /* [FI] D reg field. */
242 #define VD(x) V ((x), 5, TXVU_SHIFT_DREG)
244 #define VDEST(x) V ((x), 4, 21)
246 /* Masks for fields in both upper and lower instructions.
247 These mask out all bits but the ones for the field in the instruction. */
252 #define MDEST VDEST (~0)
254 /* Upper instruction Value macros. */
256 /* Upper Flag bits. */
257 #define VUF(x) V ((x), 5, 27)
258 /* Upper REServed two bits next to flag bits. */
259 #define VURES(x) V ((x), 2, 25)
260 /* 4 bit opcode field. */
261 #define VUOP4(x) V ((x), 4, 2)
262 /* 6 bit opcode field. */
263 #define VUOP6(x) V ((x), 6, 0)
264 /* 9 bit opcode field. */
265 #define VUOP9(x) V ((x), 9, 2)
266 /* 11 bit opcode field. */
267 #define VUOP11(x) V ((x), 11, 0)
268 /* BroadCast field. */
269 #define VUBC(x) V ((x), 2, 0)
271 /* Upper instruction field masks. */
272 #define MUUBITS (VUF (~0) + VURES (~0))
273 #define MURES VURES (~0)
274 #define MUOP4 VUOP4 (~0)
275 #define MUOP6 VUOP6 (~0)
276 #define MUOP9 VUOP9 (~0)
277 #define MUOP11 VUOP11 (~0)
279 /* A space, separates instruction name (mnemonic + mnemonic operands) from
282 /* Commas separate operands. */
284 /* Special I,P,Q,R operands. */
290 /* TXVU instructions.
291 [??? some of these comments are left over from the ARC port from which
292 this code is borrowed, delete in time]
294 Longer versions of insns must appear before shorter ones (if gas sees
295 "lsr r2,r3,1" when it's parsing "lsr %a,%b" it will think the ",1" is
296 junk). This isn't necessary for `ld' because of the trailing ']'.
298 Instructions that are really macros based on other insns must appear
299 before the real insn so they're chosen when disassembling. Eg: The `mov'
300 insn is really the `and' insn.
302 This table is best viewed on a wide screen (161 columns). I'd prefer to
303 keep it this way. The rest of the file, however, should be viewable on an
304 80 column terminal. */
306 /* ??? This table also includes macros: asl, lsl, and mov. The ppc port has
307 a more general facility for dealing with macros which could be used if
310 /* These tables can't be `const' because members `next_asm' and `next_dis' are
311 computed at run-time. We could split this into two, as that would put the
312 constant stuff into a readonly section. */
314 struct txvu_opcode txvu_upper_opcodes
[] =
316 /* Macros appear first, so the disassembler will try them first. */
317 /* ??? Any aliases? */
318 /* ??? When close to being finished, clean up by aligning fields. */
320 /* The rest of these needn't be sorted, but it helps to find them if they are. */
321 { "abs", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MURES
+ MUOP11
, VUOP11 (0x1fd) },
322 { "add", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP6
, VUOP6 (0x28) },
323 { "addi", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x22) },
324 { "addq", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, Q
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x20) },
325 { "add", { UBC
, DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ VUOP4 (~0), VUOP4 (0) },
326 { "adda", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP11
, VUOP11 (0x2bc) },
327 { "addai", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP11
, VUOP11 (0x23e) },
328 { "addaq", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, Q
}, MURES
+ MT
+ MUOP11
, VUOP11 (0x23c) },
329 { "adda", { UBC
, DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ MUOP9
, VUOP9 (0xf) },
330 { "clip", { DOTDEST
, SP
, VFSREG
}, MURES
+ MDEST
+ MT
+ MUOP11
, VDEST (0xf) + VUOP11 (0x1ff) },
331 { "ftoi0", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MURES
+ MUOP11
, VUOP11 (0x17c) },
332 { "ftoi4", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MURES
+ MUOP11
, VUOP11 (0x17d) },
333 { "ftoi12", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MURES
+ MUOP11
, VUOP11 (0x17e) },
334 { "ftoi15", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MURES
+ MUOP11
, VUOP11 (0x17f) },
335 { "itof0", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MURES
+ MUOP11
, VUOP11 (0x13c) },
336 { "itof4", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MURES
+ MUOP11
, VUOP11 (0x13d) },
337 { "itof12", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MURES
+ MUOP11
, VUOP11 (0x13e) },
338 { "itof15", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MURES
+ MUOP11
, VUOP11 (0x13f) },
339 { "madd", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP6
, VUOP6 (0x29) },
340 { "maddi", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x23) },
341 { "maddq", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, Q
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x21) },
342 { "madd", { UBC
, DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ MUOP4
, VUOP4 (0x2) },
343 { "madda", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP11
, VUOP11 (0x2bd) },
344 { "maddai", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP11
, VUOP11 (0x23f) },
345 { "maddaq", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, Q
}, MURES
+ MT
+ MUOP11
, VUOP11 (0x23d) },
346 { "madda", { UBC
, DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ MUOP9
, VUOP9 (0x2f) },
347 { "max", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP6
, VUOP6 (0x2b) },
348 { "maxi", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x2d) },
349 { "max", { UBC
, DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ MUOP4
, VUOP4 (0x4) },
350 /* ??? mini or min? */
351 { "mini", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP6
, VUOP6 (0x2f) },
352 { "minii", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x1f) },
353 { "mini", { UBC
, DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ MUOP4
, VUOP4 (0x5) },
354 { "msub", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP6
, VUOP6 (0x2d) },
355 { "msubi", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x27) },
356 { "msubq", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, Q
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x25) },
357 { "msub", { UBC
, DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ MUOP4
, VUOP4 (0x3) },
358 { "msuba", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP11
, VUOP11 (0x2fd) },
359 { "msubai", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP11
, VUOP11 (0x27f) },
360 { "msubaq", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, Q
}, MURES
+ MT
+ MUOP11
, VUOP11 (0x27d) },
361 { "msuba", { UBC
, DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ MUOP9
, VUOP9 (0x3f) },
362 { "mul", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP6
, VUOP6 (0x2a) },
363 { "muli", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x1e) },
364 { "mulq", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, Q
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x1c) },
365 { "mul", { UBC
, DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ VUOP4 (~0), VUOP4 (6) },
366 { "mula", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP11
, VUOP11 (0x2be) },
367 { "mulai", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP11
, VUOP11 (0x1fe) },
368 { "mulaq", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, Q
}, MURES
+ MT
+ MUOP11
, VUOP11 (0x1fc) },
369 { "mula", { UBC
, DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ MUOP9
, VUOP9 (0x6f) },
370 { "nop", { 0 }, MURES
+ MDEST
+ MT
+ MS
+ MUOP11
, VUOP11 (0x2ff) },
371 { "opmula", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, VFTREG
, UXYZ
}, MURES
+ MUOP11
, VUOP11 (0x2fe) },
372 { "opmsub", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, VFTREG
, UXYZ
}, MURES
+ MUOP6
, VUOP6 (0x2e) },
373 { "sub", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP6
, VUOP6 (0x2c) },
374 { "subi", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x26) },
375 { "subq", { DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, Q
}, MURES
+ MT
+ MUOP6
, VUOP6 (0x24) },
376 { "sub", { UBC
, DOTDEST
, SP
, VFDREG
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ VUOP4 (~0), VUOP4 (1) },
377 { "suba", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, VFTREG
}, MURES
+ MUOP11
, VUOP11 (0x2fc) },
378 { "subai", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, I
}, MURES
+ MT
+ MUOP11
, VUOP11 (0x27e) },
379 { "subaq", { DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, Q
}, MURES
+ MT
+ MUOP11
, VUOP11 (0x27c) },
380 { "suba", { UBC
, DOTDEST
, SP
, UACCDEST
, C
, VFSREG
, C
, UBCFTREG
}, MURES
+ MUOP9
, VUOP9 (0x1f) }
382 const int txvu_upper_opcodes_count
= sizeof (txvu_upper_opcodes
) / sizeof (txvu_upper_opcodes
[0]);
384 /* Lower instruction Value macros. */
387 #define VLOP6(x) V ((x), 6, 0)
389 #define VLOP7(x) V ((x), 7, 25)
391 #define VLOP11(x) V ((x), 11, 0)
392 /* 11 bit immediate. */
393 #define VLIMM11(x) V ((x), 11, 0)
395 #define VLFTF(x) V ((x), 2, 23)
397 #define VLFSF(x) V ((x), 2, 21)
398 /* Upper bit of 12 bit unsigned immediate. */
399 #define VLUIMM12TOP(x) V ((x), 1, 21)
400 /* Upper 4 bits of 15 bit unsigned immediate. */
401 #define VLUIMM15TOP(x) VDEST (x)
403 /* Lower instruction field masks. */
404 #define MLOP6 VLOP6 (~0)
405 #define MLOP7 VLOP7 (~0)
406 #define MLOP11 VLOP11 (~0)
407 #define MLIMM11 VLIMM11 (~0)
408 #define MLB24 V (1, 1, 24)
409 #define MLUIMM12TOP VLUIMM12TOP (~0)
410 /* 12 bit unsigned immediates are split into two parts, 1 bit and 11 bits.
411 The upper 1 bit is part of the `dest' field. This mask is for the
412 other 3 bits of the dest field. */
413 #define MLUIMM12UNUSED V (7, 3, 22)
414 #define MLUIMM15TOP MDEST
416 struct txvu_opcode txvu_lower_opcodes
[] =
418 /* Macros appear first, so the disassembler will try them first. */
419 /* ??? Any aliases? */
420 /* ??? There isn't an explicit nop. Apparently it's "move vf0,vf0". */
421 { "nop", { 0 }, 0xffffffff, VLOP7 (0x40) + VLIMM11 (0x33c) },
423 /* The rest of these needn't be sorted, but it helps to find them if they are. */
424 { "b", { SP
, LPCREL11
}, MLOP7
+ MDEST
+ MT
+ MS
, VLOP7 (0x20) },
425 { "bal", { SP
, LITREG
, C
, LPCREL11
}, MLOP7
+ MDEST
+ MS
, VLOP7 (0x21) },
426 { "div", { SP
, Q
, C
, LFSFFSREG
, C
, LFTFFTREG
}, MLOP7
+ MLOP11
, VLOP7 (0x40) + VLOP11 (0x3bc) },
427 { "eatan", { SP
, P
, C
, LFSFFSREG
}, MLOP7
+ VLFTF (~0) + MT
+ MLOP11
, VLOP7 (0x40) + VLOP11 (0x7fd) },
428 { "eatanxy", { SP
, P
, C
, LFSREG
}, MLOP7
+ MDEST
+ MT
+ MLOP11
, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x77c) },
429 { "eatanxz", { SP
, P
, C
, LFSREG
}, MLOP7
+ MDEST
+ MT
+ MLOP11
, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x77d) },
430 { "eexp", { SP
, P
, C
, LFSFFSREG
}, MLOP7
+ VLFTF (~0) + MT
+ MLOP11
, VLOP7 (0x40) + VLOP11 (0x7fe) },
431 { "eleng", { SP
, P
, C
, LFSREG
}, MLOP7
+ MDEST
+ MT
+ MLOP11
, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x74e) },
432 { "ercpr", { SP
, P
, C
, LFSFFSREG
}, MLOP7
+ VLFTF (~0) + MT
+ MLOP11
, VLOP7 (0x40) + VLOP11 (0x7be) },
433 { "erleng", { SP
, P
, C
, LFSREG
}, MLOP7
+ MDEST
+ MT
+ MLOP11
, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x73f) },
434 { "ersadd", { SP
, P
, C
, LFSREG
}, MLOP7
+ MDEST
+ MT
+ MLOP11
, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x73d) },
435 { "ersqrt", { SP
, P
, C
, LFSFFSREG
}, MLOP7
+ VLFTF (~0) + MT
+ MLOP11
, VLOP7 (0x40) + VLOP11 (0x7bd) },
436 { "esadd", { SP
, P
, C
, LFSREG
}, MLOP7
+ MDEST
+ MT
+ MLOP11
, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x73c) },
437 { "esin", { SP
, P
, C
, LFSFFSREG
}, MLOP7
+ VLFTF (~0) + MT
+ MLOP11
, VLOP7 (0x40) + VLOP11 (0x7fc) },
438 { "esqrt", { SP
, P
, C
, LFSFFSREG
}, MLOP7
+ VLFTF (~0) + MT
+ MLOP11
, VLOP7 (0x40) + VLOP11 (0x7bc) },
439 { "esum", { SP
, P
, C
, LFSREG
}, MLOP7
+ MDEST
+ MT
+ MLOP11
, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x77e) },
440 { "fcand", { SP
, LVI01
, C
, LUIMM24
}, MLOP7
+ MLB24
, VLOP7 (0x12) },
441 { "fceq", { SP
, LVI01
, C
, LUIMM24
}, MLOP7
+ MLB24
, VLOP7 (0x10) },
442 { "fcget", { SP
, LITREG
}, MLOP7
+ MDEST
+ MS
+ MLIMM11
, VLOP7 (0x1c) },
443 { "fcor", { SP
, LVI01
, C
, LUIMM24
}, MLOP7
+ MLB24
, VLOP7 (0x13) },
444 { "fcset", { SP
, LUIMM24
}, MLOP7
+ MLB24
, VLOP7 (0x11) },
445 { "fmand", { SP
, LITREG
, C
, LISREG
}, MLOP7
+ MDEST
+ MLIMM11
, VLOP7 (0x1a) },
446 { "fmeq", { SP
, LITREG
, C
, LISREG
}, MLOP7
+ MDEST
+ MLIMM11
, VLOP7 (0x18) },
447 { "fmor", { SP
, LITREG
, C
, LISREG
}, MLOP7
+ MDEST
+ MLIMM11
, VLOP7 (0x1b) },
448 { "fsand", { SP
, LITREG
, C
, LUIMM12
}, MLOP7
+ MLUIMM12UNUSED
+ MS
, VLOP7 (0x16) },
449 { "fseq", { SP
, LITREG
, C
, LUIMM12
}, MLOP7
+ MLUIMM12UNUSED
+ MS
, VLOP7 (0x14) },
450 { "fsor", { SP
, LITREG
, C
, LUIMM12
}, MLOP7
+ MLUIMM12UNUSED
+ MS
, VLOP7 (0x17) },
451 { "fsset", { SP
, LUIMM12UP6
}, MLOP7
+ MLUIMM12UNUSED
+ V (~0, 6, 0) + MS
+ MT
, VLOP7 (0x15) },
452 { "iadd", { SP
, LIDREG
, C
, LISREG
, C
, LITREG
}, MLOP7
+ MDEST
+ MLOP6
, VLOP7 (0x40) + VLOP6 (0x30) },
453 { "iaddi", { SP
, LITREG
, C
, LISREG
, C
, LIMM5
}, MLOP7
+ MDEST
+ MLOP6
, VLOP7 (0x40) + VLOP6 (0x32) },
454 { "iaddiu", { SP
, LITREG
, C
, LISREG
, C
, LUIMM15
}, MLOP7
, VLOP7 (0x08) },
455 { "iand", { SP
, LIDREG
, C
, LISREG
, C
, LITREG
}, MLOP7
+ MDEST
+ MLOP6
, VLOP7 (0x40) + VLOP6 (0x34) },
456 { "ibeq", { SP
, LITREG
, C
, LISREG
, C
, LPCREL11
}, MLOP7
+ MDEST
, VLOP7 (0x28) },
457 { "ibgez", { SP
, LISREG
, C
, LPCREL11
}, MLOP7
+ MDEST
+ MT
, VLOP7 (0x2f) },
458 { "ibgtz", { SP
, LISREG
, C
, LPCREL11
}, MLOP7
+ MDEST
+ MT
, VLOP7 (0x2d) },
459 { "iblez", { SP
, LISREG
, C
, LPCREL11
}, MLOP7
+ MDEST
+ MT
, VLOP7 (0x2e) },
460 { "ibltz", { SP
, LISREG
, C
, LPCREL11
}, MLOP7
+ MDEST
+ MT
, VLOP7 (0x2c) },
461 { "ibne", { SP
, LITREG
, C
, LISREG
, C
, LPCREL11
}, MLOP7
+ MDEST
, VLOP7 (0x29) },
462 { "ilw", { LDOTDEST1
, SP
, LITREG
, C
, LIMM11
, '(', LISREG
, ')', LDEST1
}, MLOP7
, VLOP7 (0x04) },
463 { "ilwr", { LDOTDEST1
, SP
, LITREG
, C
, '(', LISREG
, ')', LDEST1
}, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x3fe) },
464 { "ior", { SP
, LIDREG
, C
, LISREG
, C
, LITREG
}, MLOP7
+ MDEST
+ MLOP6
, VLOP7 (0x40) + VLOP6 (0x34) },
465 { "isub", { SP
, LIDREG
, C
, LISREG
, C
, LITREG
}, MLOP7
+ MDEST
+ MLOP6
, VLOP7 (0x40) + VLOP6 (0x31) },
466 { "isubiu", { SP
, LITREG
, C
, LISREG
, C
, LUIMM15
}, MLOP7
, VLOP7 (0x09) },
467 { "isw", { LDOTDEST1
, SP
, LITREG
, C
, LIMM11
, '(', LISREG
, ')', LDEST1
}, MLOP7
, VLOP7 (0x05) },
468 { "iswr", { LDOTDEST1
, SP
, LITREG
, C
, '(', LISREG
, ')', LDEST1
}, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x3ff) },
469 { "jalr", { SP
, LITREG
, C
, LISREG
}, MLOP7
+ MDEST
+ MLIMM11
, VLOP7 (0x25) },
470 { "jr", { SP
, LISREG
}, MLOP7
+ MDEST
+ MT
+ MLIMM11
, VLOP7 (0x24) },
471 { "lq", { DOTDEST
, SP
, VFTREG
, C
, LIMM11
, '(', LISREG
, ')' }, MLOP7
, VLOP7 (0x00) },
472 { "lqd", { DOTDEST
, SP
, VFTREG
, C
, '(', '-', '-', LISREG
, ')' }, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x37e) },
473 { "lqi", { DOTDEST
, SP
, VFTREG
, C
, '(', LISREG
, '+', '+', ')' }, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x37c) },
474 /* Only a single VF reg is allowed here. We can use VFTREG because LDOTDEST1
475 handles verifying only a single choice of xyzw is present. */
476 { "mfir", { LDOTDEST1
, SP
, VFTREG
, C
, LISREG
}, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x3fc) },
477 { "mfp", { DOTDEST
, SP
, VFTREG
, C
, P
}, MLOP7
+ MS
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x67c) },
478 { "move", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x33c) },
479 { "mr32", { DOTDEST
, SP
, VFTREG
, C
, VFSREG
}, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x33d) },
480 { "mtir", { LDOTDEST1
, SP
, LITREG
, C
, VFSREG
}, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x3fd) },
481 { "rget", { DOTDEST
, SP
, VFTREG
, C
, R
}, MLOP7
+ MS
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x43d) },
482 { "rinit", { SP
, R
, C
, LFSFFSREG
}, MLOP7
+ VLFTF (~0) + MT
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x43e) },
483 { "rnext", { DOTDEST
, SP
, VFTREG
, C
, R
}, MLOP7
+ MS
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x43c) },
484 { "rsqrt", { SP
, Q
, C
, LFSFFSREG
, C
, LFTFFTREG
}, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x3be) },
485 { "rxor", { SP
, R
, C
, LFSFFSREG
}, MLOP7
+ VLFTF (~0) + MT
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x43f) },
486 { "sq", { DOTDEST
, SP
, VFTREG
, C
, LIMM11
, '(', LISREG
, ')' }, MLOP7
, VLOP7 (0x01) },
487 { "sqd", { DOTDEST
, SP
, VFTREG
, C
, '(', '-', '-', LISREG
, ')' }, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x37f) },
488 { "sqi", { DOTDEST
, SP
, VFTREG
, C
, '(', LISREG
, '+', '+', ')' }, MLOP7
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x37d) },
489 { "sqrt", { SP
, Q
, C
, LFTFFTREG
}, MLOP7
+ VLFSF (~0) + MS
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x3bd) },
490 { "waitp", { 0 }, 0xffffffff, VLOP7 (0x40) + VLIMM11 (0x7bf) },
491 { "waitq", { 0 }, 0xffffffff, VLOP7 (0x40) + VLIMM11 (0x3bf) },
492 { "xgkick", { SP
, LISREG
}, MLOP7
+ MDEST
+ MT
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x6fc) },
493 { "xitop", { SP
, LITREG
}, MLOP7
+ MDEST
+ MS
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x6bd) },
494 { "xtop", { SP
, LITREG
}, MLOP7
+ MDEST
+ MS
+ MLIMM11
, VLOP7 (0x40) + VLIMM11 (0x6bc) }
496 const int txvu_lower_opcodes_count
= sizeof (txvu_lower_opcodes
) / sizeof (txvu_lower_opcodes
[0]);
498 /* Value of DEST in use.
499 Each of the registers must specify the same value as the opcode.
500 ??? Perhaps remove the duplication? */
501 static int mnemonic_dest
;
503 /* Value of BC to use.
504 The register specified for the ftreg must match the broadcast register
505 specified in the opcode. */
506 static int mnemonic_bc
;
508 /* Multiple destination choice support.
509 The "dest" string selects any combination of x,y,z,w.
510 [The letters are ordered that way to follow the manual's style.] */
512 /* Utility to parse a `dest' spec.
513 Return the found value.
514 *PSTR is set to the character that terminated the parsing.
515 It is up to the caller to do any error checking. */
527 case 'x' : case 'X' : dest
|= TXVU_DEST_X
; break;
528 case 'y' : case 'Y' : dest
|= TXVU_DEST_Y
; break;
529 case 'z' : case 'Z' : dest
|= TXVU_DEST_Z
; break;
530 case 'w' : case 'W' : dest
|= TXVU_DEST_W
; break;
531 default : return dest
;
540 parse_dotdest (pstr
, errmsg
)
548 *errmsg
= "missing `.'";
553 dest
= _parse_dest (pstr
);
554 if (dest
== 0 || isalnum (**pstr
))
556 *errmsg
= "invalid `dest'";
563 /* Parse a `dest' spec where only a single letter is allowed,
564 but the encoding handles all four. */
567 parse_dotdest1 (pstr
, errmsg
)
576 *errmsg
= "missing `.'";
583 case 'x' : case 'X' : dest
= TXVU_DEST_X
; break;
584 case 'y' : case 'Y' : dest
= TXVU_DEST_Y
; break;
585 case 'z' : case 'Z' : dest
= TXVU_DEST_Z
; break;
586 case 'w' : case 'W' : dest
= TXVU_DEST_W
; break;
587 default : *errmsg
= "invalid `dest'"; return 0;
590 c
= tolower (**pstr
);
591 if (c
== 'x' || c
== 'y' || c
== 'z' || c
== 'w')
593 *errmsg
= "only one of x,y,z,w can be specified";
596 if (isalnum (**pstr
))
598 *errmsg
= "invalid `dest'";
605 /* Parse a `dest' spec with no leading '.', where only a single letter is
606 allowed, but the encoding handles all four. The parsed value must match
607 that recorded in `dest'. */
610 parse_dest1 (pstr
, errmsg
)
617 dest
= _parse_dest (pstr
);
618 if (dest
!= TXVU_DEST_X
619 && dest
!= TXVU_DEST_Y
620 && dest
!= TXVU_DEST_Z
621 && dest
!= TXVU_DEST_W
)
623 *errmsg
= "expecting one of x,y,z,w";
627 if (dest
!= mnemonic_dest
)
629 *errmsg
= "`dest' suffix does not match instruction `dest'";
637 insert_dotdest (insn
, operand
, mods
, value
, errmsg
)
639 const struct txvu_operand
*operand
;
644 /* Record the DEST value in use so the register parser can use it. */
645 mnemonic_dest
= value
;
646 *insn
|= value
<< operand
->shift
;
650 extract_dotdest (insn
, operand
, mods
, pinvalid
)
652 const struct txvu_operand
*operand
;
656 /* Record the DEST value in use so the register printer can use it. */
657 mnemonic_dest
= (*insn
>> operand
->shift
) & ((1 << operand
->bits
) - 1);
658 return mnemonic_dest
;
661 /* Utility to print a multiple dest spec. */
664 _print_dest (info
, insn
, value
)
665 disassemble_info
*info
;
669 if (value
& TXVU_DEST_X
)
670 (*info
->fprintf_func
) (info
->stream
, "x");
671 if (value
& TXVU_DEST_Y
)
672 (*info
->fprintf_func
) (info
->stream
, "y");
673 if (value
& TXVU_DEST_Z
)
674 (*info
->fprintf_func
) (info
->stream
, "z");
675 if (value
& TXVU_DEST_W
)
676 (*info
->fprintf_func
) (info
->stream
, "w");
680 print_dotdest (info
, insn
, value
)
681 disassemble_info
*info
;
685 (*info
->fprintf_func
) (info
->stream
, ".");
686 _print_dest (info
, insn
, value
);
690 print_dest1 (info
, insn
, value
)
691 disassemble_info
*info
;
695 _print_dest (info
, insn
, mnemonic_dest
);
698 /* Utilities for single destination choice handling. */
701 _parse_sdest (pstr
, errmsg
)
710 case 'x' : case 'X' : dest
= TXVU_SDEST_X
; break;
711 case 'y' : case 'Y' : dest
= TXVU_SDEST_Y
; break;
712 case 'z' : case 'Z' : dest
= TXVU_SDEST_Z
; break;
713 case 'w' : case 'W' : dest
= TXVU_SDEST_W
; break;
714 default : *errmsg
= "only one of x,y,z,w can be specified"; return 0;
717 c
= tolower (**pstr
);
718 if (c
== 'x' || c
== 'y' || c
== 'z' || c
== 'w')
720 *errmsg
= "only one of x,y,z,w can be specified";
723 if (isalnum (**pstr
))
725 *errmsg
= "invalid `dest'";
733 print_sdest (info
, insn
, value
)
734 disassemble_info
*info
;
742 case TXVU_SDEST_X
: c
= 'x'; break;
743 case TXVU_SDEST_Y
: c
= 'y'; break;
744 case TXVU_SDEST_Z
: c
= 'z'; break;
745 case TXVU_SDEST_W
: c
= 'w'; break;
748 (*info
->fprintf_func
) (info
->stream
, "%c", c
);
751 /* Broadcase field. */
754 parse_bc (pstr
, errmsg
)
758 long value
= _parse_sdest (pstr
, errmsg
);
762 /* Save value for later verification in register parsing. */
767 /* During the extraction process, save the bc field for use in
768 printing the bc register. */
771 extract_bc (insn
, operand
, mods
, pinvalid
)
773 const struct txvu_operand
*operand
;
777 mnemonic_bc
= *insn
& 3;
782 parse_vfreg (pstr
, errmsg
)
791 if (tolower (str
[0]) != 'v'
792 || tolower (str
[1]) != 'f')
794 *errmsg
= "unknown register";
798 /* FIXME: quick hack until the framework works. */
799 start
= str
= str
+ 2;
800 while (*str
&& isdigit (*str
))
803 if (reg
< 0 || reg
> 31)
805 *errmsg
= "invalid register number";
808 reg_dest
= _parse_dest (&str
);
809 if (reg_dest
== 0 || isalnum (*str
))
811 *errmsg
= "invalid `dest'";
814 if (reg_dest
!= mnemonic_dest
)
816 *errmsg
= "register `dest' does not match instruction `dest'";
824 print_vfreg (info
, insn
, value
)
825 disassemble_info
*info
;
829 (*info
->fprintf_func
) (info
->stream
, "vf%02ld", value
);
830 _print_dest (info
, insn
, mnemonic_dest
);
833 /* FT register in broadcast case. */
836 parse_bcftreg (pstr
, errmsg
)
845 if (tolower (str
[0]) != 'v'
846 || tolower (str
[1]) != 'f')
848 *errmsg
= "unknown register";
852 /* FIXME: quick hack until the framework works. */
853 start
= str
= str
+ 2;
854 while (*str
&& isdigit (*str
))
857 if (reg
< 0 || reg
> 31)
859 *errmsg
= "invalid register number";
862 reg_bc
= _parse_sdest (&str
, errmsg
);
865 if (reg_bc
!= mnemonic_bc
)
867 *errmsg
= "register `bc' does not match instruction `bc'";
875 print_bcftreg (info
, insn
, value
)
876 disassemble_info
*info
;
880 (*info
->fprintf_func
) (info
->stream
, "vf%02ld", value
);
881 print_sdest (info
, insn
, mnemonic_bc
);
887 parse_accdest (pstr
, errmsg
)
894 if (strncasecmp (str
, "acc", 3) != 0)
896 *errmsg
= "expecting `acc'";
900 acc_dest
= _parse_dest (&str
);
901 if (acc_dest
== 0 || isalnum (*str
))
903 *errmsg
= "invalid `dest'";
906 if (acc_dest
!= mnemonic_dest
)
908 *errmsg
= "acc `dest' does not match instruction `dest'";
912 /* Value isn't used, but we must return something. */
917 print_accdest (info
, insn
, value
)
918 disassemble_info
*info
;
922 (*info
->fprintf_func
) (info
->stream
, "acc");
923 _print_dest (info
, insn
, mnemonic_dest
);
926 /* XYZ operand handling.
927 This simplifies the opmula,opmsub entries by keeping them equivalent to
931 insert_xyz (insn
, operand
, mods
, value
, errmsg
)
933 const struct txvu_operand
*operand
;
938 if (mnemonic_dest
!= (TXVU_DEST_X
| TXVU_DEST_Y
| TXVU_DEST_Z
))
939 *errmsg
= "expecting `xyz' for `dest' value";
942 /* F[ST] register using selector in F[ST]F field.
943 Internally, the value is encoded in 7 bits: the 2 bit xyzw indicator
944 followed by the 5 bit register number. */
947 parse_ffstreg (pstr
, errmsg
)
955 if (tolower (str
[0]) != 'v'
956 || tolower (str
[1]) != 'f')
958 *errmsg
= "unknown register";
962 /* FIXME: quick hack until the framework works. */
963 start
= str
= str
+ 2;
964 while (*str
&& isdigit (*str
))
967 if (reg
< 0 || reg
> 31)
969 *errmsg
= "invalid register number";
972 xyzw
= _parse_sdest (&str
, errmsg
);
976 return reg
| (xyzw
<< 5);
980 print_ffstreg (info
, insn
, value
)
981 disassemble_info
*info
;
985 (*info
->fprintf_func
) (info
->stream
, "vf%02ld", value
& TXVU_MASK_REG
);
986 print_sdest (info
, insn
, (value
>> 5) & 3);
990 insert_ffstreg (insn
, operand
, mods
, value
, errmsg
)
992 const struct txvu_operand
*operand
;
997 if (operand
->shift
== TXVU_SHIFT_SREG
)
998 *insn
|= VLFSF (value
>> 5) | VS (value
);
1000 *insn
|= VLFTF (value
>> 5) | VT (value
);
1004 extract_ffstreg (insn
, operand
, mods
, pinvalid
)
1006 const struct txvu_operand
*operand
;
1010 if (operand
->shift
== TXVU_SHIFT_SREG
)
1011 return (((*insn
& VLFSF (~0)) >> 21) << 5) | VS (*insn
);
1013 return (((*insn
& VLFTF (~0)) >> 21) << 5) | VT (*insn
);
1019 parse_freg (pstr
, errmsg
)
1021 const char **errmsg
;
1027 if (tolower (str
[0]) != 'v'
1028 || tolower (str
[1]) != 'f')
1030 *errmsg
= "unknown register";
1034 /* FIXME: quick hack until the framework works. */
1035 start
= str
= str
+ 2;
1036 while (*str
&& isdigit (*str
))
1039 if (reg
< 0 || reg
> 31)
1041 *errmsg
= "invalid register number";
1049 print_freg (info
, insn
, value
)
1050 disassemble_info
*info
;
1054 (*info
->fprintf_func
) (info
->stream
, "vf%02ld", value
);
1060 parse_ireg (pstr
, errmsg
)
1062 const char **errmsg
;
1068 if (tolower (str
[0]) != 'v'
1069 || tolower (str
[1]) != 'i')
1071 *errmsg
= "unknown register";
1075 /* FIXME: quick hack until the framework works. */
1076 start
= str
= str
+ 2;
1077 while (*str
&& isdigit (*str
))
1080 if (reg
< 0 || reg
> 31)
1082 *errmsg
= "invalid register number";
1090 print_ireg (info
, insn
, value
)
1091 disassemble_info
*info
;
1095 (*info
->fprintf_func
) (info
->stream
, "vi%02ld", value
);
1098 /* VI01 register. */
1101 parse_vi01 (pstr
, errmsg
)
1103 const char **errmsg
;
1109 if (tolower (str
[0]) != 'v'
1110 || tolower (str
[1]) != 'i')
1112 *errmsg
= "unknown register";
1116 /* FIXME: quick hack until the framework works. */
1117 start
= str
= str
+ 2;
1118 while (*str
&& isdigit (*str
))
1123 *errmsg
= "vi01 required here";
1131 print_vi01 (info
, insn
, value
)
1132 disassemble_info
*info
;
1136 (*info
->fprintf_func
) (info
->stream
, "vi01");
1139 /* Lower instruction 12 bit unsigned immediate. */
1142 insert_luimm12 (insn
, operand
, mods
, value
, errmsg
)
1144 const struct txvu_operand
*operand
;
1147 const char **errmsg
;
1149 *insn
|= VLUIMM12TOP ((value
& (1 << 11)) != 0) | VLIMM11 (value
);
1153 extract_luimm12 (insn
, operand
, mods
, pinvalid
)
1155 const struct txvu_operand
*operand
;
1159 return (((*insn
& MLUIMM12TOP
) != 0) << 11) | VLIMM11 (*insn
);
1162 /* Lower instruction 12 bit unsigned immediate, upper 6 bits. */
1165 insert_luimm12up6 (insn
, operand
, mods
, value
, errmsg
)
1167 const struct txvu_operand
*operand
;
1170 const char **errmsg
;
1172 *insn
|= VLUIMM12TOP ((value
& (1 << 11)) != 0) | (value
& 0x7c0);
1175 /* Lower instruction 15 bit unsigned immediate. */
1178 insert_luimm15 (insn
, operand
, mods
, value
, errmsg
)
1180 const struct txvu_operand
*operand
;
1183 const char **errmsg
;
1185 *insn
|= VLUIMM15TOP (value
>> 11) | VLIMM11 (value
);
1189 extract_luimm15 (insn
, operand
, mods
, pinvalid
)
1191 const struct txvu_operand
*operand
;
1195 return (((*insn
& MLUIMM15TOP
) >> 21) << 11) | VLIMM11 (*insn
);
1200 PARSE_FN (pke_ibit
);
1201 PRINT_FN (pke_ibit
);
1203 PARSE_FN (pke_mode
);
1204 PRINT_FN (pke_mode
);
1206 PARSE_FN (pke_ability
);
1207 PRINT_FN (pke_ability
);
1209 PARSE_FN (pke_mpgaddr
);
1211 PARSE_FN (pke_varlendata
);
1213 PARSE_FN (pke_imrbits
);
1214 PRINT_FN (pke_imrbits
);
1216 PARSE_FN (pke_unpacktype
);
1217 PRINT_FN (pke_unpacktype
);
1219 PARSE_FN (pke_unpackaddr
);
1221 const struct txvu_operand pke_operands
[] =
1223 /* place holder (??? not sure if needed) */
1224 #define PKE_UNUSED 128
1228 #define PKE_IBIT (PKE_UNUSED + 1)
1229 { 1, 31, TXVU_OPERAND_SUFFIX
, parse_pke_ibit
, 0, 0, print_pke_ibit
},
1231 /* An 8 bit unsigned immediate, stored in upper 8 bits of immed field. */
1232 #define PKE_UIMM8UP (PKE_IBIT + 1)
1233 { 8, 8, 0, 0, 0, 0, 0 },
1235 /* An 8 bit unsigned immediate, stored in lower 8 bits of immed field. */
1236 #define PKE_UIMM8LO (PKE_UIMM8UP + 1)
1237 { 8, 0, 0, 0, 0, 0, 0 },
1239 /* An 16 bit unsigned immediate, stored in lower 8 bits of immed field. */
1240 #define PKE_UIMM16 (PKE_UIMM8LO + 1)
1241 { 16, 0, 0, 0, 0, 0, 0 },
1243 /* The mode operand of `stmod'. */
1244 #define PKE_MODE (PKE_UIMM16 + 1)
1245 { 2, 0, 0, parse_pke_mode
, 0, 0, print_pke_mode
},
1247 /* The ability operand of `mskpath3'. */
1248 #define PKE_ABILITY (PKE_MODE + 1)
1249 { 1, 15, 0, parse_pke_ability
, 0, 0, print_pke_ability
},
1252 #define PKE_VUADDR (PKE_ABILITY + 1)
1253 { 16, 0, 0, 0, 0, 0, 0 },
1255 /* A 32 bit immediate, appearing in 2nd,3rd,4th,5th words. */
1256 #define PKE_UIMM32 (PKE_VUADDR + 1)
1257 { 32, 0, 0, 0, 0, 0, 0 },
1259 /* VU address used by mpg insn. */
1260 #define PKE_MPGADDR (PKE_UIMM32 + 1)
1261 { 16, 0, TXVU_OPERAND_ADDRESS
, parse_pke_mpgaddr
, 0, 0, 0 },
1263 /* A variable length data specifier.
1264 Any of: file name, number, or '*'. */
1265 #define PKE_VARLENDATA (PKE_MPGADDR + 1)
1266 { 0, 0, 0, parse_pke_varlendata
, 0, 0, 0 },
1268 /* The IMR bits of the unpack insn. */
1269 #define PKE_IMRBITS (PKE_VARLENDATA + 1)
1270 { 0, 0, 0, parse_pke_imrbits
, 0, 0, print_pke_imrbits
},
1272 /* The type of the unpack insn. */
1273 #define PKE_UNPACKTYPE (PKE_IMRBITS + 1)
1274 { 4, 24, 0, parse_pke_unpacktype
, 0, 0, print_pke_unpacktype
},
1276 /* VU address used by unpack insn. */
1277 #define PKE_UNPACKADDR (PKE_UIMM32 + 1)
1278 { 16, 0, TXVU_OPERAND_ADDRESS
, parse_pke_unpackaddr
, 0, 0, 0 },
1280 /* end of list place holder */
1284 /* Field mask values. */
1285 #define MPKECMD 0x7f000000
1286 #define MPKEUNPACK 0x60000000
1289 #define VPKECMD(x) V ((x), 7, 24)
1290 #define VPKEUNPACK V (0x60, 8, 24)
1292 struct txvu_opcode pke_opcodes
[] =
1294 { "pkenop", { PKE_IBIT
}, 0x7fffffff, 0 },
1295 { "stcycle", { PKE_IBIT
, SP
, PKE_UIMM8UP
, C
, PKE_UIMM8LO
}, MPKECMD
, VPKECMD (1) },
1296 { "offset", { PKE_IBIT
, SP
, PKE_UIMM16
}, MPKECMD
, VPKECMD (2) },
1297 { "base", { PKE_IBIT
, SP
, PKE_UIMM16
}, MPKECMD
, VPKECMD (3) },
1298 { "itop", { PKE_IBIT
, SP
, PKE_UIMM16
}, MPKECMD
, VPKECMD (4) },
1299 { "stmod", { PKE_IBIT
, SP
, PKE_MODE
}, MPKECMD
+ V (~0, 14, 2), VPKECMD (5) },
1300 { "mskpath3", { PKE_IBIT
, SP
, PKE_ABILITY
}, MPKECMD
+ V (~0, 15, 0), VPKECMD (6) },
1301 { "pkemark", { PKE_IBIT
, SP
, PKE_UIMM16
}, MPKECMD
, VPKECMD (7) },
1302 { "flushe", { PKE_IBIT
}, MPKECMD
, VPKECMD (16) },
1303 { "flush", { PKE_IBIT
}, MPKECMD
, VPKECMD (17) },
1304 { "flusha", { PKE_IBIT
}, MPKECMD
, VPKECMD (19) },
1305 { "pkemscal", { PKE_IBIT
, SP
, PKE_VUADDR
}, MPKECMD
, VPKECMD (20) },
1306 { "pkemscnt", { PKE_IBIT
}, MPKECMD
, VPKECMD (23) },
1307 { "pkemscalf", { PKE_IBIT
, SP
, PKE_VUADDR
}, MPKECMD
, VPKECMD (21) },
1309 /* 2 word instructions */
1310 { "stmask", { PKE_IBIT
, SP
, PKE_UIMM32
}, MPKECMD
, VPKECMD (32), PKE_OPCODE_LEN2
},
1312 /* 5 word instructions */
1313 { "strow", { PKE_IBIT
, SP
, PKE_UIMM32
, PKE_UIMM32
, PKE_UIMM32
, PKE_UIMM32
}, MPKECMD
, VPKECMD (48), PKE_OPCODE_LEN5
},
1314 { "stcol", { PKE_IBIT
, SP
, PKE_UIMM32
, PKE_UIMM32
, PKE_UIMM32
, PKE_UIMM32
}, MPKECMD
, VPKECMD (49), PKE_OPCODE_LEN5
},
1316 /* variable length instructions */
1317 { "mpg", { PKE_IBIT
, SP
, PKE_MPGADDR
, PKE_VARLENDATA
}, MPKECMD
, VPKECMD (0x4a), PKE_OPCODE_LENVAR
+ PKE_OPCODE_MPG
},
1318 { "direct", { PKE_IBIT
, SP
, PKE_VARLENDATA
}, MPKECMD
, VPKECMD (0x50), PKE_OPCODE_LENVAR
+ PKE_OPCODE_DIRECT
},
1319 { "directhl", { PKE_IBIT
, SP
, PKE_VARLENDATA
}, MPKECMD
, VPKECMD (0x51), PKE_OPCODE_LENVAR
+ PKE_OPCODE_DIRECT
},
1320 { "unpack", { PKE_IMRBITS
, SP
, PKE_UNPACKTYPE
, C
, PKE_UNPACKADDR
, C
, PKE_VARLENDATA
}, MPKEUNPACK
, VPKEUNPACK
, PKE_OPCODE_LENVAR
+ PKE_OPCODE_UNPACK
},
1322 const int pke_opcodes_count
= sizeof (pke_opcodes
) / sizeof (pke_opcodes
[0]);
1324 /* PKE parse,insert,extract,print helper fns. */
1327 parse_pke_ibit (pstr
, errmsg
)
1329 const char **errmsg
;
1334 print_pke_ibit (info
, insn
, value
)
1335 disassemble_info
*info
;
1339 (*info
->fprintf_func
) (info
->stream
, "???");
1343 parse_pke_mode (pstr
, errmsg
)
1345 const char **errmsg
;
1350 print_pke_mode (info
, insn
, value
)
1351 disassemble_info
*info
;
1355 (*info
->fprintf_func
) (info
->stream
, "???");
1359 parse_pke_ability (pstr
, errmsg
)
1361 const char **errmsg
;
1366 print_pke_ability (info
, insn
, value
)
1367 disassemble_info
*info
;
1371 (*info
->fprintf_func
) (info
->stream
, "???");
1375 parse_pke_mpgaddr (pstr
, errmsg
)
1377 const char **errmsg
;
1382 parse_pke_varlendata (pstr
, errmsg
)
1384 const char **errmsg
;
1386 /* The result here is either the length specified,
1387 or PKE_VARLENDATA_FILE or PKE_VARLENDATA_UNKNOWN. */
1391 parse_pke_imrbits (pstr
, errmsg
)
1393 const char **errmsg
;
1398 print_pke_imrbits (info
, insn
, value
)
1399 disassemble_info
*info
;
1403 (*info
->fprintf_func
) (info
->stream
, "???");
1407 parse_pke_unpacktype (pstr
, errmsg
)
1409 const char **errmsg
;
1414 print_pke_unpacktype (info
, insn
, value
)
1415 disassemble_info
*info
;
1419 (*info
->fprintf_func
) (info
->stream
, "???");
1423 parse_pke_unpackaddr (pstr
, errmsg
)
1425 const char **errmsg
;
1431 PARSE_FN (dma_flags
);
1432 INSERT_FN (dma_flags
);
1433 EXTRACT_FN (dma_flags
);
1434 PRINT_FN (dma_flags
);
1436 PARSE_FN (dma_data
);
1437 INSERT_FN (dma_data
);
1438 EXTRACT_FN (dma_data
);
1439 PRINT_FN (dma_data
);
1441 PARSE_FN (dma_next
);
1442 INSERT_FN (dma_next
);
1443 EXTRACT_FN (dma_next
);
1444 PRINT_FN (dma_next
);
1446 const struct txvu_operand dma_operands
[] =
1448 /* place holder (??? not sure if needed) */
1449 #define DMA_UNUSED 128
1452 /* dma tag flag bits */
1453 #define DMA_FLAGS (DMA_UNUSED + 1)
1454 { 0, 0, TXVU_OPERAND_SUFFIX
,
1455 parse_dma_flags
, insert_dma_flags
, extract_dma_flags
, print_dma_flags
},
1457 /* dma tag flag bits */
1458 #define DMA_DATA (DMA_FLAGS + 1)
1460 parse_dma_data
, insert_dma_data
, extract_dma_data
, print_dma_data
},
1462 /* dma tag flag bits */
1463 #define DMA_NEXT (DMA_DATA + 1)
1465 parse_dma_next
, insert_dma_next
, extract_dma_next
, print_dma_next
},
1467 /* end of list place holder */
1471 struct txvu_opcode dma_opcodes
[] =
1473 { "dmacnt", { DMA_FLAGS
, SP
, DMA_DATA
, C
, DMA_NEXT
}, 0, 1 },
1474 { "dmanext", { DMA_FLAGS
, SP
, DMA_DATA
, C
, DMA_NEXT
}, 0, 2 },
1475 { "dmaref", { DMA_FLAGS
, SP
, DMA_DATA
, C
, DMA_NEXT
}, 0, 3 },
1476 { "dmarefs", { DMA_FLAGS
, SP
, DMA_DATA
, C
, DMA_NEXT
}, 0, 4 },
1477 { "dmacall", { DMA_FLAGS
, SP
, DMA_DATA
, C
, DMA_NEXT
}, 0, 5 },
1478 { "dmareg", { DMA_FLAGS
, SP
, DMA_DATA
, C
, DMA_NEXT
}, 0, 6 },
1479 { "dmaend", { DMA_FLAGS
, SP
, DMA_DATA
, C
, DMA_NEXT
}, 0, 7 }
1481 const int dma_opcodes_count
= sizeof (dma_opcodes
) / sizeof (dma_opcodes
[0]);
1483 /* DMA parse,insert,extract,print helper fns. */
1486 parse_dma_flags (pstr
, errmsg
)
1488 const char **errmsg
;
1496 for (str
= str
+ 1; *str
!= ']'; ++str
)
1498 switch (tolower (*str
))
1500 case '0' : flags
|= DMA_FLAG_PCE0
; break;
1501 case '1' : flags
|= DMA_FLAG_PCE1
; break;
1502 case 'i' : flags
|= DMA_FLAG_INT
; break;
1503 case 's' : flags
|= DMA_FLAG_SPR
; break;
1504 default : *errmsg
= "unknown dma flag"; return 0;
1514 insert_dma_flags (insn
, operand
, mods
, value
, errmsg
)
1516 const struct txvu_operand
*operand
;
1519 const char **errmsg
;
1524 extract_dma_flags (insn
, operand
, mods
, pinvalid
)
1526 const struct txvu_operand
*operand
;
1534 print_dma_flags (info
, insn
, value
)
1535 disassemble_info
*info
;
1541 (*info
->fprintf_func
) (info
->stream
, "[");
1542 if (value
& DMA_FLAG_PCE0
)
1543 (*info
->fprintf_func
) (info
->stream
, "0");
1544 if (value
& DMA_FLAG_PCE1
)
1545 (*info
->fprintf_func
) (info
->stream
, "1");
1546 if (value
& DMA_FLAG_INT
)
1547 (*info
->fprintf_func
) (info
->stream
, "i");
1548 if (value
& DMA_FLAG_SPR
)
1549 (*info
->fprintf_func
) (info
->stream
, "s");
1550 (*info
->fprintf_func
) (info
->stream
, "]");
1555 parse_dma_data (pstr
, errmsg
)
1557 const char **errmsg
;
1562 insert_dma_data (insn
, operand
, mods
, value
, errmsg
)
1564 const struct txvu_operand
*operand
;
1567 const char **errmsg
;
1572 extract_dma_data (insn
, operand
, mods
, pinvalid
)
1574 const struct txvu_operand
*operand
;
1582 print_dma_data (info
, insn
, value
)
1583 disassemble_info
*info
;
1587 (*info
->fprintf_func
) (info
->stream
, "???");
1591 parse_dma_next (pstr
, errmsg
)
1593 const char **errmsg
;
1598 insert_dma_next (insn
, operand
, mods
, value
, errmsg
)
1600 const struct txvu_operand
*operand
;
1603 const char **errmsg
;
1608 extract_dma_next (insn
, operand
, mods
, pinvalid
)
1610 const struct txvu_operand
*operand
;
1618 print_dma_next (info
, insn
, value
)
1619 disassemble_info
*info
;
1623 (*info
->fprintf_func
) (info
->stream
, "???");
1626 /* GPUIF support. */
1628 PARSE_FN (gpuif_prim
);
1629 INSERT_FN (gpuif_prim
);
1630 EXTRACT_FN (gpuif_prim
);
1631 PRINT_FN (gpuif_prim
);
1633 PARSE_FN (gpuif_regs
);
1634 INSERT_FN (gpuif_regs
);
1635 EXTRACT_FN (gpuif_regs
);
1636 PRINT_FN (gpuif_regs
);
1638 PARSE_FN (gpuif_nloop
);
1639 INSERT_FN (gpuif_nloop
);
1640 EXTRACT_FN (gpuif_nloop
);
1641 PRINT_FN (gpuif_nloop
);
1643 PARSE_FN (gpuif_eop
);
1644 INSERT_FN (gpuif_eop
);
1645 EXTRACT_FN (gpuif_eop
);
1646 PRINT_FN (gpuif_eop
);
1648 const struct txvu_operand gpuif_operands
[] =
1650 /* place holder (??? not sure if needed) */
1651 #define GPUIF_UNUSED 128
1654 /* PRIM=foo operand */
1655 #define GPUIF_PRIM (GPUIF_UNUSED + 1)
1656 { 0, 0, 0, parse_gpuif_prim
, insert_gpuif_prim
, extract_gpuif_prim
, print_gpuif_prim
},
1658 /* REGS=foo operand */
1659 #define GPUIF_REGS (GPUIF_PRIM + 1)
1660 { 0, 0, 0, parse_gpuif_regs
, insert_gpuif_regs
, extract_gpuif_regs
, print_gpuif_regs
},
1662 /* NLOOP=foo operand */
1663 #define GPUIF_NLOOP (GPUIF_REGS + 1)
1664 { 0, 0, 0, parse_gpuif_nloop
, insert_gpuif_nloop
, extract_gpuif_nloop
, print_gpuif_nloop
},
1667 #define GPUIF_EOP (GPUIF_NLOOP + 1)
1668 { 0, 0, 0, parse_gpuif_eop
, insert_gpuif_eop
, extract_gpuif_eop
, print_gpuif_eop
},
1670 /* end of list place holder */
1674 struct txvu_opcode gpuif_opcodes
[] =
1676 { "gpuifpacked", { SP
, GPUIF_PRIM
, C
, GPUIF_REGS
, C
, GPUIF_NLOOP
, C
, GPUIF_EOP
}, 0, 1 },
1677 { "gpuifreglist", { SP
, GPUIF_REGS
, C
, GPUIF_NLOOP
, C
, GPUIF_EOP
}, 0, 2 },
1678 { "gpuifimage", { SP
, GPUIF_NLOOP
}, 0, 3 },
1680 const int gpuif_opcodes_count
= sizeof (gpuif_opcodes
) / sizeof (gpuif_opcodes
[0]);
1682 /* GPUIF parse,insert,extract,print helper fns. */
1685 parse_gpuif_prim (pstr
, errmsg
)
1687 const char **errmsg
;
1692 insert_gpuif_prim (insn
, operand
, mods
, value
, errmsg
)
1694 const struct txvu_operand
*operand
;
1697 const char **errmsg
;
1702 extract_gpuif_prim (insn
, operand
, mods
, pinvalid
)
1704 const struct txvu_operand
*operand
;
1712 print_gpuif_prim (info
, insn
, value
)
1713 disassemble_info
*info
;
1717 (*info
->fprintf_func
) (info
->stream
, "???");
1721 parse_gpuif_regs (pstr
, errmsg
)
1723 const char **errmsg
;
1728 insert_gpuif_regs (insn
, operand
, mods
, value
, errmsg
)
1730 const struct txvu_operand
*operand
;
1733 const char **errmsg
;
1738 extract_gpuif_regs (insn
, operand
, mods
, pinvalid
)
1740 const struct txvu_operand
*operand
;
1748 print_gpuif_regs (info
, insn
, value
)
1749 disassemble_info
*info
;
1753 (*info
->fprintf_func
) (info
->stream
, "???");
1757 parse_gpuif_nloop (pstr
, errmsg
)
1759 const char **errmsg
;
1764 insert_gpuif_nloop (insn
, operand
, mods
, value
, errmsg
)
1766 const struct txvu_operand
*operand
;
1769 const char **errmsg
;
1774 extract_gpuif_nloop (insn
, operand
, mods
, pinvalid
)
1776 const struct txvu_operand
*operand
;
1784 print_gpuif_nloop (info
, insn
, value
)
1785 disassemble_info
*info
;
1789 (*info
->fprintf_func
) (info
->stream
, "???");
1793 parse_gpuif_eop (pstr
, errmsg
)
1795 const char **errmsg
;
1800 insert_gpuif_eop (insn
, operand
, mods
, value
, errmsg
)
1802 const struct txvu_operand
*operand
;
1805 const char **errmsg
;
1810 extract_gpuif_eop (insn
, operand
, mods
, pinvalid
)
1812 const struct txvu_operand
*operand
;
1820 print_gpuif_eop (info
, insn
, value
)
1821 disassemble_info
*info
;
1825 (*info
->fprintf_func
) (info
->stream
, "???");
1829 These are called before doing each of the respective activities. */
1831 /* Called by the assembler before parsing an instruction. */
1834 txvu_opcode_init_parse ()
1840 /* Called by the disassembler before printing an instruction. */
1843 txvu_opcode_init_print ()
1849 /* Indexed by first letter of opcode. Points to chain of opcodes with same
1851 /* ??? One can certainly use a better hash. Later. */
1852 static struct txvu_opcode
*upper_opcode_map
[26 + 1];
1853 static struct txvu_opcode
*lower_opcode_map
[26 + 1];
1855 /* Indexed by insn code. Points to chain of opcodes with same insn code. */
1856 static struct txvu_opcode
*upper_icode_map
[(1 << TXVU_ICODE_HASH_SIZE
) - 1];
1857 static struct txvu_opcode
*lower_icode_map
[(1 << TXVU_ICODE_HASH_SIZE
) - 1];
1859 /* Initialize any tables that need it.
1860 Must be called once at start up (or when first needed).
1862 FLAGS is currently unused but is intended to control initialization. */
1865 txvu_opcode_init_tables (flags
)
1868 static int init_p
= 0;
1870 /* We may be intentionally called more than once (for example gdb will call
1871 us each time the user switches cpu). These tables only need to be init'd
1873 /* ??? We can remove the need for txvu_opcode_supported by taking it into
1874 account here, but I'm not sure I want to do that yet (if ever). */
1879 /* Upper VU table. */
1881 memset (upper_opcode_map
, 0, sizeof (upper_opcode_map
));
1882 memset (upper_icode_map
, 0, sizeof (upper_icode_map
));
1883 /* Scan the table backwards so macros appear at the front. */
1884 for (i
= txvu_upper_opcodes_count
- 1; i
>= 0; --i
)
1886 int opcode_hash
= TXVU_HASH_UPPER_OPCODE (txvu_upper_opcodes
[i
].mnemonic
);
1887 int icode_hash
= TXVU_HASH_UPPER_ICODE (txvu_upper_opcodes
[i
].value
);
1889 txvu_upper_opcodes
[i
].next_asm
= upper_opcode_map
[opcode_hash
];
1890 upper_opcode_map
[opcode_hash
] = &txvu_upper_opcodes
[i
];
1892 txvu_upper_opcodes
[i
].next_dis
= upper_icode_map
[icode_hash
];
1893 upper_icode_map
[icode_hash
] = &txvu_upper_opcodes
[i
];
1896 /* Lower VU table. */
1898 memset (lower_opcode_map
, 0, sizeof (lower_opcode_map
));
1899 memset (lower_icode_map
, 0, sizeof (lower_icode_map
));
1900 /* Scan the table backwards so macros appear at the front. */
1901 for (i
= txvu_lower_opcodes_count
- 1; i
>= 0; --i
)
1903 int opcode_hash
= TXVU_HASH_LOWER_OPCODE (txvu_lower_opcodes
[i
].mnemonic
);
1904 int icode_hash
= TXVU_HASH_LOWER_ICODE (txvu_lower_opcodes
[i
].value
);
1906 txvu_lower_opcodes
[i
].next_asm
= lower_opcode_map
[opcode_hash
];
1907 lower_opcode_map
[opcode_hash
] = &txvu_lower_opcodes
[i
];
1909 txvu_lower_opcodes
[i
].next_dis
= lower_icode_map
[icode_hash
];
1910 lower_icode_map
[icode_hash
] = &txvu_lower_opcodes
[i
];
1915 for (i
= pke_opcodes_count
- 2; i
>= 0; --i
)
1917 pke_opcodes
[i
].next_asm
= & pke_opcodes
[i
+1];
1918 pke_opcodes
[i
].next_dis
= & pke_opcodes
[i
+1];
1923 for (i
= dma_opcodes_count
- 2; i
>= 0; --i
)
1925 dma_opcodes
[i
].next_asm
= & dma_opcodes
[i
+1];
1926 dma_opcodes
[i
].next_dis
= & dma_opcodes
[i
+1];
1931 for (i
= gpuif_opcodes_count
- 2; i
>= 0; --i
)
1933 gpuif_opcodes
[i
].next_asm
= & gpuif_opcodes
[i
+1];
1934 gpuif_opcodes
[i
].next_dis
= & gpuif_opcodes
[i
+1];
1941 /* Return the first insn in the chain for assembling upper INSN. */
1943 const struct txvu_opcode
*
1944 txvu_upper_opcode_lookup_asm (insn
)
1947 return upper_opcode_map
[TXVU_HASH_UPPER_OPCODE (insn
)];
1950 /* Return the first insn in the chain for disassembling upper INSN. */
1952 const struct txvu_opcode
*
1953 txvu_upper_opcode_lookup_dis (insn
)
1956 return upper_icode_map
[TXVU_HASH_UPPER_ICODE (insn
)];
1959 /* Return the first insn in the chain for assembling lower INSN. */
1961 const struct txvu_opcode
*
1962 txvu_lower_opcode_lookup_asm (insn
)
1965 return lower_opcode_map
[TXVU_HASH_LOWER_OPCODE (insn
)];
1968 /* Return the first insn in the chain for disassembling lower INSN. */
1970 const struct txvu_opcode
*
1971 txvu_lower_opcode_lookup_dis (insn
)
1974 return lower_icode_map
[TXVU_HASH_LOWER_ICODE (insn
)];
1977 /* Return the first insn in the chain for assembling lower INSN. */
1979 const struct txvu_opcode
*
1980 pke_opcode_lookup_asm (insn
)
1983 return &pke_opcodes
[0];
1986 /* Return the first insn in the chain for disassembling lower INSN. */
1988 const struct txvu_opcode
*
1989 pke_opcode_lookup_dis (insn
)
1992 return &pke_opcodes
[0];
1995 /* Return the first insn in the chain for assembling lower INSN. */
1997 const struct txvu_opcode
*
1998 dma_opcode_lookup_asm (insn
)
2001 return &dma_opcodes
[0];
2004 /* Return the first insn in the chain for disassembling lower INSN. */
2006 const struct txvu_opcode
*
2007 dma_opcode_lookup_dis (insn
)
2010 return &dma_opcodes
[0];
2013 /* Return the first insn in the chain for assembling lower INSN. */
2015 const struct txvu_opcode
*
2016 gpuif_opcode_lookup_asm (insn
)
2019 return &gpuif_opcodes
[0];
2022 /* Return the first insn in the chain for disassembling lower INSN. */
2024 const struct txvu_opcode
*
2025 gpuif_opcode_lookup_dis (insn
)
2028 return &gpuif_opcodes
[0];