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