* MAINTAINERS (BFIN): Remove myself as Blackfin maintainer.
[deliverable/binutils-gdb.git] / gas / config / tc-z80.c
CommitLineData
3c9b82ba 1/* tc-z80.c -- Assemble code for the Zilog Z80 and ASCII R800
2571583a 2 Copyright (C) 2005-2017 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"
3c9b82ba
NC
25
26/* Exported constants. */
27const char comment_chars[] = ";\0";
28const char line_comment_chars[] = "#;\0";
29const char line_separator_chars[] = "\0";
30const char EXP_CHARS[] = "eE\0";
31const char FLT_CHARS[] = "RrFf\0";
32
33/* For machine specific options. */
34const char * md_shortopts = ""; /* None yet. */
35
36enum options
37{
38 OPTION_MACH_Z80 = OPTION_MD_BASE,
39 OPTION_MACH_R800,
40 OPTION_MACH_IUD,
41 OPTION_MACH_WUD,
42 OPTION_MACH_FUD,
43 OPTION_MACH_IUP,
44 OPTION_MACH_WUP,
45 OPTION_MACH_FUP
46};
47
48#define INS_Z80 1
49#define INS_UNDOC 2
50#define INS_UNPORT 4
51#define INS_R800 8
52
53struct option md_longopts[] =
54{
55 { "z80", no_argument, NULL, OPTION_MACH_Z80},
56 { "r800", no_argument, NULL, OPTION_MACH_R800},
57 { "ignore-undocumented-instructions", no_argument, NULL, OPTION_MACH_IUD },
58 { "Wnud", no_argument, NULL, OPTION_MACH_IUD },
59 { "warn-undocumented-instructions", no_argument, NULL, OPTION_MACH_WUD },
60 { "Wud", no_argument, NULL, OPTION_MACH_WUD },
61 { "forbid-undocumented-instructions", no_argument, NULL, OPTION_MACH_FUD },
62 { "Fud", no_argument, NULL, OPTION_MACH_FUD },
63 { "ignore-unportable-instructions", no_argument, NULL, OPTION_MACH_IUP },
64 { "Wnup", no_argument, NULL, OPTION_MACH_IUP },
65 { "warn-unportable-instructions", no_argument, NULL, OPTION_MACH_WUP },
66 { "Wup", no_argument, NULL, OPTION_MACH_WUP },
67 { "forbid-unportable-instructions", no_argument, NULL, OPTION_MACH_FUP },
68 { "Fup", no_argument, NULL, OPTION_MACH_FUP },
69
70 { NULL, no_argument, NULL, 0 }
71} ;
72
73size_t md_longopts_size = sizeof (md_longopts);
74
75extern int coff_flags;
76/* Instruction classes that silently assembled. */
77static int ins_ok = INS_Z80 | INS_UNDOC;
78/* Instruction classes that generate errors. */
79static int ins_err = INS_R800;
80/* Instruction classes actually used, determines machine type. */
81static int ins_used = INS_Z80;
82
83int
17b9d67d 84md_parse_option (int c, const char* arg ATTRIBUTE_UNUSED)
3c9b82ba
NC
85{
86 switch (c)
87 {
88 default:
89 return 0;
90 case OPTION_MACH_Z80:
91 ins_ok &= ~INS_R800;
92 ins_err |= INS_R800;
93 break;
94 case OPTION_MACH_R800:
95 ins_ok = INS_Z80 | INS_UNDOC | INS_R800;
96 ins_err = INS_UNPORT;
97 break;
98 case OPTION_MACH_IUD:
99 ins_ok |= INS_UNDOC;
100 ins_err &= ~INS_UNDOC;
101 break;
102 case OPTION_MACH_IUP:
103 ins_ok |= INS_UNDOC | INS_UNPORT;
104 ins_err &= ~(INS_UNDOC | INS_UNPORT);
105 break;
106 case OPTION_MACH_WUD:
107 if ((ins_ok & INS_R800) == 0)
108 {
109 ins_ok &= ~(INS_UNDOC|INS_UNPORT);
110 ins_err &= ~INS_UNDOC;
111 }
112 break;
113 case OPTION_MACH_WUP:
114 ins_ok &= ~INS_UNPORT;
115 ins_err &= ~(INS_UNDOC|INS_UNPORT);
116 break;
117 case OPTION_MACH_FUD:
118 if ((ins_ok & INS_R800) == 0)
119 {
120 ins_ok &= (INS_UNDOC | INS_UNPORT);
121 ins_err |= INS_UNDOC | INS_UNPORT;
122 }
123 break;
124 case OPTION_MACH_FUP:
125 ins_ok &= ~INS_UNPORT;
126 ins_err |= INS_UNPORT;
127 break;
128 }
129
130 return 1;
131}
132
133void
134md_show_usage (FILE * f)
135{
136 fprintf (f, "\n\
137CPU model/instruction set options:\n\
138\n\
139 -z80\t\t assemble for Z80\n\
140 -ignore-undocumented-instructions\n\
141 -Wnud\n\
142\tsilently assemble undocumented Z80-instructions that work on R800\n\
143 -ignore-unportable-instructions\n\
144 -Wnup\n\
145\tsilently assemble all undocumented Z80-instructions\n\
146 -warn-undocumented-instructions\n\
147 -Wud\n\
148\tissue warnings for undocumented Z80-instructions that work on R800\n\
149 -warn-unportable-instructions\n\
150 -Wup\n\
151\tissue warnings for other undocumented Z80-instructions\n\
152 -forbid-undocumented-instructions\n\
153 -Fud\n\
154\ttreat all undocumented z80-instructions as errors\n\
155 -forbid-unportable-instructions\n\
156 -Fup\n\
157\ttreat undocumented z80-instructions that do not work on R800 as errors\n\
158 -r800\t assemble for R800\n\n\
159Default: -z80 -ignore-undocument-instructions -warn-unportable-instructions.\n");
160}
161
162static symbolS * zero;
163
25045f79
AM
164struct reg_entry
165{
f86f5863 166 const char* name;
25045f79
AM
167 int number;
168};
169#define R_STACKABLE (0x80)
170#define R_ARITH (0x40)
171#define R_IX (0x20)
172#define R_IY (0x10)
173#define R_INDEX (R_IX | R_IY)
174
175#define REG_A (7)
176#define REG_B (0)
177#define REG_C (1)
178#define REG_D (2)
179#define REG_E (3)
180#define REG_H (4)
181#define REG_L (5)
182#define REG_F (6 | 8)
183#define REG_I (9)
184#define REG_R (10)
185
186#define REG_AF (3 | R_STACKABLE)
187#define REG_BC (0 | R_STACKABLE | R_ARITH)
188#define REG_DE (1 | R_STACKABLE | R_ARITH)
189#define REG_HL (2 | R_STACKABLE | R_ARITH)
190#define REG_IX (REG_HL | R_IX)
191#define REG_IY (REG_HL | R_IY)
192#define REG_SP (3 | R_ARITH)
193
194static const struct reg_entry regtable[] =
195{
196 {"a", REG_A },
197 {"af", REG_AF },
198 {"b", REG_B },
199 {"bc", REG_BC },
200 {"c", REG_C },
201 {"d", REG_D },
202 {"de", REG_DE },
203 {"e", REG_E },
204 {"f", REG_F },
205 {"h", REG_H },
206 {"hl", REG_HL },
207 {"i", REG_I },
208 {"ix", REG_IX },
209 {"ixh",REG_H | R_IX },
210 {"ixl",REG_L | R_IX },
211 {"iy", REG_IY },
212 {"iyh",REG_H | R_IY },
213 {"iyl",REG_L | R_IY },
214 {"l", REG_L },
215 {"r", REG_R },
216 {"sp", REG_SP },
217} ;
218
219#define BUFLEN 8 /* Large enough for any keyword. */
220
3c9b82ba
NC
221void
222md_begin (void)
223{
25045f79 224 expressionS nul, reg;
3c9b82ba 225 char * p;
25045f79
AM
226 unsigned int i, j, k;
227 char buf[BUFLEN];
3c9b82ba 228
25045f79
AM
229 reg.X_op = O_register;
230 reg.X_md = 0;
231 reg.X_add_symbol = reg.X_op_symbol = 0;
232 for ( i = 0 ; i < ARRAY_SIZE ( regtable ) ; ++i )
233 {
234 reg.X_add_number = regtable[i].number;
235 k = strlen ( regtable[i].name );
236 buf[k] = 0;
237 if ( k+1 < BUFLEN )
238 {
239 for ( j = ( 1<<k ) ; j ; --j )
240 {
241 for ( k = 0 ; regtable[i].name[k] ; ++k )
242 {
243 buf[k] = ( j & ( 1<<k ) ) ? TOUPPER ( regtable[i].name[k] ) : regtable[i].name[k];
244 }
245 symbolS * psym = symbol_find_or_make(buf);
246 S_SET_SEGMENT(psym, reg_section);
247 symbol_set_value_expression(psym, &reg);
248 }
249 }
250 }
3c9b82ba 251 p = input_line_pointer;
47990a6a 252 input_line_pointer = (char *) "0";
3c9b82ba
NC
253 nul.X_md=0;
254 expression (& nul);
255 input_line_pointer = p;
256 zero = make_expr_symbol (& nul);
257 /* We do not use relaxation (yet). */
258 linkrelax = 0;
259}
260
261void
262z80_md_end (void)
263{
264 int mach_type;
265
266 if (ins_used & (INS_UNPORT | INS_R800))
267 ins_used |= INS_UNDOC;
268
269 switch (ins_used)
270 {
271 case INS_Z80:
272 mach_type = bfd_mach_z80strict;
273 break;
274 case INS_Z80|INS_UNDOC:
275 mach_type = bfd_mach_z80;
276 break;
277 case INS_Z80|INS_UNDOC|INS_UNPORT:
278 mach_type = bfd_mach_z80full;
279 break;
280 case INS_Z80|INS_UNDOC|INS_R800:
281 mach_type = bfd_mach_r800;
282 break;
283 default:
284 mach_type = 0;
285 }
286
287 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type);
288}
289
3c9b82ba
NC
290static const char *
291skip_space (const char *s)
292{
293 while (*s == ' ' || *s == '\t')
294 ++s;
295 return s;
296}
297
298/* A non-zero return-value causes a continue in the
299 function read_a_source_file () in ../read.c. */
300int
301z80_start_line_hook (void)
302{
303 char *p, quote;
304 char buf[4];
305
306 /* Convert one character constants. */
307 for (p = input_line_pointer; *p && *p != '\n'; ++p)
308 {
309 switch (*p)
310 {
311 case '\'':
312 if (p[1] != 0 && p[1] != '\'' && p[2] == '\'')
313 {
314 snprintf (buf, 4, "%3d", (unsigned char)p[1]);
315 *p++ = buf[0];
316 *p++ = buf[1];
317 *p++ = buf[2];
318 break;
319 }
1a0670f3 320 /* Fall through. */
3c9b82ba
NC
321 case '"':
322 for (quote = *p++; quote != *p && '\n' != *p; ++p)
323 /* No escapes. */ ;
324 if (quote != *p)
325 {
326 as_bad (_("-- unterminated string"));
327 ignore_rest_of_line ();
328 return 1;
329 }
330 break;
331 }
332 }
134dcee5 333 /* Check for <label>[:] [.](EQU|DEFL) <value>. */
3c9b82ba
NC
334 if (is_name_beginner (*input_line_pointer))
335 {
d02603dc 336 char *name;
3c9b82ba
NC
337 char c, *rest, *line_start;
338 int len;
339
340 line_start = input_line_pointer;
3c9b82ba
NC
341 if (ignore_input ())
342 return 0;
343
d02603dc 344 c = get_symbol_name (&name);
3c9b82ba
NC
345 rest = input_line_pointer + 1;
346
347 if (*rest == ':')
348 ++rest;
349 if (*rest == ' ' || *rest == '\t')
350 ++rest;
134dcee5
AM
351 if (*rest == '.')
352 ++rest;
3c9b82ba
NC
353 if (strncasecmp (rest, "EQU", 3) == 0)
354 len = 3;
355 else if (strncasecmp (rest, "DEFL", 4) == 0)
356 len = 4;
357 else
358 len = 0;
3c45a255 359 if (len && (!ISALPHA(rest[len]) ) )
3c9b82ba
NC
360 {
361 /* Handle assignment here. */
3c9b82ba 362 if (line_start[-1] == '\n')
f9eb6721 363 {
3c45a255
AM
364 bump_line_counters ();
365 LISTING_NEWLINE ();
f9eb6721 366 }
3c45a255
AM
367 input_line_pointer = rest + len - 1;
368 /* Allow redefining with "DEFL" (len == 4), but not with "EQU". */
d02603dc 369 equals (name, len == 4);
3c9b82ba
NC
370 return 1;
371 }
372 else
373 {
374 /* Restore line and pointer. */
d02603dc 375 (void) restore_line_pointer (c);
3c9b82ba
NC
376 input_line_pointer = line_start;
377 }
378 }
379 return 0;
380}
381
382symbolS *
383md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
384{
385 return NULL;
386}
387
6d4af3c2 388const char *
3c9b82ba
NC
389md_atof (int type ATTRIBUTE_UNUSED, char *litP ATTRIBUTE_UNUSED,
390 int *sizeP ATTRIBUTE_UNUSED)
391{
392 return _("floating point numbers are not implemented");
393}
394
395valueT
396md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size)
397{
398 return size;
399}
400
401long
402md_pcrel_from (fixS * fixp)
403{
404 return fixp->fx_where +
405 fixp->fx_frag->fr_address + 1;
406}
407
408typedef const char * (asfunc)(char, char, const char*);
409
410typedef struct _table_t
411{
f86f5863 412 const char* name;
d9235011
TS
413 unsigned char prefix;
414 unsigned char opcode;
3c9b82ba
NC
415 asfunc * fp;
416} table_t;
417
418/* Compares the key for structs that start with a char * to the key. */
419static int
420key_cmp (const void * a, const void * b)
421{
422 const char *str_a, *str_b;
423
424 str_a = *((const char**)a);
425 str_b = *((const char**)b);
426 return strcmp (str_a, str_b);
427}
428
3c9b82ba
NC
429char buf[BUFLEN];
430const char *key = buf;
431
3c9b82ba
NC
432/* Prevent an error on a line from also generating
433 a "junk at end of line" error message. */
434static char err_flag;
435
436static void
437error (const char * message)
438{
20203fb9 439 as_bad ("%s", message);
3c9b82ba
NC
440 err_flag = 1;
441}
442
443static void
444ill_op (void)
445{
446 error (_("illegal operand"));
447}
448
449static void
450wrong_mach (int ins_type)
451{
452 const char *p;
453
454 switch (ins_type)
455 {
456 case INS_UNDOC:
457 p = "undocumented instruction";
458 break;
459 case INS_UNPORT:
460 p = "instruction does not work on R800";
461 break;
462 case INS_R800:
463 p = "instruction only works R800";
464 break;
465 default:
134dcee5 466 p = 0; /* Not reachable. */
3c9b82ba
NC
467 }
468
469 if (ins_type & ins_err)
470 error (_(p));
471 else
73812f59 472 as_warn ("%s", _(p));
3c9b82ba
NC
473}
474
475static void
476check_mach (int ins_type)
477{
478 if ((ins_type & ins_ok) == 0)
479 wrong_mach (ins_type);
480 ins_used |= ins_type;
481}
482
3c9b82ba
NC
483/* Check whether an expression is indirect. */
484static int
485is_indir (const char *s)
486{
487 char quote;
488 const char *p;
489 int indir, depth;
490
491 /* Indirection is indicated with parentheses. */
492 indir = (*s == '(');
493
494 for (p = s, depth = 0; *p && *p != ','; ++p)
495 {
496 switch (*p)
497 {
498 case '"':
499 case '\'':
500 for (quote = *p++; quote != *p && *p != '\n'; ++p)
501 if (*p == '\\' && p[1])
502 ++p;
503 break;
504 case '(':
505 ++ depth;
506 break;
507 case ')':
508 -- depth;
509 if (depth == 0)
510 {
511 p = skip_space (p + 1);
512 if (*p && *p != ',')
513 indir = 0;
514 --p;
515 }
516 if (depth < 0)
517 error (_("mismatched parentheses"));
518 break;
519 }
520 }
521
522 if (depth != 0)
523 error (_("mismatched parentheses"));
524
525 return indir;
526}
527
25045f79 528/* Check whether a symbol involves a register. */
3739860c 529static int
25045f79
AM
530contains_register(symbolS *sym)
531{
532 if (sym)
533 {
534 expressionS * ex = symbol_get_value_expression(sym);
3739860c
L
535 return (O_register == ex->X_op)
536 || (ex->X_add_symbol && contains_register(ex->X_add_symbol))
25045f79
AM
537 || (ex->X_op_symbol && contains_register(ex->X_op_symbol));
538 }
539 else
540 return 0;
541}
542
2b0f3761 543/* Parse general expression, not loooking for indexed addressing. */
3c9b82ba 544static const char *
25045f79 545parse_exp_not_indexed (const char *s, expressionS *op)
3c9b82ba
NC
546{
547 const char *p;
548 int indir;
3c9b82ba
NC
549
550 p = skip_space (s);
551 op->X_md = indir = is_indir (p);
25045f79 552 input_line_pointer = (char*) s ;
73812f59 553 expression (op);
25045f79 554 switch (op->X_op)
3c9b82ba 555 {
25045f79
AM
556 case O_absent:
557 error (_("missing operand"));
558 break;
559 case O_illegal:
560 error (_("bad expression syntax"));
561 break;
abd58633
AM
562 default:
563 break;
3c9b82ba 564 }
3c9b82ba
NC
565 return input_line_pointer;
566}
567
25045f79 568/* Parse expression, change operator to O_md1 for indexed addressing*/
3c9b82ba
NC
569static const char *
570parse_exp (const char *s, expressionS *op)
571{
25045f79
AM
572 const char* res = parse_exp_not_indexed (s, op);
573 switch (op->X_op)
574 {
575 case O_add:
576 case O_subtract:
577 if (op->X_md && (O_register == symbol_get_value_expression(op->X_add_symbol)->X_op))
578 {
579 int rnum = symbol_get_value_expression(op->X_add_symbol)->X_add_number;
580 if ( ((REG_IX != rnum) && (REG_IY != rnum)) || contains_register(op->X_op_symbol) )
581 {
582 ill_op();
583 }
584 else
585 {
586 if (O_subtract == op->X_op)
587 {
588 expressionS minus;
589 minus.X_op = O_uminus;
590 minus.X_add_number = 0;
591 minus.X_add_symbol = op->X_op_symbol;
592 minus.X_op_symbol = 0;
593 op->X_op_symbol = make_expr_symbol(&minus);
594 op->X_op = O_add;
595 }
596 symbol_get_value_expression(op->X_op_symbol)->X_add_number += op->X_add_number;
597 op->X_add_number = rnum;
598 op->X_add_symbol = op->X_op_symbol;
599 op->X_op_symbol = 0;
600 op->X_op = O_md1;
601 }
602 }
603 break;
604 case O_register:
605 if ( op->X_md && ((REG_IX == op->X_add_number)||(REG_IY == op->X_add_number)) )
606 {
607 op->X_add_symbol = zero;
608 op->X_op = O_md1;
609 }
610 break;
abd58633
AM
611 default:
612 break;
25045f79
AM
613 }
614 return res;
3c9b82ba
NC
615}
616
617/* Condition codes, including some synonyms provided by HiTech zas. */
618static const struct reg_entry cc_tab[] =
619{
620 { "age", 6 << 3 },
621 { "alt", 7 << 3 },
622 { "c", 3 << 3 },
623 { "di", 4 << 3 },
624 { "ei", 5 << 3 },
625 { "lge", 2 << 3 },
626 { "llt", 3 << 3 },
627 { "m", 7 << 3 },
628 { "nc", 2 << 3 },
629 { "nz", 0 << 3 },
630 { "p", 6 << 3 },
631 { "pe", 5 << 3 },
632 { "po", 4 << 3 },
633 { "z", 1 << 3 },
634} ;
635
636/* Parse condition code. */
637static const char *
638parse_cc (const char *s, char * op)
639{
640 const char *p;
641 int i;
642 struct reg_entry * cc_p;
643
644 for (i = 0; i < BUFLEN; ++i)
645 {
646 if (!ISALPHA (s[i])) /* Condition codes consist of letters only. */
647 break;
648 buf[i] = TOLOWER (s[i]);
649 }
650
651 if ((i < BUFLEN)
652 && ((s[i] == 0) || (s[i] == ',')))
653 {
654 buf[i] = 0;
655 cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
656 sizeof (cc_tab[0]), key_cmp);
657 }
658 else
659 cc_p = NULL;
660
661 if (cc_p)
662 {
663 *op = cc_p->number;
664 p = s + i;
665 }
666 else
667 p = NULL;
668
669 return p;
670}
671
672static const char *
673emit_insn (char prefix, char opcode, const char * args)
674{
675 char *p;
676
677 if (prefix)
678 {
679 p = frag_more (2);
680 *p++ = prefix;
681 }
682 else
683 p = frag_more (1);
684 *p = opcode;
685 return args;
686}
687
134dcee5
AM
688void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp)
689{
690 bfd_reloc_code_real_type r[4] =
691 {
692 BFD_RELOC_8,
693 BFD_RELOC_16,
694 BFD_RELOC_24,
695 BFD_RELOC_32
696 };
697
3739860c 698 if (nbytes < 1 || nbytes > 4)
134dcee5
AM
699 {
700 as_bad (_("unsupported BFD relocation size %u"), nbytes);
701 }
702 else
703 {
704 fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]);
705 }
706}
707
3c9b82ba
NC
708static void
709emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
710{
711 char *p;
712 int lo, hi;
3c9b82ba
NC
713
714 p = frag_more (1);
715 *p = val->X_add_number;
25045f79
AM
716 if ( contains_register(val->X_add_symbol) || contains_register(val->X_op_symbol) )
717 {
718 ill_op();
719 }
720 else if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
134dcee5 721 {
20203fb9 722 as_bad (_("cannot make a relative jump to an absolute location"));
134dcee5
AM
723 }
724 else if (val->X_op == O_constant)
3c9b82ba
NC
725 {
726 lo = -128;
727 hi = (BFD_RELOC_8 == r_type) ? 255 : 127;
728
729 if ((val->X_add_number < lo) || (val->X_add_number > hi))
730 {
731 if (r_type == BFD_RELOC_Z80_DISP8)
732 as_bad (_("offset too large"));
733 else
734 as_warn (_("overflow"));
735 }
736 }
737 else
738 {
73812f59
NC
739 fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
740 (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type);
3c9b82ba
NC
741 /* FIXME : Process constant offsets immediately. */
742 }
743}
744
745static void
746emit_word (expressionS * val)
747{
748 char *p;
749
750 p = frag_more (2);
751 if ( (val->X_op == O_register)
25045f79
AM
752 || (val->X_op == O_md1)
753 || contains_register(val->X_add_symbol)
754 || contains_register(val->X_op_symbol) )
3c9b82ba
NC
755 ill_op ();
756 else
757 {
758 *p = val->X_add_number;
759 p[1] = (val->X_add_number>>8);
760 if (val->X_op != O_constant)
761 fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
762 val, FALSE, BFD_RELOC_16);
763 }
764}
765
766static void
767emit_mx (char prefix, char opcode, int shift, expressionS * arg)
768 /* The operand m may be r, (hl), (ix+d), (iy+d),
769 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
770{
771 char *q;
772 int rnum;
773
774 rnum = arg->X_add_number;
775 switch (arg->X_op)
776 {
777 case O_register:
778 if (arg->X_md)
779 {
780 if (rnum != REG_HL)
781 {
782 ill_op ();
783 break;
784 }
785 else
786 rnum = 6;
787 }
788 else
789 {
790 if ((prefix == 0) && (rnum & R_INDEX))
791 {
792 prefix = (rnum & R_IX) ? 0xDD : 0xFD;
793 check_mach (INS_UNDOC);
794 rnum &= ~R_INDEX;
795 }
796 if (rnum > 7)
797 {
798 ill_op ();
799 break;
800 }
801 }
802 q = frag_more (prefix ? 2 : 1);
803 if (prefix)
804 * q ++ = prefix;
805 * q ++ = opcode + (rnum << shift);
806 break;
807 case O_md1:
808 q = frag_more (2);
809 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
810 *q = (prefix) ? prefix : (opcode + (6 << shift));
761025be
AM
811 {
812 expressionS offset = *arg;
813 offset.X_op = O_symbol;
814 offset.X_add_number = 0;
815 emit_byte (&offset, BFD_RELOC_Z80_DISP8);
816 }
3c9b82ba
NC
817 if (prefix)
818 {
819 q = frag_more (1);
820 *q = opcode+(6<<shift);
821 }
822 break;
823 default:
824 abort ();
825 }
826}
827
828/* The operand m may be r, (hl), (ix+d), (iy+d),
829 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
830static const char *
831emit_m (char prefix, char opcode, const char *args)
832{
833 expressionS arg_m;
834 const char *p;
835
836 p = parse_exp (args, &arg_m);
837 switch (arg_m.X_op)
838 {
839 case O_md1:
840 case O_register:
841 emit_mx (prefix, opcode, 0, &arg_m);
842 break;
843 default:
844 ill_op ();
845 }
846 return p;
847}
848
849/* The operand m may be as above or one of the undocumented
850 combinations (ix+d),r and (iy+d),r (if unportable instructions
851 are allowed). */
852static const char *
853emit_mr (char prefix, char opcode, const char *args)
854{
855 expressionS arg_m, arg_r;
856 const char *p;
857
858 p = parse_exp (args, & arg_m);
859
860 switch (arg_m.X_op)
861 {
862 case O_md1:
863 if (*p == ',')
864 {
865 p = parse_exp (p + 1, & arg_r);
866
867 if ((arg_r.X_md == 0)
868 && (arg_r.X_op == O_register)
869 && (arg_r.X_add_number < 8))
870 opcode += arg_r.X_add_number-6; /* Emit_mx () will add 6. */
871 else
872 {
873 ill_op ();
874 break;
875 }
876 check_mach (INS_UNPORT);
877 }
1a0670f3 878 /* Fall through. */
3c9b82ba
NC
879 case O_register:
880 emit_mx (prefix, opcode, 0, & arg_m);
881 break;
882 default:
883 ill_op ();
884 }
885 return p;
886}
887
888static void
889emit_sx (char prefix, char opcode, expressionS * arg_p)
890{
891 char *q;
892
893 switch (arg_p->X_op)
894 {
895 case O_register:
896 case O_md1:
897 emit_mx (prefix, opcode, 0, arg_p);
898 break;
899 default:
900 if (arg_p->X_md)
901 ill_op ();
902 else
903 {
904 q = frag_more (prefix ? 2 : 1);
905 if (prefix)
906 *q++ = prefix;
907 *q = opcode ^ 0x46;
908 emit_byte (arg_p, BFD_RELOC_8);
909 }
910 }
911}
912
913/* The operand s may be r, (hl), (ix+d), (iy+d), n. */
914static const char *
915emit_s (char prefix, char opcode, const char *args)
916{
917 expressionS arg_s;
918 const char *p;
919
920 p = parse_exp (args, & arg_s);
921 emit_sx (prefix, opcode, & arg_s);
922 return p;
923}
924
925static const char *
926emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
927{
928 expressionS addr;
929 const char *p; char *q;
930
25045f79 931 p = parse_exp_not_indexed (args, &addr);
3c9b82ba
NC
932 if (addr.X_md)
933 ill_op ();
934 else
935 {
936 q = frag_more (1);
937 *q = opcode;
938 emit_word (& addr);
939 }
940 return p;
941}
942
943/* Operand may be rr, r, (hl), (ix+d), (iy+d). */
944static const char *
945emit_incdec (char prefix, char opcode, const char * args)
946{
947 expressionS operand;
948 int rnum;
949 const char *p; char *q;
950
951 p = parse_exp (args, &operand);
952 rnum = operand.X_add_number;
953 if ((! operand.X_md)
954 && (operand.X_op == O_register)
955 && (R_ARITH&rnum))
956 {
957 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
958 if (rnum & R_INDEX)
959 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
960 *q = prefix + ((rnum & 3) << 4);
961 }
962 else
963 {
964 if ((operand.X_op == O_md1) || (operand.X_op == O_register))
965 emit_mx (0, opcode, 3, & operand);
966 else
967 ill_op ();
968 }
969 return p;
970}
971
972static const char *
973emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
974{
975 expressionS addr;
976 const char *p;
977 char *q;
978
25045f79 979 p = parse_exp_not_indexed (args, &addr);
3c9b82ba
NC
980 if (addr.X_md)
981 ill_op ();
982 else
983 {
984 q = frag_more (1);
985 *q = opcode;
986 emit_byte (&addr, BFD_RELOC_8_PCREL);
987 }
988 return p;
989}
990
991static const char *
992emit_jp (char prefix, char opcode, const char * args)
993{
994 expressionS addr;
995 const char *p;
996 char *q;
997 int rnum;
998
25045f79 999 p = parse_exp_not_indexed (args, & addr);
3c9b82ba
NC
1000 if (addr.X_md)
1001 {
1002 rnum = addr.X_add_number;
25045f79 1003 if ((O_register == addr.X_op) && (REG_HL == (rnum & ~R_INDEX)))
3c9b82ba
NC
1004 {
1005 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1006 if (rnum & R_INDEX)
1007 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1008 *q = prefix;
1009 }
1010 else
1011 ill_op ();
1012 }
1013 else
1014 {
1015 q = frag_more (1);
1016 *q = opcode;
1017 emit_word (& addr);
1018 }
1019 return p;
1020}
1021
1022static const char *
1023emit_im (char prefix, char opcode, const char * args)
1024{
1025 expressionS mode;
1026 const char *p;
1027 char *q;
1028
1029 p = parse_exp (args, & mode);
1030 if (mode.X_md || (mode.X_op != O_constant))
1031 ill_op ();
1032 else
1033 switch (mode.X_add_number)
1034 {
1035 case 1:
1036 case 2:
1037 ++mode.X_add_number;
1038 /* Fall through. */
1039 case 0:
1040 q = frag_more (2);
1041 *q++ = prefix;
1042 *q = opcode + 8*mode.X_add_number;
1043 break;
1044 default:
1045 ill_op ();
1046 }
1047 return p;
1048}
1049
1050static const char *
1051emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1052{
1053 expressionS regp;
1054 const char *p;
1055 char *q;
1056
1057 p = parse_exp (args, & regp);
1058 if ((!regp.X_md)
1059 && (regp.X_op == O_register)
1060 && (regp.X_add_number & R_STACKABLE))
1061 {
1062 int rnum;
1063
1064 rnum = regp.X_add_number;
1065 if (rnum&R_INDEX)
1066 {
1067 q = frag_more (2);
1068 *q++ = (rnum&R_IX)?0xDD:0xFD;
1069 }
1070 else
1071 q = frag_more (1);
1072 *q = opcode + ((rnum & 3) << 4);
1073 }
1074 else
1075 ill_op ();
1076
1077 return p;
1078}
1079
1080static const char *
1081emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1082{
1083 char cc, *q;
1084 const char *p;
1085
1086 p = parse_cc (args, &cc);
1087 q = frag_more (1);
1088 if (p)
1089 *q = opcode + cc;
1090 else
1091 *q = prefix;
1092 return p ? p : args;
1093}
1094
1095static const char *
1096emit_adc (char prefix, char opcode, const char * args)
1097{
1098 expressionS term;
1099 int rnum;
1100 const char *p;
1101 char *q;
1102
1103 p = parse_exp (args, &term);
1104 if (*p++ != ',')
1105 {
9aff4b7a 1106 error (_("bad instruction syntax"));
3c9b82ba
NC
1107 return p;
1108 }
1109
1110 if ((term.X_md) || (term.X_op != O_register))
1111 ill_op ();
1112 else
1113 switch (term.X_add_number)
1114 {
1115 case REG_A:
1116 p = emit_s (0, prefix, p);
1117 break;
1118 case REG_HL:
1119 p = parse_exp (p, &term);
1120 if ((!term.X_md) && (term.X_op == O_register))
1121 {
1122 rnum = term.X_add_number;
1123 if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
1124 {
1125 q = frag_more (2);
1126 *q++ = 0xED;
1127 *q = opcode + ((rnum & 3) << 4);
1128 break;
1129 }
1130 }
1131 /* Fall through. */
1132 default:
1133 ill_op ();
1134 }
1135 return p;
1136}
1137
1138static const char *
1139emit_add (char prefix, char opcode, const char * args)
1140{
1141 expressionS term;
1142 int lhs, rhs;
1143 const char *p;
1144 char *q;
1145
1146 p = parse_exp (args, &term);
1147 if (*p++ != ',')
1148 {
9aff4b7a 1149 error (_("bad instruction syntax"));
3c9b82ba
NC
1150 return p;
1151 }
1152
1153 if ((term.X_md) || (term.X_op != O_register))
1154 ill_op ();
1155 else
1156 switch (term.X_add_number & ~R_INDEX)
1157 {
1158 case REG_A:
1159 p = emit_s (0, prefix, p);
1160 break;
1161 case REG_HL:
1162 lhs = term.X_add_number;
1163 p = parse_exp (p, &term);
1164 if ((!term.X_md) && (term.X_op == O_register))
1165 {
1166 rhs = term.X_add_number;
1167 if ((rhs & R_ARITH)
1168 && ((rhs == lhs) || ((rhs & ~R_INDEX) != REG_HL)))
1169 {
1170 q = frag_more ((lhs & R_INDEX) ? 2 : 1);
1171 if (lhs & R_INDEX)
1172 *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
1173 *q = opcode + ((rhs & 3) << 4);
1174 break;
1175 }
1176 }
1177 /* Fall through. */
1178 default:
1179 ill_op ();
1180 }
1181 return p;
1182}
1183
1184static const char *
1185emit_bit (char prefix, char opcode, const char * args)
1186{
1187 expressionS b;
1188 int bn;
1189 const char *p;
1190
1191 p = parse_exp (args, &b);
1192 if (*p++ != ',')
9aff4b7a 1193 error (_("bad instruction syntax"));
3c9b82ba
NC
1194
1195 bn = b.X_add_number;
1196 if ((!b.X_md)
1197 && (b.X_op == O_constant)
1198 && (0 <= bn)
1199 && (bn < 8))
1200 {
1201 if (opcode == 0x40)
1202 /* Bit : no optional third operand. */
1203 p = emit_m (prefix, opcode + (bn << 3), p);
1204 else
1205 /* Set, res : resulting byte can be copied to register. */
1206 p = emit_mr (prefix, opcode + (bn << 3), p);
1207 }
1208 else
1209 ill_op ();
1210 return p;
1211}
1212
1213static const char *
1214emit_jpcc (char prefix, char opcode, const char * args)
1215{
1216 char cc;
1217 const char *p;
1218
1219 p = parse_cc (args, & cc);
1220 if (p && *p++ == ',')
1221 p = emit_call (0, opcode + cc, p);
1222 else
1223 p = (prefix == (char)0xC3)
1224 ? emit_jp (0xE9, prefix, args)
1225 : emit_call (0, prefix, args);
1226 return p;
1227}
1228
1229static const char *
1230emit_jrcc (char prefix, char opcode, const char * args)
1231{
1232 char cc;
1233 const char *p;
1234
1235 p = parse_cc (args, &cc);
1236 if (p && *p++ == ',')
1237 {
1238 if (cc > (3 << 3))
1239 error (_("condition code invalid for jr"));
1240 else
1241 p = emit_jr (0, opcode + cc, p);
1242 }
1243 else
1244 p = emit_jr (0, prefix, args);
1245
1246 return p;
1247}
1248
1249static const char *
1250emit_ex (char prefix_in ATTRIBUTE_UNUSED,
1251 char opcode_in ATTRIBUTE_UNUSED, const char * args)
1252{
1253 expressionS op;
1254 const char * p;
1255 char prefix, opcode;
1256
25045f79 1257 p = parse_exp_not_indexed (args, &op);
3c9b82ba
NC
1258 p = skip_space (p);
1259 if (*p++ != ',')
1260 {
1261 error (_("bad instruction syntax"));
1262 return p;
1263 }
1264
1265 prefix = opcode = 0;
1266 if (op.X_op == O_register)
1267 switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
1268 {
1269 case REG_AF:
1270 if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
1271 {
1272 /* The scrubber changes '\'' to '`' in this context. */
1273 if (*p == '`')
1274 ++p;
1275 opcode = 0x08;
1276 }
1277 break;
1278 case REG_DE:
1279 if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
1280 opcode = 0xEB;
1281 break;
1282 case REG_SP|0x8000:
1283 p = parse_exp (p, & op);
1284 if (op.X_op == O_register
1285 && op.X_md == 0
1286 && (op.X_add_number & ~R_INDEX) == REG_HL)
1287 {
1288 opcode = 0xE3;
1289 if (R_INDEX & op.X_add_number)
1290 prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
1291 }
1292 break;
1293 }
1294 if (opcode)
1295 emit_insn (prefix, opcode, p);
1296 else
1297 ill_op ();
1298
1299 return p;
1300}
1301
1302static const char *
1303emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1304 const char * args)
1305{
1306 expressionS reg, port;
1307 const char *p;
1308 char *q;
1309
1310 p = parse_exp (args, &reg);
1311 if (*p++ != ',')
1312 {
9aff4b7a 1313 error (_("bad instruction syntax"));
3c9b82ba
NC
1314 return p;
1315 }
1316
1317 p = parse_exp (p, &port);
1318 if (reg.X_md == 0
1319 && reg.X_op == O_register
1320 && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
1321 && (port.X_md))
1322 {
1323 if (port.X_op != O_md1 && port.X_op != O_register)
1324 {
1325 if (REG_A == reg.X_add_number)
1326 {
1327 q = frag_more (1);
1328 *q = 0xDB;
1329 emit_byte (&port, BFD_RELOC_8);
1330 }
1331 else
1332 ill_op ();
1333 }
1334 else
1335 {
1336 if (port.X_add_number == REG_C)
1337 {
1338 if (reg.X_add_number == REG_F)
1339 check_mach (INS_UNDOC);
1340 else
1341 {
1342 q = frag_more (2);
1343 *q++ = 0xED;
1344 *q = 0x40|((reg.X_add_number&7)<<3);
1345 }
1346 }
1347 else
1348 ill_op ();
1349 }
1350 }
1351 else
1352 ill_op ();
1353 return p;
1354}
1355
1356static const char *
1357emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1358 const char * args)
1359{
1360 expressionS reg, port;
1361 const char *p;
1362 char *q;
1363
1364 p = parse_exp (args, & port);
1365 if (*p++ != ',')
1366 {
9aff4b7a 1367 error (_("bad instruction syntax"));
3c9b82ba
NC
1368 return p;
1369 }
1370 p = parse_exp (p, &reg);
1371 if (!port.X_md)
1372 { ill_op (); return p; }
1373 /* Allow "out (c), 0" as unportable instruction. */
1374 if (reg.X_op == O_constant && reg.X_add_number == 0)
1375 {
1376 check_mach (INS_UNPORT);
1377 reg.X_op = O_register;
1378 reg.X_add_number = 6;
1379 }
1380 if (reg.X_md
1381 || reg.X_op != O_register
1382 || reg.X_add_number > 7)
1383 ill_op ();
1384 else
1385 if (port.X_op != O_register && port.X_op != O_md1)
1386 {
1387 if (REG_A == reg.X_add_number)
1388 {
1389 q = frag_more (1);
1390 *q = 0xD3;
1391 emit_byte (&port, BFD_RELOC_8);
1392 }
1393 else
1394 ill_op ();
1395 }
1396 else
1397 {
1398 if (REG_C == port.X_add_number)
1399 {
1400 q = frag_more (2);
1401 *q++ = 0xED;
1402 *q = 0x41 | (reg.X_add_number << 3);
1403 }
1404 else
1405 ill_op ();
1406 }
1407 return p;
1408}
1409
1410static const char *
1411emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1412{
1413 expressionS addr;
1414 const char *p;
1415 char *q;
1416
25045f79 1417 p = parse_exp_not_indexed (args, &addr);
3c9b82ba
NC
1418 if (addr.X_op != O_constant)
1419 {
1420 error ("rst needs constant address");
1421 return p;
1422 }
1423
1424 if (addr.X_add_number & ~(7 << 3))
1425 ill_op ();
1426 else
1427 {
1428 q = frag_more (1);
1429 *q = opcode + (addr.X_add_number & (7 << 3));
1430 }
1431 return p;
1432}
1433
1434static void
1435emit_ldxhl (char prefix, char opcode, expressionS *src, expressionS *d)
1436{
1437 char *q;
1438
1439 if (src->X_md)
1440 ill_op ();
1441 else
1442 {
1443 if (src->X_op == O_register)
1444 {
1445 if (src->X_add_number>7)
1446 ill_op ();
1447 if (prefix)
1448 {
1449 q = frag_more (2);
1450 *q++ = prefix;
1451 }
1452 else
1453 q = frag_more (1);
1454 *q = opcode + src->X_add_number;
1455 if (d)
1456 emit_byte (d, BFD_RELOC_Z80_DISP8);
1457 }
1458 else
1459 {
1460 if (prefix)
1461 {
1462 q = frag_more (2);
1463 *q++ = prefix;
1464 }
1465 else
1466 q = frag_more (1);
1467 *q = opcode^0x46;
1468 if (d)
1469 emit_byte (d, BFD_RELOC_Z80_DISP8);
1470 emit_byte (src, BFD_RELOC_8);
1471 }
1472 }
1473}
1474
1475static void
1476emit_ldreg (int dest, expressionS * src)
1477{
1478 char *q;
1479 int rnum;
1480
1481 switch (dest)
1482 {
1483 /* 8 Bit ld group: */
1484 case REG_I:
1485 case REG_R:
1486 if (src->X_md == 0 && src->X_op == O_register && src->X_add_number == REG_A)
1487 {
1488 q = frag_more (2);
1489 *q++ = 0xED;
1490 *q = (dest == REG_I) ? 0x47 : 0x4F;
1491 }
1492 else
1493 ill_op ();
1494 break;
1495
1496 case REG_A:
1497 if ((src->X_md) && src->X_op != O_register && src->X_op != O_md1)
1498 {
1499 q = frag_more (1);
1500 *q = 0x3A;
1501 emit_word (src);
1502 break;
1503 }
1504
1505 if ((src->X_md)
1506 && src->X_op == O_register
1507 && (src->X_add_number == REG_BC || src->X_add_number == REG_DE))
1508 {
1509 q = frag_more (1);
2cf402d6 1510 *q = 0x0A + ((src->X_add_number & 1) << 4);
3c9b82ba
NC
1511 break;
1512 }
1513
1514 if ((!src->X_md)
1515 && src->X_op == O_register
1516 && (src->X_add_number == REG_R || src->X_add_number == REG_I))
1517 {
1518 q = frag_more (2);
1519 *q++ = 0xED;
1520 *q = (src->X_add_number == REG_I) ? 0x57 : 0x5F;
1521 break;
1522 }
1523 /* Fall through. */
1524 case REG_B:
1525 case REG_C:
1526 case REG_D:
1527 case REG_E:
1528 emit_sx (0, 0x40 + (dest << 3), src);
1529 break;
1530
1531 case REG_H:
1532 case REG_L:
1533 if ((src->X_md == 0)
1534 && (src->X_op == O_register)
1535 && (src->X_add_number & R_INDEX))
1536 ill_op ();
1537 else
1538 emit_sx (0, 0x40 + (dest << 3), src);
1539 break;
1540
1541 case R_IX | REG_H:
1542 case R_IX | REG_L:
1543 case R_IY | REG_H:
1544 case R_IY | REG_L:
1545 if (src->X_md)
1546 {
1547 ill_op ();
1548 break;
1549 }
1550 check_mach (INS_UNDOC);
1551 if (src-> X_op == O_register)
1552 {
1553 rnum = src->X_add_number;
1554 if ((rnum & ~R_INDEX) < 8
1555 && ((rnum & R_INDEX) == (dest & R_INDEX)
1556 || ( (rnum & ~R_INDEX) != REG_H
1557 && (rnum & ~R_INDEX) != REG_L)))
1558 {
1559 q = frag_more (2);
1560 *q++ = (dest & R_IX) ? 0xDD : 0xFD;
1561 *q = 0x40 + ((dest & 0x07) << 3) + (rnum & 7);
1562 }
1563 else
1564 ill_op ();
1565 }
1566 else
1567 {
1568 q = frag_more (2);
1569 *q++ = (dest & R_IX) ? 0xDD : 0xFD;
1570 *q = 0x06 + ((dest & 0x07) << 3);
1571 emit_byte (src, BFD_RELOC_8);
1572 }
1573 break;
1574
1575 /* 16 Bit ld group: */
1576 case REG_SP:
1577 if (src->X_md == 0
1578 && src->X_op == O_register
1579 && REG_HL == (src->X_add_number &~ R_INDEX))
1580 {
1581 q = frag_more ((src->X_add_number & R_INDEX) ? 2 : 1);
1582 if (src->X_add_number & R_INDEX)
1583 *q++ = (src->X_add_number & R_IX) ? 0xDD : 0xFD;
1584 *q = 0xF9;
1585 break;
1586 }
1587 /* Fall through. */
1588 case REG_BC:
1589 case REG_DE:
7fbe7b46 1590 if (src->X_op == O_register || src->X_op == O_md1)
3c9b82ba
NC
1591 ill_op ();
1592 q = frag_more (src->X_md ? 2 : 1);
1593 if (src->X_md)
1594 {
1595 *q++ = 0xED;
1596 *q = 0x4B + ((dest & 3) << 4);
1597 }
1598 else
1599 *q = 0x01 + ((dest & 3) << 4);
1600 emit_word (src);
1601 break;
1602
1603 case REG_HL:
1604 case REG_HL | R_IX:
1605 case REG_HL | R_IY:
1606 if (src->X_op == O_register || src->X_op == O_md1)
1607 ill_op ();
1608 q = frag_more ((dest & R_INDEX) ? 2 : 1);
1609 if (dest & R_INDEX)
1610 * q ++ = (dest & R_IX) ? 0xDD : 0xFD;
1611 *q = (src->X_md) ? 0x2A : 0x21;
1612 emit_word (src);
1613 break;
1614
1615 case REG_AF:
1616 case REG_F:
1617 ill_op ();
1618 break;
1619
1620 default:
1621 abort ();
1622 }
1623}
1624
1625static const char *
1626emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
1627 const char * args)
1628{
1629 expressionS dst, src;
1630 const char *p;
1631 char *q;
1632 char prefix, opcode;
1633
1634 p = parse_exp (args, &dst);
1635 if (*p++ != ',')
9aff4b7a 1636 error (_("bad instruction syntax"));
3c9b82ba
NC
1637 p = parse_exp (p, &src);
1638
1639 switch (dst.X_op)
1640 {
1641 case O_md1:
761025be
AM
1642 {
1643 expressionS dst_offset = dst;
1644 dst_offset.X_op = O_symbol;
1645 dst_offset.X_add_number = 0;
1646 emit_ldxhl ((dst.X_add_number & R_IX) ? 0xDD : 0xFD, 0x70,
1647 &src, &dst_offset);
1648 }
3c9b82ba
NC
1649 break;
1650
1651 case O_register:
1652 if (dst.X_md)
1653 {
1654 switch (dst.X_add_number)
1655 {
1656 case REG_BC:
1657 case REG_DE:
1658 if (src.X_md == 0 && src.X_op == O_register && src.X_add_number == REG_A)
1659 {
1660 q = frag_more (1);
1661 *q = 0x02 + ( (dst.X_add_number & 1) << 4);
1662 }
1663 else
1664 ill_op ();
1665 break;
1666 case REG_HL:
1667 emit_ldxhl (0, 0x70, &src, NULL);
1668 break;
1669 default:
1670 ill_op ();
1671 }
1672 }
1673 else
1674 emit_ldreg (dst.X_add_number, &src);
1675 break;
1676
1677 default:
1678 if (src.X_md != 0 || src.X_op != O_register)
1679 ill_op ();
1680 prefix = opcode = 0;
1681 switch (src.X_add_number)
1682 {
1683 case REG_A:
1684 opcode = 0x32; break;
1685 case REG_BC: case REG_DE: case REG_SP:
1686 prefix = 0xED; opcode = 0x43 + ((src.X_add_number&3)<<4); break;
1687 case REG_HL:
1688 opcode = 0x22; break;
1689 case REG_HL|R_IX:
1690 prefix = 0xDD; opcode = 0x22; break;
1691 case REG_HL|R_IY:
1692 prefix = 0xFD; opcode = 0x22; break;
1693 }
1694 if (opcode)
1695 {
1696 q = frag_more (prefix?2:1);
1697 if (prefix)
1698 *q++ = prefix;
1699 *q = opcode;
1700 emit_word (&dst);
1701 }
1702 else
1703 ill_op ();
1704 }
1705 return p;
1706}
1707
134dcee5
AM
1708static void
1709emit_data (int size ATTRIBUTE_UNUSED)
3c9b82ba
NC
1710{
1711 const char *p, *q;
1712 char *u, quote;
1713 int cnt;
1714 expressionS exp;
1715
134dcee5
AM
1716 if (is_it_end_of_statement ())
1717 {
1718 demand_empty_rest_of_line ();
1719 return;
1720 }
1721 p = skip_space (input_line_pointer);
3c9b82ba 1722
134dcee5 1723 do
3c9b82ba
NC
1724 {
1725 if (*p == '\"' || *p == '\'')
1726 {
134dcee5
AM
1727 for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
1728 ;
1729 u = frag_more (cnt);
1730 memcpy (u, q, cnt);
1731 if (!*p)
1732 as_warn (_("unterminated string"));
1733 else
1734 p = skip_space (p+1);
3c9b82ba
NC
1735 }
1736 else
1737 {
1738 p = parse_exp (p, &exp);
1739 if (exp.X_op == O_md1 || exp.X_op == O_register)
1740 {
1741 ill_op ();
1742 break;
1743 }
1744 if (exp.X_md)
1745 as_warn (_("parentheses ignored"));
134dcee5 1746 emit_byte (&exp, BFD_RELOC_8);
3c9b82ba
NC
1747 p = skip_space (p);
1748 }
3c9b82ba 1749 }
134dcee5
AM
1750 while (*p++ == ',') ;
1751 input_line_pointer = (char *)(p-1);
3c9b82ba
NC
1752}
1753
1754static const char *
1755emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1756{
1757 const char *p;
1758
1759 p = skip_space (args);
1760 if (TOLOWER (*p++) != 'a' || *p++ != ',')
1761 ill_op ();
1762 else
1763 {
1764 char *q, reg;
1765
1766 reg = TOLOWER (*p++);
1767 switch (reg)
1768 {
1769 case 'b':
1770 case 'c':
1771 case 'd':
1772 case 'e':
1773 check_mach (INS_R800);
1774 if (!*skip_space (p))
1775 {
1776 q = frag_more (2);
1777 *q++ = prefix;
1778 *q = opcode + ((reg - 'b') << 3);
1779 break;
1780 }
1a0670f3 1781 /* Fall through. */
3c9b82ba
NC
1782 default:
1783 ill_op ();
1784 }
1785 }
1786 return p;
1787}
1788
1789static const char *
1790emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1791{
1792 const char *p;
1793
1794 p = skip_space (args);
1795 if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
1796 ill_op ();
1797 else
1798 {
1799 expressionS reg;
1800 char *q;
1801
1802 p = parse_exp (p, & reg);
1803
1804 if ((!reg.X_md) && reg.X_op == O_register)
1805 switch (reg.X_add_number)
1806 {
1807 case REG_BC:
1808 case REG_SP:
1809 check_mach (INS_R800);
1810 q = frag_more (2);
1811 *q++ = prefix;
1812 *q = opcode + ((reg.X_add_number & 3) << 4);
1813 break;
1814 default:
1815 ill_op ();
1816 }
1817 }
1818 return p;
1819}
1820
134dcee5
AM
1821/* Port specific pseudo ops. */
1822const pseudo_typeS md_pseudo_table[] =
1823{
1824 { "db" , emit_data, 1},
1825 { "d24", cons, 3},
1826 { "d32", cons, 4},
1827 { "def24", cons, 3},
1828 { "def32", cons, 4},
3739860c 1829 { "defb", emit_data, 1},
134dcee5
AM
1830 { "defs", s_space, 1}, /* Synonym for ds on some assemblers. */
1831 { "defw", cons, 2},
1832 { "ds", s_space, 1}, /* Fill with bytes rather than words. */
1833 { "dw", cons, 2},
1834 { "psect", obj_coff_section, 0}, /* TODO: Translate attributes. */
1835 { "set", 0, 0}, /* Real instruction on z80. */
1836 { NULL, 0, 0 }
1837} ;
1838
3c9b82ba
NC
1839static table_t instab[] =
1840{
1841 { "adc", 0x88, 0x4A, emit_adc },
1842 { "add", 0x80, 0x09, emit_add },
1843 { "and", 0x00, 0xA0, emit_s },
1844 { "bit", 0xCB, 0x40, emit_bit },
1845 { "call", 0xCD, 0xC4, emit_jpcc },
1846 { "ccf", 0x00, 0x3F, emit_insn },
1847 { "cp", 0x00, 0xB8, emit_s },
1848 { "cpd", 0xED, 0xA9, emit_insn },
1849 { "cpdr", 0xED, 0xB9, emit_insn },
1850 { "cpi", 0xED, 0xA1, emit_insn },
1851 { "cpir", 0xED, 0xB1, emit_insn },
1852 { "cpl", 0x00, 0x2F, emit_insn },
1853 { "daa", 0x00, 0x27, emit_insn },
3c9b82ba 1854 { "dec", 0x0B, 0x05, emit_incdec },
3c9b82ba
NC
1855 { "di", 0x00, 0xF3, emit_insn },
1856 { "djnz", 0x00, 0x10, emit_jr },
3c9b82ba
NC
1857 { "ei", 0x00, 0xFB, emit_insn },
1858 { "ex", 0x00, 0x00, emit_ex},
1859 { "exx", 0x00, 0xD9, emit_insn },
1860 { "halt", 0x00, 0x76, emit_insn },
1861 { "im", 0xED, 0x46, emit_im },
1862 { "in", 0x00, 0x00, emit_in },
1863 { "inc", 0x03, 0x04, emit_incdec },
1864 { "ind", 0xED, 0xAA, emit_insn },
1865 { "indr", 0xED, 0xBA, emit_insn },
1866 { "ini", 0xED, 0xA2, emit_insn },
1867 { "inir", 0xED, 0xB2, emit_insn },
1868 { "jp", 0xC3, 0xC2, emit_jpcc },
1869 { "jr", 0x18, 0x20, emit_jrcc },
1870 { "ld", 0x00, 0x00, emit_ld },
1871 { "ldd", 0xED, 0xA8, emit_insn },
1872 { "lddr", 0xED, 0xB8, emit_insn },
1873 { "ldi", 0xED, 0xA0, emit_insn },
1874 { "ldir", 0xED, 0xB0, emit_insn },
1875 { "mulub", 0xED, 0xC5, emit_mulub }, /* R800 only. */
1876 { "muluw", 0xED, 0xC3, emit_muluw }, /* R800 only. */
1877 { "neg", 0xed, 0x44, emit_insn },
1878 { "nop", 0x00, 0x00, emit_insn },
1879 { "or", 0x00, 0xB0, emit_s },
1880 { "otdr", 0xED, 0xBB, emit_insn },
1881 { "otir", 0xED, 0xB3, emit_insn },
1882 { "out", 0x00, 0x00, emit_out },
1883 { "outd", 0xED, 0xAB, emit_insn },
1884 { "outi", 0xED, 0xA3, emit_insn },
1885 { "pop", 0x00, 0xC1, emit_pop },
1886 { "push", 0x00, 0xC5, emit_pop },
1887 { "res", 0xCB, 0x80, emit_bit },
1888 { "ret", 0xC9, 0xC0, emit_retcc },
1889 { "reti", 0xED, 0x4D, emit_insn },
1890 { "retn", 0xED, 0x45, emit_insn },
1891 { "rl", 0xCB, 0x10, emit_mr },
1892 { "rla", 0x00, 0x17, emit_insn },
1893 { "rlc", 0xCB, 0x00, emit_mr },
1894 { "rlca", 0x00, 0x07, emit_insn },
1895 { "rld", 0xED, 0x6F, emit_insn },
1896 { "rr", 0xCB, 0x18, emit_mr },
1897 { "rra", 0x00, 0x1F, emit_insn },
1898 { "rrc", 0xCB, 0x08, emit_mr },
1899 { "rrca", 0x00, 0x0F, emit_insn },
1900 { "rrd", 0xED, 0x67, emit_insn },
1901 { "rst", 0x00, 0xC7, emit_rst},
1902 { "sbc", 0x98, 0x42, emit_adc },
1903 { "scf", 0x00, 0x37, emit_insn },
1904 { "set", 0xCB, 0xC0, emit_bit },
1905 { "sla", 0xCB, 0x20, emit_mr },
1906 { "sli", 0xCB, 0x30, emit_mr },
1907 { "sll", 0xCB, 0x30, emit_mr },
1908 { "sra", 0xCB, 0x28, emit_mr },
1909 { "srl", 0xCB, 0x38, emit_mr },
1910 { "sub", 0x00, 0x90, emit_s },
1911 { "xor", 0x00, 0xA8, emit_s },
1912} ;
1913
1914void
1915md_assemble (char* str)
1916{
1917 const char *p;
1918 char * old_ptr;
1919 int i;
1920 table_t *insp;
1921
1922 err_flag = 0;
1923 old_ptr = input_line_pointer;
1924 p = skip_space (str);
1925 for (i = 0; (i < BUFLEN) && (ISALPHA (*p));)
1926 buf[i++] = TOLOWER (*p++);
1927
134dcee5
AM
1928 if (i == BUFLEN)
1929 {
1930 buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated. */
1931 buf[BUFLEN-1] = 0;
1932 as_bad (_("Unknown instruction '%s'"), buf);
1933 }
1934 else if ((*p) && (!ISSPACE (*p)))
1935 as_bad (_("syntax error"));
3739860c 1936 else
3c9b82ba 1937 {
134dcee5 1938 buf[i] = 0;
3c9b82ba 1939 p = skip_space (p);
134dcee5 1940 key = buf;
3739860c 1941
134dcee5
AM
1942 insp = bsearch (&key, instab, ARRAY_SIZE (instab),
1943 sizeof (instab[0]), key_cmp);
1944 if (!insp)
1945 as_bad (_("Unknown instruction '%s'"), buf);
1946 else
1947 {
1948 p = insp->fp (insp->prefix, insp->opcode, p);
1949 p = skip_space (p);
1950 if ((!err_flag) && *p)
1951 as_bad (_("junk at end of line, first unrecognized character is `%c'"),
1952 *p);
1953 }
3c9b82ba
NC
1954 }
1955 input_line_pointer = old_ptr;
1956}
1957
1958void
1959md_apply_fix (fixS * fixP, valueT* valP, segT seg ATTRIBUTE_UNUSED)
1960{
1961 long val = * (long *) valP;
de6d4f05 1962 char *p_lit = fixP->fx_where + fixP->fx_frag->fr_literal;
3c9b82ba
NC
1963
1964 switch (fixP->fx_r_type)
1965 {
1966 case BFD_RELOC_8_PCREL:
1967 if (fixP->fx_addsy)
1968 {
1969 fixP->fx_no_overflow = 1;
1970 fixP->fx_done = 0;
1971 }
1972 else
1973 {
1974 fixP->fx_no_overflow = (-128 <= val && val < 128);
1975 if (!fixP->fx_no_overflow)
1976 as_bad_where (fixP->fx_file, fixP->fx_line,
1977 _("relative jump out of range"));
de6d4f05 1978 *p_lit++ = val;
3c9b82ba
NC
1979 fixP->fx_done = 1;
1980 }
1981 break;
1982
1983 case BFD_RELOC_Z80_DISP8:
1984 if (fixP->fx_addsy)
1985 {
1986 fixP->fx_no_overflow = 1;
1987 fixP->fx_done = 0;
1988 }
1989 else
1990 {
1991 fixP->fx_no_overflow = (-128 <= val && val < 128);
1992 if (!fixP->fx_no_overflow)
1993 as_bad_where (fixP->fx_file, fixP->fx_line,
1994 _("index offset out of range"));
de6d4f05 1995 *p_lit++ = val;
3c9b82ba
NC
1996 fixP->fx_done = 1;
1997 }
1998 break;
1999
2000 case BFD_RELOC_8:
2001 if (val > 255 || val < -128)
2002 as_warn_where (fixP->fx_file, fixP->fx_line, _("overflow"));
de6d4f05 2003 *p_lit++ = val;
3739860c 2004 fixP->fx_no_overflow = 1;
3c9b82ba
NC
2005 if (fixP->fx_addsy == NULL)
2006 fixP->fx_done = 1;
2007 break;
2008
2009 case BFD_RELOC_16:
de6d4f05
AM
2010 *p_lit++ = val;
2011 *p_lit++ = (val >> 8);
3739860c 2012 fixP->fx_no_overflow = 1;
134dcee5
AM
2013 if (fixP->fx_addsy == NULL)
2014 fixP->fx_done = 1;
2015 break;
2016
2017 case BFD_RELOC_24: /* Def24 may produce this. */
de6d4f05
AM
2018 *p_lit++ = val;
2019 *p_lit++ = (val >> 8);
2020 *p_lit++ = (val >> 16);
3739860c 2021 fixP->fx_no_overflow = 1;
3c9b82ba
NC
2022 if (fixP->fx_addsy == NULL)
2023 fixP->fx_done = 1;
2024 break;
2025
134dcee5 2026 case BFD_RELOC_32: /* Def32 and .long may produce this. */
de6d4f05
AM
2027 *p_lit++ = val;
2028 *p_lit++ = (val >> 8);
2029 *p_lit++ = (val >> 16);
2030 *p_lit++ = (val >> 24);
3c9b82ba
NC
2031 if (fixP->fx_addsy == NULL)
2032 fixP->fx_done = 1;
2033 break;
2034
2035 default:
2036 printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
2037 abort ();
2038 }
2039}
2040
2041/* GAS will call this to generate a reloc. GAS will pass the
2042 resulting reloc to `bfd_install_relocation'. This currently works
2043 poorly, as `bfd_install_relocation' often does the wrong thing, and
2044 instances of `tc_gen_reloc' have been written to work around the
2045 problems, which in turns makes it difficult to fix
2046 `bfd_install_relocation'. */
2047
2048/* If while processing a fixup, a reloc really
2049 needs to be created then it is done here. */
2050
2051arelent *
2052tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
2053{
2054 arelent *reloc;
2055
2056 if (! bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type))
2057 {
2058 as_bad_where (fixp->fx_file, fixp->fx_line,
2059 _("reloc %d not supported by object file format"),
2060 (int) fixp->fx_r_type);
2061 return NULL;
2062 }
2063
325801bd
TS
2064 reloc = XNEW (arelent);
2065 reloc->sym_ptr_ptr = XNEW (asymbol *);
3c9b82ba
NC
2066 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2067 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2068 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2069 reloc->addend = fixp->fx_offset;
2070
2071 return reloc;
2072}
This page took 0.589878 seconds and 4 git commands to generate.