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