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