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