* Devices now get a issue() call.
[deliverable/binutils-gdb.git] / opcodes / txvu-opc.c
CommitLineData
54cc8ed4
DE
1/* Opcode table for the TXVU
2 Copyright 1998 Free Software Foundation, Inc.
3
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)
7 any later version.
8
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.
13
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. */
17
18#include "ansidecl.h"
19#include "dis-asm.h"
20#include "opcode/txvu.h"
21
22#ifndef NULL
23#define NULL 0
24#endif
25
26#if defined (__STDC__) || defined (ALMOST_STDC)
27#define XCONCAT2(a,b) a##b
28#else
29#define XCONCAT2(a,b) a/**/b
30#endif
31#define CONCAT2(a,b) XCONCAT2(a,b)
32
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. */
36
37#define PARSE_FN(fn) \
38static long CONCAT2 (parse_,fn) \
39 PARAMS ((char **, const char **));
40#define INSERT_FN(fn) \
41static TXVU_INSN CONCAT2 (insert_,fn) \
42 PARAMS ((TXVU_INSN, const struct txvu_operand *, \
43 int, long, const char **))
44#define EXTRACT_FN(fn) \
45static long CONCAT2 (extract_,fn) \
46 PARAMS ((TXVU_INSN, const struct txvu_operand *, \
47 int, int *))
48#define PRINT_FN(fn) \
49static void CONCAT2 (print_,fn) \
50 PARAMS ((disassemble_info *, TXVU_INSN, long));
51
52PARSE_FN (dotdest);
71af45ec
DE
53INSERT_FN (dotdest);
54EXTRACT_FN (dotdest);
54cc8ed4
DE
55PRINT_FN (dotdest);
56
8ea2f96f
DE
57PARSE_FN (dotsdest);
58
71af45ec
DE
59PARSE_FN (vfreg);
60PRINT_FN (vfreg);
54cc8ed4 61
3f897263
DE
62PARSE_FN (bc);
63PRINT_FN (bc);
64
0b988d39
DE
65PARSE_FN (bcftreg);
66PRINT_FN (bcftreg);
3f897263
DE
67
68PARSE_FN (accdest);
69PRINT_FN (accdest);
70
71PARSE_FN (xyz);
72
0b988d39
DE
73PARSE_FN (ireg);
74PRINT_FN (ireg);
75
76PARSE_FN (freg);
77PRINT_FN (freg);
78
79PARSE_FN (ffstreg);
80INSERT_FN (ffstreg);
81EXTRACT_FN (ffstreg);
82PRINT_FN (ffstreg);
83
84PARSE_FN (vi01);
85PRINT_FN (vi01);
86
87INSERT_FN (limm12);
88EXTRACT_FN (limm12);
89
8ea2f96f
DE
90INSERT_FN (luimm15);
91EXTRACT_FN (luimm15);
92
3f897263 93/* Various types of TXVU operands, including insn suffixes.
54cc8ed4
DE
94
95 Fields are:
96
97 BITS SHIFT FLAGS PARSE_FN INSERT_FN EXTRACT_FN PRINT_FN
98
99 Operand values are 128 + table index. This allows ASCII chars to be
100 included in the syntax spec. */
101
102const struct txvu_operand txvu_operands[] =
103{
3f897263 104 /* place holder (??? not sure if needed) */
54cc8ed4
DE
105#define UNUSED 128
106 { 0 },
107
8ea2f96f
DE
108 /* Operands that exist in the same place for essentially the same purpose
109 in both upper and lower instructions. */
0b988d39 110
8ea2f96f
DE
111 /* Destination indicator attached to mnemonic, with leading '.'.
112 After parsing this, the value is stored in global `dest' so that the
113 register parser can verify the same choice of xyzw is used. */
114#define DOTDEST (UNUSED + 1)
54cc8ed4 115 { 4, TXVU_SHIFT_DEST, TXVU_OPERAND_SUFFIX,
71af45ec 116 parse_dotdest, insert_dotdest, extract_dotdest, print_dotdest },
54cc8ed4 117
8ea2f96f
DE
118 /* ft reg, with vector specification same as DOTDEST */
119#define VFTREG (DOTDEST + 1)
120 { 5, TXVU_SHIFT_TREG, 0, parse_vfreg, 0, 0, print_vfreg },
54cc8ed4 121
8ea2f96f
DE
122 /* fs reg, with vector specification same as DOTDEST */
123#define VFSREG (VFTREG + 1)
124 { 5, TXVU_SHIFT_SREG, 0, parse_vfreg, 0, 0, print_vfreg },
54cc8ed4 125
8ea2f96f
DE
126 /* fd reg, with vector specification same as DOTDEST */
127#define VFDREG (VFSREG + 1)
128 { 5, TXVU_SHIFT_DREG, 0, parse_vfreg, 0, 0, print_vfreg },
129
130 /* Upper word operands. */
54cc8ed4 131
3f897263 132 /* broadcast */
8ea2f96f 133#define UBC (VFDREG + 1)
3f897263
DE
134 { 2, 0, 0, parse_bc, 0, 0, print_bc },
135
136 /* ftreg in broadcast case */
0b988d39 137#define UBCFTREG (UBC + 1)
8ea2f96f 138 { 5, TXVU_SHIFT_TREG, 0, parse_bcftreg, 0, 0, print_bcftreg },
3f897263
DE
139
140 /* accumulator dest */
0b988d39 141#define UACCDEST (UBCFTREG + 1)
3f897263
DE
142 { 0, 0, TXVU_OPERAND_FAKE, parse_accdest, 0, 0, print_accdest },
143
144 /* The XYZ operand is a fake one that is used to ensure only "xyz" is
145 specified. It simplifies the opmula and opmsub entries. */
0b988d39 146#define UXYZ (UACCDEST + 1)
3f897263
DE
147 { 0, 0, TXVU_OPERAND_FAKE, parse_xyz, 0, 0, 0 },
148
0b988d39
DE
149 /* Lower word operands. */
150
151 /* 11 bit immediate. */
8ea2f96f
DE
152#define LIMM5 (UXYZ + 1)
153 { 5, 6, 0, 0, 0, 0, 0 },
154
155 /* 11 bit immediate. */
156#define LIMM11 (LIMM5 + 1)
0b988d39
DE
157 { 11, 0, 0, 0, 0, 0, 0 },
158
8ea2f96f
DE
159 /* 15 bit unsigned immediate. */
160#define LUIMM15 (LIMM11 + 1)
161 { 15, 0, TXVU_OPERAND_UNSIGNED, 0, insert_luimm15, extract_luimm15, 0 },
162
163 /* ID register. */
164#define LIDREG (LUIMM15 + 1)
165 { 5, 6, 0, parse_ireg, 0, 0, print_ireg },
166
0b988d39 167 /* IS register. */
8ea2f96f 168#define LISREG (LIDREG + 1)
0b988d39
DE
169 { 5, 11, 0, parse_ireg, 0, 0, print_ireg },
170
171 /* IT register. */
172#define LITREG (LISREG + 1)
173 { 5, 16, 0, parse_ireg, 0, 0, print_ireg },
174
175 /* FS reg, with FSF field selector. */
176#define LFSFFSREG (LITREG + 1)
177 { 5, 11, 0, parse_ffstreg, insert_ffstreg, extract_ffstreg, print_ffstreg },
178
179 /* FS reg, no selector (choice of x,y,z,w is provided by opcode). */
180#define LFSREG (LFSFFSREG + 1)
181 { 5, 11, 0, parse_freg, 0, 0, print_freg },
182
183 /* FT reg, with FTF field selector. */
184#define LFTFFTREG (LFSREG + 1)
185 { 5, 16, 0, parse_ffstreg, insert_ffstreg, extract_ffstreg, print_ffstreg },
186
187 /* VI01 register. */
188#define LVI01 (LFTFFTREG + 1)
189 { 0, 0, TXVU_OPERAND_FAKE, parse_vi01, 0, 0, print_vi01 },
190
191 /* 24 bit immediate. */
192#define LIMM24 (LVI01 + 1)
193 { 24, 0, 0, 0, 0, 0, 0 },
194
195 /* 12 bit immediate, split into 1 and 11 bit pieces. */
196#define LIMM12 (LIMM24 + 1)
197 { 12, 0, 0, 0, insert_limm12, extract_limm12, 0 },
198
8ea2f96f
DE
199 /* 11 bit pc-releative immediate. */
200#define LPCREL11 (LIMM12 + 1)
201 { 11, 0, TXVU_OPERAND_RELATIVE_BRANCH, 0, 0, 0, 0 },
202
203 /* Destination indicator, with leading '.'. */
204#define LDOTSDEST (DOTDEST + 1)
205 { 4, TXVU_SHIFT_DEST, TXVU_OPERAND_SUFFIX,
206 /* Note that we borrow the insert/extract/print functions from the
207 vector case. */
208 parse_dotsdest, insert_dotdest, extract_dotdest, print_dotdest },
209
54cc8ed4
DE
210/* end of list place holder */
211 { 0 }
212};
213\f
214/* Macros to put a field's value into the right place. */
3f897263
DE
215/* FIXME: If assembler needs these, move to opcode/txvu.h. */
216
0b988d39
DE
217/* value X, B bits, shift S */
218#define R(x,b,s) (((x) & ((1 << (b)) - 1)) << (s))
219
8ea2f96f
DE
220/* Field value macros for both upper and lower instructions.
221 These shift a value into the right place in the instruction. */
222
223/* [FI] T reg field (remember it's V for value, not vector, here). */
224#define VT(x) R ((x), 5, TXVU_SHIFT_TREG)
225/* [FI] S reg field. */
226#define VS(x) R ((x), 5, TXVU_SHIFT_SREG)
227/* [FI] D reg field. */
228#define VD(x) R ((x), 5, TXVU_SHIFT_DREG)
229/* DEST field. */
230#define VDEST(x) R ((x), 4, 21)
231
232/* Masks for fields in both upper and lower instructions.
233 These mask out all bits but the ones for the field in the instruction. */
234
235#define MT VT (~0)
236#define MS VS (~0)
237#define MD VD (~0)
238#define MDEST VDEST (~0)
239
0b988d39 240/* Upper instruction Value macros. */
54cc8ed4 241
3f897263 242/* Upper Flag bits. */
0b988d39 243#define VUF(x) R ((x), 5, 27)
3f897263 244/* Upper REServed two bits next to flag bits. */
0b988d39 245#define VURES(x) R ((x), 2, 25)
0b988d39
DE
246/* 4 bit opcode field. */
247#define VUOP4(x) R ((x), 4, 2)
248/* 6 bit opcode field. */
249#define VUOP6(x) R ((x), 6, 0)
250/* 9 bit opcode field. */
251#define VUOP9(x) R ((x), 9, 2)
252/* 11 bit opcode field. */
253#define VUOP11(x) R ((x), 11, 0)
254/* BroadCast field. */
255#define VUBC(x) R ((x), 2, 0)
256
8ea2f96f 257/* Upper instruction field masks. */
0b988d39
DE
258#define MUUBITS (VUF (~0) + VURES (~0))
259#define MURES VURES (~0)
260#define MUOP4 VUOP4 (~0)
261#define MUOP6 VUOP6 (~0)
262#define MUOP9 VUOP9 (~0)
263#define MUOP11 VUOP11 (~0)
264
3f897263
DE
265/* A space, separates instruction name (mnemonic + mnemonic operands) from operands. */
266#define SP ' '
267
54cc8ed4
DE
268/* TXVU instructions.
269 [??? some of these comments are left over from the ARC port from which
270 this code is borrowed, delete in time]
271
272 Longer versions of insns must appear before shorter ones (if gas sees
273 "lsr r2,r3,1" when it's parsing "lsr %a,%b" it will think the ",1" is
274 junk). This isn't necessary for `ld' because of the trailing ']'.
275
276 Instructions that are really macros based on other insns must appear
277 before the real insn so they're chosen when disassembling. Eg: The `mov'
278 insn is really the `and' insn.
279
280 This table is best viewed on a wide screen (161 columns). I'd prefer to
281 keep it this way. The rest of the file, however, should be viewable on an
282 80 column terminal. */
283
284/* ??? This table also includes macros: asl, lsl, and mov. The ppc port has
285 a more general facility for dealing with macros which could be used if
286 we need to. */
287
288/* These tables can't be `const' because members `next_asm' and `next_dis' are
289 computed at run-time. We could split this into two, as that would put the
290 constant stuff into a readonly section. */
291
292struct txvu_opcode txvu_upper_opcodes[] = {
293
294 /* Macros appear first. */
295 /* ??? Any aliases? */
0b988d39 296 /* FIXME: When close to being finished, clean up by aligning fields. */
54cc8ed4 297
3f897263 298 /* The rest of these needn't be sorted, but it helps to find them if they are. */
8ea2f96f
DE
299 { "abs", { DOTDEST, SP, VFTREG, VFSREG }, MURES + MUOP11, VUOP11 (0x1fd) },
300 { "add", { DOTDEST, SP, VFDREG, VFSREG, VFTREG }, MURES + MUOP6, VUOP6 (0x28) },
301 { "addi", { DOTDEST, SP, VFDREG, VFSREG, 'i' }, MURES + MT + MUOP6, VUOP6 (0x22) },
302 { "addq", { DOTDEST, SP, VFDREG, VFSREG, 'q' }, MURES + MT + MUOP6, VUOP6 (0x20) },
303 { "add", { UBC, DOTDEST, SP, VFDREG, VFSREG, UBCFTREG }, MURES + VUOP4 (~0), VUOP4 (0) },
304 { "adda", { DOTDEST, SP, UACCDEST, VFSREG, VFTREG }, MURES + MUOP11, VUOP11 (0x2bc) },
305 { "addai", { DOTDEST, SP, UACCDEST, VFSREG, 'i' }, MURES + MT + MUOP11, VUOP11 (0x23e) },
306 { "addaq", { DOTDEST, SP, UACCDEST, VFSREG, 'q' }, MURES + MT + MUOP11, VUOP11 (0x23c) },
307 { "adda", { UBC, DOTDEST, SP, UACCDEST, VFSREG, UBCFTREG }, MURES + MUOP9, VUOP9 (0xf) },
308 { "clip", { DOTDEST, SP, VFSREG }, MURES + MDEST + MT + MUOP11, VDEST (0xf) + VUOP11 (0x1ff) },
309 { "ftoi0", { DOTDEST, SP, VFTREG, VFSREG }, MURES + MUOP11, VUOP11 (0x17c) },
310 { "ftoi4", { DOTDEST, SP, VFTREG, VFSREG }, MURES + MUOP11, VUOP11 (0x17d) },
311 { "ftoi12", { DOTDEST, SP, VFTREG, VFSREG }, MURES + MUOP11, VUOP11 (0x17e) },
312 { "ftoi15", { DOTDEST, SP, VFTREG, VFSREG }, MURES + MUOP11, VUOP11 (0x17f) },
313 { "itof0", { DOTDEST, SP, VFTREG, VFSREG }, MURES + MUOP11, VUOP11 (0x13c) },
314 { "itof4", { DOTDEST, SP, VFTREG, VFSREG }, MURES + MUOP11, VUOP11 (0x13d) },
315 { "itof12", { DOTDEST, SP, VFTREG, VFSREG }, MURES + MUOP11, VUOP11 (0x13e) },
316 { "itof15", { DOTDEST, SP, VFTREG, VFSREG }, MURES + MUOP11, VUOP11 (0x13f) },
317 { "madd", { DOTDEST, SP, VFDREG, VFSREG, VFTREG }, MURES + MUOP6, VUOP6 (0x29) },
318 { "maddi", { DOTDEST, SP, VFDREG, VFSREG, 'i' }, MURES + MT + MUOP6, VUOP6 (0x23) },
319 { "maddq", { DOTDEST, SP, VFDREG, VFSREG, 'q' }, MURES + MT + MUOP6, VUOP6 (0x21) },
320 { "madd", { UBC, DOTDEST, SP, VFDREG, VFSREG, UBCFTREG }, MURES + MUOP4, VUOP4 (0x2) },
321 { "madda", { DOTDEST, SP, UACCDEST, VFSREG, VFTREG }, MURES + MUOP11, VUOP11 (0x2bd) },
322 { "maddai", { DOTDEST, SP, UACCDEST, VFSREG, 'i' }, MURES + MT + MUOP11, VUOP11 (0x23f) },
323 { "maddaq", { DOTDEST, SP, UACCDEST, VFSREG, 'q' }, MURES + MT + MUOP11, VUOP11 (0x23d) },
324 { "madda", { UBC, DOTDEST, SP, UACCDEST, VFSREG, UBCFTREG }, MURES + MUOP9, VUOP9 (0x2f) },
325 { "max", { DOTDEST, SP, VFDREG, VFSREG, VFTREG }, MURES + MUOP6, VUOP6 (0x2b) },
326 { "maxi", { DOTDEST, SP, VFDREG, VFSREG, 'i' }, MURES + MT + MUOP6, VUOP6 (0x2d) },
327 { "max", { UBC, DOTDEST, SP, VFDREG, VFSREG, UBCFTREG }, MURES + MUOP4, VUOP4 (0x4) },
3f897263 328 /* FIXME: mini or min? */
8ea2f96f
DE
329 { "mini", { DOTDEST, SP, VFDREG, VFSREG, VFTREG }, MURES + MUOP6, VUOP6 (0x2f) },
330 { "mini", { DOTDEST, SP, VFDREG, VFSREG, 'i' }, MURES + MT + MUOP6, VUOP6 (0x1f) },
331 { "mini", { UBC, DOTDEST, SP, VFDREG, VFSREG, UBCFTREG }, MURES + MUOP4, VUOP4 (0x5) },
332 { "msub", { DOTDEST, SP, VFDREG, VFSREG, VFTREG }, MURES + MUOP6, VUOP6 (0x2d) },
333 { "msubi", { DOTDEST, SP, VFDREG, VFSREG, 'i' }, MURES + MT + MUOP6, VUOP6 (0x27) },
334 { "msubq", { DOTDEST, SP, VFDREG, VFSREG, 'q' }, MURES + MT + MUOP6, VUOP6 (0x25) },
335 { "msub", { UBC, DOTDEST, SP, VFDREG, VFSREG, UBCFTREG }, MURES + MUOP4, VUOP4 (0x3) },
336 { "msuba", { DOTDEST, SP, UACCDEST, VFSREG, VFTREG }, MURES + MUOP11, VUOP11 (0x2fd) },
337 { "msubai", { DOTDEST, SP, UACCDEST, VFSREG, 'i' }, MURES + MT + MUOP11, VUOP11 (0x27f) },
338 { "msubaq", { DOTDEST, SP, UACCDEST, VFSREG, 'q' }, MURES + MT + MUOP11, VUOP11 (0x27d) },
339 { "msuba", { UBC, DOTDEST, SP, UACCDEST, VFSREG, UBCFTREG }, MURES + MUOP9, VUOP9 (0x3f) },
340 { "mul", { DOTDEST, SP, VFDREG, VFSREG, VFTREG }, MURES + MUOP6, VUOP6 (0x2a) },
341 { "muli", { DOTDEST, SP, VFDREG, VFSREG, 'i' }, MURES + MT + MUOP6, VUOP6 (0x1e) },
342 { "mulq", { DOTDEST, SP, VFDREG, VFSREG, 'q' }, MURES + MT + MUOP6, VUOP6 (0x1c) },
343 { "mul", { UBC, DOTDEST, SP, VFDREG, VFSREG, UBCFTREG }, MURES + VUOP4 (~0), VUOP4 (6) },
344 { "mula", { DOTDEST, SP, UACCDEST, VFSREG, VFTREG }, MURES + MUOP11, VUOP11 (0x2be) },
345 { "mulai", { DOTDEST, SP, UACCDEST, VFSREG, 'i' }, MURES + MT + MUOP11, VUOP11 (0x1fe) },
346 { "mulaq", { DOTDEST, SP, UACCDEST, VFSREG, 'q' }, MURES + MT + MUOP11, VUOP11 (0x1fc) },
347 { "mula", { UBC, DOTDEST, SP, UACCDEST, VFSREG, UBCFTREG }, MURES + MUOP9, VUOP9 (0x6f) },
348 { "nop", { 0 }, MURES + MDEST + MT + MS + MUOP11, VUOP11 (0x2ff) },
349 { "opmula", { DOTDEST, SP, UACCDEST, VFSREG, VFTREG, UXYZ }, MURES + MUOP11, VUOP11 (0x2fe) },
350 { "opmsub", { DOTDEST, SP, VFDREG, VFSREG, VFTREG, UXYZ }, MURES + MUOP6, VUOP6 (0x2e) },
351 { "sub", { DOTDEST, SP, VFDREG, VFSREG, VFTREG }, MURES + MUOP6, VUOP6 (0x2c) },
352 { "subi", { DOTDEST, SP, VFDREG, VFSREG, 'i' }, MURES + MT + MUOP6, VUOP6 (0x26) },
353 { "subq", { DOTDEST, SP, VFDREG, VFSREG, 'q' }, MURES + MT + MUOP6, VUOP6 (0x24) },
354 { "sub", { UBC, DOTDEST, SP, VFDREG, VFSREG, UBCFTREG }, MURES + VUOP4 (~0), VUOP4 (1) },
355 { "suba", { DOTDEST, SP, UACCDEST, VFSREG, VFTREG }, MURES + MUOP11, VUOP11 (0x2fc) },
356 { "subai", { DOTDEST, SP, UACCDEST, VFSREG, 'i' }, MURES + MT + MUOP11, VUOP11 (0x27e) },
357 { "subaq", { DOTDEST, SP, UACCDEST, VFSREG, 'q' }, MURES + MT + MUOP11, VUOP11 (0x27c) },
358 { "suba", { UBC, DOTDEST, SP, UACCDEST, VFSREG, UBCFTREG }, MURES + MUOP9, VUOP9 (0x1f) }
54cc8ed4
DE
359};
360const int txvu_upper_opcodes_count = sizeof (txvu_upper_opcodes) / sizeof (txvu_opcodes[0]);
8ea2f96f
DE
361\f
362/* Lower instruction Value macros. */
363
364/* 6 bit opcode. */
365#define VLOP6(x) R ((x), 6, 0)
366/* 7 bit opcode. */
367#define VLOP7(x) R ((x), 7, 25)
368/* 11 bit opcode. */
369#define VLOP11(x) R ((x), 11, 0)
370/* 11 bit immediate. */
371#define VLIMM11(x) R ((x), 11, 0)
372/* FTF field. */
373#define VLFTF(x) R ((x), 2, 23)
374/* FSF field. */
375#define VLFSF(x) R ((x), 2, 21)
376
377/* Lower instruction field masks. */
378#define MLOP6 VLOP6 (~0)
379#define MLOP7 VLOP7 (~0)
380#define MLOP11 VLOP11 (~0)
381#define MLIMM11 VLIMM11 (~0)
382#define MLB24 R (1, 1, 24)
383/* 12 bit immediates are split into two parts, 1 bit and 11 bits.
384 The upper 1 bit is part of the `dest' field. This mask is for the
385 other 3 bits of the dest field. */
386#define MLIMM12TOP R (7, 3, 22)
54cc8ed4
DE
387
388struct txvu_opcode txvu_lower_opcodes[] = {
389
390 /* Macros appear first. */
391 /* ??? Any aliases? */
392
0b988d39 393 /* The rest of these needn't be sorted, but it helps to find them if they are. */
8ea2f96f
DE
394 { "b", { SP, LPCREL11 }, MLOP7 + MDEST + MT + MS, VLOP7 (0x20) },
395 { "bal", { SP, LITREG, LPCREL11 }, MLOP7 + MDEST + MS, VLOP7 (0x21) },
396 { "div", { SP, 'q', LFSFFSREG, LFTFFTREG }, MLOP7 + MLOP11, VLOP7 (0x40) + VLOP11 (0x3bc) },
397 { "eatan", { SP, 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + MT + MLOP11, VLOP7 (0x40) + VLOP11 (0x7fd) },
398 { "eatanxy", { SP, 'p', LFSREG }, MLOP7 + MDEST + MT + MLOP11, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x77c) },
399 { "eatanxz", { SP, 'p', LFSREG }, MLOP7 + MDEST + MT + MLOP11, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x77d) },
400 { "eexp", { SP, 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + MT + MLOP11, VLOP7 (0x40) + VLOP11 (0x7fe) },
401 { "eleng", { SP, 'p', LFSREG }, MLOP7 + MDEST + MT + MLOP11, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x74e) },
402 { "ercpr", { SP, 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + MT + MLOP11, VLOP7 (0x40) + VLOP11 (0x7be) },
403 { "erleng", { SP, 'p', LFSREG }, MLOP7 + MDEST + MT + MLOP11, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x73f) },
404 { "ersadd", { SP, 'p', LFSREG }, MLOP7 + MDEST + MT + MLOP11, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x73d) },
405 { "ersqrt", { SP, 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + MT + MLOP11, VLOP7 (0x40) + VLOP11 (0x7bd) },
406 { "esadd", { SP, 'p', LFSREG }, MLOP7 + MDEST + MT + MLOP11, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x73c) },
407 { "esin", { SP, 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + MT + MLOP11, VLOP7 (0x40) + VLOP11 (0x7fc) },
408 { "esqrt", { SP, 'p', LFSFFSREG }, MLOP7 + VLFTF (~0) + MT + MLOP11, VLOP7 (0x40) + VLOP11 (0x7bc) },
409 { "esum", { SP, 'p', LFSREG }, MLOP7 + MDEST + MT + MLOP11, VLOP7 (0x40) + VDEST (0xf) + VLOP11 (0x77e) },
410 { "fcand", { SP, LVI01, LIMM24 }, MLOP7 + MLB24, VLOP7 (0x12) },
411 { "fceq", { SP, LVI01, LIMM24 }, MLOP7 + MLB24, VLOP7 (0x10) },
412 { "fcget", { SP, LITREG }, MLOP7 + MDEST + MS + MLIMM11, VLOP7 (0x1c) },
413 { "fcor", { SP, LVI01, LIMM24 }, MLOP7 + MLB24, VLOP7 (0x13) },
414 { "fcset", { SP, LVI01, LIMM24 }, MLOP7 + MLB24, VLOP7 (0x11) },
415 { "fmand", { SP, LITREG, LISREG }, MLOP7 + MDEST + MLIMM11, VLOP7 (0x1a) },
416 { "fmeq", { SP, LITREG, LISREG }, MLOP7 + MDEST + MLIMM11, VLOP7 (0x18) },
417 { "fmor", { SP, LITREG, LISREG }, MLOP7 + MDEST + MLIMM11, VLOP7 (0x1b) },
418 { "fsand", { SP, LITREG, LIMM12 }, MLOP7 + MLIMM12TOP + MS, VLOP7 (0x16) },
419 { "fseq", { SP, LITREG, LIMM12 }, MLOP7 + MLIMM12TOP + MS, VLOP7 (0x14) },
420 { "fsor", { SP, LITREG, LIMM12 }, MLOP7 + MLIMM12TOP + MS, VLOP7 (0x17) },
421 { "fsset", { SP, LITREG, LIMM12 }, MLOP7 + MLIMM12TOP + MS, VLOP7 (0x15) },
422 { "iadd", { SP, LIDREG, LISREG, LITREG }, MLOP7 + MDEST + MLOP6, VLOP7 (0x40) + VLOP6 (0x30) },
423 { "iaddi", { SP, LITREG, LISREG, LIMM5 }, MLOP7 + MDEST + MLOP6, VLOP7 (0x40) + VLOP6 (0x32) },
424 { "iaddiu", { SP, LITREG, LISREG, LUIMM15 }, MLOP7, VLOP7 (0x08) },
425 { "iand", { SP, LIDREG, LISREG, LITREG }, MLOP7 + MDEST + MLOP6, VLOP7 (0x40) + VLOP6 (0x34) },
426 { "ibeq", { SP, LITREG, LISREG, LPCREL11 }, MLOP7 + MDEST, VLOP7 (0x28) },
427 { "ibgez", { SP, LISREG, LPCREL11 }, MLOP7 + MDEST + MT, VLOP7 (0x2f) },
428 { "iblez", { SP, LISREG, LPCREL11 }, MLOP7 + MDEST + MT, VLOP7 (0x2e) },
429 { "ibltz", { SP, LISREG, LPCREL11 }, MLOP7 + MDEST + MT, VLOP7 (0x2c) },
430 { "ibne", { SP, LITREG, LISREG, LPCREL11 }, MLOP7 + MDEST, VLOP7 (0x29) },
431 /* FIXME: Need to not require commas around parens. */
432 { "ilw", { LDOTSDEST, SP, LITREG, LIMM11, '(', LISREG, ')' }, MLOP7, VLOP7 (0x04) },
433 { "ilwr", { LDOTSDEST, SP, LITREG, '(', LISREG, ')' }, MLOP7, VLOP7 (0x40) + VLIMM11 (0x3fe) },
434 { "ior", { SP, LIDREG, LISREG, LITREG }, MLOP7 + MDEST + MLOP6, VLOP7 (0x40) + VLOP6 (0x34) },
435 { "isub", { SP, LIDREG, LISREG, LITREG }, MLOP7 + MDEST + MLOP6, VLOP7 (0x40) + VLOP6 (0x31) },
436 { "isubiu", { SP, LITREG, LISREG, LUIMM15 }, MLOP7, VLOP7 (0x09) },
437 { "isw", { LDOTSDEST, SP, LITREG, LIMM11, '(', LISREG, ')' }, MLOP7, VLOP7 (0x05) },
438 { "iswr", { LDOTSDEST, SP, LITREG, '(', LISREG, ')' }, MLOP7, VLOP7 (0x40) + VLIMM11 (0x3ff) },
439 { "jalr", { SP, LITREG, LISREG }, MLOP7 + MDEST + MLIMM11, VLOP7 (0x25) },
440 { "jr", { SP, LISREG }, MLOP7 + MDEST + MT + MLIMM11, VLOP7 (0x24) },
441 { "lq", { DOTDEST, SP, VFTREG, LIMM11, '(', LISREG, ')' }, MLOP7, VLOP7 (0x00) },
442 /* FIXME: No commas around -/+. */
443 { "lqd", { DOTDEST, SP, VFTREG, LIMM11, '(', '-', '-', LISREG, ')' }, MLOP7, VLOP7 (0x40) + VLIMM11 (0x37e) },
444 { "lqi", { DOTDEST, SP, VFTREG, LIMM11, '(', LISREG, '+', '+', ')' }, MLOP7, VLOP7 (0x40) + VLIMM11 (0x37c) },
445 /* Only a single VF reg is allowed here. We can use VFTREG because LDOTSDEST
446 handles verifying only a single choice of xyzw is present. */
447 { "mfir", { LDOTSDEST, SP, VFTREG, LISREG }, MLOP7 + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x3fc) },
448 { "mfp", { DOTDEST, SP, VFTREG, 'p' }, MLOP7 + MS + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x67c) },
449 { "move", { DOTDEST, SP, VFTREG, VFSREG }, MLOP7 + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x33c) },
450 { "mr32", { DOTDEST, SP, VFTREG, VFSREG }, MLOP7 + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x33d) },
451 { "mtir", { LDOTSDEST, SP, LITREG, LFSREG }, MLOP7 + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x3fd) },
452 { "rget", { DOTDEST, SP, VFTREG, 'r' }, MLOP7 + MS + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x43d) },
453 { "rinit", { SP, 'r', LFSFFSREG }, MLOP7 + VLFTF (~0) + MT + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x43e) },
454 { "rnext", { DOTDEST, SP, VFTREG, 'r' }, MLOP7 + MS + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x43c) },
455 { "rsqrt", { SP, 'q', LFSFFSREG, LFTFFTREG }, MLOP7 + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x3be) },
456 { "rxor", { 'r', LFSFFSREG }, MLOP7 + VLFTF (~0) + MT + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x43f) },
457 { "sq", { DOTDEST, SP, VFTREG, LIMM11, '(', LISREG, ')' }, MLOP7, VLOP7 (0x01) },
458 /* FIXME: No commas around -/+. */
459 { "sqd", { DOTDEST, SP, VFTREG, LIMM11, '(', '-', '-', LISREG, ')' }, MLOP7, VLOP7 (0x40) + VLIMM11 (0x37f) },
460 { "sqi", { DOTDEST, SP, VFTREG, LIMM11, '(', LISREG, '+', '+', ')' }, MLOP7, VLOP7 (0x40) + VLIMM11 (0x37d) },
461 { "sqrt", { SP, 'q', LFTFFTREG }, MLOP7 + VLFSF (~0) + MS + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x3bd) },
462 { "waitp", { 0 }, 0xffffffff, VLOP7 (0x40) + VLIMM11 (0x7bf) },
463 { "waitq", { 0 }, 0xffffffff, VLOP7 (0x40) + VLIMM11 (0x3bf) },
464 { "xgkick", { LISREG }, MLOP7 + MDEST + MT + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x6fc) },
465 { "xitop", { LITREG }, MLOP7 + MDEST + MS + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x6bd) },
466 { "xtop", { LITREG }, MLOP7 + MDEST + MS + MLIMM11, VLOP7 (0x40) + VLIMM11 (0x6bc) }
54cc8ed4
DE
467};
468const int txvu_lower_opcodes_count = sizeof (txvu_lower_opcodes) / sizeof (txvu_opcodes[0]);
8ea2f96f 469\f
54cc8ed4
DE
470/* Indexed by first letter of opcode. Points to chain of opcodes with same
471 first letter. */
472/* ??? One can certainly use a better hash. Later. */
473static struct txvu_opcode *upper_opcode_map[26 + 1];
474static struct txvu_opcode *lower_opcode_map[26 + 1];
475
476/* Indexed by insn code. Points to chain of opcodes with same insn code. */
477static struct txvu_opcode *upper_icode_map[64];
478static struct txvu_opcode *lower_icode_map[64];
479\f
480/* Initialize any tables that need it.
481 Must be called once at start up (or when first needed).
482
483 FLAGS is currently unused but is intended to control initialization. */
484
485void
486txvu_opcode_init_tables (flags)
487 int flags;
488{
489 static int init_p = 0;
490
491 /* We may be intentionally called more than once (for example gdb will call
492 us each time the user switches cpu). These tables only need to be init'd
493 once though. */
494 /* ??? We can remove the need for txvu_opcode_supported by taking it into
495 account here, but I'm not sure I want to do that yet (if ever). */
496 if (!init_p)
497 {
498 int i,n;
499
500 memset (upper_opcode_map, 0, sizeof (upper_opcode_map));
501 memset (upper_icode_map, 0, sizeof (upper_icode_map));
502
503 /* Scan the table backwards so macros appear at the front. */
504 for (i = txvu_upper_opcodes_count - 1; i >= 0; --i)
505 {
506 int opcode_hash = TXVU_HASH_UPPER_OPCODE (txvu_upper_opcodes[i].mnemonic);
507 int icode_hash = TXVU_HASH_UPPER_ICODE (txvu_upper_opcodes[i].value);
508
509 txvu_upper_opcodes[i].next_asm = upper_opcode_map[opcode_hash];
510 upper_opcode_map[opcode_hash] = &txvu_upper_opcodes[i];
511
512 txvu_upper_opcodes[i].next_dis = upper_icode_map[icode_hash];
513 upper_icode_map[icode_hash] = &txvu_upper_opcodes[i];
514 }
515
516 memset (lower_opcode_map, 0, sizeof (lower_opcode_map));
517 memset (lower_icode_map, 0, sizeof (lower_icode_map));
518
519 /* Scan the table backwards so macros appear at the front. */
520 for (i = txvu_lower_opcodes_count - 1; i >= 0; --i)
521 {
522 int opcode_hash = TXVU_HASH_LOWER_OPCODE (txvu_lower_opcodes[i].mnemonic);
523 int icode_hash = TXVU_HASH_LOWER_ICODE (txvu_lower_opcodes[i].value);
524
525 txvu_lower_opcodes[i].next_asm = lower_opcode_map[opcode_hash];
526 lower_opcode_map[opcode_hash] = &txvu_lower_opcodes[i];
527
528 txvu_lower_opcodes[i].next_dis = lower_icode_map[icode_hash];
529 lower_icode_map[icode_hash] = &txvu_lower_opcodes[i];
530 }
531
532 init_p = 1;
533 }
534}
535
536/* Return the first insn in the chain for assembling upper INSN. */
537
538const struct txvu_opcode *
539txvu_upper_opcode_lookup_asm (insn)
540 const char *insn;
541{
542 return upper_opcode_map[TXVU_HASH_UPPER_OPCODE (insn)];
543}
544
545/* Return the first insn in the chain for assembling lower INSN. */
546
547const struct txvu_opcode *
548txvu_lower_opcode_lookup_asm (insn)
549 const char *insn;
550{
551 return lower_opcode_map[TXVU_HASH_LOWER_OPCODE (insn)];
552}
553
554/* Return the first insn in the chain for disassembling upper INSN. */
555
556const struct txvu_opcode *
557txvu_upper_opcode_lookup_dis (insn)
558 TXVU_INSN insn;
559{
560 return upper_icode_map[TXVU_HASH_UPPER_ICODE (insn)];
561}
562
563/* Return the first insn in the chain for disassembling lower INSN. */
564
565const struct txvu_opcode *
566txvu_lower_opcode_lookup_dis (insn)
567 TXVU_INSN insn;
568{
569 return lower_icode_map[TXVU_HASH_LOWER_ICODE (insn)];
570}
571\f
572/* Value of DEST in use.
71af45ec 573 Each of the registers must specify the same value as the opcode.
54cc8ed4
DE
574 ??? Perhaps remove the duplication? */
575static int dest;
3f897263
DE
576
577/* Value of BC to use.
578 The register specified for the ftreg must match the broadcast register
579 specified in the opcode. */
580static int bc;
54cc8ed4
DE
581\f
582/* Init fns.
583 These are called before doing each of the respective activities. */
584
585/* Called by the assembler before parsing an instruction. */
586
587void
588txvu_opcode_init_parse ()
589{
590 dest = -1;
3f897263 591 bc = -1;
54cc8ed4
DE
592}
593
594/* Called by the disassembler before printing an instruction. */
595
596void
597txvu_opcode_init_print ()
598{
599 dest = -1;
3f897263 600 bc = -1;
54cc8ed4
DE
601}
602\f
8ea2f96f 603/* Multiple destination choice support.
54cc8ed4
DE
604 The "dest" string selects any combination of x,y,z,w.
605 [The letters are ordered that way to follow the manual's style.] */
606
71af45ec
DE
607/* Parse a `dest' spec.
608 Return the found value.
609 *PSTR is set to the character that terminated the parsing.
610 It is up to the caller to do any error checking. */
611
54cc8ed4 612static long
71af45ec 613parse_dest (pstr)
54cc8ed4 614 char **pstr;
54cc8ed4
DE
615{
616 long dest = 0;
617
54cc8ed4
DE
618 while (**pstr)
619 {
620 switch (**pstr)
621 {
622 case 'x' : case 'X' : dest |= TXVU_DEST_X; break;
623 case 'y' : case 'Y' : dest |= TXVU_DEST_Y; break;
624 case 'z' : case 'Z' : dest |= TXVU_DEST_Z; break;
625 case 'w' : case 'W' : dest |= TXVU_DEST_W; break;
71af45ec 626 default : return dest;
54cc8ed4
DE
627 }
628 ++*pstr;
629 }
630
71af45ec
DE
631 return dest;
632}
633
634static long
635parse_dotdest (pstr, errmsg)
636 char **pstr;
637 const char **errmsg;
638{
639 long dest;
640
641 if (**pstr != '.')
642 {
643 *errmsg = "missing `.'";
644 return 0;
645 }
646
647 ++*pstr;
648 dest = parse_dest (pstr);
649 if (dest == 0 || isalnum (**pstr))
650 {
651 *errmsg = "invalid `dest'";
652 return 0;
653 }
54cc8ed4
DE
654 *errmsg = NULL;
655 return dest;
656}
657
8ea2f96f
DE
658/* Parse a `dest' spec where only a single letter is allowed. */
659
660static long
661parse_dotsdest (pstr, errmsg)
662 char **pstr;
663 const char **errmsg;
664{
665 long dest;
666
667 if (**pstr != '.')
668 {
669 *errmsg = "missing `.'";
670 return 0;
671 }
672
673 ++*pstr;
674 switch (**pstr)
675 {
676 case 'x' : case 'X' : dest = TXVU_BC_X; break;
677 case 'y' : case 'Y' : dest = TXVU_BC_Y; break;
678 case 'z' : case 'Z' : dest = TXVU_BC_Z; break;
679 case 'w' : case 'W' : dest = TXVU_BC_W; break;
680 default : *errmsg = "invalid `dest'"; return 0;
681 }
682 *errmsg = NULL;
683 return dest;
684}
685
71af45ec
DE
686static TXVU_INSN
687insert_dotdest (insn, operand, mods, value, errmsg)
688 TXVU_INSN insn;
689 const struct txvu_operand *operand;
690 int mods;
691 long value;
692 const char **errmsg;
693{
694 /* Record the DEST value in use so the register parser can use it. */
695 dest = value;
696 if (errmsg)
697 *errmsg = NULL;
698 return insn |= value << operand->shift;
699}
700
701static long
702extract_dotdest (insn, operand, mods, pinvalid)
703 TXVU_INSN insn;
704 const struct txvu_operand *operand;
705 int mods;
706 int *pinvalid;
707{
708 /* Record the DEST value in use so the register printer can use it. */
709 dest = (insn >> operand->shift) & ((1 << operand->bits) - 1);
710 return dest;
711}
712
54cc8ed4 713static void
71af45ec 714print_dest (info, insn, value)
54cc8ed4
DE
715 disassemble_info *info;
716 TXVU_INSN insn;
717 long value;
718{
54cc8ed4
DE
719 if (value & TXVU_DEST_X)
720 (*info->fprintf_func) (info->stream, "x");
721 if (value & TXVU_DEST_Y)
722 (*info->fprintf_func) (info->stream, "y");
723 if (value & TXVU_DEST_Z)
724 (*info->fprintf_func) (info->stream, "z");
725 if (value & TXVU_DEST_W)
726 (*info->fprintf_func) (info->stream, "w");
727}
71af45ec
DE
728
729static void
730print_dotdest (info, insn, value)
731 disassemble_info *info;
732 TXVU_INSN insn;
733 long value;
734{
735 (*info->fprintf_func) (info->stream, ".");
736 print_dest (info, insn, value);
737}
54cc8ed4
DE
738\f
739static long
71af45ec 740parse_vfreg (pstr, errmsg)
54cc8ed4
DE
741 char **pstr;
742 const char **errmsg;
743{
744 char *str = *pstr;
745 char *start;
746 long reg;
71af45ec 747 int reg_dest;
54cc8ed4
DE
748
749 if (tolower (str[0]) != 'v'
750 || tolower (str[1]) != 'f')
751 {
752 *errmsg = "unknown register";
753 return 0;
754 }
755
756 /* FIXME: quick hack until the framework works. */
757 start = str = str + 2;
758 while (*str && isdigit (*str))
759 ++str;
760 reg = atoi (start);
71af45ec
DE
761 reg_dest = parse_dest (&str);
762 if (reg_dest == 0 || isalnum (*str))
763 {
764 *errmsg = "invalid `dest'";
765 return 0;
766 }
767 if (reg_dest != dest)
768 {
769 *errmsg = "register `dest' does not match instruction `dest'";
770 return 0;
771 }
54cc8ed4
DE
772 *pstr = str;
773 *errmsg = NULL;
774 return reg;
775}
776
777static void
71af45ec 778print_vfreg (info, insn, value)
54cc8ed4
DE
779 disassemble_info *info;
780 TXVU_INSN insn;
781 long value;
782{
783 (*info->fprintf_func) (info->stream, "vf%ld", value);
71af45ec 784 print_dest (info, insn, dest);
54cc8ed4 785}
3f897263
DE
786\f
787/* Broadcast handling. */
788
789static long
790parse_bc (pstr, errmsg)
791 char **pstr;
792 const char **errmsg;
793{
794 long dest = 0;
795
796 switch (**pstr)
797 {
798 case 'x' : case 'X' : dest = TXVU_BC_X; break;
799 case 'y' : case 'Y' : dest = TXVU_BC_Y; break;
800 case 'z' : case 'Z' : dest = TXVU_BC_Z; break;
801 case 'w' : case 'W' : dest = TXVU_BC_W; break;
802 default : *errmsg = "invalid `bc'"; return 0;
803 }
804 ++*pstr;
805
806 *errmsg = NULL;
807 return dest;
808}
809
810static void
811print_bc (info, insn, value)
812 disassemble_info *info;
813 TXVU_INSN insn;
814 long value;
815{
816 char c;
817
818 switch (value)
819 {
820 case TXVU_BC_X : c = 'x' ; break;
821 case TXVU_BC_Y : c = 'y' ; break;
822 case TXVU_BC_Z : c = 'z' ; break;
823 case TXVU_BC_W : c = 'w' ; break;
824 }
825
826 (*info->fprintf_func) (info->stream, "%c", c);
827}
828\f
829/* FT register in broadcast case. */
830
831static long
0b988d39 832parse_bcftreg (pstr, errmsg)
3f897263
DE
833 char **pstr;
834 const char **errmsg;
835{
836 char *str = *pstr;
837 char *start;
838 long reg;
839 int reg_bc;
840
841 if (tolower (str[0]) != 'v'
842 || tolower (str[1]) != 'f')
843 {
844 *errmsg = "unknown register";
845 return 0;
846 }
847
848 /* FIXME: quick hack until the framework works. */
849 start = str = str + 2;
850 while (*str && isdigit (*str))
851 ++str;
852 reg = atoi (start);
853 reg_bc = parse_bc (&str, errmsg);
854 if (*errmsg)
855 return 0;
856 if (reg_bc != bc)
857 {
858 *errmsg = "register `bc' does not match instruction `bc'";
859 return 0;
860 }
861 *pstr = str;
862 *errmsg = NULL;
863 return reg;
864}
865
866static void
0b988d39 867print_bcftreg (info, insn, value)
3f897263
DE
868 disassemble_info *info;
869 TXVU_INSN insn;
870 long value;
871{
872 (*info->fprintf_func) (info->stream, "vf%ld", value);
873 print_bc (info, insn, bc);
874}
875\f
876/* ACC handling. */
877
878static long
879parse_accdest (pstr, errmsg)
880 char **pstr;
881 const char **errmsg;
882{
883 char *str = *pstr;
884 long acc_dest = 0;
885
886 if (strncasecmp (str, "acc", 3) != 0)
887 {
888 *errmsg = "expecting `acc'";
889 return 0;
890 }
891 str += 3;
892 acc_dest = parse_dest (&str);
893 if (acc_dest == 0 || isalnum (*str))
894 {
895 *errmsg = "invalid `dest'";
896 return 0;
897 }
898 if (acc_dest != dest)
899 {
900 *errmsg = "acc `dest' does not match instruction `dest'";
901 return 0;
902 }
903 *pstr = str;
904 *errmsg = NULL;
905 /* Value isn't used, but we must return something. */
906 return 0;
907}
908
909static void
910print_accdest (info, insn, value)
911 disassemble_info *info;
912 TXVU_INSN insn;
913 long value;
914{
915 (*info->fprintf_func) (info->stream, "acc");
916 print_dest (info, insn, value);
917}
918\f
919/* XYZ operand handling.
920 This simplifies the opmula,opmsub entries by keeping them equivalent to
921 the others. */
922
923static long
924parse_xyz (pstr, errmsg)
925 char **pstr;
926 const char **errmsg;
927{
928 if (dest != (TXVU_DEST_X | TXVU_DEST_Y | TXVU_DEST_Z))
929 {
930 *errmsg = "expecting `xyz' for `dest' value";
931 return 0;
932 }
933 return 0;
934}
0b988d39
DE
935\f
936/* F[ST] register using selector in F[ST]F field. */
937
938static long
939parse_ffstreg (pstr, errmsg)
940 char **pstr;
941 const char **errmsg;
942{
943 char *str = *pstr;
944 char *start;
945 long reg;
946 int reg_bc;
947
948 if (tolower (str[0]) != 'v'
949 || tolower (str[1]) != 'f')
950 {
951 *errmsg = "unknown register";
952 return 0;
953 }
954
955 /* FIXME: quick hack until the framework works. */
956 start = str = str + 2;
957 while (*str && isdigit (*str))
958 ++str;
959 reg = atoi (start);
960 reg_bc = parse_bc (&str, errmsg);
961 if (*errmsg)
962 return 0;
963 if (reg_bc != bc)
964 {
965 *errmsg = "register `bc' does not match instruction `bc'";
966 return 0;
967 }
968 *pstr = str;
969 *errmsg = NULL;
970 return reg;
971}
972
973static void
974print_ffstreg (info, insn, value)
975 disassemble_info *info;
976 TXVU_INSN insn;
977 long value;
978{
979 (*info->fprintf_func) (info->stream, "vf%ld", value);
980 print_bc (info, insn, bc);
981}
982
983#define INSERT_FN(fn) \
984static TXVU_INSN CONCAT2 (insert_,fn) \
985 PARAMS ((TXVU_INSN, const struct txvu_operand *, \
986 int, long, const char **))
987#define EXTRACT_FN(fn) \
988static long CONCAT2 (extract_,fn) \
989 PARAMS ((TXVU_INSN, const struct txvu_operand *, \
990 int, int *))
991
992static TXVU_INSN
993insert_ffstreg (insn, operand, mods, value, errmsg)
994 TXVU_INSN insn;
995 const struct txvu_operand *operand;
996 int mods;
997 long value;
998 const char **errmsg;
999{
1000}
1001
1002static long
1003extract_ffstreg (insn, operand, mods, pinvalid)
1004 TXVU_INSN insn;
1005 const struct txvu_operand *operand;
1006 int mods;
1007 int *pinvalid;
1008{
1009}
1010\f
1011/* F register. */
1012
1013static long
1014parse_freg (pstr, errmsg)
1015 char **pstr;
1016 const char **errmsg;
1017{
1018 char *str = *pstr;
1019 char *start;
1020 long reg;
1021 int reg_bc;
1022
1023 if (tolower (str[0]) != 'v'
1024 || tolower (str[1]) != 'f')
1025 {
1026 *errmsg = "unknown register";
1027 return 0;
1028 }
1029
1030 /* FIXME: quick hack until the framework works. */
1031 start = str = str + 2;
1032 while (*str && isdigit (*str))
1033 ++str;
1034 reg = atoi (start);
1035 reg_bc = parse_bc (&str, errmsg);
1036 if (*errmsg)
1037 return 0;
1038 if (reg_bc != bc)
1039 {
1040 *errmsg = "register `bc' does not match instruction `bc'";
1041 return 0;
1042 }
1043 *pstr = str;
1044 *errmsg = NULL;
1045 return reg;
1046}
1047
1048static void
1049print_freg (info, insn, value)
1050 disassemble_info *info;
1051 TXVU_INSN insn;
1052 long value;
1053{
1054 (*info->fprintf_func) (info->stream, "vf%ld", value);
1055 print_bc (info, insn, bc);
1056}
1057\f
1058/* I register. */
1059
1060static long
1061parse_ireg (pstr, errmsg)
1062 char **pstr;
1063 const char **errmsg;
1064{
1065 char *str = *pstr;
1066 char *start;
1067 long reg;
1068 int reg_bc;
1069
1070 if (tolower (str[0]) != 'v'
1071 || tolower (str[1]) != 'f')
1072 {
1073 *errmsg = "unknown register";
1074 return 0;
1075 }
1076
1077 /* FIXME: quick hack until the framework works. */
1078 start = str = str + 2;
1079 while (*str && isdigit (*str))
1080 ++str;
1081 reg = atoi (start);
1082 reg_bc = parse_bc (&str, errmsg);
1083 if (*errmsg)
1084 return 0;
1085 if (reg_bc != bc)
1086 {
1087 *errmsg = "register `bc' does not match instruction `bc'";
1088 return 0;
1089 }
1090 *pstr = str;
1091 *errmsg = NULL;
1092 return reg;
1093}
1094
1095static void
1096print_ireg (info, insn, value)
1097 disassemble_info *info;
1098 TXVU_INSN insn;
1099 long value;
1100{
1101 (*info->fprintf_func) (info->stream, "vf%ld", value);
1102 print_bc (info, insn, bc);
1103}
1104\f
1105/* VI01 register. */
1106
1107static long
1108parse_vi01 (pstr, errmsg)
1109 char **pstr;
1110 const char **errmsg;
1111{
1112 char *str = *pstr;
1113 char *start;
1114 long reg;
1115 int reg_bc;
1116
1117 if (tolower (str[0]) != 'v'
1118 || tolower (str[1]) != 'f')
1119 {
1120 *errmsg = "unknown register";
1121 return 0;
1122 }
1123
1124 /* FIXME: quick hack until the framework works. */
1125 start = str = str + 2;
1126 while (*str && isdigit (*str))
1127 ++str;
1128 reg = atoi (start);
1129 reg_bc = parse_bc (&str, errmsg);
1130 if (*errmsg)
1131 return 0;
1132 if (reg_bc != bc)
1133 {
1134 *errmsg = "register `bc' does not match instruction `bc'";
1135 return 0;
1136 }
1137 *pstr = str;
1138 *errmsg = NULL;
1139 return reg;
1140}
1141
1142static void
1143print_vi01 (info, insn, value)
1144 disassemble_info *info;
1145 TXVU_INSN insn;
1146 long value;
1147{
1148 (*info->fprintf_func) (info->stream, "vf%ld", value);
1149 print_bc (info, insn, bc);
1150}
1151\f
1152/* Lower instruction 12 bit immediate. */
1153
1154static TXVU_INSN
1155insert_limm12 (insn, operand, mods, value, errmsg)
1156 TXVU_INSN insn;
1157 const struct txvu_operand *operand;
1158 int mods;
1159 long value;
1160 const char **errmsg;
1161{
1162}
1163
1164static long
1165extract_limm12 (insn, operand, mods, pinvalid)
1166 TXVU_INSN insn;
1167 const struct txvu_operand *operand;
1168 int mods;
1169 int *pinvalid;
1170{
1171}
8ea2f96f
DE
1172\f
1173/* Lower instruction 15 bit unsigned immediate. */
1174
1175static TXVU_INSN
1176insert_luimm15 (insn, operand, mods, value, errmsg)
1177 TXVU_INSN insn;
1178 const struct txvu_operand *operand;
1179 int mods;
1180 long value;
1181 const char **errmsg;
1182{
1183}
1184
1185static long
1186extract_luimm15 (insn, operand, mods, pinvalid)
1187 TXVU_INSN insn;
1188 const struct txvu_operand *operand;
1189 int mods;
1190 int *pinvalid;
1191{
1192}
This page took 0.082965 seconds and 4 git commands to generate.