1/* tc-z8k.c -- Assemble code for the Zilog Z800n 2 Copyright (C) 1992-2017 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@cygnus.com>. */ 22 23#include "as.h" 24#include "safe-ctype.h" 25#define DEFINE_TABLE 26#include "opcodes/z8k-opc.h" 27 28const char comment_chars[] = "!"; 29const char line_comment_chars[] = "#"; 30const char line_separator_chars[] = ";"; 31 32extern int machine; 33extern int coff_flags; 34int 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). */ 38static int z8k_target_from_cmdline; 39 40static void 41s_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 55static void 56even (int ignore ATTRIBUTE_UNUSED) 57{ 58 frag_align (1, 0, 0); 59 record_alignment (now_seg, 1); 60} 61 62static int 63tohex (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 72static void 73sval (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 103const 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 132const 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 */ 137const char FLT_CHARS[] = "rRsSfFdDxXpP"; 138 139/* Opcode mnemonics. */ 140static struct hash_control *opcode_hash_control; 141 142void 143md_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 = XNEW (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 173typedef 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 189static expressionS *da_operand; 190static expressionS *imm_operand; 191 192static int reg[16]; 193static int the_cc; 194static int the_ctrl; 195static int the_flags; 196static 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 204static char * 205whatreg (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 245static char * 246parse_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 340static char * 341parse_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 369static char * 370checkfor (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 382static void 383regword (int mode, const 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 396static void 397regaddr (int mode, const 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 408struct ctrl_names { 409 int value; 410 const char *name; 411}; 412 413static 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 426static void 427get_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 451struct flag_names { 452 int value; 453 const char *name; 454}; 455 456static 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 467static void 468get_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 501struct interrupt_names { 502 int value; 503 const char *name; 504}; 505 506static struct interrupt_names intr_table[] = { 507 { 0x1, "nvi" }, 508 { 0x2, "vi" }, 509 { 0x3, "both" }, 510 { 0x3, "all" }, 511 { 0, 0 } 512}; 513 514static void 515get_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 565struct cc_names { 566 int value; 567 const char *name; 568}; 569 570static 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 604static void 605get_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 629static void 630get_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 729static char * 730get_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 857static opcode_entry_type * 858get_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 956static char buffer[20]; 957 958static void 959newfix (int ptr, bfd_reloc_code_real_type type, int size, expressionS *operand) 960{ 961 fixS *fixP; 962 963 /* Size is in nibbles. */ 964 if (operand->X_add_symbol 965 || operand->X_op_symbol 966 || operand->X_add_number) 967 { 968 int is_pcrel; 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 break; 976 default: 977 is_pcrel = 0; 978 break; 979 } 980 fixP = fix_new_exp (frag_now, ptr, size / 2, 981 operand, is_pcrel, type); 982 if (is_pcrel) 983 fixP->fx_no_overflow = 1; 984 } 985} 986 987static char * 988apply_fix (char *ptr, bfd_reloc_code_real_type type, expressionS *operand, 989 int size) 990{ 991 long n = operand->X_add_number; 992 993 /* size is in nibbles. */ 994 995 newfix ((ptr - buffer) / 2, type, size + 1, operand); 996 switch (size) 997 { 998 case 8: /* 8 nibbles == 32 bits. */ 999 *ptr++ = n >> 28; 1000 *ptr++ = n >> 24; 1001 *ptr++ = n >> 20; 1002 *ptr++ = n >> 16; 1003 /* Fall through. */ 1004 case 4: /* 4 nibbles == 16 bits. */ 1005 *ptr++ = n >> 12; 1006 *ptr++ = n >> 8; 1007 /* Fall through. */ 1008 case 2: 1009 *ptr++ = n >> 4; 1010 /* Fall through. */ 1011 case 1: 1012 *ptr++ = n >> 0; 1013 break; 1014 } 1015 return ptr; 1016} 1017 1018/* Now we know what sort of opcodes it is. Let's build the bytes. */ 1019 1020static void 1021build_bytes (opcode_entry_type *this_try, struct z8k_op *operand ATTRIBUTE_UNUSED) 1022{ 1023 char *output_ptr = buffer; 1024 int c; 1025 int nibble; 1026 unsigned int *class_ptr; 1027 1028 frag_wane (frag_now); 1029 frag_new (0); 1030 1031 if (frag_room () < 8) 1032 frag_grow (8); /* Make room for maximum instruction size. */ 1033 1034 memset (buffer, 0, sizeof (buffer)); 1035 class_ptr = this_try->byte_info; 1036 1037 for (nibble = 0; (c = *class_ptr++); nibble++) 1038 { 1039 1040 switch (c & CLASS_MASK) 1041 { 1042 default: 1043 abort (); 1044 1045 case CLASS_ADDRESS: 1046 /* Direct address, we don't cope with the SS mode right now. */ 1047 if (segmented_mode) 1048 { 1049 /* da_operand->X_add_number |= 0x80000000; -- Now set at relocation time. */ 1050 output_ptr = apply_fix (output_ptr, BFD_RELOC_32, da_operand, 8); 1051 } 1052 else 1053 { 1054 output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4); 1055 } 1056 da_operand = 0; 1057 break; 1058 case CLASS_DISP8: 1059 /* pc rel 8 bit */ 1060 output_ptr = apply_fix (output_ptr, BFD_RELOC_8_PCREL, da_operand, 2); 1061 da_operand = 0; 1062 break; 1063 1064 case CLASS_0DISP7: 1065 /* pc rel 7 bit */ 1066 *output_ptr = 0; 1067 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2); 1068 da_operand = 0; 1069 break; 1070 1071 case CLASS_1DISP7: 1072 /* pc rel 7 bit */ 1073 *output_ptr = 0x80; 1074 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2); 1075 output_ptr[-2] = 0x8; 1076 da_operand = 0; 1077 break; 1078 1079 case CLASS_BIT_1OR2: 1080 *output_ptr = c & 0xf; 1081 if (imm_operand) 1082 { 1083 if (imm_operand->X_add_number == 2) 1084 *output_ptr |= 2; 1085 else if (imm_operand->X_add_number != 1) 1086 as_bad (_("immediate must be 1 or 2")); 1087 } 1088 else 1089 as_bad (_("immediate 1 or 2 expected")); 1090 output_ptr++; 1091 break; 1092 case CLASS_CC: 1093 *output_ptr++ = the_cc; 1094 break; 1095 case CLASS_0CCC: 1096 if (the_ctrl < 2 || the_ctrl > 7) 1097 as_bad (_("invalid control register name")); 1098 *output_ptr++ = the_ctrl; 1099 break; 1100 case CLASS_1CCC: 1101 if (the_ctrl < 2 || the_ctrl > 7) 1102 as_bad (_("invalid control register name")); 1103 *output_ptr++ = the_ctrl | 0x8; 1104 break; 1105 case CLASS_00II: 1106 *output_ptr++ = (~the_interrupt & 0x3); 1107 break; 1108 case CLASS_01II: 1109 *output_ptr++ = (~the_interrupt & 0x3) | 0x4; 1110 break; 1111 case CLASS_FLAGS: 1112 *output_ptr++ = the_flags; 1113 break; 1114 case CLASS_IGNORE: 1115 case CLASS_BIT: 1116 *output_ptr++ = c & 0xf; 1117 break; 1118 case CLASS_REGN0: 1119 if (reg[c & 0xf] == 0) 1120 as_bad (_("can't use R0 here")); 1121 /* Fall through. */ 1122 case CLASS_REG: 1123 case CLASS_REG_BYTE: 1124 case CLASS_REG_WORD: 1125 case CLASS_REG_LONG: 1126 case CLASS_REG_QUAD: 1127 /* Insert bit mattern of right reg. */ 1128 *output_ptr++ = reg[c & 0xf]; 1129 break; 1130 case CLASS_DISP: 1131 switch (c & ARG_MASK) 1132 { 1133 case ARG_DISP12: 1134 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_CALLR, da_operand, 4); 1135 break; 1136 case ARG_DISP16: 1137 output_ptr = apply_fix (output_ptr, BFD_RELOC_16_PCREL, da_operand, 4); 1138 break; 1139 default: 1140 output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4); 1141 } 1142 da_operand = 0; 1143 break; 1144 1145 case CLASS_IMM: 1146 { 1147 switch (c & ARG_MASK) 1148 { 1149 case ARG_NIM4: 1150 if (imm_operand->X_add_number > 15) 1151 as_bad (_("immediate value out of range")); 1152 imm_operand->X_add_number = -imm_operand->X_add_number; 1153 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1); 1154 break; 1155 /*case ARG_IMMNMINUS1: not used. */ 1156 case ARG_IMM4M1: 1157 imm_operand->X_add_number--; 1158 /* Fall through. */ 1159 case ARG_IMM4: 1160 if (imm_operand->X_add_number > 15) 1161 as_bad (_("immediate value out of range")); 1162 output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1); 1163 break; 1164 case ARG_NIM8: 1165 imm_operand->X_add_number = -imm_operand->X_add_number; 1166 /* Fall through. */ 1167 case ARG_IMM8: 1168 output_ptr = apply_fix (output_ptr, BFD_RELOC_8, imm_operand, 2); 1169 break; 1170 case ARG_IMM16: 1171 output_ptr = apply_fix (output_ptr, BFD_RELOC_16, imm_operand, 4); 1172 break; 1173 case ARG_IMM32: 1174 output_ptr = apply_fix (output_ptr, BFD_RELOC_32, imm_operand, 8); 1175 break; 1176 default: 1177 abort (); 1178 } 1179 } 1180 } 1181 } 1182 1183 /* Copy from the nibble buffer into the frag. */ 1184 { 1185 int length = (output_ptr - buffer) / 2; 1186 char *src = buffer; 1187 char *fragp = frag_more (length); 1188 1189 while (src < output_ptr) 1190 { 1191 *fragp = (src[0] << 4) | src[1]; 1192 src += 2; 1193 fragp++; 1194 } 1195 } 1196} 1197 1198/* This is the guts of the machine-dependent assembler. STR points to a 1199 machine dependent instruction. This function is supposed to emit 1200 the frags/bytes it assembles to. */ 1201 1202void 1203md_assemble (char *str) 1204{ 1205 char c; 1206 char *op_start; 1207 char *op_end; 1208 struct z8k_op operand[4]; 1209 opcode_entry_type *opcode; 1210 1211 /* Drop leading whitespace. */ 1212 while (*str == ' ') 1213 str++; 1214 1215 /* Find the op code end. */ 1216 for (op_start = op_end = str; 1217 *op_end != 0 && *op_end != ' ' && ! is_end_of_line[(unsigned char) *op_end]; 1218 op_end++) 1219 ; 1220 1221 if (op_end == op_start) 1222 { 1223 as_bad (_("can't find opcode ")); 1224 } 1225 c = *op_end; 1226 1227 *op_end = 0; /* Zero-terminate op code string for hash_find() call. */ 1228 1229 opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start); 1230 1231 if (opcode == NULL) 1232 { 1233 as_bad (_("unknown opcode")); 1234 return; 1235 } 1236 1237 *op_end = c; /* Restore original string. */ 1238 1239 if (opcode->opcode == 250) 1240 { 1241 pseudo_typeS *p; 1242 char oc; 1243 char *old = input_line_pointer; 1244 1245 /* Was really a pseudo op. */ 1246 1247 input_line_pointer = op_end; 1248 1249 oc = *old; 1250 *old = '\n'; 1251 while (*input_line_pointer == ' ') 1252 input_line_pointer++; 1253 p = (pseudo_typeS *) (opcode->func); 1254 1255 (p->poc_handler) (p->poc_val); 1256 input_line_pointer = old; 1257 *old = oc; 1258 } 1259 else 1260 { 1261 char *new_input_line_pointer; 1262 1263 new_input_line_pointer = get_operands (opcode, op_end, operand); 1264 if (new_input_line_pointer) 1265 { 1266 input_line_pointer = new_input_line_pointer; 1267 opcode = get_specific (opcode, operand); 1268 } 1269 1270 if (new_input_line_pointer == NULL || opcode == NULL) 1271 { 1272 /* Couldn't find an opcode which matched the operands. */ 1273 char *where = frag_more (2); 1274 1275 where[0] = 0x0; 1276 where[1] = 0x0; 1277 1278 as_bad (_("Can't find opcode to match operands")); 1279 return; 1280 } 1281 1282 build_bytes (opcode, operand); 1283 } 1284} 1285 1286/* We have no need to default values of symbols. */ 1287 1288symbolS * 1289md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 1290{ 1291 return 0; 1292} 1293 1294/* Various routines to kill one day. */ 1295 1296const char * 1297md_atof (int type, char *litP, int *sizeP) 1298{ 1299 return ieee_md_atof (type, litP, sizeP, TRUE); 1300} 1301 1302const char *md_shortopts = "z:"; 1303 1304struct option md_longopts[] = 1305 { 1306#define OPTION_RELAX (OPTION_MD_BASE) 1307 {"linkrelax", no_argument, NULL, OPTION_RELAX}, 1308 {NULL, no_argument, NULL, 0} 1309 }; 1310 1311size_t md_longopts_size = sizeof (md_longopts); 1312 1313int 1314md_parse_option (int c, const char *arg) 1315{ 1316 switch (c) 1317 { 1318 case 'z': 1319 if (!strcmp (arg, "8001")) 1320 z8k_target_from_cmdline = 2; 1321 else if (!strcmp (arg, "8002")) 1322 z8k_target_from_cmdline = 1; 1323 else 1324 { 1325 as_bad (_("invalid architecture -z%s"), arg); 1326 return 0; 1327 } 1328 break; 1329 1330 case OPTION_RELAX: 1331 linkrelax = 1; 1332 break; 1333 1334 default: 1335 return 0; 1336 } 1337 1338 return 1; 1339} 1340 1341void 1342md_show_usage (FILE *stream) 1343{ 1344 fprintf (stream, _("\ 1345 Z8K options:\n\ 1346 -z8001 generate segmented code\n\ 1347 -z8002 generate unsegmented code\n\ 1348 -linkrelax create linker relaxable code\n")); 1349} 1350 1351void 1352md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, 1353 segT sec ATTRIBUTE_UNUSED, 1354 fragS *fragP ATTRIBUTE_UNUSED) 1355{ 1356 printf (_("call to md_convert_frag\n")); 1357 abort (); 1358} 1359 1360/* Generate a machine dependent reloc from a fixup. */ 1361 1362arelent* 1363tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, 1364 fixS *fixp ATTRIBUTE_UNUSED) 1365{ 1366 arelent *reloc; 1367 1368 reloc = XNEW (arelent); 1369 reloc->sym_ptr_ptr = XNEW (asymbol *); 1370 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 1371 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 1372 reloc->addend = fixp->fx_offset; 1373 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 1374 1375 if (! reloc->howto) 1376 { 1377 as_bad_where (fixp->fx_file, fixp->fx_line, 1378 _("Cannot represent %s relocation in object file"), 1379 bfd_get_reloc_code_name (fixp->fx_r_type)); 1380 abort (); 1381 } 1382 return reloc; 1383} 1384 1385valueT 1386md_section_align (segT seg, valueT size) 1387{ 1388 int align = bfd_get_section_alignment (stdoutput, seg); 1389 valueT mask = ((valueT) 1 << align) - 1; 1390 1391 return (size + mask) & ~mask; 1392} 1393 1394/* Attempt to simplify or eliminate a fixup. To indicate that a fixup 1395 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL, 1396 we will have to generate a reloc entry. */ 1397void 1398md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED) 1399{ 1400 long val = * (long *) valP; 1401 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; 1402 1403 switch (fixP->fx_r_type) 1404 { 1405 case BFD_RELOC_Z8K_IMM4L: 1406 if (fixP->fx_addsy) 1407 { 1408 fixP->fx_no_overflow = 1; 1409 fixP->fx_done = 0; 1410 } 1411 else 1412 buf[0] = (buf[0] & 0xf0) | (val & 0xf); 1413 break; 1414 1415 case BFD_RELOC_8: 1416 if (fixP->fx_addsy) 1417 { 1418 fixP->fx_no_overflow = 1; 1419 fixP->fx_done = 0; 1420 } 1421 else 1422 *buf++ = val; 1423 break; 1424 1425 case BFD_RELOC_16: 1426 if (fixP->fx_addsy) 1427 { 1428 fixP->fx_no_overflow = 1; 1429 fixP->fx_done = 0; 1430 } 1431 else 1432 { 1433 *buf++ = (val >> 8); 1434 *buf++ = val; 1435 } 1436 break; 1437 1438 case BFD_RELOC_32: 1439 if (fixP->fx_addsy) 1440 { 1441 fixP->fx_no_overflow = 1; 1442 fixP->fx_done = 0; 1443 } 1444 else 1445 { 1446 *buf++ = (val >> 24); 1447 *buf++ = (val >> 16); 1448 *buf++ = (val >> 8); 1449 *buf++ = val; 1450 } 1451 break; 1452 1453 case BFD_RELOC_8_PCREL: 1454 if (fixP->fx_addsy) 1455 { 1456 fixP->fx_no_overflow = 1; 1457 fixP->fx_done = 0; 1458 } 1459 else 1460 { 1461 if (val & 1) 1462 as_bad_where (fixP->fx_file, fixP->fx_line, 1463 _("cannot branch to odd address")); 1464 val /= 2; 1465 if (val > 127 || val < -128) 1466 as_bad_where (fixP->fx_file, fixP->fx_line, 1467 _("relative jump out of range")); 1468 *buf++ = val; 1469 fixP->fx_no_overflow = 1; 1470 fixP->fx_done = 1; 1471 } 1472 break; 1473 1474 case BFD_RELOC_16_PCREL: 1475 if (fixP->fx_addsy) 1476 { 1477 fixP->fx_no_overflow = 1; 1478 fixP->fx_done = 0; 1479 } 1480 else 1481 { 1482 val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size; 1483 if (val > 32767 || val < -32768) 1484 as_bad_where (fixP->fx_file, fixP->fx_line, 1485 _("relative address out of range")); 1486 *buf++ = (val >> 8); 1487 *buf++ = val; 1488 fixP->fx_no_overflow = 1; 1489 fixP->fx_done = 1; 1490 } 1491 break; 1492 1493 case BFD_RELOC_Z8K_CALLR: 1494 if (fixP->fx_addsy) 1495 { 1496 fixP->fx_no_overflow = 1; 1497 fixP->fx_done = 0; 1498 } 1499 else 1500 { 1501 if (val & 1) 1502 as_bad_where (fixP->fx_file, fixP->fx_line, 1503 _("cannot branch to odd address")); 1504 if (val > 4096 || val < -4095) 1505 as_bad_where (fixP->fx_file, fixP->fx_line, 1506 _("relative call out of range")); 1507 val = -val / 2; 1508 *buf = (*buf & 0xf0) | ((val >> 8) & 0xf); 1509 buf++; 1510 *buf++ = val & 0xff; 1511 fixP->fx_no_overflow = 1; 1512 fixP->fx_done = 1; 1513 } 1514 break; 1515 1516 case BFD_RELOC_Z8K_DISP7: 1517 if (fixP->fx_addsy) 1518 { 1519 fixP->fx_no_overflow = 1; 1520 fixP->fx_done = 0; 1521 } 1522 else 1523 { 1524 if (val & 1) 1525 as_bad_where (fixP->fx_file, fixP->fx_line, 1526 _("cannot branch to odd address")); 1527 val /= 2; 1528 if (val > 0 || val < -127) 1529 as_bad_where (fixP->fx_file, fixP->fx_line, 1530 _("relative jump out of range")); 1531 *buf = (*buf & 0x80) | (-val & 0x7f); 1532 fixP->fx_no_overflow = 1; 1533 fixP->fx_done = 1; 1534 } 1535 break; 1536 1537 default: 1538 printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type); 1539 abort (); 1540 } 1541 1542 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) 1543 fixP->fx_done = 1; 1544} 1545 1546int 1547md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, 1548 segT segment_type ATTRIBUTE_UNUSED) 1549{ 1550 printf (_("call to md_estimate_size_before_relax\n")); 1551 abort (); 1552} 1553 1554/* Put number into target byte order. */ 1555 1556void 1557md_number_to_chars (char *ptr, valueT use, int nbytes) 1558{ 1559 number_to_chars_bigendian (ptr, use, nbytes); 1560} 1561 1562/* On the Z8000, a PC-relative offset is relative to the address of the 1563 instruction plus its size. */ 1564long 1565md_pcrel_from (fixS *fixP) 1566{ 1567 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; 1568} 1569 1570void 1571tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED) 1572{ 1573} 1574