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