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