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