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