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