1 /* tc-z80.c -- Assemble code for the Zilog Z80 and ASCII R800 2 Copyright 2005 Free Software Foundation, Inc. 3 Contributed by Arnold Metselaar <arnold_m@operamail.com> 4 5 This file is part of GAS, the GNU Assembler. 6 7 GAS is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 GAS is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GAS; see the file COPYING. If not, write to the Free 19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22 #include "as.h" 23 #include "listing.h" 24 #include "bfd.h" 25 #include "safe-ctype.h" 26 #include "subsegs.h" 27 #include "symbols.h" 28 #include "libiberty.h" 29 30 /* Exported constants. */ 31 const char comment_chars[] = ";\0"; 32 const char line_comment_chars[] = "#;\0"; 33 const char line_separator_chars[] = "\0"; 34 const char EXP_CHARS[] = "eE\0"; 35 const char FLT_CHARS[] = "RrFf\0"; 36 37 /* For machine specific options. */ 38 const char * md_shortopts = ""; /* None yet. */ 39 40 enum options 41 { 42 OPTION_MACH_Z80 = OPTION_MD_BASE, 43 OPTION_MACH_R800, 44 OPTION_MACH_IUD, 45 OPTION_MACH_WUD, 46 OPTION_MACH_FUD, 47 OPTION_MACH_IUP, 48 OPTION_MACH_WUP, 49 OPTION_MACH_FUP 50 }; 51 52 #define INS_Z80 1 53 #define INS_UNDOC 2 54 #define INS_UNPORT 4 55 #define INS_R800 8 56 57 struct option md_longopts[] = 58 { 59 { "z80", no_argument, NULL, OPTION_MACH_Z80}, 60 { "r800", no_argument, NULL, OPTION_MACH_R800}, 61 { "ignore-undocumented-instructions", no_argument, NULL, OPTION_MACH_IUD }, 62 { "Wnud", no_argument, NULL, OPTION_MACH_IUD }, 63 { "warn-undocumented-instructions", no_argument, NULL, OPTION_MACH_WUD }, 64 { "Wud", no_argument, NULL, OPTION_MACH_WUD }, 65 { "forbid-undocumented-instructions", no_argument, NULL, OPTION_MACH_FUD }, 66 { "Fud", no_argument, NULL, OPTION_MACH_FUD }, 67 { "ignore-unportable-instructions", no_argument, NULL, OPTION_MACH_IUP }, 68 { "Wnup", no_argument, NULL, OPTION_MACH_IUP }, 69 { "warn-unportable-instructions", no_argument, NULL, OPTION_MACH_WUP }, 70 { "Wup", no_argument, NULL, OPTION_MACH_WUP }, 71 { "forbid-unportable-instructions", no_argument, NULL, OPTION_MACH_FUP }, 72 { "Fup", no_argument, NULL, OPTION_MACH_FUP }, 73 74 { NULL, no_argument, NULL, 0 } 75 } ; 76 77 size_t md_longopts_size = sizeof (md_longopts); 78 79 extern int coff_flags; 80 /* Instruction classes that silently assembled. */ 81 static int ins_ok = INS_Z80 | INS_UNDOC; 82 /* Instruction classes that generate errors. */ 83 static int ins_err = INS_R800; 84 /* Instruction classes actually used, determines machine type. */ 85 static int ins_used = INS_Z80; 86 87 int 88 md_parse_option (int c, char* arg ATTRIBUTE_UNUSED) 89 { 90 switch (c) 91 { 92 default: 93 return 0; 94 case OPTION_MACH_Z80: 95 ins_ok &= ~INS_R800; 96 ins_err |= INS_R800; 97 break; 98 case OPTION_MACH_R800: 99 ins_ok = INS_Z80 | INS_UNDOC | INS_R800; 100 ins_err = INS_UNPORT; 101 break; 102 case OPTION_MACH_IUD: 103 ins_ok |= INS_UNDOC; 104 ins_err &= ~INS_UNDOC; 105 break; 106 case OPTION_MACH_IUP: 107 ins_ok |= INS_UNDOC | INS_UNPORT; 108 ins_err &= ~(INS_UNDOC | INS_UNPORT); 109 break; 110 case OPTION_MACH_WUD: 111 if ((ins_ok & INS_R800) == 0) 112 { 113 ins_ok &= ~(INS_UNDOC|INS_UNPORT); 114 ins_err &= ~INS_UNDOC; 115 } 116 break; 117 case OPTION_MACH_WUP: 118 ins_ok &= ~INS_UNPORT; 119 ins_err &= ~(INS_UNDOC|INS_UNPORT); 120 break; 121 case OPTION_MACH_FUD: 122 if ((ins_ok & INS_R800) == 0) 123 { 124 ins_ok &= (INS_UNDOC | INS_UNPORT); 125 ins_err |= INS_UNDOC | INS_UNPORT; 126 } 127 break; 128 case OPTION_MACH_FUP: 129 ins_ok &= ~INS_UNPORT; 130 ins_err |= INS_UNPORT; 131 break; 132 } 133 134 return 1; 135 } 136 137 void 138 md_show_usage (FILE * f) 139 { 140 fprintf (f, "\n\ 141 CPU model/instruction set options:\n\ 142 \n\ 143 -z80\t\t assemble for Z80\n\ 144 -ignore-undocumented-instructions\n\ 145 -Wnud\n\ 146 \tsilently assemble undocumented Z80-instructions that work on R800\n\ 147 -ignore-unportable-instructions\n\ 148 -Wnup\n\ 149 \tsilently assemble all undocumented Z80-instructions\n\ 150 -warn-undocumented-instructions\n\ 151 -Wud\n\ 152 \tissue warnings for undocumented Z80-instructions that work on R800\n\ 153 -warn-unportable-instructions\n\ 154 -Wup\n\ 155 \tissue warnings for other undocumented Z80-instructions\n\ 156 -forbid-undocumented-instructions\n\ 157 -Fud\n\ 158 \ttreat all undocumented z80-instructions as errors\n\ 159 -forbid-unportable-instructions\n\ 160 -Fup\n\ 161 \ttreat undocumented z80-instructions that do not work on R800 as errors\n\ 162 -r800\t assemble for R800\n\n\ 163 Default: -z80 -ignore-undocument-instructions -warn-unportable-instructions.\n"); 164 } 165 166 static symbolS * zero; 167 168 void 169 md_begin (void) 170 { 171 expressionS nul; 172 char * p; 173 174 p = input_line_pointer; 175 input_line_pointer = "0"; 176 nul.X_md=0; 177 expression (& nul); 178 input_line_pointer = p; 179 zero = make_expr_symbol (& nul); 180 /* We do not use relaxation (yet). */ 181 linkrelax = 0; 182 } 183 184 void 185 z80_md_end (void) 186 { 187 int mach_type; 188 189 if (ins_used & (INS_UNPORT | INS_R800)) 190 ins_used |= INS_UNDOC; 191 192 switch (ins_used) 193 { 194 case INS_Z80: 195 mach_type = bfd_mach_z80strict; 196 break; 197 case INS_Z80|INS_UNDOC: 198 mach_type = bfd_mach_z80; 199 break; 200 case INS_Z80|INS_UNDOC|INS_UNPORT: 201 mach_type = bfd_mach_z80full; 202 break; 203 case INS_Z80|INS_UNDOC|INS_R800: 204 mach_type = bfd_mach_r800; 205 break; 206 default: 207 mach_type = 0; 208 } 209 210 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type); 211 } 212 213 static const char * 214 skip_space (const char *s) 215 { 216 while (*s == ' ' || *s == '\t') 217 ++s; 218 return s; 219 } 220 221 /* A non-zero return-value causes a continue in the 222 function read_a_source_file () in ../read.c. */ 223 int 224 z80_start_line_hook (void) 225 { 226 char *p, quote; 227 char buf[4]; 228 229 /* Convert one character constants. */ 230 for (p = input_line_pointer; *p && *p != '\n'; ++p) 231 { 232 switch (*p) 233 { 234 case '\'': 235 if (p[1] != 0 && p[1] != '\'' && p[2] == '\'') 236 { 237 snprintf (buf, 4, "%3d", (unsigned char)p[1]); 238 *p++ = buf[0]; 239 *p++ = buf[1]; 240 *p++ = buf[2]; 241 break; 242 } 243 case '"': 244 for (quote = *p++; quote != *p && '\n' != *p; ++p) 245 /* No escapes. */ ; 246 if (quote != *p) 247 { 248 as_bad (_("-- unterminated string")); 249 ignore_rest_of_line (); 250 return 1; 251 } 252 break; 253 } 254 } 255 /* Check for <label>[:] [.](EQU|DEFL) <value>. */ 256 if (is_name_beginner (*input_line_pointer)) 257 { 258 char c, *rest, *line_start; 259 int len; 260 symbolS * symbolP; 261 262 line_start = input_line_pointer; 263 LISTING_NEWLINE (); 264 if (ignore_input ()) 265 return 0; 266 267 c = get_symbol_end (); 268 rest = input_line_pointer + 1; 269 270 if (*rest == ':') 271 ++rest; 272 if (*rest == ' ' || *rest == '\t') 273 ++rest; 274 if (*rest == '.') 275 ++rest; 276 if (strncasecmp (rest, "EQU", 3) == 0) 277 len = 3; 278 else if (strncasecmp (rest, "DEFL", 4) == 0) 279 len = 4; 280 else 281 len = 0; 282 if (len && (rest[len] == ' ' || rest[len] == '\t')) 283 { 284 /* Handle assignment here. */ 285 input_line_pointer = rest + len; 286 if (line_start[-1] == '\n') 287 bump_line_counters (); 288 /* Most Z80 assemblers require the first definition of a 289 label to use "EQU" and redefinitions to have "DEFL". */ 290 if (len == 3 && (symbolP = symbol_find (line_start)) != NULL) 291 { 292 if (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP)) 293 as_bad (_("symbol `%s' is already defined"), line_start); 294 } 295 equals (line_start, 1); 296 return 1; 297 } 298 else 299 { 300 /* Restore line and pointer. */ 301 *input_line_pointer = c; 302 input_line_pointer = line_start; 303 } 304 } 305 return 0; 306 } 307 308 symbolS * 309 md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 310 { 311 return NULL; 312 } 313 314 char * 315 md_atof (int type ATTRIBUTE_UNUSED, char *litP ATTRIBUTE_UNUSED, 316 int *sizeP ATTRIBUTE_UNUSED) 317 { 318 return _("floating point numbers are not implemented"); 319 } 320 321 valueT 322 md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size) 323 { 324 return size; 325 } 326 327 long 328 md_pcrel_from (fixS * fixp) 329 { 330 return fixp->fx_where + 331 fixp->fx_frag->fr_address + 1; 332 } 333 334 typedef const char * (asfunc)(char, char, const char*); 335 336 typedef struct _table_t 337 { 338 char* name; 339 char prefix; 340 char opcode; 341 asfunc * fp; 342 } table_t; 343 344 /* Compares the key for structs that start with a char * to the key. */ 345 static int 346 key_cmp (const void * a, const void * b) 347 { 348 const char *str_a, *str_b; 349 350 str_a = *((const char**)a); 351 str_b = *((const char**)b); 352 return strcmp (str_a, str_b); 353 } 354 355 #define BUFLEN 8 /* Large enough for any keyword. */ 356 357 char buf[BUFLEN]; 358 const char *key = buf; 359 360 #define R_STACKABLE (0x80) 361 #define R_ARITH (0x40) 362 #define R_IX (0x20) 363 #define R_IY (0x10) 364 #define R_INDEX (R_IX | R_IY) 365 366 #define REG_A (7) 367 #define REG_B (0) 368 #define REG_C (1) 369 #define REG_D (2) 370 #define REG_E (3) 371 #define REG_H (4) 372 #define REG_L (5) 373 #define REG_F (6 | 8) 374 #define REG_I (9) 375 #define REG_R (10) 376 377 #define REG_AF (3 | R_STACKABLE) 378 #define REG_BC (0 | R_STACKABLE | R_ARITH) 379 #define REG_DE (1 | R_STACKABLE | R_ARITH) 380 #define REG_HL (2 | R_STACKABLE | R_ARITH) 381 #define REG_SP (3 | R_ARITH) 382 383 static const struct reg_entry 384 { 385 char* name; 386 int number; 387 } regtable[] = 388 { 389 {"a", REG_A }, 390 {"af", REG_AF }, 391 {"b", REG_B }, 392 {"bc", REG_BC }, 393 {"c", REG_C }, 394 {"d", REG_D }, 395 {"de", REG_DE }, 396 {"e", REG_E }, 397 {"f", REG_F }, 398 {"h", REG_H }, 399 {"hl", REG_HL }, 400 {"i", REG_I }, 401 {"ix", REG_HL | R_IX }, 402 {"ixh",REG_H | R_IX }, 403 {"ixl",REG_L | R_IX }, 404 {"iy", REG_HL | R_IY }, 405 {"iyh",REG_H | R_IY }, 406 {"iyl",REG_L | R_IY }, 407 {"l", REG_L }, 408 {"r", REG_R }, 409 {"sp", REG_SP }, 410 } ; 411 412 /* Prevent an error on a line from also generating 413 a "junk at end of line" error message. */ 414 static char err_flag; 415 416 static void 417 error (const char * message) 418 { 419 as_bad (message); 420 err_flag = 1; 421 } 422 423 static void 424 ill_op (void) 425 { 426 error (_("illegal operand")); 427 } 428 429 static void 430 wrong_mach (int ins_type) 431 { 432 const char *p; 433 434 switch (ins_type) 435 { 436 case INS_UNDOC: 437 p = "undocumented instruction"; 438 break; 439 case INS_UNPORT: 440 p = "instruction does not work on R800"; 441 break; 442 case INS_R800: 443 p = "instruction only works R800"; 444 break; 445 default: 446 p = 0; /* Not reachable. */ 447 } 448 449 if (ins_type & ins_err) 450 error (_(p)); 451 else 452 as_warn (_(p)); 453 } 454 455 static void 456 check_mach (int ins_type) 457 { 458 if ((ins_type & ins_ok) == 0) 459 wrong_mach (ins_type); 460 ins_used |= ins_type; 461 } 462 463 /* Check whether an expression is indirect. */ 464 static int 465 is_indir (const char *s) 466 { 467 char quote; 468 const char *p; 469 int indir, depth; 470 471 /* Indirection is indicated with parentheses. */ 472 indir = (*s == '('); 473 474 for (p = s, depth = 0; *p && *p != ','; ++p) 475 { 476 switch (*p) 477 { 478 case '"': 479 case '\'': 480 for (quote = *p++; quote != *p && *p != '\n'; ++p) 481 if (*p == '\\' && p[1]) 482 ++p; 483 break; 484 case '(': 485 ++ depth; 486 break; 487 case ')': 488 -- depth; 489 if (depth == 0) 490 { 491 p = skip_space (p + 1); 492 if (*p && *p != ',') 493 indir = 0; 494 --p; 495 } 496 if (depth < 0) 497 error (_("mismatched parentheses")); 498 break; 499 } 500 } 501 502 if (depth != 0) 503 error (_("mismatched parentheses")); 504 505 return indir; 506 } 507 508 /* Parse general expression. */ 509 static const char * 510 parse_exp2 (const char *s, expressionS *op, segT *pseg) 511 { 512 const char *p; 513 int indir; 514 int i; 515 const struct reg_entry * regp; 516 expressionS offset; 517 518 p = skip_space (s); 519 op->X_md = indir = is_indir (p); 520 if (indir) 521 p = skip_space (p + 1); 522 523 for (i = 0; i < BUFLEN; ++i) 524 { 525 if (!ISALPHA (p[i])) /* Register names consist of letters only. */ 526 break; 527 buf[i] = TOLOWER (p[i]); 528 } 529 530 if ((i < BUFLEN) && ((p[i] == 0) || (strchr (")+-, \t", p[i])))) 531 { 532 buf[i] = 0; 533 regp = bsearch (& key, regtable, ARRAY_SIZE (regtable), 534 sizeof (regtable[0]), key_cmp); 535 if (regp) 536 { 537 *pseg = reg_section; 538 op->X_add_symbol = op->X_op_symbol = 0; 539 op->X_add_number = regp->number; 540 op->X_op = O_register; 541 p += strlen (regp->name); 542 p = skip_space (p); 543 if (indir) 544 { 545 if (*p == ')') 546 ++p; 547 if ((regp->number & R_INDEX) && (regp->number & R_ARITH)) 548 { 549 op->X_op = O_md1; 550 551 if ((*p == '+') || (*p == '-')) 552 { 553 input_line_pointer = (char*) p; 554 expression (& offset); 555 p = skip_space (input_line_pointer); 556 if (*p != ')') 557 error (_("bad offset expression syntax")); 558 else 559 ++ p; 560 op->X_add_symbol = make_expr_symbol (& offset); 561 return p; 562 } 563 564 /* We treat (i[xy]) as (i[xy]+0), which is how it will 565 end up anyway, unless we're processing jp (i[xy]). */ 566 op->X_add_symbol = zero; 567 } 568 } 569 p = skip_space (p); 570 571 if ((*p == 0) || (*p == ',')) 572 return p; 573 } 574 } 575 /* Not an argument involving a register; use the generic parser. */ 576 input_line_pointer = (char*) s ; 577 *pseg = expression (op); 578 if (op->X_op == O_absent) 579 error (_("missing operand")); 580 if (op->X_op == O_illegal) 581 error (_("bad expression syntax")); 582 return input_line_pointer; 583 } 584 585 static const char * 586 parse_exp (const char *s, expressionS *op) 587 { 588 segT dummy; 589 return parse_exp2 (s, op, & dummy); 590 } 591 592 /* Condition codes, including some synonyms provided by HiTech zas. */ 593 static const struct reg_entry cc_tab[] = 594 { 595 { "age", 6 << 3 }, 596 { "alt", 7 << 3 }, 597 { "c", 3 << 3 }, 598 { "di", 4 << 3 }, 599 { "ei", 5 << 3 }, 600 { "lge", 2 << 3 }, 601 { "llt", 3 << 3 }, 602 { "m", 7 << 3 }, 603 { "nc", 2 << 3 }, 604 { "nz", 0 << 3 }, 605 { "p", 6 << 3 }, 606 { "pe", 5 << 3 }, 607 { "po", 4 << 3 }, 608 { "z", 1 << 3 }, 609 } ; 610 611 /* Parse condition code. */ 612 static const char * 613 parse_cc (const char *s, char * op) 614 { 615 const char *p; 616 int i; 617 struct reg_entry * cc_p; 618 619 for (i = 0; i < BUFLEN; ++i) 620 { 621 if (!ISALPHA (s[i])) /* Condition codes consist of letters only. */ 622 break; 623 buf[i] = TOLOWER (s[i]); 624 } 625 626 if ((i < BUFLEN) 627 && ((s[i] == 0) || (s[i] == ','))) 628 { 629 buf[i] = 0; 630 cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab), 631 sizeof (cc_tab[0]), key_cmp); 632 } 633 else 634 cc_p = NULL; 635 636 if (cc_p) 637 { 638 *op = cc_p->number; 639 p = s + i; 640 } 641 else 642 p = NULL; 643 644 return p; 645 } 646 647 static const char * 648 emit_insn (char prefix, char opcode, const char * args) 649 { 650 char *p; 651 652 if (prefix) 653 { 654 p = frag_more (2); 655 *p++ = prefix; 656 } 657 else 658 p = frag_more (1); 659 *p = opcode; 660 return args; 661 } 662 663 void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp) 664 { 665 bfd_reloc_code_real_type r[4] = 666 { 667 BFD_RELOC_8, 668 BFD_RELOC_16, 669 BFD_RELOC_24, 670 BFD_RELOC_32 671 }; 672 673 if (nbytes < 1 || nbytes > 4) 674 { 675 as_bad (_("unsupported BFD relocation size %u"), nbytes); 676 } 677 else 678 { 679 fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]); 680 } 681 } 682 683 static void 684 emit_byte (expressionS * val, bfd_reloc_code_real_type r_type) 685 { 686 char *p; 687 int lo, hi; 688 fixS * fixp; 689 690 p = frag_more (1); 691 *p = val->X_add_number; 692 if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant)) 693 { 694 as_bad(_("cannot make a relative jump to an absolute location")); 695 } 696 else if (val->X_op == O_constant) 697 { 698 lo = -128; 699 hi = (BFD_RELOC_8 == r_type) ? 255 : 127; 700 701 if ((val->X_add_number < lo) || (val->X_add_number > hi)) 702 { 703 if (r_type == BFD_RELOC_Z80_DISP8) 704 as_bad (_("offset too large")); 705 else 706 as_warn (_("overflow")); 707 } 708 } 709 else 710 { 711 fixp = fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val, 712 (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type); 713 /* FIXME : Process constant offsets immediately. */ 714 } 715 } 716 717 static void 718 emit_word (expressionS * val) 719 { 720 char *p; 721 722 p = frag_more (2); 723 if ( (val->X_op == O_register) 724 || (val->X_op == O_md1)) 725 ill_op (); 726 else 727 { 728 *p = val->X_add_number; 729 p[1] = (val->X_add_number>>8); 730 if (val->X_op != O_constant) 731 fix_new_exp (frag_now, p - frag_now->fr_literal, 2, 732 val, FALSE, BFD_RELOC_16); 733 } 734 } 735 736 static void 737 emit_mx (char prefix, char opcode, int shift, expressionS * arg) 738 /* The operand m may be r, (hl), (ix+d), (iy+d), 739 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */ 740 { 741 char *q; 742 int rnum; 743 744 rnum = arg->X_add_number; 745 switch (arg->X_op) 746 { 747 case O_register: 748 if (arg->X_md) 749 { 750 if (rnum != REG_HL) 751 { 752 ill_op (); 753 break; 754 } 755 else 756 rnum = 6; 757 } 758 else 759 { 760 if ((prefix == 0) && (rnum & R_INDEX)) 761 { 762 prefix = (rnum & R_IX) ? 0xDD : 0xFD; 763 check_mach (INS_UNDOC); 764 rnum &= ~R_INDEX; 765 } 766 if (rnum > 7) 767 { 768 ill_op (); 769 break; 770 } 771 } 772 q = frag_more (prefix ? 2 : 1); 773 if (prefix) 774 * q ++ = prefix; 775 * q ++ = opcode + (rnum << shift); 776 break; 777 case O_md1: 778 q = frag_more (2); 779 *q++ = (rnum & R_IX) ? 0xDD : 0xFD; 780 *q = (prefix) ? prefix : (opcode + (6 << shift)); 781 emit_byte (symbol_get_value_expression (arg->X_add_symbol), 782 BFD_RELOC_Z80_DISP8); 783 if (prefix) 784 { 785 q = frag_more (1); 786 *q = opcode+(6<<shift); 787 } 788 break; 789 default: 790 abort (); 791 } 792 } 793 794 /* The operand m may be r, (hl), (ix+d), (iy+d), 795 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */ 796 static const char * 797 emit_m (char prefix, char opcode, const char *args) 798 { 799 expressionS arg_m; 800 const char *p; 801 802 p = parse_exp (args, &arg_m); 803 switch (arg_m.X_op) 804 { 805 case O_md1: 806 case O_register: 807 emit_mx (prefix, opcode, 0, &arg_m); 808 break; 809 default: 810 ill_op (); 811 } 812 return p; 813 } 814 815 /* The operand m may be as above or one of the undocumented 816 combinations (ix+d),r and (iy+d),r (if unportable instructions 817 are allowed). */ 818 static const char * 819 emit_mr (char prefix, char opcode, const char *args) 820 { 821 expressionS arg_m, arg_r; 822 const char *p; 823 824 p = parse_exp (args, & arg_m); 825 826 switch (arg_m.X_op) 827 { 828 case O_md1: 829 if (*p == ',') 830 { 831 p = parse_exp (p + 1, & arg_r); 832 833 if ((arg_r.X_md == 0) 834 && (arg_r.X_op == O_register) 835 && (arg_r.X_add_number < 8)) 836 opcode += arg_r.X_add_number-6; /* Emit_mx () will add 6. */ 837 else 838 { 839 ill_op (); 840 break; 841 } 842 check_mach (INS_UNPORT); 843 } 844 case O_register: 845 emit_mx (prefix, opcode, 0, & arg_m); 846 break; 847 default: 848 ill_op (); 849 } 850 return p; 851 } 852 853 static void 854 emit_sx (char prefix, char opcode, expressionS * arg_p) 855 { 856 char *q; 857 858 switch (arg_p->X_op) 859 { 860 case O_register: 861 case O_md1: 862 emit_mx (prefix, opcode, 0, arg_p); 863 break; 864 default: 865 if (arg_p->X_md) 866 ill_op (); 867 else 868 { 869 q = frag_more (prefix ? 2 : 1); 870 if (prefix) 871 *q++ = prefix; 872 *q = opcode ^ 0x46; 873 emit_byte (arg_p, BFD_RELOC_8); 874 } 875 } 876 } 877 878 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */ 879 static const char * 880 emit_s (char prefix, char opcode, const char *args) 881 { 882 expressionS arg_s; 883 const char *p; 884 885 p = parse_exp (args, & arg_s); 886 emit_sx (prefix, opcode, & arg_s); 887 return p; 888 } 889 890 static const char * 891 emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 892 { 893 expressionS addr; 894 const char *p; char *q; 895 896 p = parse_exp (args, &addr); 897 if (addr.X_md) 898 ill_op (); 899 else 900 { 901 q = frag_more (1); 902 *q = opcode; 903 emit_word (& addr); 904 } 905 return p; 906 } 907 908 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */ 909 static const char * 910 emit_incdec (char prefix, char opcode, const char * args) 911 { 912 expressionS operand; 913 int rnum; 914 const char *p; char *q; 915 916 p = parse_exp (args, &operand); 917 rnum = operand.X_add_number; 918 if ((! operand.X_md) 919 && (operand.X_op == O_register) 920 && (R_ARITH&rnum)) 921 { 922 q = frag_more ((rnum & R_INDEX) ? 2 : 1); 923 if (rnum & R_INDEX) 924 *q++ = (rnum & R_IX) ? 0xDD : 0xFD; 925 *q = prefix + ((rnum & 3) << 4); 926 } 927 else 928 { 929 if ((operand.X_op == O_md1) || (operand.X_op == O_register)) 930 emit_mx (0, opcode, 3, & operand); 931 else 932 ill_op (); 933 } 934 return p; 935 } 936 937 static const char * 938 emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 939 { 940 expressionS addr; 941 const char *p; 942 char *q; 943 944 p = parse_exp (args, &addr); 945 if (addr.X_md) 946 ill_op (); 947 else 948 { 949 q = frag_more (1); 950 *q = opcode; 951 emit_byte (&addr, BFD_RELOC_8_PCREL); 952 } 953 return p; 954 } 955 956 static const char * 957 emit_jp (char prefix, char opcode, const char * args) 958 { 959 expressionS addr; 960 const char *p; 961 char *q; 962 int rnum; 963 964 p = parse_exp (args, & addr); 965 if (addr.X_md) 966 { 967 rnum = addr.X_add_number; 968 if ((addr.X_op == O_register && (rnum & ~R_INDEX) == REG_HL) 969 /* An operand (i[xy]) would have been rewritten to (i[xy]+0) 970 in parse_exp (). */ 971 || (addr.X_op == O_md1 && addr.X_add_symbol == zero)) 972 { 973 q = frag_more ((rnum & R_INDEX) ? 2 : 1); 974 if (rnum & R_INDEX) 975 *q++ = (rnum & R_IX) ? 0xDD : 0xFD; 976 *q = prefix; 977 } 978 else 979 ill_op (); 980 } 981 else 982 { 983 q = frag_more (1); 984 *q = opcode; 985 emit_word (& addr); 986 } 987 return p; 988 } 989 990 static const char * 991 emit_im (char prefix, char opcode, const char * args) 992 { 993 expressionS mode; 994 const char *p; 995 char *q; 996 997 p = parse_exp (args, & mode); 998 if (mode.X_md || (mode.X_op != O_constant)) 999 ill_op (); 1000 else 1001 switch (mode.X_add_number) 1002 { 1003 case 1: 1004 case 2: 1005 ++mode.X_add_number; 1006 /* Fall through. */ 1007 case 0: 1008 q = frag_more (2); 1009 *q++ = prefix; 1010 *q = opcode + 8*mode.X_add_number; 1011 break; 1012 default: 1013 ill_op (); 1014 } 1015 return p; 1016 } 1017 1018 static const char * 1019 emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 1020 { 1021 expressionS regp; 1022 const char *p; 1023 char *q; 1024 1025 p = parse_exp (args, & regp); 1026 if ((!regp.X_md) 1027 && (regp.X_op == O_register) 1028 && (regp.X_add_number & R_STACKABLE)) 1029 { 1030 int rnum; 1031 1032 rnum = regp.X_add_number; 1033 if (rnum&R_INDEX) 1034 { 1035 q = frag_more (2); 1036 *q++ = (rnum&R_IX)?0xDD:0xFD; 1037 } 1038 else 1039 q = frag_more (1); 1040 *q = opcode + ((rnum & 3) << 4); 1041 } 1042 else 1043 ill_op (); 1044 1045 return p; 1046 } 1047 1048 static const char * 1049 emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 1050 { 1051 char cc, *q; 1052 const char *p; 1053 1054 p = parse_cc (args, &cc); 1055 q = frag_more (1); 1056 if (p) 1057 *q = opcode + cc; 1058 else 1059 *q = prefix; 1060 return p ? p : args; 1061 } 1062 1063 static const char * 1064 emit_adc (char prefix, char opcode, const char * args) 1065 { 1066 expressionS term; 1067 int rnum; 1068 const char *p; 1069 char *q; 1070 1071 p = parse_exp (args, &term); 1072 if (*p++ != ',') 1073 { 1074 error (_("bad intruction syntax")); 1075 return p; 1076 } 1077 1078 if ((term.X_md) || (term.X_op != O_register)) 1079 ill_op (); 1080 else 1081 switch (term.X_add_number) 1082 { 1083 case REG_A: 1084 p = emit_s (0, prefix, p); 1085 break; 1086 case REG_HL: 1087 p = parse_exp (p, &term); 1088 if ((!term.X_md) && (term.X_op == O_register)) 1089 { 1090 rnum = term.X_add_number; 1091 if (R_ARITH == (rnum & (R_ARITH | R_INDEX))) 1092 { 1093 q = frag_more (2); 1094 *q++ = 0xED; 1095 *q = opcode + ((rnum & 3) << 4); 1096 break; 1097 } 1098 } 1099 /* Fall through. */ 1100 default: 1101 ill_op (); 1102 } 1103 return p; 1104 } 1105 1106 static const char * 1107 emit_add (char prefix, char opcode, const char * args) 1108 { 1109 expressionS term; 1110 int lhs, rhs; 1111 const char *p; 1112 char *q; 1113 1114 p = parse_exp (args, &term); 1115 if (*p++ != ',') 1116 { 1117 error (_("bad intruction syntax")); 1118 return p; 1119 } 1120 1121 if ((term.X_md) || (term.X_op != O_register)) 1122 ill_op (); 1123 else 1124 switch (term.X_add_number & ~R_INDEX) 1125 { 1126 case REG_A: 1127 p = emit_s (0, prefix, p); 1128 break; 1129 case REG_HL: 1130 lhs = term.X_add_number; 1131 p = parse_exp (p, &term); 1132 if ((!term.X_md) && (term.X_op == O_register)) 1133 { 1134 rhs = term.X_add_number; 1135 if ((rhs & R_ARITH) 1136 && ((rhs == lhs) || ((rhs & ~R_INDEX) != REG_HL))) 1137 { 1138 q = frag_more ((lhs & R_INDEX) ? 2 : 1); 1139 if (lhs & R_INDEX) 1140 *q++ = (lhs & R_IX) ? 0xDD : 0xFD; 1141 *q = opcode + ((rhs & 3) << 4); 1142 break; 1143 } 1144 } 1145 /* Fall through. */ 1146 default: 1147 ill_op (); 1148 } 1149 return p; 1150 } 1151 1152 static const char * 1153 emit_bit (char prefix, char opcode, const char * args) 1154 { 1155 expressionS b; 1156 int bn; 1157 const char *p; 1158 1159 p = parse_exp (args, &b); 1160 if (*p++ != ',') 1161 error (_("bad intruction syntax")); 1162 1163 bn = b.X_add_number; 1164 if ((!b.X_md) 1165 && (b.X_op == O_constant) 1166 && (0 <= bn) 1167 && (bn < 8)) 1168 { 1169 if (opcode == 0x40) 1170 /* Bit : no optional third operand. */ 1171 p = emit_m (prefix, opcode + (bn << 3), p); 1172 else 1173 /* Set, res : resulting byte can be copied to register. */ 1174 p = emit_mr (prefix, opcode + (bn << 3), p); 1175 } 1176 else 1177 ill_op (); 1178 return p; 1179 } 1180 1181 static const char * 1182 emit_jpcc (char prefix, char opcode, const char * args) 1183 { 1184 char cc; 1185 const char *p; 1186 1187 p = parse_cc (args, & cc); 1188 if (p && *p++ == ',') 1189 p = emit_call (0, opcode + cc, p); 1190 else 1191 p = (prefix == (char)0xC3) 1192 ? emit_jp (0xE9, prefix, args) 1193 : emit_call (0, prefix, args); 1194 return p; 1195 } 1196 1197 static const char * 1198 emit_jrcc (char prefix, char opcode, const char * args) 1199 { 1200 char cc; 1201 const char *p; 1202 1203 p = parse_cc (args, &cc); 1204 if (p && *p++ == ',') 1205 { 1206 if (cc > (3 << 3)) 1207 error (_("condition code invalid for jr")); 1208 else 1209 p = emit_jr (0, opcode + cc, p); 1210 } 1211 else 1212 p = emit_jr (0, prefix, args); 1213 1214 return p; 1215 } 1216 1217 static const char * 1218 emit_ex (char prefix_in ATTRIBUTE_UNUSED, 1219 char opcode_in ATTRIBUTE_UNUSED, const char * args) 1220 { 1221 expressionS op; 1222 const char * p; 1223 char prefix, opcode; 1224 1225 p = parse_exp (args, &op); 1226 p = skip_space (p); 1227 if (*p++ != ',') 1228 { 1229 error (_("bad instruction syntax")); 1230 return p; 1231 } 1232 1233 prefix = opcode = 0; 1234 if (op.X_op == O_register) 1235 switch (op.X_add_number | (op.X_md ? 0x8000 : 0)) 1236 { 1237 case REG_AF: 1238 if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f') 1239 { 1240 /* The scrubber changes '\'' to '`' in this context. */ 1241 if (*p == '`') 1242 ++p; 1243 opcode = 0x08; 1244 } 1245 break; 1246 case REG_DE: 1247 if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l') 1248 opcode = 0xEB; 1249 break; 1250 case REG_SP|0x8000: 1251 p = parse_exp (p, & op); 1252 if (op.X_op == O_register 1253 && op.X_md == 0 1254 && (op.X_add_number & ~R_INDEX) == REG_HL) 1255 { 1256 opcode = 0xE3; 1257 if (R_INDEX & op.X_add_number) 1258 prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD; 1259 } 1260 break; 1261 } 1262 if (opcode) 1263 emit_insn (prefix, opcode, p); 1264 else 1265 ill_op (); 1266 1267 return p; 1268 } 1269 1270 static const char * 1271 emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED, 1272 const char * args) 1273 { 1274 expressionS reg, port; 1275 const char *p; 1276 char *q; 1277 1278 p = parse_exp (args, ®); 1279 if (*p++ != ',') 1280 { 1281 error (_("bad intruction syntax")); 1282 return p; 1283 } 1284 1285 p = parse_exp (p, &port); 1286 if (reg.X_md == 0 1287 && reg.X_op == O_register 1288 && (reg.X_add_number <= 7 || reg.X_add_number == REG_F) 1289 && (port.X_md)) 1290 { 1291 if (port.X_op != O_md1 && port.X_op != O_register) 1292 { 1293 if (REG_A == reg.X_add_number) 1294 { 1295 q = frag_more (1); 1296 *q = 0xDB; 1297 emit_byte (&port, BFD_RELOC_8); 1298 } 1299 else 1300 ill_op (); 1301 } 1302 else 1303 { 1304 if (port.X_add_number == REG_C) 1305 { 1306 if (reg.X_add_number == REG_F) 1307 check_mach (INS_UNDOC); 1308 else 1309 { 1310 q = frag_more (2); 1311 *q++ = 0xED; 1312 *q = 0x40|((reg.X_add_number&7)<<3); 1313 } 1314 } 1315 else 1316 ill_op (); 1317 } 1318 } 1319 else 1320 ill_op (); 1321 return p; 1322 } 1323 1324 static const char * 1325 emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED, 1326 const char * args) 1327 { 1328 expressionS reg, port; 1329 const char *p; 1330 char *q; 1331 1332 p = parse_exp (args, & port); 1333 if (*p++ != ',') 1334 { 1335 error (_("bad intruction syntax")); 1336 return p; 1337 } 1338 p = parse_exp (p, ®); 1339 if (!port.X_md) 1340 { ill_op (); return p; } 1341 /* Allow "out (c), 0" as unportable instruction. */ 1342 if (reg.X_op == O_constant && reg.X_add_number == 0) 1343 { 1344 check_mach (INS_UNPORT); 1345 reg.X_op = O_register; 1346 reg.X_add_number = 6; 1347 } 1348 if (reg.X_md 1349 || reg.X_op != O_register 1350 || reg.X_add_number > 7) 1351 ill_op (); 1352 else 1353 if (port.X_op != O_register && port.X_op != O_md1) 1354 { 1355 if (REG_A == reg.X_add_number) 1356 { 1357 q = frag_more (1); 1358 *q = 0xD3; 1359 emit_byte (&port, BFD_RELOC_8); 1360 } 1361 else 1362 ill_op (); 1363 } 1364 else 1365 { 1366 if (REG_C == port.X_add_number) 1367 { 1368 q = frag_more (2); 1369 *q++ = 0xED; 1370 *q = 0x41 | (reg.X_add_number << 3); 1371 } 1372 else 1373 ill_op (); 1374 } 1375 return p; 1376 } 1377 1378 static const char * 1379 emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 1380 { 1381 expressionS addr; 1382 const char *p; 1383 char *q; 1384 1385 p = parse_exp (args, &addr); 1386 if (addr.X_op != O_constant) 1387 { 1388 error ("rst needs constant address"); 1389 return p; 1390 } 1391 1392 if (addr.X_add_number & ~(7 << 3)) 1393 ill_op (); 1394 else 1395 { 1396 q = frag_more (1); 1397 *q = opcode + (addr.X_add_number & (7 << 3)); 1398 } 1399 return p; 1400 } 1401 1402 static void 1403 emit_ldxhl (char prefix, char opcode, expressionS *src, expressionS *d) 1404 { 1405 char *q; 1406 1407 if (src->X_md) 1408 ill_op (); 1409 else 1410 { 1411 if (src->X_op == O_register) 1412 { 1413 if (src->X_add_number>7) 1414 ill_op (); 1415 if (prefix) 1416 { 1417 q = frag_more (2); 1418 *q++ = prefix; 1419 } 1420 else 1421 q = frag_more (1); 1422 *q = opcode + src->X_add_number; 1423 if (d) 1424 emit_byte (d, BFD_RELOC_Z80_DISP8); 1425 } 1426 else 1427 { 1428 if (prefix) 1429 { 1430 q = frag_more (2); 1431 *q++ = prefix; 1432 } 1433 else 1434 q = frag_more (1); 1435 *q = opcode^0x46; 1436 if (d) 1437 emit_byte (d, BFD_RELOC_Z80_DISP8); 1438 emit_byte (src, BFD_RELOC_8); 1439 } 1440 } 1441 } 1442 1443 static void 1444 emit_ldreg (int dest, expressionS * src) 1445 { 1446 char *q; 1447 int rnum; 1448 1449 switch (dest) 1450 { 1451 /* 8 Bit ld group: */ 1452 case REG_I: 1453 case REG_R: 1454 if (src->X_md == 0 && src->X_op == O_register && src->X_add_number == REG_A) 1455 { 1456 q = frag_more (2); 1457 *q++ = 0xED; 1458 *q = (dest == REG_I) ? 0x47 : 0x4F; 1459 } 1460 else 1461 ill_op (); 1462 break; 1463 1464 case REG_A: 1465 if ((src->X_md) && src->X_op != O_register && src->X_op != O_md1) 1466 { 1467 q = frag_more (1); 1468 *q = 0x3A; 1469 emit_word (src); 1470 break; 1471 } 1472 1473 if ((src->X_md) 1474 && src->X_op == O_register 1475 && (src->X_add_number == REG_BC || src->X_add_number == REG_DE)) 1476 { 1477 q = frag_more (1); 1478 *q = 0x0A + ((dest & 1) << 4); 1479 break; 1480 } 1481 1482 if ((!src->X_md) 1483 && src->X_op == O_register 1484 && (src->X_add_number == REG_R || src->X_add_number == REG_I)) 1485 { 1486 q = frag_more (2); 1487 *q++ = 0xED; 1488 *q = (src->X_add_number == REG_I) ? 0x57 : 0x5F; 1489 break; 1490 } 1491 /* Fall through. */ 1492 case REG_B: 1493 case REG_C: 1494 case REG_D: 1495 case REG_E: 1496 emit_sx (0, 0x40 + (dest << 3), src); 1497 break; 1498 1499 case REG_H: 1500 case REG_L: 1501 if ((src->X_md == 0) 1502 && (src->X_op == O_register) 1503 && (src->X_add_number & R_INDEX)) 1504 ill_op (); 1505 else 1506 emit_sx (0, 0x40 + (dest << 3), src); 1507 break; 1508 1509 case R_IX | REG_H: 1510 case R_IX | REG_L: 1511 case R_IY | REG_H: 1512 case R_IY | REG_L: 1513 if (src->X_md) 1514 { 1515 ill_op (); 1516 break; 1517 } 1518 check_mach (INS_UNDOC); 1519 if (src-> X_op == O_register) 1520 { 1521 rnum = src->X_add_number; 1522 if ((rnum & ~R_INDEX) < 8 1523 && ((rnum & R_INDEX) == (dest & R_INDEX) 1524 || ( (rnum & ~R_INDEX) != REG_H 1525 && (rnum & ~R_INDEX) != REG_L))) 1526 { 1527 q = frag_more (2); 1528 *q++ = (dest & R_IX) ? 0xDD : 0xFD; 1529 *q = 0x40 + ((dest & 0x07) << 3) + (rnum & 7); 1530 } 1531 else 1532 ill_op (); 1533 } 1534 else 1535 { 1536 q = frag_more (2); 1537 *q++ = (dest & R_IX) ? 0xDD : 0xFD; 1538 *q = 0x06 + ((dest & 0x07) << 3); 1539 emit_byte (src, BFD_RELOC_8); 1540 } 1541 break; 1542 1543 /* 16 Bit ld group: */ 1544 case REG_SP: 1545 if (src->X_md == 0 1546 && src->X_op == O_register 1547 && REG_HL == (src->X_add_number &~ R_INDEX)) 1548 { 1549 q = frag_more ((src->X_add_number & R_INDEX) ? 2 : 1); 1550 if (src->X_add_number & R_INDEX) 1551 *q++ = (src->X_add_number & R_IX) ? 0xDD : 0xFD; 1552 *q = 0xF9; 1553 break; 1554 } 1555 /* Fall through. */ 1556 case REG_BC: 1557 case REG_DE: 1558 if (src->X_op == O_register || src->X_op == O_md1) 1559 ill_op (); 1560 q = frag_more (src->X_md ? 2 : 1); 1561 if (src->X_md) 1562 { 1563 *q++ = 0xED; 1564 *q = 0x4B + ((dest & 3) << 4); 1565 } 1566 else 1567 *q = 0x01 + ((dest & 3) << 4); 1568 emit_word (src); 1569 break; 1570 1571 case REG_HL: 1572 case REG_HL | R_IX: 1573 case REG_HL | R_IY: 1574 if (src->X_op == O_register || src->X_op == O_md1) 1575 ill_op (); 1576 q = frag_more ((dest & R_INDEX) ? 2 : 1); 1577 if (dest & R_INDEX) 1578 * q ++ = (dest & R_IX) ? 0xDD : 0xFD; 1579 *q = (src->X_md) ? 0x2A : 0x21; 1580 emit_word (src); 1581 break; 1582 1583 case REG_AF: 1584 case REG_F: 1585 ill_op (); 1586 break; 1587 1588 default: 1589 abort (); 1590 } 1591 } 1592 1593 static const char * 1594 emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED, 1595 const char * args) 1596 { 1597 expressionS dst, src; 1598 const char *p; 1599 char *q; 1600 char prefix, opcode; 1601 1602 p = parse_exp (args, &dst); 1603 if (*p++ != ',') 1604 error (_("bad intruction syntax")); 1605 p = parse_exp (p, &src); 1606 1607 switch (dst.X_op) 1608 { 1609 case O_md1: 1610 emit_ldxhl ((dst.X_add_number & R_IX) ? 0xDD : 0xFD, 0x70, 1611 &src, symbol_get_value_expression (dst.X_add_symbol)); 1612 break; 1613 1614 case O_register: 1615 if (dst.X_md) 1616 { 1617 switch (dst.X_add_number) 1618 { 1619 case REG_BC: 1620 case REG_DE: 1621 if (src.X_md == 0 && src.X_op == O_register && src.X_add_number == REG_A) 1622 { 1623 q = frag_more (1); 1624 *q = 0x02 + ( (dst.X_add_number & 1) << 4); 1625 } 1626 else 1627 ill_op (); 1628 break; 1629 case REG_HL: 1630 emit_ldxhl (0, 0x70, &src, NULL); 1631 break; 1632 default: 1633 ill_op (); 1634 } 1635 } 1636 else 1637 emit_ldreg (dst.X_add_number, &src); 1638 break; 1639 1640 default: 1641 if (src.X_md != 0 || src.X_op != O_register) 1642 ill_op (); 1643 prefix = opcode = 0; 1644 switch (src.X_add_number) 1645 { 1646 case REG_A: 1647 opcode = 0x32; break; 1648 case REG_BC: case REG_DE: case REG_SP: 1649 prefix = 0xED; opcode = 0x43 + ((src.X_add_number&3)<<4); break; 1650 case REG_HL: 1651 opcode = 0x22; break; 1652 case REG_HL|R_IX: 1653 prefix = 0xDD; opcode = 0x22; break; 1654 case REG_HL|R_IY: 1655 prefix = 0xFD; opcode = 0x22; break; 1656 } 1657 if (opcode) 1658 { 1659 q = frag_more (prefix?2:1); 1660 if (prefix) 1661 *q++ = prefix; 1662 *q = opcode; 1663 emit_word (&dst); 1664 } 1665 else 1666 ill_op (); 1667 } 1668 return p; 1669 } 1670 1671 static void 1672 emit_data (int size ATTRIBUTE_UNUSED) 1673 { 1674 const char *p, *q; 1675 char *u, quote; 1676 int cnt; 1677 expressionS exp; 1678 1679 if (is_it_end_of_statement ()) 1680 { 1681 demand_empty_rest_of_line (); 1682 return; 1683 } 1684 p = skip_space (input_line_pointer); 1685 1686 do 1687 { 1688 if (*p == '\"' || *p == '\'') 1689 { 1690 for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt) 1691 ; 1692 u = frag_more (cnt); 1693 memcpy (u, q, cnt); 1694 if (!*p) 1695 as_warn (_("unterminated string")); 1696 else 1697 p = skip_space (p+1); 1698 } 1699 else 1700 { 1701 p = parse_exp (p, &exp); 1702 if (exp.X_op == O_md1 || exp.X_op == O_register) 1703 { 1704 ill_op (); 1705 break; 1706 } 1707 if (exp.X_md) 1708 as_warn (_("parentheses ignored")); 1709 emit_byte (&exp, BFD_RELOC_8); 1710 p = skip_space (p); 1711 } 1712 } 1713 while (*p++ == ',') ; 1714 input_line_pointer = (char *)(p-1); 1715 } 1716 1717 static const char * 1718 emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 1719 { 1720 const char *p; 1721 1722 p = skip_space (args); 1723 if (TOLOWER (*p++) != 'a' || *p++ != ',') 1724 ill_op (); 1725 else 1726 { 1727 char *q, reg; 1728 1729 reg = TOLOWER (*p++); 1730 switch (reg) 1731 { 1732 case 'b': 1733 case 'c': 1734 case 'd': 1735 case 'e': 1736 check_mach (INS_R800); 1737 if (!*skip_space (p)) 1738 { 1739 q = frag_more (2); 1740 *q++ = prefix; 1741 *q = opcode + ((reg - 'b') << 3); 1742 break; 1743 } 1744 default: 1745 ill_op (); 1746 } 1747 } 1748 return p; 1749 } 1750 1751 static const char * 1752 emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 1753 { 1754 const char *p; 1755 1756 p = skip_space (args); 1757 if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',') 1758 ill_op (); 1759 else 1760 { 1761 expressionS reg; 1762 char *q; 1763 1764 p = parse_exp (p, & reg); 1765 1766 if ((!reg.X_md) && reg.X_op == O_register) 1767 switch (reg.X_add_number) 1768 { 1769 case REG_BC: 1770 case REG_SP: 1771 check_mach (INS_R800); 1772 q = frag_more (2); 1773 *q++ = prefix; 1774 *q = opcode + ((reg.X_add_number & 3) << 4); 1775 break; 1776 default: 1777 ill_op (); 1778 } 1779 } 1780 return p; 1781 } 1782 1783 /* Port specific pseudo ops. */ 1784 const pseudo_typeS md_pseudo_table[] = 1785 { 1786 { "db" , emit_data, 1}, 1787 { "d24", cons, 3}, 1788 { "d32", cons, 4}, 1789 { "def24", cons, 3}, 1790 { "def32", cons, 4}, 1791 { "defb", emit_data, 1}, 1792 { "defs", s_space, 1}, /* Synonym for ds on some assemblers. */ 1793 { "defw", cons, 2}, 1794 { "ds", s_space, 1}, /* Fill with bytes rather than words. */ 1795 { "dw", cons, 2}, 1796 { "psect", obj_coff_section, 0}, /* TODO: Translate attributes. */ 1797 { "set", 0, 0}, /* Real instruction on z80. */ 1798 { NULL, 0, 0 } 1799 } ; 1800 1801 static table_t instab[] = 1802 { 1803 { "adc", 0x88, 0x4A, emit_adc }, 1804 { "add", 0x80, 0x09, emit_add }, 1805 { "and", 0x00, 0xA0, emit_s }, 1806 { "bit", 0xCB, 0x40, emit_bit }, 1807 { "call", 0xCD, 0xC4, emit_jpcc }, 1808 { "ccf", 0x00, 0x3F, emit_insn }, 1809 { "cp", 0x00, 0xB8, emit_s }, 1810 { "cpd", 0xED, 0xA9, emit_insn }, 1811 { "cpdr", 0xED, 0xB9, emit_insn }, 1812 { "cpi", 0xED, 0xA1, emit_insn }, 1813 { "cpir", 0xED, 0xB1, emit_insn }, 1814 { "cpl", 0x00, 0x2F, emit_insn }, 1815 { "daa", 0x00, 0x27, emit_insn }, 1816 { "dec", 0x0B, 0x05, emit_incdec }, 1817 { "di", 0x00, 0xF3, emit_insn }, 1818 { "djnz", 0x00, 0x10, emit_jr }, 1819 { "ei", 0x00, 0xFB, emit_insn }, 1820 { "ex", 0x00, 0x00, emit_ex}, 1821 { "exx", 0x00, 0xD9, emit_insn }, 1822 { "halt", 0x00, 0x76, emit_insn }, 1823 { "im", 0xED, 0x46, emit_im }, 1824 { "in", 0x00, 0x00, emit_in }, 1825 { "inc", 0x03, 0x04, emit_incdec }, 1826 { "ind", 0xED, 0xAA, emit_insn }, 1827 { "indr", 0xED, 0xBA, emit_insn }, 1828 { "ini", 0xED, 0xA2, emit_insn }, 1829 { "inir", 0xED, 0xB2, emit_insn }, 1830 { "jp", 0xC3, 0xC2, emit_jpcc }, 1831 { "jr", 0x18, 0x20, emit_jrcc }, 1832 { "ld", 0x00, 0x00, emit_ld }, 1833 { "ldd", 0xED, 0xA8, emit_insn }, 1834 { "lddr", 0xED, 0xB8, emit_insn }, 1835 { "ldi", 0xED, 0xA0, emit_insn }, 1836 { "ldir", 0xED, 0xB0, emit_insn }, 1837 { "mulub", 0xED, 0xC5, emit_mulub }, /* R800 only. */ 1838 { "muluw", 0xED, 0xC3, emit_muluw }, /* R800 only. */ 1839 { "neg", 0xed, 0x44, emit_insn }, 1840 { "nop", 0x00, 0x00, emit_insn }, 1841 { "or", 0x00, 0xB0, emit_s }, 1842 { "otdr", 0xED, 0xBB, emit_insn }, 1843 { "otir", 0xED, 0xB3, emit_insn }, 1844 { "out", 0x00, 0x00, emit_out }, 1845 { "outd", 0xED, 0xAB, emit_insn }, 1846 { "outi", 0xED, 0xA3, emit_insn }, 1847 { "pop", 0x00, 0xC1, emit_pop }, 1848 { "push", 0x00, 0xC5, emit_pop }, 1849 { "res", 0xCB, 0x80, emit_bit }, 1850 { "ret", 0xC9, 0xC0, emit_retcc }, 1851 { "reti", 0xED, 0x4D, emit_insn }, 1852 { "retn", 0xED, 0x45, emit_insn }, 1853 { "rl", 0xCB, 0x10, emit_mr }, 1854 { "rla", 0x00, 0x17, emit_insn }, 1855 { "rlc", 0xCB, 0x00, emit_mr }, 1856 { "rlca", 0x00, 0x07, emit_insn }, 1857 { "rld", 0xED, 0x6F, emit_insn }, 1858 { "rr", 0xCB, 0x18, emit_mr }, 1859 { "rra", 0x00, 0x1F, emit_insn }, 1860 { "rrc", 0xCB, 0x08, emit_mr }, 1861 { "rrca", 0x00, 0x0F, emit_insn }, 1862 { "rrd", 0xED, 0x67, emit_insn }, 1863 { "rst", 0x00, 0xC7, emit_rst}, 1864 { "sbc", 0x98, 0x42, emit_adc }, 1865 { "scf", 0x00, 0x37, emit_insn }, 1866 { "set", 0xCB, 0xC0, emit_bit }, 1867 { "sla", 0xCB, 0x20, emit_mr }, 1868 { "sli", 0xCB, 0x30, emit_mr }, 1869 { "sll", 0xCB, 0x30, emit_mr }, 1870 { "sra", 0xCB, 0x28, emit_mr }, 1871 { "srl", 0xCB, 0x38, emit_mr }, 1872 { "sub", 0x00, 0x90, emit_s }, 1873 { "xor", 0x00, 0xA8, emit_s }, 1874 } ; 1875 1876 void 1877 md_assemble (char* str) 1878 { 1879 const char *p; 1880 char * old_ptr; 1881 int i; 1882 table_t *insp; 1883 1884 err_flag = 0; 1885 old_ptr = input_line_pointer; 1886 p = skip_space (str); 1887 for (i = 0; (i < BUFLEN) && (ISALPHA (*p));) 1888 buf[i++] = TOLOWER (*p++); 1889 1890 if (i == BUFLEN) 1891 { 1892 buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated. */ 1893 buf[BUFLEN-1] = 0; 1894 as_bad (_("Unknown instruction '%s'"), buf); 1895 } 1896 else if ((*p) && (!ISSPACE (*p))) 1897 as_bad (_("syntax error")); 1898 else 1899 { 1900 buf[i] = 0; 1901 p = skip_space (p); 1902 key = buf; 1903 1904 insp = bsearch (&key, instab, ARRAY_SIZE (instab), 1905 sizeof (instab[0]), key_cmp); 1906 if (!insp) 1907 as_bad (_("Unknown instruction '%s'"), buf); 1908 else 1909 { 1910 p = insp->fp (insp->prefix, insp->opcode, p); 1911 p = skip_space (p); 1912 if ((!err_flag) && *p) 1913 as_bad (_("junk at end of line, first unrecognized character is `%c'"), 1914 *p); 1915 } 1916 } 1917 input_line_pointer = old_ptr; 1918 } 1919 1920 void 1921 md_apply_fix (fixS * fixP, valueT* valP, segT seg ATTRIBUTE_UNUSED) 1922 { 1923 long val = * (long *) valP; 1924 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; 1925 1926 switch (fixP->fx_r_type) 1927 { 1928 case BFD_RELOC_8_PCREL: 1929 if (fixP->fx_addsy) 1930 { 1931 fixP->fx_no_overflow = 1; 1932 fixP->fx_done = 0; 1933 } 1934 else 1935 { 1936 fixP->fx_no_overflow = (-128 <= val && val < 128); 1937 if (!fixP->fx_no_overflow) 1938 as_bad_where (fixP->fx_file, fixP->fx_line, 1939 _("relative jump out of range")); 1940 *buf++ = val; 1941 fixP->fx_done = 1; 1942 } 1943 break; 1944 1945 case BFD_RELOC_Z80_DISP8: 1946 if (fixP->fx_addsy) 1947 { 1948 fixP->fx_no_overflow = 1; 1949 fixP->fx_done = 0; 1950 } 1951 else 1952 { 1953 fixP->fx_no_overflow = (-128 <= val && val < 128); 1954 if (!fixP->fx_no_overflow) 1955 as_bad_where (fixP->fx_file, fixP->fx_line, 1956 _("index offset out of range")); 1957 *buf++ = val; 1958 fixP->fx_done = 1; 1959 } 1960 break; 1961 1962 case BFD_RELOC_8: 1963 if (val > 255 || val < -128) 1964 as_warn_where (fixP->fx_file, fixP->fx_line, _("overflow")); 1965 *buf++ = val; 1966 fixP->fx_no_overflow = 1; 1967 if (fixP->fx_addsy == NULL) 1968 fixP->fx_done = 1; 1969 break; 1970 1971 case BFD_RELOC_16: 1972 *buf++ = val; 1973 *buf++ = (val >> 8); 1974 fixP->fx_no_overflow = 1; 1975 if (fixP->fx_addsy == NULL) 1976 fixP->fx_done = 1; 1977 break; 1978 1979 case BFD_RELOC_24: /* Def24 may produce this. */ 1980 *buf++ = val; 1981 *buf++ = (val >> 8); 1982 *buf++ = (val >> 16); 1983 fixP->fx_no_overflow = 1; 1984 if (fixP->fx_addsy == NULL) 1985 fixP->fx_done = 1; 1986 break; 1987 1988 case BFD_RELOC_32: /* Def32 and .long may produce this. */ 1989 *buf++ = val; 1990 *buf++ = (val >> 8); 1991 *buf++ = (val >> 16); 1992 *buf++ = (val >> 24); 1993 if (fixP->fx_addsy == NULL) 1994 fixP->fx_done = 1; 1995 break; 1996 1997 default: 1998 printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type); 1999 abort (); 2000 } 2001 } 2002 2003 /* GAS will call this to generate a reloc. GAS will pass the 2004 resulting reloc to `bfd_install_relocation'. This currently works 2005 poorly, as `bfd_install_relocation' often does the wrong thing, and 2006 instances of `tc_gen_reloc' have been written to work around the 2007 problems, which in turns makes it difficult to fix 2008 `bfd_install_relocation'. */ 2009 2010 /* If while processing a fixup, a reloc really 2011 needs to be created then it is done here. */ 2012 2013 arelent * 2014 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp) 2015 { 2016 arelent *reloc; 2017 2018 if (! bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type)) 2019 { 2020 as_bad_where (fixp->fx_file, fixp->fx_line, 2021 _("reloc %d not supported by object file format"), 2022 (int) fixp->fx_r_type); 2023 return NULL; 2024 } 2025 2026 reloc = xmalloc (sizeof (arelent)); 2027 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); 2028 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 2029 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 2030 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 2031 reloc->addend = fixp->fx_offset; 2032 2033 return reloc; 2034 } 2035 2036