1 1.1 christos /* Disassemble z8000 code. 2 1.10 christos Copyright (C) 1992-2025 Free Software Foundation, Inc. 3 1.1 christos 4 1.1 christos This file is part of the GNU opcodes library. 5 1.1 christos 6 1.1 christos This library is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3, or (at your option) 9 1.1 christos any later version. 10 1.1 christos 11 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT 12 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 1.1 christos License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this file; see the file COPYING. If not, write to the 18 1.1 christos Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, 19 1.1 christos MA 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos #include "sysdep.h" 22 1.6 christos #include "disassemble.h" 23 1.7 christos #include "libiberty.h" 24 1.1 christos 25 1.1 christos #define DEFINE_TABLE 26 1.1 christos #include "z8k-opc.h" 27 1.1 christos 28 1.1 christos #include <setjmp.h> 29 1.1 christos 30 1.1 christos typedef struct 31 1.1 christos { 32 1.1 christos /* These are all indexed by nibble number (i.e only every other entry 33 1.1 christos of bytes is used, and every 4th entry of words). */ 34 1.1 christos unsigned char nibbles[24]; 35 1.1 christos unsigned char bytes[24]; 36 1.1 christos unsigned short words[24]; 37 1.1 christos 38 1.1 christos /* Nibble number of first word not yet fetched. */ 39 1.7 christos unsigned int max_fetched; 40 1.1 christos bfd_vma insn_start; 41 1.3 christos OPCODES_SIGJMP_BUF bailout; 42 1.1 christos 43 1.1 christos int tabl_index; 44 1.1 christos char instr_asmsrc[80]; 45 1.1 christos unsigned long arg_reg[0x0f]; 46 1.1 christos unsigned long immediate; 47 1.1 christos unsigned long displacement; 48 1.1 christos unsigned long address; 49 1.1 christos unsigned long cond_code; 50 1.1 christos unsigned long ctrl_code; 51 1.1 christos unsigned long flags; 52 1.1 christos unsigned long interrupts; 53 1.1 christos } 54 1.1 christos instr_data_s; 55 1.1 christos 56 1.1 christos /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) 57 1.1 christos to ADDR (exclusive) are valid. Returns 1 for success, longjmps 58 1.1 christos on error. */ 59 1.1 christos #define FETCH_DATA(info, nibble) \ 60 1.1 christos ((nibble) < ((instr_data_s *) (info->private_data))->max_fetched \ 61 1.1 christos ? 1 : fetch_data ((info), (nibble))) 62 1.1 christos 63 1.1 christos static int 64 1.1 christos fetch_data (struct disassemble_info *info, int nibble) 65 1.1 christos { 66 1.1 christos unsigned char mybuf[20]; 67 1.1 christos int status; 68 1.1 christos instr_data_s *priv = (instr_data_s *) info->private_data; 69 1.1 christos 70 1.1 christos if ((nibble % 4) != 0) 71 1.1 christos abort (); 72 1.1 christos 73 1.1 christos status = (*info->read_memory_func) (priv->insn_start, 74 1.1 christos (bfd_byte *) mybuf, 75 1.1 christos nibble / 2, 76 1.1 christos info); 77 1.1 christos if (status != 0) 78 1.1 christos { 79 1.1 christos (*info->memory_error_func) (status, priv->insn_start, info); 80 1.3 christos OPCODES_SIGLONGJMP (priv->bailout, 1); 81 1.1 christos } 82 1.1 christos 83 1.1 christos { 84 1.1 christos int i; 85 1.1 christos unsigned char *p = mybuf; 86 1.1 christos 87 1.1 christos for (i = 0; i < nibble;) 88 1.1 christos { 89 1.1 christos priv->words[i] = (p[0] << 8) | p[1]; 90 1.1 christos 91 1.1 christos priv->bytes[i] = *p; 92 1.1 christos priv->nibbles[i++] = *p >> 4; 93 1.1 christos priv->nibbles[i++] = *p & 0xf; 94 1.1 christos 95 1.1 christos ++p; 96 1.1 christos priv->bytes[i] = *p; 97 1.1 christos priv->nibbles[i++] = *p >> 4; 98 1.1 christos priv->nibbles[i++] = *p & 0xf; 99 1.1 christos 100 1.1 christos ++p; 101 1.1 christos } 102 1.1 christos } 103 1.1 christos priv->max_fetched = nibble; 104 1.1 christos return 1; 105 1.1 christos } 106 1.1 christos 107 1.1 christos static char *codes[16] = 108 1.1 christos { 109 1.1 christos "f", 110 1.1 christos "lt", 111 1.1 christos "le", 112 1.1 christos "ule", 113 1.1 christos "ov/pe", 114 1.1 christos "mi", 115 1.1 christos "eq", 116 1.1 christos "c/ult", 117 1.1 christos "t", 118 1.1 christos "ge", 119 1.1 christos "gt", 120 1.1 christos "ugt", 121 1.1 christos "nov/po", 122 1.1 christos "pl", 123 1.1 christos "ne", 124 1.1 christos "nc/uge" 125 1.1 christos }; 126 1.1 christos 127 1.1 christos static char *ctrl_names[8] = 128 1.1 christos { 129 1.1 christos "<invld>", 130 1.1 christos "flags", 131 1.1 christos "fcw", 132 1.1 christos "refresh", 133 1.1 christos "psapseg", 134 1.1 christos "psapoff", 135 1.1 christos "nspseg", 136 1.1 christos "nspoff" 137 1.1 christos }; 138 1.1 christos 139 1.1 christos static int seg_length; 140 1.1 christos int z8k_lookup_instr (unsigned char *, disassemble_info *); 141 1.1 christos static void output_instr (instr_data_s *, unsigned long, disassemble_info *); 142 1.1 christos static void unpack_instr (instr_data_s *, int, disassemble_info *); 143 1.1 christos static void unparse_instr (instr_data_s *, int); 144 1.1 christos 145 1.1 christos static int 146 1.1 christos print_insn_z8k (bfd_vma addr, disassemble_info *info, int is_segmented) 147 1.1 christos { 148 1.1 christos instr_data_s instr_data; 149 1.1 christos 150 1.8 christos info->private_data = &instr_data; 151 1.1 christos instr_data.max_fetched = 0; 152 1.1 christos instr_data.insn_start = addr; 153 1.3 christos if (OPCODES_SIGSETJMP (instr_data.bailout) != 0) 154 1.1 christos /* Error return. */ 155 1.1 christos return -1; 156 1.1 christos 157 1.1 christos info->bytes_per_chunk = 2; 158 1.1 christos info->bytes_per_line = 6; 159 1.1 christos info->display_endian = BFD_ENDIAN_BIG; 160 1.1 christos 161 1.1 christos instr_data.tabl_index = z8k_lookup_instr (instr_data.nibbles, info); 162 1.1 christos if (instr_data.tabl_index >= 0) 163 1.1 christos { 164 1.1 christos unpack_instr (&instr_data, is_segmented, info); 165 1.1 christos unparse_instr (&instr_data, is_segmented); 166 1.1 christos output_instr (&instr_data, addr, info); 167 1.1 christos return z8k_table[instr_data.tabl_index].length + seg_length; 168 1.1 christos } 169 1.1 christos else 170 1.1 christos { 171 1.1 christos FETCH_DATA (info, 4); 172 1.1 christos (*info->fprintf_func) (info->stream, ".word %02x%02x", 173 1.1 christos instr_data.bytes[0], instr_data.bytes[2]); 174 1.1 christos return 2; 175 1.1 christos } 176 1.1 christos } 177 1.1 christos 178 1.1 christos int 179 1.1 christos print_insn_z8001 (bfd_vma addr, disassemble_info *info) 180 1.1 christos { 181 1.1 christos return print_insn_z8k (addr, info, 1); 182 1.1 christos } 183 1.1 christos 184 1.1 christos int 185 1.1 christos print_insn_z8002 (bfd_vma addr, disassemble_info *info) 186 1.1 christos { 187 1.1 christos return print_insn_z8k (addr, info, 0); 188 1.1 christos } 189 1.1 christos 190 1.1 christos int 191 1.1 christos z8k_lookup_instr (unsigned char *nibbles, disassemble_info *info) 192 1.1 christos { 193 1.7 christos unsigned int nibl_index, tabl_index; 194 1.1 christos int nibl_matched; 195 1.1 christos int need_fetch = 0; 196 1.1 christos unsigned short instr_nibl; 197 1.1 christos unsigned short tabl_datum, datum_class, datum_value; 198 1.1 christos 199 1.1 christos nibl_matched = 0; 200 1.1 christos tabl_index = 0; 201 1.1 christos FETCH_DATA (info, 4); 202 1.1 christos while (!nibl_matched && z8k_table[tabl_index].name) 203 1.1 christos { 204 1.1 christos nibl_matched = 1; 205 1.1 christos for (nibl_index = 0; 206 1.7 christos nibl_matched 207 1.7 christos && nibl_index < ARRAY_SIZE (z8k_table[0].byte_info) 208 1.7 christos && nibl_index < z8k_table[tabl_index].length * 2; 209 1.1 christos nibl_index++) 210 1.1 christos { 211 1.1 christos if ((nibl_index % 4) == 0) 212 1.1 christos { 213 1.1 christos /* Fetch data only if it isn't already there. */ 214 1.1 christos if (nibl_index >= 4 || (nibl_index < 4 && need_fetch)) 215 1.1 christos FETCH_DATA (info, nibl_index + 4); /* Fetch one word at a time. */ 216 1.1 christos if (nibl_index < 4) 217 1.1 christos need_fetch = 0; 218 1.1 christos else 219 1.1 christos need_fetch = 1; 220 1.1 christos } 221 1.1 christos instr_nibl = nibbles[nibl_index]; 222 1.1 christos 223 1.1 christos tabl_datum = z8k_table[tabl_index].byte_info[nibl_index]; 224 1.1 christos datum_class = tabl_datum & CLASS_MASK; 225 1.1 christos datum_value = ~CLASS_MASK & tabl_datum; 226 1.1 christos 227 1.1 christos switch (datum_class) 228 1.1 christos { 229 1.1 christos case CLASS_BIT: 230 1.1 christos if (datum_value != instr_nibl) 231 1.1 christos nibl_matched = 0; 232 1.1 christos break; 233 1.1 christos case CLASS_IGNORE: 234 1.1 christos break; 235 1.1 christos case CLASS_00II: 236 1.1 christos if (!((~instr_nibl) & 0x4)) 237 1.1 christos nibl_matched = 0; 238 1.1 christos break; 239 1.1 christos case CLASS_01II: 240 1.1 christos if (!(instr_nibl & 0x4)) 241 1.1 christos nibl_matched = 0; 242 1.1 christos break; 243 1.1 christos case CLASS_0CCC: 244 1.1 christos if (!((~instr_nibl) & 0x8)) 245 1.1 christos nibl_matched = 0; 246 1.1 christos break; 247 1.1 christos case CLASS_1CCC: 248 1.1 christos if (!(instr_nibl & 0x8)) 249 1.1 christos nibl_matched = 0; 250 1.1 christos break; 251 1.1 christos case CLASS_0DISP7: 252 1.1 christos if (!((~instr_nibl) & 0x8)) 253 1.1 christos nibl_matched = 0; 254 1.1 christos nibl_index += 1; 255 1.1 christos break; 256 1.1 christos case CLASS_1DISP7: 257 1.1 christos if (!(instr_nibl & 0x8)) 258 1.1 christos nibl_matched = 0; 259 1.1 christos nibl_index += 1; 260 1.1 christos break; 261 1.1 christos case CLASS_REGN0: 262 1.1 christos if (instr_nibl == 0) 263 1.1 christos nibl_matched = 0; 264 1.1 christos break; 265 1.1 christos case CLASS_BIT_1OR2: 266 1.1 christos if ((instr_nibl | 0x2) != (datum_value | 0x2)) 267 1.1 christos nibl_matched = 0; 268 1.1 christos break; 269 1.1 christos default: 270 1.1 christos break; 271 1.1 christos } 272 1.1 christos } 273 1.1 christos 274 1.1 christos if (nibl_matched) 275 1.1 christos return tabl_index; 276 1.1 christos 277 1.1 christos tabl_index++; 278 1.1 christos } 279 1.1 christos return -1; 280 1.1 christos } 281 1.1 christos 282 1.1 christos static void 283 1.1 christos output_instr (instr_data_s *instr_data, 284 1.1 christos unsigned long addr ATTRIBUTE_UNUSED, 285 1.1 christos disassemble_info *info) 286 1.1 christos { 287 1.7 christos unsigned int num_bytes; 288 1.1 christos char out_str[100]; 289 1.1 christos 290 1.1 christos out_str[0] = 0; 291 1.1 christos 292 1.1 christos num_bytes = (z8k_table[instr_data->tabl_index].length + seg_length) * 2; 293 1.1 christos FETCH_DATA (info, num_bytes); 294 1.1 christos 295 1.1 christos strcat (out_str, instr_data->instr_asmsrc); 296 1.1 christos 297 1.1 christos (*info->fprintf_func) (info->stream, "%s", out_str); 298 1.1 christos } 299 1.1 christos 300 1.1 christos static void 301 1.1 christos unpack_instr (instr_data_s *instr_data, int is_segmented, disassemble_info *info) 302 1.1 christos { 303 1.7 christos unsigned int nibl_count, loop; 304 1.1 christos unsigned short instr_nibl, instr_byte, instr_word; 305 1.1 christos long instr_long; 306 1.1 christos unsigned int tabl_datum, datum_class; 307 1.1 christos unsigned short datum_value; 308 1.1 christos 309 1.1 christos nibl_count = 0; 310 1.1 christos loop = 0; 311 1.1 christos seg_length = 0; 312 1.1 christos 313 1.1 christos while (z8k_table[instr_data->tabl_index].byte_info[loop] != 0) 314 1.1 christos { 315 1.1 christos FETCH_DATA (info, nibl_count + 4 - (nibl_count % 4)); 316 1.1 christos instr_nibl = instr_data->nibbles[nibl_count]; 317 1.1 christos instr_byte = instr_data->bytes[nibl_count & ~1]; 318 1.1 christos instr_word = instr_data->words[nibl_count & ~3]; 319 1.1 christos 320 1.1 christos tabl_datum = z8k_table[instr_data->tabl_index].byte_info[loop]; 321 1.1 christos datum_class = tabl_datum & CLASS_MASK; 322 1.1 christos datum_value = tabl_datum & ~CLASS_MASK; 323 1.1 christos 324 1.1 christos switch (datum_class) 325 1.1 christos { 326 1.1 christos case CLASS_DISP: 327 1.1 christos switch (datum_value) 328 1.1 christos { 329 1.1 christos case ARG_DISP16: 330 1.1 christos instr_data->displacement = instr_data->insn_start + 4 331 1.1 christos + (signed short) (instr_word & 0xffff); 332 1.1 christos nibl_count += 3; 333 1.1 christos break; 334 1.1 christos case ARG_DISP12: 335 1.1 christos if (instr_word & 0x800) 336 1.1 christos /* Negative 12 bit displacement. */ 337 1.1 christos instr_data->displacement = instr_data->insn_start + 2 338 1.1 christos - (signed short) ((instr_word & 0xfff) | 0xf000) * 2; 339 1.1 christos else 340 1.1 christos instr_data->displacement = instr_data->insn_start + 2 341 1.1 christos - (instr_word & 0x0fff) * 2; 342 1.1 christos 343 1.1 christos nibl_count += 2; 344 1.1 christos break; 345 1.1 christos default: 346 1.1 christos break; 347 1.1 christos } 348 1.1 christos break; 349 1.1 christos case CLASS_IMM: 350 1.1 christos switch (datum_value) 351 1.1 christos { 352 1.1 christos case ARG_IMM4: 353 1.1 christos instr_data->immediate = instr_nibl; 354 1.1 christos break; 355 1.1 christos case ARG_NIM4: 356 1.1 christos instr_data->immediate = (- instr_nibl) & 0xf; 357 1.1 christos break; 358 1.1 christos case ARG_NIM8: 359 1.1 christos instr_data->immediate = (- instr_byte) & 0xff; 360 1.1 christos nibl_count += 1; 361 1.1 christos break; 362 1.1 christos case ARG_IMM8: 363 1.1 christos instr_data->immediate = instr_byte; 364 1.1 christos nibl_count += 1; 365 1.1 christos break; 366 1.1 christos case ARG_IMM16: 367 1.1 christos instr_data->immediate = instr_word; 368 1.1 christos nibl_count += 3; 369 1.1 christos break; 370 1.1 christos case ARG_IMM32: 371 1.1 christos FETCH_DATA (info, nibl_count + 8); 372 1.7 christos instr_long = ((unsigned) instr_data->words[nibl_count] << 16 373 1.7 christos | instr_data->words[nibl_count + 4]); 374 1.1 christos instr_data->immediate = instr_long; 375 1.1 christos nibl_count += 7; 376 1.1 christos break; 377 1.1 christos case ARG_IMMN: 378 1.1 christos instr_data->immediate = instr_nibl - 1; 379 1.1 christos break; 380 1.1 christos case ARG_IMM4M1: 381 1.1 christos instr_data->immediate = instr_nibl + 1; 382 1.1 christos break; 383 1.1 christos case ARG_IMM_1: 384 1.1 christos instr_data->immediate = 1; 385 1.1 christos break; 386 1.1 christos case ARG_IMM_2: 387 1.1 christos instr_data->immediate = 2; 388 1.1 christos break; 389 1.1 christos case ARG_IMM2: 390 1.1 christos instr_data->immediate = instr_nibl & 0x3; 391 1.1 christos break; 392 1.1 christos default: 393 1.1 christos break; 394 1.1 christos } 395 1.1 christos break; 396 1.1 christos case CLASS_CC: 397 1.1 christos instr_data->cond_code = instr_nibl; 398 1.1 christos break; 399 1.1 christos case CLASS_ADDRESS: 400 1.1 christos if (is_segmented) 401 1.1 christos { 402 1.1 christos if (instr_nibl & 0x8) 403 1.1 christos { 404 1.1 christos FETCH_DATA (info, nibl_count + 8); 405 1.7 christos instr_long = ((unsigned) instr_data->words[nibl_count] << 16 406 1.7 christos | instr_data->words[nibl_count + 4]); 407 1.7 christos instr_data->address = ((instr_word & 0x7f00) << 16 408 1.7 christos | (instr_long & 0xffff)); 409 1.1 christos nibl_count += 7; 410 1.1 christos seg_length = 2; 411 1.1 christos } 412 1.1 christos else 413 1.1 christos { 414 1.7 christos instr_data->address = ((instr_word & 0x7f00) << 16 415 1.7 christos | (instr_word & 0x00ff)); 416 1.1 christos nibl_count += 3; 417 1.1 christos } 418 1.1 christos } 419 1.1 christos else 420 1.1 christos { 421 1.1 christos instr_data->address = instr_word; 422 1.1 christos nibl_count += 3; 423 1.1 christos } 424 1.1 christos break; 425 1.1 christos case CLASS_0CCC: 426 1.1 christos case CLASS_1CCC: 427 1.1 christos instr_data->ctrl_code = instr_nibl & 0x7; 428 1.1 christos break; 429 1.1 christos case CLASS_0DISP7: 430 1.1 christos instr_data->displacement = 431 1.1 christos instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2; 432 1.1 christos nibl_count += 1; 433 1.1 christos break; 434 1.1 christos case CLASS_1DISP7: 435 1.1 christos instr_data->displacement = 436 1.1 christos instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2; 437 1.1 christos nibl_count += 1; 438 1.1 christos break; 439 1.1 christos case CLASS_01II: 440 1.1 christos instr_data->interrupts = instr_nibl & 0x3; 441 1.1 christos break; 442 1.1 christos case CLASS_00II: 443 1.1 christos instr_data->interrupts = instr_nibl & 0x3; 444 1.1 christos break; 445 1.1 christos case CLASS_IGNORE: 446 1.1 christos case CLASS_BIT: 447 1.1 christos instr_data->ctrl_code = instr_nibl & 0x7; 448 1.1 christos break; 449 1.1 christos case CLASS_FLAGS: 450 1.1 christos instr_data->flags = instr_nibl; 451 1.1 christos break; 452 1.1 christos case CLASS_REG: 453 1.1 christos instr_data->arg_reg[datum_value] = instr_nibl; 454 1.1 christos break; 455 1.1 christos case CLASS_REGN0: 456 1.1 christos instr_data->arg_reg[datum_value] = instr_nibl; 457 1.1 christos break; 458 1.1 christos case CLASS_DISP8: 459 1.1 christos instr_data->displacement = 460 1.1 christos instr_data->insn_start + 2 + (signed char) instr_byte * 2; 461 1.1 christos nibl_count += 1; 462 1.1 christos break; 463 1.1 christos case CLASS_BIT_1OR2: 464 1.1 christos instr_data->immediate = ((instr_nibl >> 1) & 0x1) + 1; 465 1.1 christos nibl_count += 1; 466 1.1 christos break; 467 1.1 christos default: 468 1.1 christos abort (); 469 1.1 christos break; 470 1.1 christos } 471 1.1 christos 472 1.1 christos loop += 1; 473 1.1 christos nibl_count += 1; 474 1.1 christos } 475 1.1 christos } 476 1.1 christos 477 1.1 christos static void 478 1.1 christos print_intr(char *tmp_str, unsigned long interrupts) 479 1.1 christos { 480 1.1 christos int comma = 0; 481 1.1 christos 482 1.1 christos *tmp_str = 0; 483 1.1 christos if (! (interrupts & 2)) 484 1.1 christos { 485 1.1 christos strcat (tmp_str, "vi"); 486 1.1 christos comma = 1; 487 1.1 christos } 488 1.1 christos if (! (interrupts & 1)) 489 1.1 christos { 490 1.1 christos if (comma) strcat (tmp_str, ","); 491 1.1 christos strcat (tmp_str, "nvi"); 492 1.1 christos } 493 1.1 christos } 494 1.1 christos 495 1.1 christos static void 496 1.1 christos print_flags(char *tmp_str, unsigned long flags) 497 1.1 christos { 498 1.1 christos int comma = 0; 499 1.1 christos 500 1.1 christos *tmp_str = 0; 501 1.1 christos if (flags & 8) 502 1.1 christos { 503 1.1 christos strcat (tmp_str, "c"); 504 1.1 christos comma = 1; 505 1.1 christos } 506 1.1 christos if (flags & 4) 507 1.1 christos { 508 1.1 christos if (comma) strcat (tmp_str, ","); 509 1.1 christos strcat (tmp_str, "z"); 510 1.1 christos comma = 1; 511 1.1 christos } 512 1.1 christos if (flags & 2) 513 1.1 christos { 514 1.1 christos if (comma) strcat (tmp_str, ","); 515 1.1 christos strcat (tmp_str, "s"); 516 1.1 christos comma = 1; 517 1.1 christos } 518 1.1 christos if (flags & 1) 519 1.1 christos { 520 1.1 christos if (comma) strcat (tmp_str, ","); 521 1.1 christos strcat (tmp_str, "p"); 522 1.1 christos } 523 1.1 christos } 524 1.1 christos 525 1.1 christos static void 526 1.1 christos unparse_instr (instr_data_s *instr_data, int is_segmented) 527 1.1 christos { 528 1.1 christos unsigned short datum_value; 529 1.1 christos unsigned int tabl_datum, datum_class; 530 1.1 christos int loop, loop_limit; 531 1.1 christos char out_str[80], tmp_str[25]; 532 1.1 christos 533 1.1 christos sprintf (out_str, "%s\t", z8k_table[instr_data->tabl_index].name); 534 1.1 christos 535 1.1 christos loop_limit = z8k_table[instr_data->tabl_index].noperands; 536 1.1 christos for (loop = 0; loop < loop_limit; loop++) 537 1.1 christos { 538 1.1 christos if (loop) 539 1.1 christos strcat (out_str, ","); 540 1.1 christos 541 1.1 christos tabl_datum = z8k_table[instr_data->tabl_index].arg_info[loop]; 542 1.1 christos datum_class = tabl_datum & CLASS_MASK; 543 1.1 christos datum_value = tabl_datum & ~CLASS_MASK; 544 1.1 christos 545 1.1 christos switch (datum_class) 546 1.1 christos { 547 1.1 christos case CLASS_X: 548 1.1 christos sprintf (tmp_str, "0x%0lx(r%ld)", instr_data->address, 549 1.1 christos instr_data->arg_reg[datum_value]); 550 1.1 christos strcat (out_str, tmp_str); 551 1.1 christos break; 552 1.1 christos case CLASS_BA: 553 1.1 christos if (is_segmented) 554 1.1 christos sprintf (tmp_str, "rr%ld(#0x%lx)", instr_data->arg_reg[datum_value], 555 1.1 christos instr_data->immediate); 556 1.1 christos else 557 1.1 christos sprintf (tmp_str, "r%ld(#0x%lx)", instr_data->arg_reg[datum_value], 558 1.1 christos instr_data->immediate); 559 1.1 christos strcat (out_str, tmp_str); 560 1.1 christos break; 561 1.1 christos case CLASS_BX: 562 1.1 christos if (is_segmented) 563 1.1 christos sprintf (tmp_str, "rr%ld(r%ld)", instr_data->arg_reg[datum_value], 564 1.1 christos instr_data->arg_reg[ARG_RX]); 565 1.1 christos else 566 1.1 christos sprintf (tmp_str, "r%ld(r%ld)", instr_data->arg_reg[datum_value], 567 1.1 christos instr_data->arg_reg[ARG_RX]); 568 1.1 christos strcat (out_str, tmp_str); 569 1.1 christos break; 570 1.1 christos case CLASS_DISP: 571 1.1 christos sprintf (tmp_str, "0x%0lx", instr_data->displacement); 572 1.1 christos strcat (out_str, tmp_str); 573 1.1 christos break; 574 1.1 christos case CLASS_IMM: 575 1.1 christos if (datum_value == ARG_IMM2) /* True with EI/DI instructions only. */ 576 1.1 christos { 577 1.1 christos print_intr (tmp_str, instr_data->interrupts); 578 1.1 christos strcat (out_str, tmp_str); 579 1.1 christos break; 580 1.1 christos } 581 1.1 christos sprintf (tmp_str, "#0x%0lx", instr_data->immediate); 582 1.1 christos strcat (out_str, tmp_str); 583 1.1 christos break; 584 1.1 christos case CLASS_CC: 585 1.1 christos sprintf (tmp_str, "%s", codes[instr_data->cond_code]); 586 1.1 christos strcat (out_str, tmp_str); 587 1.1 christos break; 588 1.1 christos case CLASS_CTRL: 589 1.1 christos sprintf (tmp_str, "%s", ctrl_names[instr_data->ctrl_code]); 590 1.1 christos strcat (out_str, tmp_str); 591 1.1 christos break; 592 1.1 christos case CLASS_DA: 593 1.1 christos case CLASS_ADDRESS: 594 1.1 christos sprintf (tmp_str, "0x%0lx", instr_data->address); 595 1.1 christos strcat (out_str, tmp_str); 596 1.1 christos break; 597 1.1 christos case CLASS_IR: 598 1.1 christos if (is_segmented) 599 1.1 christos sprintf (tmp_str, "@rr%ld", instr_data->arg_reg[datum_value]); 600 1.1 christos else 601 1.1 christos sprintf (tmp_str, "@r%ld", instr_data->arg_reg[datum_value]); 602 1.1 christos strcat (out_str, tmp_str); 603 1.1 christos break; 604 1.1 christos case CLASS_IRO: 605 1.1 christos sprintf (tmp_str, "@r%ld", instr_data->arg_reg[datum_value]); 606 1.1 christos strcat (out_str, tmp_str); 607 1.1 christos break; 608 1.1 christos case CLASS_FLAGS: 609 1.1 christos print_flags(tmp_str, instr_data->flags); 610 1.1 christos strcat (out_str, tmp_str); 611 1.1 christos break; 612 1.1 christos case CLASS_REG_BYTE: 613 1.1 christos if (instr_data->arg_reg[datum_value] >= 0x8) 614 1.1 christos sprintf (tmp_str, "rl%ld", 615 1.1 christos instr_data->arg_reg[datum_value] - 0x8); 616 1.1 christos else 617 1.1 christos sprintf (tmp_str, "rh%ld", instr_data->arg_reg[datum_value]); 618 1.1 christos strcat (out_str, tmp_str); 619 1.1 christos break; 620 1.1 christos case CLASS_REG_WORD: 621 1.1 christos sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]); 622 1.1 christos strcat (out_str, tmp_str); 623 1.1 christos break; 624 1.1 christos case CLASS_REG_QUAD: 625 1.1 christos sprintf (tmp_str, "rq%ld", instr_data->arg_reg[datum_value]); 626 1.1 christos strcat (out_str, tmp_str); 627 1.1 christos break; 628 1.1 christos case CLASS_REG_LONG: 629 1.1 christos sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]); 630 1.1 christos strcat (out_str, tmp_str); 631 1.1 christos break; 632 1.1 christos case CLASS_PR: 633 1.1 christos if (is_segmented) 634 1.1 christos sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]); 635 1.1 christos else 636 1.1 christos sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]); 637 1.1 christos strcat (out_str, tmp_str); 638 1.1 christos break; 639 1.1 christos default: 640 1.1 christos abort (); 641 1.1 christos break; 642 1.1 christos } 643 1.1 christos } 644 1.1 christos 645 1.1 christos strcpy (instr_data->instr_asmsrc, out_str); 646 1.1 christos } 647