Changeset 609 for branches/GNU/src/binutils/opcodes/z8k-dis.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/opcodes/z8k-dis.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 1 1 /* Disassemble z8000 code. 2 Copyright 1992, 1993, 1998, 2000 2 Copyright 1992, 1993, 1998, 2000, 2001, 2002 3 3 Free Software Foundation, Inc. 4 4 5 This file is part of GNU Binutils. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 5 This file is part of GNU Binutils. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 20 USA. */ 20 21 21 22 #include "sysdep.h" … … 55 56 instr_data_s; 56 57 58 static int fetch_data PARAMS ((struct disassemble_info *, int)); 59 60 57 61 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) 58 62 to ADDR (exclusive) are valid. Returns 1 for success, longjmps 59 63 on error. */ 60 64 #define FETCH_DATA(info, nibble) \ 61 ((nibble) < ((instr_data_s *) (info->private_data))->max_fetched \65 ((nibble) < ((instr_data_s *) (info->private_data))->max_fetched \ 62 66 ? 1 : fetch_data ((info), (nibble))) 63 67 … … 109 113 110 114 static char *codes[16] = 111 { 112 "f", 113 "lt", 114 "le", 115 "ule", 116 "ov/pe", 117 "mi", 118 "eq", 119 "c/ult", 120 "t", 121 "ge", 122 "gt", 123 "ugt", 124 "nov/po", 125 "pl", 126 "ne", 127 "nc/uge" 128 }; 129 115 { 116 "f", 117 "lt", 118 "le", 119 "ule", 120 "ov/pe", 121 "mi", 122 "eq", 123 "c/ult", 124 "t", 125 "ge", 126 "gt", 127 "ugt", 128 "nov/po", 129 "pl", 130 "ne", 131 "nc/uge" 132 }; 133 134 static char *ctrl_names[8] = 135 { 136 "<invld>", 137 "flags", 138 "fcw", 139 "refresh", 140 "psapseg", 141 "psapoff", 142 "nspseg", 143 "nspoff" 144 }; 145 146 static int seg_length; 147 static int print_insn_z8k PARAMS ((bfd_vma, disassemble_info *, int)); 130 148 int z8k_lookup_instr PARAMS ((unsigned char *, disassemble_info *)); 131 149 static void output_instr 132 150 PARAMS ((instr_data_s *, unsigned long, disassemble_info *)); 133 151 static void unpack_instr PARAMS ((instr_data_s *, int, disassemble_info *)); 134 static void unparse_instr PARAMS ((instr_data_s * ));152 static void unparse_instr PARAMS ((instr_data_s *, int)); 135 153 136 154 static int … … 149 167 return -1; 150 168 169 info->bytes_per_chunk = 2; 170 info->bytes_per_line = 6; 171 info->display_endian = BFD_ENDIAN_BIG; 172 151 173 instr_data.tabl_index = z8k_lookup_instr (instr_data.nibbles, info); 152 174 if (instr_data.tabl_index > 0) 153 175 { 154 176 unpack_instr (&instr_data, is_segmented, info); 155 unparse_instr (&instr_data );177 unparse_instr (&instr_data, is_segmented); 156 178 output_instr (&instr_data, addr, info); 157 return z8k_table[instr_data.tabl_index].length ;179 return z8k_table[instr_data.tabl_index].length + seg_length; 158 180 } 159 181 else … … 190 212 int nibl_index, tabl_index; 191 213 int nibl_matched; 214 int need_fetch = 0; 192 215 unsigned short instr_nibl; 193 216 unsigned short tabl_datum, datum_class, datum_value; … … 195 218 nibl_matched = 0; 196 219 tabl_index = 0; 220 FETCH_DATA (info, 4); 197 221 while (!nibl_matched && z8k_table[tabl_index].name) 198 222 { … … 203 227 { 204 228 if ((nibl_index % 4) == 0) 205 /* Fetch one word at a time. */ 206 FETCH_DATA (info, nibl_index + 4); 229 { 230 /* Fetch data only if it isn't already there. */ 231 if (nibl_index >= 4 || (nibl_index < 4 && need_fetch)) 232 FETCH_DATA (info, nibl_index + 4); /* Fetch one word at a time. */ 233 if (nibl_index < 4) 234 need_fetch = 0; 235 else 236 need_fetch = 1; 237 } 207 238 instr_nibl = nibbles[nibl_index]; 208 239 … … 217 248 nibl_matched = 0; 218 249 break; 250 case CLASS_IGNORE: 251 break; 219 252 case CLASS_00II: 220 253 if (!((~instr_nibl) & 0x4)) … … 255 288 } 256 289 } 290 257 291 if (nibl_matched) 258 { 259 return tabl_index; 260 } 292 return tabl_index; 261 293 262 294 tabl_index++; 263 295 } 264 296 return -1; 265 266 297 } 267 298 … … 269 300 output_instr (instr_data, addr, info) 270 301 instr_data_s *instr_data; 271 unsigned long addr ;302 unsigned long addr ATTRIBUTE_UNUSED; 272 303 disassemble_info *info; 273 304 { 274 int loop, loop_limit; 275 char tmp_str[20]; 305 int num_bytes; 276 306 char out_str[100]; 277 307 278 strcpy (out_str, "\t"); 279 280 loop_limit = z8k_table[instr_data->tabl_index].length * 2; 281 FETCH_DATA (info, loop_limit); 282 for (loop = 0; loop < loop_limit; loop++) 283 { 284 sprintf (tmp_str, "%x", instr_data->nibbles[loop]); 285 strcat (out_str, tmp_str); 286 } 287 288 while (loop++ < 8) 289 { 290 strcat (out_str, " "); 291 } 308 out_str[0] = 0; 309 310 num_bytes = (z8k_table[instr_data->tabl_index].length + seg_length) * 2; 311 FETCH_DATA (info, num_bytes); 292 312 293 313 strcat (out_str, instr_data->instr_asmsrc); … … 305 325 unsigned short instr_nibl, instr_byte, instr_word; 306 326 long instr_long; 307 unsigned short tabl_datum, datum_class, datum_value; 327 unsigned int tabl_datum, datum_class; 328 unsigned short datum_value; 308 329 309 330 nibl_count = 0; 310 331 loop = 0; 332 seg_length = 0; 333 311 334 while (z8k_table[instr_data->tabl_index].byte_info[loop] != 0) 312 335 { 313 336 FETCH_DATA (info, nibl_count + 4 - (nibl_count % 4)); 314 337 instr_nibl = instr_data->nibbles[nibl_count]; 315 instr_byte = instr_data->bytes[nibl_count ];316 instr_word = instr_data->words[nibl_count ];338 instr_byte = instr_data->bytes[nibl_count & ~1]; 339 instr_word = instr_data->words[nibl_count & ~3]; 317 340 318 341 tabl_datum = z8k_table[instr_data->tabl_index].byte_info[loop]; … … 322 345 switch (datum_class) 323 346 { 324 case CLASS_X:325 instr_data->address = instr_nibl;326 break;327 case CLASS_BA:328 instr_data->displacement = instr_nibl;329 break;330 case CLASS_BX:331 instr_data->arg_reg[datum_value] = instr_nibl;332 break;333 347 case CLASS_DISP: 334 348 switch (datum_value) 335 349 { 336 350 case ARG_DISP16: 337 instr_data->displacement = instr_word; 351 instr_data->displacement = instr_data->insn_start + 4 352 + (signed short) (instr_word & 0xffff); 338 353 nibl_count += 3; 339 354 break; 340 355 case ARG_DISP12: 341 instr_data->displacement = instr_word & 0x0fff; 356 if (instr_word & 0x800) 357 /* Negative 12 bit displacement. */ 358 instr_data->displacement = instr_data->insn_start + 2 359 - (signed short) ((instr_word & 0xfff) | 0xf000) * 2; 360 else 361 instr_data->displacement = instr_data->insn_start + 2 362 - (instr_word & 0x0fff) * 2; 363 342 364 nibl_count += 2; 343 365 break; … … 352 374 instr_data->immediate = instr_nibl; 353 375 break; 376 case ARG_NIM4: 377 instr_data->immediate = (- instr_nibl) & 0xf; 378 break; 354 379 case ARG_NIM8: 355 instr_data->immediate = (- instr_byte);380 instr_data->immediate = (- instr_byte) & 0xff; 356 381 nibl_count += 1; 357 382 break; … … 393 418 instr_data->cond_code = instr_nibl; 394 419 break; 395 case CLASS_CTRL:396 instr_data->ctrl_code = instr_nibl;397 break;398 case CLASS_DA:399 420 case CLASS_ADDRESS: 400 421 if (is_segmented) … … 405 426 instr_long = (instr_data->words[nibl_count] << 16) 406 427 | (instr_data->words[nibl_count + 4]); 407 instr_data->address = ((instr_word & 0x7f00) << 8) +408 (instr_long & 0xffff);428 instr_data->address = ((instr_word & 0x7f00) << 16) 429 + (instr_long & 0xffff); 409 430 nibl_count += 7; 431 seg_length = 2; 410 432 } 411 433 else 412 434 { 413 instr_data->address = ((instr_word & 0x7f00) << 8) +414 (instr_word & 0x00ff);435 instr_data->address = ((instr_word & 0x7f00) << 16) 436 + (instr_word & 0x00ff); 415 437 nibl_count += 3; 416 438 } … … 423 445 break; 424 446 case CLASS_0CCC: 425 instr_data->cond_code = instr_nibl & 0x7;426 break;427 447 case CLASS_1CCC: 428 instr_data->c ond_code = instr_nibl & 0x7;448 instr_data->ctrl_code = instr_nibl & 0x7; 429 449 break; 430 450 case CLASS_0DISP7: 431 instr_data->displacement = instr_byte & 0x7f; 451 instr_data->displacement = 452 instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2; 432 453 nibl_count += 1; 433 454 break; 434 455 case CLASS_1DISP7: 435 instr_data->displacement = instr_byte & 0x7f; 456 instr_data->displacement = 457 instr_data->insn_start + 2 - (instr_byte & 0x7f) * 2; 436 458 nibl_count += 1; 437 459 break; … … 442 464 instr_data->interrupts = instr_nibl & 0x3; 443 465 break; 466 case CLASS_IGNORE: 444 467 case CLASS_BIT: 445 /* Do nothing. */ 446 break; 447 case CLASS_IR: 448 instr_data->arg_reg[datum_value] = instr_nibl; 468 instr_data->ctrl_code = instr_nibl & 0x7; 449 469 break; 450 470 case CLASS_FLAGS: … … 454 474 instr_data->arg_reg[datum_value] = instr_nibl; 455 475 break; 456 case CLASS_REG_BYTE:457 instr_data->arg_reg[datum_value] = instr_nibl;458 break;459 case CLASS_REG_WORD:460 instr_data->arg_reg[datum_value] = instr_nibl;461 break;462 case CLASS_REG_QUAD:463 instr_data->arg_reg[datum_value] = instr_nibl;464 break;465 case CLASS_REG_LONG:466 instr_data->arg_reg[datum_value] = instr_nibl;467 break;468 476 case CLASS_REGN0: 469 477 instr_data->arg_reg[datum_value] = instr_nibl; 470 478 break; 479 case CLASS_DISP8: 480 instr_data->displacement = 481 instr_data->insn_start + 2 + (signed char) instr_byte * 2; 482 nibl_count += 1; 483 break; 484 case CLASS_BIT_1OR2: 485 instr_data->immediate = ((instr_nibl >> 1) & 0x1) + 1; 486 nibl_count += 1; 487 break; 471 488 default: 489 abort (); 472 490 break; 473 491 } … … 478 496 } 479 497 498 static char *intr_names[] = { 499 "all", /* 0 */ 500 "vi", /* 1 */ 501 "nvi", /* 2 */ 502 "none" /* 3 */ 503 }; 504 480 505 static void 481 unparse_instr (instr_data )506 unparse_instr (instr_data, is_segmented) 482 507 instr_data_s *instr_data; 483 { 484 unsigned short tabl_datum, datum_class, datum_value; 508 int is_segmented; 509 { 510 unsigned short datum_value; 511 unsigned int tabl_datum, datum_class; 485 512 int loop, loop_limit; 486 513 char out_str[80], tmp_str[25]; 487 514 488 sprintf (out_str, " \t%s\t", z8k_table[instr_data->tabl_index].name);515 sprintf (out_str, "%s\t", z8k_table[instr_data->tabl_index].name); 489 516 490 517 loop_limit = z8k_table[instr_data->tabl_index].noperands; … … 501 528 { 502 529 case CLASS_X: 503 sprintf (tmp_str, "0x%0lx(R%ld)", instr_data->address,504 530 sprintf (tmp_str, "0x%0lx(r%ld)", instr_data->address, 531 instr_data->arg_reg[datum_value]); 505 532 strcat (out_str, tmp_str); 506 533 break; 507 534 case CLASS_BA: 508 sprintf (tmp_str, "r%ld(#%lx)", instr_data->arg_reg[datum_value], 509 instr_data->immediate); 535 if (is_segmented) 536 sprintf (tmp_str, "rr%ld(#0x%lx)", instr_data->arg_reg[datum_value], 537 instr_data->immediate); 538 else 539 sprintf (tmp_str, "r%ld(#0x%lx)", instr_data->arg_reg[datum_value], 540 instr_data->immediate); 510 541 strcat (out_str, tmp_str); 511 542 break; 512 543 case CLASS_BX: 513 sprintf (tmp_str, "r%ld(R%ld)", instr_data->arg_reg[datum_value], 514 instr_data->arg_reg[ARG_RX]); 544 if (is_segmented) 545 sprintf (tmp_str, "rr%ld(r%ld)", instr_data->arg_reg[datum_value], 546 instr_data->arg_reg[ARG_RX]); 547 else 548 sprintf (tmp_str, "r%ld(r%ld)", instr_data->arg_reg[datum_value], 549 instr_data->arg_reg[ARG_RX]); 515 550 strcat (out_str, tmp_str); 516 551 break; 517 552 case CLASS_DISP: 518 sprintf (tmp_str, " #0x%0lx", instr_data->displacement);553 sprintf (tmp_str, "0x%0lx", instr_data->displacement); 519 554 strcat (out_str, tmp_str); 520 555 break; 521 556 case CLASS_IMM: 557 if (datum_value == ARG_IMM2) /* True with EI/DI instructions only. */ 558 { 559 sprintf (tmp_str, "%s", intr_names[instr_data->interrupts]); 560 strcat (out_str, tmp_str); 561 break; 562 } 522 563 sprintf (tmp_str, "#0x%0lx", instr_data->immediate); 523 564 strcat (out_str, tmp_str); … … 528 569 break; 529 570 case CLASS_CTRL: 530 sprintf (tmp_str, " 0x%0lx", instr_data->ctrl_code);571 sprintf (tmp_str, "%s", ctrl_names[instr_data->ctrl_code]); 531 572 strcat (out_str, tmp_str); 532 573 break; 533 574 case CLASS_DA: 534 575 case CLASS_ADDRESS: 535 sprintf (tmp_str, " #0x%0lx", instr_data->address);576 sprintf (tmp_str, "0x%0lx", instr_data->address); 536 577 strcat (out_str, tmp_str); 537 578 break; 538 579 case CLASS_IR: 539 sprintf (tmp_str, "@R%ld", instr_data->arg_reg[datum_value]); 580 if (is_segmented) 581 sprintf (tmp_str, "@rr%ld", instr_data->arg_reg[datum_value]); 582 else 583 sprintf (tmp_str, "@r%ld", instr_data->arg_reg[datum_value]); 540 584 strcat (out_str, tmp_str); 541 585 break; … … 546 590 case CLASS_REG_BYTE: 547 591 if (instr_data->arg_reg[datum_value] >= 0x8) 548 { 549 sprintf (tmp_str, "rl%ld", 550 instr_data->arg_reg[datum_value] - 0x8); 551 } 592 sprintf (tmp_str, "rl%ld", 593 instr_data->arg_reg[datum_value] - 0x8); 552 594 else 553 { 554 sprintf (tmp_str, "rh%ld", instr_data->arg_reg[datum_value]); 555 } 595 sprintf (tmp_str, "rh%ld", instr_data->arg_reg[datum_value]); 556 596 strcat (out_str, tmp_str); 557 597 break; … … 568 608 strcat (out_str, tmp_str); 569 609 break; 610 case CLASS_PR: 611 if (is_segmented) 612 sprintf (tmp_str, "rr%ld", instr_data->arg_reg[datum_value]); 613 else 614 sprintf (tmp_str, "r%ld", instr_data->arg_reg[datum_value]); 615 strcat (out_str, tmp_str); 616 break; 570 617 default: 618 abort (); 571 619 break; 572 620 } -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.