1 /* tc-z8k.c -- Assemble code for the Zilog Z800n 2 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2003, 3 2005, 2006, 2007, 2009 Free Software Foundation, Inc. 4 5 This file is part of GAS, the GNU Assembler. 6 7 GAS 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 3, or (at your option) 10 any later version. 11 12 GAS 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 GAS; see the file COPYING. If not, write to the Free 19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22 /* Written By Steve Chamberlain <sac@cygnus.com>. */ 23 24 #include "as.h" 25 #include "safe-ctype.h" 26 #define DEFINE_TABLE 27 #include "opcodes/z8k-opc.h" 28 29 const char comment_chars[] = "!"; 30 const char line_comment_chars[] = "#"; 31 const char line_separator_chars[] = ";"; 32 33 extern int machine; 34 extern int coff_flags; 35 int segmented_mode; 36 37 /* This is non-zero if target was set from the command line. */ 38 static int z8k_target_from_cmdline; 39 40 static void 41 s_segm (int segm) 42 { 43 if (segm) 44 { 45 segmented_mode = 1; 46 bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8001); 47 } 48 else 49 { 50 segmented_mode = 0; 51 bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8002); 52 } 53 } 54 55 static void 56 even (int ignore ATTRIBUTE_UNUSED) 57 { 58 frag_align (1, 0, 0); 59 record_alignment (now_seg, 1); 60 } 61 62 static int 63 tohex (int c) 64 { 65 if (ISDIGIT (c)) 66 return c - '0'; 67 if (ISLOWER (c)) 68 return c - 'a' + 10; 69 return c - 'A' + 10; 70 } 71 72 static void 73 sval (int ignore ATTRIBUTE_UNUSED) 74 { 75 SKIP_WHITESPACE (); 76 if (*input_line_pointer == '\'') 77 { 78 int c; 79 input_line_pointer++; 80 c = *input_line_pointer++; 81 while (c != '\'') 82 { 83 if (c == '%') 84 { 85 c = (tohex (input_line_pointer[0]) << 4) 86 | tohex (input_line_pointer[1]); 87 input_line_pointer += 2; 88 } 89 FRAG_APPEND_1_CHAR (c); 90 c = *input_line_pointer++; 91 } 92 demand_empty_rest_of_line (); 93 } 94 } 95 96 /* This table describes all the machine specific pseudo-ops the assembler 97 has to support. The fields are: 98 pseudo-op name without dot 99 function to call to execute this pseudo-op 100 Integer arg to pass to the function 101 */ 102 103 const pseudo_typeS md_pseudo_table[] = { 104 {"int" , cons , 2}, 105 {"data.b" , cons , 1}, 106 {"data.w" , cons , 2}, 107 {"data.l" , cons , 4}, 108 {"form" , listing_psize , 0}, 109 {"heading", listing_title , 0}, 110 {"import" , s_ignore , 0}, 111 {"page" , listing_eject , 0}, 112 {"program", s_ignore , 0}, 113 {"z8001" , s_segm , 1}, 114 {"z8002" , s_segm , 0}, 115 116 {"segm" , s_segm , 1}, 117 {"unsegm" , s_segm , 0}, 118 {"unseg" , s_segm , 0}, 119 {"name" , s_app_file , 0}, 120 {"global" , s_globl , 0}, 121 {"wval" , cons , 2}, 122 {"lval" , cons , 4}, 123 {"bval" , cons , 1}, 124 {"sval" , sval , 0}, 125 {"rsect" , obj_coff_section, 0}, 126 {"sect" , obj_coff_section, 0}, 127 {"block" , s_space , 0}, 128 {"even" , even , 0}, 129 {0 , 0 , 0} 130 }; 131 132 const char EXP_CHARS[] = "eE"; 133 134 /* Chars that mean this number is a floating point constant. 135 As in 0f12.456 136 or 0d1.2345e12 */ 137 const char FLT_CHARS[] = "rRsSfFdDxXpP"; 138 139 /* Opcode mnemonics. */ 140 static struct hash_control *opcode_hash_control; 141 142 void 143 md_begin (void) 144 { 145 const opcode_entry_type *opcode; 146 int idx = -1; 147 148 opcode_hash_control = hash_new (); 149 150 for (opcode = z8k_table; opcode->name; opcode++) 151 { 152 /* Only enter unique codes into the table. */ 153 if (idx != opcode->idx) 154 hash_insert (opcode_hash_control, opcode->name, (char *) opcode); 155 idx = opcode->idx; 156 } 157 158 /* Default to z8002. */ 159 if (! z8k_target_from_cmdline) 160 s_segm (0); 161 162 /* Insert the pseudo ops, too. */ 163 for (idx = 0; md_pseudo_table[idx].poc_name; idx++) 164 { 165 opcode_entry_type *fake_opcode; 166 fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type)); 167 fake_opcode->name = md_pseudo_table[idx].poc_name; 168 fake_opcode->func = (void *) (md_pseudo_table + idx); 169 fake_opcode->opcode = 250; 170 hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode); 171 } 172 } 173 174 typedef struct z8k_op { 175 /* CLASS_REG_xxx. */ 176 int regsize; 177 178 /* 0 .. 15. */ 179 unsigned int reg; 180 181 int mode; 182 183 /* Any other register associated with the mode. */ 184 unsigned int x_reg; 185 186 /* Any expression. */ 187 expressionS exp; 188 } op_type; 189 190 static expressionS *da_operand; 191 static expressionS *imm_operand; 192 193 static int reg[16]; 194 static int the_cc; 195 static int the_ctrl; 196 static int the_flags; 197 static int the_interrupt; 198 199 /* Determine register number. src points to the ascii number 200 (after "rl", "rh", "r", "rr", or "rq"). If a character 201 outside the set of {0,',',')','('} follows the number, 202 return NULL to indicate that it's not a valid register 203 number. */ 204 205 static char * 206 whatreg (unsigned int *preg, char *src) 207 { 208 unsigned int new_reg; 209 210 /* src[0] is already known to be a digit. */ 211 if (ISDIGIT (src[1])) 212 { 213 new_reg = (src[0] - '0') * 10 + src[1] - '0'; 214 src += 2; 215 } 216 else 217 { 218 new_reg = (src[0] - '0'); 219 src += 1; 220 } 221 222 if (src[0] != 0 && src[0] != ',' && src[0] != '(' && src[0] != ')') 223 return NULL; 224 225 *preg = new_reg; 226 return src; 227 } 228 229 /* Parse operands 230 231 rh0-rh7, rl0-rl7 232 r0-r15 233 rr0-rr14 234 rq0--rq12 235 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp 236 r0l,r0h,..r7l,r7h 237 @WREG 238 @WREG+ 239 @-WREG 240 #const 241 */ 242 243 /* Try to parse a reg name. Return a pointer to the first character 244 in SRC after the reg name. */ 245 246 static char * 247 parse_reg (char *src, int *mode, unsigned int *preg) 248 { 249 char *res = NULL; 250 char regno; 251 252 /* Check for stack pointer "sp" alias. */ 253 if ((src[0] == 's' || src[0] == 'S') 254 && (src[1] == 'p' || src[1] == 'P') 255 && (src[2] == 0 || src[2] == ',')) 256 { 257 if (segmented_mode) 258 { 259 *mode = CLASS_REG_LONG; 260 *preg = 14; 261 } 262 else 263 { 264 *mode = CLASS_REG_WORD; 265 *preg = 15; 266 } 267 return src + 2; 268 } 269 270 if (src[0] == 'r' || src[0] == 'R') 271 { 272 if (src[1] == 'r' || src[1] == 'R') 273 { 274 if (src[2] < '0' || src[2] > '9') 275 return NULL; /* Assume no register name but a label starting with 'rr'. */ 276 *mode = CLASS_REG_LONG; 277 res = whatreg (preg, src + 2); 278 if (res == NULL) 279 return NULL; /* Not a valid register name. */ 280 regno = *preg; 281 if (regno > 14) 282 as_bad (_("register rr%d out of range"), regno); 283 if (regno & 1) 284 as_bad (_("register rr%d does not exist"), regno); 285 } 286 else if (src[1] == 'h' || src[1] == 'H') 287 { 288 if (src[2] < '0' || src[2] > '9') 289 return NULL; /* Assume no register name but a label starting with 'rh'. */ 290 *mode = CLASS_REG_BYTE; 291 res = whatreg (preg, src + 2); 292 if (res == NULL) 293 return NULL; /* Not a valid register name. */ 294 regno = *preg; 295 if (regno > 7) 296 as_bad (_("register rh%d out of range"), regno); 297 } 298 else if (src[1] == 'l' || src[1] == 'L') 299 { 300 if (src[2] < '0' || src[2] > '9') 301 return NULL; /* Assume no register name but a label starting with 'rl'. */ 302 *mode = CLASS_REG_BYTE; 303 res = whatreg (preg, src + 2); 304 if (res == NULL) 305 return NULL; /* Not a valid register name. */ 306 regno = *preg; 307 if (regno > 7) 308 as_bad (_("register rl%d out of range"), regno); 309 *preg += 8; 310 } 311 else if (src[1] == 'q' || src[1] == 'Q') 312 { 313 if (src[2] < '0' || src[2] > '9') 314 return NULL; /* Assume no register name but a label starting with 'rq'. */ 315 *mode = CLASS_REG_QUAD; 316 res = whatreg (preg, src + 2); 317 if (res == NULL) 318 return NULL; /* Not a valid register name. */ 319 regno = *preg; 320 if (regno > 12) 321 as_bad (_("register rq%d out of range"), regno); 322 if (regno & 3) 323 as_bad (_("register rq%d does not exist"), regno); 324 } 325 else 326 { 327 if (src[1] < '0' || src[1] > '9') 328 return NULL; /* Assume no register name but a label starting with 'r'. */ 329 *mode = CLASS_REG_WORD; 330 res = whatreg (preg, src + 1); 331 if (res == NULL) 332 return NULL; /* Not a valid register name. */ 333 regno = *preg; 334 if (regno > 15) 335 as_bad (_("register r%d out of range"), regno); 336 } 337 } 338 return res; 339 } 340 341 static char * 342 parse_exp (char *s, expressionS *op) 343 { 344 char *save = input_line_pointer; 345 char *new_pointer; 346 347 input_line_pointer = s; 348 expression (op); 349 if (op->X_op == O_absent) 350 as_bad (_("missing operand")); 351 new_pointer = input_line_pointer; 352 input_line_pointer = save; 353 return new_pointer; 354 } 355 356 /* The many forms of operand: 357 358 <rb> 359 <r> 360 <rr> 361 <rq> 362 @r 363 #exp 364 exp 365 exp(r) 366 r(#exp) 367 r(r) 368 */ 369 370 static char * 371 checkfor (char *ptr, char what) 372 { 373 if (*ptr == what) 374 ptr++; 375 else 376 as_bad (_("expected %c"), what); 377 378 return ptr; 379 } 380 381 /* Make sure the mode supplied is the size of a word. */ 382 383 static void 384 regword (int mode, char *string) 385 { 386 int ok; 387 388 ok = CLASS_REG_WORD; 389 if (ok != mode) 390 { 391 as_bad (_("register is wrong size for a word %s"), string); 392 } 393 } 394 395 /* Make sure the mode supplied is the size of an address. */ 396 397 static void 398 regaddr (int mode, char *string) 399 { 400 int ok; 401 402 ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD; 403 if (ok != mode) 404 { 405 as_bad (_("register is wrong size for address %s"), string); 406 } 407 } 408 409 struct ctrl_names { 410 int value; 411 char *name; 412 }; 413 414 static struct ctrl_names ctrl_table[] = { 415 { 0x1, "flags" }, /* ldctlb only. */ 416 { 0x2, "fcw" }, /* ldctl only. Applies to all remaining control registers. */ 417 { 0x3, "refresh" }, 418 { 0x4, "psapseg" }, 419 { 0x5, "psapoff" }, 420 { 0x5, "psap" }, 421 { 0x6, "nspseg" }, 422 { 0x7, "nspoff" }, 423 { 0x7, "nsp" }, 424 { 0 , 0 } 425 }; 426 427 static void 428 get_ctrl_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 429 { 430 char *src = *ptr; 431 int i, l; 432 433 while (*src == ' ') 434 src++; 435 436 mode->mode = CLASS_CTRL; 437 for (i = 0; ctrl_table[i].name; i++) 438 { 439 l = strlen (ctrl_table[i].name); 440 if (! strncasecmp (ctrl_table[i].name, src, l)) 441 { 442 the_ctrl = ctrl_table[i].value; 443 if (*(src + l) && *(src + l) != ',') 444 break; 445 *ptr = src + l; /* Valid control name found: "consume" it. */ 446 return; 447 } 448 } 449 the_ctrl = 0; 450 } 451 452 struct flag_names { 453 int value; 454 char *name; 455 }; 456 457 static struct flag_names flag_table[] = { 458 { 0x1, "P" }, 459 { 0x1, "V" }, 460 { 0x2, "S" }, 461 { 0x4, "Z" }, 462 { 0x8, "C" }, 463 { 0x0, "+" }, 464 { 0x0, "," }, 465 { 0, 0 } 466 }; 467 468 static void 469 get_flags_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 470 { 471 char *src = *ptr; 472 char c; 473 int i; 474 int j; 475 476 while (*src == ' ') 477 src++; 478 479 mode->mode = CLASS_FLAGS; 480 the_flags = 0; 481 for (j = 0; j <= 9; j++) 482 { 483 if (!src[j]) 484 goto done; 485 c = TOUPPER(src[j]); 486 for (i = 0; flag_table[i].name; i++) 487 { 488 if (flag_table[i].name[0] == c) 489 { 490 the_flags = the_flags | flag_table[i].value; 491 goto match; 492 } 493 } 494 goto done; 495 match: 496 ; 497 } 498 done: 499 *ptr = src + j; 500 } 501 502 struct interrupt_names { 503 int value; 504 char *name; 505 }; 506 507 static struct interrupt_names intr_table[] = { 508 { 0x1, "nvi" }, 509 { 0x2, "vi" }, 510 { 0x3, "both" }, 511 { 0x3, "all" }, 512 { 0, 0 } 513 }; 514 515 static void 516 get_interrupt_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 517 { 518 char *src = *ptr; 519 int i, l; 520 521 while (*src == ' ') 522 src++; 523 524 mode->mode = CLASS_IMM; 525 the_interrupt = 0; 526 527 while (*src) 528 { 529 for (i = 0; intr_table[i].name; i++) 530 { 531 l = strlen (intr_table[i].name); 532 if (! strncasecmp (intr_table[i].name, src, l)) 533 { 534 the_interrupt |= intr_table[i].value; 535 if (*(src + l) && *(src + l) != ',') 536 { 537 *ptr = src + l; 538 invalid: 539 as_bad (_("unknown interrupt %s"), src); 540 while (**ptr && ! is_end_of_line[(unsigned char) **ptr]) 541 (*ptr)++; /* Consume rest of line. */ 542 return; 543 } 544 src += l; 545 if (! *src) 546 { 547 *ptr = src; 548 return; 549 } 550 } 551 } 552 if (*src == ',') 553 src++; 554 else 555 { 556 *ptr = src; 557 goto invalid; 558 } 559 } 560 561 /* No interrupt type specified, opcode won't do anything. */ 562 as_warn (_("opcode has no effect")); 563 the_interrupt = 0x0; 564 } 565 566 struct cc_names { 567 int value; 568 char *name; 569 }; 570 571 static struct cc_names table[] = { 572 { 0x0, "f" }, 573 { 0x1, "lt" }, 574 { 0x2, "le" }, 575 { 0x3, "ule" }, 576 { 0x4, "ov/pe" }, 577 { 0x4, "ov" }, 578 { 0x4, "pe/ov" }, 579 { 0x4, "pe" }, 580 { 0x5, "mi" }, 581 { 0x6, "eq" }, 582 { 0x6, "z" }, 583 { 0x7, "c/ult" }, 584 { 0x7, "c" }, 585 { 0x7, "ult/c" }, 586 { 0x7, "ult" }, 587 { 0x8, "t" }, 588 { 0x9, "ge" }, 589 { 0xa, "gt" }, 590 { 0xb, "ugt" }, 591 { 0xc, "nov/po" }, 592 { 0xc, "nov" }, 593 { 0xc, "po/nov" }, 594 { 0xc, "po" }, 595 { 0xd, "pl" }, 596 { 0xe, "ne" }, 597 { 0xe, "nz" }, 598 { 0xf, "nc/uge" }, 599 { 0xf, "nc" }, 600 { 0xf, "uge/nc" }, 601 { 0xf, "uge" }, 602 { 0 , 0 } 603 }; 604 605 static void 606 get_cc_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 607 { 608 char *src = *ptr; 609 int i, l; 610 611 while (*src == ' ') 612 src++; 613 614 mode->mode = CLASS_CC; 615 for (i = 0; table[i].name; i++) 616 { 617 l = strlen (table[i].name); 618 if (! strncasecmp (table[i].name, src, l)) 619 { 620 the_cc = table[i].value; 621 if (*(src + l) && *(src + l) != ',') 622 break; 623 *ptr = src + l; /* Valid cc found: "consume" it. */ 624 return; 625 } 626 } 627 the_cc = 0x8; /* Not recognizing the cc defaults to t. (Assuming no cc present.) */ 628 } 629 630 static void 631 get_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 632 { 633 char *src = *ptr; 634 char *end; 635 636 mode->mode = 0; 637 638 while (*src == ' ') 639 src++; 640 if (*src == '#') 641 { 642 mode->mode = CLASS_IMM; 643 imm_operand = &(mode->exp); 644 src = parse_exp (src + 1, &(mode->exp)); 645 } 646 else if (*src == '@') 647 { 648 mode->mode = CLASS_IR; 649 src = parse_reg (src + 1, &mode->regsize, &mode->reg); 650 } 651 else 652 { 653 unsigned int regn; 654 655 end = parse_reg (src, &mode->mode, ®n); 656 657 if (end) 658 { 659 int nw; 660 unsigned int nr; 661 662 src = end; 663 if (*src == '(') 664 { 665 src++; 666 end = parse_reg (src, &nw, &nr); 667 if (end) 668 { 669 /* Got Ra(Rb). */ 670 src = end; 671 672 if (*src != ')') 673 as_bad (_("Missing ) in ra(rb)")); 674 else 675 src++; 676 677 regaddr (mode->mode, "ra(rb) ra"); 678 mode->mode = CLASS_BX; 679 mode->reg = regn; 680 mode->x_reg = nr; 681 reg[ARG_RX] = nr; 682 } 683 else 684 { 685 /* Got Ra(disp). */ 686 if (*src == '#') 687 src++; 688 src = parse_exp (src, &(mode->exp)); 689 src = checkfor (src, ')'); 690 mode->mode = CLASS_BA; 691 mode->reg = regn; 692 mode->x_reg = 0; 693 imm_operand = &(mode->exp); 694 } 695 } 696 else 697 { 698 mode->reg = regn; 699 mode->x_reg = 0; 700 } 701 } 702 else 703 { 704 /* No initial reg. */ 705 src = parse_exp (src, &(mode->exp)); 706 if (*src == '(') 707 { 708 src++; 709 end = parse_reg (src, &(mode->mode), ®n); 710 regword (mode->mode, "addr(Ra) ra"); 711 mode->mode = CLASS_X; 712 mode->reg = regn; 713 mode->x_reg = 0; 714 da_operand = &(mode->exp); 715 src = checkfor (end, ')'); 716 } 717 else 718 { 719 /* Just an address. */ 720 mode->mode = CLASS_DA; 721 mode->reg = 0; 722 mode->x_reg = 0; 723 da_operand = &(mode->exp); 724 } 725 } 726 } 727 *ptr = src; 728 } 729 730 static char * 731 get_operands (const opcode_entry_type *opcode, char *op_end, op_type *operand) 732 { 733 char *ptr = op_end; 734 char *savptr; 735 736 switch (opcode->noperands) 737 { 738 case 0: 739 operand[0].mode = 0; 740 operand[1].mode = 0; 741 while (*ptr == ' ') 742 ptr++; 743 break; 744 745 case 1: 746 if (opcode->arg_info[0] == CLASS_CC) 747 { 748 get_cc_operand (&ptr, operand + 0, 0); 749 while (*ptr == ' ') 750 ptr++; 751 if (*ptr && ! is_end_of_line[(unsigned char) *ptr]) 752 { 753 as_bad (_("invalid condition code '%s'"), ptr); 754 while (*ptr && ! is_end_of_line[(unsigned char) *ptr]) 755 ptr++; /* Consume rest of line. */ 756 } 757 } 758 else if (opcode->arg_info[0] == CLASS_FLAGS) 759 { 760 get_flags_operand (&ptr, operand + 0, 0); 761 while (*ptr == ' ') 762 ptr++; 763 if (*ptr && ! is_end_of_line[(unsigned char) *ptr]) 764 { 765 as_bad (_("invalid flag '%s'"), ptr); 766 while (*ptr && ! is_end_of_line[(unsigned char) *ptr]) 767 ptr++; /* Consume rest of line. */ 768 } 769 } 770 else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2))) 771 get_interrupt_operand (&ptr, operand + 0, 0); 772 else 773 get_operand (&ptr, operand + 0, 0); 774 775 operand[1].mode = 0; 776 break; 777 778 case 2: 779 savptr = ptr; 780 if (opcode->arg_info[0] == CLASS_CC) 781 { 782 get_cc_operand (&ptr, operand + 0, 0); 783 while (*ptr == ' ') 784 ptr++; 785 if (*ptr != ',' && strchr (ptr + 1, ',')) 786 { 787 savptr = ptr; 788 while (*ptr != ',') 789 ptr++; 790 *ptr = 0; 791 ptr++; 792 as_bad (_("invalid condition code '%s'"), savptr); 793 } 794 } 795 else if (opcode->arg_info[0] == CLASS_CTRL) 796 { 797 get_ctrl_operand (&ptr, operand + 0, 0); 798 799 if (the_ctrl == 0) 800 { 801 ptr = savptr; 802 get_operand (&ptr, operand + 0, 0); 803 804 if (ptr == 0) 805 return NULL; 806 if (*ptr == ',') 807 ptr++; 808 get_ctrl_operand (&ptr, operand + 1, 1); 809 if (the_ctrl == 0) 810 return NULL; 811 return ptr; 812 } 813 } 814 else 815 get_operand (&ptr, operand + 0, 0); 816 817 if (ptr == 0) 818 return NULL; 819 if (*ptr == ',') 820 ptr++; 821 get_operand (&ptr, operand + 1, 1); 822 break; 823 824 case 3: 825 get_operand (&ptr, operand + 0, 0); 826 if (*ptr == ',') 827 ptr++; 828 get_operand (&ptr, operand + 1, 1); 829 if (*ptr == ',') 830 ptr++; 831 get_operand (&ptr, operand + 2, 2); 832 break; 833 834 case 4: 835 get_operand (&ptr, operand + 0, 0); 836 if (*ptr == ',') 837 ptr++; 838 get_operand (&ptr, operand + 1, 1); 839 if (*ptr == ',') 840 ptr++; 841 get_operand (&ptr, operand + 2, 2); 842 if (*ptr == ',') 843 ptr++; 844 get_cc_operand (&ptr, operand + 3, 3); 845 break; 846 847 default: 848 abort (); 849 } 850 851 return ptr; 852 } 853 854 /* Passed a pointer to a list of opcodes which use different 855 addressing modes. Return the opcode which matches the opcodes 856 provided. */ 857 858 static opcode_entry_type * 859 get_specific (opcode_entry_type *opcode, op_type *operands) 860 { 861 opcode_entry_type *this_try = opcode; 862 int found = 0; 863 unsigned int noperands = opcode->noperands; 864 865 int this_index = opcode->idx; 866 867 while (this_index == opcode->idx && !found) 868 { 869 unsigned int i; 870 871 this_try = opcode++; 872 for (i = 0; i < noperands; i++) 873 { 874 unsigned int mode = operands[i].mode; 875 876 if (((mode & CLASS_MASK) == CLASS_IR) && ((this_try->arg_info[i] & CLASS_MASK) == CLASS_IRO)) 877 { 878 mode = operands[i].mode = (operands[i].mode & ~CLASS_MASK) | CLASS_IRO; 879 } 880 881 if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK)) 882 { 883 /* It could be a pc rel operand, if this is a da mode 884 and we like disps, then insert it. */ 885 886 if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP) 887 { 888 /* This is the case. */ 889 operands[i].mode = CLASS_DISP; 890 } 891 else if (mode == CLASS_BA && this_try->arg_info[i]) 892 { 893 /* Can't think of a way to turn what we've been 894 given into something that's OK. */ 895 goto fail; 896 } 897 else if (this_try->arg_info[i] & CLASS_PR) 898 { 899 if (mode == CLASS_REG_LONG && segmented_mode) 900 { 901 /* OK. */ 902 } 903 else if (mode == CLASS_REG_WORD && !segmented_mode) 904 { 905 /* OK. */ 906 } 907 else 908 goto fail; 909 } 910 else 911 goto fail; 912 } 913 switch (mode & CLASS_MASK) 914 { 915 default: 916 break; 917 case CLASS_IRO: 918 if (operands[i].regsize != CLASS_REG_WORD) 919 as_bad (_("invalid indirect register size")); 920 reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg; 921 break; 922 case CLASS_IR: 923 if ((segmented_mode && operands[i].regsize != CLASS_REG_LONG) 924 || (!segmented_mode && operands[i].regsize != CLASS_REG_WORD)) 925 as_bad (_("invalid indirect register size")); 926 reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg; 927 break; 928 case CLASS_X: 929 case CLASS_BA: 930 case CLASS_BX: 931 case CLASS_DISP: 932 case CLASS_REG: 933 case CLASS_REG_WORD: 934 case CLASS_REG_BYTE: 935 case CLASS_REG_QUAD: 936 case CLASS_REG_LONG: 937 case CLASS_REGN0: 938 reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg; 939 break; 940 case CLASS_CTRL: 941 if (this_try->opcode == OPC_ldctlb && the_ctrl != 1) 942 as_bad (_("invalid control register name")); 943 break; 944 } 945 } 946 947 found = 1; 948 fail: 949 ; 950 } 951 if (found) 952 return this_try; 953 else 954 return 0; 955 } 956 957 static char buffer[20]; 958 959 static void 960 newfix (int ptr, int type, int size, expressionS *operand) 961 { 962 int is_pcrel = 0; 963 fixS *fixP; 964 965 /* Size is in nibbles. */ 966 if (operand->X_add_symbol 967 || operand->X_op_symbol 968 || operand->X_add_number) 969 { 970 switch(type) 971 { 972 case BFD_RELOC_8_PCREL: 973 case BFD_RELOC_Z8K_CALLR: 974 case BFD_RELOC_Z8K_DISP7: 975 is_pcrel = 1; 976 } 977 fixP = fix_new_exp (frag_now, ptr, size / 2, 978 operand, is_pcrel, type); 979 if (is_pcrel) 980 fixP->fx_no_overflow = 1; 981 } 982 } 983 984 static char * 985 apply_fix (char *ptr, int type, expressionS *operand, int size) 986 { 987 long n = operand->X_add_number; 988 989 /* size is in nibbles. */ 990 991 newfix ((ptr - buffer) / 2, type, size + 1, operand); 992 switch (size) 993 { 994 case 8: /* 8 nibbles == 32 bits. */ 995 *ptr++ = n >> 28; 996 *ptr++ = n >> 24; 997 *ptr++ = n >> 20; 998 *ptr++ = n >> 16; 999 case 4: /* 4 nibbles == 16 bits. */ 1000 *ptr++ = n >> 12; 1001 *ptr++ = n >> 8; 1002 case 2: 1003 *ptr++ = n >> 4; 1004 case 1: 1005 *ptr++ = n >> 0; 1006 break; 1007 } 1008 return ptr; 1009 } 1010 1011 /* Now we know what sort of opcodes it is. Let's build the bytes. */ 1012 1013 static void 1014 build_bytes (opcode_entry_type *this_try, struct z8k_op *operand ATTRIBUTE_UNUSED) 1015 { 1016 char *output_ptr = buffer; 1017 int c; 1018 int nibble; 1019 unsigned int *class_ptr; 1020 1021 frag_wane (frag_now); 1022 frag_new (0); 1023 1024 if (frag_room () < 8) 1025 frag_grow (8); /* Make room for maximum instruction size. */ 1026 1027 memset (buffer, 0, sizeof (buffer)); 1028 class_ptr = this_try->byte_info; 1029 1030 for (nibble = 0; (c = *class_ptr++); nibble++) 1031 { 1032 1033 switch (c & CLASS_MASK) 1034 { 1035 default: 1036 abort (); 1037 1038 case CLASS_ADDRESS: 1039 /* Direct address, we don't cope with the SS mode right now. */ 1040 if (segmented_mode) 1041 { 1042 /* da_operand->X_add_number |= 0x80000000; -- Now set at relocation time. */ 1043 output_ptr = apply_fix (output_ptr, BFD_RELOC_32, da_operand, 8); 1044 } 1045 else 1046 { 1047 output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4); 1048 } 1049 da_operand = 0; 1050 break; 1051 case CLASS_DISP8: 1052 /* pc rel 8 bit */ 1053 output_ptr = apply_fix (output_ptr, BFD_RELOC_8_PCREL, da_operand, 2); 1054 da_operand = 0; 1055 break; 1056 1057 case CLASS_0DISP7: 1058 /* pc rel 7 bit */ 1059 *output_ptr = 0; 1060 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2); 1061 da_operand = 0; 1062 break; 1063 1064 case CLASS_1DISP7: 1065 /* pc rel 7 bit */ 1066 *output_ptr = 0x80; 1067 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2); 1068 output_ptr[-2] = 0x8; 1069 da_operand = 0; 1070 break; 1071 1072 case CLASS_BIT_1OR2: 1073 *output_ptr = c & 0xf; 1074 if (imm_operand) 1075 { 1076 if (imm_operand->X_add_number == 2) 1077 *output_ptr |= 2; 1078 else if (imm_operand->X_add_number != 1) 1079 as_bad (_("immediate must be 1 or 2")); 1080 } 1081 else 1082 as_bad (_("immediate 1 or 2 expected")); 1083 output_ptr++; 1084 break; 1085 case CLASS_CC: 1086 *output_ptr++ = the_cc; 1087 break; 1088 case CLASS_0CCC: 1089 if (the_ctrl < 2 || the_ctrl > 7) 1090 as_bad (_("invalid control register name")); 1091 *output_ptr++ = the_ctrl; 1092 break; 1093 case CLASS_1CCC: 1094 if (the_ctrl < 2 || the_ctrl > 7) 1095 as_bad (_("invalid control register name")); 1096 *output_ptr++ = the_ctrl | 0x8; 1097 break; 1098 case CLASS_00II: 1099 *output_ptr++ = (~the_interrupt & 0x3); 1100 break; 1101 case CLASS_01II: 1102 *output_ptr++ = (~the_interrupt & 0x3) | 0x4; 1103 break; 1104 case CLASS_FLAGS: 1105 *output_ptr++ = the_flags; 1106 break; 1107 case CLASS_IGNORE: 1108 case CLASS_BIT: 1109 *output_ptr++ = c & 0xf; 1110 break; 1111 case CLASS_REGN0: 1112 if (reg[c & 0xf] == 0) 1113 as_bad (_("can't use R0 here")); 1114 /* Fall through. */ 1115 case CLASS_REG: 1116 case CLASS_REG_BYTE: 1117 case CLASS_REG_WORD: 1118 case CLASS_REG_LONG: 1119 case CLASS_REG_QUAD: 1120 /* Insert bit mattern of right reg. */ 1121 *output_ptr++ = reg[c & 0xf]; 1122 break; 1123 case CLASS_DISP: 1124 switch (c & ARG_MASK) 1125 { 1126 case ARG_DISP12: 1127 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_CALLR, da_operand, 4); 1128 break; 1129 case ARG_DISP16: 1130 output_ptr = apply_fix (output_ptr, BFD_RELOC_16_PCREL, da_operand, 4); 1131 break; 1132 default: 1133 output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4); 1134 } 1135 da_operand = 0; 1136 break; 1137 1138 case CLASS_IMM: 1139 { 1140 switch (c & ARG_MASK) 1141 { 1142 case ARG_NIM4: 1143 if (imm_operand->X_add_number > 15) 1144 as_bad (_("immediate value out of range")); 1145 imm_operand->X_add_number = -imm_operand->X_add_number; 1146 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1); 1147 break; 1148 /*case ARG_IMMNMINUS1: not used. */ 1149 case ARG_IMM4M1: 1150 imm_operand->X_add_number--; 1151 /* Drop through. */ 1152 case ARG_IMM4: 1153 if (imm_operand->X_add_number > 15) 1154 as_bad (_("immediate value out of range")); 1155 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1); 1156 break; 1157 case ARG_NIM8: 1158 imm_operand->X_add_number = -imm_operand->X_add_number; 1159 /* Drop through. */ 1160 case ARG_IMM8: 1161 output_ptr = apply_fix (output_ptr, BFD_RELOC_8, imm_operand, 2); 1162 break; 1163 case ARG_IMM16: 1164 output_ptr = apply_fix (output_ptr, BFD_RELOC_16, imm_operand, 4); 1165 break; 1166 case ARG_IMM32: 1167 output_ptr = apply_fix (output_ptr, BFD_RELOC_32, imm_operand, 8); 1168 break; 1169 default: 1170 abort (); 1171 } 1172 } 1173 } 1174 } 1175 1176 /* Copy from the nibble buffer into the frag. */ 1177 { 1178 int length = (output_ptr - buffer) / 2; 1179 char *src = buffer; 1180 char *fragp = frag_more (length); 1181 1182 while (src < output_ptr) 1183 { 1184 *fragp = (src[0] << 4) | src[1]; 1185 src += 2; 1186 fragp++; 1187 } 1188 } 1189 } 1190 1191 /* This is the guts of the machine-dependent assembler. STR points to a 1192 machine dependent instruction. This function is supposed to emit 1193 the frags/bytes it assembles to. */ 1194 1195 void 1196 md_assemble (char *str) 1197 { 1198 char c; 1199 char *op_start; 1200 char *op_end; 1201 struct z8k_op operand[4]; 1202 opcode_entry_type *opcode; 1203 1204 /* Drop leading whitespace. */ 1205 while (*str == ' ') 1206 str++; 1207 1208 /* Find the op code end. */ 1209 for (op_start = op_end = str; 1210 *op_end != 0 && *op_end != ' ' && ! is_end_of_line[(unsigned char) *op_end]; 1211 op_end++) 1212 ; 1213 1214 if (op_end == op_start) 1215 { 1216 as_bad (_("can't find opcode ")); 1217 } 1218 c = *op_end; 1219 1220 *op_end = 0; /* Zero-terminate op code string for hash_find() call. */ 1221 1222 opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start); 1223 1224 if (opcode == NULL) 1225 { 1226 as_bad (_("unknown opcode")); 1227 return; 1228 } 1229 1230 *op_end = c; /* Restore original string. */ 1231 1232 if (opcode->opcode == 250) 1233 { 1234 pseudo_typeS *p; 1235 char oc; 1236 char *old = input_line_pointer; 1237 1238 /* Was really a pseudo op. */ 1239 1240 input_line_pointer = op_end; 1241 1242 oc = *old; 1243 *old = '\n'; 1244 while (*input_line_pointer == ' ') 1245 input_line_pointer++; 1246 p = (pseudo_typeS *) (opcode->func); 1247 1248 (p->poc_handler) (p->poc_val); 1249 input_line_pointer = old; 1250 *old = oc; 1251 } 1252 else 1253 { 1254 char *new_input_line_pointer; 1255 1256 new_input_line_pointer = get_operands (opcode, op_end, operand); 1257 if (new_input_line_pointer) 1258 { 1259 input_line_pointer = new_input_line_pointer; 1260 opcode = get_specific (opcode, operand); 1261 } 1262 1263 if (new_input_line_pointer == NULL || opcode == NULL) 1264 { 1265 /* Couldn't find an opcode which matched the operands. */ 1266 char *where = frag_more (2); 1267 1268 where[0] = 0x0; 1269 where[1] = 0x0; 1270 1271 as_bad (_("Can't find opcode to match operands")); 1272 return; 1273 } 1274 1275 build_bytes (opcode, operand); 1276 } 1277 } 1278 1279 /* We have no need to default values of symbols. */ 1280 1281 symbolS * 1282 md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 1283 { 1284 return 0; 1285 } 1286 1287 /* Various routines to kill one day. */ 1288 1289 char * 1290 md_atof (int type, char *litP, int *sizeP) 1291 { 1292 return ieee_md_atof (type, litP, sizeP, TRUE); 1293 } 1294 1295 const char *md_shortopts = "z:"; 1296 1297 struct option md_longopts[] = 1298 { 1299 #define OPTION_RELAX (OPTION_MD_BASE) 1300 {"linkrelax", no_argument, NULL, OPTION_RELAX}, 1301 {NULL, no_argument, NULL, 0} 1302 }; 1303 1304 size_t md_longopts_size = sizeof (md_longopts); 1305 1306 int 1307 md_parse_option (int c, char *arg) 1308 { 1309 switch (c) 1310 { 1311 case 'z': 1312 if (!strcmp (arg, "8001")) 1313 s_segm (1); 1314 else if (!strcmp (arg, "8002")) 1315 s_segm (0); 1316 else 1317 { 1318 as_bad (_("invalid architecture -z%s"), arg); 1319 return 0; 1320 } 1321 z8k_target_from_cmdline = 1; 1322 break; 1323 1324 case OPTION_RELAX: 1325 linkrelax = 1; 1326 break; 1327 1328 default: 1329 return 0; 1330 } 1331 1332 return 1; 1333 } 1334 1335 void 1336 md_show_usage (FILE *stream) 1337 { 1338 fprintf (stream, _("\ 1339 Z8K options:\n\ 1340 -z8001 generate segmented code\n\ 1341 -z8002 generate unsegmented code\n\ 1342 -linkrelax create linker relaxable code\n")); 1343 } 1344 1345 void 1346 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, 1347 segT sec ATTRIBUTE_UNUSED, 1348 fragS *fragP ATTRIBUTE_UNUSED) 1349 { 1350 printf (_("call to md_convert_frag\n")); 1351 abort (); 1352 } 1353 1354 /* Generate a machine dependent reloc from a fixup. */ 1355 1356 arelent* 1357 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, 1358 fixS *fixp ATTRIBUTE_UNUSED) 1359 { 1360 arelent *reloc; 1361 1362 reloc = xmalloc (sizeof (*reloc)); 1363 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); 1364 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 1365 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 1366 reloc->addend = fixp->fx_offset; 1367 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 1368 1369 if (! reloc->howto) 1370 { 1371 as_bad_where (fixp->fx_file, fixp->fx_line, 1372 _("Cannot represent %s relocation in object file"), 1373 bfd_get_reloc_code_name (fixp->fx_r_type)); 1374 abort (); 1375 } 1376 return reloc; 1377 } 1378 1379 valueT 1380 md_section_align (segT seg, valueT size) 1381 { 1382 int align = bfd_get_section_alignment (stdoutput, seg); 1383 valueT mask = ((valueT) 1 << align) - 1; 1384 1385 return (size + mask) & ~mask; 1386 } 1387 1388 /* Attempt to simplify or eliminate a fixup. To indicate that a fixup 1389 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL, 1390 we will have to generate a reloc entry. */ 1391 void 1392 md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED) 1393 { 1394 long val = * (long *) valP; 1395 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; 1396 1397 switch (fixP->fx_r_type) 1398 { 1399 case BFD_RELOC_Z8K_IMM4L: 1400 if (fixP->fx_addsy) 1401 { 1402 fixP->fx_no_overflow = 1; 1403 fixP->fx_done = 0; 1404 } 1405 else 1406 buf[0] = (buf[0] & 0xf0) | (val & 0xf); 1407 break; 1408 1409 case BFD_RELOC_8: 1410 if (fixP->fx_addsy) 1411 { 1412 fixP->fx_no_overflow = 1; 1413 fixP->fx_done = 0; 1414 } 1415 else 1416 *buf++ = val; 1417 break; 1418 1419 case BFD_RELOC_16: 1420 if (fixP->fx_addsy) 1421 { 1422 fixP->fx_no_overflow = 1; 1423 fixP->fx_done = 0; 1424 } 1425 else 1426 { 1427 *buf++ = (val >> 8); 1428 *buf++ = val; 1429 } 1430 break; 1431 1432 case BFD_RELOC_32: 1433 if (fixP->fx_addsy) 1434 { 1435 fixP->fx_no_overflow = 1; 1436 fixP->fx_done = 0; 1437 } 1438 else 1439 { 1440 *buf++ = (val >> 24); 1441 *buf++ = (val >> 16); 1442 *buf++ = (val >> 8); 1443 *buf++ = val; 1444 } 1445 break; 1446 1447 case BFD_RELOC_8_PCREL: 1448 if (fixP->fx_addsy) 1449 { 1450 fixP->fx_no_overflow = 1; 1451 fixP->fx_done = 0; 1452 } 1453 else 1454 { 1455 if (val & 1) 1456 as_bad_where (fixP->fx_file, fixP->fx_line, 1457 _("cannot branch to odd address")); 1458 val /= 2; 1459 if (val > 127 || val < -128) 1460 as_bad_where (fixP->fx_file, fixP->fx_line, 1461 _("relative jump out of range")); 1462 *buf++ = val; 1463 fixP->fx_no_overflow = 1; 1464 fixP->fx_done = 1; 1465 } 1466 break; 1467 1468 case BFD_RELOC_16_PCREL: 1469 if (fixP->fx_addsy) 1470 { 1471 fixP->fx_no_overflow = 1; 1472 fixP->fx_done = 0; 1473 } 1474 else 1475 { 1476 val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size; 1477 if (val > 32767 || val < -32768) 1478 as_bad_where (fixP->fx_file, fixP->fx_line, 1479 _("relative address out of range")); 1480 *buf++ = (val >> 8); 1481 *buf++ = val; 1482 fixP->fx_no_overflow = 1; 1483 fixP->fx_done = 1; 1484 } 1485 break; 1486 1487 case BFD_RELOC_Z8K_CALLR: 1488 if (fixP->fx_addsy) 1489 { 1490 fixP->fx_no_overflow = 1; 1491 fixP->fx_done = 0; 1492 } 1493 else 1494 { 1495 if (val & 1) 1496 as_bad_where (fixP->fx_file, fixP->fx_line, 1497 _("cannot branch to odd address")); 1498 if (val > 4096 || val < -4095) 1499 as_bad_where (fixP->fx_file, fixP->fx_line, 1500 _("relative call out of range")); 1501 val = -val / 2; 1502 *buf = (*buf & 0xf0) | ((val >> 8) & 0xf); 1503 buf++; 1504 *buf++ = val & 0xff; 1505 fixP->fx_no_overflow = 1; 1506 fixP->fx_done = 1; 1507 } 1508 break; 1509 1510 case BFD_RELOC_Z8K_DISP7: 1511 if (fixP->fx_addsy) 1512 { 1513 fixP->fx_no_overflow = 1; 1514 fixP->fx_done = 0; 1515 } 1516 else 1517 { 1518 if (val & 1) 1519 as_bad_where (fixP->fx_file, fixP->fx_line, 1520 _("cannot branch to odd address")); 1521 val /= 2; 1522 if (val > 0 || val < -127) 1523 as_bad_where (fixP->fx_file, fixP->fx_line, 1524 _("relative jump out of range")); 1525 *buf = (*buf & 0x80) | (-val & 0x7f); 1526 fixP->fx_no_overflow = 1; 1527 fixP->fx_done = 1; 1528 } 1529 break; 1530 1531 default: 1532 printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type); 1533 abort (); 1534 } 1535 1536 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) 1537 fixP->fx_done = 1; 1538 } 1539 1540 int 1541 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, 1542 segT segment_type ATTRIBUTE_UNUSED) 1543 { 1544 printf (_("call to md_estimate_size_before_relax\n")); 1545 abort (); 1546 } 1547 1548 /* Put number into target byte order. */ 1549 1550 void 1551 md_number_to_chars (char *ptr, valueT use, int nbytes) 1552 { 1553 number_to_chars_bigendian (ptr, use, nbytes); 1554 } 1555 1556 /* On the Z8000, a PC-relative offset is relative to the address of the 1557 instruction plus its size. */ 1558 long 1559 md_pcrel_from (fixS *fixP) 1560 { 1561 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; 1562 } 1563 1564 void 1565 tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED) 1566 { 1567 } 1568