tc-z8k.c revision 1.1.1.4
1/* tc-z8k.c -- Assemble code for the Zilog Z800n 2 Copyright (C) 1992-2016 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, 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 983static char * 984apply_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 1012static void 1013build_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 1194void 1195md_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 1280symbolS * 1281md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 1282{ 1283 return 0; 1284} 1285 1286/* Various routines to kill one day. */ 1287 1288const char * 1289md_atof (int type, char *litP, int *sizeP) 1290{ 1291 return ieee_md_atof (type, litP, sizeP, TRUE); 1292} 1293 1294const char *md_shortopts = "z:"; 1295 1296struct option md_longopts[] = 1297 { 1298#define OPTION_RELAX (OPTION_MD_BASE) 1299 {"linkrelax", no_argument, NULL, OPTION_RELAX}, 1300 {NULL, no_argument, NULL, 0} 1301 }; 1302 1303size_t md_longopts_size = sizeof (md_longopts); 1304 1305int 1306md_parse_option (int c, const char *arg) 1307{ 1308 switch (c) 1309 { 1310 case 'z': 1311 if (!strcmp (arg, "8001")) 1312 z8k_target_from_cmdline = 2; 1313 else if (!strcmp (arg, "8002")) 1314 z8k_target_from_cmdline = 1; 1315 else 1316 { 1317 as_bad (_("invalid architecture -z%s"), arg); 1318 return 0; 1319 } 1320 break; 1321 1322 case OPTION_RELAX: 1323 linkrelax = 1; 1324 break; 1325 1326 default: 1327 return 0; 1328 } 1329 1330 return 1; 1331} 1332 1333void 1334md_show_usage (FILE *stream) 1335{ 1336 fprintf (stream, _("\ 1337 Z8K options:\n\ 1338 -z8001 generate segmented code\n\ 1339 -z8002 generate unsegmented code\n\ 1340 -linkrelax create linker relaxable code\n")); 1341} 1342 1343void 1344md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, 1345 segT sec ATTRIBUTE_UNUSED, 1346 fragS *fragP ATTRIBUTE_UNUSED) 1347{ 1348 printf (_("call to md_convert_frag\n")); 1349 abort (); 1350} 1351 1352/* Generate a machine dependent reloc from a fixup. */ 1353 1354arelent* 1355tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, 1356 fixS *fixp ATTRIBUTE_UNUSED) 1357{ 1358 arelent *reloc; 1359 1360 reloc = XNEW (arelent); 1361 reloc->sym_ptr_ptr = XNEW (asymbol *); 1362 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 1363 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 1364 reloc->addend = fixp->fx_offset; 1365 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 1366 1367 if (! reloc->howto) 1368 { 1369 as_bad_where (fixp->fx_file, fixp->fx_line, 1370 _("Cannot represent %s relocation in object file"), 1371 bfd_get_reloc_code_name (fixp->fx_r_type)); 1372 abort (); 1373 } 1374 return reloc; 1375} 1376 1377valueT 1378md_section_align (segT seg, valueT size) 1379{ 1380 int align = bfd_get_section_alignment (stdoutput, seg); 1381 valueT mask = ((valueT) 1 << align) - 1; 1382 1383 return (size + mask) & ~mask; 1384} 1385 1386/* Attempt to simplify or eliminate a fixup. To indicate that a fixup 1387 has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL, 1388 we will have to generate a reloc entry. */ 1389void 1390md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED) 1391{ 1392 long val = * (long *) valP; 1393 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; 1394 1395 switch (fixP->fx_r_type) 1396 { 1397 case BFD_RELOC_Z8K_IMM4L: 1398 if (fixP->fx_addsy) 1399 { 1400 fixP->fx_no_overflow = 1; 1401 fixP->fx_done = 0; 1402 } 1403 else 1404 buf[0] = (buf[0] & 0xf0) | (val & 0xf); 1405 break; 1406 1407 case BFD_RELOC_8: 1408 if (fixP->fx_addsy) 1409 { 1410 fixP->fx_no_overflow = 1; 1411 fixP->fx_done = 0; 1412 } 1413 else 1414 *buf++ = val; 1415 break; 1416 1417 case BFD_RELOC_16: 1418 if (fixP->fx_addsy) 1419 { 1420 fixP->fx_no_overflow = 1; 1421 fixP->fx_done = 0; 1422 } 1423 else 1424 { 1425 *buf++ = (val >> 8); 1426 *buf++ = val; 1427 } 1428 break; 1429 1430 case BFD_RELOC_32: 1431 if (fixP->fx_addsy) 1432 { 1433 fixP->fx_no_overflow = 1; 1434 fixP->fx_done = 0; 1435 } 1436 else 1437 { 1438 *buf++ = (val >> 24); 1439 *buf++ = (val >> 16); 1440 *buf++ = (val >> 8); 1441 *buf++ = val; 1442 } 1443 break; 1444 1445 case BFD_RELOC_8_PCREL: 1446 if (fixP->fx_addsy) 1447 { 1448 fixP->fx_no_overflow = 1; 1449 fixP->fx_done = 0; 1450 } 1451 else 1452 { 1453 if (val & 1) 1454 as_bad_where (fixP->fx_file, fixP->fx_line, 1455 _("cannot branch to odd address")); 1456 val /= 2; 1457 if (val > 127 || val < -128) 1458 as_bad_where (fixP->fx_file, fixP->fx_line, 1459 _("relative jump out of range")); 1460 *buf++ = val; 1461 fixP->fx_no_overflow = 1; 1462 fixP->fx_done = 1; 1463 } 1464 break; 1465 1466 case BFD_RELOC_16_PCREL: 1467 if (fixP->fx_addsy) 1468 { 1469 fixP->fx_no_overflow = 1; 1470 fixP->fx_done = 0; 1471 } 1472 else 1473 { 1474 val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size; 1475 if (val > 32767 || val < -32768) 1476 as_bad_where (fixP->fx_file, fixP->fx_line, 1477 _("relative address out of range")); 1478 *buf++ = (val >> 8); 1479 *buf++ = val; 1480 fixP->fx_no_overflow = 1; 1481 fixP->fx_done = 1; 1482 } 1483 break; 1484 1485 case BFD_RELOC_Z8K_CALLR: 1486 if (fixP->fx_addsy) 1487 { 1488 fixP->fx_no_overflow = 1; 1489 fixP->fx_done = 0; 1490 } 1491 else 1492 { 1493 if (val & 1) 1494 as_bad_where (fixP->fx_file, fixP->fx_line, 1495 _("cannot branch to odd address")); 1496 if (val > 4096 || val < -4095) 1497 as_bad_where (fixP->fx_file, fixP->fx_line, 1498 _("relative call out of range")); 1499 val = -val / 2; 1500 *buf = (*buf & 0xf0) | ((val >> 8) & 0xf); 1501 buf++; 1502 *buf++ = val & 0xff; 1503 fixP->fx_no_overflow = 1; 1504 fixP->fx_done = 1; 1505 } 1506 break; 1507 1508 case BFD_RELOC_Z8K_DISP7: 1509 if (fixP->fx_addsy) 1510 { 1511 fixP->fx_no_overflow = 1; 1512 fixP->fx_done = 0; 1513 } 1514 else 1515 { 1516 if (val & 1) 1517 as_bad_where (fixP->fx_file, fixP->fx_line, 1518 _("cannot branch to odd address")); 1519 val /= 2; 1520 if (val > 0 || val < -127) 1521 as_bad_where (fixP->fx_file, fixP->fx_line, 1522 _("relative jump out of range")); 1523 *buf = (*buf & 0x80) | (-val & 0x7f); 1524 fixP->fx_no_overflow = 1; 1525 fixP->fx_done = 1; 1526 } 1527 break; 1528 1529 default: 1530 printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type); 1531 abort (); 1532 } 1533 1534 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) 1535 fixP->fx_done = 1; 1536} 1537 1538int 1539md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, 1540 segT segment_type ATTRIBUTE_UNUSED) 1541{ 1542 printf (_("call to md_estimate_size_before_relax\n")); 1543 abort (); 1544} 1545 1546/* Put number into target byte order. */ 1547 1548void 1549md_number_to_chars (char *ptr, valueT use, int nbytes) 1550{ 1551 number_to_chars_bigendian (ptr, use, nbytes); 1552} 1553 1554/* On the Z8000, a PC-relative offset is relative to the address of the 1555 instruction plus its size. */ 1556long 1557md_pcrel_from (fixS *fixP) 1558{ 1559 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address; 1560} 1561 1562void 1563tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED) 1564{ 1565} 1566