1*3d8817e4Smiod /* Print VAX instructions.
2*3d8817e4Smiod Copyright 1995, 1998, 2000, 2001, 2002, 2005
3*3d8817e4Smiod Free Software Foundation, Inc.
4*3d8817e4Smiod Contributed by Pauline Middelink <middelin@polyware.iaf.nl>
5*3d8817e4Smiod
6*3d8817e4Smiod This program is free software; you can redistribute it and/or modify
7*3d8817e4Smiod it under the terms of the GNU General Public License as published by
8*3d8817e4Smiod the Free Software Foundation; either version 2 of the License, or
9*3d8817e4Smiod (at your option) any later version.
10*3d8817e4Smiod
11*3d8817e4Smiod This program is distributed in the hope that it will be useful,
12*3d8817e4Smiod but WITHOUT ANY WARRANTY; without even the implied warranty of
13*3d8817e4Smiod MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14*3d8817e4Smiod GNU General Public License for more details.
15*3d8817e4Smiod
16*3d8817e4Smiod You should have received a copy of the GNU General Public License
17*3d8817e4Smiod along with this program; if not, write to the Free Software
18*3d8817e4Smiod Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19*3d8817e4Smiod MA 02110-1301, USA. */
20*3d8817e4Smiod
21*3d8817e4Smiod #include <setjmp.h>
22*3d8817e4Smiod #include <string.h>
23*3d8817e4Smiod #include "sysdep.h"
24*3d8817e4Smiod #include "opcode/vax.h"
25*3d8817e4Smiod #include "dis-asm.h"
26*3d8817e4Smiod
27*3d8817e4Smiod static char *reg_names[] =
28*3d8817e4Smiod {
29*3d8817e4Smiod "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
30*3d8817e4Smiod "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc"
31*3d8817e4Smiod };
32*3d8817e4Smiod
33*3d8817e4Smiod /* Definitions for the function entry mask bits. */
34*3d8817e4Smiod static char *entry_mask_bit[] =
35*3d8817e4Smiod {
36*3d8817e4Smiod /* Registers 0 and 1 shall not be saved, since they're used to pass back
37*3d8817e4Smiod a function's result to its caller... */
38*3d8817e4Smiod "~r0~", "~r1~",
39*3d8817e4Smiod /* Registers 2 .. 11 are normal registers. */
40*3d8817e4Smiod "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
41*3d8817e4Smiod /* Registers 12 and 13 are argument and frame pointer and must not
42*3d8817e4Smiod be saved by using the entry mask. */
43*3d8817e4Smiod "~ap~", "~fp~",
44*3d8817e4Smiod /* Bits 14 and 15 control integer and decimal overflow. */
45*3d8817e4Smiod "IntOvfl", "DecOvfl",
46*3d8817e4Smiod };
47*3d8817e4Smiod
48*3d8817e4Smiod /* Sign-extend an (unsigned char). */
49*3d8817e4Smiod #define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
50*3d8817e4Smiod
51*3d8817e4Smiod /* Get a 1 byte signed integer. */
52*3d8817e4Smiod #define NEXTBYTE(p) \
53*3d8817e4Smiod (p += 1, FETCH_DATA (info, p), \
54*3d8817e4Smiod COERCE_SIGNED_CHAR(p[-1]))
55*3d8817e4Smiod
56*3d8817e4Smiod /* Get a 2 byte signed integer. */
57*3d8817e4Smiod #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
58*3d8817e4Smiod #define NEXTWORD(p) \
59*3d8817e4Smiod (p += 2, FETCH_DATA (info, p), \
60*3d8817e4Smiod COERCE16 ((p[-1] << 8) + p[-2]))
61*3d8817e4Smiod
62*3d8817e4Smiod /* Get a 4 byte signed integer. */
63*3d8817e4Smiod #define COERCE32(x) ((int) (((x) ^ 0x80000000) - 0x80000000))
64*3d8817e4Smiod #define NEXTLONG(p) \
65*3d8817e4Smiod (p += 4, FETCH_DATA (info, p), \
66*3d8817e4Smiod (COERCE32 ((((((p[-1] << 8) + p[-2]) << 8) + p[-3]) << 8) + p[-4])))
67*3d8817e4Smiod
68*3d8817e4Smiod /* Maximum length of an instruction. */
69*3d8817e4Smiod #define MAXLEN 25
70*3d8817e4Smiod
71*3d8817e4Smiod struct private
72*3d8817e4Smiod {
73*3d8817e4Smiod /* Points to first byte not fetched. */
74*3d8817e4Smiod bfd_byte * max_fetched;
75*3d8817e4Smiod bfd_byte the_buffer[MAXLEN];
76*3d8817e4Smiod bfd_vma insn_start;
77*3d8817e4Smiod jmp_buf bailout;
78*3d8817e4Smiod };
79*3d8817e4Smiod
80*3d8817e4Smiod /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
81*3d8817e4Smiod to ADDR (exclusive) are valid. Returns 1 for success, longjmps
82*3d8817e4Smiod on error. */
83*3d8817e4Smiod #define FETCH_DATA(info, addr) \
84*3d8817e4Smiod ((addr) <= ((struct private *)(info->private_data))->max_fetched \
85*3d8817e4Smiod ? 1 : fetch_data ((info), (addr)))
86*3d8817e4Smiod
87*3d8817e4Smiod static int
fetch_data(struct disassemble_info * info,bfd_byte * addr)88*3d8817e4Smiod fetch_data (struct disassemble_info *info, bfd_byte *addr)
89*3d8817e4Smiod {
90*3d8817e4Smiod int status;
91*3d8817e4Smiod struct private *priv = (struct private *) info->private_data;
92*3d8817e4Smiod bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
93*3d8817e4Smiod
94*3d8817e4Smiod status = (*info->read_memory_func) (start,
95*3d8817e4Smiod priv->max_fetched,
96*3d8817e4Smiod addr - priv->max_fetched,
97*3d8817e4Smiod info);
98*3d8817e4Smiod if (status != 0)
99*3d8817e4Smiod {
100*3d8817e4Smiod (*info->memory_error_func) (status, start, info);
101*3d8817e4Smiod longjmp (priv->bailout, 1);
102*3d8817e4Smiod }
103*3d8817e4Smiod else
104*3d8817e4Smiod priv->max_fetched = addr;
105*3d8817e4Smiod
106*3d8817e4Smiod return 1;
107*3d8817e4Smiod }
108*3d8817e4Smiod
109*3d8817e4Smiod /* Entry mask handling. */
110*3d8817e4Smiod static unsigned int entry_addr_occupied_slots = 0;
111*3d8817e4Smiod static unsigned int entry_addr_total_slots = 0;
112*3d8817e4Smiod static bfd_vma * entry_addr = NULL;
113*3d8817e4Smiod
114*3d8817e4Smiod /* Parse the VAX specific disassembler options. These contain function
115*3d8817e4Smiod entry addresses, which can be useful to disassemble ROM images, since
116*3d8817e4Smiod there's no symbol table. Returns TRUE upon success, FALSE otherwise. */
117*3d8817e4Smiod
118*3d8817e4Smiod static bfd_boolean
parse_disassembler_options(char * options)119*3d8817e4Smiod parse_disassembler_options (char * options)
120*3d8817e4Smiod {
121*3d8817e4Smiod const char * entry_switch = "entry:";
122*3d8817e4Smiod
123*3d8817e4Smiod while ((options = strstr (options, entry_switch)))
124*3d8817e4Smiod {
125*3d8817e4Smiod options += strlen (entry_switch);
126*3d8817e4Smiod
127*3d8817e4Smiod /* The greater-than part of the test below is paranoia. */
128*3d8817e4Smiod if (entry_addr_occupied_slots >= entry_addr_total_slots)
129*3d8817e4Smiod {
130*3d8817e4Smiod /* A guesstimate of the number of entries we will have to create. */
131*3d8817e4Smiod entry_addr_total_slots +=
132*3d8817e4Smiod strlen (options) / (strlen (entry_switch) + 5);
133*3d8817e4Smiod
134*3d8817e4Smiod entry_addr = realloc (entry_addr, sizeof (bfd_vma)
135*3d8817e4Smiod * entry_addr_total_slots);
136*3d8817e4Smiod }
137*3d8817e4Smiod
138*3d8817e4Smiod if (entry_addr == NULL)
139*3d8817e4Smiod return FALSE;
140*3d8817e4Smiod
141*3d8817e4Smiod entry_addr[entry_addr_occupied_slots] = bfd_scan_vma (options, NULL, 0);
142*3d8817e4Smiod entry_addr_occupied_slots ++;
143*3d8817e4Smiod }
144*3d8817e4Smiod
145*3d8817e4Smiod return TRUE;
146*3d8817e4Smiod }
147*3d8817e4Smiod
148*3d8817e4Smiod #if 0 /* FIXME: Ideally the disassembler should have target specific
149*3d8817e4Smiod initialisation and termination function pointers. Then
150*3d8817e4Smiod parse_disassembler_options could be the init function and
151*3d8817e4Smiod free_entry_array (below) could be the termination routine.
152*3d8817e4Smiod Until then there is no way for the disassembler to tell us
153*3d8817e4Smiod that it has finished and that we no longer need the entry
154*3d8817e4Smiod array, so this routine is suppressed for now. It does mean
155*3d8817e4Smiod that we leak memory, but only to the extent that we do not
156*3d8817e4Smiod free it just before the disassembler is about to terminate
157*3d8817e4Smiod anyway. */
158*3d8817e4Smiod
159*3d8817e4Smiod /* Free memory allocated to our entry array. */
160*3d8817e4Smiod
161*3d8817e4Smiod static void
162*3d8817e4Smiod free_entry_array (void)
163*3d8817e4Smiod {
164*3d8817e4Smiod if (entry_addr)
165*3d8817e4Smiod {
166*3d8817e4Smiod free (entry_addr);
167*3d8817e4Smiod entry_addr = NULL;
168*3d8817e4Smiod entry_addr_occupied_slots = entry_addr_total_slots = 0;
169*3d8817e4Smiod }
170*3d8817e4Smiod }
171*3d8817e4Smiod #endif
172*3d8817e4Smiod /* Check if the given address is a known function entry. Either there must
173*3d8817e4Smiod be a symbol of function type at this address, or the address must be
174*3d8817e4Smiod a forced entry point. The later helps in disassembling ROM images, because
175*3d8817e4Smiod there's no symbol table at all. Forced entry points can be given by
176*3d8817e4Smiod supplying several -M options to objdump: -M entry:0xffbb7730. */
177*3d8817e4Smiod
178*3d8817e4Smiod static bfd_boolean
is_function_entry(struct disassemble_info * info,bfd_vma addr)179*3d8817e4Smiod is_function_entry (struct disassemble_info *info, bfd_vma addr)
180*3d8817e4Smiod {
181*3d8817e4Smiod unsigned int i;
182*3d8817e4Smiod
183*3d8817e4Smiod /* Check if there's a BSF_FUNCTION symbol at our address. */
184*3d8817e4Smiod if (info->symbols
185*3d8817e4Smiod && info->symbols[0]
186*3d8817e4Smiod && (info->symbols[0]->flags & BSF_FUNCTION)
187*3d8817e4Smiod && addr == bfd_asymbol_value (info->symbols[0]))
188*3d8817e4Smiod return TRUE;
189*3d8817e4Smiod
190*3d8817e4Smiod /* Check for forced function entry address. */
191*3d8817e4Smiod for (i = entry_addr_occupied_slots; i--;)
192*3d8817e4Smiod if (entry_addr[i] == addr)
193*3d8817e4Smiod return TRUE;
194*3d8817e4Smiod
195*3d8817e4Smiod return FALSE;
196*3d8817e4Smiod }
197*3d8817e4Smiod
198*3d8817e4Smiod static int
print_insn_mode(const char * d,int size,unsigned char * p0,bfd_vma addr,disassemble_info * info)199*3d8817e4Smiod print_insn_mode (const char *d,
200*3d8817e4Smiod int size,
201*3d8817e4Smiod unsigned char *p0,
202*3d8817e4Smiod bfd_vma addr, /* PC for this arg to be relative to. */
203*3d8817e4Smiod disassemble_info *info)
204*3d8817e4Smiod {
205*3d8817e4Smiod unsigned char *p = p0;
206*3d8817e4Smiod unsigned char mode, reg;
207*3d8817e4Smiod
208*3d8817e4Smiod /* Fetch and interpret mode byte. */
209*3d8817e4Smiod mode = (unsigned char) NEXTBYTE (p);
210*3d8817e4Smiod reg = mode & 0xF;
211*3d8817e4Smiod switch (mode & 0xF0)
212*3d8817e4Smiod {
213*3d8817e4Smiod case 0x00:
214*3d8817e4Smiod case 0x10:
215*3d8817e4Smiod case 0x20:
216*3d8817e4Smiod case 0x30: /* Literal mode $number. */
217*3d8817e4Smiod if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
218*3d8817e4Smiod (*info->fprintf_func) (info->stream, "$0x%x [%c-float]", mode, d[1]);
219*3d8817e4Smiod else
220*3d8817e4Smiod (*info->fprintf_func) (info->stream, "$0x%x", mode);
221*3d8817e4Smiod break;
222*3d8817e4Smiod case 0x40: /* Index: base-addr[Rn] */
223*3d8817e4Smiod p += print_insn_mode (d, size, p0 + 1, addr + 1, info);
224*3d8817e4Smiod (*info->fprintf_func) (info->stream, "[%s]", reg_names[reg]);
225*3d8817e4Smiod break;
226*3d8817e4Smiod case 0x50: /* Register: Rn */
227*3d8817e4Smiod (*info->fprintf_func) (info->stream, "%s", reg_names[reg]);
228*3d8817e4Smiod break;
229*3d8817e4Smiod case 0x60: /* Register deferred: (Rn) */
230*3d8817e4Smiod (*info->fprintf_func) (info->stream, "(%s)", reg_names[reg]);
231*3d8817e4Smiod break;
232*3d8817e4Smiod case 0x70: /* Autodecrement: -(Rn) */
233*3d8817e4Smiod (*info->fprintf_func) (info->stream, "-(%s)", reg_names[reg]);
234*3d8817e4Smiod break;
235*3d8817e4Smiod case 0x80: /* Autoincrement: (Rn)+ */
236*3d8817e4Smiod if (reg == 0xF)
237*3d8817e4Smiod { /* Immediate? */
238*3d8817e4Smiod int i;
239*3d8817e4Smiod
240*3d8817e4Smiod FETCH_DATA (info, p + size);
241*3d8817e4Smiod (*info->fprintf_func) (info->stream, "$0x");
242*3d8817e4Smiod if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
243*3d8817e4Smiod {
244*3d8817e4Smiod int float_word;
245*3d8817e4Smiod
246*3d8817e4Smiod float_word = p[0] | (p[1] << 8);
247*3d8817e4Smiod if ((d[1] == 'd' || d[1] == 'f')
248*3d8817e4Smiod && (float_word & 0xff80) == 0x8000)
249*3d8817e4Smiod {
250*3d8817e4Smiod (*info->fprintf_func) (info->stream, "[invalid %c-float]",
251*3d8817e4Smiod d[1]);
252*3d8817e4Smiod }
253*3d8817e4Smiod else
254*3d8817e4Smiod {
255*3d8817e4Smiod for (i = 0; i < size; i++)
256*3d8817e4Smiod (*info->fprintf_func) (info->stream, "%02x",
257*3d8817e4Smiod p[size - i - 1]);
258*3d8817e4Smiod (*info->fprintf_func) (info->stream, " [%c-float]", d[1]);
259*3d8817e4Smiod }
260*3d8817e4Smiod }
261*3d8817e4Smiod else
262*3d8817e4Smiod {
263*3d8817e4Smiod for (i = 0; i < size; i++)
264*3d8817e4Smiod (*info->fprintf_func) (info->stream, "%02x", p[size - i - 1]);
265*3d8817e4Smiod }
266*3d8817e4Smiod p += size;
267*3d8817e4Smiod }
268*3d8817e4Smiod else
269*3d8817e4Smiod (*info->fprintf_func) (info->stream, "(%s)+", reg_names[reg]);
270*3d8817e4Smiod break;
271*3d8817e4Smiod case 0x90: /* Autoincrement deferred: @(Rn)+ */
272*3d8817e4Smiod if (reg == 0xF)
273*3d8817e4Smiod (*info->fprintf_func) (info->stream, "*0x%x", NEXTLONG (p));
274*3d8817e4Smiod else
275*3d8817e4Smiod (*info->fprintf_func) (info->stream, "@(%s)+", reg_names[reg]);
276*3d8817e4Smiod break;
277*3d8817e4Smiod case 0xB0: /* Displacement byte deferred: *displ(Rn). */
278*3d8817e4Smiod (*info->fprintf_func) (info->stream, "*");
279*3d8817e4Smiod case 0xA0: /* Displacement byte: displ(Rn). */
280*3d8817e4Smiod if (reg == 0xF)
281*3d8817e4Smiod (*info->print_address_func) (addr + 2 + NEXTBYTE (p), info);
282*3d8817e4Smiod else
283*3d8817e4Smiod (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTBYTE (p),
284*3d8817e4Smiod reg_names[reg]);
285*3d8817e4Smiod break;
286*3d8817e4Smiod case 0xD0: /* Displacement word deferred: *displ(Rn). */
287*3d8817e4Smiod (*info->fprintf_func) (info->stream, "*");
288*3d8817e4Smiod case 0xC0: /* Displacement word: displ(Rn). */
289*3d8817e4Smiod if (reg == 0xF)
290*3d8817e4Smiod (*info->print_address_func) (addr + 3 + NEXTWORD (p), info);
291*3d8817e4Smiod else
292*3d8817e4Smiod (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTWORD (p),
293*3d8817e4Smiod reg_names[reg]);
294*3d8817e4Smiod break;
295*3d8817e4Smiod case 0xF0: /* Displacement long deferred: *displ(Rn). */
296*3d8817e4Smiod (*info->fprintf_func) (info->stream, "*");
297*3d8817e4Smiod case 0xE0: /* Displacement long: displ(Rn). */
298*3d8817e4Smiod if (reg == 0xF)
299*3d8817e4Smiod (*info->print_address_func) (addr + 5 + NEXTLONG (p), info);
300*3d8817e4Smiod else
301*3d8817e4Smiod (*info->fprintf_func) (info->stream, "0x%x(%s)", NEXTLONG (p),
302*3d8817e4Smiod reg_names[reg]);
303*3d8817e4Smiod break;
304*3d8817e4Smiod }
305*3d8817e4Smiod
306*3d8817e4Smiod return p - p0;
307*3d8817e4Smiod }
308*3d8817e4Smiod
309*3d8817e4Smiod /* Returns number of bytes "eaten" by the operand, or return -1 if an
310*3d8817e4Smiod invalid operand was found, or -2 if an opcode tabel error was
311*3d8817e4Smiod found. */
312*3d8817e4Smiod
313*3d8817e4Smiod static int
print_insn_arg(const char * d,unsigned char * p0,bfd_vma addr,disassemble_info * info)314*3d8817e4Smiod print_insn_arg (const char *d,
315*3d8817e4Smiod unsigned char *p0,
316*3d8817e4Smiod bfd_vma addr, /* PC for this arg to be relative to. */
317*3d8817e4Smiod disassemble_info *info)
318*3d8817e4Smiod {
319*3d8817e4Smiod int arg_len;
320*3d8817e4Smiod
321*3d8817e4Smiod /* Check validity of addressing length. */
322*3d8817e4Smiod switch (d[1])
323*3d8817e4Smiod {
324*3d8817e4Smiod case 'b' : arg_len = 1; break;
325*3d8817e4Smiod case 'd' : arg_len = 8; break;
326*3d8817e4Smiod case 'f' : arg_len = 4; break;
327*3d8817e4Smiod case 'g' : arg_len = 8; break;
328*3d8817e4Smiod case 'h' : arg_len = 16; break;
329*3d8817e4Smiod case 'l' : arg_len = 4; break;
330*3d8817e4Smiod case 'o' : arg_len = 16; break;
331*3d8817e4Smiod case 'w' : arg_len = 2; break;
332*3d8817e4Smiod case 'q' : arg_len = 8; break;
333*3d8817e4Smiod default : abort ();
334*3d8817e4Smiod }
335*3d8817e4Smiod
336*3d8817e4Smiod /* Branches have no mode byte. */
337*3d8817e4Smiod if (d[0] == 'b')
338*3d8817e4Smiod {
339*3d8817e4Smiod unsigned char *p = p0;
340*3d8817e4Smiod
341*3d8817e4Smiod if (arg_len == 1)
342*3d8817e4Smiod (*info->print_address_func) (addr + 1 + NEXTBYTE (p), info);
343*3d8817e4Smiod else
344*3d8817e4Smiod (*info->print_address_func) (addr + 2 + NEXTWORD (p), info);
345*3d8817e4Smiod
346*3d8817e4Smiod return p - p0;
347*3d8817e4Smiod }
348*3d8817e4Smiod
349*3d8817e4Smiod return print_insn_mode (d, arg_len, p0, addr, info);
350*3d8817e4Smiod }
351*3d8817e4Smiod
352*3d8817e4Smiod /* Print the vax instruction at address MEMADDR in debugged memory,
353*3d8817e4Smiod on INFO->STREAM. Returns length of the instruction, in bytes. */
354*3d8817e4Smiod
355*3d8817e4Smiod int
print_insn_vax(bfd_vma memaddr,disassemble_info * info)356*3d8817e4Smiod print_insn_vax (bfd_vma memaddr, disassemble_info *info)
357*3d8817e4Smiod {
358*3d8817e4Smiod static bfd_boolean parsed_disassembler_options = FALSE;
359*3d8817e4Smiod const struct vot *votp;
360*3d8817e4Smiod const char *argp;
361*3d8817e4Smiod unsigned char *arg;
362*3d8817e4Smiod struct private priv;
363*3d8817e4Smiod bfd_byte *buffer = priv.the_buffer;
364*3d8817e4Smiod
365*3d8817e4Smiod info->private_data = & priv;
366*3d8817e4Smiod priv.max_fetched = priv.the_buffer;
367*3d8817e4Smiod priv.insn_start = memaddr;
368*3d8817e4Smiod
369*3d8817e4Smiod if (! parsed_disassembler_options
370*3d8817e4Smiod && info->disassembler_options != NULL)
371*3d8817e4Smiod {
372*3d8817e4Smiod parse_disassembler_options (info->disassembler_options);
373*3d8817e4Smiod
374*3d8817e4Smiod /* To avoid repeated parsing of these options. */
375*3d8817e4Smiod parsed_disassembler_options = TRUE;
376*3d8817e4Smiod }
377*3d8817e4Smiod
378*3d8817e4Smiod if (setjmp (priv.bailout) != 0)
379*3d8817e4Smiod /* Error return. */
380*3d8817e4Smiod return -1;
381*3d8817e4Smiod
382*3d8817e4Smiod argp = NULL;
383*3d8817e4Smiod /* Check if the info buffer has more than one byte left since
384*3d8817e4Smiod the last opcode might be a single byte with no argument data. */
385*3d8817e4Smiod if (info->buffer_length - (memaddr - info->buffer_vma) > 1)
386*3d8817e4Smiod {
387*3d8817e4Smiod FETCH_DATA (info, buffer + 2);
388*3d8817e4Smiod }
389*3d8817e4Smiod else
390*3d8817e4Smiod {
391*3d8817e4Smiod FETCH_DATA (info, buffer + 1);
392*3d8817e4Smiod buffer[1] = 0;
393*3d8817e4Smiod }
394*3d8817e4Smiod
395*3d8817e4Smiod /* Decode function entry mask. */
396*3d8817e4Smiod if (is_function_entry (info, memaddr))
397*3d8817e4Smiod {
398*3d8817e4Smiod int i = 0;
399*3d8817e4Smiod int register_mask = buffer[1] << 8 | buffer[0];
400*3d8817e4Smiod
401*3d8817e4Smiod (*info->fprintf_func) (info->stream, ".word 0x%04x # Entry mask: <",
402*3d8817e4Smiod register_mask);
403*3d8817e4Smiod
404*3d8817e4Smiod for (i = 15; i >= 0; i--)
405*3d8817e4Smiod if (register_mask & (1 << i))
406*3d8817e4Smiod (*info->fprintf_func) (info->stream, " %s", entry_mask_bit[i]);
407*3d8817e4Smiod
408*3d8817e4Smiod (*info->fprintf_func) (info->stream, " >");
409*3d8817e4Smiod
410*3d8817e4Smiod return 2;
411*3d8817e4Smiod }
412*3d8817e4Smiod
413*3d8817e4Smiod for (votp = &votstrs[0]; votp->name[0]; votp++)
414*3d8817e4Smiod {
415*3d8817e4Smiod vax_opcodeT opcode = votp->detail.code;
416*3d8817e4Smiod
417*3d8817e4Smiod /* 2 byte codes match 2 buffer pos. */
418*3d8817e4Smiod if ((bfd_byte) opcode == buffer[0]
419*3d8817e4Smiod && (opcode >> 8 == 0 || opcode >> 8 == buffer[1]))
420*3d8817e4Smiod {
421*3d8817e4Smiod argp = votp->detail.args;
422*3d8817e4Smiod break;
423*3d8817e4Smiod }
424*3d8817e4Smiod }
425*3d8817e4Smiod if (argp == NULL)
426*3d8817e4Smiod {
427*3d8817e4Smiod /* Handle undefined instructions. */
428*3d8817e4Smiod (*info->fprintf_func) (info->stream, ".word 0x%x",
429*3d8817e4Smiod (buffer[0] << 8) + buffer[1]);
430*3d8817e4Smiod return 2;
431*3d8817e4Smiod }
432*3d8817e4Smiod
433*3d8817e4Smiod /* Point at first byte of argument data, and at descriptor for first
434*3d8817e4Smiod argument. */
435*3d8817e4Smiod arg = buffer + ((votp->detail.code >> 8) ? 2 : 1);
436*3d8817e4Smiod
437*3d8817e4Smiod /* Make sure we have it in mem */
438*3d8817e4Smiod FETCH_DATA (info, arg);
439*3d8817e4Smiod
440*3d8817e4Smiod (*info->fprintf_func) (info->stream, "%s", votp->name);
441*3d8817e4Smiod if (*argp)
442*3d8817e4Smiod (*info->fprintf_func) (info->stream, " ");
443*3d8817e4Smiod
444*3d8817e4Smiod while (*argp)
445*3d8817e4Smiod {
446*3d8817e4Smiod arg += print_insn_arg (argp, arg, memaddr + arg - buffer, info);
447*3d8817e4Smiod argp += 2;
448*3d8817e4Smiod if (*argp)
449*3d8817e4Smiod (*info->fprintf_func) (info->stream, ",");
450*3d8817e4Smiod }
451*3d8817e4Smiod
452*3d8817e4Smiod return arg - buffer;
453*3d8817e4Smiod }
454*3d8817e4Smiod
455