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