1/* tc-z80.c -- Assemble code for the Zilog Z80, Z180, EZ80 and ASCII R800 2 Copyright (C) 2005-2020 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 3, or (at your option) 10 any later version. 11 12 GAS is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GAS; see the file COPYING. If not, write to the Free 19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22#include "as.h" 23#include "safe-ctype.h" 24#include "subsegs.h" 25#include "elf/z80.h" 26#include "dwarf2dbg.h" 27#include "dw2gencfi.h" 28 29/* Exported constants. */ 30const char comment_chars[] = ";\0"; 31const char line_comment_chars[] = "#;\0"; 32const char line_separator_chars[] = "\0"; 33const char EXP_CHARS[] = "eE\0"; 34const char FLT_CHARS[] = "RrDdFfSsHh\0"; 35 36/* For machine specific options. */ 37const char * md_shortopts = ""; /* None yet. */ 38 39enum options 40{ 41 OPTION_MARCH = OPTION_MD_BASE, 42 OPTION_MACH_Z80, 43 OPTION_MACH_R800, 44 OPTION_MACH_Z180, 45 OPTION_MACH_EZ80_Z80, 46 OPTION_MACH_EZ80_ADL, 47 OPTION_MACH_INST, 48 OPTION_MACH_NO_INST, 49 OPTION_MACH_IUD, 50 OPTION_MACH_WUD, 51 OPTION_MACH_FUD, 52 OPTION_MACH_IUP, 53 OPTION_MACH_WUP, 54 OPTION_MACH_FUP, 55 OPTION_FP_SINGLE_FORMAT, 56 OPTION_FP_DOUBLE_FORMAT, 57 OPTION_COMPAT_LL_PREFIX, 58 OPTION_COMPAT_COLONLESS, 59 OPTION_COMPAT_SDCC 60}; 61 62#define INS_Z80 (1 << 0) 63#define INS_R800 (1 << 1) 64#define INS_GBZ80 (1 << 2) 65#define INS_Z180 (1 << 3) 66#define INS_EZ80 (1 << 4) 67#define INS_Z80N (1 << 5) 68#define INS_MARCH_MASK 0xffff 69 70#define INS_IDX_HALF (1 << 16) 71#define INS_IN_F_C (1 << 17) 72#define INS_OUT_C_0 (1 << 18) 73#define INS_SLI (1 << 19) 74#define INS_ROT_II_LD (1 << 20) /* instructions like SLA (ii+d),r; which is: LD r,(ii+d); SLA r; LD (ii+d),r */ 75#define INS_TUNE_MASK 0xffff0000 76 77#define INS_NOT_GBZ80 (INS_Z80 | INS_Z180 | INS_R800 | INS_EZ80 | INS_Z80N) 78 79#define INS_ALL 0 80#define INS_UNDOC (INS_IDX_HALF | INS_IN_F_C) 81#define INS_UNPORT (INS_OUT_C_0 | INS_SLI | INS_ROT_II_LD) 82 83struct option md_longopts[] = 84{ 85 { "march", required_argument, NULL, OPTION_MARCH}, 86 { "z80", no_argument, NULL, OPTION_MACH_Z80}, 87 { "r800", no_argument, NULL, OPTION_MACH_R800}, 88 { "z180", no_argument, NULL, OPTION_MACH_Z180}, 89 { "ez80", no_argument, NULL, OPTION_MACH_EZ80_Z80}, 90 { "ez80-adl", no_argument, NULL, OPTION_MACH_EZ80_ADL}, 91 { "fp-s", required_argument, NULL, OPTION_FP_SINGLE_FORMAT}, 92 { "fp-d", required_argument, NULL, OPTION_FP_DOUBLE_FORMAT}, 93 { "strict", no_argument, NULL, OPTION_MACH_FUD}, 94 { "full", no_argument, NULL, OPTION_MACH_IUP}, 95 { "with-inst", required_argument, NULL, OPTION_MACH_INST}, 96 { "Wnins", required_argument, NULL, OPTION_MACH_INST}, 97 { "without-inst", required_argument, NULL, OPTION_MACH_NO_INST}, 98 { "local-prefix", required_argument, NULL, OPTION_COMPAT_LL_PREFIX}, 99 { "colonless", no_argument, NULL, OPTION_COMPAT_COLONLESS}, 100 { "sdcc", no_argument, NULL, OPTION_COMPAT_SDCC}, 101 { "Fins", required_argument, NULL, OPTION_MACH_NO_INST}, 102 { "ignore-undocumented-instructions", no_argument, NULL, OPTION_MACH_IUD }, 103 { "Wnud", no_argument, NULL, OPTION_MACH_IUD }, 104 { "warn-undocumented-instructions", no_argument, NULL, OPTION_MACH_WUD }, 105 { "Wud", no_argument, NULL, OPTION_MACH_WUD }, 106 { "forbid-undocumented-instructions", no_argument, NULL, OPTION_MACH_FUD }, 107 { "Fud", no_argument, NULL, OPTION_MACH_FUD }, 108 { "ignore-unportable-instructions", no_argument, NULL, OPTION_MACH_IUP }, 109 { "Wnup", no_argument, NULL, OPTION_MACH_IUP }, 110 { "warn-unportable-instructions", no_argument, NULL, OPTION_MACH_WUP }, 111 { "Wup", no_argument, NULL, OPTION_MACH_WUP }, 112 { "forbid-unportable-instructions", no_argument, NULL, OPTION_MACH_FUP }, 113 { "Fup", no_argument, NULL, OPTION_MACH_FUP }, 114 115 { NULL, no_argument, NULL, 0 } 116} ; 117 118size_t md_longopts_size = sizeof (md_longopts); 119 120extern int coff_flags; 121/* Instruction classes that silently assembled. */ 122static int ins_ok = INS_Z80 | INS_UNDOC; 123/* Instruction classes that generate errors. */ 124static int ins_err = ~(INS_Z80 | INS_UNDOC); 125/* eZ80 CPU mode (ADL or Z80) */ 126static int cpu_mode = 0; /* 0 - Z80, 1 - ADL */ 127/* accept SDCC specific instruction encoding */ 128static int sdcc_compat = 0; 129/* accept colonless labels */ 130static int colonless_labels = 0; 131/* local label prefix (NULL - default) */ 132static const char *local_label_prefix = NULL; 133/* floating point support */ 134typedef const char *(*str_to_float_t)(char *litP, int *sizeP); 135static str_to_float_t str_to_float; 136static str_to_float_t str_to_double; 137 138/* mode of current instruction */ 139#define INST_MODE_S 0 /* short data mode */ 140#define INST_MODE_IS 0 /* short instruction mode */ 141#define INST_MODE_L 2 /* long data mode */ 142#define INST_MODE_IL 1 /* long instruction mode */ 143#define INST_MODE_FORCED 4 /* CPU mode changed by instruction suffix*/ 144static char inst_mode; 145 146struct match_info 147{ 148 const char *name; 149 int ins_ok; 150 int ins_err; 151 int cpu_mode; 152 const char *comment; 153}; 154 155static const struct match_info 156match_cpu_table [] = 157{ 158 {"z80", INS_Z80, 0, 0, "Zilog Z80" }, 159 {"ez80", INS_EZ80, 0, 0, "Zilog eZ80" }, 160 {"gbz80", INS_GBZ80, INS_UNDOC|INS_UNPORT, 0, "GameBoy Z80" }, 161 {"r800", INS_R800, INS_UNPORT, 0, "Ascii R800" }, 162 {"z180", INS_Z180, INS_UNDOC|INS_UNPORT, 0, "Zilog Z180" }, 163 {"z80n", INS_Z80N, 0, 0, "Z80 Next" } 164}; 165 166static const struct match_info 167match_ext_table [] = 168{ 169 {"full", INS_UNDOC|INS_UNPORT, 0, 0, "assemble all known instructions" }, 170 {"adl", 0, 0, 1, "eZ80 ADL mode by default" }, 171 {"xyhl", INS_IDX_HALF, 0, 0, "instructions with halves of index registers" }, 172 {"infc", INS_IN_F_C, 0, 0, "instruction IN F,(C)" }, 173 {"outc0", INS_OUT_C_0, 0, 0, "instruction OUT (C),0" }, 174 {"sli", INS_SLI, 0, 0, "instruction known as SLI, SLL, or SL1" }, 175 {"xdcb", INS_ROT_II_LD, 0, 0, "instructions like RL (IX+d),R (DD/FD CB dd oo)" } 176}; 177 178static void 179setup_march (const char *name, int *ok, int *err, int *mode) 180{ 181 unsigned i; 182 size_t len = strcspn (name, "+-"); 183 for (i = 0; i < ARRAY_SIZE (match_cpu_table); ++i) 184 if (!strncasecmp (name, match_cpu_table[i].name, len) 185 && strlen (match_cpu_table[i].name) == len) 186 { 187 *ok = match_cpu_table[i].ins_ok; 188 *err = match_cpu_table[i].ins_err; 189 *mode = match_cpu_table[i].cpu_mode; 190 break; 191 } 192 193 if (i >= ARRAY_SIZE (match_cpu_table)) 194 as_fatal (_("Invalid CPU is specified: %s"), name); 195 196 while (name[len]) 197 { 198 name = &name[len + 1]; 199 len = strcspn (name, "+-"); 200 for (i = 0; i < ARRAY_SIZE (match_ext_table); ++i) 201 if (!strncasecmp (name, match_ext_table[i].name, len) 202 && strlen (match_ext_table[i].name) == len) 203 { 204 if (name[-1] == '+') 205 { 206 *ok |= match_ext_table[i].ins_ok; 207 *err &= ~match_ext_table[i].ins_ok; 208 *mode |= match_ext_table[i].cpu_mode; 209 } 210 else 211 { 212 *ok &= ~match_ext_table[i].ins_ok; 213 *err |= match_ext_table[i].ins_ok; 214 *mode &= ~match_ext_table[i].cpu_mode; 215 } 216 break; 217 } 218 if (i >= ARRAY_SIZE (match_ext_table)) 219 as_fatal (_("Invalid EXTENSION is specified: %s"), name); 220 } 221} 222 223static int 224setup_instruction (const char *inst, int *add, int *sub) 225{ 226 int n; 227 if (!strcmp (inst, "idx-reg-halves")) 228 n = INS_IDX_HALF; 229 else if (!strcmp (inst, "sli")) 230 n = INS_SLI; 231 else if (!strcmp (inst, "op-ii-ld")) 232 n = INS_ROT_II_LD; 233 else if (!strcmp (inst, "in-f-c")) 234 n = INS_IN_F_C; 235 else if (!strcmp (inst, "out-c-0")) 236 n = INS_OUT_C_0; 237 else 238 return 0; 239 *add |= n; 240 *sub &= ~n; 241 return 1; 242} 243 244static const char * 245str_to_zeda32 (char *litP, int *sizeP); 246static const char * 247str_to_float48 (char *litP, int *sizeP); 248static const char * 249str_to_ieee754_h (char *litP, int *sizeP); 250static const char * 251str_to_ieee754_s (char *litP, int *sizeP); 252static const char * 253str_to_ieee754_d (char *litP, int *sizeP); 254 255static str_to_float_t 256get_str_to_float (const char *arg) 257{ 258 if (strcasecmp (arg, "zeda32") == 0) 259 return str_to_zeda32; 260 261 if (strcasecmp (arg, "math48") == 0) 262 return str_to_float48; 263 264 if (strcasecmp (arg, "half") != 0) 265 return str_to_ieee754_h; 266 267 if (strcasecmp (arg, "single") != 0) 268 return str_to_ieee754_s; 269 270 if (strcasecmp (arg, "double") != 0) 271 return str_to_ieee754_d; 272 273 if (strcasecmp (arg, "ieee754") == 0) 274 as_fatal (_("invalid floating point numbers type `%s'"), arg); 275 return NULL; 276} 277 278static int 279setup_instruction_list (const char *list, int *add, int *sub) 280{ 281 char buf[16]; 282 const char *b; 283 const char *e; 284 int sz; 285 int res = 0; 286 for (b = list; *b != '\0';) 287 { 288 e = strchr (b, ','); 289 if (e == NULL) 290 sz = strlen (b); 291 else 292 sz = e - b; 293 if (sz == 0 || sz >= (int)sizeof (buf)) 294 { 295 as_bad (_("invalid INST in command line: %s"), b); 296 return 0; 297 } 298 memcpy (buf, b, sz); 299 buf[sz] = '\0'; 300 if (setup_instruction (buf, add, sub)) 301 res++; 302 else 303 { 304 as_bad (_("invalid INST in command line: %s"), buf); 305 return 0; 306 } 307 b = &b[sz]; 308 if (*b == ',') 309 ++b; 310 } 311 return res; 312} 313 314int 315md_parse_option (int c, const char* arg) 316{ 317 switch (c) 318 { 319 default: 320 return 0; 321 case OPTION_MARCH: 322 setup_march (arg, & ins_ok, & ins_err, & cpu_mode); 323 break; 324 case OPTION_MACH_Z80: 325 setup_march ("z80", & ins_ok, & ins_err, & cpu_mode); 326 break; 327 case OPTION_MACH_R800: 328 setup_march ("r800", & ins_ok, & ins_err, & cpu_mode); 329 break; 330 case OPTION_MACH_Z180: 331 setup_march ("z180", & ins_ok, & ins_err, & cpu_mode); 332 break; 333 case OPTION_MACH_EZ80_Z80: 334 setup_march ("ez80", & ins_ok, & ins_err, & cpu_mode); 335 break; 336 case OPTION_MACH_EZ80_ADL: 337 setup_march ("ez80+adl", & ins_ok, & ins_err, & cpu_mode); 338 break; 339 case OPTION_FP_SINGLE_FORMAT: 340 str_to_float = get_str_to_float (arg); 341 break; 342 case OPTION_FP_DOUBLE_FORMAT: 343 str_to_double = get_str_to_float (arg); 344 break; 345 case OPTION_MACH_INST: 346 if ((ins_ok & INS_GBZ80) == 0) 347 return setup_instruction_list (arg, & ins_ok, & ins_err); 348 break; 349 case OPTION_MACH_NO_INST: 350 if ((ins_ok & INS_GBZ80) == 0) 351 return setup_instruction_list (arg, & ins_err, & ins_ok); 352 break; 353 case OPTION_MACH_WUD: 354 case OPTION_MACH_IUD: 355 if ((ins_ok & INS_GBZ80) == 0) 356 { 357 ins_ok |= INS_UNDOC; 358 ins_err &= ~INS_UNDOC; 359 } 360 break; 361 case OPTION_MACH_WUP: 362 case OPTION_MACH_IUP: 363 if ((ins_ok & INS_GBZ80) == 0) 364 { 365 ins_ok |= INS_UNDOC | INS_UNPORT; 366 ins_err &= ~(INS_UNDOC | INS_UNPORT); 367 } 368 break; 369 case OPTION_MACH_FUD: 370 if ((ins_ok & (INS_R800 | INS_GBZ80)) == 0) 371 { 372 ins_ok &= (INS_UNDOC | INS_UNPORT); 373 ins_err |= INS_UNDOC | INS_UNPORT; 374 } 375 break; 376 case OPTION_MACH_FUP: 377 ins_ok &= ~INS_UNPORT; 378 ins_err |= INS_UNPORT; 379 break; 380 case OPTION_COMPAT_LL_PREFIX: 381 local_label_prefix = (arg && *arg) ? arg : NULL; 382 break; 383 case OPTION_COMPAT_SDCC: 384 sdcc_compat = 1; 385 break; 386 case OPTION_COMPAT_COLONLESS: 387 colonless_labels = 1; 388 break; 389 } 390 391 return 1; 392} 393 394void 395md_show_usage (FILE * f) 396{ 397 unsigned i; 398 fprintf (f, _("\n\ 399CPU model options:\n\ 400 -march=CPU[+EXT...][-EXT...]\n\ 401\t\t\t generate code for CPU, where CPU is one of:\n")); 402 for (i = 0; i < ARRAY_SIZE(match_cpu_table); ++i) 403 fprintf (f, " %-8s\t\t %s\n", match_cpu_table[i].name, match_cpu_table[i].comment); 404 fprintf (f, _("And EXT is combination (+EXT - add, -EXT - remove) of:\n")); 405 for (i = 0; i < ARRAY_SIZE(match_ext_table); ++i) 406 fprintf (f, " %-8s\t\t %s\n", match_ext_table[i].name, match_ext_table[i].comment); 407 fprintf (f, _("\n\ 408Compatibility options:\n\ 409 -local-prefix=TEXT\t treat labels prefixed by TEXT as local\n\ 410 -colonless\t\t permit colonless labels\n\ 411 -sdcc\t\t\t accept SDCC specific instruction syntax\n\ 412 -fp-s=FORMAT\t\t set single precision FP numbers format\n\ 413 -fp-d=FORMAT\t\t set double precision FP numbers format\n\ 414Where FORMAT one of:\n\ 415 ieee754\t\t IEEE754 compatible (depends on directive)\n\ 416 half\t\t\t IEEE754 half precision (16 bit)\n\ 417 single\t\t IEEE754 single precision (32 bit)\n\ 418 double\t\t IEEE754 double precision (64 bit)\n\ 419 zeda32\t\t Zeda z80float library 32 bit format\n\ 420 math48\t\t 48 bit format from Math48 library\n\ 421\n\ 422Default: -march=z80+xyhl+infc\n")); 423} 424 425static symbolS * zero; 426 427struct reg_entry 428{ 429 const char* name; 430 int number; 431 int isa; 432}; 433#define R_STACKABLE (0x80) 434#define R_ARITH (0x40) 435#define R_IX (0x20) 436#define R_IY (0x10) 437#define R_INDEX (R_IX | R_IY) 438 439#define REG_A (7) 440#define REG_B (0) 441#define REG_C (1) 442#define REG_D (2) 443#define REG_E (3) 444#define REG_H (4) 445#define REG_L (5) 446#define REG_F (6 | 8) 447#define REG_I (9) 448#define REG_R (10) 449#define REG_MB (11) 450 451#define REG_AF (3 | R_STACKABLE) 452#define REG_BC (0 | R_STACKABLE | R_ARITH) 453#define REG_DE (1 | R_STACKABLE | R_ARITH) 454#define REG_HL (2 | R_STACKABLE | R_ARITH) 455#define REG_IX (REG_HL | R_IX) 456#define REG_IY (REG_HL | R_IY) 457#define REG_SP (3 | R_ARITH) 458 459static const struct reg_entry regtable[] = 460{ 461 {"a", REG_A, INS_ALL }, 462 {"af", REG_AF, INS_ALL }, 463 {"b", REG_B, INS_ALL }, 464 {"bc", REG_BC, INS_ALL }, 465 {"c", REG_C, INS_ALL }, 466 {"d", REG_D, INS_ALL }, 467 {"de", REG_DE, INS_ALL }, 468 {"e", REG_E, INS_ALL }, 469 {"f", REG_F, INS_IN_F_C | INS_Z80N | INS_R800 }, 470 {"h", REG_H, INS_ALL }, 471 {"hl", REG_HL, INS_ALL }, 472 {"i", REG_I, INS_NOT_GBZ80 }, 473 {"ix", REG_IX, INS_NOT_GBZ80 }, 474 {"ixh", REG_H | R_IX, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N }, 475 {"ixl", REG_L | R_IX, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N }, 476 {"iy", REG_IY, INS_NOT_GBZ80 }, 477 {"iyh", REG_H | R_IY, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N }, 478 {"iyl", REG_L | R_IY, INS_IDX_HALF | INS_EZ80 | INS_R800 | INS_Z80N }, 479 {"l", REG_L, INS_ALL }, 480 {"mb", REG_MB, INS_EZ80 }, 481 {"r", REG_R, INS_NOT_GBZ80 }, 482 {"sp", REG_SP, INS_ALL }, 483} ; 484 485#define BUFLEN 8 /* Large enough for any keyword. */ 486 487void 488md_begin (void) 489{ 490 expressionS nul, reg; 491 char * p; 492 unsigned int i, j, k; 493 char buf[BUFLEN]; 494 495 if (ins_ok & INS_EZ80) /* if select EZ80 cpu then */ 496 listing_lhs_width = 6; /* use 6 bytes per line in the listing */ 497 498 reg.X_op = O_register; 499 reg.X_md = 0; 500 reg.X_add_symbol = reg.X_op_symbol = 0; 501 for ( i = 0 ; i < ARRAY_SIZE ( regtable ) ; ++i ) 502 { 503 if (regtable[i].isa && !(regtable[i].isa & ins_ok)) 504 continue; 505 reg.X_add_number = regtable[i].number; 506 k = strlen ( regtable[i].name ); 507 buf[k] = 0; 508 if ( k+1 < BUFLEN ) 509 { 510 for ( j = ( 1<<k ) ; j ; --j ) 511 { 512 for ( k = 0 ; regtable[i].name[k] ; ++k ) 513 { 514 buf[k] = ( j & ( 1<<k ) ) ? TOUPPER (regtable[i].name[k]) : regtable[i].name[k]; 515 } 516 symbolS * psym = symbol_find_or_make (buf); 517 S_SET_SEGMENT (psym, reg_section); 518 symbol_set_value_expression (psym, ®); 519 } 520 } 521 } 522 p = input_line_pointer; 523 input_line_pointer = (char *) "0"; 524 nul.X_md=0; 525 expression (& nul); 526 input_line_pointer = p; 527 zero = make_expr_symbol (& nul); 528 /* We do not use relaxation (yet). */ 529 linkrelax = 0; 530} 531 532void 533z80_md_end (void) 534{ 535 int mach_type; 536 537 switch (ins_ok & INS_MARCH_MASK) 538 { 539 case INS_Z80: 540 mach_type = bfd_mach_z80; 541 break; 542 case INS_R800: 543 mach_type = bfd_mach_r800; 544 break; 545 case INS_Z180: 546 mach_type = bfd_mach_z180; 547 break; 548 case INS_GBZ80: 549 mach_type = bfd_mach_gbz80; 550 break; 551 case INS_EZ80: 552 mach_type = cpu_mode ? bfd_mach_ez80_adl : bfd_mach_ez80_z80; 553 break; 554 case INS_Z80N: 555 mach_type = bfd_mach_z80n; 556 break; 557 default: 558 mach_type = 0; 559 } 560 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type); 561} 562 563#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) 564void 565z80_elf_final_processing (void) 566{/* nothing to do, all is done by BFD itself */ 567/* 568 unsigned elf_flags; 569 elf_elfheader (stdoutput)->e_flags = elf_flags; 570*/ 571} 572#endif 573 574static const char * 575skip_space (const char *s) 576{ 577 while (*s == ' ' || *s == '\t') 578 ++s; 579 return s; 580} 581 582/* A non-zero return-value causes a continue in the 583 function read_a_source_file () in ../read.c. */ 584int 585z80_start_line_hook (void) 586{ 587 char *p, quote; 588 char buf[4]; 589 590 /* Convert one character constants. */ 591 for (p = input_line_pointer; *p && *p != '\n'; ++p) 592 { 593 switch (*p) 594 { 595 case '\'': 596 if (p[1] != 0 && p[1] != '\'' && p[2] == '\'') 597 { 598 snprintf (buf, 4, "%3d", (unsigned char)p[1]); 599 *p++ = buf[0]; 600 *p++ = buf[1]; 601 *p++ = buf[2]; 602 break; 603 } 604 /* Fall through. */ 605 case '"': 606 for (quote = *p++; quote != *p && '\n' != *p; ++p) 607 /* No escapes. */ ; 608 if (quote != *p) 609 { 610 as_bad (_("-- unterminated string")); 611 ignore_rest_of_line (); 612 return 1; 613 } 614 break; 615 case '#': 616 if (sdcc_compat) 617 *p = (*skip_space (p + 1) == '(') ? '+' : ' '; 618 break; 619 } 620 } 621 /* Check for <label>[:] =|([.](EQU|DEFL)) <value>. */ 622 if (is_name_beginner (*input_line_pointer)) 623 { 624 char *name; 625 char c, *rest, *line_start; 626 int len; 627 628 line_start = input_line_pointer; 629 if (ignore_input ()) 630 return 0; 631 c = get_symbol_name (&name); 632 rest = input_line_pointer + 1; 633 if (c == ':' && *rest == ':') 634 { 635 /* remove second colon if SDCC compatibility enabled */ 636 if (sdcc_compat) 637 *rest = ' '; 638 ++rest; 639 } 640 rest = (char*)skip_space (rest); 641 if (*rest == '=') 642 len = (rest[1] == '=') ? 2 : 1; 643 else 644 { 645 if (*rest == '.') 646 ++rest; 647 if (strncasecmp (rest, "EQU", 3) == 0) 648 len = 3; 649 else if (strncasecmp (rest, "DEFL", 4) == 0) 650 len = 4; 651 else 652 len = 0; 653 } 654 if (len && (len <= 2 || !ISALPHA (rest[len]))) 655 { 656 /* Handle assignment here. */ 657 if (line_start[-1] == '\n') 658 { 659 bump_line_counters (); 660 LISTING_NEWLINE (); 661 } 662 input_line_pointer = rest + len - 1; 663 /* Allow redefining with "DEFL" (len == 4), but not with "EQU". */ 664 switch (len) 665 { 666 case 1: /* label = expr */ 667 case 4: /* label DEFL expr */ 668 equals (name, 1); 669 break; 670 case 2: /* label == expr */ 671 case 3: /* label EQU expr */ 672 equals (name, 0); 673 break; 674 } 675 return 1; 676 } 677 else 678 { 679 /* Restore line and pointer. */ 680 (void) restore_line_pointer (c); 681 input_line_pointer = line_start; 682 } 683 } 684 return 0; 685} 686 687symbolS * 688md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 689{ 690 return NULL; 691} 692 693const char * 694md_atof (int type, char *litP, int *sizeP) 695{ 696 switch (type) 697 { 698 case 'f': 699 case 'F': 700 case 's': 701 case 'S': 702 if (str_to_float) 703 return str_to_float (litP, sizeP); 704 break; 705 case 'd': 706 case 'D': 707 case 'r': 708 case 'R': 709 if (str_to_double) 710 return str_to_double (litP, sizeP); 711 break; 712 } 713 return ieee_md_atof (type, litP, sizeP, FALSE); 714} 715 716valueT 717md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size) 718{ 719 return size; 720} 721 722long 723md_pcrel_from (fixS * fixp) 724{ 725 return fixp->fx_where + fixp->fx_frag->fr_address; 726} 727 728typedef const char * (asfunc)(char, char, const char*); 729 730typedef struct _table_t 731{ 732 const char* name; 733 unsigned char prefix; 734 unsigned char opcode; 735 asfunc * fp; 736 unsigned inss; /*0 - all CPU types or list of supported INS_* */ 737} table_t; 738 739/* Compares the key for structs that start with a char * to the key. */ 740static int 741key_cmp (const void * a, const void * b) 742{ 743 const char *str_a, *str_b; 744 745 str_a = *((const char**)a); 746 str_b = *((const char**)b); 747 return strcmp (str_a, str_b); 748} 749 750char buf[BUFLEN]; 751const char *key = buf; 752 753/* Prevent an error on a line from also generating 754 a "junk at end of line" error message. */ 755static char err_flag; 756 757static void 758error (const char * message) 759{ 760 if (err_flag) 761 return; 762 763 as_bad ("%s", message); 764 err_flag = 1; 765} 766 767static void 768ill_op (void) 769{ 770 error (_("illegal operand")); 771} 772 773static void 774wrong_mach (int ins_type) 775{ 776 if (ins_type & ins_err) 777 ill_op (); 778 else 779 as_warn (_("undocumented instruction")); 780} 781 782static void 783check_mach (int ins_type) 784{ 785 if ((ins_type & ins_ok) == 0) 786 wrong_mach (ins_type); 787} 788 789/* Check whether an expression is indirect. */ 790static int 791is_indir (const char *s) 792{ 793 char quote; 794 const char *p; 795 int indir, depth; 796 797 /* Indirection is indicated with parentheses. */ 798 indir = (*s == '('); 799 800 for (p = s, depth = 0; *p && *p != ','; ++p) 801 { 802 switch (*p) 803 { 804 case '"': 805 case '\'': 806 for (quote = *p++; quote != *p && *p != '\n'; ++p) 807 if (*p == '\\' && p[1]) 808 ++p; 809 break; 810 case '(': 811 ++ depth; 812 break; 813 case ')': 814 -- depth; 815 if (depth == 0) 816 { 817 p = skip_space (p + 1); 818 if (*p && *p != ',') 819 indir = 0; 820 --p; 821 } 822 if (depth < 0) 823 error (_("mismatched parentheses")); 824 break; 825 } 826 } 827 828 if (depth != 0) 829 error (_("mismatched parentheses")); 830 831 return indir; 832} 833 834/* Check whether a symbol involves a register. */ 835static bfd_boolean 836contains_register (symbolS *sym) 837{ 838 if (sym) 839 { 840 expressionS * ex = symbol_get_value_expression (sym); 841 842 switch (ex->X_op) 843 { 844 case O_register: 845 return TRUE; 846 847 case O_add: 848 case O_subtract: 849 if (ex->X_op_symbol && contains_register (ex->X_op_symbol)) 850 return TRUE; 851 /* Fall through. */ 852 case O_uminus: 853 case O_symbol: 854 if (ex->X_add_symbol && contains_register (ex->X_add_symbol)) 855 return TRUE; 856 break; 857 858 default: 859 break; 860 } 861 } 862 863 return FALSE; 864} 865 866/* Parse general expression, not looking for indexed addressing. */ 867static const char * 868parse_exp_not_indexed (const char *s, expressionS *op) 869{ 870 const char *p; 871 int indir; 872 int make_shift = -1; 873 874 p = skip_space (s); 875 if (sdcc_compat && (*p == '<' || *p == '>')) 876 { 877 switch (*p) 878 { 879 case '<': /* LSB request */ 880 make_shift = 0; 881 break; 882 case '>': /* MSB request */ 883 make_shift = cpu_mode ? 16 : 8; 884 break; 885 } 886 s = ++p; 887 p = skip_space (p); 888 } 889 890 op->X_md = indir = is_indir (p); 891 if (indir && (ins_ok & INS_GBZ80)) 892 { /* check for instructions like ld a,(hl+), ld (hl-),a */ 893 p = skip_space (p+1); 894 if (!strncasecmp (p, "hl", 2)) 895 { 896 p = skip_space(p+2); 897 if (*skip_space(p+1) == ')' && (*p == '+' || *p == '-')) 898 { 899 op->X_op = O_md1; 900 op->X_add_symbol = NULL; 901 op->X_add_number = (*p == '+') ? REG_HL : -REG_HL; 902 input_line_pointer = (char*)skip_space(p + 1) + 1; 903 return input_line_pointer; 904 } 905 } 906 } 907 input_line_pointer = (char*) s ; 908 expression (op); 909 switch (op->X_op) 910 { 911 case O_absent: 912 error (_("missing operand")); 913 break; 914 case O_illegal: 915 error (_("bad expression syntax")); 916 break; 917 default: 918 break; 919 } 920 921 if (make_shift >= 0) 922 { 923 /* replace [op] by [op >> shift] */ 924 expressionS data; 925 op->X_add_symbol = make_expr_symbol (op); 926 op->X_add_number = 0; 927 op->X_op = O_right_shift; 928 memset (&data, 0, sizeof (data)); 929 data.X_op = O_constant; 930 data.X_add_number = make_shift; 931 op->X_op_symbol = make_expr_symbol (&data); 932 } 933 return input_line_pointer; 934} 935 936static int 937unify_indexed (expressionS *op) 938{ 939 if (O_register != symbol_get_value_expression (op->X_add_symbol)->X_op) 940 return 0; 941 942 int rnum = symbol_get_value_expression (op->X_add_symbol)->X_add_number; 943 if ( ((REG_IX != rnum) && (REG_IY != rnum)) || contains_register (op->X_op_symbol)) 944 { 945 ill_op (); 946 return 0; 947 } 948 949 /* Convert subtraction to addition of negative value. */ 950 if (O_subtract == op->X_op) 951 { 952 expressionS minus; 953 minus.X_op = O_uminus; 954 minus.X_add_number = 0; 955 minus.X_add_symbol = op->X_op_symbol; 956 minus.X_op_symbol = 0; 957 op->X_op_symbol = make_expr_symbol (&minus); 958 op->X_op = O_add; 959 } 960 961 /* Clear X_add_number of the expression. */ 962 if (op->X_add_number != 0) 963 { 964 expressionS add; 965 memset (&add, 0, sizeof (add)); 966 add.X_op = O_symbol; 967 add.X_add_number = op->X_add_number; 968 add.X_add_symbol = op->X_op_symbol; 969 add.X_op_symbol = 0; 970 op->X_add_symbol = make_expr_symbol (&add); 971 } 972 else 973 op->X_add_symbol = op->X_op_symbol; 974 975 op->X_add_number = rnum; 976 op->X_op_symbol = 0; 977 return 1; 978} 979 980/* Parse expression, change operator to O_md1 for indexed addressing. */ 981static const char * 982parse_exp (const char *s, expressionS *op) 983{ 984 const char* res = parse_exp_not_indexed (s, op); 985 switch (op->X_op) 986 { 987 case O_add: 988 case O_subtract: 989 if (unify_indexed (op) && op->X_md) 990 op->X_op = O_md1; 991 break; 992 case O_register: 993 if (op->X_md && ((REG_IX == op->X_add_number) || (REG_IY == op->X_add_number))) 994 { 995 op->X_add_symbol = zero; 996 op->X_op = O_md1; 997 } 998 break; 999 case O_constant: 1000 /* parse SDCC syntax where index register offset placed before parentheses */ 1001 if (sdcc_compat && is_indir (res)) 1002 { 1003 expressionS off; 1004 off = *op; 1005 res = parse_exp (res, op); 1006 if (op->X_op != O_md1 || op->X_add_symbol != zero) 1007 ill_op (); 1008 else 1009 op->X_add_symbol = make_expr_symbol (&off); 1010 } 1011 break; 1012 default: 1013 break; 1014 } 1015 return res; 1016} 1017 1018/* Condition codes, including some synonyms provided by HiTech zas. */ 1019static const struct reg_entry cc_tab[] = 1020{ 1021 { "age", 6 << 3, INS_ALL }, 1022 { "alt", 7 << 3, INS_ALL }, 1023 { "c", 3 << 3, INS_ALL }, 1024 { "di", 4 << 3, INS_ALL }, 1025 { "ei", 5 << 3, INS_ALL }, 1026 { "lge", 2 << 3, INS_ALL }, 1027 { "llt", 3 << 3, INS_ALL }, 1028 { "m", 7 << 3, INS_ALL }, 1029 { "nc", 2 << 3, INS_ALL }, 1030 { "nz", 0 << 3, INS_ALL }, 1031 { "p", 6 << 3, INS_ALL }, 1032 { "pe", 5 << 3, INS_ALL }, 1033 { "po", 4 << 3, INS_ALL }, 1034 { "z", 1 << 3, INS_ALL }, 1035} ; 1036 1037/* Parse condition code. */ 1038static const char * 1039parse_cc (const char *s, char * op) 1040{ 1041 const char *p; 1042 int i; 1043 struct reg_entry * cc_p; 1044 1045 for (i = 0; i < BUFLEN; ++i) 1046 { 1047 if (!ISALPHA (s[i])) /* Condition codes consist of letters only. */ 1048 break; 1049 buf[i] = TOLOWER (s[i]); 1050 } 1051 1052 if ((i < BUFLEN) 1053 && ((s[i] == 0) || (s[i] == ','))) 1054 { 1055 buf[i] = 0; 1056 cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab), 1057 sizeof (cc_tab[0]), key_cmp); 1058 } 1059 else 1060 cc_p = NULL; 1061 1062 if (cc_p) 1063 { 1064 *op = cc_p->number; 1065 p = s + i; 1066 } 1067 else 1068 p = NULL; 1069 1070 return p; 1071} 1072 1073static const char * 1074emit_insn (char prefix, char opcode, const char * args) 1075{ 1076 char *p; 1077 1078 if (prefix) 1079 { 1080 p = frag_more (2); 1081 *p++ = prefix; 1082 } 1083 else 1084 p = frag_more (1); 1085 *p = opcode; 1086 return args; 1087} 1088 1089void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp) 1090{ 1091 bfd_reloc_code_real_type r[4] = 1092 { 1093 BFD_RELOC_8, 1094 BFD_RELOC_16, 1095 BFD_RELOC_24, 1096 BFD_RELOC_32 1097 }; 1098 1099 if (nbytes < 1 || nbytes > 4) 1100 { 1101 as_bad (_("unsupported BFD relocation size %u"), nbytes); 1102 } 1103 else 1104 { 1105 fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]); 1106 } 1107} 1108 1109static void 1110emit_data_val (expressionS * val, int size) 1111{ 1112 char *p; 1113 bfd_reloc_code_real_type r_type; 1114 1115 p = frag_more (size); 1116 if (val->X_op == O_constant) 1117 { 1118 int i; 1119 for (i = 0; i < size; ++i) 1120 p[i] = (char)(val->X_add_number >> (i*8)); 1121 return; 1122 } 1123 1124 switch (size) 1125 { 1126 case 1: r_type = BFD_RELOC_8; break; 1127 case 2: r_type = BFD_RELOC_16; break; 1128 case 3: r_type = BFD_RELOC_24; break; 1129 case 4: r_type = BFD_RELOC_32; break; 1130 case 8: r_type = BFD_RELOC_64; break; 1131 default: 1132 as_fatal (_("invalid data size %d"), size); 1133 } 1134 1135 if ( (val->X_op == O_register) 1136 || (val->X_op == O_md1) 1137 || contains_register (val->X_add_symbol) 1138 || contains_register (val->X_op_symbol)) 1139 ill_op (); 1140 1141 if (size <= 2 && val->X_op_symbol) 1142 { 1143 bfd_boolean simplify = TRUE; 1144 int shift = symbol_get_value_expression (val->X_op_symbol)->X_add_number; 1145 if (val->X_op == O_bit_and && shift == (1 << (size*8))-1) 1146 shift = 0; 1147 else if (val->X_op != O_right_shift) 1148 shift = -1; 1149 1150 if (size == 1) 1151 { 1152 switch (shift) 1153 { 1154 case 0: r_type = BFD_RELOC_Z80_BYTE0; break; 1155 case 8: r_type = BFD_RELOC_Z80_BYTE1; break; 1156 case 16: r_type = BFD_RELOC_Z80_BYTE2; break; 1157 case 24: r_type = BFD_RELOC_Z80_BYTE3; break; 1158 default: simplify = FALSE; 1159 } 1160 } 1161 else /* if (size == 2) */ 1162 { 1163 switch (shift) 1164 { 1165 case 0: r_type = BFD_RELOC_Z80_WORD0; break; 1166 case 16: r_type = BFD_RELOC_Z80_WORD1; break; 1167 default: simplify = FALSE; 1168 } 1169 } 1170 1171 if (simplify) 1172 { 1173 val->X_op = O_symbol; 1174 val->X_op_symbol = NULL; 1175 val->X_add_number = 0; 1176 } 1177 } 1178 1179 fix_new_exp (frag_now, p - frag_now->fr_literal, size, val, FALSE, r_type); 1180} 1181 1182static void 1183emit_byte (expressionS * val, bfd_reloc_code_real_type r_type) 1184{ 1185 char *p; 1186 1187 if (r_type == BFD_RELOC_8) 1188 { 1189 emit_data_val (val, 1); 1190 return; 1191 } 1192 p = frag_more (1); 1193 *p = val->X_add_number; 1194 if (contains_register (val->X_add_symbol) || contains_register (val->X_op_symbol)) 1195 { 1196 ill_op (); 1197 } 1198 else if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant)) 1199 { 1200 as_bad (_("cannot make a relative jump to an absolute location")); 1201 } 1202 else if (val->X_op == O_constant) 1203 { 1204 if ((val->X_add_number < -128) || (val->X_add_number >= 128)) 1205 { 1206 if (r_type == BFD_RELOC_Z80_DISP8) 1207 as_bad (_("index overflow (%+ld)"), val->X_add_number); 1208 else 1209 as_bad (_("offset overflow (%+ld)"), val->X_add_number); 1210 } 1211 } 1212 else 1213 { 1214 /* For symbols only, constants are stored at begin of function. */ 1215 fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val, 1216 (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type); 1217 } 1218} 1219 1220static void 1221emit_word (expressionS * val) 1222{ 1223 emit_data_val (val, (inst_mode & INST_MODE_IL) ? 3 : 2); 1224} 1225 1226static void 1227emit_mx (char prefix, char opcode, int shift, expressionS * arg) 1228 /* The operand m may be r, (hl), (ix+d), (iy+d), 1229 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */ 1230{ 1231 char *q; 1232 int rnum; 1233 1234 rnum = arg->X_add_number; 1235 switch (arg->X_op) 1236 { 1237 case O_register: 1238 if (arg->X_md) 1239 { 1240 if (rnum != REG_HL) 1241 { 1242 ill_op (); 1243 break; 1244 } 1245 else 1246 rnum = 6; 1247 } 1248 else 1249 { 1250 if ((prefix == 0) && (rnum & R_INDEX)) 1251 { 1252 prefix = (rnum & R_IX) ? 0xDD : 0xFD; 1253 if (!(ins_ok & (INS_EZ80|INS_R800|INS_Z80N))) 1254 check_mach (INS_IDX_HALF); 1255 rnum &= ~R_INDEX; 1256 } 1257 if (rnum > 7) 1258 { 1259 ill_op (); 1260 break; 1261 } 1262 } 1263 q = frag_more (prefix ? 2 : 1); 1264 if (prefix) 1265 * q ++ = prefix; 1266 * q ++ = opcode + (rnum << shift); 1267 break; 1268 case O_md1: 1269 if (ins_ok & INS_GBZ80) 1270 { 1271 ill_op (); 1272 break; 1273 } 1274 q = frag_more (2); 1275 *q++ = (rnum & R_IX) ? 0xDD : 0xFD; 1276 *q = (prefix) ? prefix : (opcode + (6 << shift)); 1277 { 1278 expressionS offset = *arg; 1279 offset.X_op = O_symbol; 1280 offset.X_add_number = 0; 1281 emit_byte (&offset, BFD_RELOC_Z80_DISP8); 1282 } 1283 if (prefix) 1284 { 1285 q = frag_more (1); 1286 *q = opcode+(6<<shift); 1287 } 1288 break; 1289 default: 1290 abort (); 1291 } 1292} 1293 1294/* The operand m may be r, (hl), (ix+d), (iy+d), 1295 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */ 1296static const char * 1297emit_m (char prefix, char opcode, const char *args) 1298{ 1299 expressionS arg_m; 1300 const char *p; 1301 1302 p = parse_exp (args, &arg_m); 1303 switch (arg_m.X_op) 1304 { 1305 case O_md1: 1306 case O_register: 1307 emit_mx (prefix, opcode, 0, &arg_m); 1308 break; 1309 default: 1310 ill_op (); 1311 } 1312 return p; 1313} 1314 1315/* The operand m may be as above or one of the undocumented 1316 combinations (ix+d),r and (iy+d),r (if unportable instructions 1317 are allowed). */ 1318 1319static const char * 1320emit_mr (char prefix, char opcode, const char *args) 1321{ 1322 expressionS arg_m, arg_r; 1323 const char *p; 1324 1325 p = parse_exp (args, & arg_m); 1326 1327 switch (arg_m.X_op) 1328 { 1329 case O_md1: 1330 if (*p == ',') 1331 { 1332 p = parse_exp (p + 1, & arg_r); 1333 1334 if ((arg_r.X_md == 0) 1335 && (arg_r.X_op == O_register) 1336 && (arg_r.X_add_number < 8)) 1337 opcode += arg_r.X_add_number - 6; /* Emit_mx () will add 6. */ 1338 else 1339 { 1340 ill_op (); 1341 break; 1342 } 1343 if (!(ins_ok & INS_Z80N)) 1344 check_mach (INS_ROT_II_LD); 1345 } 1346 /* Fall through. */ 1347 case O_register: 1348 emit_mx (prefix, opcode, 0, & arg_m); 1349 break; 1350 default: 1351 ill_op (); 1352 } 1353 return p; 1354} 1355 1356static void 1357emit_sx (char prefix, char opcode, expressionS * arg_p) 1358{ 1359 char *q; 1360 1361 switch (arg_p->X_op) 1362 { 1363 case O_register: 1364 case O_md1: 1365 emit_mx (prefix, opcode, 0, arg_p); 1366 break; 1367 default: 1368 if (arg_p->X_md) 1369 ill_op (); 1370 else 1371 { 1372 q = frag_more (prefix ? 2 : 1); 1373 if (prefix) 1374 *q++ = prefix; 1375 *q = opcode ^ 0x46; 1376 emit_byte (arg_p, BFD_RELOC_8); 1377 } 1378 } 1379} 1380 1381/* The operand s may be r, (hl), (ix+d), (iy+d), n. */ 1382static const char * 1383emit_s (char prefix, char opcode, const char *args) 1384{ 1385 expressionS arg_s; 1386 const char *p; 1387 1388 p = parse_exp (args, & arg_s); 1389 if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A) 1390 { /* possible instruction in generic format op A,x */ 1391 if (!(ins_ok & INS_EZ80) && !sdcc_compat) 1392 ill_op (); 1393 ++p; 1394 p = parse_exp (p, & arg_s); 1395 } 1396 emit_sx (prefix, opcode, & arg_s); 1397 return p; 1398} 1399 1400static const char * 1401emit_sub (char prefix, char opcode, const char *args) 1402{ 1403 expressionS arg_s; 1404 const char *p; 1405 1406 if (!(ins_ok & INS_GBZ80)) 1407 return emit_s (prefix, opcode, args); 1408 p = parse_exp (args, & arg_s); 1409 if (*p++ != ',') 1410 { 1411 error (_("bad instruction syntax")); 1412 return p; 1413 } 1414 1415 if (arg_s.X_md != 0 || arg_s.X_op != O_register || arg_s.X_add_number != REG_A) 1416 ill_op (); 1417 1418 p = parse_exp (p, & arg_s); 1419 1420 emit_sx (prefix, opcode, & arg_s); 1421 return p; 1422} 1423 1424static const char * 1425emit_swap (char prefix, char opcode, const char *args) 1426{ 1427 expressionS reg; 1428 const char *p; 1429 char *q; 1430 1431 if (!(ins_ok & INS_Z80N)) 1432 return emit_mr (prefix, opcode, args); 1433 1434 /* check for alias swap a for swapnib of Z80N */ 1435 p = parse_exp (args, ®); 1436 if (reg.X_md != 0 || reg.X_op != O_register || reg.X_add_number != REG_A) 1437 ill_op (); 1438 1439 q = frag_more (2); 1440 *q++ = 0xED; 1441 *q = 0x23; 1442 return p; 1443} 1444 1445static const char * 1446emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 1447{ 1448 expressionS addr; 1449 const char *p; char *q; 1450 1451 p = parse_exp_not_indexed (args, &addr); 1452 if (addr.X_md) 1453 ill_op (); 1454 else 1455 { 1456 q = frag_more (1); 1457 *q = opcode; 1458 emit_word (& addr); 1459 } 1460 return p; 1461} 1462 1463/* Operand may be rr, r, (hl), (ix+d), (iy+d). */ 1464static const char * 1465emit_incdec (char prefix, char opcode, const char * args) 1466{ 1467 expressionS operand; 1468 int rnum; 1469 const char *p; char *q; 1470 1471 p = parse_exp (args, &operand); 1472 rnum = operand.X_add_number; 1473 if ((! operand.X_md) 1474 && (operand.X_op == O_register) 1475 && (R_ARITH&rnum)) 1476 { 1477 q = frag_more ((rnum & R_INDEX) ? 2 : 1); 1478 if (rnum & R_INDEX) 1479 *q++ = (rnum & R_IX) ? 0xDD : 0xFD; 1480 *q = prefix + ((rnum & 3) << 4); 1481 } 1482 else 1483 { 1484 if ((operand.X_op == O_md1) || (operand.X_op == O_register)) 1485 emit_mx (0, opcode, 3, & operand); 1486 else 1487 ill_op (); 1488 } 1489 return p; 1490} 1491 1492static const char * 1493emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 1494{ 1495 expressionS addr; 1496 const char *p; 1497 char *q; 1498 1499 p = parse_exp_not_indexed (args, &addr); 1500 if (addr.X_md) 1501 ill_op (); 1502 else 1503 { 1504 q = frag_more (1); 1505 *q = opcode; 1506 addr.X_add_number--; /* pcrel computes after offset code */ 1507 emit_byte (&addr, BFD_RELOC_8_PCREL); 1508 } 1509 return p; 1510} 1511 1512static const char * 1513emit_jp (char prefix, char opcode, const char * args) 1514{ 1515 expressionS addr; 1516 const char *p; 1517 char *q; 1518 int rnum; 1519 1520 p = parse_exp_not_indexed (args, & addr); 1521 if (addr.X_md) 1522 { 1523 rnum = addr.X_add_number; 1524 if ((O_register == addr.X_op) && (REG_HL == (rnum & ~R_INDEX))) 1525 { 1526 q = frag_more ((rnum & R_INDEX) ? 2 : 1); 1527 if (rnum & R_INDEX) 1528 *q++ = (rnum & R_IX) ? 0xDD : 0xFD; 1529 *q = prefix; 1530 } 1531 else if (addr.X_op == O_register && rnum == REG_C && (ins_ok & INS_Z80N)) 1532 { 1533 q = frag_more (2); 1534 *q++ = 0xED; 1535 *q = 0x98; 1536 } 1537 else 1538 ill_op (); 1539 } 1540 else 1541 { 1542 q = frag_more (1); 1543 *q = opcode; 1544 emit_word (& addr); 1545 } 1546 return p; 1547} 1548 1549static const char * 1550emit_im (char prefix, char opcode, const char * args) 1551{ 1552 expressionS mode; 1553 const char *p; 1554 char *q; 1555 1556 p = parse_exp (args, & mode); 1557 if (mode.X_md || (mode.X_op != O_constant)) 1558 ill_op (); 1559 else 1560 switch (mode.X_add_number) 1561 { 1562 case 1: 1563 case 2: 1564 ++mode.X_add_number; 1565 /* Fall through. */ 1566 case 0: 1567 q = frag_more (2); 1568 *q++ = prefix; 1569 *q = opcode + 8*mode.X_add_number; 1570 break; 1571 default: 1572 ill_op (); 1573 } 1574 return p; 1575} 1576 1577static const char * 1578emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 1579{ 1580 expressionS regp; 1581 const char *p; 1582 char *q; 1583 1584 p = parse_exp (args, & regp); 1585 if ((!regp.X_md) 1586 && (regp.X_op == O_register) 1587 && (regp.X_add_number & R_STACKABLE)) 1588 { 1589 int rnum; 1590 1591 rnum = regp.X_add_number; 1592 if (rnum&R_INDEX) 1593 { 1594 q = frag_more (2); 1595 *q++ = (rnum&R_IX)?0xDD:0xFD; 1596 } 1597 else 1598 q = frag_more (1); 1599 *q = opcode + ((rnum & 3) << 4); 1600 } 1601 else 1602 ill_op (); 1603 1604 return p; 1605} 1606 1607static const char * 1608emit_push (char prefix, char opcode, const char * args) 1609{ 1610 expressionS arg; 1611 const char *p; 1612 char *q; 1613 1614 p = parse_exp (args, & arg); 1615 if (arg.X_op == O_register) 1616 return emit_pop (prefix, opcode, args); 1617 1618 if (arg.X_md || arg.X_op == O_md1 || !(ins_ok & INS_Z80N)) 1619 ill_op (); 1620 1621 q = frag_more (2); 1622 *q++ = 0xED; 1623 *q = 0x8A; 1624 1625 q = frag_more (2); 1626 fix_new_exp (frag_now, q - frag_now->fr_literal, 2, &arg, FALSE, 1627 BFD_RELOC_Z80_16_BE); 1628 1629 return p; 1630} 1631 1632static const char * 1633emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 1634{ 1635 char cc, *q; 1636 const char *p; 1637 1638 p = parse_cc (args, &cc); 1639 q = frag_more (1); 1640 if (p) 1641 *q = opcode + cc; 1642 else 1643 *q = prefix; 1644 return p ? p : args; 1645} 1646 1647static const char * 1648emit_adc (char prefix, char opcode, const char * args) 1649{ 1650 expressionS term; 1651 int rnum; 1652 const char *p; 1653 char *q; 1654 1655 p = parse_exp (args, &term); 1656 if (*p++ != ',') 1657 { 1658 error (_("bad instruction syntax")); 1659 return p; 1660 } 1661 1662 if ((term.X_md) || (term.X_op != O_register)) 1663 ill_op (); 1664 else 1665 switch (term.X_add_number) 1666 { 1667 case REG_A: 1668 p = emit_s (0, prefix, p); 1669 break; 1670 case REG_HL: 1671 p = parse_exp (p, &term); 1672 if ((!term.X_md) && (term.X_op == O_register)) 1673 { 1674 rnum = term.X_add_number; 1675 if (R_ARITH == (rnum & (R_ARITH | R_INDEX))) 1676 { 1677 q = frag_more (2); 1678 *q++ = 0xED; 1679 *q = opcode + ((rnum & 3) << 4); 1680 break; 1681 } 1682 } 1683 /* Fall through. */ 1684 default: 1685 ill_op (); 1686 } 1687 return p; 1688} 1689 1690static const char * 1691emit_add (char prefix, char opcode, const char * args) 1692{ 1693 expressionS term; 1694 int lhs, rhs; 1695 const char *p; 1696 char *q; 1697 1698 p = parse_exp (args, &term); 1699 if (*p++ != ',') 1700 { 1701 error (_("bad instruction syntax")); 1702 return p; 1703 } 1704 1705 if ((term.X_md) || (term.X_op != O_register)) 1706 ill_op (); 1707 else 1708 switch (term.X_add_number) 1709 { 1710 case REG_A: 1711 p = emit_s (0, prefix, p); 1712 break; 1713 case REG_SP: 1714 p = parse_exp (p, &term); 1715 if (!(ins_ok & INS_GBZ80) || term.X_md || term.X_op == O_register) 1716 ill_op (); 1717 q = frag_more (1); 1718 *q = 0xE8; 1719 emit_byte (&term, BFD_RELOC_Z80_DISP8); 1720 break; 1721 case REG_BC: 1722 case REG_DE: 1723 if (!(ins_ok & INS_Z80N)) 1724 { 1725 ill_op (); 1726 break; 1727 } 1728 /* Fall through. */ 1729 case REG_HL: 1730 case REG_IX: 1731 case REG_IY: 1732 lhs = term.X_add_number; 1733 p = parse_exp (p, &term); 1734 rhs = term.X_add_number; 1735 if (term.X_md != 0 || term.X_op == O_md1) 1736 ill_op (); 1737 else if ((term.X_op == O_register) && (rhs & R_ARITH) && (rhs == lhs || (rhs & ~R_INDEX) != REG_HL)) 1738 { 1739 if (1) 1740 { 1741 q = frag_more ((lhs & R_INDEX) ? 2 : 1); 1742 if (lhs & R_INDEX) 1743 *q++ = (lhs & R_IX) ? 0xDD : 0xFD; 1744 *q = opcode + ((rhs & 3) << 4); 1745 break; 1746 } 1747 } 1748 else if (!(lhs & R_INDEX) && (ins_ok & INS_Z80N)) 1749 { 1750 if (term.X_op == O_register && rhs == REG_A) 1751 { /* ADD BC/DE/HL,A */ 1752 q = frag_more (2); 1753 *q++ = 0xED; 1754 *q = 0x33 - (lhs & 3); 1755 break; 1756 } 1757 else if (term.X_op != O_register && term.X_op != O_md1) 1758 { /* ADD BC/DE/HL,nn */ 1759 q = frag_more (2); 1760 *q++ = 0xED; 1761 *q = 0x36 - (lhs & 3); 1762 emit_word (&term); 1763 break; 1764 } 1765 } 1766 /* Fall through. */ 1767 default: 1768 ill_op (); 1769 } 1770 return p; 1771} 1772 1773static const char * 1774emit_bit (char prefix, char opcode, const char * args) 1775{ 1776 expressionS b; 1777 int bn; 1778 const char *p; 1779 1780 p = parse_exp (args, &b); 1781 if (*p++ != ',') 1782 error (_("bad instruction syntax")); 1783 1784 bn = b.X_add_number; 1785 if ((!b.X_md) 1786 && (b.X_op == O_constant) 1787 && (0 <= bn) 1788 && (bn < 8)) 1789 { 1790 if (opcode == 0x40) 1791 /* Bit : no optional third operand. */ 1792 p = emit_m (prefix, opcode + (bn << 3), p); 1793 else 1794 /* Set, res : resulting byte can be copied to register. */ 1795 p = emit_mr (prefix, opcode + (bn << 3), p); 1796 } 1797 else 1798 ill_op (); 1799 return p; 1800} 1801 1802/* BSLA DE,B; BSRA DE,B; BSRL DE,B; BSRF DE,B; BRLC DE,B (Z80N only) */ 1803static const char * 1804emit_bshft (char prefix, char opcode, const char * args) 1805{ 1806 expressionS r1, r2; 1807 const char *p; 1808 char *q; 1809 1810 p = parse_exp (args, & r1); 1811 if (*p++ != ',') 1812 error (_("bad instruction syntax")); 1813 p = parse_exp (p, & r2); 1814 if (r1.X_md || r1.X_op != O_register || r1.X_add_number != REG_DE || 1815 r2.X_md || r2.X_op != O_register || r2.X_add_number != REG_B) 1816 ill_op (); 1817 q = frag_more (2); 1818 *q++ = prefix; 1819 *q = opcode; 1820 return p; 1821} 1822 1823static const char * 1824emit_jpcc (char prefix, char opcode, const char * args) 1825{ 1826 char cc; 1827 const char *p; 1828 1829 p = parse_cc (args, & cc); 1830 if (p && *p++ == ',') 1831 p = emit_call (0, opcode + cc, p); 1832 else 1833 p = (prefix == (char)0xC3) 1834 ? emit_jp (0xE9, prefix, args) 1835 : emit_call (0, prefix, args); 1836 return p; 1837} 1838 1839static const char * 1840emit_jrcc (char prefix, char opcode, const char * args) 1841{ 1842 char cc; 1843 const char *p; 1844 1845 p = parse_cc (args, &cc); 1846 if (p && *p++ == ',') 1847 { 1848 if (cc > (3 << 3)) 1849 error (_("condition code invalid for jr")); 1850 else 1851 p = emit_jr (0, opcode + cc, p); 1852 } 1853 else 1854 p = emit_jr (0, prefix, args); 1855 1856 return p; 1857} 1858 1859static const char * 1860emit_ex (char prefix_in ATTRIBUTE_UNUSED, 1861 char opcode_in ATTRIBUTE_UNUSED, const char * args) 1862{ 1863 expressionS op; 1864 const char * p; 1865 char prefix, opcode; 1866 1867 p = parse_exp_not_indexed (args, &op); 1868 p = skip_space (p); 1869 if (*p++ != ',') 1870 { 1871 error (_("bad instruction syntax")); 1872 return p; 1873 } 1874 1875 prefix = opcode = 0; 1876 if (op.X_op == O_register) 1877 switch (op.X_add_number | (op.X_md ? 0x8000 : 0)) 1878 { 1879 case REG_AF: 1880 if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f') 1881 { 1882 /* The scrubber changes '\'' to '`' in this context. */ 1883 if (*p == '`') 1884 ++p; 1885 opcode = 0x08; 1886 } 1887 break; 1888 case REG_DE: 1889 if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l') 1890 opcode = 0xEB; 1891 break; 1892 case REG_SP|0x8000: 1893 p = parse_exp (p, & op); 1894 if (op.X_op == O_register 1895 && op.X_md == 0 1896 && (op.X_add_number & ~R_INDEX) == REG_HL) 1897 { 1898 opcode = 0xE3; 1899 if (R_INDEX & op.X_add_number) 1900 prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD; 1901 } 1902 break; 1903 } 1904 if (opcode) 1905 emit_insn (prefix, opcode, p); 1906 else 1907 ill_op (); 1908 1909 return p; 1910} 1911 1912static const char * 1913emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED, 1914 const char * args) 1915{ 1916 expressionS reg, port; 1917 const char *p; 1918 char *q; 1919 1920 p = parse_exp (args, ®); 1921 if (reg.X_md && reg.X_op == O_register && reg.X_add_number == REG_C) 1922 { /* permit instruction in (c) as alias for in f,(c) */ 1923 port = reg; 1924 reg.X_md = 0; 1925 reg.X_add_number = REG_F; 1926 } 1927 else 1928 { 1929 if (*p++ != ',') 1930 { 1931 error (_("bad instruction syntax")); 1932 return p; 1933 } 1934 p = parse_exp (p, &port); 1935 } 1936 if (reg.X_md == 0 1937 && reg.X_op == O_register 1938 && (reg.X_add_number <= 7 || reg.X_add_number == REG_F) 1939 && (port.X_md)) 1940 { 1941 if (port.X_op != O_md1 && port.X_op != O_register) 1942 { 1943 if (REG_A == reg.X_add_number) 1944 { 1945 q = frag_more (1); 1946 *q = 0xDB; 1947 emit_byte (&port, BFD_RELOC_8); 1948 } 1949 else 1950 ill_op (); 1951 } 1952 else 1953 { 1954 if (port.X_add_number == REG_C || port.X_add_number == REG_BC) 1955 { 1956 if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80)) 1957 ill_op (); 1958 else if (reg.X_add_number == REG_F && !(ins_ok & (INS_R800|INS_Z80N))) 1959 check_mach (INS_IN_F_C); 1960 q = frag_more (2); 1961 *q++ = 0xED; 1962 *q = 0x40|((reg.X_add_number&7)<<3); 1963 } 1964 else 1965 ill_op (); 1966 } 1967 } 1968 else 1969 ill_op (); 1970 return p; 1971} 1972 1973static const char * 1974emit_in0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED, 1975 const char * args) 1976{ 1977 expressionS reg, port; 1978 const char *p; 1979 char *q; 1980 1981 p = parse_exp (args, ®); 1982 if (*p++ != ',') 1983 { 1984 error (_("bad instruction syntax")); 1985 return p; 1986 } 1987 1988 p = parse_exp (p, &port); 1989 if (reg.X_md == 0 1990 && reg.X_op == O_register 1991 && reg.X_add_number <= 7 1992 && port.X_md 1993 && port.X_op != O_md1 1994 && port.X_op != O_register) 1995 { 1996 q = frag_more (2); 1997 *q++ = 0xED; 1998 *q = 0x00|(reg.X_add_number << 3); 1999 emit_byte (&port, BFD_RELOC_8); 2000 } 2001 else 2002 ill_op (); 2003 return p; 2004} 2005 2006static const char * 2007emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED, 2008 const char * args) 2009{ 2010 expressionS reg, port; 2011 const char *p; 2012 char *q; 2013 2014 p = parse_exp (args, & port); 2015 if (*p++ != ',') 2016 { 2017 error (_("bad instruction syntax")); 2018 return p; 2019 } 2020 p = parse_exp (p, ®); 2021 if (!port.X_md) 2022 { ill_op (); return p; } 2023 /* Allow "out (c), 0" as unportable instruction. */ 2024 if (reg.X_op == O_constant && reg.X_add_number == 0) 2025 { 2026 if (!(ins_ok & INS_Z80N)) 2027 check_mach (INS_OUT_C_0); 2028 reg.X_op = O_register; 2029 reg.X_add_number = 6; 2030 } 2031 if (reg.X_md 2032 || reg.X_op != O_register 2033 || reg.X_add_number > 7) 2034 ill_op (); 2035 else 2036 if (port.X_op != O_register && port.X_op != O_md1) 2037 { 2038 if (REG_A == reg.X_add_number) 2039 { 2040 q = frag_more (1); 2041 *q = 0xD3; 2042 emit_byte (&port, BFD_RELOC_8); 2043 } 2044 else 2045 ill_op (); 2046 } 2047 else 2048 { 2049 if (REG_C == port.X_add_number || port.X_add_number == REG_BC) 2050 { 2051 if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80)) 2052 ill_op (); 2053 q = frag_more (2); 2054 *q++ = 0xED; 2055 *q = 0x41 | (reg.X_add_number << 3); 2056 } 2057 else 2058 ill_op (); 2059 } 2060 return p; 2061} 2062 2063static const char * 2064emit_out0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED, 2065 const char * args) 2066{ 2067 expressionS reg, port; 2068 const char *p; 2069 char *q; 2070 2071 p = parse_exp (args, & port); 2072 if (*p++ != ',') 2073 { 2074 error (_("bad instruction syntax")); 2075 return p; 2076 } 2077 p = parse_exp (p, ®); 2078 if (port.X_md != 0 2079 && port.X_op != O_register 2080 && port.X_op != O_md1 2081 && reg.X_md == 0 2082 && reg.X_op == O_register 2083 && reg.X_add_number <= 7) 2084 { 2085 q = frag_more (2); 2086 *q++ = 0xED; 2087 *q = 0x01 | (reg.X_add_number << 3); 2088 emit_byte (&port, BFD_RELOC_8); 2089 } 2090 else 2091 ill_op (); 2092 return p; 2093} 2094 2095static const char * 2096emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 2097{ 2098 expressionS addr; 2099 const char *p; 2100 char *q; 2101 2102 p = parse_exp_not_indexed (args, &addr); 2103 if (addr.X_op != O_constant) 2104 { 2105 error ("rst needs constant address"); 2106 return p; 2107 } 2108 2109 if (addr.X_add_number & ~(7 << 3)) 2110 ill_op (); 2111 else 2112 { 2113 q = frag_more (1); 2114 *q = opcode + (addr.X_add_number & (7 << 3)); 2115 } 2116 return p; 2117} 2118 2119/* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */ 2120static void 2121emit_ld_m_n (expressionS *dst, expressionS *src) 2122{ 2123 char *q; 2124 char prefix; 2125 expressionS dst_offset; 2126 2127 switch (dst->X_add_number) 2128 { 2129 case REG_HL: prefix = 0x00; break; 2130 case REG_IX: prefix = 0xDD; break; 2131 case REG_IY: prefix = 0xFD; break; 2132 default: 2133 ill_op (); 2134 return; 2135 } 2136 2137 q = frag_more (prefix ? 2 : 1); 2138 if (prefix) 2139 *q++ = prefix; 2140 *q = 0x36; 2141 if (prefix) 2142 { 2143 dst_offset = *dst; 2144 dst_offset.X_op = O_symbol; 2145 dst_offset.X_add_number = 0; 2146 emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8); 2147 } 2148 emit_byte (src, BFD_RELOC_8); 2149} 2150 2151/* For 8-bit load register to memory instructions: LD (<expression>),r. */ 2152static void 2153emit_ld_m_r (expressionS *dst, expressionS *src) 2154{ 2155 char *q; 2156 char prefix = 0; 2157 expressionS dst_offset; 2158 2159 switch (dst->X_op) 2160 { 2161 case O_md1: 2162 if (ins_ok & INS_GBZ80) 2163 { /* LD (HL+),A or LD (HL-),A */ 2164 if (src->X_op != O_register || src->X_add_number != REG_A) 2165 break; 2166 *frag_more (1) = (dst->X_add_number == REG_HL) ? 0x22 : 0x32; 2167 return; 2168 } 2169 else 2170 prefix = (dst->X_add_number == REG_IX) ? 0xDD : 0xFD; 2171 /* Fall through. */ 2172 case O_register: 2173 switch (dst->X_add_number) 2174 { 2175 case REG_BC: /* LD (BC),A */ 2176 case REG_DE: /* LD (DE),A */ 2177 if (src->X_add_number == REG_A) 2178 { 2179 q = frag_more (1); 2180 *q = 0x02 | ((dst->X_add_number & 3) << 4); 2181 return; 2182 } 2183 break; 2184 case REG_IX: 2185 case REG_IY: 2186 case REG_HL: /* LD (HL),r or LD (ii+d),r */ 2187 if (src->X_add_number <= 7) 2188 { 2189 q = frag_more (prefix ? 2 : 1); 2190 if (prefix) 2191 *q++ = prefix; 2192 *q = 0x70 | src->X_add_number; 2193 if (prefix) 2194 { 2195 dst_offset = *dst; 2196 dst_offset.X_op = O_symbol; 2197 dst_offset.X_add_number = 0; 2198 emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8); 2199 } 2200 return; 2201 } 2202 break; 2203 default:; 2204 } 2205 break; 2206 default: /* LD (nn),A */ 2207 if (src->X_add_number == REG_A) 2208 { 2209 q = frag_more (1); 2210 *q = (ins_ok & INS_GBZ80) ? 0xEA : 0x32; 2211 emit_word (dst); 2212 return; 2213 } 2214 break; 2215 } 2216 ill_op (); 2217} 2218 2219/* For 16-bit load register to memory instructions: LD (<expression>),rr. */ 2220static void 2221emit_ld_m_rr (expressionS *dst, expressionS *src) 2222{ 2223 char *q; 2224 int prefix = 0; 2225 int opcode = 0; 2226 expressionS dst_offset; 2227 2228 switch (dst->X_op) 2229 { 2230 case O_md1: /* eZ80 instructions LD (ii+d),rr */ 2231 case O_register: /* eZ80 instructions LD (HL),rr */ 2232 if (!(ins_ok & INS_EZ80)) /* 16-bit indirect load group is supported by eZ80 only */ 2233 ill_op (); 2234 switch (dst->X_add_number) 2235 { 2236 case REG_IX: prefix = 0xDD; break; 2237 case REG_IY: prefix = 0xFD; break; 2238 case REG_HL: prefix = 0xED; break; 2239 default: 2240 ill_op (); 2241 } 2242 switch (src->X_add_number) 2243 { 2244 case REG_BC: opcode = 0x0F; break; 2245 case REG_DE: opcode = 0x1F; break; 2246 case REG_HL: opcode = 0x2F; break; 2247 case REG_IX: opcode = (prefix != 0xFD) ? 0x3F : 0x3E; break; 2248 case REG_IY: opcode = (prefix != 0xFD) ? 0x3E : 0x3F; break; 2249 default: 2250 ill_op (); 2251 } 2252 q = frag_more (prefix ? 2 : 1); 2253 *q++ = prefix; 2254 *q = opcode; 2255 if (prefix == 0xFD || prefix == 0xDD) 2256 { 2257 dst_offset = *dst; 2258 dst_offset.X_op = O_symbol; 2259 dst_offset.X_add_number = 0; 2260 emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8); 2261 } 2262 break; 2263 default: /* LD (nn),rr */ 2264 if (ins_ok & INS_GBZ80) 2265 { 2266 /* GBZ80 supports only LD (nn),SP */ 2267 if (src->X_add_number == REG_SP) 2268 { 2269 prefix = 0x00; 2270 opcode = 0x08; 2271 } 2272 else 2273 ill_op (); 2274 } 2275 else 2276 { 2277 switch (src->X_add_number) 2278 { 2279 case REG_BC: prefix = 0xED; opcode = 0x43; break; 2280 case REG_DE: prefix = 0xED; opcode = 0x53; break; 2281 case REG_HL: prefix = 0x00; opcode = 0x22; break; 2282 case REG_IX: prefix = 0xDD; opcode = 0x22; break; 2283 case REG_IY: prefix = 0xFD; opcode = 0x22; break; 2284 case REG_SP: prefix = 0xED; opcode = 0x73; break; 2285 default: 2286 ill_op (); 2287 } 2288 } 2289 q = frag_more (prefix ? 2 : 1); 2290 if (prefix) 2291 *q++ = prefix; 2292 *q = opcode; 2293 emit_word (dst); 2294 } 2295} 2296 2297static void 2298emit_ld_r_m (expressionS *dst, expressionS *src) 2299{ /* for 8-bit memory load to register: LD r,(xxx) */ 2300 char *q; 2301 char prefix = 0; 2302 char opcode = 0; 2303 expressionS src_offset; 2304 2305 if (dst->X_add_number == REG_A && src->X_op == O_register) 2306 { /* LD A,(BC) or LD A,(DE) */ 2307 switch (src->X_add_number) 2308 { 2309 case REG_BC: opcode = 0x0A; break; 2310 case REG_DE: opcode = 0x1A; break; 2311 default: break; 2312 } 2313 if (opcode != 0) 2314 { 2315 q = frag_more (1); 2316 *q = opcode; 2317 return; 2318 } 2319 } 2320 2321 switch (src->X_op) 2322 { 2323 case O_md1: 2324 if (ins_ok & INS_GBZ80) 2325 { /* LD A,(HL+) or LD A,(HL-) */ 2326 if (dst->X_op == O_register && dst->X_add_number == REG_A) 2327 *frag_more (1) = (src->X_add_number == REG_HL) ? 0x2A : 0x3A; 2328 else 2329 ill_op (); 2330 break; 2331 } 2332 /* Fall through. */ 2333 case O_register: 2334 if (dst->X_add_number > 7) 2335 ill_op (); 2336 opcode = 0x46; /* LD B,(HL) */ 2337 switch (src->X_add_number) 2338 { 2339 case REG_HL: prefix = 0x00; break; 2340 case REG_IX: prefix = 0xDD; break; 2341 case REG_IY: prefix = 0xFD; break; 2342 default: 2343 ill_op (); 2344 } 2345 q = frag_more (prefix ? 2 : 1); 2346 if (prefix) 2347 *q++ = prefix; 2348 *q = opcode | ((dst->X_add_number & 7) << 3); 2349 if (prefix) 2350 { 2351 src_offset = *src; 2352 src_offset.X_op = O_symbol; 2353 src_offset.X_add_number = 0; 2354 emit_byte (& src_offset, BFD_RELOC_Z80_DISP8); 2355 } 2356 break; 2357 default: /* LD A,(nn) */ 2358 if (dst->X_add_number == REG_A) 2359 { 2360 q = frag_more (1); 2361 *q = (ins_ok & INS_GBZ80) ? 0xFA : 0x3A; 2362 emit_word (src); 2363 } 2364 } 2365} 2366 2367static void 2368emit_ld_r_n (expressionS *dst, expressionS *src) 2369{ /* for 8-bit immediate value load to register: LD r,n */ 2370 char *q; 2371 char prefix = 0; 2372 2373 switch (dst->X_add_number) 2374 { 2375 case REG_H|R_IX: 2376 case REG_L|R_IX: 2377 prefix = 0xDD; 2378 break; 2379 case REG_H|R_IY: 2380 case REG_L|R_IY: 2381 prefix = 0xFD; 2382 break; 2383 case REG_A: 2384 case REG_B: 2385 case REG_C: 2386 case REG_D: 2387 case REG_E: 2388 case REG_H: 2389 case REG_L: 2390 break; 2391 default: 2392 ill_op (); 2393 } 2394 2395 q = frag_more (prefix ? 2 : 1); 2396 if (prefix) 2397 { 2398 if (ins_ok & INS_GBZ80) 2399 ill_op (); 2400 else if (!(ins_ok & (INS_EZ80|INS_R800|INS_Z80N))) 2401 check_mach (INS_IDX_HALF); 2402 *q++ = prefix; 2403 } 2404 *q = 0x06 | ((dst->X_add_number & 7) << 3); 2405 emit_byte (src, BFD_RELOC_8); 2406} 2407 2408static void 2409emit_ld_r_r (expressionS *dst, expressionS *src) 2410{ /* mostly 8-bit load register from register instructions: LD r,r */ 2411 /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */ 2412 char *q; 2413 int prefix = 0; 2414 int opcode = 0; 2415 int ii_halves = 0; 2416 2417 switch (dst->X_add_number) 2418 { 2419 case REG_SP: 2420 switch (src->X_add_number) 2421 { 2422 case REG_HL: prefix = 0x00; break; 2423 case REG_IX: prefix = 0xDD; break; 2424 case REG_IY: prefix = 0xFD; break; 2425 default: 2426 ill_op (); 2427 } 2428 opcode = 0xF9; 2429 break; 2430 case REG_HL: 2431 if (!(ins_ok & INS_EZ80)) 2432 ill_op (); 2433 if (src->X_add_number != REG_I) 2434 ill_op (); 2435 if (cpu_mode < 1) 2436 error (_("ADL mode instruction")); 2437 /* LD HL,I */ 2438 prefix = 0xED; 2439 opcode = 0xD7; 2440 break; 2441 case REG_I: 2442 if (src->X_add_number == REG_HL) 2443 { 2444 if (!(ins_ok & INS_EZ80)) 2445 ill_op (); 2446 if (cpu_mode < 1) 2447 error (_("ADL mode instruction")); 2448 prefix = 0xED; 2449 opcode = 0xC7; 2450 } 2451 else if (src->X_add_number == REG_A) 2452 { 2453 prefix = 0xED; 2454 opcode = 0x47; 2455 } 2456 else 2457 ill_op (); 2458 break; 2459 case REG_MB: 2460 if (!(ins_ok & INS_EZ80) || (src->X_add_number != REG_A)) 2461 ill_op (); 2462 if (cpu_mode < 1) 2463 error (_("ADL mode instruction")); 2464 prefix = 0xED; 2465 opcode = 0x6D; 2466 break; 2467 case REG_R: 2468 if (src->X_add_number == REG_A) /* LD R,A */ 2469 { 2470 prefix = 0xED; 2471 opcode = 0x4F; 2472 } 2473 else 2474 ill_op (); 2475 break; 2476 case REG_A: 2477 if (src->X_add_number == REG_I) /* LD A,I */ 2478 { 2479 prefix = 0xED; 2480 opcode = 0x57; 2481 break; 2482 } 2483 else if (src->X_add_number == REG_R) /* LD A,R */ 2484 { 2485 prefix = 0xED; 2486 opcode = 0x5F; 2487 break; 2488 } 2489 else if (src->X_add_number == REG_MB) /* LD A,MB */ 2490 { 2491 if (!(ins_ok & INS_EZ80)) 2492 ill_op (); 2493 else 2494 { 2495 if (cpu_mode < 1) 2496 error (_("ADL mode instruction")); 2497 prefix = 0xED; 2498 opcode = 0x6E; 2499 } 2500 break; 2501 } 2502 /* Fall through. */ 2503 case REG_B: 2504 case REG_C: 2505 case REG_D: 2506 case REG_E: 2507 case REG_H: 2508 case REG_L: 2509 prefix = 0x00; 2510 break; 2511 case REG_H|R_IX: 2512 case REG_L|R_IX: 2513 prefix = 0xDD; 2514 ii_halves = 1; 2515 break; 2516 case REG_H|R_IY: 2517 case REG_L|R_IY: 2518 prefix = 0xFD; 2519 ii_halves = 1; 2520 break; 2521 default: 2522 ill_op (); 2523 } 2524 2525 if (opcode == 0) 2526 { 2527 switch (src->X_add_number) 2528 { 2529 case REG_A: 2530 case REG_B: 2531 case REG_C: 2532 case REG_D: 2533 case REG_E: 2534 break; 2535 case REG_H: 2536 case REG_L: 2537 if (prefix != 0) 2538 ill_op (); /* LD iiH/L,H/L are not permitted */ 2539 break; 2540 case REG_H|R_IX: 2541 case REG_L|R_IX: 2542 if (prefix == 0xFD || dst->X_add_number == REG_H || dst->X_add_number == REG_L) 2543 ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */ 2544 prefix = 0xDD; 2545 ii_halves = 1; 2546 break; 2547 case REG_H|R_IY: 2548 case REG_L|R_IY: 2549 if (prefix == 0xDD || dst->X_add_number == REG_H || dst->X_add_number == REG_L) 2550 ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */ 2551 prefix = 0xFD; 2552 ii_halves = 1; 2553 break; 2554 default: 2555 ill_op (); 2556 } 2557 opcode = 0x40 + ((dst->X_add_number & 7) << 3) + (src->X_add_number & 7); 2558 } 2559 if ((ins_ok & INS_GBZ80) && prefix != 0) 2560 ill_op (); 2561 if (ii_halves && !(ins_ok & (INS_EZ80|INS_R800|INS_Z80N))) 2562 check_mach (INS_IDX_HALF); 2563 if (prefix == 0 && (ins_ok & INS_EZ80)) 2564 { 2565 switch (opcode) 2566 { 2567 case 0x40: /* SIS prefix, in Z80 it is LD B,B */ 2568 case 0x49: /* LIS prefix, in Z80 it is LD C,C */ 2569 case 0x52: /* SIL prefix, in Z80 it is LD D,D */ 2570 case 0x5B: /* LIL prefix, in Z80 it is LD E,E */ 2571 as_warn (_("unsupported instruction, assembled as NOP")); 2572 opcode = 0x00; 2573 break; 2574 default:; 2575 } 2576 } 2577 q = frag_more (prefix ? 2 : 1); 2578 if (prefix) 2579 *q++ = prefix; 2580 *q = opcode; 2581} 2582 2583static void 2584emit_ld_rr_m (expressionS *dst, expressionS *src) 2585{ /* for 16-bit indirect load from memory to register: LD rr,(xxx) */ 2586 char *q; 2587 int prefix = 0; 2588 int opcode = 0; 2589 expressionS src_offset; 2590 2591 /* GBZ80 has no support for 16-bit load from memory instructions */ 2592 if (ins_ok & INS_GBZ80) 2593 ill_op (); 2594 2595 prefix = 0xED; 2596 switch (src->X_op) 2597 { 2598 case O_md1: /* LD rr,(ii+d) */ 2599 prefix = (src->X_add_number == REG_IX) ? 0xDD : 0xFD; 2600 /* Fall through. */ 2601 case O_register: /* LD rr,(HL) */ 2602 /* currently only EZ80 has support for 16bit indirect memory load instructions */ 2603 if (!(ins_ok & INS_EZ80)) 2604 ill_op (); 2605 switch (dst->X_add_number) 2606 { 2607 case REG_BC: opcode = 0x07; break; 2608 case REG_DE: opcode = 0x17; break; 2609 case REG_HL: opcode = 0x27; break; 2610 case REG_IX: opcode = (prefix == 0xED || prefix == 0xDD) ? 0x37 : 0x31; break; 2611 case REG_IY: opcode = (prefix == 0xED || prefix == 0xDD) ? 0x31 : 0x37; break; 2612 default: 2613 ill_op (); 2614 } 2615 q = frag_more (2); 2616 *q++ = prefix; 2617 *q = opcode; 2618 if (prefix != 0xED) 2619 { 2620 src_offset = *src; 2621 src_offset.X_op = O_symbol; 2622 src_offset.X_add_number = 0; 2623 emit_byte (& src_offset, BFD_RELOC_Z80_DISP8); 2624 } 2625 break; 2626 default: /* LD rr,(nn) */ 2627 switch (dst->X_add_number) 2628 { 2629 case REG_BC: prefix = 0xED; opcode = 0x4B; break; 2630 case REG_DE: prefix = 0xED; opcode = 0x5B; break; 2631 case REG_HL: prefix = 0x00; opcode = 0x2A; break; 2632 case REG_SP: prefix = 0xED; opcode = 0x7B; break; 2633 case REG_IX: prefix = 0xDD; opcode = 0x2A; break; 2634 case REG_IY: prefix = 0xFD; opcode = 0x2A; break; 2635 default: 2636 ill_op (); 2637 } 2638 q = frag_more (prefix ? 2 : 1); 2639 if (prefix) 2640 *q++ = prefix; 2641 *q = opcode; 2642 emit_word (src); 2643 } 2644 return; 2645} 2646 2647static void 2648emit_ld_rr_nn (expressionS *dst, expressionS *src) 2649{ /* mostly load imediate value to multibyte register instructions: LD rr,nn */ 2650 char *q; 2651 int prefix = 0x00; 2652 int opcode = 0x21; /* LD HL,nn */ 2653 switch (dst->X_add_number) 2654 { 2655 case REG_IX: 2656 prefix = 0xDD; 2657 break; 2658 case REG_IY: 2659 prefix = 0xFD; 2660 break; 2661 case REG_HL: 2662 break; 2663 case REG_BC: 2664 case REG_DE: 2665 case REG_SP: 2666 opcode = 0x01 + ((dst->X_add_number & 3) << 4); 2667 break; 2668 default: 2669 ill_op (); 2670 return; 2671 } 2672 if (prefix && (ins_ok & INS_GBZ80)) 2673 ill_op (); 2674 q = frag_more (prefix ? 2 : 1); 2675 if (prefix) 2676 *q++ = prefix; 2677 *q = opcode; 2678 emit_word (src); 2679} 2680 2681static const char * 2682emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED, 2683 const char * args) 2684{ 2685 expressionS dst, src; 2686 const char *p; 2687 2688 p = parse_exp (args, & dst); 2689 if (*p++ != ',') 2690 error (_("bad instruction syntax")); 2691 p = parse_exp (p, & src); 2692 2693 if (dst.X_md) 2694 { 2695 if (src.X_op == O_register) 2696 { 2697 if (src.X_add_number <= 7) 2698 emit_ld_m_r (& dst, & src); /* LD (xxx),r */ 2699 else 2700 emit_ld_m_rr (& dst, & src); /* LD (xxx),rr */ 2701 } 2702 else 2703 emit_ld_m_n (& dst, & src); /* LD (hl),n or LD (ix/y+r),n */ 2704 } 2705 else if (dst.X_op == O_register) 2706 { 2707 if (src.X_md) 2708 { 2709 if (dst.X_add_number <= 7) 2710 emit_ld_r_m (& dst, & src); 2711 else 2712 emit_ld_rr_m (& dst, & src); 2713 } 2714 else if (src.X_op == O_register) 2715 emit_ld_r_r (& dst, & src); 2716 else if ((dst.X_add_number & ~R_INDEX) <= 7) 2717 emit_ld_r_n (& dst, & src); 2718 else 2719 emit_ld_rr_nn (& dst, & src); 2720 } 2721 else 2722 ill_op (); 2723 2724 return p; 2725} 2726 2727static const char * 2728emit_lddldi (char prefix, char opcode, const char * args) 2729{ 2730 expressionS dst, src; 2731 const char *p; 2732 char *q; 2733 2734 if (!(ins_ok & INS_GBZ80)) 2735 return emit_insn (prefix, opcode, args); 2736 2737 p = parse_exp (args, & dst); 2738 if (*p++ != ',') 2739 error (_("bad instruction syntax")); 2740 p = parse_exp (p, & src); 2741 2742 if (dst.X_op != O_register || src.X_op != O_register) 2743 ill_op (); 2744 2745 /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */ 2746 opcode = (opcode & 0x08) * 2 + 0x22; 2747 2748 if (dst.X_md != 0 2749 && dst.X_add_number == REG_HL 2750 && src.X_md == 0 2751 && src.X_add_number == REG_A) 2752 opcode |= 0x00; /* LDx (HL),A */ 2753 else if (dst.X_md == 0 2754 && dst.X_add_number == REG_A 2755 && src.X_md != 0 2756 && src.X_add_number == REG_HL) 2757 opcode |= 0x08; /* LDx A,(HL) */ 2758 else 2759 ill_op (); 2760 2761 q = frag_more (1); 2762 *q = opcode; 2763 return p; 2764} 2765 2766static const char * 2767emit_ldh (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED, 2768 const char * args) 2769{ 2770 expressionS dst, src; 2771 const char *p; 2772 char *q; 2773 2774 p = parse_exp (args, & dst); 2775 if (*p++ != ',') 2776 { 2777 error (_("bad instruction syntax")); 2778 return p; 2779 } 2780 2781 p = parse_exp (p, & src); 2782 if (dst.X_md == 0 2783 && dst.X_op == O_register 2784 && dst.X_add_number == REG_A 2785 && src.X_md != 0 2786 && src.X_op != O_md1) 2787 { 2788 if (src.X_op != O_register) 2789 { 2790 q = frag_more (1); 2791 *q = 0xF0; 2792 emit_byte (& src, BFD_RELOC_8); 2793 } 2794 else if (src.X_add_number == REG_C) 2795 *frag_more (1) = 0xF2; 2796 else 2797 ill_op (); 2798 } 2799 else if (dst.X_md != 0 2800 && dst.X_op != O_md1 2801 && src.X_md == 0 2802 && src.X_op == O_register 2803 && src.X_add_number == REG_A) 2804 { 2805 if (dst.X_op == O_register) 2806 { 2807 if (dst.X_add_number == REG_C) 2808 { 2809 q = frag_more (1); 2810 *q = 0xE2; 2811 } 2812 else 2813 ill_op (); 2814 } 2815 else 2816 { 2817 q = frag_more (1); 2818 *q = 0xE0; 2819 emit_byte (& dst, BFD_RELOC_8); 2820 } 2821 } 2822 else 2823 ill_op (); 2824 2825 return p; 2826} 2827 2828static const char * 2829emit_ldhl (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 2830{ 2831 expressionS dst, src; 2832 const char *p; 2833 char *q; 2834 p = parse_exp (args, & dst); 2835 if (*p++ != ',') 2836 { 2837 error (_("bad instruction syntax")); 2838 return p; 2839 } 2840 2841 p = parse_exp (p, & src); 2842 if (dst.X_md || dst.X_op != O_register || dst.X_add_number != REG_SP 2843 || src.X_md || src.X_op == O_register || src.X_op == O_md1) 2844 ill_op (); 2845 q = frag_more (1); 2846 *q = opcode; 2847 emit_byte (& src, BFD_RELOC_Z80_DISP8); 2848 return p; 2849} 2850 2851static const char * 2852parse_lea_pea_args (const char * args, expressionS *op) 2853{ 2854 const char *p; 2855 p = parse_exp (args, op); 2856 if (sdcc_compat && *p == ',' && op->X_op == O_register) 2857 { 2858 expressionS off; 2859 p = parse_exp (p + 1, &off); 2860 op->X_op = O_add; 2861 op->X_add_symbol = make_expr_symbol (&off); 2862 } 2863 return p; 2864} 2865 2866static const char * 2867emit_lea (char prefix, char opcode, const char * args) 2868{ 2869 expressionS dst, src; 2870 const char *p; 2871 char *q; 2872 int rnum; 2873 2874 p = parse_exp (args, & dst); 2875 if (dst.X_md != 0 || dst.X_op != O_register) 2876 ill_op (); 2877 2878 rnum = dst.X_add_number; 2879 switch (rnum) 2880 { 2881 case REG_BC: 2882 case REG_DE: 2883 case REG_HL: 2884 opcode = 0x02 | ((rnum & 0x03) << 4); 2885 break; 2886 case REG_IX: 2887 opcode = 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */ 2888 break; 2889 case REG_IY: 2890 opcode = 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */ 2891 break; 2892 default: 2893 ill_op (); 2894 } 2895 2896 if (*p++ != ',') 2897 error (_("bad instruction syntax")); 2898 2899 p = parse_lea_pea_args (p, & src); 2900 if (src.X_md != 0 || src.X_op != O_add /*&& src.X_op != O_register*/) 2901 ill_op (); 2902 2903 rnum = src.X_add_number; 2904 switch (src.X_op) 2905 { 2906 case O_add: 2907 break; 2908 case O_register: /* permit instructions like LEA rr,IX without displacement specified */ 2909 src.X_add_symbol = zero; 2910 break; 2911 default: 2912 ill_op (); 2913 } 2914 2915 switch (rnum) 2916 { 2917 case REG_IX: 2918 opcode = (opcode == (char)0x33) ? 0x55 : (opcode|0x00); 2919 break; 2920 case REG_IY: 2921 opcode = (opcode == (char)0x32) ? 0x54 : (opcode|0x01); 2922 } 2923 2924 q = frag_more (2); 2925 *q++ = prefix; 2926 *q = opcode; 2927 2928 src.X_op = O_symbol; 2929 src.X_add_number = 0; 2930 emit_byte (& src, BFD_RELOC_Z80_DISP8); 2931 2932 return p; 2933} 2934 2935static const char * 2936emit_mlt (char prefix, char opcode, const char * args) 2937{ 2938 expressionS arg; 2939 const char *p; 2940 char *q; 2941 2942 p = parse_exp (args, & arg); 2943 if (arg.X_md != 0 || arg.X_op != O_register || !(arg.X_add_number & R_ARITH)) 2944 ill_op (); 2945 2946 q = frag_more (2); 2947 if (ins_ok & INS_Z80N) 2948 { 2949 if (arg.X_add_number != REG_DE) 2950 ill_op (); 2951 *q++ = 0xED; 2952 *q = 0x30; 2953 } 2954 else 2955 { 2956 *q++ = prefix; 2957 *q = opcode | ((arg.X_add_number & 3) << 4); 2958 } 2959 2960 return p; 2961} 2962 2963/* MUL D,E (Z80N only) */ 2964static const char * 2965emit_mul (char prefix, char opcode, const char * args) 2966{ 2967 expressionS r1, r2; 2968 const char *p; 2969 char *q; 2970 2971 p = parse_exp (args, & r1); 2972 if (*p++ != ',') 2973 error (_("bad instruction syntax")); 2974 p = parse_exp (p, & r2); 2975 2976 if (r1.X_md != 0 || r1.X_op != O_register || r1.X_add_number != REG_D || 2977 r2.X_md != 0 || r2.X_op != O_register || r2.X_add_number != REG_E) 2978 ill_op (); 2979 2980 q = frag_more (2); 2981 *q++ = prefix; 2982 *q = opcode; 2983 2984 return p; 2985} 2986 2987static const char * 2988emit_nextreg (char prefix, char opcode ATTRIBUTE_UNUSED, const char * args) 2989{ 2990 expressionS rr, nn; 2991 const char *p; 2992 char *q; 2993 2994 p = parse_exp (args, & rr); 2995 if (*p++ != ',') 2996 error (_("bad instruction syntax")); 2997 p = parse_exp (p, & nn); 2998 if (rr.X_md != 0 || rr.X_op == O_register || rr.X_op == O_md1 || 2999 nn.X_md != 0 || nn.X_op == O_md1) 3000 ill_op (); 3001 q = frag_more (2); 3002 *q++ = prefix; 3003 emit_byte (&rr, BFD_RELOC_8); 3004 if (nn.X_op == O_register && nn.X_add_number == REG_A) 3005 *q = 0x92; 3006 else if (nn.X_op != O_register) 3007 { 3008 *q = 0x91; 3009 emit_byte (&nn, BFD_RELOC_8); 3010 } 3011 else 3012 ill_op (); 3013 return p; 3014} 3015 3016static const char * 3017emit_pea (char prefix, char opcode, const char * args) 3018{ 3019 expressionS arg; 3020 const char *p; 3021 char *q; 3022 3023 p = parse_lea_pea_args (args, & arg); 3024 if (arg.X_md != 0 3025 || (/*arg.X_op != O_register &&*/ arg.X_op != O_add) 3026 || !(arg.X_add_number & R_INDEX)) 3027 ill_op (); 3028 /* PEA ii without displacement is mostly typo, 3029 because there is PUSH instruction which is shorter and faster */ 3030 /*if (arg.X_op == O_register) 3031 as_warn (_("PEA is used without displacement, use PUSH instead"));*/ 3032 3033 q = frag_more (2); 3034 *q++ = prefix; 3035 *q = opcode + (arg.X_add_number == REG_IY ? 1 : 0); 3036 3037 arg.X_op = O_symbol; 3038 arg.X_add_number = 0; 3039 emit_byte (& arg, BFD_RELOC_Z80_DISP8); 3040 3041 return p; 3042} 3043 3044static const char * 3045emit_reti (char prefix, char opcode, const char * args) 3046{ 3047 if (ins_ok & INS_GBZ80) 3048 return emit_insn (0x00, 0xD9, args); 3049 3050 return emit_insn (prefix, opcode, args); 3051} 3052 3053static const char * 3054emit_tst (char prefix, char opcode, const char *args) 3055{ 3056 expressionS arg_s; 3057 const char *p; 3058 char *q; 3059 int rnum; 3060 3061 p = parse_exp (args, & arg_s); 3062 if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A) 3063 { 3064 if (!(ins_ok & INS_EZ80)) 3065 ill_op (); 3066 ++p; 3067 p = parse_exp (p, & arg_s); 3068 } 3069 3070 rnum = arg_s.X_add_number; 3071 switch (arg_s.X_op) 3072 { 3073 case O_md1: 3074 ill_op (); 3075 break; 3076 case O_register: 3077 rnum = arg_s.X_add_number; 3078 if (arg_s.X_md != 0) 3079 { 3080 if (rnum != REG_HL) 3081 ill_op (); 3082 else 3083 rnum = 6; 3084 } 3085 q = frag_more (2); 3086 *q++ = prefix; 3087 *q = opcode | (rnum << 3); 3088 break; 3089 default: 3090 if (arg_s.X_md) 3091 ill_op (); 3092 q = frag_more (2); 3093 if (ins_ok & INS_Z80N) 3094 { 3095 *q++ = 0xED; 3096 *q = 0x27; 3097 } 3098 else 3099 { 3100 *q++ = prefix; 3101 *q = opcode | 0x60; 3102 } 3103 emit_byte (& arg_s, BFD_RELOC_8); 3104 } 3105 return p; 3106} 3107 3108static const char * 3109emit_insn_n (char prefix, char opcode, const char *args) 3110{ 3111 expressionS arg; 3112 const char *p; 3113 char *q; 3114 3115 p = parse_exp (args, & arg); 3116 if (arg.X_md || arg.X_op == O_register || arg.X_op == O_md1) 3117 ill_op (); 3118 3119 q = frag_more (2); 3120 *q++ = prefix; 3121 *q = opcode; 3122 emit_byte (& arg, BFD_RELOC_8); 3123 3124 return p; 3125} 3126 3127static void 3128emit_data (int size ATTRIBUTE_UNUSED) 3129{ 3130 const char *p, *q; 3131 char *u, quote; 3132 int cnt; 3133 expressionS exp; 3134 3135 if (is_it_end_of_statement ()) 3136 { 3137 demand_empty_rest_of_line (); 3138 return; 3139 } 3140 p = skip_space (input_line_pointer); 3141 3142 do 3143 { 3144 if (*p == '\"' || *p == '\'') 3145 { 3146 for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt) 3147 ; 3148 u = frag_more (cnt); 3149 memcpy (u, q, cnt); 3150 if (!*p) 3151 as_warn (_("unterminated string")); 3152 else 3153 p = skip_space (p+1); 3154 } 3155 else 3156 { 3157 p = parse_exp (p, &exp); 3158 if (exp.X_op == O_md1 || exp.X_op == O_register) 3159 { 3160 ill_op (); 3161 break; 3162 } 3163 if (exp.X_md) 3164 as_warn (_("parentheses ignored")); 3165 emit_byte (&exp, BFD_RELOC_8); 3166 p = skip_space (p); 3167 } 3168 } 3169 while (*p++ == ',') ; 3170 input_line_pointer = (char *)(p-1); 3171} 3172 3173static void 3174z80_cons (int size) 3175{ 3176 const char *p; 3177 expressionS exp; 3178 3179 if (is_it_end_of_statement ()) 3180 { 3181 demand_empty_rest_of_line (); 3182 return; 3183 } 3184 p = skip_space (input_line_pointer); 3185 3186 do 3187 { 3188 p = parse_exp (p, &exp); 3189 if (exp.X_op == O_md1 || exp.X_op == O_register) 3190 { 3191 ill_op (); 3192 break; 3193 } 3194 if (exp.X_md) 3195 as_warn (_("parentheses ignored")); 3196 emit_data_val (&exp, size); 3197 p = skip_space (p); 3198 } while (*p++ == ',') ; 3199 input_line_pointer = (char *)(p-1); 3200} 3201 3202/* next functions were commented out because it is difficult to mix 3203 both ADL and Z80 mode instructions within one COFF file: 3204 objdump cannot recognize point of mode switching. 3205*/ 3206static void 3207set_cpu_mode (int mode) 3208{ 3209 if (ins_ok & INS_EZ80) 3210 cpu_mode = mode; 3211 else 3212 error (_("CPU mode is unsupported by target")); 3213} 3214 3215static void 3216assume (int arg ATTRIBUTE_UNUSED) 3217{ 3218 char *name; 3219 char c; 3220 int n; 3221 3222 input_line_pointer = (char*)skip_space (input_line_pointer); 3223 c = get_symbol_name (& name); 3224 if (strncasecmp (name, "ADL", 4) != 0) 3225 { 3226 ill_op (); 3227 return; 3228 } 3229 3230 restore_line_pointer (c); 3231 input_line_pointer = (char*)skip_space (input_line_pointer); 3232 if (*input_line_pointer++ != '=') 3233 { 3234 error (_("assignment expected")); 3235 return; 3236 } 3237 input_line_pointer = (char*)skip_space (input_line_pointer); 3238 n = get_single_number (); 3239 3240 set_cpu_mode (n); 3241} 3242 3243static const char * 3244emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 3245{ 3246 const char *p; 3247 3248 p = skip_space (args); 3249 if (TOLOWER (*p++) != 'a' || *p++ != ',') 3250 ill_op (); 3251 else 3252 { 3253 char *q, reg; 3254 3255 reg = TOLOWER (*p++); 3256 switch (reg) 3257 { 3258 case 'b': 3259 case 'c': 3260 case 'd': 3261 case 'e': 3262 check_mach (INS_R800); 3263 if (!*skip_space (p)) 3264 { 3265 q = frag_more (2); 3266 *q++ = prefix; 3267 *q = opcode + ((reg - 'b') << 3); 3268 break; 3269 } 3270 /* Fall through. */ 3271 default: 3272 ill_op (); 3273 } 3274 } 3275 return p; 3276} 3277 3278static const char * 3279emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args) 3280{ 3281 const char *p; 3282 3283 p = skip_space (args); 3284 if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',') 3285 ill_op (); 3286 else 3287 { 3288 expressionS reg; 3289 char *q; 3290 3291 p = parse_exp (p, & reg); 3292 3293 if ((!reg.X_md) && reg.X_op == O_register) 3294 switch (reg.X_add_number) 3295 { 3296 case REG_BC: 3297 case REG_SP: 3298 check_mach (INS_R800); 3299 q = frag_more (2); 3300 *q++ = prefix; 3301 *q = opcode + ((reg.X_add_number & 3) << 4); 3302 break; 3303 default: 3304 ill_op (); 3305 } 3306 } 3307 return p; 3308} 3309 3310static int 3311assemble_suffix (const char **suffix) 3312{ 3313 static 3314 const char sf[8][4] = 3315 { 3316 "il", 3317 "is", 3318 "l", 3319 "lil", 3320 "lis", 3321 "s", 3322 "sil", 3323 "sis" 3324 }; 3325 const char *p; 3326 const char (*t)[4]; 3327 char sbuf[4]; 3328 int i; 3329 3330 p = *suffix; 3331 if (*p++ != '.') 3332 return 0; 3333 3334 for (i = 0; (i < 3) && (ISALPHA (*p)); i++) 3335 sbuf[i] = TOLOWER (*p++); 3336 if (*p && !ISSPACE (*p)) 3337 return 0; 3338 *suffix = p; 3339 sbuf[i] = 0; 3340 3341 t = bsearch (sbuf, sf, ARRAY_SIZE (sf), sizeof (sf[0]), (int(*)(const void*, const void*)) strcmp); 3342 if (t == NULL) 3343 return 0; 3344 i = t - sf; 3345 switch (i) 3346 { 3347 case 0: /* IL */ 3348 i = cpu_mode ? 0x5B : 0x52; 3349 break; 3350 case 1: /* IS */ 3351 i = cpu_mode ? 0x49 : 0x40; 3352 break; 3353 case 2: /* L */ 3354 i = cpu_mode ? 0x5B : 0x49; 3355 break; 3356 case 3: /* LIL */ 3357 i = 0x5B; 3358 break; 3359 case 4: /* LIS */ 3360 i = 0x49; 3361 break; 3362 case 5: /* S */ 3363 i = cpu_mode ? 0x52 : 0x40; 3364 break; 3365 case 6: /* SIL */ 3366 i = 0x52; 3367 break; 3368 case 7: /* SIS */ 3369 i = 0x40; 3370 break; 3371 } 3372 *frag_more (1) = (char)i; 3373 switch (i) 3374 { 3375 case 0x40: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IS; break; 3376 case 0x49: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IS; break; 3377 case 0x52: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IL; break; 3378 case 0x5B: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IL; break; 3379 } 3380 return 1; 3381} 3382 3383static void 3384psect (int arg) 3385{ 3386#if defined(OBJ_ELF) 3387 return obj_elf_section (arg); 3388#elif defined(OBJ_COFF) 3389 return obj_coff_section (arg); 3390#else 3391#error Unknown object format 3392#endif 3393} 3394 3395static void 3396set_inss (int inss) 3397{ 3398 int old_ins; 3399 3400 if (!sdcc_compat) 3401 as_fatal (_("Invalid directive")); 3402 3403 old_ins = ins_ok; 3404 ins_ok &= INS_MARCH_MASK; 3405 ins_ok |= inss; 3406 if (old_ins != ins_ok) 3407 cpu_mode = 0; 3408} 3409 3410static void 3411ignore (int arg ATTRIBUTE_UNUSED) 3412{ 3413 ignore_rest_of_line (); 3414} 3415 3416static void 3417area (int arg) 3418{ 3419 char *p; 3420 if (!sdcc_compat) 3421 as_fatal (_("Invalid directive")); 3422 for (p = input_line_pointer; *p && *p != '(' && *p != '\n'; p++) 3423 ; 3424 if (*p == '(') 3425 { 3426 *p = '\n'; 3427 psect (arg); 3428 *p++ = '('; 3429 ignore_rest_of_line (); 3430 } 3431 else 3432 psect (arg); 3433} 3434 3435/* Port specific pseudo ops. */ 3436const pseudo_typeS md_pseudo_table[] = 3437{ 3438 { ".area", area, 0}, 3439 { ".assume", assume, 0}, 3440 { ".ez80", set_inss, INS_EZ80}, 3441 { ".gbz80", set_inss, INS_GBZ80}, 3442 { ".module", ignore, 0}, 3443 { ".optsdcc", ignore, 0}, 3444 { ".r800", set_inss, INS_R800}, 3445 { ".set", s_set, 0}, 3446 { ".z180", set_inss, INS_Z180}, 3447 { ".z80", set_inss, INS_Z80}, 3448 { ".z80n", set_inss, INS_Z80N}, 3449 { "db" , emit_data, 1}, 3450 { "d24", z80_cons, 3}, 3451 { "d32", z80_cons, 4}, 3452 { "def24", z80_cons, 3}, 3453 { "def32", z80_cons, 4}, 3454 { "defb", emit_data, 1}, 3455 { "defm", emit_data, 1}, 3456 { "defs", s_space, 1}, /* Synonym for ds on some assemblers. */ 3457 { "defw", z80_cons, 2}, 3458 { "ds", s_space, 1}, /* Fill with bytes rather than words. */ 3459 { "dw", z80_cons, 2}, 3460 { "psect", psect, 0}, /* TODO: Translate attributes. */ 3461 { "set", 0, 0}, /* Real instruction on z80. */ 3462 { "xdef", s_globl, 0}, /* Synonym for .GLOBAL */ 3463 { "xref", s_ignore, 0}, /* Synonym for .EXTERN */ 3464 { NULL, 0, 0 } 3465} ; 3466 3467static table_t instab[] = 3468{ 3469 { "adc", 0x88, 0x4A, emit_adc, INS_ALL }, 3470 { "add", 0x80, 0x09, emit_add, INS_ALL }, 3471 { "and", 0x00, 0xA0, emit_s, INS_ALL }, 3472 { "bit", 0xCB, 0x40, emit_bit, INS_ALL }, 3473 { "brlc", 0xED, 0x2C, emit_bshft,INS_Z80N }, 3474 { "bsla", 0xED, 0x28, emit_bshft,INS_Z80N }, 3475 { "bsra", 0xED, 0x29, emit_bshft,INS_Z80N }, 3476 { "bsrf", 0xED, 0x2B, emit_bshft,INS_Z80N }, 3477 { "bsrl", 0xED, 0x2A, emit_bshft,INS_Z80N }, 3478 { "call", 0xCD, 0xC4, emit_jpcc, INS_ALL }, 3479 { "ccf", 0x00, 0x3F, emit_insn, INS_ALL }, 3480 { "cp", 0x00, 0xB8, emit_s, INS_ALL }, 3481 { "cpd", 0xED, 0xA9, emit_insn, INS_NOT_GBZ80 }, 3482 { "cpdr", 0xED, 0xB9, emit_insn, INS_NOT_GBZ80 }, 3483 { "cpi", 0xED, 0xA1, emit_insn, INS_NOT_GBZ80 }, 3484 { "cpir", 0xED, 0xB1, emit_insn, INS_NOT_GBZ80 }, 3485 { "cpl", 0x00, 0x2F, emit_insn, INS_ALL }, 3486 { "daa", 0x00, 0x27, emit_insn, INS_ALL }, 3487 { "dec", 0x0B, 0x05, emit_incdec,INS_ALL }, 3488 { "di", 0x00, 0xF3, emit_insn, INS_ALL }, 3489 { "djnz", 0x00, 0x10, emit_jr, INS_NOT_GBZ80 }, 3490 { "ei", 0x00, 0xFB, emit_insn, INS_ALL }, 3491 { "ex", 0x00, 0x00, emit_ex, INS_NOT_GBZ80 }, 3492 { "exx", 0x00, 0xD9, emit_insn, INS_NOT_GBZ80 }, 3493 { "halt", 0x00, 0x76, emit_insn, INS_ALL }, 3494 { "im", 0xED, 0x46, emit_im, INS_NOT_GBZ80 }, 3495 { "in", 0x00, 0x00, emit_in, INS_NOT_GBZ80 }, 3496 { "in0", 0xED, 0x00, emit_in0, INS_Z180|INS_EZ80 }, 3497 { "inc", 0x03, 0x04, emit_incdec,INS_ALL }, 3498 { "ind", 0xED, 0xAA, emit_insn, INS_NOT_GBZ80 }, 3499 { "ind2", 0xED, 0x8C, emit_insn, INS_EZ80 }, 3500 { "ind2r",0xED, 0x9C, emit_insn, INS_EZ80 }, 3501 { "indm", 0xED, 0x8A, emit_insn, INS_EZ80 }, 3502 { "indmr",0xED, 0x9A, emit_insn, INS_EZ80 }, 3503 { "indr", 0xED, 0xBA, emit_insn, INS_NOT_GBZ80 }, 3504 { "indrx",0xED, 0xCA, emit_insn, INS_EZ80 }, 3505 { "ini", 0xED, 0xA2, emit_insn, INS_NOT_GBZ80 }, 3506 { "ini2", 0xED, 0x84, emit_insn, INS_EZ80 }, 3507 { "ini2r",0xED, 0x94, emit_insn, INS_EZ80 }, 3508 { "inim", 0xED, 0x82, emit_insn, INS_EZ80 }, 3509 { "inimr",0xED, 0x92, emit_insn, INS_EZ80 }, 3510 { "inir", 0xED, 0xB2, emit_insn, INS_NOT_GBZ80 }, 3511 { "inirx",0xED, 0xC2, emit_insn, INS_EZ80 }, 3512 { "jp", 0xC3, 0xC2, emit_jpcc, INS_ALL }, 3513 { "jr", 0x18, 0x20, emit_jrcc, INS_ALL }, 3514 { "ld", 0x00, 0x00, emit_ld, INS_ALL }, 3515 { "ldd", 0xED, 0xA8, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */ 3516 { "lddr", 0xED, 0xB8, emit_insn, INS_NOT_GBZ80 }, 3517 { "lddrx",0xED, 0xBC, emit_insn, INS_Z80N }, 3518 { "lddx", 0xED, 0xAC, emit_insn, INS_Z80N }, 3519 { "ldh", 0xE0, 0x00, emit_ldh, INS_GBZ80 }, 3520 { "ldhl", 0x00, 0xF8, emit_ldhl, INS_GBZ80 }, 3521 { "ldi", 0xED, 0xA0, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */ 3522 { "ldir", 0xED, 0xB0, emit_insn, INS_NOT_GBZ80 }, 3523 { "ldirx",0xED, 0xB4, emit_insn, INS_Z80N }, 3524 { "ldix", 0xED, 0xA4, emit_insn, INS_Z80N }, 3525 { "ldpirx",0xED,0xB7, emit_insn, INS_Z80N }, 3526 { "ldws", 0xED, 0xA5, emit_insn, INS_Z80N }, 3527 { "lea", 0xED, 0x02, emit_lea, INS_EZ80 }, 3528 { "mirror",0xED,0x24, emit_insn, INS_Z80N }, 3529 { "mlt", 0xED, 0x4C, emit_mlt, INS_Z180|INS_EZ80|INS_Z80N }, 3530 { "mul", 0xED, 0x30, emit_mul, INS_Z80N }, 3531 { "mulub",0xED, 0xC5, emit_mulub,INS_R800 }, 3532 { "muluw",0xED, 0xC3, emit_muluw,INS_R800 }, 3533 { "neg", 0xED, 0x44, emit_insn, INS_NOT_GBZ80 }, 3534 { "nextreg",0xED,0x91,emit_nextreg,INS_Z80N }, 3535 { "nop", 0x00, 0x00, emit_insn, INS_ALL }, 3536 { "or", 0x00, 0xB0, emit_s, INS_ALL }, 3537 { "otd2r",0xED, 0xBC, emit_insn, INS_EZ80 }, 3538 { "otdm", 0xED, 0x8B, emit_insn, INS_Z180|INS_EZ80 }, 3539 { "otdmr",0xED, 0x9B, emit_insn, INS_Z180|INS_EZ80 }, 3540 { "otdr", 0xED, 0xBB, emit_insn, INS_NOT_GBZ80 }, 3541 { "otdrx",0xED, 0xCB, emit_insn, INS_EZ80 }, 3542 { "oti2r",0xED, 0xB4, emit_insn, INS_EZ80 }, 3543 { "otim", 0xED, 0x83, emit_insn, INS_Z180|INS_EZ80 }, 3544 { "otimr",0xED, 0x93, emit_insn, INS_Z180|INS_EZ80 }, 3545 { "otir", 0xED, 0xB3, emit_insn, INS_NOT_GBZ80 }, 3546 { "otirx",0xED, 0xC3, emit_insn, INS_EZ80 }, 3547 { "out", 0x00, 0x00, emit_out, INS_NOT_GBZ80 }, 3548 { "out0", 0xED, 0x01, emit_out0, INS_Z180|INS_EZ80 }, 3549 { "outd", 0xED, 0xAB, emit_insn, INS_NOT_GBZ80 }, 3550 { "outd2",0xED, 0xAC, emit_insn, INS_EZ80 }, 3551 { "outi", 0xED, 0xA3, emit_insn, INS_NOT_GBZ80 }, 3552 { "outi2",0xED, 0xA4, emit_insn, INS_EZ80 }, 3553 { "outinb",0xED,0x90, emit_insn, INS_Z80N }, 3554 { "pea", 0xED, 0x65, emit_pea, INS_EZ80 }, 3555 { "pixelad",0xED,0x94,emit_insn, INS_Z80N }, 3556 { "pixeldn",0xED,0x93,emit_insn, INS_Z80N }, 3557 { "pop", 0x00, 0xC1, emit_pop, INS_ALL }, 3558 { "push", 0x00, 0xC5, emit_push, INS_ALL }, 3559 { "res", 0xCB, 0x80, emit_bit, INS_ALL }, 3560 { "ret", 0xC9, 0xC0, emit_retcc,INS_ALL }, 3561 { "reti", 0xED, 0x4D, emit_reti, INS_ALL }, /*GBZ80 has its own opcode for it*/ 3562 { "retn", 0xED, 0x45, emit_insn, INS_NOT_GBZ80 }, 3563 { "rl", 0xCB, 0x10, emit_mr, INS_ALL }, 3564 { "rla", 0x00, 0x17, emit_insn, INS_ALL }, 3565 { "rlc", 0xCB, 0x00, emit_mr, INS_ALL }, 3566 { "rlca", 0x00, 0x07, emit_insn, INS_ALL }, 3567 { "rld", 0xED, 0x6F, emit_insn, INS_NOT_GBZ80 }, 3568 { "rr", 0xCB, 0x18, emit_mr, INS_ALL }, 3569 { "rra", 0x00, 0x1F, emit_insn, INS_ALL }, 3570 { "rrc", 0xCB, 0x08, emit_mr, INS_ALL }, 3571 { "rrca", 0x00, 0x0F, emit_insn, INS_ALL }, 3572 { "rrd", 0xED, 0x67, emit_insn, INS_NOT_GBZ80 }, 3573 { "rsmix",0xED, 0x7E, emit_insn, INS_EZ80 }, 3574 { "rst", 0x00, 0xC7, emit_rst, INS_ALL }, 3575 { "sbc", 0x98, 0x42, emit_adc, INS_ALL }, 3576 { "scf", 0x00, 0x37, emit_insn, INS_ALL }, 3577 { "set", 0xCB, 0xC0, emit_bit, INS_ALL }, 3578 { "setae",0xED, 0x95, emit_insn, INS_Z80N }, 3579 { "sl1", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N }, 3580 { "sla", 0xCB, 0x20, emit_mr, INS_ALL }, 3581 { "sli", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N }, 3582 { "sll", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N }, 3583 { "slp", 0xED, 0x76, emit_insn, INS_Z180|INS_EZ80 }, 3584 { "sra", 0xCB, 0x28, emit_mr, INS_ALL }, 3585 { "srl", 0xCB, 0x38, emit_mr, INS_ALL }, 3586 { "stmix",0xED, 0x7D, emit_insn, INS_EZ80 }, 3587 { "stop", 0x00, 0x10, emit_insn, INS_GBZ80 }, 3588 { "sub", 0x00, 0x90, emit_sub, INS_ALL }, 3589 { "swap", 0xCB, 0x30, emit_swap, INS_GBZ80|INS_Z80N }, 3590 { "swapnib",0xED,0x23,emit_insn, INS_Z80N }, 3591 { "test", 0xED, 0x27, emit_insn_n, INS_Z80N }, 3592 { "tst", 0xED, 0x04, emit_tst, INS_Z180|INS_EZ80|INS_Z80N }, 3593 { "tstio",0xED, 0x74, emit_insn_n,INS_Z180|INS_EZ80 }, 3594 { "xor", 0x00, 0xA8, emit_s, INS_ALL }, 3595} ; 3596 3597void 3598md_assemble (char *str) 3599{ 3600 const char *p; 3601 char * old_ptr; 3602 int i; 3603 table_t *insp; 3604 3605 err_flag = 0; 3606 inst_mode = cpu_mode ? (INST_MODE_L | INST_MODE_IL) : (INST_MODE_S | INST_MODE_IS); 3607 old_ptr = input_line_pointer; 3608 p = skip_space (str); 3609 for (i = 0; (i < BUFLEN) && (ISALPHA (*p) || ISDIGIT (*p));) 3610 buf[i++] = TOLOWER (*p++); 3611 3612 if (i == BUFLEN) 3613 { 3614 buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated. */ 3615 buf[BUFLEN-1] = 0; 3616 as_bad (_("Unknown instruction '%s'"), buf); 3617 } 3618 else 3619 { 3620 dwarf2_emit_insn (0); 3621 if ((*p) && (!ISSPACE (*p))) 3622 { 3623 if (*p != '.' || !(ins_ok & INS_EZ80) || !assemble_suffix (&p)) 3624 { 3625 as_bad (_("syntax error")); 3626 goto end; 3627 } 3628 } 3629 buf[i] = 0; 3630 p = skip_space (p); 3631 key = buf; 3632 3633 insp = bsearch (&key, instab, ARRAY_SIZE (instab), 3634 sizeof (instab[0]), key_cmp); 3635 if (!insp || (insp->inss && !(insp->inss & ins_ok))) 3636 { 3637 *frag_more (1) = 0; 3638 as_bad (_("Unknown instruction `%s'"), buf); 3639 } 3640 else 3641 { 3642 p = insp->fp (insp->prefix, insp->opcode, p); 3643 p = skip_space (p); 3644 if ((!err_flag) && *p) 3645 as_bad (_("junk at end of line, " 3646 "first unrecognized character is `%c'"), *p); 3647 } 3648 } 3649 end: 3650 input_line_pointer = old_ptr; 3651} 3652 3653static int 3654is_overflow (long value, unsigned bitsize) 3655{ 3656 long fieldmask = (2UL << (bitsize - 1)) - 1; 3657 long signmask = ~fieldmask; 3658 long a = value & fieldmask; 3659 long ss = a & signmask; 3660 if (ss != 0 && ss != (signmask & fieldmask)) 3661 return 1; 3662 return 0; 3663} 3664 3665void 3666md_apply_fix (fixS * fixP, valueT* valP, segT seg) 3667{ 3668 long val = *valP; 3669 char *p_lit = fixP->fx_where + fixP->fx_frag->fr_literal; 3670 3671 if (fixP->fx_addsy == NULL) 3672 fixP->fx_done = 1; 3673 else if (fixP->fx_pcrel) 3674 { 3675 segT s = S_GET_SEGMENT (fixP->fx_addsy); 3676 if (s == seg || s == absolute_section) 3677 { 3678 val += S_GET_VALUE (fixP->fx_addsy); 3679 fixP->fx_done = 1; 3680 } 3681 } 3682 3683 switch (fixP->fx_r_type) 3684 { 3685 case BFD_RELOC_8_PCREL: 3686 case BFD_RELOC_Z80_DISP8: 3687 case BFD_RELOC_8: 3688 case BFD_RELOC_16: 3689 case BFD_RELOC_24: 3690 case BFD_RELOC_32: 3691 case BFD_RELOC_Z80_16_BE: 3692 fixP->fx_no_overflow = 0; 3693 break; 3694 default: 3695 fixP->fx_no_overflow = 1; 3696 break; 3697 } 3698 3699 switch (fixP->fx_r_type) 3700 { 3701 case BFD_RELOC_8_PCREL: 3702 case BFD_RELOC_Z80_DISP8: 3703 if (fixP->fx_done && (val < -0x80 || val > 0x7f)) 3704 as_bad_where (fixP->fx_file, fixP->fx_line, 3705 _("8-bit signed offset out of range (%+ld)"), val); 3706 *p_lit++ = val; 3707 break; 3708 3709 case BFD_RELOC_Z80_BYTE0: 3710 *p_lit++ = val; 3711 break; 3712 3713 case BFD_RELOC_Z80_BYTE1: 3714 *p_lit++ = (val >> 8); 3715 break; 3716 3717 case BFD_RELOC_Z80_BYTE2: 3718 *p_lit++ = (val >> 16); 3719 break; 3720 3721 case BFD_RELOC_Z80_BYTE3: 3722 *p_lit++ = (val >> 24); 3723 break; 3724 3725 case BFD_RELOC_8: 3726 if (fixP->fx_done && is_overflow(val, 8)) 3727 as_warn_where (fixP->fx_file, fixP->fx_line, 3728 _("8-bit overflow (%+ld)"), val); 3729 *p_lit++ = val; 3730 break; 3731 3732 case BFD_RELOC_Z80_WORD1: 3733 *p_lit++ = (val >> 16); 3734 *p_lit++ = (val >> 24); 3735 break; 3736 3737 case BFD_RELOC_Z80_WORD0: 3738 *p_lit++ = val; 3739 *p_lit++ = (val >> 8); 3740 break; 3741 3742 case BFD_RELOC_16: 3743 if (fixP->fx_done && is_overflow(val, 16)) 3744 as_warn_where (fixP->fx_file, fixP->fx_line, 3745 _("16-bit overflow (%+ld)"), val); 3746 *p_lit++ = val; 3747 *p_lit++ = (val >> 8); 3748 break; 3749 3750 case BFD_RELOC_24: /* Def24 may produce this. */ 3751 if (fixP->fx_done && is_overflow(val, 24)) 3752 as_warn_where (fixP->fx_file, fixP->fx_line, 3753 _("24-bit overflow (%+ld)"), val); 3754 *p_lit++ = val; 3755 *p_lit++ = (val >> 8); 3756 *p_lit++ = (val >> 16); 3757 break; 3758 3759 case BFD_RELOC_32: /* Def32 and .long may produce this. */ 3760 if (fixP->fx_done && is_overflow(val, 32)) 3761 as_warn_where (fixP->fx_file, fixP->fx_line, 3762 _("32-bit overflow (%+ld)"), val); 3763 *p_lit++ = val; 3764 *p_lit++ = (val >> 8); 3765 *p_lit++ = (val >> 16); 3766 *p_lit++ = (val >> 24); 3767 break; 3768 3769 case BFD_RELOC_Z80_16_BE: /* Z80N PUSH nn instruction produce this. */ 3770 *p_lit++ = val >> 8; 3771 *p_lit++ = val; 3772 break; 3773 3774 default: 3775 printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP->fx_r_type); 3776 abort (); 3777 } 3778} 3779 3780/* GAS will call this to generate a reloc. GAS will pass the 3781 resulting reloc to `bfd_install_relocation'. This currently works 3782 poorly, as `bfd_install_relocation' often does the wrong thing, and 3783 instances of `tc_gen_reloc' have been written to work around the 3784 problems, which in turns makes it difficult to fix 3785 `bfd_install_relocation'. */ 3786 3787/* If while processing a fixup, a reloc really 3788 needs to be created then it is done here. */ 3789 3790arelent * 3791tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp) 3792{ 3793 arelent *reloc; 3794 3795 if (fixp->fx_subsy != NULL) 3796 { 3797 as_bad_where (fixp->fx_file, fixp->fx_line, _("expression too complex")); 3798 return NULL; 3799 } 3800 3801 reloc = XNEW (arelent); 3802 reloc->sym_ptr_ptr = XNEW (asymbol *); 3803 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 3804 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 3805 reloc->addend = fixp->fx_offset; 3806 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 3807 if (reloc->howto == NULL) 3808 { 3809 as_bad_where (fixp->fx_file, fixp->fx_line, 3810 _("reloc %d not supported by object file format"), 3811 (int) fixp->fx_r_type); 3812 return NULL; 3813 } 3814 3815 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT 3816 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY) 3817 reloc->address = fixp->fx_offset; 3818 3819 return reloc; 3820} 3821 3822int 3823z80_tc_labels_without_colon (void) 3824{ 3825 return colonless_labels; 3826} 3827 3828int 3829z80_tc_label_is_local (const char *name) 3830{ 3831 const char *n; 3832 const char *p; 3833 if (local_label_prefix == NULL) 3834 return 0; 3835 for (p = local_label_prefix, n = name; *p && *n && *n == *p; p++, n++) 3836 ; 3837 return *p == '\0'; 3838} 3839 3840/* Parse floating point number from string and compute mantissa and 3841 exponent. Mantissa is normalized. 3842*/ 3843#define EXP_MIN -0x10000 3844#define EXP_MAX 0x10000 3845static int 3846str_to_broken_float (bfd_boolean *signP, bfd_uint64_t *mantissaP, int *expP) 3847{ 3848 char *p; 3849 bfd_boolean sign; 3850 bfd_uint64_t mantissa = 0; 3851 int exponent = 0; 3852 int i; 3853 3854 p = (char*)skip_space (input_line_pointer); 3855 sign = (*p == '-'); 3856 *signP = sign; 3857 if (sign || *p == '+') 3858 ++p; 3859 if (strncasecmp (p, "NaN", 3) == 0) 3860 { 3861 *mantissaP = 0; 3862 *expP = 0; 3863 input_line_pointer = p + 3; 3864 return 1; 3865 } 3866 if (strncasecmp (p, "inf", 3) == 0) 3867 { 3868 *mantissaP = 1ull << 63; 3869 *expP = EXP_MAX; 3870 input_line_pointer = p + 3; 3871 return 1; 3872 } 3873 for (; ISDIGIT (*p); ++p) 3874 { 3875 if (mantissa >> 60) 3876 { 3877 if (*p >= '5') 3878 mantissa++; 3879 break; 3880 } 3881 mantissa = mantissa * 10 + (*p - '0'); 3882 } 3883 /* skip non-significant digits */ 3884 for (; ISDIGIT (*p); ++p) 3885 exponent++; 3886 3887 if (*p == '.') 3888 { 3889 p++; 3890 if (!exponent) /* If no precision overflow. */ 3891 { 3892 for (; ISDIGIT (*p); ++p, --exponent) 3893 { 3894 if (mantissa >> 60) 3895 { 3896 if (*p >= '5') 3897 mantissa++; 3898 break; 3899 } 3900 mantissa = mantissa * 10 + (*p - '0'); 3901 } 3902 } 3903 for (; ISDIGIT (*p); ++p) 3904 ; 3905 } 3906 if (*p == 'e' || *p == 'E') 3907 { 3908 int es; 3909 int t = 0; 3910 ++p; 3911 es = (*p == '-'); 3912 if (es || *p == '+') 3913 p++; 3914 for (; ISDIGIT (*p); ++p) 3915 { 3916 if (t < 100) 3917 t = t * 10 + (*p - '0'); 3918 } 3919 exponent += (es) ? -t : t; 3920 } 3921 if (ISALNUM (*p) || *p == '.') 3922 return 0; 3923 input_line_pointer = p; 3924 if (mantissa == 0) 3925 { 3926 *mantissaP = 1ull << 63; 3927 *expP = EXP_MIN; 3928 return 1; /* result is 0 */ 3929 } 3930 /* normalization */ 3931 for (; mantissa <= ~0ull/10; --exponent) 3932 mantissa *= 10; 3933 /* Now we have sign, mantissa, and signed decimal exponent 3934 need to recompute to binary exponent. */ 3935 for (i = 64; exponent > 0; --exponent) 3936 { 3937 /* be sure that no integer overflow */ 3938 while (mantissa > ~0ull/10) 3939 { 3940 mantissa >>= 1; 3941 i += 1; 3942 } 3943 mantissa *= 10; 3944 } 3945 for (; exponent < 0; ++exponent) 3946 { 3947 while (!(mantissa >> 63)) 3948 { 3949 mantissa <<= 1; 3950 i -= 1; 3951 } 3952 mantissa /= 10; 3953 } 3954 /* normalization */ 3955 for (; !(mantissa >> 63); --i) 3956 mantissa <<= 1; 3957 *mantissaP = mantissa; 3958 *expP = i; 3959 return 1; 3960} 3961 3962static const char * 3963str_to_zeda32(char *litP, int *sizeP) 3964{ 3965 bfd_uint64_t mantissa; 3966 bfd_boolean sign; 3967 int exponent; 3968 unsigned i; 3969 3970 *sizeP = 4; 3971 if (!str_to_broken_float (&sign, &mantissa, &exponent)) 3972 return _("invalid syntax"); 3973 /* I do not know why decrement is needed */ 3974 --exponent; 3975 /* shift by 39 bits right keeping 25 bit mantissa for rounding */ 3976 mantissa >>= 39; 3977 /* do rounding */ 3978 ++mantissa; 3979 /* make 24 bit mantissa */ 3980 mantissa >>= 1; 3981 /* check for overflow */ 3982 if (mantissa >> 24) 3983 { 3984 mantissa >>= 1; 3985 ++exponent; 3986 } 3987 /* check for 0 */ 3988 if (exponent < -127) 3989 { 3990 exponent = -128; 3991 mantissa = 0; 3992 } 3993 else if (exponent > 127) 3994 { 3995 exponent = -128; 3996 mantissa = sign ? 0xc00000 : 0x400000; 3997 } 3998 else if (mantissa == 0) 3999 { 4000 exponent = -128; 4001 mantissa = 0x200000; 4002 } 4003 else if (!sign) 4004 mantissa &= (1ull << 23) - 1; 4005 for (i = 0; i < 24; i += 8) 4006 *litP++ = (char)(mantissa >> i); 4007 *litP = (char)(0x80 + exponent); 4008 return NULL; 4009} 4010 4011/* 4012 Math48 by Anders Hejlsberg support. 4013 Mantissa is 39 bits wide, exponent 8 bit wide. 4014 Format is: 4015 bit 47: sign 4016 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1) 4017 bit 7-0: exponent+128 (0 - value is null) 4018 MIN: 2.938735877e-39 4019 MAX: 1.701411835e+38 4020*/ 4021static const char * 4022str_to_float48(char *litP, int *sizeP) 4023{ 4024 bfd_uint64_t mantissa; 4025 bfd_boolean sign; 4026 int exponent; 4027 unsigned i; 4028 4029 *sizeP = 6; 4030 if (!str_to_broken_float (&sign, &mantissa, &exponent)) 4031 return _("invalid syntax"); 4032 /* shift by 23 bits right keeping 41 bit mantissa for rounding */ 4033 mantissa >>= 23; 4034 /* do rounding */ 4035 ++mantissa; 4036 /* make 40 bit mantissa */ 4037 mantissa >>= 1; 4038 /* check for overflow */ 4039 if (mantissa >> 40) 4040 { 4041 mantissa >>= 1; 4042 ++exponent; 4043 } 4044 if (exponent < -127) 4045 { 4046 memset (litP, 0, 6); 4047 return NULL; 4048 } 4049 if (exponent > 127) 4050 return _("overflow"); 4051 if (!sign) 4052 mantissa &= (1ull << 39) - 1; 4053 *litP++ = (char)(0x80 + exponent); 4054 for (i = 0; i < 40; i += 8) 4055 *litP++ = (char)(mantissa >> i); 4056 return NULL; 4057} 4058 4059static const char * 4060str_to_ieee754_h(char *litP, int *sizeP) 4061{ 4062 return ieee_md_atof ('h', litP, sizeP, FALSE); 4063} 4064 4065static const char * 4066str_to_ieee754_s(char *litP, int *sizeP) 4067{ 4068 return ieee_md_atof ('s', litP, sizeP, FALSE); 4069} 4070 4071static const char * 4072str_to_ieee754_d(char *litP, int *sizeP) 4073{ 4074 return ieee_md_atof ('d', litP, sizeP, FALSE); 4075} 4076 4077#ifdef TARGET_USE_CFIPOP 4078/* Initialize the DWARF-2 unwind information for this procedure. */ 4079void 4080z80_tc_frame_initial_instructions (void) 4081{ 4082 static int sp_regno = -1; 4083 4084 if (sp_regno < 0) 4085 sp_regno = z80_tc_regname_to_dw2regnum ("sp"); 4086 4087 cfi_add_CFA_def_cfa (sp_regno, 0); 4088} 4089 4090int 4091z80_tc_regname_to_dw2regnum (const char *regname) 4092{ 4093 static const char *regs[] = 4094 { /* same registers as for GDB */ 4095 "af", "bc", "de", "hl", 4096 "sp", "pc", "ix", "iy", 4097 "af_", "bc_", "de_", "hl_", 4098 "ir" 4099 }; 4100 unsigned i; 4101 4102 for (i = 0; i < ARRAY_SIZE(regs); ++i) 4103 if (!strcasecmp (regs[i], regname)) 4104 return i; 4105 4106 return -1; 4107} 4108#endif 4109 4110/* Implement DWARF2_ADDR_SIZE. */ 4111int 4112z80_dwarf2_addr_size (const bfd *abfd) 4113{ 4114 switch (bfd_get_mach (abfd)) 4115 { 4116 case bfd_mach_ez80_adl: 4117 return 3; 4118 default: 4119 return 2; 4120 } 4121} 4122