1 /* tc-z8k.c -- Assemble code for the Zilog Z800n 2 Copyright (C) 1992-2014 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to the Free 18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 02110-1301, USA. */ 20 21 /* Written By Steve Chamberlain <sac (at) cygnus.com>. */ 22 23 #include "as.h" 24 #include "safe-ctype.h" 25 #define DEFINE_TABLE 26 #include "opcodes/z8k-opc.h" 27 28 const char comment_chars[] = "!"; 29 const char line_comment_chars[] = "#"; 30 const char line_separator_chars[] = ";"; 31 32 extern int machine; 33 extern int coff_flags; 34 int segmented_mode; 35 36 /* This is non-zero if target was set from the command line. 37 If non-zero, 1 means Z8002 (non-segmented), 2 means Z8001 (segmented). */ 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 s_segm (z8k_target_from_cmdline ? z8k_target_from_cmdline - 1 : 0); 160 161 /* Insert the pseudo ops, too. */ 162 for (idx = 0; md_pseudo_table[idx].poc_name; idx++) 163 { 164 opcode_entry_type *fake_opcode; 165 fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type)); 166 fake_opcode->name = md_pseudo_table[idx].poc_name; 167 fake_opcode->func = (void *) (md_pseudo_table + idx); 168 fake_opcode->opcode = 250; 169 hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode); 170 } 171 } 172 173 typedef struct z8k_op { 174 /* CLASS_REG_xxx. */ 175 int regsize; 176 177 /* 0 .. 15. */ 178 unsigned int reg; 179 180 int mode; 181 182 /* Any other register associated with the mode. */ 183 unsigned int x_reg; 184 185 /* Any expression. */ 186 expressionS exp; 187 } op_type; 188 189 static expressionS *da_operand; 190 static expressionS *imm_operand; 191 192 static int reg[16]; 193 static int the_cc; 194 static int the_ctrl; 195 static int the_flags; 196 static int the_interrupt; 197 198 /* Determine register number. src points to the ascii number 199 (after "rl", "rh", "r", "rr", or "rq"). If a character 200 outside the set of {0,',',')','('} follows the number, 201 return NULL to indicate that it's not a valid register 202 number. */ 203 204 static char * 205 whatreg (unsigned int *preg, char *src) 206 { 207 unsigned int new_reg; 208 209 /* src[0] is already known to be a digit. */ 210 if (ISDIGIT (src[1])) 211 { 212 new_reg = (src[0] - '0') * 10 + src[1] - '0'; 213 src += 2; 214 } 215 else 216 { 217 new_reg = (src[0] - '0'); 218 src += 1; 219 } 220 221 if (src[0] != 0 && src[0] != ',' && src[0] != '(' && src[0] != ')') 222 return NULL; 223 224 *preg = new_reg; 225 return src; 226 } 227 228 /* Parse operands 229 230 rh0-rh7, rl0-rl7 231 r0-r15 232 rr0-rr14 233 rq0--rq12 234 WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp 235 r0l,r0h,..r7l,r7h 236 @WREG 237 @WREG+ 238 @-WREG 239 #const 240 */ 241 242 /* Try to parse a reg name. Return a pointer to the first character 243 in SRC after the reg name. */ 244 245 static char * 246 parse_reg (char *src, int *mode, unsigned int *preg) 247 { 248 char *res = NULL; 249 char regno; 250 251 /* Check for stack pointer "sp" alias. */ 252 if ((src[0] == 's' || src[0] == 'S') 253 && (src[1] == 'p' || src[1] == 'P') 254 && (src[2] == 0 || src[2] == ',')) 255 { 256 if (segmented_mode) 257 { 258 *mode = CLASS_REG_LONG; 259 *preg = 14; 260 } 261 else 262 { 263 *mode = CLASS_REG_WORD; 264 *preg = 15; 265 } 266 return src + 2; 267 } 268 269 if (src[0] == 'r' || src[0] == 'R') 270 { 271 if (src[1] == 'r' || src[1] == 'R') 272 { 273 if (src[2] < '0' || src[2] > '9') 274 return NULL; /* Assume no register name but a label starting with 'rr'. */ 275 *mode = CLASS_REG_LONG; 276 res = whatreg (preg, src + 2); 277 if (res == NULL) 278 return NULL; /* Not a valid register name. */ 279 regno = *preg; 280 if (regno > 14) 281 as_bad (_("register rr%d out of range"), regno); 282 if (regno & 1) 283 as_bad (_("register rr%d does not exist"), regno); 284 } 285 else if (src[1] == 'h' || src[1] == 'H') 286 { 287 if (src[2] < '0' || src[2] > '9') 288 return NULL; /* Assume no register name but a label starting with 'rh'. */ 289 *mode = CLASS_REG_BYTE; 290 res = whatreg (preg, src + 2); 291 if (res == NULL) 292 return NULL; /* Not a valid register name. */ 293 regno = *preg; 294 if (regno > 7) 295 as_bad (_("register rh%d out of range"), regno); 296 } 297 else if (src[1] == 'l' || src[1] == 'L') 298 { 299 if (src[2] < '0' || src[2] > '9') 300 return NULL; /* Assume no register name but a label starting with 'rl'. */ 301 *mode = CLASS_REG_BYTE; 302 res = whatreg (preg, src + 2); 303 if (res == NULL) 304 return NULL; /* Not a valid register name. */ 305 regno = *preg; 306 if (regno > 7) 307 as_bad (_("register rl%d out of range"), regno); 308 *preg += 8; 309 } 310 else if (src[1] == 'q' || src[1] == 'Q') 311 { 312 if (src[2] < '0' || src[2] > '9') 313 return NULL; /* Assume no register name but a label starting with 'rq'. */ 314 *mode = CLASS_REG_QUAD; 315 res = whatreg (preg, src + 2); 316 if (res == NULL) 317 return NULL; /* Not a valid register name. */ 318 regno = *preg; 319 if (regno > 12) 320 as_bad (_("register rq%d out of range"), regno); 321 if (regno & 3) 322 as_bad (_("register rq%d does not exist"), regno); 323 } 324 else 325 { 326 if (src[1] < '0' || src[1] > '9') 327 return NULL; /* Assume no register name but a label starting with 'r'. */ 328 *mode = CLASS_REG_WORD; 329 res = whatreg (preg, src + 1); 330 if (res == NULL) 331 return NULL; /* Not a valid register name. */ 332 regno = *preg; 333 if (regno > 15) 334 as_bad (_("register r%d out of range"), regno); 335 } 336 } 337 return res; 338 } 339 340 static char * 341 parse_exp (char *s, expressionS *op) 342 { 343 char *save = input_line_pointer; 344 char *new_pointer; 345 346 input_line_pointer = s; 347 expression (op); 348 if (op->X_op == O_absent) 349 as_bad (_("missing operand")); 350 new_pointer = input_line_pointer; 351 input_line_pointer = save; 352 return new_pointer; 353 } 354 355 /* The many forms of operand: 356 357 <rb> 358 <r> 359 <rr> 360 <rq> 361 @r 362 #exp 363 exp 364 exp(r) 365 r(#exp) 366 r(r) 367 */ 368 369 static char * 370 checkfor (char *ptr, char what) 371 { 372 if (*ptr == what) 373 ptr++; 374 else 375 as_bad (_("expected %c"), what); 376 377 return ptr; 378 } 379 380 /* Make sure the mode supplied is the size of a word. */ 381 382 static void 383 regword (int mode, char *string) 384 { 385 int ok; 386 387 ok = CLASS_REG_WORD; 388 if (ok != mode) 389 { 390 as_bad (_("register is wrong size for a word %s"), string); 391 } 392 } 393 394 /* Make sure the mode supplied is the size of an address. */ 395 396 static void 397 regaddr (int mode, char *string) 398 { 399 int ok; 400 401 ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD; 402 if (ok != mode) 403 { 404 as_bad (_("register is wrong size for address %s"), string); 405 } 406 } 407 408 struct ctrl_names { 409 int value; 410 char *name; 411 }; 412 413 static struct ctrl_names ctrl_table[] = { 414 { 0x1, "flags" }, /* ldctlb only. */ 415 { 0x2, "fcw" }, /* ldctl only. Applies to all remaining control registers. */ 416 { 0x3, "refresh" }, 417 { 0x4, "psapseg" }, 418 { 0x5, "psapoff" }, 419 { 0x5, "psap" }, 420 { 0x6, "nspseg" }, 421 { 0x7, "nspoff" }, 422 { 0x7, "nsp" }, 423 { 0 , 0 } 424 }; 425 426 static void 427 get_ctrl_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 428 { 429 char *src = *ptr; 430 int i, l; 431 432 while (*src == ' ') 433 src++; 434 435 mode->mode = CLASS_CTRL; 436 for (i = 0; ctrl_table[i].name; i++) 437 { 438 l = strlen (ctrl_table[i].name); 439 if (! strncasecmp (ctrl_table[i].name, src, l)) 440 { 441 the_ctrl = ctrl_table[i].value; 442 if (*(src + l) && *(src + l) != ',') 443 break; 444 *ptr = src + l; /* Valid control name found: "consume" it. */ 445 return; 446 } 447 } 448 the_ctrl = 0; 449 } 450 451 struct flag_names { 452 int value; 453 char *name; 454 }; 455 456 static struct flag_names flag_table[] = { 457 { 0x1, "P" }, 458 { 0x1, "V" }, 459 { 0x2, "S" }, 460 { 0x4, "Z" }, 461 { 0x8, "C" }, 462 { 0x0, "+" }, 463 { 0x0, "," }, 464 { 0, 0 } 465 }; 466 467 static void 468 get_flags_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 469 { 470 char *src = *ptr; 471 char c; 472 int i; 473 int j; 474 475 while (*src == ' ') 476 src++; 477 478 mode->mode = CLASS_FLAGS; 479 the_flags = 0; 480 for (j = 0; j <= 9; j++) 481 { 482 if (!src[j]) 483 goto done; 484 c = TOUPPER(src[j]); 485 for (i = 0; flag_table[i].name; i++) 486 { 487 if (flag_table[i].name[0] == c) 488 { 489 the_flags = the_flags | flag_table[i].value; 490 goto match; 491 } 492 } 493 goto done; 494 match: 495 ; 496 } 497 done: 498 *ptr = src + j; 499 } 500 501 struct interrupt_names { 502 int value; 503 char *name; 504 }; 505 506 static struct interrupt_names intr_table[] = { 507 { 0x1, "nvi" }, 508 { 0x2, "vi" }, 509 { 0x3, "both" }, 510 { 0x3, "all" }, 511 { 0, 0 } 512 }; 513 514 static void 515 get_interrupt_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 516 { 517 char *src = *ptr; 518 int i, l; 519 520 while (*src == ' ') 521 src++; 522 523 mode->mode = CLASS_IMM; 524 the_interrupt = 0; 525 526 while (*src) 527 { 528 for (i = 0; intr_table[i].name; i++) 529 { 530 l = strlen (intr_table[i].name); 531 if (! strncasecmp (intr_table[i].name, src, l)) 532 { 533 the_interrupt |= intr_table[i].value; 534 if (*(src + l) && *(src + l) != ',') 535 { 536 *ptr = src + l; 537 invalid: 538 as_bad (_("unknown interrupt %s"), src); 539 while (**ptr && ! is_end_of_line[(unsigned char) **ptr]) 540 (*ptr)++; /* Consume rest of line. */ 541 return; 542 } 543 src += l; 544 if (! *src) 545 { 546 *ptr = src; 547 return; 548 } 549 } 550 } 551 if (*src == ',') 552 src++; 553 else 554 { 555 *ptr = src; 556 goto invalid; 557 } 558 } 559 560 /* No interrupt type specified, opcode won't do anything. */ 561 as_warn (_("opcode has no effect")); 562 the_interrupt = 0x0; 563 } 564 565 struct cc_names { 566 int value; 567 char *name; 568 }; 569 570 static struct cc_names table[] = { 571 { 0x0, "f" }, 572 { 0x1, "lt" }, 573 { 0x2, "le" }, 574 { 0x3, "ule" }, 575 { 0x4, "ov/pe" }, 576 { 0x4, "ov" }, 577 { 0x4, "pe/ov" }, 578 { 0x4, "pe" }, 579 { 0x5, "mi" }, 580 { 0x6, "eq" }, 581 { 0x6, "z" }, 582 { 0x7, "c/ult" }, 583 { 0x7, "c" }, 584 { 0x7, "ult/c" }, 585 { 0x7, "ult" }, 586 { 0x8, "t" }, 587 { 0x9, "ge" }, 588 { 0xa, "gt" }, 589 { 0xb, "ugt" }, 590 { 0xc, "nov/po" }, 591 { 0xc, "nov" }, 592 { 0xc, "po/nov" }, 593 { 0xc, "po" }, 594 { 0xd, "pl" }, 595 { 0xe, "ne" }, 596 { 0xe, "nz" }, 597 { 0xf, "nc/uge" }, 598 { 0xf, "nc" }, 599 { 0xf, "uge/nc" }, 600 { 0xf, "uge" }, 601 { 0 , 0 } 602 }; 603 604 static void 605 get_cc_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 606 { 607 char *src = *ptr; 608 int i, l; 609 610 while (*src == ' ') 611 src++; 612 613 mode->mode = CLASS_CC; 614 for (i = 0; table[i].name; i++) 615 { 616 l = strlen (table[i].name); 617 if (! strncasecmp (table[i].name, src, l)) 618 { 619 the_cc = table[i].value; 620 if (*(src + l) && *(src + l) != ',') 621 break; 622 *ptr = src + l; /* Valid cc found: "consume" it. */ 623 return; 624 } 625 } 626 the_cc = 0x8; /* Not recognizing the cc defaults to t. (Assuming no cc present.) */ 627 } 628 629 static void 630 get_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED) 631 { 632 char *src = *ptr; 633 char *end; 634 635 mode->mode = 0; 636 637 while (*src == ' ') 638 src++; 639 if (*src == '#') 640 { 641 mode->mode = CLASS_IMM; 642 imm_operand = &(mode->exp); 643 src = parse_exp (src + 1, &(mode->exp)); 644 } 645 else if (*src == '@') 646 { 647 mode->mode = CLASS_IR; 648 src = parse_reg (src + 1, &mode->regsize, &mode->reg); 649 } 650 else 651 { 652 unsigned int regn; 653 654 end = parse_reg (src, &mode->mode, ®n); 655 656 if (end) 657 { 658 int nw; 659 unsigned int nr; 660 661 src = end; 662 if (*src == '(') 663 { 664 src++; 665 end = parse_reg (src, &nw, &nr); 666 if (end) 667 { 668 /* Got Ra(Rb). */ 669 src = end; 670 671 if (*src != ')') 672 as_bad (_("Missing ) in ra(rb)")); 673 else 674 src++; 675 676 regaddr (mode->mode, "ra(rb) ra"); 677 mode->mode = CLASS_BX; 678 mode->reg = regn; 679 mode->x_reg = nr; 680 reg[ARG_RX] = nr; 681 } 682 else 683 { 684 /* Got Ra(disp). */ 685 if (*src == '#') 686 src++; 687 src = parse_exp (src, &(mode->exp)); 688 src = checkfor (src, ')'); 689 mode->mode = CLASS_BA; 690 mode->reg = regn; 691 mode->x_reg = 0; 692 imm_operand = &(mode->exp); 693 } 694 } 695 else 696 { 697 mode->reg = regn; 698 mode->x_reg = 0; 699 } 700 } 701 else 702 { 703 /* No initial reg. */ 704 src = parse_exp (src, &(mode->exp)); 705 if (*src == '(') 706 { 707 src++; 708 end = parse_reg (src, &(mode->mode), ®n); 709 regword (mode->mode, "addr(Ra) ra"); 710 mode->mode = CLASS_X; 711 mode->reg = regn; 712 mode->x_reg = 0; 713 da_operand = &(mode->exp); 714 src = checkfor (end, ')'); 715 } 716 else 717 { 718 /* Just an address. */ 719 mode->mode = CLASS_DA; 720 mode->reg = 0; 721 mode->x_reg = 0; 722 da_operand = &(mode->exp); 723 } 724 } 725 } 726 *ptr = src; 727 } 728 729 static char * 730 get_operands (const opcode_entry_type *opcode, char *op_end, op_type *operand) 731 { 732 char *ptr = op_end; 733 char *savptr; 734 735 switch (opcode->noperands) 736 { 737 case 0: 738 operand[0].mode = 0; 739 operand[1].mode = 0; 740 while (*ptr == ' ') 741 ptr++; 742 break; 743 744 case 1: 745 if (opcode->arg_info[0] == CLASS_CC) 746 { 747 get_cc_operand (&ptr, operand + 0, 0); 748 while (*ptr == ' ') 749 ptr++; 750 if (*ptr && ! is_end_of_line[(unsigned char) *ptr]) 751 { 752 as_bad (_("invalid condition code '%s'"), ptr); 753 while (*ptr && ! is_end_of_line[(unsigned char) *ptr]) 754 ptr++; /* Consume rest of line. */ 755 } 756 } 757 else if (opcode->arg_info[0] == CLASS_FLAGS) 758 { 759 get_flags_operand (&ptr, operand + 0, 0); 760 while (*ptr == ' ') 761 ptr++; 762 if (*ptr && ! is_end_of_line[(unsigned char) *ptr]) 763 { 764 as_bad (_("invalid flag '%s'"), ptr); 765 while (*ptr && ! is_end_of_line[(unsigned char) *ptr]) 766 ptr++; /* Consume rest of line. */ 767 } 768 } 769 else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2))) 770 get_interrupt_operand (&ptr, operand + 0, 0); 771 else 772 get_operand (&ptr, operand + 0, 0); 773 774 operand[1].mode = 0; 775 break; 776 777 case 2: 778 savptr = ptr; 779 if (opcode->arg_info[0] == CLASS_CC) 780 { 781 get_cc_operand (&ptr, operand + 0, 0); 782 while (*ptr == ' ') 783 ptr++; 784 if (*ptr != ',' && strchr (ptr + 1, ',')) 785 { 786 savptr = ptr; 787 while (*ptr != ',') 788 ptr++; 789 *ptr = 0; 790 ptr++; 791 as_bad (_("invalid condition code '%s'"), savptr); 792 } 793 } 794 else if (opcode->arg_info[0] == CLASS_CTRL) 795 { 796 get_ctrl_operand (&ptr, operand + 0, 0); 797 798 if (the_ctrl == 0) 799 { 800 ptr = savptr; 801 get_operand (&ptr, operand + 0, 0); 802 803 if (ptr == 0) 804 return NULL; 805 if (*ptr == ',') 806 ptr++; 807 get_ctrl_operand (&ptr, operand + 1, 1); 808 if (the_ctrl == 0) 809 return NULL; 810 return ptr; 811 } 812 } 813 else 814 get_operand (&ptr, operand + 0, 0); 815 816 if (ptr == 0) 817 return NULL; 818 if (*ptr == ',') 819 ptr++; 820 get_operand (&ptr, operand + 1, 1); 821 break; 822 823 case 3: 824 get_operand (&ptr, operand + 0, 0); 825 if (*ptr == ',') 826 ptr++; 827 get_operand (&ptr, operand + 1, 1); 828 if (*ptr == ',') 829 ptr++; 830 get_operand (&ptr, operand + 2, 2); 831 break; 832 833 case 4: 834 get_operand (&ptr, operand + 0, 0); 835 if (*ptr == ',') 836 ptr++; 837 get_operand (&ptr, operand + 1, 1); 838 if (*ptr == ',') 839 ptr++; 840 get_operand (&ptr, operand + 2, 2); 841 if (*ptr == ',') 842 ptr++; 843 get_cc_operand (&ptr, operand + 3, 3); 844 break; 845 846 default: 847 abort (); 848 } 849 850 return ptr; 851 } 852 853 /* Passed a pointer to a list of opcodes which use different 854 addressing modes. Return the opcode which matches the opcodes 855 provided. */ 856 857 static opcode_entry_type * 858 get_specific (opcode_entry_type *opcode, op_type *operands) 859 { 860 opcode_entry_type *this_try = opcode; 861 int found = 0; 862 unsigned int noperands = opcode->noperands; 863 864 int this_index = opcode->idx; 865 866 while (this_index == opcode->idx && !found) 867 { 868 unsigned int i; 869 870 this_try = opcode++; 871 for (i = 0; i < noperands; i++) 872 { 873 unsigned int mode = operands[i].mode; 874 875 if (((mode & CLASS_MASK) == CLASS_IR) && ((this_try->arg_info[i] & CLASS_MASK) == CLASS_IRO)) 876 { 877 mode = operands[i].mode = (operands[i].mode & ~CLASS_MASK) | CLASS_IRO; 878 } 879 880 if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK)) 881 { 882 /* It could be a pc rel operand, if this is a da mode 883 and we like disps, then insert it. */ 884 885 if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP) 886 { 887 /* This is the case. */ 888 operands[i].mode = CLASS_DISP; 889 } 890 else if (mode == CLASS_BA && this_try->arg_info[i]) 891 { 892 /* Can't think of a way to turn what we've been 893 given into something that's OK. */ 894 goto fail; 895 } 896 else if (this_try->arg_info[i] & CLASS_PR) 897 { 898 if (mode == CLASS_REG_LONG && segmented_mode) 899 { 900 /* OK. */ 901 } 902 else if (mode == CLASS_REG_WORD && !segmented_mode) 903 { 904 /* OK. */ 905 } 906 else 907 goto fail; 908 } 909 else 910 goto fail; 911 } 912 switch (mode & CLASS_MASK) 913 { 914 default: 915 break; 916 case CLASS_IRO: 917 if (operands[i].regsize != CLASS_REG_WORD) 918 as_bad (_("invalid indirect register size")); 919 reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg; 920 break; 921 case CLASS_IR: 922 if ((segmented_mode && operands[i].regsize != CLASS_REG_LONG) 923 || (!segmented_mode && operands[i].regsize != CLASS_REG_WORD)) 924 as_bad (_("invalid indirect register size")); 925 reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg; 926 break; 927 case CLASS_X: 928 case CLASS_BA: 929 case CLASS_BX: 930 case CLASS_DISP: 931 case CLASS_REG: 932 case CLASS_REG_WORD: 933 case CLASS_REG_BYTE: 934 case CLASS_REG_QUAD: 935 case CLASS_REG_LONG: 936 case CLASS_REGN0: 937 reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg; 938 break; 939 case CLASS_CTRL: 940 if (this_try->opcode == OPC_ldctlb && the_ctrl != 1) 941 as_bad (_("invalid control register name")); 942 break; 943 } 944 } 945 946 found = 1; 947 fail: 948 ; 949 } 950 if (found) 951 return this_try; 952 else 953 return 0; 954 } 955 956 static char buffer[20]; 957 958 static void 959 newfix (int ptr, int type, int size, expressionS *operand) 960 { 961 int is_pcrel = 0; 962 fixS *fixP; 963 964 /* Size is in nibbles. */ 965 if (operand->X_add_symbol 966 || operand->X_op_symbol 967 || operand->X_add_number) 968 { 969 switch(type) 970 { 971 case BFD_RELOC_8_PCREL: 972 case BFD_RELOC_Z8K_CALLR: 973 case BFD_RELOC_Z8K_DISP7: 974 is_pcrel = 1; 975 } 976 fixP = fix_new_exp (frag_now, ptr, size / 2, 977 operand, is_pcrel, type); 978 if (is_pcrel) 979 fixP->fx_no_overflow = 1; 980 } 981 } 982 983 static char * 984 apply_fix (char *ptr, int type, expressionS *operand, int size) 985 { 986 long n = operand->X_add_number; 987 988 /* size is in nibbles. */ 989 990 newfix ((ptr - buffer) / 2, type, size + 1, operand); 991 switch (size) 992 { 993 case 8: /* 8 nibbles == 32 bits. */ 994 *ptr++ = n >> 28; 995 *ptr++ = n >> 24; 996 *ptr++ = n >> 20; 997 *ptr++ = n >> 16; 998 case 4: /* 4 nibbles == 16 bits. */ 999 *ptr++ = n >> 12; 1000 *ptr++ = n >> 8; 1001 case 2: 1002 *ptr++ = n >> 4; 1003 case 1: 1004 *ptr++ = n >> 0; 1005 break; 1006 } 1007 return ptr; 1008 } 1009 1010 /* Now we know what sort of opcodes it is. Let's build the bytes. */ 1011 1012 static void 1013 build_bytes (opcode_entry_type *this_try, struct z8k_op *operand ATTRIBUTE_UNUSED) 1014 { 1015 char *output_ptr = buffer; 1016 int c; 1017 int nibble; 1018 unsigned int *class_ptr; 1019 1020 frag_wane (frag_now); 1021 frag_new (0); 1022 1023 if (frag_room () < 8) 1024 frag_grow (8); /* Make room for maximum instruction size. */ 1025 1026 memset (buffer, 0, sizeof (buffer)); 1027 class_ptr = this_try->byte_info; 1028 1029 for (nibble = 0; (c = *class_ptr++); nibble++) 1030 { 1031 1032 switch (c & CLASS_MASK) 1033 { 1034 default: 1035 abort (); 1036 1037 case CLASS_ADDRESS: 1038 /* Direct address, we don't cope with the SS mode right now. */ 1039 if (segmented_mode) 1040 { 1041 /* da_operand->X_add_number |= 0x80000000; -- Now set at relocation time. */ 1042 output_ptr = apply_fix (output_ptr, BFD_RELOC_32, da_operand, 8); 1043 } 1044 else 1045 { 1046 output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4); 1047 } 1048 da_operand = 0; 1049 break; 1050 case CLASS_DISP8: 1051 /* pc rel 8 bit */ 1052 output_ptr = apply_fix (output_ptr, BFD_RELOC_8_PCREL, da_operand, 2); 1053 da_operand = 0; 1054 break; 1055 1056 case CLASS_0DISP7: 1057 /* pc rel 7 bit */ 1058 *output_ptr = 0; 1059 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2); 1060 da_operand = 0; 1061 break; 1062 1063 case CLASS_1DISP7: 1064 /* pc rel 7 bit */ 1065 *output_ptr = 0x80; 1066 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2); 1067 output_ptr[-2] = 0x8; 1068 da_operand = 0; 1069 break; 1070 1071 case CLASS_BIT_1OR2: 1072 *output_ptr = c & 0xf; 1073 if (imm_operand) 1074 { 1075 if (imm_operand->X_add_number == 2) 1076 *output_ptr |= 2; 1077 else if (imm_operand->X_add_number != 1) 1078 as_bad (_("immediate must be 1 or 2")); 1079 } 1080 else 1081 as_bad (_("immediate 1 or 2 expected")); 1082 output_ptr++; 1083 break; 1084 case CLASS_CC: 1085 *output_ptr++ = the_cc; 1086 break; 1087 case CLASS_0CCC: 1088 if (the_ctrl < 2 || the_ctrl > 7) 1089 as_bad (_("invalid control register name")); 1090 *output_ptr++ = the_ctrl; 1091 break; 1092 case CLASS_1CCC: 1093 if (the_ctrl < 2 || the_ctrl > 7) 1094 as_bad (_("invalid control register name")); 1095 *output_ptr++ = the_ctrl | 0x8; 1096 break; 1097 case CLASS_00II: 1098 *output_ptr++ = (~the_interrupt & 0x3); 1099 break; 1100 case CLASS_01II: 1101 *output_ptr++ = (~the_interrupt & 0x3) | 0x4; 1102 break; 1103 case CLASS_FLAGS: 1104 *output_ptr++ = the_flags; 1105 break; 1106 case CLASS_IGNORE: 1107 case CLASS_BIT: 1108 *output_ptr++ = c & 0xf; 1109 break; 1110 case CLASS_REGN0: 1111 if (reg[c & 0xf] == 0) 1112 as_bad (_("can't use R0 here")); 1113 /* Fall through. */ 1114 case CLASS_REG: 1115 case CLASS_REG_BYTE: 1116 case CLASS_REG_WORD: 1117 case CLASS_REG_LONG: 1118 case CLASS_REG_QUAD: 1119 /* Insert bit mattern of right reg. */ 1120 *output_ptr++ = reg[c & 0xf]; 1121 break; 1122 case CLASS_DISP: 1123 switch (c & ARG_MASK) 1124 { 1125 case ARG_DISP12: 1126 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_CALLR, da_operand, 4); 1127 break; 1128 case ARG_DISP16: 1129 output_ptr = apply_fix (output_ptr, BFD_RELOC_16_PCREL, da_operand, 4); 1130 break; 1131 default: 1132 output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4); 1133 } 1134 da_operand = 0; 1135 break; 1136 1137 case CLASS_IMM: 1138 { 1139 switch (c & ARG_MASK) 1140 { 1141 case ARG_NIM4: 1142 if (imm_operand->X_add_number > 15) 1143 as_bad (_("immediate value out of range")); 1144 imm_operand->X_add_number = -imm_operand->X_add_number; 1145 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1); 1146 break; 1147 /*case ARG_IMMNMINUS1: not used. */ 1148 case ARG_IMM4M1: 1149 imm_operand->X_add_number--; 1150 /* Drop through. */ 1151 case ARG_IMM4: 1152 if (imm_operand->X_add_number > 15) 1153 as_bad (_("immediate value out of range")); 1154 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1); 1155 break; 1156 case ARG_NIM8: 1157 imm_operand->X_add_number = -imm_operand->X_add_number; 1158 /* Drop through. */ 1159 case ARG_IMM8: 1160 output_ptr = apply_fix (output_ptr, BFD_RELOC_8, imm_operand, 2); 1161 break; 1162 case ARG_IMM16: 1163 output_ptr = apply_fix (output_ptr, BFD_RELOC_16, imm_operand, 4); 1164 break; 1165 case ARG_IMM32: 1166 output_ptr = apply_fix (output_ptr, BFD_RELOC_32, imm_operand, 8); 1167 break; 1168 default: 1169 abort (); 1170 } 1171 } 1172 } 1173 } 1174 1175 /* Copy from the nibble buffer into the frag. */ 1176 { 1177 int length = (output_ptr - buffer) / 2; 1178 char *src = buffer; 1179 char *fragp = frag_more (length); 1180 1181 while (src < output_ptr) 1182 { 1183 *fragp = (src[0] << 4) | src[1]; 1184 src += 2; 1185 fragp++; 1186 } 1187 } 1188 } 1189 1190 /* This is the guts of the machine-dependent assembler. STR points to a 1191 machine dependent instruction. This function is supposed to emit 1192 the frags/bytes it assembles to. */ 1193 1194 void 1195 md_assemble (char *str) 1196 { 1197 char c; 1198 char *op_start; 1199 char *op_end; 1200 struct z8k_op operand[4]; 1201 opcode_entry_type *opcode; 1202 1203 /* Drop leading whitespace. */ 1204 while (*str == ' ') 1205 str++; 1206 1207 /* Find the op code end. */ 1208 for (op_start = op_end = str; 1209 *op_end != 0 && *op_end != ' ' && ! is_end_of_line[(unsigned char) *op_end]; 1210 op_end++) 1211 ; 1212 1213 if (op_end == op_start) 1214 { 1215 as_bad (_("can't find opcode ")); 1216 } 1217 c = *op_end; 1218 1219 *op_end = 0; /* Zero-terminate op code string for hash_find() call. */ 1220 1221 opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start); 1222 1223 if (opcode == NULL) 1224 { 1225 as_bad (_("unknown opcode")); 1226 return; 1227 } 1228 1229 *op_end = c; /* Restore original string. */ 1230 1231 if (opcode->opcode == 250) 1232 { 1233 pseudo_typeS *p; 1234 char oc; 1235 char *old = input_line_pointer; 1236 1237 /* Was really a pseudo op. */ 1238 1239 input_line_pointer = op_end; 1240 1241 oc = *old; 1242 *old = '\n'; 1243 while (*input_line_pointer == ' ') 1244 input_line_pointer++; 1245 p = (pseudo_typeS *) (opcode->func); 1246 1247 (p->poc_handler) (p->poc_val); 1248 input_line_pointer = old; 1249 *old = oc; 1250 } 1251 else 1252 { 1253 char *new_input_line_pointer; 1254 1255 new_input_line_pointer = get_operands (opcode, op_end, operand); 1256 if (new_input_line_pointer) 1257 { 1258 input_line_pointer = new_input_line_pointer; 1259 opcode = get_specific (opcode, operand); 1260 } 1261 1262 if (new_input_line_pointer == NULL || opcode == NULL) 1263 { 1264 /* Couldn't find an opcode which matched the operands. */ 1265 char *where = frag_more (2); 1266 1267 where[0] = 0x0; 1268 where[1] = 0x0; 1269 1270 as_bad (_("Can't find opcode to match operands")); 1271 return; 1272 } 1273 1274 build_bytes (opcode, operand); 1275 } 1276 } 1277 1278 /* We have no need to default values of symbols. */ 1279 1280 symbolS * 1281 md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 1282 { 1283 return 0; 1284 } 1285 1286 /* Various routines to kill one day. */ 1287 1288 char * 1289 md_atof (int type, char *litP, int *sizeP) 1290 { 1291 return ieee_md_atof (type, litP, sizeP, TRUE); 1292 } 1293 1294 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 z8k_target_from_cmdline = 2; 1314 else if (!strcmp (arg, "8002")) 1315 z8k_target_from_cmdline = 1; 1316 else 1317 { 1318 as_bad (_("invalid architecture -z%s"), arg); 1319 return 0; 1320 } 1321 break; 1322 1323 case OPTION_RELAX: 1324 linkrelax = 1; 1325 break; 1326 1327 default: 1328 return 0; 1329 } 1330 1331 return 1; 1332 } 1333 1334 void 1335 md_show_usage (FILE *stream) 1336 { 1337 fprintf (stream, _("\ 1338 Z8K options:\n\ 1339 -z8001 generate segmented code\n\ 1340 -z8002 generate unsegmented code\n\ 1341 -linkrelax create linker relaxable code\n")); 1342 } 1343 1344 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